外部APP與內部應用systemUI進程aidl通信
目標實現:通過aidl通信,動態控制導航欄和狀態欄的顯示/隱藏,並將此狀態持久化保存,即使機器重啓也保持之前設置的狀態。
1.創建aidl文件:/frameworks/base/packages/SystemUI/src/systemui/IExtelCom.aidl
package com.android.systemui; interface IExtelCom { void setNavigationViewVisible(boolean b); void setStatusViewVisible(boolean b); }
2.創建ExtelComService.java文件:/frameworks/base/packages/SystemUI/src/systemui/ExtelComService.java
package com.android.systemui; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class ExtelComService extends Service { private final IExtelCom.Stub stub = new IExtelCom.Stub() { @Override public void setNavigationViewVisible(boolean b) throws RemoteException{ try { Log.i("tag","aidl_service_setNavigationShow"); ExtelComHelper.getInstance().setNavigationViewVisible(b); }catch (Exception e){ e.printStackTrace(); } } @Override public void setStatusViewVisible(boolean b) throws RemoteException{ try { Log.i("tag","aidl_service_setStatusViewVisible"); ExtelComHelper.getInstance().setStatusViewVisible(b); }catch (Exception e){ e.printStackTrace(); } } }; @Override public IBinder onBind(Intent intent) { return stub; } }
3.創建ExtelComHelper.java文件:/frameworks/base/packages/SystemUI/src/systemui/ExtelComHelper.java
package com.android.systemui; import android.os.Handler; import android.util.Log; import android.view.View; import com.android.systemui.navigationbar.NavigationBarController; import com.android.systemui.util.ShareUtils; import java.util.Properties; public class ExtelComHelper { private static ExtelComHelper instance; private static Properties systemProperties; private String info; private View navigationView; private View statusView; public static ExtelComHelper getInstance(){ if(instance == null){ synchronized (ExtelComHelper.class){ if(instance == null){ instance = new ExtelComHelper(); systemProperties = System.getProperties(); } } } return instance; } public void setNavigationView(View view){ this.navigationView = view; } public void setStatusView(View view){ this.statusView = view; } //aidl的邏輯調用是在工作線程中執行的,而進行View的操作必須要在主線程,所以需新建Handler在主線程 public void setNavigationViewVisible(boolean b) { if(navigationView != null){ Log.i("tag","navigationView != null"); new Handler(SystemUIApplication.me().getMainLooper()).post(new Runnable() { @Override public void run() { if(b && navigationView.getVisibility() == View.GONE){ navigationView.setVisibility(View.VISIBLE); ShareUtils.putInt(SystemUIApplication.me(),"navigationBarVisible",1); }else if(!b && navigationView.getVisibility() == View.VISIBLE){ navigationView.setVisibility(View.GONE); ShareUtils.putInt(SystemUIApplication.me(),"navigationBarVisible",0); } } }); } } public void setStatusViewVisible(boolean b) { if(statusView != null){ Log.i("tag","statusView != null"); new Handler(SystemUIApplication.me().getMainLooper()).post(new Runnable() { @Override public void run() { if(b && statusView.getVisibility() == View.GONE){ statusView.setVisibility(View.VISIBLE); ShareUtils.putInt(SystemUIApplication.me(),"statusBarVisible",1); }else if(!b && statusView.getVisibility() == View.VISIBLE){ statusView.setVisibility(View.GONE); ShareUtils.putInt(SystemUIApplication.me(),"statusBarVisible",0); } } }); } } }
4.創建ShareUtils.java文件,供數據持久化:/frameworks/base/packages/SystemUI/src/systemui/util/ShareUtils.java
package com.android.systemui.util; import android.content.Context; import android.content.SharedPreferences; import java.util.Map; public class ShareUtils { public static final String NAME = "test"; /** * 存储Int类型的值 * @param mContext this * @param key key * @param value 要存储的Int值 */ public static void putInt(Context mContext, String key, int value) { SharedPreferences sharedPreferences = mContext.getSharedPreferences(NAME, Context.MODE_PRIVATE); sharedPreferences.edit().putInt(key, value).commit(); } /** * 获取Int类型的值 * @param mContext this * @param key key * @param defValue 默认值 * @return */ public static int getInt(Context mContext, String key, int defValue) { SharedPreferences sharedPreferences = mContext.getSharedPreferences(NAME, Context.MODE_PRIVATE); return sharedPreferences.getInt(key, defValue); } }
5.修改StatusBar.java文件
***************************************************************************************************** mStatusBarView = (PhoneStatusBarView) statusBarFragment.getView(); mStatusBarView.setBar(this); mStatusBarView.setPanel(mNotificationPanelViewController); mStatusBarView.setScrimController(mScrimController); mStatusBarView.setExpansionChangedListeners(mExpansionChangedListeners); //modifyFrom:wangdan ExtelComHelper.getInstance().setStatusView(mStatusBarView); int statusBarVisible = ShareUtils.getInt(SystemUIApplication.me(),"statusBarVisible",-1); Log.i("tag","statusBarVisibleState ="+statusBarVisible); if(statusBarVisible != -1 && statusBarVisible == 0){ mStatusBarView.setVisibility(View.GONE); }else{ mStatusBarView.setVisibility(View.VISIBLE); }
6.修改NavigationBarController.java文件:
@VisibleForTesting void createNavigationBar(Display display, Bundle savedState, RegisterStatusBarResult result) { ********************************************************************************************** //在此方法最後面添加: //modifyFrom:wangdan ExtelComHelper.getInstance().setNavigationView(navigationBarView); int navigationBarVisible = ShareUtils.getInt(SystemUIApplication.me(),"navigationBarVisible",-1);; Log.i("tag","navigationBarVisibleState ="+navigationBarVisible); if(navigationBarVisible != -1 && navigationBarVisible == 0){ navigationBarView.setVisibility(View.GONE); }else{ navigationBarView.setVisibility(View.VISIBLE); } }
7.修改SystemUIApplication.java文件
private static SystemUIApplication instance; public void onCreate() { super.onCreate(); //modifyFrom:wangdan instance = this; ***************************************************************************************************** } public static SystemUIApplication me(){ return instance; }
8.在AndroidManifest.xml文件中添加 :(注冊服務)
<service android:name=".ExtelComService" android:exported="true"> <intent-filter> <action android:name="com.android.systemui.ExtelComService"/> </intent-filter> </service>
9.外部app的正常aidl綁定服務,調用即可。