android 4.1 hdmi 開關
需求:通過程式碼控制HDMI輸出開關
思路:參考android系統設定Settings原始碼中HDMISettings.java
問題:無法呼叫IWindowManager和ServiceManager
解決辦法:
java反射機制 呼叫android得隱藏api
android原始碼下有一些標 注有hide得類 ,這些是android隱藏得api
我們可以通過java得反射來呼叫這些類
比如我下面就用反射來呼叫IWindowManager得hdmi_ops方法來開啟關閉HDMI輸出
Class<?> ServiceManager = Class.forName("android.os.ServiceManager" );
Class<?> IWindowManager = Class.forName("android.view.IWindowManager");
這裡分別獲取類得名字。僅僅只是類名
Method getService = ServiceManager.getMethod("getService",String.class);
這裡是獲取ServiceManager得方法getservice ,這個方法得有一個引數是 String型別的
mIWindowManager = android.view.IWindowManager.Stub.asInterface((IBinder)getService.invoke (ServiceManager.newInstance(),"window"));
這裡是getService.invoke(ServiceManager.newInstance(), “window”)); 是呼叫了這個getservice得方法
方法名字.invoke() 第一個引數必須為類得例項 必須newInstance() 第二個引數 就是方法要傳得引數
這樣就等於呼叫了ServiceManager.getService(“window”); 返回一個binder
IWindowManager.Stub.asInterface((IBinder) 這裡IwindowManager 是不能被eclipse識別得 我們必須去原始碼那把這個類拷過來 建一個相同得包名 放置這個類 比如android.view.IWindowManager的aidl(在系統原始碼中找 /frameworks\base\core\java\android\view目錄下)
就可以生成一個IWindowManager得類了
就可以獲得這個IWindowManager得例項了
現在,就可以呼叫系統方法了
//參考settings原始碼中HDMISettings.java
//IngenicDisplayControl根據包名在framework中找
mIWindowManager.hdmi_ops(IngenicDisplayControl.SET_HDMI_ENABLE_STATE,1,0);
到這裡程式碼就寫完了,但是一執行發現缺少許可權,新增之:
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<use-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
這裡要注意:
在android中,如果要使用系限制的許可權(比如android.permission.WRITE_SECURE_SETTINGS),我們需要把程式安裝到/system/app/下。