I am asking here as all other solutions have not worked. I want to read a text file from the web and have this string put into a textview. I am just testing at the moment and the only thing in the text file is the value "223". My app is crashing on start can anyone please help?
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.StringBuilderPrinter;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private StringBuilder text = new StringBuilder();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BufferedReader reader = null;
try {
URL url = new URL("http://something.uk/pmt/status.txt");
reader = new BufferedReader(
new InputStreamReader(url.openStream()));
String str;
while ((str = reader.readLine()) != null) {
text.append(str);
text.append('\n');
}
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Error reading file.", Toast.LENGTH_LONG).show();
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (MalformedURLException e) {
}
catch (IOException e) {
}
}
TextView output = (TextView) findViewById(R.id.textView);
output.setText((CharSequence) text);
}
}
}
STACKTRACE:
https://pastebin.com/YSCB9RBg
Probably because you are using StringBuilder which is not a CharSequence. Use output.setText(text.toString()); instead of output.setText((CharSequence) text);
TextView.setText() expects a CharSequence as an argument. String is a CharSequence, but StringBuilder is not. To get a String you gave to call StringBuilder.toString()
You should look at the crash though. And post it next time you ask a question on stackoverflow.
The crash log you provided clearly states the reason for crash: android.os.NetworkOnMainThreadException. It means that you are trying to do a network operation on the main thread and the Android OS does not let you. It is a rule since Honeycomb. The solution is to use AsyncTask, for example. Here is an article about network ops and AsyncTask.
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.StringBuilderPrinter;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private StringBuilder text = new StringBuilder();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BufferedReader reader = null;
new AsyncTask<Void,Void,Void>(){
#Override
protected Void doInBackground(Void... params) {
try {
URL url = new URL("http://something.uk/pmt/status.txt");
reader = new BufferedReader(
new InputStreamReader(url.openStream()));
String str;
while ((str = reader.readLine()) != null) {
text.append(str);
text.append('\n');
}
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Error reading file.", Toast.LENGTH_LONG).show();
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (MalformedURLException e) {
}
catch (IOException e) {
}
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
TextView output = (TextView) findViewById(R.id.textView);
output.setText(text.toString());
}
}.execute(null,null,null);
}
}
}
Related
Im creating a weight tracking app where the user inputs their weight clicks a save button and then the weight is saved. There is also a load button that loads all the previous inputs. The problem I'am having is that once load is clicked it does load up the weights on the screen but it does it all in one line other than a separate line for each.
I have checked the text file and all the weights are stored in a line each so there's no problem in the function that stores the inputs.
Here is the code for the `weight tracker
package com.example.workouttracker;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class WeightTracking extends AppCompatActivity {
private static final String FILE_NAME = "WeightTracking.txt";
EditText mEditText;
EditText mEditText2;
private Button button_back_home;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_weight_tracking);
mEditText = findViewById(R.id.weight);
mEditText2 = findViewById(R.id.weight2);
button_back_home=(Button) findViewById(R.id.button_back_home);
button_back_home.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
homePage();
}
private void homePage(){
startActivity(new Intent(getApplicationContext(),MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
});
}
public void save(View v) {
String text = mEditText.getText().toString();
FileOutputStream fos = null;
try {
fos = openFileOutput(FILE_NAME, MODE_APPEND);
fos.write((text + "kg's\n").getBytes());
mEditText.getText().clear();
Toast.makeText(this, "Saved to " + getFilesDir() + "/" + FILE_NAME,
Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void load(View v) {
FileInputStream fis = null;
try {
fis = openFileInput(FILE_NAME);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String text;
while ((text = br.readLine()) != null) {
sb.append(text);
sb.append('\n');
}
mEditText2.setText(sb.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Someone know's how to get it to load each weight line by line?
Thanks
`
can you please check your xml file, if you have added property android:inputType="textMultiLine" on the edittext
Try changing your code like this:
String sb = "";
String text;
while ((text = br.readLine()) != null) {
sb = sb + text + "\n";
}
//[(START)File:ThirdActivity.java] -->
package com.example.caleb.splash_screen;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.io.IOException;
import java.io.OutputStream;
public class ThirdActivity extends AppCompatActivity {
//public String text = "https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt";
public TextView text;
private void writeStream(OutputStream out){
String output = "Hello world";
// out.write(output.getBytes());
//out.flush();
}
/*private String readStream(InputStream is) {
try {`enter code here`
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int i = is.read();
while(i != -1) {
bo.write(i);
i = is.read();
}
return bo.toString();
} catch (IOException e) {
return "";
}
}*/
//[(START) readStream -->
private String readStream(InputStream in) throws IOException {
BufferedReader bin = new BufferedReader(new InputStreamReader(in));
//temporary
try {
StringBuilder sb = new StringBuilder();
String inputLine;
while ((inputLine = bin.readLine()) != null) {
sb.append(inputLine);
}
return sb.toString();
} finally {
}
}
//[(END) readStream -->
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third2);
text = (TextView)findViewById(R.id.textView);
new JSONTask().execute("https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt");
}
}
//[(END)File:ThirdActivity] -->
//[(START)File:JSONTask] -->
package com.example.caleb.splash_screen;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.widget.TextViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Created by Caleb on 12/17/2017.
*/
public class JSONTask extends AsyncTask<String,String,String> {
//final TextView txt = (TextView)findViewById(R.id.textView);
private Context context;
public JSONTask(Activity ThirdActivity) {
context = ThirdActivity;
}
#Override
protected String doInBackground(String... params) {
BufferedReader reader = null;
HttpURLConnection urlConnection = null;
//{(START)] Working Connection:ALERT! Error within code will cause crash -->
try {
URL url = new URL(params[0]);
Log.w("testing", "test");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(false);
urlConnection.connect();
//urlConnection.setChunkedStreamingMode(0);
//OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
//writeStream(out);
/*int a = urlConnection.getResponseCode();
String b = String.valueOf(a);
Log.e(b, "yesssssssssssssssss");*/
InputStream in = urlConnection.getInputStream();
//InputStream in = new BufferedInputStream(urlConnection.getInputStream());
reader = new BufferedReader(new InputStreamReader(in));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
/*String data = readStream(in);
/*final TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("hello");
*/
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//{(END)] Working Connection -->
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
TextView text = (TextView) ((AppCompatActivity) context).findViewById(R.id.textView);
text.setText(result);
}
}
//[(END)File:JSONTask] -->
/Desired Effect/
Blockquote
I would like to pull data from the json file that the url points to and change the TextView within the UI called textView. I don't understand how to access the findviewbyid within the AsyncTask. I've looked all throughout the internet and couldn't find anything :( Any suggestions are greatly appreciated!!
try weak reference to get textview in asynctask
//call async task
new JSONTask(yourTextView).execute();
//in your async task
private final WeakReference<TextView> textViewReference;
public JSONTask (TextView textView){
textViewReference = new WeakReference<TextView>( textView);
}
#Override
protected void onPostExecute() {
TextView textView = textViewReference.get();
//set values to text view
}
I'm using OkHttp to do the same task in my apps
HTTP/2 support allows all requests to the same host to share a socket.
Connection pooling reduces request latency (if HTTP/2 isn’t available).
Transparent GZIP shrinks download sizes.
Response caching avoids the network completely for repeat requests.
Add this dependency
implementation 'com.squareup.okhttp3:okhttp:3.9.1'
Then create/code a new Class named OkHttpHandler
class OkHttpHandler extends AsyncTask<String, String, String> {
OkHttpClient client = new OkHttpClient();
private volatile String data;
public String getResult() {
return data;
}
#Override
protected String doInBackground(String... params) {
try {
Request.Builder builder = new Request.Builder();
builder.url(params[0]);
Request request = builder.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
data = s;
}
}
}
and use it like this way
String str = new OkHttpHandler().execute("http://www.<TEST>.com/json").get();
I also suggest to check whether Wi-fi-Connected/Bluetooth-Connected or PhoneData-Enabled is false if true/else, Proceed to your code
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java .lang.String;
import static android.support.v7.appcompat.R.id.text;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView text = (TextView) findViewById(R.id.tv);
Button btn = (Button) findViewById(R.id.btn_hit);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new Jsontask().execute("https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt");
}
});
}
public class Jsontask extends AsyncTask<String,String,String>{
#Override
protected String doInBackground(String... params) {
HttpURLConnection http=null;
BufferedReader reader = null;
try {
URL url=new URL(params[0]);
http=(HttpURLConnection)url.openConnection();
http.connect();
InputStream inp=http.getInputStream();
reader=new BufferedReader(new InputStreamReader(inp));
String line=" ";
StringBuffer read=new StringBuffer();
while((line=reader.readLine())!=null)
read.append(line);
return reader.toString();
} catch(MalformedURLException e1){
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
if (http != null)
http.disconnect();
try {
if(reader!=null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result){
super.onPostExecute(result);
text.setText(result);
}
}
}
I think the issue is with this line:
import static android.support.v7.appcompat.R.id.text;
and when you are setting text here:
text.setText(result);
This text is not referred to TextView text.So,please check this thing once that if It is correctly referring to it.
TextView text = (TextView) findViewById(R.id.tv);
"text" is local variable so asynctask can not find it
Please define it at outside of onCreate()
I am trying to populate spinner from darabase but the application crashes, "Unfortunately, "Application" has stopped." and in the logcat I have got this error "
at com.exemple.user.modele.Categorie.onCreate(Categorie.java:43)"
when I remove all the try catch code the activity works, but I copied this code from another activity in the same application to populate a listView and it worked, so please if anyone could help me, thank you !
package com.exemple.user.modele;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
public class Categorie extends AppCompatActivity {
Spinner spinner1;
String result = null;
String line = null;
InputStream is = null;
String cat_url = "http://10.0.2.2/webapp/categories_spinner.php";
ArrayList<String> list1=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_categorie);
spinner1 = (Spinner) findViewById(R.id.sSelect);
try {
URL url=new URL(cat_url);
HttpURLConnection con= (HttpURLConnection) url.openConnection();
is=new BufferedInputStream(con.getInputStream());
BufferedReader br=new BufferedReader(new InputStreamReader(is));
StringBuffer sb=new StringBuffer();
if(br != null) {
while ((line=br.readLine()) != null) {
sb.append(line+"\n");
}
}
result = sb.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(is != null)
{
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
//ADD THAT DATA TO JSON ARRAY FIRST
JSONArray ja = new JSONArray(result);
//CREATE JO OBJ TO HOLD A SINGLE ITEM
JSONObject jo = null;
list1.clear();
//LOOP THRU ARRAY
for (int i = 0; i < ja.length(); i++) {
jo = ja.getJSONObject(i);
//RETRIOEVE NAME
String name = jo.getString("name");
//ADD IT TO OUR ARRAYLIST
list1.add(name);
}
spinner_fn();
} catch (JSONException e) {
e.printStackTrace();
}
}
private void spinner_fn() {
ArrayAdapter<String> dataAdapter1 = new ArrayAdapter<String>(Categorie.this,
android.R.layout.simple_spinner_item, list1);
spinner1.setAdapter(dataAdapter1);
spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
spinner1.setSelection(position);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
}
I'm trying to call the function getUrlContents(string) inside my seismic_text.java file to my MainActivity.java file. How can I call the function from anywhere in the file? Any information or tip is appreciated. I include my files down below.
This is my MainActivity.java:
package bt.alfaquake;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.app.NotificationManager;
import android.content.Intent;
import android.view.View;
import android.app.PendingIntent;
import android.support.v7.app.ActionBarActivity;
import android.support.v4.app.NotificationCompat;
import bt.alfaquake.seismic_text;
public class MainActivity extends AppCompatActivity {
NotificationCompat.Builder notification;
private static final int uniqueID = 123;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
notification = new NotificationCompat.Builder(this);
}
}
This is my seismic_text.java:
package bt.alfaquake;
import java.net.*;
import java.io.*;
public class seismic_text {
public static String getUrlContents(String theUrl) {
StringBuilder content = new StringBuilder();
try
{
URL url = new URL(theUrl);
URLConnection urlConnection = url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null)
{
content.append(line + "\n");
}
bufferedReader.close();
}
catch(Exception e)
{
e.printStackTrace();
}
return content.toString();
}
}
}
You can call seismic_text.getUrlContents(url); but it will cause NetworkOnMainThreadException
Just wrap this call to Simple AsynkTask.
class MyTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
try {
return seismic_text.getUrlContents(url);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// TODO handle result here
}
}
And call it from your code:
new MyTask().execute();
Simply call this in your MainActivty.java:
seismic_text.getUrlContents(url);