Android Studio: App crashes on some phones - java

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();
}
}
}
}

Related

Android 11 - LocationManager.addProximityAlert does not trigger alerts

The addProximityAlert call stopped triggering alerts on Android 11 devices.
I call the addProximityAlert for the special locations (calculated for the user location) from the Application.onCreate method or whenever the ACCESS_FINE_LOCATION permission is granted using the following code:
mLocationManager = (LocationManager) mApplicationContext.getSystemService(Context.LOCATION_SERVICE);
if (mLocationManager != null) {
final Criteria criteria = new Criteria();
//criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String provider = mLocationManager.getBestProvider(criteria, true);
if (!TextUtils.isEmpty(provider)) {
mLocationUpdatelistener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
subscribeForProximityAlert(location);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
final Location lastKnownLocation = mLocationManager.getLastKnownLocation(provider);
if (lastKnownLocation == null) {
try {
mLocationManager.requestSingleUpdate(criteria, mLocationUpdatelistener, Looper.getMainLooper());
} catch (Throwable e) {
e.printStackTrace();
}
} else {
subscribeForProximityAlert(lastKnownLocation);
}
}
}
The subscribeForProximityAlert function is as follows (it is called actually after the successful single location update - I've checked that):
void subscribeForProximityAlert(Location location) {
String id;
double lat;
double lng;
long radius;
// ... compute the params above using the location
final Intent intent = new Intent(ACTION_FILTER);
intent.putExtra("_id", id);
intent.putExtra("_lat", lat);
intent.putExtra("_lng", lng);
intent.putExtra("_rad", radius);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(mApplicationContext, i, intent, 0);
mPendingIntents.add(pendingIntent);
mLocationManager.addProximityAlert(
lat,
lng,
(float) radius,
24 * 60 * 60 * 1000,
pendingIntent
);
}
The ACTION_FILTER is the com.example.appname.ProximityAlert exactly the value I use in manifest to subscribe for the Proximity Alert broadcasts (com.example.appname is the package name of the app):
<application>
<receiver android:name="com.example.appname.ProximityAlertBroadcastReceiver">
<intent-filter>
<action android:name="com.example.appname.ProximityAlert" />
</intent-filter>
</receiver>
</application>
The ProximityAlertBroadcastReceiver can be as simple as:
public class ProximityAlertBroadcastReceiver extends BroadcastReceiver {
public ProximityAlertBroadcastReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
}
}
its onReceive method is never called on Android 11 devices (checked with Lod.d and Toast.makeText...show() calls). Not when the app is running, not when it's in background. Not when I'm already in the radius of specified point, not when I'm entering/exiting.
Tried to add the android.permission.ACCESS_BACKGROUND_LOCATION permission to the manifest (nothing about it in the LocationManager.addProximityAlerts docs anyway) and grant the permission in system settings for the app, but it didn't help.
Also tried to reduce the targetSdkVersion from 30 to 28, but it didn't help.
The problem happened because of the implicit intent for the broadcast receiver, which is prohibited for the app targeting Android 8+ (SDK version 26):
https://developer.android.com/about/versions/oreo/background#broadcasts
After changing the
final Intent intent = new Intent(ACTION_FILTER);
to
final Intent intent = new Intent(mApplicationContext, ProximityAlertBroadcastReceiver.class);
I started to receive the broadcasts.
UPDATE: There's a bug in recent Android versions (11, 12, maybe others) which makes Geofences unresponsive on some devices and completely non-working on other devices if no app is actively requesting location at the moment:
https://issuetracker.google.com/issues/218335535
addProximityAlert creates a geofence under the hood, so it's affected too.

android studio app keeps stopping when posting json

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.

Not able to get location with Service (LocationManager)

i am in real trouble here. Trying to get lat and lon with a background service every 3 sec but i am only able to get some data written when i click send lat and lon in extended controls of the emulator , so both phone and emulator are not working. Here is my code below, it would be awesome if someone could help me. Thanks!
Service
public class GPSService extends Service {
private static final String TAG = "GpsService";
private LocationListener locationListener;
private LocationManager locationManager;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Intent i = new Intent("location_update");
i.putExtra("latExtra",location.getLatitude());
i.putExtra("lonExtra",location.getLongitude());
sendBroadcast(i);
Log.i(TAG, "onLocationChanged: extras lat lon"+location.getLatitude()+" "+location.getLongitude());
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
Log.i(TAG, "onProviderDisabled: DISABLED");
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
};
locationManager =(LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
Criteria c = new Criteria();
String provider =locationManager.getBestProvider(c,true);
Log.i(TAG, "onCreate: bestProvider "+provider);
//noinspection MissingPermission
locationManager.requestLocationUpdates(provider,2000,0,locationListener);
}
#Override
public void onDestroy() {
super.onDestroy();
if (locationManager != null){
Log.i(TAG, "onDestroy: Location manager nije null i brisem");
//noinspection MissingPermission
locationManager.removeUpdates(locationListener);
}
}
}
MainActivity
private final String TAG = "Main";
...
BroadcastReceiver broadcastReciever;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//setStatusBarTranslucent(false);
if(!runtimePermisions()){
startLocationUpdate();}
...
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//stopService();
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//REQUEST PERMISSION
Log.i(TAG, "onClick: NO PERMISION");
} else {
Log.i(TAG, "onClick: got permision");
}
...
}
public void startLocationUpdate(){
Intent i = new Intent(this,GPSService.class);
startService(i);
Log.i(TAG, "startLocationUpdate: Pokrenuo sam service");
}
#Override
protected void onResume() {
super.onResume();
if (broadcastReciever == null){
broadcastReciever = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
lat = (Double) intent.getExtras().get("latExtra");
lon = (Double) intent.getExtras().get("lonExtra");
Log.i(TAG, "onReceive: lat lon "+lat+" "+lon);
}
};
}
registerReceiver(broadcastReciever,new IntentFilter("location_update"));
}
#Override
protected void onDestroy() {
super.onDestroy();
if (broadcastReciever!=null){
unregisterReceiver(broadcastReciever);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100) {
if (grantResults [0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){
startLocationUpdate();
}else{
runtimePermisions();}
}
}
private boolean runtimePermisions() {
if (Build.VERSION.SDK_INT >= 23 &&ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
requestPermissions(new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
},100);
return true;
}
return false;
}
MANIFEST
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.digiart.yoweather">
<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=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SettingsActivity"
android:theme="#style/SettingsTheme"></activity>
<service android:name=".Gps.GPSService"/>
</application>
</manifest>
Again... Any help would be great! THANKS :D
As K. Sopheak said, it can take a while to get the location. From the documentation:
It may take a while to receive the first location update. If an immediate location is required, applications may use the getLastKnownLocation(String) method.
So, you could try getting the last known location using getLastKnownLocation(String) when the service is started and, assuming it exists, broadcast it in the same way you would a location update. Bear in mind, though, that the last known location could be out of date. Depending on what you're using the location for this may or may not be acceptable.
Also, as an aside, a couple of thoughts:
You said 3 seconds, but the code uses 2,000 milliseconds - was that just a typo?
The frequency of location updates is a minimum time - you are not guaranteed to get updates that often. As per the documentation:
The location update interval can be controlled using the minTime parameter. The elapsed time between location updates will never be less than minTime, although it can be more depending on the Location Provider implementation and the update interval requested by other applications.
Is there any particular reason you need location updates at such a high frequency? Obtaining a location can be battery intensive, particularly given that you are requesting FINE as well as COARSE location permissions, so requesting it so frequently could place an enormous drain on device battery life. This is particularly so given that the code is running in a service and will therefore continue to run even when the application is in the background or the user is in an activity which does not require location data. Again, from the documentation:
Choosing a sensible value for minTime is important to conserve battery life. Each location update requires power from GPS, WIFI, Cell and other radios. Select a minTime value as high as possible while still providing a reasonable user experience. If your application is not in the foreground and showing location to the user then your application should avoid using an active provider (such as NETWORK_PROVIDER or GPS_PROVIDER), but if you insist then select a minTime of 5 * 60 * 1000 (5 minutes) or greater. If your application is in the foreground and showing location to the user then it is appropriate to select a faster update interval.
Google recommends using the Google Play services location APIs instead of the Android framework location APIs:
The Google Play services location APIs are preferred over the Android framework location APIs (android.location) as a way of adding location awareness to your app. If you are currently using the Android framework location APIs, you are strongly encouraged to switch to the Google Play services location APIs as soon as possible.

How to get current location in Android [duplicate]

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

Android location issue

Hi i am trying to get the device location using the Location api in android using the device network or wifi connection. However it doesnt seem to get the latt or longitude.
i have created a location provider and manager, and registered a location listener.
i then
launched
locationManagaer.requestLocationUpdates(locationProvide.getName(),TIME_INTERVAL, DISTANCE, this);
and from that point on, the app doesnt retrieve new location changes at all. what am i missing?
here is my userLocation Code
public class UserLocation implements LocationListener{
public static final int UPDATE_LATT = 0;
private static final int TIME_INTERVAL = 1000;
private static final int DISTANCE = 10;
private LocationManager locationManagaer;
private LocationProvider locationProvide;
private Handler mHandler;
public UserLocation(Context context, Handler handler){
locationManagaer = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
locationProvide = locationManagaer.getProvider(LocationManager.NETWORK_PROVIDER);
mHandler = handler;
}
public void startSearchLocation(){
Log.d("", "sart location search");
locationManagaer.requestLocationUpdates(locationProvide.getName(),TIME_INTERVAL, DISTANCE, this);
}
#Override
public void onLocationChanged(Location location) {
Log.d("", "location update on " + location.getLongitude());
Message.obtain(mHandler,UPDATE_LATT, new Position(location.getLongitude(), location.getLatitude()));
}
#Override
public void onProviderDisabled(String provider) {
Log.d("", "onProviderDisabled");
}
#Override
public void onProviderEnabled(String provider) {
Log.d("", "onProviderEnabled");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("", "onStatusChanged");
}
}
here is my activity that uses this class to setup and listen for new locations
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
position = (Position) msg.obj;
Toast.makeText(
getApplicationContext(),
position.getLattitude() + " " + position.getLongetude(),
Toast.LENGTH_LONG).show();
}
};
userLocation = new UserLocation(this, mHandler);
initializeViews();
userLocation.startSearchLocation();
}
Here is my position POJO
public class Position {
private double longetude;
private double lattitude;
public Position(){
}
public Position(double longetude, double lattitude){
}
public double getLongetude() {
return longetude;
}
public void setLongetude(double longetude) {
this.longetude = longetude;
}
public double getLattitude() {
return lattitude;
}
public void setLattitude(double lattitude) {
this.lattitude = lattitude;
}
}
Here is part of my manifest file
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.jr.haliotest.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>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
Logcat:
03-23 20:19:14.309: D/(16992): sart location search
03-23 20:19:14.384: E/(16992): file /data/data/com.nvidia.NvCPLSvc/files/driverlist.txt: not found!
03-23 20:19:14.384: I/(16992): Attempting to load EGL implementation /system/lib//egl/libEGL_tegra_impl
03-23 20:19:14.449: I/(16992): Loaded EGL implementation /system/lib//egl/libEGL_tegra_impl
03-23 20:19:14.514: I/(16992): Loading GLESv2 implementation /system/lib//egl/libGLESv2_tegra_impl
Testing on a htc one x thats rooted if that helps. wifi is on and god signal
If you are within a building then it is probably that your device is not able to connect to a GPS Provider. I would suggest if you move to a more open space so that you can get a signal.
One hint that if the device is connected to receive a gps signal. The sign of the gps will stop blinking and will become solid.
I would start by checking if your phones location services are enabled and maybe try rebooting. Also try using "GPS" instead of "network" to see if the problem is related to your network not providing location info.
From my experience wifi networks will sometimes simply not provide location info. I'm not sure if that's also true for cell networks, but I suspect there is no guarantee.

Categories

Resources