การกำหนดแอ็พพลิเคชันเบื้องหน้าปัจจุบันจากงานพื้นหลังหรือบริการ


112

ฉันต้องการมีแอปพลิเคชั่นหนึ่งตัวที่ทำงานอยู่เบื้องหลังซึ่งจะรู้ว่าเมื่อใดที่มีแอปพลิเคชันในตัว (การส่งข้อความรายชื่อติดต่อ ฯลฯ ) กำลังทำงานอยู่

ดังนั้นคำถามของฉันคือ:

  1. ฉันควรเรียกใช้แอปพลิเคชันของฉันในพื้นหลังอย่างไร

  2. แอปพลิเคชันพื้นหลังของฉันจะรู้ได้อย่างไรว่าแอปพลิเคชันที่กำลังทำงานอยู่เบื้องหน้าคืออะไร

คำตอบจากผู้ที่มีประสบการณ์จะได้รับการชื่นชมอย่างมาก


ฉันไม่คิดว่าคุณได้ให้คำอธิบายที่เพียงพอเกี่ยวกับสิ่งที่คุณกำลังพยายามทำ สิ่งที่แอพลิเคชันพื้นหลังของคุณพยายามที่จะทำคืออะไร? มันควรจะโต้ตอบกับผู้ใช้ได้ในทางใด? ทำไมคุณต้องรู้ว่าแอปเบื้องหน้าปัจจุบันคืออะไร? ฯลฯ
Charles Duffy


1
สำหรับการตรวจจับแอปเบื้องหน้าคุณสามารถใช้github.com/ricvalerio/foregroundappchecker
rvalerio

คำตอบ:


104

เกี่ยวกับ "2. แอปพลิเคชันพื้นหลังของฉันจะรู้ได้อย่างไรว่าแอปพลิเคชันกำลังทำงานอยู่เบื้องหน้าคืออะไร"

อย่าใช้getRunningAppProcesses()วิธีนี้เนื่องจากจะส่งคืนขยะระบบทุกประเภทจากประสบการณ์ของฉันและคุณจะได้ผลลัพธ์หลายRunningAppProcessInfo.IMPORTANCE_FOREGROUNDอย่าง ใช้getRunningTasks()แทน

นี่คือรหัสที่ฉันใช้ในบริการของฉันเพื่อระบุแอปพลิเคชันเบื้องหน้าปัจจุบันซึ่งง่ายมาก:

ActivityManager am = (ActivityManager) AppService.this.getSystemService(ACTIVITY_SERVICE);
// The first in the list of RunningTasks is always the foreground task.
RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);

เพียงเท่านี้คุณก็สามารถเข้าถึงรายละเอียดของแอพ / กิจกรรมเบื้องหน้าได้อย่างง่ายดาย:

String foregroundTaskPackageName = foregroundTaskInfo .topActivity.getPackageName();
PackageManager pm = AppService.this.getPackageManager();
PackageInfo foregroundAppPackageInfo = pm.getPackageInfo(foregroundTaskPackageName, 0);
String foregroundTaskAppName = foregroundAppPackageInfo.applicationInfo.loadLabel(pm).toString();

สิ่งนี้ต้องได้รับอนุญาตเพิ่มเติมในกิจกรรมที่ใกล้เคียงที่สุดและทำงานได้อย่างสมบูรณ์

<uses-permission android:name="android.permission.GET_TASKS" />

1
ควรทำเครื่องหมายว่าเป็นคำตอบที่ถูกต้อง การอนุญาตที่จำเป็น: android.permission.GET_TASKS เป็นเพียงข้อเสียเล็กน้อยของวิธีการอื่น ๆ ที่สามารถหลีกเลี่ยงได้
brandall

3
แก้ไขด้านบน: หมายเหตุ: วิธีนี้มีไว้สำหรับการดีบักและนำเสนอส่วนติดต่อผู้ใช้การจัดการงานเท่านั้น <- เพิ่งพบว่าในเอกสาร Java ดังนั้นวิธีนี้อาจเปลี่ยนแปลงได้โดยไม่ต้องแจ้งให้ทราบในอนาคต
brandall

47
หมายเหตุ: getRunningTasks()เลิกใช้แล้วใน API 21 (Lollipop) - developer.android.com/reference/android/app/…
dtyler

@dtyler ตกลงแล้ว มีวิธีอื่นแทนหรือไม่? แม้ว่า Google จะไม่ต้องการให้แอปของบุคคลที่สามได้รับข้อมูลที่ละเอียดอ่อน แต่ฉันก็มีคีย์แพลตฟอร์มของอุปกรณ์ มีวิธีอื่นที่ทำเช่นเดียวกันหรือไม่หากฉันมีสิทธิ์ในระบบ?
Yeung

มีวิธีใช้ "API สถิติการใช้งาน" ที่เปิดตัวในวันที่ 21
KunalK

38

ฉันต้องหาวิธีแก้ปัญหาที่ถูกต้องด้วยวิธีที่ยากลำบาก โค้ดด้านล่างนี้เป็นส่วนหนึ่งของ cyanogenmod7 (แท็บเล็ต tweaks) และได้รับการทดสอบบน Android 2.3.3 / Gingerbread

วิธีการ:

  • getForegroundApp - ส่งคืนแอปพลิเคชันเบื้องหน้า
  • getActivityForApp - ส่งคืนกิจกรรมของแอพที่พบ
  • isStillActive - กำหนดว่าแอปที่พบก่อนหน้านี้ยังคงเป็นแอปที่ใช้งานอยู่หรือไม่
  • isRunningService - ฟังก์ชันตัวช่วยสำหรับ getForegroundApp

หวังว่าจะตอบปัญหานี้ได้ในทุกส่วนขยาย (:

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

1
ถ้าคุณไม่สนใจฉันถามทำไมคุณต้องใช้วิธีการเพื่อดูว่ากำลังเรียกใช้บริการยังคงใช้งานอยู่และรับกิจกรรมเพื่อรับแอปพลิเคชันเบื้องหน้าหรือไม่

2
ขออภัยมันใช้งานไม่ได้ บางแอพถูกกรองโดยไม่มีเหตุผลฉันคิดว่ามันเป็นตอนที่เรียกใช้บริการบางอย่าง ดังนั้น isRunningService จึงไล่พวกเขาออกไป
seb

15
ขออภัย getRunningTasks () เลิกใช้งานตั้งแต่ Android L (API 20) สำหรับ L วิธีนี้ไม่สามารถใช้ได้กับแอปพลิเคชันของบุคคลที่สามอีกต่อไป: การแนะนำล่าสุดที่เน้นเอกสารเป็นศูนย์กลางหมายความว่าสามารถรั่วไหลข้อมูลของบุคคลไปยังผู้โทรได้ สำหรับความเข้ากันได้แบบย้อนกลับจะยังคงส่งคืนข้อมูลชุดย่อยเล็ก ๆ : อย่างน้อยงานของผู้โทรเองและอาจเป็นงานอื่น ๆ เช่นบ้านที่รู้ว่าไม่มีความละเอียดอ่อน
Sam Lu

ไม่มีใครรู้ว่าแนวทางนี้ดีกว่าการทำง่ายๆmActivityManager.getRunningTasks(1).get(0).topActivityอย่างไร?
แซม

35

ลองใช้รหัสต่อไปนี้:

ActivityManager activityManager = (ActivityManager) newContext.getSystemService( Context.ACTIVITY_SERVICE );
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
for(RunningAppProcessInfo appProcess : appProcesses){
    if(appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
        Log.i("Foreground App", appProcess.processName);
    }
}

ชื่อกระบวนการคือชื่อแพ็กเกจของแอปที่ทำงานอยู่เบื้องหน้า เปรียบเทียบกับชื่อแพ็กเกจของแอปพลิเคชันของคุณ หากเหมือนกันแสดงว่าแอปพลิเคชันของคุณกำลังทำงานอยู่เบื้องหน้า

ฉันหวังว่านี้ตอบคำถามของคุณ.


7
ตั้งแต่ Android เวอร์ชัน L เป็นต้นไปนี่เป็นโซลูชันเดียวที่ใช้งานได้เนื่องจากวิธีการที่ใช้ในโซลูชันอื่นเลิกใช้แล้ว
androidGuy

4
อย่างไรก็ตามสิ่งนี้ใช้ไม่ได้ในกรณีที่แอปอยู่เบื้องหน้าและหน้าจอถูกล็อก
กฤษณ์

คำตอบที่ถูกต้องควรเลือก
A_rmas

1
ต้องได้รับอนุญาตเพิ่มเติมเช่นคำตอบที่ยอมรับหรือไม่?
wonsuc

1
นี่ไม่ถูกต้องนัก ชื่อของกระบวนการไม่เหมือนกับชื่อแพ็กเกจแอปที่เกี่ยวข้องเสมอไป
แซม

25

ตั้งแต่อมยิ้มเป็นต้นไปสิ่งนี้เปลี่ยนไป โปรดค้นหารหัสด้านล่างก่อนที่ผู้ใช้จะต้องไปที่การตั้งค่า -> ความปลอดภัย -> (เลื่อนลงไปที่สุดท้าย) แอปที่เข้าถึงการใช้งาน -> ให้สิทธิ์แก่แอปของเรา

private void printForegroundTask() {
    String currentApp = "NULL";
    if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE);
        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(TAG, "Current App in foreground is: " + currentApp);
}

1
ไม่สามารถตั้งค่าสถิติการใช้งานนี้โดยใช้โปรแกรมได้หรือไม่
rubmz

@rubmz คุณมีวิธีแก้ปัญหานี้หรือไม่?
VVB

1
ใน doogee ของฉันกับ android 5.1 ไม่มีตัวเลือก "ให้สิทธิ์กับแอปของเรา"
djdance

สิ่งนี้ไม่ได้ให้ผลลัพธ์ที่แม่นยำ 100% ... ถูกต้องเกือบตลอดเวลา
CamHart

1
การดำเนินการนี้จะไม่แสดงแอปสุดท้ายในเบื้องหน้า แต่อาจเป็น "ใช้" ครั้งสุดท้ายหากคุณออกจากกิจกรรมและไปที่แอปอื่นดึงเมนูตัวเรียกใช้งานจากด้านบนแล้วปล่อยคุณจะอยู่ในส่วน " ผิด "จนกว่าจะไปทำกิจกรรมอื่น ไม่สำคัญว่าคุณจะเลื่อนหน้าจอหรือไม่ แต่จะรายงานกิจกรรมที่ไม่ถูกต้องจนกว่าคุณจะเปิดขึ้นมาใหม่
Azurlake

9

สำหรับกรณีที่เราต้องตรวจสอบจากบริการ / background-thread ของเราเองว่าแอพของเราอยู่เบื้องหน้าหรือไม่ นี่คือวิธีที่ฉันใช้งานและมันก็ใช้ได้ดีสำหรับฉัน:

public class TestApplication extends Application implements Application.ActivityLifecycleCallbacks {

    public static WeakReference<Activity> foregroundActivityRef = null;

    @Override
    public void onActivityStarted(Activity activity) {
        foregroundActivityRef = new WeakReference<>(activity);
    }

    @Override
    public void onActivityStopped(Activity activity) {
        if (foregroundActivityRef != null && foregroundActivityRef.get() == activity) {
            foregroundActivityRef = null;
        }
    }

    // IMPLEMENT OTHER CALLBACK METHODS
}

ตอนนี้หากต้องการตรวจสอบจากชั้นเรียนอื่น ๆ ว่าแอปอยู่เบื้องหน้าหรือไม่เพียงโทร:

if(TestApplication.foregroundActivityRef!=null){
    // APP IS IN FOREGROUND!
    // We can also get the activity that is currently visible!
}

อัปเดต (ตามที่SHSชี้ให้เห็น):

อย่าลืมลงทะเบียนสำหรับการโทรกลับในonCreateวิธีการของคลาสแอปพลิเคชันของคุณ

@Override
public void onCreate() {
    ...
    registerActivityLifecycleCallbacks(this);
}

2
นั่นคือสิ่งที่ฉันมองหามาตั้งแต่สองชั่วโมงที่ผ่านมา ขอบคุณ! :)
waseefakhtar

1
เราต้องเรียก "registerActivityLifecycleCallbacks (this);" ภายในเมธอด Override "onCreate ()" ของคลาส Application (TestApplication) สิ่งนี้จะเริ่มต้นการโทรกลับในคลาสแอปพลิเคชันของเรา
SHS

@SarthakMittal หากอุปกรณ์เข้าสู่โหมดสแตนด์บายหรือเมื่อเราล็อคอุปกรณ์จะเรียกใช้ onActivityStopped () ขึ้นอยู่กับรหัสของคุณสิ่งนี้จะบ่งชี้ว่าแอปพลิเคชันอยู่ในพื้นหลัง แต่มันอยู่เบื้องหน้าจริงๆ
Ayaz Alifov

@AyazAlifov ถ้าโทรศัพท์อยู่ในโหมดสแตนด์บายหรือโทรศัพท์ถูกล็อคฉันจะไม่คิดว่ามันอยู่เบื้องหน้า แต่ก็ขึ้นอยู่กับความชอบอีกครั้ง
Sarthak Mittal

8

เพื่อตรวจสอบโปรแกรมเบื้องหน้าคุณสามารถใช้สำหรับการตรวจสอบแอปเบื้องหน้าคุณสามารถใช้https://github.com/ricvalerio/foregroundappchecker ใช้วิธีการที่แตกต่างกันขึ้นอยู่กับเวอร์ชัน Android ของอุปกรณ์

สำหรับบริการ repo ยังให้รหัสที่คุณต้องการสำหรับมัน โดยพื้นฐานแล้วให้ android studio สร้างบริการให้คุณจากนั้น onCreate เพิ่มข้อมูลโค้ดที่ใช้ appChecker คุณจะต้องขออนุญาตอย่างไรก็ตาม


สมบูรณ์แบบ !! ทดสอบบน Android 7
Pratik Tank

ขอบคุณมาก. นี่เป็นคำตอบเดียวที่ช่วยแก้ปัญหาที่เราพบด้วยการแจ้งเตือนแอพ เมื่อการแจ้งเตือนปรากฏขึ้นคำตอบอื่น ๆ ทั้งหมดจะให้ชื่อแพ็กเกจของแอปที่ส่งการแจ้งเตือนกลับมา LollipopDetector ของคุณแก้ปัญหานี้ได้ คำใบ้อย่างหนึ่ง: จาก API 29 MOVE_TO_FOREGROUND เลิกใช้งานแล้วใน UsageEvents.Event ดังนั้นตั้งแต่ Android Q เป็นต้นไปควรใช้ ACTIVITY_RESUMED แล้วมันจะทำงานอย่างมีเสน่ห์!
Jorn Rigter

8

เมื่อพิจารณาว่าgetRunningTasks()เลิกใช้แล้วและgetRunningAppProcesses()ไม่น่าเชื่อถือฉันจึงตัดสินใจรวม 2 วิธีที่กล่าวถึงใน StackOverflow:

   private boolean isAppInForeground(Context context)
    {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
        {
            ActivityManager am = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
            ActivityManager.RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0);
            String foregroundTaskPackageName = foregroundTaskInfo.topActivity.getPackageName();

            return foregroundTaskPackageName.toLowerCase().equals(context.getPackageName().toLowerCase());
        }
        else
        {
            ActivityManager.RunningAppProcessInfo appProcessInfo = new ActivityManager.RunningAppProcessInfo();
            ActivityManager.getMyMemoryState(appProcessInfo);
            if (appProcessInfo.importance == IMPORTANCE_FOREGROUND || appProcessInfo.importance == IMPORTANCE_VISIBLE)
            {
                return true;
            }

            KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
            // App is foreground, but screen is locked, so show notification
            return km.inKeyguardRestrictedInputMode();
        }
    }

4
คุณต้องพูดถึงเพื่อเพิ่มการอนุญาตที่เลิกใช้แล้ว <ใช้ - อนุญาต android: name = "android.permission.GET_TASKS" /> ในรายการมิฉะนั้นแอปจะหยุดทำงาน
RJFares

1
android.permission.GET_TASKS - ปัจจุบันเป็นสิ่งต้องห้ามใน Play Store
Duna


1

สิ่งนี้ได้ผลสำหรับฉัน แต่จะให้เฉพาะชื่อเมนูหลัก นั่นคือถ้าผู้ใช้เปิดการตั้งค่า -> บลูทู ธ -> หน้าจอชื่ออุปกรณ์ RunningAppProcessInfo เรียกว่าเป็นเพียงการตั้งค่า ไม่สามารถเจาะลึกเฟอร์เธอร์ได้

ActivityManager activityManager = (ActivityManager) context.getSystemService( Context.ACTIVITY_SERVICE );
                PackageManager pm = context.getPackageManager();
                List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
                for(RunningAppProcessInfo appProcess : appProcesses) {              
                    if(appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                        CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(appProcess.processName, PackageManager.GET_META_DATA));
                        Log.i("Foreground App", "package: " + appProcess.processName + " App: " + c.toString());
                    }               
                }

4
ฉันคิดว่าจะใช้ได้ก็ต่อเมื่อแอปของคุณทำงานอยู่เบื้องหน้า จะไม่รายงานอะไรเลยเมื่อมีแอพอื่นอยู่เบื้องหน้า
Alice Van Der Land

0

ทำสิ่งนี้:

int showLimit = 20;

/* Get all Tasks available (with limit set). */
ActivityManager mgr = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> allTasks = mgr.getRunningTasks(showLimit);
/* Loop through all tasks returned. */
for (ActivityManager.RunningTaskInfo aTask : allTasks) 
{                  
    Log.i("MyApp", "Task: " + aTask.baseActivity.getClassName()); 
    if (aTask.baseActivity.getClassName().equals("com.android.email.activity.MessageList")) 
        running=true;
}

Google อาจปฏิเสธแอปที่ใช้ ActivityManager.getRunningTasks () เอกสารระบุว่าเป็นเป้าหมายเพื่อการพัฒนาของศัตรูเท่านั้น: developer.android.com/reference/android/app/… ดูความคิดเห็น
เบื้องต้น

3
@ForceMagic - Google ไม่ได้ปฏิเสธแอปเพียงเพราะใช้API ที่ไม่น่าเชื่อถือ ยิ่งไปกว่านั้น Google ไม่ใช่ช่องทางการจัดจำหน่ายเดียวสำหรับแอปพลิเคชัน Android ที่กล่าวว่าเป็นสิ่งที่ควรทราบว่าข้อมูลจาก API นี้ไม่สามารถเชื่อถือได้
Chris Stratton

@ChrisStratton น่าสนใจ แต่คุณคิดถูกแม้ว่าจะไม่แนะนำให้ใช้เพื่อตรรกะหลัก แต่ก็ไม่ปฏิเสธแอป คุณอาจต้องการเตือน Sky Kelsey จากลิงก์ความคิดเห็น
ForceMagic

3
"getRunningTasks" ใช้งานได้กับ api 21 และอื่น ๆ ดังนั้นจึงเป็นความคิดที่ดีที่จะหาวิธีอื่นในการทำให้ LOLLIPOP ใช้งานได้ (ตัวฉันเองยังไม่ได้คิดสิ่งนี้ด้วยตัวเอง :()
amIT

0

ในอมยิ้มขึ้นไป:

เพิ่มใน mainfest:

<uses-permission android:name="android.permission.GET_TASKS" />

และทำสิ่งนี้:

if( mTaskId < 0 )
{
    List<AppTask> tasks = mActivityManager.getAppTasks(); 
    if( tasks.size() > 0 )
        mTaskId = tasks.get( 0 ).getTaskInfo().id;
}

4
เลิกใช้เป็นมาร์ชเมลโล่
jinkal

0

นี่คือวิธีตรวจสอบว่าแอปของฉันอยู่เบื้องหน้าหรือไม่ หมายเหตุฉันใช้AsyncTaskตามที่แนะนำโดยเอกสารอย่างเป็นทางการของAndroid

`

    private class CheckIfForeground extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... voids) {

        ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                Log.i("Foreground App", appProcess.processName);

                if (mContext.getPackageName().equalsIgnoreCase(appProcess.processName)) {
                    Log.i(Constants.TAG, "foreground true:" + appProcess.processName);
                    foreground = true;
                    // close_app();
                }
            }
        }
        Log.d(Constants.TAG, "foreground value:" + foreground);
        if (foreground) {
            foreground = false;
            close_app();
            Log.i(Constants.TAG, "Close App and start Activity:");

        } else {
            //if not foreground
            close_app();
            foreground = false;
            Log.i(Constants.TAG, "Close App");

        }

        return null;
    }
}

และดำเนินการ AsyncTask เช่นนี้ new CheckIfForeground().execute();


คุณมีลิงค์สำหรับสิ่งนี้ไหม
user1743524

0

ฉันรวมสองโซลูชันไว้ในวิธีเดียวและใช้ได้กับฉันสำหรับ API 24 และสำหรับ API 21 อื่น ๆ ที่ฉันไม่ได้ทดสอบ

รหัสใน Kotlin:

private fun isAppInForeground(context: Context): Boolean {
    val appProcessInfo = ActivityManager.RunningAppProcessInfo()
    ActivityManager.getMyMemoryState(appProcessInfo)
    if (appProcessInfo.importance == IMPORTANCE_FOREGROUND ||
            appProcessInfo.importance == IMPORTANCE_VISIBLE) {
        return true
    } else if (appProcessInfo.importance == IMPORTANCE_TOP_SLEEPING ||
            appProcessInfo.importance == IMPORTANCE_BACKGROUND) {
        return false
    }

    val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    val foregroundTaskInfo = am.getRunningTasks(1)[0]
    val foregroundTaskPackageName = foregroundTaskInfo.topActivity.packageName
    return foregroundTaskPackageName.toLowerCase() == context.packageName.toLowerCase()
}

และในรายการ

<!-- Check whether app in background or foreground -->
<uses-permission android:name="android.permission.GET_TASKS" />
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.