hi guys i want to sent location name and some other string values to the server...i am new in android so i dont know much about it....i pass the location and other values with url...url hits but the values are not receive by the server..help please me out...
public class SearchResult extends AppCompatActivity {
private ListView lvSearch;
private ProgressDialog dialog;
private final String URL_TO_HIT = "http://www.abcd.com/mobile_search.php";
private String location = "bathinda";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_result);
setContentView(R.layout.activity_search_result);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Search Result");
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onBackPressed();
}
});
dialog = new ProgressDialog(this);
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.setMessage("Loading. Please wait...");
// Create default options which will be used for every
// displayImage(...) call if no options will be passed to this method
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.build();
ImageLoader.getInstance().init(config); // Do it on Application start
lvSearch = (ListView)findViewById(R.id.lvSearch);
Bundle bundle = getIntent().getExtras();
String bar = bundle.getString("bar");
String nights = bundle.getString("nights");
String nearby = bundle.getString("nearby");
String deals = bundle.getString("deals");
// To start fetching the data when app start, uncomment below line to start the async task.
new JSONTask().execute(URL_TO_HIT, location, bar, nights, nearby, deals );
}
public class JSONTask extends AsyncTask<String,String, List<SearchData> >{
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog.show();
}
#Override
protected List<SearchData> doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line ="";
while ((line = reader.readLine()) != null){
buffer.append(line);
}
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("search");
List<SearchData> searchDataList = new ArrayList<>();
Gson gson = new Gson();
for(int i=0; i<parentArray.length(); i++) {
JSONObject finalObject = parentArray.getJSONObject(i);
/**
* below single line of code from Gson saves you from writing the json parsing yourself which is commented below
*/
SearchData searchData = gson.fromJson(finalObject.toString(), SearchData.class);
searchDataList.add(searchData);
}
return searchDataList;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if(connection != null) {
connection.disconnect();
}
try {
if(reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(final List<SearchData> result) {
super.onPostExecute(result);
dialog.dismiss();
if(result != null) {
SearchAdapter adapter = new SearchAdapter(getApplicationContext(), R.layout.searchresultrow, result);
lvSearch.setAdapter(adapter);
} else {
Toast.makeText(getApplicationContext(), "Not able to fetch data from server, please check internet", Toast.LENGTH_SHORT).show();
}
}
}
public class SearchAdapter extends ArrayAdapter{
private List<SearchData> searchDataList;
private int resource;
private LayoutInflater inflater;
public SearchAdapter(Context context, int resource, List<SearchData> objects) {
super(context, resource, objects);
searchDataList = objects;
this.resource = resource;
inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
holder = new ViewHolder();
convertView = inflater.inflate(resource, null);
holder.searchimg11 = (ImageView)convertView.findViewById(R.id.searchimg1);
holder.barname1 = (TextView)convertView.findViewById(R.id.barname);
holder.address1 = (TextView)convertView.findViewById(R.id.address);
holder.offer1 = (TextView)convertView.findViewById(R.id.offer);
holder.hourtext1 = (TextView)convertView.findViewById(R.id.hourtext);
holder.coststext1 = (TextView)convertView.findViewById(R.id.coststext);
holder.textv11 = (TextView)convertView.findViewById(R.id.textv1);
holder.featuredtext1 = (TextView)convertView.findViewById(R.id.featuredtext);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//final ProgressBar progressBar = (ProgressBar)convertView.findViewById(R.id.progressBar);
// Then later, when you want to display image
ImageLoader.getInstance().displayImage(searchDataList.get(position).getBar_image(), holder.searchimg11, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
// progressBar.setVisibility(View.VISIBLE);
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
//progressBar.setVisibility(View.GONE);
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// progressBar.setVisibility(View.GONE);
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
// progressBar.setVisibility(View.GONE);
}
});
holder.barname1.setText(searchDataList.get(position).getBarname());
holder.address1.setText(searchDataList.get(position).getLocation());
holder.offer1.setText( searchDataList.get(position).getOffers());
holder.hourtext1.setText( searchDataList.get(position).getOpen_hours());
holder.coststext1.setText(searchDataList.get(position).getCost_for_two());
holder.textv11.setText(searchDataList.get(position).getFreebe());
holder.featuredtext1.setText(searchDataList.get(position).getFeaured());
return convertView;
}
class ViewHolder{
private ImageView searchimg11;
private TextView address1;
private TextView offer1;
private TextView hourtext1;
private TextView coststext1;
private TextView textv11;
private TextView barname1;
private TextView featuredtext1;
}
}
}
You are not passing any parameters to the server there . You are calling URL without any parameters
Read this solution to know how to pass parameters to HttpURLConnection using POST
How to add parameters to HttpURLConnection using POST
I did not go through your code. I suggest you to use the library to do much of the work instead of you developing on top of HTTP stack.
Use Retrofit(http://square.github.io/retrofit/) or Volley(https://developer.android.com/training/volley/index.html).
Retrofit is easy to use and manage but volley give you lot of control. Since you are new to programming on the client side, I suggest you use the Retrofit. You can't go wrong with sending JSON data, and few post using this libraries.
Related
I hope someone out there can help me solve my problem. I have android app that have 3 tabs, i use fragment, first tab is recyclerView list, second tabs is map. the problem is in tabs 1, i need to fetch data with volley to recyclerView on tabs 1, if run fine but i cannot see the data on first app start, but when i change tab and back to tab 1 again it will refresh the data and show the data on recyclerView.
Adapter.java
public class CustomListAdapterWarkop extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Warkop> mWarkop;
private LayoutInflater inflater;
public CustomListAdapterWarkop(Context context, List<Warkop> mWarkop) {
this.context=context;
inflater= LayoutInflater.from(context);
this.mWarkop = mWarkop;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.list_warkop_row, parent, false);
ItemViewHolder holder = new ItemViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ItemViewHolder viewHolder = (ItemViewHolder) holder;
Warkop current = mWarkop.get(position);
viewHolder.tvNamaWarkop.setText(current.getNamaWarkop());
ImageLoader imageLoader = ImageLoader.getInstance();
DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true)
.cacheOnDisc(true).resetViewBeforeLoading(true)
.showImageForEmptyUri(R.drawable.noimage)
.showImageOnFail(R.drawable.noimage)
.showImageOnLoading(R.drawable.noimage).build();
imageLoader.displayImage(current.getFotoWarkop(), viewHolder.ivFotoWarkop, options);
}
#Override
public int getItemCount() {
return mWarkop.size();
}
}
ItemHolder.java
package com.andylah.warkopedia;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
* Created by andylah on 11/3/2017.
*/
public class ItemViewHolder extends RecyclerView.ViewHolder {
public ImageView ivFotoWarkop;
public TextView tvNamaWarkop;
public ItemViewHolder(View itemView) {
super(itemView);
tvNamaWarkop = itemView.findViewById(R.id.nama_warkop);
ivFotoWarkop = itemView.findViewById(R.id.image_warkop);
}
}
Tab 1.java
public class tabSatu extends Fragment {
private static final String TAG = tabDua.class.getSimpleName();
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private boolean isFragmentLoaded = false;
View vTabSatu;
private RecyclerView recyclerView;
public static List<Warkop> warkopList = new ArrayList<Warkop>();
private CustomListAdapterWarkop warkopAdapter;
public tabSatu(){
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
new AsyncFetch().execute();
vTabSatu = inflater.inflate(R.layout.tabsatu_view, container, false);
recyclerView = vTabSatu.findViewById(R.id.warkop_container);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
Log.d("LOG : ", "onCreatedView Run");
// Inflate the layout for this fragment
return vTabSatu;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
warkopAdapter = new CustomListAdapterWarkop(getActivity(), warkopList);
warkopAdapter.notifyDataSetChanged();
recyclerView.setAdapter(warkopAdapter);
Log.d("LOG : ", "onViewCreated Run");
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && !isFragmentLoaded ) {
// Load your data here or do network operations here
isFragmentLoaded = true;
//new AsyncFetch().execute();
}else{
isFragmentLoaded = false;
Log.d("LOG : ", "isFragmentLoaded = false");
}
}
private class AsyncFetch extends AsyncTask<String, String, String> {
ProgressDialog pDialog = new ProgressDialog(getActivity());
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog.setMessage("Loading list warkop ...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... strings) {
try {
// Enter URL address where your json file resides
// Even you can make call to php file which returns json data
url = new URL(AppConfig.LOAD_WARKOP);
} 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("POST");
// 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) {
pDialog.dismiss();
try{
JSONObject object = new JSONObject(result);
String getObject = object.getString("warkop");
JSONArray jsonArray = new JSONArray(getObject);
boolean error = object.getBoolean("error");
if(!error){
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Warkop warkop = new Warkop();
warkop.setNamaWarkop(jsonObject.getString("nama_warkop"));
warkop.setAlamatWrkop(jsonObject.getString("alamat_warkop"));
warkop.setKotaWarkop(jsonObject.getString("kota_warkop"));
warkop.setLatWarkop(Double.parseDouble(jsonObject.getString("lat_warkop")));
warkop.setLangWarkop(Double.parseDouble(jsonObject.getString("long_warkop")));
warkop.setIsWifi(Integer.parseInt(jsonObject.getString("is_wifi")));
warkop.setIsToilet(Integer.parseInt(jsonObject.getString("is_toilet")));
warkop.setIsTv(Integer.parseInt(jsonObject.getString("is_tv")));
warkop.setIsColokan(Integer.parseInt(jsonObject.getString("is_colokan")));
warkop.setIsParkir(Integer.parseInt(jsonObject.getString("is_parkir")));
warkop.setFotoWarkop(jsonObject.getString("foto_warkop"));
warkopList.add(warkop);
}
}else{
String errorMsg = object.getString("error_msg");
Toast.makeText(getContext(),
errorMsg, Toast.LENGTH_LONG).show();
}
}catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getActivity(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
}
Problem: Even you call notifyDataSetChanged() but there are no data in Adapter.
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
warkopAdapter = new CustomListAdapterWarkop(getActivity(), warkopList);
warkopAdapter.notifyDataSetChanged();
recyclerView.setAdapter(warkopAdapter);
}
So you need to set and notify warkopList to Adapter after API call. It will help you.
tabSatu:
#Override
protected void onPostExecute(String result) {
pDialog.dismiss();
try {
JSONObject object = new JSONObject(result);
String getObject = object.getString("warkop");
JSONArray jsonArray = new JSONArray(getObject);
boolean error = object.getBoolean("error");
if (!error) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Warkop warkop = new Warkop();
...
warkopList.add(warkop);
adapter.setItems(warkopList);
}
}
...
}
CustomListAdapterWarkop: add setItem() method to Adapter
public class CustomListAdapterWarkop extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
...
public void setItems(List<WarkopList> warkopList) {
mWarkop = warkopList;
notifyDataSetChanged();
}
...
}
I am loading JSON from server but the app crashes if the internet is not available. How to fix this problem? I have added try catch in most part. Unable to find the problem. lvMovies.setAdapter(adapter); gives error when internet is not available. Code works fine when internet is available
public class JSONTest extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {
private ListView lvMovies;
private ProgressDialog dialog;
private SwipeRefreshLayout swipeRefreshLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_jsontest);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeMovieHits);
swipeRefreshLayout.setOnRefreshListener(this);
// Create default options which will be used for every
// displayImage(...) call if no options will be passed to this method
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.build();
ImageLoader.getInstance().init(config); // Do it on Application start
lvMovies = (ListView) findViewById(R.id.lvMovies);
dialog = new ProgressDialog(this);
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.setMessage("Loading...");
//new JSONTask().execute("http://ankushkapoor2016.16mb.com/ankush/myjson.txt");
//new JSONTask().execute("http://jsonparsing.parseapp.com/jsonData/moviesDemoList.txt");
}
#Override
public void onRefresh() { //SwipeRefreshLayout Refresh Listener
try {
new JSONTask().execute("http://jsonparsing.parseapp.com/jsonData/moviesData.txt");
} catch (Exception e) {
Toast.makeText(JSONTest.this, e.getMessage() + "\n\n" + e.getCause(), Toast.LENGTH_LONG).show();
}
}
public class JSONTask extends AsyncTask<String, String, List<MovieModel>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog.show();
}
#Override
protected List<MovieModel> doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson1 = buffer.toString();
SharedPreferences sharedPreferences = getSharedPreferences("JSON_DATA", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("json", finalJson1);
editor.commit();
String finalJson=sharedPreferences.getString("json","N/A");
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = parentObject.getJSONArray("movies");
List<MovieModel> movieModelList = new ArrayList<>();
for (int i = 0; i < parentArray.length(); i++) {
JSONObject finalObject = parentArray.getJSONObject(i);
MovieModel movieModel = new MovieModel();
movieModel.setMovie(finalObject.getString("movie"));
movieModel.setYear(finalObject.getInt("year"));
movieModel.setRating((float) finalObject.getDouble("rating"));
movieModel.setDuration(finalObject.getString("duration"));
movieModel.setDirector(finalObject.getString("director"));
movieModel.setTagline(finalObject.getString("tagline"));
movieModel.setImage(finalObject.getString("image"));
movieModel.setStory(finalObject.getString("story"));
List<MovieModel.Cast> castList = new ArrayList<>();
for (int j = 0; j < finalObject.getJSONArray("cast").length(); j++) {
MovieModel.Cast cast = new MovieModel.Cast();
cast.setName(finalObject.getJSONArray("cast").getJSONObject(j).getString("name"));
castList.add(cast);
}
movieModel.setCastList(castList);
movieModelList.add(movieModel);
}
return movieModelList;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null)
connection.disconnect();
try {
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(List<MovieModel> s) {
super.onPostExecute(s);
dialog.dismiss();
MovieAdapter adapter = new MovieAdapter(getApplicationContext(), R.layout.row, s);
lvMovies.setAdapter(adapter);
if (swipeRefreshLayout.isRefreshing()) {
swipeRefreshLayout.setRefreshing(false);
}
}
}
public class MovieAdapter extends ArrayAdapter {
private List<MovieModel> movieModelList;
private int resource;
private LayoutInflater inflater;
public MovieAdapter(Context context, int resource, List<MovieModel> objects) {
super(context, resource, objects);
movieModelList = objects;
this.resource = resource;
inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(resource, null);
holder.ivMovieIcon = (ImageView) convertView.findViewById(R.id.ivIcon);
holder.tvMovie = (TextView) convertView.findViewById(R.id.tvMovie);
holder.tvTagline = (TextView) convertView.findViewById(R.id.tvTagline);
holder.tvYear = (TextView) convertView.findViewById(R.id.tvYear);
holder.tvDuration = (TextView) convertView.findViewById(R.id.tvDuration);
holder.tvDirector = (TextView) convertView.findViewById(R.id.tvDirector);
holder.rbMovieRating = (RatingBar) convertView.findViewById(R.id.rbMovie);
holder.tvCast = (TextView) convertView.findViewById(R.id.tvCast);
holder.tvStory = (TextView) convertView.findViewById(R.id.tvStory);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final ProgressBar progressBar;
progressBar = (ProgressBar) convertView.findViewById(R.id.progressBar);
try {
ImageLoader.getInstance().displayImage(movieModelList.get(position).getImage(), holder.ivMovieIcon, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
progressBar.setVisibility(View.VISIBLE);
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
progressBar.setVisibility(View.GONE);
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
progressBar.setVisibility(View.GONE);
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
progressBar.setVisibility(View.GONE);
}
});
holder.tvMovie.setText(movieModelList.get(position).getMovie());
holder.tvTagline.setText(movieModelList.get(position).getTagline());
holder.tvYear.setText("Year: " + movieModelList.get(position).getYear());
holder.tvDuration.setText(movieModelList.get(position).getDuration());
holder.tvDirector.setText(movieModelList.get(position).getDirector());
holder.rbMovieRating.setRating(movieModelList.get(position).getRating() / 2);
StringBuffer stringBuffer = new StringBuffer();
for (MovieModel.Cast cast : movieModelList.get(position).getCastList()) {
stringBuffer.append(cast.getName() + ", ");
}
holder.tvCast.setText(stringBuffer);
holder.tvStory.setText(movieModelList.get(position).getStory());
} catch (Exception e) {
Toast.makeText(getContext(), e.getMessage() + "\n" + e.getCause(), Toast.LENGTH_SHORT).show();
}
return convertView;
}
class ViewHolder {
private ImageView ivMovieIcon;
private TextView tvMovie;
private TextView tvTagline;
private TextView tvYear;
private TextView tvDuration;
private TextView tvDirector;
private RatingBar rbMovieRating;
private TextView tvCast;
private TextView tvStory;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_json, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.jsonRefresh) {
try {
new JSONTask().execute("http://jsonparsing.parseapp.com/jsonData/moviesData.txt");
return true;
} catch (Exception e) {
Toast.makeText(JSONTest.this, e.getMessage() + "\n\n" + e.getCause(), Toast.LENGTH_LONG).show();
}
}
return super.onOptionsItemSelected(item);
}
}
To prevent crash you should check is device have internet connection, to do that you can use:
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
You will also need to add to your AndroidManifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
If you provide logcat message, then maybe I can tell you more about your problem.
Your problem is that you are returning a null arraylist when the internet exceptions are caught. So, the onPostExecute gets null, then the adapter gets null.
If you don't want a null value, pre-declare an empty list and always return it.
Then, the app won't crash, but you will see no data populate in the list, so you may want to do some additional validation that internet is available.
#Override
protected List<MovieModel> doInBackground(String... params) {
List<MovieModel> movieModelList = new ArrayList<>();
try {
// TODO: Stuff
return movieModelList;
} catch ( ... ) {
} finally {
}
return movieModelList;
}
First of all, PLEASE HELP ... I have done almost everything to figure out and now I am here !
1st confusion is: why on earth Async class works so slow, I am using the click event to fetch some data from api, while using SYSO to see the output of populated array in Android monitor, it nearly took 4,5 seconds every time to populate the arraylist with 20 elements. There must be something very wrong which i dont know right now ....
Activity code is :
Toolbar toolbar;
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_news);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Get Request
String url = "MY URL HERE";
new JSONAsync(getApplicationContext()).execute(url);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(MainNews.this, JSONAsync.dataArray);
recyclerViewAdapter.notifyDataSetChanged();
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(recyclerViewAdapter);
recyclerViewAdapter.notifyDataSetChanged();
}
Async class is written as:
Context context;
public static List<Data> dataArray = new ArrayList<>();
public JSONAsync(Context context) {
this.context = context;
dataArray.clear();
}
#Override
protected Boolean doInBackground(String... params) {
try {
return downloadUrl(params[0]);
} catch (IOException e) {
return false;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
public boolean downloadUrl(String myurl) throws IOException, JSONException {
InputStream is = null;
int response;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
response = conn.getResponseCode();
is = conn.getInputStream();
if (response == 200) {
String responseBody = convertToString(conn.getInputStream());
JSONArray jArray = new JSONArray(responseBody);
for (int i = 0; i < jArray.length(); i++) {
JSONObject jobj = jArray.getJSONObject(i);
System.out.println("Output is: ....."+jobj);
Data data = new Data();
data.setId(jobj.getInt("id"));
data.setHeading(jobj.getString("heading"));
data.setBrief(jobj.getString("brief"));
data.setDate(jobj.getString("date"));
String imageURL = "http://paktribune.com/images/news/";
imageURL = imageURL.concat(jobj.getString("limage"));
data.setImage(getBitmapFromURL(imageURL));
dataArray.add(data);
}
return true;
} else return false;
} finally {
if (is != null) {
is.close();
}
}
}
public Bitmap getBitmapFromURL(String imageURL) {
Bitmap myBitmap = null;
try {
int responseCode;
URL url = new URL(imageURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
responseCode = connection.getResponseCode();
if (responseCode==200)
{
InputStream input = connection.getInputStream();
myBitmap = BitmapFactory.decodeStream(input);
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
return myBitmap;
}
public String convertToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
} catch (IOException e) {
} finally {
try {
is.close();
} catch (IOException e) {
}
}
return sb.toString();
}
#Override
protected void onPostExecute(Boolean result) {
if (result == false) {
Toast.makeText(context, "Unable to fetch data from server", Toast.LENGTH_SHORT).show();
}
}
And the adapter is :
private LayoutInflater inflater;
Context context;
List<Data> dataArray;
private int lastPosition = -1;
public RecyclerViewAdapter(Context context, List<Data> dataArray) {
this.dataArray = dataArray;
this.context = context;
inflater = LayoutInflater.from(context);
}
#Override
public RecyclerViewAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.cardview, parent, false);
CustomViewHolder holder = new CustomViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
Data current = dataArray.get(position);
holder.textView1.setText(current.heading);
holder.textView2.setText(current.date);
holder.textView3.setText(current.brief);
holder.image.setImageBitmap(current.image);
setAnimation(holder.relativeLayout, position);
}
#Override
public int getItemCount() {
return dataArray.size();
}
public static class CustomViewHolder extends admin.myproject.CustomViewHolder {
ImageView image;
RelativeLayout relativeLayout;
TextView textView1, textView2, textView3;
public CustomViewHolder(View itemView) {
super(itemView);
textView1 = (TextView) itemView.findViewById(R.id.heading);
textView2 = (TextView) itemView.findViewById(R.id.date);
textView3 = (TextView) itemView.findViewById(R.id.brief);
image = (ImageView) itemView.findViewById(R.id.imageView);
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.Relative);
}
}
private void setAnimation(View viewToAnimate, int position) {
if (position > lastPosition) {
Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
Can anyone tell me why the app moves to the next activity when i click some button before the loop in doInBackground completes.
I am clearing the dataArray and also updating the notifyDataSetChanged(). If i use the notifyDataSetChanged() in doInBackground() or in postExecute method, it just points the Null pointer exception so this is the reason I am using it in adapter but i think it's okay to use it there as well.
PLEASE HELP guys !
Your logic is flawed and the implementation is vulnerable to many problematic issues.
1) Async task, as its name suggets performs its task asynchronously. That is, the line new JSONAsync(getApplicationContext()).execute(url); returns immediately and execution continues in the activity. As you tell the adapter that data is ready, it most probably is not ready and async task is trying to do its job in the mean time.
2) Using the static member to communicate in a multi-threaded environment is prone to errors. Instead, implement a listener interface in your activity and let the async task call the listener's method in onPostExecute. Only then tell the adapter about the data change.
private List<Data> dataArray = new ArrayList<>();
private IAsyncTaskListener listener;
public JSONAsync(Context context, IAsyncTaskListener listener) {
this.context = context;
this.listener = listener;
}
public interface IAsyncTaskListener {
void onCompleted(List<Data> dataArray);
}
#Override
protected void onPostExecute(Boolean result) {
this.listener.onCompleted(dataArray);
}
Your activity can implement IAsyncTaskListener
public class YourActivity extends AppCompatActivity implements JSONAsync.IAsyncTaskListener {
#Override
public void onCompleted(List<Data> dataArray) {
recyclerViewAdapter.setData(dataArray);
recyclerViewAdapter.notifyDataSetChanged();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_news);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Get Request
String url = "http://paktribune.com/api/newsList";
new JSONAsync(getApplicationContext(), this).execute(url);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(MainNews.this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(recyclerViewAdapter);
}
}
You would provide a method to change the adapter's data. In the listener callback, you set the data on the adapter and call notifyDataSetChanged on it, to inform the adapter about the changes.
Try using Picasso or Glide library for downloading images. Those libraries might provide faster downloads, their cache handling is better.
I am working on an app which performs (in an AsyncTask) a query to a remote server obtaining a JSON string.
To show the data on my ListView i have extended an ArrayAdapter.
When i execute my app, from the LogCat i can see that data is retrieved correctly but not shown in the ListView.
The only way i have to make everything work (and data be shown on the ListView) is by running the app in Debug mode, set a breakpoint on the line
myListView.setAdapter(myAdapter);
wait for a couple seconds and then resume the application.
After this procedure, everything works correctly.
Why is this happening?
Is the AsyncTask the right way for such a long operation, or should I use some other approach (but i don't know which one!).
Here is the MainActivity code
public class MainActivityFragment extends Fragment {
private List<Station> stationList = new ArrayList<Station>();
private StationAdapter stationsAdapter;
private ProgressDialog pd;
private String LOG_TAG = "ProvaAsyncTask";
public MainActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
mioAsync mioTask = new mioAsync();
mioTask.execute();
stationsAdapter = new StationAdapter(stationList, getActivity());
ListView stationsListView = (ListView) rootView.findViewById(R.id.miaListView);
stationsListView.setAdapter(stationsAdapter);
return rootView;
}
public class mioAsync extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Creo la ProgressDialog che precede il caricamento dei dati
pd = new ProgressDialog(getActivity());
pd.setMessage(MainActivityFragment.this.getString(R.string.preloader_stations_list));
pd.show();
}
#Override
protected Void doInBackground(Void... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String forecastJsonStr = null;
try {
URL url = new URL("*remoteserver*");
// Create the request to the server, and open the connection
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) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
forecastJsonStr = buffer.toString();
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
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{
getStationsListFromJson(forecastJsonStr);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
pd.dismiss();
}
private void getStationsListFromJson(String stationsJsonStr) throws JSONException {
JSONArray stationsArray = new JSONArray(stationsJsonStr);
String nomeStaz;
String numSat;
stationList.clear();
for (int i = 0; i < stationsArray.length(); i++) {
JSONObject j = stationsArray.optJSONObject(i);
Iterator it = j.keys();
while (it.hasNext()) {
String n = it.next().toString();
numSat = j.getString(n) + " stazioni";
n = it.next().toString();
nomeStaz = j.getString(n);
stationList.add(new Station(nomeStaz, numSat));
}
}
}
}
}
The JSON string i get in return is like this
[{"nome":"Station1","satelliti":"11"},{"nome":"Station2","satelliti":"9"},{"nome":"Station3","satelliti":"8"}]
Here is where i extend the ArrayList
public class StationAdapter extends ArrayAdapter<Station> {
private List<Station> stationsList;
private Context context;
public StationAdapter(List<Station> lista, Context cont){
super(cont, R.layout.listitems, lista);
this.stationsList = lista;
this.context = cont;
}
public int getCount() {
return stationsList.size();
}
public Station getItem(int position) {
return stationsList.get(position);
}
public long getItemId(int position) {
return stationsList.get(position).hashCode();
}
public View getView(int position, View convertView, ViewGroup parent){
View v = convertView;
StationHolder holder = new StationHolder();
// controllo che il convertview non sia null
if (convertView == null){
// This a new view we inflate the new layout
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.listitems, null);
// Now we can fill the layout with the right values
TextView stationName = (TextView) v.findViewById(R.id.testataUno);
TextView satellitesNumber = (TextView) v.findViewById(R.id.testataDue);
holder.stationNameView = stationName;
holder.satellitesNumberView = satellitesNumber;
v.setTag(holder);
} else {
holder = (StationHolder) v.getTag();
}
Station p = stationsList.get(position);
holder.stationNameView.setText(p.getName());
holder.satellitesNumberView.setText("" + p.getSatellites());
return v;
}
/* *********************************
* We use the holder pattern
* It makes the view faster and avoid finding the component
* **********************************/
private static class StationHolder {
public TextView stationNameView;
public TextView satellitesNumberView;
}
}
Here is the Station code
public class Station {
private String name;
private String satellites;
public Station(String nome, String satelliti){
this.name = nome;
this.satellites = satelliti;
}
public String getName(){
return this.name;
}
public String getSatellites(){
return this.satellites;
}
public void setName(String nome){
this.name = nome;
}
public void setSatellites(String satelliti){
this.satellites = satelliti;
}
}
You got the flow broken. It works in debug mode only because you stop execution of UI thread on your breakpoint, but line before your breakpoint you fired AsyncTask, and as this is not stopped, it downloads the data while you enjoy your breakpoint. You most likely assumed that AsyncTask (which is abbreviation of Asynchronous Task) is... well... synchronous. It's not. Your main code will not wait for asynctask,it will start it and continue. You need to rework your code and in asynctask's onPostExecute() method update your dataset based on downloaded content and then call notifyDatasetChanged() on your list's adapter. That should trigger list refresh.
I have to ListView custom adapters returning both Twitter and Facebook feeds. Also they do have their own XML. Till now I was showing them in separate Activity, now I am planning to combine both data and show in one adapter. I heard there is some concept like "Merge Adapters". Can someone help me with below posted code ?
File : FacebookAdapter.java :
public class FacebookAdapter extends ArrayAdapter<RssFeedStructure> {
List<RssFeedStructure> imageAndTexts1 = null;
public FacebookAdapter(Activity activity,
List<RssFeedStructure> imageAndTexts) {
super(activity, 0, imageAndTexts);
imageAndTexts1 = imageAndTexts;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Activity activity = (Activity) getContext();
LayoutInflater inflater = activity.getLayoutInflater();
View rowView = inflater.inflate(R.layout.facebookadapter, null);
TextView textView = (TextView) rowView.findViewById(R.id.feed_text);
TextView timeFeedText = (TextView) rowView
.findViewById(R.id.feed_updatetime);
ImageView imageView = (ImageView) rowView.findViewById(R.id.feed_image);
try {
Log.d("rssfeed", "imageAndTexts1.get(position).getImgLink() :: "
+ imageAndTexts1.get(position).getImgLink() + " :: "
+ imageAndTexts1.get(position).getTitle());
textView.setText(imageAndTexts1.get(position).getDescription());
SpannableString content = new SpannableString(imageAndTexts1.get(
position).getPubDate());
content.setSpan(new UnderlineSpan(), 0, 13, 0);
timeFeedText.setText(content);
if (imageAndTexts1.get(position).getImgLink() != null) {
URL feedImage = new URL(imageAndTexts1.get(position)
.getImgLink().toString());
if (!feedImage.toString().equalsIgnoreCase("null")) {
HttpURLConnection conn = (HttpURLConnection) feedImage
.openConnection();
InputStream is = conn.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is);
imageView.setImageBitmap(img);
} else {
imageView.setBackgroundResource(R.drawable.rss_tab_tweets);
}
}
} catch (MalformedURLException e) {
} catch (IOException e) {
}
return rowView;
}
}
File : FacebookActivity.java :
public class FacebookFeeds extends Activity {
/** Called when the activity is first created. */
ListView _rssFeedListView;
List<JSONObject> jobs;
List<RssFeedStructure> rssStr;
private FacebookAdapter _adapter;
String sorti = "";
String mode = "";
//Button sort_Btn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview);
_rssFeedListView = (ListView) findViewById(R.id.rssfeed_listview);
RssFeedTask rssTask = new RssFeedTask();
rssTask.execute();
}
private class RssFeedTask extends AsyncTask<String, Void, String> {
// private String Content;
private ProgressDialog Dialog;
String response = "";
#Override
protected void onPreExecute() {
Dialog = new ProgressDialog(FacebookFeeds.this);
Dialog.setMessage("Rss Loading...");
Dialog.show();
}
#Override
protected String doInBackground(String... urls) {
try {
String feed = "https://someurl";
XmlHandler rh = new XmlHandler();
rssStr = rh.getLatestArticles(feed);
} catch (Exception e) {
}
return response;
}
#Override
protected void onPostExecute(String result) {
if (rssStr != null) {
_adapter = new FacebookAdapter(FacebookFeeds.this, rssStr);
_rssFeedListView.setAdapter(_adapter);
}
Dialog.dismiss();
}
}
}
File : TwitterAdapter.java :
public class TwitterAdapter extends ArrayAdapter<RssFeedStructure> {
List<RssFeedStructure> imageAndTexts1 = null;
public TwitterAdapter(Activity activity,
List<RssFeedStructure> imageAndTexts) {
super(activity, 0, imageAndTexts);
imageAndTexts1 = imageAndTexts;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Activity activity = (Activity) getContext();
LayoutInflater inflater = activity.getLayoutInflater();
View rowView = inflater.inflate(R.layout.twitteradapter, null);
TextView textView = (TextView) rowView.findViewById(R.id.feed_text);
TextView timeFeedText = (TextView) rowView
.findViewById(R.id.feed_updatetime);
ImageView imageView = (ImageView) rowView.findViewById(R.id.feed_image);
try {
Log.d("rssfeed", "imageAndTexts1.get(position).getImgLink() :: "
+ imageAndTexts1.get(position).getImgLink() + " :: "
+ imageAndTexts1.get(position).getTitle());
textView.setText(imageAndTexts1.get(position).getTitle());
SpannableString content = new SpannableString(imageAndTexts1.get(
position).getPubDate());
content.setSpan(new UnderlineSpan(), 0, 13, 0);
timeFeedText.setText(content);
if (imageAndTexts1.get(position).getImgLink() != null) {
URL feedImage = new URL(imageAndTexts1.get(position)
.getImgLink().toString());
if (!feedImage.toString().equalsIgnoreCase("null")) {
HttpURLConnection conn = (HttpURLConnection) feedImage
.openConnection();
InputStream is = conn.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is);
imageView.setImageBitmap(img);
} else {
imageView.setBackgroundResource(R.drawable.rss_tab_tweets);
}
}
} catch (MalformedURLException e) {
} catch (IOException e) {
}
return rowView;
}
}
File : TwitterActivity.java :
public class TwitterFeeds extends Activity {
/** Called when the activity is first created. */
ListView _rssFeedListView;
List<JSONObject> jobs;
List<RssFeedStructure> rssStr;
private TwitterAdapter _adapter;
String sorti = "";
String mode = "";
//Button sort_Btn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview);
_rssFeedListView = (ListView) findViewById(R.id.rssfeed_listview);
RssFeedTask rssTask = new RssFeedTask();
rssTask.execute();
}
private class RssFeedTask extends AsyncTask<String, Void, String> {
// private String Content;
private ProgressDialog Dialog;
String response = "";
#Override
protected void onPreExecute() {
Dialog = new ProgressDialog(TwitterFeeds.this);
Dialog.setMessage("Rss Loading...");
Dialog.show();
}
#Override
protected String doInBackground(String... urls) {
try {
String feed = "https://someurl";
XmlHandler rh = new XmlHandler();
rssStr = rh.getLatestArticles(feed);
} catch (Exception e) {
}
return response;
}
#Override
protected void onPostExecute(String result) {
if (rssStr != null) {
_adapter = new TwitterAdapter(TwitterFeeds.this,
rssStr);
_rssFeedListView.setAdapter(_adapter);
}
Dialog.dismiss();
}
}
}
Maybe this MergeAdapter can help you : https://github.com/commonsguy/cwac-merge
Make a new adapter something like FacebookTwitterAdapter, probably taking both adapters as constructor parameters.
getViewTypeCount - Return 2 (either facebook or twitter view)
getItemViewType - Return 0 for facebook view and 1 for twitter view
getView - Return either the facebook or twitter view depending on how you want to display the views maybe by timeline?
The easiest option might be to create one giant arraylist of items, and populating it over a single listview, maybe you could assign section breaks in between in the listview and maybe you can design custom layouts to differentiate facebook and twitter layouts. OR you can use "mergeadapter" by "commonsware" in "github".