Android 5.0(L)服务意图必须在Google分析中明确

我的代码工作在<5,但在Android 5.0我遇到了一个我不太明白的问题。

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) } 

我的代码在4.4.4及更低版本上工作,甚至现在。 那么我需要做什么? 我将在下面发布相关的代码。 此外,在我的谷歌search,我发现这篇文章关于java.lang.IllegalArgumentException:服务意图必须明确的Android 5.0,但我不明白这是什么意思。

performance

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="xxxxx.android.phone.xxxxx" android:versionCode="3" android:versionName="v1.2.4065" > <uses-sdk android:minSdkVersion="12" android:targetSdkVersion="21" /> <!-- Required for Google Analytics --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- For push notifications (GCM) --> <permission android:name="xxxxx.android.phone.xxxxx.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="xxxxx.android.phone.xxxxx.permission.C2D_MESSAGE" /> <!-- App receives GCM messages. --> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <!-- GCM connects to Google Services. --> <uses-permission android:name="android.permission.INTERNET" /> <!-- GCM requires a Google account. --> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <!-- Keeps the processor from sleeping when a message is received. --> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- GCM - We handle notifications differently if the app is running --> <uses-permission android:name="android.permission.GET_TASKS" /> <!-- Caching --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- The event subscribe button adds events to the calendar --> <!-- <uses-permission android:name="android.permission.WRITE_CALENDAR" /> --> <!-- <uses-permission android:name="android.permission.READ_CALENDAR" /> --> <supports-screens android:resizeable="true" android:smallScreens="false" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" /> <application android:name="xxxxx.xxxxxApplication" android:icon="@drawable/app_icon" android:label="@string/app_name" android:allowBackup="true" android:largeHeap="true" > <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <category android:name="xxxxx.android.phone.xxxxx" /> </intent-filter> <intent-filter> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <category android:name="xxxxx.android.phone.xxxxx" /> </intent-filter> </receiver> <receiver android:name="xxxxx.ConnectivityReceiver" android:enabled="false" > <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> <activity android:name=".SplashActivity" android:configChanges="locale|orientation" android:theme="@style/Theme.Splash" android:screenOrientation="portrait" android:noHistory="true" > <intent-filter > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:label="@string/app_name" android:theme="@style/Theme" android:windowSoftInputMode="adjustPan|stateVisible" android:name=".LoginActivity" android:configChanges="locale|orientation|screenSize" android:screenOrientation="portrait" > </activity> <activity android:name=".MainActivity" android:theme="@style/Theme" android:configChanges="locale|orientation|screenSize" android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan|stateVisible" /> <activity android:name=".CountryPickerActivity" android:theme="@style/Theme.Floating" android:configChanges="locale|orientation|screenSize" android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan|stateVisible" /> <activity android:name=".EventPickerActivity" android:theme="@style/Theme.Floating" android:configChanges="locale|orientation|screenSize" android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan|stateVisible" /> <activity android:name=".TutorialActivity" android:theme="@style/Theme.Transparent" android:configChanges="locale|orientation|screenSize" android:screenOrientation="portrait" /> <activity android:name=".VideoPlayerActivity" android:theme="@style/Theme" android:configChanges="orientation|screenSize" /> <service android:name=".GCMIntentService" android:enabled="true" /> <meta-data android:name="com.crashlytics.ApiKey" android:value="xxxxxxxxxxxxxxxx"/> </application> </manifest> 

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; } } ... } 

**编辑**

GCMIntentService.java这个问题越多,我认为这不是在GCMIntentService.java 。 我应该发布我的堆栈跟踪之前是:

 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) 

所以我会试着按照明确的意图运行GA。

从Google Analytics(分析)v2迁移到v3,为我解决了这个问题。

如果您尝试使用Google的授权机制,那么适用于我的解决scheme:

 // 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); 

这位于com/google/android/vending/licensing/LicenseChecker.java 。 search“ Base64.decode(

编辑:

添加对必须修补的Google授权java文件的引用:

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

补丁:

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

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

由于Android 5.0(棒棒糖)bindService()必须总是被明确的意图调用。 这是以前的build议,但是自从Lollipop被强制执行以外: java.lang.IllegalArgumentException: Service Intent must be explicit每次调用bindService()都会使用隐式意图来引发java.lang.IllegalArgumentException: Service Intent must be explicit 。 隐式和显式意图之间的区别在于后者指定了以名称开头的组件(完全限定的类名称)。 在这里查看关于意图types的文档。

你遇到的问题是由于没有升级到更新版本的谷歌库,这符合在Android 5 Lollipop上绑定服务时Android对隐式意图的限制。 要解决该问题,可以将库升级到更新的版本(如果可用),或者自行更新库代码并使用修改后的版本构build项目。

如果在一般情况下没有合适的库升级,则需要修改源代码(在您的情况下, com.google.analytics.tracking.android.AnalyticsGmsCoreClient.connect() )以在调用intent.setPackage(packageName)之前调用bindService() intent.setPackage(packageName) bindService()其中, intentbindService()调用的第一个参数, packageName是包含代码试图启动的服务的包的名称(在你的例子中是“com.google.android.gms.analytics”)。

您可以使用此代码作为示例如何执行此操作: Unity更新版本的Google授权库(LVL),它以明确的意图调用bindService,不会导致IllegalArgumentException。

解决这个问题的另一种方法是在19以前使用targetSDK重build你的项目和谷歌库。这将使得它不会在Lollipop崩溃的情况下运行,但是是不太安全的选项,并且阻止你使用在更高版本中引入的SDKfunction(对于Android 5)。

我只是自己有这个问题。 问题在于你的活动开始你的服务。

基本上,当服务启动时,一个明确的意图直接在意图中命名服务。 请参阅http://developer.android.com/guide/components/intents-filters.html以获得更深入的解释。;

既然你没有发布你的活动代码,我不知道你现在是怎么开始的,但它应该看起来像这样:

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

我用这个 ,它很好用

  public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) { //Retrieve all services that can match the given intent PackageManager pm = context.getPackageManager(); List<ResolveInfo> 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; } 

我正在开发一个项目,我们希望允许用户使用旧设备。 我想出了与Marias答案中提到的解决scheme相同的解决scheme,但是我已经为setPackage调用添加了条件语句,因为它仅在API 4(Ice Cream Sandwich == SDK 14)及更高版本中可用。 如果开发的版本低于我认为你不需要包含setPackage调用。

在函数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); 

如果你想启动另一个应用程序的服务,你可以使用这个:

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

这对我工作..这在棒棒糖使用android sdk 21 ..

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

对于看到此错误的PhoneGap / Cordova用户,这是因为半官方GAPlugin使用了弃用的Google Analytics(分析)v2库。 khalidb91分叉它并更新到v3,这个写作尚未被合并到半官方插件。 从他的叉子抓取代码,直接replace为插件/ com.adobe.plugins.GAPlugin,并且不再有崩溃。 谢谢khalidb91!

https://github.com/khalidb91/GAPlugin

这适用于我:

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

如果您尝试启动服务,请尝试以下方法:

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