Получение packageName приложения переднего плана в Зефире задерживается на 3 секунды
В Android 6.0 Marshmallow я запрашиваю приложение переднего плана со следующим кодом, но возникла проблема с входящими уведомлениями, поскольку оно отображает приложение переднего плана в приложении, которое отправляет уведомление. Проблема существует только в Зефире (5.X работает правильно).
// API 21 and above
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static String getProcessNew(UsageStatsManager mUsageStatsManager, Context c) throws Exception {
String st = null;
try {
long endTime = System.currentTimeMillis();
long beginTime = endTime - 1000 * 10;
// We get usage stats for the last minute
List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, beginTime,
endTime);
// Sort the stats by the last time used
if (stats != null) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : stats) {
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
st = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
} catch (Exception e) {
Log.d("main", "Wxxxxexx " + e);
}
return st;
}
и тогда проблема уведомления решена, используя решение от этого ответа UsageEvents.
В качестве решения в ответ я поместил код и его работу, чтобы получить приложение Foreground, но оно задержалось на 3 секунды. Мой сервис проверяет приложение переднего плана и повторяется каждые 500 мс, но пакет whatsapp обнаруживает через 3 секунды после запуска WhatsApp. это код UsageEvents, который я использую сверху решения.
if (BuildV >= 23) {
long endTime = System.currentTimeMillis();
long beginTime = endTime - 1000 * 10;
UsageEvents usageEvents = mUsageStatsManager.queryEvents(beginTime, endTime);
UsageEvents.Event event = new UsageEvents.Event();
while (usageEvents.hasNextEvent()) {
usageEvents.getNextEvent(event);
}
if (st.equals(event.getPackageName())
&& event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
pack = st;
}
}
1 ответ
Попробуйте этот код и убедитесь, что код применяется после того, как пользователю предоставлено разрешение времени выполнения
private RunningAppProcessInfo getForegroundApp() {
RunningAppProcessInfo result=null, info=null;
if(mActivityManager==null)
mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List <RunningAppProcessInfo> l = mActivityManager.getRunningAppProcesses();
Iterator <RunningAppProcessInfo> i = l.iterator();
while(i.hasNext()){
info = i.next();
if(info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
&& !isRunningService(info.processName)){
result=info;
break;
}
}
return result;
}
private ComponentName getActivityForApp(RunningAppProcessInfo target){
ComponentName result=null;
ActivityManager.RunningTaskInfo info;
if(target==null)
return null;
if(mActivityManager==null)
mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List <ActivityManager.RunningTaskInfo> l = mActivityManager.getRunningTasks(9999);
Iterator <ActivityManager.RunningTaskInfo> i = l.iterator();
while(i.hasNext()){
info=i.next();
if(info.baseActivity.getPackageName().equals(target.processName)){
result=info.topActivity;
break;
}
}
return result;
}
private boolean isStillActive(RunningAppProcessInfo process, ComponentName activity)
{
// activity can be null in cases, where one app starts another. for example, astro
// starting rock player when a move file was clicked. we dont have an activity then,
// but the package exits as soon as back is hit. so we can ignore the activity
// in this case
if(process==null)
return false;
RunningAppProcessInfo currentFg=getForegroundApp();
ComponentName currentActivity=getActivityForApp(currentFg);
if(currentFg!=null && currentFg.processName.equals(process.processName) &&
(activity==null || currentActivity.compareTo(activity)==0))
return true;
Slog.i(TAG, "isStillActive returns false - CallerProcess: " + process.processName + " CurrentProcess: "
+ (currentFg==null ? "null" : currentFg.processName) + " CallerActivity:" + (activity==null ? "null" : activity.toString())
+ " CurrentActivity: " + (currentActivity==null ? "null" : currentActivity.toString()));
return false;
}
private boolean isRunningService(String processname){
if(processname==null || processname.isEmpty())
return false;
RunningServiceInfo service;
if(mActivityManager==null)
mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);
List <RunningServiceInfo> l = mActivityManager.getRunningServices(9999);
Iterator <RunningServiceInfo> i = l.iterator();
while(i.hasNext()){
service = i.next();
if(service.process.equals(processname))
return true;
}
return false;
}