app Client调用app Service 中的service时候出现 java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.ada.aidls.IMyAidlInterface }
查阅资料表明,是Android 5.0出来后,其中有个特性就是Service Intent must be explitict。本地调用使用显示调用解决,但是aidl跨进程访问service时候确实需要使用隐式调用。
源码如下:
private void validateServiceIntent(Intent service) {
if (service.getComponent() == null && service.getPackage() == null) {
if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
IllegalArgumentException ex = new IllegalArgumentException(
"Service Intent must be explicit: " + service);
throw ex;
} else {
Log.w(TAG, "Implicit intents with startService are not safe: " + service
+ " " + Debug.getCallers(2, 3));
}
}
}
Google官网给出了解决方案 ,隐式调用是除了设置setAction()外,还需要设置setPackage();
Intent mIntent = new Intent();
mIntent.setAction("XXX.XXX.XXX");//你定义的service的action
mIntent.setPackage("XXX.XXX.XXX");//这里你需要设置你应用的包名
context.startService(mIntent);
Note:
setPackage(""),中的报名,为服务器的APP Service的包名,在AndroidManifest.xml中查看,注意不要引入service服务所在的包名。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ada.binderdemo">
下面是我的例子
public class ClientActivity extends AppCompatActivity implements View.OnClickListener{
IMyAidlInterface mIMyAidlInterface;
private Button btnDate;
private Button btnBind;
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
btnDate=(Button) findViewById(R.id.btn_get_remote_time);
mContext=this;
btnDate.setOnClickListener(this);
btnBind=(Button) findViewById(R.id.btn_bind_remote_service);
btnBind.setOnClickListener(this);
}
private ServiceConnection mConnect=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mIMyAidlInterface= IMyAidlInterface.Stub.asInterface(iBinder);
Log.e("ClientActivity", "connect success");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.e("ClientActivity", "Service has unexpectedly disconnected");
mIMyAidlInterface=null;
}
};
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_bind_remote_service:
Log.e("ClientActivity", "开始绑定");
Intent bindIntent = new Intent();
//方法一:
bindIntent.setAction("com.ada.aidls.IMyAidlInterface");
bindIntent.setPackage("com.ada.aidlservicedemo");
// 方法二:
// bindIntent.setClassName("com.ada.aidlservicedemo", "com.ada.aidlservicedemo.service.RemoteService");
boolean a=bindService(bindIntent, mConnect, Context.BIND_AUTO_CREATE);
break;
case R.id.btn_get_remote_time:
try {
String id=mIMyAidlInterface.getID();
Toast.makeText(mContext,"id="+id, Toast.LENGTH_LONG).show();
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
}