проблема подключения Bluetooth с внешним устройством - PullRequest
0 голосов
/ 07 июня 2018

Я пытаюсь подключиться к внешнему аппаратному устройству под названием «шифер» с моим кодом.Я следую инструкциям в руководстве по API, чтобы устройство работало с моим приложением для Android.Но, кажется, здесь есть что-то, что меня не замечает, о чем я даже не могу найти информацию в их примере приложения ... Суть в том, что я пытаюсь подключиться к устройству, но соединение не установлено.Вот отладочный вывод до того, как я нажму кнопку «Подключиться к», и до того, как я нажму кнопку «Подключиться» ...

06-07 02:44:06.384 4444-4444/com.example.qwill.thoughtcast I/BluetoothDevice: connectGatt
06-07 02:44:06.386 1553-2143/? W/Bth: BluetoothFreeze:tag: 181  uid: 10143  pid: 4444
06-07 02:44:06.387 1873-2001/? I/BluetoothState: new active bluetooth uid: 10143, pid:4444, reason:BLE_CONNECT
06-07 02:44:06.396 1553-2143/? W/Bth: BluetoothFreeze:tag: 181  uid: 10143  pid: 4444
06-07 02:44:06.396 1553-2143/? I/BtGatt.JNI: gattClientRegisterAppNative(L997): gattClientRegisterAppNative, register_client begin
    gattClientRegisterAppNative(L1003): gattClientRegisterAppNative, register_client
    gattClientRegisterAppNative(L1005): gattClientRegisterAppNative, register_client finish
06-07 02:44:06.396 1553-2048/? I/bt_att: GATT_Register
    GATT_Register: allocated gatt_if=6
    GATT_StartIf gatt_if=6
06-07 02:44:06.396 1553-1762/? W/bt_btif: HAL bt_gatt_callbacks->client->register_client_cb

Если для кого-то это имеет смысл, почему я не могу подключиться к своему устройству, просиммне.

Здесь я подключаюсь к своему устройству ...

listie.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int  position, long id) {
                // Stop scanning
                slateManager.stopScan();
                slateManager.connect(slateManager.getDeviceByIndex(position));
            }
        });

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

Как я видел во многих приложениях BLE, они сохраняют некоторое время между методами stopScan() и connecGatt().

  1. Сканирование и выбор, т.е. startScan() и stopScan()
  2. Соединение, т. Е. connectGatt()
  3. Выполнение задач, таких как transferData()

Удержание некоторого времени между этими задачами определенно помогает в эффективности соединений LE.

0 голосов
/ 07 июня 2018

Для сопряжения устройства.используйте этот код.Это работает для меня

public class BTBluetoothActivity extends AppCompatActivity {
    private ArrayList<BluetoothDevice> mDeviceList = new 
    ArrayList<BluetoothDevice>();
    private BluetoothAdapter mBluetoothAdapter;
    private ProgressDialog mProgressDlg;

    private TextView mStatusTv;
    private Button mActivateBtn;
    private Button mPairedBtn;
    private Button mScanBtn;

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

            mStatusTv = (TextView) findViewById(R.id.tv_status);
            mActivateBtn = (Button) findViewById(R.id.btn_enable);
            mPairedBtn = (Button) findViewById(R.id.btn_view_paired);
            mScanBtn = (Button) findViewById(R.id.btn_scan);

            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

            mProgressDlg = new ProgressDialog(this);

            mProgressDlg.setMessage("Scanning...");
            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 == null) {
                showUnsupported();
            } else {
                mPairedBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();

                        if (pairedDevices == null || pairedDevices.size() == 0) {
                            showToast("No Paired Devices Found");
                        } else {
                            ArrayList<BluetoothDevice> list = new ArrayList<BluetoothDevice>();

                            list.addAll(pairedDevices);

                            if (list != null) {
                                Intent intent = new Intent(BTBluetoothActivity.this, DeviceListActivity.class);
                                intent.putParcelableArrayListExtra("device.list", list);
                                startActivity(intent);
                            } else {
                                Toast.makeText(BTBluetoothActivity.this, "Bluetooth device not found", Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
                });

                mScanBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View arg0) {
                        ensureDiscoverable();
                        mBluetoothAdapter.startDiscovery();
                    }
                });


                mActivateBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (mBluetoothAdapter.isEnabled()) {
                            mBluetoothAdapter.disable();

                            showDisabled();
                        } 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);
            filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);

            registerReceiver(mReceiver, filter);

            IntentFilter btCheck = new IntentFilter();
            btCheck.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
            btCheck.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
            registerReceiver(btConnectionCheck, btCheck);
        }

    private void ensureDiscoverable() {
            if (mBluetoothAdapter.getScanMode() !=
                    BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 3000);
                startActivity(discoverableIntent);
            }
        }

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

    @Override
        public void onDestroy() {
            unregisterReceiver(mReceiver);
            unregisterReceiver(btConnectionCheck);
            mBluetoothAdapter.disable();
            super.onDestroy();
        }

    private void showEnabled() {

            mStatusTv.setText("Bluetooth is On");
            mStatusTv.setTextColor(Color.BLUE);

            mActivateBtn.setText("Turn OFF");
            mActivateBtn.setEnabled(true);

            mPairedBtn.setEnabled(true);
            mScanBtn.setEnabled(true);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                mPairedBtn.setBackground(getResources().getDrawable(R.drawable.rectangle));
                mScanBtn.setBackground(getResources().getDrawable(R.drawable.rectangle));
            }
        }

        private void showDisabled() {
        inCheck = true;
            mStatusTv.setText("Bluetooth is Off");
            mStatusTv.setTextColor(Color.RED);

            mActivateBtn.setText("Turn ON");
            mActivateBtn.setEnabled(true);

            mPairedBtn.setEnabled(false);
            mScanBtn.setEnabled(false);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                mPairedBtn.setBackground(getResources().getDrawable(R.drawable.rectcheck));
                mScanBtn.setBackground(getResources().getDrawable(R.drawable.rectcheck));
            }
        }

        private void showUnsupported() {
            mStatusTv.setText("Bluetooth is unsupported by this device");
        inCheck = false;
            mActivateBtn.setText("Turn ON");
            mActivateBtn.setEnabled(false);

            mPairedBtn.setEnabled(false);
            mScanBtn.setEnabled(false);
        }

    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) {
                        showToast("Enabled");

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

                    mProgressDlg.show();
                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    mProgressDlg.dismiss();
                    if (inCheck) {
                        if (mDeviceList == null || mDeviceList.size() == 0) {
                            showToast("No bluetooth device found around");
                        } else {
                            Intent newIntent = new Intent(BTBluetoothActivity.this, DeviceListActivity.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);

    //                showToast("Found device " + device.getName());
                }
                else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){
                    BluetoothDevice mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                    if (mDevice.getBondState() == BluetoothDevice.BOND_BONDED){
                        Log.d(DEVICE_NAME, "BroadcastReceiver: BOND_BONDED.");
            // Device will be pair and return here
                    }
                    //case2: creating a bone
                    if (mDevice.getBondState() == BluetoothDevice.BOND_BONDING) {
                        Log.d(DEVICE_NAME, "BroadcastReceiver: BOND_BONDING.");
                    }
                    //case3: breaking a bond
                    if (mDevice.getBondState() == BluetoothDevice.BOND_NONE) {
                        Log.d(DEVICE_NAME, "BroadcastReceiver: BOND_NONE.");
                    }
                }
            }
        };

    BroadcastReceiver btConnectionCheck = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)){
                    Toast.makeText(context, "BT Connected", Toast.LENGTH_SHORT).show();

                } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)){
                    Toast.makeText(context, "BT DisConnected", Toast.LENGTH_SHORT).show();
                }
            }
        };
    }

Класс списка устройств

public class DeviceListActivity extends AppCompatActivity {

    private ListView mListView;
    private TextView status;
    private DeviceListAdapters mAdapter;
    private ArrayList<BluetoothDevice> mDeviceList;
    private boolean doubleActivity;
    private BluetoothDevice device;

    private boolean stopWorker;
    private int readBufferPosition;
    private Thread workerThread;
    InputStream mmInputStream;
    private byte[] readBuffer;
    private BluetoothSocket mmSocket;

    @Override
    protected 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);

        mAdapter        = new DeviceListAdapters(this);

        status = findViewById(R.id.tv_status);
        status.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });

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

                if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                    unpairDevice(device);
                } else {
                    showToast("Pairing...");
                    pairDevice(device);
                }
            }
        });

        mListView.setAdapter(mAdapter);

        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);
            doubleActivity = true;
        } 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) {
                    showToast("Paired");
                } else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED){
                    showToast("Unpaired");
                }

                mAdapter.notifyDataSetChanged();
            }
        }
    };

    @Override
    protected void onPause() {
        if (doubleActivity){
            finish();
        }
        super.onPause();
    }
}

Класс адаптера

    public class DeviceListAdapters extends BaseAdapter {

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

    public DeviceListAdapters(Context context) {
        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.list_item_devices, 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);
    }

}

activity_btbluetooth.xml

    <RelativeLayout
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/green"
    tools:context="com.BTBluetooth.BTBluetoothActivity">
    <ImageView
        android:id="@+id/icon_bt"
        android:scaleType="matrix"
        android:layout_marginTop="20dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:src="@drawable/btbackground"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <android.support.v7.widget.CardView
        android:layout_below="@id/icon_bt"
        app:cardElevation="60dp"
        app:cardCornerRadius="40dp"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:padding="30dp"
            android:layout_gravity="center"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TextView
                android:background="@drawable/loginrect"
                android:textStyle="bold"
                android:id="@+id/tv_status"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textSize="24sp"
                android:textColor="#ff0000"
                android:text="Bluetooth off" />

            <Button
                android:layout_marginTop="3dp"
                android:background="@drawable/rectangle"
                android:textColor="@color/white"
                android:textStyle="bold"
                android:id="@+id/btn_enable"
                android:layout_gravity="end"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Turn On" />

            <Button
                android:layout_marginTop="3dp"
                android:background="@drawable/rectangle"
                android:textColor="@color/white"
                android:textStyle="bold"
                android:id="@+id/btn_view_paired"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:enabled="false"
                android:text="view paired" />

            <Button
                android:layout_marginTop="3dp"
                android:background="@drawable/rectangle"
                android:textColor="@color/white"
                android:textStyle="bold"
                android:id="@+id/btn_scan"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:enabled="false"
                android:text="scan devices" />
        </LinearLayout>

    </android.support.v7.widget.CardView>

</RelativeLayout>

activity_device_list.xml

    <LinearLayout
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#bebebe"
    tools:context="com..BTBluetooth.DeviceListActivity">
    <TextView
        android:id="@+id/tv_status"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:padding="5dp"
        android:textStyle="bold"
        android:textColor="@color/white"
        android:background="@color/toolbarcolor"
        android:text="Bluetooth Devices" />

    <ListView
        android:id="@+id/lv_paired"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="2dp"
        android:cacheColorHint="#00000000" />
</LinearLayout>

list_item_devices.xml

    <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:cardElevation="20dp"
    app:cardCornerRadius="2dp">
    <RelativeLayout
        android:padding="16dp"
        android:background="#e1e1e1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:background="@drawable/switch_track_on"
            android:textColor="@color/white"
            android:textStyle="bold"
            android:id="@+id/btn_pair"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_alignParentRight="true"
            android:text="text pair" />

        <TextView
            android:id="@+id/tv_name"
            android:textStyle="bold"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/btn_pair"
            android:layout_alignTop="@+id/btn_pair"
            android:layout_alignParentLeft="true"
            android:textSize="18sp"
            android:textColor="@color/black"
            android:text="Galaxy Nexus" />

        <TextView
            android:layout_marginTop="2dp"
            android:id="@+id/tv_address"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/btn_pair"
            android:layout_alignParentLeft="true"
            android:layout_alignBottom="@+id/btn_pair"
            android:text="000000000" />
    </RelativeLayout>

</android.support.v7.widget.CardView>
...