Muszę uzyskać nazwę dowolnej aplikacji Android, gdy zostanie otwarty i uruchomić okno hasła. Szukałem wszędzie, jak znaleźć nazwę aplikacji, którą użytkownik został otwarty, ale nie znalazłem jeszcze rozwiązania roboczego. Mam usługę, która działa na tle, ale zwraca nazwę mojej aplikacji lub nazwa ekranu głównego, bez względu na to, która aplikacja otwarta.

Oto mój kod usługi:

package com.example.applock

import android.app.ActivityManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.IBinder
import android.provider.Settings


class BackAppListenerService  : Service() {
    private var isRunning = false
    private var lastApp = ""

    override fun onCreate() {
        println(TAG + "Service onCreate")
        isRunning = true
        val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        println(TAG + "Service onStartCommand")

        //Creating new thread for my service
        //Always write your long running tasks in a separate thread, to avoid ANR
        Thread(Runnable { //Your logic that service will perform will be placed here
            //In this example we are just looping and waits for 1000 milliseconds in each loop.

            while (true) {
                try {
                    Thread.sleep(1000)
                } catch (e: Exception) {
                }

                val mActivityManager = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
                val mPackageName = mActivityManager.runningAppProcesses[0].processName
                println(mPackageName)
            }
        }).start()
        return START_STICKY
    }

    override fun onBind(arg0: Intent): IBinder? {
        println(TAG + "Service onBind")
        return null
    }

    override fun onDestroy() {
        isRunning = false
        println(TAG + "Service onDestroy")
    }

    companion object {
        private const val TAG = "HelloService"
    }
}
0
Samuel 4 październik 2020, 05:05

1 odpowiedź

Najlepsza odpowiedź

OK, więc zrozumiałem. Najpierw dodaj to do manifest.xml pod manifestem tagiem:

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

Następnie przejdź do apps permissions > Usage Stats Idź do swojej aplikacji i włączyć go. Możesz także wykonać popypienie, aby poprosić o użytkownik, aby to zrobić, gdy aplikacje ładuje.

Teraz, aby uzyskać aktualną aplikację na pierwszym planie:

fun getForegroundApp(): String {
    var currentApp = "NULL"
    // You can delete the if-else statement if you don't care about Android versions
    // lower than 5.0. Just keep the code that is inside the if and delete the one
    // inside the else statement.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        val usm = this.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
        val time = System.currentTimeMillis()
        val appList =
            usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1000, time)
        if (appList != null && appList.size > 0) {
            val mySortedMap: SortedMap<Long, UsageStats> =
                TreeMap<Long, UsageStats>()
            for (usageStats in appList) {
                mySortedMap.put(usageStats.lastTimeUsed, usageStats)
            }
            if (mySortedMap != null && !mySortedMap.isEmpty()) {
                currentApp = mySortedMap.get(mySortedMap.lastKey())!!.getPackageName()
            }
        }
    } else {
        val am = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val tasks = am.runningAppProcesses
        currentApp = tasks[0].processName
    }
    // Get only the app name name
    return currentApp.split(".").last()
}

Czasami nazwa aplikacji nie jest wyświetlana, na przykład aplikacja "Gmail" ma nazwę "GM", gdy go przetestowałem. Nazwa ekranu głównego zmienia się również z urządzenia do urządzenia

Logika nazywa go co kilka milisekund, aby uzyskać aktualną aplikację na pierwszym planie, jest prosta:

override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
    //Creating new thread for my service
    //Always write your long running tasks in a separate thread, to avoid ANR
    Thread(Runnable {
        while (true) {
            try {
                Thread.sleep(10)
            } catch (e: Exception) {
            }
            val currentApp = getForegroundApp()
            if (currentApp != lastApp) {
                println(currentApp)
                // New app on front
                lastApp = currentApp
                println(currentApp)
                // Do whatever you wan
            }
        }
    }).start()
    return START_STICKY
}

I to wszystko.

0
Samuel 5 październik 2020, 19:08