I am trying to develop customization of 2 applications (application-application-application-client) using AIDL. Currently I have 3 modules installed:
- Android-agent structure (Android library module containing only AIDL file)
- android agent (service)
- android-example-client (client)
The Android agent and the Android agent infrastructure are dependent on the former to gain access to the interface.
Whenever a client calls bindService (), it gets false as a return, and in ServiceConnection onServiceConnected () is not called. Also, onBind () is not called in the service implementation. There are no errors in the logs.
Here is the code:
Android Agent Activity:
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()); } }
Android Agent Service:
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); } }; }
Android manifest:
<?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> <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> </application> </manifest>
Activity-example-client-client:
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); } } } } }
A call to printServices () before attempting to bind a service actually lists the service so that it runs.
The log is error free and the client runs in a loop at the end, but the service is still empty.
Perhaps someone has encountered a similar problem before.