Service Intent must be explicit: Intent

后端 未结 5 679
你的背包
你的背包 2020-12-01 00:27

I have an app some time now in which I call a service through a broadcast receiver (MyStartupIntentReceiver). The code in the broadcast receiver in order to call the service

相关标签:
5条回答
  • 2020-12-01 01:02

    Convert implicit intent to explicit intent then fire start service.

            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;
            }
    
    0 讨论(0)
  • 2020-12-01 01:03

    any intent you make to a service, activity etc. in your app should always follow this format

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

    or

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

    implicit intents (what you have in your code currently) are considered a security risk

    0 讨论(0)
  • 2020-12-01 01:03

    Set your packageName works.

    intent.setPackage(this.getPackageName());
    
    0 讨论(0)
  • 2020-12-01 01:15

    Try this. it works for me. Here MonitoringService is my service class. I have two action, which indicate service to stop or start. I send that value from my broadcast receiver depend on 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: I add following code to trigger my broadcast receiver named: 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 讨论(0)
  • 2020-12-01 01:16

    I improved the answer of Shahidul to remove the context dependency:

    public class ServiceUtils {
        public static void startService(String intentUri) {
            Intent implicitIntent = new Intent();
            implicitIntent.setAction(intentUri);
            Context context = SuperApplication.getContext();
            Intent explicitIntent = convertImplicitIntentToExplicitIntent(implicitIntent, context);
            if(explicitIntent != null){
                context.startService(explicitIntent);
            }
        }
    
        private 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;
        }
    }
    

    Inside the SuperApplication class:

    public class SuperApplication extends Application {
        private static MyApp instance;
    
        public static SuperApplication getInstance() {
            return instance;
        }
    
        public static Context getContext(){
            return instance;
            // or return instance.getApplicationContext();
        }
    
        @Override
        public void onCreate() {
            instance = this;
            super.onCreate();
        }
    }
    

    In your manifest:

    <application
        android:name="com.example.app.SuperApplication "
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        .......
        <activity
            ......
    

    And then, just call:

    ServiceUtils.startService("com.myservice");
    
    0 讨论(0)
提交回复
热议问题