Как узнать, видно ли приложение для Android?
У меня есть таймер, который начинает уведомление, когда он заканчивается. Но я хотел бы запустить уведомление с помощью notificationManager только в том случае, если приложение в настоящее время не видно, и показать alertDialog, если таймер заканчивается, когда приложение находится на переднем плане.
Я уже пробовал с этим:
ActivityManager actMngr = (ActivityManager) ValeoMobileApplication.getContext().getSystemService(Activity.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningAppProcesses = actMngr.getRunningAppProcesses();
Tools.log("TimerBroadcastReceiver", "onReceive", "All running processes are listed below :");
for (RunningAppProcessInfo pi : runningAppProcesses) {
//Check pi.processName and do your stuff
//also check pi importance - check if process is in foreground or background
Tools.log("TimerBroadcastReceiver", "onReceive", pi.processName + " importance = "+pi.importance);
if(pi.processName.equalsIgnoreCase("MY_APP_PROCESS_NAME")){
if (pi.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
isApplicationInForeground = true;
}
}
}
Но, похоже, не имеет значения, является ли приложение передним или нет. Как я могу это сделать?
Ответы
Ответ 1
Но я хотел бы запустить уведомление с помощью notificationManager только в том случае, если приложение в настоящее время не видно, и показать alertDialog, если таймер заканчивается, когда приложение находится на переднем плане.
Используйте упорядоченную широковещательную рассылку с активностью, имеющей приемник с высоким приоритетом, если он находится на переднем плане, плюс приемник с подтверждением манифеста для случаев, когда он не находится на переднем плане.
Вот сообщение в блоге, излагающее эту технику.
UPDATE 2018-01-04. Описанный выше подход работает, но он включает в себя системные трансляции, что не является отличным выбором для большинства (однопроцессорных) приложений. Вместо этого может использоваться шина событий (LocalBroadcastManager
, greenrobot EventBus) с лучшей производительностью и безопасностью. См. это примерное приложение, которое использует LocalBroadcastManager
и это примерное приложение, которое использует greenrobot EventBus, оба из которых реализуют этот шаблон.
Ответ 2
Вы можете определить, видимо ли ваше приложение или нет:
Во всех ваших Activity
, установите:
@Override
protected void onResume() {
super.onResume();
myVisibilityManager.setIsVisible(true);
}
@Override
protected void onPause() {
myVisibilityManager.setIsVisible(false);
super.onPause();
}
(это может привести к тому, что вы определите суперкласс для всех своих действий, которые будут реализовывать это поведение)
Затем создайте VisibilityManager
(этот очень простой, вам может понадобиться нечто более продвинутое):
public class VisibilityManager {
private boolean mIsVisible = false;
public void setIsVisible(boolean visible) {
mIsVisible = visible;
}
public boolean getIsVisible() {
return mIsVisible;
}
}
И затем в потоке таймера, когда обратный отсчет достигнет нуля:
if (VisibilityManager.getIsVisible()) {
showAlertDialog();
}
else {
showNotification();
}
EDIT: но я даже предпочитаю подход CommonsWare, описанный здесь на этой странице. Это более элегантно.
Ответ 3
Я бы посоветовал вам использовать Service, а не активность в этом случае.
Служба запускается в фоновом режиме и не влияет на жизненный цикл активности, если она запущена правильно.
Важно помнить, что когда вы вернетесь к пользовательскому интерфейсу, служба должна явно вызвать поток пользовательского интерфейса, иначе вы получите ANR-ошибки, так как поток пользовательского интерфейса не является потокобезопасным.
Прочитайте этот документ, он поможет вам получить лучшее решение для того, что вы пытаетесь сделать!
Надеюсь, что это помогло
Ответ 4
Вот решение:
public static boolean uygulamaCalisiyormu(Context context)
{
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> islemler = activityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo uygulamaIslemi : islemler)
{
if (uygulamaIslemi.processName.equals(context.getPackageName()))
{
if (uygulamaIslemi.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE || uygulamaIslemi.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
{
return true;
}
}
}
return false;
}
...
if (uygulamaCalisiyormu(getApplicationContext()))
{
Log.d("asd","App Already Started");
}
else
{
Log.d("asd","App Started");
}
Ответ 5
если
getIntent()
возвращает null, ваша активность не находится на переднем плане.