0

I need to send data to server continuously (say after every x seconds or min) even if app is in background.i know service is the best option for this.as i have never tried such scenario is there any handy example on how to make web-service call from service and then after deliver response to activity (whether data successfully or not).any approach or other way on how to achieve this. any help is appreciated.

Hardik Mehta
  • 867
  • 1
  • 12
  • 20

2 Answers2

0

First add this in mainactivity:

AlarmManager alarmManager;
PendingIntent pendingIntent;
Calendar calendar;
Intent alarm;
final int SDK_INT = Build.VERSION.SDK_INT;

    calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());

alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm = new Intent(this, TestForecastService.class);
pendingIntent = PendingIntent.getService(this, 0, alarm, 0);

if (SDK_INT < Build.VERSION_CODES.KITKAT) {
    alarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+10000, pendingIntent);
    Log.d("lowerMF","hahah");
}
else if (Build.VERSION_CODES.KITKAT <= SDK_INT  && SDK_INT < Build.VERSION_CODES.M) {
    alarmManager.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+10000,pendingIntent);
    Log.d("kitkatMF","hahah");
}
else if (SDK_INT >= Build.VERSION_CODES.M) {
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+10000,pendingIntent);
    Log.d("marshmallowMF","hahah");
}

Now, TestForecastService: in which you can define your work:

public class TestForecastService extends IntentService {

    Context context;
    PowerManager powerManager;
    PowerManager.WakeLock wakeLock;
    final int SDK_INT = Build.VERSION.SDK_INT;
    AlarmManager alarmManager;
    PendingIntent pendingIntent;
    Intent alarm;

    public TestForecastService() {
        super("");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "FCFCFCFC");

        wakeLock.acquire();
        sendDATA(city);

    }

    private void sendDATA(String city) {
        try {

           ......DO YOUR DATA SENDING WORK.........

        } catch (Exception e) {
            Log.v("fserviceerror","erre");
        }

        reSETALARAM();
        wakeLock.release();
    }

    private void reSETALARAM() {
        alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        alarm = new Intent(this,TestForecastService.class);
        pendingIntent = PendingIntent.getService(this, 0, alarm, 0);

        if (SDK_INT < Build.VERSION_CODES.KITKAT) {
            alarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+10000, pendingIntent);
            Log.d("lowerFS","hahah");
        }
        else if (Build.VERSION_CODES.KITKAT <= SDK_INT  && SDK_INT < Build.VERSION_CODES.M) {
            alarmManager.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+10000,pendingIntent);
            Log.d("kitkatFS","hahah");
        }
        else if (SDK_INT >= Build.VERSION_CODES.M) {
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+10000,pendingIntent);
            Log.d("marshmallowFS","hahah");
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

Now, make BrodcastReceiver class that run your service when device restarted:

public class Auto extends BroadcastReceiver {

        final int SDK_INT = Build.VERSION.SDK_INT;

        @Override
        public void onReceive(Context ctx, Intent intent) {

                if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")){
                        AlarmManager alarmMgr = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
                        Intent intent1 = new Intent(ctx, TestForecastService.class);
                        PendingIntent alarmIntent = PendingIntent.getService(ctx, 0, intent1, 0);

                        if (SDK_INT < Build.VERSION_CODES.KITKAT) {
                                alarmMgr.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+10000, alarmIntent);
                                Log.d("lowerFB","hahah");
                        }
                        else if (Build.VERSION_CODES.KITKAT <= SDK_INT  && SDK_INT < Build.VERSION_CODES.M) {
                                alarmMgr.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+10000,alarmIntent);
                                Log.d("kitkatFB","hahah");
                        }
                        else if (SDK_INT >= Build.VERSION_CODES.M) {
                                alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+10000,alarmIntent);
                                Log.d("marshmallowFB","hahah");
                        }
                }
        }
    }

Finally, add this in Manifest file:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>

<service android:name=".TestForecastService" android:exported="true" android:enabled="true"/>
<receiver android:name=".Auto" android:exported="true" android:enabled="true" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
Divyesh Patel
  • 2,576
  • 2
  • 15
  • 30
0
import com.google.android.gms.gcm.GcmTaskService;
import com.google.android.gms.gcm.TaskParams;

import android.content.Context;
import android.content.SharedPreferences;
import android.location.Address;
import android.location.Geocoder;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.gcm.GcmNetworkManager;

import com.google.android.gms.gcm.OneoffTask;
import com.google.android.gms.gcm.PeriodicTask;
import com.google.android.gms.gcm.Task;
import java.util.List;
import java.util.Locale;


/**
 * Created by MAYURKUMAR TERAIYA on 20-09-2017.
*/

public class GCMServiceTracking extends GcmTaskService {


private static final String TAG = GCMServiceTracking.class.getSimpleName();

public static final String GCM_ONEOFF_TAG = "oneoff|[0,0]";
public static final String GCM_REPEAT_TAG = "repeat|[7200,1800]";

@Override
public void onInitializeTasks() {
//called when app is updated to a new version, reinstalled etc.
//you have to schedule your repeating tasks again
super.onInitializeTasks();
}

@Override
public int onRunTask(TaskParams taskParams) {
//do some stuff (mostly network) - executed in background thread (async)

//Toast.makeText(getApplicationContext(), "Service Executed", 
Toast.LENGTH_SHORT).show();

//obtain your data
Bundle extras = taskParams.getExtras();

Handler h = new Handler(getMainLooper());
Log.v(TAG, "onRunTask");


if (taskParams.getTag().equals(GCM_ONEOFF_TAG)) {
    h.post(new Runnable() {
        @Override
        public void run() {
            //Toast.makeText(GCMServiceTracking.this, "ONEOFF executed", 
    Toast.LENGTH_SHORT).show();
        }
    });
} else if (taskParams.getTag().equals(GCM_REPEAT_TAG)) {
    h.post(new Runnable() {
        @Override
        public void run() {
            //Toast.makeText(GCMServiceTracking.this, "REPEATING executed", 
    Toast.LENGTH_SHORT).show();

            gpsTracker = new GPSTracker(GCMServiceTracking.this);

            Toast.makeText(getApplicationContext(), "Data Syncing.", 
        Toast.LENGTH_SHORT).show();


        }
    });
}
return GcmNetworkManager.RESULT_SUCCESS;
}



public static void scheduleOneOff(Context context) {
//in this method, single OneOff task is scheduled (the target service 
that will be called is MyTaskService.class)
Bundle data = new Bundle();
data.putString("some key", "some budle data");
try {
    OneoffTask oneoff = new OneoffTask.Builder()
            //specify target service - must extend GcmTaskService
            .setService(GCMServiceTracking.class)
            //tag that is unique to this task (can be used to cancel task)
            .setTag(GCM_ONEOFF_TAG)
            //executed between 0 - 10s from now
            .setExecutionWindow(10, 10)
            //set required network state, this line is optional
            .setRequiredNetwork(Task.NETWORK_STATE_ANY)
            //request that charging must be connected, this line is optional
            .setRequiresCharging(false)
            //set some data we want to pass to our task
            .setExtras(data)
            //if another task with same tag is already scheduled, replace it 
 with this task
            .setUpdateCurrent(true)
            .build();
    GcmNetworkManager.getInstance(context).schedule(oneoff);
    Log.v(TAG, "oneoff task scheduled");
} catch (Exception e) {
    e.printStackTrace();
}
}

public static void scheduleRepeat(Context context) {
//in this method, single Repeating task is scheduled (the target service 
  that will be called is MyTaskService.class)
try {
    PeriodicTask periodic = new PeriodicTask.Builder()
            //specify target service - must extend GcmTaskService
            .setService(GCMServiceTracking.class)
            //repeat every 60 seconds
            .setPeriod(300)
            //specify how much earlier the task can be executed (in seconds)
            .setFlex(30)
            //tag that is unique to this task (can be used to cancel task)
            .setTag(GCM_REPEAT_TAG)
            //whether the task persists after device reboot
            .setPersisted(true)
            //if another task with same tag is already scheduled, replace it 
        with this task
            .setUpdateCurrent(true)
            //set required network state, this line is optional
            .setRequiredNetwork(Task.NETWORK_STATE_ANY)
            //request that charging must be connected, this line is optional
            .setRequiresCharging(false)
            .build();
    GcmNetworkManager.getInstance(context).schedule(periodic);
    Log.v(TAG, "repeating task scheduled");
} catch (Exception e) {
    Log.e(TAG, "scheduling failed");
    e.printStackTrace();
}
}

public static void cancelOneOff(Context context) {
GcmNetworkManager
        .getInstance(context)
        .cancelTask(GCM_ONEOFF_TAG, GCMServiceTracking.class);
}

public static void cancelRepeat(Context context) {
GcmNetworkManager

    .getInstance(context)
        .cancelTask(GCM_REPEAT_TAG, GCMServiceTracking.class);
}

public static void cancelAll(Context context) {
 GcmNetworkManager
        .getInstance(context)
        .cancelAllTasks(GCMServiceTracking.class);
}


// CODE FOR START BACKGROUND TASK

GoogleApiAvailability api = GoogleApiAvailability.getInstance();
Int errorCheck = api.isGooglePlayServicesAvailable(LoginActivity.this);

       if(errorCheck == ConnectionResult.SUCCESS) {
                //google play services available, hooray
            } else if(api.isUserResolvableError(errorCheck)) {
                //GPS_REQUEST_CODE = 1000, and is used in onActivityResult
                api.showErrorDialogFragment(LoginActivity.this, errorCheck, 
     GPS_REQUEST_CODE);
                //stop our activity initialization code
                return;
            } else {
                //GPS not available, user cannot resolve this error
                //todo: somehow inform user or fallback to different 
              method
                //stop our activity initialization code
                return;
 }

 GCMServiceTracking.scheduleRepeat(LoginActivity.this);

GRADLE FILE
compile 'com.google.android.gms:play-services:8.3.0'

MENIFEST FILE

<service
android:name=".services.GCMServiceTracking"
android:exported="true" 
android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVIC>
    <intent-filter>
        <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>
    </intent-filter>
</service>
Teraiya Mayur
  • 1,094
  • 10
  • 18