3

I need to store this object into the internal storage memory of the phone, and i have the <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"></uses-permission> set on the manifest. The object itself haves two static methods for store and reload it from the internal memory:

public class SaveState implements Serializable {
static public List<FullMagazine> fms = new ArrayList<FullMagazine>();
static SaveState instance=null;

public static SaveState getInstance(){      
    if( instance == null )
        instance = new SaveState();     
    return instance;
}

public static void saveData(SaveState instance){
    ObjectOutput out;
    try {
        out = new ObjectOutputStream(new FileOutputStream("appSaveState.data"));        
        out.writeObject(instance);
        out.close();
    } catch (Exception e) {e.printStackTrace();}
}

public static SaveState loadData(){
    ObjectInput in;
    SaveState ss=null;
    try {
        in = new ObjectInputStream(new FileInputStream("appSaveState.data"));       
        ss=(SaveState) in.readObject();
        in.close();
    } catch (Exception e) {e.printStackTrace();}
    return ss;
}
}

I'm trying to store it and reopen it using this call in my activity:

            SaveState.fms.add(fm);
            SaveState.saveData(SaveState.getInstance());                
            SaveState sv = SaveState.loadData();

But it is not working, it is not storing the object, and ofcourse it is not reading the objecto, i'm getting these two exception while storing and reading the object:

    03-23 09:18:16.702: WARN/System.err(9060): java.io.FileNotFoundException: /appSaveState.data (Read-only file system)
03-23 09:18:16.702: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.openImpl(Native Method)
03-23 09:18:16.702: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:152)
03-23 09:18:16.702: WARN/System.err(9060):     at java.io.FileOutputStream.<init>(FileOutputStream.java:97)
03-23 09:18:16.702: WARN/System.err(9060):     at java.io.FileOutputStream.<init>(FileOutputStream.java:168)
03-23 09:18:16.702: WARN/System.err(9060):     at java.io.FileOutputStream.<init>(FileOutputStream.java:147)
03-23 09:18:16.702: WARN/System.err(9060):     at com.Magazine.SaveState.saveData(SaveState.java:35)
03-23 09:18:16.702: WARN/System.err(9060):     at com.Magazine.MainMenu$DownloadThread.run(MainMenu.java:807)
03-23 09:18:16.709: WARN/System.err(9060): java.io.FileNotFoundException: /appSaveState.data (No such file or directory)
03-23 09:18:16.709: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.openImpl(Native Method)
03-23 09:18:16.709: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:152)
03-23 09:18:16.709: WARN/System.err(9060):     at java.io.FileInputStream.<init>(FileInputStream.java:82)
03-23 09:18:16.709: WARN/System.err(9060):     at java.io.FileInputStream.<init>(FileInputStream.java:134)
03-23 09:18:16.709: WARN/System.err(9060):     at com.Magazine.SaveState.loadData(SaveState.java:46)
03-23 09:18:16.709: WARN/System.err(9060):     at com.Magazine.MainMenu$DownloadThread.run(MainMenu.java:809)

What's wrong in the code?

Thanks

NullPointerException
  • 36,107
  • 79
  • 222
  • 382

3 Answers3

6

change this

out = new ObjectOutputStream(new FileOutputStream("appSaveState.data"));

with

   File outFile = new File(Environment.getExternalStorageDirectory(), "appSaveState.data");
   out = new ObjectOutputStream(new FileOutputStream(outFile)); 

as correctly pointed out by @e-x, the file will not be removed clearing application's data or uninstalling the app

Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • and what happens if the phone doesn't have a SDCARD installed? i'm trying to store it on the internal memory storage because i must store this data on all the phones, including the phones without SDCARD – NullPointerException Mar 23 '12 at 09:29
  • 1
    if you are referring to mobile phones without sdcard support (like the samsung nexus s), the Enviromenet.getExternalStorageDirectory() will return the path to the phone internal storage archive. – Blackbelt Mar 23 '12 at 09:36
  • 1
    I think it's worth mentioning that if the phone has an SDCARD then the file will remain when clearing the application's data. – E_X Sep 26 '14 at 10:43
  • @E_X, I updated the answer, thanks for the contribution – Blackbelt Sep 26 '14 at 10:53
2

You're not allowed to just write into the internal storage (even if you get that permission). Try it with the external sd or your cache folder instead.

Tim
  • 6,692
  • 2
  • 25
  • 30
  • Cachefolder data is persisent until the app is uninstalled from the phone? tell me how to do it with the cache folder please, what i should change into my code? – NullPointerException Mar 23 '12 at 09:28
  • File cacheFile = new File(activity.getCacheDir(), "appSaveState.data"); - write into that file like you did before. – Tim Mar 23 '12 at 09:32
  • 2
    Cachefolder is prone to be deleted by OS when free space is becoming low! – Dumbo Jul 03 '14 at 01:43
1

This was my aproach based on this post and this

I wrote this on my User class

private static File mFolder;
public void saveData(Activity pContext) {
    //this could be initialized once onstart up
    if(mFolder == null){
        mFolder = pContext.getExternalFilesDir(null);
    }
    this.save();
    ObjectOutput out;
    try {
        File outFile = new File(mFolder,
                "someRandom.data");
        out = new ObjectOutputStream(new FileOutputStream(outFile));
        out.writeObject(this);
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static User loadData(Context pContext) {
    if(mFolder == null){
        mFolder = pContext.getExternalFilesDir(null);
    }
    ObjectInput in;
    User lUser = null;
    try {
        FileInputStream fileIn = new FileInputStream(mFolder.getPath() + File.separator + "someRandom.data");
        in = new ObjectInputStream(fileIn);
        lUser = (User) in.readObject();
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (lUser != null) {
        lUser.save();
        Log.d("current User: ", lUser.nickname);
    } else {
        Log.d("current User: ", "null");
    }
    return lUser;
}

Edit:

Then from my activity i call

mUser = User.loadData(mSelf);

or

mUser = User.loadData(this);

mSelf would be an instance I store

Hope this helps :)

Aerim
  • 1,960
  • 3
  • 16
  • 28