Android如何实现将固件(.hex文件)蓝牙传输到信标

时间:2019-06-21 14:07:30

标签: java android bluetooth hex android-bluetooth

我真的是Bluetooth和.hex世界的新手,我正在尝试实现一个基本上包含以下内容的android应用:选择要发送的文件(.hex),进行Bluetooth扫描以查找与设备关闭的设备在智能手机上,单击列表上的所需设备(信标),然后通过蓝牙将.hex文件发送到该设备。因此,最麻烦的功能是通过蓝牙将.hex文件传输到信标设备。

直到现在,我还根据一些指南和论坛开发了此代码,但似乎无法正常工作(并且我仍然不确定如何将流启动到所选的特定设备):

public class MainActivity extends AppCompatActivity {

    private static final int READ_REQUEST_CODE = 42;
    private static final int SCAN_PERMISSIONS_CODE = 1;
    private static final String TAG = "MyActivity";
    private DevicesListAdapter adapter;
    private ListView listView;
    private SeekBar seekBar;
    private TextView valueDB;
    private ArrayList<BluetoothDevice> devicesList;
    private BluetoothLeScanner scanner;
    private EditText editFile;
    private Uri uriFirmware;
    private StringBuffer mOutStringBuffer;
    private BTInterface mBtInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        devicesList = new ArrayList<>();

        setContentView(R.layout.activity_main);
        editFile = findViewById(R.id.bt_edit_file);
        final int step = 1;
        int max = 100;
        final int min = 40;
        mBtInterface= new BTInterface();

        Button startScanButton = (Button) findViewById(R.id.buttonStartScan);
        startScanButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startScanForDevices();
            }
        });

        Button stopScanButton = (Button) findViewById(R.id.buttonStopScan);
        stopScanButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                scanner.stopScan(bleScanCallback);
            }
        });

        ImageButton btnFileLookup = (ImageButton) findViewById(R.id.btn_file_lookup);
        btnFileLookup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                performFileSearch();
            }
        });

        Log.d(TAG,"Requesting permission");
        int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION);
        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.ACCESS_FINE_LOCATION)) {

            } else {
                ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},SCAN_PERMISSIONS_CODE);
            }
        }
    }

    private void performFileSearch() {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");

        startActivityForResult(intent, READ_REQUEST_CODE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    protected void onActivityResult(int resultCode, int responseCode, Intent data) {
        super.onActivityResult(resultCode, responseCode,data);

        switch (resultCode) {
            case READ_REQUEST_CODE:
                if (responseCode == RESULT_OK && data != null) {
                    Uri uri = data.getData();
                    fileDisplayName(uri);
                    uriFirmware = uri;
                } else {
                    uriFirmware = null;
                }
                break;
        }
    }

    private void fileDisplayName(Uri uri) {
        Cursor cursor = getContentResolver().query(uri, null, null, null, null, null);
        try {
            if (cursor != null && cursor.moveToFirst()) {
                String displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                editFile.setText(displayName);
            }
        } finally {
            cursor.close();
        }
    }

    public void startScanForDevices() {
        BluetoothManager bluetoothManager = (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);
        BluetoothAdapter adapter = bluetoothManager.getAdapter();

        scanner = adapter.getBluetoothLeScanner();
        if (scanner != null) {
            scanner.startScan(bleScanCallback);
        } else {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Error");
            builder.setMessage("Cannot start scan, might be that Bluetooth is turned off");
            builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    return;
                }
            }).create().show();
        }
    }

    public static byte[] getBytes(Context context, Uri uri) throws IOException {
        InputStream iStream = context.getContentResolver().openInputStream(uri);
        try {
            return getBytes(iStream);
        } finally {
            // close the stream
            try {
                iStream.close();
            } catch (IOException ignored) { /* do nothing */ }
        }
    }

    public static byte[] getBytes(InputStream inputStream) throws IOException {
        byte[] bytesResult = null;
        ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];
        try {
            int len;
            while ((len = inputStream.read(buffer)) != -1) {
                byteBuffer.write(buffer, 0, len);
            }
            bytesResult = byteBuffer.toByteArray();
        } finally {
            // close the stream
            try{ byteBuffer.close(); } catch (IOException ignored){ /* do nothing */ }
        }
        return bytesResult;
    }
    
    private ScanCallback bleScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            adapter = new DevicesListAdapter(MainActivity.this, R.layout.list_item, devicesList);

            listView = findViewById(R.id.listView);
            listView.setAdapter(adapter);

                if (!devicesList.contains(result.getDevice())) {
                    Log.d(TAG, "Found new device: " + result.getDevice().getName() + " (" + result.getDevice().getAddress() + ")");
                    devicesList.add(result.getDevice());

                    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                        @Override
                        public void onItemClick(AdapterView<?> parent, View v, final int position, long id) {

                            scanner.stopScan(bleScanCallback);
                            android.app.AlertDialog.Builder mBuilder = new android.app.AlertDialog.Builder(MainActivity.this);
                            mBuilder.setTitle("Upload .hex file");
                            mBuilder.setMessage("Do you want upload the file on " + devicesList.get(position).getName() + "?")
                                    .setPositiveButton("send", new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int id) {
                                         byte[] inputData = new byte[0];
                                            try {
                                                inputData = getBytes(MainActivity.this, uriFirmware);
                                            } catch (IOException e) {
                                                e.printStackTrace();
                                            }
                                            mBtInterface.write(inputData);
                                        }
                                    })
                                    .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int id) {
                                            onResume();
                                        }
                                    });

                            android.app.AlertDialog mDialog = mBuilder.create();
                            mDialog.show();
                        }
                    });

                }
            }
    };
}

这是BTInterface类:

public class BTInterface {

    ProgressDialog mProgressDialog;
    private ConnectedThread mConnectedThread;

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            Log.d(TAG, "ConnectedThread: Starting.");

            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try{
                mProgressDialog.dismiss();
            }catch (NullPointerException e){
                e.printStackTrace();
            }


            try {
                tmpIn = mmSocket.getInputStream();
                tmpOut = mmSocket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run(){
            byte[] buffer = new byte[1024];  
            int bytes;

            while (true) {
                try {
                    bytes = mmInStream.read(buffer);
                    String incomingMessage = new String(buffer, 0, bytes);
                    Log.d(TAG, "InputStream: " + incomingMessage);
                } catch (IOException e) {
                    Log.e(TAG, "write: Error reading Input Stream. " + e.getMessage() );
                    break;
                }
            }
        }

        public void write(byte[] bytes) {
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) {
                Log.e(TAG, "write: Error writing to output stream. " + e.getMessage() );
            }
        }

        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }

    private void connected(BluetoothSocket mmSocket, BluetoothDevice mmDevice) {
        Log.d(TAG, "connected: Starting.");

        mConnectedThread = new ConnectedThread(mmSocket);
        mConnectedThread.start();
    }

    public void write(byte[] out) {
        ConnectedThread r;
        Log.d(TAG, "write: Write Called.");
        mConnectedThread.write(out);
    }

}

当我单击“发送”时,应用崩溃,并显示以下错误:

Attempt to invoke virtual method 'void com.example.safectoryfu.helper.BTInterface$ConnectedThread.write(byte[])' on a null object reference

0 个答案:

没有答案