답변:
오래된 질문이지만 명시적인 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과 유사한 "새로운 메시지"유형 응용 프로그램에서 어떻게 수행 할 수 있는지 보여주는 기사입니다.
@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);
AndroidManifest.xml 예:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.pritesh.resourceidentifierexample.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<!--<category android:name="android.intent.category.LAUNCHER"/>-->
</intent-filter>
</activity>
<activity-alias android:label="RED"
android:icon="@drawable/ic_android_red"
android:name="com.pritesh.resourceidentifierexample.MainActivity-Red"
android:enabled="true"
android:targetActivity="com.pritesh.resourceidentifierexample.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias android:label="GREEN"
android:icon="@drawable/ic_android_green"
android:name="com.pritesh.resourceidentifierexample.MainActivity-Green"
android:enabled="false"
android:targetActivity="com.pritesh.resourceidentifierexample.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias android:label="BLUE"
android:icon="@drawable/ic_android_blue"
android:name="com.pritesh.resourceidentifierexample.MainActivity-Blue"
android:enabled="false"
android:targetActivity="com.pritesh.resourceidentifierexample.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
</application>
그런 다음 아래 주어진 코드를 따르십시오 MainActivity.
ImageView imageView = (ImageView)findViewById(R.id.imageView);
int imageResourceId;
String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
int hours = new Time(System.currentTimeMillis()).getHours();
Log.d("DATE", "onCreate: " + hours);
getPackageManager().setComponentEnabledSetting(
getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
if(hours == 13)
{
imageResourceId = this.getResources().getIdentifier("ic_android_red", "drawable", this.getPackageName());
getPackageManager().setComponentEnabledSetting(
new ComponentName("com.pritesh.resourceidentifierexample", "com.pritesh.resourceidentifierexample.MainActivity-Red"),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}else if(hours == 14)
{
imageResourceId = this.getResources().getIdentifier("ic_android_green", "drawable", this.getPackageName());
getPackageManager().setComponentEnabledSetting(
new ComponentName("com.pritesh.resourceidentifierexample", "com.pritesh.resourceidentifierexample.MainActivity-Green"),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}else
{
imageResourceId = this.getResources().getIdentifier("ic_android_blue", "drawable", this.getPackageName());
getPackageManager().setComponentEnabledSetting(
new ComponentName("com.pritesh.resourceidentifierexample", "com.pritesh.resourceidentifierexample.MainActivity-Blue"),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}
imageView.setImageResource(imageResourceId);
com.pritesh.resourceidentifierexample.MainActivity-Red doesn't exist in com.pritesh.resourceidentifierexample예외 가 발생합니다. 여기서 나는 당신의 이름을 내 문제를 설명하기 위해 사용했습니다
언급 한 제안을 적용하면 기본 아이콘이 새 아이콘으로 변경 될 때마다 앱이 종료되는 문제에 직면했습니다. 그래서 약간의 조정으로 코드를 구현했습니다. 1 단계). AndroidManifest.xml 파일에서 android : enabled = "true"로 기본 활동 및 android : enabled = "false"로 다른 별명을 작성하십시오. 귀하는 android : enabled = "true"를 포함하지 않고 추가합니다.
<activity
android:name=".activities.SplashActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/SplashTheme">
</activity>
<!-- <activity-alias used to change app icon dynamically> : default icon, set enabled true -->
<activity-alias
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:name=".SplashActivityAlias1" <!--put any random name started with dot-->
android:enabled="true"
android:targetActivity=".activities.SplashActivity"> <!--target activity class path will be same for all alias-->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<!-- <activity-alias used to change app icon dynamically> : sale icon, set enabled false initially -->
<activity-alias
android:label="@string/app_name"
android:icon="@drawable/ic_store_marker"
android:roundIcon="@drawable/ic_store_marker"
android:name=".SplashActivityAlias" <!--put any random name started with dot-->
android:enabled="false"
android:targetActivity=".activities.SplashActivity"> <!--target activity class path will be same for all alias-->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
2 단계). 기본 아이콘이 포함 된 첫 번째 활동 별칭을 비활성화하고 아이콘이 포함 된 두 번째 별칭을 활성화하는 데 사용할 방법을 변경해야합니다.
/**
* method to change the app icon dynamically
*
* @param context
* @param isNewIcon : true if new icon need to be set; false to set default
* icon
*/
public static void changeAppIconDynamically(Context context, boolean isNewIcon) {
PackageManager pm = context.getApplicationContext().getPackageManager();
if (isNewIcon) {
pm.setComponentEnabledSetting(
new ComponentName(context,
"com.example.dummy.SplashActivityAlias1"), //com.example.dummy will be your package
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(
new ComponentName(context,
"com.example.dummy.SplashActivityAlias"),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
} else {
pm.setComponentEnabledSetting(
new ComponentName(context,
"com.example.dummy.SplashActivityAlias1"),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(
new ComponentName(context,
"com.example.dummy.SplashActivityAlias"),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
}
3 단계). 이제 버튼 클릭 또는 날짜 또는 특정 상황에 따라 요구 사항에 따라이 방법을 호출하십시오.
// Switch app icon to new icon
GeneralUtils.changeAppIconDynamically(EditProfileActivity.this, true);
// Switch app icon to default icon
GeneralUtils.changeAppIconDynamically(EditProfileActivity.this, false);
아이콘 변경으로 인해 앱이 죽는 문제에 직면하는 사람들에게 도움이되기를 바랍니다. 행복한 코딩 :)