【问题标题】:Android internal storage not saving fileAndroid内部存储不保存文件
【发布时间】:2014-05-13 14:47:45
【问题描述】:

我有一个主要活动,当按下一个列表项时,它会通过一个意图启动一个新活动。这个新 Activity 的主题是 Dialog(因此看起来第二个 Activity 漂浮在主 Activity 之上)。

在这个新活动中,我在 EditTexts 中输入了一些数据,然后使用该数据创建了一个自定义对象,并尝试将其保存在内部存储中。

它似乎没有创建文件。我真的不明白为什么它不起作用,因为我在其他活动中使用与其他对象相同的结构并且它工​​作正常。这就是让我认为它一定与这个活动的主题是Dialog这一事实有关。自定义对象类显然实现了可序列化,并且我在我的 android 清单中拥有所有权限。可能问题与 我传递的上下文 到保存方法 (getApplicationContext()) 有关。

这是 Dialog 主题的 Activity:

package es.lagoacunado.lagoacunadoconsutores;

import java.io.File;

import utilidades.SeriaPreferencias;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import clases.Preferencia;

public class Preferencias extends Activity {

    EditText ftpDir, ftpUser, ftpPass;
    Button btnGuardar, btnCancelar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.preferencias);

        this.setFinishOnTouchOutside(false);

        ftpDir = (EditText) findViewById(R.id.ftpDIR);
        ftpUser = (EditText) findViewById(R.id.ftpUSER);
        ftpPass = (EditText) findViewById(R.id.ftpPASS);
        btnGuardar = (Button) findViewById(R.id.btnGuardar);
        btnCancelar = (Button) findViewById(R.id.btnCancelar);

        File filePref = new File("preferencias.dat");
        if (filePref.exists()) {
            /*
             * ftpDir.setText(SeriaPreferencias.cargarPreferencias(
             * getApplicationContext()).getDirFTP());
             * ftpUser.setText(SeriaPreferencias.cargarPreferencias(
             * getApplicationContext()).getUsrFTP());
             * ftpPass.setText(SeriaPreferencias.cargarPreferencias(
             * getApplicationContext()).getPssFTP());
             */
            Preferencia loadPref = SeriaPreferencias
                    .cargarPreferencias(getApplicationContext());
            ftpDir.setText(loadPref.getDirFTP());
            ftpUser.setText(loadPref.getUsrFTP());
            ftpPass.setText(loadPref.getPssFTP());
        }

        btnGuardar.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                String dir, usr, pss;
                dir = ftpDir.getText().toString();
                usr = ftpUser.getText().toString();
                pss = ftpPass.getText().toString();

                //Log.d("PRUEBA Guardar Preferencias", "dir= "+dir+" -- user= "+usr+" -- pss= "+pss);

                Preferencia pref = new Preferencia(dir, usr, pss);
                // METHOD THAT SAVES THE OBJECT pref
                SeriaPreferencias.guardarPreferencias(getApplicationContext(),
                        pref);

                File prueba = new File("preferencias.dat");
                if(prueba.exists()){
                    Log.d("-->PRUEBA", "EL ARCHIVO EXISTE");
                }

                finish();
            }
        });

        btnCancelar.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

}

这是具有保存和加载方法的类:

package utilidades;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import android.content.Context;
import android.util.Log;
import clases.Preferencia;

public class SeriaPreferencias {

    private static String FICHERO = "preferencias.dat";

    public static void guardarPreferencias(Context context, Preferencia prefs) {

        try {
            FileOutputStream fos = context.openFileOutput(FICHERO,
                    Context.MODE_PRIVATE);
            ObjectOutputStream oos = new ObjectOutputStream(fos);

            oos.writeObject(prefs);

            oos.close();
            fos.close();

        } catch (Exception e) {
            Log.e("MiCV", e.getMessage(), e);
        }
    }

    public static Preferencia cargarPreferencias(Context context) {
        Preferencia prefs = null;

        try {

            FileInputStream fis = context.openFileInput(FICHERO);
            ObjectInputStream ois = new ObjectInputStream(fis);

            prefs = (Preferencia) ois.readObject();

            ois.close();
            fis.close();

        } catch (Exception e) {
            Log.e("MiCV", e.getMessage(), e);
        }

        return prefs;
    }

}

这是自定义对象类:

package clases;

import java.io.Serializable;

public class Preferencia implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private String dirFTP, usrFTP, pssFTP;

    public Preferencia() {

    }

    public Preferencia(String dirFTP, String usrFTP, String pssFTP) {
        this.dirFTP = dirFTP;
        this.usrFTP = usrFTP;
        this.pssFTP = pssFTP;
    }

    public String getDirFTP() {
        return dirFTP;
    }

    public void setDirFTP(String dirFTP) {
        this.dirFTP = dirFTP;
    }

    public String getUsrFTP() {
        return usrFTP;
    }

    public void setUsrFTP(String usrFTP) {
        this.usrFTP = usrFTP;
    }

    public String getPssFTP() {
        return pssFTP;
    }

    public void setPssFTP(String pssFTP) {
        this.pssFTP = pssFTP;
    }

}

【问题讨论】:

  • 你如何确定文件没有被保存?如果您在日志中看到任何内容怎么办?你的catch块有什么吗?如何在尝试保存时添加提供部分进度报告的消息,告诉您文件的创建位置等等。
  • 因为我在保存方法后面有这个IF语句,如果文件存在它必须显示一个log.d确认它。File prueba = new File("preferencias.dat"); if(prueba.exists()){ Log.d("-->PRUEBA", "EL ARCHIVO EXISTE"); }
  • 问题一定出在保存方法SeriaPreferencias.guardarPreferencias(getApplicationContext(), pref);,或者在我传递给这个方法的上下文中。

标签: android android-context internal-storage


【解决方案1】:
 File filePref = new File("preferencias.dat");

仅指定文件名而不指定目录将引用当前工作目录中的文件 - 但这很可能是文件系统根目录,它不仅是一个不合适的位置,而且您的应用程序不可写。

当您使用 Context.openFileOuput(filename) 打开或创建 FileOutputStream 时,文件名指的是您应用内部存储的私有目录中的位置。

要在应用程序的私有存储区域中创建指向同一文件的文件对象,在 Activity 类或其他有效上下文中,在其 onCreate() 方法期间或之后,您可以使用:

File filePref = new File(getFilesDir(), "preferencias.dat");

因为 Context.getFilesDir() 引用的私有文件夹位置与 Context.openFileOutput() 使用的相同。

【讨论】:

  • 我没有使用 File() 构造函数来创建文件。该文件由SeriaPreferencias.guardarPreferencias() 创建。我正在使用文件构造函数来检查文件是否存在。我不同意你回答的第二部分。正如我在我的问题中所说,我已经使用相同的结构将文件保存在内部存储中并且它可以工作,所以再一次,问题必须是我传递的上下文,因为 Dialog 是为此活动设置的主题。
  • 如果您的上下文无效,您应该会看到来自日志语句的消息或来自系统异常处理程序的消息。不,你没有在你的保存方法之后运行存在检查 - 你在你的活动的 onCreate() 中调用它。此外,需要解决无法为用于存在性检查的 File() 构造函数提供有效路径的问题。
  • 不,onCreate() 中的一项是检查文件是否已经存在,如果存在,则将文件中包含的数据加载到 EditTexts 中。如果你继续阅读代码,你会看到一个 OnClickListener,它就是我调用保存方法的地方。
  • 您仍然在使用无效路径的 File() 构造函数。
  • 为什么是-1?我没有滥用 file() 构造函数,因为我告诉你它在其他类似的情况下也有效,并且这种情况与其他情况之间的唯一区别是 Dialog 主题。
猜你喜欢
  • 2023-03-10
  • 2011-10-10
  • 2012-10-21
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多