Android hide/unhide app icon programmatically

107,618

Solution 1

Hide app's icon using below code:

PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, com.apps.MainActivity.class); // activity which is first time open in manifiest file which is declare as <category android:name="android.intent.category.LAUNCHER" />
p.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

Here is how to bring back the app's icon.

PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, com.apps.MainActivity.class);
p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

Important Edit:

According to docs, as of Android Q (API 29) all app icons will be visible in the launcher no matter what unless:

As of Android Q, at least one of the app's activities or synthesized activities appears in the returned list unless the app satisfies at least one of the following conditions:

  • The app is a system app.
  • The app doesn't request any permissions.
  • The tag in the app's manifest doesn't contain any child elements that represent app components.

Additionally, the system hides synthesized activities for some or all apps in the following enterprise-related cases:

  • If the device is a fully managed device, no synthesized activities for any app appear in the returned list.
  • If the current user has a work profile, no synthesized activities for the user's work apps appear in the returned list.

Solution 2

Best Way To Hide Application Icon From Launcher You Can Use

<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>

In Your Manifest MainActivity

  <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
        </intent-filter>
    </activity>

also add uses-feature in Manifest Tag

<uses-feature
    android:name="android.software.leanback"
    android:required="true" />

Solution 3

To hide icon use this:

PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, com.apps.MainActivity.class); 
p.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

and to unhide icon:

PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, com.apps.MainActivity.class);
p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

IMPORTANT: It's somehow tricky if you need to do something with main activity in your app when it's hidden. you will face an ActivityNotFoundException. to make it work, you should unhide icon before doing anything to your main activity and hide it again after you are finished.
simple steps: 1-call received here
2-unhide icon
3-launch main activity
4-do your things on main activity
5-hide icon again

Solution 4

Download source code from here (Hide and Unhide the app icon in android programmatically)

MainActivity.java:

package com.deepshikha.hideappicon;

import android.Manifest;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    Button btn_hide;
    private static final ComponentName LAUNCHER_COMPONENT_NAME = new ComponentName(
            "com.deepshikha.hideappicon", "com.deepshikha.hideappicon.Launcher");

    public static int REQUEST_PERMISSIONS = 1;
    boolean boolean_permission;
    ProgressDialog progressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        fn_permission();
        listener();
    }

    private void init() {
        btn_hide = (Button) findViewById(R.id.btn_hide);
        progressDialog = new ProgressDialog(MainActivity.this);
        progressDialog.setTitle("Alert");
        progressDialog.setMessage("Please wait");


        if (isLauncherIconVisible()) {
            btn_hide.setText("Hide");
        } else {
            btn_hide.setText("Unhide");
        }


    }

    private void listener() {
        btn_hide.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_hide:

                progressDialog.show();
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        progressDialog.dismiss();
                        if (isLauncherIconVisible()) {
                            btn_hide.setText("Hide");
                        } else {
                            btn_hide.setText("Unhide");
                        }
                    }
                }, 10000);


                if (boolean_permission) {

                    if (isLauncherIconVisible()) {
                        fn_hideicon();
                    } else {
                        fn_unhide();
                    }
                } else {
                    Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();
                }
                break;

        }

    }

    private boolean isLauncherIconVisible() {
        int enabledSetting = getPackageManager().getComponentEnabledSetting(LAUNCHER_COMPONENT_NAME);
        return enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
    }

    private void fn_hideicon() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Important!");
        builder.setMessage("To launch the app again, dial phone number 1234567890");
        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                getPackageManager().setComponentEnabledSetting(LAUNCHER_COMPONENT_NAME,
                        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                        PackageManager.DONT_KILL_APP);
            }
        });
        builder.setIcon(android.R.drawable.ic_dialog_alert);
        builder.show();
    }

    private void fn_unhide() {
        PackageManager p = getPackageManager();
        ComponentName componentName = new ComponentName(this, com.deepshikha.hideappicon.MainActivity.class);
        p.setComponentEnabledSetting(LAUNCHER_COMPONENT_NAME, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
    }

    private void fn_permission() {
        if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.PROCESS_OUTGOING_CALLS) != PackageManager.PERMISSION_GRANTED) ||
                (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.PROCESS_OUTGOING_CALLS) != PackageManager.PERMISSION_GRANTED)) {

            if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.PROCESS_OUTGOING_CALLS))) {
            } else {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.PROCESS_OUTGOING_CALLS},
                        REQUEST_PERMISSIONS);

            }

            if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.PROCESS_OUTGOING_CALLS))) {
            } else {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.PROCESS_OUTGOING_CALLS},
                        REQUEST_PERMISSIONS);

            }
        } else {
            boolean_permission = true;


        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSIONS) {

            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                boolean_permission = true;


            } else {
                Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();

            }
        }
    }
}

LaunchAppReceiver.java:

package com.deepshikha.hideappicon;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;

/**
 * Created by deepshikha on 9/6/17.
 */

public class LaunchAppReceiver extends BroadcastReceiver {
    String LAUNCHER_NUMBER = "1234567890";
    private static final ComponentName LAUNCHER_COMPONENT_NAME = new ComponentName(
            "com.deepshikha.hideappicon", "com.deepshikha.hideappicon.Launcher");

    @Override
    public void onReceive(Context context, Intent intent) {
        String phoneNubmer = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
        if (LAUNCHER_NUMBER.equals(phoneNubmer)) {
            setResultData(null);

            if (isLauncherIconVisible(context)) {

            } else {
                Intent appIntent = new Intent(context, MainActivity.class);
                appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(appIntent);
            }


        }

    }

    private boolean isLauncherIconVisible(Context context) {
        int enabledSetting = context.getPackageManager().getComponentEnabledSetting(LAUNCHER_COMPONENT_NAME);
        return enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
    }

}

Thanks!

Solution 5

this is what I've found so far, unfortunately it's not an answer to the original question, just alternatives

  1. This is the first option, but if your apps require permission and is not useful anymore (at least in Android 10) as @CoronaPintu mentioned here https://stackoverflow.com/a/22754642/1712446 this method works but have many restrictions

    private void hideIcon(Context context, Class activityToHide) {
        PackageManager packageManager = getPackageManager();
        ComponentName componentName = new ComponentName(context, activityToHide);
        packageManager.setComponentEnabledSetting(
            componentName,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);
    }
    
  2. Using the same method above plus adb command, even is your app require permission this alternative works, but you must have access to devices and connect to a pc, then run this command

    to hide: $adb shell settings put global show_hidden_icon_apps_enabled 0

    to show: $adb shell settings put global show_hidden_icon_apps_enabled 1

Just in case, you cannot run this command from the app

  1. Another option is DevicePolicyManager

    private void hideIcon(Context context, Class activityToHide) {
        ComponentName componentName = new ComponentName(context, activityToHide);
            DevicePolicyManager devicePolicyManager = (DevicePolicyManager) getSystemService(getApplicationContext().DEVICE_POLICY_SERVICE);
            devicePolicyManager.setApplicationHidden(componentName, "your.package.name.here", true);
    }
    

This method works, but again we have some restrictions, you need to enable Device Owner Mode, you can find more info here

To enable this mode you must run this adb command

adb shell dpm set-device-owner my.package.name/.DevAdminReceiver

However you can this command from the app

Runtime.getRuntime().exec("dpm set-device-owner my.package.name/.DevAdminReceiver");    

But, if the phone already have set an account, this method going to failed with the next error:

java.lang.IllegalStateException: Not allowed to set the device owner because there are already several users on the device
Share:
107,618
PankajAndroid
Author by

PankajAndroid

Android Developer

Updated on March 25, 2020

Comments

  • PankajAndroid
    PankajAndroid over 4 years

    i had used below code for hide app icon programmatically

    try{
        PackageManager p = getPackageManager();
        p.setComponentEnabledSetting(getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
    }catch (Exception e) {
        e.printStackTrace();
    }
    

    Now I want to make icon visible programmatically

  • Scorpion
    Scorpion about 10 years
    Hello, Your code is working perfect but I am having one tricky thing to do. After hiding icon I would like to launch the app if user called on specific number like #007. I have implemented outgoing call receiver and matching on number I am trying to start my main activity but its giving me ActivityNotFoundException. Can you help me if you have any idea..
  • CoronaPintu
    CoronaPintu about 10 years
    @Scorpion yes you right that will destroy your activity you can not access that activity. for that u need to use another way.
  • Scorpion
    Scorpion about 10 years
    Can you suggest that how can i do that? I am getting Caused by: java.lang.NullPointerException on startActivity line of my code
  • CoronaPintu
    CoronaPintu about 10 years
    @Scorpion for this isssue i had R&D about 2 day.. yes now just give you solution that your are going to hide you mainActivity once you hide it the activity will not be found it's destroy so you need to create same another activity like mainActivity2 and you need to store boolean value to sharerdprefrence that whether icon is hiddne then u need to open mainActivity2 else MainActivity... pls check it
  • Muhammad Zeeshan Karamat
    Muhammad Zeeshan Karamat almost 10 years
    @Scorpion your solution works. But app icon continues to display until reboot. Any solution for that??
  • Muhammad Zeeshan Karamat
    Muhammad Zeeshan Karamat almost 10 years
    Same request from you that your solution works. But app icon continues to display until reboot. Any solution for that?? @CoronaPintu
  • nawaab saab
    nawaab saab almost 10 years
    @CoronaPintu is this the package name of the application that we want to hide, and can we hide others apps by placing there package name in place of com.apps.MainActivity.class in our application????
  • CoronaPintu
    CoronaPintu almost 10 years
    @DevilAbhi dont know about other apps but this is for out apps
  • Didi Kohen
    Didi Kohen over 8 years
    I understand it's been a while since it was asked, but I think there should be another activity, not defined with a launcher intent filter (so it'll not appear in the app launcher) that will have the outgoing call intent filter to enable the main activity.
  • Nwawel A Iroume
    Nwawel A Iroume about 6 years
    this is definetely the best and clean solution regarding to others former solution. thanks a lot
  • CrazyMind
    CrazyMind almost 6 years
    is that only for TV application
  • NoBugs
    NoBugs almost 6 years
    BEWARE, if you use this code and switch/add an icon, and user removes the icons you made with COMPONENT_ENABLED_STATE_ENABLED from the home screen, the app is effectively useless and it is unavailable anywhere except to be uninstalled and then installed again!
  • Abandoned Cart
    Abandoned Cart over 4 years
    How does this differ from the code posted a year before it? Shouldn't your suggestion be a comment on that?
  • Amir Oveisi
    Amir Oveisi over 4 years
    @AbandonedCart my answer also provides how to work with MainActivity while you have disabled it. it's highly possible to get ActivityNotFoundException when you follow this approach to hide your app but none of answers has no details about it. that's why i added my answer as new so people could see it.
  • Abandoned Cart
    Abandoned Cart over 4 years
    The question is how to unhide the app once it was hidden. The only original part of the answer appears to be a method that isn't really relevant to the question, as the OP is not asking what error they get by attempting to use it while hidden, but how to unhide it (resolving the error by default). It should have been a comment.
  • Ranjan
    Ranjan over 4 years
    Any solution for this guys. I am also having the same issue. Despite of having Admin access.
  • RaRa
    RaRa about 4 years
    Any way to handle this manually? @Ahmad Yes its working well, but i did not find any way to handle this manually. – Nwawel A Iroume did you implemented this? please advise. stuck on this from many days
  • Ahmad
    Ahmad about 4 years
    @RaRa i am using Java Code to hide icon but on Android 10 only my code not working.
  • Naveen Kumar
    Naveen Kumar about 4 years
    how to open it ?
  • Chauyan
    Chauyan almost 4 years
    This android.software.leanback the feature means you create an App based on the LeanBack UI and you set the requirement to true which also means it won't display on the mobile device. And, in this way, you might not be able to dynamically change it back.
  • Ahmad
    Ahmad over 3 years
    Hi any possibility of icon hide with any permission. I did not find any till now . If its not possible now any method to open manually hidden setting when user can hide our app icon ?