【问题标题】:Error Saving a List in a xml File in Android在 Android 中将列表保存在 xml 文件中时出错
【发布时间】:2014-03-10 10:04:11
【问题描述】:

我已经实现了一个能够检测 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 将列表保存到 xml 文件中。这是我执行应用程序时的 Logcat:

新的 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。谁能解决这个新问题??!!!!!!

【问题讨论】:

    标签: android xml list file


    【解决方案1】:

    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;
    

    【讨论】:

    • 我已经更改了您告诉我的代码,但它不会创建或保存文件。我现在更新了新的 Logcat。你能告诉我现在有什么问题吗?
    • 请提出完全不同的新问题作为新问题,而不是编辑当前问题
    【解决方案2】:

    您的 savedata 方法中的第 290 行有一个空引用。我看不到您的行号,但请在您尝试使用之前检查您的 getExtras() 是否确实返回了某些内容。

    另请查看:stackoverflow.com/questions/6065258/how-to-interpret-logcat

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多