4

I follow the official example to write this program

public class BluetoothActivity extends AppCompatActivity {
    private static final long SCANNING_TIMEOUT = 5000; /* 5 seconds */
    private static final int ENABLE_BT_REQUEST_ID = 1;
    private BleWrapper mBleWrapper = null;
    private boolean mScanning = false;
    private Handler mHandler = new Handler();
    private BluetoothAdapter mBluetoothAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth);
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(this, "no ble", Toast.LENGTH_SHORT).show();
            finish();
        }
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, 1);
        }
        scanLeDevice(true);


    }
    private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {
                @Override
                public void onLeScan(final BluetoothDevice device, int rssi,
                                     byte[] scanRecord) {
                    Log.v("ble",device.getName());
                }
            };
    // Stops scanning after 10 seconds.
    private static final long SCAN_PERIOD = 3000;
    private void scanLeDevice(final boolean enable) {
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                }
            }, SCAN_PERIOD);

            mScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        } else {
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
    }
}

And this is permission in manifests.xml

<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" />

But I still got this exception

03-24 15:52:01.126 2223-2236/com.test W/Binder: Caught a RuntimeException from the binder stub implementation.
03-24 15:52:01.126 2223-2236/com.test W/Binder: java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results

How to make BLE work on Android 6, the Android version of my device is 6.0.1

Why I added that permission, still got that exception?

CL So
  • 3,647
  • 10
  • 51
  • 95
  • have you gave the permission during runtime ? If you have then use ACCESS_FINE_LOCATION. Don't know why but ACCESS_COARSE_LOCATION doesn't work – Gautam Mar 24 '16 at 08:14

1 Answers1

5

Andorid M features requesting permissions at runtime. It means that when your app is installed it does not have permission to use Bluetooth yet. User have to manually grant that permission (once per install).

Just follow official guide -> Requesting Permissions at Run Time

rafakob
  • 3,946
  • 3
  • 26
  • 36