目录
main.xml
layout_item.xml
BleView
BleAdapter
BtUtil
MainActivity
main.xml
<?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">
<Button
android:id="@+id/search_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="search"
android:textAllCaps="false"/>
<ListView
android:id="@+id/search_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
</LinearLayout>
layout_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingLeft="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<!--显示头像-->
<ImageView
android:id="@+id/logo_image"
android:layout_width="50dp"
android:layout_height="40dp"
android:adjustViewBounds="true"
android:layout_toLeftOf="@+id/my_text"
android:layout_gravity="right" />
<!--显示名称-->
<TextView
android:id="@+id/my_text"
android:layout_width="match_parent"
android:layout_height="40dp"
android:height="44dp"
android:textSize="12dp"
android:gravity="left" />
</LinearLayout>
BleView
public class BleView {
private String aName;
private int aIcon;
private String TAG = "BleView";
public BleView (int aIcon, String aName) {
Log.i(TAG,"名称:" + aName);
this.aName = aName;
Log.i(TAG,"图片:" + aIcon);
this.aIcon = aIcon;
}
public String getaName() {
Log.i(TAG,"返回名称:" + aName);
return aName;
}
public int getaIcon() {
return aIcon;
}
public void setaName(String aName) {
this.aName = aName;
}
public void setaIcon(int aIcon) {
this.aIcon = aIcon;
}
}
BleAdapter
public class BleAdapter extends BaseAdapter {
private List<BleView> BleList;
private Context mContext;
private String TAG = "BleAdapter";
public BleAdapter (Context context, List<BleView> BleList) {
this.BleList = BleList;
this.mContext = context;
}
@Override
public int getCount() {
return BleList.size();
}
@Override
public Object getItem(int position) {
return BleList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private ViewHolder holder;
private class ViewHolder {
private TextView textView;
private ImageView imageView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
//通过flater获取list行对象
convertView = LayoutInflater.from(mContext).inflate(R.layout.layout_item, parent, false);
holder = new ViewHolder();
//设置图片
holder.imageView = (ImageView) convertView.findViewById(R.id.logo_image);
holder.imageView.setImageResource(BleList.get(position).getaIcon());
//设置名称
holder.textView = (TextView) convertView.findViewById(R.id.my_text);
Log.i(TAG, "名称:" + BleList.get(position).getaName());
holder.textView.setText(BleList.get(position).getaName());
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
}
BtUtil
public class BtUtil {
public static final int PROFILE_HEADSET = 0;
public static final int PROFILE_A2DP = 1;
public static final int PROFILE_OPP = 2;
public static final int PROFILE_HID = 3;
public static final int PROFILE_PANU = 4;
public static final int PROFILE_NAP = 5;
public static final int PROFILE_A2DP_SINK = 6;
public static int getDeviceType(BluetoothClass bluetoothClass) {
if (bluetoothClass == null) {
return R.drawable.ic_settings_bluetooth;
}
switch (bluetoothClass.getMajorDeviceClass()) {
case BluetoothClass.Device.Major.COMPUTER:
return R.drawable.ic_bt_laptop;
case BluetoothClass.Device.Major.PHONE:
return R.drawable.ic_bt_cellphone;
case BluetoothClass.Device.Major.PERIPHERAL:
return R.drawable.ic_bt_misc_hid;
case BluetoothClass.Device.Major.IMAGING:
return R.drawable.ic_bt_imaging;
default:
if (BtUtil.doesClassMatch(bluetoothClass, PROFILE_HEADSET))
return R.drawable.ic_bt_headset_hfp;
else if (BtUtil.doesClassMatch(bluetoothClass, PROFILE_A2DP)) {
return R.drawable.ic_bt_headphones_a2dp;
} else {
return R.drawable.ic_settings_bluetooth;
}
}
}
public static boolean doesClassMatch(BluetoothClass bluetoothClass, int profile) {
if (profile == PROFILE_A2DP) {
if (bluetoothClass.hasService(BluetoothClass.Service.RENDER)) {
return true;
}
// By the A2DP spec, sinks must indicate the RENDER service.
// However we found some that do not (Chordette). So lets also
// match on some other class bits.
switch (bluetoothClass.getDeviceClass()) {
case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER:
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
return true;
default:
return false;
}
} else if (profile == PROFILE_A2DP_SINK) {
if (bluetoothClass.hasService(BluetoothClass.Service.CAPTURE)) {
return true;
}
// By the A2DP spec, srcs must indicate the CAPTURE service.
// However if some device that do not, we try to
// match on some other class bits.
switch (bluetoothClass.getDeviceClass()) {
case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
case BluetoothClass.Device.AUDIO_VIDEO_SET_TOP_BOX:
case BluetoothClass.Device.AUDIO_VIDEO_VCR:
return true;
default:
return false;
}
} else if (profile == PROFILE_HEADSET) {
// The render service class is required by the spec for HFP, so is a
// pretty good signal
if (bluetoothClass.hasService(BluetoothClass.Service.RENDER)) {
return true;
}
// Just in case they forgot the render service class
switch (bluetoothClass.getDeviceClass()) {
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
return true;
default:
return false;
}
} else if (profile == PROFILE_OPP) {
if (bluetoothClass.hasService(BluetoothClass.Service.OBJECT_TRANSFER)) {
return true;
}
switch (bluetoothClass.getDeviceClass()) {
case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
case BluetoothClass.Device.COMPUTER_DESKTOP:
case BluetoothClass.Device.COMPUTER_SERVER:
case BluetoothClass.Device.COMPUTER_LAPTOP:
case BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA:
case BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA:
case BluetoothClass.Device.COMPUTER_WEARABLE:
case BluetoothClass.Device.PHONE_UNCATEGORIZED:
case BluetoothClass.Device.PHONE_CELLULAR:
case BluetoothClass.Device.PHONE_CORDLESS:
case BluetoothClass.Device.PHONE_SMART:
case BluetoothClass.Device.PHONE_MODEM_OR_GATEWAY:
case BluetoothClass.Device.PHONE_ISDN:
return true;
default:
return false;
}
} else if (profile == PROFILE_HID) {
return (bluetoothClass.getDeviceClass() & BluetoothClass.Device.Major.PERIPHERAL) == BluetoothClass.Device.Major.PERIPHERAL;
} else if (profile == PROFILE_PANU || profile == PROFILE_NAP) {
// No good way to distinguish between the two, based on class bits.
if (bluetoothClass.hasService(BluetoothClass.Service.NETWORKING)) {
return true;
}
return (bluetoothClass.getDeviceClass() & BluetoothClass.Device.Major.NETWORKING) == BluetoothClass.Device.Major.NETWORKING;
} else {
return false;
}
}
}
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemClickListener {
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
private String TAG ="MainActivity";
IntentFilter intentFilter;
private List<String> bluetoothList = new ArrayList<String>();
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
ArrayAdapter<String> adapter;
private List<BleView> BleList = new ArrayList<BleView>();
private Context mContext;
private BleAdapter mAdapter;
private ListView list_ble;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = MainActivity.this;
setContentView(R.layout.activity_main);
Button search = (Button)findViewById(R.id.search_button);
list_ble = (ListView) findViewById(R.id.search_result);
list_ble.setOnItemClickListener(this);
search.setOnClickListener(this);
//安卓6以后使用蓝牙要用定位权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Android M Permission check
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
}
//蓝牙广播注册
registerBluetooth();
//listView点击函数
listClick();
}
//listView点击的实现
void listClick(){
list_ble.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
});
}
//广播注册的实现
void registerBluetooth(){
// 设置广播信息过滤
intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//注册广播
registerReceiver(bluetoothReceiver, intentFilter);
}
//安卓6回调(有bug)
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG,"回调request");
//TODO request success/
}
break;
}
}
//button点击的实现
@Override
public void onClick(View view){
switch (view.getId()){
// case R.id.turn_on:
// {
// if(mBluetoothAdapter==null){
// Toast.makeText(this,"当前设备不支持蓝牙功能",Toast.LENGTH_SHORT).show();
// }
// if(!mBluetoothAdapter.isEnabled()){
// /* Intent i = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
// startActivity(i);*/
// mBluetoothAdapter.enable();
// }
// //开启被其它蓝牙设备发现的功能
// if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
// Intent i = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
// //设置为一直开启
// i.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
// startActivity(i);
// }
// }
// break;
// case R.id.turn_off:
// //
// break;
case R.id.search_button:
Log.i(TAG,"有点击 search_button");
if (BleList == null || !BleList.isEmpty())
BleList.clear();
//如果当前在搜索,就先取消搜索
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
//开启搜索
mBluetoothAdapter.startDiscovery();
break;
default:
break;
}
}
//注册销毁
@Override
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(bluetoothReceiver);
}
//蓝牙开始搜索的回调
private BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG,"有回调");
if (action.equals(BluetoothDevice.ACTION_FOUND)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//蓝牙设备
String str = device.getName() + "\n" + device.getAddress();
int deviceTypeImg = BtUtil.getDeviceType(device.getBluetoothClass());
Log.d(TAG,"列表:" + str + " 图片:" + Long.toHexString(deviceTypeImg));
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
BleList.add(new BleView(deviceTypeImg, (str + "(已配对设备)")));
} else {
if (BleList.indexOf(str) == -1) {// 防止重复添加
BleList.add(new BleView(deviceTypeImg, (str + "(未配对设备)")));
}
}
} else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Toast.makeText(MainActivity.this,"开始搜索",Toast.LENGTH_SHORT).show();
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Toast.makeText(MainActivity.this,"搜索完毕",Toast.LENGTH_SHORT).show();
}
mAdapter = new BleAdapter(context, BleList);
list_ble.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
}
};
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
?
|