簡體   English   中英

Android 以編程方式隱藏/取消隱藏應用程序圖標

[英]Android hide/unhide app icon programmatically

我使用以下代碼以編程方式隱藏應用程序圖標

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

現在我想以編程方式使圖標可見

使用以下代碼隱藏應用程序圖標:

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);

這是恢復應用程序圖標的方法。

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

重要編輯:

根據docs ,從 Android Q (API 29) 開始,無論如何,所有應用程序圖標都將在啟動器中可見,除非:

從 Android Q 開始,除非應用至少滿足以下條件之一,否則返回列表中至少會出現應用的 Activity 或合成 Activity 之一:

  • 該應用程序是一個系統應用程序。
  • 該應用程序不請求任何權限。
  • 應用清單中的標簽不包含任何代表應用組件的子元素。

此外,在以下與企業相關的情況下,系統會隱藏部分或所有應用程序的合成活動:

  • 如果設備是完全托管的設備,則返回的列表中不會顯示任何應用程序的合成活動。
  • 如果當前用戶有工作資料,則返回的列表中不會顯示用戶工作應用的合成活動。

從您可以使用的啟動器中隱藏應用程序圖標的最佳方法

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

在您的清單 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>

還在Manifest標簽中添加使用功能

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

要隱藏圖標,請使用:

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

並取消隱藏圖標:

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

重要提示:如果您需要在應用程序中的主要活動處於隱藏狀態時對其執行某些操作,這會有些棘手。 您將面臨ActivityNotFoundException 要使其工作,您應該在對主要活動執行任何操作之前取消隱藏圖標,並在完成后再次隱藏它。
簡單步驟: 1-call 在這里收到
2-取消隱藏圖標
3-啟動主要活動
4-在主要活動上做你的事情
5-再次隱藏圖標

只需使用以下代碼。

 PackageManager p = getPackageManager();
 ComponentName componentName = new ComponentName("com.example.removeicon","com.example.removeicon.LauncherActivity");
 p.setComponentEnabledSetting(componentName , PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

請注意,直到下一次重新啟動,圖標才會消失。

從這里下載源代碼( 以編程方式隱藏和取消隱藏 android 中的應用程序圖標

主活動.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;
    }

}

謝謝!

自 Android Q (API 29) 起不再支持此功能。 詳細信息也已添加到以前的答案中 您的應用程序的圖標將可見,除非它滿足文檔中規定的以下條件之一:

  • 該應用程序是一個系統應用程序。
  • 該應用程序不請求任何權限。
  • 應用清單中的標簽不包含任何代表應用組件的子元素。

這是我到目前為止發現的,不幸的是它不是原始問題的答案,只是替代方案

  1. 這是第一個選項,但如果您的應用程序需要許可並且不再有用(至少在 Android 10 中),如這里提到的@CoronaPintu https://stackoverflow.com/a/22754642/1712446此方法有效但有很多限制

    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. 使用與上述相同的方法加上adb 命令,即使您的應用程序需要權限,此替代方法也有效,但您必須有權訪問設備並連接到 pc,然后運行此命令

    隱藏: $adb shell settings put global show_hidden_icon_apps_enabled 0

    顯示: $adb shell settings put global show_hidden_icon_apps_enabled 1

以防萬一,您無法從應用程序運行此命令

  1. 另一種選擇是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); }

此方法有效,但我們也有一些限制,您需要啟用設備所有者模式,您可以在此處找到更多信息

要啟用此模式,您必須運行此 adb 命令

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

但是,您可以從應用程序中執行此命令

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

但是,如果手機已經設置了帳戶,則此方法將失敗並出現下一個錯誤:

java.lang.IllegalStateException: Not allowed to set the device owner because there are already several users on the device

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM