免root,反编译应用使其应用内状态栏透明

此文章只针对魅族手机Flyme 3.0以上ROM

前面写的两篇文章《免root,反编译软件去掉SmartBar》以及《针对魅族Flyme OS让应用中状态栏呈现透明效果》,从这两篇文章得到此想法——反编译应用使其应用内状态栏透明。

###思路

自己先写一个超级简单的更改应用中状态栏为透明的DEMO,然后反编译此DEMO,得到更改应用中状态栏为透明的smali代码。再去反编译需要更改状态栏为透明的应用,把刚才得到的smali代码添加进去。

###代码

更改应用中状态栏为透明的JAVA代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 设置通知栏透明
WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
// 反射调用Meizu API
Class<?> mzLpClass = localLayoutParams.getClass();
try {
Field meizuFlagsField = mzLpClass.getField("meizuFlags");
int meizuFlags = (Integer) meizuFlagsField.get(localLayoutParams);
meizuFlags |= 0x40; // 设置状态栏透明
meizuFlagsField.set(localLayoutParams, meizuFlags);
} catch (NoSuchFieldException e) {
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
}
getWindow().setAttributes(localLayoutParams);

更改应用中状态栏为透明的smali代码:

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
    invoke-virtual {p0}, Lcom/buzzpia/aqua/launcher/app/HomeActivity;->getWindow()Landroid/view/Window;

move-result-object v4

invoke-virtual {v4}, Landroid/view/Window;->getAttributes()Landroid/view/WindowManager$LayoutParams;

move-result-object v0

.local v0, localLayoutParams:Landroid/view/WindowManager$LayoutParams;
invoke-virtual {v0}, Ljava/lang/Object;->getClass()Ljava/lang/Class;

move-result-object v3

.local v3, mzLpClass:Ljava/lang/Class;,"Ljava/lang/Class<*>;"
:try_start_0
const-string v4, "meizuFlags"

invoke-virtual {v3, v4}, Ljava/lang/Class;->getField(Ljava/lang/String;)Ljava/lang/reflect/Field;

move-result-object v2

.local v2, meizuFlagsField:Ljava/lang/reflect/Field;
invoke-virtual {v2, v0}, Ljava/lang/reflect/Field;->get(Ljava/lang/Object;)Ljava/lang/Object;

move-result-object v4

check-cast v4, Ljava/lang/Integer;

invoke-virtual {v4}, Ljava/lang/Integer;->intValue()I

move-result v1

.local v1, meizuFlags:I
or-int/lit8 v1, v1, 0x40

invoke-static {v1}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;

move-result-object v4

invoke-virtual {v2, v0, v4}, Ljava/lang/reflect/Field;->set(Ljava/lang/Object;Ljava/lang/Object;)V
:try_end_0
.catch Ljava/lang/NoSuchFieldException; {:try_start_0 .. :try_end_0} :catch_2
.catch Ljava/lang/IllegalAccessException; {:try_start_0 .. :try_end_0} :catch_1
.catch Ljava/lang/IllegalArgumentException; {:try_start_0 .. :try_end_0} :catch_0

.end local v1 #meizuFlags:I
.end local v2 #meizuFlagsField:Ljava/lang/reflect/Field;

:goto_0
invoke-virtual {p0}, Lcom/buzzpia/aqua/launcher/app/HomeActivity;->getWindow()Landroid/view/Window;

move-result-object v4

invoke-virtual {v4, v0}, Landroid/view/Window;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V

return-void

:catch_0
move-exception v4

goto :goto_0

:catch_1
move-exception v4

goto :goto_0

:catch_2
move-exception v4

goto :goto_0
.end method

###注意

return-void是当前方法的返回语句。
.end method是当前方法的结束标记。
根据当前Activity,请将Lcom/buzzpia/aqua/launcher/app/HomeActivity替换为当前的Activity。例如你的Activity是 com.example.test.MainActivity,则将Lcom/buzzpia/aqua/launcher/app/HomeActivity替换为Lcom/example/test/MainActivity

###使用方法

如果这篇文章《免root,反编译软件去掉SmartBar》,你看懂了的话,相信你已经想到怎么添加smali代码了——打开activity后,查找oncreate,找到后面接着的return-void.end method。一般来说,return-void下一行就是.end method,只需要将更改应用中状态栏为透明的smali代码替换这2行即可。然后保存编译生成APK文件。