অ্যান্ড্রয়েড 5.1.1 এবং তার থেকেও উপরে - getRunningAppProcesses () কেবলমাত্র আমার অ্যাপ্লিকেশন প্যাকেজটি ফেরত দেয়


100

দেখে মনে হচ্ছে বর্তমান গুগল বর্তমান অগ্রভাগের অ্যাপ্লিকেশন প্যাকেজ পাওয়ার জন্য সমস্ত দরজা বন্ধ করে দিয়েছে।

ললিপপ আপডেটের পরে, যা নিহত হয়েছিল getRunningTasks(int maxNum)এবং এই উত্তরটির জন্য ধন্যবাদ , আমি এই কোডটি ললিপপের পর থেকে অগ্রভাগের অ্যাপ্লিকেশন প্যাকেজটি পেতে ব্যবহার করেছি:

final int PROCESS_STATE_TOP = 2;
RunningAppProcessInfo currentInfo = null;
Field field = null;
try {
    field = RunningAppProcessInfo.class.getDeclaredField("processState");
} catch (Exception ignored) { 
}
ActivityManager am = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> appList = am.getRunningAppProcesses();
for (RunningAppProcessInfo app : appList) {
    if (app.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
        app.importanceReasonCode == 0 ) {
        Integer state = null;
        try {
            state = field.getInt( app );
        } catch (Exception ignored) {
        }
        if (state != null && state == PROCESS_STATE_TOP) {
            currentInfo = app;
            break;
        }
    }
}
return currentInfo;

অ্যান্ড্রয়েড 5.1.1 এবং তার getRunningAppProcesses()থেকেও উপরে (6.0 মার্শমেলো), মনে হয় এটিও মারা গেছে। এটি এখন আপনার নিজস্ব অ্যাপ্লিকেশন প্যাকেজের একটি তালিকা ফেরত দেয়।


ব্যবহারকারীর স্ট্যাটাসম্যানেজার

এখানে বর্ণিতUsageStatsManager হিসাবে আমরা নতুন এপিআই ব্যবহার করতে পারি তবে এটি সমস্ত অ্যাপ্লিকেশনগুলিতে কাজ করে না। কিছু সিস্টেম অ্যাপ্লিকেশন একই প্যাকেজটি ফিরিয়ে দেবে

com.google.android.googlequicksearchbox

অ্যাক্সেসিবিলিটি সার্ভিস (ডিসেম্বর 2017: গুগল ব্যবহারের জন্য নিষিদ্ধ হতে যাচ্ছে)

কিছু অ্যাপ্লিকেশন ব্যবহার করে AccessibilityService( এখানে যেমন দেখেছে ) তবে এর কিছু অসুবিধা রয়েছে।


বর্তমান চলমান অ্যাপ্লিকেশন প্যাকেজ পাওয়ার অন্য কোনও উপায় আছে কি?


4
ডু স্পিড বুস্টার কাজ মনে হচ্ছে। আমি নিশ্চিত না যে এটি ব্যবহারকারীর স্ট্যাটাসম্যানেজার ব্যবহার করে কিনা।
thecr0w

4
নোট করুন যে বেশ কয়েকটি বড় বিক্রেতারা তাদের ডিভাইস থেকে ইউজেজ স্ট্যাটস এপিআই-এ অ্যাক্সেস দেয় এমন সিস্টেম ক্রিয়াকলাপ সরিয়ে ফেলেছে। এর অর্থ এই যে ডিভাইসগুলির অ্যাপসটি কখনই প্রয়োজনীয় অনুমতি অর্জন করতে পারে না can
কেভিন ক্রামউইদে

4
স্যামসুং তাদের মধ্যে অন্যতম। এটি বাজারের %০% এরও বেশি।
কেভিন ক্রামউইদে

4
এই সমস্যাটি সম্পর্কিত অ্যান্ড্রয়েড বাগ ট্র্যাকারের কাছ থেকে এখানে একটি টিকিট দেওয়া হয়েছে: Code.google.com/p/android-developer-preview/issues/…
ফ্লোরিয়ান বার্থ

4
যদি আমি psকোনও শেলের মধ্যে চলমান আউটপুটকে পার্স করি এবং নীতিটি হয় "fg"এবং /proc/[pid]/oom_adj_scoreসমান বিষয়বস্তু হয় 0তবে অ্যাপ্লিকেশনটি হ'ল অগ্রভাগ অ্যাপ্লিকেশন। দুর্ভাগ্যক্রমে, মনে /proc/[pid]/oom_adj_scoreহয় এটি আর অ্যান্ড্রয়েড 6.0 তে পঠনযোগ্য নয়। gist.github.com/jaredrummler/7d1498485e584c8a120e
জারেড রুম্মার

উত্তর:


93

অ্যান্ড্রয়েড ১.6 - অ্যান্ড্রয়েড .0.০ এ চলমান প্রক্রিয়াগুলির একটি তালিকা পেতে আপনি এই লাইব্রেরিটি ব্যবহার করতে পারেন আমি লিখেছি: https://github.com/jaredrummler/AndroidProcesses প্রক্রিয়া সম্পর্কিত তথ্য পেতে লাইব্রেরিটি পড়ে / প্রোক্ট করে।

গুগল অ্যান্ড্রয়েড নুগাটে / প্রোগের অ্যাক্সেসকে উল্লেখযোগ্যভাবে সীমাবদ্ধ করেছে। অ্যান্ড্রয়েড নুগাটে চলমান প্রক্রিয়াগুলির একটি তালিকা পেতে আপনাকে ব্যবহারের স্ট্যাটাসম্যানেজার ব্যবহার করতে হবে বা রুট অ্যাক্সেস করতে হবে।

পূর্ববর্তী বিকল্প সমাধানগুলির জন্য সম্পাদনা ইতিহাসকে ক্লিক করুন।


4
@ অ্যান্ড্রয়েড ডেভেলপার নং, আমি কেবল লিবসুপারসার ব্যবহার করেছি কারণ এটি শেল কমান্ড (নন-রুট বা মূল) চালানোর এবং আউটপুট পাওয়ার সহজ উপায় সরবরাহ করে। পর্যাপ্ত চাহিদা থাকলে আমি এটিকে পুনরায় লিখতে পারি।
জারেড রুম্মার

4
তার জন্য দুঃখিত। শুধু কৌতূহলী হচ্ছে। :(
অ্যান্ড্রয়েড বিকাশকারী

4
@ জ্যারেডআম্মার বর্তমানে আমি আমার অ্যাপ্লিকেশনে আপনার সমাধানটি প্রয়োগের প্রক্রিয়াধীন। আমি যতদূর বলতে পারি ঠিক কাজ করছে বলে মনে হচ্ছে
gc

4
@ অ্যান্ড্রয়েড ডেভেলপার, যদি আপনি এটি আলাদা বৈশিষ্ট্যের ভিত্তিতে বাছাই করতে চান তবে পদ্ধতিটি Processপ্রয়োগ করুন Comparableএবং ওভাররাইড করুন compareTo। তারপরে, আপনি যখন ব্যবহার Collections.sort(processesList)করবেন এটি আপনার নির্দিষ্ট করা আদেশটি ব্যবহার করবে।
শ্রীনী

4
@ ব্রুসওয়েইন আমার কাছে মনে হয় জ্যারেড এই লিঙ্কটি উল্লেখ করছে: https://source.android.com/devices/tech/security/selinux/index.html
এডুয়ার্ডো হার্জার

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

অগ্রভাগ টাস্ক পাওয়ার জন্য এই পদ্ধতিটি ব্যবহার করুন। আপনার একটি সিস্টেমের অনুমতি প্রয়োজন হবে "অ্যান্ড্রয়েড: get_usage_stats"

public static boolean needPermissionForBlocking(Context context){
    try {
        PackageManager packageManager = context.getPackageManager();
        ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
        AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, applicationInfo.uid, applicationInfo.packageName);
        return  (mode != AppOpsManager.MODE_ALLOWED);
    } catch (PackageManager.NameNotFoundException e) {
        return true;
    }
}

ব্যবহারকারী যদি ব্যবহারের অ্যাক্সেস সহ সেটিং -> সুরক্ষা-> অ্যাপে এটি সক্ষম করে থাকেন। এর পরে আপনি ফোরগ্রাউন্ড টাস্ক পাবেন। অনুরূপ প্রক্রিয়া চিটহ্যামোবাইল গুগল প্লে লিঙ্ক দ্বারা ক্লিন ম্যাটসর


ওপিতে এবং মন্তব্যগুলিতে নির্দেশিত হিসাবে, ব্যবহারের বড় আকার রয়েছে UsageStatsManager। স্যামসুং অনুরোধগুলি সরিয়ে নিয়েছে এবং কোনও ব্যবহারকারীকে সিস্টেমের অনুমতি দেওয়ার জন্য এটি বেশ বিরক্তিকর।
জারেড রুম্মার ১১

আমি মোটো ই 2 ডিভাইসে পরীক্ষা করেছি। এটি ঠিকঠাক কাজ করছে এবং হ্যাঁ, আমাদের এই অনুমতিটি কার্যকর করতে হবে। আমরা সকলেই একই সমস্যার মুখোমুখি হই। আমাদের সকলেরই আরও ভাল পদ্ধতির প্রয়োজন। শুভকামনা বন্ধু
তরুন শর্মা

4
এই পদ্ধতিটি কমপক্ষে LG G3 এ কাজ করে না কারণ মেনু আইটেমটিতে "সেটিংস -> সুরক্ষা-> অ্যাপ্লিকেশন অ্যাক্সেস সহ অ্যাপ্লিকেশন" নেই
দিমিত্রি

4
এটি আমার প্রশ্নের উত্তর নয়। তদুপরি, এই উত্তরে কোনও নতুন তথ্য সরবরাহ করা হয়নি।
লাইয়ার ইলুজ

4
ভাল কাজ করছে তবে মার্শমেলোতে সঠিকভাবে নয়। যদি বিজ্ঞপ্তি আসে তবে বর্তমান চলমান প্রক্রিয়াটি প্যাকেজ বিজ্ঞপ্তি প্রাপ্ত হবে। প্রকৃতপক্ষে অ্যাপ্লিকেশনটি অগ্রভাগ বা ব্যাকগ্রাউন্ডে চলছে না :( সমাধানের প্রয়োজন
ওয়ান্ডারসফটওয়্যারস

6

কটাক্ষপাত https://github.com/ricvalerio/foregroundappchecker , এটা হতে পারে আপনার যা প্রয়োজন। নমুনা কোড সরবরাহ করে এবং ক্রস সংস্করণ অগ্রভাগ সনাক্তকারী প্রয়োগ করার ব্যথা সরিয়ে দেয়।

এখানে দুটি নমুনা দেওয়া হল:

AppChecker appChecker = new AppChecker();
String packageName = appChecker.getForegroundApp();

বা নিয়মিত পরীক্ষা করুন:

AppChecker appChecker = new AppChecker();
appChecker
    .when("com.other.app", new AppChecker.Listener() {
        @Override
        public void onForeground(String packageName) {
            // do something
        }
    )
    .when("com.my.app", new AppChecker.Listener() {
        @Override
        public void onForeground(String packageName) {
            // do something
        }
    )
    .other(new AppChecker.Listener() {
        @Override
        public void onForeground(String packageName) {
            // do something
        }
    )
    .timeout(1000)
    .start(this);

4
ধন্যবাদ তবে কিছুই এখানে নতুন নয়। তিনি সবেমাত্র ইউজেজ স্ট্যাটস ম্যানেজার এপিআই মুড়েছিলেন যা ওপিতে উল্লেখ করা হয়েছে। ব্যবহারকারীর অ্যান্ড্রয়েড 5.1.1 থেকে অন্যান্য পদ্ধতি হিসাবে অ্যাক্সেস সক্ষম করতে হবে
লায়ার ইলুজ

@ জুরমি আপনি প্রয়োজনীয় অনুমতিগুলির জন্য অনুরোধ করেছিলেন?
rvalerio

4

গুগল কেবল সিস্টেম অ্যাপগুলির জন্য এই কার্যকারিতা সীমাবদ্ধ করে। বাগের টিকিটে যেমন রিপোর্ট করা হয়েছে , সেখানে প্রবেশের জন্য আপনাকে REAL_GET_TASKS অনুমতি প্রয়োজন ।

অ্যাপ্লিকেশনগুলির অবশ্যই এখন ... অনুমতি থাকতে হবে all সমস্ত অ্যাপ্লিকেশনগুলির প্রক্রিয়া সম্পর্কিত তথ্য পেতে সক্ষম হতে REAL_GET_TASKS। অ্যাপ্লিকেশনটির অনুমতি না থাকলে কেবল কলিং অ্যাপ্লিকেশনটির প্রক্রিয়া সম্পর্কিত তথ্যই ফিরে আসবে। প্রাইভেলিজ অ্যাপ্লিকেশনগুলিতে অস্থায়ীভাবে সমস্ত অ্যাপ্লিকেশনগুলির জন্য প্রসেসের তথ্য পেতে সক্ষম হবে যদি তাদের কাছে নতুন অনুমতি না থাকলেও তারা হ'ল ... অনুমতি.GET_TASKS এছাড়াও, কেবলমাত্র সিস্টেম অ্যাপ্লিকেশনগুলি REAL_GET_TASKS অনুমতি অর্জন করতে পারে।


আমি দেখেছি অ্যাপলকটি এখনও 5.1.1 এ কাজ করছে, একবার অ্যাপটিতে সুরক্ষার অনুমতি পেয়ে -> "অ্যাপ্লিকেশন ব্যবহারের অ্যাপস" ... এটি কিছুটা আশ্চর্যজনক
mahesh ren

"সুরক্ষা স্তরের স্বাক্ষর, অধিকারযুক্ত বা স্বাক্ষরঅরসিস্টেম সহ অনুমতিগুলি কেবলমাত্র সিস্টেম অ্যাপ্লিকেশনগুলিতে মঞ্জুরিপ্রাপ্ত হয় an কোনও অ্যাপ যদি নিয়মিত নন-সিস্টেম অ্যাপ হয় তবে এটি কখনই এই অনুমতিগুলি ব্যবহার করতে সক্ষম হবে না" "অ্যান্ড্রয়েড স্টুডিও বলুন .. গুগলকে "সিস্টেম অ্যাপ" হিসাবে গ্রহণ করা হবে।
জার্মি

2

আমি যেটি কল্পনা করি তার জন্য কেবলমাত্র একটি সম্ভাব্য অপটিমাইজেশন ছুঁড়ে ফেলা হচ্ছে অ্যান্ড্রয়েড এম-এ সর্বাধিক সর্বাধিক অ্যাপ্লিকেশন সনাক্ত করার জন্য কোডের একটি ভারী কপি-পেস্ট করা বিট is

এই

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
    UsageStatsManager usm = (UsageStatsManager)this.getSystemService("usagestats");
    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();
        }
    }
}

এটি সহজ করা যেতে পারে

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
    UsageStatsManager usm = (UsageStatsManager) context.getSystemService(
        Context.USAGE_STATS_SERVICE);
    long time = System.currentTimeMillis();
    List<UsageStats> appStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
            time - 1000 * 1000, time);
    if (appStatsList != null && !appStatsList.isEmpty()) {
        currentApp = Collections.max(appStatsList, (o1, o2) ->
            Long.compare(o1.getLastTimeUsed(), o2.getLastTimeUsed())).getPackageName();
    }
}

আমি এই কোডটি 2 সেকেন্ডের লুপে নিজেকে ব্যবহার করে দেখতে পেয়েছি এবং অবাক হয়েছি কেন আমি যখন একটি জটিল সমাধান O (n * লগ (এন)) ব্যবহার করছিলাম তখন যখন কালেকশন.ম্যাক্সে আরও সহজ সমাধান পাওয়া যায় যা ও (এন) )।


0
public class AccessibilityDetectingService extends AccessibilityService {

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

    //Configure these here for compatibility with API 13 and below.

    AccessibilityServiceInfo config = new AccessibilityServiceInfo();
    config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
    config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;

    if (Build.VERSION.SDK_INT >= 16)
        //Just in case this helps
        config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;

    setServiceInfo(config);
}

@Override
public void onAccessibilityEvent(final AccessibilityEvent event) {
        if (event == null ) {
            return;
        } else if(event.getPackageName() == null && event.getClassName() == null){
            return;
        }

            if (activityInfo != null){

                Log.d("CurrentActivity", componentName.flattenToShortString());
        }

}

private ActivityInfo tryGetActivity(ComponentName componentName) {
    try {
        return getPackageManager().getActivityInfo(componentName, 0);
    } catch (PackageManager.NameNotFoundException e) {
        return null;
    }
}
@Override
public void onInterrupt() {
}                
}
}//`enter code here`uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
<uses-permission android:name="android.permission.GET_TASKS" />

তারপরে সেই পরিষেবাটিতে আপনার ডিভাইস সেটিং-> অ্যাক্সেসযোগ্যতা-> অ্যাপ্লিকেশনটিতে পরিষেবা এবং অ্যাপ্লিকেশন অ্যাক্সেসযোগ্যতা চালু করুন।


এটি ইতিমধ্যে প্রশ্নে আচ্ছাদিত এবং আপনি স্ট্যাকওভারফ্লোতে কোডটি মূল উত্স থেকে অনুলিপি করেছেন।
স্যাম

-2

পদ্ধতির getRunningServices()পরিবর্তে ব্যবহার করার চেষ্টা করুন getRunningAppProcesses()

 ActivityManager mActivityManager = (ActivityManager) getSy stemService(Context.ACTIVITY_SERVICE);

 List<ActivityManager.RunningServiceInfo> appProcessInfoList = mActivityManager.getRunningServices(Integer.MAX_VALUE);

4
স্ট্যাক ওভারফ্লোতে স্বাগতম! অগ্রণী অ্যাপ্লিকেশন কোনও পরিষেবা চালাচ্ছে না বলে এটি কাজ করবে বলে আমি মনে করি না।
স্যাম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.