I'm using this code to save data to file and read data from the file:
public static void save(FileIO files) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
files.writeFile(".save")));
for (int i = 0; i < 20; i++) {
out.write(Integer.toString(scores[i]));
out.write("\n");
}
} catch (IOException e) {
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
}
}
}
public static void load(FileIO files) {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
files.readFile(".save")));
for (int i = 0; i < 20; i++) {
scores[i] = Integer.parseInt(in.readLine());
}
} catch (IOException e) {
} catch (NumberFormatException e) {
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
}
}
}
FileIO.java
package com.avoidblocks.avoidblocks.framework;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.SharedPreferences;
public interface FileIO {
public InputStream readFile(String file) throws IOException;
public OutputStream writeFile(String file) throws IOException;
public InputStream readAsset(String file) throws IOException;
public SharedPreferences getSharedPref();
}
I'm calling save(FileIO files) and load(FileIO files) multiple times in an app and it works fine while I'm in an app, but when I exit the app and start the app again, all data is gone.
Does anyone know how to create that data remains saved even when I exit the app, so that I could restore the data when I start the app again?
Also, is this the right way to save data if I want that saved data is only visible to my app and that after uninstall, all saved data is erased?
EDIT-EDIT-EDIT:
ok its your FileIO files variable that looks like it is wrong,
what are you using to get that variable?
should be
context.openFileOutput(".save", Context.MODE_PRIVATE)
for save and
context.openFileInput(".save")
for load
and it should be FileOutputStream for save and FileInputStream for read instead of FileIO.
and when adding it to the stream just pass that in.
so in your code you should create the BufferedWriter like this:
out = new BufferedWriter(new OutputStreamWriter(
context.openFileOutput(".save", Context.MODE_PRIVATE)));
and create BufferedReader like this:
in = new BufferedReader(new InputStreamReader(
context.openFileInput(".save")));
==================EDIT: my testing code=================
Ok, I created an activity and made the following two methods and declared an array of ints:
public static int scores[] = {11,12,13,14,15};
public static void save(Context context) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
context.openFileOutput(".saveingTest", Context.MODE_PRIVATE)));
for (int i = 0; i < scores.length; i++) {
out.write(Integer.toString(scores[i]));
out.write("\n");
}
} catch (IOException e) {
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
}
}
}
public static void load(Context context) {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
context.openFileInput(".saveingTest")));
for (int i = 0; i < scores.length; i++) {
Log.d("testingApp", "test: " + Integer.parseInt(in.readLine()));
// scores[i] = Integer.parseInt(in.readLine());
}
} catch (IOException e) {
} catch (NumberFormatException e) {
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
}
}
}
in my onCreate I have the following two lines of code:
save(this);
load(this);
to test I did the following:
commented out load in onCreate, ran the app, than I removed the comment on load and commented out save in onCreate and i changed the numbers in the scores variable(this is unnecessary but i did it anyway) and ran the app, the result was the int values in scores from the first time the app was run, inside the android log viewer window on eclipse. you can also have buttons that trigger save and load instead if you don't want to comment and run.
try it yourself, it should work, and make sure you are doing the same thing in your actual android app, if it still dose not work you are doing something else wrong and its not an issue with saving the file.
Related
I want to read data of type double saved in a .txt file from a previously specified folder. I've implemented the following code to read data then put them in an array of type double named savg1. when I run my application , it going to crash and the application stop. I tried to debug the application step by step and found that crash happens when the code reaches to savg1[i] = Double.parseDouble(str).
public void filereader()
{
InputStream is=this.getResources().openRawResource(R.raw.nums);
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String str=null;
int i=0;
try
{
if (is !=null)
{
str=br.readLine();
while (str != null) {
savg1[i] = Double.parseDouble(str);
i++;
str=br.readLine();
}
is.close();
br.close();
}
} catch (IOException e)
{
e.printStackTrace();
}
}
I am a newbie in Android developing so excuse me about my elementary question. Can anybody guide me how I can solve this problem?
Use following code to read data from your file. Note that in this method each number should be in a separate line:
double svg1[] = new double[10];
try {
InputStream is = getResources().openRawResource(R.raw.data);
DataInputStream dis = new DataInputStream(is);
while (dis.available() > 0) {
String test = dis.readLine();
double a = Double.parseDouble(test);
}
}catch (Exception e){
e.printStackTrace();
}
You can use file scanner for reading double type data saved in a text file as bellow:
public void fileReader(){
Scanner scan;
File file = new File("resources\\scannertester\\data.txt");
int idx = 0;
try {
scan = new Scanner(file);
while(scan.hasNextDouble())
savg1[idx++] = scan.nextDouble();
} catch (FileNotFoundException error) {
error.printStackTrace();
}
scan.close();
}
My App is writing data into a txt-file. (the code was on here some time ago for another reason)
Im always reading the whole file into a String Array and replacing an explicit line.
After reading the File I log the Data to observe it. My main is calling the App 7 times (for each line) but after the first call the data im logging is just weird.
Here is my code:
public void writeFileData(String data, int line) {
String[] lines = new String[999];
File file = null;
BufferedReader br = null;
FileOutputStream fos = null;
OutputStreamWriter os = null;
try {
file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "data.txt");
if(!file.exists())
{
try
{
if(file.createNewFile())
{
Toast.makeText(BaseActivity.this, "File was created", Toast.LENGTH_LONG).show();
}
}
catch(Exception ex)
{
Log.e("Error creating file", ex.getMessage());
}
}
br = new BufferedReader(new FileReader(file));
int i = 0;
while(i < 7)
{
buffer = br.readLine();
lines[i] = buffer;
i++;
}
br.close();
fos = new FileOutputStream(file, false);
lines[line] = data;
for(i = 0; i < 7; i++)
{
if (lines[i].isEmpty())
{
Log.e(TAG, i + "is empty");
}
else
{
Log.e(TAG, lines[i]);
}
}
for(i = 0; i < 7; i++)
{
try {
fos.write(lines[0].getBytes());
}
catch (Exception ex)
{
Log.e("Error writing", ex.getMessage());
}
}
try
{
fos.close();
}
catch(Exception ex)
{
Log.e("Error closing/flushing", ex.getMessage());
}
}
catch(Exception ex)
{
Log.e("Error creating streams", ex.getMessage());
}
}
My logcat
The calls inside the main look like:
writeFullData();
writeFileData("001",0);
writeFileData("002",1);
writeFileData("110",2);
writeFileData("110",3);
writeFileData("110",4);
writeFileData("110",5);
writeFileData("110",6);
writeFullData(); is writing into the txt file (visible in the logcat image)
Thanks in advance.
Xaver Seiringer
I called a function overwriting the whole file. That way i was able to overwatch every single line and Log the input so i will notice a change in the lines and my writeFileData() Function also had to read something.
I didnt write false in the FileWriter!
BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));
I wrote 21 lines into the file instead of 7 (after calling 4 times).
The 2nd mistake was i forgot to bw.newLine in writeFileData.
Those mistakes doe...
But thanks for the help.
I am developing an Android application in which I need to show the saved WiFi passwords in the mobile or tablet. Like for example, if my mobile is connected to any network that n/w password is saved in my mobile. I want to get it.
Unless you are rooted, I don't know of any way to do it. If you are rooted, or are willing to root your Galaxy for those nice guy points, you should be able to use a file manager (ASTRO, Root Browser, etc.) to find it.
Use the file manager to locate your data/misc/file folder, then look for wpa_supplicant.conf, or I assume it could be wep_supplicant.conf if his/her network is using WEP instead of WPA. Open the .conf file using a text editor (which is probably built into your file manager application, if not, add that to your shopping list). You should be able to read the password in plain text at that point.
Your Comments helped me to some extent to find out the solution to my question. Especially #Namik Kalavadia I am talking about you Thanks for that.
Finally here is the solution.
public class MainActivity extends Activity {
File file;
public StringBuffer ab;
public File savefile;
public InputStream in = null;
public String filename = "wpa_supplicant.conf";
public File ot_path;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
ot_path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
Log.d("aaa", ""+ot_path.toString());
}
public void path(View v){
getPath();
}
private void getPath(){
file = Environment.getRootDirectory();
String ext = ".conf";
File list[] = file.listFiles();
ab = new StringBuffer();
if(list!=null){
fileNameSearch(list);
}
}
public void fileNameSearch(File list[]){
if(list!=null){
for(int f = 0;f<list.length;f++){
ab.append(list[f].getName()+"\n");
File fi = list[f];
String path = fi.getPath();
if(fi.isDirectory()){
fileNameSearch(fi.listFiles());
}
else if(path.endsWith(".conf")){
if(path.contains(filename)){
try{
File fileForParse = copyFile(path,ot_path);
in = new FileInputStream(fileForParse);
getStringFromInputStream(in);
Log.d("aaa", "conf I got it"+path);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
else{
Log.d("aaa", "List is null in method");
}
}
private File copyFile(String inputPath, File outputPath) {
InputStream input = null;
OutputStream out = null;
try {
if (!outputPath.exists())
{
outputPath.mkdirs();
}
savefile = new File(outputPath,filename);
if (!savefile.exists()) {
savefile.createNewFile();
File f = new File(inputPath);
Log.d("aaa",""+f.length());
input = new FileInputStream(inputPath);
out = new FileOutputStream(savefile);
byte[] buffer = new byte[1024];
int read;
while ((read = input.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
Log.d("aaa",""+savefile.length());
input.close();
input = null;
out.flush();
out.close();
out = null;
}
} catch (FileNotFoundException fnfe1) {
Log.e("aaa", fnfe1.getMessage());
return null;
}
catch (Exception e) {
Log.e("aaa", e.getMessage());
return null;
}
return savefile;
}
#SuppressWarnings("deprecation")
private String getStringFromInputStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
if(line.contains("ssid")||line.contains("psk")){
sb.append(line+"\n");
}
if(line.contains("}")){
sb.append("-----------------\n");
}
AlertDialog ad = new AlertDialog.Builder(MainActivity.this).create();
ad.setTitle("Lis of WiFi Passwords Saved in your Mobile");
ad.setMessage(sb);
ad.setButton("OK",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
finish();
}
});
ad.show();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
}
It is not possible as far as I know . It will be a security problem if sdk tools allows to do so .
Retrieving saved Wifi password programatically is not possible due to security issue.If you root your phone you may able to get it,but that too in an encrypted form.
I have a code inside myActivity.class
InputStream inputStream = getApplicationContext().getResources().openRawResource(R.raw.text);
BufferedReader buff = new BufferedReader(new InputStreamReader(inputStream));
String s;
ArrayList <String> list = new ArrayList <String>();
try
{ while((s = buff.readLine()) != null)
{
list.add(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I want to move that part of code to separate java.class, but here I face a problem, how I can to access a raw file by InputStream without using getApplicationContext()?
For instance:
public class MyArrayList extends ArrayList<String>
{
private InputStream in = ???; // how to declare InpuStream without Context???
private BufferedReader buff = new BufferedReader(new InputStreamReader(in));;
private String s;
private MyArrayList array;
public MyArrayList ()
{
try
{
while ((s = buff.readLine()) != null)
{
array.add(s);
}
} catch (IOException e)
{
e.printStackTrace();
} finally
{
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I have tried
InputStream in = Resources.getSystem().openRawResource(R.raw.text); but it gave me NullPointerException
So my question is: Does exist some way to initialize InputStream with raw file outside Activity ?
how I can to access a raw file by InputStream without using getApplicationContext()?
First, you do not need getApplicationContext() in your existing code. Deleting it will work just fine, and it saves an unnecessary call.
Beyond that -- and assuming that you really think that an ArrayList should be responsible for I/O -- MyArrayList needs you to pass in one of the following:
the InputStream, or
the Resources (so you can call openRawResource() on it), or
a suitable Context (so you can call getResources() on it) (and which, depending on the lifetime of MyArrayList, could be one of several possible objects)
You can't access App resources without current app context. If you want to move code in diff Java file simply Make a class and inside that class make a function with activity as one of the function's parameter and your required return type.
As activity is parent for context we can use it where ever we need activity or context reference out side the activity class.
public class Demo{
public static "whatEverReturnTypeYouNeedToReturnFromFunction" f1(Activity act, ...){
InputStream inputStream = act.getResources().openRawResource(R.raw.text);
BufferedReader buff = new BufferedReader(new InputStreamReader(inputStream));
String s;
ArrayList <String> list = new ArrayList <String>();
try
{ while((s = buff.readLine()) != null)
{
list.add(s);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return whatEverReturnTypeYouNeedToReturnFromFunction;
}
}
}
In the above code make variables static as our function is static.
And to call it from Activity class simply call
Type "whateverYouWhatToGetFromFunction" = Demo.f1(this, ...);
I'm programming a little game and I want to save on sd-card the scores and the the volume (enabled or disabled)
the code of my two functions is:
public static void load(FileIO files) {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(
files.readFile(".save")));
soundEnabled = Boolean.parseBoolean(in.readLine());
for (int i = 0; i < 5; i++) {
highscores[i] = Integer.parseInt(in.readLine());
}
} catch (IOException e) {
// :( It's ok we have defaults
} catch (NumberFormatException e) {
// :/ It's ok, defaults save our day
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
}
}
}
//-----------------------
public static void save(FileIO files) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
files.writeFile(".save")));
out.write(Boolean.toString(soundEnabled));
for (int i = 0; i < 5; i++) {
out.write(Integer.toString(highscores[i]));
}
} catch (IOException e) {
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
}
}
}
while the program is running this code is ok but if I restart my device the scores are lost..
do you know why?
thanks!!
ps: the FileIO class is:
public class AndroidFileIO implements FileIO {
Context context;
AssetManager assets;
String externalStoragePath;
public AndroidFileIO(Context context) {
this.context = context;
this.assets = context.getAssets();
this.externalStoragePath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator;
}
public InputStream readAsset(String fileName) throws IOException {
return assets.open(fileName);
}
public InputStream readFile(String fileName) throws IOException {
return new FileInputStream(externalStoragePath + fileName);
}
public OutputStream writeFile(String fileName) throws IOException {
return new FileOutputStream(externalStoragePath + fileName);
}
public SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(context);
}
}
There are two problems here. First, out.write does not insert a newline at the end of each call, you have to do that manually. So what is happening is when you do the readline in the cal to parse the Boolean you are actually consuming ALL the data in the file. Second, you need to flush and close the file before leaving that function to be sure you do not leave any data in the buffers.
Here is save rewritten that should work:
public static void save(FileIO files) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
files.writeFile(".mrnom")));
out.write(Boolean.toString(soundEnabled));
out.write("\n");
for (int i = 0; i < 5; i++) {
out.write(Integer.toString(highscores[i]));
out.write("\n");
}
out.flush();
out.close();
} catch (IOException e) {
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
}
}
}
I'm proggraming for first time but iv solved this using shared prefs. That way you avoid losing data when updating the app.