私のコードは<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以前で動作します。だから私は何をする必要がありますか?以下に相対コードを投稿します。また、グーグルでこれを見つけました Java.lang.IllegalArgumentExceptionに関する投稿:Android 5.0に関してサービスインテントを明示的に指定する必要があります ですが、その意味がわかりません。
<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>
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
にはないように思います。スタックトレースを投稿しておく必要があります。
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アナリティクスv2からv3に移行すると、問題が解決します。
Googleのライセンスメカニズムを使用するを試している場合、私にとってはうまくいった解決策です:
// 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
にあります。 「Base64.decode(
」を検索してください
編集:
パッチを適用する必要があるGoogle Licensing 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(Lollipop)以降、bindService()は常に明示的な目的で呼び出す必要があります。これは以前は推奨事項でしたが、Lollipop以降では強制されます。暗黙のインテントを使用してbindService()
の呼び出しが行われるたびにJava.lang.IllegalArgumentException: Service Intent must be explicit
がスローされます。暗黙的意図と明示的意図の違いは、後者が名前(完全修飾クラス名)で開始するコンポーネントを指定することです。 インテントタイプに関するドキュメントを参照してください。
発生している問題は、Android 5 Lollipopでサービスをバインドする際の暗黙的なインテントに関するAndroidの制限に準拠するGoogleライブラリの新しいバージョンにアップグレードしていないことが原因です。この問題を修正するには、ライブラリを新しいバージョンにアップグレードし(使用可能な場合)、ライブラリコードを自分で更新して、変更したバージョンでプロジェクトをビルドします。
一般的なケースで適切なライブラリのアップグレードがない場合は、com.google.analytics.tracking.Android.AnalyticsGmsCoreClient.connect()
を呼び出す前にintent.setPackage(packageName)
を呼び出すようにソースコードを変更する必要があります(bindService()
)。ここで、intent
はbindService()
呼び出しの最初の引数とpackageName
は、コードが開始しようとしているサービスを含むパッケージの名前です(この場合は「com.google.Android.gms.analytics」)。
これを行う方法の例として、このコードを使用できます。 nityのGoogle Licensing Library(LVL)の更新バージョン。明示的な意図でbindServiceを呼び出し、IllegalArgumentExceptionになりません。
さらに問題を回避する別の方法は、19以下でtargetSDKを使用してプロジェクトとgoogleライブラリを再構築することです。これにより、Lollipopでクラッシュすることなく実行されますが、安全性が低いオプションであり、以降のバージョンで導入されたSDK機能を使用できなくなります(Android 5の場合)。
私はこの問題を自分で抱えていました。問題は、サービスを開始するアクティビティにあります。
基本的に、明示的なインテントは、サービスの開始時にインテント内でサービスに直接名前を付けます。より詳細な説明については、 http://developer.Android.com/guide/components/intents-filters.html を参照してください。
アクティビティコードが投稿されていないため、今どのように開始しているのかわかりませんが、おそらく次のようになります。
Intent startIntent = new Intent(this, ServiceToStart.class);
this.startService(startIntent); // or bindService(...)
this を使用しましたが、うまく機能します
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の回答に記載されているものと同じソリューションを思い付きましたが、API [4](アイスクリームサンドイッチ== SDK 14)以降でのみ使用できるため、setPackage
呼び出しの条件ステートメントを追加しました。 。それ以下のバージョン用に開発している場合、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を使用してLollipopで働いた。
Intent intent = new Intent(this, Class.forName(ServiceClassName.class.getName()));
bindService(intent,serviceConnection, Service.BIND_AUTO_CREATE);
このエラーが表示されるPhoneGap/Cordovaユーザーの場合、準公式のGAPluginが非推奨のGoogle Analytics v2 libを使用しているためです。 khalidb91はそれを分岐し、v3に更新しました。この記事の執筆時点では、半公式のプラグインにはマージされていません。彼のフォークからコードを取得し、plugins/com.Adobe.plugins.GAPluginへの直接の置き換えとしてドロップすれば、クラッシュすることはありません。ありがとうkhalidb91!
これは私のために働く:
Intent intent = new Intent(ACTION);
intent.setPackage(context.getPackageName());
context.startService(intent);