別のアプローチを使用することもできます。アクティビティにカテゴリを設定するのではなく、アプリケーション マニフェストにメタ情報を設定します。削除されたパッケージ情報は取得できないことに注意してください (アプリケーションがフラグ DONT_DELETE_DATA で削除されていない場合)。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.package.name"
android:versionCode="1"
android:versionName="1" >
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<meta-data
android:name="meta-name"
android:value="meta-value" />
</application>
</manifest>
パッケージのインストールを追跡するブロードキャスト レシーバーを追加します。パッケージのメタ情報をチェックして、値が既に存在することを確認します。
private BroadcastReceiver packageListener = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
Log.i(intent.getAction(), intent.getData().getEncodedSchemeSpecificPart());
//Currently being installed or deleted package
String packageName = intent.getData().getEncodedSchemeSpecificPart();
Object value = null;
try {
ApplicationInfo appInfo = getPackageManager().getApplicationInfo(packageName,PackageManager.GET_META_DATA);
//Get meta value if exits
value = appInfo.metaData.get("meta-name");
} catch (NameNotFoundException e) {
Log.e(TAG, "exception occured", e);
}
//check meta info if it is yours
}
}
ご覧のとおり、他のアプリケーションはメタデータをマニフェストに設定できるため、独自のアプリを認識するための安全な方法ではありません。最善の方法は、すべてが同じ証明書で署名されている場合、apk 署名を確認することです。
private BroadcastReceiver packageListener = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
Log.i(intent.getAction(), intent.getData().getEncodedSchemeSpecificPart());
String packageName = intent.getData().getEncodedSchemeSpecificPart();
Signature[] signatures = null;
try {
PackageInfo packageInfo = getPackageManager().getPackageInfo(packageName,PackageManager.GET_SIGNATURES);
signatures = packageInfo.signatures;
} catch (NameNotFoundException e) {
Log.e(TAG, "exception occured", e);
}
//check installed package signature if it matches
}
}