ブロードキャストレシーバー(MyStartupIntentReceiver)を介してサービスを呼び出すアプリがあります。サービスを呼び出すためのブロードキャストレシーバーのコードは次のとおりです。
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent();
serviceIntent.setAction("com.duk3r.eortologio2.MyService");
context.startService(serviceIntent);
}
問題は、Android 5.0 Lollipopで次のエラーが発生することです(Androidの以前のバージョンでは、すべて正常に動作します)。
Unable to start receiver com.duk3r.eortologio2.MyStartupIntentReceiver: Java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.duk3r.eortologio2.MyService }
サービスを明示的に宣言し、正常に開始するには、何を変更する必要がありますか?他の同様のスレッドでいくつかの回答を試みましたが、メッセージを取り除きましたが、サービスは開始しませんでした。
アプリのサービス、アクティビティなどに対して行う意図は、常にこの形式に従う必要があります
Intent serviceIntent = new Intent(context,MyService.class);
context.startService(serviceIntent);
または
Intent bi = new Intent("com.Android.vending.billing.InAppBillingService.BIND");
bi.setPackage("com.Android.vending");
暗黙のインテント(現在コードにあるもの)はセキュリティリスクと見なされます
packageName
の動作を設定します。
intent.setPackage(this.getPackageName());
暗黙的インテントを明示的インテントに変換してから、サービスを開始します。
Intent implicitIntent = new Intent();
implicitIntent.setAction("com.duk3r.eortologio2.MyService");
Context context = getApplicationContext();
Intent explicitIntent = convertImplicitIntentToExplicitIntent(implicitIntent, context);
if(explicitIntent != null){
context.startService(explicitIntent);
}
public static Intent convertImplicitIntentToExplicitIntent(Intent implicitIntent, Context context) {
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfoList = pm.queryIntentServices(implicitIntent, 0);
if (resolveInfoList == null || resolveInfoList.size() != 1) {
return null;
}
ResolveInfo serviceInfo = resolveInfoList.get(0);
ComponentName component = new ComponentName(serviceInfo.serviceInfo.packageName, serviceInfo.serviceInfo.name);
Intent explicitIntent = new Intent(implicitIntent);
explicitIntent.setComponent(component);
return explicitIntent;
}
これを試して。わたしにはできる。ここでMonitoringServiceは私のサービスクラスです。サービスを停止または開始することを示す2つのアクションがあります。 ブロードキャストレシーバーからAIRPLANE_MODE_CHANGEDに依存して、その値を送信します。
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.ACTION_AIRPLANE_MODE_CHANGED.equalsIgnoreCase(action)){
boolean isOn = intent.getBooleanExtra("state", false);
String serviceAction = isOn? MonitoringService.StopAction : MonitoringService.StartAction;
Intent serviceIntent = new Intent(context, MonitoringService.class);
serviceIntent.setAction(serviceAction);
context.startService(serviceIntent);
}
}
注:次のコードを追加して、ブロードキャストレシーバーをトリガーします:ManageLocationListenerReceiver。
<receiver
Android:name=".ManageLocationListenerReceiver"
Android:enabled="true"
Android:exported="true">
<intent-filter>
<action Android:name="Android.intent.action.AIRPLANE_MODE" />
</intent-filter>
</receiver>