使用Android的知道,有快捷方式這么一說,可以通過長按桌面來添加,也有的是第一次運行時候詢問是否需要安裝,有的直接放在桌面(MIUI是直接放在桌面的),那么為了驅(qū)動用戶使用,有些應(yīng)用在安裝以后便直接安裝了快捷方式,還有些應(yīng)用是在用戶第一次進(jìn)入的時候,詢問用戶是否安裝快捷方式,那么接下來就看看快捷方式的實現(xiàn)。
安裝即帶
這個實現(xiàn)方法比較簡單,直接在AndroidManifest.xml里面就可申明
1 <activity-alias
2 android:name="demoAlias"
3 android:icon="@drawable/logo"
4 android:label="demoAliasLabel"
5 android:targetActivity=".MainActivity" >
6 <intent-filter>
7 <action android:name="android.intent.action.MAIN" />
8
9 <category android:name="android.intent.category.DEFAULT" />
10 <category android:name="android.intent.category.LAUNCHER" />
11 </intent-filter>
12 </activity-alias>
name表示快捷方式顯示的名字
icon表示快捷方式圖標(biāo)
targetActivity表示點擊快捷方式啟動的活動
這個表情直接申明在Application中即可,有一點需要說明的是從快捷方式進(jìn)入和從默認(rèn)桌面Activity進(jìn)入,對于Application有一些參數(shù)是有差異的,例如
getIntent().getComponent().getClassName()
主APP進(jìn)入:{package}.MainActivity
快捷方式進(jìn)入:{package}.demoAlias
注意:這種本質(zhì)上不屬于快捷方式,只是在Launcher中添加了一個APP入口的副本,重點在下面的動態(tài)創(chuàng)建。
動態(tài)創(chuàng)建
方式1:托管給系統(tǒng)桌面的快捷方式來創(chuàng)建
對于Android原生系統(tǒng),桌面空白處長按可以添加小控件、快捷方式等。點擊快捷方式,里面會呈現(xiàn)申明了快捷方式的APP快捷方式列表。
那么如何申明快捷方式呢?這就是第一步
第一步:申明快捷方式
1 <activity-alias
2 android:name="DemoShortCutName"
3 android:icon="@drawable/logo"
4 android:label="DemoShortCutLabel"
5 android:targetActivity=".DynamicShortcut" >
6 <intent-filter>
7 <action android:name="android.intent.action.CREATE_SHORTCUT" />
8 </intent-filter>
9 </activity-alias>
快捷方式也是一個Activity,可以看成一個虛擬的Activity不需要實體的承載
name:表示這個Activity的標(biāo)示,通過getClassName()會獲取name屬性
icon:在桌面快捷方式列表中的圖標(biāo)
label:在桌面快捷方式列表中的文字
targetActivity:既然說他是一個虛擬的Activity,那么需要制定一個實體,也即快捷方式的啟動
通過申明android.intent.action.CREATE_SHORTCUT申明,讓這個虛擬的Activity加入到桌面快捷方式列表中。
如果在桌面快捷方式列表中點擊這個快捷方式,會發(fā)現(xiàn)僅僅是啟動了TargetActivity,在桌面上并沒有看到這個快捷方式被添加,那么接下來需要在TargetActivity中去實現(xiàn)這個。
第二步:實現(xiàn)快捷方式的添加
1 private void generateShortcut() {
2 // 快捷方式要啟動的Activity
3 Intent shortcutIntent = new Intent();
4 shortcutIntent.setClassName(this, this.getClass().getName());
5
6 // 動態(tài)生成快捷方式
7 Intent intent = new Intent();
8 intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
9 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "test");
10 Parcelable iconResource = Intent.ShortcutIconResource.fromContext(this, R.drawable.icon0);
11 intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
12 // 將生成的快捷方式遞交給系統(tǒng)生成桌面快捷方式
13 setResult(RESULT_OK, intent);
14 }
快捷方式的添加方法和在AndroidManifest中申明遠(yuǎn)離基本相同。
添加原理知道了,那么在什么時候去觸發(fā)添加動作
第三步:結(jié)合快捷方式列表中點擊生成快捷方式
TargetActivity可以是單獨為創(chuàng)建快捷方式功能而存在,也可以是應(yīng)用程序的啟動頁面。那么來看下在啟動頁作為TargetActivity的時候,該如何觸發(fā)添加快捷方式,
代碼實現(xiàn)原理是:
1.點擊桌面快捷方式
2.啟動TargetActivity
3.添加快捷方式到桌面。
期望結(jié)果是沒有第二步,點擊直接添加到桌面,那么在實現(xiàn)的時候,就可以做下處理:
1 @Override
2 protected void onCreate(Bundle savedInstanceState) {
3 super.onCreate(savedInstanceState);
4 setContentView(R.layout.dynamic_shortcut);
5
6 final String intentAction = getIntent().getAction();
7 if (Intent.ACTION_CREATE_SHORTCUT.equals(intentAction)) {
8 generateShortcut();
9 finish();
10 return;
11 }
12 }
這樣的話,就達(dá)到了期望的結(jié)果,到此為止,快捷方式就添加完畢,如果想做成類似“金山開關(guān),360快捷開關(guān)”這樣的,可以專門做個Dialog樣式的Activity來作為TargetActivity。
方式2:通過代碼在任意時刻通過任意方式創(chuàng)建
例如通過點擊應(yīng)用里面的某個Button或者應(yīng)用程序第一次啟動,或者。。。,這里看下原理
1 private void createShortcut() {
2 // 快捷方式要啟動的Activity
3 Intent target = new Intent();
4 target.setClassName(this, this.getClass().getName());
5
6 // 動態(tài)生成快捷方式
7 Intent shortcutIntent = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
8 shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "shortcutName");
9 shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(this, R.drawable.icon1));
10 shortcutIntent.putExtra("duplicate", false);
11 shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, target);
12
13 // 利用receiver通知系統(tǒng)創(chuàng)建快捷方式
14 sendBroadcast(shortcutIntent);
15
16 }
可以看到,和第一種方式實現(xiàn)基本一樣,只不過通知系統(tǒng)生成的方式不一樣,此處用的是通知。其實第一種方式也可以利用通知來實現(xiàn)。
添加“duplicate”是表示快捷方式不能重復(fù)添加,當(dāng)然這塊和第一種實現(xiàn)方式重復(fù)添加不沖突。
那么到這里,第二種方式核心實現(xiàn)完成。
擴(kuò)展
上述僅僅介紹了核心實現(xiàn),那么對于快捷方式的添加,當(dāng)然還需要申明創(chuàng)建快捷方式的權(quán)限了:
1 <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
這個當(dāng)然不能忘掉。
還有對于MIUI這種神奇的rom是沒有快捷方式這一說的,大家測試的時候,多用些不同的rom機(jī)器試試。
那么既然可以重復(fù)創(chuàng)建快捷方式,如果想限制只能有一個快捷方式存在,怎么辦,上面設(shè)置“duplicate”屬性只能限制第二種方式通知添加,而且會有提示,且是系統(tǒng)去判斷的,那么我們怎么能自己判斷是否已經(jīng)存在快捷方式了呢,當(dāng)然可以,來一次看看。
實現(xiàn)思路可以這么想:快捷方式在桌面,那么如果能獲取系統(tǒng)桌面的應(yīng)用程序?qū)傩,判斷是否我的?yīng)用在被放到了桌面就行。
那么來看下代碼:
1 private boolean hasShortcut() {
2 final String AUTHORITY = "com.android.launcher.settings";
3 final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/favorites?notify=true");
4 Cursor c = getContentResolver().query(
5 CONTENT_URI,
6 new String[] { "title" },
7 "title=?",
8 new String[] { "test" },
9 null);
10 if (c != null && c.moveToNext()) {
11 return true;
12 }
13 return false;
14 }
簡單的說明下:
通過Context的getContentResolve獲取系統(tǒng)的共享數(shù)據(jù),在共享數(shù)據(jù)中,查找指定Uri的數(shù)據(jù),也即launcher中的favorite表,也即快捷方式表。
然后query的參數(shù)是篩選表的title列,并且title=“test”的行數(shù)據(jù),如果查詢有結(jié)果,表示快捷方式名為test的存在,也即返回快捷方式已經(jīng)添加到桌面。
那么如果你時間了,如果你的測試機(jī)是MIUI,或者HTC等rom,你會發(fā)現(xiàn)c為null,怎么回事,解釋下
android系統(tǒng)桌面的基本信息由一個launcher.db的Sqlite數(shù)據(jù)庫管理,里面有三張表,其中一張表就是favorites。這個db文件一般放在data/data/com.android.launcher(launcher2)文件的databases下。但是對于不同的rom會放在不同的地方,例如MIUI放在data/data/com.miui.home/databases下面,htc放在data/data/com.htc.launcher/databases下面,那么如何用程序來找到這個認(rèn)證標(biāo)示呢
1 private String getAuthorityFromPermission(Context context, String permission) {
2 if (TextUtils.isEmpty(permission)) {
3 return null;
4 }
5 List<PackageInfo> packs = context.getPackageManager().getInstalledPackages(PackageManager.GET_PROVIDERS);
6 if (packs == null) {
7 return null;
8 }
9 for (PackageInfo pack : packs) {
10 ProviderInfo[] providers = pack.providers;
11 if (providers != null) {
12 for (ProviderInfo provider : providers) {
13 if (permission.equals(provider.readPermission) || permission.equals(provider.writePermission)) {
14 return provider.authority;
15 }
16 }
17 }
18 }
19 return null;
20 }
通過Permission來找到這個Authority,那么修改驗證方法:
1 private boolean hasShortcut() {
2 final String AUTHORITY = getAuthorityFromPermission(getApplicationContext(), "com.android.launcher.permission.READ_SETTINGS");
3 final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/favorites?notify=true");
4 Cursor c = getContentResolver().query(
5 CONTENT_URI,
6 new String[] { "title" },
7 "title=?",
8 new String[] { "test" },
9 null);
10 if (c != null && c.moveToNext()) {
11 return true;
12 }
13 return false;
14 }
這樣就可以了,對于某些系統(tǒng),找不到的話,可能是由于權(quán)限原因或者是系統(tǒng)文件順壞等,你可以通過es explorer工具去找下該文件,并試著用DDMS去讀取
DDMS讀取文件的時候,我出現(xiàn)了權(quán)限問題,參考了http://www.cnblogs.com/zdz8207/archive/2012/08/31/android-file-explore.html
總結(jié)
OK,快捷方式通過一天的搜索,試驗,找問題,找機(jī)器試,總結(jié)完畢,把網(wǎng)上出現(xiàn)的一些問題和解決方案都對應(yīng)的總結(jié)了下,希望對大家有幫組。