写在前面的话
AndroidManifest.xml这个文件如果你搞过android相关的东西(如果没搞过,我希望你去搞一下), 你一定很熟悉. 我们在工作可能会有一些动态修改或者获取manifest里面的值的情况, 那么今天涛哥就带你研究一下.
开始写脚本
准备
- 我们把脚本放到跟AndroidManifest.xml同级的目录
- 下面我们来看一下manifest的基本结构
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.me"
android:versionCode="481"
android:versionName="3.1.1">
<uses-permission android:name="android.permission.INTERNET" />
<meta-data android:name="TEST_CHANNEL" android:value="test"/>
<application
android:name=".Application"
android:icon="@drawable/icon"
android:label="@string/app_name" >
<activity
android:name=".MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.test.TestService"
android:exported="true"
android:process=":DownloadingService" >
</service>
</application>
</manifest>
- 因为manifest是一个xml文件. 所以我们就得需要用到能解析xml的库. 这里面我们使用xml.etree.cElementTree库
import xml.etree.cElementTree as ET #引用库,并简写成ET
#变量
SPACE = '{http://schemas.android.com/apk/res/android}' #这个后面会讲
打开AndroidManifest.xml
curPath = os.getcwd() + '/' #获取当前目录的绝对路径
tree = ET.parse(curPath + 'AndroidManifest.xml') #打开xml
root = tree.getroot() #找到manifest的根文件
print(root.tag) #我们输出一下就知道root目录就是manifest目录
print(root.attrib) #输出一下root目录的成员
我们来看一下root.attrib的输出:
{'{http://schemas.android.com/apk/res/android}versionName': '1.0', '{http://schemas.android.com/apk/res/android}versionCode': '1', 'package': 'com.carrot.iceworld.channel'}
在versionName和versionCode前面的是什么? 没错, 就是我们上面配置的SPACE,所以如果我们要想正确的获取到值,别忘了加上.
获取和修改versionName和versionCode
通过上面我们可以看到, versionName和versionCode都是属于manifest根目录的成员
#获取
versionName = root.get(SPACE + 'versionName')
versionCode = root.get(SPACE + 'versionCode')
#修改
root.set(SPACE + 'versionName', '9.9.9')
root.set(SPACE + 'versionCode', '999')
#写入
tree.write('manifest的绝对路径')
处理权限
因为权限属性(uses-permission)在manifest一级子属性
for child in root.iter('uses-permission'):
#1.输出所有权限
print(child.get(SPACE + 'name'))
#2.删除某一个权限
if (child.get(SPACE + 'name') == 'android.permission.INTERNET'):
root.remove(child)
#3.增加一个新权限, 我们要新建一个xml的element, 然后按照格式制造一个新的permission, 插入到原manifest里
permission = ET.Element('uses-permission')
permission.set(SPACE + 'name', 'android.permission.INTERNET')
root.insert(-1, permission) #为了方便插入都最后了
处理activity
因为activity不是manifest的一级子属性, 而是application的子属性
#1.先获取application目录
application = root.find('application')
#2.遍历所有activity, 打印name
for item in application.iter('activity'):
print(item.attrib.get(SPACE + 'name'))
#3.增加一个新的activity
activity = ET.Element('activity')
activity.set(SPACE + 'name', "com.test.MainActivity")
activity.set(SPACE + 'configChanges', "keyboardHidden|orientation|screenSize")
application.insert(-1, activity)
处理meta和service
meta和service因为跟acitity是同级的, 所以处理方法一样, 我就不赘述了
总结
其实如果你搞明白了,manifest的本质是xml, 然后知道如何用python操作xml, 那么这个问题就变得很简单
参考
https://docs.python.org/2/library/xml.etree.elementtree.html#element-objects
网友评论