注:下面的方法在4.4.2更新后已失效!
PreferenceActivity的switchToHeaderInner()函數中會調用isValidFragment函數來檢查fragment是否合法。而在Settings.java的isValidFragment
函數中沒有把AppOpsSummary放到ENTRY_FRAGMENTS數組中,AppOpsSummaryActivity又沒有聲明,所以在不修改Settings代碼的情況下沒
有辦法打開AppOpsSummary了 -_-
在Android4.3/4.4中Google在Settings中加入了AppOPs(可以對程序的權限進行控制,但是被隱藏了).
本文將教你如何打開這個界面,以及這么做的原理.
1 Intent intent = new Intent(); 2 intent.setClassName("com.android.settings", 3 "com.android.settings.Settings"); 4 intent.setAction(Intent.ACTION_MAIN); 5 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 6 | Intent.FLAG_ACTIVITY_CLEAR_TASK 7 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 8 intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, 9 "com.android.settings.applications.AppOpsSummary"); 10 startActivity(intent);
通過上面這一段代碼你就可以打開Settings中AppOps界面了,就是這么簡單!
那么,為什么上面的代碼可以打開AppOps界面呢?這個的實現原理是什么?如果以后Google在后續版本中在Settings中隱藏了其它界面
我又應該如何打開呢?
顯然,如果你想舉一反三的話,那你必須要了解Settings中界面的加載機制、流程,那么Settings中的界面是如何展示出來的呢?
簡單來講,在Settings中,每個界面實際上是由Fragment構造好以后用一個Activity(大部分情況下用的是SubSettings這個Activity)把這個
Fragment顯示出來.如,Settings中'Display'這個界面實際上是由DisplaySettings這個Fragment構造的,然后用一個Activity顯示出來.
如果你想詳細的了解Settings的界面加載等問題,可以參考本人(http://www.cnblogs.com/Lefter)的這一篇文章:關於Android Settings中的八個問題
在了解了Settings的這套界面顯示機制后,我們就找到了顯示AppOps的方案,即啟動Settings中的一個Activity,然后用它來展示構造整個
AppOps界面的Fragment(AppOpsSummary,如果你不知道為什么是這個Fragment,再去讀一下關於Android Settings中的八個問題這篇文章吧^_^).
這個方案的難點在於,我如何把AppOpsSummary這個Fragment傳給Settings里面的那些PreferenceActivity呢?
閱讀PreferenceActivity(Settings.java繼承自該類)的onCreate函數代碼,可以知道它首先會用
String initialFragment = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT);
來試圖獲取要顯示的Fragment,則顯示這個Fragment(當然,也需要其它條件成熟,但我們完全滿足).Great,這個Intent.EXTRA_SHOW_FRAGMENT
就是我們要使用的屬性了,我們將AppOpsSummary寫到Intent對象的這個key里
intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT,
"com.android.settings.applications.AppOpsSummary");
然后用這個intent對象來啟動Settings.java(當然,你還需要設置一些其他的屬性來讓程序更nice).
經過上面的分析后,相信你再看我們在開篇給出的代碼就不會陌生了吧.
我寫的一個Demo(對Activity使用了透明效果):http://pan.baidu.com/s/1panAD
Hope u guys enjoy it!