我写了一个简单的广播接收器,它接听来电并用来电号码开始活动:
package com.example.nrsearch;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
public class CallReceiver extends BroadcastReceiver {
public CallReceiver() {
}
public Context context;
@Override
public void onReceive(Context context, Intent intent) {
Log.i("CallReceiverBroadcast", "onReceive() is called. ");
this.context = context;
TelephonyManager teleMgr = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener psl = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
Log.i("CallReceiverBroadcast", "onCallStateChanged() is called. ");
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
Log.i("CallReceiverBroadcast", "Incoming call caught. Caller's number is " + incomingNumber + ".");
startNumberDisplayActivity(incomingNumber);
}
}
};
teleMgr.listen(psl, PhoneStateListener.LISTEN_CALL_STATE);
teleMgr.listen(psl, PhoneStateListener.LISTEN_NONE);
}
public void startNumberDisplayActivity(String incomingNumber) {
Intent i = new Intent(context, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("incomingNumber", incomingNumber);
context.startActivity(i);
}
}
然而,在第一个来电后,我觉得我的设备电池开始很快耗尽。我担心某些进程仍会阻止我的广播接收器断开连接(我的意思是我的广播接收器可能永远在运行)。那么,我的代码中是否存在可能导致此类行为的内容,并且此行确实会阻止TelephonyManager监听调用状态更改:teleMgr.listen(psl, PhoneStateListener.LISTEN_NONE);
还是应该以其他方式执行此操作?
答案 0 :(得分:1)
方法
@Override
public void onPause() {
super.onPause();
mActivity.unregisterReceiver(myReceiver);
}
你可以放置其他地方,但那是一个好地方。请在onResume注册。
另请阅读broadcastreceiver docs,他们不会按照您认为他们的方式工作:
http://developer.android.com/reference/android/content/BroadcastReceiver.html
接收器生命周期基本上是:
接收器生命周期
BroadcastReceiver对象仅在通话期间有效 to onReceive(Context,Intent)。一旦你的代码从此返回 功能,系统认为要完成的对象不再 活性
这对你能做些什么有重要的影响 onReceive(Context,Intent)实现:需要的任何东西 异步操作不可用,因为您需要 从函数返回来处理异步操作,但是在 那一点,BroadcastReceiver不再是活动的,因此 系统可以在异步操作之前自由地终止其进程 完成。
特别是,您可能无法显示对话框或绑定到服务 在BroadcastReceiver中。对于前者,你应该使用 NotificationManager API。对于后者,你可以使用 Context.startService()将命令发送到服务。
编辑:
根据您的意见 - 关于BroadcastReceiver吃电池寿命的担忧并不现实。接收器只持续运行接收器方法中的代码所需的时间。在那时,Android会在它认为必要的时候清理它。如果你的代码中的任何内容破坏了它,那就是:
this.context = context;
/// these three lines
TelephonyManager teleMgr = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
.....
teleMgr.listen(psl, PhoneStateListener.LISTEN_CALL_STATE);
teleMgr.listen(psl, PhoneStateListener.LISTEN_NONE);
因为您创建了一个对象,然后尝试监听它。
但是你应该真正阅读文档:
任何需要的东西 异步操作不可用,
您在代码中正在做什么 - 附加到服务并等待其异步响应。这在BroadcastReceiver中是不可接受的,此时在文档中明确指出:
特别是,您可能无法显示对话框或绑定到服务 在BroadcastReceiver中。