Hello i'm new to android studio and i have code which is showing recycler view list from json data. Now i want to open items in new activity.I want to open item from recyclerview and show image and some text in new activity. I need solution code.
I have tried some ways but it doesn't work.
This is my code:
public class MainActivity extends AppCompatActivity {
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private RecyclerView mRVFishPrice;
private AdapterFish mAdapter;
SwipeRefreshLayout mSwipeRefreshLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSwipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swifeRefresh);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
new AsyncFetch().execute();
}
});
new AsyncFetch().execute();
}
private class AsyncFetch extends AsyncTask<String, String, String> {
ProgressDialog pdLoading = new ProgressDialog(MainActivity.this);
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
#Override
protected String doInBackground(String... params) {
try {
url = new URL("https://MYURL.com");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("GET");
// setDoOutput to true as we recieve data from json file
conn.setDoOutput(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return e1.toString();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
mSwipeRefreshLayout.setRefreshing(false);
pdLoading.dismiss();
List<DataFish> data=new ArrayList<>();
pdLoading.dismiss();
try {
JSONArray jArray = new JSONArray(result);
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
DataFish fishData = new DataFish();
fishData.fishImage= json_data.getString("fish_img");
fishData.fishName= json_data.getString("fish_name");
fishData.catName= json_data.getString("cat_name");
fishData.sizeName= json_data.getString("size_name");
fishData.price= json_data.getInt("price");
data.add(fishData);
}
mRVFishPrice = (RecyclerView)findViewById(R.id.fishPriceList);
mAdapter = new AdapterFish(MainActivity.this, data);
mRVFishPrice.setAdapter(mAdapter);
mRVFishPrice.setLayoutManager(new LinearLayoutManager(MainActivity.this));
} catch (JSONException e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
I expect to open item from recyclerview list in new activity and show image item and some text.
You can archive this by passing an instance of the interface in your adapter class and implement that interface in your activity.
refer this to get insights link
Sample Snippets
Declare interface:
public interface AdapterCallback {
void onFishClick(DataFish item);
}
Pass interface instance via setup your adapter in activity.
new AdapterFish(MainActivity.this, data, new AdapterCallback() {
#Override
void onfishClick(DataFish item) {
// herer do your work
}
});
In your adapter constructor
private AdapterCallback callback;
AdapterFish(Context contex, data, AdapterCallback callback) {
...
this.callback = callback;
}
define click listener in a holder and inside a method call callback.onFishCall(selectedItem);
OnBindViewHolder(...) {
holder.button.onClicklistener(new OnClickListener{
...
if(callback != null) { // for null check
callback.onFishClikc(item);
}
});
}
Related
I followed a tutorial that allows me to load data from a mysql database in a recycling android and everything is well done. Among the loaded data, there are links to videos and I would like that when the user clicks on a recyclerview element, that he can play the corresponding video. How can I do this please?
here is the code that loads the videos from the database
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
// CONNECTION_TIMEOUT and READ_TIMEOUT are in milliseconds
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private RecyclerView recyclerView;
private Adapter mAdapter;
private DatabaseReference mDatabase;
List<Data> data = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Make call to AsyncTask
new AsyncLogin().execute();
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
RecycleClick.addTo(recyclerView).setOnItemClickListener(new RecycleClick.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
String url = data.get(position).sizeName;
String name = data.get(position).fishName;
String titre = data.get(position).catName;
for(int i = 0;i<data.size();i++) {
Intent intent = new Intent(MainActivity.this, PlayVideo.class);
intent.putExtra("url", url);
intent.putExtra("name", name);
intent.putExtra("title", titre);
startActivity(intent);
}
overridePendingTransition(R.anim.activity_back_in, R.anim.activity_back_out);
finish();
Toast.makeText(getApplicationContext(), "On Click\nPosition : "+(position+1)+"\nTitle : "+"", Toast.LENGTH_SHORT).show();
}
});
RecycleClick.addTo(recyclerView).setOnItemLongClickListener(new RecycleClick.OnItemLongClickListener() {
#Override
public boolean onItemLongClicked(RecyclerView recyclerView, int position, View v) {
return true;
}
});
}
private class AsyncLogin extends AsyncTask<String, String, String> {
ProgressDialog pdLoading = new ProgressDialog(MainActivity.this);
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
#Override
protected String doInBackground(String... params) {
try {
// Enter URL address where your json file resides
// Even you can make call to php file which returns json data
url = new URL("http://192.168.43.196/vibe2/essai4.php");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("GET");
// setDoOutput to true as we recieve data from json file
conn.setDoOutput(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return e1.toString();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
pdLoading.dismiss();
List<Data> data=new ArrayList<>();
pdLoading.dismiss();
try {
JSONArray jArray = new JSONArray(result);
// Extract data from json and store into ArrayList as class objects
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
Data DataItem = new Data();
DataItem.fishImage= json_data.getString("ImagePath");
DataItem.fishName= json_data.getString("AndroidNames");
DataItem.catName= json_data.getString("titre");
DataItem.sizeName= json_data.getString("url");
DataItem.price= json_data.getInt("counter");
data.add(DataItem);
}
// Setup and Handover data to recyclerview
mAdapter = new Adapter(MainActivity.this, data);
recyclerView.setAdapter(mAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
} catch (JSONException e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
and here is my click
RecycleClick.addTo(recyclerView).setOnItemClickListener(new RecycleClick.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
}
});
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
pdLoading.dismiss();
final List<Data> data=new ArrayList<>();
pdLoading.dismiss();
try {
JSONArray jArray = new JSONArray(result);
// Extract data from json and store into ArrayList as class objects
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
Data DataItem = new Data();
DataItem.fishImage= json_data.getString("ImagePath");
DataItem.fishName= json_data.getString("AndroidNames");
DataItem.catName= json_data.getString("titre");
DataItem.sizeName= json_data.getString("url");
DataItem.price= json_data.getInt("counter");
data.add(DataItem);
}
// Setup and Handover data to recyclerview
mAdapter = new Adapter(MainActivity.this, data);
recyclerView.setAdapter(mAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
RecycleClick.addTo(recyclerView).setOnItemClickListener(new RecycleClick.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
Intent intent = new Intent(MainActivity.this, PlayVideo.class);
intent.putExtra("url", data.get(position).sizeName);
startActivity(intent);
overridePendingTransition(R.anim.activity_back_in, R.anim.activity_back_out);
finish();
}
});
} catch (JSONException e) {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
i am using simple asynctask function for getting values from mysql database through json.it was working fine with emulator but if i am trying from the mobile i am getting error. like Java.lang.NullPointerExceprtion:Attempt to invke virtual metho 'java.lang.string.java.lang.stringbuilder.toString() on a null object reference.
I tried with new project but result is same. this application is not working in all the devices except emulator. can you help me on this.
My Code is -
public class MainActivity extends AppCompatActivity {
private static final String Latest_Products7 = "Questions";
JSONArray productsArray7 = null;
public static final int CONNECTION_TIMEOUT7=100000;
public static final int READ_TIMEOUT7=150000;
HashMap<String,ArrayList<WorldPopulation>> hasmap = new HashMap<String,ArrayList<WorldPopulation>>();
ArrayList<WorldPopulation> arraylist7 = null;
StringBuilder result7;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new AsyncLogin7().execute();
}
private class AsyncLogin7 extends AsyncTask<String, String, StringBuilder> {
ProgressDialog pdLoading = new ProgressDialog(MainActivity.this);
HttpURLConnection conn7;
URL url7 = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();
}
#Override
protected StringBuilder doInBackground(String... params) {
try {
// Enter URL address where your php file resides
url7 = new URL("http:/Samplesite/****/somephp.php");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn7 = (HttpURLConnection)url7.openConnection();
conn7.setReadTimeout(READ_TIMEOUT7);
conn7.setConnectTimeout(CONNECTION_TIMEOUT7);
conn7.setRequestMethod("POST");
// setDoInput and setDoOutput method depict handling of both send and receive
conn7.setDoInput(true);
conn7.setDoOutput(true);
// Append parameters to URL
Uri.Builder builder7 = new Uri.Builder().appendQueryParameter("reg_id", "hai") ;
String query7 = builder7.build().getEncodedQuery();
// Open connection for sending data
OutputStream os7 = conn7.getOutputStream();
BufferedWriter writer7 = new BufferedWriter(new OutputStreamWriter(os7, "UTF-8"));
writer7.write(query7);
writer7.flush();
writer7.close();
os7.close();
conn7.connect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
int response_code7 = conn7.getResponseCode();
// Check if successful connection made
if (response_code7 == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input7 = conn7.getInputStream();
BufferedReader reader7 = new BufferedReader(new InputStreamReader(input7));
result7 = new StringBuilder();
String line7;
while ((line7 = reader7.readLine()) != null) {
result7.append(line7);
}
// Pass data to onPostExecute method
}
} catch (IOException e) {
e.printStackTrace();
} finally {
conn7.disconnect();
}
return result7;
}
#Override
protected void onPostExecute(StringBuilder result7) {
super.onPostExecute(result7);
Log.e("dai",result7.toString());
Toast.makeText(MainActivity.this,result7.toString(),Toast.LENGTH_LONG).show();
pdLoading.dismiss();
/* Intent intnt = new Intent(Checklist_activity.this,Task_main.class);
intnt.putExtra("task",hasmap);
startActivity(intnt);*/
}
}
}
Change
try {
int response_code7 = conn7.getResponseCode();
// Check if successful connection made
if (response_code7 == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input7 = conn7.getInputStream();
BufferedReader reader7 = new BufferedReader(new InputStreamReader(input7));
result7 = new StringBuilder();
String line7;
while ((line7 = reader7.readLine()) != null) {
result7.append(line7);
}
// Pass data to onPostExecute method
}
} catch (IOException e) {
e.printStackTrace();
} finally {
conn7.disconnect();
}
return result7;
To
try {
int response_code7 = conn7.getResponseCode();
result7 = new StringBuilder();
// Check if successful connection made
if (response_code7 == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input7 = conn7.getInputStream();
BufferedReader reader7 = new BufferedReader(new InputStreamReader(input7));
String line7;
while ((line7 = reader7.readLine()) != null) {
result7.append(line7);
}
// Pass data to onPostExecute method
}
} catch (IOException e) {
e.printStackTrace();
} finally {
conn7.disconnect();
}
return result7;
Try something like this
Log.e("dai",MainActivity.this.result7.toString());
Toast.makeText(MainActivity.this,MainActivity.this.result7.toString(),Toast.LENGTH_LONG).show();
OR
#Override
protected void onPostExecute(StringBuilder result) {
super.onPostExecute(result);
Log.e("dai",result.toString());
Toast.makeText(MainActivity.this,result.toString(),Toast.LENGTH_LONG).show();
pdLoading.dismiss();
/* Intent intnt = new Intent(Checklist_activity.this,Task_main.class);
intnt.putExtra("task",hasmap);
startActivity(intnt);*/
}
}
I am have sql DB and I am trying to display queried values in a listView. I created a custom adapter for the listView. problem is
I am not able to see any data displayed on my listView.
code of main
public class _songs_playlist extends AppCompatActivity {
ArrayList<songsarray> listofsoongs = new ArrayList<songsarray>();
private static int SPLASH_TIME_OUT=2000;
AlertDialog alertDialog;
private boolean loggedIn = false;
String type;
String result;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity__songs_playlist);
new JSONParse().execute();
MyCustomAdapterSongs itemsAdapter = new MyCustomAdapterSongs(this, listofsoongs);
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(itemsAdapter);
itemsAdapter.notifyDataSetChanged();
}
private class JSONParse extends AsyncTask<String, String, JSONObject> {
private ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
alertDialog=new AlertDialog.Builder(_songs_playlist.this).create();
alertDialog.setTitle("Upadting Data");
pDialog = new ProgressDialog(_songs_playlist.this);
pDialog.setMessage("Getting Data ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected JSONObject doInBackground(String... args) {
HTTPHandler sh = new HTTPHandler();
String login_URL = "http://2f179dfb.ngrok.io/getsong.php";
try {
//Fetching the boolean value form sharedpreferences
URL url = new URL(login_URL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
Log.e("RESULT", result);
JSONObject jsonObject = new JSONObject(result);
JSONArray result1 = jsonObject.getJSONArray("result");
for (int i = 0; i < result1.length(); i++) {
JSONObject c = result1.getJSONObject(i);
String id = c.getString("songID");
String names = c.getString("songName");
String ss = c.getString("singerName");
listofsoongs.add(new songsarray(ss,id,names));
}
return jsonObject;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(JSONObject json) {
pDialog.dismiss();
if(true)
{
}
else
{
}
}
}
}
code of custom array adapter
public class MyCustomAdapterSongs extends ArrayAdapter<songsarray> {
Context context;
ArrayList<songsarray> items;
public MyCustomAdapterSongs(Activity context, ArrayList<songsarray> songsarrays) {
super(context, 0, songsarrays);
this.context=context;
this.items=songsarrays;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.itemlist, parent, false);
}
TextView nameTextView = (TextView) listItemView.findViewById(R.id.textView1);
nameTextView.setText(currentAndroidFlavor.getSingername());
Log.e("hhhh", nameTextView.getText().toString());
TextView numberTextView = (TextView) listItemView.findViewById(R.id.textView2);
numberTextView.setText(currentAndroidFlavor.getSongname());
Log.e("jjjj", numberTextView.getText().toString());
CheckBox ch=(CheckBox)listItemView.findViewById(R.id.checkBox1);
ch.setSelected(currentAndroidFlavor.isSelected());
return listItemView;
}
#Override
public int getCount() {
if(items == null)
return 0;
return items.size();
}
#Override
public songsarray getItem(int i) {
return items.get(i);
}
}
Call itemsAdapter.notifyDataSetChanged() within onPostExecute.
Your list is empty until the AsyncTask finishes there.
You'll have to make the adapter a member variable of the Activity class
As in your code I can see you are updating the list in doInBackground but you are not notifying the adapter for the changes.
In onPostExecute method you need to call itemsAdapter.notifyDataSetChanged() and make sure it you are not calling it inside doInBackground as in background thread you can't to UI related work.
Check the EDITS in this code snippet
`
public class _songs_playlist extends AppCompatActivity {
ArrayList<songsarray> listofsoongs = new ArrayList<songsarray>();
private static int SPLASH_TIME_OUT=2000;
AlertDialog alertDialog;
private boolean loggedIn = false;
String type;
String result;
//EDIT 1: Make these member variables
MyCustomAdapterSongs itemsAdapter;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity__songs_playlist);
//EDIT 2: get references your views before AsyncTask
listView = (ListView) findViewById(R.id.listView1);
new JSONParse().execute();
}
private class JSONParse extends AsyncTask<String, String, JSONObject> {
private ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
alertDialog=new AlertDialog.Builder(_songs_playlist.this).create();
alertDialog.setTitle("Upadting Data");
pDialog = new ProgressDialog(_songs_playlist.this);
pDialog.setMessage("Getting Data ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected JSONObject doInBackground(String... args) {
HTTPHandler sh = new HTTPHandler();
String login_URL = "http://2f179dfb.ngrok.io/getsong.php";
try {
//Fetching the boolean value form sharedpreferences
URL url = new URL(login_URL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
Log.e("RESULT", result);
JSONObject jsonObject = new JSONObject(result);
JSONArray result1 = jsonObject.getJSONArray("result");
for (int i = 0; i < result1.length(); i++) {
JSONObject c = result1.getJSONObject(i);
String id = c.getString("songID");
String names = c.getString("songName");
String ss = c.getString("singerName");
listofsoongs.add(new songsarray(ss,id,names));
}
return jsonObject;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(JSONObject json) {
pDialog.dismiss();
//EDIT 3: set your adapter here as this method will be called on the UI Thread
itemsAdapter = new MyCustomAdapterSongs(this, listofsoongs);
listView.setAdapter(itemsAdapter);
}
}
}
}
`
This app is supposed to parse some JSON data (hard coded for now) from the Google Books API, and pass an ArrayList of Books to the adapter that will display it on a ListView. The problem I have is that the JSON parse is returning null instead of the parsed data.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
ProgressBar pBar;
List<MyTask> tasks;
ArrayList<Book> bookList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pBar = (ProgressBar) findViewById(R.id.progressBar);
pBar.setVisibility(View.INVISIBLE);
Button sButton = (Button) findViewById(R.id.s_button);
sButton.setOnClickListener(this);
tasks = new ArrayList<>();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.s_button: {
if (isOnline()) {
new MyTask().execute("https://www.googleapis.com/books/v1/volumes?q=millionare"); //https://www.googleapis.com/books/v1/volumes?q=soft+skills
} else {
Toast.makeText(this, "Connection failed", Toast.LENGTH_LONG).show();
}
break;
}
}
}
protected boolean isOnline() {
ConnectivityManager connectManager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = connectManager.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
} else {
return false;
}
}
private class MyTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return HttpManager.getData(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
#Override
protected void onPostExecute(String result) {
bookList = BookJSONParser.parseFeed(result);
updateDisplay();
}
}
protected void updateDisplay() {
BookAdapter adapter = new BookAdapter(this, bookList);
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
}
}
public class BookJSONParser {
public static ArrayList<Book> parseFeed(String content) {
try {
JSONArray jsonArray = new JSONArray(content);
ArrayList<Book> bookList = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String name = object.getString("title").toString();
Book book = new Book(name);
bookList.add(book);
}
return bookList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
}
public class BookAdapter extends ArrayAdapter<Book> {
public BookAdapter(Context context, ArrayList<Book> bookList) {
super(context, 0, bookList);
}
#Override
public View getView(int position, View convertedView, ViewGroup parent) {
View listItemView = convertedView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
Book currentBook = getItem(position);
TextView locationName = (TextView) listItemView.findViewById(R.id.book_title);
locationName.setText(currentBook.getTittle());
TextView locationAddress = (TextView) listItemView.findViewById(R.id.book_author);
locationAddress.setText(currentBook.getAuthor());
return listItemView;
}
}
public class HttpManager {
public static String getData(String myUrl) throws IOException {
// BufferedReader reader = null;
InputStream inputStream = null;
int len = 10000;
try {
URL url = new URL(myUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(10000 /* milliseconds */);
connection.setConnectTimeout(15000 /* milliseconds */);
connection.setRequestMethod("GET");
connection.setDoInput(true);
// Starts the query
connection.connect();
int response = connection.getResponseCode();
inputStream = connection.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(inputStream, len);
return contentAsString;
// Makes sure that the InputStream inputStream closed after the app inputStream
// finished using it.
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
}
// Reads an InputStream and converts it to a String.
public static String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
}
public class Book {
private String mTittle;
/**
* This is the constructor.
* #param title is the book title being passed in.
*/
public Book(String title) {
mTittle = title;
}
public String getTittle() {
return mTittle;
}
public void setTittle(String tittle) {
mTittle = tittle;
}
}
FATAL EXCEPTION: main
Process: com.narvin.android.booklisting, PID: 3278
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
at android.widget.ListView.setAdapter(ListView.java:502)
at com.narvin.android.booklisting.MainActivity.updateDisplay(MainActivity.java:113)
at com.narvin.android.booklisting.MainActivity$MyTask.onPostExecute(MainActivity.java:100)
at com.narvin.android.booklisting.MainActivity$MyTask.onPostExecute(MainActivity.java:79)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5942)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
The issue is that one of the arguments in BookAdapter adapter = new BookAdapter(this, bookList); is null for some reason. Try passing bookList as an argument to updateDisplay and checking whether it's not null.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
ProgressBar pBar;
List<MyTask> tasks;
ArrayList<Book> bookList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pBar = (ProgressBar) findViewById(R.id.progressBar);
pBar.setVisibility(View.INVISIBLE);
Button sButton = (Button) findViewById(R.id.s_button);
sButton.setOnClickListener(this);
tasks = new ArrayList<>();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.s_button: {
if (isOnline()) {
new MyTask().execute("https://www.googleapis.com/books/v1/volumes?q=millionare"); //https://www.googleapis.com/books/v1/volumes?q=soft+skills
} else {
Toast.makeText(this, "Connection failed", Toast.LENGTH_LONG).show();
}
break;
}
}
}
protected boolean isOnline() {
ConnectivityManager connectManager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = connectManager.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
} else {
return false;
}
}
private class MyTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return HttpManager.getData(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
#Override
protected void onPostExecute(String result) {
ArrayList<Book> bookList = BookJSONParser.parseFeed(result);
updateDisplay(bookList);
}
}
protected void updateDisplay(ArrayList<Book> bookList) {
if (bookList != null){
BookAdapter adapter = new BookAdapter(this, bookList);
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
}
}
}
It would appear you are getting a JSONParseException... therefore causing a NullPointerExpcetion for the List into the Adapter
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
That is your error, here is how you get it
public static ArrayList<Book> parseFeed(String content) {
try {
JSONArray jsonArray = new JSONArray(content); // <-- Throws an error
ArrayList<Book> bookList = new ArrayList<>();
// Stuff...
return bookList;
} catch (JSONException e) {
e.printStackTrace();
return null; // <----- Null is returned
}
And you use that null value here
#Override
protected void onPostExecute(String result) {
bookList = BookJSONParser.parseFeed(result);
updateDisplay();
}
Followed by
protected void updateDisplay() {
BookAdapter adapter = new BookAdapter(this, bookList); // <-- Null here
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
}
So, the way to fix that NullPointerExpception is to always return an ArrayList
ArrayList<Book> bookList = new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(content);
// Stuff...
} catch (JSONException e) {
e.printStackTrace();
}
return bookList;
to get json string from url you should do it like that
String content = new MyTask()
.execute("https://www.googleapis.com/books/v1/volumes?q=millionare")
.get();
//pass the content to BookJSONParser class
booklist = new BookJSONParser().parseFeed(content);
updateDisplay();
what you get from the url you provided is NOT jsonArray it's a jsonobject
so I think this code will work "assuming that you did everything else correctly"
JSONObject o = new JSONObject(content);
JSONArray jsonArray = o.getJSONArray("items");
the you can do the for loop
I tried the code below and also tried the AsyncTaskLoader approach. The app crashes when I instantiate the AsyncTask. Pleas advise me on the best approach to load JSON in a list fragment inside tab host.
The code below is the tab fragment (I use action bar tabs in main activity):
public class TabTop extends ListFragment {
Context context = getActivity().getBaseContext();
String API_URL = "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/similar.json?apikey=crhhxb4accwwa6cy6fxrm8vj&limit=1";
ArrayList<Deal> deals;
DealsListAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
#SuppressWarnings("unused")
int a = 0;
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
GetTopDeals getTopDeals = new GetTopDeals(context);
getTopDeals.execute(API_URL);
super.onActivityCreated(savedInstanceState);
}
class GetTopDeals extends AsyncTask<String, Void, ArrayList<Deal>>{
ProgressDialog progressDialog;
public GetTopDeals(Context activity) {
this.progressDialog = new ProgressDialog(activity);
}
#Override
protected void onPostExecute(ArrayList<Deal> result) {
adapter = new DealsListAdapter(context, result);
setListAdapter(adapter);
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
progressDialog.setCancelable(true);
progressDialog.setProgress(0);
progressDialog.setMessage("loading Top deals...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
super.onPreExecute();
}
#Override
protected ArrayList<Deal> doInBackground(String... urls) {
String response = sendRequest(urls[0]); // make request for json
return processResponse(response); // parse the Json and return ArrayList to postExecute
}
private String sendRequest(String apiUrl) {
BufferedReader input = null; // get the json
HttpURLConnection httpCon = null; // the http connection object
StringBuilder response = new StringBuilder(); // hold all the data from the jason in string separated with "\n"
try {
URL url = new URL(apiUrl);
httpCon = (HttpURLConnection) url.openConnection();
if (httpCon.getResponseCode() != HttpURLConnection.HTTP_OK) { // check for connectivity with server
return null;
}
input = new BufferedReader(new InputStreamReader(httpCon.getInputStream())); // pull all the json from the site
String line;
while ((line = input.readLine()) != null) {
response.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpCon != null) {
httpCon.disconnect();
}
}
return response.toString();
}
}
public ArrayList<Deal> processResponse(String response) {
try {
JSONObject responseObject = new JSONObject(response); // Creates a new JSONObject with name/value mappings from the JSON string.
JSONArray results = responseObject.getJSONArray("movies"); // Returns the value mapped by name if it exists and is a JSONArray.
deals = new ArrayList<Deal>();
for (int i = 0; i < results.length(); i++) { // in this loop i copy the json array to movies arraylist in order to display listView
JSONObject jMovie = results.getJSONObject(i);
int api_id = jMovie.getInt("id");
String name = jMovie.getString("title");
String content = jMovie.getString("synopsis");
JSONObject posters = jMovie.getJSONObject("posters");
String image_url = posters.getString("profile");
}
}catch (JSONException e) {
e.printStackTrace();
}
return deals;
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent(getActivity().getBaseContext(), DealInformation.class);
startActivity(intent);
super.onListItemClick(l, v, position, id);
}
}
Make your asynctask in his own file.
And when your asynctask is finish, implement OnPostExecute which is automatically call. Notify your adapter by a notifyDataSetChanged like that :
#Override
protected void onPostExecute(List<NewItem> list) {
Adapter.getListe().clear();
Adapter.getListe().addAll(list);
Adapter.notifyDataSetChanged();
}
thank you guys,
i want to post my answer. after some research i decided to go with AsyncTaskLoader.
this is my code
public class TabOurPicks extends ListFragment implements LoaderCallbacks<String[]> {
// when activity loads- onActivityCreated() calls the initLoader() who activate onCreateLoader()
#Override
public void onActivityCreated(Bundle savedInstance) {
super.onActivityCreated(savedInstance);
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, new String[]{}));
getLoaderManager().initLoader(0, null,this).forceLoad();
}
// onCreateLoader instantiate the asynctaskloaser who work in bg
#Override
public RSSLoader onCreateLoader(int arg0, Bundle arg1) {
return new RSSLoader(getActivity()); //
}
// after bg process invoke onLoadFinished() who work in ui thread
#Override
public void onLoadFinished(Loader<String[]> loader, String[] data) {
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, data
) );
}
#Override
public void onLoaderReset(Loader<String[]> arg0) {
// TODO Auto-generated method stub
}
and this is the inner class for the loader:
static public class RSSLoader extends AsyncTaskLoader<String[]>
{
public RSSLoader(Context context) {
super(context);
}
#Override
public String[] loadInBackground() {
String url = "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/similar.json?apikey=crhhxb4accwwa6cy6fxrm8vj&limit=1";
String response = sendRequest(url);
return processResponse(response);
}
private String sendRequest(String url) {
BufferedReader input = null; // get the json
HttpURLConnection httpCon = null; // the http connection object
StringBuilder response = new StringBuilder(); // hold all the data from the jason in string separated with "\n"
try {
URL apiUrl = new URL(url);
httpCon = (HttpURLConnection) apiUrl.openConnection();
if (httpCon.getResponseCode() != HttpURLConnection.HTTP_OK) { // check for connectivity with server
return null;
}
input = new BufferedReader(new InputStreamReader(httpCon.getInputStream())); // pull all the json from the site
String line;
while ((line = input.readLine()) != null) {
response.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (httpCon != null) {
httpCon.disconnect();
}
}
return response.toString();
}
private String[] processResponse(String response) {
String[] deals = null;
try {
JSONObject responseObject = new JSONObject(response); // Creates a new JSONObject with name/value mappings from the JSON string.
JSONArray results = responseObject.getJSONArray("movies"); // Returns the value mapped by name if it exists and is a JSONArray.
deals = new String[10];
for (int i = 0; i < 9; i++) { // in this loop i copy the json array to movies arraylist in order to display listView
JSONObject jMovie = results.getJSONObject(i);
String name = jMovie.getString("title");
deals[i] = name;
}
}catch (JSONException e) {
e.printStackTrace();
}
return deals;
}
}
}
It doesn't matter if your asynctask has its own file. You just don't want your activity to extends asynctask as this would make your activity asynchronous - but this is impossible to do anyways due to java's double inheritance rule.
Based on the architecture of your app and your programming style the asyntask can be an inner class in the activity. on the PostExecute method make sure you have given data to your adapter and that the adapter is set to the list, then just run notifyDataSetChanged().
Assuming your asynctask is loading data from cache or the network you are on the right track with your approach to this.