I have an activity, in which the user is sent to device settings if the GPS is off to turn it on, and when the user is back from settings, then the device is asking for location permission.
So the first GPS dialog is done via AlertDialog builder, here is my full code:
public class Okoli extends AppCompatActivity implements LocationListener {
private final static int ALL_PERMISSIONS_RESULT = 101;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1;
private static final long MIN_TIME_BW_UPDATES = 90000; //1.5 mins
LocationManager locationManager;
Location loc;
ArrayList<String> permissions = new ArrayList<>();
ArrayList<String> permissionsToRequest= new ArrayList<>();
ArrayList<String> permissionsRejected = new ArrayList<>();
boolean isGPS = false;
boolean isNetwork = false;
boolean canGetLocation = true;
ArrayList<Actors> actorsList;
ActorAdapterDist adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setTitle((Html.fromHtml("<font color=\"#c6c6c6\">V okolí (vzdušná čiara)</font>")));
getSupportActionBar().setHomeAsUpIndicator(R.drawable.back);
}
setContentView(R.layout.okoli_fragment);
actorsList = new ArrayList<>();
adapter = new ActorAdapterDist(this, R.layout.okoli_item, actorsList);
TextView listTitle = findViewById(R.id.booklist_title1);
listTitle.setText("Čakám na signál GPS");
getIntent().setAction("created");
String MY_PREFS_NAME = "resumecheck";
SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
editor.putInt("idName", 2);
editor.apply();
ListView lv = findViewById(R.id.listViewx); lv.setAdapter(adapter);
locationManager = (LocationManager) this.getSystemService(Service.LOCATION_SERVICE);
assert locationManager != null;
isGPS = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetwork = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
permissionsToRequest = findUnAskedPermissions(permissions);
if (!isGPS && !isNetwork) {
showSettingsAlert(getString(R.string.askgps), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (dialog != null) {
dialog.dismiss(); dialog = null;
}
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
});
getLastLocation();
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (permissionsToRequest.size() > 0) {
requestPermissions(permissionsToRequest.toArray(new String[permissionsToRequest.size()]),
ALL_PERMISSIONS_RESULT);
canGetLocation = false;
}
}
getLocation();
}
}
@Override
public void onLocationChanged(Location location) {updateUI(location);}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {}
@Override
public void onProviderEnabled(String s) {
getLocation();
}
@Override
public void onProviderDisabled(String s) {
if (locationManager != null) {
locationManager.removeUpdates(this);
}
}
private void getLocation() { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
try {
if (canGetLocation) {
if (isGPS) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (loc != null) {updateUI(loc);}
}
} else if (isNetwork) {
// from Network Provider
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (loc != null) {updateUI(loc);}
}
} else {
loc.setLatitude(0);
loc.setLongitude(0);
updateUI(loc);
}
} else {
Toast.makeText(this, R.string.nolocation,
Toast.LENGTH_LONG).show();
}
} catch (SecurityException e) {
e.printStackTrace();
}
}
private void getLastLocation() {
try {
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, false);
if(provider==null) { showSettingsAlert(getString(R.string.askgps), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
});}
else {
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {updateUI(location);}
}
} catch (SecurityException e) {
e.printStackTrace();
}
}
private ArrayList findUnAskedPermissions(ArrayList<String> wanted) {
ArrayList<String> result = new ArrayList<>();
for (String perm : wanted) {
if (!hasPermission(perm)) {
result.add(perm);
}
}
return result;
}
private boolean hasPermission(String permission) {
if (canAskPermission()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return (this.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED);
}
}
return true;
}
private boolean canAskPermission() {
return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case ALL_PERMISSIONS_RESULT:
for (String perms : permissionsToRequest) {
if (!hasPermission(perms)) {
permissionsRejected.add(perms);
}
}
if (permissionsRejected.size() > 0) {//Log.e("rejected", "onRequestPermissionsResult");
String MY_PREFS_NAME = "resumecheck";
SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
editor.putInt("idName", 2);
editor.apply();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(permissionsRejected.get(0))) {
editor.putInt("idName", 1);
editor.apply();
showMessageOKCancel(getString(R.string.denied),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(permissionsRejected.toArray(
new String[permissionsRejected.size()]), ALL_PERMISSIONS_RESULT);
}
}
});
return;
}
}
} else {
// Log.e("ON", "No rejected permissions.");
String MY_PREFS_NAME = "resumecheck";
SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
editor.putInt("idName", 2);
editor.apply();
canGetLocation = true;
getLocation();
}
break;
}
}
public void showSettingsAlert(String message, DialogInterface.OnClickListener okListener) {
AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Theme_AppCompat_Dialog_Alert);
builder.setTitle(R.string.nogps);
builder.setMessage(message);
builder.setPositiveButton(R.string.ano, okListener);
builder.setNegativeButton(R.string.nie, null);
builder.create();
builder.show();
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this, R.style.Theme_AppCompat_Dialog_Alert)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton(R.string.cancel, null)
.create()
.show();
}
public void updateUI(Location loc) {
double Act1=loc.getLatitude();
double Act2=loc.getLongitude();
adapter.clear();adapter.notifyDataSetChanged();
TextView listTitle = findViewById(R.id.booklist_title1);
ListView lv = findViewById(R.id.listViewx);
if (Act1 > 0.0) { listTitle.setVisibility(View.GONE);lv.setVisibility(View.VISIBLE);GetContacts task = new GetContacts (Act1, Act2);
task.execute();
// new GetContacts().execute(Act1,Act2);
} else {
listTitle.setVisibility(View.VISIBLE);listTitle.setText("Čakám na signál GPS");lv.setVisibility(View.GONE);
}
}
ProgressDialog dialog;
@Override
public void onDestroy() {
super.onDestroy();
if (locationManager != null) {
locationManager.removeUpdates(this);
}
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
}
@Override
protected void onPause() {
super.onPause();
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
}
class GetContacts extends AsyncTask<Double, Void, Boolean> {
private Double act1;
private Double act2;
GetContacts(double act1, double act2) {
this.act1 = act1;
this.act2 = act2;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(Okoli.this);
dialog.setMessage("Načítavam");
dialog.setTitle("Pripájam sa k serveru");
dialog.show();
dialog.setCancelable(false);
dialog.dismiss();
dialog=null;
}
@Override
protected Boolean doInBackground(Double... args) {
HttpHandler sh = new HttpHandler();
String url = "https://www.myweb.sk";
String jsonStr = sh.makeServiceCall(url);
int pocet =0;
if (jsonStr != null) {
try {JSONObject jsonObj = new JSONObject(jsonStr);
JSONArray actors = jsonObj.getJSONArray("result");
double myDistx;
//Log.e("pocet",String.format("value = %d", actors.length()));
for (int i = 0; i < actors.length(); i++) {
JSONObject c = actors.getJSONObject(i);
Actors actor = new Actors();
double g1 = Double.parseDouble(c.getString("gps1"));
double g2 = Double.parseDouble(c.getString("gps2"));
myDistx = calculateDistance(act1, act2, g1, g2);
if (myDistx <= 50) {
actor.setLetter("x");
actor.setNazov(c.getString("nazov"));
actor.setThumb(c.getString("thumb"));
actor.setPerex(c.getString("perex"));
actor.setTyp(c.getString("typ"));
actor.setPlace(c.getString("place"));
actor.setGps1(c.getString("gps1"));
actor.setGps2(c.getString("gps2"));
actor.setExterier(c.getString("adresar"));
actor.setDist(myDistx);
actorsList.add(actor);
pocet++;
}
}
if (pocet == 0) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(Okoli.this.getApplicationContext(), R.string.nothing_around, Toast.LENGTH_LONG).show();
}
});
}
Collections.sort(actorsList, new Comparator<Actors>() {
@Override
public int compare(Actors lhs, Actors rhs) {
return lhs.getDist().compareTo(rhs.getDist());
}
});
} catch (final JSONException e) {
Okoli.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Okoli.this.getApplicationContext(),
"Chyba dát: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}); }
return true;
} else {
Okoli.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Okoli.this.getApplicationContext(),
"Chyba internetového pripojenia.",
Toast.LENGTH_LONG).show();
}
});
return false;
}
}
final static double AVERAGE_RADIUS_OF_EARTH = 6371;
double calculateDistance(double userLat, double userLng, double venueLat, double venueLng) {
double latDistance = Math.toRadians(userLat - venueLat);
double lngDistance = Math.toRadians(userLng - venueLng);
double a = (Math.sin(latDistance / 2) * Math.sin(latDistance / 2)) +
(Math.cos(Math.toRadians(userLat))) *
(Math.cos(Math.toRadians(venueLat))) *
(Math.sin(lngDistance / 2)) *
(Math.sin(lngDistance / 2));
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return (AVERAGE_RADIUS_OF_EARTH * c);
}
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (dialog != null && dialog.isShowing()) {
dialog.dismiss(); dialog = null;
}
//dialog.dismiss();
adapter.notifyDataSetChanged();
}
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() { //restart activity after back from GPS settings
super.onResume();
adapter.clear();
adapter.notifyDataSetChanged();
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
String action = getIntent().getAction();
// Prevent endless loop by adding a unique action, don't restart if action is present
if(action == null || !action.equals("created")) {
String MY_PREFS_NAME = "resumecheck";
SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
int idName = prefs.getInt("idName", 0); //0 is the default value.
if(idName == 2) {
Intent intent = new Intent(this, Okoli.class);
startActivity(intent);
finish();
} else {
SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
editor.putInt("idName", 1);
editor.apply(); }
}
// Remove the unique action so the next time onResume is called it will restart
else
getIntent().setAction(null);
}
}
However it is working fine, but the console gives me an error
android.view.WindowLeaked: Activity has leaked window DecorView@11bd862[] that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:576)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:363)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:128)
at android.app.Dialog.show(Dialog.java:454)
at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:1006)
at **.showSettingsAlert(Okoli.java:298)
at Okoli.onCreate(Okoli.java:95)**
at android.app.Activity.performCreate(Activity.java:7372)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1218)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3147)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302)
at android.app.ActivityThread.-wrap12(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891)
at android.os.Handler.dispatchMessage(Handler.java:108)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
So the lines 95 and 298 are pointing to showSettingsAlert.
I tried to dismiss dialog onDestroy, onPause, onpostExecute also onResume, but the error is still there. It is showing exactly, when I press the back arrow from device GPS settings and the permission alert is showing next.
Can you please advice, where and how to dismiss that alert window to avoid leaking?