App Crashes while switching from one Activity to another - android

Aim: Building app on Google API to fetch the data about the books the user searches
Problem Explanation:
Whenever I hit the submit Button, my app crashes.
This is my first approach in making a network request app and I need guidance.
MainActivityClass
package com.example.vidit.books;
import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText query = (EditText) findViewById(R.id.query);
Button submit= (Button) findViewById(R.id.submit);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent= new Intent(MainActivity.this,Request.class);
intent.putExtra ( "text", query.getText().toString() );
startActivity(intent);
}
});
}
}
Second Class
package com.example.vidit.books;
import android.content.Intent;
public class Request {
Intent i = getIntent();
String text = i.getStringExtra ("text");
public static final String LOG_TAG = Request.class.getSimpleName();
String APIURL="https://www.googleapis.com/books/v1/volumes?q= " + text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_request);
}
public void UpdateUi(Book book)
{
BookAdapter bookAdapter = new BookAdapter(this,book);
ListView listView= (ListView) findViewById(R.id.listview_all);
}
private class BookAsyncTask extends AsyncTask<URL,Void,Book>
{
#Override
protected Book doInBackground(URL... urls) {
URL url = createUrl(APIURL);
String jsonResponse = "";
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
// TODO Handle the IOException
}
final Book book = extractFeatureFromJson(jsonResponse);
return book;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
private String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.connect();
if(urlConnection.getResponseCode()==200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
}
} catch (IOException e) {
// TODO: Handle the exception
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// function must handle java.io.IOException here
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {#link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Returns new URL object from the given string URL.
*/
private URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
private Book extractFeatureFromJson(String bookJSON) {
try {
JSONObject baseJsonResponse = new JSONObject(bookJSON);
JSONArray items = baseJsonResponse.getJSONArray("items");
// If there are results in the features array
for(int i=0;i<10;i++)
{
JSONObject firstFeature = items.getJSONObject(i);
JSONArray author=firstFeature.getJSONArray("author");
for(int j=0;j<author.length();j++)
{
JSONObject authorFeature=author.getJSONObject(j);
}
String title = items.getString(Integer.parseInt("title"));
// Create a new {#link Event} object
return new Book(title,author);
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
}
return null;
}
}
}
BookAdapter Class:
package com.example.vidit.books;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.List;
public class BookAdapter extends ArrayAdapter<Book> {
public BookAdapter(Activity context, Book book)
{
super(context,0, (List<Book>) book);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if(listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
Book cbook=getItem(position);
TextView title = (TextView) listItemView.findViewById(R.id.title);
title.setText(cbook.getmTitle());
TextView author=(TextView) listItemView.findViewById(R.id.author);
author.setText((CharSequence) cbook.getmAuthor());
return listItemView;
}
}
Showing error in statement:
String text = i.getStringExtra ("text");
Need guidance

I don't know how your code gets compiled when you have overridden onCreate() in Request class and the Request class isn't extending Activity or AppCompatActivity.
Secondly, this line :
Intent i = getIntent();
String text = i.getStringExtra ("text");
should be inside the onCreate() method.

Showing error in statement : String text = i.getStringExtra ("text");
Request for Guidance
Well you need to get the data passed inside onCreate like below.
String APIURL;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_request);
Bundle bundle = getIntent().getExtras();
String text = bundle.getString("text");
APIURL="https://www.googleapis.com/books/v1/volumes?q= " + text;
}
And although you have the asyncTask class i can't see where exactly you execute the class. You need to do that inside onCreate as well.

Try moving this code to your onCreate method
Intent i = getIntent();
String text = i.getStringExtra ("text");
The intent extras is not available in the constructor for your Request class.

Related

Can't display data on recyclerView

This app is supposed to display movie's tittles fetched from an API into a RecyclerView. I know I am getting the data right because of logs I made on the movies Arraylist, but for some reason, I can't display the info. The app does not crash, it just shows an empty view. I do really appreciate your help.
Disclaimers: I am a newbie, and this solution might be quite simple for experienced people. I usually don't ask questions unless I can't solve the issue, actually this is my first question ever. I've been around this for a few days now and I can't find a way. I understand that this code might have more than one problem on it, and you are very welcome to point them all out.
SO, this is my main activity
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
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;
public class MainActivity extends AppCompatActivity {
public static final String LOG_TAG = MainActivity.class.getSimpleName();
private static final String MOST_POPULAR_MOVIES = "http://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=XXXXXXXXXXXXXXXXXXX";
ArrayList<Pelicula> ArrayDePeliculas;
private RecyclerView mPelisList;
private AdapterRV adapterRV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PeliculasAsyncTask task = new PeliculasAsyncTask();
task.execute(createUrl(MOST_POPULAR_MOVIES));
adapterRV = new AdapterRV(getApplicationContext(),/*Aca puede faltar algo*/ new ArrayList<Pelicula>());
mPelisList = findViewById(R.id.rv_pelis);
GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
mPelisList.setLayoutManager(layoutManager);
mPelisList.setAdapter(adapterRV);
}
public void updateUi(ArrayList<Pelicula> peliculas) {
}
/**
* Returns new URL object from the given string URL.
*/
private URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
private String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// function must handle java.io.IOException here
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {#link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* TODO modificar la url que le estas pasando
*/
public ArrayList<Pelicula> extractFeatureFromJson(String jsonResponse) {
ArrayList<Pelicula> arraydePelis = new ArrayList<>();
try {
JSONObject baseJsonResponse = new JSONObject(jsonResponse);
JSONArray resultsArray = baseJsonResponse.getJSONArray("results");
for (int i = 0; i < resultsArray.length(); i++) {
// If there are results in the features array
if (resultsArray.length() > 0) {
// Extract out the first feature (which is an earthquake)
JSONObject firstResult = resultsArray.getJSONObject(i);
String tittle = firstResult.getString("title");
Pelicula pelicula = new Pelicula(tittle);
arraydePelis.add(pelicula);
}
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
}
return arraydePelis;
}
private class PeliculasAsyncTask extends AsyncTask<URL, Void, ArrayList<Pelicula>> {
#Override
protected ArrayList<Pelicula> doInBackground(URL... urls) {
// Create URL object
URL url = createUrl(MOST_POPULAR_MOVIES);
// Perform HTTP request to the URL and receive a JSON response back
String jsonResponse = "";
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
Log.e(LOG_TAG, "Problem making the HTTP request.", e);
}
// Extract relevant fields from the JSON response and create an {#link Event} object
ArrayList<Pelicula> ArrayPeliculas = extractFeatureFromJson(jsonResponse);
// Return the {#link Event} object as the result fo the {#link TsunamiAsyncTask}
return ArrayPeliculas;
}
#Override
protected void onPostExecute(ArrayList<Pelicula> data) {
if (data == null) {
return;
}
adapterRV.notifyDataSetChanged();
mPelisList.setAdapter(adapterRV);
Log.e("Nada", data.get(6).getTittle());
super.onPostExecute(data);
}
}
}
The Movie class
public class Pelicula {
//Fields
private String mTittle;
//Constructor
public Pelicula(String Tittle){
mTittle= Tittle;
}
//Methods
public String getTittle (){
return mTittle;
}
}
And finally, the recyclerView adapter
import android.content.Context;
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.ArrayList;
import java.util.List;
public class AdapterRV extends RecyclerView.Adapter<AdapterRV.PelisViewHolder> {
//Fields
List<Pelicula> mPeliculas;
private Context context;
/* TODO, comprobar que no necesitas esto: mNumberItems = numberOfItems; y poner autofit en grid view */
//Constructor
public AdapterRV (Context context, ArrayList<Pelicula> peliculas){
mPeliculas = peliculas;
this.context= context;
}
//Metodos
#NonNull
#Override
public PelisViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
int layoutForListItem = R.layout.item_layout;
LayoutInflater inflater= LayoutInflater.from(context);
View view = inflater.inflate(layoutForListItem, parent, false);
PelisViewHolder viewHolder = new PelisViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull PelisViewHolder holder, int position) {
Pelicula peliculas = mPeliculas.get(position);
TextView textView = holder.listItemTittleView;
textView.setText(peliculas.getTittle());
}
#Override
public int getItemCount() {
return mPeliculas.size();
}
public class PelisViewHolder extends RecyclerView.ViewHolder{
TextView listItemTittleView;
public PelisViewHolder(#NonNull View itemView) {
super(itemView);
listItemTittleView = itemView.findViewById(R.id.tv_title);
}
}
}
The problem is that you are passing new ArrayList<Pelicula>() to your adapter, and this list is remaining empty. I suggest you declare a global reference of Pelicula list inside your MainActivity and then pass it to the adapter. Whenever that list changes, then notifyDataSetChanged.
If you don't want to declare a global reference, just declare a method inside your adapter:
public void setList(ArrayList list){
this.list = list;
}
and in your MainActivity, just everything you get a new list, setList(newPeliculaList) and adapterRV.notifyDataSetChanged()
Edit:
in onCreate() before declaring the AdapterRV:
just put this:
ArrayDePeliculas = new ArrayList<Pelicula>();
Do you see these 2 lines in onCreate()
adapterRV = new AdapterRV(getApplicationContext(),new ArrayList<Pelicula>());
...
...
mPelisList.setAdapter(adapterRV);
Move them to onPostExecute() of the asyncTask and pass the data instead of a new ArrayList<Pelicula>():
#Override
protected void onPostExecute(ArrayList<Pelicula> data) {
//assuming the list is full and all is good
if (data == null) {
return;
}
//here...
adapterRV = new AdapterRV(getApplicationContext(),data);
mPelisList.setAdapter(adapterRV);
Log.e("Nada", data.get(6).getTittle());
super.onPostExecute(data);
}
UPDATE:
Its because you don't initialize the list in the adapter:
public class AdapterRV extends RecyclerView.Adapter<AdapterRV.PelisViewHolder> {
//Fields
//here you must initialize like this:
List<Pelicula> mPeliculas = new ArrayList<Pelicula>();
.....

When I tap the refresh button the images never appear

I have been trying too hard to get around this problom, when I tap the refresh button in my app, the images doesn't load on the screen.
This the DataFragment file, when i build this app there are no errors.
package com.example.popularmovis;
import android.app.Fragment;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
import android.os.AsyncTask;
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.URL;
import java.util.jar.JarException;
/**
* A placeholder fragment containing a simple view.
*/
public class DataFragment extends Fragment {
public ImageAdapter display;
public DataFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add this line in order for this fragment to handle menu events.
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.datafragment_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_refresh) {
FetchMovieData movieData = new FetchMovieData();
movieData.execute();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
display = new ImageAdapter(rootView.getContext());
GridView gridView = (GridView) rootView.findViewById(R.id.gridView_movies);
gridView.setAdapter(display); // uses the view to get the context instead of getActivity().
return rootView;
}
public class FetchMovieData extends AsyncTask<Void, Void, String[]>{
private final String LOG_TAG = FetchMovieData.class.getSimpleName();
private String[] extractdisplayFromJason(String jasnData)
throws JSONException{
//These jason display need to be extracted
final String movie_results = "results";
final String movie_poster = "poster_path";
JSONObject movieData = new JSONObject(jasnData);
JSONArray movieArray = movieData.getJSONArray(movie_results);
String[] posterAddreess = new String[movieArray.length()];
//Fill ther posterAddreess with the URL to display
for(int j=0; j < movieArray.length(); j++){
String posterPath;
JSONObject movieArrayItem = movieArray.getJSONObject(j);
posterPath = movieArrayItem.getString(movie_poster);
posterAddreess[j] = "http://image.tmdb.org/t/p/w185/" + posterPath;
}
for (String s : posterAddreess) {
Log.v(LOG_TAG, "Thumbnail Links: " + s);
}
return posterAddreess;
}
#Override
protected String[] doInBackground(Void... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String JsonData = null;
String country = "US";
String rating = "R";
String sort = "popularity.desc";
String apiKey = "";
//building the URL for the movie DB
try {
//building the URL for the movie DB
final String MovieDatabaseUrl = "https://api.themoviedb.org/3/discover/movie?";
final String Country_for_release = "certification_country";
final String Rating = "certification";
final String Sorting_Order = "sort_by";
final String Api_Id = "api_key";
Uri buildUri = Uri.parse(MovieDatabaseUrl).buildUpon()
.appendQueryParameter(Country_for_release, country)
.appendQueryParameter(Rating, rating)
.appendQueryParameter(Sorting_Order, sort)
.appendQueryParameter(Api_Id, apiKey)
.build();
//Converting URI to URL
URL url = new URL(buildUri.toString());
Log.v(LOG_TAG, "Built URI = "+ buildUri.toString());
//Create the request to the Movie Database
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
//Read the input from the database into string
InputStream inputStream = urlConnection.getInputStream();
//StringBuffer for string Manipulation
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
JsonData = buffer.toString();
Log.v(LOG_TAG,"Forecaast Jason String" + JsonData );
} catch (IOException e) {
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
try {
return extractdisplayFromJason(JsonData);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(String[] posterAddreess) {
for (String poster : posterAddreess) {
display.addItem(poster);
}
}
}
}
This the ImageAdapter code
package com.example.popularmovis;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import com.example.popularmovis.R;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ArrayList<String> images = new ArrayList<String>();
public ImageAdapter(Context c){
mContext = c;
}
#Override
public int getCount(){
return images.size();
}
#Override
public Object getItem(int position){
return images.get(position);
}
public long getItemId(int position){
return 0;
}
public View getView(int position, View convertView, ViewGroup parent){
ImageView imageview;
if (convertView == null){
imageview = new ImageView(mContext);
imageview.setPadding(0, 0, 0, 0);
//imageview.setLayoutParams(new GridLayout.MarginLayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
imageview.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageview.setAdjustViewBounds(true);
} else {
imageview = (ImageView) convertView;
}
Picasso.with(mContext).load(images.get(position)).placeholder(R.mipmap.ic_launcher).into(imageview);
return imageview;
}
/*
Custom methods
*/
public void addItem(String url){
images.add(url);
}
public void clearItems() {
images.clear();
}
}
When you use this in your onCreate method like this, it means that the object is local to the method and can't be use in other methods.
ImageAdapter display = new ImageAdapter(rootView.getContext());
First create a global class member variable
private ImageAdapter display;
then inside your onCreate method do this
display = new ImageAdapter(rootView.getContext());

Pass parameter to a URL AsyncTask android

I'm developing an app and now I have to pass a parameter to a RESTful Service's URL. I'm using AsyncTask, and I need to pass a text from a list view as a parameter to the URL, for example: the URL is http://ip:7001/product?product_name=PARAM I need to get the text from the selected item from my list view, and pass as a parameter in PARAM, using AsyncTask. I've already got the text from the item in the listView, now I just need to pass it as a parameter.
This is my AsycTask class:
package com.tumta.henrique.teste;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import com.tumta.henrique.teste.ProdutoFragment;
/**
* Created by Henrique on 18/05/2015.
*/
public class FiltraProduto extends AsyncTask<String, Void, List<String>> {
private ConsultaConcluidaFiltroProdutoListener listener;
public static String URL_STRING = "http://192.168.0.20:7001/com.henrique.rest/api/v1/status/pro_filtro?pro_nome=";
public FiltraProduto(ConsultaConcluidaFiltroProdutoListener listener) {
this.listener = listener;
}
private List<String> InterpretaResultado(String resultado) throws JSONException {
JSONObject object = new JSONObject(resultado);
JSONArray jsonArray = object.getJSONArray("produto");
//JSONObject jsonProduto = jsonArray.getJSONObject(0);
// String id = jsonProduto.getString("pro_id");
//proId = id;
List<Object> listaNomes = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonProdutoInfo = jsonArray.getJSONObject(i);
String proNome= jsonProdutoInfo.getString("pro_nome");
double proPreco = jsonProdutoInfo.getDouble("pro_preco");
double proSdAtual = jsonProdutoInfo.getDouble("pro_sdAtual");
listaNomes.add(i, proNome);
listaNomes.add(i, proPreco);
listaNomes.add(i, proSdAtual);
}
List<String> strings = new ArrayList<String>();
for (Object o : listaNomes) {
strings.add(o != null ? o.toString() : null);
}
return strings;
}
private String ConsultaServidor() throws IOException {
InputStream is = null;
try {
URL url = new URL(URL_STRING);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(10000);
conn.setReadTimeout(15000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
conn.getResponseCode();
is = conn.getInputStream();
Reader reader = null;
reader = new InputStreamReader(is);
char[] buffer = new char[2048];
reader.read(buffer);
return new String(buffer);
} finally {
if (is != null) {
is.close();
}
}
}
#Override
protected List<String> doInBackground(String... params) {
try {
String resultado = ConsultaServidor();
return InterpretaResultado(resultado);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(List<String> result) {
listener.onConsultaConcluida(result);
super.onPostExecute(result);
}
public interface ConsultaConcluidaFiltroProdutoListener {
void onConsultaConcluida(List<String> result);
}
}
In the URL_STRING I need to pass the param at pro_nome=?
Here I get the item text. This is in my Fragment that has the List View:
public String retornaParam(String param){
return param;
}
#Override
public void onConsultaConcluida(List<String> result) {
final ListView listaProdutos = (ListView) getView().findViewById(R.id.listaprodutos);
ArrayAdapter arrayAdapter = new ArrayAdapter<>(getView().getContext(),android.R.layout.simple_list_item_1, result);
listaProdutos.setAdapter(arrayAdapter);
listaProdutos.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parentAdapter, View view, int position,
long id) {
String nomeProduto = listaProdutos.getItemAtPosition(position).toString();
retornaParam(nomeProduto);
Intent intent = new Intent(getActivity(), DetalhesProdutoActivity.class);
//intent.putExtra("pro_nome", listaProdutos.getItemAtPosition(position).toString());
startActivity(intent);
}
});
}
I get the text and store it in param from the retornaParam method.
Does somebody know how to do it?
If you need more information, just let me know.
You pass in params to an AsyncTask using:
YourAsyncTask.execute(yourview.getText(), "and", "more", "params");
You can then access them in
#Override
protected String doInBackground(String... params) {
URL_STRING += params[0];
...
Just add the following code before sending executing your httpClient:
URL_STRING + = textInsideYourTextView;
It should work, just avoid to manipulate your ui elements outside your UI thread.

Null Pointer Exception at Button's onClick

I have a form having one edittext and an autocompleteview. And a button to search things based on this form. In this form I can either give value in edittext and autocompleteview may be empty and vice versa. On this basis I have passed value of these view to another activity where I made a webservice call and then fetch result.
This is activity where these view are presents:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_patient_section);
getSupportActionBar().hide();
searchByNameEditText = (EditText) findViewById(R.id.searchByNameEditText);
searchByAddressEditText = (EditText) findViewById(R.id.searchByAddressEditText);
searchButton = (Button) findViewById(R.id.searchButton);
autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.selectStateSpinner);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_dropdown_item_1line,
getResources().getStringArray(R.array.state_arrays));
autoCompleteTextView.setAdapter(adapter);
patientUtilityButton = (Button) findViewById(R.id.patientUtilityButton);
patientUtilityButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PopupMenu popupMenu = new PopupMenu(PatientSectionActivity.this, patientUtilityButton);
popupMenu.getMenuInflater().inflate(R.menu.patient_utility_button_popmenu, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
String patientUtilityMenuItem = item.toString();
patientUtilityButton.setText(patientUtilityMenuItem);
return true;
}
});
popupMenu.show();
}
});
autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectedStateValue = (String) parent.getItemAtPosition(position);
}
});
doctorName = searchByNameEditText.getText().toString();
// Search Button
searchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!selectedStateValue.equals(" ") || doctorName.equals(" ")){
Intent intent = new Intent(PatientSectionActivity.this, DoctorNameActivity.class);
intent.putExtra("State Name", selectedStateValue);
startActivity(intent);
} else if (!doctorName.equals(" ") || selectedStateValue.equals(" ")){
Intent intent = new Intent(PatientSectionActivity.this, DoctorNameActivity.class);
intent.putExtra("Name", doctorName);
startActivity(intent);
}
}
});
}
And in other activity, I get these extras from intent and make webservice call in AsyncTask but my app is crashing. Please any one help me as I am new in android.
This is my other activity
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
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.URL;
public class DoctorNameActivity extends ActionBarActivity {
ArrayAdapter<String> doctorAdapter;
ListView listView;
ProgressBar progressBar;
String doctorName;
String selectedStateValue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_doctor_name);
progressBar = (ProgressBar) findViewById(R.id.progress);
listView = (ListView) findViewById(R.id.listView);
Intent intent = getIntent();
selectedStateValue = intent.getStringExtra("State Name");
doctorName = intent.getStringExtra("Name");
if (!selectedStateValue.equals(" ") || doctorName.equals(" ")){
FetchDoctorName fetchDoctorName = new FetchDoctorName();
fetchDoctorName.execute(selectedStateValue);
}else if (!doctorName.equals(" ") || selectedStateValue.equals(" ")){
FetchDoctorName fetchDoctorName = new FetchDoctorName();
fetchDoctorName.execute(doctorName);
}
}
private class FetchDoctorName extends AsyncTask<String, Void, String[]>{
private final String LOG_TAG = FetchDoctorName.class.getSimpleName();
public String[] parseDoctorName(String jsonString) throws JSONException{
final String DOCTOR_NAME_ARRAY = "name";
JSONObject object = new JSONObject(jsonString);
JSONArray array = object.getJSONArray(DOCTOR_NAME_ARRAY);
String[] doctorNamesResult = new String[array.length()];
for (int i = 0 ; i < array.length(); i++){
String doctorName = array.getString(i);
Log.v(LOG_TAG, doctorName);
doctorNamesResult[i] = doctorName;
}
return doctorNamesResult;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setVisibility(ProgressBar.VISIBLE);
}
#Override
protected String[] doInBackground(String... params) {
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String doctorJsonString = null;
try {
final String BASE_URL = "http://mycityortho.com/display_result.php";
final String NAME_PARAM = "name";
final String STATE_PARAM = "state";
URL url = null;
if (params[0].equals(doctorName)){
Uri uri = Uri.parse(BASE_URL).buildUpon()
.appendQueryParameter(NAME_PARAM, params[0])
.build();
url = new URL(uri.toString());
Log.v(LOG_TAG, url.toString());
}else if (params[0].equals(selectedStateValue)){
Uri uri = Uri.parse(BASE_URL).buildUpon()
.appendQueryParameter(STATE_PARAM, params[0])
.build();
url = new URL(uri.toString());
Log.v(LOG_TAG, url.toString());
}
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
doctorJsonString = buffer.toString();
Log.v(LOG_TAG, doctorJsonString);
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try {
return parseDoctorName(doctorJsonString);
}catch (JSONException e){
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String[] result) {
progressBar.setVisibility(ProgressBar.GONE);
if (result != null){
doctorAdapter = new ArrayAdapter<>(DoctorNameActivity.this, android.R.layout.simple_list_item_1, result);
listView.setAdapter(doctorAdapter);
}
}
}
As per your code you are sending only one value in intent that is "State Name" or "Name" but in other activity you are trying to receive both value, that why you get null pointer exception.
So use the following code to solve this error.
searchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!selectedStateValue.equals(" ") || doctorName.equals(" ")){
Intent intent = new Intent(PatientSectionActivity.this, DoctorNameActivity.class);
intent.putExtra("State Name", selectedStateValue);
intent.putExtra("Name", " ");
startActivity(intent);
} else if (!doctorName.equals(" ") || selectedStateValue.equals(" ")){
Intent intent = new Intent(PatientSectionActivity.this, DoctorNameActivity.class);
intent.putExtra("State Name", " ");
intent.putExtra("Name", doctorName);
startActivity(intent);
}
}
});

can't fetch rss feed - android

I'm trying to develop a simple application that reads rss feeds from a certain URL and then displays the results in a list view.
Here is my rss reader, which is the main thing in the app:
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
public class RssReader {
private String title = null;
private String link = null;
private String description = null;
private ArrayList<RssItem> posts = new ArrayList<RssItem>();
private Thread thread;
private String urlString = null;
private XmlPullParserFactory xmlFactoryObject;
public volatile boolean parsingComplete = true;
public RssReader(String url) {
this.urlString = url;
}
public boolean getParsingComplete() {
return this.parsingComplete;
}
public ArrayList<RssItem> getPosts() {
return posts;
}
public void parseXML(XmlPullParser parser) {
int event;
try {
event = parser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
String name = parser.getName();
switch (event) {
case XmlPullParser.START_TAG:
break;
case XmlPullParser.END_TAG:
if (name.equals("title")) {
title = parser.getText();
} else if (name.equals("link")) {
link = parser.getText();
} else if (name.equals("description")) {
description = parser.getText();
}
break;
}
if(title != null && link != null && description != null) {
RssItem item = new RssItem(this.title,this.description,this.link);
posts.add(item);
this.title = this.description = this.link = null;
}
event = parser.next();
}
parsingComplete = false;
} catch (Exception e) {
e.printStackTrace();
}
}
public void fetchXML() {
thread = new Thread(new Runnable() {
#Override
public void run() {
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream stream = conn.getInputStream();
xmlFactoryObject = XmlPullParserFactory.newInstance();
XmlPullParser myparser = xmlFactoryObject.newPullParser();
myparser.setFeature(
XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
myparser.setInput(stream, null);
parseXML(myparser);
stream.close();
} catch (Exception e) {
} finally {
parsingComplete = true;
}
}
});
thread.start();
}
And here is my MainActivity:
package com.example.ynetrssproject;
import java.util.ArrayList;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.widget.ListView;
import android.os.Bundle;
public class MainActivity extends ActionBarActivity {
private ListView news;
private String rssUrl = "http://www.themarker.com/cmlink/1.144";
private ArrayList<RssItem> list;
private RssItemAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
news = (ListView) findViewById(R.id.news);
RssReader reader = new RssReader(rssUrl);
reader.fetchXML();
while(true) {
Log.d("Runnning", "Run");
if(reader.getParsingComplete()) {
list = reader.getPosts();
break;
}
}
adapter = new RssItemAdapter(this, R.layout.post_item_list, list);
news.setAdapter(adapter);
}
}
The problem is that everytime I call fetchXML, eventually it returns me an empty ArrayList. Therefore, my listview keeps being empty.
My adapter isn't such a big deal. It works fine. The problem is that I keep getting an empty array list from the object RssReader. I know this because I performed a little if statement at the end of the code just to check if the ArrayList is empty.
P.S I have tried with multiple RSS urls but none of them works. Also, I added the permission of Internet in my manifest.
What's wrong with my code?
Your approach is a classic java approach. With android, you should use an IntentService or an AsyncTask that perform the RSS-fetch and then sends the read items to your activity.
http://developer.android.com/reference/android/app/IntentService.html
http://developer.android.com/reference/android/os/AsyncTask.html
Don't use while(true) to poll if the reader is ready.
Be aware that, when the user rotates the screen, onCreate is executed again.

Categories

Resources