Sierpień 22, 2011
Snippety Telefoniczne
Oto przykład komponentu BroadcastReceiver publikującego informacje o rozmówcy zaraz po zawieszeniu rozmowy. Informacje publikowane są przy każdym rozłączeniu telefonu (rozmowa przychodząca, wychodząca i nieodebrane połączenie).
Jednosekundowe opóźnienie wynika z tego, że informacje o ostatnim połączeniu zapisywane są w logach dopiero po otrzymaniu intencji o zmianie stanu telefonu.
Działanie powyższego kodu opiera się o akcję zmiany stanu telefonu (Intencja o akcji TelephonyManager.ACTION_PHONE_STATE_CHANGED). Kiedy otrzymamy informację o przejściu telefonu do stanu IDLE (bezczynny – uruchamiany w momencie zakończenia lub zrzucenia połączenia) odczytujemy informację z logów telefonu.
W naszym przypadku dane zapisywane są do LogCata.
W pliku AndroidManifest.xml należy dodać nasz BroadcastReceiver wraz z właściwym filtrem intencji, który go wywoła:
Należy również dodać pozwolenie na odczytywanie stanu telefonu:
O znaczeniu każdego pola zawartego w zwróconym obiekcie Cursor można poczytać w dokumentacji (link).
W dokumentacji do BroadcastReceiver (http://developer.android.com/reference/android/content/BroadcastReceiver.html) można przeczytać, że uruchamianie zadań asynchronicznych w onReceiv() nie jest dobrym rozwiązaniem. Czy podejście opisane w artykule rzeczywiście gwarantuje wpis do logu?
Przyznam, że przeoczyłem informację o której mówisz. Jednak w przypadku tego kodu źródłowego nie ma to zbyt wielkiego znaczenia.
Zgodnie z dokumentacją obiekt BroadcastReceiver może zostać usunięty w związku z czym nie należy przeprowadzać żadnych operacji asynchronicznych, które następnie wpłyną na jego stan.
W przypadku opisanym powyżej operacje nie mają żadnego wpływu na BroadcastReceiver, w związku z czym nie powinny wystąpić tu żadne problemy. Ewentualnie można przesunąć metodę showDataFromCursor(result); do wnętrza doInBackground(…) aby i ona była wykonana w osobnym wątku (a nie wątku receivera).
Zaloguj się lub skorzystaj z profilu:
Możesz również zostawić komentarz bez rejestracji, korzystając z poniższego formularza:
Musisz być zalogowany aby móc pisać komentarze.
Pobieranie informacji o rozmówcy po zakończonej rozmowie
Dodatkowe wymagania
Efekt działania
Komentarze (2)
Prześlij komentarz
public class CallReceiver extends BroadcastReceiver {
private static final String TAG = "CallLogDebug";
private Context context;
private AsyncTask<Void, Void, Cursor> lastCallerDataTask = new AsyncTask<Void, Void, Cursor>(){
@Override
protected Cursor doInBackground(Void... params) {
waitForCallLogUpdate();
return fetchLastCallData();
}
@Override
protected void onPostExecute(Cursor result) {
showDataFromCursor(result);
}
};
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if(TelephonyManager.EXTRA_STATE_IDLE.equals(state)) {
getLastCallerData();
}
}
private void getLastCallerData() {
lastCallerDataTask.execute();
}
private void waitForCallLogUpdate() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private Cursor fetchLastCallData() {
Uri uri = CallLog.Calls.CONTENT_URI;
String orderBy = String.format("%s desc limit 1",Calls.DATE);
return context.getContentResolver().query(uri, null, null, null, orderBy);
}
private void showDataFromCursor(Cursor c) {
if (c.moveToFirst()) {
for (int i = 0; i < c.getColumnCount(); i++) {
Log.d(TAG, c.getColumnName(i) + " : " + c.getString(i));
}
}
c.close();
}
}<receiver android:name=".CallReceiver"> <intent-filter> <action android:name="android.intent.action.PHONE_STATE" /> </intent-filter> </receiver>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
23 sierpnia 2011 o 17:00
23 sierpnia 2011 o 17:36