Android Desktop shortcuts and pitfalls, android

Source: Internet
Author: User

Android Desktop shortcuts and pitfalls, android

From http://blog.zanlabs.com/2015/03/14/android-shortcut-summary/

I have not written a blog for more than two months.
I have been engaged in red packet assistants for a while, so I didn't have time to write a blog, but it is really fun to write this. Did not expect to achieve simulated click on Android, so as to achieve automatic snatching of red packets, interested students can refer to the https://github.com/waylife/RedEnvelopeAssistant, the Code has been open source.
There are still some problems with the red envelope assistant, but now it is basically okay to grab the red envelope. It is being optimized and adapted to earlier versions, as well as international projects.
The following describes the shortcuts related to Andrioid development.
The data comes from the summary of your own CodeReview in the previous group.

Background

In general, to make it easier for users to open applications, the program will generate shortcuts on the desktop.
Originally, if it was a native desktop, it would be very simple to directly call system-related APIs. However, a large number of system vendors and a large number of third-party custom desktops have many problems in adaptation and compatibility.
For example, some desktops cannot delete shortcuts (such as Xiaomi), some desktops cannot generate shortcuts (such as hammers), and some systems cannot update desktop icons (such as Huawei honor 6 ).
The shortcut changes during upgrade or downgrade. For example, the shortcut changes to the main icon of the application. After the upgrade or downgrade, the shortcut does not respond when you click the shortcut. After the application is deleted, the shortcut cannot be deleted.
Many problems need to be solved. Although some problems cannot be solved due to system restrictions, they still need to find an optimal solution. This is the question to be discussed in this article.
The shortcut mentioned in this Article refers to the application desktop shortcut, which does not contain the shortcut generated by the long-press pop-up.
All information about the shortcut exists in the launcher's favorite table. Generally, the required fields are _ id, title, intent, iconResource, and icon, indicating the shortcut name, the shortcut intent, and the shortcut icon (local ), shortcut icon (data binary compressed data ).

The two intent data are as follows:

Data can be viewed through SQLite Editor, and the ROOT mobile phone is required

Add shortcuts

Add permissions in AndroidManifest. xml

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

At the same time, Intent-filter related to the declaration of the relevant Activity is displayed based on whether intent is implicit or.
Related code:

Delete shortcuts

Like adding shortcuts, you also need to add permissions. Add

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

Related code:

Shortcut Modification

Add Permissions

<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /><uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" />
To adapt to all desktops, add the permissions listed in article 2 in the appendix.
The system does not provide APIs to change Desktop shortcuts. You can only use other methods that are cumbersome. One of the feasible methods is to use ContentProvider to change database-related information. Of course, some people will say, just delete the shortcut and recreate it? This is a solution. However, some systems cannot delete shortcuts. In addition, both deleting shortcuts and creating shortcuts are implemented through broadcast. In this case, you need to control the time interval between the two. After balancing, the first method is relatively safe.
Code is not much nonsense.

/*** Update the desktop shortcut icon. Not all icons are valid. <br/> * If the shortcut does not exist, it is not updated. <br/>. */public static void updateShortcutIcon (Context context, String title, Intent intent, Bitmap bitmap) {if (bitmap = null) {XLog. I (TAG, "update shortcut icon, bitmap empty"); return;} try {final ContentResolver cr = context. getContentResolver (); StringBuilder uriStr = new StringBuilder (); String urlTemp = ""; String authority = LauncherUtil. getAuth OrityFromPermissionDefault (context); if (authority = null | authority. trim (). equals ("") {authority = LauncherUtil. getAuthorityFromPermission (context, LauncherUtil. getCurrentLauncherPackageName (context) + ". permission. READ_SETTINGS ");} uriStr. append ("content: //"); if (TextUtils. isEmpty (authority) {int sdkInt = android. OS. build. VERSION. SDK_INT; if (sdkInt <8) {// Android 2.1.x (API 7) and the following uriStr. app End ("com. android. launcher. settings ");} else if (sdkInt <19) {// uriStr under Android 4.4. append ("com. android. launcher2.settings ");} else {// 4.4 and above. append ("com. android. launcher3.settings ") ;}} else {uriStr. append (authority);} urlTemp = uriStr. toString (); uriStr. append ("/favorites? Required y = true "); Uri uri = Uri. parse (uriStr. toString (); Cursor c = cr. query (uri, new String [] {"_ id", "title", "intent"}, "title =? And intent =? ", New String [] {title, intent. toUri (0)}, null); int index =-1; if (c! = Null & c. getCount ()> 0) {c. moveToFirst (); index = c. getInt (0); // obtain the icon index ContentValues cv = new ContentValues (); cv. put ("icon", flattenBitmap (bitmap); Uri uri2 = Uri. parse (urlTemp + "/favorites/" + index + "? Optional Y = true "); int I = context. getContentResolver (). update (uri2, cv, null, null); context. getContentResolver (). notifyChange (uri, null); // uri2 cannot be used here, which is a pitfall XLog. I (TAG, "update OK: affected" + I + "rows, index is" + index);} else {XLog. I (TAG, "update result failed");} if (c! = Null &&! C. isClosed () {c. close () ;}} catch (Exception ex) {ex. printStackTrace (); XLog. I (TAG, "update shortcut icon, get errors:" + ex. getMessage () ;}} private static byte [] flattenBitmap (Bitmap bitmap) {// Try go guesstimate how much space the icon will take when serialized // to avoid unnecessary allocations/copies during the write. int size = bitmap. getWidth () * bitmap. getHeight () * 4; ByteArrayOutputStream out = new ByteArrayOutputStream (size); try {bitmap. compress (Bitmap. compressFormat.. PNG, 100, out); out. flush (); out. close (); return out. toByteArray ();} catch (IOException e) {XLog. w (TAG, "cocould not write icon"); return null ;}}

Judgment on existence of shortcuts

The permissions to be added are the same as those for modifying shortcuts.
Although SharePreference is used to ensure that shortcuts are not created repeatedly, and shortcutIntent is used. putExtra ("duplicate", false) can also be ensured, but to be foolproof, you can still query the data to determine whether the shortcut exists, to avoid repeated creation. The Code is as follows:

/*** Check whether the shortcut exists <br/> * <font color = red> note: </font> some mobile phones cannot determine whether shortcuts have been created <br/> * therefore, when creating shortcuts, add <br/> * shortcutIntent. putExtra ("duplicate", false); // repeated creation is not allowed <br/> * it is best to use {@ link # isShortCutExist (Context, String, Intent)} * for determination, because the shortcut names generated by some applications are the same <br/> * here, you need to use AndroidManifest. configure related desktop permission information in xml <br/> * error message captured <br/> */public static boolean isw.cutexist (Context context, String title) {boolean result = False; try {final ContentResolver cr = context. getContentResolver (); StringBuilder uriStr = new StringBuilder (); String authority = LauncherUtil. getAuthorityFromPermissionDefault (context); if (authority = null | authority. trim (). equals ("") {authority = LauncherUtil. getAuthorityFromPermission (context, LauncherUtil. getCurrentLauncherPackageName (context) + ". permission. READ_SETTINGS ");} uriStr. append ("Content: //"); if (TextUtils. isEmpty (authority) {int sdkInt = android. OS. build. VERSION. SDK_INT; if (sdkInt <8) {// Android 2.1.x (API 7) and the following uriStr. append ("com. android. launcher. settings ");} else if (sdkInt <19) {// uriStr under Android 4.4. append ("com. android. launcher2.settings ");} else {// 4.4 and above. append ("com. android. launcher3.settings ") ;}} else {uriStr. append (authority);} uriStr. ap Pend ("/favorites? Required y = true "); Uri uri = Uri. parse (uriStr. toString (); Cursor c = cr. query (uri, new String [] {"title"}, "title =? ", New String [] {title}, null); if (c! = Null & c. getCount ()> 0) {result = true;} if (c! = Null &&! C. isClosed () {c. close () ;}} catch (Exception e) {e. printStackTrace (); result = false;} return result;}/*** not all mobile phones are valid, because most mobile phone desktops in China are not system-native <br/> * For more information, see {@ link # isw.cutexist (Context, String)} <br/> * There are two types of desktops, system desktop (ROM built-in) and third-party desktop, generally only consider the built-in system <br/> * if the third-party desktop does not implement the system response method, it cannot be judged, for example, GO desktop <br/> * needs to be stored in AndroidManifest. configure related desktop permissions in xml <br/> * the error message is captured <br/> */public static boolean isw.cutexist (Context context, String title, Intent intent) {boolean result = false; try {final ContentResolver cr = context. getContentResolver (); StringBuilder uriStr = new StringBuilder (); String authority = LauncherUtil. getAuthorityFromPermissionDefault (context); if (authority = null | authority. trim (). equals ("") {authority = LauncherUtil. getAuthorityFromPermission (context, LauncherUtil. getCurrentLauncherPackageName (context) +". Permission. READ_SETTINGS ");} uriStr. append ("content: //"); if (TextUtils. isEmpty (authority) {int sdkInt = android. OS. build. VERSION. SDK_INT; if (sdkInt <8) {// Android 2.1.x (API 7) and the following uriStr. append ("com. android. launcher. settings ");} else if (sdkInt <19) {// uriStr under Android 4.4. append ("com. android. launcher2.settings ");} else {// 4.4 and above. append ("com. android. launcher3.settings ");}} Else {uriStr. append (authority);} uriStr. append ("/favorites? Required y = true "); Uri uri = Uri. parse (uriStr. toString (); Cursor c = cr. query (uri, new String [] {"title", "intent"}, "title =? And intent =? ", New String [] {title, intent. toUri (0)}, null); if (c! = Null & c. getCount ()> 0) {result = true;} if (c! = Null &&! C. isClosed () {c. close () ;}} catch (Exception ex) {result = false; ex. printStackTrace () ;}return result ;}

Compatibility with considerations

If the Intent of all shortcuts is not of the previous version, do not change the parameters. Otherwise, the shortcuts may fail during upgrade or downgrade;
At the same time, use implicit calling as much as possible, custom CATEGORY instead of custom ACTION. The ACTION parameter must be ACTION_MAIN. Otherwise, some mobile phones cannot delete shortcuts (WTF) When uninstalling them ).

Notes
  • [All] The shortcuts cannot be used after the previous version upgrade due to changes in the activity path.
    -> 1. Once the activity Package path is determined, do not change it later;
    -> 2. use implicit calling as much as possible. However, if a version has been released, you must always use the old method to ensure compatibility. Do not change the method of the new version as much as possible. If the user degrades, earlier versions of shortcuts cannot be used.
  • [Part] multiple shortcuts direct to one activity. As a result, the icon changes to an application icon when some mobile phones (Samsung SIDS) are upgraded.
    -> Avoid pointing multiple shortcuts to the same activity as much as possible. You may jump to the same activity through multiple activities.
  • [Part] the shortcut cannot be deleted when an application is deleted. It depends on the system desktop Launcher implementation.
    -> To adapt to all launchers, Intent Action uses Intent. ACTION_MAIN. If it is an implicit call, try to customize the CATEGORY instead of the custom ACTION.
  • [Part] some shortcuts of earlier versions need to be deleted during application upgrade, but some mobile phones cannot be deleted.
    -> No solution
  • [Part] shortcuts cannot be generated, deleted, or updated for third-party desktops.
    -> In general, there is no problem with the generation, but the deletion and updating of most Desktops may be problematic. Avoid these operations as much as possible. Alternatively, it is costly to adapt to the desktop.
  • [Part] Some desktops cannot update icons in real time and need to be restarted.
    -> No solution. I tried to restart Launcher, but the result was that the previous shortcuts also disappeared. Only restart the mobile phone. It is reasonable to trigger the Launcher to refresh.
    The preceding [all] [Part] indicates that the part appears.
Reference
  1. Http://grepcode.com/search? Query = InstallShortcutReceiver
  2. Http://developer.android.com/index.html
Appendix
  1. Complete code can refer to https://gist.github.com/waylife/437a3d98a84f245b9582
  2. General update shortcut permission list
    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.android.launcher2.permission.READ_SETTINGS" />    <uses-permission android:name="com.android.launcher2.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS" />    <uses-permission android:name="com.android.launcher3.permission.WRITE_SETTINGS" />    <uses-permission android:name="org.adw.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="org.adw.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="com.htc.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.qihoo360.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="com.qihoo360.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.lge.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="com.lge.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="net.qihoo.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="net.qihoo.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="org.adwfreak.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="org.adwfreak.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="org.adw.launcher_donut.permission.READ_SETTINGS" />    <uses-permission android:name="org.adw.launcher_donut.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.huawei.launcher3.permission.READ_SETTINGS" />    <uses-permission android:name="com.huawei.launcher3.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.fede.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="com.fede.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.sec.android.app.twlauncher.settings.READ_SETTINGS" />    <uses-permission android:name="com.sec.android.app.twlauncher.settings.WRITE_SETTINGS" />    <uses-permission android:name="com.anddoes.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="com.anddoes.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.tencent.qqlauncher.permission.READ_SETTINGS" />    <uses-permission android:name="com.tencent.qqlauncher.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.huawei.launcher2.permission.READ_SETTINGS" />    <uses-permission android:name="com.huawei.launcher2.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.android.mylauncher.permission.READ_SETTINGS" />    <uses-permission android:name="com.android.mylauncher.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.ebproductions.android.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="com.ebproductions.android.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS" />    <uses-permission android:name="telecom.mdesk.permission.READ_SETTINGS" />    <uses-permission android:name="telecom.mdesk.permission.WRITE_SETTINGS" />    <uses-permission android:name="dianxin.permission.ACCESS_LAUNCHER_DATA" />




Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.