我已经在onCreate上注册了接收器,并在Destroy上取消注册了它?它运行完美,但在某些三星 Galaxy s3 上,即使我停止服务,我仍然接收接收器。如何找到解决方案?可能吗?请帮助我。提前致谢
package com.sms.sendsms.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
/**
* Created by Navruz on 30.03.2016.
*/
public class SendSmsService extends Service {
private static Logger LOGGER = LoggerFactory.getLogger(SendSmsService.class);
@Override
public void onCreate() {
super.onCreate();
LOGGER.info("Service is onCreate");
registerReceiver(incomingCallReceiver, new IntentFilter(
TelephonyManager.ACTION_PHONE_STATE_CHANGED));
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LOGGER.info("Service is onStartCommand");
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(incomingCallReceiver);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private BroadcastReceiver incomingCallReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
LOGGER.info("IncomingCallReceiver is received.");
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
LOGGER.info("state : " + state);
}
}, PhoneStateListener.LISTEN_CALL_STATE);
}
};
}
在onDestroy()
中调用unregisterReceiver(...)
不是一个好主意,因为它并不总是保证被调用。
来自官方文档
在销毁活动之前执行任何最终清理。这可以 发生是因为活动正在完成(有人打电话 finish(),或者因为系统暂时破坏了它 用于节省空间的活动实例。您可以区分 这两个场景使用 isFinishing() 方法。
注意:不要指望调用此方法作为保存的地方 数据!例如,如果活动正在编辑内容中的数据 提供程序,这些编辑应在 onPause() 或 onSaveInstanceState(Bundle),不在这里。这种方法通常是 实现以释放资源,例如与 活动,以便被破坏的活动不会留下这些东西 在其应用程序的其余部分仍在运行时。有 系统将简单地杀死活动的托管的情况 进程而不在其中调用此方法(或任何其他方法),因此它 不应用于做打算留在身边的事情 过程消失后。
引用:
- Android Activity onDestroy() 并不总是被调用,如果调用,则只执行部分代码
- 活动销毁从未调用?
- ondestroy 不总是被调用吗?
编辑
好的,所以刚刚从@CommonsWare中找到了这个答案,它说Service
的onDestroy()
在某些情况下不会被调用为:
如果用户强制阻止您访问"设置" 应用
如果Android需要快速的RAM(例如,处理传入的电话) call) 并选择终止您的进程以释放该 RAM
从 DDMS 终止进程
此外,如果您的服务崩溃并在某处出现未经处理的异常, Android 可能会认为该服务已失效并跳过
onDestroy()
我猜你要么强制停止Service
,要么设备内存不足;因此onDestroy()
没有被调用。
如果您在某些设备中遇到问题,您可以尝试显式禁用接收器组件。无论清单中指定了什么,这都将执行相同的操作。
广播接收器类
public class Reg extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// your stuff
}
}
在 onDestroy() 调用它
ComponentName comp = new ComponentName(this,"com.example.Reg"); //package name,broadcast receiver class path
PackageManager pkg = this.getPackageManager();
pkg.setComponentEnabledSetting(comp,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);
将此添加到清单文件
<receiver android:name="com.example.Reg" />
COMPONENT_ENABLED_STATE_DISABLED
在运行时启用禁用广播接收器
我有一个解决方案,它对我有用:
/**
* if service is going to destroy, unregister broadcast receiver by main activity context.
*/
@Override
public void onDestroy() {
Log.e(TAG, ">>>>>UEventObserverService.onDestroy()");
getApplicationContext().unregisterReceiver(screen_state_receiver);
super.onDestroy();
}