致命异常:主要在蓝牙应用程序然后崩溃

时间:2013-12-22 02:08:47

标签: android xml bluetooth fatal-error

我的蓝牙应用程序已经可以自动请求启用蓝牙,但是当我在选项菜单上执行某些功能时,应用程序将在蓝牙打开后立即崩溃。

这是在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>

1 个答案:

答案 0 :(得分:1)

您永远不会为title分配值,因此当您尝试在title中调用handleMessage上的方法时,您会获得NullPointerException