Câu trả lời:
Đây là một câu hỏi cũ, nhưng vẫn hoạt động vì không có tính năng rõ ràng của Android. Và những người từ facebook đã tìm thấy một công việc xung quanh - bằng cách nào đó. Hôm nay, tôi tìm thấy một cách làm việc cho tôi. Không hoàn hảo (xem nhận xét ở cuối câu trả lời này) nhưng nó hoạt động!
Ý tưởng chính là, tôi cập nhật biểu tượng phím tắt của ứng dụng, được tạo bởi trình khởi chạy trên màn hình chính. Khi tôi muốn thay đổi một cái gì đó trên biểu tượng phím tắt, tôi xóa nó trước và tạo lại nó bằng một bitmap mới.
Đây là mã. Nó có một nút increment. Khi nhấn, phím tắt được thay thế bằng phím tắt có số đếm mới.
Trước tiên, bạn cần hai quyền này trong tệp kê khai của bạn:
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
Sau đó, bạn cần hai phương pháp này để cài đặt và gỡ cài đặt các phím tắt. Các shortcutAddphương pháp tạo ra một bitmap với một số trong đó. Đây chỉ là để chứng minh rằng nó thực sự thay đổi. Bạn có thể muốn thay đổi phần đó bằng một cái gì đó, bạn muốn trong ứng dụng của bạn.
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);
}
Và cuối cùng, đây là hai trình nghe để thêm phím tắt đầu tiên và cập nhật phím tắt với bộ đếm tăng dần.
@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);
}
});
}
Nhận xét:
Cách này cũng hoạt động nếu Ứng dụng của bạn kiểm soát nhiều phím tắt hơn trên màn hình chính, ví dụ như có thêm các phím tắt khác trong Intent. Họ chỉ cần các tên khác nhau để cái bên phải được gỡ cài đặt và cài đặt lại.
Việc xử lý các phím tắt theo chương trình trong Android là một tính năng nổi tiếng, được sử dụng rộng rãi nhưng không được hỗ trợ chính thức cho Android. Nó dường như hoạt động trên launcher mặc định và tôi chưa bao giờ thử nó ở bất kỳ nơi nào khác. Vì vậy, đừng trách tôi, khi bạn nhận được email người dùng này "Nó không hoạt động trên XYZ của tôi, điện thoại hai gốc, siêu nổ"
Trình khởi chạy viết một Toastkhi một phím tắt được cài đặt và một khi một phím tắt được gỡ cài đặt. Vì vậy, tôi nhận được hai Toasts mỗi khi tôi thay đổi biểu tượng. Điều này không hoàn hảo, nhưng tốt, miễn là phần còn lại của ứng dụng của tôi hoàn hảo ...
Hãy thử nó, nó hoạt động tốt cho tôi:
1. Sửa đổi MainActivityphần của bạn trong AndroidManifest.xml, xóa khỏi nó, phù hợp với MAINthể loại trong intent-filterphần
<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. Tạo <activity-alias>, cho mỗi biểu tượng của bạn. Như thế này
<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. Đặt chương trình: đặt thuộc tính ENABLE cho phù hợpactivity-alias
getPackageManager().setComponentEnabledSetting(
new ComponentName("ru.quickmessage.pa", "ru.quickmessage.pa.MainActivity-Red"),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
Lưu ý, Ít nhất một phải được bật mọi lúc.
Bạn không thể thay đổi tệp kê khai hoặc tài nguyên trong APK đã ký và đóng dấu, ngoại trừ thông qua nâng cấp phần mềm.
Theo lập trình, bạn có thể muốn tự xuất bản trình khởi chạy ứng dụng:
Lưu ý: phương pháp này không còn hoạt động bắt đầu với Android 8.0 - Oreo
Trong AndroidManifest.xml của bạn, thêm:
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
Sau đó, bạn cần tạo mục đích khởi chạy ứng dụng của bạn:
Intent myLauncherIntent = new Intent();
myLauncherIntent.setClassName("your.package.name", "YourLauncherActivityName");
myLauncherIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Tạo mục đích tắt cài đặt với trình khởi chạy ứng dụng và biểu tượng tùy chỉnh của bạn:
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");
Và cuối cùng là khởi động ý định phát sóng:
getApplicationContext().sendBroadcast(intent);
Giả sử bạn có nghĩa là thay đổi biểu tượng hiển thị trên màn hình chính, điều này có thể dễ dàng được thực hiện bằng cách tạo một tiện ích thực hiện chính xác điều này. Đây là một bài viết chứng minh làm thế nào có thể được thực hiện cho một ứng dụng loại "tin nhắn mới" tương tự như iPhone:
Giải pháp @ PA là một phần làm việc cho tôi. Chi tiết những phát hiện của tôi dưới đây:
1) Đoạn mã đầu tiên không chính xác, xem bên dưới:
<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) Nên sử dụng mã sau để vô hiệu hóa tất cả các biểu tượng trước khi bật một biểu tượng khác, nếu không nó sẽ thêm một biểu tượng mới, thay vì thay thế nó.
getPackageManager().setComponentEnabledSetting(
getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
NHƯNG, nếu bạn sử dụng mã ở trên, thì lối tắt trên màn hình chính sẽ bị xóa! Và nó sẽ không được tự động thêm lại. Bạn có thể lập trình thêm biểu tượng trở lại, nhưng có lẽ nó sẽ không giữ nguyên vị trí như trước.
3) Lưu ý rằng biểu tượng sẽ không được thay đổi ngay lập tức, có thể mất vài giây. Nếu bạn nhấp vào nó ngay sau khi thay đổi, bạn có thể gặp lỗi: "Ứng dụng chưa được cài đặt".
Vì vậy, IMHO giải pháp này chỉ phù hợp để thay đổi biểu tượng trong trình khởi chạy ứng dụng, không phải cho các phím tắt (tức là biểu tượng trên màn hình chính)
Hãy thử giải pháp này
<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>
Thêm mã sau đây khi bạn muốn thay đổi biểu tượng ứng dụng của mình
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 thí dụ:
<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>
Sau đó làm theo mã được đưa ra dưới đây trong 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.resourceidentifierexamplengoại lệ. Ở đây tôi đã sử dụng tên kê khai của bạn chỉ để chứng minh vấn đề của mình
Để có được giải pháp bằng Markus làm việc, tôi cần có Ý định đầu tiên, vì vậy:
Intent myLauncherIntent = new Intent(Intent.ACTION_MAIN);
myLauncherIntent.setClassName(this, this.getClass().getName());
myLauncherIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Áp dụng các đề xuất được đề cập, tôi đã phải đối mặt với vấn đề ứng dụng bị giết mỗi khi biểu tượng mặc định được thay đổi thành biểu tượng mới. Vì vậy, đã thực hiện mã với một số điều chỉnh. Bước 1). Trong tệp AndroidManifest.xml, tạo cho hoạt động mặc định với android: enable = "true" và các bí danh khác với android: enable = "false". Bạn sẽ không chứa nhưng nối thêm những người trong Android: enable = "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>
Bước 2). Tạo một phương thức sẽ được sử dụng để vô hiệu hóa bí danh hoạt động thứ nhất có chứa biểu tượng mặc định và bật bí danh thứ 2 có chứa biểu tượng cần được thay đổi.
/**
* 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);
}
}
Bước 3). Bây giờ gọi phương thức này tùy thuộc vào yêu cầu của bạn, nói vào nút bấm hoặc ngày cụ thể hoặc điều kiện cụ thể, chỉ đơn giản như -
// Switch app icon to new icon
GeneralUtils.changeAppIconDynamically(EditProfileActivity.this, true);
// Switch app icon to default icon
GeneralUtils.changeAppIconDynamically(EditProfileActivity.this, false);
Hy vọng điều này sẽ giúp những người phải đối mặt với vấn đề ứng dụng bị giết khi thay đổi biểu tượng. Chúc mừng mã hóa :)