Android 5.0 (L) La intención del servicio debe ser explícita en Google Analytics

Mi código funcionaba en <5, pero en Android 5.0 me encuentro con un problema que no entiendo del todo.

10-23 10:18:18.945: E/AndroidRuntime(8987): java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.google.android.gms.analytics.service.START (has extras) } 

Mi código funciona, incluso ahora, en 4.4.4 y abajo. Entonces, ¿qué debo hacer? Publicaré el código relativo a continuación. Además, durante mi búsqueda en Google encontré esta publicación sobre java.lang.IllegalArgumentException: Service Intent debe ser explícito con respecto a Android 5.0, pero no entiendo lo que significa.

Manifiesto

                     <!--  --> <!--  -->                                   

GCMIntentService.java

 public class GCMIntentService extends GCMBaseIntentService { private static final int ATTEMPTS_MAX = 3; final static boolean USE_DEV = false; final static String XXXXX = "https://xxxxx/api.php"; final static String XXXXX = "http://dev.xxxxx/api.php"; final static String SUBSCRIPTION_KEY = "xxxxxxxxxxxxxxx"; // unique per app public GCMIntentService() { super(xxxxxx.SENDER_ID); if(GCMIntentService.USE_DEV) { host = XXXXX; } else { host = XXXXX; } } ... } 

** EDIT **

Cuanto más miro este tema, más creo que no está en GCMIntentService.java . Debería haber publicado mi rastro de stack antes de que sea:

 10-23 13:17:08.095: E/AndroidRuntime(10560): FATAL EXCEPTION: GAThread 10-23 13:17:08.095: E/AndroidRuntime(10560): Process: xxxxx.android.phone.xxxxx, PID: 10560 10-23 13:17:08.095: E/AndroidRuntime(10560): java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.google.android.gms.analytics.service.START (has extras) } 10-23 13:17:08.095: E/AndroidRuntime(10560): at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1674) 10-23 13:17:08.095: E/AndroidRuntime(10560): at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1773) 10-23 13:17:08.095: E/AndroidRuntime(10560): at android.app.ContextImpl.bindService(ContextImpl.java:1751) 10-23 13:17:08.095: E/AndroidRuntime(10560): at android.content.ContextWrapper.bindService(ContextWrapper.java:538) 10-23 13:17:08.095: E/AndroidRuntime(10560): at com.google.analytics.tracking.android.AnalyticsGmsCoreClient.connect(AnalyticsGmsCoreClient.java:82) 10-23 13:17:08.095: E/AndroidRuntime(10560): at com.google.analytics.tracking.android.GAServiceProxy.connectToService(GAServiceProxy.java:279) 10-23 13:17:08.095: E/AndroidRuntime(10560): at com.google.analytics.tracking.android.GAServiceProxy.createService(GAServiceProxy.java:163) 10-23 13:17:08.095: E/AndroidRuntime(10560): at com.google.analytics.tracking.android.GAThread.init(GAThread.java:95) 10-23 13:17:08.095: E/AndroidRuntime(10560): at com.google.analytics.tracking.android.GAThread.run(GAThread.java:493) 

Por lo tanto, intentaré ejecutar GA como bash explícito.

La migración de Google Analytics v2 a v3 me solucionó el problema.

Si está intentando usar el mecanismo de licencias de Google, la solución que funcionó para mí:

 // explicit Intent, safe Intent serviceIntent = new Intent(ILicensingService.class.getName()); serviceIntent.setPackage("com.android.vending"); boolean bindResult = mContext.bindService(serviceIntent, this, Context.BIND_AUTO_CREATE); 

Esto se encuentra en com/google/android/vending/licensing/LicenseChecker.java . Haz una búsqueda de ” Base64.decode(

Editar:

Agregar referencia al archivo java Google Licensing que tiene que ser parcheado:

 com.google.android.vending.licensing.LicenseChecker.checkAccess(LicenseChecker.java:150) 

parche:

 new String( - Base64.decode("Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U="))), + Base64.decode("Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U="))) + .setPackage("com.android.vending"), // this fix the 'IllegalArgumentException: Service Intent must be explicit' this, // ServiceConnection. 

Fuente: https://code.google.com/p/android/issues/detail?id=78505#c19

Como Android 5.0 (Lollipop) bindService () siempre debe invocarse con un bash explícito. Anteriormente, esta era una recomendación, pero desde Lollipop se aplica: java.lang.IllegalArgumentException: Service Intent must be explicit se lanza cada vez que se realiza una llamada a bindService() utilizando intenciones implícitas. La diferencia entre los bashs implícitos y explícitos es que el último especifica el componente para comenzar por el nombre (el nombre de clase completamente calificado). Consulte la documentación sobre los tipos de intención aquí.

El problema que está teniendo se debe a que no se actualizó a una versión más nueva de las bibliotecas de Google, que cumplen con las restricciones de Android sobre bashs implícitos al vincular un servicio en Android 5 Lollipop. Para solucionar el problema, puede actualizar la biblioteca a una versión más reciente, si está disponible, o actualizar el código de la biblioteca usted mismo y crear su proyecto con la versión modificada.

Si no hay una actualización de biblioteca adecuada en el caso general, debe modificar el código fuente (en su caso com.google.analytics.tracking.android.AnalyticsGmsCoreClient.connect() ) para llamar a intent.setPackage(packageName) antes de llamar a bindService() donde intent es el primer argumento de la llamada bindService() y packageName es el nombre del paquete que contiene el servicio que el código intenta iniciar (en su caso “com.google.android.gms.analytics”).

Puede usar este código como ejemplo de cómo hacer esto: la versión actualizada de Unity de la Biblioteca de licencias de Google (LVL) que llama bindService con un bash explícito y no da como resultado IllegalArgumentException.

Otra forma de evitar el problema es reconstruir tu proyecto y las bibliotecas de google utilizando targetSDK antes de las 19. Esto hará que se ejecute sin fallar en Lollipop, pero es la opción menos segura e impide utilizar la funcionalidad SDK introducida en versiones posteriores. (para Android 5).

Solo estaba teniendo este problema yo mismo. El problema radica en su actividad que está comenzando su servicio.

Básicamente, un bash explícito nombra el servicio directamente en la intención cuando se inicia el servicio. Consulte http://developer.android.com/guide/components/intents-filters.html para obtener una explicación más detallada.

Como no se ha publicado su código de actividad, no sé cómo lo está iniciando ahora, pero probablemente debería verse más o menos así:

 Intent startIntent = new Intent(this, ServiceToStart.class); this.startService(startIntent); // or bindService(...) 

Usé esto y funciona muy bien

  public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) { //Retrieve all services that can match the given intent PackageManager pm = context.getPackageManager(); List resolveInfo = pm.queryIntentServices(implicitIntent, 0); //Make sure only one match was found if (resolveInfo == null || resolveInfo.size() != 1) { return null; } //Get component info and create ComponentName ResolveInfo serviceInfo = resolveInfo.get(0); String packageName = serviceInfo.serviceInfo.packageName; String className = serviceInfo.serviceInfo.name; ComponentName component = new ComponentName(packageName, className); //Create a new intent. Use the old one for extras and such reuse Intent explicitIntent = new Intent(implicitIntent); //Set the component to be explicit explicitIntent.setComponent(component); return explicitIntent; } 

Estoy trabajando en un proyecto en el que queremos permitir a los usuarios usar dispositivos más antiguos. Se me ocurrió la misma solución que la mencionada en la respuesta de Marias, sin embargo, he agregado una statement condicional para la llamada a setPackage ya que solo está disponible en API 4 (Ice Cream Sandwich == SDK 14) y superior. Si desarrolla versiones inferiores a las que considero, no es necesario que incluya la llamada setPackage .

En la función com.google.android.vending.licensing.LicenseChecker.checkAccess(callback)

 Intent serviceIntent = new Intent(new String( Base64.decode("Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U="))); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { serviceIntent.setPackage("com.android.vending"); } boolean bindResult = mContext.bindService( serviceIntent, this, // ServiceConnection. Context.BIND_AUTO_CREATE); 

Si desea iniciar un servicio que está en otra aplicación, puede usar esto:

 Intent serviceIntent = new Intent("action name for the service"); serviceIntent.setPackage("the PackageName for which the service in)");//the destination packageName context.startService(serviceIntent); 

Esto funcionó para mí … Esto funcionó en lollipop usando Android SDK 21.

 Intent intent = new Intent(this, Class.forName(ServiceClassName.class.getName())); bindService(intent,serviceConnection, Service.BIND_AUTO_CREATE); 

Para los usuarios de PhoneGap / Cordova que están viendo este error, es porque GAPlugin semioficial usa la versión obsoleta de Google Analytics v2 lib. khalidb91 lo bifurcó y actualizó a v3, que a partir de este momento no se ha fusionado en el complemento semioficial. Toma el código de su tenedor, colócalo como un reemplazo directo a plugins / com.adobe.plugins.GAPlugin y no más lockings. Gracias khalidb91!

https://github.com/khalidb91/GAPlugin

Esto funciona para mí:

 Intent intent = new Intent(ACTION); intent.setPackage(context.getPackageName()); context.startService(intent); 

Si está intentando iniciar el servicio, pruébelo de esta manera:

 var intent = new Intent (this,typeof(MyBoundService)); var serviceConnection = new MyBindServiceConnection (this); BindService (intent, serviceConnection, Bind.AutoCreate);