On this Blog I am going to explain about location update when the applications is running on background. In some cases we need to send location updated to our server when the application is on background. For this I am using startForeground() function.
Here LocationService.java is my Service Class which I used to get the location update on Background.
LocationService.java
public class LocationService extends Service implements LocationListener, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
private static final String TAG = "LocationService";
private static final int LOCATION_INTERVAL = 10000;
private static final int FASTEST_INTERVAL = 10000;
@Override
public void onCreate() {
if (isGooglePlayServicesAvailable()) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(LOCATION_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
//mLocationRequest.setSmallestDisplacement(10.0f); /* min dist for location change, here it is 10 meter */
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
}
//Check Google play is available or not
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
return ConnectionResult.SUCCESS == status;
}
@Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "Connected");
startLocationUpdates();
}
@Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "Connection suspended");
}
protected void startLocationUpdates() {
Log.d(TAG, "Start Location Updates");
try {
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
} catch (IllegalStateException e) {
}
}
@Override
public void onLocationChanged(Location location) {
if (location != null) {
Log.d(TAG, "Location Changed: " + location.getLatitude() + "," + location.getLongitude());
//Send Broadcast
Intent intent = new Intent(getPackageName());
intent.putExtra(Constants.LocationUpdated, location);
sendBroadcast(intent);
}
}
/* LocationListener[] mLocationListeners = new LocationListener[]{
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};*/
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Notification.Builder builder = new Notification.Builder(this, Constants.LOCATION_CHANNEL_ID)
.setContentTitle(getString(R.string.app_name))
.setContentText(Constants.LocationChange)
.setAutoCancel(true);
Notification notification = builder.build();
startForeground(1, notification);
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.app_name))
.setContentText(Constants.LocationChange)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true);
Notification notification = builder.build();
startForeground(1, notification);
}
return START_NOT_STICKY;
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionFailed:: " + connectionResult.getErrorMessage());
}
}
Once you create the Service Class you need to add this service class to AndroidManifest.xml file, Also You need to add the Location permissions if you didn't added on your Manifest file, Here is my Manifest file,
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="Your Package Here ">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:name=".AppController"
android:allowBackup="true"
android:hardwareAccelerated="false"
android:icon="@drawable/logo_squre"
android:label="@string/app_name"
android:largeHeap="true"
android:launchMode="singleInstance"
android:roundIcon="@drawable/logo_circle"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".HomeActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".service.LocationService" />
</application>
</manifest>
On the next step you need to create the Notification channel on your application class. We are using createNotificationChannel()method to Create Notification channel, Here us my Application class,
AppController.java
public class AppController extends Application {
public static final String TAG = AppController.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
createNotificationChannel();
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
public static synchronized AppController getInstance() {
return mInstance;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
Constants.LOCATION_CHANNEL_ID,
getString(R.string.app_name),
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}
Next step is to integrate the service class on our Activity class. To handle the broadcast we need to register the Broadcast Receiver on the Activity class. Here I am going to use createBroadcastReceiver() method for Register the Broadcast Receiver. This method will Invoke in onCreate(Bundle savedInstanceState) method like, Here is my method for register the receiver,
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//To Register the Receiver
broadcastReceiver = createBroadcastReceiver();
registerReceiver(broadcastReceiver, new IntentFilter(getPackageName()));
}
//Method for Register Broadcast receiver
private BroadcastReceiver createBroadcastReceiver() {
return new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
if (intent.hasExtra(Constants.LocationUpdated)){
Location location = AppController.getInstance().getCurrentLocation();
if (location != null) {
Log.e("Broadcast: ", "New Location: " + location.getLatitude() + "," + location.getLongitude());
}
}
}
}
};
}
To start and stop the location location service am using startLocationService() and stopLocationService() method.
//Service Intent Decleration
Intent locationServiceIntent;
//Start Location Service
public void startLocationService() {
if (locationServiceIntent == null)
locationServiceIntent = new Intent(this, LocationService.class);
if (!Helper.isServiceRunning(HomeActivity.this, LocationService.class)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(locationServiceIntent);
} else {
startService(locationServiceIntent);
}
}
}
//Stop Location service
public void stopLocationService() {
if (locationServiceIntent != null && Helper.isServiceRunning(HomeActivity.this, LocationService.class))
stopService(locationServiceIntent);
}
---------------
Thanks For Reading, Wish you a Happy Coding....
No comments:
Post a Comment