i am trying to develop a speedometer app for testing purposes i have already written the code that will get the speed but i am not sure if it is the real time speed because sometimes i see that there's some delay, this is my code:
public class MainActivity extends AppCompatActivity {
LocationManager locationManager;
LocationListener locationListener;
public void startListening() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
if (locationManager != null) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
}
}
public void updateLocationInfo(Location location){
TextView speedtextView = (TextView) findViewById(R.id.speedTextView);
speedtextView.setText("Current speed: " + location.getSpeed()*3600/1000);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startListening();
}
}}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
updateLocationInfo(location);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
};
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
} else {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
updateLocationInfo(location);
}
}
}
}
do i have to do anything else? is there any special way to get the real time speed? because i have used a lot of apps that gets the real time speed and right now i am wondering how did they do it? could it possibly be the "fair" GPS connection? or am i doing it wrong?
Related
I have made a simple sample of the FusedLocationProviderClient according to this: https://developer.android.com/training/location/request-updates#java
The issue is that I get a location every now and then (waaaay above an interval of 4000ms) and the accuracy is 2000 meters. I need a more precise location and more often. I get the feeling that the location client is not set up properly but at the same time, when using the locationmanager I also get a slow update rate on gps when using the gps provider, network provider also gives me an accuracy of 2000 meters.
Here is my code:
public class MainActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {
Context context;
private LocationCallback locationCallback;
private FusedLocationProviderClient fusedLocationClient;
private LocationRequest locationRequest;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
locationRequest = new LocationRequest();
locationRequest.setFastestInterval(2000);
locationRequest.setInterval(4000);
locationRequest.setMaxWaitTime(5000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
fusedLocationClient = new FusedLocationProviderClient(this);
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
Log.e("Got location from provider " + location.getProvider(), location.getLatitude() + ", " + location.getLongitude());
Log.e("getAccuracy", String.valueOf(location.getAccuracy()));
}
}
#Override
public void onLocationAvailability(#NonNull LocationAvailability locationAvailability) {
super.onLocationAvailability(locationAvailability);
Log.e("asdf", "available");
}
};
}
private void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
String[] PERMISSIONS = {android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION};
ActivityCompat.requestPermissions(this, PERMISSIONS, 112);
return;
}
fusedLocationClient.requestLocationUpdates(locationRequest,
locationCallback,
Looper.getMainLooper());
}
private void stopLocationUpdates() {
fusedLocationClient.removeLocationUpdates(locationCallback);
}
#Override
public void onRequestPermissionsResult(int i, #NonNull String[] strings, #NonNull int[] ints) {
Intent intent = getIntent();
finish();
startActivity(intent);
}
#Override
protected void onResume() {
super.onResume();
startLocationUpdates();
}
public void onPause() {
super.onPause();
stopLocationUpdates();
}
}
How can I resolve this?
I am trying to obtain a user's longitude and latitude when a button is clicked.
The following code obtains the GPS when the app is first installed, however, when the app is closed and reopened, it does not obtain any location.
I'm not sure if I incorrectly wrote the code to obtain the GPS location or I am missing something. Any advice would be appreciated.
public class MainActivity extends AppCompatActivity {
private Button button;
private EditText editText;
private LocationManager locationManager
private LocationListener locationListener;
private double longitude;
private double latitude;
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById((R.id.button2));
editText = (EditText) findViewById((R.id.editText2));
//My code
textView = (TextView) findViewById((R.id.textView2));
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
textView.append(("\n" + location.getLatitude() + " " + location.getLongitude()));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
Intent intent = new Intent((Settings.ACTION_LOCATION_SOURCE_SETTINGS));
startActivity(intent);
}
};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{
android.Manifest.permission.ACCESS_FINE_LOCATION,android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.INTERNET
}, 10);
//return;
}
}
else {
configureButton();
}
button.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
configureButton();
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode){
case 10:
if (grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
configureButton();
}
return;
}
}
private void configureButton() {
/* button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
locationManager.requestLocationUpdates("gps", 5000, 0, locationListener);
}
});*/
locationManager.requestLocationUpdates("gps", 5000, 0, locationListener);
}
}
Just just need to request location updates if the user has already granted the Location permission:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{
android.Manifest.permission.ACCESS_FINE_LOCATION,android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.INTERNET
}, 10);
} else {
//Added:
locationManager.requestLocationUpdates("gps", 5000, 0, locationListener);
}
}
else {
locationManager.requestLocationUpdates("gps", 5000, 0, locationListener);
}
hey this is my code for retrieving users location periodically
#Override
protected void onCreate(Bundle savedInstanceState) {
buildGoogleApiClient();
}
private void prepareLocationServices() {
int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
} else {
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean enabled = service
.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!enabled) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
} else {
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(1000);
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
}
}
private void buildGoogleApiClient() {
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
if (!googleApiClient.isConnected() || !googleApiClient.isConnecting()) {
googleApiClient.connect();
}
}
}
#Override
public void onLocationChanged(Location location) {
lat = location.getLatitude();
lng = location.getLongitude();
Log.d("location", location.toString());
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
prepareLocationServices();
}
}
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
prepareLocationServices();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
buildGoogleApiClient();
}
but onLocationChanged is not calling at all while I have Cellular Data and GPS enabled. What is wrong?
My google maps app is sending my coordinates every 5 seconds after I click the button (mapbttn). I want to make another button to stop sending these coordinates. How can I do that?
Here is my .java file:
private GoogleMap mMap;
Button mapbttn;
private LocationManager locationManager;
private LocationListener locationListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mapbttn = (Button) findViewById(R.id.setRangeButton);
mapbttn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
btncoord();
}
});
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Toast.makeText(getApplicationContext(), "" + location.getLatitude() + '\n' + location.getLongitude(), Toast.LENGTH_LONG).show();
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
public void onProviderDisabled(String s) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.INTERNET
}, 10);
return;
} else {
btncoord();
}
}
Bundle save = getIntent().getExtras();
if (save != null) color = save.getString("marker color");
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 10:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
btncoord();
return;
}
}
public void btncoord() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 5000, 0, locationListener);
}
Simply un-register your location manager like
locationManager.removeUpdates(ActivityName.this);
docs
Try this
public void stopUpdates(){
locationManager.removeUpdates(context);
}
call stopUpdate() method on stop button.
Included in the manifest:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
The activity code:
public class ActivityLogin extends AppCompatActivity {
public static LocationManager mLocationManager;
public static MyLocationListener locationListener = new MyLocationListener();
//...
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
ActivityCompat.requestPermissions(ActivityLogin.this,
new String[] {
Manifest.permission.ACCESS_FINE_LOCATION
},
2);
// ...
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 2:
{
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10 * 1000, 0, locationListener);
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10 * 1000, 0, locationListener);
mLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 10 * 1000, 0, locationListener);
}
return;
}
}
}
}
}
public class MyLocationListener implements LocationListener {
public void onLocationChanged(Location location) {
MapsActivity.Mylocation = new LatLng(
location.getLatitude(), location.getLongitude());
}
public void onProviderDisabled(String provider) {
// ...
}
public void onProviderEnabled(String provider) {
// ...
Location location = ActivityLogin.mLocationManager
.getLastKnownLocation(provider);
if (location != null) {
MapsActivity.Mylocation = new LatLng(
location.getLatitude(), location.getLongitude());
}
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// ...
}
}
As a result, the event onLocationChanged doesn't occur. If I am switching wifi off and then on again, the event onProviderEnabled occurs and ActivityLogin.mLocationManager.getLastKnownLocation(provider) returns null.
In the end, I can't get my coordinates.
I have had trouble with the locationListener in the past and the only way I got it working was by implementing the LocationListener in the mainActivity, a local or silent locationlistener would just not work.
eg
public class ActivityLogin extends AppCompatActivity implements LocationListener
That said, google is deprecating the locationListener and replacing it with the Google location API. This uses the fusedLocationAPI with an GoogleApiClient.
In your onCreate you should have something like
GoogleApiClient api_client;
api_client = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
In your onConnected method you should have something like
location = LocationServices.FusedLocationApi.getLastLocation(api_client);
I do not think it is an improvement but google are forcing this on us.