I am working on a simple word processing app, and I'm close to the point of being able to release it, except that I have one problem. When I click on an item in a ListView that displays the file names of all the text files the user has created with my app, I would like to open the file that corresponds with the item name, and place the text from that file inside the main EditText that the user uses to input data. However, when the item is clicked, nothing happens. Here is my code for that action.
filesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String itemName = filesListView.getItemAtPosition(position).toString();
FileInputStream fis;
String content = null;
try {
fis = openFileInput(itemName);
byte[] input = new byte[fis.available()];
while (fis.read(input) != -1) {
content += new String(input);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
textEntryEditText = (EditText) findViewById(R.id.textEntryEditText);
textEntryEditText.setText(content);
}
});
Please help. Thanks!
EDIT: SOLVED, check my Answer to see what I did.
There might be a problem with the focusable of your listView items.Set the focusable to false for the editText in the ListView.
Try to get the file or path object from the Listview adapter not file name.
when using openFileInput(String) method it creates or get the file from application files folder not from that file location. so use BaseAdapter and get File object using getItem(int) method
I believe you are using any a dapter for binding data to your listView,
So in custom adapter class
if(convertView==null){
convertView.setTag(holder);
convertView.setTag(R.string.fileName, array.get(position).getfileName());
}else {
holder = (ViewHolder) convertView.getTag();
}
then on item click try to fetch file name like this
fileName = view.getTag(R.string.fileName).toString();
Never mind, I solved it. After several hours of tears, rage, and frustration, I finally solved it, lol. But thank you everyone who responded. As for anyone else who has a similar problem, here's what I did.
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String itemName = filesListView.getItemAtPosition(position).toString();
StringBuffer fileRead = new StringBuffer("");
try {
FileInputStream fileInputStream = new FileInputStream(new File(getDir("FOLDER", Context.MODE_APPEND), itemName));
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String readString = bufferedReader.readLine();
while (readString != null) {
fileRead.append(readString);
readString = bufferedReader.readLine();
}
fileInputStream.close();
inputStreamReader.close();
bufferedReader.close();
textEntryEditText.setText(fileRead);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
My previous method of using the openFileInput was flawed, because I was trying to locate the file inside the default directory that openFileInput looks in, which is not where my file was. After, I tried referencing it directly, and found out that openFileInput does not allow this. So, I eventually tried just making a new FileInputStream, and telling it to make a new File object that uses the getDir method to reference the directory FOLDER, and the name of the file as determined by itemName. Hopefully this helps other who were struggling as I was, so that they don't have to suffer like I did. Thanks again to those who responded, even if I didn't use your advice!
Related
How can i read a large text file into my Application?
This is my code but it does not work. My code must read a file called list.txt. The code worked only with a file with only 10.000 lines.
can someone helps me?
Thanks!
My code:(Worked with small files, but not with large files)
private void largefile(){
String strLine2="";
wwwdf2 = new StringBuffer();
InputStream fis2 = this.getResources().openRawResource(R.raw.list);
BufferedReader br2 = new BufferedReader(new InputStreamReader(fis2));
if(fis2 != null) {
try {
LineNumberReader lnr = new LineNumberReader(br2);
String linenumber = String.valueOf(lnr);
while ((strLine2 = br2.readLine()) != null) {
wwwdf2.append(strLine2 + "\n");
}
// Toast.makeText(getApplicationContext(), linenumber, Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), wwwdf2, Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Since you are processing a large file, you should process the data in chunks . Here your file reading is fine but then you keep adding all rows in string buffer and finally passing to Toast.makeText(). It creates a big foot-print in memory. Instead you can read 100-100 lines and call Toast.makeText() to process in chunks. One more thing, use string builder instead of string buffer go avoid unwanted overhead of synchronization. You initializing wwwdf2 variable inside the method but looks it is a instance variable which I think is not required. Declare it inside method to make it's scope shorter.
I'm currently working on an android project which allows user to write text using different colors and store them for later use(i.e., editing or reading).
Is their any way to store a file in android with multi color text ??
NOTE: I googled out for the solution but can't find anything useful.
I'm guessing the user has to perform some action to switch color?
If so - you can use that trigger to store the text position/length when switching and save a list of text position - color.
A commenter suggested HTML, and that may be a good choice. You are welcome to try Html.fromHtml() to populate your EditText with the contents of a simple HTML-formatted file, and you are welcome to try Html.toHtml() to generate HTML from the contents of your EditText. However, historically, those methods were not written to do a good job of implementing a "round trip", meaning that the contents of the EditText may wind up changing from its starting point to what it contains after doing Html.toHtml() (to generate and save the HTML) and Html.fromHtml() (to populate the EditText with the previously-saved HTML). If they do not work, you can either fork that Html class and try to modify it as needed, or write your own code to take a Spanned object and convert it to/from HTML, by examining the spans and generating HTML tags from them.
PROBLEM SOLVED:
Code for storing a multi color text from EditText to a txt file:
protected void onDestroy() {
super.onDestroy();
boolean writing_allowed= ExternalStorageWriting.isWritingPossible();
if(writing_allowed)
{
String store= Html.toHtml(et.getEditableText());
File myExternalFile = new File(getExternalFilesDir(filepath), filename3);
try {
FileOutputStream fos = new FileOutputStream(myExternalFile);
fos.write(store.getBytes());
fos.close();
} catch (Exception e) {
Toast.makeText(Notes.this, "Something went wrong...", Toast.LENGTH_SHORT).show();
}
}
}
Code for reading that txt file and displaying it in EditText :
private void setNotes()
{
String myData="";
try {
File myExternalFile = new File(getExternalFilesDir(filepath), filename3);
FileInputStream fis = new FileInputStream(myExternalFile);
DataInputStream in = new DataInputStream(fis);
BufferedReader br =
new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
myData = myData + strLine;
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
Spanned htmlText = Html.fromHtml(myData);
et.setText(htmlText);
}
I just started to learn developping android and I have a (probably) basic questions, but I didn't find anything clear.
I'm trying to store data in a JSON file, well, I've understood the logic to store it, my way is:
public boolean writeFileJson(JSONObject jobj) {
try {
FileOutputStream fOut = openFileOutput(file, Context.MODE_PRIVATE);
fOut.write(jobj.toString().getBytes());
fOut.close();
Toast.makeText(getBaseContext(), "file saved", Toast.LENGTH_SHORT).show();
} catch (Exception e1) {
e1.printStackTrace();
}
return true;
}
But my problem is to read, and concretely for the first time, because the way I do it is:
public String readFileJson() {
int c;
String temp = "";
try {
FileInputStream fin = openFileInput(file);
while ((c = fin.read()) != -1) {
temp = temp + Character.toString((char) c);
}
Toast.makeText(getBaseContext(), "file read", Toast.LENGTH_SHORT).show();
} catch (Exception e2) {
}
return temp;
}
So wen I read it for the first time and I want to acces to a parameter of my JSON is obvious that any JSON Object already exist in the file.
So I try to save a first JSON Object with my parameters in onCreate() method and save it in the file, but wen I run the app, and I stop it, it returns again to execute onCreate() and deletes all data stored during the run time.
So my question is: There is any way to init only for one time the parameters of the JSON file to could access for the first time unlike it's empty???
I hope that I'd explained well!!
Thanxxxx!!!!
You can create your own flag boolean and check when you start.
Well I don't understand well why you can use a flag if the flag is set to init value in onCreate(), but I've tried a basic method: check each time if the json file is null. But it's like so basic no? Is there any ther way, or trying to understand how to use flags without reset their values?
msgjson = readFileJson();
if(msgjson == "") {
json.put("ARRAY", jsonArray);
}else{
json = new JSONObject(msgjson);
}
Thanx!!
I am trying to write and read a text file which is full of words and add it to an ArrayList. The ArrayList later is used from another part of the program to display text in a TextView. But when i run the program and open the specific part of it, then there is nothing. The ArrayList is just empty. I don't get any exceptions but for some reason it doesn't work. Please help me.
I don't seem to have problems with the file writing:
TextView txt = (TextView)findViewById(R.id.testTxt);
safe = txt.getText().toString();
try {
FileOutputStream fOut = openFileOutput("test.txt", MODE_WORLD_READABLE);
OutputStreamWriter osw = new OutputStreamWriter(fOut);
try {
osw.write(safe);
osw.flush();
osw.close();
Toast.makeText(getBaseContext(), "Added to favorites", Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException ex){
Log.e("Exception", "File write failed: ");
}
} catch (IOException e) {
Log.e("Exception", "File write failed: ");
}
But I think the problem is in the file reading. I made some "Log.d" and found out that everything works fine till the InputStreamReader line:
public favHacks() {
testList = new ArrayList<String>();
try {
//Works fine till here
InputStreamReader inputStreamReader = new InputStreamReader(openFileInput("test.txt"));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
while ( (receiveString = bufferedReader.readLine()) != null )
{
testList.add(receiveString);
}
bufferedReader.close();
}
catch (FileNotFoundException ex) {
Log.d("login activity", "File not found: ");
} catch (IOException ex) {
Log.d("login activity", "Can not read file: ");
}
}
If you have a relatively small collection of key-values that you'd like to save, you should use the SharedPreferences APIs.
http://developer.android.com/training/basics/data-storage/shared-preferences.html
also if you want to write/read files, or do any kind of operations that can block the Main Thread try to use another Thread like when you are trying to save the data in a file or use a Handler if you have multiple Threads (one for saving and one for reading).
https://developer.android.com/training/multiple-threads/index.html
In your code the method called favHacks can return an ArrayList with the list of all the strings Something like
//
public ArrayList<String> readFromFile(String file){
ArrayList<String> mArrayList= new ArrayList<String>();
//read from file here
return mArrayList;
}
but as I said before, you need to the operations that can block the UI thread in a new Thread.
https://developer.android.com/training/multiple-threads/communicate-ui.html
And also I think that the best way to do this is using Asynk task
Why and how to use asynctask
I have an equation which result is displayed in a TextView.
Then i have another TextView which act like a History. This History i want to save with a file and the file should be reloaded after the app will be killed an restarted.
Whats i dont understand is that the second TextView which is the View that i will save is displayed wierd stuff after starting the app
Thise line over and over again.
android.widget.TextView{41852c0 VFED.VCL ..... ID32,316-419,351 #7f09000a app:id/tvHistory}
My own Code:
final static String FILENAME = "marks.txt";
mNotenHistory=(TextView)findViewById(R.id.tVhistory);
mNotenHistory.setMovementMethod(new ScrollingMovementMethod());
private void loadTextfromFile()
{
File f = new File(getFilesDir(),FILENAME);
try {
BufferedReader br = new BufferedReader(new FileReader(f));
String line;
try {
while ((line = br.readLine()) != null)
{
mNotenHistory.setText(line+"\n"+mNotenHistory.getText());
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
#Override
public void onClick(View view)
{
[...]
mNotenHistory.setText(mNotenHistory.getText() + "\n" + string_note);
String noten_history_string = String.valueOf(mNotenHistory);
try {
FileOutputStream fo = openFileOutput(FILENAME, Context.MODE_APPEND);
fo.write(noten_history_string.getBytes());
fo.write("\n".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Here is the offending line:
String noten_history_string = String.valueOf(mNotenHistory);
Look at this definition, from the Android documentation:
public static String valueOf(Object value)
Added in API level 1
Converts the specified object to its string representation. If the object is null return the string "null", otherwise use toString() to get the string representation.
The TextView class inherits toString() from the View class. Here is its definition:
public String toString ()
Added in API level 1
Returns a string containing a concise, human-readable description of this object. Subclasses are encouraged to override this method and provide an implementation that takes into account the object's type and data. The default implementation is equivalent to the following expression: getClass().getName() + '#' + Integer.toHexString(hashCode())
So this is your problem. String.valueOf(mNotenHistory) does not give you the text within the text view. Thus, you are writing something else (specifically, the line you mentioned) to your file. To obtain the text from your TextView, use the getText() method instead. This is what the line should look like:
String noten_history_string = mNotenHistory.getText();
Quick resume what i do want to a complish.
TextView A gets the result of an equation which is clear after each new calculation.
To save the result there is TextView B.
The Results should write from botton to top in TextView B so that the newest in on top.
The same time it should write the content of the TextView into a file.
After closing/killing the App and reopen it the TextView B will show all the saved data.
A Reset Button should clear all the content of the file so it will be empty.