我对Android开发很陌生。我目前正在尝试编写一个简单的 Android 应用程序来将字符串发送到用 Python 编写的服务器。代码主要来自此站点:示例以及 Android开发人员站点作为参考。请注意,我选择了这个示例,以便在添加更多内容之前,我可以主要在单个活动中使用蓝牙 API。一开始,我发现 BluetoothChat 示例对我来说有点压倒性。
每当应用程序在未启用蓝牙的情况下运行时,会出现请求启用蓝牙的对话框,但应用程序崩溃了。为什么?我已经完成了有关活动生命周期的课程,我认为当 startActivityForResult() 完成时,焦点应该返回到我的应用程序而不会崩溃 - 回到 onResume()?。我有我的主要活动如下:
package com.example.connecttest;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
import com.example.connecttest.R;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
public class ConnectTest extends Activity {
TextView intro;
TextView out;
private static final int REQUEST_ENABLE_BT = 1;
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
//This is the well known UUID for SPP of general Bluetooth adapter.
private static String address = "00:1F:81:00:08:30";
//my bluetooth dongle MAC address
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
intro = (TextView) findViewById(R.id.intro);
intro.append("\nThis App send a string to a server over Bluetooth SPP module");
out = (TextView) findViewById(R.id.out);
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
btAdapter = BluetoothAdapter.getDefaultAdapter();
if(btAdapter==null) {
AlertBox("Fatal Error", "Bluetooth Not supported. Aborting.");
} else {
if (btAdapter.isEnabled()) {
Toast.makeText(getApplicationContext(), "Bluetooth is enabled", Toast.LENGTH_SHORT).show();
} else {
//Prompt user to turn on Bluetooth
Intent enableBtIntent = new Intent(btAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
BluetoothDevice device = btAdapter.getRemoteDevice(address);
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
AlertBox("Fatal Error", "Failed to create socket" + e.getMessage() + ".");
}
btAdapter.cancelDiscovery();
try {
btSocket.connect();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
AlertBox("Fatal Error", "Unable to close socket during connection failure" + e2.getMessage() + ".");
}
}
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
AlertBox("Fatal Error", "Output stream creation failed:" + e.getMessage() + ".");
}
String message = "This is a string sent from Android\n";
byte[] msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
Toast.makeText(getApplicationContext(), "Done! Message is successfully transferred!", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
String msg = "Please ensure the Server is up and listening for incoming connection\n\n";
AlertBox("Server Error", msg);
}
}
@Override
public void onPause() {
super.onPause();
if (outStream != null) {
try {
outStream.flush();
} catch (IOException e) {
AlertBox("Fatal Error", "Failed to flush output stream: " + e.getMessage() + ".");
}
}
try {
btSocket.close();
} catch (IOException e2) {
AlertBox("Fatal Error", "Failed to close socket." + e2.getMessage() + ".");
}
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
}
//Alert box methods for all error messages
public void AlertBox( String title, String message ){
new AlertDialog.Builder(this)
.setTitle( title )
.setMessage( message + " Press OK to exit." )
.setPositiveButton("OK", new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
finish();
}
}).show();
}
}
我的日志猫:
W/dalvikvm(29753): threadid=1: thread exiting with uncaught exception (group=0x40d49258)
E/AndroidRuntime(29753): FATAL EXCEPTION: main
E/AndroidRuntime(29753): java.lang.RuntimeException: Unable to resume activity {com.example.connecttest/com.example.connecttest.ConnectTest}: java.lang.NullPointerException
E/AndroidRuntime(29753): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2595)
E/AndroidRuntime(29753): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2623)
E/AndroidRuntime(29753): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2109)
E/AndroidRuntime(29753): at android.app.ActivityThread.access$600(ActivityThread.java:134)
E/AndroidRuntime(29753): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
E/AndroidRuntime(29753): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(29753): at android.os.Looper.loop(Looper.java:154)
E/AndroidRuntime(29753): at android.app.ActivityThread.main(ActivityThread.java:4624)
E/AndroidRuntime(29753): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(29753): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(29753): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
E/AndroidRuntime(29753): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
E/AndroidRuntime(29753): at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:106)
E/AndroidRuntime(29753): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(29753): Caused by: java.lang.NullPointerException
E/AndroidRuntime(29753): at com.example.connecttest.ConnectTest.onResume(ConnectTest.java:91)
E/AndroidRuntime(29753): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1159)
E/AndroidRuntime(29753): at android.app.Activity.performResume(Activity.java:4553)
E/AndroidRuntime(29753): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2581)
正如@codeMagic 所建议的那样,我在 startActivityForResult() 之后将 OnResume() 中的所有内容删除到一个新方法 OnActivityResult(),但同样的问题仍然存在。这是新的 logcat 日志。
07-30 03:39:44.129: D/dalvikvm(2022): threadid=10: interp stack at 0x50c0f000
07-30 03:39:44.155: D/jdwp(2022): sendBufferedRequest : len=0x45
07-30 03:39:44.171: D/ActivityThread(2022): BIND_APPLICATION handled : 0 / AppBindData{appInfo=ApplicationInfo{416753a0 com.example.connecttest}}
07-30 03:39:44.174: D/WindowManager(2022): create CompatModeWrapper appName:com.example.connecttest/com.example.connecttest.ConnectTest
07-30 03:39:44.238: D/ActivityThread(2022): ACT-AM_ON_RESUME_CALLED ActivityRecord{416768d0 token=android.os.BinderProxy@41676098 {com.example.connecttest/com.example.connecttest.ConnectTest}}
07-30 03:39:44.245: D/ActivityThread(2022): ACT-LAUNCH_ACTIVITY handled : 0 / ActivityRecord{416768d0 token=android.os.BinderProxy@41676098 {com.example.connecttest/com.example.connecttest.ConnectTest}}
07-30 03:39:44.246: D/AndroidRuntime(2022): Shutting down VM
07-30 03:39:44.246: W/dalvikvm(2022): threadid=1: thread exiting with uncaught exception (group=0x40d63258)
07-30 03:39:44.248: E/AndroidRuntime(2022): FATAL EXCEPTION: main
07-30 03:39:44.248: E/AndroidRuntime(2022): java.lang.RuntimeException: Unable to pause activity {com.example.connecttest/com.example.connecttest.ConnectTest}: java.lang.NullPointerException
07-30 03:39:44.248: E/AndroidRuntime(2022): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2861)
07-30 03:39:44.248: E/AndroidRuntime(2022): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2813)
07-30 03:39:44.248: E/AndroidRuntime(2022): at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2791)
07-30 03:39:44.248: E/AndroidRuntime(2022): at android.app.ActivityThread.access$800(ActivityThread.java:134)
07-30 03:39:44.248: E/AndroidRuntime(2022): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1254)
07-30 03:39:44.248: E/AndroidRuntime(2022): at android.os.Handler.dispatchMessage(Handler.java:99)
07-30 03:39:44.248: E/AndroidRuntime(2022): at android.os.Looper.loop(Looper.java:154)
07-30 03:39:44.248: E/AndroidRuntime(2022): at android.app.ActivityThread.main(ActivityThread.java:4624)
07-30 03:39:44.248: E/AndroidRuntime(2022): at java.lang.reflect.Method.invokeNative(Native Method)
07-30 03:39:44.248: E/AndroidRuntime(2022): at java.lang.reflect.Method.invoke(Method.java:511)
07-30 03:39:44.248: E/AndroidRuntime(2022): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
07-30 03:39:44.248: E/AndroidRuntime(2022): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
07-30 03:39:44.248: E/AndroidRuntime(2022): at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:106)
07-30 03:39:44.248: E/AndroidRuntime(2022): at dalvik.system.NativeStart.main(Native Method)
07-30 03:39:44.248: E/AndroidRuntime(2022): Caused by: java.lang.NullPointerException
07-30 03:39:44.248: E/AndroidRuntime(2022): at com.example.connecttest.ConnectTest.onPause(ConnectTest.java:139)
07-30 03:39:44.248: E/AndroidRuntime(2022): at android.app.Activity.performPause(Activity.java:4577)
07-30 03:39:44.248: E/AndroidRuntime(2022): at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1201)
07-30 03:39:44.248: E/AndroidRuntime(2022): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2844)