40

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.

4
  • 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. Commented Nov 8, 2013 at 5:25
  • @AmitGupta I am also facing same problem .I want to lock an application at the time of accessing..Can help me :) Commented Nov 8, 2013 at 5:33
  • Hi Amit.. I do want the same. Want to lock at the time of accessing the app. :) Commented Nov 8, 2013 at 5: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 Commented Jan 16, 2015 at 6:18

2 Answers 2

58

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.

Sign up to request clarification or add additional context in comments.

38 Comments

@Shakeeb Shaheen and thampi joseph if you have any query related to this post feel free to ask...
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.
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?
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.
@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
|
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;
}

12 Comments

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.
@RahulVats Ask a new question and link here
@RahulVats have you found any solution , how to launch the same app after successful password . because its open my lock app .
on password match use below code Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage(package_name_to_start); startActivity(LaunchIntent); finish();
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?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.