2016-07-05 51 views

回答

1

我正在快速工作几天的表情符号键盘。我需要三天时间才能获取前台应用程序包名称以发送表情符号图像,因为每当我想发送图像时,它都会弹出intentchooser以选择其中一个可将图像作为额外处理的应用程序。

所有教程和链接对我来说都不起作用,因为Google不赞成使用getRunningTasks()方法来获取当前正在运行的应用程序。

然后我有一个绝妙的想法,使用ResolveInfo获得设备上当前运行的应用程序的堆栈,但它没有用。

最后,我在API 21中引入了一个名为UsageStatsManager的新类,它适用于我。 This github link提供如何使用此类来获取正在运行的应用程序包名。

下面是我的代码是怎么在上面运行的程序包名的应用程序:

public class UStats { 
    public static final String TAG = UStats.class.getSimpleName(); 
    @SuppressLint("SimpleDateFormat") 
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("M-d-yyyy HH:mm:ss"); 

    public static ArrayList<String> printCurrentUsageStatus(Context context) { 
     return printUsageStats(getUsageStatsList(context)); 
    } 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public static ArrayList<String> printUsageStats(List<UsageStats> usageStatsList) { 
     HashMap<String, Integer> lastApp = new HashMap<String, Integer>(); 
     for (UsageStats u : usageStatsList) { 
      lastApp.put(u.getPackageName(), (int) u.getLastTimeStamp()); 
      /*Log.d(TAG, "Pkg: " + u.getPackageName() + "\t" + "ForegroundTime: " 
        + u.getTotalTimeInForeground() + "\t" + "LastTimeStamp: " + new Date(u.getLastTimeStamp()));*/ 
     } 
     Map<String, Integer> sortedMapAsc = sortByComparator(lastApp); 
     ArrayList<String> firstApp = new ArrayList<>(); 
     for (Map.Entry<String, Integer> entry : sortedMapAsc.entrySet()) { 
      String key = entry.getKey(); 
      //Integer value = entry.getValue(); 
      firstApp.add(key); 
      /*System.out.println("package name: " + key + ", time " + new Date(Math.abs(value)));*/ 
     } 

     return firstApp; 
    } 

    // To check the USAGE_STATS_SERVICE permission 
    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public static List<UsageStats> getUsageStatsList(Context context) { 
     UsageStatsManager usm = getUsageStatsManager(context); 
     Calendar calendar = Calendar.getInstance(); 
     long endTime = calendar.getTimeInMillis(); 
     calendar.add(Calendar.MINUTE, -1); 
     long startTime = calendar.getTimeInMillis(); 

     Log.d(TAG, "Under getUsageStateList"); 
     Log.d(TAG, "Range start:" + dateFormat.format(startTime)); 
     Log.d(TAG, "Range end:" + dateFormat.format(endTime)); 

     List<UsageStats> usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, startTime, endTime); 
     return usageStatsList; 
    } 

    // Sort the map in the ascending order of the timeStamp 
    private static Map<String, Integer> sortByComparator(Map<String, Integer> unsortMap) { 
     List<Map.Entry<String, Integer>> list = new LinkedList<>(unsortMap.entrySet()); 

     // Sorting the list based on values 
     Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { 
      public int compare(Map.Entry<String, Integer> o1, 
           Map.Entry<String, Integer> o2) { 
       return o2.getValue().compareTo(o1.getValue()); 
      } 
     }); 

     // Maintaining insertion order with the help of LinkedList 
     Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>(); 
     for (Map.Entry<String, Integer> entry : list) { 
      sortedMap.put(entry.getKey(), entry.getValue()); 
     } 
     return sortedMap; 
    } 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1) 
    @SuppressWarnings("ResourceType") 
    private static UsageStatsManager getUsageStatsManager(Context context) { 
     UsageStatsManager usm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); 
     return usm; 
    } 
} 

然后,我只是得到了应用包名称的ArrayList中,使用下面的代码:

ArrayList<String> sortedApplication = UStats.printCurrentUsageStatus(SimpleIME.this); 
Log.d("TAG", "applicationList: " + sortedApplication.toString()); 

不要忘了添加权限:

<uses-permission android:name = "android.permission.PACKAGE_USAGE_STATS" 
        tools:ignore = "ProtectedPermissions"/> 

和下面的代码来检查我们的应用程序,以获得其他应用程序状态的权限:

if (UStats.getUsageStatsList(this).isEmpty()) { 
    Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); 
    Toast.makeText(MainActivity.this, "Enable Usage Access for YOUR_APP_NAME to use this app", Toast.LENGTH_LONG).show(); 
    startActivity(intent); 
} 

上面的代码将打开一个访问设置页面,以使我们的应用程序,以获得其他应用程序使用状态(一次)。

希望这会有所帮助。

相关问题