今天我开始了我的第一个Android应用程序项目 - 当然 - 我遇到了问题。我想让一个非常简单的应用程序进入整个编程的事情,我现在在我的假期,所以我认为在我上床睡觉时醒来时会很有趣。所以它不应该那么难,而且几乎所有东西都像我想要的那样。 现在的问题是,我将日期保存在ArrayList中,因此它们显示在ListView中。我读到我无法在SharedPrefs中保存ArrayLists,我没有理解SQLite的东西,所以我决定使用FileOutputStream等。我在互联网上阅读了它并试图像他们那样做但是它根本不起作用。控制台中没有错误,但如果我关闭并重新打开应用程序,我的所有元素都将消失。 谁可以帮助我? :) (我不知道代码的哪一部分很重要,哪些不是,所以这里是整个代码)
package com.gaminggears.sleeplist.sleep;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Path;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
public class MainActivity extends AppCompatActivity{
private ListView dataListView;
private ListView dataListView1;
private ArrayAdapter arrayAdapter;
File file = new File("/mnt/sdcard/SleepApp/save.sav");
File dir = new File("/mnt/sdcard/SleepApp");
Date date = new Date();
SimpleDateFormat ft = new SimpleDateFormat ("E d-M-y kk:mm");
ArrayList<String> data = new ArrayList<String>();
ArrayList<String> data1 = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(!dir.exists()){
file.mkdir();
}
loadDataFromFile();
dataListView1 = (ListView) findViewById(R.id.listView2);
dataListView = (ListView) findViewById(R.id.listView);
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, data);
dataListView.setAdapter(arrayAdapter);
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, data1);
dataListView1.setAdapter(arrayAdapter);
System.out.println("\t\t" + data);
}
public void sleepClick(View v) {
data.add(ft.format(date));
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, data);
dataListView.setAdapter(arrayAdapter);
saveDataToFile();
}
public void wakeUpClick(View v){
data1.add(ft.format(date));
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, data1);
dataListView1.setAdapter(arrayAdapter);
saveDataToFile();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void saveDataToFile(){
try{
FileOutputStream sF = new FileOutputStream(file);
ObjectOutputStream save = new ObjectOutputStream(sF);
save.writeObject(data);
save.writeObject(data1);
save.close();
} catch(Exception exc){
exc.printStackTrace();
}
}
public void loadDataFromFile(){
try{
FileInputStream saveFile = new FileInputStream(file);
ObjectInputStream save = new ObjectInputStream(saveFile);
data.clear();
data.addAll((ArrayList) save.readObject());
data1.clear();
data1.addAll((ArrayList) save.readObject());
save.close();
} catch(Exception exc) {
exc.printStackTrace();
}
}
}
编辑:更新了代码。现在我的错误是&#34; java.io.FileNotFoundException:/mnt/sdcard/SleepApp/save.sav:open failed:EACCES(Permission denied)&#34;。有什么想法吗?
答案 0 :(得分:1)
你的代码有点遍布。以下是主要内容:
您应该做的是创建两个方法:
查看API您可能会注意到,在共享偏好设置中,您可以调用putStringSet 这可能非常方便。看看这个。
尝试始终指定您在列表中保留的对象类型。在你的情况下,它是一个字符串,所以它应该是这样的:
ArrayList<String> data = new ArrayList<>();
删除“main”方法。不会进入细节,但基本上它在这里没用。只需确保首先将其功能复制到“LoadDataFromFile”方法。
您遇到的最后一个问题是,即使您正确保存并加载数据,也不会显示它,因为您覆盖了要显示的数据的对象。您应该做什么而不是覆盖是清除以前的数据和添加新数据。它应该是这样的:
data.clear();
data.addAll((ArrayList) save.readObject());
希望这些笔记能为您提供一些指导。如果您有任何问题,我会尽力澄清。
编辑:(对您的编辑)
你得到错误的原因有两个:
需要写入文件的权限。 基本上将以下内容添加到清单中:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
更多信息here。
文件和路径不存在。您不能简单地写出文件的名称,而是提供完整的路径。为此,请首先使用以下命令保存设备外部存储根路径:
private static final String ROOT_PATH = Environment.getExternalStorageDirectory();
private static final String FILE_NAME = "SaveFile.sav";
然后在你的FileInputStream和FileOutputStream中使用根路径和文件名,用“/”分隔,如下所示:
new FileInputStream(ROOT_PATH + "/" + FILE_NAME);
在子目录中写入文件时,你必须做的另一件事是:在失踪的父母上调用mkdir或mkdirs 来创建失踪的父母或父母。例如:
File file = new File(ROOT_PATH + "/" + "SOME_FOLDER");
file.mkdirs();
答案 1 :(得分:0)
您必须创建自己的类/对象,然后实现Parcelable接口,继续使用它,并在使用bundle发送时传递,或者只是重新创建活动/片段,以重新获得。
看看这个答案:Android: How to implement Parcelable to my objects?
另一个答案: Save ArrayList to SharedPreferences
问候。