動(dòng)態(tài)更換圖標(biāo)
首先先解決下實(shí)際問題箕母。動(dòng)態(tài)更換圖標(biāo)。android可以根據(jù)activity-alias來設(shè)置桌面可以存在多個(gè)icon俱济,那直接通過設(shè)置某個(gè)activity-alias顯示其他隱藏即可實(shí)現(xiàn)嘶是。下面上代碼
在xml添加多個(gè)activity-alias、刪除mainActivity標(biāo)簽的<categoryandroid:name="android.intent.category.LAUNCHER" />屬性
<activity-alias
android:name=".icon_tag"
android:enabled="true"
android:icon="@mipmap/ic_launcher"
android:label="111111"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".icon_tag_1212"
android:enabled="false"
android:icon="@mipmap/head"
android:label="222222"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
</application>
如上圖 指向的targetActivity可以是不同的蛛碌,這樣啟動(dòng)的activity也是不是一樣的聂喇,主要的是name要和代碼中保持一致
2、代碼中控制活動(dòng)和普通圖標(biāo)的切換
/**
* @param useCode =1左医、為活動(dòng)圖標(biāo) =2 為用普通圖標(biāo) =3授帕、不啟用判斷
*/
private void switchIcon(int useCode) {
try {
//要跟manifest的activity-alias 的name保持一致
String icon_tag = "top.vchao.icon.icon_tag";
String icon_tag_1212 = "top.vchao.icon.icon_tag_1212";
if (useCode != 3) {
PackageManager pm = getPackageManager();
ComponentName normalComponentName = new ComponentName(
getBaseContext(),
icon_tag);
//正常圖標(biāo)新狀態(tài)
int normalNewState = useCode == 2 ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
if (pm.getComponentEnabledSetting(normalComponentName) != normalNewState) {//新狀態(tài)跟當(dāng)前狀態(tài)不一樣才執(zhí)行
pm.setComponentEnabledSetting(
normalComponentName,
normalNewState,
PackageManager.DONT_KILL_APP);
}
ComponentName actComponentName = new ComponentName(
getBaseContext(),
icon_tag_1212);
//正常圖標(biāo)新狀態(tài)
int actNewState = useCode == 1 ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
if (pm.getComponentEnabledSetting(actComponentName) != actNewState) {//新狀態(tài)跟當(dāng)前狀態(tài)不一樣才執(zhí)行
pm.setComponentEnabledSetting(
actComponentName,
actNewState,
PackageManager.DONT_KILL_APP);
}
}
} catch (Exception e) {
}
}
上圖的icon_tag和icon_tag_1212要和你xml中的activity-alias的name保持一致
補(bǔ)坑。浮梢。activity-alias的name是不能改的!!
如果當(dāng)前版本的是icon_tag_1212跛十,下版本改成icon_tag_act,就會(huì)導(dǎo)致系統(tǒng)找icon_tag_1212找不到秕硝,導(dǎo)致桌面無圖標(biāo)芥映,應(yīng)用打不開!T恫颉奈偏!此坑嚴(yán)重請(qǐng)注意
activity-alias標(biāo)簽元素
實(shí)現(xiàn)了功能,下面就來看一下原理躯护。所周知惊来,AndroidManifest是一個(gè)xml文件,它包含很多標(biāo)簽元素棺滞,如application裁蚁、activity、receiver等继准,其中有一個(gè)叫做activity-alias枉证,因?yàn)樵摌?biāo)簽平時(shí)很少用到,可能大家對(duì)這個(gè)標(biāo)簽還不是很熟悉移必。
activity-alias室谚,顧名思義,即activity的別名崔泵∶氤啵看到這里,大家會(huì)想那它究竟是哪個(gè)Activity的別名呢憎瘸?我們?cè)趧?chuàng)建一個(gè)Activity時(shí)倒脓,必須在AndroidManifest中靜態(tài)聲明該Activity,同時(shí)配置android:name含思、android:label崎弃、android:icon等屬性,還可配置intent-filter含潘。對(duì)于activity-alias標(biāo)簽饲做,它有一個(gè)屬性叫android:targetActivity,這個(gè)屬性就是用來為該標(biāo)簽設(shè)置目標(biāo)Activity的遏弱,或者說它就是這個(gè)目標(biāo)Activity的別名盆均。至此我們已經(jīng)明白activity-alias并非代表一個(gè)獨(dú)立的Activity,而是為一個(gè)已經(jīng)存在的Activity創(chuàng)建的別名漱逸。
activity-alias功能
知道了activity-alias的概念泪姨,那么它的功能是什么呢游沿?activity-alias作為一個(gè)已存在Activity的別名,則應(yīng)該可以通過該別名標(biāo)簽聲明快速打開目標(biāo)Activity肮砾。因此activity-alias可用來設(shè)置某個(gè)Activity的快捷入口诀黍,可以放在桌面上或者通過該別名被其他組件快速調(diào)起。該標(biāo)簽元素支持一些屬性及intent-filter仗处、meta-data等配置眯勾,因此可以觸發(fā)一些跟目標(biāo)Activity不同的功能邏輯,雖然打開的是同一個(gè)Activity婆誓。舉個(gè)簡單的例子吃环,如之前需要先打開主界面,然后才能點(diǎn)擊進(jìn)入某個(gè)Activity洋幻,如果使用activity-alias為該Activity配置一個(gè)快捷入口郁轻,甚至可以為其在桌面生成一個(gè)圖標(biāo),然后點(diǎn)擊桌面圖標(biāo)可直接進(jìn)入該Activity文留,該功能可滿足某些需要快速到達(dá)功能界面的需求范咨。
activity-alias語法及聲明
其基本語法如下
<activity-alias android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
android:name="string"
android:permission="string"
android:targetActivity="string" >
. . .
</activity-alias>
部分屬性說明如下
- android:enable 該屬性用來決定目標(biāo)Activity可否通過別名被系統(tǒng)實(shí)例化,默認(rèn)為true厂庇。需要注意的是application也有enable屬性渠啊,只用當(dāng)它們同時(shí)為true時(shí),activity-alias的enable才生效权旷。
- android:exported 該屬性為true的話替蛉,則目標(biāo)Activity可被其他應(yīng)用調(diào)起,如為false則只能被應(yīng)用自身調(diào)起拄氯。其默認(rèn)值根據(jù)activity-alias是否包含intent-filter元素決定躲查,如果有的話,則默認(rèn)為true译柏;沒有的話則為false镣煮。其實(shí)也很好理解,如果有intent-filter鄙麦,則目標(biāo)Activity可以匹配隱式Intent典唇,因此可被外部應(yīng)用喚起;如果沒有intent-filter胯府,則目標(biāo)Activity要被調(diào)起的話必須知道其精確類名介衔,因?yàn)橹挥袘?yīng)用本身才知道精確類名,所以此時(shí)默認(rèn)為false骂因。
- android:icon 該屬性就比較好玩了炎咖,允許自定義icon,可以不同于應(yīng)用本身在桌面的icon。如果需要在桌面上創(chuàng)建快捷入口乘盼,也許產(chǎn)品會(huì)要求換個(gè)不同的icon升熊。
- android:label 該屬性類似于android:icon,圖標(biāo)都換了绸栅,換個(gè)名稱也合情合理吧级野,此屬性就是為此而生的。
- android:name 該屬性可以為任意字符串阴幌,但最好符合類名命名規(guī)范勺阐。activity元素的name屬性實(shí)質(zhì)上都會(huì)指向一個(gè)具體的Activity類卷中,而activity-alias的name屬性僅作為一個(gè)唯一標(biāo)識(shí)而已矛双。
- android:permission 該屬性指明了通過別名聲明調(diào)起目標(biāo)Activity所必需的權(quán)限。
- android:targetActivity 該屬性指定了目標(biāo)Activity蟆豫,即通過activity-alias調(diào)起的Activity是哪個(gè)议忽,此屬性其實(shí)類似于activity標(biāo)簽中的name屬性,需要規(guī)范的Activity包名類名十减。
看了以上幾個(gè)主要屬性栈幸,大家應(yīng)該意識(shí)到activity-alias的屬性是activity屬性的子集,如果是activity-alias和activity共有的屬性帮辟,則以activity-alias為準(zhǔn)速址,目標(biāo)Activity中的設(shè)置并不會(huì)在activity-alias中生效;如果是僅activity才有的屬性由驹,則為目標(biāo)Activity配置的屬性會(huì)在activity-alias中生效芍锚。
activity-alias可以設(shè)置自己的intent-filter或meta-date,最常用的就是設(shè)置如下intent-filter從而在桌面Launcher上創(chuàng)建一個(gè)快捷入口:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
另外需要注意的一點(diǎn)是蔓榄,在AndroidManifest配置文件中并炮,activity-alias標(biāo)簽元素必須聲明在目標(biāo)Acitvity對(duì)應(yīng)的activity標(biāo)簽元素之后,否則會(huì)編譯錯(cuò)誤甥郑。
activity-alias用法示例
到此大家已經(jīng)對(duì)activity-alias了解的比較深入了逃魄,來看一個(gè)activity-alias的經(jīng)典用法:為某個(gè)Activity在桌面創(chuàng)建一個(gè)快捷入口。
代碼很簡單澜搅,應(yīng)用包含兩個(gè)Activity:MainActivity和SecondActivity伍俘,MainActivity有一個(gè)Button,點(diǎn)擊跳轉(zhuǎn)到SecondActivity勉躺;我們?yōu)镾econdActivity配置一個(gè)activity-alias標(biāo)簽元素养篓,在桌面上為其創(chuàng)建一個(gè)快捷入口,點(diǎn)擊可以直接打開SecondActivity赂蕴。
該示例應(yīng)用的AndroidManifest.xml內(nèi)容如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="me.geed.activityalias">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity"></activity>
<activity-alias
android:name="SecondActivityAlias"
android:label="Alias快捷入口"
android:targetActivity=".SecondActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
</application>
</manifest>
將應(yīng)用部署到手機(jī)上柳弄,你會(huì)發(fā)現(xiàn)生成了兩個(gè)桌面圖標(biāo)(此處由于沒有為activity-alias另指定icon,因此兩者icon相同),名稱分別為“ActivityAlias”和“Alias快捷入口”碧注。
點(diǎn)擊“ActivityAlias”應(yīng)用圖標(biāo)嚣伐,會(huì)啟動(dòng)MainActivity,在MainActivity中點(diǎn)擊Button萍丐,跳轉(zhuǎn)到SecondActivity轩端。
點(diǎn)擊“Alias快捷入口”圖標(biāo),則可以直接打開SecondActivity逝变,且SecondActivity的title為我們?cè)赼ctivity-alias中設(shè)置的 label屬性名稱基茵。