public class BluetoothActivity extends Activity {
// Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// Whenever a remote Bluetooth device is found
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
adapter.add(bluetoothDevice.getName() + "\n"
+ bluetoothDevice.getAddress());
}
}
};
//declaration
TextView myLabel;
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
volatile boolean stopWorker;
private BluetoothAdapter mBluetoothAdapter;
private ListView listview;
private ArrayAdapter adapter;
private ToggleButton toggleButton;
private static final int REQUEST_ENABLE_BT =0;
private static final int DISCOVERABLE_DURATION = 0;
private static final int DISCOVERABLE_BT_REQUEST_CODE = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluetooth_main);
toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
listview = (ListView) findViewById(R.id.listView);
// ListView Item Click Listener
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// ListView Clicked item value
String itemValue = (String) listview.getItemAtPosition(position);
Toast.makeText(getApplicationContext(), "clicked", Toast.LENGTH_LONG).show();
String MAC = itemValue.substring(itemValue.length() - 17);
BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(MAC);
// Initiate a connection request in a separate thread
ConnectingThread t = new ConnectingThread(bluetoothDevice);
t.start();
}
});
adapter = new ArrayAdapter
(this,android.R.layout.simple_list_item_1);
listview.setAdapter(adapter);
//verify bluetooth is supported on the device
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// Device does not support Bluetooth
if (mBluetoothAdapter == null) {
}
}//end oncreate
public void onToggle(View view) {
adapter.clear();
if (toggleButton.isChecked()){
//enable bluetooth
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
Toast.makeText(getApplicationContext(), "Turned on", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(),"Already on", Toast.LENGTH_LONG).show();
//To discover remote Bluetooth devices
discoverDevices();
// Make local device discoverable by other devices
makeDiscoverable();
}
}//end of 1st if
else{
//turn off bluetooth
mBluetoothAdapter.disable();
adapter.clear();
Toast.makeText(getApplicationContext(),"Turned off" ,Toast.LENGTH_LONG).show();
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
// Bluetooth successfully enabled!
if (resultCode == Activity.RESULT_OK) {
Toast.makeText(getApplicationContext(), "Bluetooth is now enabled.",Toast.LENGTH_SHORT).show();
// Make local device discoverable by other devices
makeDiscoverable();
// To discover remote Bluetooth devices
Log.e("calldiscover", "func");
discoverDevices();
Log.e("Discover", "device");
// Start a thread to create a server socket to listen
// for connection request
Log.e("listenthread", "listenthread");
ListeningThread t = new ListeningThread();
Log.e("call", "t.start");
t.start();
Log.e("t.start", "over");
}
else {
// RESULT_CANCELED as user refused
Toast.makeText(getApplicationContext(), "Bluetooth is not enabled.",
Toast.LENGTH_SHORT).show();
// Turn off togglebutton
toggleButton.setChecked(false);
}
}//end of 1st if
}
protected void discoverDevices(){
// To scan for remote Bluetooth devices
if (mBluetoothAdapter.startDiscovery()) {Log.e("disc", "print");
Toast.makeText(getApplicationContext(), "Discovering other bluetooth devices...", Toast.LENGTH_SHORT).show();
}
else {
Log.e("print", "print");
Toast.makeText(getApplicationContext(), "Discovery failed to start.", Toast.LENGTH_SHORT).show();
}
}
protected void makeDiscoverable(){
// Make local device discoverable
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVERABLE_DURATION);
startActivityForResult(discoverableIntent, DISCOVERABLE_BT_REQUEST_CODE);
}
@Override
protected void onResume() {
super.onResume();
// Register the BroadcastReceiver for ACTION_FOUND
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(broadcastReceiver, filter);
}
@Override
protected void onPause() {
super.onPause();
this.unregisterReceiver(broadcastReceiver);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class ListeningThread extends Thread {
private final BluetoothServerSocket bluetoothServerSocket;
public ListeningThread() {
BluetoothServerSocket temp = null;
try {
temp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(getString(R.string.app_name), uuid);
} catch (IOException e) {
e.printStackTrace();
}
bluetoothServerSocket = temp;
}
public void run() {
BluetoothSocket bluetoothSocket;
// This will block while listening until a BluetoothSocket is returned
// or an exception occurs
while (true) {
try {
Log.e("while", "over");
bluetoothSocket = bluetoothServerSocket.accept();
Log.e("bt", "accept");
} catch (IOException e) {Log.e("error", "catch");
break;
}
// If a connection is accepted
if (bluetoothSocket != null) {
Log.e("connection is accepted", "over");
BluetoothActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(BluetoothActivity.this, "Connected!", Toast.LENGTH_SHORT).show();
}
});
// Manage the connection in a separate thread
try {Log.e("callserver", "close");
bluetoothServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}//end of while
}
// Cancel the listening socket and terminate the thread
public void cancel() {
try {Log.e("cancel", "socket");
bluetoothServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//Setting Up a Connecting Client
private class ConnectingThread extends Thread {
OutputStream mmOutputStream;
InputStream mmInputStream;
private final BluetoothSocket bluetoothSocket;
private final BluetoothDevice bluetoothDevice;
public ConnectingThread(BluetoothDevice device) {
BluetoothSocket temp = null;
bluetoothDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try { Log.e("click6", "click6");
temp = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
e.printStackTrace();
}
bluetoothSocket = temp;
}
public void run() {
// Cancel any discovery as it will slow down the connection
Log.e("click7", "click7");
mBluetoothAdapter.cancelDiscovery();
Log.e("click8", "click8");
try {
// This will block until it succeeds in connecting to the device
// through the bluetoothSocket or throws an exception
bluetoothSocket.connect();
mmOutputStream = bluetoothSocket.getOutputStream();
mmInputStream = bluetoothSocket.getInputStream();
beginListenForData();
Log.e("listendata", "lsitendata");
BluetoothActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(BluetoothActivity.this, "Connected with Device!", Toast.LENGTH_SHORT).show();
}
});
Log.e("click9", "click9");
} catch (IOException connectException) {
connectException.printStackTrace();
try {
bluetoothSocket.close();
Log.e("click6", "blueclose");
} catch (IOException closeException) {
closeException.printStackTrace();
}
}
}
void beginListenForData()
{
final Handler handler = new Handler();
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];//It uses a 1024 bytes long buffer because it doesn't have any way of knowing the length of the input stream.
workerThread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !stopWorker)
{
try
{
int bytesAvailable = mmInputStream.available();
if(bytesAvailable > 0)
{
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++)
{
byte b = packetBytes[i];
if(b == delimiter)
{
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable()
{
public void run()
{
myLabel.setText(data);
}
});
}
else
{
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex)
{
stopWorker = true;
}
}
}
});
workerThread.start();
}
当我尝试调用beginListenForData()时,应用程序崩溃了错误状态,无法在未调用Looper.prepare()
的线程内创建处理程序有谁知道什么是错的?我是android的新手。请帮忙。
下面的Bluetooth.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".BluetoothActivity">
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Turn off Bluetooth"
android:textOff="Turn on Bluetooth"
android:id="@+id/toggleButton"
android:onClick="onToggle"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/listView"
android:layout_alignParentStart="true"
android:layout_marginStart="76dp"
android:layout_below="@+id/toggleButton" />
<TextView
android:id="@+id/label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Type here:"
android:layout_below="@+id/toggleButton"
android:layout_centerHorizontal="true"
android:layout_marginTop="66dp" />
</RelativeLayout>
答案 0 :(得分:0)
在 beginListenForData()
中尝试此操作替换
final Handler handler = new Handler();
有了这个
final Handler handler = new Handler(Looper.getMainLooper());