Android hide/unhide app icon programmatically
Asked Answered
K

6

75

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

Koralle answered 1/10, 2013 at 10:58 Comment(2)
i was looking for this, but Where i need to write this code?Cartagena
how dynamically passing package name and hide that particular appicon in deviceQuent
E
138

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.
Ethic answered 31/3, 2014 at 6:8 Comment(12)
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..Albrecht
@Albrecht yes you right that will destroy your activity you can not access that activity. for that u need to use another way.Ethic
Can you suggest that how can i do that? I am getting Caused by: java.lang.NullPointerException on startActivity line of my codeAlbrecht
@Albrecht 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 itEthic
@Albrecht your solution works. But app icon continues to display until reboot. Any solution for that??Taxiplane
Same request from you that your solution works. But app icon continues to display until reboot. Any solution for that?? @EthicTaxiplane
@Ethic 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????Shackleford
@DevilAbhi dont know about other apps but this is for out appsEthic
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.Locris
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!Moro
Any solution for this guys. I am also having the same issue. Despite of having Admin access.Dinner
@Moro use instead <category android:name="android.intent.category.INFO"/> for the "front door" activity. You can now also launch the app from App Info list within system builtin Settings app.Cheerless
W
30

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" />
Wording answered 21/3, 2018 at 5:23 Comment(7)
this is definetely the best and clean solution regarding to others former solution. thanks a lotAccumulator
is that only for TV applicationConvexity
Any way to handle this manually? @Dufy 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 daysNudd
@Nudd i am using Java Code to hide icon but on Android 10 only my code not working.Dufy
how to open it ?Strode
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.Hurried
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 ?Dufy
C
14

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

Caughey answered 28/4, 2015 at 4:46 Comment(3)
How does this differ from the code posted a year before it? Shouldn't your suggestion be a comment on that?Semilunar
@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.Caughey
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.Semilunar
R
6

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!

Reincarnate answered 13/6, 2017 at 5:57 Comment(0)
C
4

This feature is no longer supported as of Android Q (API 29). Details have also been added to a previous answer. Your app's icon will be visible unless it satisfies one of the following conditions stated in the docs:

  • 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.
Coprolalia answered 25/9, 2019 at 5:42 Comment(0)
V
4

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://mcmap.net/q/268353/-android-hide-unhide-app-icon-programmatically 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
Vikki answered 25/3, 2020 at 4:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.