0

即使应用程序在后台,我也需要连续向服务器发送数据(比如每 x 秒或分钟后)。我知道服务是最好的选择。因为我从未尝试过这种情况,有没有关于如何制作的方便示例来自服务的 Web 服务调用,然后在传递对活动的响应(无论数据是否成功)之后。任何方法或其他方式来实现这一点。任何帮助表示赞赏。

4

2 回答 2

0

首先在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");
}

现在,TestForecastService: 你可以在其中定义你的工作:

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();
    }
}

现在,让 BrodcastReceiver 类在设备重新启动时运行您的服务:

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");
                        }
                }
        }
    }

最后,在 Manifest 文件中添加:

    <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>
于 2016-12-09T13:23:25.783 回答
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>
于 2017-09-21T06:44:55.533 回答