我的蓝牙应用程序已经可以自动请求启用蓝牙,但是当我在选项菜单上执行某些功能时,应用程序将在蓝牙打开后立即崩溃。
这是在LogCat中找到的消息:
12-21 15:20:08.531: D/BluetoothCommandService(1203): start
12-21 15:20:08.531: D/BluetoothCommandService(1203): setState() 0 -> 1
12-21 15:20:08.581: W/dalvikvm(1203): threadid=1: thread exiting with uncaught exception (group=0x40028870)
12-21 15:20:08.851: E/AndroidRuntime(1203): FATAL EXCEPTION: main
12-21 15:20:08.851: E/AndroidRuntime(1203): java.lang.NullPointerException
12-21 15:20:08.851: E/AndroidRuntime(1203): at com.example.javac101.MainActivity$1.handleMessage(MainActivity.java:171)
12-21 15:20:08.851: E/AndroidRuntime(1203): at android.os.Handler.dispatchMessage(Handler.java:95)
12-21 15:20:08.851: E/AndroidRuntime(1203): at android.os.Looper.loop(Looper.java:123)
12-21 15:20:08.851: E/AndroidRuntime(1203): at android.app.ActivityThread.main(ActivityThread.java:4627)
12-21 15:20:08.851: E/AndroidRuntime(1203): at java.lang.reflect.Method.invokeNative(Native Method)
12-21 15:20:08.851: E/AndroidRuntime(1203): at java.lang.reflect.Method.invoke(Method.java:521)
12-21 15:20:08.851: E/AndroidRuntime(1203): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
12-21 15:20:08.851: E/AndroidRuntime(1203): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
12-21 15:20:08.851: E/AndroidRuntime(1203): at dalvik.system.NativeStart.main(Native Method)
虽然这是我在MainActivity中的代码:
package com.example.javac101;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.KeyEvent;
import android.widget.Toast;
import android.widget.TextView;
//public class MainActivity extends Activity {
public class MainActivity extends Activity implements OnClickListener {
//BLUETOOTH
BluetoothAdapter BTAdapter;
BluetoothDevice BTDevice;
//Layout view daw
private TextView title;
//Intent
private static final int REQUEST_DEVICE_CONNECT = 1;
private static final int REQUEST_ENABLE_BLUETOOTH = 2;
//object for bluetooth command service
private BluetoothCommandService commandService = null;
//
private String connectedDeviceName = null;
//Message types sent from the Handler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
//Will be used in BluetoothCommandSrvice jave file
public static final String TOAST = "toast";
public static final String DEVICENAME = "device name";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Button openButton = (Button)findViewById(R.id.open);
BTAdapter = BluetoothAdapter.getDefaultAdapter();
//A code that will detect if BT is enabled otherwise will require it.
if (BTAdapter == null)
{
//Toast.makeText(context, text, duration)
Toast.makeText(this, "No Bluetooth adapter is available.", Toast.LENGTH_LONG).show();
finish();
return;
}
}
@Override
protected void onStart() {
super.onStart();
//Requesting Bluetooth automatically when its not yet enabled.
if (!BTAdapter.isEnabled())
{
Intent enableIntent = new Intent (BluetoothAdapter.ACTION_REQUEST_ENABLE);
//startActivityForResult(enableIntent, 0);
startActivityForResult(enableIntent, REQUEST_ENABLE_BLUETOOTH);
}
else
{
if (commandService == null)
setupCommand();
}
}
//Will automatically enable and request to be discoverable for 500 sec.gi comment since dili pa sure kung needed pa ba nga ma discoverable
//if (BTAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE)
//{
//Intent discoverableIntent = new Intent (BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
//discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 500);
//startActivity(discoverableIntent);
//}
@Override
protected void onResume() {
super.onResume();
if (commandService != null)
{
if (commandService.getState() == BluetoothCommandService.stateNothing)
{
commandService.start();
}
}
}
private void setupCommand()
{
commandService = new BluetoothCommandService(this, bluetoothHandler);
}
@Override
protected void onDestroy()
{
super.onDestroy();
if (commandService != null)
commandService.stop();
}
private void ensureDiscoverable()
{
//Get the current Bluetooth scan mode of the local Bluetooth adapter. The Bluetooth scan mode determines if the local adapter is connectable and/or discoverable from remote Bluetooth devices.
if (BTAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE)
{
Intent ensureDiscoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
ensureDiscoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(ensureDiscoverableIntent);
}
}
//This gets information back from the "BluetoothChatService"/"BluetoothCommandService"
//@SuppressLint("HandlerLeak")
private final Handler bluetoothHandler = new Handler(new Handler.Callback()
// @Override
// public boolean handleMessage(Message arg0) {
// TODO Auto-generated method stub
// return false;
// }
// })
{
@Override
//public void handleMessage(Message msg)
public boolean handleMessage(Message msg)
{
switch (msg.what)
{
case MESSAGE_STATE_CHANGE:
switch (msg.arg1)
{
case BluetoothCommandService.stateConnected:
title.setText(R.string.title_connectedTo);
title.append(connectedDeviceName);
break;
case BluetoothCommandService.stateConnecting:
title.setText(R.string.title_connecting);
break;
case BluetoothCommandService.stateListen:
case BluetoothCommandService.stateNothing:
title.setText(getString(R.string.title_notConnected));
break;
}
break;
case MESSAGE_DEVICE_NAME:
connectedDeviceName = msg.getData().getString(DEVICENAME);
Toast.makeText(getApplicationContext(), "Connected to " + connectedDeviceName, Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), Toast.LENGTH_SHORT).show();
break;
}
return false;
}
//};
});
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_DEVICE_CONNECT:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
String address = data.getExtras()
.getString(DeviceList.EXTRA_DEVICE_MAC_ADDRESS);
// Get the BLuetoothDevice object
BluetoothDevice device = BTAdapter.getRemoteDevice(address);
// Attempt to connect to the device
commandService.connect(device);
}
break;
case REQUEST_ENABLE_BLUETOOTH:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a chat session
setupCommand();
} else {
// User did not enable Bluetooth or an error occured
Toast.makeText(this, R.string.notEnabledBluetooth, Toast.LENGTH_SHORT).show();
finish();
}
}
}
@Override
//Creating an Option Menu for connectivity and discoverability of a BT device
public boolean onCreateOptionsMenu(Menu menu)
{
//MenuInflater is a class
MenuInflater OptionMenu = getMenuInflater();
//OptionMenu.inflate(menuRes, menu)
OptionMenu.inflate(R.menu.main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.connect:
Intent serverIntent = new Intent(this, DeviceList.class);
//startActivityForResult(serverIntent, REQUEST_DEVICE_CONNECT);
this.startActivityForResult(serverIntent, REQUEST_DEVICE_CONNECT);
return true;
case R.id.discoverable:
ensureDiscoverable();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP)
{
commandService.write(BluetoothCommandService.VOL_UP);
return true;
}
else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
{
commandService.write(BluetoothCommandService.VOL_DOWN);
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}
在我的AndroidManifest代码中:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.javac101"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- <uses-permission android:name="android.permission.WRITE_EXTERAL_STORAGE"/> i added this when the UI crash (12/21/13) still doesn't effect -->
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.javac101.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
答案 0 :(得分:1)
您永远不会为title
分配值,因此当您尝试在title
中调用handleMessage
上的方法时,您会获得NullPointerException
。