不知道什么是Perl猛戳这个链接 http://zh.wikipedia.org/wiki/Perl
任务:
随着手机/平板的各方面性能的不断发展(CPU,内存,存储),Android这个移动领域绝对的霸主也升级到了4.1版本,软硬件的提高意味着人们对使用体验有了越来越高的要求,在移动设备里面安装的App也越来越多,但是Android总是以刷机为乐趣的,每次刷机就意味着要备份软件(这里不讨论软件数据的备份),也就意味着备份apk,apk一多,管理起来就成了一件头痛的事情,最起码的,我们要知道我们都备份了哪些apk,最最起码要知道它们叫什么名字,因为不管在windows还是linux平台下面,都是无法直接解析apk的名字的。所以不管你是以什么样的方式备份出来的apk,它总不可能是按你的要求来命名的,今天的目标/任务就是把apk按你的要求来命名。
方法:
由于在windows/linux上无法直接通过系统的文件管理器解析apk的名字等等属性,所以必须要借助别的工具,这其中最好的必须是Google自家的aapt工具,不知道aapt是什么?猛戳这个链接http://www.ltesting.net/ceshi/ceshijishu/sjcs/android/2012/0511/204843.html。aapt可以直接读取出来一个apk的各种属性,比如AndroidManifest.xml里面定义的包名,软件名,版本号,使用的权限等等信息。使用aapt读取出来的信息是一大堆,所以必须要使用正则表达式的模式匹配获取我们所需要的信息,然后再根据要求来给相应的apk重命名。注意,这个地方是要给当前目录下所有的apk自动重命名,所以,必然要用到for语句(在perl里面是foreach)。
先介绍一下aapt的使用。这里只介绍用到的功能,dump,具体命令是aapt d(ump) badging mms.apk。它会打印出如下的信息:
package: name='com.elsdoerfer.android.autostarts' versionCode='24' versionName='1.7.7'
sdkVersion:'4'
targetSdkVersion:'14'
application-label:'Autostarts'
application-label-zh:'自启管家'
application-icon-160:'res/drawable/icon.png'
application-icon-240:'res/drawable-hdpi/icon.png'
application: label='Autostarts' icon='res/drawable/icon.png'
launchable-activity: name='com.elsdoerfer.android.autostarts.ListActivity' label='Autostarts' icon=''
uses-permission:'android.permission.WRITE_SETTINGS'
uses-permission:'android.permission.WRITE_SECURE_SETTINGS'
uses-permission:'android.permission.CHANGE_COMPONENT_ENABLED_STATE'
uses-configuration:
uses-gl-es:'0xffffffff'
uses-feature:'android.hardware.touchscreen'
uses-implied-feature:'android.hardware.touchscreen','assumed you require a touch screen unless explicitly made optional'
main
other-activities
supports-screens: 'small' 'normal' 'large' 'xlarge'
supports-any-density: 'true'
locales: '--_--' 'zh'
densities: '160' '240'
注意,在windows的cmd里面,编码是cp936,和aapt默认输出的utf8是冲突的,所以如果你直接执行上述命令,会在cmd的窗口中看到所有的中文都是乱码的,正确的方法是把输出的结果重定向到文本文件里面,再用记事本或其它的工具打开输出的文本文件,就不会有乱码了。关于aapt的其它用法请自行查看帮助,直接输入aapt即可。
我们的目标就是要从上面的那一堆的数据中,用perl里面的正则表达式提取出我们需要的信息,我所需要的信息数据于这样:Google Play 音乐_v5.0.1053J.731804_(com.google.android.music).apk,软件名称_v版本号_(apk的包名).apk。
通过分析上面的输出结果可以看到:
name='com.elsdoerfer.android.autostarts'
versionName='1.7.7'
application-label:'Autostarts'
application-label-zh:'自启管家'
这四个字符串是我们要需要的,下面的任务就是如何把它们的值提取出来。下面上整个程序的perl源代码。
# use strict;
use Encode;
use open ':encoding(GBK)', ':std';
use open ':encoding(UTF-8)';
my @files = (glob(".*.apk"), glob("*.apk"));
foreach (@files)
{
# print "Start Processing -> $_ \n";
# 执行aapt并赋值给$info
$info = `aapt d badging $_`;
$info =~ m/name=\'(.*?)\'/;
$pkg_name = $1; # apk的包名
$info =~ m/versionName=\'(.*?)\'/;
$version = $1; # apk的版本号
# 判断是否存在 label-zh_CN名字,
# 若不存在则以label名字代替
if ($info =~ m/application-label-zh_CN:\'(.*?)\'/) {
$name = $1;
}
else {
$info =~ m/application-label:\'(.*?)\'/;
$name = $1;
}
# 拼接格式化后想要的文件名
$out_filename = "$name\_v$version\_($pkg_name).apk";
open(LOG, ">>log.txt") || warn "Can't Open the file";
print LOG "$out_filename \n";
# 必须要转换成gb2312编码,否则会造成中文乱码
$out_filename = encode("gb2312", $out_filename);
print decode("gb2312", $out_filename);
# 若修改后导致文件重名,则输出警告,不作处理
if(-e $out_filename){
warn "Can't rename $_ to $out_filename.
The $out_filename exists!\n";
}
else{
# 重命名文件,若重命名失败,则输出警告
# 注意此处不要调用system("ren $a $b")或`ren a b`
# 因为直接调用会造成文件名有空格会重命名失败的问题
rename $_, $out_filename
or warn "Rename $_ to $out_filename failed: $!\n";
}
print "\n";
}
close LOG || warn "Can't close the file";
对这个perl文件作一个小小的解释:
my @files = (glob(".*.apk"), glob("*.apk")); 使用glob()函数获取到目录下面的所有文件名,这里使用的是*.apk和.*.apk,这两个是有区别的,因为perl源于unix/linux,在linux下面,所有以点开头的文件都是隐藏文件,程序默认是不解析的,所以我们必须要加上.*.apk。
foreach (@files)
转载于:https://www.cnblogs.com/iwantcomputer/p/8489813.html