Em meu console de desenvolvedor, as pessoas continuam relatando um erro que não consigo reproduzir em nenhum telefone que possuo. Uma pessoa deixou uma mensagem dizendo que entende quando tenta abrir a tela de configurações do meu serviço de bateria. Como você pode ver no erro diz que o receptor não está registrado.
java.lang.RuntimeException: Unable to stop service .BatteryService@4616d688: java.lang.IllegalArgumentException: Receiver not registered: com.app.notifyme.BatteryService$BatteryNotifyReceiver@4616d9d0
at android.app.ActivityThread.handleStopService(ActivityThread.java:3164)
at android.app.ActivityThread.access$3900(ActivityThread.java:129)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2173)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:4701)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Receiver not registered:com..BatteryService$BatteryNotifyReceiver@4616d9d0
at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:805)
at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:859)
at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:331)
at com.app.notifyme.BatteryService.onDestroy(BatteryService.java:128)
at android.app.ActivityThread.handleStopService(ActivityThread.java:3150)
Eu me registro no meu onCreate
@Override
public void onCreate(){
super.onCreate();
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
registerReceiver(batteryNotifyReceiver,filter);
pref.registerOnSharedPreferenceChangeListener(this);
}
Cancelar o registro em onDestroy e também com um ouvinte de preferência
@Override
public void onDestroy(){
super.onDestroy();
unregisterReceiver(batteryNotifyReceiver);
}
e este é meu receptor no serviço
private final class BatteryNotifyReceiver extends BroadcastReceiver {
boolean connected;
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor edit = prefs.edit();
updatePreferences(prefs);
level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
if(intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)){
connected = true;
}else if(intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)){
connected = false;
}else if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){
if(level < lastLevel){
if(level > 40){
edit.putBoolean("first", false).commit();
edit.putBoolean("second", false).commit();
edit.putBoolean("third", false).commit();
edit.putBoolean("fourth",false).commit();
edit.putBoolean("fifth", false).commit();
}
if(level == 40){
if(!first){
notification(context,battColor,battBlink,battVib,battSound);
edit.putBoolean("first", true).commit();
}
}else if(level == 30){
if(!second){
notification(context,battColor,battBlink,battVib,battSound);
edit.putBoolean("second", true).commit();
}
}else if(level == 20){
if(!third){
notification(context,battColor,battBlink,battVib,battSound);
edit.putBoolean("third", true).commit();
}
}else if(level == 15){
if(!fourth){
notification(context,battColor,battBlink,battVib,battSound);
edit.putBoolean("fourth", true).commit();
}
}else if(level == 5){
if(!fifth){
notification(context,battColor,battBlink,battVib,battSound);
edit.putBoolean("fifth", true).commit();
}
}
lastLevel = temp;
}
}
Intent i = new Intent(context,BatteryNotifyReceiver.class);
context.startService(i);
}
}
alguma ideia de por que eles estariam recebendo esse erro?
LocalBroadcastManager.getInstance(context).unregisterReceiver()
oucontext.unregisterReceiver()
Tenha cuidado ao se registrar por
você não pode cancelar o registro por
você deve usar
ou o aplicativo travará, faça o seguinte:
fonte
Use este código em qualquer lugar para unregisterReceiver:
fonte
Conforme mencionado em outras respostas, a exceção está sendo lançada porque cada chamada para
registerReceiver
não está sendo correspondida por exatamente uma chamada paraunregisterReceiver
. Por que não?Um
Activity
não tem sempre uma correspondênciaonDestroy
chamada para cadaonCreate
chamada. Se o sistema ficar sem memória, seu aplicativo será despejado sem chamadaonDestroy
.O local correto para fazer uma
registerReceiver
chamada é naonResume
chamada eunregisterReceiver
emonPause
. Este par de chamadas é sempre correspondido. Consulte o diagrama do ciclo de vida da atividade para obter mais detalhes. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycleSeu código mudaria para:
fonte
EDIT: Esta é a resposta para inazaruk e electrichead ... Eu tive um problema semelhante para eles e descobri o seguinte ...
Há um bug antigo para esse problema aqui: http://code.google.com/p/android/issues/detail?id=6191
Parece que tudo começou em torno do Android 2.1 e está presente em todas as versões do Android 2.x desde então. Não tenho certeza se ainda é um problema no Android 3.x ou 4.x.
De qualquer forma, esta postagem StackOverflow explica como contornar o problema corretamente (não parece relevante pelo URL, mas eu prometo que é)
Por que o slide do teclado trava meu aplicativo?
fonte
Usei um bloco try-catch para resolver o problema temporariamente.
fonte
Declare o receptor como nulo e, a seguir, coloque os métodos de registro e cancelamento de registro em onResume () e onPause () da atividade, respectivamente.
fonte
Quando o componente de IU que registra o BR é destruído, o BR também é. Portanto, quando o código chega ao cancelamento do registro, o BR pode já ter sido destruído.
fonte
Para qualquer pessoa que se deparar com esse problema e tentar tudo o que foi sugerido e nada ainda funciona, foi assim que resolvi meu problema, em vez de fazer
LocalBroadcastManager.getInstance(this).registerReceiver(...)
primeiro criei uma variável local do tipo LocalBroadcastManager,E utilizou esta variável para realizar o cadastramento e o cancelamento do cadastramento no emissor, ou seja,
e
fonte
Vamos supor que seu
broadcastReceiver
seja definido assim:Se você estiver usando
LocalBroadcast
em uma atividade, é assim que cancelará o registro:Se você estiver usando
LocalBroadcast
em um fragmento, é assim que cancelará o registro:Se você estiver usando uma transmissão normal em uma atividade, é assim que cancelará o registro:
Se você estiver usando transmissão normal em um Fragment, é assim que você cancelará o registro:
fonte