次のコードを使用して、変数foregroundTaskPackageNameでフォアグラウンドアプリのアクティビティ名を取得します。 4.1から4.4までのすべてのOSバージョンで動作しますが、Android 5.0 Lollipopでは動作しません。
5.0 Lollipopの変更点についてだれでも支援できますか? Lollipopでは、foregroundTaskPackageNameで取得するテキストは「Launcher3」です。 Genymotion Emulatorを使用しています。
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0); // get
// list
// of
// running
// tasks
String foregroundTaskAppName = null;
String foregroundTaskPackageName = foregroundTaskInfo.topActivity
.getPackageName();
起動されたアクティビティの履歴を取得するには、新しいUsageStatsManager
を使用し、そのqueryUsageStats
メソッドを呼び出す必要があります。ユーザーは、[セキュリティ]-> [使用権限のあるアプリ]でデバイス設定の使用統計にアクセスする必要があります。
リンク:
これは私のためにLollipopで動作します(21):
ActivityManager manager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses();
Log.i("current_app",tasks.get(0).processName);
以下のコードを使用して、現在のフォアグラウンドアクティビティパッケージ名を取得できます。
if (Android.os.Build.VERSION.SDK_INT >= Android.os.Build.VERSION_CODES.Lollipop) {
// intentionally using string value as Context.USAGE_STATS_SERVICE was
// strangely only added in API 22 (Lollipop_MR1)
@SuppressWarnings("WrongConstant")
UsageStatsManager usm = (UsageStatsManager) getSystemService("usagestats");
long time = System.currentTimeMillis();
List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
time - 1000 * 1000, time);
if (appList != null && appList.size() > 0) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : appList) {
mySortedMap.put(usageStats.getLastTimeUsed(),
usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(
mySortedMap.lastKey()).getPackageName();
}
}
} else {
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = am
.getRunningAppProcesses();
currentApp = tasks.get(0).processName;
}
これらのアクセス許可をマニフェストファイルに追加します(最初のアクセス許可は<API 21、2番目のアクセス許可は> = API 21)。
<uses-permission Android:name="Android.permission.GET_TASKS" />
<uses-permission Android:name="Android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
getRunningTasks() docs:
このメソッドはAPIレベル21で非推奨になりました。Lollipopの時点で、このメソッドはサードパーティのアプリケーションでは使用できなくなりました:ドキュメント中心の最近の手段の導入発信者に個人情報が漏洩する可能性があります。後方互換性のために、それはまだそのデータの小さなサブセットを返します:少なくとも呼び出し側の自身のタスク、そしておそらくは重要ではないことが知られている家のような他のいくつかのタスク。
利用可能ですが、最良ではない方法は、アクセシビリティを使用することです。
AndroidManifest xmlファイルでアクセシビリティサービスを宣言する
<service
Android:name=".MyAccessibilityService"
Android:label="@string/accessibility_service_label"
Android:permission="Android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter>
<action Android:name="Android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
Android:name="Android.accessibilityservice"
Android:resource="@xml/accessibility_service_config" />
</service>
accessibility_service_config.xmlファイル
<accessibility-service xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:description="@string/accessibility_service_desc"
Android:accessibilityEventTypes="typeAllMask"
Android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews"
Android:accessibilityFeedbackType="feedbackSpoken"
Android:notificationTimeout="100"
Android:canRetrieveWindowContent="true"
/>
ウィンドウの状態が変化したときにアクティビティ名を保存する
public class MyAccessibilityService extends AccessibilityService{
public static String sActivityName;
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
// TODO Auto-generated method stub
if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){
Log.d("activitytest", "onAccessibilityEvent with window state changed");
sActivityName = event.getClassName().toString();
}
}
@Override
public void onInterrupt() {
// TODO Auto-generated method stub
}
}
欠点は、ユーザーが設定でアクセシビリティサービスを有効にできるようにする必要があることです。
/system/bin/toolbox
コマンドを使用してプロセスを識別し、次に可視アプリケーションを識別するクラスを作成しました。追加の必要性は、UIおよびAndroidランチャーのないシステムアプリを識別します。
これを試して
public static boolean isForeground(Context context) {
ActivityManager manager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses();
if(tasks.isEmpty())
return false;
for (ActivityManager.RunningAppProcessInfo task : tasks) {
if(context.getPackageName().equalsIgnoreCase(task.processName)){
return task.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
}
}
return false;
}