安卓取消注册接收器,但仍在接收



我已经在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),不在这里。这种方法通常是 实现以释放资源,例如与 活动,以便被破坏的活动不会留下这些东西 在其应用程序的其余部分仍在运行时。有 系统将简单地杀死活动的托管的情况 进程而不在其中调用此方法(或任何其他方法),因此它 不应用于做打算留在身边的事情 过程消失后。

引用:

  1. Android Activity onDestroy() 并不总是被调用,如果调用,则只执行部分代码
  2. 活动销毁从未调用?
  3. ondestroy 不总是被调用吗?

编辑

好的,所以刚刚从@CommonsWare中找到了这个答案,它说ServiceonDestroy()在某些情况下不会被调用为:

  • 如果用户强制阻止您访问"设置" 应用

  • 如果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();
}

最新更新