服务意图必须是明确的:意图

我有一个应用程序现在我通过广播接收器(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()); 

对于像我这样懒惰的人来说就用

 public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) { // Retrieve all services that can match the given intent PackageManager pm = context.getPackageManager(); List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0); // Make sure only one match was found if (resolveInfo == null || resolveInfo.size() != 1) { return null; } // Get component info and create ComponentName ResolveInfo serviceInfo = resolveInfo.get(0); String packageName = serviceInfo.serviceInfo.packageName; String className = serviceInfo.serviceInfo.name; ComponentName component = new ComponentName(packageName, className); // Create a new intent. Use the old one for extras and such reuse Intent explicitIntent = new Intent(implicitIntent); // Set the component to be explicit explicitIntent.setComponent(component); return explicitIntent; } 

发送上下文和你的意图在这个方法,并得到意图使用的结果。

将隐式意图转换为显式意图,然后启动启动服务。

  Intent implicitIntent = new Intent(); implicitIntent.setAction("com.duk3r.eortologio2.MyService"); Context context = getApplicationContext(); Intent explicitIntent = convertImplicitIntentToExplicitIntent(implicitIntent, context); if(explicitIntent != null){ context.startActivity(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是我的服务类。 我有两个动作,表示服务停止或启动。 我从广播接收机发送该值取决于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>