我正在开发一个简单的应用程序,主要是通过蓝牙发送数据。
我的主要活动:
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[] { "[email protected]" });
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.send("test");
行NullPointerException
崩溃了,我看不出原因。我是Android上的蓝牙初学者;帮助将不胜感激。
我希望我能得到的最终结果是简单地连接到设备并发送数据,甚至没有发生。
编辑:我现在也面临另一个问题。我通过意图将String地址从第一个活动(https://gist.github.com/shlokj/12c4e2c62ca0f5284c5c3c041775654f)传递给第二个活动(https://gist.github.com/shlokj/f80d0902ad1a366ab03e178164968cfb)。在那里,我尝试在第163行(bluetoothObject.connectToAddress(address);
)连接,并且它与NullPointerException崩溃。我不知道为什么,因为我用address
语句检查蓝牙对象和if
不为空。堆栈跟踪:https://gist.github.com/shlokj/56e3c9e311dea6f77a1acd8953a317c8整个存储库:https://github.com/shlokj/JR-Bluetooth-Control。因此,简而言之,我现在需要能够正确连接,不要单独发送数据。
我刚刚浏览了您提供的图书馆链接,似乎有人遇到了类似的问题:
https://github.com/OmarAflak/Bluetooth-Library/issues/16
事实证明连接尚未建立,所以在调用send之前,请检查设备是否通过使用isConnected()
功能连接。
在正确建立连接之前,您不应该调用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();