web-dev-qa-db-ja.com

サービス意図は明示的でなければなりません:意図

ブロードキャストレシーバー(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 }

サービスを明示的に宣言し、正常に開始するには、何を変更する必要がありますか?他の同様のスレッドでいくつかの回答を試みましたが、メッセージを取り除きましたが、サービスは開始しませんでした。

62
duk3r

アプリのサービス、アクティビティなどに対して行う意図は、常にこの形式に従う必要があります

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");

暗黙のインテント(現在コードにあるもの)はセキュリティリスクと見なされます

107
tyczj

packageNameの動作を設定します。

intent.setPackage(this.getPackageName());
29
kai chen

暗黙的インテントを明示的インテントに変換してから、サービスを開始します。

        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;
        }
5
Shahidul

これを試して。わたしにはできる。ここで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>
0
reza.cse08