web-dev-qa-db-fra.com

L'intention de service doit être explicite: Intention

J'ai une application dans laquelle j'appelle un service depuis un récepteur de diffusion (MyStartupIntentReceiver). Le code dans le récepteur de radiodiffusion pour appeler le service est le suivant:

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

Le problème est que dans Android 5.0 Lollipop, l'erreur suivante apparaît (dans les versions précédentes d'Android, tout fonctionne correctement):

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

Que dois-je changer pour que le service soit déclaré comme explicite et qu'il démarre normalement? J'ai essayé des réponses dans d'autres discussions similaires, mais bien que je me suis débarrassé du message, le service ne pouvait pas démarrer.

56
duk3r

toute intention que vous faites d'un service, d'une activité, etc. dans votre application doit toujours suivre ce format

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

ou 

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

les intentions implicites (ce que vous avez actuellement dans votre code) sont considérées comme un risque de sécurité

98
tyczj

Définissez vos travaux packageName.

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

Convertissez l'intention implicite en intention explicite, puis lancez le service de démarrage.

        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

Essaye ça. ça marche pour moi. Ici MonitoringService est ma classe de service. J'ai deux actions qui indiquent au service d'arrêter ou de démarrer. J'envoie cette valeur depuis mon broadcast receiver depend sur 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);
    }
}

NOTE: J'ajoute le code suivant pour déclencher mon récepteur de radiodiffusion nommé: 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