[android] Android에서 프로그래밍 방식으로 응용 프로그램 아이콘을 변경하는 방법은 무엇입니까?

프로그램에서 직접 응용 프로그램 아이콘을 변경할 수 있습니까?
나는 변화를 의미 icon.png에서 res\drawable폴더를.
다음에 시작 프로그램에서 이전에 선택한 아이콘을 볼 수 있도록 프로그램에서 응용 프로그램 아이콘을 변경할 수 있도록하겠습니다.



답변

오래된 질문이지만 명시적인 Android 기능이 없으므로 여전히 활성화되어 있습니다. 그리고 페이스 북의 사람들은 어떻게 든 문제를 발견했습니다. 오늘 저는 저에게 효과적인 방법을 찾았습니다. 완벽하지는 않지만 (이 답변의 끝에있는 설명 참조) 작동합니다!

기본 아이디어는 홈 화면의 실행기로 만든 앱 바로 가기 아이콘을 업데이트하는 것입니다. 바로 가기 아이콘에서 무언가를 변경하려면 먼저 제거하고 새 비트 맵으로 다시 만듭니다.

코드는 다음과 같습니다. 버튼이 increment있습니다. 누르면 바로 가기가 새로운 계산 번호가있는 바로 가기로 바뀝니다.

먼저 매니페스트에 다음 두 가지 권한이 필요합니다.

<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />

그런 다음 바로 가기를 설치 및 제거하기위한이 두 가지 방법이 필요합니다. 이 shortcutAdd메서드는 숫자가 포함 된 비트 맵을 만듭니다. 이것은 실제로 변경됨을 보여주기위한 것입니다. 앱에서 원하는 부분으로 무언가를 변경하고 싶을 것입니다.

private void shortcutAdd(String name, int number) {
    // Intent to be send, when shortcut is pressed by user ("launched")
    Intent shortcutIntent = new Intent(getApplicationContext(), Play.class);
    shortcutIntent.setAction(Constants.ACTION_PLAY);

    // Create bitmap with number in it -> very default. You probably want to give it a more stylish look
    Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
    Paint paint = new Paint();
    paint.setColor(0xFF808080); // gray
    paint.setTextAlign(Paint.Align.CENTER);
    paint.setTextSize(50);
    new Canvas(bitmap).drawText(""+number, 50, 50, paint);
    ((ImageView) findViewById(R.id.icon)).setImageBitmap(bitmap);

    // Decorate the shortcut
    Intent addIntent = new Intent();
    addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
    addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
    addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap);

    // Inform launcher to create shortcut
    addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
    getApplicationContext().sendBroadcast(addIntent);
}

private void shortcutDel(String name) {
    // Intent to be send, when shortcut is pressed by user ("launched")
    Intent shortcutIntent = new Intent(getApplicationContext(), Play.class);
    shortcutIntent.setAction(Constants.ACTION_PLAY);

    // Decorate the shortcut
    Intent delIntent = new Intent();
    delIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
    delIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);

    // Inform launcher to remove shortcut
    delIntent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
    getApplicationContext().sendBroadcast(delIntent);
}

마지막으로 두 번째 리스너는 첫 번째 바로 가기를 추가하고 바로 가기를 증분 카운터로 업데이트합니다.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.test);
    findViewById(R.id.add).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            shortcutAdd("changeIt!", count);
        }
    });
    findViewById(R.id.increment).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            shortcutDel("changeIt!");
            count++;
            shortcutAdd("changeIt!", count);
        }
    });
}

비고 :

  • 이 방법은 앱이 홈 화면에서 더 많은 바로 가기를 제어하는 ​​경우에도 작동합니다 (예 :에서 다른 추가 항목이있는 경우) Intent. 올바른 이름을 제거하고 다시 설치할 수 있도록 다른 이름 만 있으면됩니다.

  • Android에서 프로그래밍 방식으로 단축키를 처리하는 것은 잘 알려져 있지만 널리 사용되지만 공식적으로 지원되지 않는 Android 기능입니다. 기본 런처에서 작동하는 것 같으며 다른 곳에서는 시도하지 않았습니다. 따라서이 사용자 이메일을받을 때 나를 비난하지 마십시오.

  • 런처는 Toast바로 가기가 설치 될 때와 바로 가기가 제거되었을 때를 씁니다 . Toast아이콘을 변경할 때마다 2 초씩 표시됩니다. 이것은 내 앱의 나머지 부분이 완벽하다면 완벽하지는 않지만 …


답변

이것을 시도하십시오, 그것은 나를 위해 잘 작동합니다 :

1 . MainActivity섹션에서 섹션을 수정하고 섹션에서 카테고리 AndroidManifest.xml와 함께 삭제 하십시오.MAINintent-filter

<activity android:name="ru.quickmessage.pa.MainActivity"
    android:configChanges="keyboardHidden|orientation"
    android:screenOrientation="portrait"
    android:label="@string/app_name"
    android:theme="@style/CustomTheme"
    android:launchMode="singleTask">
    <intent-filter>
        ==> <action android:name="android.intent.action.MAIN" /> <== Delete this line
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

2. <activity-alias>각 아이콘 마다을 만듭니다 . 이렇게

<activity-alias android:label="@string/app_name"
    android:icon="@drawable/icon"
    android:name=".MainActivity-Red"
    android:enabled="false"
    android:targetActivity=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>

삼 . 프로그래밍 방식으로 설정 : 적절한 ENABLE 속성 설정activity-alias

 getPackageManager().setComponentEnabledSetting(
        new ComponentName("ru.quickmessage.pa", "ru.quickmessage.pa.MainActivity-Red"),
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);

항상 하나 이상을 활성화해야합니다.


답변

소프트웨어 업그레이드를 제외하고 서명 및 봉인 된 APK에서 매니페스트 또는 리소스를 변경할 수 없습니다.


답변

프로그래밍 방식으로 응용 프로그램 시작 관리자를 직접 게시 할 수 있습니다.

참고 :이 방법은 더 이상 Android 8.0부터 작동하지 않습니다.-Oreo

AndroidManifest.xml에서 다음을 추가하십시오.

<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>

그런 다음 앱 시작 관리자 의도를 만들어야합니다.

Intent myLauncherIntent = new Intent();
myLauncherIntent.setClassName("your.package.name", "YourLauncherActivityName");
myLauncherIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

앱 런처 및 사용자 정의 아이콘을 사용하여 설치 바로 가기 의도를 작성하십시오.

Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, myLauncherIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Application Name");
intent.putExtra
       (
        Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
        Intent.ShortcutIconResource.fromContext
                                    (
                                         getApplicationContext(),
                                         R.drawable.app_icon
                                    )
       );
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");

마지막으로 방송 의도를 시작하십시오.

getApplicationContext().sendBroadcast(intent);


답변

홈 화면에 표시된 아이콘을 변경한다고 가정하면, 정확하게 수행하는 위젯을 작성하여 쉽게 수행 할 수 있습니다. 다음은 iPhone과 유사한 “새로운 메시지”유형 응용 프로그램에서 어떻게 수행 할 수 있는지 보여주는 기사입니다.

http://www.cnet.com/8301-19736_1-10278814-251.html


답변

@PA의 솔루션은 부분적으로 효과적입니다. 내 결과를 아래에 자세히 설명하십시오.

1) 첫 번째 코드 스 니펫이 올바르지 않습니다 (아래 참조).

<activity
    ...
    <intent-filter>
        ==> <action android:name="android.intent.action.MAIN" /> <== This line shouldn't be deleted, otherwise will have compile error
        <category android:name="android.intent.category.LAUNCHER" /> //DELETE THIS LINE
    </intent-filter>
</activity>

2) 다른 아이콘을 활성화하기 전에 다음 코드를 사용하여 모든 아이콘을 비활성화해야합니다. 그렇지 않으면 새 아이콘이 바뀌지 않고 추가됩니다.

getPackageManager().setComponentEnabledSetting(
        getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

그러나 위의 코드를 사용하면 홈 화면의 바로 가기가 제거됩니다! 그리고 자동으로 다시 추가되지 않습니다. 프로그래밍 방식으로 아이콘을 다시 추가 할 수 있지만 이전과 같은 위치에 있지 않을 수 있습니다.

3) 아이콘이 즉시 변경되지 않으며 몇 초가 걸릴 수 있습니다. 변경 후 바로 클릭하면 “앱이 설치되지 않았습니다”라는 오류가 표시 될 수 있습니다.

따라서 IMHO이 솔루션은 바로 가기가 아닌 앱 실행기의 아이콘 변경에만 적합합니다 (예 : 홈 화면의 아이콘).


답변

이 솔루션을 사용해보십시오

<activity android:name=".SplashActivity"
        android:label="@string/app_name"
        android:icon="@drawable/ic_launcher">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity-alias android:label="ShortCut"
        android:icon="@drawable/ic_short_cut"
        android:name=".SplashActivityAlias"
        android:enabled="false"
        android:targetActivity=".SplashActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity-alias>

앱 아이콘을 변경하려면 다음 코드를 추가하십시오.

PackageManager pm = getPackageManager();
                    pm.setComponentEnabledSetting(
                            new ComponentName(YourActivity.this,
                                    "your_package_name.SplashActivity"),
                            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                            PackageManager.DONT_KILL_APP);

                    pm.setComponentEnabledSetting(
                            new ComponentName(YourActivity.this,
                                    "your_package_name.SplashActivityAlias"),
                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                            PackageManager.DONT_KILL_APP);