版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第7章Android開發(fā)實例7.1
GPS定位軟件7.2網(wǎng)絡(luò)監(jiān)控軟件7.3基于手機的便攜式遠程醫(yī)療監(jiān)護系統(tǒng)7.1GPS定位軟件
1.設(shè)置權(quán)限
首先,添加GPS定位權(quán)限到AndroidManifest文件中,代碼如下:
<!--允許一個程序訪問精確位置-->
<uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--允許程序創(chuàng)建模擬位置用于測試-->
<uses-permissionandroid:name="android.permission.ACCESS_MOCK_LOCATION"/>
2.編寫主頁面代碼
在界面布局文件(main.xml)中添加TextView控件,分別用來顯示緯度和經(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主程序代碼
具體實現(xiàn)的步驟如下:
(1)首先,我們需要獲取LocationManager的一個實例,這里需要注意的是此實例只能通過下面這種方式來獲取,直接實例化LocationManager是不被允許的:
locationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
(2)定義Location事件監(jiān)聽,當位置改變或狀態(tài)變化,可用和不可用時,設(shè)置相應(yīng)的處理方式。具體代碼如下:
LocationListenerlocationListener=newLocationListener()
{
@Override
publicvoidonLocationChanged(Locationlocation)
{
//這部分是自動產(chǎn)生方法樁
updateLocation(location); }
@Override
publicvoidonProviderDisabled(Stringprovider)
{
//這部分是自動產(chǎn)生方法樁
updateLocation(null);
}
@Override
publicvoidonProviderEnabled(Stringprovider) {
//這部分是自動產(chǎn)生方法樁
updateLocation(location);
}
@Override
publicvoidonStatusChanged(Stringprovider,intstatus, Bundleextras){
//Provider的轉(zhuǎn)態(tài)在可用、暫時不可用和無服務(wù)三個狀態(tài)直接切換時觸發(fā)此函數(shù)
//這部分是自動產(chǎn)生方法樁
}
};
(3)判讀GPS模式是否開啟,如果開啟將得到內(nèi)容提供器,并通過內(nèi)容提供器得到位置信息,調(diào)用updateLocation方法來更新位置數(shù)據(jù);如果沒有開啟,則轉(zhuǎn)到設(shè)置中的安全模塊,手動開啟GPS,設(shè)置完成返回程序界面。通過GPS位置提供器獲得位置(指定具體的位置提供器),代碼如下:
Stringprovider=LocationManager.GPS_PROVIDER;
location=locationManager.getLastKnownLocation(provider);
(4)更新位置方法updateLocation(Locationlocation),當位置信息location為空時,設(shè)置經(jīng)緯度為0,否則讀取經(jīng)緯度信息,設(shè)置TextView信息。
privatevoidupdateLocation(Locationlocation)
{
//這部分是自動產(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.實現(xiàn)效果經(jīng)過編譯,將GPS軟件安裝到AVD中后,效果實現(xiàn)圖如圖7.1所示。
7.2網(wǎng)絡(luò)監(jiān)控軟件
1.設(shè)置權(quán)限
在AndroidManifest文件中添加相應(yīng)的權(quán)限,代碼如下:
<!--允許一個程序訪問CellID或WiFi熱點來獲取粗略的位置-->
<uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/>
2.編寫主界面代碼
程序采用ListView來展示手機參數(shù),因此編寫的主界面布局文件代碼如下:
<ListView
android:id=“@+id/listview”
android:layout_width=“fill_parent”
android:layout_height=“wrap_content”>
</ListView>
3.編寫數(shù)據(jù)頁面代碼
程序界面主體采用ListView作為數(shù)據(jù)展示方式,顯示數(shù)據(jù)采用自定義方式來實現(xiàn)。每一個ListView的Item都是由兩個TextView控件組成的,這兩個TextView控件采用水平布局,分別用來顯示標題和內(nèi)容。編寫的數(shù)據(jù)頁面代碼如下:
<?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ò)類型、手機制式和小區(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;
}
//手機類型
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方法
首先定義一個列表用來存放數(shù)據(jù),其中每個元素為HashMap<String,String>;然后使用SimpleAdapter作為ListView的適配器,將列表數(shù)據(jù)與listview_item.xml中的TextView控件對應(yīng)起來,并進行數(shù)據(jù)填充,代碼如下:privatevoidshow()
{
t=newTime();
t.setToNow();
//創(chuàng)建列表用于存儲數(shù)據(jù)
ArrayList<HashMap<String,String>>list=newArrayList<HashMap<String,String>>();
//時間 HashMap<String,String>map0=newHashMap<String,String>();
map0.put("title","時間");
map0.put("value",String.valueOf(t.format("%Y-%m-%d%H:%M:%S")));
//手機類型
HashMap<String,String>map1=newHashMap<String,String>();
map1.put("title","手機類型");
map1.put("value",showPhoneType); //網(wǎng)絡(luò)類型
HashMap<String,String>map2=newHashMap<String,String>();
map2.put("title","網(wǎng)絡(luò)類型");
map2.put("value",showNetWorkType);
//運營商
HashMap<String,String>map3=newHashMap<String,String>();
map3.put("title","運營商名字"); 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.實現(xiàn)效果
程序運行結(jié)果顯示的界面如圖7.2所示。圖7.2網(wǎng)絡(luò)信息獲取軟件運行結(jié)果
7.3基于手機的便攜式遠程醫(yī)療監(jiān)護系統(tǒng)
信息采集設(shè)備將人體生理參數(shù)采集后使用藍牙發(fā)送至基于Android系統(tǒng)的手機,隨后由手機將數(shù)據(jù)通過移動通信網(wǎng)絡(luò)傳至服務(wù)器端,并由基于Linux的服務(wù)器端進行數(shù)據(jù)匯總、存儲和分析。
基于手機的便攜式遠程醫(yī)療監(jiān)護系統(tǒng)框架圖如圖7.3
所示。圖7.3基于手機的便攜式遠程醫(yī)療監(jiān)護系統(tǒng)框架圖7.3.1功能分析
(1)采集人體血氧與心率數(shù)據(jù)。該功能由單片機控制采集模塊實現(xiàn)。由于本書重點并不在單片機控制采集模塊上,所以這一部分不再介紹。
(2)將人體血氧與心率數(shù)據(jù)發(fā)送至手機。該功能使用了藍牙技術(shù),采集端由單片機控制藍牙模塊實現(xiàn)數(shù)據(jù)發(fā)送,手機上通過Java編程實現(xiàn)數(shù)據(jù)接收。
(3)手機人性化界面。該功能使用了Android操作系統(tǒng)提供的界面控件,通過XML語言進行布局,通過Java編程實現(xiàn)控制。
(4)手機將生理參數(shù)發(fā)送至服務(wù)器。該功能使用了Socket通信,由Java語言實現(xiàn)。
(5)服務(wù)器接收生理數(shù)據(jù)。該功能運行于一基于Linux的服務(wù)器,通過Java編程實現(xiàn)Socket監(jiān)聽和接收數(shù)據(jù)的功能。
(6)保存生理參數(shù)歷史數(shù)據(jù)。在服務(wù)器上通過使用Mysql數(shù)據(jù)庫實現(xiàn)數(shù)據(jù)的保存與備份,并且它可以允許有權(quán)限的人隨時查閱。
(7)給出相關(guān)意見。由服務(wù)器對數(shù)據(jù)進行分析,根據(jù)醫(yī)學理論對使用者提出相關(guān)建議,以實現(xiàn)更深入的智能化。由以上功能分析可知,手機端需要實現(xiàn)的是(2)~(4)步驟,對應(yīng)的流程圖如圖7.4所示,這幾個步驟就是Android應(yīng)用的體現(xiàn),所以我們將重點介紹這幾步的實現(xiàn)。服務(wù)器端采用的是Linux操作系統(tǒng)而非Android操作系統(tǒng),因此,其功能實現(xiàn)在此不予介紹。圖7.4Android手機端流程圖7.3.2手機端界面布局
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>
運行以后,效果如圖7.5所示。圖7.5醫(yī)療監(jiān)護系統(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>運行之后,登錄頁面效果如圖7.6所示。圖7.6醫(yī)療監(jiān)護系統(tǒng)登錄界面
3.監(jiān)控界面布局
監(jiān)控界面主要顯示所監(jiān)控的參數(shù)及其數(shù)值,監(jiān)控展示頁面布局文件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手機端功能的設(shè)計與實現(xiàn)
根據(jù)上面功能分析可知,手機端需要完成的功能包括:
(1)藍牙設(shè)備連接。
(2)藍牙數(shù)據(jù)獲取。
(3)用戶登錄醫(yī)療監(jiān)控系統(tǒng)。
(4)將藍牙獲取到的數(shù)據(jù)發(fā)送到醫(yī)療監(jiān)控系統(tǒng)服務(wù)器。
1.藍牙連接
藍牙連接包括藍牙設(shè)備連接和藍牙數(shù)據(jù)獲取,其實現(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;
/***這個類完成安裝和管理藍牙和其他設(shè)備連接的所有工作。它有一個線程負責監(jiān)聽進來的連接,
*一個線程負責連接設(shè)備,還有一個線程完成連接時的數(shù)據(jù)傳輸
*/
publicclassBluetoothChatService{
//Debug調(diào)試
privatestaticfinalStringTAG="BluetoothMedicService";
privatestaticfinalbooleanD=true; //創(chuàng)建服務(wù)器套接字時的SDP記錄的名字
privatestaticfinalStringNAME="BluetoothMedic";
//這個應(yīng)用程序唯一的UUID
privatestaticfinalUUIDMY_UUID=UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
//成員域 privatefinalBluetoothAdaptermAdapter;
privatefinalHandlermHandler;
privateAcceptThreadmAcceptThread;
privateConnectThreadmConnectThread;
privateConnectedThreadmConnectedThread;
privateintmState;
//表明當前連接狀態(tài)的常量 publicstaticfinalintSTATE_NONE=0; //我們現(xiàn)在什么都沒做
publicstaticfinalintSTATE_LISTEN=1; //現(xiàn)在監(jiān)聽進來的連接
publicstaticfinalintSTATE_CONNECTING=2; //現(xiàn)在初始化一個出去的連接
publicstaticfinalintSTATE_CONNECTED=3; //現(xiàn)在連接到一個遠端設(shè)備
/** *構(gòu)造方法。準備一個新的BluetoothChat會話
*@paramcontextUI活動上下文
*@paramhandler將消息發(fā)送回UI活動的句柄
*/
publicBluetoothChatService(Contextcontext,Handlerhandler){
mAdapter=BluetoothAdapter.getDefaultAdapter();
mState=STATE_NONE;
mHandler=handler; }
/**
*設(shè)置對話連接的當前狀態(tài)
*@paramstate一個整數(shù)定義當前連接狀態(tài)
*/
privatesynchronizedvoidsetState(intstate){
if(D)Log.d(TAG,"setState()"+mState+"->"+state);
mState=state; //給句柄一個新狀態(tài),這樣UI活動可以更新
mHandler.obtainMessage(monitor.MESSAGE_STATE_CHANGE,state,-1).sendToTarget();
}
/**
*返回當前的狀態(tài)*/
publicsynchronizedintgetState(){
returnmState;}
/**
*啟動聊天服務(wù)。特別之處是以偵聽(服務(wù)器)模式啟動AcceptThread以開始一個會話*/
publicsynchronizedvoidstart(){
if(D)Log.d(TAG,"start");
//取消任何一個試圖建立連接的線程 if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}
//取消任何一個當前正在運行連接的線程
if(mConnectedThread!=null){
mConnectedThread.cancel();
mConnectedThread=null;
} //啟動線程偵聽藍牙服務(wù)器套接字
if(mAcceptThread==null){
mAcceptThread=newAcceptThread();
mAcceptThread.start();
}
setState(STATE_LISTEN);
}
/** *啟動ConnectThread以初始化一個到遠端設(shè)備的連接
*@paramdevice要連接的藍牙設(shè)備
*/
publicsynchronizedvoidconnect(BluetoothDevicedevice){
if(D)Log.d(TAG,"connectto:"+device);
//取消任何一個試圖建立連接的線程
if(mState==STATE_CONNECTING){ if(mConnectThread!=null){
mConnectThread.cancel();
mConnectThread=null;}
}
//取消任何一個當前正在運行連接的線程
if(mConnectedThread!=null){
mConnectedThread.cancel();
mConnectedThread=null;} //啟動連接給定設(shè)備的線程
mConnectThread=newConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
/**
*啟動ConnectedThread開始對藍牙連接的管理 *@paramsocket建立連接處的藍牙套接字
*@paramdevice已經(jīng)被連接上的藍牙設(shè)備
*/
publicsynchronizedvoidconnected(BluetoothSocketsocket,BluetoothDevicedevice)
{if(D)Log.d(TAG,"connected");
//取消完成連接的線程 if(mConnectThread!=null){mConnectThread.cancel();mConnectThread=null;}
//取消任何一個正在運行連接的線程
if(mConnectedThread!=null){
mConnectedThread.cancel();
mConnectedThread=null;} //取消接受線程因為我們只想連接到一個設(shè)備
if(mAcceptThread!=null){mAcceptThread.cancel();mAcceptThread=null;}
//啟動管理連接和完成傳輸?shù)木€程
mConnectedThread=newConnectedThread(socket);
mConnectedThread.start();
//將被連接的設(shè)備的名字發(fā)送回UI活動 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)建臨時對象
ConnectedThreadr;
//同步ConnectedThread的一個拷貝
synchronized(this){
if(mState!=STATE_CONNECTED)return;
r=mConnectedThread }
//完成非同步寫入
r.write(out);
}
/**
*表明連接嘗試失敗并通知UI活動
*/
privatevoidconnectionFailed(){
setState(STATE_LISTEN);
//發(fā)送一個失敗消息回給活動 Messagemsg=mHandler.obtainMessage(monitor.MESSAGE_TOAST);
Bundlebundle=newBundle();
bundle.putString(monitor.TOAST,"無法連接");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
*表明丟失連接并通知UI活動
*/ privatevoidconnectionLost(){
setState(STATE_LISTEN);
//發(fā)送失敗消息返回給這個活動
Messagemsg=mHandler.obtainMessage(monitor.MESSAGE_TOAST);
Bundlebundle=newBundle();
bundle.putString(monitor.TOAST,"設(shè)備丟失");
msg.setData(bundle);
mHandler.sendMessage(msg); }
/**
*偵聽進來的連接時運行這個線程。它就像一個服務(wù)器端的客戶。
*它持續(xù)運行直到一個連接被接受(或者直到一個連接被取消)
*/
privateclassAcceptThreadextendsThread{
//本地服務(wù)器套接字
privatefinalBluetoothServerSocketmmServerSocket; publicAcceptThread(){
BluetoothServerSockettmp=null;
//創(chuàng)建一個新的偵聽服務(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;
//如果我們沒有被連接就偵聽服務(wù)器套接字 while(mState!=STATE_CONNECTED){
try{
//這是一個塊調(diào)用,它只會在成功連接或者出現(xiàn)異常時返回
socket=mmServerSocket.accept();
}catch(IOExceptione){
Log.e(TAG,"accept()failed",e);
break;
} //如果接受了一個連接
if(socket!=null){
synchronized(BluetoothChatService.this){
switch(mState){
caseSTATE_LISTEN:
caseSTATE_CONNECTING:
//情況正常。啟動連接的線程 connected(socket,socket.getRemoteDevice());
break;
caseSTATE_NONE:
caseSTATE_CONNECTED:
//或者沒準備或者已經(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);
}
}
} /**
*當嘗試建立一個和設(shè)備建立出去的連接時運行這個線程。
*它直接運行過去;連接或者成功或者失敗。
*/
privateclassConnectThreadextendsThread{
privatefinalBluetoothSocketmmSocket;
privatefinalBluetoothDevicemmDevice; publicConnectThread(BluetoothDevicedevice){
mmDevice=device;
BluetoothSockettmp=null;
//獲取一個連接到給定藍牙設(shè)備的藍牙套接字
try{
tmp=device.createRfcommSocketToServiceRecord(MY_UUID);
}catch(IOExceptione){
Log.e(TAG,"create()failed",e); }
mmSocket=tmp;
}
publicvoidrun(){
Log.i(TAG,"BEGINmConnectThread");
setName("ConnectThread");
//總是取消探索因為它會放慢連接
mAdapter.cancelDiscovery();
//建立一個到藍牙套接字的連接 try{
//這是一個塊調(diào)用,只會在成功連接或者出現(xiàn)異常時返回
mmSocket.connect();
}catch(IOExceptione){
connectionFailed();
//關(guān)閉套接字
try{
mmSocket.close();
}catch(IOExceptione2){
Log.e(TAG,"unabletoclose()socketduringconnectionfailure",e2);
} //啟動服務(wù)重啟偵聽模式
BluetoothChatService.this.start();
return;
}
//重置連接線程因為我們已經(jīng)做過了
synchronized(BluetoothChatService.this){
mConnectThread=null;
}
//啟動連接的線程
connected(mmSocket,mmDevice); }
publicvoidcancel(){
try{
mmSocket.close();
}catch(IOExceptione){
Log.e(TAG,"close()ofconnectsocketfailed",e);
}
}
} /**
*在連接到一個遠端設(shè)備過程中運行這個線程。它處理所有進入和出去的傳輸
*/
privateclassConnectedThreadextendsThread{
privatefinalBluetoothSocketmmSocket;
privatefinalInputStreammmInStream;
privatefinalOutputStreammmOutStream; publicConnectedThread(BluetoothSocketsocket){
Log.d(TAG,"createConnectedThread");
mmSocket=socket;
InputStreamtmpIn=null;
OutputStreamtmpOut=null;
//獲取藍牙套接字輸入和輸出流 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;
//當連接時持續(xù)偵聽輸入流
while(true){
try{
//從輸入流讀取
bytes=mmInStream.read(buffer); //給UI活動發(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活動
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通信實現(xiàn)手機與服務(wù)器的通信,其實現(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.主頁面代碼
主頁面的實現(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;
/*當首次創(chuàng)建這個活動時被調(diào)用*/ @Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setTitle(“正在啟動中,請稍后”);
startState=(TextView)findViewById(R.id.state);
startState.setText(“點擊進入...”);
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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 質(zhì)量檢驗員聘用合同格式
- 2024年度醫(yī)療器械代理注冊合同規(guī)范范本3篇
- 食品安全合同管理流程
- 2025年度五星級酒店VIP客戶住宿服務(wù)協(xié)議書3篇
- 能源檢測薪資結(jié)構(gòu)
- 語言培訓中心外教勞動合同樣本
- 2025奧菱達電梯有限企業(yè)電梯部件供應(yīng)及維修服務(wù)協(xié)議3篇
- 施工成本鋼結(jié)構(gòu)安全協(xié)議
- 投資入伙協(xié)議書范本
- 2025年度口腔醫(yī)療市場營銷合作協(xié)議書3篇
- 湖南省部分學校2023-2024學年高二上學期期末聯(lián)合考試政治試卷 含解析
- 電大《人力資源管理》期末復(fù)習綜合練習題答案(2024年)
- 西師版數(shù)學(四上題)2023-2024學年度小學學業(yè)質(zhì)量監(jiān)測(試卷)
- 2022-2023學年廣東省廣州市白云區(qū)華南師大附屬太和實驗學校九年級(上)期末數(shù)學試卷(含答案)
- 2024年煤礦安全生產(chǎn)知識競賽題庫及答案(共100題)
- 古代小說戲曲專題-形考任務(wù)2-國開-參考資料
- GA/T 2133.1-2024便攜式微型計算機移動警務(wù)終端第1部分:技術(shù)要求
- 人教版四年級上冊數(shù)學數(shù)學復(fù)習資料
- 個人營業(yè)執(zhí)照注銷委托書范文
- SB/T 10439-2007醬腌菜
- 氨吹脫塔單元設(shè)計標準規(guī)定樣式(共15頁)
評論
0/150
提交評論