Intent在启动service时如果不指定package会提出一个警告,大致内容是:Implicit intents with startService are not safe.所以在intent中需指定引用包名:
Intent sub_intent = new Intent();
sub_intent.setAction("com.turman.app.client.QueryService");
sub_intent.setPackage("com.turman.app.client"); //指定应用包名
startService(sub_intent);
<service android:name=".example.newservice.AService">
<intent-filter>
<action android:name="com.turman.app.client.QueryService"/>
</intent-filter>
</service>
另,将隐式Intent转化为显示Intent也可以解决该问题:
public class NewUtils {
/**
* 本方法将隐式Intent转化为显示的Intent
* @param context
* @param implicitIntent
* @return
*/
public static Intent getExplicitIntent(Context context, Intent implicitIntent) {
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfoList = pm.queryIntentServices(implicitIntent, 0);
//如果没有匹配当前intent的service或者有多个service匹配返回null
if (resolveInfoList == null || resolveInfoList.size() != 1) {
return null;
}
ResolveInfo serviceInfo = resolveInfoList.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName componentName = new ComponentName(packageName, className);
Intent explicitIntent = new Intent(implicitIntent);
explicitIntent.setComponent(componentName);
return explicitIntent;
}
}
调用注册的service可以通过定义的action来查找相应的service组件,在activity中也可以定义类似的action,所以通过指定Intent的action也是可以调用相应的activity组件的,这里在manifest文件中定义:
<activity android:name=".example.drable.DrawableActivity">
<intent-filter>
<action android:name="com.turman.fb.example.drable.ABC"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
这里需要指定category来指定action在什么情况下响应,如未指定action的响应行为将无法通过action启动activity。
代码调用:
final Intent intent = new Intent();
intent.setAction("com.turman.fb.example.drable.ABC");
intent.setPackage("com.turman.fb");
startActivity(intent);
通过这种方式也可以调用其他应用中的activity组件,前提是该应用中的相应activity也配置了action并且你知道该actiion的名称。
以下是一般的跨应用activity调用方式:
Intent sub_intent = new Intent();
sub_intent.setClassName("com.turman.app.client", "com.turman.app.client.ClientActivity");
//sub_intent.setComponent(new ComponentName("com.turman.app.client","com.turman.app.client.ClientActivity"));