是否可以直接从程序中更改应用程序图标?
我的意思是,改变icon.png了在res\drawable文件夹中.
我想让用户从程序中更改应用程序的图标,以便下次他们在启动器中看到之前选择的图标.
小智 126
试试这个,它对我来说很好:
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>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
注意,必须始终至少启用一个.
jbo*_*boi 71
这是一个老问题,但仍然有效,因为没有明确的Android功能.来自facebook的人找到了一个解决方法 - 不知何故.今天,我发现了一种适合我的方式.不完美(请参阅本答案末尾的评论),但它确实有效!
主要的想法是,我更新了我的主屏幕上的启动器创建的应用程序快捷方式的图标.当我想在快捷方式图标上更改某些内容时,我先删除它并使用新的位图重新创建它.
这是代码.它有一个按钮increment.按下时,快捷方式将替换为具有新计数的快捷方式.
首先,您需要在清单中使用这两个权限:
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
Run Code Online (Sandbox Code Playgroud)
然后,您需要这两种方法来安装和卸载快捷方式.该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);
}
Run Code Online (Sandbox Code Playgroud)
最后,这里有两个监听器添加第一个快捷方式并使用递增计数器更新快捷方式.
@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);
}
});
}
Run Code Online (Sandbox Code Playgroud)
备注:
如果您的应用程序控制主屏幕上的更多快捷方式,例如使用不同的额外内容,这种方式也适用Intent.它们只需要不同的名称,以便卸载并重新安装正确的名称.
Android中快捷方式的程序化处理是众所周知的,广泛使用但未经官方支持的Android功能.它似乎适用于默认启动器,我从未尝试过其他任何地方.所以不要怪我,当你收到这个用户的电子邮件"它不适用于我的XYZ,双根,超级爆破手机"
启动器Toast在安装快捷方式时写入一个,在卸载快捷方式时写入一个.所以Toast每次更改图标时我都会得到两个.这不是完美的,但是,只要我的应用程序的其余部分是完美的...
Com*_*are 35
除非通过软件升级,否则无法更改已签名密封的APK中的清单或资源.
And*_*cut 17
以编程方式,您可能希望自己发布应用程序启动器:
注意:此方法不再适用于Android 8.0 - Oreo
在AndroidManifest.xml中,添加:
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
Run Code Online (Sandbox Code Playgroud)
然后你需要创建你的应用程序启动器意图:
Intent myLauncherIntent = new Intent();
myLauncherIntent.setClassName("your.package.name", "YourLauncherActivityName");
myLauncherIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Run Code Online (Sandbox Code Playgroud)
使用您的应用启动器和自定义图标创建安装快捷方式意图:
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");
Run Code Online (Sandbox Code Playgroud)
最后发布广播意图:
getApplicationContext().sendBroadcast(intent);
Run Code Online (Sandbox Code Playgroud)
Mar*_*ahl 10
假设您的意思是更改主屏幕上显示的图标,可以通过创建完全相同的小部件轻松完成.这篇文章演示了如何为类似于iPhone的"新消息"类型应用程序实现:
http://www.cnet.com/8301-19736_1-10278814-251.html
如前所述,您需要使用<activity-alias>更改应用程序图标。\n为了避免在启用适当的活动别名后终止应用程序,您需要在终止应用程序后执行此操作。要查明应用程序是否被杀死,您可以使用此方法
<activity android:name=".ui.MainActivity"/>\n\n<activity-alias\n android:name=".one"\n android:icon="@mipmap/ic_launcher_one"\n android:targetActivity=".ui.MainActivity"\n android:enabled="true">\n\n <intent-filter>\n <action android:name="android.intent.action.MAIN" />\n <category android:name="android.intent.category.LAUNCHER" />\n </intent-filter>\n\n</activity-alias>\n\n<activity-alias\n android:name=".two"\n android:icon="@mipmap/ic_launcher_two"\n android:targetActivity=".ui.MainActivity"\n android:enabled="false">\n\n <intent-filter>\n <action android:name="android.intent.action.MAIN" />\n <category android:name="android.intent.category.LAUNCHER" />\n </intent-filter>\n\n</activity-alias>\nRun Code Online (Sandbox Code Playgroud)\nclass ChangeAppIconService: Service() {\n private val aliases = arrayOf(".one", ".two")\n\n override fun onBind(intent: Intent?): IBinder? = null\n\n override fun onTaskRemoved(rootIntent: Intent?) {\n changeAppIcon()\n stopSelf()\n }\n\n fun changeAppIcon() {\n val sp = getSharedPreferences("appSettings", Context.MODE_PRIVATE)\n\n sp.getString("activeActivityAlias", ".one").let { aliasName ->\n if (!isAliasEnabled(aliasName)) {\n setAliasEnabled(aliasName)\n }\n }\n }\n\n private fun isAliasEnabled(aliasName: String): Boolean {\n return packageManager.getComponentEnabledSetting(\n ComponentName(\n this,\n "${BuildConfig.APPLICATION_ID}$aliasName"\n )\n ) == PackageManager.COMPONENT_ENABLED_STATE_ENABLED\n }\n\n private fun setAliasEnabled(aliasName: String) {\n aliases.forEach {\n val action = if (it == aliasName)\n PackageManager.COMPONENT_ENABLED_STATE_ENABLED\n else\n PackageManager.COMPONENT_ENABLED_STATE_DISABLED\n \n packageManager.setComponentEnabledSetting(\n ComponentName(\n this,\n "${BuildConfig.APPLICATION_ID}$aliasName"\n ),\n action,\n PackageManager.DONT_KILL_APP\n )\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n<service \n android:name=".ChangeAppIconService"\n android:stopWithTask="false"\n />\nRun Code Online (Sandbox Code Playgroud)\nChangeAppIconService于MainActivity.onCreateclass MainActivity: Activity {\n\n ...\n\n override fun onCreate(savedInstanceState: Bundle?) {\n ...\n\n startService(Intent(this, ChangeAppIconService::class.java))\n\n ...\n }\n\n ...\n\n}\nRun Code Online (Sandbox Code Playgroud)\n
@ 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>
Run Code Online (Sandbox Code Playgroud)
2)在启用另一个图标之前,应使用以下代码禁用所有图标,否则它将添加新图标,而不是替换它.
getPackageManager().setComponentEnabledSetting(
getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
Run Code Online (Sandbox Code Playgroud)
但是,如果你使用上面的代码,那么主屏幕上的快捷方式将被删除!它不会自动添加回来.您可以以编程方式添加图标,但它可能不会保持与以前相同的位置.
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>
Run Code Online (Sandbox Code Playgroud)
当您想更改应用程序图标时添加以下代码
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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
147204 次 |
| 最近记录: |