Приложение Bluetooth с библиотекой (https://github.com/OmarAflak/Bluetooth-Library) вылетает - PullRequest
0 голосов
/ 09 апреля 2019

Я работаю над простым приложением, в основном для отправки данных по Bluetooth.

Моя основная активность:

package in.justrobotics.jrbluetoothcontrol;

import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import me.aflak.bluetooth.Bluetooth;
import me.aflak.bluetooth.BluetoothCallback;
import me.aflak.bluetooth.DiscoveryCallback;

public class MainActivity extends AppCompatActivity {

    Bluetooth bluetooth;
    private ArrayAdapter<String> mBTArrayAdapter;
    String address,name;

    public void composeEmail(String message) {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("*/*");
        intent.putExtra(android.content.Intent.EXTRA_EMAIL,new String[] { "shlokj@gmail.com" });
        intent.putExtra(Intent.EXTRA_SUBJECT, "Would like to get in touch");
        intent.putExtra(Intent.EXTRA_TEXT, message);
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivity(intent);
        }
    }


    public void sendEmail () {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Send a message: ");
        final EditText input = new EditText(this);
        input.setInputType(InputType.TYPE_CLASS_TEXT);
        builder.setView(input);
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                final String Message = input.getText().toString();
                composeEmail(Message);
            }
        });
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });

        builder.show();

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bluetoothOn();
        mBTArrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
        List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
        bluetooth = new Bluetooth(getApplicationContext());
        if (bluetooth==null){
            Toast.makeText(getApplicationContext(),"Bluetooth null",Toast.LENGTH_SHORT).show();
        }
        if (bluetooth!=null){
            Toast.makeText(getApplicationContext(),"Bluetooth not null",Toast.LENGTH_SHORT).show();
            BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();

            for (BluetoothDevice device : pairedDevices)
                mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
        }

        Button openController = (Button) findViewById(R.id.open_controller);
        openController.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent startController = new Intent(MainActivity.this,ControllerActivity.class);
                //startController.putExtra("BLUETOOTH_CONNECTED_THREAD",mConnectedThread);
                startActivity(startController);
            }
        });
        Button openAccelController = (Button) findViewById(R.id.open_accel_controller);
        openAccelController.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent startControllerAccel = new Intent(MainActivity.this,AccelerometerControl.class);
                startActivity(startControllerAccel);
            }
        });

        bluetooth.setBluetoothCallback(new BluetoothCallback() {
            @Override
            public void onBluetoothTurningOn() {

            }

            @Override
            public void onBluetoothOn() {

            }

            @Override
            public void onBluetoothTurningOff() {

            }

            @Override
            public void onBluetoothOff() {

            }

            @Override
            public void onUserDeniedActivation() {

            }
        });
        bluetooth.setDiscoveryCallback(new DiscoveryCallback() {
            @Override public void onDiscoveryStarted() {}
            @Override public void onDiscoveryFinished() {}
            @Override public void onDeviceFound(BluetoothDevice device) {}
            @Override public void onDevicePaired(BluetoothDevice device) {}
            @Override public void onDeviceUnpaired(BluetoothDevice device) {}
            @Override public void onError(String message) {}
        });
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
        LayoutInflater inflater = getLayoutInflater();
        View convertView = (View) inflater.inflate(R.layout.dialog_btdevices, null);
        alertDialog.setView(convertView);
        alertDialog.setTitle("Select your device");
        alertDialog.setMessage("A JR Bluetooth device name is of the form JR_X");
        ListView devicesListView = (ListView) convertView.findViewById(R.id.mDevicesListView);
        devicesListView.setAdapter(mBTArrayAdapter);
        devicesListView.setOnItemClickListener(mDeviceClickListener);
        alertDialog.show();
    }

    private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {

            String connectStatus="";
            if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
                Toast.makeText(getBaseContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
                return;
            }

            //mBluetoothStatus.setText("Connecting...");
            // Get the device MAC address, which is the last 17 chars in the View
            String info = ((TextView) v).getText().toString();
            address = info.substring(info.length() - 17);
            Toast.makeText(getBaseContext(), address, Toast.LENGTH_SHORT).show();
            name = info.substring(0, info.length() - 17);

            if (bluetooth.isConnected()){
                connectStatus="Connected";
            }
            if (!bluetooth.isConnected()){
                connectStatus="Not connected";
            }

            Toast.makeText(getBaseContext(), connectStatus, Toast.LENGTH_SHORT).show();
            bluetooth.connectToAddress(address);
            Toast.makeText(getBaseContext(), "Connected (hopefully)", Toast.LENGTH_SHORT).show();
            bluetooth.send("test");
            Toast.makeText(getBaseContext(), "Sent data (hopefully)", Toast.LENGTH_SHORT).show();
        }};

    @Override
    protected void onStart() {
        super.onStart();
        bluetooth.onStart();
        bluetooth.enable();
    }

    @Override
    protected void onStop() {
        super.onStop();
        bluetooth.onStop();
    }

    private void bluetoothOn(){
        if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, 1);
            //mBluetoothStatus.setText("Bluetooth enabled");
            Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();
        }
        else{
            Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
        }
    }

}

Следы стека:

2019-04-09 20:16:48.222 23737-23737/in.justrobotics.jrbluetoothcontrol E/AndroidRuntime: FATAL EXCEPTION: main
    Process: in.justrobotics.jrbluetoothcontrol, PID: 23737
    java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.OutputStream.write(byte[])' on a null object reference
        at me.aflak.bluetooth.Bluetooth.send(Bluetooth.java:185)
        at me.aflak.bluetooth.Bluetooth.send(Bluetooth.java:201)
        at in.justrobotics.jrbluetoothcontrol.MainActivity$7.onItemClick(MainActivity.java:197)
        at android.widget.AdapterView.performItemClick(AdapterView.java:310)
        at android.widget.AbsListView.performItemClick(AbsListView.java:1164)
        at android.widget.AbsListView$PerformClick.run(AbsListView.java:3154)
        at android.widget.AbsListView$3.run(AbsListView.java:4097)
        at android.os.Handler.handleCallback(Handler.java:754)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:163)
        at android.app.ActivityThread.main(ActivityThread.java:6238)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)

Пользовательский класс Bluetooth: https://github.com/OmarAflak/Bluetooth-Library/blob/master/bluetooth/src/main/java/me/aflak/bluetooth/Bluetooth.java

Мой код падает на линии bluetooth.send("test"); с NullPointerException, и я не понимаю, почему.Я новичок с Bluetooth на Android;Мы будем благодарны за помощь.

Окончательный результат, который, я надеюсь, я смогу получить, заключается в простом подключении к устройству и отправке данных, и даже этого не происходит.

Редактировать: Iсейчас сталкиваюсь и с другой проблемой.Я передаю строковый адрес во второе действие (https://gist.github.com/shlokj/12c4e2c62ca0f5284c5c3c041775654f) из первого действия (https://gist.github.com/shlokj/f80d0902ad1a366ab03e178164968cfb) через намерение). Там я пытаюсь подключиться в строке 163 (bluetoothObject.connectToAddress(address);), и происходит сбой сNullPointerException. Я понятия не имею, почему, потому что я проверяю, что объект Bluetooth и address не равны нулю с помощью оператора if. Трассировки стека: https://gist.github.com/shlokj/56e3c9e311dea6f77a1acd8953a317c8 Весь репозиторий: https://github.com/shlokj/JR-Bluetooth-Control. Итак,Короче говоря, теперь мне нужно также иметь возможность правильно подключаться, не говоря уже об отправке данных.

1 Ответ

1 голос
/ 10 апреля 2019

Я только что просмотрел предоставленную вами ссылку на библиотеку, и, похоже, кто-то другой столкнулся с подобной проблемой, приведенной здесь:

https://github.com/OmarAflak/Bluetooth-Library/issues/16

И оказалось, что соединение не было установленотем не менее, прежде чем вызывать send, проверьте, подключено ли устройство с помощью функции * 1006. *

Вы не должны вызывать send до того, как соединение будет установлено правильно. Вы можете установить обратный вызов для того же самого, используя setDiscoveryCallbackи сделайте работу внутри наиболее вероятной после получения подтверждения в void onDevicePaired(BluetoothDevice device).

Редактировать 1: из комментариев.

Вы уверены, что именно в onDevicePaired () я должен отправлять данные?

Может быть, нет, я думаю, что я неправильно понял пример, приведенный автором библиотеки, теперь я думаю, что вы должны сделать это на onDeviceConnected.

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

Да, для этого можно установить обратный вызов, используя следующее:

 bluetooth.setDeviceCallback(new DeviceCallback() {
            @Override
            public void onDeviceConnected(BluetoothDevice device) {
               // do your work here.
            }

            @Override
            public void onDeviceDisconnected(BluetoothDevice device, String message) {

            }

            @Override
            public void onMessage(String message) {

            }

            @Override
            public void onError(String message) {

            }

            @Override
            public void onConnectError(BluetoothDevice device, String message) {

            }
        });

Изменить 2:

Там я пытаюсь подключиться в строке 163 (bluetoothObject.connectToAddress (address);), и происходит сбой с исключением NullPointerException.

Этот сбой происходит из-за того, что BluetoothAdapter еще не инициализирован, поэтому при вызове bluetoothObject.connectToAddress(address) выдается NullPointerException.

Вам необходимо инициализировать это перед подключением следующим образом:

bluetoothObject = new Bluetooth(getApplicationContext());
        bluetoothObject.onStart();//this is the line that initializes adapter.
        bluetoothObject.enable();
...