Я пытаюсь разработать настройку 2 приложений (приложение-приложение-приложение + клиентское приложение) с использованием AIDL. У меня в настоящее время на установке 3-х модулей:Служба AIDL не подключается после bindService()
- андроида-агент-структура (Android модуль библиотеки может содержать только файл AIDL)
- андроида-агента (службу)
- Android-пример-клиента (клиент)
Андроид-агент и андроид-агент-каркас имеют зависимость от первого, чтобы получить доступ к интерфейсу.
Всякий раз, когда клиент вызывает bindService(), он получает false как возврат, а в ServiceConnection onServiceConnected() не вызывается. Также в реализации сервиса onBind() не вызывается. В журналах ошибок нет.
Вот код:
андроид-агентская деятельность:
public class MyCompanyStartActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(MyCompanyStartActivity.class.toString(), "Create MyCompanyStartActivity");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ComponentName service = startService(new Intent(this, MyCompanyRequestService.class));
Log.i("tag", service.getClassName() + "::" + service.getPackageName());
}
}
сервис андроид-агента:
public class MyCompanyRequestService extends Service {
@Override
public IBinder onBind(Intent intent) {
Log.i(MyCompanyRequestService.class.toString(), "Starting SmartRest Service");
return mBinder;
}
private final IMyCompanyRequestService.Stub mBinder = new IMyCompanyRequestService.Stub() {
@Override
public void sendData(String xid, String authentication, String data) throws RemoteException{
Log.i(MyCompanyRequestService.class.toString(), "sending data: " + data);
}
};
}
андроида-агент манифест:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mycompany.android.agent" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MyCompanyStartActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Services -->
<service
android:name="com.mycompany.android.agent.framework.MyCompanyRequestService"
android:process=":remote"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="MyCompanyRequestService"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
<!-- Permissions -->
</application>
</manifest>
андроида -example-client activity:
public class ClientStarter extends Activity {
protected IMyCompanyRequestService mycompanyRequestService = null;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i("tag","create client");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
if (mycompanyRequestService == null) {
printServices();
Intent it = new Intent("MyCompanyRequestService");
it.setPackage("com.mycompany.android.agent.framework");
Log.i("tag","before binding service: " + it.getAction() + "::" + it.getPackage());
boolean serviceBinding = getApplicationContext().bindService(it, connection, Context.BIND_AUTO_CREATE);
Log.i("tag", "service is bound: " + serviceBinding);
}
Handler handler = new Handler();
handler.postDelayed(new Runner(), 10000);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("service", "Service connected");
mycompanyRequestService = IMyCompanyRequestService.Stub.asInterface(service);
Toast.makeText(getApplicationContext(), "Service Connected", Toast.LENGTH_SHORT).show();
Log.i("service", "Service connected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("service", "Service disconnected");
mycompanyRequestService = null;
Toast.makeText(getApplicationContext(), "Service Disconnected", Toast.LENGTH_SHORT).show();
Log.i("service", "Service disconnected");
}
};
private void printServices() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
Log.d("service", service.service.getClassName());
}
}
private class Runner implements Runnable {
@Override
public void run() {
Log.i("tag","starting");
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location loc;
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
Log.e(ClientStarter.class.toString(), "Error", e);
} while(true) {
try {
if (mycompanyRequestService != null) {
loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Log.i(ClientStarter.class.toString(), loc.getLatitude() + " - " + loc.getLongitude() + " - " + loc.getAltitude());
mycompanyRequestService.sendData("test", "auth", String.valueOf(loc.getLatitude()) + "," + String.valueOf(loc.getLongitude()) + "," + String.valueOf(loc.getAltitude()));
} else {
Log.i(ClientStarter.class.toString(), "service not yet available");
}
Thread.sleep(5000);
} catch (InterruptedException e) {
Log.e(ClientStarter.class.toString(), "Error", e);
} catch (RemoteException e) {
Log.e(ClientStarter.class.toString(), "Error", e);
}
}
}
}
}
Вызов printServices(), прежде чем пытаться связать службу, фактически перечисляет службу так, что она запущена.
Журнал не содержит ошибок, и клиент в конце работает в цикле, но служба по-прежнему равна нулю.
Возможно, кто-то столкнулся с аналогичной проблемой раньше.
В Android 5.0+ вам нужно использовать явное «намерение» для привязки к службе. Я скептически отношусь к тому, что 'setPackage()' достаточно. – CommonsWare
@CommonsWare Я фактически добавил setPackage() после того, как столкнулся с проблемой Android, жалующейся на то, что намерение не было явным. Я протестировал один пример проекта AIDL, который также использовал setPackage() на том же телефоне, и он сработал. С setPackage() ошибка исчезла и в моем проекте – TyrManuZ