Android : 简单的蓝牙

直接上代码

    <!--添加蓝牙的权限-->
    <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 );
    }
}

以上

猜你喜欢

转载自blog.csdn.net/weixin_43603192/article/details/83897463