2012-02-02 21 views
6

この質問は複数回尋ねられていますが、誰も私が見たことから働く回答を思い付くことはできませんでした。Sms ContentObserver onChange()複数回発生

私は、テキストメッセージを傍受し、送信することによって、カスタムアラートをポップアップ表示します。私はそれが放送受信機で美しく動作しているが、ユーザーがgoSmsをインストールした場合、onReceive()メソッドは決して呼び出されない。

これを回避するには、コンテンツオブザーバを試してみてくださいcontent://sms/ 正確には、同じパラメータを使用してonChange()が2回呼び出されます。 Iveはタイムスタンプをチェックしようとしましたが、タイプと他のパラメータが設定されているのと同じです。

私が見たことから、これはよくある問題ですが、私がどこでも答えを見たことはありません。

@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()が2回発生するため、2つのアラートも取得します。私の人生はこれを回避する方法を考え出すことができません。

+1

他の(不完全な)回答へのリンクは役に立ちます – KevinDTimm

答えて

4

2が同一の場合:見つかった場合は、各メッセージは
は、前のメッセージにそれを比較recv'd
店は
見つからない場合は、プロセス
をrecv'd、メッセージ

の生活を捨てます格納されたメッセージは無限小でなければなりません。5つのメッセージの小さな循環バッファが問題ありません。

+0

メッセージは一度だけ受信されています。それは二度来ない。 tbh、私は2番目の 'onChange'がトリガーされているものさえ知っていません。 – r2DoesInc

+2

ああ。 http://stackoverflow.com/questions/7012703/android-detect-sms-outgoing-incorrect-countとアイデアを結びました。初めて読んだときの意味を誤解していたと思います。静的な 'arrayList'を作成し、これをチェックするために使用しました。 \t \t \t 'if(!ids.contains(id)); ids.add(id); context.startActivity(intent);} – r2DoesInc

3

最後のメッセージのIDを保存し、curによって返されたメッセージのIDとonChangeに比較することができます。 idsが同じであれば、メッセージを無視することができます。

// 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 
} 

は、しかし - ( - 他のメッセージ通知を無効レシーブ設定) - SMSが唯一のユーザーがこのオプションを選択した場合、ブロードキャストが供給から他のアプリのを防ぐGOので、ユーザは、他のアプリが彼を邪魔したくない場合 - Iそうしないことをお勧めします。ここ

+0

これは無視されるべきではありません。そのデバイスにプリインストールされ、現在電話で実行されている他のものよりも優先されます。私はあなたが見ることができる以下の答えのコメントを見れば、これに似た何かをしました。 – r2DoesInc

+1

あなたが投稿したスニペットは、事前に来る予定のアプリで使用される前に、本当に、本当に長い道のりになるはずですね。 – Vladimir

+0

ああもちろんです。 iveはちょうどプロジェクトを開始しました。その長い道のりがある – r2DoesInc

4

はそれが私はちょうど最後のSMS情報(:id\type ...など)を指摘すべきSharedPreferenceを使用

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

私のために正常に動作します、私のコードです。それが同じなら、私はreturnになります。

関連する問題