I am calling an Activity called MapsActivity from a Fragment.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_one, container, false);
ibTrackEmp = (ImageView)rootView.findViewById(R.id.ibTrackEmp);
ibTrackEmp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), MapsActivity.class);
startActivity(intent);
}
});
return rootView;
}
Now, in the MapsActivity.java, i call a Web Service as a BackGround Task
private class GetALLGPSTask extends AsyncTask<String, Void, String> {
private TextView textView;
public GetALLGPSTask() {
}
#Override
protected String doInBackground(String... strings) {
String result = "Unable to fetch from SAP";
try {
URL url = new URL(strings[0]);
final String basicAuth = "Basic " + Base64.encodeToString("xxxx:xxxx#1223".getBytes(), Base64.NO_WRAP);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(90000);
urlConnection.setConnectTimeout(55000);
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty ("Authorization", basicAuth);
InputStream stream = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream));
StringBuilder builder = new StringBuilder();
String inputString;
while ((inputString = bufferedReader.readLine()) != null) {
builder.append(inputString);
}
int responsecode = urlConnection.getResponseCode();
Log.d("ResponseCode", String.valueOf(responsecode));
if(responsecode == 200){
result = "GPS Coordinates Updated Successfully";
try {
JSONArray jsonArray = new JSONArray(builder.toString());
List<Pair<String, String>> allNames = new ArrayList<>();
final int numberOfItemsInResp = jsonArray.length();
for (int i = 0; i < numberOfItemsInResp; i++) {
JSONObject jobj = jsonArray.getJSONObject(i);
String name = jobj.getString("NAME");
String addlatitude = jobj.getString("LATITUDE");
String addlongitude = jobj.getString("LONGITUDE");
LatLng newemp = new LatLng(Double.valueOf(addlatitude), Double.valueOf(addlongitude));
mMap.addMarker(new MarkerOptions().position(newemp).title("UserName: "+name));
}
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
}
urlConnection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(String temp) {
Toast.makeText(MapsActivity.this,
temp, Toast.LENGTH_SHORT).show();
}
Here, the Web Service is getting called, but the app initializes to the first screen.
I get the following error log
--------- beginning of crash
09-27 15:52:31.912 31508-31767/com.example.sd0003.appslider E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.example.sd0003.appslider, PID: 31508
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IllegalStateException: Not on the main thread
at maps.w.d.a(Unknown Source)
at maps.y.F.a(Unknown Source)
at maps.ad.t.a(Unknown Source)
at ua.onTransact(:com.google.android.gms.DynamiteModulesB:167)
at android.os.Binder.transact(Binder.java:392)
at com.google.android.gms.maps.internal.IGoogleMapDelegate$zza$zza.addMarker(Unknown Source)
at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source)
at com.example.sd0003.appslider.MapsActivity$GetALLGPSTask.doInBackground(MapsActivity.java:152)
at com.example.sd0003.appslider.MapsActivity$GetALLGPSTask.doInBackground(MapsActivity.java:105)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
09-27 15:52:31.912 31508-31767/com.example.sd0003.appslider E/AbstractTracker: Can't create handler inside thread that has not called Looper.prepare()
09-27 15:52:31.913 31508-31767/com.example.sd0003.appslider D/AppTracker: App Event: crash
09-27 15:52:31.916 31508-31767/com.example.sd0003.appslider E/AbstractTracker: mTrackerAsyncQueryHandler is null
09-27 15:52:31.942 31508-31767/com.example.sd0003.appslider I/Process: Sending signal. PID: 31508 SIG: 9
You should not be performing UI updates from a background thread. In this particular case, you should not be adding markers to your mMap reference.
Instead, you should return a list of location names and latitude/longitude pairs and handle updating the UI from the main thread in onPostExecute. Think about returning a dataset that resembles something like List<Pair<String, LatLng>> locations.
Your implementation would then look like this:
private class GetALLGPSTask extends AsyncTask<String, Void, List<Pair<String, LatLng>>> {
private TextView textView;
public GetALLGPSTask() {
}
#Override
protected List<Pair<String, LatLng>> doInBackground(String... strings) {
List<Pair<String, LatLng>> allLocations = new ArrayList<>();
try {
URL url = new URL(strings[0]);
final String basicAuth = "Basic " + Base64.encodeToString("xxxx:xxxx#1223".getBytes(), Base64.NO_WRAP);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(90000);
urlConnection.setConnectTimeout(55000);
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty ("Authorization", basicAuth);
InputStream stream = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream));
StringBuilder builder = new StringBuilder();
String inputString;
while ((inputString = bufferedReader.readLine()) != null) {
builder.append(inputString);
}
int responsecode = urlConnection.getResponseCode();
Log.d("ResponseCode", String.valueOf(responsecode));
if(responsecode == 200){
try {
JSONArray jsonArray = new JSONArray(builder.toString());
final int numberOfItemsInResp = jsonArray.length();
for (int i = 0; i < numberOfItemsInResp; i++) {
JSONObject jobj = jsonArray.getJSONObject(i);
String name = jobj.getString("NAME");
String latitude = jobj.getString("LATITUDE");
String longitude = jobj.getString("LONGITUDE");
LatLng latLng = new LatLng(Double.valueOf(addlatitude), Double.valueOf(addlongitude));
allLocations.add(new Pair<>(name, latLng))
}
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
}
urlConnection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return allLocations;
}
#Override
protected void onPostExecute(List<Pair<String, LatLng>> locations) {
for (Pair<String, LatLng> location : locations) {
mMap.addMarker(new MarkerOptions().position(location.second).title("UserName: " + location.first));
}
}
}
Side note: Your allNames list was never used.
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
when i tried to put direction from source to destination on map
this null pointer exception heppen
when i tried to put direction from source to destination on map
this null pointer exception heppen
l
ocat:
07-05 02:19:21.569 23133-23133/com.example.saad.testapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.saad.testapp, PID: 23133
java.lang.NullPointerException
at com.example.saad.testapp.map$TaskParser.onPostExecute(map.java:248)
at com.example.saad.testapp.map$TaskParser.onPostExecute(map.java:205)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5511)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
map.class is as follows :
public class map extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
loc ambLoc;
loc patLoc;
String tempE;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
ambLoc=new loc();
patLoc=new loc();
tempE=new String();
}
#Override
public void onMapReady(GoogleMap googleMap) {
getPoints();
}
void getPoints()
{
//some code here
String url=getRequestUrl(ambLoc,patLoc);
TaskRequestDirections taskRequestDirections = new TaskRequestDirections();
taskRequestDirections.execute(url);
}
private String getRequestUrl(loc origin, loc dest) {
//Value of origin
String str_org = "origin=" + origin.getLatitude() +","+origin.getLongitude();
//Value of destination
String str_dest = "destination=" + dest.getLatitude()+","+dest.getLongitude();
//Set value enable the sensor
String sensor = "sensor=false";
//Mode for find direction
String mode = "mode=driving";
//Build the full param
String param = str_org +"&" + str_dest + "&" +sensor+"&" +mode;
//Output format
String output = "json";
//Create url to request
String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + param;
return url;
}
private String requestDirection(String reqUrl) throws IOException {
String responseString = "";
InputStream inputStream = null;
HttpURLConnection httpURLConnection = null;
try{
URL url = new URL(reqUrl);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
//Get the response result
inputStream = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuffer stringBuffer = new StringBuffer();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line);
}
responseString = stringBuffer.toString();
bufferedReader.close();
inputStreamReader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
inputStream.close();
}
httpURLConnection.disconnect();
}
return responseString;
}
public class TaskRequestDirections extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... strings) {
String responseString = "";
try {
responseString = requestDirection(strings[0]);
} catch (IOException e) {
e.printStackTrace();
}
return responseString;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//Parse json here
TaskParser taskParser = new TaskParser();
taskParser.execute(s);
}
}
having exception on the below line
public class TaskParser extends AsyncTask<String, Void, List<List<HashMap<String, String>>> > {
#Override
protected List<List<HashMap<String, String>>> doInBackground(String... strings) {
JSONObject jsonObject = null;
List<List<HashMap<String, String>>> routes = null;
try {
jsonObject = new JSONObject(strings[0]);
DirectionParser directionsParser = new DirectionParser();
routes = directionsParser.parse(jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
return routes;
}
#Override
protected void onPostExecute(List<List<HashMap<String, String>>> lists) {
//Get list route and display it into the map
ArrayList points = null;
PolylineOptions polylineOptions = null;
for (List<HashMap<String, String>> path : lists) {
points = new ArrayList();
polylineOptions = new PolylineOptions();
for (HashMap<String, String> point : path) {
double lat = Double.parseDouble(point.get("lat"));
double lon = Double.parseDouble(point.get("lon"));
points.add(new LatLng(lat,lon));
}
polylineOptions.addAll(points);
polylineOptions.width(15);
polylineOptions.color(Color.BLUE);
polylineOptions.geodesic(true);
}
if (polylineOptions!=null) {
Toast.makeText(getApplicationContext(), "adding polyline!", Toast.LENGTH_SHORT).show();
having exception on the
mMap.addPolyline(polylineOptions);
} else {
Toast.makeText(getApplicationContext(), "Direction not found!", Toast.LENGTH_SHORT).show();
}
}
}
}
suggest any solution if you have
thank you
thank you
thank you
thank you
You never set mMap variable try like this
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
getPoints();
}
I have created a fragment which if it is activated it will show MySQL data but it takes time to fetch the data and show it on a custom ListView.
I tried to implement AsyncTask so that while fetching the data you can do something else on the fragment while waiting but am having this error.
"FATAL EXCEPTION: main java.lang.NullPointerException"
Here is the code
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_markets,container,false);
//lvMarkets.setAdapter(new CustomAdapter(getActivity().getApplicationContext(),Symbols,Prices,Balances));
DBHelper db = new DBHelper(getActivity().getApplicationContext());
final ListView lvMarkets = (ListView)getActivity().findViewById(R.id.lvMarkets);
final String c_androidid = Settings.Secure.getString(getActivity().getContentResolver(), Settings.Secure.ANDROID_ID);
final Cursor rs = db.getID(c_androidid);
rs.moveToFirst();
final String c_login = rs.getString(rs.getColumnIndex(DBHelper.c_login));
AsyncTaskRunner taskRunner = new AsyncTaskRunner();
taskRunner.execute(c_login);
lvMarkets.setAdapter(jAdapter);
return rootView;
}
private class AsyncTaskRunner extends AsyncTask<String,String,String>
{
#Override
protected String doInBackground(String... params)
{
final String fin_login=params[0];
StringRequest stringRequest = new StringRequest(Request.Method.POST,url, new Response.Listener<String>() {
#Override
public void onResponse(String response)
{
Log.d(debug,response);
try
{
jsonArray =new JSONArray(response);
jAdapter= new JsonAdapter(getActivity(),jsonArray,login);
}
catch (JSONException e)
{
Log.d(debug,e.toString());
}
}
}, new Response.ErrorListener()
{
public void onErrorResponse(VolleyError error)
{
Log.d(debug,error.toString());
}
}){
#Override
protected Map<String,String>getParams()
{
Map<String,String> params=new HashMap<String,String>();
params.put("c_login",fin_login);
return params;
}
};
RequestQueue queue = Volley.newRequestQueue(getActivity().getApplicationContext());
queue.add(stringRequest);
return fin_login;
}
}
Hope someone could point out what went wrong with my code and someone could also point out on how to fetch data on online much more faster.
Thanks...
Try this:
private void parsingValues() {
URL obj = null;
HttpURLConnection con = null;
String USER_AGENT = "Mozilla/5.0";
try {
//parameter to post
String POST_PARAMS = "deviceos=" + deveiceOs + "&devicetype=" + deviceType +"&deviceid=" ;
obj = new URL("Your URI");
con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
// For POST only - START
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
os.write(POST_PARAMS.getBytes());
os.flush();
os.close();
int responseCode = con.getResponseCode();
System.out.println("POST Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { //success
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//getResponse
String subsResponse = response.toString();
final JSONObject responsesubs = new JSONObject(subsResponse);
//Here your parsing process
}
}
});
} else {
System.out.println("POST request not worked");
}
} catch (Exception e) {
e.printStackTrace();
}
}
// Call this method to your doinbackground of Asynhronous Task(parsingValues())
I am trying to get a list of data from MySQL that is hosted then return the result in a listview. But I am not able to make it when using fragments.
I am getting the following error:
com.example.test.myapp E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.exampletest.myapp, PID: 31491
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at com.example.test.myapp.homeOperation.doInBackground(homeOperation.java:71)
at com.example.test.myapp.homeOperation.doInBackground(homeOperation.java:23)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
With the class shown below: I connect to the server, then I fetch the result, so I can parse the data and put in in ArrayLists.
public class homeOperation extends AsyncTask<String, Void, String> {
List<String> title_list = new ArrayList<String>();
List<String> id_list = new ArrayList<String>();
Context context;
AlertDialog alertDialog;
homeOperation(Context ctx) {
context = ctx;
}
#Override
protected String doInBackground(String... params) {
String type = params[0];
String login_url = "http://xxxx/data.php";
if (type.equals("home")) {
try {
String events = params[1];
String task_owner = params[2];
URL url = new URL(login_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String post_data = URLEncoder.encode("events", "UTF-8") + "=" + URLEncoder.encode(events, "UTF-8") + "&"
+ URLEncoder.encode("task_owner", "UTF-8") + "=" + URLEncoder.encode(task_owner, "UTF-8");
bufferedWriter.write(post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
String[] arr = result.split("--");
for (int i = 0; i < arr.length; i++) {
String cur = arr[i];
title_list.add(cur.split(":")[0]);
id_list.add(cur.split(":")[1]);
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(String result) {
Toast toast = Toast.makeText(this.context, result, Toast.LENGTH_LONG);
toast.show();
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
Now, this is the class in which I'm trying to get the data from the homeOperation class and then put the data into a ListView.
public class ContentFragment extends Fragment {
ListView lv;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_fragment, container, false);
lv = (ListView) view.findViewById(R.id.resultList);
String type = "home";
homeOperation homeOperation = new homeOperation(ContentFragment.this.getActivity());
homeOperation.execute(type, "", "");
// This is the array adapter, it takes the context of the activity as a
// first parameter, the type of list view as a second parameter and your
// array as a third parameter.
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(ContentFragment.this.getActivity(), android.R.layout.simple_list_item_1, homeOperation.title_list);
lv.setAdapter(arrayAdapter);
//addButton onClick
ImageButton addButton = (ImageButton) view.findViewById(R.id.addButton);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
addPaige(view);
}
});
return view;
}
public void addPaige(View v) {
Intent goToAddPaige = new Intent(getActivity(), AddPaige.class);
startActivity(goToAddPaige);
}
}
I think there is a problem when sending the context using fragments.
title_list will have no data because your AsyncTask.execute() will be done after lv.setAdapter(arrayAdapter);.
So if you want to handling title_list with enough data, use android.os.Handler in onPostExecute() to send your result of AsyncTask.
Try as below:
Your AsyncTask
public class homeOperation extends AsyncTask<String,Void,String> {
List<String> title_list = new ArrayList<String>();
List<String> id_list = new ArrayList<String>();
Context context;
Handler handler;
AlertDialog alertDialog;
homeOperation(Context ctx, Handler hnd) {
context = ctx;
handler = hnd;
}
#Override
protected String doInBackground(String... params) {
String type = params[0];
String login_url = "http://xxxx/data.php";
if (type.equals("home")) {
try {
String events = params[1];
String task_owner = params[2];
URL url = new URL(login_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String post_data = URLEncoder.encode("events", "UTF-8") + "=" + URLEncoder.encode(events, "UTF-8") + "&"
+ URLEncoder.encode("task_owner", "UTF-8") + "=" + URLEncoder.encode(task_owner, "UTF-8");
bufferedWriter.write(post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
String[] arr = result.split("--");
for (int i = 0; i < arr.length; i++) {
String cur = arr[i];
title_list.add(cur.split(":")[0]);
id_list.add(cur.split(":")[1]);
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(String result) {
Toast toast = Toast.makeText(this.context, result, Toast.LENGTH_LONG);
toast.show();
handler.sendEmptyMessage(0);
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
Your Fragment
public class ContentFragment extends Fragment {
ListView lv;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_fragment,container,false);
lv = (ListView) view.findViewById(R.id.resultList);
ViewHandler viewHnd = new ViewHandler(ContentFragment.this); // add this handler for parameter of yout AsyncTask.
String type = "home";
homeOperation homeOperation = new homeOperation(ContentFragment.this.getActivity(), viewHnd);
homeOperation.execute(type, "", "");
// This is the array adapter, it takes the context of the activity as a
// first parameter, the type of list view as a second parameter and your
// array as a third parameter.
// ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(ContentFragment.this.getActivity() , android.R.layout.simple_list_item_1, homeOperation.title_list);
//
// lv.setAdapter(arrayAdapter);
//addButton onClick
ImageButton addButton = (ImageButton) view.findViewById(R.id.addButton);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
addPaige(view);
}
});
return view;
}
public void addPaige(View v){
Intent goToAddPaige = new Intent(getActivity(), AddPaige.class);
startActivity(goToAddPaige);
}
private static class ViewHandler extends Handler {
private final WeakReference<ContentFragment> mFragment;
ViewHandler(ContentFragment fragment) {
mFragment = new WeakReference<ContentFragment>(fragment);
}
#Override
public void handleMessage(Message msg) {
ContentFragment fragment = mFragment.get();
if (fragment != null) {
fragment.handleMessage(msg);
}
}
}
private void handleMessage(Message msg) {
if (msg.what == 0) {
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(ContentFragment.this.getActivity() , android.R.layout.simple_list_item_1, homeOperation.title_list);
lv.setAdapter(arrayAdapter);
}
}
}
Replace:
for (int i = 0; i < arr.length; i++) {
String cur = arr[i];
title_list.add(cur.split(":")[0]);
id_list.add(cur.split(":")[1]);
}
with:
for (int i = 0; i < arr.length; i++) {
String cur = arr[i];
String[] temp = cur.split(":");
if (temp.length == 2){
title_list.add(cur.split(":")[0]);
id_list.add(cur.split(":")[1]);
}
}
The stack trace is very clear by itself:
java.lang.Thread.run(Thread.java:818) Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1 at
which should translate to this line:
id_list.add(cur.split(":")[1]);
You shouldn't expect that the split method will always give you a certain number of substrings. So you have to write a fallback for when it doesn't.
I've build an AsyncTask and want to start another Activity when it ends (onPostExecute) but it won't work and I can't find the problem. Maybe there is a problem with String, String, String ?
Here is my code:
public class StartSearch extends AsyncTask<String, String, String> {
private Activity activity;
#Override
protected String doInBackground(String... strings) {
StringBuilder sb = new StringBuilder();
String http = "https://list-creater-service.herokuapp.com/api/v1/search";
HttpURLConnection urlConnection = null;
JSONObject json = null;
HttpResponse response = null;
try {
//connect to server
URL url = new URL(http);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setUseCaches(false);
urlConnection.setConnectTimeout(10000);
urlConnection.setReadTimeout(10000);
urlConnection.setRequestProperty("Content-Type","application/json");
urlConnection.setRequestProperty("Host", "list-creater-service.herokuapp.com");
urlConnection.connect();
//Create JSONObject here
JSONObject jsonParam = new JSONObject();
jsonParam.put("gamemode", gametype);
jsonParam.put("country", selCountry);
jsonParam.put("min_size", minSize);
jsonParam.put("max_size", maxSize);
OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
out.write(jsonParam.toString());
out.close();
int HttpResult = urlConnection.getResponseCode();
if(HttpResult == HttpURLConnection.HTTP_OK){
BufferedReader br = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream(),"utf-8"));
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
String jsonS = sb.toString();
JSONArray jsonArray = new JSONArray(jsonS);
int length = jsonArray.length();
String[] names = new String[length];
for (int i = 0; i < length; i++) {
JSONObject jsonObject = new JSONObject(jsonArray.get(i).toString());
ArrayList serverList = new ArrayList();
serverList.add(jsonObject.getString("name"));
serverData = getSharedPreferences(filename, 0);
SharedPreferences.Editor editor = serverData.edit();
Set<String> set = new HashSet<String>();
set.addAll(serverList);
editor.putStringSet("name", set);
editor.commit();
System.out.println(jsonObject.getString("name"));
names[i] = jsonObject.getString("name");
}
//String name = jsonObject.getString("name");
System.out.println("" + sb.toString());
}else{
System.out.println(urlConnection.getResponseMessage());
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(urlConnection!=null)
urlConnection.disconnect();
}
return null;
}
#Override
protected void onPostExecute(String result) {
activity.startActivity(new Intent(activity, ServerIndex.class));
}
}
Need some help!
Thx :)
You have Activity activity declared , but you have not assigned your current activity context to it . Assign the current activity context to it.
Like
activity=currentContext;
You should use runOnUIThread in your onPostExecute
runOnUiThread(new Runnable() {
public void run() {
activity.startActivity(new Intent(activity, ServerIndex.class));
}});
And as Raghunandan said, activity is not initialized. You can access the startActivity method from your StartSearch class by using
SomeActivity.this.startActivity (SomeActivity has to be initialized)
And since onPostExecute runs on the UI thread, you may or may not call runOnUIThread.
I'm developing an Android app which, basing on the GPS location, queries a database to retrieve the nearest places within a certain distance (setting a marker on them).
I followed this tutorial http://www.androidhive.info/2012/05/how-to-connect-android-with-php-mysql/, so I'm trying to do a HttpRequest to retrieve a JSON from the PHP script.
I'm getting a NullPointerException when calling the getJSONArray method.
Here's the logcat
05-27 22:22:56.964: E/AndroidRuntime(26452): FATAL EXCEPTION: main
05-27 22:22:56.964: E/AndroidRuntime(26452): java.lang.NullPointerException
05-27 22:22:56.964: E/AndroidRuntime(26452): at com.example.mypackage.fragments.MyFragment$GetBuildings$1.run(MyFragment.java:130)
05-27 22:22:56.964: E/AndroidRuntime(26452): at android.os.Handler.handleCallback(Handler.java:615)
05-27 22:22:56.964: E/AndroidRuntime(26452): at android.os.Handler.dispatchMessage(Handler.java:92)
05-27 22:22:56.964: E/AndroidRuntime(26452): at android.os.Looper.loop(Looper.java:137)
05-27 22:22:56.964: E/AndroidRuntime(26452): at android.app.ActivityThread.main(ActivityThread.java:4867)
05-27 22:22:56.964: E/AndroidRuntime(26452): at java.lang.reflect.Method.invokeNative(Native Method)
05-27 22:22:56.964: E/AndroidRuntime(26452): at java.lang.reflect.Method.invoke(Method.java:511)
05-27 22:22:56.964: E/AndroidRuntime(26452): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
05-27 22:22:56.964: E/AndroidRuntime(26452): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
05-27 22:22:56.964: E/AndroidRuntime(26452): at dalvik.system.NativeStart.main(Native Method)
Here's the fragment (note that if I put out the AsyncTask the map displays correctly):
public class MyFragment extends Fragment {
MapView mapView;
GoogleMap map;
private ProgressDialog pDialog;
private static String url = "http://mySite/query.php";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment, container, false);
mapView = (MapView) v.findViewById(R.id.map);
mapView.onCreate(savedInstanceState);
map = mapView.getMap();
map.getUiSettings().setMyLocationButtonEnabled(true);
map.setMyLocationEnabled(true);
MapsInitializer.initialize(this.getActivity());
LocationManager locationManager = (LocationManager) this.getActivity().getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, true));
if (location != null)
{
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(location.getLatitude(), location.getLongitude()))
.zoom(14)
.bearing(0)
.tilt(0)
.build();
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
new GetBuildings().execute();
return v;
}
#Override
public void onResume() {
mapView.onResume();
super.onResume();
}
#Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
class GetBuildings extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Loading...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
protected String doInBackground(String... params) {
getActivity().runOnUiThread(new Runnable()
{
LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, true));
public void run() {
JSONParser jparser = new JSONParser();
double lat = location.getLatitude();
double lon = location.getLongitude();
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("lat", Double.toString(lat)));
params.add(new BasicNameValuePair("lon", Double.toString(lon)));
JSONObject json = jparser.makeHttpRequest(
url, "POST", params);
try {
JSONArray jarray = json.getJSONArray("Buildings details");// NULLPOINTEREXCEPTION HERE
for(int i = 0; i < jarray.length(); i++)
{
JSONObject object = jarray.getJSONObject(i);
LatLng latlng = new LatLng(Double.parseDouble(object.getString("lat")),
Double.parseDouble(object.getString("lon")));
MarkerOptions mo = new MarkerOptions().position(latlng)
.title(object.getString("name"));
map.addMarker(mo);
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
});
return null;
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
}
JSONParser.java
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
public JSONParser() {
}
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {
try {
if(method == "POST"){
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}else if(method == "GET"){
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
e.printStackTrace();
}
return jObj;
}
}
query.php
<?php
$response = array();
$pi = 3.1415926535898;
$earth_radius = 6372.795477598;
$range= 40.0; //km
$mysqli = new mysqli("host", "user", "psw", "db");
$query = "SELECT id, name, city, lat, lon,
($earth_radius*ACOS(
(SIN($pi * $lat / 180)*SIN($pi * lat / 180)) +
(COS($pi * $lat / 180)*COS($pi * lat / 180) * COS(ABS(($pi * $lon / 180) - ($pi * lon / 180))) )
)
) as distance from BuildingsDetails HAVING distance<$range ORDER BY distance";
if ( (isset($_POST['lat'])) && (isset($_POST['lon'])) ) {
$lat = $_POST["lat"];
$lon = $_POST["lon"];
$result = $mysqli->query($query);
if ($result->num_rows > 0) {
$response["Buildings Details"] = array();
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
$buildingsdetails = array();
$buildingsdetails["id"] = $row["id"];
$buildingsdetails["name"] = $row["name"];
$buildingsdetails["city"] = $row["city"];
$buildingsdetails["lat"] = $row["lat"];
$buildingsdetails["lon"] = $row["lon"];
$buildingsdetails["distance"] = $row["distance"];
array_push($response["Buildings Details"], $buildingsdetails);
}
echo json_encode($response);
} else {
$response["message"] = "No buildings found";
echo json_encode($response);
}
} else {
$response["message"] = "Missing parameter(s)";
echo json_encode($response);
}
?>
Note that if I set lat and lon values manually in the script and i type the URL in the browser I correctly get the JSON, like this:
{"Buildings Details":[{"id":"3","name":"building1","city":"city1","lat":"52.5014076","lon":"13.4023285","distance":"26.2818230530031"},{"id":"5","name":"building2","city":"city2","lat":"52.379173","lon":"12.819091","distance":"26.4070424101156"},{"id":"26","name":"building3","city":"city3","lat":"52.656543","lon":"13.976542","distance":"32.5675097399059"}]}
So I guess the problem is presenting when the app passes the latitude and longitude parameters to the PHP script. Anyone has ideas?
UPDATE: I really don't know what has changed, but now I don't get any errors. Unfortunately, no markers show up on the map. Null JSON?
You have a problem here :
getActivity().runOnUiThread(new Runnable() {..}
In android you are not allowed to perform network operation on main thread.
Your code most likely doesn't hit the PHP script therefore will result in null.