开发者

How to know if my android app is visible?

开发者 https://www.devze.com 2023-03-23 02:19 出处:网络
I have a timer that start a notification when it ends. But I would like to fire a notification using notificationManager only if the app is not currently visible, and to show an alertDialog if the tim

I have a timer that start a notification when it ends. But I would like to fire a notification using notificationManager only if the app is not currently visible, and to show an alertDialog if the timer ends while the app is in foreground.

I've already tried with this :

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;
        }
    }
}

But it seems that it doesn't matter if the app is foreground or not. How can I do this?


But I would like to fire a notification using notificationManager only if the app is not currently visible, and to show an alertDialog if the timer ends while the app is in foreground.

Use an ordered broadcast, with the activity having a high-priority receiver if it is in the foreground, plus a manifest-registered receiver for the cases when it is not in the foreground.

Here is a blog post outlining this technique.

UPDATE 2018-01-04: The approach described above works, but it involves system broadcasts, which is not a great choice for most (single-process) apps. An event bus (LocalBroadcastManager, greenrobot's EventBus) can be used instead, with better performance and security. See this sample app that uses LocalBroadcastManager and this sample app that uses greenrobot's EventBus, both of which implement this pattern.


You can detect whether your app is visible or not the following way:

In all your your Activity, set:

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

    myVisibilityManager.setIsVisible(true);
}

@Override
protected void onPause() {
    myVisibilityManager.setIsVisible(false);

    super.onPause();
}

(this may lead you to define a superclass to all your activities that would implement this behaviour)

Then create a VisibilityManager (this one is very basic, you may need something more advanced):

public class VisibilityManager {
    private boolean mIsVisible = false;

    public void setIsVisible(boolean visible) { 
         mIsVisible = visible; 
    }

    public boolean getIsVisible() {
         return mIsVisible;
    }
}

And then, in your timer thread, when the countdown reached zero:

if (VisibilityManager.getIsVisible()) {
    showAlertDialog();
}
else {
    showNotification();
}

EDIT: but I even prefer the CommonsWare's approach described here in this page. It is more elegant.


I would advise you use a Service rather than an activity in this case.

A service runs in the background and is not affected by the activity lifecycle if it is started correctly.

One important thing to remember is that when you go back to the UI, the service must explicitly call the UI thread, otherwise you will get ANR errors, as the UI thread is not threadsafe.

Please read through that document, it should help you get a better solution for what you're trying to do!

Hope this helped


Here is the solution:

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");
}

EDIT: If you want to check specific activity (class) use this;

  if (uygulamaIslemi.processName.equals("com.TRSoft.timetab:PIN"))
            {
                if (uygulamaIslemi.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE || uygulamaIslemi.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) // Lanet olasıca şey Visible ile Foreground arasındaki fark ne oç illaha ya da yı kullanarak olduğunu keşfetmem mi lazım!
                {
                    return true;
                }
            }

And at your Manifest File:

 <activity android:name=".PINSayfasi"
            android:process=":PIN"></activity>

So the main logic is opening and reading process.

0

精彩评论

暂无评论...
验证码 换一张
取 消