Android Fragment

时间:2017-03-22 15:22:28

标签: android listview bluetooth android-adapter tablet

目标:构建一个片段页面,用于发现范围内蓝牙设备的名称和地址,并将其显示在ListView中,用户可以从中选择要连接的设备。它类似于本地设备中的蓝牙扫描过程。

遇到的问题:

  1. 有时,扫描过程会持续很长时间(> 5分钟)和 不停止

  2. 有时,发现过程很快,并且能够输出“未找到设备”或相应找到的设备的输出名称和地址

  3. 有时,虽然在本地蓝牙设置中发现了蓝牙设备,但ListView中的蓝牙设备不会出现在ListView中。但是,当我切换到本地蓝牙设置并切换回我的应用程序时,ListView会开始显示本地蓝牙设置中列出的蓝牙设备。

  4. 我花了几周时间试图解决这些问题,但无济于事。欣赏任何可以指出我的错误的灵魂?

    图片:

    Long scanning

    My app's Listview got updated after switching back from Local Bluetooth setting

    这是我的代码:

         import android.app.Activity; 
         import android.bluetooth.BluetoothAdapter;
         import android.bluetooth.BluetoothDevice;
         import android.content.BroadcastReceiver;
         import android.content.Context;
         import android.content.IntentFilter;
         import android.os.Bundle;
         import android.support.v4.app.Fragment;
         import android.view.LayoutInflater;
         import android.view.View;
         import android.view.ViewGroup;
    
         import android.widget.AdapterView;
         import android.widget.ArrayAdapter;
         import android.content.Intent;
         import android.widget.CompoundButton;
         import android.widget.ListView;
         import android.widget.ProgressBar;
         import android.widget.Switch;
         import android.widget.TextView;
         import android.widget.Toast;
    
         import java.util.Set;
    
    
        /**
         * A simple {@link Fragment} subclass.
         */
        public class Server_fragment extends Fragment {
    
    
        // Component fields
        Switch bluetoothSwitch;
        TextView titlePairedDevices;
        ListView pairedListView;
        TextView titleNewDevices;
        ListView newDevicesListView;
        ProgressBar progressBar;
    
        // Member fields
        private BluetoothAdapter mBluetoothAdapter = null;
        private ArrayAdapter<String> mPairedDevicesArrayAdapter;
        private ArrayAdapter<String> mNewDevicesArrayAdapter;
    
        private static final int REQUEST_ENABLE_BT = 3;
    
        Set<BluetoothDevice> pairedDevices;
    
        public Server_fragment() {
            // Required empty public constructor
        }
    
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
    
            // Inflate the layout for this fragment
            final View v = inflater.inflate(R.layout.fragment_server_fragment, container, false);
    
            // Initialize the switch to perform Bluetooth on/off
            bluetoothSwitch = (Switch) v.findViewById(R.id.bluetoothSwitch);
            titlePairedDevices = (TextView) v.findViewById(R.id.title_paired_devices);
            pairedListView = (ListView) v.findViewById(R.id.paired_devices);
            titleNewDevices = (TextView) v.findViewById(R.id.title_new_devices);
            newDevicesListView = (ListView) v.findViewById(R.id.new_devices);
            progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
    
            // Initialize array adapters.
            // One for already paired devices and
            // one for newly discovered devices
            mPairedDevicesArrayAdapter = new ArrayAdapter<String>(getActivity(), R.layout.device_name);
            mNewDevicesArrayAdapter = new ArrayAdapter<String>(getActivity(), R.layout.device_name);
    
            // Find and set up the ListView for paired devices
            pairedListView.setAdapter(mPairedDevicesArrayAdapter);
            pairedListView.setOnItemClickListener(mDeviceClickListener);
    
            // Find and set up the ListView for newly discovered devices
            newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
            newDevicesListView.setOnItemClickListener(mDeviceClickListener);
    
            IntentFilter filter = new IntentFilter();
    
            // Register for broadcasts when a device is discovered
            filter.addAction(BluetoothDevice.ACTION_FOUND);
            getActivity().registerReceiver(mReceiver, filter);
    
            // Register for broadcasts when discovery has finished
            filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            getActivity().registerReceiver(mReceiver, filter);
    
            // Get local Bluetooth Adapter
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    
            /**
             *  If the switch is off initially,
             *  This method enables Bluetooth when user presses switch
             *  If the switch is on initially,
             *  This method disables Bluetooth when user presses switch
             */
            bluetoothSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked) {
                        bluetoothSupportCheck();
                        titlePairedDevices.setVisibility(View.VISIBLE);
                        displayPairedList();
                        titleNewDevices.setVisibility(View.VISIBLE);
                        doDiscovery();
                    } else {
                        bluetoothSupportCheck();
                        titlePairedDevices.setVisibility(View.GONE);
                        displayPairedList();
                        titleNewDevices.setVisibility(View.GONE);
                        progressBar.setVisibility(View.GONE);
                        newDevicesListView.setVisibility(View.GONE);
                    }
                }
            });
    
            pairedDevices = mBluetoothAdapter.getBondedDevices();
    
            // Set switch mode according to local Bluetooth status
            if (mBluetoothAdapter.isEnabled()) {
                bluetoothSwitch.setChecked(true);
                titlePairedDevices.setVisibility(View.VISIBLE);
                displayPairedList();
                titleNewDevices.setVisibility(View.VISIBLE);
                doDiscovery();
                makeDiscoverable();
            } else {
                bluetoothSwitch.setChecked(false);
                titlePairedDevices.setVisibility(View.GONE);
                titleNewDevices.setVisibility(View.GONE);
                progressBar.setVisibility(View.GONE);
                newDevicesListView.setVisibility(View.GONE);
            }
    
            return v;
        }
    
    
        @Override
        public void onResume() {
            super.onResume();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
    
            // Make sure we're not doing discovery anymore
            if (mBluetoothAdapter != null) {
                mBluetoothAdapter.cancelDiscovery();
            }
    
            // Unregister broadcast listeners
            getActivity().unregisterReceiver(mReceiver);
        }
    
    
        /**
         *  This method checks whether Bluetooth is supported
         *  If yes, ask user for permission to allow Bluetooth to be on
         */
        private void bluetoothSupportCheck() {
    
            if (mBluetoothAdapter == null) {
                Toast.makeText(getContext(), "No bluetooth device available", Toast.LENGTH_LONG).show();
                bluetoothSwitch.setChecked(false);
            } else if (!mBluetoothAdapter.isEnabled() && bluetoothSwitch.isChecked()) {
                Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBluetooth, REQUEST_ENABLE_BT);
            } else {
                mBluetoothAdapter.disable();
                Toast.makeText(getContext(), "ADAPTER DISABLED", Toast.LENGTH_LONG).show();
            }
    
        }
    
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
    
            switch (requestCode) {
                case REQUEST_ENABLE_BT:
                    if (resultCode == Activity.RESULT_OK) {
                        makeDiscoverable();
                    } else {
                        Toast.makeText(getActivity(), "Bluetooth was not enabled. Exiting...", Toast.LENGTH_SHORT).show();
                        bluetoothSwitch.setChecked(false);
                        getActivity().finish();
                    }
                default:
                    break;
            }
        }
    
        private void makeDiscoverable() {
    
            if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
                startActivity(discoverableIntent);
            }
        }
    
    
        /**
         *   Display the list of paired devices
         */
        private void displayPairedList() {
    
            // If there are paired devices, add each one to the ArrayAdapter
            // Display the list of paired Bluetooth devices
            if (pairedDevices.size() > 0) {
                getView().findViewById(R.id.paired_devices).setVisibility(View.VISIBLE);
                for (BluetoothDevice device : pairedDevices) {
                    mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                }
            } else {
                mPairedDevicesArrayAdapter.clear();
                if ( bluetoothSwitch.isChecked() ) {
                    String noDevices = "\t No device has been paired".toString();
                    mPairedDevicesArrayAdapter.add(noDevices);
                }
                else {
                    mPairedDevicesArrayAdapter.clear();
                }
            }
        }
    
    
        /**
         *  The on-click listener for all devices in the ListViews
         */
        private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
    
                // Cancel discovery because it's costly and we're about to connect
                mBluetoothAdapter.cancelDiscovery();
    
                // Get the device MAC address, which is the last 17 chars in the View
                String info = ((TextView) v).getText().toString();
                String address = info.substring(info.length() - 17);
    
                // Finish this Activity
                getActivity().finish();
            }
        };
    
    
        /**
         *  The BroadcastReceiver that listens for discovered devices and
         *  changes the title when discovery is finished
         */
        private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
    
                String action = intent.getAction();
    
                // When discovery finds a device
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
    
                    // Get the BluetoothDevice object from the Intent
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    
                    // If it's already paired, skip it, because it's been listed already
                    if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                        mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                    }
    
                    // When discovery is finished
                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
    
                    progressBar.setVisibility(View.GONE);
                    titleNewDevices.setText("Other Available Devices");
    
                    // If no new devices found
                    if (mNewDevicesArrayAdapter.getCount() == 0) {
    
                        if ( bluetoothSwitch.isChecked() ) {
                            String noDevices = "\t No device found".toString();
                            mNewDevicesArrayAdapter.add(noDevices);
                        } else {
                            mNewDevicesArrayAdapter.clear();
                        }
                    } else {
                        if (!bluetoothSwitch.isChecked()) {
                            mNewDevicesArrayAdapter.clear();
                        }
                    }
    
                }
            }
        };
    
    
        private void doDiscovery() {
    
            titleNewDevices.setVisibility(View.VISIBLE);
            progressBar.setVisibility(View.VISIBLE);
    
            titleNewDevices.setText("Scanning for devices...");
    
            // If we're already discovering, stop it
            if (mBluetoothAdapter.isDiscovering()) {
                mBluetoothAdapter.cancelDiscovery();
            }
    
            // Request discover from BluetoothAdapter
            mBluetoothAdapter.startDiscovery();
    
        }
    
    
    }
    

0 个答案:

没有答案