简体   繁体   中英

Scanning for bluetooth devices programmatically don't find anything in android 6+

I created an application which pairs a cellphone to a bluetooth module. i tested this application with a 4.2 android cellphone and it worked quite well but in cellphones with android higher than 6 the device is not fidning anything when i press " Scan for new devices " button. but when i go through my phone bluetooth itself, i can find the module i was looking for..

Bluetooth connection class :

public class BluetoothConnectionActivity extends AppCompatActivity {

    private ProgressDialog mProgressDlg;

    private ArrayList<BluetoothDevice> mDeviceList = new ArrayList<BluetoothDevice>();

    private BluetoothAdapter mBluetoothAdapter;
    BluetoothDevice device ;

    private MediaPlayer mediaplayer = null ;

    private Button bluetoothOnOff;
    private Button viewpairedDevices;
    private Button scanfornewDevices;
    private Button blue2;


    ImageView unMute;

    View view1;
    View view2;
    private Activity context;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.bluetoothconnectionlayout);


        bluetoothOnOff = (Button) findViewById(R.id.bluetoothOnOff);
        viewpairedDevices = (Button) findViewById(R.id.viewpairedDevicesButton);
        scanfornewDevices = (Button) findViewById(R.id.scanfornewDevicesButton);
        blue2 = (Button) findViewById(R.id.bluetoothOnOff2);
        view1 = findViewById(R.id.viewFader);
        view2 = findViewById(R.id.viewFader2);
        unMute = (ImageView) findViewById(R.id.settingStartupSecondary);


        mediaplayer = MediaPlayer.create(getApplicationContext(),R.raw.sfxturnon);







        Handler startup1 = new Handler();
        startup1.postDelayed(new Runnable() {
            @Override
            public void run() {

                view1.animate().alpha(1f).setDuration(500);
                view2.animate().alpha(1f).setDuration(500);


            }
        },1000);



        Handler startup2 = new Handler();
        startup2.postDelayed(new Runnable() {
            @Override
            public void run() {

                bluetoothOnOff.animate().alpha(1f).setDuration(500);
                viewpairedDevices.animate().alpha(1f).setDuration(500);
                scanfornewDevices.animate().alpha(1f).setDuration(500);
                unMute.animate().alpha(1f).setDuration(100);


            }
        },1000);


//
//        settingBtn.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
//
//
//                AudioManager amanager=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
//                amanager.setStreamMute(AudioManager.STREAM_NOTIFICATION, true);
//
////                settingBtn.setEnabled(false);
////                settingBtn.animate().alpha(0f);
//
//                unMute.animate().alpha(1f);
//                unMute.setEnabled(true);
//
//
//                Toast.makeText(getApplicationContext(), " Application muted. ", Toast.LENGTH_SHORT).show();
//
//
//            }
//        });










        Handler dawg = new Handler();
        dawg.postDelayed(new Runnable() {
            @Override
            public void run() {

                bluetoothOnOff.animate().alpha(1f).setDuration(1500);
                viewpairedDevices.animate().alpha(1f).setDuration(2500);
                scanfornewDevices.animate().alpha(1f).setDuration(3000);



            }
        },500);












        mBluetoothAdapter   = BluetoothAdapter.getDefaultAdapter();



        mProgressDlg        = new ProgressDialog(this);

        mProgressDlg.setMessage("Scanning, Please wait...");
        mProgressDlg.setCancelable(false);
        mProgressDlg.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();

                mBluetoothAdapter.cancelDiscovery();
            }
        });}








        if (mBluetoothAdapter.isEnabled()){
            bluetoothOnOff.setText("Bluetooth is On");
            blue2.setText("Bluetooth is On");
        }else {

            blue2.setText("Bluetooth is Off");
            bluetoothOnOff.setText("Bluetooth is Off");

        }


        if (mBluetoothAdapter == null) {
            showUnsupported();
        } else {
            viewpairedDevices.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {






                    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();

                    if (pairedDevices == null || pairedDevices.size() == 0) {
                        Toast toast = Toast.makeText(getApplicationContext()," No paired device found.", Toast.LENGTH_SHORT);
                        View view3 = toast.getView();
                        view3.setBackgroundColor(Color.parseColor("#ffff5b"));
                        TextView text = (TextView) view3.findViewById(android.R.id.message);

                        text.setTextColor(Color.parseColor("#000000"));
                        toast.show();
                    } else {
                        ArrayList<BluetoothDevice> list = new ArrayList<BluetoothDevice>();

                        list.addAll(pairedDevices);

                        Intent intent = new Intent(BluetoothConnectionActivity.this, DeviceList.class);

                        intent.putParcelableArrayListExtra("device.list", list);

                        startActivity(intent);
                    }
                }
            });

            scanfornewDevices.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View arg0) {



                    mBluetoothAdapter.startDiscovery();

                }
            });






            bluetoothOnOff.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {


                    if (mBluetoothAdapter.isEnabled()) {
                        mBluetoothAdapter.disable();
                        showDisabled();



                        bluetoothOnOff.setText("Bluetooth is OFF");




                        final Handler handler6 = new Handler();
                        handler6.postDelayed(new Runnable() {
                            @Override
                            public void run() {


                                mediaplayer.start();


                            }
                        }, 500);



                        final Handler handler3 = new Handler();
                        handler3.postDelayed(new Runnable() {
                            @Override
                            public void run() {



                                bluetoothOnOff.animate().translationY(-1f).setDuration(5000);
                                blue2.animate().translationY(-1f).setDuration(5000);

                                bluetoothOnOff.animate().alpha(1f).setDuration(3000);
                                blue2.animate().alpha(0f).setDuration(3000);






                            }
                        }, 500);



                    } else {
                        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

                        startActivityForResult(intent, 1000);






                    }}
            });


            blue2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {


                    if (mBluetoothAdapter.isEnabled()) {
                        mBluetoothAdapter.disable();
                        showDisabled();



                        bluetoothOnOff.setText("Bluetooth is OFF");





                        final Handler handler6 = new Handler();
                        handler6.postDelayed(new Runnable() {
                            @Override
                            public void run() {


                                mediaplayer.start();


                            }
                        }, 500);



                        final Handler handler3 = new Handler();
                        handler3.postDelayed(new Runnable() {
                            @Override
                            public void run() {



                                bluetoothOnOff.animate().translationY(-1f).setDuration(5000);
                                blue2.animate().translationY(-1f).setDuration(5000);

                                bluetoothOnOff.animate().alpha(1f).setDuration(3000);
                                blue2.animate().alpha(0f).setDuration(3000);






                            }
                        }, 500);



                    } else {
                        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

                        startActivityForResult(intent, 1000);






                    }}
            });





            if (mBluetoothAdapter.isEnabled()) {



                showEnabled();
            } else {

                showDisabled();
            }
        }


        IntentFilter filter = new IntentFilter();

        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

        registerReceiver(mReceiver, filter);

    }































    @Override
    public void onPause() {
        if (mBluetoothAdapter != null) {
            if (mBluetoothAdapter.isDiscovering()) {
                mBluetoothAdapter.cancelDiscovery();
            }
        }

        super.onPause();
    }

    @Override
    public void onBackPressed() {


    }

    @Override
    public void onDestroy() {
        unregisterReceiver(mReceiver);

        super.onDestroy();
    }

    private void showEnabled() {



        bluetoothOnOff.setEnabled(true);

        viewpairedDevices.setEnabled(true);
        viewpairedDevices.setBackgroundResource(R.drawable.selectorstylish);
        scanfornewDevices.setEnabled(true);
        scanfornewDevices.setBackgroundResource(R.drawable.selectorstylish);
    }

    private void showDisabled() {




        bluetoothOnOff.setEnabled(true);

        viewpairedDevices.setEnabled(false);
        viewpairedDevices.setBackgroundResource(R.drawable.selectorstylish);
        scanfornewDevices.setEnabled(false);
        scanfornewDevices.setBackgroundResource(R.drawable.selectorstylish);
    }

    private void showUnsupported() {
        Toast toast = Toast.makeText(getApplicationContext()," Bluetooth is not supported by this device.", Toast.LENGTH_SHORT);
        View view3 = toast.getView();
        view3.setBackgroundColor(Color.parseColor("#ffff5b"));
        TextView text = (TextView) view3.findViewById(android.R.id.message);

        text.setTextColor(Color.parseColor("#000000"));
        toast.show();


        bluetoothOnOff.setEnabled(false);
        viewpairedDevices.setEnabled(false);
        viewpairedDevices.setBackgroundResource(R.drawable.selectorstylish);
        scanfornewDevices.setEnabled(false);
        scanfornewDevices.setBackgroundResource(R.drawable.selectorstylish);

    }

    private void showToast(String message) {
        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();


            if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);

                if (state == BluetoothAdapter.STATE_ON) {




                    bluetoothOnOff.setText("Bluetooth is On");
                    blue2.setText("Bluetooth is On");



                    showEnabled();



                    final Handler handler5 = new Handler();
                    handler5.postDelayed(new Runnable() {
                        @Override
                        public void run() {


                            mediaplayer.start();


                        }
                    }, 500);



                    final Handler handler = new Handler();
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {



                            bluetoothOnOff.animate().translationY(150f).setDuration(5000);
                            blue2.animate().translationY(150f).setDuration(5000);


                            bluetoothOnOff.animate().alpha(0f).setDuration(3000);
                            blue2.animate().alpha(1f).setDuration(3000);





                        }
                    }, 500);


                }







            } else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
                mDeviceList = new ArrayList<BluetoothDevice>();

                mProgressDlg.show();
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                mProgressDlg.dismiss();

//                Intent newIntent = new Intent(BluetoothConnectionActivity.this, DeviceList.class);
//
//                newIntent.putParcelableArrayListExtra("device.list", mDeviceList);
//
//                startActivity(newIntent);
            } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                mDeviceList.add(device);

                Toast toast = Toast.makeText(getApplicationContext()," Found device" + device.getName(), Toast.LENGTH_SHORT);
                View view3 = toast.getView();
                view3.setBackgroundColor(Color.parseColor("#ffff5b"));
                TextView text = (TextView) view3.findViewById(android.R.id.message);

                text.setTextColor(Color.parseColor("#000000"));
                toast.show();
            }
        }
    };


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.optionmenu,menu);
        return super.onCreateOptionsMenu(menu);





    }
 }

Device list Class :

public class DeviceList extends AppCompatActivity {

    private ListView mListView;
    private AdapterClassBluetooth mAdapterClassBluetooth;
    private ArrayList<BluetoothDevice> mDeviceList;
    private BluetoothDevice device ;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_device_list);





        mDeviceList     = getIntent().getExtras().getParcelableArrayList("device.list");

        mListView       = (ListView) findViewById(R.id.lv_paired);

        mAdapterClassBluetooth = new AdapterClassBluetooth(this);

        mAdapterClassBluetooth.setData(mDeviceList);
        mAdapterClassBluetooth.setListener(new AdapterClassBluetooth.OnPairButtonClickListener() {
            @Override
            public void onPairButtonClick(int position) {
                BluetoothDevice device = mDeviceList.get(position);

                if (device.getBondState() == BluetoothDevice.BOND_BONDED) {

                    unpairDevice(device);
                } else {
                    Toast toast = Toast.makeText(getApplicationContext(), "Pairing..." , Toast.LENGTH_SHORT);
                    View view = toast.getView();
                    view.setBackgroundColor(Color.parseColor("#ffff5b"));
                    TextView text = (TextView) view.findViewById(android.R.id.message);

                    text.setTextColor(Color.parseColor("#000000"));
                    toast.show();

                    pairDevice(device);
                }
            }
        });

        mListView.setAdapter(mAdapterClassBluetooth);


        registerReceiver(mPairReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));













    }

    @Override
    public void onDestroy() {
        unregisterReceiver(mPairReceiver);

        super.onDestroy();
    }


    private void showToast(String message) {
        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
    }

    private void pairDevice(BluetoothDevice device) {
        try {
            Method method = device.getClass().getMethod("createBond", (Class[]) null);
            method.invoke(device, (Object[]) null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void unpairDevice(BluetoothDevice device) {
        try {
            Method method = device.getClass().getMethod("removeBond", (Class[]) null);
            method.invoke(device, (Object[]) null);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
                final int state         = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
                final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);

                if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {




                    Toast toast = Toast.makeText(getApplicationContext()," Device are paired, please wait...", Toast.LENGTH_SHORT);
                    View view = toast.getView();
                    view.setBackgroundColor(Color.parseColor("#ffff5b"));
                    TextView text = (TextView) view.findViewById(android.R.id.message);

                    text.setTextColor(Color.parseColor("#000000"));
                    toast.show();





                    Handler delaying = new Handler();
                    delaying.postDelayed(new Runnable() {
                        @Override
                        public void run() {

                            Intent communicate = new Intent(DeviceList.this,Security.class);
                            startActivity(communicate);
                            finish();

                        }
                    },1500);








                } else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED){
                    Toast toast = Toast.makeText(getApplicationContext(),"Unpaired.", Toast.LENGTH_SHORT);
                    View view = toast.getView();
                    view.setBackgroundColor(Color.parseColor("#ffff5b"));
                    TextView text = (TextView) view.findViewById(android.R.id.message);

                    text.setTextColor(Color.parseColor("#000000"));
                    toast.show();
                }

                mAdapterClassBluetooth.notifyDataSetChanged();
            }
        }

    };}

Adapter class :

public class AdapterClassBluetooth extends BaseAdapter{

    private LayoutInflater mInflater;
    private List<BluetoothDevice> mData;
    private OnPairButtonClickListener mListener;

    public AdapterClassBluetooth(){


    }

    public AdapterClassBluetooth(Context context) {
        super();
        mInflater = LayoutInflater.from(context);
    }

    public void setData(List<BluetoothDevice> data) {
        mData = data;
    }

    public void setListener(OnPairButtonClickListener listener) {
        mListener = listener;
    }

    public int getCount() {
        return (mData == null) ? 0 : mData.size();
    }

    public Object getItem(int position) {
        return null;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;

        if (convertView == null) {
            convertView         =  mInflater.inflate(R.layout.adapterlist, null);

            holder              = new ViewHolder();

            holder.nameTv       = (TextView) convertView.findViewById(R.id.tv_name);
            holder.addressTv    = (TextView) convertView.findViewById(R.id.tv_address);
            holder.pairBtn      = (Button) convertView.findViewById(R.id.btn_pair);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        BluetoothDevice device  = mData.get(position);

        holder.nameTv.setText(device.getName());
        holder.addressTv.setText(device.getAddress());
        holder.pairBtn.setText((device.getBondState() == BluetoothDevice.BOND_BONDED) ? "Unpair" : "Pair");
        holder.pairBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null) {
                    mListener.onPairButtonClick(position);
                }
            }
        });


        return convertView;
    }

    static class ViewHolder {
        TextView nameTv;
        TextView addressTv;
        TextView pairBtn;
    }

    public interface OnPairButtonClickListener {
        public abstract void onPairButtonClick(int position);
    }




}

in an article i studied about this issue and find out that with this code :

 if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(context,
                    new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                    1);

i can make the application to support phones with android more than 6 so i can discover all nearby devices and pair with them,

The issue is, i don't know where should i exactly use this code.. i would really appreciate if you could tell me where to use it within the codes i showed here.

or simply tell me how to overcome this problem with any other code you may know.

In your AndroidManifest.xml file add this:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Then, instead of calling registerReceiver call this function:

private tryRegisterReceiver() {    
    if (ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.ACCESS_COARSE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {
            // Here, permission is not granted
            // after calling requestPermissions, the result must be treated in onRequestPermissionResult
            ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                1000); // 100 or other desired code
    } else {
        // Permission has already been granted
        // continue registering your receiver
        registerReceiver();
    }
}

To treat the result of the permission request

@Override
public void onRequestPermissionsResult(int requestCode,
        String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case 1000: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted
                // continue registering your receiver
                registerReceiver();
            } else {
                // permission denied
                // show a message or finish your activity
            }
            return;
        }

        // other 'case' for other permissions if needed
    }
}    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM