web-dev-qa-db-de.com

Service Intent muss explizit sein: Intent

Ich habe jetzt schon eine App, in der ich einen Dienst über einen Broadcast-Empfänger (MyStartupIntentReceiver) anrufe. Der Code im Rundfunkempfänger, um den Dienst anzurufen, lautet:

public void onReceive(Context context, Intent intent) {
    Intent serviceIntent = new Intent();
    serviceIntent.setAction("com.duk3r.eortologio2.MyService");
    context.startService(serviceIntent);
}

Das Problem ist, dass ich in Android 5.0 Lollipop folgende Fehlermeldung bekomme (in früheren Versionen von Android funktioniert alles in Ordnung):

Unable to start receiver com.duk3r.eortologio2.MyStartupIntentReceiver: Java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.duk3r.eortologio2.MyService }

Was muss ich ändern, damit der Dienst als explizit deklariert wird und normal startet? Ich habe ein paar Antworten in anderen ähnlichen Threads ausprobiert, aber obwohl ich die Nachricht los wurde, konnte der Dienst nicht gestartet werden.

56
duk3r

jede Absicht, die Sie auf einen Dienst, eine Aktivität usw. in Ihrer App legen, sollte immer diesem Format entsprechen

Intent serviceIntent = new Intent(context,MyService.class);
context.startService(serviceIntent);

oder 

Intent bi = new Intent("com.Android.vending.billing.InAppBillingService.BIND");
bi.setPackage("com.Android.vending");

implizite Absichten (was Sie derzeit in Ihrem Code haben) werden als Sicherheitsrisiko betrachtet

98
tyczj

Stellen Sie Ihre packageName-Werke ein.

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

Konvertieren Sie die implizite Absicht in eine explizite Absicht, und starten Sie dann den Startdienst.

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

Versuche dies. Für mich geht das. Hier MonitoringService ist meine Serviceklasse. Ich habe zwei Aktionen, die anzeigen, dass der Dienst gestoppt oder gestartet werden soll. Ich sende diesen Wert von meinem broadcast receiver abhängig von 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);
    }
}

HINWEIS: Ich füge folgenden Code hinzu, um meinen Broadcast-Empfänger mit dem Namen auszulösen: 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