An error occurs when searching for a city using the Android application. After I type a city, state, country (for example: New York, New York, US) and press the search button, the app crashes and gives me a NullPointerException.
MainActivity.java
package com.xxxx.weatherviewer;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ListView;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
// List of Weather objects representing the forecast
private List<Weather> weatherList = new ArrayList<>();
// ArrayAdapter for binding Weather objects to a ListView
private WeatherArrayAdapter weatherArrayAdapter;
private ListView weatherListView; // displays weather info
// configure Toolbar, ListView and FAB
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// autogenerated code to inflate layout and configure Toolbar
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// create ArrayAdapter to bind weatherList to the weatherListView
weatherListView = findViewById(R.id.weatherListView);
weatherArrayAdapter = new WeatherArrayAdapter(this, weatherList);
weatherListView.setAdapter(weatherArrayAdapter);
// configure FAB to hide keyboard and initiate web service request
FloatingActionButton fab =
findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// get text from locationEditText and create web service URL
EditText locationEditText =
findViewById(R.id.locationEditText);
URL url = createURL(locationEditText.getText().toString());
// hide keyboard and initiate a GetWeatherTask to download
// weather data from OpenWeatherMap.org in a separate thread
if (url != null) {
dismissKeyboard(locationEditText);
GetWeatherTask getLocalWeatherTask = new GetWeatherTask();
getLocalWeatherTask.execute(url);
}
else {
Snackbar.make(findViewById(R.id.coordinatorLayout),
R.string.invalid_url, Snackbar.LENGTH_LONG).show();
}
}
});
}
// programmatically dismiss keyboard when user touches FAB
private void dismissKeyboard(View view) {
InputMethodManager imm = (InputMethodManager) getSystemService(
Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
// create openweathermap.org web service URL using city
private URL createURL(String city) {
String apiKey = getString(R.string.api_key);
String baseUrl = getString(R.string.web_service_url);
try {
// create URL for specified city and imperial units (Fahrenheit)
String urlString = baseUrl + URLEncoder.encode(city, "UTF-8") +
"&units=imperial&cnt=16&APPID=" + apiKey;
return new URL(urlString);
}
catch (Exception e) {
e.printStackTrace();
}
return null; // URL was malformed
}
// makes the REST web service call to get weather data and
// saves the data to a local HTML file
private class GetWeatherTask extends AsyncTask<URL, Void, JSONObject> {
#Override
protected JSONObject doInBackground(URL... params) {
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) params[0].openConnection();
int response = connection.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
StringBuilder builder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
}
catch (IOException e) {
Snackbar.make(findViewById(R.id.coordinatorLayout),
R.string.read_error, Snackbar.LENGTH_LONG).show();
e.printStackTrace();
}
return new JSONObject(builder.toString());
}
else {
Snackbar.make(findViewById(R.id.coordinatorLayout),
R.string.connect_error, Snackbar.LENGTH_LONG).show();
}
}
catch (Exception e) {
Snackbar.make(findViewById(R.id.coordinatorLayout),
R.string.connect_error, Snackbar.LENGTH_LONG).show();
e.printStackTrace();
}
finally {
assert connection != null;
connection.disconnect(); // close the HttpURLConnection
}
return null;
}
// process JSON response and update ListView
#Override
protected void onPostExecute(JSONObject weather) {
convertJSONtoArrayList(weather); // repopulate weatherList
weatherArrayAdapter.notifyDataSetChanged(); // rebind to ListView
weatherListView.smoothScrollToPosition(0); // scroll to top
}
}
// create Weather objects from JSONObject containing the forecast
private void convertJSONtoArrayList(JSONObject forecast) {
weatherList.clear(); // clear old weather data
try {
// get forecast's "list" JSONArray
JSONArray list = forecast.getJSONArray("list");
// convert each element of list to a Weather object
for (int i = 0; i < list.length(); ++i) {
JSONObject day = list.getJSONObject(i); // get one day's data
// get the day's temperatures ("temp") JSONObject
JSONObject temperatures = day.getJSONObject("temp");
// get day's "weather" JSONObject for the description and icon
JSONObject weather =
day.getJSONArray("weather").getJSONObject(0);
// add new Weather object to weatherList
weatherList.add(new Weather(
day.getLong("dt"), // date/time timestamp
temperatures.getDouble("min"), // minimum temperature
temperatures.getDouble("max"), // maximum temperature
day.getDouble("humidity"), // percent humidity
weather.getString("description"), // weather conditions
weather.getString("icon"))); // icon name
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
}
This is the error message from the stacktrace:
java.lang.NullPointerException: Attempt to invoke virtual method 'org.json.JSONArray org.json.JSONObject.getJSONArray(java.lang.String)' on a null object reference
at com.xxxx.weatherviewer.MainActivity.convertJSONtoArrayList(MainActivity.java:171)
at com.xxxx.weatherviewer.MainActivity.access$300(MainActivity.java:30)
at com.xxxx.weatherviewer.MainActivity$GetWeatherTask.onPostExecute(MainActivity.java:157)
at com.xxxx.weatherviewer.MainActivity$GetWeatherTask.onPostExecute(MainActivity.java:106)
at android.os.AsyncTask.finish(AsyncTask.java:755)
at android.os.AsyncTask.access$900(AsyncTask.java:192)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:772)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
I believe there might be an issue with the line listed below:
JSONArray list = forecast.getJSONArray("list");
However, I am unsure of how to start....can someone please help me?
A simple fix could be to turn your catch block from:
catch (JSONException e) {
e.printStackTrace();
}
into:
catch (Exception e) {
e.printStackTrace();
}
This catches your NPE, but do note that, if you have an API for this the "list" value could be empty or having a null value in that case you can always have a checker before doing the operation on JSONArray list variable. So for example before doing this:
JSONObject day = list.getJSONObject(i);
you can surround it with:
if(forecast.has("list")) {
JSONObject day = list.getJSONObject(i);
// Same goes for day etc...
}
This ensures that it should check if the object exists in the first place before processing it to avoid NPE.
Related
I have created REST web service using jersey which returns JSON response. JSON response returned by web service is as follow-
{
"Disease": "Bacterial_blight",
"Control": "Foliar sprays of streptocycline sulphate # 0.5 gm/land copper-oxychlode # 3 g / l of water as and when symptoms seen."
}
I have made Android app activity for demo purpose which contains one radio button, one Edit text box and one Button to submit the parameters to REST web service. But Problem is I'm getting force close when I try to click on Submit Button.
This is the actual android activity class code-
package com.doitgeek.agroadvisorysystem;
import android.app.ProgressDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
public class DiseaseResultActivity extends AppCompatActivity {
public TextView diseaseTV;
public TextView controlMechanismTV;
public EditText etSymptom;
public RadioButton rbL;
public Button btnSubmit;
ProgressDialog dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_disease_result);
diseaseTV = (TextView)findViewById(R.id.diseaseTV);
controlMechanismTV = (TextView)findViewById(R.id.controlMechanismTV);
etSymptom = (EditText)findViewById(R.id.etSymptom);
rbL = (RadioButton)findViewById(R.id.rbL1);
btnSubmit = (Button)findViewById(R.id.btnSubmit);
}
public void onClickSubmit(View view) {
RequestParams params = new RequestParams();
String affectedPart = rbL.getText().toString();
String symptom = etSymptom.getText().toString();
params.put("affectedPart", affectedPart);
params.put("symptom", symptom);
invokeWS(params);
}
/* Invocation of RESTful WS */
public void invokeWS(RequestParams params) {
dialog.show();
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://192.168.0.100:8080/AgroAdvisorySystem/webapi/disease_prediction/result", params, new AsyncHttpResponseHandler(){
#Override
public void onSuccess(String response) {
dialog.hide();
try {
JSONObject obj = (JSONObject)new JSONTokener(response.toString()).nextValue();
JSONObject obj2 = obj.getJSONObject("Disease");
String disease = obj2.toString();
/*JSONObject obj = new JSONObject(response);
String disease = obj.getJSONObject("Disease").toString();*/
diseaseTV.setText(disease);
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Error Occurred [Server's JSON response might be invalid]!", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
#Override
public void onFailure(int statusCode, Throwable error, String content) {
dialog.hide();
if(statusCode == 404) {
Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show();
} else if(statusCode == 500) {
Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Unexpected Error occurred! [Most common Error: Device might not be connected to Internet or remote server is not up and running]", Toast.LENGTH_LONG).show();
}
}
});
}
}
I didn't find working solution till now that is why I am posting this as question.
So, what`s the Exception record?
It seems that the problem is in:
JSONObject obj2 = obj.getJSONObject("Disease");
where the item Disease is no longer a JSONObject.
Try obj.getSyting("Disease")
I have an app that goes out and gets the time from the internet. Does some maths on it and then after that is done it starts another activity.
Here is the code in my splashscreen activity
package com.firefluxentertainment.retroclicker;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SplashActivity extends AppCompatActivity {
long endTime;
long timeDelta;
Long endTimeMaths;
long timeStamp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
load();
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
DownloadTask task = new DownloadTask();
String result = null;
try {
result = task.execute("http://www.currenttimestamp.com/").get();
Pattern p = Pattern.compile("current_time = (.*?);");
Matcher m = p.matcher(result);
m.find();
String unixTime = (m.group(1));
timeStamp = Integer.parseInt(unixTime);
endTimeMaths = endTime/1000;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
Toast.makeText(SplashActivity.this, "you aint got no internet man", Toast.LENGTH_SHORT).show();
}
timeDelta = timeStamp-endTimeMaths;
Log.i("TimeDelta", timeDelta+"");
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
#Override
public void onResume() {
super.onResume();
new CountDownTimer(2000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
Intent i = new Intent(getApplicationContext(), MainActivity.class);
startActivity(i);
}
}.start();
}
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
void save(){
SharedPreferences pref = this.getSharedPreferences("TEST_PREFS", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putLong("endTime", endTime);
editor.commit();
}
void load() {
SharedPreferences pref = this.getSharedPreferences("TEST_PREFS", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
endTime = pref.getLong("endTime", System.currentTimeMillis()/1000);
editor.apply();
}
}
I have the webpage content containing the time download in the background and then i run a pattern and matcher on it. The problem is that most of the time is being wasted running the matcher rather than downloading the webpage. Since the matcher is running on the main thread it is delaying the UI thread causing the logo that i have set in the splashscreen layout not to display until the matcher is finished. How would I make it so that the matcher runs in the background as well so that the UI is not delayed?
Thank you for your help
The problem you have is that the AsyncTask will run as long as the Activity is alive. To decouple it from the Activity you have a couple options:
The best thing to do is probably sent an Intent to an IntentService that handles this. You will need to persist the results (like in SharedPrefs) and/or create a binder/callback or use other methods to get the data.
Put the AsyncTask in your Application class. This is not really a great idea because it is not the purpose of that class, but it would work.
In the splashscreen, only make the call to get the data, then pass it in an intent to the next Activity - and in that Activity run the AsyncTask to do the pattern matching. This breaks up the processing, but probably will result in the user waiting for these calls on both screens. Still, it would be better to see the app "doing something" rather than having a very long wait.
There are other ways to handle this, but these are probably the best approaches without getting too complex.
I work in a android app which should show the details of a virtual database(WAMPSERVER i use) and make new documents. When i push the button of show details the app displays the above error.The following is the allproductsactivity.java file.I have see and other similar post but i can't understand and solve my problem. I put x.x.x.x:80 on IP address for security reasons.
AllProductsActivity.java
package com.panos.appphpconnect;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.NameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class AllProductsActivity extends ListActivity {
private ProgressDialog pDialog;
JSONParser jParser=new JSONParser();
ArrayList<HashMap<String, String>> productsList;
// url to get all products list
private static String url_all_products = "http://x.x.x.x:80/connect/get_all_products.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_CLASSES = "classes";
private static final String TAG_PID = "_id";
private static final String TAG_NAME = "username";
// products JSONArray
JSONArray products = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.allproducts);
// Hashmap for ListView
productsList = new ArrayList<HashMap<String, String>>();
// Loading products in Background Thread
new LoadAllProducts().execute();
// Get listview
ListView lv = getListView();
// on seleting single product
// launching Edit Product Screen
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String _id = ((ListView) view.findViewById(R.id.id)).getAdapter().toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(),EditProductActivity.class);
// sending pid to next activity
in.putExtra(TAG_PID, _id);
// starting new activity and expecting some response back
startActivityForResult(in, 100);
}
});
}
// Response from Edit Product Activity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// if result code 100
if (resultCode == 100) {
// if result code 100 is received
// means user edited/deleted product
// reload this screen again
Intent intent = getIntent();
finish();
startActivity(intent);
}
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if(pDialog!=null && pDialog.isShowing()){
pDialog.cancel();
}
}
/**
* Background Async Task to Load all product by making HTTP Request
* */
class LoadAllProducts extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(AllProductsActivity.this);
pDialog.setMessage("Loading products. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);
// Check your log cat for JSON response
Log.d("All products:",json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
products = json.getJSONArray(TAG_CLASSES);
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_PID);
String name = c.getString(TAG_NAME);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_PID, id);
map.put(TAG_NAME, name);
// adding HashList to ArrayList
productsList.add(map);
}
} else {
// no products found
// Launch Add New product Activity
Intent i = new Intent(getApplicationContext(),NewProductActivity.class);
// Closing all previous activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
AllProductsActivity.this, productsList,
R.layout.list_item, new String[] { TAG_PID,
TAG_NAME},
new int[] { R.id.id, R.id.name });
// updating listview
setListAdapter(adapter);
}
});
}
}
}
The code of get_all_products.php is the following
<?php
/*
* Following code will list all the products
*/
// array for json response
$response = array();
// include db connect class
require("db_connect.php");
// connecting to db
$db = new DB_CONNECT();
// get all products from classes table
$result = mysql_query("SELECT *FROM classes") or die(mysql_error());
// check for empty result
if (mysql_num_rows($result)>0) {
// looping through all results
// products node
$response["classes"] = array();
while ($row = mysql_fetch_array($result)) {
// temp user array
$classes = array();
$classes["_id"] = $row["_id"];
$classes["username"] = $row["username"];
$classes["password"] = $row["password"];
// push single product into final response array
array_push($response["classes"], $classes);
}
// success
$response["success"] = 1;
// echoing panos response
echo json_encode($response);
} else {
// no products found
$response["success"] = 0;
$response["message"] = "No submissions found";
// echo no users json
echo json_encode($response);
}
?>
Also when i run the file get_all_products.php on my browser displays me the error " Parse error: syntax error, unexpected T_STRING, expecting T_FUNCTION in C:\wamp\www\connect\db_connect.php on line 6" but i don't understand which is line 6 and what is the error.The code of db_connect.php file is the below.
<?php
//A class file to connect to database
class DB_CONNECT{
function_constructor(){
$db = new DB_CONNECT();
//connecting to database
$this->connect();
}
function_destruct(){
//closing db connection
$this->close();
}
//Function to connect with database
function connect(){
//import database connection variables
require_once_DIR_ . '/db_config.php';
//connecting to mysql db
$con=mysql_connect(DB_SERVER,DB_USER,DB_PASSWORD) or die(mysql_error());
//selecting database
$db=mysql_select_db(DB_DATABASE) or die(mysql_error());
//returning connrction cursor
return $con;
}
//function close to db connection
function close(){
//closing db connection
mysql_close();
}
}
?>
That's all errors of logocat
E/JSON Parser(2234): Error parsing dataorg.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject
W/dalvikvm(2234): threadid=10: thread exiting with uncaught exception (group=0xb4e1e908)
E/AndroidRuntime(2234): FATAL EXCEPTION: AsyncTask #1
E/AndroidRuntime(2234): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime(2234): at android.os.AsyncTask$3.done(AsyncTask.java:299)
E/AndroidRuntime(2234): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
E/AndroidRuntime(2234): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
E/AndroidRuntime(2234): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
E/AndroidRuntime(2234): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
E/AndroidRuntime(2234): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
E/AndroidRuntime(2234): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
E/AndroidRuntime(2234): at java.lang.Thread.run(Thread.java:856)
E/AndroidRuntime(2234): Caused by: java.lang.NullPointerException
E/AndroidRuntime(2234): at com.panos.appphpconnect.AllProductsActivity$LoadAllProducts.doInBackground(AllProductsActivity.java:141)
E/AndroidRuntime(2234): at com.panos.appphpconnect.AllProductsActivity$LoadAllProducts.doInBackground(AllProductsActivity.java:1)
E/AndroidRuntime(2234): at android.os.AsyncTask$2.call(AsyncTask.java:287)
E/AndroidRuntime(2234): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
E/AndroidRuntime(2234): ... 4 more
SELECT *FROM classes is invalid syntax and when you query you should pass the connection to mysql_query
$result = mysql_query("SELECT * FROM classes", $db) or die(mysql_error());
And forget about android now, get this to work in your browser then you can worry about parsing it in your app.
I'm developing an APP that get user specified latitude,longitude, and altitude, then fake this GPS location on the phone, and show that I am at that location in google map. I have the required permission on manifest file and mocked location is enabled in developer settings.
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//lm.clearTestProviderEnabled(mocLocationProvider);
lm.addTestProvider(mocLocationProvider, false, false, false, false, false, false, false, 0, 10);
lm.setTestProviderEnabled(mocLocationProvider, true);
mockLocation = new Location(mocLocationProvider); // a string
mockLocation.setLatitude(Integer.parseInt(latitude.getText().toString())); // double
mockLocation.setLongitude(Integer.parseInt(longitude.getText().toString()));
mockLocation.setAltitude(Integer.parseInt(altitude.getText().toString()));
mockLocation.setTime(System.currentTimeMillis());
lm.setTestProviderLocation( mocLocationProvider, mockLocation);
But looks like my GPS location is not changed at all on google map, what is the problem?
Update: I just installed an app called "fake GPS location" on my phone and that app works fine, but I still don't know what's wrong with my code, but I think mine is a formal way to achieve this.
Update #2: Although some of similar applications can run on my phone, but I found some exceptions, http://www.cowlumbus.nl/forum/MockGpsProvider.zip, this app is not working on my phone. can someone help me with this issue? millions of thanks! I'm not getting any error message when setting the location each time.
Update#3 : I noticed that this app is fairly old, so it does not run on 4.1. if so, how to do the same thing in the new version? my phone is samsung galaxy s3, hope it helps.
Update#4: for your info, the code from app in my update#2 is:
package nl.cowlumbus.android.mockgps;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MockGpsProviderActivity extends Activity implements LocationListener {
public static final String LOG_TAG = "MockGpsProviderActivity";
private static final String MOCK_GPS_PROVIDER_INDEX = "GpsMockProviderIndex";
private MockGpsProvider mMockGpsProviderTask = null;
private Integer mMockGpsProviderIndex = 0;
/** Called when the activity is first created. */
/* (non-Javadoc)
* #see android.app.Activity#onCreate(android.os.Bundle)
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/** Use saved instance state if necessary. */
if(savedInstanceState instanceof Bundle) {
/** Let's find out where we were. */
mMockGpsProviderIndex = savedInstanceState.getInt(MOCK_GPS_PROVIDER_INDEX, 0);
}
/** Setup GPS. */
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
// use real GPS provider if enabled on the device
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
else if(!locationManager.isProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER)) {
// otherwise enable the mock GPS provider
locationManager.addTestProvider(MockGpsProvider.GPS_MOCK_PROVIDER, false, false,
false, false, true, false, false, 0, 5);
locationManager.setTestProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER, true);
}
if(locationManager.isProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER)) {
locationManager.requestLocationUpdates(MockGpsProvider.GPS_MOCK_PROVIDER, 0, 0, this);
/** Load mock GPS data from file and create mock GPS provider. */
try {
// create a list of Strings that can dynamically grow
List<String> data = new ArrayList<String>();
/** read a CSV file containing WGS84 coordinates from the 'assets' folder
* (The website http://www.gpsies.com offers downloadable tracks. Select
* a track and download it as a CSV file. Then add it to your assets folder.)
*/
InputStream is = getAssets().open("mock_gps_data.csv");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
// add each line in the file to the list
String line = null;
while ((line = reader.readLine()) != null) {
data.add(line);
}
// convert to a simple array so we can pass it to the AsyncTask
String[] coordinates = new String[data.size()];
data.toArray(coordinates);
// create new AsyncTask and pass the list of GPS coordinates
mMockGpsProviderTask = new MockGpsProvider();
mMockGpsProviderTask.execute(coordinates);
}
catch (Exception e) {}
}
}
#Override
public void onDestroy() {
super.onDestroy();
// stop the mock GPS provider by calling the 'cancel(true)' method
try {
mMockGpsProviderTask.cancel(true);
mMockGpsProviderTask = null;
}
catch (Exception e) {}
// remove it from the location manager
try {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.removeTestProvider(MockGpsProvider.GPS_MOCK_PROVIDER);
}
catch (Exception e) {}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// store where we are before closing the app, so we can skip to the location right away when restarting
savedInstanceState.putInt(MOCK_GPS_PROVIDER_INDEX, mMockGpsProviderIndex);
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onLocationChanged(Location location) {
// show the received location in the view
TextView view = (TextView) findViewById(R.id.text);
view.setText( "index:" + mMockGpsProviderIndex
+ "\nlongitude:" + location.getLongitude()
+ "\nlatitude:" + location.getLatitude()
+ "\naltitude:" + location.getAltitude() );
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
/** Define a mock GPS provider as an asynchronous task of this Activity. */
private class MockGpsProvider extends AsyncTask<String, Integer, Void> {
public static final String LOG_TAG = "GpsMockProvider";
public static final String GPS_MOCK_PROVIDER = "GpsMockProvider";
/** Keeps track of the currently processed coordinate. */
public Integer index = 0;
#Override
protected Void doInBackground(String... data) {
// process data
for (String str : data) {
// skip data if needed (see the Activity's savedInstanceState functionality)
if(index < mMockGpsProviderIndex) {
index++;
continue;
}
// let UI Thread know which coordinate we are processing
publishProgress(index);
// retrieve data from the current line of text
Double latitude = null;
Double longitude = null;
Double altitude= null;
try {
String[] parts = str.split(",");
latitude = Double.valueOf(parts[0]);
longitude = Double.valueOf(parts[1]);
altitude = Double.valueOf(parts[2]);
}
catch(NullPointerException e) { break; } // no data available
catch(Exception e) { continue; } // empty or invalid line
// translate to actual GPS location
Location location = new Location(GPS_MOCK_PROVIDER);
location.setLatitude(latitude);
location.setLongitude(longitude);
location.setAltitude(altitude);
location.setTime(System.currentTimeMillis());
location.setLatitude(latitude);
location.setLongitude(longitude);
location.setAccuracy(16F);
location.setAltitude(0D);
location.setTime(System.currentTimeMillis());
location.setBearing(0F);
// show debug message in log
Log.d(LOG_TAG, location.toString());
// provide the new location
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.setTestProviderLocation(GPS_MOCK_PROVIDER, location);
// sleep for a while before providing next location
try {
Thread.sleep(200);
// gracefully handle Thread interruption (important!)
if(Thread.currentThread().isInterrupted())
throw new InterruptedException("");
} catch (InterruptedException e) {
break;
}
// keep track of processed locations
index++;
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
Log.d(LOG_TAG, "onProgressUpdate():"+values[0]);
mMockGpsProviderIndex = values[0];
}
}
}
Problem solved: I added the following code to set my current location and it can successfully show up in google map application.
location.setLatitude(latitude);
location.setLongitude(longitude);
location.setBearing(bearing);
location.setSpeed(speed);
location.setAltitude(altitude);
location.setTime(new Date().getTime());
location.setProvider(LocationManager.GPS_PROVIDER);
location.setAccuracy(1);
Conclusion: If you want to use mock location service in the new version of android, you have to set every attribute by yourself.
I want to read a data from MYSQL database via PHP, JSON from Android.
I've been trying many different examples, but my Android phone wasn't able to read any data.
When I run the application my phone doesn't do anything after loading the application :(
MYSQL db info
Data Base Name : PeopleData
Table Name : people
Table has : id, name, sex, birthyear
PHP source : I tested index.php, and the result was correct.
-index.php
<?php
mysql_connect("127.0.0.1","root","");
mysql_select_db("PeopleData");
$q=mysql_query("SELECT * FROM people WHERE birthyear>1980");
while($e=mysql_fetch_assoc($q))
$output[]=$e;
print(json_encode($output));
mysql_close();
?>
Android java file for fetching database
package com.json;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class JSON extends Activity {
TextView resultView;
HttpClient client;
JSONObject json;
// the year data to send
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.json);
resultView = (TextView) findViewById(R.id.tvjson);
client = new DefaultHttpClient();
new Read().execute("text");
}
public JSONObject RedData() throws ClientProtocolException,IOException,JSONException {
HttpPost httppost = new HttpPost("http://127.0.0.1/series/database/index.php");
HttpResponse r = client.execute(httppost);
int status = r.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
JSONArray jArray = new JSONArray(data);
JSONObject last = jArray.getJSONObject(0); // 0 -> the last object
return last;
} else {
Toast.makeText(JSON.this, "error", Toast.LENGTH_LONG);
return null;
}
}
public class Read extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
try {
json = RedData();
return json.getString(arg0[0]);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String data) {
// TODO Auto-generated method stub
resultView.setText(data);
}
}
}
xml
<TextView
android:id="#+id/tvjson"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TextView>
manifest
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".JSON"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Console
[2012-02-22 16:19:58 - json] Android Launch!
[2012-02-22 16:19:58 - json] adb is running normally.
[2012-02-22 16:19:58 - json] Performing com.json.JSON activity launch
[2012-02-22 16:19:58 - json] Automatic Target Mode: Unable to detect device compatibility. Please select a target device.
[2012-02-22 16:19:59 - json] Uploading json.apk onto device '01499EF80D00D009'
[2012-02-22 16:19:59 - json] Installing json.apk...
[2012-02-22 16:20:01 - json] Success!
[2012-02-22 16:20:01 - json] Starting activity com.json.JSON on device 01499EF80D00D009
[2012-02-22 16:20:02 - json] ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.json/.JSON }
device
doing nothing
I don't know what I can do anymore. Please anybody help me.
Thank you.
This should work
package com.Online.Test;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class OnlineTestActivity extends Activity {
/** Called when the activity is first created. */
TextView resultView;
HttpClient client;
JSONObject json;
String Dat;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
resultView = (TextView) findViewById(R.id.tvjson);
client = new DefaultHttpClient();
try {
json = RedData();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Dat = json.toString();
new Read().onPostExecute(Dat);
}
public JSONObject RedData() throws ClientProtocolException, IOException, JSONException {
HttpPost httppost = new HttpPost("//link.php");
HttpResponse r = client.execute(httppost);
// int status = r.getStatusLine().getStatusCode();
//if (status == 200) {
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
JSONArray jArray = new JSONArray(data);
JSONObject last = jArray.getJSONObject(0); // 0 -> the last object
return last;
// } else {
// Toast.makeText(OnlineTestActivity.this, "error", Toast.LENGTH_LONG);
// return null;
//}
}
public class Read extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
try {
json = RedData();
//Toast.makeText(OnlineTestActivity.this, json.getString(arg0[0]), Toast.LENGTH_LONG);
return json.getString(arg0[0]);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String data) {
// TODO Auto-generated method stub
resultView.setText(data);
}
}
}
Have a look to the points
The IP address 127.0.0.1 refers to the local device, so for one the
HTTP request is not leaving the device/emulator.
At your Server Side Script (here PHP), set
header('content-type:application/json;charset=utf-8');
At doInBackground's Try block, check whether your ReadData() null or
not.
At JSONArray jArray = new JSONArray(data); check whether jArray null
or not
The following tutorials may help you
http://www.codeproject.com/Articles/267023/Send-and-receive-json-between-android-and-php
http://appinventor.blogspot.com/2011/09/android-mysql-connectivity-via-json.html
Cannot parse JSON data from MySQL Database
Make sure your computer is tethered in the same network as your phone.
replace 127.0.0.1 with the ipaddress of your computer,, to get the ip address of your computer, perform a :
"ipconfig" in windows cmd as admin or "ifconfig" on linux, idk for mac
then run your app, this should worj....if still you dont get any data, replace your code, and specifically here:
Dont use JSONArray, instead pass all the data from EnyityUtils to a String and later to a JSONObject without passing via a JSONArray
Make sure your computer is tethered in the same network as your phone.
replace 127.0.0.1 with the ipaddress of your computer,, to get the ip address of your computer, perform a :
"ipconfig" in windows cmd as admin or "ifconfig" on linux, idk for mac
then run your app, this should worry you..if still you dont get any data, replace your code, and specifically here:
Dont use JSONArray, instead pass all the data from EnyityUtils to a String and later to a JSONObject without passing via a JSONArray