2014-02-06 124 views
3

我希望在收到短信時對Toast進行敬酒。意圖過濾器不會以編程方式取消註冊

我試圖明確地將意圖過濾器放在清單中,我除了在應用程序被殺時不想調​​用它時,我部分成功了,所以在這裏一些程序員的建議下,我嘗試了播放接收器通過在我的用戶界面中放置兩個按鈕編程式,即registerunregister,因此它們的唯一目的是註冊和取消註冊廣播接收器。

我的主要目標是運行廣播接收器,即使應用程序是背景(滿足條件,用戶按下了註冊表,並在使用其他應用程序之後)。
我一直在使用這個教程:http://www.javacodegeeks.com/2012/09/android-broadcast-receiver.html,但基本上用sms接收器修改它。

這裏是我的代碼:

package gates.apps.automaticmessageresponder; 

import android.app.Activity; 
import android.content.ComponentName; 
import android.content.IntentFilter; 
import android.content.pm.PackageManager; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.View; 

public class MainActivity extends Activity { 

SmsReceiver broadcastReceiver=new SmsReceiver(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
} 

public void register(View view){ 

    this.registerReceiver(broadcastReceiver, new IntentFilter(
      "android.provider.Telephony.SMS_RECEIVED")); 
    Log.e("register","pressed"); 

} 
public void unRegister(View view){ 

    this.unregisterReceiver(broadcastReceiver); 
    Log.e("unregister","pressed"); 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

} 

而其他類

package gates.apps.automaticmessageresponder; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.telephony.SmsManager; 
import android.telephony.SmsMessage; 
import android.util.Log; 
import android.widget.Toast; 

public class SmsReceiver extends BroadcastReceiver { 

// Get the object of SmsManager 
final SmsManager sms = SmsManager.getDefault(); 

@Override 
public void onReceive(Context context, Intent intent) { 
    // TODO Auto-generated method stub 

    // Retrieves a map of extended data from the intent. 
    final Bundle bundle = intent.getExtras(); 

    try { 

     if (bundle != null) { 

      final Object[] pdusObj = (Object[]) bundle.get("pdus"); 

      for (int i = 0; i < pdusObj.length; i++) { 

       SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]); 
       String phoneNumber = currentMessage.getDisplayOriginatingAddress(); 

       String senderNum = phoneNumber; 
       String message = currentMessage.getDisplayMessageBody(); 

       Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + message); 


       // Show alert 
       int duration = Toast.LENGTH_LONG; 
       Toast toast = Toast.makeText(context, "senderNum: "+ senderNum + ", message: " + message, duration); 
       toast.show(); 

      } // end for loop 
      } // bundle is null 

    } catch (Exception e) { 
     Log.e("SmsReceiver", "Exception smsReceiver" +e); 

    } 

} 

} 

我沒有修改清單文件,除了我添加了允許接收短信。 即使我在日誌中,註冊按下和unpressressed。我認爲問題在於寄存器接收器按鈕被調用,即使沒有點擊,是一種不正常的行爲?或者我的看法是錯誤的?

回答

3

而不是在明顯的嘗試宣告BroadcastReceiver你的活動範圍內,如下所示,將與Activity生命週期配合它(不要忘了在清單文件中添加權限):

public class ExampleMainActivity extends Activity { 

    //Activity Stuff 

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, final Intent intent) { 

      //Do things you want with message. 

      AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); 
      builder.setTitle("Title"); 
      builder.setMessage("You may add your things here"); 
      builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which) { 

        dialog.dismiss(); 
       } 
      }); 
      builder.show(); 
     } 
    }; 

    protected void onResume() { 
     super.onResume(); 

     // OR YOU CAN REGISTER UNREGISTER AS YOU WANT 

     this.registerReceiver(broadcastReceiver, new IntentFilter(
       "android.provider.Telephony.SMS_RECEIVED")); 
    }; 

    @Override 
    protected void onPause() { 
     super.onPause(); 

     // OR YOU CAN REGISTER UNREGISTER AS YOU WANT 

     this.unregisterReceiver(broadcastReceiver); 
    } 
} 

編輯:

您可以使用應用程序首選項檢查此交替解決方案

而且

package gates.apps.automaticmessageresponder; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.telephony.SmsManager; 
import android.telephony.SmsMessage; 
import android.util.Log; 
import android.widget.Toast; 

public class SmsReceiver extends BroadcastReceiver { 

// Get the object of SmsManager 
final SmsManager sms = SmsManager.getDefault(); 

@Override 
public void onReceive(Context context, Intent intent) { 
    // TODO Auto-generated method stub 

    // Retrieves a map of extended data from the intent. 
    final Bundle bundle = intent.getExtras(); 

    try { 

     if (bundle != null) { 

      final Object[] pdusObj = (Object[]) bundle.get("pdus"); 

      for (int i = 0; i < pdusObj.length; i++) { 

       SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]); 
       String phoneNumber = currentMessage.getDisplayOriginatingAddress(); 

       String senderNum = phoneNumber; 
       String message = currentMessage.getDisplayMessageBody(); 

       Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + message); 

     SharedPreferences preferences = context.getSharedPreferences("FILE_NAME", Context.MODE_PRIVATE); 
     boolean isRegistered = preferences.getBoolean("isRegistered", false); 

       if(isRegistered) { 
        // Show alert 
        int duration = Toast.LENGTH_LONG; 
        Toast toast = Toast.makeText(context, "senderNum: "+ senderNum + ", 
             message: " + message, duration); 
        toast.show(); 
     } 

      } // end for loop 
      } // bundle is null 

    } catch (Exception e) { 
     Log.e("SmsReceiver", "Exception smsReceiver" +e); 

    } 

} 

} 
2

造成這種情況不起作用的原因是因爲註冊/取消註冊不與活動生命週期綁定,可能會使多個廣播接收器被註冊。 考慮這種情況:

用戶導航到MainActivity,然後點擊註冊按鈕。然後,用戶離開活動(不註銷),應用程序可能沒有被殺死。請注意,您的廣播接收器仍在註冊。

然後,過了一段時間,用戶導航回活動並重新註冊。現在,您有兩個不同的廣播接收器正在監聽這個動作。你幾乎泄露了一個接收器。

解決方案: 將您的接收器註冊到清單中。使用共享首選項鍵/值對保存註冊按鈕單擊。然後,當你在onReceive被調用時使用鍵/值對狀態來確定你是否想要Toast。

+0

我認爲這是正確的答案。這就是爲什麼我使用單例註冊和註銷'BroadcastReceiver's並檢查它們是否被註冊,以避免創建新的實例,當這不是你想要的。 – slinden77

+0

@WindsurferOak:OK你提到的問題似乎有潛力,但即使它不在onResume()中,我的應用程序也會被調用,而且我不必按下注冊按鈕 –

相關問題