Answers:
这是一个古老的问题,但由于没有明确的Android功能,因此仍然很活跃。来自facebook的家伙找到了解决方法-不知何故。今天,我找到了一种对我有用的方法。并不完美(请参阅此答案末尾的备注),但是可以正常工作!
主要想法是,我更新了应用程序快捷方式的图标,该图标是由启动程序在主屏幕上创建的。当我想更改快捷方式图标上的某些内容时,请先将其删除,然后使用新的位图重新创建它。
这是代码。它有一个按钮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功能。它似乎可以在默认启动器上运行,而我从未在其他任何地方尝试过。因此,当您收到此用户电子邮件时,请不要怪我:“它不适用于我的XYZ,双根超级爆炸电话”
启动器Toast在安装快捷方式时会写一个,卸载时会写一个。因此,Toast每次更改图标都会得到2 s。只要我的应用程序的其余部分是完美的,这并不是完美的,但是...
试试这个,对我来说很好:
1。修改中的MainActivity部分AndroidManifest.xml,将其删除,并与MAIN该intent-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>
3。以编程方式设置:为适当的设置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)请注意,图标不会立即更改,可能需要几秒钟。如果在更改后立即单击它,可能会收到错误消息:“未安装应用程序”。
因此,恕我直言,此解决方案仅适用于仅更改应用启动器中的图标,不适用于快捷方式(即主屏幕上的图标)
试试这个解决方案
<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);
希望这将帮助那些面对应用程序问题的人因图标更改而丧命。快乐编码:)