2012-02-02 20 views
6

मुझे पता है कि इस सवाल से कई बार पूछा गया है, लेकिन मैंने जो भी देखा है उससे कोई भी काम करने का जवाब नहीं दे पाया है।एसएमएस सामग्री ऑब्सर्वर ऑन चेंज() कई बार आग लगती है

मैं टेक्स्ट संदेशों को रोकने और भेजने के आधार पर एक ऐप पर काम कर रहा हूं, कस्टम अलर्ट के साथ पॉप अप करता हूं। मैंने ब्रॉडकास्ट रिसीवर के साथ खूबसूरती से काम किया है, हालांकि यदि उपयोगकर्ता ने onReceive() को स्थापित किया है तो विधि को कभी भी मेरे ऐप तक पहुंचने से पहले गोम्स के रूप में कभी भी कॉल नहीं किया जाता है।

इस के आसपास जाने के लिए, मैं content://sms/ पर एक सामग्री पर्यवेक्षक की कोशिश कर रहा हूं, यह ठीक काम कर रहा है, हालांकि onChange() को दो बार कहा जाता है, ठीक उसी पैरामीटर के साथ। मैंने टाइम टिकटें जांचने की कोशिश की, लेकिन वे वही हैं, जैसा कि मैंने टाइप किया है और हर दूसरे पैरामीटर को सेट किया है।

जो मैंने देखा है, यह एक आम मुद्दा है, लेकिन ऐसा नहीं है जिसे मैंने कहीं भी देखा है।

@Override 
public void onChange(boolean selfChange) { 
    super.onChange(selfChange); 
    querySMS(); 
} 

protected void querySMS() { 
    Cursor cur = getContentResolver().query(u, null, null, null, null); 
    cur.moveToNext(); // this will make it point to the first record, which is the last SMS sent 
    String type = cur.getString(cur.getColumnIndex("type")); 
    String body = cur.getString(cur.getColumnIndex("body")); //content of sms 
    String add = cur.getString(cur.getColumnIndex("address")); //phone num 
    if (type.equals("1")) { 
     if (add.equals(Test.SENDER)) {    
      String[] bodys = body.split(" ", 7); 
      if (bodys[0].equals("test")) { 
       test = true; 
      } 
      cat = bodys[1]; 
      level = bodys[2]; 
      urgency = bodys[3]; 
      certainty = bodys[4]; 
      carrier = bodys[5]; 
      message = bodys[6]; 
      final Intent intent = new Intent(context, AlertActivity.class); 
      Bundle b = new Bundle(); 
      b.putString("title", cat); 
      b.putString("certainty", certainty); 
      b.putString("urgency", urgency); 
      b.putString("level", level); 
      b.putString("message", message); 
      b.putBoolean("test", test); 
      intent.putExtras(b); 
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
      TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
      carrierName = manager.getNetworkOperatorName(); 
      if (carrierName.replaceAll(" ", "").equals(carrier)) { 

       context.startActivity(intent); 
      } else { 
       //testing 
       Toast.makeText(context, carrierName.replaceAll(" ", ""), Toast.LENGTH_LONG).show(); 
      } 
     } 
    } 
} 
onChange() की वजह से

दो बार इम दो अलर्ट हो रही साथ ही निकाल दिया जा रहा है। मैं अपने जीवन के लिए इस के आसपास एक रास्ता नहीं समझ सकता।

+1

अन्य (अपूर्ण) उत्तरों के लिंक उपयोगी होंगे – KevinDTimm

उत्तर

4

दो समान हैं:
दुकान प्रत्येक संदेश recv'd
पिछले संदेशों की तुलना recv'd
न मिलने पर, प्रक्रिया
अगर पाया, संदेश त्यागने

के जीवन संग्रहीत संदेश infinitesimal होना चाहिए, 5 संदेशों का एक छोटा परिपत्र बफर ठीक होना चाहिए।

+0

संदेश केवल एक बार प्राप्त किया जा रहा है। यह दो बार नहीं आ रहा है। टीबीएच, मैं यह भी नहीं जानता कि दूसरा 'ऑन चेंज' भी ट्रिगर किया जा रहा है। – r2DoesInc

+2

आह। http://stackoverflow.com/questions/7012703/android-detect-sms-outgoing-incorrect-count के साथ आपको विचार आया और मुझे यह काम मिल गया। मुझे लगता है कि मैंने पहली बार जब आप इसे पढ़ा था तो मैंने गलत समझा। मैंने एक स्थिर 'सरणी सूची' बनाई और इसे जांचने के लिए उपयोग किया। \t \t \t 'if (! Ids.contains (id)) {ids.add (id); context.startActivity (इरादा);}' – r2DoesInc

3

आप अंतिम संदेश की आईडी को सहेज सकते हैं और द्वारा onChange पर लौटाए गए संदेश की आईडी पर इसकी तुलना कर सकते हैं। यदि आप आईडी समान हैं तो आप बस संदेश को अवहेलना कर सकते हैं।

// might contain mistakes, but you'll get the idea: 
protected void querySMS() { 
    Cursor cur = getContentResolver().query(u, null, null, null, null); 
    cur.moveToNext(); 
    if (lastId == cur.getLong(cur.getColumnIndex("_id"))) 
     return; 
    lastId = cur.getLong(cur.getColumnIndex("_id")); 
    ... //continue as it was 
} 

हालांकि - GO एसएमएस केवल प्रसारण प्राप्त उपयोगकर्ता इस विकल्प का चयन करता है, तो अन्य एप्लिकेशन की रोकता है (प्राप्त सेटिंग्स - अन्य संदेश सूचना अक्षम) - तो उपयोगकर्ता अन्य एप्लिकेशन उसे परेशान करने के लिए नहीं चाहता है, तो - मैं ऐसा लगता है कि ऐसा नहीं करना अच्छा विचार है। (: ... id\type की तरह)

+0

ऐप मैं जिस पर काम कर रहा हूं वह अनदेखा नहीं होना चाहिए। यह डिवाइस पर प्रीइंस्टॉल किया गया है और वर्तमान में फोन पर चल रहे किसी भी चीज़ पर कुल प्राथमिकता लेना है। मैंने कुछ ऐसा किया है, यदि आप नीचे दिए गए उत्तर की टिप्पणियों को देखते हैं तो आप देख सकते हैं। – r2DoesInc

+1

आप समझते हैं कि आपके द्वारा पोस्ट किए गए स्निपेट को वास्तव में लंबे समय तक जाना चाहिए, इससे पहले कि इसे पूर्व में आने वाले ऐप में इस्तेमाल किया जा सके, है ना? – Vladimir

+0

ओह हां बिल्कुल। आईव सिर्फ परियोजना शुरू की। इसे जाने का लंबा रास्ता तय हुआ – r2DoesInc

4

यहाँ मेरी कोड, यह मेरे

public class SmsObserver extends ContentObserver { 
    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; 
     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 { 
         if (initialPos != getLastMsgId()) { 
          // Here you get the last sms. Do what you want. 
          String receiver = cur.getString(cur.getColumnIndex("address")); 
          System.out.println(" Receiver Ph no :"+receiver); 


          // Then, set initialPos to the current position. 
          initialPos = getLastMsgId(); 
         } 
        } catch (Exception e) { 
         // Treat exception here 
        } 
       } 
       cur.close(); 
      } 
     }).start(); 

    } 

}//End of class SmsObserver 
0

मैं अभी पिछले एसएमएस की जानकारी ने टिप्पणी दी SharedPreference का उपयोग के लिए ठीक काम करता है है। यदि यह वही है, तो मैं return होगा।

संबंधित मुद्दे