How to programmatically set a lock or pin for an app
Asked Answered
P

4

18

So right now I am trying to develop an Android App for my young children. I want to set a pin or passwords on selected applications for a particular amount of time to prevent them from opening the app. For example, let's say that my daughter wants to play angry birds for some time on my phone while I am doing work. I will select my important apps like messaging, gmail, etc and put a pin or password on it for 30 minutes while she plays angry birds. After 30 minutes, I get my phone from my daughter and I can open the app without a pin because the time limit expired.

I have done a ton of research on this, but I haven't been able to find an implementation for my particular case.

How do android "app lock" applications work?

I know that app lock has a similar kind of structure of what I want to do. I just to place a time limit for the lock.

https://play.google.com/store/apps/details?id=com.domobile.applock&hl=en

I am staying away from killing activities/ applications with ActivityManager etc. I really just want a clean lock screen over a selected app for a particular amount of time.

I have a CountdownTimer to count down the timer for a time I set. How would I modify this code to block certain applications for a chosen amount of time if I had all the packagename?

    start_timer.setOnClickListener(new View.OnClickListener() {


        @Override
        public void onClick(View view) {

            new AlertDialog.Builder( MainActivity.this )
                    .setMessage( "Are you sure you want to block the selected apps for the set amount of time?" )
                    .setPositiveButton( "Yeah man!", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            Log.d( "AlertDialog", "Positive" );

                            hourint = Integer.valueOf(number_text.getText().toString());

                            minuteint = Integer.valueOf(minute_text.getText().toString());

                            secondint = Integer.valueOf(second_text.getText().toString());

                            Log.i("YourActivity", "Hours: " + hourint);

                            Log.i("YourActivity", "Minutes: " + minuteint);

                            Log.i("YourActivity", "Seconds: " + secondint);

                            totalTimeCountInMilliseconds = ((hourint*60*60) +(minuteint*60) + (secondint)) * 1000;      // time count
                            timeBlinkInMilliseconds = 30*1000;

                            countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 500) {
                                // 500 means, onTick function will be called at every 500 milliseconds

                                @Override
                                public void onTick(long leftTimeInMilliseconds) {
                                    Context context = MainActivity.this;





                                    long seconds = leftTimeInMilliseconds / 1000;
                                    mSeekArc.setVisibility(View.INVISIBLE);
                                    start_timer.setVisibility(View.INVISIBLE);
                                    block_button1.setVisibility(View.INVISIBLE);



                                    if ( leftTimeInMilliseconds < timeBlinkInMilliseconds ) {
                                        // textViewShowTime.setTextAppearance(getApplicationContext(), R.style.blinkText);
                                        // change the style of the textview .. giving a red alert style

                                        if ( blink ) {
                                            number_text.setVisibility(View.VISIBLE);
                                            minute_text.setVisibility(View.VISIBLE);
                                            second_text.setVisibility(View.VISIBLE);


                                            // if blink is true, textview will be visible
                                        } else {
                                            number_text.setVisibility(View.INVISIBLE);
                                            minute_text.setVisibility(View.INVISIBLE);
                                            second_text.setVisibility(View.INVISIBLE);


                                        }

                                        blink = !blink;         // toggle the value of blink
                                    }

                                    second_text.setText(String.format("%02d", seconds % 60));
                                    minute_text.setText(String.format("%02d", (seconds / 60) % 60));
                                    number_text.setText(String.format("%02d", seconds / 3600));                     // format the textview to show the easily readable format
                                }


                                @Override
                                public void onFinish() {
                                    // this function will be called when the timecount is finished
                                    //textViewShowTime.setText("Time up!");
                                    number_text.setVisibility(View.VISIBLE);
                                    minute_text.setVisibility(View.VISIBLE);
                                    second_text.setVisibility(View.VISIBLE);
                                    mSeekArc.setVisibility(View.VISIBLE);
                                    start_timer.setVisibility(View.VISIBLE);
                                    block_button1.setVisibility(View.VISIBLE);


                                }

                            }.start();
                        }
                    })
                    .setNegativeButton("Nope!", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            Log.d("AlertDialog", "Negative");
                            dialog.cancel();
                        }
                    })
                    .show();

EDITED: http://pastebin.com/MHGFw7PK

Poteet answered 22/8, 2014 at 6:21 Comment(0)
L
17

Logic

  • You have to make and start a service when you want to block apps,
  • And In Service you have to check packagenames of the apps, so that you can decide which app to run and which to show a pin/password activity

Now Code Example:

  • To Start a service, code like this,

    startService(new Intent(this, SaveMyAppsService.class));
    
  • Now, Inside your service, check packages like this,

    public class SaveMyAppsService extends android.app.Service 
    {
    
        String CURRENT_PACKAGE_NAME = {your this app packagename};
        String lastAppPN = "";
        boolean noDelay = false;
        public static SaveMyAppsService instance;
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // TODO Auto-generated method stub
    
            scheduleMethod();
            CURRENT_PACKAGE_NAME = getApplicationContext().getPackageName();
            Log.e("Current PN", "" + CURRENT_PACKAGE_NAME);
    
            instance = this;
    
            return START_STICKY;
        }
    
        private void scheduleMethod() {
            // TODO Auto-generated method stub
    
            ScheduledExecutorService scheduler = Executors
                    .newSingleThreadScheduledExecutor();
            scheduler.scheduleAtFixedRate(new Runnable() {
    
                @Override
                public void run() {
                    // TODO Auto-generated method stub
    
                    // This method will check for the Running apps after every 100ms
                    if(30 minutes spent){
                         stop();
                    }else{
                       checkRunningApps();
                   }
                }
            }, 0, 100, TimeUnit.MILLISECONDS);
        }
    
        public void checkRunningApps() {
            ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> RunningTask = mActivityManager.getRunningTasks(1);
            ActivityManager.RunningTaskInfo ar = RunningTask.get(0);
            String activityOnTop = ar.topActivity.getPackageName();
            Log.e("activity on TOp", "" + activityOnTop);
    
            // Provide the packagename(s) of apps here, you want to show password activity
        if (activityOnTop.contains("whatsapp")  // you can make this check even better
                || activityOnTop.contains(CURRENT_PACKAGE_NAME)) {
                // Show Password Activity                
            } else {
                // DO nothing
            }
         }
    
        public static void stop() {
            if (instance != null) {
            instance.stopSelf();
            }
        }
    }   
    

Edit: (Get Top Package Name for Lollipop)

A very good answer is here.

Laboured answered 22/8, 2014 at 6:53 Comment(13)
I see. I guess since I need to store the selected packagenames in an array and add a for loop. I think I am starting to understand a little bit more now. But about the actual pin/password code I need to implement. Would I have to use DevicePolicyManager? developer.android.com/reference/android/app/admin/… Or in that case how would that be done?Poteet
You can, But however you can also use the Simple activity to show up the edittext and get password :)Laboured
:D awesome haha thx. Also by lastAppPN do you mean the last packagename or what do I use that for?Poteet
I have pasted my project's code, so it was my logic. you can leave that.Laboured
Oh I see. Wait if you don't mind me asking, what was your last project? just curiousPoteet
Dang, I am unable to setContentView in the service classPoteet
Where are you adding setcontentview() in above code(pastebin code)?Laboured
I was trying to do in in an onCreate method I made, but that obviously that method isn't able to be used in a service class, so my approach is wrongPoteet
Iqbal! I finally managed to get it somewhat working. However, the problem is that I block my OWN app. How can I undo that? pastebin.com/BeJMWMXqPoteet
What is your default packagename of your app(Declared in top lines of Manifest)?? is It "com.spicycurryman.getdisciplined10.app.dev" ???Laboured
Ok, hmmm... What packagename are you getting in logcat when your app is in foreground?Laboured
Let us continue this discussion in chat.Poteet
getRunningTasks() is deprecated nowRemunerate
C
2
String lastAppPN = "";
public void checkRunningApps() {
    ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    String activityOnTop;
    if (Build.VERSION.SDK_INT > 20) {
        activityOnTop = mActivityManager.getRunningAppProcesses().get(0).processName;
    } else {
        List<ActivityManager.RunningTaskInfo> RunningTask = mActivityManager.getRunningTasks(1);
        ActivityManager.RunningTaskInfo ar = RunningTask.get(0);
        activityOnTop = ar.topActivity.getPackageName();
    }
    //Log.e("activity on TOp", "" + activityOnTop);

    // Provide the packagename(s) of apps here, you want to show password activity
    if (activityOnTop.contains("whatsapp")  // you can make this check even better
            || activityOnTop.contains(CURRENT_PACKAGE_NAME)) {
        if (!(lastAppPN.equals(activityOnTop))) {
            lastAppPN = activityOnTop;
            Log.e("Whatsapp", "started");
        }
    } else {
        if (lastAppPN.contains("whatsapp")) {
            if (!(activityOnTop.equals(lastAppPN))) {
                Log.e("Whatsapp", "stoped");
                lastAppPN = "";
            }
        }
        // DO nothing
    }
}
Confuse answered 3/8, 2016 at 10:18 Comment(0)
J
1

I have created small demo project. Hope this might be useful to someone Link to project

Juratory answered 8/4, 2020 at 6:41 Comment(0)
P
0

You can use a DialogAlertView also:

  1. Use shared preferences to keep the password in storage.
  2. If the user enabled password for the app, then show the alert in home page
  3. Ask for the password, confirm if it is equal to the saved password.
  4. If yes, dismiss alert view and if wrong, show alert view again
  5. Make sure alert view setCancellable() is false
  6. You can have your own design and animations in the view

I think it is easy to do. Nobody can crack the password also. Suppose if somebody uninstalls (or clear data) the app then they have to login or register again (which is more secure).

Tip - you can save the password in the cloud or anywhere you want.

Panek answered 4/1, 2021 at 9:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.