《Android操作系統(tǒng)與應(yīng)用開發(fā)》課件第7章_第1頁(yè)
《Android操作系統(tǒng)與應(yīng)用開發(fā)》課件第7章_第2頁(yè)
《Android操作系統(tǒng)與應(yīng)用開發(fā)》課件第7章_第3頁(yè)
《Android操作系統(tǒng)與應(yīng)用開發(fā)》課件第7章_第4頁(yè)
《Android操作系統(tǒng)與應(yīng)用開發(fā)》課件第7章_第5頁(yè)
已閱讀5頁(yè),還剩158頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第7章Android開發(fā)實(shí)例7.1

GPS定位軟件7.2網(wǎng)絡(luò)監(jiān)控軟件7.3基于手機(jī)的便攜式遠(yuǎn)程醫(yī)療監(jiān)護(hù)系統(tǒng)7.1GPS定位軟件

1.設(shè)置權(quán)限

首先,添加GPS定位權(quán)限到AndroidManifest文件中,代碼如下:

<!--允許一個(gè)程序訪問(wèn)精確位置-->

<uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>

<!--允許程序創(chuàng)建模擬位置用于測(cè)試-->

<uses-permissionandroid:name="android.permission.ACCESS_MOCK_LOCATION"/>

2.編寫主頁(yè)面代碼

在界面布局文件(main.xml)中添加TextView控件,分別用來(lái)顯示緯度和經(jīng)度數(shù)據(jù),其代碼如下:

<TextView

android:id="@+id/text_latitude"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/text_latitude"/><TextView

android:id="@+id/text_longitude"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/text_longitude"/>

3.編寫GPS主程序代碼

具體實(shí)現(xiàn)的步驟如下:

(1)首先,我們需要獲取LocationManager的一個(gè)實(shí)例,這里需要注意的是此實(shí)例只能通過(guò)下面這種方式來(lái)獲取,直接實(shí)例化LocationManager是不被允許的:

locationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);

(2)定義Location事件監(jiān)聽,當(dāng)位置改變或狀態(tài)變化,可用和不可用時(shí),設(shè)置相應(yīng)的處理方式。具體代碼如下:

LocationListenerlocationListener=newLocationListener()

{

@Override

publicvoidonLocationChanged(Locationlocation)

{

//這部分是自動(dòng)產(chǎn)生方法樁

updateLocation(location); }

@Override

publicvoidonProviderDisabled(Stringprovider)

{

//這部分是自動(dòng)產(chǎn)生方法樁

updateLocation(null);

}

@Override

publicvoidonProviderEnabled(Stringprovider) {

//這部分是自動(dòng)產(chǎn)生方法樁

updateLocation(location);

}

@Override

publicvoidonStatusChanged(Stringprovider,intstatus, Bundleextras){

//Provider的轉(zhuǎn)態(tài)在可用、暫時(shí)不可用和無(wú)服務(wù)三個(gè)狀態(tài)直接切換時(shí)觸發(fā)此函數(shù)

//這部分是自動(dòng)產(chǎn)生方法樁

}

};

(3)判讀GPS模式是否開啟,如果開啟將得到內(nèi)容提供器,并通過(guò)內(nèi)容提供器得到位置信息,調(diào)用updateLocation方法來(lái)更新位置數(shù)據(jù);如果沒(méi)有開啟,則轉(zhuǎn)到設(shè)置中的安全模塊,手動(dòng)開啟GPS,設(shè)置完成返回程序界面。通過(guò)GPS位置提供器獲得位置(指定具體的位置提供器),代碼如下:

Stringprovider=LocationManager.GPS_PROVIDER;

location=locationManager.getLastKnownLocation(provider);

(4)更新位置方法updateLocation(Locationlocation),當(dāng)位置信息location為空時(shí),設(shè)置經(jīng)緯度為0,否則讀取經(jīng)緯度信息,設(shè)置TextView信息。

privatevoidupdateLocation(Locationlocation)

{

//這部分是自動(dòng)產(chǎn)生方法樁

if(location!=null)

{

doublela=location.getLatitude();

doublelo=location.getLongitude();

latitude.setText("緯度為:"+la);

longitude.setText("經(jīng)度為:"+lo);

}

else

{

latitude.setText("緯度為:"+0);

longitude.setText("經(jīng)度為:"+0);

}

}圖7.1GPS軟件示例效果圖

4.實(shí)現(xiàn)效果經(jīng)過(guò)編譯,將GPS軟件安裝到AVD中后,效果實(shí)現(xiàn)圖如圖7.1所示。

7.2網(wǎng)絡(luò)監(jiān)控軟件

1.設(shè)置權(quán)限

在AndroidManifest文件中添加相應(yīng)的權(quán)限,代碼如下:

<!--允許一個(gè)程序訪問(wèn)CellID或WiFi熱點(diǎn)來(lái)獲取粗略的位置-->

<uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/>

2.編寫主界面代碼

程序采用ListView來(lái)展示手機(jī)參數(shù),因此編寫的主界面布局文件代碼如下:

<ListView

android:id=“@+id/listview”

android:layout_width=“fill_parent”

android:layout_height=“wrap_content”>

</ListView>

3.編寫數(shù)據(jù)頁(yè)面代碼

程序界面主體采用ListView作為數(shù)據(jù)展示方式,顯示數(shù)據(jù)采用自定義方式來(lái)實(shí)現(xiàn)。每一個(gè)ListView的Item都是由兩個(gè)TextView控件組成的,這兩個(gè)TextView控件采用水平布局,分別用來(lái)顯示標(biāo)題和內(nèi)容。編寫的數(shù)據(jù)頁(yè)面代碼如下:

<?xmlversion=“1.0”encoding=“utf-8”?>

<LinearLayout

xmlns:android="/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:orientation="horizontal"><TextView

android:id="@+id/title"

android:layout_width="100sp"

android:layout_height="wrap_content"

android:textSize="15sp"/><TextView

android:id="@+id/value"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="15sp"/>

</LinearLayout>

4.獲取網(wǎng)絡(luò)信息

1)?network方法

利用network方法獲取網(wǎng)絡(luò)信息包括如下兩步:

(1)調(diào)用系統(tǒng)服務(wù)方法獲取TelephonyManager,具體代碼如下:

tm=

(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

(2)分別調(diào)用getNetworkType、getPhoneType、getCellLocation方法獲取網(wǎng)絡(luò)類型、手機(jī)制式和小區(qū)信息。具體代碼如下:

//網(wǎng)絡(luò)類型

networkType=tm.getNetworkType();

switch(networkType)

{case0:

showNetWorkType="NETWORK_TYPE_UNKNOWN";

break;

case1:

showNetWorkType="NETWORK_TYPE_GPRS";

break;

case2:

showNetWorkType="NETWORK_TYPE_EDGE";

break;case3:

showNetWorkType="NETWORK_TYPE_UMTS";

break;

case4:

showNetWorkType="NETWORK_TYPE_CDMA";

break;

case5:

showNetWorkType="NETWORK_TYPE_EVDO_0";

break;case6:

showNetWorkType="NETWORK_TYPE_EVDO_A";

break;

case7:

showNetWorkType="NETWORK_TYPE_1xRTT";

break;

case8:

showNetWorkType="NETWORK_TYPE_HSDPA";

break;case9:

showNetWorkType="NETWORK_TYPE_HSUPA";

break;

case10:

showNetWorkType="NETWORK_TYPE_HSPA";

break;

case11:

showNetWorkType="NETWORK_TYPE_IDEN";

break;case12:

showNetWorkType="NETWORK_TYPE_EVDO_B";

break;

case13:

showNetWorkType="NETWORK_TYPE_LTE";

break;

case14:

showNetWorkType="NETWORK_TYPE_EHRPD";

break;case15:

showNetWorkType="NETWORK_TYPE_HSPAP";

break;

}

//手機(jī)類型

phoneType=tm.getPhoneType();

switch(phoneType){

case0:

showPhoneType="PHONE_TYPE_NONE";

break;

case1:

showPhoneType="PHONE_TYPE_GSM";

break;

case2:

showPhoneType="PHONE_TYPE_CDMA";

break;case3:

showPhoneType="PHONE_TYPE_SIP";

break;

}

//服務(wù)小區(qū)信息

cellLocation=(GsmCellLocation)tm.getCellLocation();

2)?show方法

首先定義一個(gè)列表用來(lái)存放數(shù)據(jù),其中每個(gè)元素為HashMap<String,String>;然后使用SimpleAdapter作為L(zhǎng)istView的適配器,將列表數(shù)據(jù)與listview_item.xml中的TextView控件對(duì)應(yīng)起來(lái),并進(jìn)行數(shù)據(jù)填充,代碼如下:privatevoidshow()

{

t=newTime();

t.setToNow();

//創(chuàng)建列表用于存儲(chǔ)數(shù)據(jù)

ArrayList<HashMap<String,String>>list=newArrayList<HashMap<String,String>>();

//時(shí)間 HashMap<String,String>map0=newHashMap<String,String>();

map0.put("title","時(shí)間");

map0.put("value",String.valueOf(t.format("%Y-%m-%d%H:%M:%S")));

//手機(jī)類型

HashMap<String,String>map1=newHashMap<String,String>();

map1.put("title","手機(jī)類型");

map1.put("value",showPhoneType); //網(wǎng)絡(luò)類型

HashMap<String,String>map2=newHashMap<String,String>();

map2.put("title","網(wǎng)絡(luò)類型");

map2.put("value",showNetWorkType);

//運(yùn)營(yíng)商

HashMap<String,String>map3=newHashMap<String,String>();

map3.put("title","運(yùn)營(yíng)商名字"); map3.put("value",tm.getNetworkOperatorName());

//服務(wù)小區(qū)信息

HashMap<String,String>map4=newHashMap<String,String>();

map4.put("title","cellLocation");

map4.put("value",String.valueOf(cellLocation));

list.add(map0);

list.add(map1); list.add(map2);

list.add(map3);

list.add(map4);

SimpleAdaptersa=newSimpleAdapter(this,list,R.layout.listview_item,newString[]{"title","value"},newint[]{R.id.title,R.id.value});

listView.setAdapter(sa);

}

5.實(shí)現(xiàn)效果

程序運(yùn)行結(jié)果顯示的界面如圖7.2所示。圖7.2網(wǎng)絡(luò)信息獲取軟件運(yùn)行結(jié)果

7.3基于手機(jī)的便攜式遠(yuǎn)程醫(yī)療監(jiān)護(hù)系統(tǒng)

信息采集設(shè)備將人體生理參數(shù)采集后使用藍(lán)牙發(fā)送至基于Android系統(tǒng)的手機(jī),隨后由手機(jī)將數(shù)據(jù)通過(guò)移動(dòng)通信網(wǎng)絡(luò)傳至服務(wù)器端,并由基于Linux的服務(wù)器端進(jìn)行數(shù)據(jù)匯總、存儲(chǔ)和分析。

基于手機(jī)的便攜式遠(yuǎn)程醫(yī)療監(jiān)護(hù)系統(tǒng)框架圖如圖7.3

所示。圖7.3基于手機(jī)的便攜式遠(yuǎn)程醫(yī)療監(jiān)護(hù)系統(tǒng)框架圖7.3.1功能分析

(1)采集人體血氧與心率數(shù)據(jù)。該功能由單片機(jī)控制采集模塊實(shí)現(xiàn)。由于本書重點(diǎn)并不在單片機(jī)控制采集模塊上,所以這一部分不再介紹。

(2)將人體血氧與心率數(shù)據(jù)發(fā)送至手機(jī)。該功能使用了藍(lán)牙技術(shù),采集端由單片機(jī)控制藍(lán)牙模塊實(shí)現(xiàn)數(shù)據(jù)發(fā)送,手機(jī)上通過(guò)Java編程實(shí)現(xiàn)數(shù)據(jù)接收。

(3)手機(jī)人性化界面。該功能使用了Android操作系統(tǒng)提供的界面控件,通過(guò)XML語(yǔ)言進(jìn)行布局,通過(guò)Java編程實(shí)現(xiàn)控制。

(4)手機(jī)將生理參數(shù)發(fā)送至服務(wù)器。該功能使用了Socket通信,由Java語(yǔ)言實(shí)現(xiàn)。

(5)服務(wù)器接收生理數(shù)據(jù)。該功能運(yùn)行于一基于Linux的服務(wù)器,通過(guò)Java編程實(shí)現(xiàn)Socket監(jiān)聽和接收數(shù)據(jù)的功能。

(6)保存生理參數(shù)歷史數(shù)據(jù)。在服務(wù)器上通過(guò)使用Mysql數(shù)據(jù)庫(kù)實(shí)現(xiàn)數(shù)據(jù)的保存與備份,并且它可以允許有權(quán)限的人隨時(shí)查閱。

(7)給出相關(guān)意見。由服務(wù)器對(duì)數(shù)據(jù)進(jìn)行分析,根據(jù)醫(yī)學(xué)理論對(duì)使用者提出相關(guān)建議,以實(shí)現(xiàn)更深入的智能化。由以上功能分析可知,手機(jī)端需要實(shí)現(xiàn)的是(2)~(4)步驟,對(duì)應(yīng)的流程圖如圖7.4所示,這幾個(gè)步驟就是Android應(yīng)用的體現(xiàn),所以我們將重點(diǎn)介紹這幾步的實(shí)現(xiàn)。服務(wù)器端采用的是Linux操作系統(tǒng)而非Android操作系統(tǒng),因此,其功能實(shí)現(xiàn)在此不予介紹。圖7.4Android手機(jī)端流程圖7.3.2手機(jī)端界面布局

1.主界面布局

主界面布局文件main.xml的代碼如下:

<?xmlversion=“1.0”encoding=“utf-8”?>

<AbsoluteLayoutxmlns:android=“/apk/res/android”

android:orientation=“vertical”

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”

>

<ImageViewandroid:id="@+id/startpic"

android:background="@drawable/white"

android:layout_width="fill_parent"

android:layout_height="fill_parent"/>

<TextView

android:id="@+id/state"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:gravity="center"

android:textColor="@drawable/dark" android:background=“@drawable/white”

android:textSize=“20sp”

android:layout_x=“0px”

android:layout_y=“400px”

>

</TextView>

</AbsoluteLayout>

運(yùn)行以后,效果如圖7.5所示。圖7.5醫(yī)療監(jiān)護(hù)系統(tǒng)主界面

2.登錄界面布局

登錄界面主要包括輸入用戶名和密碼、登錄或退出按鈕等內(nèi)容,其布局文件login.xml的代碼如下:

<?xmlversion="1.0"encoding="utf-8"?>

<AbsoluteLayoutxmlns:android="/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<TextView

android:id="@+id/user"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="20sp"

android:text="用戶名:"

android:layout_x="0px"

android:layout_y="10px"

>

</TextView>

<EditText

android:id="@+id/userValue"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text=""

android:textSize="18sp"

android:layout_x="0px"

android:layout_y="50px"

>

</EditText>

<TextView

android:id="@+id/password"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="20sp"

android:text="密碼:"

android:layout_x="0px"

android:layout_y="95px" >

</TextView>

<EditText

android:id="@+id/passwordValue"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:password="true"

android:text=""

android:textSize="18sp"

android:layout_x="0px"

android:layout_y="135px" >

</EditText>

<Button

android:id="@+id/enter"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="20sp"

android:text="登錄"

android:layout_x="50px"

android:layout_y="185px" >

</Button>

<Button

android:id="@+id/cancel"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="20sp"

android:text="取消"

android:layout_x="200px"

android:layout_y="185px"

>

</Button>

<ImageView

android:id=“@+id/picLogin”

android:layout_width=“fill_parent”

android:layout_height=“wrap_content”

android:layout_x=“0px”

android:layout_y=“100px”

>

</ImageView>

</AbsoluteLayout>運(yùn)行之后,登錄頁(yè)面效果如圖7.6所示。圖7.6醫(yī)療監(jiān)護(hù)系統(tǒng)登錄界面

3.監(jiān)控界面布局

監(jiān)控界面主要顯示所監(jiān)控的參數(shù)及其數(shù)值,監(jiān)控展示頁(yè)面布局文件monitor.xml的代碼如下:

<?xmlversion=“1.0”encoding=“utf-8”?>

<AbsoluteLayout

xmlns:android="/apk/res/android"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

<TextView

android:id="@+id/helloString"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text=""

android:textSize="20sp"

android:layout_x="0px"

android:layout_y="0px"

>

</TextView>

<TextView

android:id="@+id/speed"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="心率:"

android:textSize="25sp"

android:layout_x="35px"

android:layout_y="55px"

>

</TextView>

<TextView

android:id="@+id/speedValue"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text=""

android:textSize="25sp" android:textStyle=“bold”

android:textColor=“@drawable/red”

android:layout_x=“110px”

android:layout_y=“55px”

>

</TextView>

<TextView android:id=“@+id/speedUnit”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:text=“次/分”

android:textSize=“25sp”

android:layout_x=“150px”

android:layout_y=“55px”

>

</TextView>

<TextView

android:id="@+id/oxygen"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="血氧:"

android:textSize="25sp"

android:layout_x="35px"

android:layout_y="95px">

</TextView>

<TextView

android:id="@+id/oxygenValue"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text=""

android:textSize="25sp"

android:textStyle="bold"

android:textColor="@drawable/red"

android:layout_x="110px"

android:layout_y="95px">

</TextView>

<TextView

android:id="@+id/oxygenUnit"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="%"

android:textSize="25sp"

android:layout_x="150px"

android:layout_y="95px"

></TextView>

<ImageView

android:id="@+id/picMedic"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_x="0px"

android:layout_y="100px"

>

</ImageView>

</AbsoluteLayout>7.3.3手機(jī)端功能的設(shè)計(jì)與實(shí)現(xiàn)

根據(jù)上面功能分析可知,手機(jī)端需要完成的功能包括:

(1)藍(lán)牙設(shè)備連接。

(2)藍(lán)牙數(shù)據(jù)獲取。

(3)用戶登錄醫(yī)療監(jiān)控系統(tǒng)。

(4)將藍(lán)牙獲取到的數(shù)據(jù)發(fā)送到醫(yī)療監(jiān)控系統(tǒng)服務(wù)器。

1.藍(lán)牙連接

藍(lán)牙連接包括藍(lán)牙設(shè)備連接和藍(lán)牙數(shù)據(jù)獲取,其實(shí)現(xiàn)代碼如下:

importjava.io.IOException;

importjava.io.InputStream;

importjava.io.OutputStream;

importjava.util.UUID;

importandroid.bluetooth.BluetoothAdapter;

importandroid.bluetooth.BluetoothDevice;importandroid.bluetooth.BluetoothServerSocket;

importandroid.bluetooth.BluetoothSocket;

importandroid.content.Context;

importandroid.os.Bundle;

importandroid.os.Handler;

importandroid.os.Message;

importandroid.util.Log;

/***這個(gè)類完成安裝和管理藍(lán)牙和其他設(shè)備連接的所有工作。它有一個(gè)線程負(fù)責(zé)監(jiān)聽進(jìn)來(lái)的連接,

*一個(gè)線程負(fù)責(zé)連接設(shè)備,還有一個(gè)線程完成連接時(shí)的數(shù)據(jù)傳輸

*/

publicclassBluetoothChatService{

//Debug調(diào)試

privatestaticfinalStringTAG="BluetoothMedicService";

privatestaticfinalbooleanD=true; //創(chuàng)建服務(wù)器套接字時(shí)的SDP記錄的名字

privatestaticfinalStringNAME="BluetoothMedic";

//這個(gè)應(yīng)用程序唯一的UUID

privatestaticfinalUUIDMY_UUID=UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

//成員域 privatefinalBluetoothAdaptermAdapter;

privatefinalHandlermHandler;

privateAcceptThreadmAcceptThread;

privateConnectThreadmConnectThread;

privateConnectedThreadmConnectedThread;

privateintmState;

//表明當(dāng)前連接狀態(tài)的常量 publicstaticfinalintSTATE_NONE=0; //我們現(xiàn)在什么都沒(méi)做

publicstaticfinalintSTATE_LISTEN=1; //現(xiàn)在監(jiān)聽進(jìn)來(lái)的連接

publicstaticfinalintSTATE_CONNECTING=2; //現(xiàn)在初始化一個(gè)出去的連接

publicstaticfinalintSTATE_CONNECTED=3; //現(xiàn)在連接到一個(gè)遠(yuǎn)端設(shè)備

/** *構(gòu)造方法。準(zhǔn)備一個(gè)新的BluetoothChat會(huì)話

*@paramcontextUI活動(dòng)上下文

*@paramhandler將消息發(fā)送回UI活動(dòng)的句柄

*/

publicBluetoothChatService(Contextcontext,Handlerhandler){

mAdapter=BluetoothAdapter.getDefaultAdapter();

mState=STATE_NONE;

mHandler=handler; }

/**

*設(shè)置對(duì)話連接的當(dāng)前狀態(tài)

*@paramstate一個(gè)整數(shù)定義當(dāng)前連接狀態(tài)

*/

privatesynchronizedvoidsetState(intstate){

if(D)Log.d(TAG,"setState()"+mState+"->"+state);

mState=state; //給句柄一個(gè)新狀態(tài),這樣UI活動(dòng)可以更新

mHandler.obtainMessage(monitor.MESSAGE_STATE_CHANGE,state,-1).sendToTarget();

}

/**

*返回當(dāng)前的狀態(tài)*/

publicsynchronizedintgetState(){

returnmState;}

/**

*啟動(dòng)聊天服務(wù)。特別之處是以偵聽(服務(wù)器)模式啟動(dòng)AcceptThread以開始一個(gè)會(huì)話*/

publicsynchronizedvoidstart(){

if(D)Log.d(TAG,"start");

//取消任何一個(gè)試圖建立連接的線程 if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}

//取消任何一個(gè)當(dāng)前正在運(yùn)行連接的線程

if(mConnectedThread!=null){

mConnectedThread.cancel();

mConnectedThread=null;

} //啟動(dòng)線程偵聽藍(lán)牙服務(wù)器套接字

if(mAcceptThread==null){

mAcceptThread=newAcceptThread();

mAcceptThread.start();

}

setState(STATE_LISTEN);

}

/** *啟動(dòng)ConnectThread以初始化一個(gè)到遠(yuǎn)端設(shè)備的連接

*@paramdevice要連接的藍(lán)牙設(shè)備

*/

publicsynchronizedvoidconnect(BluetoothDevicedevice){

if(D)Log.d(TAG,"connectto:"+device);

//取消任何一個(gè)試圖建立連接的線程

if(mState==STATE_CONNECTING){ if(mConnectThread!=null){

mConnectThread.cancel();

mConnectThread=null;}

}

//取消任何一個(gè)當(dāng)前正在運(yùn)行連接的線程

if(mConnectedThread!=null){

mConnectedThread.cancel();

mConnectedThread=null;} //啟動(dòng)連接給定設(shè)備的線程

mConnectThread=newConnectThread(device);

mConnectThread.start();

setState(STATE_CONNECTING);

}

/**

*啟動(dòng)ConnectedThread開始對(duì)藍(lán)牙連接的管理 *@paramsocket建立連接處的藍(lán)牙套接字

*@paramdevice已經(jīng)被連接上的藍(lán)牙設(shè)備

*/

publicsynchronizedvoidconnected(BluetoothSocketsocket,BluetoothDevicedevice)

{if(D)Log.d(TAG,"connected");

//取消完成連接的線程 if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}

//取消任何一個(gè)正在運(yùn)行連接的線程

if(mConnectedThread!=null){

mConnectedThread.cancel();

mConnectedThread=null;} //取消接受線程因?yàn)槲覀冎幌脒B接到一個(gè)設(shè)備

if(mAcceptThread!=null){mAcceptThread.cancel();mAcceptThread=null;}

//啟動(dòng)管理連接和完成傳輸?shù)木€程

mConnectedThread=newConnectedThread(socket);

mConnectedThread.start();

//將被連接的設(shè)備的名字發(fā)送回UI活動(dòng) Messagemsg=mHandler.obtainMessage(monitor.MESSAGE_DEVICE_NAME);

Bundlebundle=newBundle();

bundle.putString(monitor.DEVICE_NAME,device.getName());

msg.setData(bundle);

mHandler.sendMessage(msg);

setState(STATE_CONNECTED); }

/**

*終止所有線程

*/

publicsynchronizedvoidstop(){

if(D)Log.d(TAG,"stop");

if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}

if(mConnectedThread!=null){mConnectedThread.cancel();

mConnectedThread=null;}

if(mAcceptThread!=null){mAcceptThread.cancel();mAcceptThread=null;}

setState(STATE_NONE);

}

/**

*以非同步方式寫到ConnectedThread

*@paramout要寫的類型 *@seeConnectedThread#write(byte[])

*/

publicvoidwrite(byte[]out){

//創(chuàng)建臨時(shí)對(duì)象

ConnectedThreadr;

//同步ConnectedThread的一個(gè)拷貝

synchronized(this){

if(mState!=STATE_CONNECTED)return;

r=mConnectedThread }

//完成非同步寫入

r.write(out);

}

/**

*表明連接嘗試失敗并通知UI活動(dòng)

*/

privatevoidconnectionFailed(){

setState(STATE_LISTEN);

//發(fā)送一個(gè)失敗消息回給活動(dòng) Messagemsg=mHandler.obtainMessage(monitor.MESSAGE_TOAST);

Bundlebundle=newBundle();

bundle.putString(monitor.TOAST,"無(wú)法連接");

msg.setData(bundle);

mHandler.sendMessage(msg);

}

/**

*表明丟失連接并通知UI活動(dòng)

*/ privatevoidconnectionLost(){

setState(STATE_LISTEN);

//發(fā)送失敗消息返回給這個(gè)活動(dòng)

Messagemsg=mHandler.obtainMessage(monitor.MESSAGE_TOAST);

Bundlebundle=newBundle();

bundle.putString(monitor.TOAST,"設(shè)備丟失");

msg.setData(bundle);

mHandler.sendMessage(msg); }

/**

*偵聽進(jìn)來(lái)的連接時(shí)運(yùn)行這個(gè)線程。它就像一個(gè)服務(wù)器端的客戶。

*它持續(xù)運(yùn)行直到一個(gè)連接被接受(或者直到一個(gè)連接被取消)

*/

privateclassAcceptThreadextendsThread{

//本地服務(wù)器套接字

privatefinalBluetoothServerSocketmmServerSocket; publicAcceptThread(){

BluetoothServerSockettmp=null;

//創(chuàng)建一個(gè)新的偵聽服務(wù)器套接字

try{

tmp=mAdapter.listenUsingRfcommWithServiceRecord(NAME,MY_UUID);

}catch(IOExceptione){

Log.e(TAG,"listen()failed",e);

} mmServerSocket=tmp;

}

publicvoidrun(){

if(D)Log.d(TAG,"BEGINmAcceptThread"+this);

setName("AcceptThread");

BluetoothSocketsocket=null;

//如果我們沒(méi)有被連接就偵聽服務(wù)器套接字 while(mState!=STATE_CONNECTED){

try{

//這是一個(gè)塊調(diào)用,它只會(huì)在成功連接或者出現(xiàn)異常時(shí)返回

socket=mmServerSocket.accept();

}catch(IOExceptione){

Log.e(TAG,"accept()failed",e);

break;

} //如果接受了一個(gè)連接

if(socket!=null){

synchronized(BluetoothChatService.this){

switch(mState){

caseSTATE_LISTEN:

caseSTATE_CONNECTING:

//情況正常。啟動(dòng)連接的線程 connected(socket,socket.getRemoteDevice());

break;

caseSTATE_NONE:

caseSTATE_CONNECTED:

//或者沒(méi)準(zhǔn)備或者已經(jīng)連接。終止新套接字

try{

socket.close(); }catch(IOExceptione){

Log.e(TAG,"Couldnotcloseunwantedsocket",e);

}

break;

}

}

}

}

if(D)Log.i(TAG,"ENDmAcceptThread"); }

publicvoidcancel(){

if(D)Log.d(TAG,"cancel"+this);

try{

mmServerSocket.close();

}catch(IOExceptione){

Log.e(TAG,"close()ofserverfailed",e);

}

}

} /**

*當(dāng)嘗試建立一個(gè)和設(shè)備建立出去的連接時(shí)運(yùn)行這個(gè)線程。

*它直接運(yùn)行過(guò)去;連接或者成功或者失敗。

*/

privateclassConnectThreadextendsThread{

privatefinalBluetoothSocketmmSocket;

privatefinalBluetoothDevicemmDevice; publicConnectThread(BluetoothDevicedevice){

mmDevice=device;

BluetoothSockettmp=null;

//獲取一個(gè)連接到給定藍(lán)牙設(shè)備的藍(lán)牙套接字

try{

tmp=device.createRfcommSocketToServiceRecord(MY_UUID);

}catch(IOExceptione){

Log.e(TAG,"create()failed",e); }

mmSocket=tmp;

}

publicvoidrun(){

Log.i(TAG,"BEGINmConnectThread");

setName("ConnectThread");

//總是取消探索因?yàn)樗鼤?huì)放慢連接

mAdapter.cancelDiscovery();

//建立一個(gè)到藍(lán)牙套接字的連接 try{

//這是一個(gè)塊調(diào)用,只會(huì)在成功連接或者出現(xiàn)異常時(shí)返回

mmSocket.connect();

}catch(IOExceptione){

connectionFailed();

//關(guān)閉套接字

try{

mmSocket.close();

}catch(IOExceptione2){

Log.e(TAG,"unabletoclose()socketduringconnectionfailure",e2);

} //啟動(dòng)服務(wù)重啟偵聽模式

BluetoothChatService.this.start();

return;

}

//重置連接線程因?yàn)槲覀円呀?jīng)做過(guò)了

synchronized(BluetoothChatService.this){

mConnectThread=null;

}

//啟動(dòng)連接的線程

connected(mmSocket,mmDevice); }

publicvoidcancel(){

try{

mmSocket.close();

}catch(IOExceptione){

Log.e(TAG,"close()ofconnectsocketfailed",e);

}

}

} /**

*在連接到一個(gè)遠(yuǎn)端設(shè)備過(guò)程中運(yùn)行這個(gè)線程。它處理所有進(jìn)入和出去的傳輸

*/

privateclassConnectedThreadextendsThread{

privatefinalBluetoothSocketmmSocket;

privatefinalInputStreammmInStream;

privatefinalOutputStreammmOutStream; publicConnectedThread(BluetoothSocketsocket){

Log.d(TAG,"createConnectedThread");

mmSocket=socket;

InputStreamtmpIn=null;

OutputStreamtmpOut=null;

//獲取藍(lán)牙套接字輸入和輸出流 try{

tmpIn=socket.getInputStream();

tmpOut=socket.getOutputStream();

}catch(IOExceptione){

Log.e(TAG,"tempsocketsnotcreated",e);

}

mmInStream=tmpIn;

mmOutStream=tmpOut;

} publicvoidrun(){

Log.i(TAG,“BEGINmConnectedThread”);

byte[]buffer=newbyte[256];

intbytes;

//當(dāng)連接時(shí)持續(xù)偵聽輸入流

while(true){

try{

//從輸入流讀取

bytes=mmInStream.read(buffer); //給UI活動(dòng)發(fā)送獲取的類型

mHandler.obtainMessage(monitor.MESSAGE_READ,bytes,-1,buffer)

.sendToTarget();

}catch(IOExceptione){

Log.e(TAG,"disconnected",e);

connectionLost();

break;

}

}

} /**

*寫入連接的OutStream

*@parambuffer要寫入的類型

*/

publicvoidwrite(byte[]buffer){

try{

mmOutStream.write(buffer);

//共享發(fā)送的消息回UI活動(dòng)

mHandler.obtainMessage(monitor.MESSAGE_WRITE,-1,-1,buffer)

.sendToTarget(); }catch(IOExceptione){

Log.e(TAG,"Exceptionduringwrite",e);

}

}

publicvoidcancel(){

try{

mmSocket.close(); }catch(IOExceptione){

Log.e(TAG,“close()ofconnectsocketfailed”,e);

}

}

}

}

2.?Socket通信

Socket通信實(shí)現(xiàn)手機(jī)與服務(wù)器的通信,其實(shí)現(xiàn)代碼如下:

importjava.io.DataInputStream;

importjava.io.DataOutputStream;

import.Socket;

publicclassSocketService{

privatestaticfinalStringHOST="02"; privatestaticfinalintPORT=1234;

publicStringsendData(StringdataVar1){

Sockets=null;

DataOutputStreamdout=null;

DataInputStreamdin=null;

Stringrecieved=newString(); try{

s=newSocket(HOST,PORT); //連接服務(wù)器

dout=newDataOutputStream(s.getOutputStream()); //得到輸出流

din=newDataInputStream(s.getInputStream()); //得到輸入流

dout.writeUTF(dataVar1); //向服務(wù)器發(fā)送消息

recieved=din.readUTF();

din.close(); dout.close();

//關(guān)閉此Socket連接

s.close();

}catch(Exceptione){

e.printStackTrace(); //打印異常信息

}

returnrecieved;

}

}

3.主頁(yè)面代碼

主頁(yè)面的實(shí)現(xiàn)代碼如下:

importandroid.app.Activity;

importandroid.app.AlertDialog;

importandroid.bluetooth.BluetoothAdapter;

importandroid.content.DialogInterface;

importandroid.content.Intent;

importandroid.os.Bundle;importandroid.view.View;

importandroid.widget.ImageView;

importandroid.widget.TextView;

publicclassmainextendsActivity{

ImageViewstartPic;

TextViewstartState;

protectedstaticfinalintREQUEST_ENABLE_BT=0;

/*當(dāng)首次創(chuàng)建這個(gè)活動(dòng)時(shí)被調(diào)用*/ @Override

publicvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

setTitle(“正在啟動(dòng)中,請(qǐng)稍后”);

startState=(TextView)findViewById(R.id.state);

startState.setText(“點(diǎn)擊進(jìn)入...”);

startPic=(ImageView)findViewById(R.id.startpic);

startPic.setImageDrawable(getResources().

getDrawable(R.drawable.startup));

startPic.setOnClickListener(newImageView.OnClickListener(){

publicvoidonClick(Viewv){

Intentintent=newIntent();

intent.setClass(main.this,login.class);

startActivity(intent);

main.this.finish();

}

}); BluetoothAdaptercwjBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();

if(cwjBluetoothAdapter==null){

newAlertDialog.Builder(main.this)

.setTitle(R.string.error)

.setIcon(R.drawable.error)

.setMessage(R.string.no_bluetooth) .setPositiveButton(R.string.certain,

newDialogInterface.OnClickListener()

{

publicvoidonClick(DialogInterfacedialoginterface,inti)

{

//main.this.finish();

}

}

)

.show(

溫馨提示

  • 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)論