-1

i am having service in which i am getting latitude and longitude from background service. The code is working fine but not working in marshmallow and above because i need to set permission but i am not getting how to set permission in marshmallow.

This my service class

public class Example_services extends Service {
    public static final String BROADCAST_ACTION = "com.guards.anshul.hindguard.CUSTOM_INTENT";
    private static final int TWO_MINUTES = 1000 * 60 * 2;
    public LocationManager locationManager;
    public MyLocationListener listener;
    public Location previousBestLocation = null;
    public  String editTextValue;
    Intent intent;
    String restoredText;
    private final static int MY_PERMISSION_FINE_LOCATION = 101;

    @Override
    public void onCreate() {
        super.onCreate();
        intent = new Intent(BROADCAST_ACTION);
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();

        if(editTextValue!=null){

            editTextValue = intent.getStringExtra("B");
            SharedPreferences.Editor editor = getSharedPreferences("Guard_Id", MODE_PRIVATE).edit();
            editor.putString("guard_id", editTextValue);
            editor.apply();
        }else{
            SharedPreferences prefs = getSharedPreferences("Guard_Id", MODE_PRIVATE);
            restoredText = prefs.getString("guard_id", null);
        }
        Toast.makeText(Example_services.this.getApplicationContext(),restoredText,Toast.LENGTH_SHORT).show();

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        listener = new MyLocationListener();

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            Toast.makeText(Example_services.this.getApplicationContext(),"Need Permission",Toast.LENGTH_SHORT).show();

            return Service.START_STICKY;
        }
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
        return Service.START_STICKY;
    }



    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    protected boolean isBetterLocation(Location location, Location currentBestLocation) {
        if (currentBestLocation == null) {

            return true;
        }

        long timeDelta = location.getTime() - currentBestLocation.getTime();
        boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
        boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
        boolean isNewer = timeDelta > 0;


        if (isSignificantlyNewer) {
            return true;

        } else if (isSignificantlyOlder) {
            return false;
        }


        int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
        boolean isLessAccurate = accuracyDelta > 0;
        boolean isMoreAccurate = accuracyDelta < 0;
        boolean isSignificantlyLessAccurate = accuracyDelta > 200;


        boolean isFromSameProvider = isSameProvider(location.getProvider(),
                currentBestLocation.getProvider());

        if (isMoreAccurate) {
            return true;
        } else if (isNewer && !isLessAccurate) {
            return true;
        } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
            return true;
        }
        return false;
    }

     private boolean isSameProvider(String provider1, String provider2){
         if(provider1==null){
             return provider2 == null;
         }
         return provider1.equals(provider2);
     }

    @Override
    public void onDestroy() {
        // handler.removeCallbacks(sendUpdatesToUI);
        super.onDestroy();
        Log.v("STOP_SERVICE", "DONE");
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        locationManager.removeUpdates(listener);
    }

    public static Thread performOnBackgroundThread(final Runnable runnable) {
        final Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    runnable.run();
                } finally {

                }
            }
        };
        t.start();
        return t;
    }





    public class MyLocationListener implements LocationListener
    {

        public void onLocationChanged(final Location loc)
        {

            if(isBetterLocation(loc, previousBestLocation)) {
                double v =   loc.getLatitude();
                double b =  loc.getLongitude();

                //Log.e("<<a--b>>>>>>",String.valueOf(v)+ String.valueOf(b));

               Toast.makeText(getApplicationContext(), String.valueOf(v)+String.valueOf(b), Toast.LENGTH_SHORT).show();
                intent.setAction("com.guards.anshul.hindguard.CUSTOM_INTENT");
                intent.putExtra("latitude",v);
                intent.putExtra("longitude", b);
                intent.putExtra("A",restoredText);
                intent.putExtra("Provider", loc.getProvider());
                sendBroadcast(intent);

            }

        }

        public void onProviderDisabled(String provider)
        {
            Toast.makeText(getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT).show();
        }

        public void onProviderEnabled(String provider)
        {
            Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
        }


        public void onStatusChanged(String provider, int status, Bundle extras)
        {

        }

    }
}
Richa Singh
  • 603
  • 1
  • 7
  • 16

2 Answers2

1

You cannot request permissions for your service separately. But your problem is in fact different - you start the service regardless the permission status and this is wrong. You need to fix the logic and check permissions first. IF you got it granted - start the service. If not, let user know if is mandatory for your app to work and let him decide to quit or grant.

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
0

You cannot request runtime permissions from a service. You can call checkSelfPermission() to see if you hold the runtime permission, but that is it.

Check to see if you have the right runtime permissions before your activity starts the service. Then, if the service determines that it does not have the permissions (e.g., the user revoked them from Settings), raise a Notification that leads the user back to the activity.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • So if you have a background-only application (for example a Content Provider that serves data to other applications, but does not, itself, interact with the user) you are out of luck (or you have to create run a dummy, one-time GUI to get the permissions straightened out? – Dale Wilson Feb 28 '17 at 14:47
  • @DaleWilson: There is no such thing as a "background-only application", unless it is pre-installed on an Android device or serves as a plugin for some other app. Otherwise, it will need an activity or something that the user can start up, to move the app out of the stopped state. While in the stopped state -- which the app is in immediately after installation -- the app will no respond (e.g., to system broadcasts). – CommonsWare Feb 28 '17 at 14:51
  • "Serves as a plugin for some other app." like for instance a "Content Provider that serves data to other applications" I have written such a beast (long ago -- I believe on Eclair) and it worked just fine then. Haven't tried it recently. (i.e. since the on-demand permissions were added.) It wouldn't be that hard to add a run-once activity that handled requesting the permissions, but it was not necessary back then. – Dale Wilson Feb 28 '17 at 23:34
  • @DaleWilson: "it worked just fine then" -- the stopped state was introduced in API Level 13 or thereabouts. – CommonsWare Feb 28 '17 at 23:37