remotamente - escritorio remoto chrome android
¿Cómo llamar a un servicio remoto de Android(IPC) desde un servicio Widget/local? (1)
Encontré la respuesta a mi propia pregunta. Para facilitar las cosas a los demás, aquí está la solución:
Al hacer un servicio remoto, uno tiene que escribir el AIDL que se compilará en una especie de interfaz de código auxiliar, la implementación de esa interfaz (es decir, el código que se ejecuta cuando alguien llama a los métodos remotos) y una clase que amplía "Servicio". "que devuelve la clase de implementación en el método onBind (). (Un servicio local normal devolvería nulo en ese método)
Ahora lo que no entendí es que DEBE tener una definición de servicio en el manifiesto: ¡CON FILTRO DE INTENCIÓN!
Digamos que su AIDL se llama IRemoteService.aidl, luego tiene una clase llamada RemoteService que se ve así:
public class RemoteService extends Service {
public IBinder onBind(Intent intent) {
Log.i("RemoteService", "onBind() called");
return new RemoteServiceImpl();
}
/**
* The IRemoteInterface is defined through IDL
*/
public class RemoteServiceImpl extends IRemoteService.Stub {
public void remoteDetonateBirthdayCake() throws RemoteException {
//your code here
}
};
}
En tu manifiesto de Android, quieres esto:
<service android:name="RemoteService">
<intent-filter>
<action android:name="com.sofurry.favorites.IRemoteService"></action>
</intent-filter>
</service>
Tenga en cuenta el nombre del servicio: es "RemoteService", no "IRemoteService" o incluso "RemoteServiceImpl". Necesita el nombre de la clase que extiende "Servicio", cuyo método onBind reemplazamos.
Para completar el asunto, aquí está el código del lado del cliente, y sí, este código también funciona desde otro servicio, por ejemplo, uno que inició desde su widget;
IRemoteService mService;
RemoteServiceConnection mConnection = new RemoteServiceConnection();
getApplicationContext().bindService(new Intent(IRemoteService.class.getName()), mConnection, Context.BIND_AUTO_CREATE);
... donde RemoteServiceConnection puede ser una clase interna como esta:
class RemoteServiceConnection implements ServiceConnection {
public void onServiceConnected(ComponentName className,
IBinder service ) {
mService = IRemoteService.Stub.asInterface(service);
isBound = true;
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
isBound = false;
}
};
Y ahora, puedes llamar ...
mService.remoteDetonateBirthdayCake();
En resumen: asegúrese de tener una sección de servicio en el manifiesto de Android, configure "nombre" para la clase que devuelve la implementación real en su método onBind (), y también debe tener un filtro de intención con una definición de acción que apunte al Interfaz AIDL.
Sugerencia: si está llamando a servicios remotos desde una aplicación dentro de una APK diferente, agregue también un elemento de "categoría" al filtro de intención y configúrelo en PREDETERMINADO.
Intento controlar a distancia un fondo de pantalla en vivo desde un widget. Están en la misma APK, pero obviamente diferentes procesos. Llamar a una "actividad" del fondo de pantalla en vivo me sirve de poco, ya que es un proceso diferente. El widget tiene botones simples que, cuando se presiona,
Entonces, lo que (creo) necesito es IPC y AIDL.
Primero creé el AIDL en el lado del fondo de pantalla, que funcionó bien. Tiene tres métodos sin parámetros adicionales. Pero cuando agregué el cliente al widget, recibí un error al decirme que no puedo enlazar a esa interfaz remota porque el widget ya es un BroadcastListener. Intenté obtener el manejo de los botones sin necesidad de que el Widget fuera un BroadcastListener, pero eso parece ser imposible.
Bueno, no hay problema, ¿verdad? Acabo de crear un servicio dentro del widget que se une a la interfaz remota, porque aunque el widget es un BroadcastListener, el servicio no lo es, y todo debería estar bien.
O eso pensé.
Bueno, obtengo los botones del widget para activar el servicio de widgets. La vinculación al servicio remoto me da la siguiente advertencia:
No se puede iniciar el servicio Intención (act = com.blabla.IRemoteService): no encontrado.
Estoy usando getApplicationContext () dentro del servicio del widget para enlazar a las cosas remotas. Tengo el servicio de widgets en el manifiesto, pero no tengo el servicio remoto allí. Cuando lo pongo allí, obtengo una InstantiationException no específica.
En el Widget''s Service onStart () estoy haciendo esto:
getApplicationContext().bindService(new Intent(IWallpaperRemote.class.getName()),
mConnection, Context.BIND_AUTO_CREATE);
Tambien tengo...
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
mService = IWallpaperRemote.Stub.asInterface(service);
isBound = true;
Log.i("WidgetServiceConnection", "binding to service succeeded");
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
isBound = false;
Log.i("WidgetServiceConnection", "binding to service lost!");
}
};
Mi pregunta es esta: ¿alguna vez alguien ha realizado con éxito una llamada remota desde un widget a otra aplicación? Teniendo en cuenta que estoy hablando de un fondo de pantalla en vivo aquí, y el hecho de que no estoy interesado en llamar una actividad dentro del proceso de widgets sino que causa llamadas de función dentro del fondo de pantalla en vivo, ¿qué opciones tengo aparte de IPC, si hay alguna?
Y si IPC es la manera de ir aquí, ¿qué estoy haciendo mal?