【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android源碼個(gè)個(gè)擊破之“設(shè)置”_第1頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android源碼個(gè)個(gè)擊破之“設(shè)置”_第2頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android源碼個(gè)個(gè)擊破之“設(shè)置”_第3頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android源碼個(gè)個(gè)擊破之“設(shè)置”_第4頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android源碼個(gè)個(gè)擊破之“設(shè)置”_第5頁(yè)
已閱讀5頁(yè),還剩12頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

付費(fèi)下載

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android源碼個(gè)個(gè)擊破之“設(shè)置”

6.0設(shè)置源碼分析:/zrf1335348191/article/details/51469058?locationNum=8

1.

源碼位置:/packages/apps/Settings/2.

Settings.java即是應(yīng)用的首頁(yè)3.

|SettingsActivity.java

(和Settings.java就在一個(gè)包下,不要全局搜索,否則會(huì)搜到多個(gè)SettingsActivity這個(gè)類)4.

Android6.0源碼分析:

1-1:清單文件分析

通過(guò)清單文件可以知道設(shè)置應(yīng)用的啟動(dòng)類是Settings.java

看看清單文件里,可以發(fā)現(xiàn)很多的activity都有這樣的meta標(biāo)簽定義,這些activity都是Settings.java的內(nèi)部類,UI都是通過(guò)Fragment來(lái)實(shí)現(xiàn)的。

1-2:Settings.java分析

繼承自SettingsActivity,其它的都是一些內(nèi)部類,雖然是空實(shí)現(xiàn),但是都繼承了SettingsActivity.

說(shuō)實(shí)話,這么詭異的寫(xiě)法我生平還是第一次見(jiàn)!

1-3:SettingsActivity分析

第一步:看onCreate方法

首先調(diào)用了一個(gè)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從清單文件里解析當(dāng)前Activity的信息,并且從META_DATA獲取到了對(duì)應(yīng)的Fragment的類名。

private

static

final

String

META_DATA_KEY_FRAGMENT_CLASS

=212

"com.android.settings.FRAGMENT_CLASS";

這個(gè)正與清單文件里的meta的key一樣。

1-4:Usb網(wǎng)絡(luò)共享界面

/kc58236582/article/details/48313315

項(xiàng)目有個(gè)需要,需要判斷一下USB網(wǎng)絡(luò)共享開(kāi)關(guān)是否打開(kāi)。但是百度幾乎是沒(méi)有答案的,我就想著研究一下源碼,看看設(shè)置里的那個(gè)頁(yè)面是怎么去刷新這個(gè)UI的。

找到網(wǎng)絡(luò)共享設(shè)置頁(yè)面:TetherSettings.java

TetherSettings

|SettingsPreferenceFragment

|InstrumentedPreferenceFragment

|PreferenceFragment

布局是在PreferenceFragment這個(gè)類里實(shí)現(xiàn)的,默認(rèn)使用布局<LinearLayout

xmlns:android="/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>

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

可以看到USB網(wǎng)絡(luò)共享的開(kāi)關(guān)是通過(guò)mUsbTether這個(gè)對(duì)象來(lái)控制的。至此,USB網(wǎng)絡(luò)共享是否開(kāi)啟的代碼也就找到了。

findPreference是父類PreferenceFragment的方法:

方法引用了PreferenceManager對(duì)象,對(duì)象在fragment創(chuàng)建時(shí)創(chuàng)建:

通過(guò)代碼可以判斷刷新布局的應(yīng)該這個(gè)方法:

將preferenceScreen這個(gè)對(duì)象與前面提到的布局里的ListView綁定起來(lái)。

這個(gè)preferenceScreen對(duì)象通過(guò)下面的方法賦值:

那么,問(wèn)題來(lái)了,這兩個(gè)方法什么在哪里被調(diào)用的呢?

文件內(nèi)容如下:<PreferenceScreen

xmlns:android="/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里的這些開(kāi)關(guān),并不是單獨(dú)使用switchButtont等控制堆疊起來(lái)的,而是通過(guò)解析res/xml下的xml文件,將標(biāo)簽解析(采用XmlPullParser)出現(xiàn),轉(zhuǎn)化成PreferenceScreen對(duì)象,

再將PreferenceBean對(duì)象與布局里的ListView綁定起來(lái)。

當(dāng)然,設(shè)置里的源碼粘貼過(guò)來(lái),不能直接使用,很多字段和方法是hide的,需要通過(guò)反射來(lái)搞定。下面是我測(cè)試過(guò)的判斷usb網(wǎng)絡(luò)共享是否開(kāi)啟的源碼: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

.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.

*

監(jiān)聽(tīng)USB網(wǎng)絡(luò)共享是否開(kāi)啟

*/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

=

".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

=

"ent.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;

}}如何獲取藍(lán)牙物理MAC

#################################################################################################/kehyuanyu/article/details/49074847

(有關(guān)于獲取藍(lán)牙物理的影子,順著果真能找到存儲(chǔ)藍(lán)牙物理mac的文件)1)2)

3)4)5)#################################################################################################設(shè)備信息-本機(jī)信息:順著路徑找到這個(gè)類,找到藍(lán)牙獲取的方法。獲取藍(lán)牙m(xù)ac的調(diào)用順序:BluetoothAdapter-->BluetoothManagerService很明顯上面用到AIDL技術(shù)搜索消息關(guān)鍵字

MESSAGE_BLUETOOTH_SERVICE_CONNECTED,找到消息發(fā)送的地方上面的就是Binder機(jī)制了,注意注意的代碼。(由后面的分析可知arg1應(yīng)該是Ad

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論