1. 程式人生 > >android launcher3桌面快捷方式分析

android launcher3桌面快捷方式分析

背景

一般情況下,為了讓使用者更方便的開啟應用,程式會在桌面上生成一些快捷方式。
本來呢,如果是原生的桌面,其實是十分簡單,直接呼叫系統相關的API就行了。但是眾多的系統廠商以及眾多第三方自己定製的桌面(Launcher),導致在適配、相容方面存在很多問題。
比如,有些桌面無法刪除快捷方式(比如小米),有些桌面無法生成快捷方式(比如錘子),有些系統無法更新桌面圖示(比如華為榮耀6)。
在升級、降級的時候快捷方式發生變化;比如,全部變成應用的主圖示,升級、降級後點擊快捷方式沒有反應,刪除應用後無法刪除快捷方式。
很多問題都是需要解決的,雖然有些由於系統限制,沒有辦法搞定所有的,但是仍然需要尋求一個最優的方案。這也就是本文需要討論的問題。
本文說指的快捷方式是指應用桌面快捷方式,不包含長按彈出的生成快捷方式。
快捷方式所有資訊都是存在於launcher的favorite表。一般需要用到的欄位為_id,title,intent,iconResource,icon,分別表示 快捷方式名稱,快捷方式intent,快捷方式圖示(本地),快捷方式圖示(data二進位制壓縮資料)。

兩個intent資料如下

資料可以通過SQLite Editor檢視,需要已經ROOT的手機

實現

增加快捷方式

在AndroidManifest.xml增加許可權

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

同時,根據Intent是隱式還是顯示在相關的Activity宣告相關的intent-filter。
相關程式碼:

刪除快捷方式

跟增加快捷方式一樣,也是需要增加許可權的。加上

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

相關程式碼:

快捷方式修改

需要增加許可權

  1. <uses-permissionandroid:name="com.android.launcher.permission.READ_SETTINGS"/>
  2. <uses-permissionandroid:name="com.android.launcher.permission.WRITE_SETTINGS"
    />
如果適配所有桌面,請新增附錄中第二條所列出的許可權。
系統並沒有提供API去更改桌面快捷方式。只能通過其他猥瑣的辦法了,可行的的辦法之一就是通過ContentProvider去更改資料庫相關的資訊。當然有人會說了,先刪掉快捷方式,再重新建立不就行了?這是個辦法。但是有些系統是無法刪除快捷方式的;另外,刪除快捷方式與建立快捷方式都是通過廣播實現的,這個地方需要控制兩者的時間間隔。權衡之後,選用第一種辦法相對穩妥。
廢話不多少,上程式碼。
  1. /** 
  2.   * 更新桌面快捷方式圖示,不一定所有圖示都有效<br/> 
  3.   * 如果快捷方式不存在,則不更新<br/>. 
  4.   */
  5.  publicstaticvoid updateShortcutIcon(Context context, String title, Intent intent,Bitmap bitmap) {  
  6.   if(bitmap==null){  
  7.    XLog.i(TAG, "update shortcut icon,bitmap empty");  
  8.    return;  
  9.   }  
  10.   try{  
  11.    final ContentResolver cr = context.getContentResolver();  
  12.    StringBuilder uriStr = new StringBuilder();  
  13.    String urlTemp="";  
  14.    String authority = LauncherUtil.getAuthorityFromPermissionDefault(context);  
  15.    if(authority==null||authority.trim().equals("")){  
  16.     authority = LauncherUtil.getAuthorityFromPermission(context,LauncherUtil.getCurrentLauncherPackageName(context)+".permission.READ_SETTINGS");  
  17.    }  
  18.    uriStr.append("content://");  
  19.    if (TextUtils.isEmpty(authority)) {  
  20.     int sdkInt = android.os.Build.VERSION.SDK_INT;  
  21.     if (sdkInt < 8) { // Android 2.1.x(API 7)以及以下的
  22.      uriStr.append("com.android.launcher.settings");  
  23.     } elseif (sdkInt < 19) {// Android 4.4以下
  24.      uriStr.append("com.android.launcher2.settings");  
  25.     } else {// 4.4以及以上
  26.      uriStr.append("com.android.launcher3.settings");  
  27.     }  
  28.    } else {  
  29.     uriStr.append(authority);  
  30.    }  
  31.    urlTemp=uriStr.toString();  
  32.    uriStr.append("/favorites?notify=true");  
  33.    Uri uri = Uri.parse(uriStr.toString());  
  34.    Cursor c = cr.query(uri, new String[] {"_id""title""intent" },  
  35.      "title=?  and intent=? ",  
  36.      new String[] { title, intent.toUri(0) }, null);  
  37.    int index=-1;  
  38.    if (c != null && c.getCount() > 0) {  
  39.     c.moveToFirst();  
  40.     index=c.getInt(0);//獲得圖示索引
  41.     ContentValues cv=new ContentValues();  
  42.     cv.put("icon", flattenBitmap(bitmap));  
  43.     Uri uri2=Uri.parse(urlTemp+"/favorites/"+index+"?notify=true");  
  44.     int i=context.getContentResolver().update(uri2, cv, null,null);  
  45.     context.getContentResolver().notifyChange(uri,null);//此處不能用uri2,是個坑
  46.     XLog.i(TAG, "update ok: affected "+i+" rows,index is"+index);  
  47.    }else{  
  48.     XLog.i(TAG, "update result failed");  
  49.    }  
  50.    if (c != null && !c.isClosed()) {  
  51.     c.close();  
  52.    }  
  53.   }catch(Exception ex){  
  54.    ex.printStackTrace();  
  55.    XLog.i(TAG, "update shortcut icon,get errors:"+ex.getMessage());  
  56.   }  
  57.  }  
  58.  privatestaticbyte[] flattenBitmap(Bitmap bitmap) {  
  59.   // Try go guesstimate how much space the icon will take when serialized
  60.   // to avoid unnecessary allocations/copies during the write.
  61.   int size = bitmap.getWidth() * bitmap.getHeight() * 4;  
  62.   ByteArrayOutputStream out = new ByteArrayOutputStream(size);  
  63.   try {  
  64.    bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);  
  65.    out.flush();  
  66.    out.close();  
  67.    return out.toByteArray();  
  68.   } catch (IOException e) {  
  69.    XLog.w(TAG, "Could not write icon");  
  70.    returnnull;  
  71.   }  
  72.  }  

快捷方式存在判斷

需要增加的許可權同修改快捷方式
雖然說通過SharePreference來保證快捷方式不會重複建立,以及通過shortcutIntent.putExtra(“duplicate”, false)也可以確保,但是為了萬無一失,還是可以通過去查詢資料判斷快捷方式是否存在,來避免重複建立。 程式碼如下:

  1. /** 
  2.   * 檢查快捷方式是否存在 <br/> 
  3.   * <font color=red>注意:</font> 有些手機無法判斷是否已經建立過快捷方式<br/> 
  4.   * 因此,在建立快捷方式時,請新增<br/> 
  5.   * shortcutIntent.putExtra("duplicate", false);// 不允許重複建立<br/> 
  6.   * 最好使用{@link #isShortCutExist(Context, String, Intent)} 
  7.   * 進行判斷,因為可能有些應用生成的快捷方式名稱是一樣的的<br/> 
  8.   * 此處需要在AndroidManifest.xml中配置相關的桌面許可權資訊<br/> 
  9.   * 錯誤資訊已捕獲<br/> 
  10. 相關推薦

    android launcher3桌面快捷方式分析

    背景 一般情況下,為了讓使用者更方便的開啟應用,程式會在桌面上生成一些快捷方式。 本來呢,如果是原生的桌面,其實是十分簡單,直接呼叫系統相關的API就行了。但是眾多的系統廠商以及眾多第三方自己定製的桌面(Launcher),導致在適配、相容方面存在很多問題。

    Android生成桌面快捷方式

    生成快捷方式: 1.判斷是否已經以後快捷方式 if(!SpUtil.getBoolean(this, ConstantValue.HAS_SHORTCUT, false)){ //生成快捷方式 initShortCut();

    Android 新增App快捷方式桌面

    主要原理是通過向系統傳送建立快捷方式的廣播 設定Intent,傳遞快捷方式的資訊,名字和圖示等 Intent shortcut = new Intent("com.android.l

    android 桌面快捷方式

            private void addShortcut(){         Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");                         //快捷方

    Android應用新增(建立)和刪除及判斷是否存在桌面快捷方式

    Android桌面程式提供了應用新增和刪除桌面快捷方式的功能以及判斷快捷方式是否存在,只要傳入快捷方式標題、圖示及點選快捷方式執行的應用Intent即可。程式碼如下: /** * 為當前應用新增桌面快捷方式 * * @param cx * @param appNa

    QQ是怎樣實現好友桌面快捷方式的?

    users blog href 展開 路徑 ros 例如 兩個 處理 QQ是怎樣實現好友桌面快捷方式的? 不知道什麽時候,QQ推出了好友桌面快捷方式。方便用戶和最常保持聯系的好友一鍵聯系。核心功能一:若QQ啟動了。則雙擊快捷方式直接打開好友聊天界面;核心

    為程序創建桌面快捷方式

    baidu hao123 桌面 view 快捷 music 創建 istview 5% LIsTVIEW%E6%BB%91%E5%8A%A8%E9%80%9F%E5%BA%A6%E6%80%8E%E4%B9%88%E6%94%B9%E5%8F%98 http://music

    Ubuntu 建立桌面快捷方式

    evel andro ext xxx name eve 解決 oid 出發 非常多時候,在Ubuntu下軟件能夠通過命令安裝。可是有時候比較方便的方法就是下載一個壓縮包,解壓就能夠使用了。可是每次使用都要先跳到解壓文件夾。這就比較麻煩。所以能夠通過創建桌

    ubuntu 創建桌面快捷方式

    logs xxx apt edi edit desktop usr err 名稱 $sudo apt-get install gnome-panel $gnome-desktop-item-edit /home/xxx/桌面 --create-new 命令行:填入程

    Ubuntu 16.04安裝Eclipse並創建桌面快捷方式

    x86 linux nbsp har ref try 動圖 文件夾 als 轉載自:http://www.linuxidc.com/Linux/2017-02/140909.htm 系統:Ubuntu 16.04 JDK版本:1.8.0_121 1.官網下載eclipse,

    關於eclipse發送桌面快捷方式後打不開的問題

    img blog 桌面快捷方式 技術 clas 環境 電腦 http jdk1.8 最近裝了一個最新版的eclipse,jdk是我之前就已經裝好的,安裝完eclipse後發現啟動不了,然後就上網查,有的說讓重新配置java環境,有的說在eclipse.ini中添加E:\cl

    設置桌面快捷方式

    快捷 share rmi desktop /usr develop exe png als cd /usr/share/applications sudo vim idea.desktop [Desktop Entry] Name=idea-java Comment=

    CentOS 7 創建桌面快捷方式

    str for xdg text utility not Go 後綴 term 一,在桌面新建一個文件   文件名隨意,但必須帶有.desktop的後綴名, 以Eclipse為例 vi /home/lenmom/Desktop/eclipse.desktop

    deepin ubuntu等創建桌面快捷方式

    1.0 terminal image 創建 linux als false idea 分享 Linux網上下載軟件一般只會有.sh結尾執行程序。並不會像商店下載一樣自動創建桌面圖標。此時需要自行進行編輯。 #創建一個桌面圖標後綴名為.desktop touch myDesk

    Python3創建RIDE桌面快捷方式的另一種方法

    文本 comm 嘗試 環境 robot bubuko 分享 找到 .net 今天嘗試了一下Python3下安裝Robot Framework,但是原來的Python2下創建ride快捷方式的方法都不奏效,啟動不了ride。於是,轉為VBS腳本的方式來間接創建快捷方式。畢竟,

    C++ API實現創建桌面快捷方式

    路徑 clu oca item obj print 句柄 回收 程序 1 #include<windows.h> 2 #include <string> 3 #include <shellapi.h> 4 #includ

    在deepin系統中製作桌面快捷方式

    在使用deepin-wine 安裝一些軟體的時候,每次啟動都需要到.deepinwine目錄下執行deepin-wine xx.exe。筆者在安裝過HeidiSql之後,一直苦於這種情況。比較好的解決方案是,建立一個該應用桌面快捷方式。 下面是具體步驟 製作deepin桌面快捷方式的步驟 新建r

    ubuntu16.04下建立桌面快捷方式

    在ubuntu中,很多應用下載下來都沒有桌面快捷方式,需要通過命令來執行(開啟),很不方便。 所以需要我們手動新增桌面快捷方式。 開啟==/usr/share/applications==,我們可以看到很多圖示, 通過命令視窗輸入ll檢視檢視,發現字尾名都為==.desktop== 所以

    ubuntu中,新增安裝的軟體的桌面快捷方式

    Linux 系統中的Desktop Entry 檔案以desktop為字尾名。Desktop Entry 檔案是 Linux 桌面系統中用於描述程式啟動配置資訊的檔案。此文是以ubuntu16.04為作業系統。整體可以分為以下幾個步驟: (1)新建檔案    所有的軟體圖示都在usr/sha

    安裝火狐瀏覽器並建立桌面快捷方式

    安裝火狐瀏覽器並建立桌面快捷方式 1 安裝火狐安裝步驟: 下載最新版的firefox 在firefox官網下載最新版的Firefox41.0 中文 (簡體) Linux 64-bit;下載後文件名為Firefox-latest-x86_64.tar.bz2; 2.解壓並移至目標路徑/opt 可以直接雙