This question already has answers here:
How do I get the current GPS location programmatically in Android?
(21 answers)
Closed 9 years ago.
I'm having troubles of getting my current position coordinates using the NETWORK provider of android location system.
Already read a lot of tutorials and implemented 4 or 5 existing classes to my project and all of them are giving me the last coordinates but not the current ones.
I'm pretty sure that the problem is something fundamental that I am missing but I am not able to understand what exactly it is.
Codes I'm using now:
This is my main Activity
package com.example.locationtests;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GPSTracker mGPS = new GPSTracker(this);
TextView text = (TextView) findViewById(R.id.texts);
if(mGPS.canGetLocation ){
mGPS.getLocation();
text.setText("Lat"+mGPS.getLatitude()+"Lon"+mGPS.getLongitude());
}else{
text.setText("Unabletofind");
System.out.println("Unable");
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
This is the class I'm using for Tracking:
package com.example.locationtests;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
public final class GPSTracker implements LocationListener {
private final Context mContext;
// flag for GPS status
public boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
/**
* Function to get the user's current location
*
* #return
*/
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(Context.LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
Log.v("isGPSEnabled", "=" + isGPSEnabled);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Log.v("isNetworkEnabled", "=" + isNetworkEnabled);
if (isGPSEnabled == false && isNetworkEnabled == false) {
// no network provider is enabled
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
location=null;
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
location=null;
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
/**
* Stop using GPS listener Calling this function will stop using GPS in your
* app
* */
public void stopUsingGPS() {
if (locationManager != null) {
locationManager.removeUpdates(GPSTracker.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude() {
if (location != null) {
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude() {
if (location != null) {
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
*
* #return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog On pressing Settings button will
* lauch Settings Options
* */
public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS is settings");
// Setting Dialog Message
alertDialog
.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
This is my AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.locationtests"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.location" android:required="true" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.locationtests.MainActivity"
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>
</manifest>
Actually GPS positioning works fine, but NETWORK positioning dosn't.
When Ive turned devices GPS on coordinates keep changing while i'm moving, but the same doesn't happen when I have turn it off and relay on the NETWORK_PROVIDER
First you need to define a LocationListener to handle location changes.
int LOCATION_REFRESH_TIME = 15000; // 15 seconds to update
int LOCATION_REFRESH_DISTANCE = 500; // 500 meters to update
....
private final LocationListener mLocationListener = new LocationListener() {
#Override
public void onLocationChanged(final Location location) {
//your code here
}
};
Then get the LocationManager and ask for location updates
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, LOCATION_REFRESH_TIME,
LOCATION_REFRESH_DISTANCE, mLocationListener);
}
And finally make sure that you have added the permission on the Manifest,
For using only network based location use this one
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
For GPS based location, this one
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
You need to write code in the OnLocationChanged method, because this method is called when the location has changed. I.e. you need to save the new location to return it if getLocation is called.
If you don't use the onLocationChanged it always will be the old location.
I'm using this tutorial and it works nicely for my application.
In my activity I put this code:
GPSTracker tracker = new GPSTracker(this);
if (!tracker.canGetLocation()) {
tracker.showSettingsAlert();
} else {
latitude = tracker.getLatitude();
longitude = tracker.getLongitude();
}
also check if your emulator runs with Google API
Related
I want to know the distance between two coordinates.
When the coordinates change, I want to know the distance between them in a meter.
Code MainActivity:
private TextView textView;
private TextView label3,label2;
private EditText editText;
protected LocationManager locationManager;
private String name;
double latitude;
double longitude;
RequestQueue queue;
double Lan;
double Lon;
#SuppressLint("MissingPermission")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText)findViewById(R.id.editText);
label3 = (TextView)findViewById(R.id.label3);
label2 = (TextView)findViewById(R.id.label2);
textView = (TextView) findViewById(R.id.label);
int permissionStatus = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionStatus == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(),"access is",Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION},
1);
}
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 10,
10, this);
queue = Volley.newRequestQueue(this);
}
#Override
public void onLocationChanged(final Location location) {
textView.setText("My location = Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude());
if (latitude != location.getLatitude() && longitude != location.getLongitude()) {
Toast.makeText(this,"location changed",Toast.LENGTH_LONG).show();
latitude = location.getLatitude();
longitude = location.getLongitude();
getvalue();
}
}
#Override
public void onProviderDisabled(String provider) {
Log.e("Latitude","disable");
}
#Override
public void onProviderEnabled(String provider) {
Log.e("Latitude","enable");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.e("Latitude","status");
}
public void Insert(View view){
name = editText.getText().toString();
Insert.BackGround b=new Insert.BackGround();
String lan = String.valueOf(latitude);
String lon = String.valueOf(longitude);
b.execute(name,lan,lon);
String result = b.Result();
Toast.makeText(this,result,Toast.LENGTH_LONG).show();
}
public void getvalue(){
Log.e("st","getvalue");
String url = "http://my_url";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String name = response.getString("name");
Lan = response.getDouble("latitude");
Lon = response.getDouble("longitude");
Log.e("lan", String.valueOf(Lan));
Log.e("lon", String.valueOf(Lon));
calculate(latitude,longitude,Lan,Lon);
label3.setText("name="+name+" Lan="+Lan+" Lon="+Lon);
} catch (JSONException ex) {
ex.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
queue.add(request);
}
public void calculate( double lan1, double lon1, double lan2, double lon2){
Log.e("st","calculate");
Location loc1 = new Location("point A");
loc1.setLatitude(lan1);
loc1.setLongitude(lon1);
Location loc2 = new Location("point B");
loc2.setLatitude(lan2);
loc2.setLongitude(lon2);
String distanceInMeters = String.valueOf(loc1.distanceTo(loc2));
label2.setText("Distance = "+distanceInMeters );
}
Manifest:
<uses-sdk
android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission. ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
android:networkSecurityConfig="#xml/network_security_config"
android:usesCleartextTraffic="true"
android:testOnly="false"
android:debuggable="true"
tools:ignore="HardcodedDebugMode">
The program works well in
Redmi Note 4 and emulator BlueStacks
but in Redmi Note 5 and Android > 8 app give such error "app keeps stopping"
I can not find the error and answer on the Internet
help me please
I would be very happy if someone writes a code which works in any device :)
Android logcat
2020-02-26 18:22:42.553 3897-3897/com.example.getlocation E/GMPM: GoogleService failed to initialize, status: 10, Missing an expected resource: 'R.string.google_app_id' for initializing Google services. Possible causes are missing google-services.json or com.google.gms.google-services gradle plugin.
2020-02-26 18:22:42.554 3897-3897/com.example.getlocation E/GMPM: Scheduler not set. Not logging error/warn.
2020-02-26 18:22:42.560 3897-3927/com.example.getlocation E/GMPM: Uploading is not possible. App measurement disabled
2020-02-26 18:22:44.854 3897-3897/com.example.getlocation E/st: getvalue
2020-02-26 18:22:44.874 3897-3931/com.example.getlocation E/AndroidRuntime: FATAL EXCEPTION: Thread-4
Process: com.example.getlocation, PID: 3897
java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/ProtocolVersion;
at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:108)
at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:93)
at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:105)
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.apache.http.ProtocolVersion" on path: DexPathList[[zip file "/data/app/com.example.getlocation-9UATZ0srGfq2w1rY4vtYKQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.getlocation-9UATZ0srGfq2w1rY4vtYKQ==/lib/arm64, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:108)
at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:93)
at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:105)
You are probably using a deprecated library for volley. Use official version instead
implementation 'com.android.volley:volley:1.1.1'
For other issue I see in log cat is related to this GoogleService failed to initialize, status: 10, Missing an expected resource: 'R.string.google_app_id' for initializing Google services. Possible causes are missing google-services.json or com.google.gms.google-services gradle plugin.
I was making an application, which has a MapView, in which I want to show a marker in the position obtained from the gps of the device when I press a button. The problem I have is that the first time I enter the mapview activity, the getLastKnowLocation returns null so it doesn't put the marker on the map, however if I go back to the MainActivity and then to the activity of the mapview ,I get a position and the marker is put on the map.
I do not know if I should use another method instead of getLastKnowLocation.
I put the code in which I have not yet implemented the GPS permission and the active GPS verification.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_incidencia_mapa);
bt_getgps=(Button)findViewById(R.id.bt_getgps);
bt_getgps.setOnClickListener(this);
mapView = (MapView) findViewById(R.id.map_incidencia);
if (mapView != null) {
mapView.onCreate(null);
mapView.onResume();
mapView.getMapAsync(this);
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//SOLICITUD DE PERMISOS
return;
}
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this);
Location location = locationManager.getLastKnownLocation(locationManager.GPS_PROVIDER);
if (location == null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
if(location != null){
lat=location.getLatitude();
longi= location.getLongitude();
}
}
Onclick:
public void onClick(View view) {
if (lat != 0 && longi != 0) {
place = new LatLng(lat, longi);
marcador = new MarkerOptions();
marcador.position(place);
marcador.title("Zona del incidencia");
marcador.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_incidencia_mapa));
marcador.draggable(true);
gMap.setMinZoomPreference(5);
gMap.addMarker(marcador);
gMap.animateCamera(CameraUpdateFactory.newLatLngZoom(place, 17));
geocoder = new Geocoder(this, Locale.getDefault());
try {
direciones = geocoder.getFromLocation(lat, longi, 1);
} catch (IOException e) {
e.printStackTrace();
}
calle = direciones.get(0).getAddressLine(0);
Toast.makeText(this, direciones.get(0).getAddressLine(0), Toast.LENGTH_LONG).show();
bt_getgps.setText(direciones.get(0).getAddressLine(0));
} else {
Toast.makeText(this, "No hay longitud ni latitud", Toast.LENGTH_LONG).show();
}
}
Manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
getLastKnowLocation returns null if no location was stored on the API before accessing (such reiniting the cellphone), you must waiit for locationManager.requestLocationUpdates to respond on the listener you added, there you will have a valid location.
getLastKnowLoation IF NOT NULL is a good starting point for a mapapplicaiton, but you should update trough requestLocationUpdates
I'm new at android development and really confused by this problem.
I'm making a simple app which has 3 TextViews: text, text2 and text3.
text shows the latitude of user
text2 shows the longitude of the user and
text3 shows distance between user and the place called "Azadi Square".
The app runs properly on Samsung Galaxy S4 and Samsung Galaxy Tab S, but in Huawei Y511 and one of Sony Xperias (I do not know the exact name.), the app doesn't Open and says The App has unfortunately stopped
Here is my Java code:
public class Map extends Activity implements LocationListener {
private TextView text,text2,text3;
private String provider;
private LocationManager locationManager;
private double latitude,longitude;
private Location azadiSquare;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
text = (TextView)findViewById(R.id.text);
text2 = (TextView)findViewById(R.id.text2);
text3 = (TextView)findViewById(R.id.text3);
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria,false);
azadiSquare = new Location(provider);
azadiSquare.setLatitude(35.6996540);
azadiSquare.setLongitude(51.3379906);
Location location = locationManager.getLastKnownLocation(provider);
text.setText(location.getLatitude()+"");
text2.setText(location.getLongitude()+"");
text3.setText(distanceBetweenMeter(azadiSquare,location)+"");
}
#Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(provider,400,1,this);
}
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
text.setText(latitude+"");
text2.setText(longitude+"");
text3.setText(distanceBetweenMeter(azadiSquare,location)+"");
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String s) {
Toast.makeText(this,"Enabled new provider " + provider,Toast.LENGTH_LONG).show();
}
#Override
public void onProviderDisabled(String s) {
Toast.makeText(this,"Disabled provider " + provider,Toast.LENGTH_LONG).show();
}
private double getDistanceFromLatLonInKm(double lat1,double lon1,double lat2,double lon2) {
double R = 6371; // Radius of the earth in km
double dLat = deg2rad(lat2-lat1); // deg2rad below
double dLon = deg2rad(lon2-lon1);
double a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double d = R * c; // Distance in km
return d;
}
private double deg2rad(double deg) {
return deg * (Math.PI/180);
}
private int distanceBetweenMeter(Location location1, Location location2){
double distanceKM = getDistanceFromLatLonInKm(location1.getLatitude(),location1.getLongitude(),
location2.getLatitude(),location2.getLongitude());
int distanceMeter = (int)(distanceKM*1000);
return distanceMeter;
}
}
Note: I just deleted the imports!
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".Map" android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Notes: I turned On the Location of the phone before opening the app, so it is not the problem. The other thing I want to say is that all the calculations are okay and they are working fine.
On Android 6.0 (API level 23) and higher you need to request permission for ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION at run time. See, Requesting Permissions at Run Time. That may be the case.
The best thing to do is to logcat the issue and backtrace it so you could see where it's going bad or at least have one clue. If the answer from user35603 didn't worked then try this and post the logcat part regarding to your issue.
Finally the problem is solved! This part of the code was making trouble:
Location location = locationManager.getLastKnownLocation(provider);
text.setText(location.getLatitude()+"");
text2.setText(location.getLongitude()+"");
I guess it takes a little bit of time for location to get the current location. Actually, when app wants to run the line below, location is still null and app crashes:
text1.setText(location.getLatitude()+"");
I solved the crash with something like this:
Location location = locationManager.getLastKnownLocation(provider);
while(location==null){}
text.setText(location.getLatitude()+"");
text2.setText(location.getLongitude() + "");
text3.setText(distanceBetweenMeter(azadiSquare,location)+"");
Crash is solved, but the app freezes with white screen. I don't know exactly, but I guess it is trapped on while loop. Thanks!
public class MainActivity extends AppCompatActivity {
pb=findViewById(R.id.progressbar);
Example ex=new Example();//The subclass object is created here
boolean stop=false;//a boolean variable to start or stop the thread to get location.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (location== null) {
showSettingDialog();//this will show your custom way of displaying
//the location setting intent
new Thread(ex).start();//here the fetching location gets started
}
else{
//here write code after your location is fetched
//here to got some other base activity or stay in this
finish();//if you wan to stay in this activity then omit this line.
}
}
public class Example implements Runnable{ //This is a sub class in your main activity.
#Override
public void run() {//overriding run medthod
try {
while(location==null) { //this part keeps on running whithout
//ui freeze
if (stop) {
return;
}
runOnUiThread(new Runnable() {
#Override
public void run() {
pb.setVisibility(View.VISIBLE);
}
});
getLastLocation();//this function will fetch location.
Thread.sleep(1500);
pb.setVisibility(View.INVISIBLE);
if (location != null) {
//do your code here
stop = true;
finish();
}
}
}
catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
Each time I run the application, my SecurityException gets thrown and the error from the debugger reads as so:
java.lang.SecurityException: "gps" location provider requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission.
This seems like a simple mistake, however, my manifest file is completely correct. Here it is, and here is my MapActivity code as well:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.dev.cromer.jason.coverme.permission.MAPS_RECEIVE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value= "#string/google_maps_key" />
<activity
android:name=".MapActivity"
android:label="#string/title_activity_map" >
</activity>
</application>
My Activity:
package com.dev.cromer.jason.coverme;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapActivity extends FragmentActivity implements LocationListener {
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
setUpMapIfNeeded();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
//mMap.setMyLocationEnabled(true);
//mMap.setOnMyLocationChangeListener(this);
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
mMap.setMyLocationEnabled(true);
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
try {
Location myLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (myLocation != null) {
Log.d("TAG", "Not null");
}
else {
Log.d("TAG", "NULL");
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
}
catch (SecurityException se) {
Log.d("TAG", "SE CAUGHT");
se.printStackTrace();
}
}
#Override
public void onLocationChanged(Location location) {
Log.d("CHANGED", "LOCATION UPDATED");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION, and WRITE_EXTERNAL_STORAGE are all part of the Android 6.0 runtime permission system. In addition to having them in the manifest as you do, you also have to request them from the user at runtime (using requestPermissions()) and see if you have them (using checkSelfPermission()).
One workaround in the short term is to drop your targetSdkVersion below 23.
But, eventually, you will want to update your app to use the runtime permission system.
For example, this activity works with five permissions. Four are runtime permissions, though it is presently only handling three (I wrote it before WRITE_EXTERNAL_STORAGE was added to the runtime permission roster).
/***
Copyright (c) 2015 CommonsWare, LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
From _The Busy Coder's Guide to Android Development_
https://commonsware.com/Android
*/
package com.commonsware.android.permmonger;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String[] INITIAL_PERMS={
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.READ_CONTACTS
};
private static final String[] CAMERA_PERMS={
Manifest.permission.CAMERA
};
private static final String[] CONTACTS_PERMS={
Manifest.permission.READ_CONTACTS
};
private static final String[] LOCATION_PERMS={
Manifest.permission.ACCESS_FINE_LOCATION
};
private static final int INITIAL_REQUEST=1337;
private static final int CAMERA_REQUEST=INITIAL_REQUEST+1;
private static final int CONTACTS_REQUEST=INITIAL_REQUEST+2;
private static final int LOCATION_REQUEST=INITIAL_REQUEST+3;
private TextView location;
private TextView camera;
private TextView internet;
private TextView contacts;
private TextView storage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
location=(TextView)findViewById(R.id.location_value);
camera=(TextView)findViewById(R.id.camera_value);
internet=(TextView)findViewById(R.id.internet_value);
contacts=(TextView)findViewById(R.id.contacts_value);
storage=(TextView)findViewById(R.id.storage_value);
if (!canAccessLocation() || !canAccessContacts()) {
requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
}
}
#Override
protected void onResume() {
super.onResume();
updateTable();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.actions, menu);
return(super.onCreateOptionsMenu(menu));
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.camera:
if (canAccessCamera()) {
doCameraThing();
}
else {
requestPermissions(CAMERA_PERMS, CAMERA_REQUEST);
}
return(true);
case R.id.contacts:
if (canAccessContacts()) {
doContactsThing();
}
else {
requestPermissions(CONTACTS_PERMS, CONTACTS_REQUEST);
}
return(true);
case R.id.location:
if (canAccessLocation()) {
doLocationThing();
}
else {
requestPermissions(LOCATION_PERMS, LOCATION_REQUEST);
}
return(true);
}
return(super.onOptionsItemSelected(item));
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
updateTable();
switch(requestCode) {
case CAMERA_REQUEST:
if (canAccessCamera()) {
doCameraThing();
}
else {
bzzzt();
}
break;
case CONTACTS_REQUEST:
if (canAccessContacts()) {
doContactsThing();
}
else {
bzzzt();
}
break;
case LOCATION_REQUEST:
if (canAccessLocation()) {
doLocationThing();
}
else {
bzzzt();
}
break;
}
}
private void updateTable() {
location.setText(String.valueOf(canAccessLocation()));
camera.setText(String.valueOf(canAccessCamera()));
internet.setText(String.valueOf(hasPermission(Manifest.permission.INTERNET)));
contacts.setText(String.valueOf(canAccessContacts()));
storage.setText(String.valueOf(hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)));
}
private boolean canAccessLocation() {
return(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
}
private boolean canAccessCamera() {
return(hasPermission(Manifest.permission.CAMERA));
}
private boolean canAccessContacts() {
return(hasPermission(Manifest.permission.READ_CONTACTS));
}
private boolean hasPermission(String perm) {
return(PackageManager.PERMISSION_GRANTED==checkSelfPermission(perm));
}
private void bzzzt() {
Toast.makeText(this, R.string.toast_bzzzt, Toast.LENGTH_LONG).show();
}
private void doCameraThing() {
Toast.makeText(this, R.string.toast_camera, Toast.LENGTH_SHORT).show();
}
private void doContactsThing() {
Toast.makeText(this, R.string.toast_contacts, Toast.LENGTH_SHORT).show();
}
private void doLocationThing() {
Toast.makeText(this, R.string.toast_location, Toast.LENGTH_SHORT).show();
}
}
(from this sample project)
For the requestPermissions() function, should the parameters just be "ACCESS_COARSE_LOCATION"? Or should I include the full name "android.permission.ACCESS_COARSE_LOCATION"?
I would use the constants defined on Manifest.permission, as shown above.
Also, what is the request code?
That will be passed back to you as the first parameter to onRequestPermissionsResult(), so you can tell one requestPermissions() call from another.
My simple solution is this
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED) {
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
} else {
Toast.makeText(this, R.string.error_permission_map, Toast.LENGTH_LONG).show();
}
or you can open permission dialog in else like this
} else {
ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION },
TAG_CODE_PERMISSION_LOCATION);
}
CAUSE: "Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app." In this case, "ACCESS_FINE_LOCATION" is a "dangerous permission and for that reason, you get this 'java.lang.SecurityException: "gps" location provider requires ACCESS_FINE_LOCATION permission.' error (https://developer.android.com/training/permissions/requesting.html).
SOLUTION: Implementing the code provided at https://developer.android.com/training/permissions/requesting.html under the "Request the permissions you need" and "Handle the permissions request response" headings.
I have seen many posts regarding this problem, but none of them offered a solution for me.
I am trying to get the user position through the GPS (or, ultimately, any other valid provider). But I am always getting null locations. I do get a map, and can set an arbitrary location, is the providers that don't work.
I have my MAPS key properly set (also checked that it was the right one), all necessary permissions set (android.permission.INTERNET, android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_FINE_LOCATION) and in fact, all seemed to be working just fine yesterday!
I tried getting all possible providers with this code:
List<String> providers = locManager.getAllProviders();
for (String provider : providers) {
printProvider(provider);
}
Which shows all providers (4, in my case) are DummyLocationProviders.
I am trying to run my app on the phone, not the emulator (although I also tried with the emulator, with GPS enabled, to no avail).
This is the code I am using to fetch the location (which, again, worked just fine yesterday):
//Get criteria
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
//Get best provider
String bestProvider = locManager.getBestProvider(criteria, false);
printProvider(bestProvider);
//get the current location (last known location) from the location manager
Location location = locManager.getLastKnownLocation(bestProvider);
//if location found display as a toast the current latitude and longitude
if (location != null) {
Toast.makeText(this, "Current location:\nLatitude: " + location.getLatitude() + "\n" + "Longitude: " + location.getLongitude(), Toast.LENGTH_LONG).show();
point = new GeoPoint((int) (location.getLatitude()*1E6),(int)(location.getLongitude() *1E6));
controller.animateTo(point);
} else {
Toast.makeText(this, "Cannot fetch current location!", Toast.LENGTH_LONG).show();
}
My manifest file:
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".activities.MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-library android:name="com.google.android.maps" />
<activity
android:name=".activities.GoogleMapsActivity"
android:label="#string/title_activity_maps" >
</activity>
<activity
android:name=".activities.MyMapsActivity"
android:label="#string/title_activity_maps" >
</activity>
</application>
</manifest>
Try this code :
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import android.content.Context;
import android.graphics.Canvas;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
public class MyMapsActivity extends MapActivity
{
MapView mapView;
MapController mapController;
LocationManager locationManager;
LocationListener locationListener;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView) findViewById(R.id.mapView);
// enable Street view by default
mapView.setStreetView(true);
// enable to show Satellite view
// mapView.setSatellite(true);
// enable to show Traffic on map
// mapView.setTraffic(true);
mapView.setBuiltInZoomControls(true);
mapController = mapView.getController();
mapController.setZoom(5);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0, locationListener);
Touchy t = new Touchy();
List<Overlay> overlayList = mapView.getOverlays();
overlayList.add(t);
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
class Touchy extends Overlay
{
public boolean onTap(GeoPoint point, MapView mapView)
{
Context contexto = mapView.getContext();
String msg = "Latitude : " + point.getLatitudeE6()/1E6 + " - " + "Longitude : " + point.getLongitudeE6()/1E6;
Toast toast = Toast.makeText(contexto, msg, Toast.LENGTH_SHORT);
toast.show();
return true;
}
}
private class GPSLocationListener implements LocationListener
{
public void onLocationChanged(Location location)
{
if (location != null)
{
GeoPoint point = new GeoPoint((int) (location.getLatitude() * 1E6),(int) (location.getLongitude() * 1E6));
Toast.makeText(getBaseContext(),"Latitude: " + location.getLatitude() + " Longitude: " + location.getLongitude(),
Toast.LENGTH_SHORT).show();
mapController.animateTo(point);
mapController.setZoom(5);
mapView.invalidate();
}
if (location != null)
{
GeoPoint point=null;
String address = ConvertPointToLocation(point);
Toast.makeText(getBaseContext(), address, Toast.LENGTH_SHORT).show();
}
}
public String ConvertPointToLocation(GeoPoint point) {
String address = "";
Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocation(point.getLatitudeE6() / 1E6,
point.getLongitudeE6() / 1E6, 1);
if (addresses.size() > 0) {
for (int index = 0;
index < addresses.get(0).getMaxAddressLineIndex(); index++)
address += addresses.get(0).getAddressLine(index) + " ";
}
}
catch (IOException e) {
e.printStackTrace();
}
return address;
}
}
Layout Coding :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="#+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="Your MAP API Key"/>
<LinearLayout android:id="#+id/zoom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Link for getting own API key process :
http://sanathnandasiri.blogspot.in/2011/04/obtaining-google-maps-api-key-for.html
//get the current location (last known location) from the location manager
Location location = locManager.getLastKnownLocation(bestProvider);
use this instead of above line
location = locManager.getLastKnownLocation(bestProvider);
locManager.requestLocationUpdates(bestProvider,0, 0, locationListener);
location = locManager.getLastKnownLocation(bestProvider);
locManager.requestLocationUpdates(bestProvider,0, 0, locationListener);
First time location is null , so set your current location is last location .