I intended to fetch data from ConnectionClass in background and then populate it into recyclerView.
Now, I have successfully fetched the data from url in json format, but my app is crashing when I am trying to display data using recyclerView.
Adapter Class for recyclerview
package com.example.mainapp;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import Model.PersonDetails;
public class PersonDetailsAdapter extends RecyclerView.Adapter<PersonDetailsAdapter.ViewHolder> {
private List<PersonDetails> personDetails;
PersonDetailsAdapter(List<PersonDetails>details)
{
personDetails = details;
}
#NonNull
#Override
public PersonDetailsAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Log.d("create view " , personDetails.toString());
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context) ;
View personView = inflater.inflate(R.layout.person_details_view , parent , true) ;
ViewHolder view = new ViewHolder(personView) ;
return view;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
PersonDetails details = personDetails.get(position);
holder.nameTextView.setText(details.getName());
holder.aliasTextView.setText(details.getAlias());
}
#Override
public int getItemCount() {
return personDetails.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView nameTextView;
public TextView aliasTextView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
nameTextView = (TextView) itemView.findViewById(R.id.nameHolder);
aliasTextView = (TextView) itemView.findViewById(R.id.aliasHolder);
}
}
}
MainActivity.java
package com.example.mainapp;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.example.mainapp.Utility.ConnectionClass;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;
import java.net.MalformedURLException;
import java.util.List;
import Model.PersonDetails;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button getButton = findViewById(R.id.get);
Button postButton = findViewById(R.id.post);
Context context = this.getBaseContext();
getButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ConnectionClass conn = null;
try {
conn = new ConnectionClass("URL", context);
conn.execute();
} catch (MalformedURLException e) {
System.out.println("connection not set ");
e.printStackTrace();
}
}
});
postButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
postRequest();
}
}
);
}
public void updateView( List<PersonDetails> personDetails ) {
Log.d("1" , "******************************************called fro");
RecyclerView rView = (RecyclerView)findViewById(R.id.recyclerViewPerson);
Log.d("2" , "******************************************iosdjdsa");
PersonDetailsAdapter adapter = new PersonDetailsAdapter(personDetails);
rView.setLayoutManager(new GridLayoutManager(this, 5));
rView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
private void postRequest() {
}
}
ConnectionClass.java
package com.example.mainapp.Utility;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import com.example.mainapp.MainActivity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import Model.PersonDetails;
public class ConnectionClass extends AsyncTask<Void, Void, Void> {
private URL url ;
private HttpURLConnection conn;
private String response ;
private Context context ;
public ConnectionClass() {
super();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Log.d("onPost", "*****************************************postexe");
Toast.makeText(context, "Records fetched",Toast.LENGTH_SHORT);
List<PersonDetails> details = new ArrayList<>();
try {
JSONArray arr = new JSONArray(response);
for( int i = 0; i < arr.length() ; ++i )
{
JSONObject jObject = arr.getJSONObject(i);
PersonDetails record = new PersonDetails(jObject.getString("name"),jObject.getString("alias") );
details.add(record);
}
} catch (JSONException e) {
Log.d("t","json exception");
e.printStackTrace();
}
Log.d( "detalis", "**************************************"+details.toString());
MainActivity activity = new MainActivity();
activity.updateView(details);
}
public ConnectionClass(String url, Context context) throws MalformedURLException {
this.url = new URL (url);
conn = null ;
this.context = context;
}
// public void sendRequest(){
// try {
// System.out.println("\n\n***************************************hello**********************\n\n");
// conn = (HttpURLConnection) url.openConnection();
// conn.setDoOutput(false);
// conn.setDoInput(true);
// conn.setUseCaches(false);
// conn.setRequestMethod("GET");
// conn.setRequestProperty("Content-Type", "application/json");
// conn.connect();
// // handle the response
// System.out.println("\n\n***************************************here**********************\n\n");
//
// int status = conn.getResponseCode();
// System.out.println(status);
//
// if (status != 200)
// throw new IOException("Request not completed");
// else
// {
// BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
// String inputLine ;
// StringBuilder builder = new StringBuilder() ;
// while((inputLine = in.readLine()) != null )
// builder.append(inputLine);
// in.close();
// response = builder.toString();
// }
//
// }
// catch (IOException e) {
// e.printStackTrace();
// }
// finally{
// if( conn != null )
// conn.disconnect();
// }
// }
public void setUrl(String url) throws MalformedURLException {
this.url = new URL(url);
}
public String getResponse() {
return response;
}
#Override
protected Void doInBackground(Void... voids) {
try {
conn = (HttpURLConnection) url.openConnection();
Log.d("conn", "***************************************************************************connectioon set " ) ;
} catch (IOException e) {
e.printStackTrace();
}
try {
conn.setRequestMethod("GET");
} catch (ProtocolException e) {
e.printStackTrace();
}
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setDoOutput(true);
try {
conn.connect();
Log.d("conn " , "**********************************************************************connected ");
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
try{
br =new BufferedReader(new InputStreamReader(url.openStream()));
char[] buffer = new char[1024];
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
Log.d("sb" , String.valueOf(sb));
}
catch (IOException e)
{
e.printStackTrace();
}
finally{
Log.d("finally ", "*****************************************************************************************finally");
response = sb.toString();
System.out.println("JSON: " + response);
conn.disconnect();
}
return null ;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentTop="true"
android:layout_marginTop="-3dp">
<TextView
android:id="#+id/nameText"
android:layout_width="141dp"
android:layout_height="45dp"/>
<TextView
android:id="#+id/aliasText"
android:layout_width="141dp"
android:layout_height="45dp"
android:layout_marginLeft="119dp"
android:layout_toRightOf="#+id/nameText" />
<Button
android:id="#+id/post"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="-11dp"
android:layout_marginBottom="2dp"
android:text="POST" />
<Button
android:id="#+id/get"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="1dp"
android:layout_marginBottom="3dp"
android:text="GET" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewPerson"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#972A2A" />
</RelativeLayout>
xml for RecyclerView content
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="50dp"
android:padding="10dp">
<TextView
android:id="#+id/nameHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="TextView" />
<TextView
android:id="#+id/aliasHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="TextView" />
</LinearLayout>
Application is crashing when control reaches updateView()?
Add your AsyncTask code at the bottom of your MainActivity and then update the recyclerview like this:
updateView(details);
Let me clarify #sdex answer:
When you create an instance of Activity - in your case MainActivity - it doesn't have a view, it is not visible to the user and it's not added to the Activity stack. You could say - this activity is "Dead"
In order to display the result to your currently running MainActivity, so it's displayed to the user, you need to pass the instance of it to the ConnectionClass class. For example - pass it to the constructor of the ConnectionClass.
By the way - please consider moving away from AsyncTask, it's been deprecated and could be a reason for the Context leaks, meaning - you'll have massive objects, that are no more visible to the user are retaining in the memory.
In order to avoid leaking the Activity reference, please store it as the "WeakReference"
MainActivity activity = new MainActivity();
activity.updateView(details);
You can't instantiate activity like this; if you want to call a method in the activity within the AsynkTask class ConnectionClass; you can pass a listener to it and implement this listener in the activity, and then invoke the callback of that listener when you want to call some functionality in the activity.
interface ConnectionClassListener {
void onPostExecuteFinished(List<PersonDetails> personDetails);
}
Pass the class to the AsyncTask constructor
public class ConnectionClass extends AsyncTask<Void, Void, Void> {
ConnectionClassListener mConnectionClassListener;
public ConnectionClass(String url, Context context, ConnectionClassListener listener) throws MalformedURLException {
this.url = new URL (url);
conn = null ;
this.context = context;
mConnectionClassListener = listener;
}
Implement the listener by the activity
public class MainActivity extends AppCompatActivity implements ConnectionClassListener {
#Override
void onPostExecuteFinished(List<PersonDetails> personDetails) {
// Do here what you want when the ConnectionClass calls `onPostExecuteFinished()`
updateView(personDetails);
}
}
add this when creating the AsynkTask class
conn = new ConnectionClass("URL", context, this);
And finally call onPostExecuteFinished() in your ConnectionClass
public class ConnectionClass extends AsyncTask<Void, Void, Void> {
// ...
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// ...
mConnectionClassListener.onPostExecuteFinished(details);
MainActivity activity = new MainActivity();
You cannot just create the instance using the constructor. You should pass a reference of MainActivity to make it work. You need just to change a few lines of the code:
In ConnectionClass replace field private Context context; by private MainActivity activity; and change the constructor accordingly:
public ConnectionClass(String url, MainActivity activity) throws MalformedURLException {
this.url = new URL (url);
conn = null ;
this.activity = activity;
}
After that, you will be able to call activity.updateView(details);.
And don't forget to remove MainActivity activity = new MainActivity();
Further reading:
Proper use of AsyncTask
AsyncTask deprecation and alternatives
Related
In my activity, I want to take voice input when we click imageView and convert into text and display it in textfield and after we press button it converts it into french(currently it is fixed) and display it in textfield2.
I am using yandex translator.
My error::
When I click button for the first time nothing happens in textfield2 but in log, it display the correct translation.After my 2nd click,it changes the textfield2. But i want to show the translation after 1st click only.Why it is taking 2 click for working while my output is coming correct after 2nd click??
here is my XML file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:layout_centerHorizontal="true"
android:layout_below="#+id/textView"
tools:layout_editor_absoluteX="131dp"
tools:layout_editor_absoluteY="202dp" />
<ImageView
android:id="#+id/imageView"
android:layout_centerHorizontal="true"
android:layout_width="267dp"
android:layout_height="244dp"
app:srcCompat="#android:drawable/ic_btn_speak_now" />
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:layout_below="#+id/imageView"
android:layout_centerHorizontal="true"
android:text="Text to be Translated" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/button"
android:text="Translated Text"
android:textSize="30sp"
/>
</RelativeLayout>
Here is my MainActivty:
package com.example.translator;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
final static int REQUEST_CODE_SPEECH=1000;
ImageView listen;
TextView ans,mresult;
Context context=this;
Button b;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listen=findViewById(R.id.imageView);
ans=findViewById(R.id.textView);
mresult=findViewById(R.id.textView2);
b=findViewById(R.id.button);
listen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
speak();
}
});
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String textToBeTranslated = ans.getText().toString();
String languagePair = "en-fr"; //English to French ("<source_language>-<target_language>")
//Executing the translation function
Translate(textToBeTranslated,languagePair);
}
});
}
void Translate(String textToBeTranslated,String languagePair){
TranslatorBackgroundTask translatorBackgroundTask= new TranslatorBackgroundTask(context);
if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.HONEYCOMB) {
translatorBackgroundTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,textToBeTranslated,languagePair);
} else {
translatorBackgroundTask.execute(textToBeTranslated,languagePair);
}
Log.d("Translation Result:", translatorBackgroundTask.t); // Logs the result in Android Monitor
mresult.setText(translatorBackgroundTask.t);
}
void speak(){
Intent intent=new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "hi say something!!!");
try{
startActivityForResult(intent,REQUEST_CODE_SPEECH);
}
catch(Exception e) {
Toast.makeText(MainActivity.this, "" + e.getMessage(),Toast.LENGTH_LONG).show();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case REQUEST_CODE_SPEECH:{
if(resultCode==RESULT_OK && data!=null) {
ArrayList<String>result=data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
ans.setText(result.get(0));
}
break;
}
}
}
}
Here is my API File:
package com.example.translator;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
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;
public class TranslatorBackgroundTask extends AsyncTask<String, Void, String> {
//Declare Context
Context ctx;
public static String t="";
//Set Context
TranslatorBackgroundTask(Context ctx){
this.ctx = ctx;
}
#Override
public String doInBackground(String... params) {
//String variables
String textToBeTranslated = params[0];
String languagePair = params[1];
String jsonString;
try {
//Set up the translation call URL
String yandexKey = "MY-API-KEY";
String yandexUrl = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=" + yandexKey
+ "&text=" + textToBeTranslated + "&lang=" + languagePair;
URL yandexTranslateURL = new URL(yandexUrl);
//Set Http Conncection, Input Stream, and Buffered Reader
HttpURLConnection httpJsonConnection = (HttpURLConnection) yandexTranslateURL.openConnection();
InputStream inputStream = httpJsonConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
//Set string builder and insert retrieved JSON result into it
StringBuilder jsonStringBuilder = new StringBuilder();
while ((jsonString = bufferedReader.readLine()) != null) {
jsonStringBuilder.append(jsonString + "\n");
}
//Close and disconnect
bufferedReader.close();
inputStream.close();
httpJsonConnection.disconnect();
//Making result human readable
String resultString = jsonStringBuilder.toString().trim();
//Getting the characters between [ and ]
resultString = resultString.substring(resultString.indexOf('[')+1);
resultString = resultString.substring(0,resultString.indexOf("]"));
//Getting the characters between " and "
resultString = resultString.substring(resultString.indexOf("\"")+1);
resultString = resultString.substring(0,resultString.indexOf("\""));
Log.d("Translation Result:", resultString);
t=resultString;
return jsonStringBuilder.toString().trim();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
I think it's this line:
mresult.setText(TranslatorBackgroundTask.t);
Shouldn't it be:
mresult.setText(translatorBackgroundTask.t);
I'm making a simple program where I can get a content from JSON in this url
https://www.haliminfo.com/feeds/posts/summary/?max-results=10&start-index=1&alt=json
and make it a list Using RecyclerView on Android.
I have made several necessary components such as Model, Adapter, Post Row Item and HttpHandler
when I try RecyclerView with a method like this it works.
private void addData () {
postsArrayList = new ArrayList <> ();
postsArrayList.add (new Posts ("TITLE", "SUMMARY"));
}
but when I apply the method below nothing appears in the activity
private class getContent extends AsyncTask <Void, Void, Void> {
# Override
protected Void doInBackground (Void ... voids) {
HttpHandler sh = new HttpHandler ();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall (URL_FIX);
if (jsonStr! = null) {
try {
JSONObject jsonObj = new JSONObject (jsonStr);
JSONObject feed = jsonObj.getJSONObject ("feed");
JSONArray entry = feed.getJSONArray ("entry");
Posts postsModel = new Posts ();
for (int i = 0; i <entry.length (); i ++) {
postsModel.setTitle (entry.getJSONObject (i) .getJSONObject ("title"). getString ("$ t"));
postsModel.setSummary (entry.getJSONObject (i) .getJSONObject ("summary"). getString ("$ t"));
postsArrayList.add (postsModel);
}
} catch (final JSONException e) {
Log.e ("RESPONSE", "Json parsing error:" + e.getMessage ());
runOnUiThread (new Runnable () {
# Override
public void run () {
Toast.makeText (getApplicationContext (),
"Json parsing error:" + e.getMessage (),
Toast.LENGTH_LONG)
.show ();
}
});
}
} else {
Log.e ("RESPONSE", "Couldn't get json from server.");
runOnUiThread (new Runnable () {
# Override
public void run () {
Toast.makeText (getApplicationContext (),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show ();
}
});
}
return null;
}
}
this is a full file of some important files in my project
MainActivity.java
package com.badjing.bloggercoba.activities;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.badjing.bloggercoba.R;
import com.badjing.bloggercoba.adapter.PostRecyclerViewAdapter;
import com.badjing.bloggercoba.config.Config;
import com.badjing.bloggercoba.handler.HttpHandler;
import com.badjing.bloggercoba.model.Posts;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private PostRecyclerViewAdapter postAdapter;
private ArrayList<Posts> postsArrayList;
private ProgressDialog pDialog;
private Config config = new Config();
String URL_FIX = Config.BLOG_URL + Config.BLOG_URL_MAX_RESULT + Config.MAX_RESULT + config.BLOG_URL_START_INDEX + config.START_INDEX + config.BLOG_URL_ALT_TYPE;;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
postsArrayList = new ArrayList<>();
new getContent().execute();
recyclerView = (RecyclerView) findViewById(R.id.post_recycle_view);
postAdapter = new PostRecyclerViewAdapter(postsArrayList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(postAdapter);
}
// private void addData() {
//
// postsArrayList = new ArrayList<>();
// postsArrayList.add(new Posts("JUDUL", "SUMMARY"));
//
// }
private class getContent extends AsyncTask<Void, Void, Void> {
// #Override
// protected void onPreExecute() {
// super.onPreExecute();
// // Showing progress dialog
// pDialog = new ProgressDialog(MainActivity.this);
// pDialog.setMessage("Please wait...");
// pDialog.setCancelable(false);
// pDialog.show();
// }
#Override
protected Void doInBackground(Void... voids) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(URL_FIX);
if (jsonStr != null) {
try{
JSONObject jsonObj = new JSONObject(jsonStr);
JSONObject feed = jsonObj.getJSONObject("feed");
JSONArray entry = feed.getJSONArray("entry");
Posts postsModel = new Posts();
for (int i = 0; i < entry.length(); i++) {
postsModel.setTitle(entry.getJSONObject(i).getJSONObject("title").getString("$t"));
postsModel.setSummary(entry.getJSONObject(i).getJSONObject("summary").getString("$t"));
postsArrayList.add(postsModel);
}
} catch (final JSONException e) {
Log.e("RESPONSE", "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e("RESPONSE", "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
}
private void urlBuilder() {
URL_FIX = Config.BLOG_URL + Config.BLOG_URL_MAX_RESULT + 10 + config.BLOG_URL_START_INDEX + 1 + config.BLOG_URL_ALT_TYPE;
}
}
Post.java (post model)
package com.badjing.bloggercoba.model;
public class Posts {
String title;
String summary;
public Posts() {
}
public Posts(String title, String summary) {
this.title = title;
this.summary = summary;
}
public String getTitle() {
return title;
}
public String getSummary() {
return summary;
}
public void setTitle(String title) {
this.title = title;
}
public void setSummary(String summary) {
this.summary = summary;
}
}
PostRecyclerViewAdapter.java
package com.badjing.bloggercoba.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.badjing.bloggercoba.R;
import com.badjing.bloggercoba.model.Posts;
import java.util.ArrayList;
public class PostRecyclerViewAdapter extends RecyclerView.Adapter<PostRecyclerViewAdapter.MyViewHolder> {
private ArrayList<Posts> postsList;
public PostRecyclerViewAdapter(ArrayList<Posts> postsArrayList) {
this.postsList = postsArrayList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.post_row_item, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.blog_post_title.setText(postsList.get(position).getTitle());
holder.blog_post_sumary.setText(postsList.get(position).getSummary());
}
#Override
public int getItemCount() {
return (postsList!= null) ? postsList.size() : 0;
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView blog_post_title, blog_post_sumary, blog_post_author;
ImageView img_thumbnail;
public MyViewHolder(View itemView) {
super(itemView);
blog_post_title = itemView.findViewById(R.id.blog_post_title);
blog_post_sumary = itemView.findViewById(R.id.blog_post_sumary);
// blog_post_author = itemView.findViewById(R.id.blog_post_author);
// img_thumbnail = itemView.findViewById(R.id.post_thumbnail);
}
}
}
post_row_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_marginTop="5dp"
android:padding="8dp"
android:background="#fff">
<ImageView
android:id="#+id/post_thumbnail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/loading_shape"></ImageView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="230dp"
android:orientation="vertical"
android:layout_margin="8dp" >
<TextView
android:id="#+id/blog_post_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="blog post title"
android:textSize="20dp"
android:textStyle="bold"/>
<TextView
android:id="#+id/blog_post_sumary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="blog post summary"/>
<TextView
android:id="#+id/blog_post_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="~ author"/>
</LinearLayout>
</LinearLayout>
thank you for your attention and help.
I have created an app that displays a list of 10 books based on a query keyword entered by the user.
I have used an EditText View for the user to enter the query.
I have also used an ImageButton for the search button.
I have used a custom class that extents AsyncTaskLoader to load content to my ListView.
I have called the initloader() method from the MainActivity of the app and has called my custom loader from the OnCreateLoader override method.
I want the loader to fetch the data only on a button click and not automatically when the activity starts.
Main Activity
package com.example.shara.booklistapp;
import android.app.LoaderManager;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import static android.app.LoaderManager.*;
import static com.example.shara.booklistapp.BookQueryUtils.LOG_TAG;
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Blist>> {
private ListAdapter mAdapter;
private static final int BOOK_LOADER_ID = 1;
private String Book_list_request_url = "Michael Jackson";
private ProgressBar progressBar;
private NetworkInfo networkInfo;
private TextView emptytextview;
private EditText editText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView booklistview = findViewById(R.id.list);
progressBar = findViewById(R.id.progressbar);
mAdapter = new ListAdapter(this, new ArrayList<Blist>());
booklistview.setAdapter(mAdapter);
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
networkInfo = connectivityManager.getActiveNetworkInfo();
emptytextview = (TextView) findViewById(R.id.emptytextview);
editText = findViewById(R.id.search_query_text_view);
booklistview.setEmptyView(emptytextview);
booklistview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Blist currentBook = mAdapter.getItem(position);
Uri currentbookk = Uri.parse(currentBook.getUrl());
startActivity(new Intent(Intent.ACTION_VIEW, currentbookk));
}
});
LoaderManager loaderManager = getLoaderManager();
loaderManager.initLoader(BOOK_LOADER_ID, null, this);
}
//Overriding the abstract methods of the Loadermanager
#Override
public Loader<List<Blist>> onCreateLoader(int id, Bundle bundle) {
Log.i(LOG_TAG, Book_list_request_url);
return new BlistLoader(this, Book_list_request_url);
}
#Override
public void onLoadFinished(Loader<List<Blist>> loader, List<Blist> blists) {
progressBar.setVisibility(View.GONE);
//Using the networkInfo variable declared earlier to check whether the system has internet connectivity and displays a message if there isn't one.
if (networkInfo == null) {
emptytextview.setText(R.string.no_network);
} else {
emptytextview.setVisibility(View.GONE);
}
mAdapter.clear();
if (blists != null && !blists.isEmpty()) {
mAdapter.addAll(blists);
}
}
#Override
public void onLoaderReset(Loader loader) {
Log.i(LOG_TAG, "Testing: onLoaderReset is successfully called");
mAdapter.clear();
}
}
Custom Loader class
package com.example.shara.booklistapp;
import android.content.AsyncTaskLoader;
import android.content.Context;
import android.util.Log;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import org.json.JSONException;
import java.io.IOException;
import java.util.List;
public class BlistLoader extends AsyncTaskLoader<List<Blist>> {
private static final String LOG_TAG = BaseAdapter.class.getName();
private String mUrl;
public BlistLoader(Context context, String url) {
super(context);
mUrl = url;
}
#Override
protected void onStartLoading() {
Log.i(LOG_TAG, "Testing: onStartLoading is successfully called");
forceLoad();
}
#Override
public List<Blist> loadInBackground() {
Log.i(LOG_TAG, "Testing: loadInBackground is successfully called");
if (mUrl == null) {
return null;
}
List<Blist> blists = null;
try {
blists = BookQueryUtils.fetchBookList(mUrl);
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return blists;
}
}
XML that contains the ImageButton
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal">
<EditText
android:id="#+id/search_query_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:hint="#string/hint" />
<ImageButton
android:id="#+id/search_button1"
android:layout_width="42dp"
android:layout_height="42dp"
android:src="#drawable/search" />
</LinearLayout>
<TextView
android:id="#+id/result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:backgroundTint="#color/colorPrimaryDark"
android:backgroundTintMode="add"
android:text="Results" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:dividerHeight="1dp" />
<ProgressBar
android:id="#+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<TextView
android:id="#+id/emptytextview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="" />
</RelativeLayout>
</LinearLayout>
I want the oncreateloader method to only execute when the search button is clicked and not otherwise.
How can this be achieved? Does my code need heavy modification or is it just something that I missed altogether.
I have previously asked the same question here but I didn't get any answers.
Any help would be greatly appreciated.
Book query utils is for the HTTP request and JSON parsing.
package com.example.shara.booklistapp;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
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.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* Created by shara on 12/17/2017.
*/
public final class BookQueryUtils {
public static final String LOG_TAG = BookQueryUtils.class.getName();
private BookQueryUtils() {
}
private static URL createURL(String search_query) throws MalformedURLException {
URL url = null;
String q = "q";
try {
final String base_URL = "https://www.googleapis.com/books/v1/volumes?";
Uri final_Url = Uri.parse(base_URL).buildUpon()
.appendQueryParameter(q, search_query)
.build();
url = new URL(final_Url.toString());
Log.i(LOG_TAG, "The final Url is" + url);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Url could not be formed", e);
}
return url;
}
private static String theHTTPRequest(URL url) throws IOException {
String jsonResponse = "";
if (url == null) {
return jsonResponse;
}
HttpURLConnection connectionUrl = null;
InputStream theInputStream = null;
try {
connectionUrl = (HttpURLConnection) url.openConnection();
connectionUrl.setReadTimeout(10000);
connectionUrl.setConnectTimeout(15000);
connectionUrl.setRequestMethod("GET");
connectionUrl.connect();
if (connectionUrl.getResponseCode() == 200) {
theInputStream = connectionUrl.getInputStream();
jsonResponse = readFromStream(theInputStream);
} else {
Log.e(LOG_TAG, "could not make the connection");
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem getting the requested data", e);
} finally {
if (connectionUrl != null) {
connectionUrl.disconnect();
}
if (theInputStream != null) {
theInputStream.close();
}
}
return jsonResponse;
}
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder streamoutput = new StringBuilder();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String urlline = bufferedReader.readLine();
while (urlline != null) {
streamoutput.append(urlline);
urlline = bufferedReader.readLine();
}
return streamoutput.toString();
}
private static List<Blist> extractFeatureFromJSON(String BlistJSON) throws JSONException {
if (TextUtils.isEmpty(BlistJSON)) {
return null;
}
List<Blist> blists = new ArrayList<>();
try {
String a = "";
JSONObject baseJSON = new JSONObject(BlistJSON);
JSONArray items = baseJSON.getJSONArray("items");
for (int i = 0; i < items.length(); i++) {
Blist blistss = new Blist();
JSONObject j = items.getJSONObject(i);
JSONObject vInfo = j.getJSONObject("volumeInfo");
if (vInfo.has("authors")) {
JSONArray athrs = vInfo.getJSONArray("authors");
if (athrs.length() != 0) {
for (int k = 0; k < athrs.length(); k++) {
a = athrs.getString(k);
blistss.setAuthor(a);
}
}
}
if (vInfo.has("imageLinks")) {
JSONObject thumbnail = vInfo.getJSONObject("imageLinks");
blistss.setImage(thumbnail.getString("thumbnail"));
}
blistss.setUrl(vInfo.getString("previewLink"));
blistss.setTitle(vInfo.getString("title"));
blistss.setPublisher(vInfo.getString("publisher"));
blists.add(blistss);
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Could not parse JSON", e);
}
return blists;
}
public static List<Blist> fetchBookList(String query_url) throws IOException, JSONException {
URL url = createURL(query_url);
String JSONResponse = null;
try {
JSONResponse = theHTTPRequest(url);
} catch (IOException e) {
Log.e(LOG_TAG, "Could not fetch data");
}
List<Blist> blists = extractFeatureFromJSON(JSONResponse);
return blists;
}
}
This is my adapter for the listview.
package com.example.shara.booklistapp;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.SearchView;
import android.widget.TextView;
import java.io.InputStream;
import java.util.ArrayList;
/**
* Created by shara on 12/17/2017.
*/
public class ListAdapter extends ArrayAdapter<Blist> {
private ProgressBar progressBar;
public ListAdapter(#NonNull Context context, ArrayList<Blist> blists) {
super(context, 0, blists);
}
public String rslt;
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View listitemview = convertView;
if (listitemview == null) {
listitemview = LayoutInflater.from(getContext()).inflate(R.layout.list_layout, parent, false);
}
Blist blist = getItem(position);
ImageView thumbnail = listitemview.findViewById(R.id.thumbnail_imageview);
new imageLoader(thumbnail).execute(blist.getImage());
progressBar = listitemview.findViewById(R.id.Image_Progress_bar);
progressBar.setVisibility(View.GONE);
TextView title = listitemview.findViewById(R.id.title_textview);
title.setText(blist.gettitle());
TextView author = listitemview.findViewById(R.id.author_textview);
author.setText(blist.getauthor());
TextView publisher = listitemview.findViewById(R.id.publisher_texview);
publisher.setText(blist.getpublisher());
return listitemview;
}
private class imageLoader extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public imageLoader(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
Updated in Code
Initially set empty query
private String Book_list_request_url = "";
Create method for "Search Click(imagebutton)"
public void Search(View v)
{
Book_list_request_url = editText.getText().toString();
loaderManager.restartLoader(BOOK_LOADER_ID, null, this);
}
Add method to imagebutton
<ImageButton
android:id="#+id/search_button1"
android:layout_width="42dp"
android:layout_height="match_parent"
android:onClick="Search"
android:src="#drawable/ic_launcher_background" />
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
Hi I am learning Android App Development. For this, I wanted to make myself a simple wallpaper app. Hence, I wrote something roughly which is presented here. I want to get wallpaper urls from json. Unfortunately, I am unable to get data from my server. java.lang.NullPointerException: Attempt to read from null array
How do I get the data correctly from the jsonParse asynctask?
I am stuck on this the whole day. What could have gone wrong here?
Here is my code:
myjson.json:
{
"walls":[
{"ourUrl":"http://www.hdbloggers.net/wp-content/uploads/2016/01/Wallpapers-for-Android.jpg"},
{"ourUrl":"http://androidwallpape.rs/content/02-wallpapers/131-night-sky/wallpaper-2707591.jpg"},
{"ourUrl":"http://androidwallpape.rs/content/02-wallpapers/155-starrynight/starry-night-sky-star-galaxy-space-dark-9-wallpaper.jpg"}
]
}
MainActivity.java:
package regalstreak.me.wallpapers;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
public class MainActivity extends Activity {
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
RecyclerView.Adapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new RecyclerAdapter(this);
recyclerView.setAdapter(adapter);
}
}
RecyclerAdapter.java:
package regalstreak.me.wallpapers;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
// This is a recycleradapter which will set the correct images to the correct position in the recyclerview.
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private Context myCtx1;
String[] arr;
String[] arrurl;
String jsonURL = "http://dev.regalstreak.me/myjson.json";
public RecyclerAdapter(Context ctx) {
this.myCtx1 = ctx;
}
public ImageView Image;
private String[] mText = {
"Text 1",
"Text 2",
"Text 3"
};
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView Text;
public ViewHolder(View itemView) {
super(itemView);
Image = (ImageView) itemView.findViewById(R.id.image_view);
Text = (TextView) itemView.findViewById(R.id.text_view);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.wallpapers_list, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.Text.setText(mText[i]);
new jsonParse().execute();
new DownloadImageTask(Image).execute(arrurl[i]);
}
#Override
public int getItemCount() {
return mText.length;
}
class jsonParse extends AsyncTask<String, Void, String[]> {
protected String[] doInBackground(String[] urls) {
String myText = null;
String url = urls[0];
String ourUrl;
try {
InputStream in = new java.net.URL(jsonURL).openStream();
myText = IOUtils.toString(in, "utf-8");
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
// Parse the json
List<String> allUrls = new ArrayList<String>();
JSONObject jsonObjectRoot = new JSONObject(myText);
JSONArray jsonArray = jsonObjectRoot.getJSONArray("walls");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
ourUrl = jsonObject.getString("ourUrl");
allUrls.add(ourUrl);
}
arr = allUrls.toArray(new String[allUrls.size()]);
} catch (JSONException e) {
e.printStackTrace();
}
return arr;
}
protected void onPostExecute(String[] result){
arrurl = result;
}
}
}
DownloadImageTask.java:
package regalstreak.me.wallpapers;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
import java.io.InputStream;
// Here, we will download the wallpapers obtained from jsonData with an asynctask.
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap>{
ImageView bmImage;
public DownloadImageTask(ImageView bmImage){
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
in.close();
} catch (Exception e) {
Log.e("Error getting images.", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result){
bmImage.setImageBitmap(result);
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="regalstreak.me.wallpapers.MainActivity">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/recycler_view" />
</RelativeLayout>
wallpaper_list.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relative"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp">
<ImageView
android:id="#+id/image_view"
android:layout_width="match_parent"
android:layout_height="150dp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/image_view"
android:alpha="0.6"
android:background="#color/colorDivider"
android:padding="9dp">
<TextView
android:id="#+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textColor="#color/colorPrimaryText" />
</RelativeLayout>
</RelativeLayout>
I have used HttpURLConnection class here for quick response and features like cache. The data received from the URL is being added to an input stream which we then convert to a String builder to get a string object which we can further use with the JSON classes.
PS - Add the AsyncTask code to your MainActivity itself, don't make a separate java file for this.
Tip - Always verify the json using this tool - jsonlint.com
MainActivity
/*
your code
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
new MyAsyncTask().execute("");
}
class MyAsyncTask extends AsyncTask<String, String, Void> {
private ProgressDialog progressDialog = new ProgressDialog(StartScreen.this);
InputStream inputStream = null;
String result = "";
ArrayList<String> list;
protected void onPreExecute() {
progressDialog.setTitle("Downloading JSON Data");
progressDialog.show();
// above code makes a dialog with a progress bar
}
#Override
protected Void doInBackground(String... params) {
ArrayList<String> param = new ArrayList<String>();
URL url, url2;
try{
url = new URL("http://dev.regalstreak.me/myjson.json");
// link to your json file
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setUseCaches(false);
inputStream = new BufferedInputStream(urlConnection.getInputStream());
}catch (MalformedURLException malle){
Log.e("Mal", ""+malle);
malle.printStackTrace();
}catch (IOException ioe){
Log.e("IO", ""+ioe);
ioe.printStackTrace();
}
// Convert response to string using String Builder
try {
BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"), 8);
StringBuilder sBuilder = new StringBuilder();
String line = null;
while ((line = bReader.readLine()) != null) {
sBuilder.append(line + "\n");
}
inputStream.close();
result = sBuilder.toString();
} catch (Exception e) {
Log.e("StringBuilding", "Error converting result " + e.toString());
}
return null;
}
protected void onPostExecute(Void v) {
//parse JSON data
try {
JSONObject jobj = new JSONObject(result);
//Taking a JSON Array from the JSONObject created above
String url = jobj.getString("ourUrl");
// We are adding this string to the ArrayList
list.add(url);
progressDialog.dismiss();
Context con = ListLoader.this.getApplication();
adapter = new RecyclerAdapter(list,con);
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
Log.e("JSONException", "Error: " + e.toString());
} // catch (JSONException e)
}
}
/*
your code
*/
Now to display the images more effectively in the list, use the repo Universal image loader. It has a lot of features. You can get it here - https://github.com/nostra13/Android-Universal-Image-Loader
And then add this kind of code to display the images. Put it inside the onBindViewHolder
Adapter
#Override
public void onBindViewHolder(DataHolder holder, int position) {
ImageLoaderConfiguration config;
config = new ImageLoaderConfiguration.Builder(mContext).build();
ImageLoader.getInstance().init(config);
imageLoader = ImageLoader.getInstance();
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_error_black_48dp) // displays this image not found
.showImageOnFail(R.drawable.ic_error_black_48dp) // Displays this on failure
.showImageOnLoading(R.drawable.white) // Displays while loading
.cacheInMemory(false)
.cacheOnDisk(true)
.build();
imageLoader.displayImage(list.get(position), holder.imageView, options);
// We are feeding the urls here.
}
I developed an app to connect my android app to remote server and display data in listview.
I did everything but the data doesn't show up in the listview.
These are the files I used to accomplish that, please help me:
MediaActivity.java
package com.shadatv.shada;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Locale;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.ParseException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MediaActivity extends OptionsMenu {
Locale locale;
// boolean mybooks;
Configuration config = new Configuration();
static SharedPreferences sharedPreferenceid;
static SharedPreferences.Editor editorid;
public static final String Myid = "Myid";
String myid = "";
InputStream is = null;
StringBuilder sb = null;
String resultt = "";
JSONArray jArray;
String result = null;
public DAOCanticles cantDatabase = null;
int numberofrowssss;
int responseCode;
String targetcover, targetbname, targetauthname;
public String caNameField = "", caLinkField = "", caImgField = "";
// ///////////////////ONLINE BESTSALED//////////////////////
String caNameJson, caLinkJson, caImgJson;
public ArrayList<String> caNameHolder = new ArrayList<String>();
public ArrayList<String> caLinkHolder = new ArrayList<String>();
public ArrayList<String> caImgHolder = new ArrayList<String>();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.media);
cantDatabase = new DAOCanticles(this);
new LoadData().execute();
}
// =============================================================================
public void onClickPrograms(View view) {
startActivity(new Intent("com.shadatv.ProgramsActivity"));
}
// =============================================================================
public void onClickCanticles(View view) {
startActivity(new Intent("com.shadatv.CanticlesActivity"));
}
// =============================================================================
public void onClickDocumentaries(View view) {
startActivity(new Intent("com.shadatv.DocumentariesActivity"));
}
// =============================================================================
private class LoadData extends AsyncTask<Void, Void, Void> {
public ProgressDialog progressDialog1;
#Override
protected Void doInBackground(Void... params) {
cantDatabase.deletetable();
getCanticlesByJSON();
addCanticles();
return null;
}
#Override
// can use UI thread here
protected void onPreExecute() {
CharSequence contentTitle = getString(R.string.loading);
this.progressDialog1 = ProgressDialog.show(MediaActivity.this, "",
contentTitle);
}
// -------------------------------------------//
#Override
protected void onPostExecute(final Void unused) {
this.progressDialog1.dismiss();
}
}
// =============================================================================
public void getCanticlesByJSON() {
try {
HttpClient httpclient = new DefaultHttpClient();
try {
} catch (Exception e) {
Log.e("my_log_tag", e.toString());
}
// buffered reader
try {
HttpPost httppost = new HttpPost(
"http://dt-works.com/ags/shadatv/canticles/android_data");
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "UTF-8"), 80);
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line = "0";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = EntityUtils.toString(entity);
//result = sb.toString();
} catch (Exception e) {
Log.e("my_log_tag", e.toString());
}
try {
result = result.substring(1);
jArray = new JSONArray(result);
JSONObject json_data = null;
for (int i = 0; i < jArray.length(); i++) {
json_data = jArray.getJSONObject(i);
caNameJson = json_data.getString("ca_name");
caLinkJson = json_data.getString("ca_link");
caImgJson = json_data.getString("ca_link");
caNameHolder.add(caNameJson);
caLinkHolder.add(caLinkJson);
caImgHolder.add(caImgJson);
}
} catch (JSONException e) {
Log.e("my_log_tag", e.toString());
}
} catch (ParseException e) {
Log.e("my_log_tag", e.toString());
} catch (Exception e) {
Log.e("my_log_tag", e.toString());
}
}
// =============================================================================
public void addCanticles() {
try {
for (int i = 0; i < caNameHolder.size(); i++) {
caNameField = caNameHolder.get(i);
caLinkField = caLinkHolder.get(i);
caImgField = caImgHolder.get(i);
cantDatabase.createCanticle(caNameField, caLinkField,
caImgField);
}
} catch (Exception e) {
Log.e("my_log_tag", "notfilled yet");
}
}
}
CanticlesActivity.java
package com.shadatv.shada;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.zip.ZipInputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.content.SharedPreferences;
import android.database.Cursor;
public class CanticlesActivity extends Activity {
int read;
boolean flage;
final Context context = this;
String picpath="http://img.youtube.com/vi/";
ArrayList<String> getCaName = new ArrayList<String>();
ArrayList<String> getCaLink = new ArrayList<String>();
ArrayList<String> getCaImg = new ArrayList<String>();
String targetCaName;
String targetCaLink;
String targetCaImg;
File sdcard = Environment.getExternalStorageDirectory();
File shadaRoot = new File (sdcard.getAbsolutePath() + "/Shada_Folder");
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bm ;
ImageView img ;
public DAOCanticles cantDatabase =null;
byte[] encoded;
String value;
String useriddd;
//=============================================================================
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.canticles);
cantDatabase = new DAOCanticles(this);
new LoadData().execute();
}
//=============================================================================
private class LoadData extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
#Override
// can use UI thread here
protected void onPreExecute() {
CharSequence contentTitle = getString(R.string.loading);
this.progressDialog = ProgressDialog.show(CanticlesActivity.this,"",contentTitle);
}
//-------------------------------------------//
#Override
protected void onPostExecute(final Void unused) {
this.progressDialog.dismiss();
showCanticles();
}
//-------------------------------------------//
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
// HTTP post
getCanticles();
return null;
}
}
//=============================================================================
public void getCanticles() {
try{
Cursor canticles = cantDatabase.getCanticlesList();
do{
getCaName.add(canticles.getString(0));
getCaLink.add(canticles.getString(1));
getCaImg.add(canticles.getString(2));
}
while(canticles.moveToNext());
}catch(Exception e){
}
}
//=============================================================================
public void Downloadimage(String imgURL) {
try {
String finlpth="";
finlpth=picpath + imgURL + "/2.jpg";
shadaRoot.mkdirs();
URL u = new URL(finlpth);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
File DownloadedFile=new File(shadaRoot, imgURL + ".jpg");
// if(!outfile.exists())
FileOutputStream f = new FileOutputStream(DownloadedFile);
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
Log.d("Downloader", e.getMessage());
}
}
//=============================================================================
public void showCanticles()
{
final ListView listview = (ListView) findViewById(R.id.listView1);
for(int i=0; i < getCaName.size(); i++)
{
String caName=getCaName.get(i);
String caLink=getCaLink.get(i);
String caImg=getCaImg.get(i);
Toast.makeText(getBaseContext(), caName, Toast.LENGTH_SHORT).show();
if(!caImg.equalsIgnoreCase("0"))
{
Downloadimage(caLink);
}
}
listview.setOnItemClickListener(new ListView.OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
long selectedItemId = listview.getSelectedItemId();
ListAdapter adapterr = listview.getAdapter();
String selectedValue = (adapterr.getItem(position)).toString();
String selectedCaName=getCaName.get(position);
String selectedCaLink=getCaLink.get(position);
// // custom dialog
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.customdialogue);
dialog.setTitle(selectedCaName);
// set the custom dialog components - text, image and button
String selectedbookcover=getCaImg.get(position);
String test= shadaRoot+"/"+ selectedCaName;
String myJpgPath = test+".jpg";
TextView caLink = (TextView) dialog.findViewById(R.id.ca_link);
caLink.setText(selectedCaLink);
options.inSampleSize = 6;
Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
dialog.getWindow().setLayout(350,350);
}
});
listview.setAdapter(new DataAdapter(
CanticlesActivity.this,
getCaName.toArray(new String[getCaName.size()]),
getCaLink.toArray(new String[getCaLink.size()]),
getCaImg.toArray(new String[getCaImg.size()])));
}
}
canticles.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/bg1"
android:orientation="vertical" >
<ListView
android:id="#+id/listView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#b5b5b5"
android:dividerHeight="1dp"
android:listSelector="#drawable/list_selector" >
</ListView>
</LinearLayout>
custom_grid.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/list_selector"
android:gravity="left"
android:orientation="horizontal"
android:padding="10dip" >
<!-- ListRow Left sied Thumbnail image -->
<ImageView
android:id="#+id/caImgView"
android:layout_width="57dip"
android:layout_height="84dip"
android:layout_alignLeft="#+id/linearLayout1"
android:layout_alignTop="#+id/linearLayout1"
android:paddingLeft="0dip"
android:scaleType="fitXY"
android:src="#drawable/noimage" />
<LinearLayout
android:id="#+id/linearLayout2"
android:layout_width="170dip"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/targetmonth1"
android:layout_alignTop="#+id/targetmonth1"
android:layout_marginLeft="16dp"
android:layout_toRightOf="#+id/targetmonth1"
android:orientation="vertical"
android:padding="0dip" >
<TextView
android:id="#+id/caNameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/linearLayout1"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:text="dddddddd"
android:textColor="#040404"
android:textSize="13dip"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="#+id/caLinkView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/caNameView"
android:layout_alignRight="#+id/caNameView"
android:layout_below="#+id/caNameView"
android:layout_gravity="center_horizontal"
android:text="author"
android:textColor="#343434"
android:textSize="9dip"
android:typeface="sans" />
</LinearLayout>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="#drawable/arrow" />
</RelativeLayout>
use this
public List< String> caNameHolder = new ArrayList< String>();
instead of
public ArrayList< String> caNameHolder = new ArrayList< String>();