Intent對象的使用及.apk反編譯
Jiangdg_VIP
https://blog.csdn.net/u012637501
前三節主要學習瞭Intent對象的作用、屬性以及不同Activity之間值的傳遞,這節將著重學習Intent對象的用法。在我的語音識別項目中,通過使用Inteng對象來啟動應用內組件、系統應用程序以及第三方應用程序(如QQ、微信等)。
一、Intent對象開發方法
首先,我們還是先學習下Intent對象啟動組件(應用)有哪幾種方法:
1.利用Intent對象的Component屬性
使用這種方法的前提知道組件的或第三方應用程序的包名、類名,來啟動應用程序內組件、第三方應用程序。Intent的Component屬性需要要接受一個ComponentName對象,一個基本ComponentName需要指定包名和類名,這可以唯一地確定一個組件類。基本格式:
ComponentName comp=new ComponentName(包名,類名);
intent.setComponent(comp);
ComponentName對象包括以下幾種構造器:
a.ComponentName(String pkg,String cls):創建pkg所在包下的cls類所對應的組件(字符串形式)
b.ComponentName(Context pkg,String cls):創建pkg所在包下的cls類所對應的組件
c.ComponentName(Context pkg,Classcls):創建pkg所在包下的cls類所對應的組件(上下文)
應用舉例:
(1)intent啟動自身組件
Intent intent=new Intent(); ComponentName comp=new ComponentName(PocketSphinxDemo.this,help.class );//使用第三種構造器 intent.setComponent(comp); startActivity(intent);
註意:這裡PocketSphinxDemo.this指定的是我們應用程序的包,help.class為包內將要啟動的組件類。
(2)intent啟動第三方應用程序
Intent intent=new Intent(); intent.setClassName("com.tencent.mobileqq", "com.tencent.mobileqq.activity.SplashActivity"); startActivity(intent);
註意:關於第三方應用程序的包名(com.tencent.mobileqq)、類名()com.tencent.mobileqq.activity.SplashActivity,我們可以通過反編譯其.apk獲取AndroidManifest.xml文件的”package”屬性,以及action聲明為MAIN常量的”android:name”屬性,具體如何反編譯獲取我將會在下面文章中詳細述說。
(3)intent啟動系統程序
這部分我覺得使用方法可能會比較好,這裡就不說瞭。
2.利用setClass啟動組件
使用這種方法的前提知道組件的或第三方應用程序的包名、類名,來啟動應用程序內組件、第三方應用程序。setClass*為Intent類的成員方法,功能與Intent對象的Component屬性一樣,都是通過intent指定需要啟動的組件。其也有三種形式:
a.setClass(Context packageContext,Classcls):設置該Intent將要啟動的組件的對應類
b.setClassName(Context packageContext,String className): 設置該Intent將要啟動的組件的對應類名
c.setClassName(String packageName,String className):設置該Intent將要啟動的組將的對應類名
其中,Android應用的Context代表瞭訪問該應用環境信息的接口,而Android應用的包名則作為應用的唯一標識,即Context對象與該應用的包名有一一對應的關系。setClass方法就是指定包名和組件的實現類。
應用舉例:
(1)intent啟動自身組件
Intent intent=new Intent(); intent.setClassName(PocketSphinxDemo.this,help.class );//使用第三種構造器 startActivity(intent);
註意:這裡PocketSphinxDemo.this指定的是我們應用程序的包,help.class為包內已經實現瞭的將要啟動的組件類
(2)intent啟動第三方應用
Intent intent=new Intent(); intent.setClassName("com.tencent.mobileqq","com.tencent.mobileqq.activity.SplashActivity"); startActivity(intent);
註意:關於第三方應用程序的包名(com.tencent.mobileqq)、類名()com.tencent.mobileqq.activity.SplashActivity,我們可以通過反編譯其.apk獲取AndroidManifest.xml文件的”package”屬性,以及action聲明為MAIN常量的”android:name”屬性,具體如何反編譯獲取我將會在下面文章中詳細述說。
3.利用intent-filter配置(Intent對象的5個屬性)
Intent的Action、Category屬性都是一個普通的字符串,其基本思想是:在發出”意圖”的組件中,調用Intent成員方法設置好其計劃啟動組件的一些特征,然後在接收”意圖”組件的AndroidManifest.xml文件中的配置是否符合”意圖”要求,從而確定是否能被啟動。其中:
Action屬性代表該Intent所需要完成的一個抽象”動作”;
Category屬性用於為Action增加額外的附加類別信息
Data屬性用於向Action屬性提供操作的數據,且其接受一個Uri對象
Type屬性用於指定該Data所指定Uri對應的MIME類型,這種MIME類型可以是任何自定義的MIME類型,隻要符合abc/xyz格式的字符串即可
Extras屬性用於多個Action之間進行數據交換,即值傳遞,通常用於不同Activity之間的數據傳遞交換
Flags屬性用於該Intent添加一些額外的控制旗標,Intent可調用addFlags()方法來為Intent添加控制旗標。
(1)利用intent-filter配置啟動系統程序
由於Android手機中的系統程序,其屬性的設置可以說是通用的,所以使用這種方法比前面的方法要方便可靠。示例代碼如下:
啟動系統相機 Intent intent=new Intent(); intent.setAction(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); //啟動相機app startActivity(intent); 啟動瀏覽器 Uri uri=Uri.parse("https://blog.csdn.net/u012637501"); Intent intent=new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(uri); startActivity(intent);
(2)利用intent-filter啟動應用自身組件
a.創建一個Intent對象,並自定義字符串設置給intent的屬性
Intent intent=new Intent(); //創建一個Intent對象 String data="lee://www.fkjava.org:8888/mypath"; //自定義字符串 Uri uri=Uri.parse(data); //將字符串轉換為Uri intent.setAction(Intent.ACTION_VIEW); intent.setData(uri); //設置Intent對象Data屬性 startActivity(intent); 或者 Intent intent=new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse("lee://www.fkjava.org:8888/mypath")); startActivity(intent);
b.實現想要啟動的一個及以上組件(比如SecondaryActivity)
c.在AndroidManifest.xml中為組件(如Activity)添加一個元素並設置元素中的相關內容
可以全部設置,也可以選擇性設置。
經過上述設置,intent就會根據其他組件的元素裡所能匹配的項依次列出符合intent條件的一系列組件。
二、Intent對象啟動第三方應用
Intent對象除瞭能給啟動應用自身組件、系統應用,還可以啟動第三方應用,比如QQ、微信、文件管理器等。由於第三方應用的屬性是各應用開發商自定義的,不能調用Intent預定義的相關屬性常量。為瞭成功啟動第三方應用,我們可以利用Intent對象的Component屬性或者調用Intent類的setClassName方法,通過指定第三方應用的包名、類名來啟動。
由於第三方應用大部分都是封裝好的,為瞭從AndroidManifest.xml工程文件中獲取應用的包名、類名以及獲取相關的Java格式源碼,我們可以對應用安裝包(.apk)進行反編譯。
1.搭建反編譯環境
(1)Win7 x86
(2)Fedora14或cygwin,即linux編譯環境。這裡我直接使用cygwin, Cygwin相當於Windows下的Linux環境。具體的安裝配置方法配置,詳見我這一篇博文:https://blog.csdn.net/u012637501/article/details/40480823
(3)反編譯工具:https://download.csdn.net/detail/u012637501/8166977
2.apk反編譯生成程序的XML配置、圖片、語言等資源文件
(1)下載上述反編譯工具包,打開apk2java目錄下的apktool1.4.1文件夾,內含三個文件:aapt.exe,apktool.bat,apktool.jar vcD4KPHA+PGltZyBzcmM9″/uploadfile/Collfiles/20141119/2014111908391056.png” alt=”\”>
註:裡面的apktool_bk.jar是備份的老版本,最好用最新的apktool.jar
(2)切換到apktool1.4.1文件夾,使用apktool.bat工具進行反編譯
a.切換命令:
b.編譯命令:
apktool.bat 命令行解釋:apktool.bat d -f [apk文件 ] [輸出文件夾]
c.result文件夾下,反編譯的結果:
3.重新打包成apk
將反編譯完的文件重新打包成apk,很簡單,輸入apktool.bat b abc123(你編譯出來文件夾)即可,命令如下:
打包apk後的文件在目錄C:\HelloAndroid下,生成瞭兩個文件夾:
build
dist
其中,打包生成的HelloAndroid.apk,在上面的dist文件夾下.
4.apk反編譯得到Java源代碼
下載上述反編譯工具包,打開apk2java目錄下的dex2jar-0.0.9.9文件夾,內含apk反編譯成java源碼工具,以及源碼查看工具。
dex2ja:rapk反編譯工具,是將apk中的classes.dex轉化成jar文件
jdgui:源碼查看工具,是一個反編譯工具,可以直接查看反編譯後的jar包源代碼
dex2jar 和 jdgui 最新版本下載,分別見google code:
dex2jar(google
code)
jdgui(google
code),最新版本請見 官方
(1)首先將apk文件後綴改為zip並解壓,得到其中的classes.dex,它就是java文件編譯再通過dx工具打包而成的,將classes.dex復制到dex2jar.bat所在目錄dex2jar-0.0.9.9文件夾。
(2)在命令行下定位到dex2jar.bat所在目錄,運行dex2jar.bat classes.dex生成classes_dex2jar.jar
(3)進入jdgui文件夾雙擊jd-gui.exe,打開上面生成的jar包classes_dex2jar.jar,即可看到源代碼瞭,如下圖:
HelloAndroid源碼在反編譯前後的對照如下:
經過以上幾步我們就可以成功的對apk安裝包進行反編譯,獲取源碼。其實,如果我們隻是反編譯用來實現Intent啟動第三方應用隻需操作第二步即可獲得安裝包的AndroidManifest.xml工程文件。
如inten啟動微信.apk
1.反編譯”微信.apk”,查看AndroidManifest.xml工程文件獲取包名、主Activity類名
2.intent設置
Intent intent=new Intent(); intent.setClassName("com.tencent.mm","com.tencent.mm.app.MMApplication"); startActivity(intent);