中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android源碼個個擊破之“設置”

發布時間:2020-05-27 09:00:38 來源:網絡 閱讀:1539 作者:屠夫章哥 欄目:移動開發

6.0設置源碼分析:https://blog.csdn.net/zrf1335348191/article/details/51469058?locationNum=8

?

1.?源碼位置:/packages/apps/Settings/

2.?Settings.java即是應用的首頁

3.?|----SettingsActivity.java? ?(和Settings.java就在一個包下,不要全局搜索,否則會搜到多個SettingsActivity這個類)

4.??Android6.0源碼分析:

? ? ? ?1-1:清單文件分析

? ? ? ?通過清單文件可以知道設置應用的啟動類是Settings.java

? ? ? ??Android源碼個個擊破之“設置”? ? ? ?

? ? ? ? ?看看清單文件里,可以發現很多的activity都有這樣的meta標簽定義,這些activity都是Settings.java的內部類,UI都是通過Fragment來實現的。

? ? ? ??Android源碼個個擊破之“設置”

???????? 1-2:Settings.java分析

? ? ? ? ? ? ? ??Android源碼個個擊破之“設置”

? ? ? ? ? ? ? ? 繼承自SettingsActivity,其它的都是一些內部類,雖然是空實現,但是都繼承了SettingsActivity.

????????????? ?說實話,這么詭異的寫法我生平還是第一次見!

?????

????????????????

? ? ? ? ?1-3:SettingsActivity分析

?????????第一步:看onCreate方法
? ? ? ? ?Android源碼個個擊破之“設置”

? ? ? ? ?首先調用了一個getMetaData的方法

?????private?void?getMetaData()?{
????try?{
????????ActivityInfo?ai?=?getPackageManager().getActivityInfo(getComponentName(),
????????????????PackageManager.GET_META_DATA);
????????if?(ai?==?null?||?ai.metaData?==?null)?return;
????????mFragmentClass?=?ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
????}?catch?(NameNotFoundException?nnfe)?{
????????//?No?recovery
????????Log.d(LOG_TAG,?"Cannot?get?Metadata?for:?"?+?getComponentName().toString());
????}
}

? ? ? ??PackageManager從清單文件里解析當前Activity的信息,并且從META_DATA獲取到了對應的Fragment的類名。

???private?static?final?String?META_DATA_KEY_FRAGMENT_CLASS?=212????????"com.android.settings.FRAGMENT_CLASS";

????????這個正與清單文件里的meta的key一樣。

? ? ? ??

????1-4:Usb網絡共享界面

?????????https://blog.csdn.net/kc58236582/article/details/48313315

????????

????????項目有個需要,需要判斷一下USB網絡共享開關是否打開 。但是百度幾乎是沒有答案的,我就想著研究一下源碼,看看設置里的那個頁面是怎么去刷新這個UI的。

?

? ? ? ??Android源碼個個擊破之“設置”

? ? ? ? ?

????????找到網絡共享設置頁面:TetherSettings.java

?????? ?TetherSettings

????????????????|-----SettingsPreferenceFragment

? ? ???????????????? |---------InstrumentedPreferenceFragment

????????????????????????????|--------PreferenceFragment

????????

????? ? 布局是在PreferenceFragment這個類里實現的,默認使用Android源碼個個擊破之“設置”布局

<LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"
????????android:orientation="vertical"
????????android:layout_height="match_parent"
????????android:layout_width="match_parent"
????????android:background="@android:color/transparent"
????????android:layout_removeBorders="true">
????
????????<ListView?android:id="@android:id/list"
????????????
????????????android:layout_width="match_parent"
????????????android:layout_height="0px"
????????????android:layout_weight="1"
????????????android:paddingTop="0dip"
????????????android:paddingBottom="@dimen/preference_fragment_padding_bottom"
????????????android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
????????????android:clipToPadding="false"
????????????android:drawSelectorOnTop="false"
????????????android:cacheColorHint="@android:color/transparent"
????????????android:scrollbarAlwaysDrawVerticalTrack="true"?/>
????
????????<TextView?android:id="@android:id/empty"
????????????android:layout_width="match_parent"
????????????android:layout_height="match_parent"
????????????android:padding="@dimen/preference_fragment_padding_side"
????????????android:gravity="center"
????????????android:visibility="gone"?/>
????
????????<RelativeLayout?android:id="@+id/button_bar"
????????????android:layout_height="wrap_content"
????????????android:layout_width="match_parent"
????????????android:layout_weight="0"
????????????android:visibility="gone">
????
????????????<Button?android:id="@+id/back_button"
????????????????android:layout_width="0dip"
????????????????android:layout_height="wrap_content"
????????????????android:layout_margin="5dip"
????????????????android:layout_alignParentStart="true"
????????????????android:text="@string/back_button_label"
????????????/>
????????????<LinearLayout
????????????????android:orientation="horizontal"
????????????????android:layout_width="wrap_content"
????????????????android:layout_height="wrap_content"
????????????????android:layout_alignParentEnd="true">
????
????????????????<Button?android:id="@+id/skip_button"
????????????????????android:layout_width="0dip"
????????????????????android:layout_height="wrap_content"
????????????????????android:layout_margin="5dip"
????????????????????android:text="@string/skip_button_label"
????????????????????android:visibility="gone"
????????????????/>
????
????????????????<Button?android:id="@+id/next_button"
????????????????????android:layout_width="0dip"
????????????????????android:layout_height="wrap_content"
????????????????????android:layout_margin="5dip"
????????????????????android:text="@string/next_button_label"
????????????????/>
????????????</LinearLayout>
????????</RelativeLayout>
????</LinearLayout>

????????這些設置里的按鈕,是如何更新UI的呢?

????????Android源碼個個擊破之“設置”

? ? ? ??

? ? ? ?可以看到USB網絡共享的開關是通過mUsbTether這個對象來控制的。至此,USB網絡共享是否開啟的代碼也就找到了。

?

? ? ??Android源碼個個擊破之“設置”

????????findPreference是父類PreferenceFragment的方法:

? ? ?Android源碼個個擊破之“設置”

????方法引用了PreferenceManager對象,對象在fragment創建時創建:

? ? ??Android源碼個個擊破之“設置”

? ? ????? 通過代碼可以判斷刷新布局的應該這個方法:

????????Android源碼個個擊破之“設置”

????????? 將preferenceScreen這個對象與前面提到的布局里的ListView綁定起來。

???????? 這個preferenceScreen對象通過下面的方法賦值:

? ? ? ? ?Android源碼個個擊破之“設置”

????????????那么,問題來了,這兩個方法什么在哪里被調用的呢?

? ? ? ? ? ?

? ? ? ? ?Android源碼個個擊破之“設置”

?????? ? ?

? ? ? ? 文件內容如下:

<PreferenceScreen?xmlns:android="http://schemas.android.com/apk/res/android">
????
????????<SwitchPreference
????????????android:key="usb_tether_settings"
????????????android:title="@string/usb_tethering_button_text"
????????????android:persistent="false"?/>
????
????????<SwitchPreference
????????????android:key="enable_wifi_ap"
????????????android:title="@string/wifi_tether_checkbox_text"
????????????android:persistent="false"?/>
????
????????<Preference
????????????android:key="wifi_ap_ssid_and_security"
????????????android:title="@string/wifi_tether_configure_ap_text"
????????????android:persistent="false"?/>
????
????????<SwitchPreference
????????????android:key="enable_bluetooth_tethering"
????????????android:title="@string/bluetooth_tether_checkbox_text"
????????????android:persistent="false"?/>
????
????</PreferenceScreen>
???到這里就清楚了,settings里的這些開關,并不是單獨使用switchButtont等控制堆疊起來的,而是通過解析res/xml下的xml文件,將標簽解析(采用XmlPullParser)出現,轉化成PreferenceScreen對象,
???再將PreferenceBean對象與布局里的ListView綁定起來。

? ? ? ?

當然,設置里的源碼粘貼過來,不能直接使用,很多字段和方法是hide的,需要通過反射來搞定。下面是我測試過的判斷usb網絡共享是否開啟的源碼:

package?com.refactor.usb_share;

import?android.content.BroadcastReceiver;
import?android.content.Context;
import?android.content.Intent;
import?android.content.IntentFilter;
import?android.hardware.usb.UsbManager;
import?android.net.ConnectivityManager;
import?android.util.Log;

import?java.lang.reflect.InvocationTargetException;
import?java.lang.reflect.Method;
import?java.util.ArrayList;

/**
?*?Created?by?XinYi?on?8/8/10.
?*?監聽USB網絡共享是否開啟
?*/
public?class?UsbShareStateMonitor?{
????private?Context?context;
????private?final?String?TAG?=?"UsbShareStateMonitor";
????private?static?UsbShareStateMonitor?instance?=?new?UsbShareStateMonitor();
????private?ConnectivityManager?cm;
????private?String[]?forReflect?=?new?String[]{};
????private?boolean?mMassStorageActive;
????private?boolean?mUsbConnected;

????private?String?ACTION_TETHER_STATE_CHANGED?=?"android.net.conn.TETHER_STATE_CHANGED";
????/**
?????*?@hide?gives?a?String[]?listing?all?the?interfaces?configured?for
?????*?tethering?and?currently?available?for?tethering.
?????*/
????private?final?String?EXTRA_AVAILABLE_TETHER?=?"availableArray";

????/**
?????*?@hide?gives?a?String[]?listing?all?the?interfaces?currently?tethered
?????*?(ie,?has?dhcp?support?and?packets?potentially?forwarded/NATed)
?????*/
????private?final?String?EXTRA_ACTIVE_TETHER?=?"activeArray";

????/**
?????*?@hide?gives?a?String[]?listing?all?the?interfaces?we?tried?to?tether?and
?????*?failed.??Use?{@link?#getLastTetherError}?to?find?the?error?code
?????*?for?any?interfaces?listed?here.
?????*/
????private?final?String?EXTRA_ERRORED_TETHER?=?"erroredArray";

????/**
?????*?Broadcast?Action:??External?media?is?no?longer?being?shared?via?USB?mass?storage.
?????*?The?path?to?the?mount?point?for?the?previously?shared?media?is?contained?in?the?Intent.mData?field.
?????*
?????*?@hide
?????*/
????private?final?String?ACTION_MEDIA_UNSHARED?=?"android.intent.action.MEDIA_UNSHARED";
????private?final?String?ACTION_USB_STATE?=
????????????"android.hardware.usb.action.USB_STATE";
????private?final?String?USB_CONNECTED?=?"connected";
????private?final?int?TETHER_ERROR_NO_ERROR?=?0;
????private?String[]?mUsbRegexs;
????private?boolean?isUsbShareOpened;
????private?TetherChangeReceiver?mTetherChangeReceiver;

????private?UsbShareStateMonitor()?{
????????isUsbShareOpened?=?false;
????}

????public?static?UsbShareStateMonitor?getInstance()?{
????????return?instance;
????}

????public?void?regist(Context?context)?{
????????this.context?=?context;
????????cm?=?(ConnectivityManager)?context.getSystemService(Context.CONNECTIVITY_SERVICE);
????????mUsbRegexs?=?getTetherableUsbRegexs();
????????registTetherChangeReceiver();
????}

????public?void?unRegist(){
????????if(context?!=?null){
????????????context.unregisterReceiver(mTetherChangeReceiver);
????????????mTetherChangeReceiver?=?null;
????????}
????}

????private?void?registTetherChangeReceiver()?{
????????mTetherChangeReceiver?=?new?TetherChangeReceiver();
????????IntentFilter?filter?=?new?IntentFilter(ACTION_TETHER_STATE_CHANGED);
????????Intent?intent?=?context.registerReceiver(mTetherChangeReceiver,?filter);

????????filter?=?new?IntentFilter();
????????filter.addAction(ACTION_USB_STATE);
????????context.registerReceiver(mTetherChangeReceiver,?filter);

????????filter?=?new?IntentFilter();
????????filter.addAction(Intent.ACTION_MEDIA_SHARED);
????????filter.addAction(ACTION_MEDIA_UNSHARED);
????????filter.addDataScheme("file");
????????context.registerReceiver(mTetherChangeReceiver,?filter);
????????if?(intent?!=?null)?mTetherChangeReceiver.onReceive(context,?intent);
????}

????public?boolean?isUsbShareOpened()?{
????????return?isUsbShareOpened;
????}


????private?class?TetherChangeReceiver?extends?BroadcastReceiver?{
????????@Override
????????public?void?onReceive(Context?content,?Intent?intent)?{
????????????String?action?=?intent.getAction();
????????????if?(action.equals(ACTION_TETHER_STATE_CHANGED))?{
????????????????//?TODO?-?this?should?understand?the?interface?types
????????????????ArrayList<String>?available?=?intent.getStringArrayListExtra(
????????????????????????EXTRA_AVAILABLE_TETHER);
????????????????ArrayList<String>?active?=?intent.getStringArrayListExtra(
????????????????????????EXTRA_ACTIVE_TETHER);
????????????????ArrayList<String>?errored?=?intent.getStringArrayListExtra(
????????????????????????EXTRA_ERRORED_TETHER);
????????????????updateState(available.toArray(new?String[available.size()]),
????????????????????????active.toArray(new?String[active.size()]),
????????????????????????errored.toArray(new?String[errored.size()]));
????????????}?else?if?(action.equals(Intent.ACTION_MEDIA_SHARED))?{
????????????????mMassStorageActive?=?true;
????????????????updateState();
????????????}?else?if?(action.equals(ACTION_MEDIA_UNSHARED))?{
????????????????mMassStorageActive?=?false;
????????????????updateState();
????????????}?else?if?(action.equals(ACTION_USB_STATE))?{
????????????????mUsbConnected?=?intent.getBooleanExtra(USB_CONNECTED,?false);
????????????????updateState();
????????????}
????????}
????}

????private?void?updateState()?{
????????String[]?available?=?getTetherableIfaces();
????????String[]?tethered?=?getTetheredIfaces();
????????String[]?errored?=?getTetheringErroredIfaces();
????????updateState(available,?tethered,?errored);
????}

????private?void?updateState(String[]?available,?String[]?tethered,
?????????????????????????????String[]?errored)?{
????????updateUsbState(available,?tethered,?errored);
????}


????private?void?updateUsbState(String[]?available,?String[]?tethered,
????????????????????????????????String[]?errored)?{
????????mUsbRegexs?=?getTetherableUsbRegexs();
????????if(mUsbRegexs?==?null)?{
????????????Log.e(TAG,?"mUsbRegexs?==?null?");
????????????return;
????????}
????????boolean?usbTethered?=?false;
????????for?(String?s?:?tethered)?{
????????????for?(String?regex?:?mUsbRegexs)?{
????????????????if?(s.matches(regex))?usbTethered?=?true;
????????????}
????????}
????????isUsbShareOpened?=?usbTethered;
????}

????//hide方法
????private?String[]?getTetherableUsbRegexs()?{
????????return?getCmHideMethods("getTetherableUsbRegexs");
????}

????private?String[]?getTetherableIfaces()?{
????????return?getCmHideMethods("getTetherableIfaces");
????}

????private?String[]?getTetheredIfaces()?{
????????return?getCmHideMethods("getTetheredIfaces");
????}

????private?String[]?getTetheringErroredIfaces()?{
????????return?getCmHideMethods("getTetheringErroredIfaces");
????}


????private?String[]?getCmHideMethods(String?methodName)?{
????????try?{
????????????Method?method?=?cm.getClass().getDeclaredMethod(methodName);
????????????method.setAccessible(true);
????????????String[]?result?=?(String[])?method.invoke(cm);
????????????return?result;
????????}?catch?(NoSuchMethodException?e)?{
????????????e.printStackTrace();
????????}?catch?(IllegalAccessException?e)?{
????????????e.printStackTrace();
????????}?catch?(InvocationTargetException?e)?{
????????????e.printStackTrace();
????????}
????????return?null;
????}


}




如何獲取藍牙物理MAC? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??



#################################################################################################

https://blog.csdn.net/kehyuanyu/article/details/49074847? (有關于獲取藍牙物理的影子,順著果真能找到存儲藍牙物理 mac的文件)


1)

Android源碼個個擊破之“設置”


2)

Android源碼個個擊破之“設置”


? ??Android源碼個個擊破之“設置”

3)

Android源碼個個擊破之“設置”


4)

Android源碼個個擊破之“設置”


5)



#################################################################################################


設備信息-本機信息:

Android源碼個個擊破之“設置”


順著路徑找到這個類,找到藍牙獲取的方法。

Android源碼個個擊破之“設置”


獲取藍牙mac的調用順序:

BluetoothAdapter-->BluetoothManagerService


Android源碼個個擊破之“設置”

很明顯上面用到AIDL技術

搜索消息關鍵字? ?MESSAGE_BLUETOOTH_SERVICE_CONNECTED ,找到消息發送的地方


Android源碼個個擊破之“設置”

上面的就是Binder機制了 ,注意注意的代碼。(由后面的分析可知arg1應該是AdapterService)

然后根據

Android源碼個個擊破之“設置”

找到bind的地方:

第1處:enable藍牙的地方,注意intent的參數是IBluetooth

Android源碼個個擊破之“設置”

第2處:注意intent的參數是IBluetoothGatt

Android源碼個個擊破之“設置”

還有一處無關的doBind調用。






注意到這里的intent的構造參數,是IBluetoothGatt。

看doBind方法

Android源碼個個擊破之“設置”

注意解析intent組件的這個方法,最后應該是與GattService或者AdapterService進行了綁定。

那么到底是哪個service呢,后面發現AdapterService才有getAddress()方法,所以綁定的應該是AdapterService。


所以獲取藍牙物理mac的調用順序又清楚了一步

BluetoothAdapter-->BluetoothManagerService-->AdapterService


看AdapterService,通過它的AdapterServiceBinder與BluetoothManagerService通訊


Android源碼個個擊破之“設置”


Binder會調用AdapterService的getAddress()方法

Android源碼個個擊破之“設置”


Android源碼個個擊破之“設置”


Android源碼個個擊破之“設置”

?

??Android源碼個個擊破之“設置”


? 由上面的順序可知:

? 在AdapterService里創建了AdapterProperties,創建JniCallbacks,JniCallbacks封裝了AdapterProperties。


?

注意JniCallbacks這個類,它是與底層cpp交互的橋梁,包括它的adapterPropertyChangedCallback方法。

Android源碼個個擊破之“設置”

注意上面的寫法,怎么通過jni調用的JniCallbacks這個類的。



static?void?adapter_properties_callback(bt_status_t?status,?int?num_properties,
????????????????????????????????????bt_property_t?*properties)?{
???????...
????
????????callbackEnv->CallVoidMethod(sJniCallbacksObj,?method_adapterPropertyChangedCallback,?types,
????????????????????????????????????????????props);
????????checkAndClearExceptionFromCallback(callbackEnv,?__FUNCTION__);
????????callbackEnv->DeleteLocalRef(props);
????????callbackEnv->DeleteLocalRef(types);
????????return;
????
????}

查詢adapter_properties_callback方法的調用? (注意CPP的回調是通過傳入方法名進行回調的)

Android源碼個個擊破之“設置”


Android源碼個個擊破之“設置”

最終是由HAL層回調過來的

Android源碼個個擊破之“設置”


xref: /hardware/libhardware/hardware.c,分析這個類。


獲取module:


https://blog.csdn.net/u014135607/article/details/79840130? (參考資料)


https://blog.csdn.net/u011913612/article/details/52576831?(超級詳細)


Android源碼個個擊破之“設置”


?調用HMI

?注意dlopen和dlsym這2個方法

Android源碼個個擊破之“設置”

? ? 上面這個dlsym方法屬于“<dlfcn.h>”這個接口,看它的實現類:

? ?注意這個類在bionic包下

? ?

??


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

广宁县| 莫力| 利川市| 涞水县| 阿勒泰市| 洪雅县| 巴塘县| 金昌市| 连南| 淳安县| 黄大仙区| 伊春市| 上蔡县| 宣恩县| 华阴市| 桃江县| 子洲县| 井冈山市| 揭阳市| 澄城县| 樟树市| 广西| 永胜县| 芷江| 买车| 图们市| 霍山县| 交口县| 湖州市| 新巴尔虎右旗| 徐汇区| 类乌齐县| 确山县| 樟树市| 望都县| 内黄县| 麻江县| 万年县| 宜州市| 都安| 任丘市|