41

I tried to develop such an app, in the sense I want to lock all the applications in my device with a password whatever I want. But I didn't find any piece of code for the solution. So I developed one by myself and unfortunately it didn't succeed. I found many solutions for locking android devices but, didn't find one for locking an app. Will be glad if you suggest a solution.

Cœur
  • 37,241
  • 25
  • 195
  • 267
thampi joseph
  • 700
  • 1
  • 8
  • 20
  • 2
    Do you want to lock an application at the time of accessing. If yes then i will help you bcz i have developed an application in which user will able to lock (any or all) installed application in the device. – Amit Gupta Nov 08 '13 at 05:25
  • @AmitGupta I am also facing same problem .I want to lock an application at the time of accessing..Can help me :) – Shakeeb Ayaz Nov 08 '13 at 05:33
  • Hi Amit.. I do want the same. Want to lock at the time of accessing the app. :) – thampi joseph Nov 08 '13 at 05:39
  • @AmitGupta i have tried ur code it looks fine but whenever i m trying to open any app then my app using service is not detecting app package name of that app – nida Jan 16 '15 at 06:18

2 Answers2

57

I used a background service to check which application is in the foreground (which means that application is being used by the user). Then I check to see whether I need to lock the application or not.

To find the list of all installed applications (excluding system applications):

PackageManager packageManager = getPackageManager();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);

List<ResolveInfo> appList = packageManager.queryIntentActivities(mainIntent, 0);
Collections.sort(appList, new ResolveInfo.DisplayNameComparator(packageManager));
List<PackageInfo> packs = packageManager.getInstalledPackages(0);
for (int i = 0; i < packs.size(); i++) {
    PackageInfo p = packs.get(i);
    ApplicationInfo a = p.applicationInfo;
    // skip system apps if they shall not be included
    if ((a.flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
        continue;
    }
    appList.add(p.packageName);
}

To find the current foreground application:

ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> RunningTask = mActivityManager.getRunningTasks(1);
ActivityManager.RunningTaskInfo ar = RunningTask.get(0);
activityOnTop=ar.topActivity.getClassName();

Here the class-name provides the package name of the application. I suggest that you use the package name to identify any application so we know that the package name is always unique.

Now, the functionality to lock the application:

To find which application is running in the foreground and want to lock it, we just have to start another activity which has an EditText for password and OK and Cancel button.

Intent lockIntent = new Intent(mContext, LockScreen.class);
lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(lockIntent);

On click of OK, if the password is correct then simply finish the LockScreen activity. If the password is incorrect then simply use the code below, which closes the application and shows the home screen of the device:

Intent startHomescreen = new Intent(Intent.ACTION_MAIN);
startHomescreen.addCategory(Intent.CATEGORY_HOME);
startHomescreen.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(startHomescreen);

The same code is also used on the cancel button.

Scott Smith
  • 3,900
  • 2
  • 31
  • 63
Amit Gupta
  • 1,067
  • 13
  • 26
  • **@Shakeeb Shaheen** and **thampi joseph** if you have any query related to this post feel free to ask... – Amit Gupta Nov 08 '13 at 06:48
  • Hey wait.. I want to block the system app as well as the app running in backround also. Can you help me in that too?? :) – thampi joseph Nov 08 '13 at 07:18
  • In the sense, applications like watsapp and Google map are always running in background. I want to block that too :) – thampi joseph Nov 08 '13 at 07:31
  • 2
    yes you can do this just remove this code if((a.flags & ApplicationInfo.FLAG_SYSTEM) == 1) { continue; } and u will get a list of all installed application either it is system app or third party application. – Amit Gupta Nov 08 '13 at 08:02
  • It helped me alot but need one more help how to start the same application if password is true – Bhavika Jan 30 '14 at 07:28
  • @AmitGupta you are awesome and your answer also. thnx – M D Feb 28 '14 at 13:12
  • This was a clever way to get the thing done. I was earlier trying to kill the process related to package name, but it got restarted every time. Kudos! – Parvaz Bhaskar Jul 10 '14 at 09:10
  • 3
    It works. But I have a problem. If user enters correct password, the locked app is on foreground again, and the service locks the app again. How to allow locked app on foreground if user enters correct password? – Phuc Tran Nov 16 '14 at 16:24
  • I have a question: In the first code snippet; where does the object "apps" come from? You call apps.add(p.packageName); but that name isn't used at all up until that point. – Super Fighting Robot Nov 20 '14 at 22:55
  • @Bhavika did u find solution for your query how to start the same application if password is true – nida Jan 16 '15 at 04:42
  • @AmitGupta why i need service for that ? just to find that which app is going to be opened i m not getting service will do which type of work ? – nida Jan 16 '15 at 04:43
  • @MD CAN u tell me when i m trying to launch any app from home screen then my app should detect those app package name right now its only detecting my own app package name – nida Jan 16 '15 at 06:16
  • Intent lockIntent = new Intent(mContext, LockScreen.class); lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(lockIntent); this code is not opening new activity if package name matches and even not coming inside if conditioon while package name is correct – nida Jan 16 '15 at 08:30
  • @AmitGupta can u pls help me i have started service but when i close my app and trying to access any other app my service is not showing any logcat about current accessed app package name – Erum Jan 17 '15 at 11:54
  • @nida yes i used background service to check Which app is in foreground and if we need to apply lock on that app that code also written in that service – Amit Gupta Jan 18 '15 at 15:18
  • @Erum Hannan yes we need to apply lock code in this service – Amit Gupta Jan 18 '15 at 15:20
  • How can i lock the app after the application is closed ( or exit ) and for a specific time. means if i use an application for 10 mins i want to block that application for 20 mins after exit. – Gaurav Manral Jan 28 '15 at 14:51
  • 1
    `mActivityManager.getRunningTasks` is deprecated as of Lollipop. From the official documentation: _This method was deprecated in API level 21. As of LOLLIPOP, this method is no longer available to third party applications: the introduction of document-centric recents means it can leak personal information to the caller. For backwards compatibility, it will still return a small subset of its data: at least the caller's own tasks (though see getAppTasks() for the correct supported way to retrieve that information), and possibly some other tasks such as home that are known to not be sensitive._ – Sudara Jul 09 '15 at 15:35
  • @GauravManral, did you find how to lock app for specific time? – user3806649 Sep 09 '15 at 14:49
  • I using this on App Laucher it always shows AppLaucher name on top whenever i am opening a new app its shows only applauncher package how can i resolve this @AmitGupta – Sunil Chaudhary Jan 06 '16 at 06:58
  • Hi sunil i am not getting your point clearly please attach any screen shot or explain in detail what problem you are facing – Amit Gupta Jan 07 '16 at 07:07
  • @ Phuc Tran:- need help in (It works. But I have a problem. If user enters correct password, the locked app is on foreground again, and the service locks the app again. How to allow locked app on foreground if user enters correct password?). please share how to resolve that issue? – Vishnu Apr 04 '16 at 07:30
  • So many thanks to you @AmitGupta, you save my life, i have been research for 3 days about this. Thanks. – Khang Tran Apr 04 '16 at 16:09
  • @AmitGupta Your code works, but I have simple problem, I am making app locker, then how can I get notify when other app lunch and get the package name, Tried with background service but it just execute once and print my app's package name, any idea? help would be highly appreciate. – Smit.Satodia Jul 22 '16 at 12:22
  • @Smit.Satodia I used background servce too for my application but you also need to use timer inside the background service which will execute in every 2 seconds and you will check that which app is in forground, i also used the same concept – Amit Gupta Jul 26 '16 at 07:58
  • @AmitGupta Android 6.0.1. The code for getting foreground app shows the activity name including package name of the app from which it is called from (when that app is in foreground) but when any other app is opened, it shows the name of the launcher. So what could be the possible issue in this case. I understand that you've worked on it a long time ago. PS. Is there a better alternative or a solution to this. Cheers – 7geeky Aug 31 '16 at 07:00
  • 1
    @7geeky Sorry, i have worked on this long time ago and didn't try it for new version, so i can not give a good solution for this problem – Amit Gupta Aug 31 '16 at 11:27
  • @AmitGupta No worries, your answer lead me to a solution (posted below now). and thanks – 7geeky Aug 31 '16 at 11:47
  • Hi, I successfully the open lock activity when other application open which I need to ask password but when user enters correct password its show my app instead of the app for which I opened the activity. How to open lock screen and close it without open my app in background. Please help I am stuck here. – Rahul Vats Sep 01 '17 at 16:12
  • @RahulVats You have the package name of the activity you have locked, why won't you launch the same app using the package name when user enters the correct password. hope it works – Amit Gupta Sep 04 '17 at 09:35
  • @AmitGupta Hi Let me check will let you know if it works. – Rahul Vats Sep 04 '17 at 12:12
  • @PhucTran have you found any solution , how to launch the same app after successful password . because its open my lock app – Tejas Pandya Dec 18 '17 at 06:34
  • Are you checking foreground app in service continuously? i.e after every second?? – Tabish Jul 16 '18 at 09:38
  • Yes I was checking foreground app in service continuously. – Amit Gupta Jul 26 '18 at 06:00
  • something wrong with code: appList.add(p.packageName); ? – nobjta_9x_tq Dec 03 '18 at 10:49
  • Not Sure!, How you were able to get the Foreground running app used by the user, when the method you used will return only the list of tasks of your calling application – ABI Jan 29 '19 at 07:13
  • can you build an example application as a public repository so that it will be helpful – Tara Oct 22 '19 at 12:38
  • how i know time of the launch locked app? may bee have some listener laucnhed app? – Baskya Visuk Oct 03 '20 at 11:35
15

Looks like this is still a mystery as suggested by above mentioned comments.So I'm putting the code that helped me to solve this problem.

getForegroundApp

public String getForegroundApp() {
    String currentApp = "NULL";
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        UsageStatsManager usm = (UsageStatsManager) this.mContext.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.mContext.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> tasks = am.getRunningAppProcesses();
        currentApp = tasks.get(0).processName;
    }

    return currentApp;
}

Call getForegroundApp() and it will return a string which contains the name of the currentForegroundApp including the package name e.g. com.example.app

Now, to use this code, we need this line of code in Manifest file

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

and take user to Usage Data access Settings:

usageAccessSettingsPage

  public void usageAccessSettingsPage(){
    Intent intent = new Intent();
    intent.setAction(Settings.ACTION_USAGE_ACCESS_SETTINGS);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    Uri uri = Uri.fromParts("package", mContext.getPackageName(), null);
    intent.setData(uri);
    startActivity(intent);
}

or manually by finding in LockScreen and Security> Other security settings> Usage access data.

Now comes the part for blocking the app, this part is covered in Amit's answer very well. However, if someone is looking for a way to restrict user from using an app then a trick is to open home screen when a particular app is launched.

This could be done by calling the following method when the currentApp is equal to a blocked app

if(<NameOfBlockedApp>.equals currentApp){
     showHomeScreen();
   }

ShowHomeScreen

 public boolean showHomeScreen(){
    Intent startMain = new Intent(Intent.ACTION_MAIN);
    startMain.addCategory(Intent.CATEGORY_HOME);
    startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    mContext.startActivity(startMain);
    return true;
}
7geeky
  • 438
  • 1
  • 12
  • 26
  • Hi, I successfully the open lock activity when other application open which I need to ask password but when user enters correct password its show my app instead of the app for which I opened the activity. How to open lock screen and close it without open my app in background. Please help I am stuck here. – Rahul Vats Sep 01 '17 at 16:12
  • @RahulVats Ask a new question and link here – 7geeky Sep 03 '17 at 23:53
  • @RahulVats have you found any solution , how to launch the same app after successful password . because its open my lock app . – Tejas Pandya Dec 18 '17 at 06:35
  • 1
    on password match use below code Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage(package_name_to_start); startActivity(LaunchIntent); finish(); – Rahul Vats Dec 18 '17 at 11:08
  • Are you checking for the Foreground App in service continuously ? after every second `getForegroundApp();` is called? if YES, is there any way to only call the method when a new app is launched to save battery? – Tabish Jul 16 '18 at 09:40
  • @Tabish Hi ! Did you get any answer to your question ? – Bhavit S. Sengar Sep 02 '18 at 15:47
  • @BhavitS.Sengar Unfortunately no! I am still going with this solution and checking for recent app in a loop – Tabish Sep 03 '18 at 13:44
  • @BhavitS.Sengar ^ – 7geeky Sep 06 '18 at 04:56
  • @7geeky It's the exact same thing – Tabish Sep 06 '18 at 05:35
  • @Tabish Why can't we do one thing ! We should register for the broadcasts for phone lock and unlock. When user locks the phone, we should stop the service, so that it doesn't consume the battery, at least when user is not using the phone. And whenever he unlocks the phone, we'll start the service again. Correct me if I'm wrong somewhere, or if it's not feasible. – Bhavit S. Sengar Sep 06 '18 at 06:39
  • @BhavitS.Sengar yes actually i've implemented this also ... when device is in sleep mode I'm killing the service and starting it only if device is awake – Tabish Sep 06 '18 at 09:37
  • @Tabish Can you please tell me how do you kill and restart the service when a device in sleep mode? I'm new with Android programming and couldn't find any way to do this? – AFT Jul 02 '19 at 02:46