I am trying to have Android Studio read a text file from a URL into a string array. Then, use the URLS within Picasso to display a simple gallery. My attempts at achieving this are below.
My GrabData.java script:
public class GrabData
{
static public String[] LIST = {};
public static void main(String[] args)
{
ReadFile rf = new ReadFile();
// The text file.
String filename = "http://www.example.com/my/website/directory/thefile.txt";
try
{
String[] LIST = rf.readLines(filename);
for (String line : LIST)
{
System.out.println(LIST);
}
}
catch(IOException e)
{
System.out.println("ReadFile : Unable to create "+filename+": "+e.getMessage());
}
}
}
My ReadFile.java script:
public class ReadFile extends Activity
{
public String[] readLines(String filename) throws IOException
{
FileReader fileReader = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(fileReader);
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = bufferedReader.readLine()) != null)
{
lines.add(line);
}
bufferedReader.close();
return lines.toArray(new String[lines.size()]);
}
}
However, when I try to use a URL in the filename string, it doesn't display any images on the gallery, which is able to load from arrays. I am guessing this method can't read URLS. If anyone has any help on how to get this, it is much appreciated.
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new MyAsyncFileReader().execute("http://www.example.com/my/website/directory/thefile.txt");
}
public static class MyAsyncFileReader extends AsyncTask<String, Void,String []>
{
#Override
protected String [] doInBackground(String... params){
String url= params[0];
List<String> lines = new ArrayList<String>();
try{
URL u= new URL(url);
HttpURLConnection conn= (HttpURLConnection) u.openConnection();
InputStream is= conn.getInputStream();
BufferedReader br =new BufferedReader(new InputStreamReader(is));
String line=null;
while((line=br.readLine())!=null){
lines.add(line);
}
br.close();
}catch(Exception e){
}
return lines.toArray(new String[lines.size()]);
}
#Override
protected void onPostExecute(String[] strings) {
//You will get your string array result here .
// do whatever operations you want to do
for(int i=0;i<strings.length;i++){
Log.e("LOG", strings[i]);
}
}
}
}
This is how it looks in My Activity . Use similarly in you activity.
My edits: Made the MyAsyncFileReader class public and static to be read through other activities.
Related
I'm trying to pass the matchday to the URL for the Http connection. I know I can't get a value from the EditText in the doInBackground method so I thought to get the value in the onPreExecute method. Of I then add the variable to the URL, the program doesn't recognise the String. I saw on StackOverflow you need to add the parameters in the execute method but I don't really have got that part of the explanation.
Does anyone have an idea how to add the matchday to the URL, entered in the EditText matchdayText?
Thanks in advance!
Rob Nickmans
CODE:
package ga.rndevelopment.footballpronostics;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
EditText matchdayText;
TextView responseView;
ProgressBar progressBar;
static final String API_KEY = "HIDDEN";
static final String API_URL = "http://api.football-data.org/v2/competitions/PL/matches/?matchday=";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
responseView = findViewById(R.id.responseView);
matchdayText = findViewById(R.id.matchdayText);
progressBar = findViewById(R.id.progressBar);
Button queryButton = findViewById(R.id.queryButton);
queryButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new FetchData().execute();
}
});
}
class FetchData extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
progressBar.setVisibility(View.VISIBLE);
responseView.setText("");
String matchDay = matchdayText.getText().toString();
String apiUrl = API_URL + matchDay;
}
#Override
protected String doInBackground(Void... params) {
try {
URL url = new URL(apiUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.addRequestProperty("X-Auth-Token", API_KEY);
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
bufferedReader.close();
return stringBuilder.toString();
} finally {
urlConnection.disconnect();
}
} catch (Exception e) {
Log.e("ERROR", e.getMessage(), e);
return null;
}
}
#Override
protected void onPostExecute(String response) {
if (response == null) {
response = "THERE WAS AN ERROR";
}
progressBar.setVisibility(View.GONE);
Log.i("INFO", response);
responseView.setText(response);
}
}
}
First Create the connection using URL Connection.There by create
buffer writer and pass the all requested data in one single String
buffer variable there by it will take to concern URL and along with
Requested parameter and its values. Please go Through this Below
sample Example
URL url = new URL("give your URL ");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
final StringBuilder reqstData = new StringBuilder(100);
reqstData.append("&userId=").append(userId);
reqstData.append("&roleId=").append(roleId);
reqstData.append("&userName=").append(userName);
out.write(reqstData);
out.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
I am learning android development and in a tutorial i am following demonstrated how to download a web page and print it into logs with AsyncTask class but the problem is, app is hanging ( ui elements not appearing neither in emulator nor in my phone ) and when the ui elements appear ( after a long time say 5 minutes) the html source in log is not showing
here is the code
package com.example.slimshady.downloadhtml;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
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 javax.net.ssl.HttpsURLConnection;
public class MainActivity extends AppCompatActivity {
public class DownloadTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... buttoks) {
URL url;
HttpURLConnection httpURLConnection = null;
String result = "";
// try catch for if malformed url
try {
url = new URL(buttoks[0]);
httpURLConnection = (HttpURLConnection)url.openConnection();
InputStream in = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while(data != -1)
{
char current = (char)data;
result+=current;
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
return "failed";
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadTask downloadTask = new DownloadTask();
try {
String content = downloadTask.execute("https://www.google.com").get();
Log.i("returned STring", content.toString());
}catch (Exception e)
{
e.printStackTrace();
}
}
}
everything seems ok but still no html source logging and what can be the cause for the ui elements appearing alot later than they should ? i mean the whole reason for an AsyncTask is that they run independent of the main thread so the ui elements are not effected by the task am i right ?
The issue is , you are invoking get which will block your thread until you get the response so simply use
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadTask().downloadTask.execute("https://www.google.com");
}
and update UI in onPostExecute
You can also improve the code using StringBuffer and BufferReader as
public class DownloadTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... buttoks) {
URL url;
HttpURLConnection httpURLConnection = null;
String result = "";
StringBuffer buf = new StringBuffer();
// try catch for if malformed url
try {
url = new URL(buttoks[0]);
httpURLConnection = (HttpURLConnection)url.openConnection();
InputStream in = httpURLConnection.getInputStream();
BufferedReader reader =new BufferedReader(new InputStreamReader(in));
if (is != null) {
while ((result = reader.readLine()) != null) {
buf.append(result);
}
}
return buf.toString();
} catch (Exception e) {
e.printStackTrace();
return "failed";
}
}
#Override
... onPostExecute(String str){
// update UI here
}
}
//[(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
This is what I essentially want to do, but can't. I want the value of urlData and size to be updated from the inner class functions. The app is crashing by giving a Null Pointer Exception at the line where I try to access these variables from the CreateTextView() function.
package edu.ahduni.seas.gyapak;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import org.json.JSONException;
import org.json.JSONArray;
import org.json.JSONObject;
import android.util.Log;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
public ArrayList<Data> urlData; //Culprit 1
public int size; //no. of dirs + files, Culprit 2
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void parseJSON() throws JSONException {
ParseActivity parse = new ParseActivity();
String url = "RDovQWNhZGVtaWMvU2FuamF5IENoYXVkaGFyeQ==";
parse.execute(url);
CreateTextView();
Log.e("RETURNING JSON","RETURNING");
}
public void CreateTextView() {
TextView text = (TextView) findViewById(R.id.text);
text.setText(Integer.toString(size));
Button myButton = new Button(this);
if(urlData==null) //workaround for crash
return;
myButton.setText(urlData.get(0).getName());
LinearLayout ll = (LinearLayout)findViewById(R.id.textlayout);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
ll.addView(myButton, lp);
}
class ParseActivity extends AsyncTask<String, Void, ArrayList<Data>> {
InputStream is = null;
JSONArray jObj = null;
String json = "";
#Override
public void onPostExecute(ArrayList<Data> data) {
size = data.size(); //here!
}
#Override
protected ArrayList<Data> doInBackground(String... params) {
final String BASE_URL = "http://111.93.66.162/json/main.php?f=" + params[0];
HttpURLConnection urlConnection;
// Making HTTP request
try {
Log.e("OPENING: ", "URL");
URL url = new URL(BASE_URL);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
is = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (is == null) {
// Nothing to do.
return null;
}
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = in.readLine()) != null) {
buffer.append(line + "\n");
Log.e("JSON: ", line);
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
is.close();
json = buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
try {
return getData(json);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
public ArrayList<Data> getData(String jsonString) throws JSONException {
// try parse the string to a JSON object
final String EXT = "ext";
final String PATH = "path";
final String NAME = "name";
try {
jObj = new JSONArray(jsonString);
} catch (JSONException e) {
e.printStackTrace();
}
urlData = new ArrayList<Data>();
for (int i=0;i<jObj.length();i++) {
JSONObject obj = jObj.getJSONObject(i);
String ext = obj.getString(EXT);
String path = obj.getString(PATH);
String name = obj.getString(NAME);
urlData.add(new Data(ext,path,name)); //and here!
}
return urlData;
}
}
}
The inner class is not static, so it needs an instance of the enclosing class to be instantiated. Like so:
public class abcd {
static int x;
public static void main(String[] args) {
abcd o = new abcd(); // Create instance of abcd called 'o'
abcd.efgh o2 = o.new efgh(); // Use instance 'o' to create an instance of efgh
System.out.println(x); // 0
o2.ok();
System.out.println(x); // 5
}
class efgh {
public void ok() {
x = 5;
}
}
}
I'm trying to read in a text file of words into an array or String where I would be able to access each word. Separating the words if it comes in one long String is no issue but I have having some real problems reading the file. I am using Android Studio and the file is under the assets folder (app/app/src/main/assets/wordsEasy.txt)
So far I have the following code:
public String[] getWords(String difficulty){
ArrayList<String> wordList = new ArrayList<String>();
String[] words = new String[wordList.size()];
String wordList = getQuestions() //Location of error
//Haven't finished here but would consist of transferring the words in the String into an array
return words;
}
private static String getQuestions(Context ctx,String file_name) {
AssetManager assetManager = ctx.getAssets();
ByteArrayOutputStream outputStream = null;
InputStream inputStream = null;
try {
inputStream = assetManager.open(file_name);
outputStream = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, len);
}
outputStream.close();
inputStream.close();
} catch (IOException e) {
}
} catch (IOException e) {
}
return outputStream.toString();
}
I don't know how to get the context in this situation and would appreciate any help. Also if you know an alternative way to read the file to a String or array please share it.
Check this, working for me
import android.content.Context;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
List<String> wordList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wordList = getWordsFromFile("text_file.txt", MainActivity.this);
Toast.makeText(this,"Word Size:"+wordList.size(),Toast.LENGTH_SHORT).show();
TextView textView = (TextView) findViewById(R.id.tv_words);
for(String word : wordList){
textView.append("\n"+word);
}
}
public List<String> getWordsFromFile(String textFileName, Context context){
List<String> wordList = new ArrayList<>();
String textStr = "";
AssetManager am = context.getAssets();
try {
InputStream is = am.open(textFileName);
textStr = getStringFromInputStream(is);
} catch (IOException e) {
e.printStackTrace();
}
if(textStr !=null){
String[] words = textStr.split("\\s+");
for (int i = 0; i < words.length; i++) {
words[i] = words[i].replaceAll("[^\\w]", "");
wordList.add(words[i]);
}
}
return wordList;
}
private static String getStringFromInputStream(InputStream is) {
BufferedReader bufferedReader = null;
StringBuilder stringBuilder = new StringBuilder();
String line;
try {
bufferedReader = new BufferedReader(new InputStreamReader(is));
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return stringBuilder.toString();
}
}
Make sure your assets folder is in your "app" project and not the outer project
Then, you can get the file by simply using following code:
InputStream myFile = mContext.getAssets().open("myfile.txt");