在 Android 中保存 xml 文件的问题

Posted

技术标签:

【中文标题】在 Android 中保存 xml 文件的问题【英文标题】:Problems saving a xml file in Android 【发布时间】:2014-03-10 17:49:23 【问题描述】:

我正在尝试使用 Xmlserializer 将数组列表保存到内部存储中的 xml 文件中。该应用程序扫描 BLE,当按下停止按钮时,它应该从它检测到的 BLE 列表中保存一些参数。它运行完美,当我按下停止按钮时,它会停止扫描并在移动屏幕上显示一条 xml 文件已成功创建的 toast 消息。但是,当我搜索 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 org.xmlpull.v1.XmlSerializer;

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.text.format.DateFormat;
import android.util.Xml;
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 = 100;

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    

  /**
 * 
 */

private BleDevicesAdapter leDeviceListAdapter;

Save(BleDevicesAdapter BLEList) 

    leDeviceListAdapter = BLEList;



public void savedata() throws FileNotFoundException

    String filename = "Dragon.txt";
    //String date = (DateFormat.format("dd-MM-yyyy hh:mm:ss", new java.util.Date()).toString());


    FileOutputStream fos = null;
    int size = leDeviceListAdapter.getCount(); 
    //Bundle extras = getIntent().getExtras();
    //long timestamp = extras.getLong("currentTime");
    try 
    fos= openFileOutput(filename, Context.MODE_PRIVATE);
    XmlSerializer serializer = Xml.newSerializer();
    serializer.setOutput(fos, "UTF-8");
    serializer.startDocument(null, Boolean.valueOf(true));
    serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);

    serializer.startTag("", "root");
    //serializer.startTag("", "timestamp");
    //serializer.text(date);
    //serializer.endTag("", "timestamp");

    for(int j = 0 ; j < size ; j++)
    
        BluetoothDevice devices = leDeviceListAdapter.getDevice(j);
        //Integer signal = leDeviceListAdapter.getRSSI(j);
        serializer.startTag("", "name");
        serializer.text(devices.getName());
        serializer.endTag("", "name");

        serializer.startTag("", "address");
        serializer.text(devices.getAddress());
        serializer.endTag("", "address");

        //serializer.startTag(null, "rssi");
        //serializer.setProperty(null, signal);
        //serializer.endTag(null, "rssi");
    
    //ObjectOutputStream out = new ObjectOutputStream(fos);
    //out.write((int) timestamp);
    //out.writeObject(leDeviceListAdapter);
    //out.close();
    serializer.endDocument();
    serializer.flush();
    fos.close();
    Toast.makeText(DeviceScanActivity.this, R.string.list_saved, Toast.LENGTH_SHORT).show();
     catch (FileNotFoundException e)
        e.printStackTrace();
     catch (IOException e)
        e.printStackTrace();
    

  
 


在 Save 类中,我实现了 savedata 方法将列表保存到 xml 文件中。

有谁知道问题出在哪里?请帮忙!!!!

【问题讨论】:

【参考方案1】:

openFileOutput 将它放在 /data/data/your_packagename/files 目录中。此目录只能由 root 和您的应用程序读取 - 如果没有 root 设备,您将无法在任何其他程序中找到该文件。除非您具有 root 访问权限,否则您将无法在文件资源管理器中找到它。如果您希望能够看到该文件,则需要将其写入世界可访问的位置,例如 sd 卡。

【讨论】:

以及我如何才能成为可访问的文件世界,或者如您所说,在 sd 卡中?? 不要使用 openFileOutput。使用 Environment.getExternalStorageDirectory() 获取 sd 卡目录,并写入其中的文件。

以上是关于在 Android 中保存 xml 文件的问题的主要内容,如果未能解决你的问题,请参考以下文章

Java / Android - 读取、操作 XML 文件并将其保存到内部存储

将 XML 文件保存到正在运行的 Android 项目

麻烦请问一下,android如何修改xml文件中节点的值,并保存进去,谢谢

android 怎么读取在androidmanifest.xml中配置xml文件

如何将xml文件保存在我想要的目录中(android studio)[关闭]

xml 属性 singleLine 在 Android 中是不是已弃用?