Android中的Serializable、Parcelable">Android中的Serializable、Parcelable
791
2025-04-04
視頻課:https://edu.csdn.net/course/play/7621
學習內容
??藍牙的基本概念
??Android中藍牙的應用
能力目標
??了解藍牙的基本概念
??掌握Android中藍牙的應用
??掌握如何使用Android中Wi-Fi
本章簡介
藍牙是一種重要的短距離無線通信技術,它被廣泛應用于各種設備,比如計算機、手機、汽車等,支持設備之間的近距離通信,從而是數據傳輸更加快捷有效。Wi-Fi是一種高速的無線通信協議,它具有傳輸速度高,傳輸距離長的特點。通過WiFi,手機、PDA、電腦等移動設備可以以無線方式連接網絡。本節中我們主要來學習Android開發中如何調用系統中藍牙以及wifi的功能。
核心技能部分
11.1?藍牙簡介
藍牙(Bluettoth)是目前使用最廣泛的一種短距離(10M)無線通信協議之一,廣泛應用于各種設備中,比如手機、計算機、耳機、鼠標、鍵盤等。
藍牙采用了分散式網絡結構以及快跳頻和短包技術,支持點對點及點對多點的通信,工作在全球通用的2.4GHz頻度。根據不同的藍牙版本,傳輸速度會差很多,例如:最新的藍牙3.0傳輸速度為3Mb/s,而未來的藍牙4.0技術從理論上可達到60Mb/s。
藍牙協議分為核心協議層、電纜替代協議層、電話控制協議層、采納的其它協議層等4層,藍牙的核心協議包括基帶、鏈路管理、邏輯鏈路控制和適應協議四部分。其中鏈路管理(LMP)負責藍牙組件間連接的建立。邏輯鏈路控制與適應協議(L2CAP)位于基帶協議層上,屬于數據鏈路層,是一個為高層傳輸和應用層協議屏蔽基帶協議的適配協議。
藍牙技術作為目前比較常用的無線通信技術,早已經成為手機的標配之一,基于Android的手機設備也不例外。但遺憾的是模擬器不支持藍牙程序的調試,藍牙程序必須運行在真機上,且必須是在Android版本2.0以上的真機上。
Android中藍牙有關的類和接口都位于android.bluetooth包中,如下表11-1-1所示。
表11-1-1 藍牙功能包
功能包
說明
BluetoothAdapter
本地藍牙適配器
BluetoothClass
藍牙類,主要包括服務和設備
BluetoothClass.Device
藍牙設備類
BluetoothClass.Device.Major
藍牙設備管理器
BluetoothClass.Service
有關藍牙的服務類
BluetoothDevice
遠程藍牙設備
BluetoothServerSocket
監聽藍牙連接的類
BluetoothSocket
藍牙連接類
這些藍牙API允許應用程序掃描、連接和斷開其它藍牙設備,包括編寫和修改本地服務的SDP協議數據庫和查詢其它藍牙設備上的SDP協議數據庫,以及在Android上建立RFCOMM協議的連接并連接到其它指定設備上。
11.2?藍牙的打開、關閉及搜索
通過11.1小節的學習我們知道Android中與藍牙相關的類和接口都定義在了android.bluetooth包中,我們常用的主要是BluetoothAdapter和BluetoothDevice兩個類。其中BluetoothAdapter類的對象代表了本地的藍牙適配器;BluetoothDevice代表了一個遠程的Bluetooth設備。
掃描已經配對的藍牙設備時,包括手機和電腦配對,必須得通過手動完成,不能通過代碼完成,我們應該把主要的精力放在配對完成之后的操作上來。核心步驟如下:
(1)?獲得BluetoothAdapter對象;
(2)?判斷當前設備中是否擁有藍牙設備;
(3)?判斷當前設備中的藍牙設備是否已經打開,如果沒有打開的話,要打開;
(4)?得到所有已經配對的藍牙設備對象BluetoothDevice;
在使用藍牙之前,需要在功能清單文件AndroidManifest.xm中添加如下權限,
BluetoothAdapter是藍牙的核心類,下面的代碼創建了BluetoothAdapter對象:
adapter?= BluetoothAdapter.getDefaultAdapter();
通過代碼還可以直接打開系統的藍牙設置界面,代碼如下:
Intent enable?= new?Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enable, 22);
或直接使用enable()方法打開藍牙功能,代碼如下:
adapter.enable();
要關閉藍牙,可以使用如下的代碼:
adapter.disable();
藍牙設備打開之后,還需要讓其它的藍牙設備可以搜索到自己,藍牙才能使用,要想讓別人能夠搜索到自己,需要在程序中加入如下代碼:
Intent discoveryIntent =
new?Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(discoveryIntent,22);
每一個藍牙設備由BluetoothDevice描述,需要定義一個List對象,來保存搜索到的藍牙設備,具體代碼如下:
private?List
接著調用BluetoothAdapter的startDiscovery()方法就可以搜索附近的藍牙設備了。系統會在每搜索到一個藍牙設備時發送一個廣播,通過接收這個廣播,可以獲得搜索到的藍牙設備信息。當搜索完成時還會發送一個廣播,可以在該廣播接收器中做一些收尾工作。
示例11.1:
演示了上述藍牙的常用操作,Activity類的詳細代碼如下所示:
public?class?DiscoveryActivity extends?ListActivity {
private?Handler handler?= null;
private?BluetoothAdapter adapter?= null;// 藍牙適配器對象
private?List
private?volatile?boolean?discoveryFinished;// 表示搜索是否完成
private?Runnable discoveryWorkder?= new?Runnable() {
public?void?run() {
adapter.startDiscovery();// 開始搜索
while?(true) {
if?(discoveryFinished) {
break;
}
try?{
Thread.sleep(100);
} catch?(InterruptedException e) {
}
}
}
};
// 搜索藍牙設備時調用
private?BroadcastReceiver foundReceiver?= new?BroadcastReceiver() {
public?void?onReceive(Context context, Intent intent) {
// 獲得搜索結果數據
BluetoothDevice device =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 將結果添加到設備列表中
devices.add(device);
// 顯示列表
showDevices();
}
};
// 搜索完成時調用
private?BroadcastReceiver discoveryReceiver?= new?BroadcastReceiver() {
@Override
public?void?onReceive(Context context, Intent intent) {
// 卸載注冊的接收器
unregisterReceiver(foundReceiver);
unregisterReceiver(this);
discoveryFinished?= true;
}
};
protected?void?onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(LayoutParams.FLAG_BLUR_BEHIND, LayoutParams.FLAG_BLUR_BEHIND);
setContentView(R.layout.discovery);
devices?= new?ArrayList
adapter?= BluetoothAdapter.getDefaultAdapter();
handler?= new?Handler();
if?(adapter?!= null) {
System.out.println("本機擁有藍牙設備");
// 如果藍牙適配器沒有打開,則打開
if?(!adapter.isEnabled()) {
adapter.enable();
}
// 注冊discoveryReceiver接收器
IntentFilter discoveryFilter = new?IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(discoveryReceiver, discoveryFilter);
// 注冊foundReceiver接收器
IntentFilter foundFilter = new?IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(foundReceiver, foundFilter);
// 顯示一個對話框,正在搜索藍牙設備
SamplesUtils.indeterminate(DiscoveryActivity.this,
handler, "正在掃描...",
discoveryWorkder,
new?OnDismissListener() {
public?void?onDismiss(DialogInterface dialog) {
for?(; adapter.isDiscovering();) {
adapter.cancelDiscovery();
}
discoveryFinished?= true;
}
}, true);
}else?{
System.out.println("本機沒有藍牙設備");
}
}
// 顯示搜索設備列表
protected?void?showDevices() {
List
for?(int?i = 0, size = devices.size(); i < size; ++i) {
StringBuilder builder = new?StringBuilder();
BluetoothDevice device = devices.get(i);
builder.append(device.getName()).append(" ?: ?") .append(device.getAddress());
list.add(builder.toString());
}
final?ArrayAdapter
handler.post(new?Runnable() {
public?void?run() {
setListAdapter(adapter);
}
});
}
protected?void?onListItemClick(ListView l, View v, int?position, long?id) {
Intent result = new?Intent();
result.putExtra(BluetoothDevice.EXTRA_DEVICE, devices.get(position));
setResult(RESULT_OK, result);
finish();
}
}
將程序部署到真機上運行測試程序,結果如下圖10.1.1和圖10.1.2所示。
11.3?Wi-Fi入門
Wi-Fi的全稱是Wireless Fidelity,是一種高速的無線通信協議。Wi-Fi最大的優點是傳輸速度高,傳輸速度可以達到11M/S,另外Wi-Fi的有效傳輸距離也很長。
Wi-Fi的頻段在世界范圍內是無需任何電信運營執照就可以免費使用,因此WLAN無線設備提供了一個世界范圍內可用的、費用極低且數據帶寬極高的無線空中接口。用戶可以在Wi-Fi覆蓋區域內快速瀏覽網頁、隨時隨地接聽、撥打電話。而其它一些基于WLAN的寬帶數據應用,如流媒體、網絡游戲等功能更是值得用戶期待。有了Wi-Fi功能,我們打電話(包括國際長途)、瀏覽網頁、收發電子郵件、音樂下載、數碼照片傳遞等,再也無需擔心速度慢和花費高的問題。現在Wi-Fi在國內的覆蓋范圍越來越廣泛,比如高級賓館、豪華住宅區、飛機場以及咖啡廳之類的場所都有Wi-Fi接口。當我們去旅游、辦公時,就可以在這些場所使用我們的移動設備盡情網上沖浪了。
實際上,對于Wi-Fi并不需要過多的控制,當成功連接Wi-Fi后,就可以直接通過IP在Wi-Fi設備之間進行通信了。一般只需要控制打開或關閉Wi-Fi以及獲得一些與Wi-Fi相關的信息,基本上來自請求端的信息都是可見的,比如連接速度、IP地址、完成狀態等。不幸的是Wi-Fi功能不能在Android模擬器上測試,得使用支持Wi-Fi功能的Android真機才行,就算在有Wi-Fi功能的真機上也需要先通過Wi-Fi和其它Wi-Fi設備連接后,才能獲得Wi-Fi相關的信息。
Android中編寫Wi-Fi程序,主要涉及以下幾個類和接口。
??ScanResult:主要用來描述已經檢測出的接入點,包括接入點的地址、接入點的名稱、身份認證、頻率、信號強度等信息。
??WifiConfiguration:Wi-Fi網絡的配置,包括安全配置等。
??WifiManager:提供了管理Wi-Fi連接的大部分API,它主要包括如下內容
(1)?已經配置好的網絡清單。這個清單可以查看和修改,而且可以修改個別記錄的屬性。
(2)?當連接中有活動的Wi-Fi網絡時,可以建立或關閉這個連接,并且可以查詢有關網絡的狀態信息。
(3)?對接入點的掃描結果包含足夠的信息來決定需要與什么接入點建立連接。
(4)?定義了許多常量來表示Wi-Fi狀態的改變。
??WifiInfo:Wi-Fi無線連接的描述,包括接入點、網絡連接狀態、隱藏的接入點、IP地址、連接速度、MAC地址、網絡ID、信號強度等信息。
示例11.2
演示如何開關閉Wi-Fi以及獲取Wi-Fi相關信息,這些信息包括:MAC地址、接入點的BSSID、IP地址、網絡ID等。
布局文件的詳細代碼如下:
android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"?> android:id="@+id/chkOpenCloseWifi" android:layout_width="fill_parent" android:layout_height="wrap_content"?/> android:id="@+id/tvScanResult" android:layout_width="wrap_content" android:layout_height="wrap_content"?/> android:id="@+id/tvWifiInfo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp"?/> android:id="@+id/tvWifiConfigurations" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:textSize="20sp"?/>
Activity類代碼如下:
public?class?WIFIActivity extends?Activity implements?OnCheckedChangeListener {
private?WifiManager manager;
private?WifiInfo?wifiInfo;
private?CheckBox chkOpenCloseWifiBox;
private?List
@Override
public?void?onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.wifi);
manager?= (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifiInfo?= manager.getConnectionInfo();
chkOpenCloseWifiBox?= (CheckBox) findViewById(R.id.chkOpenCloseWifi);
TextView tvWifiConfigurations = ?(TextView) findViewById(R.id.tvWifiConfigurations);
TextView tvWifiInfo = (TextView) findViewById(R.id.tvWifiInfo);
chkOpenCloseWifiBox.setOnCheckedChangeListener(this);
if?(manager.isWifiEnabled()) {
chkOpenCloseWifiBox.setText("Wifi已開啟");
chkOpenCloseWifiBox.setChecked(true);
} else?{
chkOpenCloseWifiBox.setText("Wifi已關閉");
chkOpenCloseWifiBox.setChecked(false);
}
// 獲得
Wifi
信息
StringBuffer sb = new?StringBuffer();
sb.append("Wifi信息\n");
sb.append("MAC地址:"?+ wifiInfo.getMacAddress() + "\n");
sb.append("接入點的BSSID:"?+ wifiInfo.getBSSID() + "\n");
sb.append("IP地址(int):"?+ wifiInfo.getIpAddress() + "\n");
sb.append("IP地址(Hex):"? ???+ Integer.toHexString(wifiInfo.getIpAddress()) + "\n");
sb.append("IP地址:"?+ ipIntToString(wifiInfo.getIpAddress()) + "\n");
sb.append("網絡ID:"?+ wifiInfo.getNetworkId() + "\n");
tvWifiInfo.setText(sb.toString());
// 得到配置好的網絡
wifiConfigurations?= manager.getConfiguredNetworks();
tvWifiConfigurations.setText("已連接的無線網絡\n");
for?(WifiConfiguration wifiConfiguration : wifiConfigurations) {
tvWifiConfigurations.setText(tvWifiConfigurations.getText() + wifiConfiguration.SSID?+ "\n");
}
}
private?String ipIntToString(int?ip) {
try?{
byte[] bytes = new?byte[4];
bytes[0] = (byte) (0xff & ip);
bytes[1] = (byte) ((0xff00 & ip) >> 8);
bytes[2] = (byte) ((0xff0000 & ip) >> 16);
bytes[3] = (byte) ((0xff000000 & ip) >> 24);
return?Inet4Address.getByAddress(bytes).getHostAddress();
} catch?(Exception e) {
return?"";
}
}
@Override
public?void?onCheckedChanged(CompoundButton buttonView, boolean?isChecked){
if?(isChecked) {
manager.setWifiEnabled(true);
chkOpenCloseWifiBox.setText("Wifi已開啟");
} else?{
manager.setWifiEnabled(false);
chkOpenCloseWifiBox.setText("Wifi已關閉");
}
}
}
在有Wi-Fi接入點的環境中,將本程序部署到真機上進行測試,程序運行效果如下圖11.1.3所示。
任務實訓部分
1:實現一個藍牙搜索程序
訓練技能點
利用BluetoothDevice實現藍牙設備搜索
需求說明
藍牙實現的功能是在兩臺或多臺設備之間傳傳輸數據,因此我們要想使用藍牙設備,首先需要能夠搜索到對應的藍牙設備,然后才能完成數據的傳輸。本實訓要求大家參考11.2節的內容實現一個藍牙搜索程序,當搜索到別的藍牙設備后,要求以Toast的形式給用戶彈出提示信息。
2:獲取Wi-Fi相關信息
訓練技能點
如何獲取Wi-Fi相關信息
需求說明
Wi-Fi的連接信息在實際的應用中是很有用的,以連接速度為例,當我們可以在程序中根據連接速度的快慢做不同的工作,比如速度比較快時上傳或下載資源、慢時瀏覽網頁等。再比如,當我們的程序需要網絡時,可以根據Wi-Fi的完成狀態,來判斷用戶是否聯網,如果沒有聯網給用戶以相應的提示。本示例要實現的功能就是獲取Wi-Fi的所有信息,然后顯現給用戶。
鞏固練習
一、選擇題
1.?藍牙工作的頻度是()
A.?1.8GHz
B.?2.4GHz
C.?3.2GHz
D.?3.0GHz
2.?下列說法中正確的是( ?)
A.?WIFI的全稱是Wireless Fidelety
B.?WIFI的頻段在世界范圍內是無需任何電信運營執照就可以免費使用
C.?當成功連接WIFI后,就可以直接通過IP在WIFI設備之間進行通信了
D.?ScanResult類主要用來描述已經檢測出的接入點
二、上機練習
編寫一程序,實現對Wi-Fi和藍牙開啟、關閉狀態的控制。
Android 網絡
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。