Start location tracking on button click in WebView Android

Viewed 203

I want to track the location of the user when a button on WebView is clicked. I'm using a background service so that it can track location in the background. The app should first request for location access. The code for service and location tracking was working when a button on activity was clicked. However, on button click in WebView, no dialog is shown for requesting permission.

Here's the code for WebView integration and start service

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final Intent intent = new Intent(this.getApplication(), BackgroundLocationService.class);
    this.getApplication().startService(intent);
    this.getApplication().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

    webView = (WebView) findViewById(R.id.webview);
    webView.addJavascriptInterface(new WebAppInterface(this), "Android");
    WebSettings webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    MyWebViewClient webViewClient = new MyWebViewClient(this);
    webView.setWebViewClient(webViewClient);
    webView.loadUrl("https://utopiaaa.000webhostapp.com/"); //just a sample website
}

Here's the code for service connection in MainActivity:

 private ServiceConnection serviceConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        String name = className.getClassName();
        if (name.endsWith("BackgroundLocationService")) {
            Log.e("onServiceConnected","Let's see");
            gpsService = ((BackgroundLocationService.LocationServiceBinder) service).getService();

        }
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        if (componentName.getClassName().equals("BackgroundLocationService")) {
            gpsService = null;
        }
    }

    @Override
    public void onBindingDied(ComponentName name) {

    }

    @Override
    public void onNullBinding(ComponentName name) {

    }
};

Here's the code for requesting permission for location tracking access and to start tracking location:

 @RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    if (ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {  
        gpsService.startTracking();
    }
}
@Override
public void onLocationChanged(Location location) {
    wayLatitude = location.getLatitude();
    wayLongitude = location.getLongitude();

    String msg = "Updated Location: " +
            Double.toString(location.getLatitude()) + "," +
            Double.toString(location.getLongitude());
    Log.e("onLocationChanged",msg);
    Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
}

@RequiresApi(api = Build.VERSION_CODES.M)
public void startTracking() {
    //check for permission
    if (ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        Log.e("startTracking","Permission given");
        gpsService.startTracking();

    } else {
        Log.e("startTracking","Permission denied");
        ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, locationRequestCode);
    }
}

And here's the code for WebView interface:

   public class WebAppInterface {
    /**
     * Instantiate the interface and set the context
     */
    WebAppInterface(Context c) {
        mContext = c;

    }

    @JavascriptInterface
    @RequiresApi(api = Build.VERSION_CODES.M)
    public void TrackingOn() {   
        startTracking();
    }
}

And here's the code for BackgroundLocationService:

public class BackgroundLocationService extends Service {
String date;
private final LocationServiceBinder binder = new LocationServiceBinder();
private static final String TAG = "BackgroundLocationServi";
private LocationListener mLocationListener;
private LocationManager mLocationManager;
private NotificationManager notificationManager;
public static final String CHANNEL_ID = "channel";
private  FusedLocationProviderClient mFusedLocationClient;
private final int LOCATION_INTERVAL = 1000*60*10;
private final int LOCATION_DISTANCE = 1;
private final String URL_POST=  "";
DateFormat df;
SimpleDateFormat simpleDateFormat;
private LocationRequest mLocationRequest;
LocationCallback locationCallback=new LocationCallback() {
    @Override
    public void onLocationResult(LocationResult locationResult) {
        // do work here
        onLocationChanged(locationResult.getLastLocation());
    }
};

public BackgroundLocationService() {
}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    return binder;
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    Log.e("onStartCommand","Here");
    return START_NOT_STICKY;
}

@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onCreate() {
    Log.i(TAG, "onCreate");
    Log.i(TAG, "onCreate");
    df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    df.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));



}

@Override
public void onDestroy() {
    super.onDestroy();
    if (mLocationManager != null) {
        try {
            mLocationManager.removeUpdates(mLocationListener);


        } catch (Exception ex) {
            Log.i(TAG, "fail to remove location listeners, ignore", ex);
        }
    }
}



public void onLocationChanged(Location location) {

    Log.i(TAG, "LocationChanged: " + location);
    date=df.format(location.getTime());
    Toast.makeText(BackgroundLocationService.this, "LAT: " + location.getLatitude() + "\n LONG: " + location.getLongitude() + "\n" + date, Toast.LENGTH_SHORT).show();


}



@TargetApi(Build.VERSION_CODES.O)
@RequiresApi(api = Build.VERSION_CODES.M)
public void startTracking() {

    startForeground(12345678, getNotification());
    mLocationRequest = new LocationRequest();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(LOCATION_INTERVAL);
    mLocationRequest.setFastestInterval(LOCATION_INTERVAL);

    // Create LocationSettingsRequest object using location request
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
    builder.addLocationRequest(mLocationRequest);
    LocationSettingsRequest locationSettingsRequest = builder.build();

    // Check whether location settings are satisfied
    // https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient
    SettingsClient settingsClient = LocationServices.getSettingsClient(this);
    settingsClient.checkLocationSettings(locationSettingsRequest);

    // new Google API SDK v11 uses getFusedLocationProviderClient(this)
    if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    Activity#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 Activity#requestPermissions for more details.
        return;
    }
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

    mFusedLocationClient.requestLocationUpdates(mLocationRequest, locationCallback,
            Looper.myLooper());


}
private void stopLocationUpdates() {
    mFusedLocationClient.removeLocationUpdates(locationCallback);
}
public void stopTracking() {
    stopLocationUpdates();
    stopForeground(true);
    this.onDestroy();
}
@RequiresApi(api = Build.VERSION_CODES.O)
private Notification getNotification() {

    NotificationChannel channel = new NotificationChannel("channel_01", "My Channel", NotificationManager.IMPORTANCE_DEFAULT);

    NotificationManager notificationManager = getSystemService(NotificationManager.class);
    notificationManager.createNotificationChannel(channel);

    Notification.Builder builder = new Notification.Builder(getApplicationContext(), "channel_01").setAutoCancel(true);

    return builder.build();
}
public class LocationServiceBinder extends Binder {
    public BackgroundLocationService getService() {
        return BackgroundLocationService.this;
    }
}

}

And here's the complete code for MainActivity:

public class MainActivity extends AppCompatActivity implements LocationListener{
    public BackgroundLocationService gpsService;
    private WebView webView;
    private int locationRequestCode = 1000;
    Context mContext;
    private double wayLatitude = 0.0, wayLongitude = 0.0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final Intent intent = new Intent(this.getApplication(), BackgroundLocationService.class);
        this.getApplication().startService(intent);
        this.getApplication().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

        webView = (WebView) findViewById(R.id.webview);
        webView.addJavascriptInterface(new WebAppInterface(this), "Android");
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        MyWebViewClient webViewClient = new MyWebViewClient(this);
        webView.setWebViewClient(webViewClient);
        webView.loadUrl("https://utopiaaa.000webhostapp.com/");
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && this.webView.canGoBack()) {
            this.webView.goBack();
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }

    private ServiceConnection serviceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            String name = className.getClassName();
            if (name.endsWith("BackgroundLocationService")) {

                gpsService = ((BackgroundLocationService.LocationServiceBinder) service).getService();

            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            if (componentName.getClassName().equals("BackgroundLocationService")) {
                gpsService = null;
            }
        }

        @Override
        public void onBindingDied(ComponentName name) {

        }

        @Override
        public void onNullBinding(ComponentName name) {

        }
    };

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            gpsService.startTracking();
        }



    }

    @Override
    public void onLocationChanged(Location location) {
        wayLatitude = location.getLatitude();
        wayLongitude = location.getLongitude();

        String msg = "Updated Location: " +
                Double.toString(location.getLatitude()) + "," +
                Double.toString(location.getLongitude());
        Log.e("onLocationChanged",msg);
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }


    public class WebAppInterface {
        /**
         * Instantiate the interface and set the context
         */
        WebAppInterface(Context c) {
            mContext = c;

        }

        @JavascriptInterface
        @RequiresApi(api = Build.VERSION_CODES.M)
        public void TrackingOn() {

            startTracking();
        }

    }


    @RequiresApi(api = Build.VERSION_CODES.M)
    public void startTracking() {
        //check for permission
        if (ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

            gpsService.startTracking();

        } else {

            ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, locationRequestCode);
        }
    }
}
0 Answers
Related