code

Android 5.1.1 이상-getRunningAppProcesses ()는 내 애플리케이션 패키지 만 반환합니다.

codestyles 2020. 8. 27. 07:49
반응형

Android 5.1.1 이상-getRunningAppProcesses ()는 내 애플리케이션 패키지 만 반환합니다.


Google은 마침내 현재 포 그라운드 애플리케이션 패키지를 얻기 위해 모든 문을 닫은 것 같습니다.

이 답변getRunningTasks(int maxNum) 덕분에 Lollipop 업데이트 후 Lollipop 이후 포 그라운드 애플리케이션 패키지를 가져 오는 데이 코드를 사용했습니다.

final int PROCESS_STATE_TOP = 2;
RunningAppProcessInfo currentInfo = null;
Field field = null;
try {
    field = RunningAppProcessInfo.class.getDeclaredField("processState");
} catch (Exception ignored) { 
}
ActivityManager am = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> appList = am.getRunningAppProcesses();
for (RunningAppProcessInfo app : appList) {
    if (app.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
        app.importanceReasonCode == 0 ) {
        Integer state = null;
        try {
            state = field.getInt( app );
        } catch (Exception ignored) {
        }
        if (state != null && state == PROCESS_STATE_TOP) {
            currentInfo = app;
            break;
        }
    }
}
return currentInfo;

Android 5.1.1 이상 (6.0 Marshmallow)도 종료 된 것 같습니다 getRunningAppProcesses(). 이제 자체 애플리케이션 패키지 목록을 반환합니다.


UsageStatsManager

여기에 설명 된대로UsageStatsManagerAPI를 사용할 수 있지만 모든 애플리케이션에서 작동하는 것은 아닙니다. 일부 시스템 응용 프로그램은 동일한 패키지를 반환합니다.

com.google.android.googlequicksearchbox

AccessibilityService (2017 년 12 월 : Google에서 사용 금지 예정)

일부 응용 프로그램은 AccessibilityService( 여기 에서 볼 수 있듯이 ) 사용하지만 몇 가지 단점이 있습니다.


현재 실행중인 애플리케이션 패키지를 가져 오는 다른 방법이 있습니까?


Android 1.6-Android 6.0에서 실행중인 프로세스 목록을 얻으려면 내가 작성한이 라이브러리를 사용할 수 있습니다. https://github.com/jaredrummler/AndroidProcesses 라이브러리는 프로세스 정보를 얻기 위해 / proc을 읽습니다.

Google은 Android Nougat에서 / proc에 대한 액세스를 크게 제한했습니다. Android Nougat에서 실행중인 프로세스 목록을 얻으려면 UsageStatsManager를 사용하거나 루트 액세스 권한이 있어야합니다.

이전 대체 솔루션에 대한 편집 내역을 클릭하십시오.


 private String printForegroundTask() {
    String currentApp = "NULL";
    if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        UsageStatsManager usm = (UsageStatsManager)this.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)this.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> tasks = am.getRunningAppProcesses();
        currentApp = tasks.get(0).processName;
    }

    Log.e("adapter", "Current App in foreground is: " + currentApp);
    return currentApp;
}

이 방법을 사용하여 포 그라운드 작업을 가져옵니다. 시스템 권한 "android : get_usage_stats"가 필요합니다.

public static boolean needPermissionForBlocking(Context context){
    try {
        PackageManager packageManager = context.getPackageManager();
        ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
        AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, applicationInfo.uid, applicationInfo.packageName);
        return  (mode != AppOpsManager.MODE_ALLOWED);
    } catch (PackageManager.NameNotFoundException e) {
        return true;
    }
}

IF user enable this in setting -> Security-> app with usage access. After that u will get foreground task. Similar process Clean matser by Cheetahamobile google play link


Take a look at https://github.com/ricvalerio/foregroundappchecker, it might be what you need. Provides sample code, and takes away the pain of having to implement cross version foreground detector.

Here are two samples:

AppChecker appChecker = new AppChecker();
String packageName = appChecker.getForegroundApp();

Or regularly check:

AppChecker appChecker = new AppChecker();
appChecker
    .when("com.other.app", new AppChecker.Listener() {
        @Override
        public void onForeground(String packageName) {
            // do something
        }
    )
    .when("com.my.app", new AppChecker.Listener() {
        @Override
        public void onForeground(String packageName) {
            // do something
        }
    )
    .other(new AppChecker.Listener() {
        @Override
        public void onForeground(String packageName) {
            // do something
        }
    )
    .timeout(1000)
    .start(this);

Google limited this functionality for system apps only. As been reported in a bug ticket, you will need the REAL_GET_TASKS permission to access there.

Applications must now have ...permission.REAL_GET_TASKS to be able to get process information for all applications. Only the process information for the calling application will be returned if the app doesn't have the permission. Privileges apps will temporarily be able to get process information for all applications if they don't have the new permission, but have deprecated ...permission.GET_TASKS Also,only system apps can acquire the REAL_GET_TASKS permission.


Just throwing out a potential optimization to what I imagine is a heavily copy-pasted bit of code for detecting the top-most application on Android M.

This

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
    UsageStatsManager usm = (UsageStatsManager)this.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();
        }
    }
}

Can be simplified to this

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
    UsageStatsManager usm = (UsageStatsManager) context.getSystemService(
        Context.USAGE_STATS_SERVICE);
    long time = System.currentTimeMillis();
    List<UsageStats> appStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
            time - 1000 * 1000, time);
    if (appStatsList != null && !appStatsList.isEmpty()) {
        currentApp = Collections.max(appStatsList, (o1, o2) ->
            Long.compare(o1.getLastTimeUsed(), o2.getLastTimeUsed())).getPackageName();
    }
}

I found myself using this code in a 2 second loop, and wondered why I was using a complex solution that was O(n*log(n)) when a more simple solution was available in Collections.max() which is O(n).


public class AccessibilityDetectingService extends AccessibilityService {

@Override
protected void onServiceConnected() {
    super.onServiceConnected();

    //Configure these here for compatibility with API 13 and below.

    AccessibilityServiceInfo config = new AccessibilityServiceInfo();
    config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
    config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;

    if (Build.VERSION.SDK_INT >= 16)
        //Just in case this helps
        config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;

    setServiceInfo(config);
}

@Override
public void onAccessibilityEvent(final AccessibilityEvent event) {
        if (event == null ) {
            return;
        } else if(event.getPackageName() == null && event.getClassName() == null){
            return;
        }

            if (activityInfo != null){

                Log.d("CurrentActivity", componentName.flattenToShortString());
        }

}

private ActivityInfo tryGetActivity(ComponentName componentName) {
    try {
        return getPackageManager().getActivityInfo(componentName, 0);
    } catch (PackageManager.NameNotFoundException e) {
        return null;
    }
}
@Override
public void onInterrupt() {
}                
}
}//`enter code here`uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
<uses-permission android:name="android.permission.GET_TASKS" />

Then start the service and app accessibility on in your device setting->accessibility->App on that service.


//This is Working Fast than above answer.

 String mforegoundPppPackageName;
 UsageStatsManager usage = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
 long time = System.currentTimeMillis();

 List<UsageStats> stats = usage.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, 0, time);
 Collections.sort(stats, usageStatsComparator);

      if (stats != null && stats.size() > 0) {
          if (stats.get(stats.size()).getPackageName().equals("android")) {
              stats.remove(stats.size());
          }
          mforegoundPppPackageName = stats.get(stats.size()).getPackageName();
      } else {
          mforegoundPppPackageName = "";
      }

**//How to sort**

Comparator<UsageStats> usageStatsComparator = new Comparator<UsageStats>() {
        @Override
        public int compare(UsageStats o1, UsageStats o2) {
            if (o1.getLastTimeUsed() > o2.getLastTimeUsed()) {
                return 1;
            } else if (o1.getLastTimeUsed() < o2.getLastTimeUsed()) {
                return -1;
            } else {
                return 0;
            }
        }
    };

Please try to use getRunningServices() instead of getRunningAppProcesses() method.

 ActivityManager mActivityManager = (ActivityManager) getSy stemService(Context.ACTIVITY_SERVICE);

 List<ActivityManager.RunningServiceInfo> appProcessInfoList = mActivityManager.getRunningServices(Integer.MAX_VALUE);

참고URL : https://stackoverflow.com/questions/30619349/android-5-1-1-and-above-getrunningappprocesses-returns-my-application-packag

반응형