简单的蓝牙
程序员文章站
2024-03-24 22:04:58
...
直接上代码
<!--添加蓝牙的权限-->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
mine里面的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_margin="10dp"
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="" />
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@color/colorAccent"
android:dividerHeight="1dp" />
</LinearLayout>
适配器中的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/device_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"
/>
<TextView
android:id="@+id/device_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"
/>
<TextView
android:id="@+id/device_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/device_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"/>
</LinearLayout>
//适配器
package com.example.bluetooth.myadapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.example.bluetooth.R;
import java.util.List;
;
public class MyAdapter extends BaseAdapter {
private List<BluetoothDevice> mBluelist;
private LayoutInflater layoutInflater;
public MyAdapter(Context context, List<BluetoothDevice> list) {
this.mBluelist = list;
this.layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mBluelist.size();
}
@Override
public Object getItem(int position) {
return mBluelist.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
view = layoutInflater.inflate(R.layout.list_device_item, null);
viewHolder.deviceName = view.findViewById(R.id.device_name);
viewHolder.deviceAddress = view.findViewById(R.id.device_address);
viewHolder.deviceType = view.findViewById(R.id.device_type);
viewHolder.deviceState = view.findViewById(R.id.device_state);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
//详细参考:http://blog.csdn.net/mirkowu/article/details/53862842
BluetoothDevice blueDevice = mBluelist.get(position);
//设备名称
String deviceName = blueDevice.getName();
viewHolder.deviceName.setText(TextUtils.isEmpty(deviceName) ? "未知设备" : deviceName);
//设备的蓝牙地(地址为17位,都为大写字母-该项貌似不可能为空)
String deviceAddress = blueDevice.getAddress();
viewHolder.deviceAddress.setText(deviceAddress);
//设备的蓝牙设备类型(DEVICE_TYPE_CLASSIC 传统蓝牙 常量值:1, DEVICE_TYPE_LE 低功耗蓝牙 常量值:2
//DEVICE_TYPE_DUAL 双模蓝牙 常量值:3. DEVICE_TYPE_UNKNOWN:未知 常量值:0)
int deviceType = blueDevice.getType();
if (deviceType == 0) {
viewHolder.deviceType.setText("未知类型");
} else if (deviceType == 1) {
viewHolder.deviceType.setText("传统蓝牙");
} else if (deviceType == 2) {
viewHolder.deviceType.setText("低功耗蓝牙");
} else if (deviceType == 3) {
viewHolder.deviceType.setText("双模蓝牙");
}
//设备的状态(BOND_BONDED:已绑定 常量值:12, BOND_BONDING:绑定中 常量值:11, BOND_NONE:未匹配 常量值:10)
int deviceState = blueDevice.getBondState();
if (deviceState == 10) {
viewHolder.deviceState.setText("未匹配");
} else if (deviceState == 11) {
viewHolder.deviceState.setText("绑定中");
} else if (deviceState == 12) {
viewHolder.deviceState.setText("已绑定");
}
//返回远程设备支持的UUID。此方法从远程设备检索UUID不启动服务。 而是返回服务UUID的本地缓存。
//如果需要刷新UUID,使用fetchUuidsWithSdp()方法
//ParcelUuid[] deviceUuid = blueDevice.getUuids();
//blueDevice.fetchUuidsWithSdp(); boolean类型
return view;
}
private class ViewHolder {
TextView deviceName;
TextView deviceAddress;
TextView deviceType;
TextView deviceState;
}
}
//主页面的代码
package com.example.bluetooth;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.bluetooth.myadapter.MyAdapter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private final static int SEARCH_CODE = 0x123;
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private static final String TAG = "MainActivity";
private List<BluetoothDevice> mBlueList = new ArrayList<>();
private ListView lisetView;
private TextView textView1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lisetView = (ListView) findViewById(R.id.list_view);
textView1 = (TextView) findViewById(R.id.textView1);
Log.e(TAG, "onCreate: GPS是否可用:" + isGpsEnable(this));
init();
}
//gps是否可用(有些设备可能需要定位)
public static final boolean isGpsEnable(final Context context) {
LocationManager locationManager
= (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (gps || network) {
return true;
}
return false;
}
/**
* 判断蓝牙是否开启
*/
private void init() {
// 判断手机是否支持蓝牙
if (mBluetoothAdapter == null) {
Toast.makeText(this, "设备不支持蓝牙", Toast.LENGTH_SHORT).show();
finish();
}
// 判断是否打开蓝牙
if (!mBluetoothAdapter.isEnabled()) {
//弹出对话框提示用户是后打开
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, SEARCH_CODE);
} else {
// 不做提示,强行打开
mBluetoothAdapter.enable();
}
startDiscovery();
Log.e(TAG, "startDiscovery: 开启蓝牙");
}
/**
* 注册异步搜索蓝牙设备的广播
*/
private void startDiscovery() {
// 找到设备的广播
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
// 注册广播
registerReceiver(receiver, filter);
// 搜索完成的广播
IntentFilter filter1 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
// 注册广播
registerReceiver(receiver, filter1);
Log.e(TAG, "startDiscovery: 注册广播");
startScanBluth();
}
/**
* 广播接收器
*/
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 收到的广播类型
String action = intent.getAction();
// 发现设备的广播
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// 从intent中获取设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 没否配对
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
if (!mBlueList.contains(device)) {
mBlueList.add(device);
}
textView1.setText("附近设备:" + mBlueList.size() + "个\u3000\u3000本机蓝牙地址:" + getBluetoothAddress());
MyAdapter adapter = new MyAdapter(MainActivity.this, mBlueList);
lisetView.setAdapter(adapter);
Log.e(TAG, "onReceive: " + mBlueList.size());
Log.e(TAG, "onReceive: " + (device.getName() + ":" + device.getAddress() + " :" + "m" + "\n"));
}
// 搜索完成
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
// 关闭进度条
progressDialog.dismiss();
Log.e(TAG, "onReceive: 搜索完成");
}
}
};
private ProgressDialog progressDialog;
/**
* 搜索蓝牙的方法
*/
private void startScanBluth() {
// 判断是否在搜索,如果在搜索,就取消搜索
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
// 开始搜索
mBluetoothAdapter.startDiscovery();
if (progressDialog == null) {
progressDialog = new ProgressDialog(this);
}
progressDialog.setMessage("正在搜索,请稍后!");
progressDialog.show();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (receiver != null) {
//取消注册,防止内存泄露(onDestroy被回调代不代表Activity被回收?:具体回收看系统,由GC回收,同时广播会注册到系统
//管理的ams中,即使activity被回收,reciver也不会被回收,所以一定要取消注册),
unregisterReceiver(receiver);
}
}
/**
* 获取本机蓝牙地址
*/
private String getBluetoothAddress() {
try {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Field field = bluetoothAdapter.getClass().getDeclaredField("mService");
// 参数值为true,禁用访问控制检查
field.setAccessible(true);
Object bluetoothManagerService = field.get(bluetoothAdapter);
if (bluetoothManagerService == null) {
return null;
}
Method method = bluetoothManagerService.getClass().getMethod("getAddress");
Object address = method.invoke(bluetoothManagerService);
if (address != null && address instanceof String) {
return (String) address;
} else {
return null;
}
//抛一个总异常省的一堆代码...
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==SEARCH_CODE){
startDiscovery();
}
Log.e(TAG, "onActivityResult: "+requestCode );
Log.e(TAG, "onActivityResult: "+resultCode );
Log.e(TAG, "onActivityResult: "+requestCode );
}
}
以上
上一篇: Android MTU 值修改
下一篇: Python ---- 多线程的详细解读