I use this code to start bluetooth:
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
if(btAdapter == null)
returns; /no bluetooth
if(btAdapter.isEnabled() == false)
{ Toast("Bluetooth off. Starting it...");
if(btAdapter.enable() == false)
Toast("Error enabling bluetooth.");
}
It should be very simple. Just gets and adapter and if it is not enabled then I start it.
The problem is that isEnabled() returns false when bluetooth is actualy ON (it should return true) And calling to enable() returns false so it shows "Error enabling bluetooth." I guess because it was already ON. After that my bluetooth symbols (in the status bar) is gone.
Any hint?
Of course I have the permissions.
ensure you have the permissions correct in the manifest file
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
You can't enable Bluetooth without the user's confirmation. You need to do it like this,
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null) {
// Device supports Bluetooth
if (!mBluetoothAdapter.isEnabled()) {
// Bluetooth isn't enabled, so enable it.
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
A dialog will appear requesting user permission to enable Bluetooth, as shown below.
If the user responds "Yes," the system will begin to enable Bluetooth and focus will return to your application once the process completes (or fails).
To check Bluetooth state, ON programmatically:
Add Following Permission : -
android.permission.BLUETOOTH
Use Following Function For Enable BLUETOOTH:-
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private void turnOn() {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBtIntent);
}
}
Related
I am using MI note 4(Android 7.0) and Moto x play (Android 7.1.1)
I am doing BLE scan in sperate service.
While scanning I am getting scan response as "scan failed"
Turning ON/OFF Bluetooth is not affecting in scan response.
Turning ON/OFF Wifi is also not affecting in scan response.
(But in this case android inbuilt(from Settings->Bluetooth) Bluetooth scanning was working fine).
I used BLE scanner app also but that app is also not detecting BLE advertisement!
I tried with Turn ON/OFF airplane mode with this and my device is able to scan without fail.
Scan Function:
mLeScanner.startScan(filters, scanSettings, mScanCallback);
ScanCallback:
ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
Log.e("TAG","onScanResult");
}
#Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
Log.e("TAG","onScanFailed");
}
}
ScanSettings:
scanSettings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
filters:
List<ScanFilter> filters = new ArrayList<>();
ScanFilter filter = new ScanFilter.Builder().setDeviceAddress("device address").build();
filters.add(filter);
Beacon Scan filter
ScanFilter.Builder builder = new ScanFilter.Builder();
builder.setManufacturerData(0x004c, new byte[]{});
Anyone have an idea why it only worked with switching airplane mode?
will network affect for BLE scanning?
The error code 0x02 means SCAN_FAILED_APPLICATION_REGISTRATION_FAILED(Fails to start scan as app cannot be registered). This means, before moving to scan we need to initialize Bluetooth adapter
/**
* Initialize BluetoothAdapter
* Check the device has the hardware feature BLE
* Then enable the hardware,
*/
public boolean init(Context context) {
BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
return mBluetoothAdapter != null && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
}
Then register receiver
**
* Register GATT update receiver
*/
private void registerServiceReceiver() {
this.registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
registerReceiver(mReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
}
The service initialization method also including in the answer. The Service creation is optional.
/**
* Initialize Bluetooth service.
*/
public void initBLEService(Context context) {
try {
this.mContext = context;
if (mBLEService == null) {
Intent gattServiceIntent = new Intent(mContext, BLEService.class);
if (this.mContext != null) {
isBind = mContext.bindService(gattServiceIntent, mServiceConnection, mContext.BIND_AUTO_CREATE);
}
}
} catch (Exception e) {
AppLog.logError(TAG, e.getMessage());
}
}
I hope you have already added permission in the manifest given below
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
I hope this will help you.
My issue was resolved after user permission ACCESS_COARSE_LOCATION is granted. You could ask user permission in onStart()
Java Syntax
if (ContextCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
PERMISSIONS_REQUEST_LOCATION);
}
Kotlin syntax
if (ContextCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION),
PERMISSIONS_REQUEST_LOCATION)
}
My App works with BLE devices and searches them in the following way (API 21+):
adapter.getBluetoothLeScanner().startScan(filters, scanSettings, this);
It works just perfect for most devices (f.e. Samsung) but returns null on some LGE and HTC devices (with Android 6.0) and crashes:
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'void android.bluetooth.le.BluetoothLeScanner.startScan(java.util.List, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback)' on a null object reference
The app is targeted to pre-marshmallow android so the premissions are (should be) granted.
I think you might call startScan just right after adapter.enable().
Because BluetoothAdapter.enable() is an asynchronous call, so you might get NullPointer exception, you can try to register broadcast receiver to receive BluetoothAdapter status, something like below.
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_OFF:
break;
case BluetoothAdapter.STATE_TURNING_OFF:
break;
case BluetoothAdapter.STATE_ON:
//to check if BluetoothAdapter is enable by your code
if(enableFlag){
adapter.getBluetoothLeScanner().startScan(filters, scanSettings, callBack);
}
break;
case BluetoothAdapter.STATE_TURNING_ON:
break;
}
}
}
};
You would need to enable Bluetooth by doing this:
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
I've noticed that if Bluetooth isn't enabled on the device, mBluetoothAdapter.getBluetoothLeScanner(); returns null. You can enable Bluetooth by running the above code, which generates an Activity to allow the user enable it, or the user can go to their settings and turn on Bluetooth.
Since Android 6.0, your app must have a new permission to access the BT adapter:
Android 6.0 - Access to Hardware Identifier.
And since Android 6.0 as well, permissions need to be requested at runtime, not during app install: Android 6.0 - Requesting Permissions at Run Time.
fun startScan(filters: List<ScanFilter>) {
val isAdapterEnabled = getBluetoothAdapter().isEnabled()
if (!isScanRunning && isAdapterEnabled) {
// some logick
scanner = getBluetoothAdapter().bluetoothLeScanner
scanner.startScan(filters, scanSettings, this)
}
}
fun getBluetoothAdapter(): BluetoothAdapter {
return Objects.requireNonNull(
getBluetoothManager().adapter,
"Cannot get BluetoothAdapter"
)
}
fun getBluetoothManager(): BluetoothManager {
return Objects.requireNonNull(
context.getSystemService(Context.BLUETOOTH_SERVICE) as
BluetoothManager,
"Cannot get BluetoothManager"
)
}
I am trying to enumerate all paired bluetooth devices with my device. In settings I can view the paired devices, but the following code does not return any items:
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDeviceSet = bluetoothAdapter.getBondedDevices();
I have seen this and other posts that use this method, but I cannot seem to get it to work.
I have the following permissions in Manifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Furthermore, if I put one of the paired devices into discovery mode, and scan, then the device comes back as paired. If I check:
device.getBondState() == BluetoothDevice.BOND_BONDED
from the scan, it returns true.
What am I doing wrong or not understanding?
Your code is completely correct. I have the exact same thing in my app and I never got any complain from any user that this feature does not work. Please check for other parts of your app. Below is the snippet of my app that does the same thing, and I have the same permission as you described.
BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
for (BluetoothDevice device : pairedDevices) {
mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
} else {
mPairedDevicesArrayAdapter.add("No Paired Device.");
}
Make sure bluetooth state is enabled before starting your Activity
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
}
how to show text ((this device not support the Bluetooth )) if this app installed on device not support the Bluetooth
here is my code
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
// want to add code here to show text ((this device not support
//the Bluetooth )) if this app installed on device not support
// the Bluetooth
If BT is not suppored by the device the code BluetoothAdapter.getDefaultAdapter() will return null. See android docs. And usefull tutorial also is there.
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}
How can i check whether NFC is enabled or not programmatically? Is there any way to enable the NFC on the device from my program? Please help me
NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
NfcAdapter adapter = manager.getDefaultAdapter();
if (adapter != null && adapter.isEnabled()) {
// adapter exists and is enabled.
}
You cannot enable the NFC programmatically. The user has to do it manually through settings or hardware button.
This can be done simply using the following code:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
// NFC is not available for device
} else if (!nfcAdapter.isEnabled()) {
// NFC is available for device but not enabled
} else {
// NFC is enabled
}
Remember that the user can turn off NFC, even while using your app.
Source: https://developer.android.com/guide/topics/connectivity/nfc/nfc#manifest
Although you can't programically enable NFC yourself, you can ask the user to enable it by having a button to open NFC settings like so:
Intent intent
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
intent = new Intent(Settings.ACTION_NFC_SETTINGS);
} else {
Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
}
startActivity(intent);
I might be a little late here, but I've implemented a 'complete' example with detection of
NFC capability (hardware), and
Initial NFC state (enabled or disabled in settings), and
Changes to the state
I've also added a corresponding Beam example which uses the
nfcAdapter.isNdefPushEnabled()
method introduced in later Android versions to detect beam state like in 2) and 3).
Use PackageManager and hasSystemFeature("android.hardware.nfc"), matching the <uses-feature android:name="android.hardware.nfc" android:required="false" /> element you should have in your manifest.
Since 2.3.3 you can also use NfcAdapter.getDefaultAdapter() to get the adapter (if available) and call its isEnabled() method to check whether NFC is currently turned on.
mNfcAdapter = NfcAdapter.getDefaultAdapter(this.getApplicationContext());
try {
if (mNfcAdapter != null) {
result = true;
}
}
We can verify using NfcAdapter with context.