I am trying to run this script, but somewhere in doInBackground() it's being launched back to starting activity.
(What I'm trying to do is scan all available SSID's and check them in database)
Here is my code:
Button btnHit;
TextView txtJson;
private static final String TAG = "My Activity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_find_connection);
btnHit = (Button) findViewById(R.id.request);
txtJson = (TextView) findViewById(R.id.results);
if (Build.VERSION.SDK_INT > 22) {
final String CoarseLocation = Manifest.permission.ACCESS_COARSE_LOCATION;
final String AccessWifi = Manifest.permission.ACCESS_WIFI_STATE;
final String ChangeWifi = Manifest.permission.CHANGE_WIFI_STATE;
if (checkSelfPermission(CoarseLocation) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 123);
}
if (checkSelfPermission(AccessWifi) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_WIFI_STATE, Manifest.permission.ACCESS_WIFI_STATE}, 123);
}
if (checkSelfPermission(ChangeWifi) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CHANGE_WIFI_STATE, Manifest.permission.CHANGE_WIFI_STATE}, 123);
}
}
LocationManager lman = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
boolean network_enabled = false;
try
{
network_enabled = lman.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {}
if (!network_enabled)
{
startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 0);
}
final WifiManager mWifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
mWifiManager.setWifiEnabled(true);
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
List<ScanResult> results = mWifiManager.getScanResults();
final int Amount = results.size();
Log.v(TAG, "Wifi Scan Results Count: " + Amount);
int num = 0;
while (num < Amount)
{
Log.v(TAG, "SSID = " + results.get(num).SSID);
num = num+1;
}
int dis = 0;
String res = "Results:\n\n\n";
while (dis < Amount)
{
res = res + results.get(dis).SSID + "\n\n";
String surl = "http://myurl.com?ssid=" + results.get(dis).SSID;
new JsonTask().execute(surl);
dis = dis+1;
}
TextView textres = (TextView) findViewById(R. id. resnet);
textres.setText(res);
}
}, filter);
mWifiManager.startScan();
}
private class JsonTask extends AsyncTask<String, String, String> {
ProgressDialog pd;
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(FindConnection.this);
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
if (line != "null")
{
Toast.makeText(getApplicationContext(), "Found one...", Toast.LENGTH_SHORT).show();
}
Log.d("Response: ", "> " + line);
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (pd.isShowing()){
pd.dismiss();
}
txtJson.setText(result);
}
}
And here's the error that I get:
11-12 19:48:56.920 21711-21811/com.comhet.comhet E/AndroidRuntime:
FATAL EXCEPTION: AsyncTask #1
Process: com.comhet.comhet, PID: 21711
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.RuntimeException: Can't create handler inside thread
that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:362)
at android.widget.Toast.<init>(Toast.java:109)
at android.widget.Toast.makeText(Toast.java:276)
at com.comhet.comhet.FindConnection$JsonTask.doInBackground(FindConnection.java:194)
at com.comhet.comhet.FindConnection$JsonTask.doInBackground(FindConnection.java:156)
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)
You are trying to show a Toast in the doInBackground() method of the AsyncTask. This is not allowed, as the doInBackground() method runs on a background thread and cannot perform actions related to the UI thread.
If you want to check the returned value, log the returned value or make the Toast inside the onPostExecute() method.
") Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()"
You can't create a Handler on a thread that hasn't called Looper.prepare. The main thread has that called for you. If you want to post to the main thread, you need to create than handler while on the main thread.
Have a look at your doInBackground method
You cannot do UI related operations in doInBackground.It should be done in onPostExecute{} method.
remove this from doInBackground:
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
if (line != "null")
{
Toast.makeText(getApplicationContext(), "Found one...", Toast.LENGTH_SHORT).show();
}
Log.d("Response: ", "> " + line);
}
}
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I am trying to create an Android app for weather. After some failed results, I decided to try a code from the internet. It still doesn't work.
I found it here: https://androstock.com/tutorials/create-a-weather-app-on-android-android-studio.html
The error I'm getting is:
I have checked the url with my actual API key - in browser it works.
MainActivity:
public class MainActivity extends AppCompatActivity {
TextView selectCity, cityField, detailsField, currentTemperatureField, humidity_field, pressure_field, weatherIcon, updatedField;
ProgressBar loader;
Typeface weatherFont;
String city = "Rome, IT";
/* Please Put your API KEY here */
String OPEN_WEATHER_MAP_API = "f2b6e17d5a21b6580934286ac8fa696a";
/* Please Put your API KEY here */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loader = (ProgressBar) findViewById(R.id.loader);
selectCity = (TextView) findViewById(R.id.selectCity);
cityField = (TextView) findViewById(R.id.city_field);
updatedField = (TextView) findViewById(R.id.updated_field);
detailsField = (TextView) findViewById(R.id.details_field);
currentTemperatureField = (TextView) findViewById(R.id.current_temperature_field);
humidity_field = (TextView) findViewById(R.id.humidity_field);
pressure_field = (TextView) findViewById(R.id.pressure_field);
weatherIcon = (TextView) findViewById(R.id.weather_icon);
weatherFont = Typeface.createFromAsset(getAssets(), "fonts/weathericons-regular-webfont.ttf");
weatherIcon.setTypeface(weatherFont);
taskLoadUp(city);
selectCity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
alertDialog.setTitle("Change City");
final EditText input = new EditText(MainActivity.this);
input.setText(city);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
alertDialog.setView(input);
alertDialog.setPositiveButton("Change",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
city = input.getText().toString();
taskLoadUp(city);
}
});
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
});
}
public void taskLoadUp(String query) {
if (Function.isNetworkAvailable(getApplicationContext())) {
Log.w("myApp", "network available in main 91");
DownloadWeather task = new DownloadWeather();
task.execute(query);
} else {
Toast.makeText(getApplicationContext(), "No Internet Connection", Toast.LENGTH_LONG).show();
}
}
class DownloadWeather extends AsyncTask < String, Void, String > {
#Override
protected void onPreExecute() {
super.onPreExecute();
loader.setVisibility(View.VISIBLE);
}
protected String doInBackground(String...args) {
String xml = Function.excuteGet("http://api.openweathermap.org/data/2.5/weather?q=" + args[0] +
"&units=metric&appid=" + OPEN_WEATHER_MAP_API);
Log.w("myApp", "xml is " +xml);
return xml;
}
#Override
protected void onPostExecute(String xml) {
try {
JSONObject json = new JSONObject(xml);
if (json != null) {
JSONObject details = json.getJSONArray("weather").getJSONObject(0);
JSONObject main = json.getJSONObject("main");
DateFormat df = DateFormat.getDateTimeInstance();
cityField.setText(json.getString("name").toUpperCase(Locale.US) + ", " + json.getJSONObject("sys").getString("country"));
detailsField.setText(details.getString("description").toUpperCase(Locale.US));
currentTemperatureField.setText(String.format("%.2f", main.getDouble("temp")) + "°");
humidity_field.setText("Humidity: " + main.getString("humidity") + "%");
pressure_field.setText("Pressure: " + main.getString("pressure") + " hPa");
updatedField.setText(df.format(new Date(json.getLong("dt") * 1000)));
weatherIcon.setText(Html.fromHtml(Function.setWeatherIcon(details.getInt("id"),
json.getJSONObject("sys").getLong("sunrise") * 1000,
json.getJSONObject("sys").getLong("sunset") * 1000)));
loader.setVisibility(View.GONE);
}else{
Toast.makeText(getApplicationContext(), "Json variable is null", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Error, Check City", Toast.LENGTH_SHORT).show();
}
}
}
}
Function:
public class Function {
// Project Created by Ferdousur Rahman Shajib
// www.androstock.com
public static boolean isNetworkAvailable(Context context)
{
return ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo() != null;
}
public static String excuteGet(String targetURL)
{
URL url;
HttpURLConnection connection = null;
try {
//Create connection
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty("content-type", "application/json; charset=utf-8");
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(false);
InputStream is;
int status = connection.getResponseCode();
if (status != HttpURLConnection.HTTP_OK)
is = connection.getErrorStream();
else
is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
return null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
}
public static String setWeatherIcon(int actualId, long sunrise, long sunset){
int id = actualId / 100;
String icon = "";
if(actualId == 800){
long currentTime = new Date().getTime();
if(currentTime>=sunrise && currentTime<sunset) {
icon = "";
} else {
icon = "";
}
} else {
switch(id) {
case 2 : icon = "";
break;
case 3 : icon = "";
break;
case 7 : icon = "";
break;
case 8 : icon = "";
break;
case 6 : icon = "";
break;
case 5 : icon = "";
break;
}
}
return icon;
}
}
The output:
FATAL EXCEPTION: main
Process: com.example.weatherapp, PID: 30032
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
at org.json.JSONTokener.nextValue(JSONTokener.java:94)
at org.json.JSONObject.<init>(JSONObject.java:159)
at org.json.JSONObject.<init>(JSONObject.java:176)
at com.example.weatherapp.MainActivity$DownloadWeather.onPostExecute(MainActivity.java:117)
at com.example.weatherapp.MainActivity$DownloadWeather.onPostExecute(MainActivity.java:101)
at android.os.AsyncTask.finish(AsyncTask.java:695)
at android.os.AsyncTask.access$600(AsyncTask.java:180)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
2019-02-09 18:27:45.489 30032-30032/com.example.weatherapp I/Process: Sending signal. PID: 30032 SIG: 9
The app begins to start, but then closes immediately.
EDIT: The question should not be a duplicate, in my opinion, as the problem is not from wrong initialization of an object, but from not adding a specific line in the manifest file
The issue can be with the permission for internet and permission for cleartext HTTP traffic value in your manifest.
Please make sure to add
?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
</manifest>
I have an AsyncTask(.execute()) with an onPostExecute method. This method starts another AsyncTask(.execute()) that needs to be done before continuing the execution of the first onPostExecute. Is it possible to pause the first thread and to wait for the second thread to finish? I need the result from the second postExecute method in order to finish the first postExecute.
An example below:
public class RetrieveData extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... strings) {
HttpURLConnection conn = null;
try {
URL url = new URL(strings[0]);
conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String linieNoua = "";
String crlf = System.getProperty("line.separator");
StringBuilder sb = new StringBuilder();
while((linieNoua = br.readLine()) != null) {
sb.append(linieNoua);
sb.append(crlf);
}
conn.disconnect();
return sb.toString();
} catch (Exception e){
e.printStackTrace();
}
return null;
}
}
RetrieveData retrieveData = new RetrieveData() {
#Override
protected void onPostExecute(String s) {
if (s != null) {
retrieveTransport(transportRegNr);
} else {
Toast.makeText(getApplicationContext(), R.string.login_server_error, Toast.LENGTH_LONG).show();
}
}
};
retrieveData.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"http://192.168.0.101:3000/route/" + prefs.getString("email",null));
}
private void retrieveTransport(String regNr){
RetrieveData retrieveData = new RetrieveData() {
#Override
protected void onPostExecute(String s) {
if (s != null) {
try {
JSONObject jsonObject = new JSONObject(s);
String model = jsonObject.getString("model");
String regNr = jsonObject.getString("regNr");
int type = jsonObject.getInt("type");
int seats = jsonObject.getInt("seats");
t = new Transport(model,regNr,null,seats,type);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(), R.string.login_server_error, Toast.LENGTH_LONG).show();
}
}
};
retrieveData.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"http://192.168.0.101:3000/transport/registryNr/" + regNr);
}
If I use the execute method, onPostExecute from retrieveTransport(String regNr) is never called. If I use executeOnExecutor, they are running simultaneously, and that's not good, either. I need to finish the first retrieveTransport; without that, I can't continue the first onPostExecute.
use
getStatus()
checks whether the the AsyncTask is pending, running, or finished.and when finsh start your new task.like:
if(retrieveTransport.getStatus() == AsyncTask.Status.PENDING){
// My AsyncTask has not started yet
}
if(retrieveTransport.getStatus() == AsyncTask.Status.RUNNING){
// My AsyncTask is currently doing work in doInBackground()
}
if(retrieveTransport.getStatus() == AsyncTask.Status.FINISHED){
// START NEW TASK HERE
}
example for your app:
if (retrieveTransport!= null && retrieveTransport.getStatus() == AsyncTask.Status.FINISHED) {
//START retrieveData TASK HERE
}
else
{
//IGNORE
}
I have a button that when used to run a asyntask class, I use it for set into a value in a textView. When he returns to the class that called the method, the value of the TextView caught and put in a Toast but the first time I click the Toast not appear any message, in the second works. What to do?
This is the method that calls the button
btnDadosPessoais.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String pega = TextAux.getText().toString();
Toast.makeText(getActivity(), pega, Toast.LENGTH_SHORT).show();
gravarDadoss(view);
}
});
TV is my TextView, I'm putting a simple string
protected void onPostExecute(String resposta) {
if(resposta.equals("Sem acesso à Internet")&&dialog.isShowing())
{
tv.setText(resposta);
dialog.dismiss();
}
else if (dialog.isShowing()) {
dialog.dismiss();
valida(resposta);
}
}
Asyntask here
`public class BackgroudCadPessoa extends AsyncTask {
ProgressDialog dialog;
Context ctx;
String pega;
ConnectivityManager connectivityManager;
TextView tv;
BackgroudCadPessoa(Context ctx, View v) {
this.ctx = ctx;
dialog = new ProgressDialog(ctx);
tv = (TextView) v.findViewById(R.id.textAux);
}
#Override
protected void onPreExecute() {
connectivityManager = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
dialog.setMessage("Aguarde...");
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setIndeterminate(true);
dialog.show();
}
#Override
protected String doInBackground(String... params) {
if (connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isAvailable() && connectivityManager.getActiveNetworkInfo().isConnected()) {
String urls = "my URL";
String nome = params[0];
try {
URL url = new URL(urls);
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 data = URLEncoder.encode("nome", "UTF-8") + "=" + URLEncoder.encode(nome, "UTF-8");
bufferedWriter.write(data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String response = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
response += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
return response;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
return "Sem acesso à Internet";
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String resposta) {
if(resposta.equals("Sem acesso à Internet")&&dialog.isShowing())
{
tv.setText(resposta);
dialog.dismiss();
}
else if (dialog.isShowing()) {
dialog.dismiss();
valida(resposta);
}
}
public void valida(String js)
{
JSONArray jsonArray;
if (js.equals(null)) {
tv.setText("Erro ao Cadastrar");
} else {
try {
JSONObject jo = new JSONObject(js);
jsonArray = jo.getJSONArray("Resposta");
int count = 0;
while (count < jsonArray.length()) {
JSONObject jsonObject = jsonArray.getJSONObject(count);
pega = jsonObject.getString("resposta");
count++;
}
if (pega == null)
{
tv.setText("Erro ao Cadastrar");
}
else if (pega.equals("Dados Cadastrados"))
{
tv.setText("Dados Cadastrados");
}
else if (pega.equals("Erro ao Cadastrar"))
{
tv.setText("Erro ao Cadastrar");
}
else
{
tv.setText("Dados Cadastrados");
}
} catch (JSONException ex) {
ex.printStackTrace();
}
}
}
}
`
You want your Toast to appear AFTER your AsyncTask finishes its output to TextAux?
Then you need to put your toaster in the onPostExecute
#Override
protected void onPostExecute(String resposta) {
if(resposta.equals("Sem acesso à Internet")&&dialog.isShowing())
{
tv.setText(resposta);
dialog.dismiss();
Toast.makeText(getActivity(), resposta, Toast.LENGTH_SHORT).show();
}
else if (dialog.isShowing()) {
dialog.dismiss();
valida(resposta);
}
}
i have two AsyncTask which works with Current user location data, the first goes well without any problem, but the second, stop the app works and app will crash.
notice that, just in real device the first task will works but in virtual devices even the first didn't work :|
code of mainActivity:
public class MainActivity extends AppCompatActivity {
Button btnShowLocation;
public static TextView txtTemperature;
public static TextView txtWindSpeed;
public static TextView txtHumidity;
public static TextView txtSummary;
public static TextView txtCityName;
GpsTracker gps;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnShowLocation = (Button)findViewById(R.id.btnupdate);
txtTemperature = (TextView) findViewById(R.id.txtTemperature);
txtWindSpeed = (TextView) findViewById(R.id.txtWindSpeed);
txtHumidity = (TextView) findViewById(R.id.txthumidity);
txtSummary = (TextView) findViewById(R.id.txtSummary);
txtSummary = (TextView) findViewById(R.id.txtCityName);
//find geoLocation
btnShowLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
gps = new GpsTracker(MainActivity.this);
if(gps.canGetLocation()){
Double lat = gps.getLatitude();
Double lng = gps.getLongtitude();
Toast.makeText(getApplicationContext(),
"Your location is -\nLat:"+lat+"\nLng:"+lng,
Toast.LENGTH_LONG).show();
String url = "https://api.forecast.io/forecast/KEY/"+lat+","+lng+"?units=ca";
JsonTask task = new JsonTask(getApplicationContext());
task.execute(url);
String url2 = "http://maps.googleapis.com/maps/api/geocode/json?latlng="+lat+","+lng;
CityNameTask city = new CityNameTask(getApplicationContext());
city.execute(url2);
}
else {
gps.showSettingsAlert();
}
}
});
}
}
the First AsyncTask which work fine:
class JsonTask extends AsyncTask<String, String, String> {
private Context mContext;
public JsonTask (Context context){
mContext = context;
}
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
String data = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
//Log.d("Response: ", "> " + line); //here u ll get whole response...... :-)
try{
JSONObject jsonObject= new JSONObject(line).getJSONObject("currently");
data=
jsonObject.getString("temperature")+","+
jsonObject.getString("windSpeed")+","+
jsonObject.getString("humidity")+","+
jsonObject.getString("summary");
}
catch(JSONException e)
{
}
}
return data.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
String string = result;
String[] parts = string.split(",");
String temperature = parts[0];
String windSpeed = parts[1];
String humidity = parts[2];
String summary = parts[3];
MainActivity.txtTemperature.setText(temperature);
MainActivity.txtWindSpeed.setText(windSpeed);
MainActivity.txtHumidity.setText(humidity);
MainActivity.txtSummary.setText(summary);
}
}
the second Task which fails:
class CityNameTask extends AsyncTask<String, String, String> {
private Context mContext;
public CityNameTask (Context context){
mContext = context;
}
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
String data = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
}
Log.d("Response: ", "> " + line);
try {
JSONObject jsonRootObject = new JSONObject(line);
JSONArray jsonArray = jsonRootObject.optJSONArray("results");
for(int i=0; i < jsonArray.length(); i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
data = jsonObject.getString("formatted_address");
}
} catch (JSONException e) {e.printStackTrace();}
return data.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
MainActivity.txtCityName.setText(result);
}
}
-- edited: logcat:
06-03 22:00:07.998 2804-2804/com.mortezaaghili.havamoon E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mortezaaghili.havamoon, PID: 2804
java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at com.mortezaaghili.havamoon.GpsTracker.getLatitude(GpsTracker.java:131)
at com.mortezaaghili.havamoon.MainActivity$1.onClick(MainActivity.java:54)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
edited again:
this is GPSTracker class:
public class GpsTracker extends Service implements LocationListener {
private final Context context;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location;
Double latitude;
Double longtitude;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1;
protected LocationManager locationManager;
public GpsTracker(Context context){
this.context = context;
getLocation();
}
public Location getLocation(){
try {
locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled){}
else{
this.canGetLocation = true;
if(isNetworkEnabled){
try {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES,
this);
if (locationManager != null){
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(location != null){
latitude = location.getLatitude();
longtitude = location.getLongitude();
}
}
}
catch (SecurityException e)
{
}
}
if(isGPSEnabled){
if (location == null){
try {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES,
this);
if (locationManager != null){
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null){
latitude = location.getLatitude();
longtitude = location.getLongitude();
}
}
}
catch (SecurityException e)
{
}
}
}
}
}
catch (Exception e){
e.printStackTrace();
}
return location;
}
public void stopUsingGPS(){
if (locationManager != null){
try{
locationManager.removeUpdates(GpsTracker.this);
}
catch(SecurityException e){
}
}
}
public double getLatitude(){
if (locationManager != null){
latitude = location.getLatitude();
}
return latitude;
}
public double getLongtitude(){
if (locationManager != null) {
longtitude = location.getLongitude();
}
return longtitude;
}
public boolean canGetLocation(){
return this.canGetLocation;
}
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
alertDialog.setTitle("GPS is setting");
alertDialog.setMessage("GPS is not enabled. do you want go to settings?");
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
What it seems like is that your location variable is not initialized from the GpsTracker class.
Therefore when you are extending Service class and implementing LocationListener you would have overridden a method called getLocation(), which should return Location object, but in your case is returning null.
If you could just post the code for that file, or debug it on your own.
probably your GpsTracker class must include something like:
public double getLatitude() {
if(location != null) { // here must be checked if location is available and it's not null, coz now you probably get crash coz this has not been checked
latitude = location.getLatitude();
}
return latitude;
}
In order to avoid getting Null Locations you need to use google play locations API
which is recommended by google.
Also Try
String line = "";
String data = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
}
At the end of this loop the line object is null
So save a copy of the last line element in some variable and
Then apply the following code on that.
Log.d("Response: ", "> " + line);
try {
JSONObject jsonRootObject = new JSONObject(line);
JSONArray jsonArray = jsonRootObject.optJSONArray("results");
for(int i=0; i < jsonArray.length(); i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
data = jsonObject.getString("formatted_address");
}
The relavent part of the stack trace is:
java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object
reference at com.mortezaaghili.havamoon.GpsTracker.getLatitude(GpsTracker.java:131)
Broken code mentioned:
public double getLatitude(){
if (locationManager != null){
latitude = location.getLatitude();
}
return latitude;
}
You're checking for a null locationManager but then calling a method on location which may have been null from the big try/catch swallowing in the getLocation() setup method called during the GPSTracker constructor.
Check for location null instead:
public double getLatitude(){
if (location != null){
latitude = location.getLatitude();
}
return latitude;
}
When i try to set the ImageView variable "profilePicture" to the bitmap from the image url, it doesn't show anything. Please help!! I am getting the image url link from my database. This is what that async task result is.
System.out: Resulted Value: {"image":"http://www.myegotest.com/PhotoUpload/uploads/5.png"}
Here is my Java code
public class HomeActivity extends AppCompatActivity {
//View item variables
private TextView loggedUsersName;
private TextView successMessage;
private Button logoutButton;
private ImageView profilePicture;
//Other variables
private String getProfileImageURL = "http://www.myegotest.com/PhotoUpload/getAllImages.php";
private String firstName;
private String lastName;
private String email;
private Bitmap profilePicBitmap;
LocalDataBase mLocalDataBase;
Boolean imageSet;
Drawable d;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//Get logged in user from LocalDataBase and
//Destroy Activity if user is logged out
mLocalDataBase = new LocalDataBase(this);
User user = mLocalDataBase.getLoggedInUserInfo();
if(!mLocalDataBase.userIsLoggedIn()){
HomeActivity.this.finish();
}
//Initialize view item variables.
loggedUsersName = (TextView)findViewById(R.id.login_user);
successMessage = (TextView)findViewById(R.id.message);
logoutButton = (Button)findViewById(R.id.logoutButton);
profilePicture = (ImageView)findViewById(R.id.profile_Picture);
//Get intent and values from the intent started this activity and
//Get loggedIn user values from the LocalDataBase .
Intent intent = getIntent();
String message = intent.getStringExtra("MESSAGE");
firstName = user.mFirstName;
lastName = user.mLastName;
email = user.mEmail;
//Set view values to equal values sent from intent.
loggedUsersName.setText(firstName + " " + lastName);
successMessage.setText(message);
netAsync();
}
//Call this method to execute the Async Task
private void netAsync() {
new NetCheck().execute();
}
//Async Task to check whether internet connection is working.
private class NetCheck extends AsyncTask {
private ProgressDialog mDialog;
//Create and show progress dialog box so user knows the app is trying to login.
#Override
protected void onPreExecute() {
super.onPreExecute();
mDialog = new ProgressDialog(HomeActivity.this);
mDialog.setTitle("Logging In...");
mDialog.setMessage("connecting to server");
mDialog.setIndeterminate(false);
mDialog.setCancelable(true);
mDialog.show();
}
//Gets current device state and checks for working internet connection by trying Google.
#Override
protected Boolean doInBackground(Object[] objects) {
ConnectivityManager mCM = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo myNetInfo = mCM.getActiveNetworkInfo();
if ( (myNetInfo != null) && (myNetInfo.isConnected())){
try {
URL url = new URL("http://google.com");
HttpURLConnection myConnection = (HttpURLConnection) url.openConnection();
myConnection.setConnectTimeout(3000);
myConnection.connect();
if (myConnection.getResponseCode() == 200){
return true;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
//If successful internet connection start AsyncTask to register user info on server
if(o.equals(true)){
mDialog.dismiss();
new RegisterUser().execute(getProfileImageURL, email);
} else {
mDialog.dismiss();
Toast.makeText(getApplicationContext(), "Error in Network Connection", Toast.LENGTH_SHORT).show();
}
}
}
//AsyncTask to get profile pic url string from server
private class RegisterUser extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
try {
URL url = new URL(params[0]);
HttpURLConnection LucasHttpURLConnection = (HttpURLConnection)url.openConnection();
LucasHttpURLConnection.setRequestMethod("POST");
LucasHttpURLConnection.setDoOutput(true);
LucasHttpURLConnection.setDoInput(true);
LucasHttpURLConnection.setConnectTimeout(1000 * 6);
LucasHttpURLConnection.setReadTimeout(1000 * 6);
//OutputStream to get response
OutputStream outputStream = LucasHttpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,"UTF-8"));
String data =
URLEncoder.encode("email", "UTF-8")+"="+URLEncoder.encode(params[1], "UTF-8");
bufferedWriter.write(data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
//InputStream to get response
InputStream IS = LucasHttpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(IS, "iso-8859-1"));
StringBuilder response = new StringBuilder();
String json;
while( (json = bufferedReader.readLine()) != null){
response.append(json + "\n");
break;
}
bufferedReader.close();
IS.close();
LucasHttpURLConnection.disconnect();
return response.toString().trim();
} catch (MalformedInputException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Print server AsyncTask response
System.out.println("Resulted Value: " + result);
//If null Response
if (result != null && !result.equals("")) {
String profilepic = returnParsedJsonObject(result);
new GetBitmapImageFromUrl().execute(profilepic);
profilePicture = (ImageView)findViewById(R.id.profile_Picture);
profilePicture.setImageBitmap(profilePicBitmap);
} else {
Toast.makeText(HomeActivity.this, "Sorry, there was an error. Please try again", Toast.LENGTH_LONG).show();
}
}
//Method to parse json result and get the value of the key "image"
private String returnParsedJsonObject(String result){
JSONObject resultObject = null;
String returnedResult = "";
try {
resultObject = new JSONObject(result);
returnedResult = resultObject.getString("image");
} catch (JSONException e) {
e.printStackTrace();
}
return returnedResult;
}
}
class GetBitmapImageFromUrl extends AsyncTask<String,Void,Bitmap>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Bitmap doInBackground(String... params) {
try {
profilePicBitmap = BitmapFactory.decodeStream((InputStream)new URL(params[0]).getContent());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
}
}
}
If you are seeing background white instead image. Out of memory exception by using bitmap.
You could use
Option 1
URL newurl = new URL(photo_url_str);
mIcon_val = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream());
profile_photo.setImageBitmap(mIcon_val);
Picasso
Picasso.with(context).load("http://www.myegotest.com/PhotoUpload/uploads/5.png").into(profilePicture);
I would suggest to go with Piccasso. Since it will handle everything.