I have a feature in my app that gets a users gps coordinates then returns nearby breweries. When I use the feature it has never forced closed, and others have tested it to and it worked. One user reported this error when they opened the activity that gets the user location and tries to get the location of breweries:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.beerportfolio.beerportfoliopro/com.example.beerportfoliopro.FindBrewery}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2355)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2391)
at android.app.ActivityThread.access$600(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1335)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5511)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.beerportfoliopro.FindBrewery.onCreate(FindBrewery.java:42)
at android.app.Activity.performCreate(Activity.java:5066)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1101)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2311)
... 11 more
My activity that is launched is:
package com.example.beerportfoliopro;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.widget.TextView;
import android.widget.Toast;
import com.beerportfolio.beerportfoliopro.R;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
* Created by mike on 7/3/13.
*/
public class FindBrewery extends ActionbarMenu {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.beer_location_list);
String title = "Nearby Breweries";
TextView topTitle = (TextView) findViewById(R.id.beerLocationTitle);
topTitle.setText(title);
//get user location
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
double longitude = location.getLongitude();
double latitude = location.getLatitude();
//construct url
String url = myURLandKey;
Log.d("urlTest",url);
//async task goes here
new GetNearbyBreweries(this).execute(url);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main2, menu);
return true;
}
}
Lastly my asynctask is:
package com.example.beerportfoliopro;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import com.beerportfolio.beerportfoliopro.R;
public class GetNearbyBreweries extends AsyncTask
<String, Void, String> {
Context c;
private ProgressDialog Dialog;
public GetNearbyBreweries (Context context)
{
c = context;
Dialog = new ProgressDialog(c);
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
return readJSONFeed(arg0[0]);
}
protected void onPreExecute() {
Dialog.setMessage("Locating Breweries");
Dialog.setTitle("Loading");
Dialog.setCancelable(false);
Dialog.show();
}
protected void onPostExecute(String result){
//decode json here
try{
JSONObject json = new JSONObject(result);
//acces listview
ListView lv = (ListView) ((Activity) c).findViewById(R.id.locationList);
//make array list for beer
final List<BreweryLocationData> tasteList = new ArrayList<BreweryLocationData>();
for(int i = 0; i < json.getJSONArray("data").length(); i++) {
String brewery = json.getJSONArray("data").getJSONObject(i).getJSONObject("brewery").getString("name");
String id = json.getJSONArray("data").getJSONObject(i).getJSONObject("brewery").getString("id");
String latitude = json.getJSONArray("data").getJSONObject(i).getString("latitude");
String longitude = json.getJSONArray("data").getJSONObject(i).getString("longitude");
String distance = json.getJSONArray("data").getJSONObject(i).getString("distance");
int count = i + 1;
//create object
BreweryLocationData tempLocation = new BreweryLocationData(brewery, id, longitude , latitude,distance);
//add to arraylist
tasteList.add(tempLocation);
//add items to listview
BreweryLocationInfoAdapter adapter1 = new BreweryLocationInfoAdapter(c ,R.layout.listview_item_row, tasteList);
lv.setAdapter(adapter1);
//set up clicks
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
BreweryLocationData o=(BreweryLocationData)arg0.getItemAtPosition(arg2);
String tempID = o.id;
Toast toast = Toast.makeText(c, tempID, Toast.LENGTH_SHORT);
toast.show();
//get beer details from id
Intent myIntent = new Intent(c, BreweryPage2.class);
myIntent.putExtra("id", tempID);
c.startActivity(myIntent);
}
});
}
}
catch(Exception e){
}
Dialog.dismiss();
}
public String readJSONFeed(String URL) {
StringBuilder stringBuilder = new StringBuilder();
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(URL);
try {
HttpResponse response = httpClient.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
inputStream.close();
} else {
Log.d("JSON", "Failed to download file");
}
} catch (Exception e) {
Log.d("readJSONFeed", e.getLocalizedMessage());
}
return stringBuilder.toString();
}
}
You are getting a force close when attempting to get the users location. I would add validation that the use has GPS enabled and if not then give them an alert dialog asking them to enable, you may also send them directly to GPS settings.
Can the user reproduce the error?
From your code listing it seems line 42 is(maybe you edited it though):
39 LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
40 Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
41 double longitude = location.getLongitude();
42 double latitude = location.getLatitude();
Cant see why getLatitude() would break and not getLongitude()
You should validate location, to make sure you have it.
As a couple of others have pointed out, it is telling you that the error is on line 42. Unfortunately you have slightly affected the line numbers pasting it here. On your line 42 you are assuming something is not null, and it actually is null.
Given that LocationManager#getLastKnownLocation can return null, and you're not checking for that, I'd say that was your issue, and that your line 42 is where you call location.getLongitude().
getLastKnownLocation will only return a Location if the provider you specify has been used recently. If nothing has forced it to find a location yet, or for a long time (Android considers the last location too old to be correct), then you will get null.
Related
I have an async task that when data is loaded it also set an onClick for a star rating bar.
When I user clicks the star rating bar, I want to load a new fragment. I am trying this:
package com.example.mike.beerportfoliomaterial;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RatingBar;
import android.widget.TextView;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Mike on 6/22/15.
*/
public class getReviewToRateJSON extends AsyncTask<String, Void, String> {
Context c;
String noteWriter;
String noteID;
private ProgressDialog Dialog;
public getReviewToRateJSON(Context context)
{
c = context;
Dialog = new ProgressDialog(c);
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
return readJSONFeed(arg0[0]);
}
protected void onPreExecute() {
Dialog.setMessage("Getting A Taste Note");
Dialog.setTitle("Loading");
Dialog.show();
}
protected void onPostExecute(String result){
//decode json here
try{
JSONObject jsonObject = new JSONObject(result);
noteWriter = jsonObject.getString("reviewer");
String beer = jsonObject.getString("beer");
noteID = jsonObject.getString("noteID");
String noteToRead = jsonObject.getString("note");
TextView note = (TextView) ((Activity) c).findViewById(R.id.reviewToRate);
note.setText(noteToRead);
}
catch(Exception e){
}
//todo: url to send rating too
addListenerOnRatingBar(c);
Dialog.dismiss();
}
public String readJSONFeed(String URL) {
StringBuilder stringBuilder = new StringBuilder();
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(URL);
try {
HttpResponse response = httpClient.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
inputStream.close();
} else {
Log.d("JSON", "Failed to download file");
}
} catch (Exception e) {
Log.d("readJSONFeed", e.getLocalizedMessage());
}
return stringBuilder.toString();
}
private void addListenerOnRatingBar(final Context view) {
RatingBar ratingBar = (RatingBar) ((Activity) view).findViewById(R.id.reviewRatingBar);
ratingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
public void onRatingChanged(RatingBar ratingBar, float rating,
boolean fromUser) {
//next async task to update online database
float stars = ratingBar.getRating();
String s = Float.toString(stars);
//get user id
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
String userName = prefs.getString("userName", null);
final String userID = prefs.getString("userID", null);
String url = "myURL;
//async task to update rating in database
new AddNoteRate(c).execute(url);
Fragment Fragment_four;
FragmentManager man= ((Activity) view).getSupportFragmentManager();
FragmentTransaction tran = man.beginTransaction();
Fragment_four = new RateReviews();
tran.replace(R.id.main, Fragment_four);//tran.
tran.addToBackStack(null);
tran.commit();
}
});
}
}
My big issue is I ca not get it to load a new fragment on these lines:
Fragment Fragment_four;
FragmentManager man= ((Activity) view).getSupportFragmentManager();
FragmentTransaction tran = man.beginTransaction();
Fragment_four = new RateReviews();
tran.replace(R.id.main, Fragment_four);//tran.
tran.addToBackStack(null);
tran.commit();
I get a "cannot resolve method" error on this line:
FragmentManager man= ((Activity) view).getSupportFragmentManager();
I also tried to change getSupportFragmentManager to getFragmentManager, neith worked.
Activity does not have a getSupportFragmentManager function. The FragmentActivity class in the v4 support library does. Cast it as that instead, and make sure your actual Activity derives from that rather than from Activity.
Side note- this may fail anyway. A Context is not necessarily an Activity. In fact it will frequently get wrapped in a ContextWrapper or ContextThemeWrapper. In either case this code will fail.
You should make a constructor in asynctask, passing activity as parameter.
AsyncTask.class
public class AsyncTaskExample extends AsyncTask<String, Integer, String>
{
Activity atv;
public AsyncTaskExample (Activity atv)
{
this.atv = atv;
}
#Override
protected void onPostExecute(String result) // contain according to regCheck.php
{
FragmentManager fragmentManager;
fragmentManager = atv.getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.main, Fragment_four)
.commit();
}
}
Fragment passing in
AsyncTaskExample task = new AsyncTaskExample( getActivity() );
I am trying to get an image from my data base and insert it using imageView in android
my php code:
<?php
if(isset($_POST["IdToSearch"]) && $_POST["IdToSearch"] != "") {
$firstid = $_POST["IdToSearch"];
$con = mysqli_connect("localhost","root","","bdUniv");
if(mysqli_connect_errno()) {
echo'Database connection error: '. mysqli_connect_error();
exit();
}
$firstid = mysqli_real_escape_string($con,$firstid);
$userdetails = mysqli_query($con,"SELECT * FROM Etudiant WHERE id = '$firstid'");
if(!$userdetails) {
echo'Couldnotrunquery: '. mysqli_error($con);
exit();
}
$row = mysqli_fetch_row($userdetails);
$result_data = array(
'id' => $row[0],
'nom' => $row[1],
'prenom' => $row[2],
'age' => $row[3],
'photo' => $row[4],
);
echo json_encode($result_data);
}else{
echo"Could not complete query. Missingparameter";
}
?>
My java code:
package com.example.getdatafrombdd;
import java.io.File;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity_GET extends Activity {
Button buttonGetData = null;
EditText editTextSearchString = null;
TextView textViewId = null;
TextView textViewNom = null;
TextView textViewPrenom = null;
TextView textViewAge = null;
ImageView imgViewPhoto = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_activity_get);
buttonGetData = (Button) findViewById(R.id.buttonGetData);
editTextSearchString = (EditText) findViewById(R.id.editTextSearchString);
textViewId = (TextView) findViewById(R.id.txtId);
textViewNom = (TextView) findViewById(R.id.txtNom);
textViewPrenom = (TextView) findViewById(R.id.txtPrenom);
textViewAge = (TextView) findViewById(R.id.txtAge);
imgViewPhoto = (ImageView) findViewById(R.id.imgPhoto);
//Setup the Button's OnClickListener
buttonGetData.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Get the data
DoPOST mDoPOST = new DoPOST(MainActivity_GET.this, editTextSearchString.getText().toString());
mDoPOST.execute("");
buttonGetData.setEnabled(false);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_activity__get, menu);
return true;
}
public class DoPOST extends AsyncTask<String, Void, Boolean> {
// String: le type des paramètres fournis à la tâche.
// Void: le type de données transmises durant la progression du traitement.
// Boolean: le type du résultat de la tâche.
Context mContext = null;
String IdToSearch = "";
//Result data
int intId;
String strNom;
String strPrenom;
int intAge;
String strPictPath;
Exception exception = null;
DoPOST(Context context, String nameToSearch) {
mContext = context;
IdToSearch = nameToSearch;
}
#Override
protected Boolean doInBackground(String... arg0) {
try{
//Setup the parameters
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
// key value
nameValuePairs.add(new BasicNameValuePair("IdToSearch", IdToSearch));
//Add more parameters as necessary
//Create the HTTP request
HttpParams httpParameters = new BasicHttpParams();
//Setup timeouts
HttpConnectionParams.setConnectionTimeout(httpParameters, 15000);
HttpConnectionParams.setSoTimeout(httpParameters, 15000);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpPost httppost = new HttpPost("http://10.0.2.2/univ/getFromUniv.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
// Create a JSON object from the request response
JSONObject jsonObject = new JSONObject(result);
//Retrieve the data from the JSON object
intId = jsonObject.getInt("id");
strNom = jsonObject.getString("nom");
strPrenom = jsonObject.getString("prenom");
intAge = jsonObject.getInt("age");
strPictPath = jsonObject.getString("photo");
}catch (Exception e){
Log.e("ClientServerDemo", "Error:", e);
exception = e;
}
return true;
}
#Override
protected void onPostExecute(Boolean valid){
//Update the UI
textViewId.setText("Id: " + intId);
textViewNom.setText("Nom: " + strNom);
textViewPrenom.setText("Prenom: " + strPrenom);
textViewAge.setText("Age: " + intAge);
File imgFile = new File(strPictPath);
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
imgViewPhoto.setImageBitmap(myBitmap);
buttonGetData.setEnabled(true);
if(exception != null){
Toast.makeText(mContext, exception.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
}
When i compiled it i get the: id, name, 2nd name, age but no image found!
And the error is:
1-06 20:19:17.527: E/BitmapFactory(786): Unable to decode stream: java.io.FileNotFoundException: /home/user/images/myPict.jpg: open failed: ENOENT (No such file or directory)
Help please!
You are doing this very wrong. Your server is returning the path of the photo on the server, not in the app. When you go to open the file, your app gives you an error because the file is not found locally, which is where your app is looking. To fix this, you should either download the photo from the server in your AsyncTask or store the Internet path of your picture and use a library like Picasso to download the image at that path to the ImageView.
EDIT:
As #Zerkz noted in his comment, you could also pass the image contents itself in your JSON by encoding them in base64 and then decoding those contents to a Bitmap in your AsyncTask. This would be advantageous if you don't plan on publicly exposing the URL to any of your images or if they will eventually be stored in a database.
I have created a custom list view which keeps force closing and I am having trouble figuring out why. I think I may have not named one of the view correctly since I was modeling this view off another. But I cant find my mistake yet.
Here is my force close error:
08-30 22:04:44.073 4011-4011/com.beerportfolio.beerportfoliopro E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.beerportfoliopro.BreweryLocationInfoAdapter.getView(BreweryLocationInfoAdapter.java:50)
at android.widget.AbsListView.obtainView(AbsListView.java:2410)
at android.widget.ListView.makeAndAddView(ListView.java:1963)
at android.widget.ListView.fillDown(ListView.java:815)
at android.widget.ListView.fillFromTop(ListView.java:876)
at android.widget.ListView.layoutChildren(ListView.java:1813)
at android.widget.AbsListView.onLayout(AbsListView.java:2238)
at android.view.View.layout(View.java:13900)
at android.view.ViewGroup.layout(ViewGroup.java:4391)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)
at android.view.View.layout(View.java:13900)
at android.view.ViewGroup.layout(ViewGroup.java:4391)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:13900)
at android.view.ViewGroup.layout(ViewGroup.java:4391)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)
at android.view.View.layout(View.java:13900)
at android.view.ViewGroup.layout(ViewGroup.java:4391)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:13900)
at android.view.ViewGroup.layout(ViewGroup.java:4391)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2183)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1984)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1221)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4710)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:746)
at android.view.Choreographer.doCallbacks(Choreographer.java:572)
at android.view.Choreographer.doFrame(Choreographer.java:538)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:731)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5536)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1074)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:841)
at dalvik.system.NativeStart.main(Native Method)
My BreweryLocationInfoAdapter code:
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.RatingBar;
import android.widget.TextView;
import com.beerportfolio.beerportfoliopro.R;
public class BreweryLocationInfoAdapter extends ArrayAdapter<BreweryLocationData>{
Context context;
int layoutResourceId;
List<BreweryLocationData> data = null;
public BreweryLocationInfoAdapter(Context context, int layoutResourceId, List<BreweryLocationData> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
breweryHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new breweryHolder();
holder.txtBrewery = (TextView)row.findViewById(R.id.beerNameList);
holder.txtDistance = (TextView)row.findViewById(R.id.beerBreweryNameList);
row.setTag(holder);
}
else
{
holder = (breweryHolder)row.getTag();
}
BreweryLocationData beer = data.get(position);
holder.txtBrewery.setText(beer.brewery);
holder.txtBrewery.setText(beer.distance);
return row;
}
static class breweryHolder
{
TextView txtBrewery;
TextView txtDistance;
}
}
GetNearbyBreweries code:
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import com.beerportfolio.beerportfoliopro.R;
public class GetNearbyBreweries extends AsyncTask
<String, Void, String> {
Context c;
private ProgressDialog Dialog;
public GetNearbyBreweries (Context context)
{
c = context;
Dialog = new ProgressDialog(c);
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
return readJSONFeed(arg0[0]);
}
protected void onPreExecute() {
Dialog.setMessage("Locating Breweries");
Dialog.setTitle("Loading");
Dialog.setCancelable(false);
Dialog.show();
}
protected void onPostExecute(String result){
//decode json here
try{
JSONObject json = new JSONObject(result);
//acces listview
ListView lv = (ListView) ((Activity) c).findViewById(R.id.topTasteBeers);
//make array list for beer
final List<BreweryLocationData> tasteList = new ArrayList<BreweryLocationData>();
for(int i = 0; i < json.getJSONArray("data").length(); i++) {
String brewery = json.getJSONArray("data").getJSONObject(i).getJSONObject("brewery").getString("name");
String id = json.getJSONArray("data").getJSONObject(i).getJSONObject("brewery").getString("id");
String latitude = json.getJSONArray("data").getJSONObject(i).getString("latitude");
String longitude = json.getJSONArray("data").getJSONObject(i).getString("longitude");
String distance = json.getJSONArray("data").getJSONObject(i).getString("distance");
Toast.makeText(c, "Brewery: " + brewery, Toast.LENGTH_SHORT).show();
int count = i + 1;
//create object
BreweryLocationData tempLocation = new BreweryLocationData(brewery, id, longitude , latitude,distance);
//add to arraylist
tasteList.add(tempLocation);
//add items to listview
BreweryLocationInfoAdapter adapter1 = new BreweryLocationInfoAdapter(c ,R.layout.toptaste_layout, tasteList);
lv.setAdapter(adapter1);
//set up clicks
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
ShortBeerInfo o=(ShortBeerInfo)arg0.getItemAtPosition(arg2);
String tempID = o.id;
String tempBrewID = o.brewery;
Toast toast = Toast.makeText(c, tempID, Toast.LENGTH_SHORT);
toast.show();
//get beer details from id
Intent myIntent = new Intent(c, BeerPage2.class);
myIntent.putExtra("id", tempID);
myIntent.putExtra("breweryID", tempBrewID);
c.startActivity(myIntent);
}
});
}
}
catch(Exception e){
}
Dialog.dismiss();
}
public String readJSONFeed(String URL) {
StringBuilder stringBuilder = new StringBuilder();
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(URL);
try {
HttpResponse response = httpClient.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
inputStream.close();
} else {
Log.d("JSON", "Failed to download file");
}
} catch (Exception e) {
Log.d("readJSONFeed", e.getLocalizedMessage());
}
return stringBuilder.toString();
}
}
I think for some reason row isn't getting created.
Can you double check by debugging that row != null by the time you arrive set row.setTag(holder).
I can only guess that 1. maybe the context you are using to get your inflater isn't correct, either way I prefer to use the following method
LayoutInflater.from(context).inflate(R.layout.cell, viewGroup, false);
Or, your resourceID is not right..
You have not written getCount method in your custom adapter:
public int getCount() {
return //Something here
}
Row 50 seems to be
holder.txtBrewery.setText(beer.brewery);
So either the TextView which should have id R.id.beerNameList has another id or beer.brewery is null.
You can solve these type of issues quickly if you use the debugger. Just put a breakpoint at the offending line, run the debugger and it will pause at the given line. You can then see exactly which object is null, allowing you to fix the problem in no time.
Don't hold the data in your custom adapter. Always use
BreweryLocationData beer = getItem(position);
to obtain the object that should be represented by the adapter. This way you can avoid issues with the data being modified outside of your adapter.
So I am trying to create an Android app which basically reads out the twitter feed according to the search query inside a UI. The feed that I need to display form the parsed JSON is the user name, handle, profile picture and the tweet.
Now I have created the whole thing and my code compiles but as soon as I run it the app opens and I write something in the search feed and hit enter - " Unfortunately, AppName has stopped working " I am attaching my logcat and my source code for reference.
*Solved the issue by removing set text from DoInBackground and then giving adequate permission for Android to access internet. The issue now is that as I try and display the profile picture, the URL gets displayed, not the image.
Source code :
package com.example.twittersearchactivity;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class TwitterSearchActivity extends Activity {
private TextView tweetDisplay;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_twitter_search);
tweetDisplay = (TextView)findViewById(R.id.tweet_txt);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.twitter_search, menu);
return true;
}
public void searchTwitter(View view){
EditText searchTxt = (EditText)findViewById(R.id.search_edit);
String searchTerm = searchTxt.getText().toString();
if(searchTerm.length()>0){
try{
String encodedSearch = URLEncoder.encode(searchTerm, "UTF-8");
String searchURL = "http://search.twitter.com/search.json?q="+encodedSearch;
new GetTweets().execute(searchURL);
Log.i("1", "entered the searchterm");
}
catch(Exception e){
tweetDisplay.setText("Whoops - something went wrong!");
e.printStackTrace();
}
}
else
tweetDisplay.setText("Enter a search query!");
}
private class GetTweets extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... twitterURL) {
StringBuilder tweetFeedBuilder = new StringBuilder();
for (String searchURL : twitterURL) {
HttpClient tweetClient = new DefaultHttpClient();
try {
HttpGet tweetGet = new HttpGet(searchURL);
HttpResponse tweetResponse = tweetClient.execute(tweetGet);
StatusLine searchStatus = tweetResponse.getStatusLine();
if (searchStatus.getStatusCode() == 200) {
HttpEntity tweetEntity = tweetResponse.getEntity();
Log.i("2", "entered gettweets");
InputStream tweetContent = tweetEntity.getContent();
InputStreamReader tweetInput = new InputStreamReader(tweetContent);
BufferedReader tweetReader = new BufferedReader(tweetInput);
String lineIn;
while ((lineIn = tweetReader.readLine()) != null) {
tweetFeedBuilder.append(lineIn);
Log.i("3", "entered while in dobackground");
}
}
else {Log.i("error", "error");}
//tweetDisplay.setText("Whoops - something went wrong!");
}
catch(Exception e) {
Log.e("DEBUGTAG", "Remote Image Exception", e);
//tweetDisplay.setText("Whoops - something went wrong!");
e.printStackTrace();
}}
return tweetFeedBuilder.toString();
}
protected void onPostExecute(String result) {
StringBuilder y;
StringBuilder tweetResultBuilder = new StringBuilder();
try {
Log.i("tag", "entered try block");
JSONObject resultObject = new JSONObject(result);
JSONArray tweetArray = resultObject.getJSONArray("results");
for (int t=0; t<tweetArray.length(); t++) {
Log.i("tag", "entered the json stream");
JSONObject tweetObject = tweetArray.getJSONObject(t);
tweetResultBuilder.append(tweetObject.getString("from_user")+": ");
tweetResultBuilder.append(tweetObject.getString("from_user_name")+": ");
tweetResultBuilder.append(tweetObject.get("text")+"\n\n");
String imageURL = (String) tweetObject.get(("profile_image_url")+": ");
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageURL).getContent());
#SuppressWarnings("deprecation")
Drawable d =new BitmapDrawable(bitmap);
d.setAlpha(255);
TextView.setCompoundDrawablesWithIntrinsicBounds(0,0,1,0);
}
}
catch (Exception e) {
tweetDisplay.setText("Whoops - something went wrong!");
e.printStackTrace();}
if(tweetResultBuilder.length()>0)
tweetDisplay.setText(tweetResultBuilder.toString());
else
tweetDisplay.setText("Sorry - no tweets found for your search!");
}
}}
You can't call view functions like setText on another thread like an AsyncTask doInBackground function. You need to do it in onPostExecute.
I want to get the latitude and longitude positions from the Geo Coding API. I wrote the following code for that.
package com.appulento.mapsexample.pack;
import android.graphics.Point;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
import com.mapsinfo.pack.DBAdapter;
public class MapsMianClass extends MapActivity {
private MapController mapController;
private LocationManager locationManager;
private MapView mapView;
List<Overlay> listOfOverlays ;
private List mapOverlays;
private Projection projection;
private Geocoder geoCoder;
private MapController mc;
private GeoPoint gP;
private DBAdapter db;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//here i am giving the Maps Geo coding API URL
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true_or_false"));
startActivity(intent);
//starting the Intent
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
//default method of maps Activity.
}
}
Is it correct? How can I incorporate JSON in the above code for getting latitude and longitude values from the URL?
Try this Code
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
public class MyActivity extends Activity {
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AsyncTask<String, Void, Void> stringVoidVoidAsyncTask = new AsyncTask<String, Void, Void>() {
BufferedReader in;
#Override
protected Void doInBackground(String... strings) {
String url = "";
if (strings.length > 0) {
url = strings[0];
} else {
return null;
}
try {
HttpClient httpClient = new DefaultHttpClient();// Client
HttpGet getRequest = new HttpGet();
getRequest.setURI(new URI(url));
HttpResponse response = httpClient.execute(getRequest);
in = new BufferedReader
(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String page = sb.toString();
JSONObject jsonObject = new JSONObject(page);
JSONArray jsonArray = (JSONArray) jsonObject.get("results");
if (jsonArray.length() > 0) {
jsonObject = (JSONObject) jsonArray.get(0);
jsonObject = (JSONObject) jsonObject.get("geometry");
JSONObject location = (JSONObject) jsonObject.get("location");
Double lat = (Double) location.get("lat");
Double lng = (Double) location.get("lng");
System.out.println("lat - " + lat + " , lon - " + lng);
}
System.out.println(page);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
};
stringVoidVoidAsyncTask.execute("http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true");
}
}
And do add permission in AndroidManifest for Internet
<uses-permission android:name="android.permission.INTERNET"/>
And for next time do homework before asking question do googleing first. Hope this help you.
What are you want to start in StartActivity() method in Activity's onCreate()?
You should go for http request using HttpClient
and parse the response from it