openFileInput reading only 1 line - android

I am accessing a file from my fragment in my Android app.
But my problem is that only 1 line of that file is being read.
My code is:
FragmentTab2.java
package com.adhish.pagertabstriptutorial;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class FragmentTab2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Get the view from fragmenttab2.xml
View v = inflater.inflate(R.layout.fragmenttab2, container, false);
TextView txt = (TextView)v.findViewById(R.id.optext);
try
{
FileInputStream fIn = getActivity().openFileInput("sample_details.txt");
InputStreamReader in = new InputStreamReader(fIn);
BufferedReader bufferedReader = new BufferedReader(in);
//StringBuilder sb = new StringBuilder();
String line = null;
String str = "";
while ((line = bufferedReader.readLine()) != null) {
str += line;
}
txt.setText(str);
bufferedReader.close();
in.close();
}
catch (Exception e)
{
Log.e("File not found.",e.toString());
}
return v;
}
}
The code which writes the file (in a different fragment) is:
#Override
public void onClick(View view)
{
if(view == getView().findViewById(R.id.button1))
{
//Call all the elements of this Fragment here becuase they are accessible easily through
//getView(); method. Use the getText(); method to get the Text and toString(); to convert
//it.
String name = ((EditText)getView().findViewById(R.id.name)).getText().toString();
String email = ((EditText)getView().findViewById(R.id.email)).getText().toString();
if(name.isEmpty() || email.isEmpty())
{
Toast.makeText(getActivity(), "Cannot store empty values !", Toast.LENGTH_SHORT).show();
}
else
{
try
{
FileOutputStream fOut = getActivity().openFileOutput("sample_details.txt", Context.MODE_MULTI_PROCESS);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fOut);
outputStreamWriter.write(name + " " + email + ";");
Log.e("String Concat Done", "Concatenation of the Strings is done to write in the File. Write Success.");
outputStreamWriter.flush();
Log.e("Flush","Flush Success");
outputStreamWriter.close();
fOut.close();
Log.e("Stream Closed","Both Streams are flushed and closed");
Toast.makeText(getActivity(), "Submitted", Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
Toast.makeText(getActivity(), "FAILED !", Toast.LENGTH_SHORT).show();
Log.e("Error in File Write",e.toString());
}
}
}
}
I don't know the correct way of implementing this.
Please let me know in detail how to do it, because I am new to Android.
Thanks.

Because your
FileOutputStream fOut = getActivity().openFileOutput("sample_details.txt", Context.MODE_MULTI_PROCESS);
should be
openFileOutput(yourFile, Context.MODE_APPEND);
FileOutputStream also have a constructor where you can append to the original file if you don't have context to be used with Android's openFileOutput() instead.
Extra reference for similar questions: OutputStreamWriter does not append

Related

To save file in a directory of Internal Storage

Here's a code of MainActivity.java to save a file named filename.txt in App's Internal Storage, which is working fine.
package com.bla.smthing;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class MainActivity extends Activity {
EditText textmsg;
static final int READ_BLOCK_SIZE = 100;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textmsg=(EditText)findViewById(R.id.editText1);
}
// write text to file
public void WriteBtn(View v) {
// add-write text into file
try {
FileOutputStream fileout=openFileOutput("mytextfile.txt", MODE_PRIVATE);
OutputStreamWriter outputWriter=new OutputStreamWriter(fileout);
outputWriter.write(textmsg.getText().toString());
outputWriter.close();
//display file saved message
Toast.makeText(getBaseContext(), "File saved successfully!",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
// Read text from file
public void ReadBtn(View v) {
//reading text from file
try {
FileInputStream fileIn=openFileInput("mytextfile.txt");
InputStreamReader InputRead= new InputStreamReader(fileIn);
char[] inputBuffer= new char[READ_BLOCK_SIZE];
String s="";
int charRead;
while ((charRead=InputRead.read(inputBuffer))>0) {
// char to string conversion
String readstring=String.copyValueOf(inputBuffer,0,charRead);
s +=readstring;
}
InputRead.close();
textmsg.setText(s);
} catch (Exception e) {
e.printStackTrace();
}
}
}
I am able to see the file by File Explorer of Android Studio. How can I save the file in a directory say files/Somefolder/otherfolderchild/filename.txt?
Currently, it is saving as files/filename.txt
Do I need to create additional parent file directories for that?
Try this it might help you. For the above marshmallow version please check the write permissions.
public void saveToExternalStorage() {
String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/directoryName";
try
{
File dir = new File(fullPath);
if (!dir.exists()) {
dir.mkdirs();
}
OutputStream fOut = null;
File file = new File(fullPath, "fileName.txt");
if(file.exists())
file.delete();
file.createNewFile();
fOut = new FileOutputStream(file);
fOut.flush();
fOut.close();
}
catch (Exception e)
{
Log.e("saveToExternalStorage()", e.getMessage());
}
}

CSV File not opening for reading in Android

I am trying to open a CSV file downloaded into internal storage for reading purpose alone. This is the code I have used:
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
import java.io.FileInputStream;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View v) {
try {
String FileName = "/storage/emulated/0/Download/MyDocument.csv";
FileInputStream fis = openFileInput(FileName);
fis.read();
fis.close();
Toast.makeText(getBaseContext(),"File Access Permitted",Toast.LENGTH_SHORT).show();
}
catch (Exception e) {
Toast.makeText(getBaseContext(),"File Access Denied",Toast.LENGTH_SHORT).show();
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
While the file is downloaded and I am able to open it in File Manager, the above code does not work. How do I achieve the required functionality?
As per this stackoverflow question's accepted answer, you could try this:
public String readFileFromDownloads(String fileName) {
File downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
if (!downloadsDir.exists()) return null;
File file = new File(downloadsDir, fileName);
if (!file.exists()) return null;
try {
StringBuilder fileContent = new StringBuilder();
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
fileContent.append(line);
fileContent.append('\n');
}
br.close();
return fileContent.toString();
} catch (IOException ex) {
//Handle error
return null;
}
}
And then call readFileFromDownloads("MyDocument.csv"); from inside your onClick(); method.
Also, you might need to add android.permission.READ_EXTERNAL_STORAGE to your Manifest and handle Android 6.0 new permission system as per Android Docs.

Proper use of openFileInput

I am new to Android Development, and I want to create an App which stores data in a file, and then reads the Data from the file. For that I have created 2 Tabs. Tab1 shows the form to enter data. And Tab2 shows the saved data.
FragmentTab1.java
package com.adhish.pagertabstriptutorial;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
public class FragmentTab1 extends Fragment implements View.OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Get the view from fragmenttab1.xml
//first inflate the view.
View v = inflater.inflate(R.layout.fragmenttab1, container, false);
//then access the elements
v.findViewById(R.id.button1).setOnClickListener(this);
//then return the view
return v;
}
#Override
public void onClick(View view)
{
if(view == getView().findViewById(R.id.button1))
{
//Call all the elements of this Fragment here becuase they are accessible easily through
//getView(); method. Use the getText(); method to get the Text and toString(); to convert
//it.
String name = ((EditText)getView().findViewById(R.id.name)).getText().toString();
String email = ((EditText)getView().findViewById(R.id.email)).getText().toString();
if(name.isEmpty() || email.isEmpty())
{
Toast.makeText(getActivity(), "Cannot store empty values !", Toast.LENGTH_SHORT).show();
}
else
{
try
{
FileOutputStream fOut = getActivity().openFileOutput("sample_details.txt", Context.MODE_MULTI_PROCESS);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fOut);
outputStreamWriter.write(name + " " + email + ";");
Log.e("String Concat Done", "Concatenation of the Strings is done to write in the File. Write Success.");
outputStreamWriter.flush();
Log.e("Flush","Flush Success");
outputStreamWriter.close();
fOut.close();
Log.e("Stream Closed","Both Streams are flushed and closed");
Toast.makeText(getActivity(), "Submitted", Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
Toast.makeText(getActivity(), "FAILED !", Toast.LENGTH_SHORT).show();
Log.e("Error in File Write",e.toString());
}
}
}
}
}
FragmentTab2.java
package com.adhish.pagertabstriptutorial;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class FragmentTab2 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Get the view from fragmenttab2.xml
View v = inflater.inflate(R.layout.fragmenttab2, container, false);
TextView txt = (TextView)v.findViewById(R.id.optext);
try
{
FileInputStream fIn = getActivity().openFileInput("sample_details.txt");
InputStreamReader in = new InputStreamReader(fIn);
BufferedReader bufferedReader = new BufferedReader(in);
StringBuilder sb = new StringBuilder();
String line = null;
String str = null;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line).append("\n");
}
txt.setText(line);
bufferedReader.close();
in.close();
}
catch (Exception e)
{
Log.e("File not found.",e.toString());
}
return v;
}
}
Only one line is displayed in the text view.
Please help me in detail as I am very new to Android.
Please suggest a better way in detail if exists.
I am attaching my UI here:
Thanks.
First Edit your try block with this code
FileOutputStream fOut = openFileOutput(
"sample_details.txt", Context.MODE_MULTI_PROCESS);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fOut);
JSONObject jobj=new JSONObject();
jobj.put("Name", "name");
jobj.put("Email", "email");
outputStreamWriter.write(jobj.toString());
Log.e("String Concat Done",
"Concatenation of the Strings is done to write in the File. Write Success.");
outputStreamWriter.flush();
Log.e("Flush", "Flush Success");
outputStreamWriter.close();
fOut.close();
Log.e("Stream Closed", "Both Streams are flushed and closed");
And in second tab(fragment) first get(read) the string as:
public static String convertStreamToString(InputStream is) throws Exception
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
return sb.toString();
}
public static String getStringFromFile (String filePath) throws Exception {
File fl = new File(filePath);
FileInputStream fin = new FileInputStream(fl);
String ret = convertStreamToString(fin);
//Make sure you close all streams.
fin.close();
return ret;
}
You will get(read) the string by calling getStringFromFile(filepath) method
the string is in JSON form so you have to parse it as:
public void Readvalue(String jsonvalue)
{
try {
JSONObject jobj=new JSONObject(jsonvalue);
String name=jobj.getString("Name");
String email=jobj.getString("Email");
System.out.println("Name is : "+name +" Email is : "+email);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Can not write more than 1 line into file

I am trying to write to a text file a list of names. It is written one line at a time and I have a class for Writing to File and Reading from it.
Here is the class:
package com.example.mobiledayoff;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import android.content.Context;
public class userListIO {
Context fileContext;
public userListIO(Context fileContext){
this.fileContext=fileContext;
}
public void writeItems(String fileName, String name){
final String ls = System.getProperty("line.separator");
BufferedWriter writer = null;
try{
writer =
new BufferedWriter(new OutputStreamWriter(fileContext.getApplicationContext().openFileOutput(fileName, Context.MODE_PRIVATE)));
writer.write(name + ls);
} catch (Exception e){
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public ArrayList<CharSequence> readItems(String filename){
ArrayList<CharSequence> list = new ArrayList<CharSequence> ();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(fileContext.getApplicationContext().openFileInput(filename)));
String line;
while((line = br.readLine()) != null){
list.add(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return list;
}
}
I use this class to write a line from user input (EditText) to the file. And then I read from file and Display contents of the file in another EditText. Here is how I do it:
public void addUser(View view){
EditText text = new EditText(this);
text = (EditText)findViewById(R.id.add_user_text);
String name = text.getText().toString();
String filename = "userList.txt";
userListIO messenger = new userListIO(this);
messenger.writeItems(filename, name);
text.setText("");
ArrayList<CharSequence> list = messenger.readItems(filename);
EditText editText = (EditText) findViewById(R.id.debug_text);
String info = "";
int count = 0;
for (CharSequence item: list){
info += item.toString();
count++;
}
info += "; there are " + count + " lines";
editText.setText(info);
}
My main problem is that it seems that file gets overwritten each time I write into it and so I always have 1 line. Do you guys know how to fix this? By fix I mean: How to append to the file if it already exists or create one if it doesn't exist.
Also I found out that after I close and reopen an app, the file does not exist. How to create and save a file, so that after closing and reopening I could still use the data stored there?
p.s. Read/Write was taken from here:
The best way to store user input data for later work
Change
new BufferedWriter(new OutputStreamWriter(fileContext.getApplicationContext().openFileOutput(fileName, Context.MODE_PRIVATE)));
to
new BufferedWriter(new OutputStreamWriter(fileContext.getApplicationContext().openFileOutput(fileName, Context.MODE_PRIVATE | Context.MODE_APPEND)));
This will combine the MODE_PRIVATE flag aswell as the MODE_APPEND flag.
P.S. You should get away from opening and closing a stream everytime you write a line. This produces a lot of overhead and rather should you try to keep the stream opened until all your data has been processed.

Downloading a website to a string

Having done some basic tutorials, I started making my first real android app in eclipse. I want this app to check if the text in an EditText matches the text on a website (this one: http://www.augustinianum.eu/roosterwijzigingen/14062012.pdf (it contains my school's schedule changes)). I've found out how to make the app check if the text in the EditText matches a string (with the method contains()), so now the only thing I need to do is to download all of the text of that website to a string. But I have no idea how to. Or is there maybe a method which I can check with if a website contains a certain word without downloading the website's text to a string.
Thank You!
(BTW I'm not English so plz forgive me if I've made some language-related mistakes.)
#androider I can't post my code in the comment box so here it is:
package me.moop.mytwitter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.app.Activity;
import android.app.ProgressDialog;
public class MainActivity extends Activity {
Button mBtnCheck;
EditText mEtxtGroup;
ProgressDialog mProgressDialog;
TwitterUser mTwitterUser;
TextView mTxtv1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nicelayout3);
mBtnCheck = (Button) findViewById(R.id.btnCheck);
mEtxtGroup = (EditText) findViewById(R.id.etxtGroup);
mTxtv1 = (TextView) findViewById(R.id.textView1);
}
public void checkScheduleChange(View view){
if (view == mBtnCheck){
String group;
group = mEtxtGroup.getText().toString();
if (group.length() > 0){
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Bezig met checken voor roosterwijzigingen...");
mProgressDialog.show();
try
{
URL url = new URL("http://www.augustinianum.eu/roosterwijzigingen/14062012.pdf");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null){
mProgressDialog.dismiss();
if(str.contains(mEtxtGroup.getText().toString())){
Toast.makeText(this, "U hebt een roosterwijziging.", Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(this, "U hebt geen roosterwijzigingen", Toast.LENGTH_LONG).show();
}
}
in.close();
} catch (MalformedURLException e) {
Toast.makeText(this, "Er is een fout opgetreden, probeer opniew.", Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(this, "Er is een fout opgetreden, probeer opniew.", Toast.LENGTH_LONG).show();
}
}
else{
Toast.makeText(this, "Voer een klas in", Toast.LENGTH_LONG).show();
}
}
}
}
Here are the button's properties:
<Button
android:id="#+id/btnCheck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:clickable="true"
android:onClick="checkScheduleChange"
android:text="Check" >
You can get the text using InputStream Reader like this.
try
{
URL url = new URL("http://yourwebpage.com");
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null)
{
// str is one line of text; readLine() strips the newline character(s)
// You can use the contain method here.
if(str.contains(editText.getText().toString))
{
You can perform your logic here!!!!!
}
}
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
Also add an additional permission in your apps Manifest file:
<uses-permission android:name="android.permission.INTERNET/>
//============================EDIT================================//
if (group.length() > 0)
{
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Bezig met checken voor roosterwijzigingen...");
mProgressDialog.show();
try
{
URL url = new URL("http://www.augustinianum.eu/roosterwijzigingen/14062012.pdf");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null){
if(str.contains(mEtxtGroup.getText().toString())){
if(mProgressDialog.isShowing())
{
mProgressDialog.dismiss();
}
Toast.makeText(this, "U hebt een roosterwijziging.", Toast.LENGTH_LONG).show();
break;
}
}
in.close();
} catch (MalformedURLException e) {
Toast.makeText(this, "Er is een fout opgetreden, probeer opniew.", Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(this, "Er is een fout opgetreden, probeer opniew.", Toast.LENGTH_LONG).show();
}
if(mProgressDialog.isShowing())
{
mProgressDialog.dismiss();
}
}
else{
Toast.makeText(this, "Voer een klas in", Toast.LENGTH_LONG).show();
}
This is a good related Java question: How do you Programmatically Download a Webpage in Java
You can then implement whatever method you choose into your app. One thing to note is that you will need to enable the INTERNET permission on your app in order to access the internet.

Categories

Resources