I have a problem when the service is started: the appliaction shows a force close message.
my startservice in the main activity looks like this:
startService(new Intent(Main.this,GPSService.class));
GPSService.class
public class GPSService extends Service implements LocationListener {
LocationManager locationManager;
double x1,x2;
#Override
public IBinder onBind(Intent intent)
{
return null;
}
#Override
public void onCreate()
{
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
public void onLocationChanged(Location loc)
{
x1=loc.getAltitude();
x2=loc.getLatitude();
}
public void onProviderEnabled(String s){
//locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
public void onProviderDisabled(String s){
//locationManager.removeUpdates(this);
//x1=0;
// x2=0;
}
public void onStatusChanged(String s, int i, Bundle b){}
#Override
public void onDestroy() {
locationManager.removeUpdates(this);
}
}
You need to give following permissions in androidManifest.xml
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CONTROL_LOCATION_UPDATES">
Related
My application contains 6 separated activities, one of them returns GPS coordination, this activity work perfectly when it's open but first I return to the main activity it stops updating location.
details :
I have created a GPS services and called it in the Manifest.xml
<service android:name=".Services.GPS_Service" />
This is the Service :
public class GPS_Service extends Service {
private LocationListener listener;
private LocationManager locationManager;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#SuppressLint("MissingPermission")
#Override
public void onCreate() {
listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Intent i = new Intent("location_update");
i.putExtra("Longitude", location.getLongitude());
i.putExtra("Latitude", location.getLatitude());
final Date date = new Date(location.getTime());
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
i.putExtra("time", sdf.format(date));
sendBroadcast(i);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
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);
//noinspection MissingPermission
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, listener);
}
#SuppressLint("MissingPermission")
#Override
public void onDestroy() {
super.onDestroy();
if (locationManager != null) {
//noinspection MissingPermission
locationManager.removeUpdates(listener);
}
}
}
According to your answers and the phrasing you use: "when it's open but first I return to the main activity" - I am assuming by 'I return to the main activity' you mean that either onBackPressed is involved, or just a simple finish() was called. For that reason, onDestroy was called so your listener gets cancelled, and that why it stops working.
You cannot have two activities active at the same time. You must use Android Service to update location.
I want to implement location tracking in android but in a small time interval (seconds), after searching and reading the documentation i found that there is restrictions on location access when app is in the background, and the solution is to use foreground service, But i need another legal and efficient solution without the need to show notification to the user.
You could use something like that
public class GPSService extends Service {
private LocationListener listener;
private LocationManager locationManager;
public IBinder onBind(Intent intent){
return null;
}
#SuppressLint("MissingPermission")
#Override
public void onCreate() {
super.onCreate();
listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Intent i = new Intent("location_update");
i.putExtra("coordinates",location);
sendBroadcast(i);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
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);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,5000,0,listener);
}
#Override
public void onDestroy() {
super.onDestroy();
if (locationManager != null){
locationManager.removeUpdates(listener);
}
}
}
And retreive by broadcaster
I tried to get gps data (speed) when I don't use the app i'm programming.
but always when I close the app it stops asking for gps updates. now I got told, that I have to use a service. so i did, but it still stops asking for updates everytime I close to ui of the app.
here is my code of the service:
package com.example.slartibartfast.kslordered;
public class BackroundService extends Service {
private static float speed;
//initializing the Location Manager and Listener
LocationManager locationManager;
LocationListener locationListener;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#SuppressLint("MissingPermission")
#Override
public void onCreate() {
//Instantiating the device manager an listener
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//when the location changed
Log.d("Location", ""+location);
Log.d("Float Location", ""+ location.getLongitude() + " " + location.getLatitude());
Log.d("Speed", " "+location.getSpeed());
//initializing the variable speed with the speed number given by the LocationListener
speed = location.getSpeed();
//creating a broadcast reciever
Intent intent = new Intent("speed_update");
intent.putExtra("speed", speed);
//sending speed to main activity
sendBroadcast(intent);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
//if gps is disabled, this opens the gps settings
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
};
locationManager.requestLocationUpdates("gps", 5000, 0, locationListener);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
}
and here of my main activity:
package com.example.slartibartfast.kslordered;
public class MainActivity extends AppCompatActivity {
//initializing ui elements
TextView textviewSpeed;
Button button;
//initializing ui BroadcastReciever
private BroadcastReceiver broadcastReceiver;
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//instantiating the ui elements
textviewSpeed = (TextView)findViewById(R.id.textview_speed);
//checking if permission to use gps location is given
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[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 10);
return;
}else{
}
startService(new Intent(this, BackroundService.class));
}
#Override
protected void onResume() {
super.onResume();
//broadcast reciever gets speed from the backround service
if (broadcastReceiver == null){
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//speed get's set on the textview
textviewSpeed.setText(""+ intent.getExtras().get("speed"));
}
};
}
registerReceiver(broadcastReceiver, new IntentFilter("speed_update"));
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//asks for the gps user permission
switch (requestCode){
case 10:
if (grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//(5000);
}
}
}
I think you need to add your code on OnStart instead of OnCreate
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
//when the location changed
Log.d("Location", ""+location);
Log.d("Float Location", ""+ location.getLongitude() + " " + location.getLatitude());
Log.d("Speed", " "+location.getSpeed());
//initializing the variable speed with the speed number given by the LocationListener
speed = location.getSpeed();
//creating a broadcast reciever
Intent intent = new Intent("speed_update");
intent.putExtra("speed", speed);
//sending speed to main activity
sendBroadcast(intent);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
//if gps is disabled, this opens the gps settings
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
};
locationManager.requestLocationUpdates("gps", 5000, 0, locationListener);
return START_STICKY;
}
I am using GPS either GPS_PROVIDER or NETWORK_SERVICE_PROVIDER for latitude and longitude . I want to detect when specifically App goes background to foreground (Either By Home button) .
ISSUES:
GPS detected location is not updated from time to time until any app used it so can get the updated location .
Detect the Background to foreground of app and detect location without battery issues .
Any GPS location update time to time without any battery issues.
For get location in background frequently use FusedLocation provider in a android service class.
Fused location provide give more accurate location and consume less power.
public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,LocationListener{
private static final String TAG = "LocationService";
private static final int LOCATION_INTERVAL = 1000;
private Context mContext;
private LocationRequest locationRequest;
private GoogleApiClient googleApiClient;
private FusedLocationProviderApi fusedLocationProviderApi;
#Override
public IBinder onBind(Intent arg0){
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onCreate(){
Log.e(TAG, "onCreate");
mContext = this;
getLocation();
}
#Override
public void onDestroy(){
Log.e(TAG, "onDestroy");
super.onDestroy();
try{
if(googleApiClient!=null){
googleApiClient.disconnect();
}
}
catch(Exception e){
e.printStackTrace();
}
}
private void getLocation(){
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(LOCATION_INTERVAL);
locationRequest.setFastestInterval(LOCATION_INTERVAL);
fusedLocationProviderApi = LocationServices.FusedLocationApi;
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
if (googleApiClient != null) {
googleApiClient.connect();
}
}
#Override
public void onConnected(Bundle arg0) {
// Location location = fusedLocationProviderApi.getLastLocation(googleApiClient);
fusedLocationProviderApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
#Override
public void onConnectionSuspended(int arg0) {
}
#Override
public void onResponse(int reqCode, int statusCode, String json) {
}
#Override
public void onCancel(boolean canceled) {
}
#Override
public void onProgressChange(int progress) {
}
#Override
public void onLocationChanged(Location location) {
Toast.makeText(mContext, "Driver location :"+location.getLatitude()+" , "+location.getLongitude(), Toast.LENGTH_SHORT).show();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
}
}
and call service from your activity-
startService(new Intent(mContext,LocationService.class));
hope it will help you.
EDITED
Also add below code to your manifest -
<service
android:name=".LocationService">
</service>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
i want a background service class that which will get the user current location sends as a notification to the user if the user changes its location then the updated location will sends back to the user as a notification..even if the user close the application then also will receive the notification (the service will trace the location in background even application closed)
currently i am using this service for tracing the location which works if the application in foreground
can u pls. help me to get out of this i am struggling for 4 hours
in your activity unlike the one that you are using make your buttons start and stop the service and it will run in the background unless the user reopens the app and stops it
Intent i = new Intent(MainActivity.this,gpsservice.class);
startService(new Intent(i));
or to stop
Intent j = new Intent(MainActivity.this,gpsservice.class);
stopService(new Intent(j));
use this service
public class gpsservice extends Service{
private LocationManager locationManager;
MyLocationListener locationListenerp;
public gpsservice() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
locationListenerp = new MyLocationListener();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 5000, 10, locationListenerp);
}
#Override
public void onDestroy() {
locationManager.removeUpdates(locationListenerp);
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "location Service Started", Toast.LENGTH_LONG).show();
}
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
Toast.makeText(getApplicationContext(), "I was here", Toast.LENGTH_LONG).show();
}
#Override
public void onProviderDisabled(String s) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
}