我已经实现了一个能够检测BLE信号并在ListView中显示它们的代码(在List的每个项目中它将显示名称,地址和rssi)但是当我尝试将其保存到xml文件中时,它会发生错误并停止应用程序。这是代码:
package com.example.newblescan;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import com.example.newblescan.R;
import android.app.Activity;
import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
import com.example.newblescan.adapter.BleDevicesAdapter;
/**
* Activity for scanning and displaying available Bluetooth LE devices.
*/
public class DeviceScanActivity extends ListActivity {
private static final int REQUEST_ENABLE_BT = 1;
private static final long SCAN_PERIOD = 500;
private BleDevicesAdapter leDeviceListAdapter;
private BluetoothAdapter bluetoothAdapter;
private Scanner scanner;
private Save save;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setTitle(R.string.title_devices);
// Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (bluetoothAdapter == null) {
Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.gatt_scan, menu);
if (scanner == null || !scanner.isScanning()) {
menu.findItem(R.id.menu_stop).setVisible(false);
menu.findItem(R.id.menu_scan).setVisible(true);
menu.findItem(R.id.menu_refresh).setActionView(null);
} else {
menu.findItem(R.id.menu_stop).setVisible(true);
menu.findItem(R.id.menu_scan).setVisible(false);
menu.findItem(R.id.menu_refresh).setActionView(
R.layout.actionbar_indeterminate_progress);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_scan:
leDeviceListAdapter.clear();
if (scanner == null) {
scanner = new Scanner(bluetoothAdapter, mLeScanCallback);
scanner.startScanning();
invalidateOptionsMenu();
}
break;
case R.id.menu_stop:
if (scanner != null) {
save = new Save(leDeviceListAdapter);
scanner.stopScanning();
try {
save.savedata();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
scanner = null;
invalidateOptionsMenu();
}
break;
}
return true;
}
@Override
protected void onResume() {
super.onResume();
// Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
// fire an intent to display a dialog asking the user to grant permission to enable it.
if (!bluetoothAdapter.isEnabled()) {
final Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
return;
}
init();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// User chose not to enable Bluetooth.
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == Activity.RESULT_CANCELED) {
finish();
} else {
init();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onPause() {
super.onPause();
if (scanner != null) {
scanner.stopScanning();
scanner = null;
}
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final BluetoothDevice device = leDeviceListAdapter.getDevice(position);
if (device == null)
return;
//final Intent intent = new Intent(this, DeviceServicesActivity.class);
//intent.putExtra(DeviceServicesActivity.EXTRAS_DEVICE_NAME, device.getName());
//intent.putExtra(DeviceServicesActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress());
//startActivity(intent);
}
private void init() {
if (leDeviceListAdapter == null) {
leDeviceListAdapter = new BleDevicesAdapter(getBaseContext());
setListAdapter(leDeviceListAdapter);
}
if (scanner == null) {
scanner = new Scanner(bluetoothAdapter, mLeScanCallback);
scanner.startScanning();
}
invalidateOptionsMenu();
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
leDeviceListAdapter.addDevice(device, rssi);
leDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
private static class Scanner extends Thread {
private final BluetoothAdapter bluetoothAdapter;
private final BluetoothAdapter.LeScanCallback mLeScanCallback;
private volatile boolean isScanning = false;
Scanner(BluetoothAdapter adapter, BluetoothAdapter.LeScanCallback callback) {
bluetoothAdapter = adapter;
mLeScanCallback = callback;
}
public boolean isScanning() {
return isScanning;
}
public void startScanning() {
synchronized (this) {
isScanning = true;
start();
}
}
public void stopScanning() {
synchronized (this) {
isScanning = false;
bluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
@Override
public void run() {
try {
while (true) {
synchronized (this) {
if (!isScanning)
break;
bluetoothAdapter.startLeScan(mLeScanCallback);
}
sleep(SCAN_PERIOD);
synchronized (this) {
bluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
} catch (InterruptedException ignore) {
} finally {
bluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
}
public class Save implements Serializable {
/**
*
*/
private BleDevicesAdapter leDeviceListAdapter;
private static final long serialVersionUID = 1L;
Save(BleDevicesAdapter BLEList) {
leDeviceListAdapter = BLEList;
}
public void savedata() throws FileNotFoundException{
String filename = "file.txt";
FileOutputStream fos = null;
//Bundle extras = getIntent().getExtras();
//long timestamp = extras.getLong("currentTime");
try {
fos= openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
//out.write((int) timestamp);
out.writeObject(leDeviceListAdapter);
out.close();
Toast.makeText(DeviceScanActivity.this, R.string.list_saved, Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
在这里我希望当我按下按钮时,在R.id.menu_stop的情况下,它调用类Save来将List保存到xml文件中。这是我执行应用程序时的Logcat:
NEW LOGCAT !!!!!:
03-10 10:33:02.426: D/BluetoothAdapter(21891): startLeScan(): null
03-10 10:33:02.431: D/BluetoothAdapter(21891): onClientRegistered() - status=0 clientIf=4
03-10 10:33:02.441: D/AbsListView(21891): unregisterIRListener() is called
03-10 10:33:02.466: D/AbsListView(21891): unregisterIRListener() is called
03-10 10:33:02.486: D/BluetoothAdapter(21891): stopLeScan()
03-10 10:33:02.521: W/System.err(21891): java.io.NotSerializableException: com.example.newblescan.adapter.BleDevicesAdapter
03-10 10:33:02.521: W/System.err(21891): at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1364)
03-10 10:33:02.521: W/System.err(21891): at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
03-10 10:33:02.521: W/System.err(21891): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
03-10 10:33:02.521: W/System.err(21891): at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
03-10 10:33:02.521: W/System.err(21891): at com.example.newblescan.DeviceScanActivity$Save.savedata(DeviceScanActivity.java:295)
03-10 10:33:02.521: W/System.err(21891): at com.example.newblescan.DeviceScanActivity.onOptionsItemSelected(DeviceScanActivity.java:116)
03-10 10:33:02.521: W/System.err(21891): at android.app.Activity.onMenuItemSelected(Activity.java:2640)
03-10 10:33:02.521: W/System.err(21891): at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:1171)
03-10 10:33:02.521: W/System.err(21891): at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
03-10 10:33:02.521: W/System.err(21891): at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
03-10 10:33:02.526: W/System.err(21891): at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
03-10 10:33:02.526: W/System.err(21891): at com.android.internal.view.menu.ActionMenuView.invokeItem(ActionMenuView.java:630)
03-10 10:33:02.526: W/System.err(21891): at com.android.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:200)
03-10 10:33:02.526: W/System.err(21891): at android.view.View.performClick(View.java:4475)
03-10 10:33:02.526: W/System.err(21891): at android.view.View$PerformClick.run(View.java:18786)
03-10 10:33:02.526: W/System.err(21891): at android.os.Handler.handleCallback(Handler.java:730)
03-10 10:33:02.526: W/System.err(21891): at android.os.Handler.dispatchMessage(Handler.java:92)
03-10 10:33:02.526: W/System.err(21891): at android.os.Looper.loop(Looper.java:137)
03-10 10:33:02.526: W/System.err(21891): at android.app.ActivityThread.main(ActivityThread.java:5493)
03-10 10:33:02.526: W/System.err(21891): at java.lang.reflect.Method.invokeNative(Native Method)
03-10 10:33:02.526: W/System.err(21891): at java.lang.reflect.Method.invoke(Method.java:525)
03-10 10:33:02.526: W/System.err(21891): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
03-10 10:33:02.526: W/System.err(21891): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
03-10 10:33:02.531: W/System.err(21891): at dalvik.system.NativeStart.main(Native Method)
03-10 10:33:02.931: D/BluetoothAdapter(21891): stopLeScan()
03-10 10:33:02.931: D/BluetoothAdapter(21891): stopLeScan()
03-10 10:33:07.701: D/AbsListView(21891): unregisterIRListener() is called
03-10 10:33:07.911: D/AbsListView(21891): onDetachedFromWindow
任何人都可以解决错误或将此代码更正为可能缺少的代码吗?请帮助!!!!!!!
更新:现在当我按下按钮停止扫描时,它完全停止,但我不知道它为什么不保存甚至创建xml文件。此外,它不会因为知道它已被保存而出现。我更新了上面的代码和logcat。任何人都可以解决这个新问题吗?? !!!!!!
答案 0 :(得分:0)
您在savedata方法中的第290行有一个空引用。我无法看到您的行号,但在您尝试使用之前,请尝试检查您的getExtras()
是否实际返回了某些内容。
另请查看:stackoverflow.com/questions/6065258/how-to-interpret-logcat
答案 1 :(得分:0)
在savedata()
Toast.makeText(null, R.string.list_saved, Toast.LENGTH_SHORT).show();
在上下文中传递null! ?
那应该是,
Toast.makeText(DeviceScanActivity.this, R.string.list_saved, Toast.LENGTH_SHORT).show();
此外,请初始化FileOutputStream
变量,
FileOutputStream fos = null;
而不是
FileOutputStream fos;