
Creator
By debbuging after @RequiresBluetoothLocationPermission annotation program will exit function startScan in BluetoothLeScanner object
Could you please help me to find the problem why startScan function is not executed. By debugging after @RequiresBluetoothLocationPermission program will not go the next line.
My phone is Samsung Galaxy S22 Ultra Anfroid14, Compile Target SDK 34
Location, Connect, Scan - Permissions will be grandet at Run time This is a function that should be executed with provided ScanCallback
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothScanPermission
**@RequiresBluetoothLocationPermission**
@RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
public void startScan(final ScanCallback callback) {
startScan(null, new ScanSettings.Builder().build(), callback);
}
My program Code:
package com.example.navigationleftexample.ui.gallery;
import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.ListFragment;
import androidx.lifecycle.ViewModelProvider;
import android.os.*;
import com.example.navigationleftexample.MainActivity;
import com.example.navigationleftexample.R;
import com.example.navigationleftexample.databinding.FragmentBluetoothBinding;
import com.example.navigationleftexample.ui.Bluetooth.LeDeviceListAdapter;
import pub.devrel.easypermissions.EasyPermissions;
public class BluetoothFragment extends Fragment {
Switch bluetoothSwitch;
private FragmentBluetoothBinding binding;
private BluetoothAdapter mBluetoothAdapter;
private LayoutInflater layoutInflater;
private BluetoothLeScanner bluetoothLeScanner;
private boolean scanning;
private Handler handler = new Handler();
public static final String[] BLUETOOTH_PERMISSIONS_S =
{ Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT} ;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 456;
private static final int REQUEST_CODE_BLUETOOTH_SCAN = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
//LeDeviceListAdapter leDeviceListAdapter = new LeDeviceListAdapter(layoutInflater);
LeDeviceListAdapter leDeviceListAdapter;
private boolean checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
int permission = ContextCompat.checkSelfPermission
(getContext(), Manifest.permission.ACCESS_FINE_LOCATION);
return permission == PackageManager.PERMISSION_GRANTED;
}else{
return true;
}
}
// Device scan callback.
private ScanCallback leScanCallback =
new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
leDeviceListAdapter.addDevice(result.getDevice());
leDeviceListAdapter.notifyDataSetChanged();
}
};
private void scanLeDevice() {
if (!scanning) {
// Stops scanning after a predefined scan period.
handler.postDelayed(new Runnable() {
@Override
public void run() {
scanning = false;
if (ActivityCompat.checkSelfPermission(getContext(),
Manifest.permission.BLUETOOTH_SCAN)
!= PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
bluetoothLeScanner.stopScan(leScanCallback);
}
}, SCAN_PERIOD);
scanning = true;
bluetoothLeScanner.startScan(leScanCallback);
} else {
scanning = false;
//bluetoothLeScanner.stopScan(leScanCallback);
scanLeDevice();
}
}
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
BluetoothViewModel bluetoothViewModel =
new ViewModelProvider(this).get(BluetoothViewModel.class);
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) getContext().getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null) {
Toast.makeText(getContext(), R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
getActivity().finish();
}
bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
layoutInflater = inflater;
binding = FragmentBluetoothBinding.inflate(inflater, container, false);
View root = binding.getRoot();
// Check Bluetooth Switch
bluetoothSwitch = (Switch) binding.switchBluetoothOn;
bluetoothSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Toast.makeText(root.getContext(), "Bluetooth was changed", Toast.LENGTH_SHORT).show();
if (isChecked==true)
{
// Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features.
if (!getActivity().getPackageManager().
hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(getContext(),
R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
getActivity().finish();
}
// Check permissions for Bluetooth Connect
if (ContextCompat.checkSelfPermission(getContext(),
Manifest.permission.BLUETOOTH_CONNECT)
== PackageManager.PERMISSION_DENIED)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
{
ActivityCompat.requestPermissions(getActivity(),
new String[] {Manifest.permission.BLUETOOTH_CONNECT}, 2);
return;
}
}
// Request Scan permission
ActivityCompat.requestPermissions(getActivity(),
new String[]
{Manifest.permission.BLUETOOTH_SCAN}, REQUEST_CODE_BLUETOOTH_SCAN);
boolean fineLocation = checkPermission();
leDeviceListAdapter = new LeDeviceListAdapter(layoutInflater);
scanLeDevice();
}
else
{
leDeviceListAdapter.clear();
//scanLeDevice(false);
}
}
});
// Show Connected Bluetooth Device
final TextView textView = binding.textViewBluetoothDeviceChosen;
bluetoothViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
// Show List of Bluetooth scanned devices
final ListView listView = (ListView) binding.listBluetoothDeviceView;
//String [] deviceArray = bluetoothViewModel.getDeviceArray();
listView.setAdapter(leDeviceListAdapter);
// Create Listener for the List
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final String item = (String) parent.getItemAtPosition(position);
Toast.makeText(root.getContext(), "You have selected item: " + item,
Toast.LENGTH_SHORT).show();
}
});
return root;
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
ActivityResultLauncher<String[]> locationPermissionRequest =
registerForActivityResult(new ActivityResultContracts
.RequestMultiplePermissions(), result -> {
Boolean fineLocationGranted = result.getOrDefault(
Manifest.permission.ACCESS_FINE_LOCATION, false);
Boolean coarseLocationGranted = result.getOrDefault(
Manifest.permission.ACCESS_COARSE_LOCATION,false);
if (fineLocationGranted != null && fineLocationGranted) {
// Precise location access granted.
Toast.makeText(getContext(), "Precise location granted" ,
Toast.LENGTH_SHORT).show();
} else if (coarseLocationGranted != null && coarseLocationGranted) {
// Only approximate location access granted.
Toast.makeText(getContext(), "Aproximate location granted" ,
Toast.LENGTH_SHORT).show();
} else {
// No location access granted.
Toast.makeText(getContext(), "No location granted" ,
Toast.LENGTH_SHORT).show();
}
}
);
locationPermissionRequest.launch(new String[] {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
});
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
Permissions from Android manifest:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
<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"/>
<uses-feature android:name="android.hardware.bluetooth_le" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BILLING" />
Most Liked

Creator
Code is working fine. I have not initialized leDeviceListAdapter befor i set it to ListView
1
Popular Android topics

I am in the process of research for my next technical blog about bypassing certificate pinning with Frida, thus I need to find some open ...
New

I am making an app with Nativescript-vue and I would like to have an event where I click on an icon and then a new box appears. For the i...
New

I need to know how to implement outgoing call in my custom application instead of using default phone call app i need my own app call.
New

Dear Sir,
I am a beginner in Android App development and I am currently trying to establish a connection between my Android Studio Java ...
New

Could you please help me to find the problem why startScan function is not executed. By debugging after @RequiresBluetoothLocationPermiss...
New

I’m new to Android Studio, and curious about how long you’ve been using your Android Studio IDE. I read on Wikipedia that this year, Andr...
New

I’m developing an Android application in which I need to add functionality to automatically read a CSV file from a file manager, parse it...
New

Helo,
I’m using doubleviewpager in my project:
Is there something similar that works with android x?
New

I am trying to implement the PIN entry page using device’s TEE. I have acquired the confidential OEM Documentation. It have some C++ code...
New

I need to create an android app to receive contactless payment from my clients. how can I start that? My clients will be phisicaly in the...
New
Other popular topics

@AstonJ prompted me to open this topic after I mentioned in the lockdown thread how I started to do a lot more for my fitness.
https://f...
New

I know that -t flag is used along with -i flag for getting an interactive shell. But I cannot digest what the man page for docker run com...
New

We have a thread about the keyboards we have, but what about nice keyboards we come across that we want? If you have seen any that look n...
New

This looks like a stunning keycap set :orange_heart:
A LEGENDARY KEYBOARD LIVES ON
When you bought an Apple Macintosh computer in the e...
New

If you are experiencing Rails console using 100% CPU on your dev machine, then updating your development and test gems might fix the issu...
New

Crystal recently reached version 1. I had been following it for awhile but never got to really learn it. Most languages I picked up out o...
New

Biggest jackpot ever apparently! :upside_down_face:
I don’t (usually) gamble/play the lottery, but working on a program to predict the...
New

Rails 7 completely redefines what it means to produce fantastic user experiences and provides a way to achieve all the benefits of single...
New

Author Spotlight
Rebecca Skinner
@RebeccaSkinner
Welcome to our latest author spotlight, where we sit down with Rebecca Skinner, auth...
New

Author Spotlight:
Tammy Coron
@Paradox927
Gaming, and writing games in particular, is about passion, vision, experience, and immersio...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /ruby
- /wasm
- /erlang
- /phoenix
- /keyboards
- /rails
- /js
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /emacs
- /haskell
- /java
- /onivim
- /svelte
- /typescript
- /crystal
- /c-plus-plus
- /kotlin
- /tailwind
- /gleam
- /ocaml
- /react
- /flutter
- /elm
- /vscode
- /ash
- /opensuse
- /centos
- /php
- /deepseek
- /html
- /scala
- /zig
- /textmate
- /sublime-text
- /debian
- /nixos
- /lisp
- /agda
- /react-native
- /kubuntu
- /arch-linux
- /revery
- /ubuntu
- /django
- /manjaro
- /spring
- /nodejs
- /diversity
- /lua
- /julia
- /slackware
- /c
- /neovim