2012-02-02 35 views
6

Tôi biết câu hỏi này đã được hỏi nhiều lần, nhưng không ai có thể đưa ra câu trả lời làm việc từ những gì tôi đã thấy.Sms ContentObserver onChange() cháy nhiều lần

Im làm việc trên ứng dụng để chặn tin nhắn văn bản và tùy thuộc vào số lần gửi #, bật lên bằng cảnh báo tùy chỉnh. Tôi có nó làm việc tốt đẹp với một máy thu phát sóng, tuy nhiên nếu người dùng đã goSms cài đặt các phương pháp onReceive() không bao giờ được gọi là goSms hủy bỏ nó trước khi nó đến ứng dụng của tôi.

Để giải quyết vấn đề này, hãy thử người quan sát nội dung theo số content://sms/ Chỉ hoạt động tốt, tuy nhiên, onChange() được gọi hai lần, với chính xác cùng thông số. Ive đã cố gắng kiểm tra tem thời gian, nhưng chúng giống nhau, cũng như kiểu và mọi tham số khác tôi đã đặt.

Từ những gì tôi đã thấy, đây là vấn đề phổ biến, nhưng không phải là vấn đề mà tôi đã thấy được trả lời ở bất kỳ đâu.

@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(); 
      } 
     } 
    } 
} 

Vì số onChange() bị hủy hai lần, tôi cũng nhận được hai cảnh báo. Tôi không thể cho cuộc sống của tôi tìm ra một cách xung quanh điều này.

+1

liên kết đến câu trả lời khác (không đầy đủ) sẽ hữu ích – KevinDTimm

Trả lời

4

Nếu hai giống hệt nhau:
cửa hàng mỗi tin nhắn recv'd
so sánh nó với tin nhắn trước recv'd
nếu không tìm thấy, quá trình
nếu tìm thấy, loại bỏ các thông điệp

Cuộc đời các tin nhắn được lưu trữ phải là infinitesimal, một bộ đệm tròn nhỏ của 5 tin nhắn sẽ được sử dụng tốt.

+0

thư chỉ được nhận một lần. nó không đến gấp đôi. tbh, tôi thậm chí không biết những gì 'onChange' thứ hai thậm chí còn được kích hoạt từ. – r2DoesInc

+2

Ah. cùng với ý tưởng của bạn với http://stackoverflow.com/questions/7012703/android-detect-sms-outgoing-incorrect-count và tôi nhận được nó hoạt động. Tôi nghĩ rằng tôi hiểu lầm những gì bạn có nghĩa là lần đầu tiên tôi đọc qua nó. Tôi tạo ra một 'mảng' tĩnh và sử dụng nó để kiểm tra. \t \t \t 'if (! Ids.contains (id)) {ids.add (id); context.startActivity (intent);}' – r2DoesInc

3

Bạn có thể lưu id của tin nhắn cuối cùng và so sánh nó với id của tin nhắn được trả về cur trong onChange. sau đó bạn chỉ có thể bỏ qua thông báo nếu id giống nhau.

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

Tuy nhiên - GO SMS chỉ ngăn của ứng dụng khác từ recieving Broadcast nếu người dùng chọn tùy chọn này (Nhận các Cài đặt - Vô hiệu hoá thông báo tin nhắn khác) - vì vậy nếu người dùng không muốn các ứng dụng khác làm phiền anh ấy - Tôi nghĩ rằng đó là ý tưởng hay để không làm như vậy.

+0

Ứng dụng Im hoạt động trên isnt mà không được bỏ qua, bao giờ hết. Nó được cài đặt sẵn trên các thiết bị và được ưu tiên hơn bất kỳ thứ gì khác hiện đang chạy trên điện thoại. Tôi đã làm một cái gì đó tương tự với điều này, nếu bạn nhìn vào các ý kiến ​​của câu trả lời dưới đây bạn có thể nhìn thấy. – r2DoesInc

+1

bạn hiểu rằng đoạn trích bạn đã đăng nên thực sự có chiều dài thực sự trước khi nó có thể được sử dụng trong ứng dụng được đặt trước, phải không? – Vladimir

+0

oh vâng, tất nhiên rồi. ive chỉ mới bắt đầu dự án. nó có một chặng đường dài để đi – r2DoesInc

4

đây là mã của tôi, nó hoạt động tốt đối với tôi

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

tôi chỉ sử dụng SharedPreference để nhận xét cuối cùng thông tin SMS (như: id\type ...). nếu nó giống nhau, tôi sẽ return.

Các vấn đề liên quan