Android添加快捷方式(Short)到手機桌面

一、在日常開發中,我們經常會遇到這樣的需求就是網桌面添加快捷方式:常見的快捷方式有兩種:一是APP的快捷方式,一是widget插件的快捷方式。下面詳細介紹這兩種情況的應用:

   參考網站:http://www.cnblogs.com/lhxin/archive/2012/05/30/2526525.html

                      http://blog.csdn.net/xubin341719/article/details/7059285

二、APP的快捷方式:

      1、 app快捷方式的實現又有兩種情況,一是直接在桌面生成;一是通過長按桌面,在彈出的快捷菜單中生成。

      2、直接生成快捷方式主要是通過發送系統廣播InstallShortcutReceiver實現的。

           我們先來看一下InstallShortcutReceiver的源代碼。位於packages\apps\Launcher2\src\com\android\launcher2下面:

          

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. /* 
  2.  * Copyright (C) 2008 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package com.android.launcher2;  
  18.   
  19. import java.util.ArrayList;  
  20.   
  21. import android.content.BroadcastReceiver;  
  22. import android.content.Context;  
  23. import android.content.Intent;  
  24. import android.widget.Toast;  
  25.   
  26. import com.android.launcher.R;  
  27.   
  28. public class InstallShortcutReceiver extends BroadcastReceiver {  
  29.     public static final String ACTION_INSTALL_SHORTCUT =  
  30.             "com.android.launcher.action.INSTALL_SHORTCUT";  
  31.   
  32.     // A mime-type representing shortcut data  
  33.     public static final String SHORTCUT_MIMETYPE =  
  34.             "com.android.launcher/shortcut";  
  35.   
  36.     private final int[] mCoordinates = new int[2];  
  37.   
  38.     public void onReceive(Context context, Intent data) {  
  39.         if (!ACTION_INSTALL_SHORTCUT.equals(data.getAction())) {  
  40.             return;  
  41.         }  
  42.   
  43.         int screen = Launcher.getScreen();  
  44.   
  45.         if (!installShortcut(context, data, screen)) {  
  46.             // The target screen is full, let's try the other screens  
  47.             for (int i = 0; i < Launcher.SCREEN_COUNT; i++) {  
  48.                 if (i != screen && installShortcut(context, data, i)) break;  
  49.             }  
  50.         }  
  51.     }  
  52.   
  53.     private boolean installShortcut(Context context, Intent data, int screen) {  
  54.         String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);  
  55.   
  56.         if (findEmptyCell(context, mCoordinates, screen)) {  
  57.             Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);  
  58.             if (intent != null) {  
  59.                 if (intent.getAction() == null) {  
  60.                     intent.setAction(Intent.ACTION_VIEW);  
  61.                 }  
  62.   
  63.                 // By default, we allow for duplicate entries (located in  
  64.                 // different places)  
  65.                 boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);  
  66.                 if (duplicate || !LauncherModel.shortcutExists(context, name, intent)) {  
  67.                     LauncherApplication app = (LauncherApplication) context.getApplicationContext();  
  68.                     app.getModel().addShortcut(context, data,  
  69.                             LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, mCoordinates[0],  
  70.                             mCoordinates[1], true);  
  71.                     Toast.makeText(context, context.getString(R.string.shortcut_installed, name),  
  72.                             Toast.LENGTH_SHORT).show();  
  73.                 } else {  
  74.                     Toast.makeText(context, context.getString(R.string.shortcut_duplicate, name),  
  75.                             Toast.LENGTH_SHORT).show();  
  76.                 }  
  77.   
  78.                 return true;  
  79.             }  
  80.         } else {  
  81.             Toast.makeText(context, context.getString(R.string.out_of_space),  
  82.                     Toast.LENGTH_SHORT).show();  
  83.         }  
  84.   
  85.         return false;  
  86.     }  
  87.   
  88.     private static boolean findEmptyCell(Context context, int[] xy, int screen) {  
  89.         final int xCount = LauncherModel.getCellCountX();  
  90.         final int yCount = LauncherModel.getCellCountY();  
  91.         boolean[][] occupied = new boolean[xCount][yCount];  
  92.   
  93.         ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);  
  94.         ItemInfo item = null;  
  95.         int cellX, cellY, spanX, spanY;  
  96.         for (int i = 0; i < items.size(); ++i) {  
  97.             item = items.get(i);  
  98.             if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {  
  99.                 if (item.screen == screen) {  
  100.                     cellX = item.cellX;  
  101.                     cellY = item.cellY;  
  102.                     spanX = item.spanX;  
  103.                     spanY = item.spanY;  
  104.                     for (int x = cellX; x < cellX + spanX && x < xCount; x++) {  
  105.                         for (int y = cellY; y < cellY + spanY && y < yCount; y++) {  
  106.                             occupied[x][y] = true;  
  107.                         }  
  108.                     }  
  109.                 }  
  110.             }  
  111.         }  
  112.   
  113.         return CellLayout.findVacantCell(xy, 11, xCount, yCount, occupied);  
  114.     }  
  115. }  
通過以上源代碼的閱讀,我相信你基本瞭解創建的原理了。

權限

  要在手機桌面上添加快捷方式,首先需要在manifest中添加權限。

複製代碼
    <!-- 添加快捷方式 -->
    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
    <!-- 移除快捷方式 -->
    <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
    <!-- 查詢快捷方式 -->
    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
複製代碼

 

添加快捷方式

  添加快捷方式,是向桌面應用(launcher)發送相關action的廣播,相關的action如下:

  public static final String ACTION_ADD_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT";

 

  添加快捷方式:

複製代碼
    private void addShortcut(String name) {
        Intent addShortcutIntent = new Intent(ACTION_ADD_SHORTCUT);

        // 不允許重複創建
        addShortcutIntent.putExtra("duplicate", false);// 經測試不是根據快捷方式的名字判斷重複的
        // 應該是根據快鏈的Intent來判斷是否重複的,即Intent.EXTRA_SHORTCUT_INTENT字段的value
        // 但是名稱不同時,雖然有的手機系統會顯示Toast提示重複,仍然會建立快鏈
        // 屏幕上沒有空間時會提示
        // 注意:重複創建的行爲MIUI和三星手機上不太一樣,小米上似乎不能重複創建快捷方式

        // 名字
        addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);

        // 圖標
        addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
                Intent.ShortcutIconResource.fromContext(MainActivity.this,
                        R.drawable.ic_launcher));

        // 設置關聯程序
        Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
        launcherIntent.setClass(MainActivity.this, MainActivity.class);
        launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        addShortcutIntent
                .putExtra(Intent.EXTRA_SHORTCUT_INTENT, launcherIntent);

        // 發送廣播
        sendBroadcast(addShortcutIntent);
    }
複製代碼

 

移除快捷方式

  移除快捷方式的action:

public static final String ACTION_REMOVE_SHORTCUT = "com.android.launcher.action.UNINSTALL_SHORTCUT";

 

  移除快捷方式的方法:

複製代碼
    private void removeShortcut(String name) {
        // remove shortcut的方法在小米系統上不管用,在三星上可以移除
        Intent intent = new Intent(ACTION_REMOVE_SHORTCUT);

        // 名字
        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);

        // 設置關聯程序
        Intent launcherIntent = new Intent(MainActivity.this,
                MainActivity.class).setAction(Intent.ACTION_MAIN);

        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launcherIntent);

        // 發送廣播
        sendBroadcast(intent);
    }
複製代碼

  在兩個手機上測試,發現小米手機上添加了快捷方式後不能移除,三星手機可以。

 

查詢快捷方式

  查詢快捷方式是否存在的方法是從網上其他資料那裏查來的,但是測試查詢的時候失敗了,兩個手機(小米、三星)都查不到。

  先留着代碼以後看看是什麼原因吧:

複製代碼
    private boolean hasInstallShortcut(String name) {

        boolean hasInstall = false;

        final String AUTHORITY = "com.android.launcher2.settings";
        Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
                + "/favorites?notify=true");

        // 這裏總是failed to find provider info
        // com.android.launcher2.settings和com.android.launcher.settings都不行
        Cursor cursor = this.getContentResolver().query(CONTENT_URI,
                new String[] { "title", "iconResource" }, "title=?",
                new String[] { name }, null);

        if (cursor != null && cursor.getCount() > 0) {
            hasInstall = true;
        }

        return hasInstall;

    }
複製代碼

 

 

參考資料

  Android之生成桌面快捷方式(一)

  Android之生成桌面快捷方式(二)

  http://blog.csdn.net/ldj299/article/details/6298452

  http://www.xmumu.com/post/2012-04-01/17357119

  http://www.cnblogs.com/CoolPigs/p/3317234.html

權限

  要在手機桌面上添加快捷方式,首先需要在manifest中添加權限。

複製代碼
    <!-- 添加快捷方式 -->
    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
    <!-- 移除快捷方式 -->
    <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
    <!-- 查詢快捷方式 -->
    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
複製代碼

 

添加快捷方式

  添加快捷方式,是向桌面應用(launcher)發送相關action的廣播,相關的action如下:

  public static final String ACTION_ADD_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT";

 

  添加快捷方式:

複製代碼
    private void addShortcut(String name) {
        Intent addShortcutIntent = new Intent(ACTION_ADD_SHORTCUT);

        // 不允許重複創建
        addShortcutIntent.putExtra("duplicate", false);// 經測試不是根據快捷方式的名字判斷重複的
        // 應該是根據快鏈的Intent來判斷是否重複的,即Intent.EXTRA_SHORTCUT_INTENT字段的value
        // 但是名稱不同時,雖然有的手機系統會顯示Toast提示重複,仍然會建立快鏈
        // 屏幕上沒有空間時會提示
        // 注意:重複創建的行爲MIUI和三星手機上不太一樣,小米上似乎不能重複創建快捷方式

        // 名字
        addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);

        // 圖標
        addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
                Intent.ShortcutIconResource.fromContext(MainActivity.this,
                        R.drawable.ic_launcher));

        // 設置關聯程序
        Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
        launcherIntent.setClass(MainActivity.this, MainActivity.class);
        launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        addShortcutIntent
                .putExtra(Intent.EXTRA_SHORTCUT_INTENT, launcherIntent);

        // 發送廣播
        sendBroadcast(addShortcutIntent);
    }
複製代碼

 

移除快捷方式

  移除快捷方式的action:

public static final String ACTION_REMOVE_SHORTCUT = "com.android.launcher.action.UNINSTALL_SHORTCUT";

 

  移除快捷方式的方法:

複製代碼
    private void removeShortcut(String name) {
        // remove shortcut的方法在小米系統上不管用,在三星上可以移除
        Intent intent = new Intent(ACTION_REMOVE_SHORTCUT);

        // 名字
        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);

        // 設置關聯程序
        Intent launcherIntent = new Intent(MainActivity.this,
                MainActivity.class).setAction(Intent.ACTION_MAIN);

        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launcherIntent);

        // 發送廣播
        sendBroadcast(intent);
    }
複製代碼

  在兩個手機上測試,發現小米手機上添加了快捷方式後不能移除,三星手機可以。

 

查詢快捷方式

  查詢快捷方式是否存在的方法是從網上其他資料那裏查來的,但是測試查詢的時候失敗了,兩個手機(小米、三星)都查不到。

  先留着代碼以後看看是什麼原因吧:

複製代碼
    private boolean hasInstallShortcut(String name) {

        boolean hasInstall = false;

        final String AUTHORITY = "com.android.launcher2.settings";
        Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
                + "/favorites?notify=true");

        // 這裏總是failed to find provider info
        // com.android.launcher2.settings和com.android.launcher.settings都不行
        Cursor cursor = this.getContentResolver().query(CONTENT_URI,
                new String[] { "title", "iconResource" }, "title=?",
                new String[] { name }, null);

        if (cursor != null && cursor.getCount() > 0) {
            hasInstall = true;
        }

        return hasInstall;

    }
複製代碼

 

 

參考資料

  Android之生成桌面快捷方式(一)

  Android之生成桌面快捷方式(二)

  http://blog.csdn.net/ldj299/article/details/6298452

  http://www.xmumu.com/post/2012-04-01/17357119

  http://www.cnblogs.com/CoolPigs/p/3317234.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章