How to disable virtual home button in any activity

2019-01-27 06:58发布

问题:

I need to disable 3 virtual buttons in any activity in my app. I disabled back button and multitask button somehow but I cannot dsable home button.

I tried onAttachedToWindow() style answers on stackoverflow but they didn't work for me.

I don't want to disable home button for entire app, I just want to disable it for a single activity window. Thanks for your helps!

回答1:

NOTE : I highly encourage you not to do this in your app, if you want to deploy it. This is only to show how we can do it.

Since Android 4 there is no effective method to Disable the home button.It needs little hack. I think your need is KIOSK mode in app. In general the idea is to detect when a new application is in foreground and restart your Activity immediately. The processes are Below..

At first create a class called KioskService that extends Service and add the following snippet :

 public class KioskService extends Service {

  private static final long INTERVAL = TimeUnit.SECONDS.toMillis(2); // periodic interval to check in seconds -> 2 seconds
  private static final String TAG = KioskService.class.getSimpleName();
  private static final String PREF_KIOSK_MODE = "pref_kiosk_mode";

  private Thread t = null;
  private Context ctx = null;
  private boolean running = false;

  @Override
  public void onDestroy() {
    Log.i(TAG, "Stopping service 'KioskService'");
    running =false;
    super.onDestroy();
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i(TAG, "Starting service 'KioskService'");
    running = true;
    ctx = this;

    // start a thread that periodically checks if your app is in the foreground
    t = new Thread(new Runnable() {
      @Override
      public void run() {
        do {
          handleKioskMode();
          try {
            Thread.sleep(INTERVAL);
          } catch (InterruptedException e) {
            Log.i(TAG, "Thread interrupted: 'KioskService'");
          }
        }while(running);
        stopSelf();
      }
    });

    t.start();
    return Service.START_NOT_STICKY;
  }

  private void handleKioskMode() {
    // is Kiosk Mode active? 
      if(isKioskModeActive()) {
        // is App in background?
      if(isInBackground()) {
        restoreApp(); // restore!
      }
    }
  }

  private boolean isInBackground() {
    ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);

    List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
    ComponentName componentInfo = taskInfo.get(0).topActivity;
    return (!ctx.getApplicationContext().getPackageName().equals(componentInfo.getPackageName()));
  }

  private void restoreApp() {
    // Restart activity
    Intent i = new Intent(ctx, MyActivity.class);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    ctx.startActivity(i);
  }

  public boolean isKioskModeActive(final Context context) {
    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
    return sp.getBoolean(PREF_KIOSK_MODE, false);
  }

  @Override
  public IBinder onBind(Intent intent) {
    return null;
  }
}

Add the following method in your AppContext class to start the service via application context creation.

@Override
public void onCreate() {
  super.onCreate();
  instance = this;
  registerKioskModeScreenOffReceiver();
  startKioskService();  // add this
}

private void startKioskService() { // ... and this method
  startService(new Intent(this, KioskService.class));
}

You AppContext class looks like this

  public class AppContext extends Application {

  private AppContext instance;
  private PowerManager.WakeLock wakeLock;
  private OnScreenOffReceiver onScreenOffReceiver;


  @Override
  public void onCreate() {
    super.onCreate();
    instance = this;
    registerKioskModeScreenOffReceiver();
  }

  private void registerKioskModeScreenOffReceiver() {
    // register screen off receiver
    final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
    onScreenOffReceiver = new OnScreenOffReceiver();
    registerReceiver(onScreenOffReceiver, filter);
  }

  public PowerManager.WakeLock getWakeLock() {
    if(wakeLock == null) {
      // lazy loading: first call, create wakeLock via PowerManager.
      PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
      wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "wakeup");
    }
    return wakeLock;
  }
}

Add the service declaration and the permission for retrieving the foreground process to the manifest:

<service android:name=".KioskService" android:exported="false"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
//Added permission Edit 1
<uses-permission android:name="android.permission.WAKE_LOCK" />

I've seen this all at one site but forgot the link, whatever I have is only contents and codes, so that I am posting all as an answer. As soon as I get the link, I will share that with you.



回答2:

If i am not wrong then, you want to disable home button or you can say keep your activity on front of every activity screen.

For this i suggest you to start your activity window with window manager screen. When you start your activity with window manager your home button activity goes to background. It means your activity can not close by presing home button.

So simply, use your activity as window manager activity. Many lock screen app also working on this way

sorry for code.I can not post code because i left android programming and now I am working with animation so you may have to do hard work for this.

But you can defeat home button and all other system button with window manager activity.

I have my incomplete lock screen app project. You have to make some changes and should remove unwanted java class file and adapter file.

Also i have develop new lock with 81 images on screen. Two unlock phone you have to set your selected images.

You can download my incomplete project from here.

I update link and know its works.