Warum wird der ContentObserver mehrfach aufgerufen?

Ich habe folgende ContentObserver Implementierung für das Empfangen und Schreiben von SMS, aber es wird mehrfach genannt.

Code:

  • Android - Entfernen von Artikel aus ListView auf lange klicken
  • ActiveAndroid App autocloses, wenn auf Lebkuchen laufen
  • Equalizer - Effektbibliothek nicht geladen
  • Android - Kann keine einfache Rechteckform erstellen ... Nicht unterstützteOperationException?
  • Spinner: onItemSelected nicht aufgerufen, wenn ausgewähltes Element bleibt das gleiche
  • Android-Apps, die mit einem Gerät kommunizieren, das an den USB-Port angeschlossen ist
  •  public class SMSObserverActivity extends Activity { protected MyContentObserver observer = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); String url = "content://mms-sms/"; Uri uri = Uri.parse(url); observer = new MyContentObserver(new Handler()); getContentResolver().registerContentObserver(uri, true, observer); } @Override protected void onDestroy(){ super.onDestroy(); getContentResolver().unregisterContentObserver(observer); } class MyContentObserver extends ContentObserver { ContentValues values = new ContentValues(); Handler handler; public MyContentObserver(Handler handler){ super(handler); this.handler = handler; } @Override public boolean deliverSelfNotifications(){ return false; } @Override public void onChange(boolean arg0){ super.onChange(arg0); Log.v("SMS", "Notification on SMS observer"); values.put("status", 5); Message msg = new Message(); msg.obj = "xxxxxxxxxx"; int threadId = 0; handler.sendMessage(msg); Uri uriSMSURI = Uri.parse("content://sms/"); Cursor cur = getContentResolver().query(uriSMSURI, null, null, null, null); cur.moveToNext(); Log.e("sms", cur.getString(4)+" "+cur.getString(11)); } } } 

    Manifest:

     <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <uses-permission android:name="android.permission.READ_SMS"></uses-permission> <uses-permission android:name="android.permission.WRITE_SMS"></uses-permission> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".SMSObserverActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 

    Warum wird es mehrfach genannt?

    BEARBEITEN:
    Es gab die Idee, dass das Problem durch den fehlenden unregisterContentObserver verursacht wird, aber es macht keinen Unterschied.

  • Android SDK Log zeigt: "Download unterbrochen: Verbindung zu https://dl-ssl.google.com abgelehnt", was kann getan werden?
  • Wie man auf Kontakte in meinem Android-Programm zugreifen kann
  • Wie kann ich feststellen, ob ein Android APK debugable auf true oder false in seinem Manifest gesetzt hat, ohne es zu installieren?
  • Erkennen Sie, ob Android SurfaceView zeichnet / bewegt
  • Wie kann ich verhindern, dass ListView footer ausgewählt wird?
  • Android TextView Text wird nicht zentrieren
  • 3 Solutions collect form web for “Warum wird der ContentObserver mehrfach aufgerufen?”

    Dies geschieht, weil Sie Ihren Content-Beobachter für die gesamte SMS-Datenbank registrieren. So wird Ihr Content-Beobachter jedes Mal benachrichtigt, wenn ein Tabelleneintrag in der Datenbank aktualisiert wird.

    In diesem Fall, wenn eine Nachricht zum Beispiel um 7 Tabellen gesendet wird, werden die Einträge aktualisiert, so dass Ihr Content-Beobachter 7 mal benachrichtigt wird.

    Da bin ich nur interessiert, wenn eine Nachricht gesendet wird, habe ich geändert, um nur die in der Warteschlange befindlichen Nachrichten zu beobachten und das bedeutet, dass mein Beobachter immer genau dreimal benachrichtigt wird, also habe ich Code implementiert, um davor zu schützen.

    Es gibt wahrscheinlich einige andere Themen wie Multi-Empfänger oder Multi-Part-Nachrichten, aber die Grundlagen arbeiten so weit.

    Um zu vermeiden, senden Sie mehrere SMS von Content-Beobachter versuchen Sie dies

     public class SmsObserver extends ContentObserver { SharedPreferences trackMeData; private Context context; private static int initialPos; private static final String TAG = "SMSContentObserver"; private static final Uri uriSMS = Uri.parse("content://sms/sent"); public SmsObserver(Handler handler, Context ctx) { super(handler); context = ctx; trackMeData = context.getSharedPreferences("LockedSIM", 0); initialPos = getLastMsgId(); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); queryLastSentSMS(); } public int getLastMsgId() { Cursor cur = context.getContentResolver().query(uriSMS, null, null, null, null); cur.moveToFirst(); int lastMsgId = cur.getInt(cur.getColumnIndex("_id")); Log.i(TAG, "Last sent message id: " + String.valueOf(lastMsgId)); return lastMsgId; } protected void queryLastSentSMS() { new Thread(new Runnable() { @Override public void run() { Cursor cur = context.getContentResolver().query(uriSMS, null, null, null, null); if (cur.moveToNext()) { try { String body = cur.getString(cur.getColumnIndex("body")); if (initialPos != getLastMsgId()) { String receiver = cur.getString(cur.getColumnIndex("address")); Log.i("account", myDeviceId); Log.i("date", day + "-" + month + "-" + year + " " + hour + ":" + minute + ":" + seconde); Log.i("sender", myTelephoneNumber); Log.i("receiver", receiver ); // Then, set initialPos to the current position. initialPos = getLastMsgId(); sendsmstoph(receiver, body); } } catch (Exception e) { // Treat exception here } } cur.close(); } }).start(); } 

    Wenn du deinen Beobachter nur dann aktivieren möchtest, wenn die Aktivität aktiv ist, empfehle ich dir, registerContentObserver() und unregisterContentObserver() auf die Methoden onResume() bzw. onPause() zu verschieben. onDestroy() darf nicht aufgerufen werden, wenn dein Antrag onPause() , aber onPause() garantiert.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.