package com.sirius.botasky.bledemo;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.tbruyelle.rxpermissions.RxPermissions;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class DiscoverActivity extends AppCompatActivity implements BluetoothAdapter.LeScanCallback {
private Button mScanButton;
private RecyclerView mDevicesRecycler;
private BluetoothAdapter mBleAdapter;
private BleDeviceAdapter mRecyclerAdapter;
private boolean isScaning = false;
private static final int REQUEST_ENABLE_BT = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_discover);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
setupViews();
getBleAdapter();
setupPermissions();
}
/**
* 获取BluetoothAdapter
*/
private void getBleAdapter() {
//获取BluetoothManager, 再从BluetoothManager获取适配器,需要的话去判断蓝牙是否可用或者蓝牙是否打开
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBleAdapter = bluetoothManager.getAdapter();
}
/**
* 判断是否打开蓝牙
*/
private boolean enableBle() {
if (!mBleAdapter.isEnabled()) {
if (!mBleAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
return false;
}
}
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT && resultCode == RESULT_OK) {
startScan();
} else {
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
/**
* 基础view
*/
private void setupViews() {
mScanButton = (Button) findViewById(R.id.start_scan);
mDevicesRecycler = ((RecyclerView) findViewById(R.id.device_list));
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mDevicesRecycler.setLayoutManager(linearLayoutManager);
mRecyclerAdapter = new BleDeviceAdapter();
mDevicesRecycler.setAdapter(mRecyclerAdapter);
//开始扫描
mScanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startScan();
}
});
}
/**
* 动态获取权限
*/
private void setupPermissions() {
RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions.request(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN)
.subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Boolean aBoolean) {
if (aBoolean) {
startScan();
} else {
return;
}
}
});
}
private void startScan() {
if (!enableBle()) {
return;
}
//判断权限是否都有
RxPermissions rxPermissions = new RxPermissions(this);
if (rxPermissions.isGranted(Manifest.permission.ACCESS_COARSE_LOCATION)
&& rxPermissions.isGranted(Manifest.permission.ACCESS_FINE_LOCATION)
&& rxPermissions.isGranted(Manifest.permission.BLUETOOTH)
&& rxPermissions.isGranted(Manifest.permission.BLUETOOTH_ADMIN)) {
if (isScaning) {
Snackbar.make(mScanButton, " is scanning now ", Snackbar.LENGTH_LONG).show();
return;
}
mRecyclerAdapter.clear();
UUID[] insole = {UUID.fromString(SampleGattAttributes.UUID_MEASUREMENT)};
mBleAdapter.startLeScan(insole, this);
isScaning = true;
Observable.timer(10, TimeUnit.SECONDS)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Long>() {
@Override
public void onCompleted() {
Log.e("Timer onComplete", " complete");
mBleAdapter.stopLeScan(DiscoverActivity.this);
isScaning = false;
}
@Override
public void onError(Throwable e) {
Log.e("Timer onError", " error " + e);
e.printStackTrace();
}
@Override
public void onNext(Long aLong) {
Log.e("Timer onNext", " long " + aLong);
}
});
} else {
setupPermissions();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_discover, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
Log.e("Timer device", " device " + device.getAddress());
runOnUiThread(new Runnable() {
@Override
public void run() {
mRecyclerAdapter.addDevice(device, rssi);
}
});
}
private class BleDeviceAdapter extends RecyclerView.Adapter<BleDeviceAdapter.ViewHolder> {
private List<BluetoothDevice> devices;
private LayoutInflater mInflator;
private Map<String, Integer> mDevicesRssi;
public BleDeviceAdapter() {
this.devices = new ArrayList<>();
this.mDevicesRssi = new HashMap<>();
this.mInflator = DiscoverActivity.this.getLayoutInflater();
}
private void addDevice(BluetoothDevice device, int rssi) {
if (!devices.contains(device)) {
devices.add(device);
mDevicesRssi.put(device.getAddress(), rssi);
notifyDataSetChanged();
}
}
private void clear() {
devices.clear();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflator.inflate(R.layout.item_device, parent, false);
ViewHolder item = new ViewHolder(view);
return item;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
ViewHolder viewHolder = ((ViewHolder) holder);
final BluetoothDevice device = devices.get(position);
final String deviceName = device.getName();
if (deviceName != null && deviceName.length() > 0)
viewHolder.deviceName.setText(deviceName);
else
viewHolder.deviceName.setText("Unknow");
viewHolder.deviceAddress.setText(device.getAddress());
viewHolder.content.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(DiscoverActivity.this, ConnectActivity.class);
intent.putExtra(ConnectActivity.DEVICE_ADDRESS, device.getAddress());
intent.putExtra(ConnectActivity.DEVICE_NAME, device.getName());
startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return devices.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private LinearLayout content;
private TextView deviceName;
private TextView deviceAddress;
public ViewHolder(View itemView) {
super(itemView);
content = ((LinearLayout) itemView.findViewById(R.id.content));
deviceAddress = ((TextView) itemView.findViewById(R.id.device_address));
deviceName = (TextView) itemView.findViewById(R.id.device_name);
}
}
}
}