2014-02-06 71 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()中,我的应用程序也会被调用,而且我不必按下注册按钮 –

相关问题