Android バージョン 4.1.2 で次のエラーが発生します。
Fatal Exception: java.lang.RuntimeException: Unable to start receiver com.example.PluggedInBroadcastReceiver:
android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to register to receive intents
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2287)
at android.app.ActivityThread.access$1600(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4961)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to register to receive intents
at android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:152)
at android.app.ReceiverRestrictedContext.registerReceiver(ContextImpl.java:146)
at com.example.PluggedInBroadcastReceiver.getBatteryLevel(Unknown Source)
at com.example.PluggedInBroadcastReceiver.onReceive(Unknown Source)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2280)
at android.app.ActivityThread.access$1600(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4961)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
at dalvik.system.NativeStart.main(NativeStart.java)
エラーの原因となっているコードは次のとおりです。このレシーバーは、動的ではなく静的に (AndroidManifest.xml で) 登録されています。
public class PluggedInBroadcastReceiver extends WakefulBroadcastReceiver {
public static final String LOG_TAG = PluggedInBroadcastReceiver.class.getSimpleName();
private IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
String action = intent.getAction();
if (action != null && action.equals(Intent.ACTION_POWER_CONNECTED)) {
try {
Intent batteryStatusIntent = context.getApplicationContext().registerReceiver(null, iFilter);
double battPercentage = BatteryUtils.getBatteryLevel(batteryStatusIntent);
//Do something with the battery percentage value...
} catch (Exception e) {
Log.e(LOG_TAG, "Battery status intent was null");
}
}
}
}
}
私は過去にこのエラーに遭遇し、Broadcast Receiver に渡されたコンテキストに registerReceiver() を呼び出す機能がないことが原因であることがわかりました。
Broadcast Receiver に渡されたコンテキストをアプリケーション コンテキストに変換し、アプリケーション コンテキストで registerReceiver() を呼び出すことができることを示唆するリソースをいくつか見つけました。これは Android バージョン 4.2 以降で機能しますが、4.1.2 では失敗します (それより低い可能性もありますが、明示的にテストされていません)。アプリケーション コンテキストに変換すると registerReceiver() を呼び出せるようになりますが、すべてのバージョンの Android で機能するとは限りません。
この動作について誰か説明がありますか?
編集: プロットが厚くなります...このクラッシュは Android バージョン 4.1.1、4.1.2、4.3.0、および 5.1.1 で発生し、クラッシュの 93% 以上が 4.1.2 で発生したことがわかりました。これに対する解決策が見つかるかどうかはわかりませんが、今後の私の修正は、BroadcastReceiver から registerReceiver() を呼び出さないことです。明らかにこれを許可するはずのアプリケーションコンテキストを使用している場合でも、動作は未定義で予測できないようです。