开发:不可以
产品:我们可以动态更换App在Launcher里面的Icon吗
开发:不可以
产品:我们可以动态更换App在Launcher里面的Icon吗
开发:不可以
产品:我们可以动态更换App在Launcher里面的Icon吗
开发:让我想想……
原理1——activity-alias
在AndroidMainifest中,有两个属性:
1
2
3
4
|
// 决定应用程序最先启动的Activity
android
.
intent
.
action
.
MAIN
// 决定应用程序是否显示在程序列表里
android
.
intent
.
category
.
LAUNCHER
|
另外,还有一个activity-alias属性,这个属性可以用于创建多个不同的入口,相信做过系统Setting和Launcher开发的开发者在系统的源码中应该见过很多。
原理2——PM.setComponentEnabledSetting
PackageManager是一个大统领类,可以管理所有的系统组件,当然,如果Root了,你还可以管理其它App的所有组件,一些系统优化工具就是通过这个方式来禁用一些后台Service的。
使用方式异常简单:
1
2
3
4
5
6
7
8
9
10
11
|
private
void
enableComponent
(
ComponentName
componentName
)
{
mPm
.
setComponentEnabledSetting
(
componentName
,
PackageManager
.
COMPONENT_ENABLED_STATE_ENABLED
,
PackageManager
.
DONT_KILL_APP
)
;
}
private
void
disableComponent
(
ComponentName
componentName
)
{
mPm
.
setComponentEnabledSetting
(
componentName
,
PackageManager
.
COMPONENT_ENABLED_STATE_DISABLED
,
PackageManager
.
DONT_KILL_APP
)
;
}
|
根据PackageManager.COMPONENT_ENABLED_STATE_ENABLED和PackageManager.COMPONENT_ENABLED_STATE_DISABLED这两个标志量和对应的ComponentName,就可以控制一个组件的是否启用。
动态换Icon
有了上面的两个原理,来实现动态更换Icon就只剩下思路问题了。
首先,我们创建一个Activity,作为默认的入口并带着默认的图片,再创建一个双11的activity-alias,指向默认的Activity并带有双11的图片,再创建一个双12的activity-alias,指向默认的Activity并带有双12的图片……等等等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<
activity
android
:
name
=
".MainActivity"
>
<
intent
-
filter
>
<
action
android
:
name
=
"android.intent.action.MAIN"
/
>
<
category
android
:
name
=
"android.intent.category.LAUNCHER"
/
>
<
/
intent
-
filter
>
<
/
activity
>
<
activity
-
alias
android
:
name
=
".Test11"
android
:
enabled
=
"false"
android
:
icon
=
"@drawable/s11"
android
:
label
=
"双11"
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
=
".Test12"
android
:
enabled
=
"false"
android
:
icon
=
"@drawable/s12"
android
:
label
=
"双12"
android
:
targetActivity
=
".MainActivity"
>
<
intent
-
filter
>
<
action
android
:
name
=
"android.intent.action.MAIN"
/
>
<
category
android
:
name
=
"android.intent.category.LAUNCHER"
/
>
<
/
intent
-
filter
>
<
/
activity
-
alias
>
|
等等,这样有个问题,那就是这样会在Launcher上显示3个入口,所以,默认我们会把这些activity-alias先禁用,等到要用的时候再启用,养兵千日,用兵一时。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
public
class
MainActivity
extends
AppCompatActivity
{
private
ComponentName
mDefault
;
private
ComponentName
mDouble11
;
private
ComponentName
mDouble12
;
private
PackageManager
mPm
;
@
Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
setContentView
(
R
.
layout
.
activity_main
)
;
mDefault
=
getComponentName
(
)
;
mDouble11
=
new
ComponentName
(
getBaseContext
(
)
,
"com.xys.changeicon.Test11"
)
;
mDouble12
=
new
ComponentName
(
getBaseContext
(
)
,
"com.xys.changeicon.Test12"
)
;
mPm
=
getApplicationContext
(
)
.
getPackageManager
(
)
;
}
public
void
changeIcon11
(
View
view
)
{
disableComponent
(
mDefault
)
;
disableComponent
(
mDouble12
)
;
enableComponent
(
mDouble11
)
;
}
public
void
changeIcon12
(
View
view
)
{
disableComponent
(
mDefault
)
;
disableComponent
(
mDouble11
)
;
enableComponent
(
mDouble12
)
;
}
private
void
enableComponent
(
ComponentName
componentName
)
{
mPm
.
setComponentEnabledSetting
(
componentName
,
PackageManager
.
COMPONENT_ENABLED_STATE_ENABLED
,
PackageManager
.
DONT_KILL_APP
)
;
}
private
void
disableComponent
(
ComponentName
componentName
)
{
mPm
.
setComponentEnabledSetting
(
componentName
,
PackageManager
.
COMPONENT_ENABLED_STATE_DISABLED
,
PackageManager
.
DONT_KILL_APP
)
;
}
}
|
OK了,禁用默认的Activity后,启用双11的activity-alias,结果不变还是指向了默认的Activity,但图标已经发生了改变。
根据ROM的不同,在禁用了组件之后,会等一会,Launcher会自动刷新图标。
效果参考下图。