New to Android development, I have made an app (the server) in Android Studio, and I have made a simple plugin in civTAK (client). To put simply, my app is proprietary, so I can't expose or share the package/module of the app. So I came up with the solution to make a new library which will contain the aidl information, e.g., "aidlinterface" with the package name com.aidlinterface, and then add that to the app level gradle for both server and client apps.
So the tree structure is project/server_app and project/aidlinterface and for the client project/client_app and project/aidlinterface. So, the app and the library are at the same hierarchy. Becuase of the this I was able to create the server and client packages to be the exact same "com.aidlInterface". First question: is this approach ok for this problem/is this approach viable or is there a better way?
Second question, I have then made the service in the server app, and ensured that the service is initialised by going in the MainActivity.kt in the onCreate function:
startService(Intent(this, ServiceName::class.java))
And for the purposes of this example we can say that the service only has a log statement that says "service initialised", but when I go on logcat and filter by com.aidlinterface, nothing is showing up, which tells me that the package is not attached. but I have added the package in:
dependencies {
implementation(project(":aidlInterface"))
...
}
Here is the AIDL interface:
// IAIDLColorInterface.aidl
package com.aidlinterface;
// Declare any non-default types here with import statements
interface IAIDLColorInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
int getColor();
}
The same interface is present in the client app library.
Here is the service in the server app:
package com.aidlinterface;
import android.app.Service;
import android.content.Intent;
import android.graphics.Color;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import java.util.Random;
public class AIDLColorService extends Service {
private static final String TAG ="AIDLColorService" ;
public AIDLColorService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return binder;
}
private final IAIDLColorInterface.Stub binder = new IAIDLColorInterface.Stub() {
@Override
public int getColor() throws RemoteException {
Random rnd = new Random();
int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
Log.d(TAG, "getColor: "+ color);
return color;
}
};
}
The manifest for the server app's aidlInterface library:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="@string/app_name"
android:supportsRtl="true">
<service
android:name=".AIDLColorService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="AIDLColorService" />
</intent-filter>
</service>
</application>
</manifest>
Here is the code from the client app where I am using this information:
<civTAK imports>
import com.aidlinterface.IAIDLColorInterface
class ColorPlugin(
mapView:MapView ){
private var AIDLColorService: IAIDLColorInterface? = null
private val serviceConnection = object: ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service:IBinder?){
AIDLColorService = IAIDLColorInterface.Stub.asInterface(service)
}
override fun onServiceDisconnected(name: ComponentName?){
AIDLColorService = null
}
init{
val serviceIntent = Intent("AIDLColorService")
serviceIntent.setPackage("com.aidlInterface")
pluginContext.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE)
override fun disposeImpl(){
pluginContext.unbindService(serviceConnection)
}
override fun onReceive(context:Context, intent: Intent){
// code for plugin
// CODE THAT CALLS SERVICE
b.setOnClickListener {
try {
val color = iADILColorService.color
it.setBackgroundColor(color)
} catch (e: RemoteException) {
// Handle exception
}
}
}
Any advice on this will be greatly appreciated. I understand this is a very vague problem, but I will try to answer any questions as best as possible!
server_apphas some other package name. So, unless you are including the stringcom.aidlinterfacein your log statement, I would not expect it to show up in Logcat. In general, this is why we encourage a minimal reproducible example for questions of the form "why is my code not working?", since usually we cannot help you without seeing the code that is not working.AIDLColorServiceorgetColor? Also, please do not catch exceptions without logging them. In this case, you havecatch (e: RemoteException)that does nothing, so if you are getting aRemoteException, you will never find out about it.Unable to start service Intent {act=com.aidlinterface.AIDLColorService pkg=com.aidlinterface } U=0:not found. Thank you for the RemoteException comment!project/aidlinterfaceshould result in the following:dependencies { implementation(project(":aidlinterface")) ... }. I think you used camelcase