如題,拿Oppo 手機做個示例,小米 華為也是如此。
在編寫Android應用的時候,我們經常會有這樣的需求,我們想直接打開系統應用的某個頁面。比如在Oppo R9 手機上我們想打開某個應用的通知管理界面如下圖
點擊QQ圖標,跳轉到如下界面
同時我們在terminal中 通過 adb logcat |grep “ActivityManager” 我們可以看到Activity的相關信息
I/ActivityManager( 902): START u0 {act=com.coloros.notificationmanager.app.detail cmp=com.coloros.notificationmanager/.AppDetailPreferenceActivity (has extras)} from uid 1000 from pid 31395 on display 0
D/ActivityManager( 902): Delay resumeKeyDispatchingLocked() to avoid deadlock.
I/ActivityManager( 902): [AppLaunch] Displayed Displayed com.coloros.notificationmanager/.AppDetailPreferenceActivity: +160ms
D/ActivityManager( 902): AP_PROF:AppLaunch_LaunchTime:com.coloros.notificationmanager/.AppDetailPreferenceActivity:160:27986714
D/ActivityManager( 902): ACT-IDLE_NOW_MSG from windowsVisible() for idle: ActivityRecord{293543ae u0 com.coloros.notificationmanager/.AppDetailPreferenceActivity t157}
通過日志我們看到了設置QQ通知管理的Activity的包名和類名分別是
com.coloros.notificationmanager/.AppDetailPreferenceActivity.但是啟動這個Activity是需要附加Extras的,至少應用的包名是需要傳遞進去的,要不然憑什么知道這就是設置QQ的通知權限而不是微信的通知權限呢。動動腳趾頭猜下 至少是傳遞了一個包名進去,但是具體的key我們是不得而知。怎么辦!?我們想知道這個類到底傳了哪些key-value,以及這個Activity是否能被外部應用吊起,那只能反編譯源碼,到AppDetailPreferenceActivity.java中查看到底傳遞了哪些key以及得到AndroidManifest.xml 查看聲明的AppDetailPreferenceActivity exported 屬性是否為false。
1.1既然是反編譯,那首先我們要確定這個系統應用的APK到底在哪里,連上手機,打開terminal輸入以下命令
adb shell pm path com.coloros.notificationmanager
輸出如下
1.2 接下來的心情應該是興高采烈,躍躍一試,迫不及待的想要把apk pull到本地,進行反編譯,那么我可以很負責任的告訴你,你高興的太早了,這樣根本無法反編譯出源代碼。不信且看
adb pull /system/app/notification_center/notification_center.apk ~/oppo
1.3這樣我們就把系統apk pull到本地了,先確認下apk中是否有dex文件
unzip notification_center.apk
1.4.然后我在解壓后的文件夾想努力的找到classes.dex,最后震驚了,什么鬼,apk 怎么可以沒有classes.dex文件,特么的是在逗我嗎,真的不敢直視自己的才疏學淺, 反正事實就是這樣子了,就是沒有classes.dex,怎么着吧。既然是這樣的話,那么能拿到真正的apk嗎,答案當然是能。
到這里我需要隆重介紹三個利器Lordroid、enjarify以及Apktool
,Lordroid 它能將系統優化過的odex 解碼成dex,就是利用它能夠將得到可以被反編譯的Apk、enjarify可以將apk反編譯成jar、Apktool可以獲取apk的資源文件。具體使用請自行解決,不做過多介紹了。
正確打開方式
2.1 把手機/system 拉取到電腦上
adb pull /system ~/system
這里有三個比較重要的文件或文件夾 build.pro、framework、priv-app。請注意!!!我們目標apk notification_center.apk不是說好的在 app文件夾里面嗎,怎么沒有拉取到呢。怎么辦?再手動拉取一遍唄!
cd priv-app
rm -rf *
adb pull /system/app/notification-center .
這樣notification-center文件夾就被拉取下來了
2.2接下來打開Lordroid主界面,cd Lordroid主目錄
java -jar Launcher.jar
2.3點擊browse 選擇 ~/system(前面拉取Apk 的目錄) 目錄,如下提示找到priv-app 和framework目錄
2.4點擊Deodex now!
2.5至此Deodex 已經成功,我們到priv-app/notification-center 中已經生成了一個notification-center.apk,再解壓看看是否有classes.dex
至此我們看到了classes.dex又重回apk的懷抱。可以按常規的方法去反編譯,此處省略xxx字,請自行腦補。
3.1 最后我們得到了notification-center.apk的jar包,用JD-GUI打開,定位到AppDetailPreferenceActivity,查找Extra關鍵字
會發現傳了”pkg_name” “app_name” “class_name”三個key。
3.2 那么寫個demo 驗證下吧
private void startOppoNotification() { //Intent intent = new //Intent("com.coloros.notificationmanager.app.detail_ab//andon"); Intent intent = new Intent(); intent.setComponent(new ComponentName("com.coloros.notificationmanager", "com.coloros.notificationmanager.AppDetailPreferenceActivity")); intent.putExtra("pkg_name", "com.coohuaclient"); intent.putExtra("app_name", "酷划鎖屏"); intent.putExtra("class_name", "com.coohuaclient.ui.activity.SplashActivity"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); }
3.3效果如下
理論上講有了這樣的方法,我們基本上可以直達任何應用的可以被外部訪問的界面了
