我想让服务器每隔30分钟更新一次位置,安卓

问题描述 投票:0回答:1

我正在尝试在服务器上发送用户位置。但当应用程序处于后台时,我无法每30分钟获取一次位置。

/在主活动中调用

PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(MyWorker.class, 30, TimeUnit.MINUTES)
                                .addTag(TAG)
                                .build();

WorkManager.getInstance().enqueueUniquePeriodicWork("Location", ExistingPeriodicWorkPolicy.REPLACE, periodicWork);

/工人阶级

public class MyWorker extends Worker {
private static final String DEFAULT_START_TIME = "00:00";
private static final String DEFAULT_END_TIME = "30:00";

private static final String TAG = "MyWorker";

/**
 * The desired interval for location updates. Inexact. Updates may be more or less frequent.
 */
private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;

/**
 * The fastest rate for active location updates. Updates will never be more frequent
 * than this value.
 */
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
        UPDATE_INTERVAL_IN_MILLISECONDS / 2;
/**
 * The current location.
 */
private Location mLocation;

/**
 * Provides access to the Fused Location Provider API.
 */
private FusedLocationProviderClient mFusedLocationClient;

private Context mContext;
/**
 * Callback for changes in location.
 */
private LocationCallback mLocationCallback;

public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
    super(context, workerParams);
    mContext = context;
}

@NonNull
@Override
public Result doWork() {

    LocationDAO locationDAO = Room.databaseBuilder(mContext, AppDatabase.class, "db-locations")
            .allowMainThreadQueries()   //Allows room to do operation on main thread
            .build()
            .getLocationDAO();
    Log.d(TAG, "doWork: Done");

    Log.d(TAG, "onStartJob: STARTING JOB..");

    DateFormat dateFormat = new SimpleDateFormat("HH:mm", Locale.getDefault());

    Calendar c = Calendar.getInstance();
    Date date = c.getTime();
    String formattedDate = dateFormat.format(date);

    try {
        Date currentDate = dateFormat.parse(formattedDate);
        Date startDate = dateFormat.parse(DEFAULT_START_TIME);
        Date endDate = dateFormat.parse(DEFAULT_END_TIME);

        if (currentDate.after(startDate) && currentDate.before(endDate)) {
            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(mContext);
            mLocationCallback = new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {
                    super.onLocationResult(locationResult);
                }
            };

            LocationRequest mLocationRequest = new LocationRequest();
            mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
            mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

            try {
                mFusedLocationClient
                        .getLastLocation()
                        .addOnCompleteListener(new OnCompleteListener<Location>() {
                            @Override
                            public void onComplete(@NonNull Task<Location> task) {
                                Log.d(TAG, "Location : " + task.getResult());

                                if (task.isSuccessful() && task.getResult() != null) {
                                    mLocation = task.getResult();
                                    Log.d(TAG, "Location : " + mLocation);

                                    Date today = new Date();
                                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a");
                                    String dateToStr = format.format(today);

                                    LocationModel locationModel =new LocationModel();
                                    locationModel.setLat(String.valueOf(mLocation.getLatitude()));
                                    locationModel.setLng(String.valueOf(mLocation.getLongitude()));
                                    locationModel.setDateToStr(dateToStr);

                                    //locationDAO.insert(locationModel);
                                    SaveTask st = new SaveTask(locationModel);
                                    st.execute();

                                     //Create the NotificationChannel, but only on API 26+ because
                                    // the NotificationChannel class is new and not in the support library
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                        CharSequence name = mContext.getString(R.string.app_name);
                                        String description = mContext.getString(R.string.app_name);
                                        int importance = NotificationManager.IMPORTANCE_DEFAULT;
                                        NotificationChannel channel = new NotificationChannel(mContext.getString(R.string.app_name), name, importance);
                                        channel.setDescription(description);
                                        // Register the channel with the system; you can't change the importance
                                        // or other notification behaviors after this
                                        NotificationManager notificationManager = mContext.getSystemService(NotificationManager.class);
                                        notificationManager.createNotificationChannel(channel);
                                    }

                                    NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, mContext.getString(R.string.app_name))
                                            .setSmallIcon(android.R.drawable.ic_menu_mylocation)
                                            .setContentTitle("New Location Update")
                                            .setContentText("You are at " + getCompleteAddressString(mLocation.getLatitude(), mLocation.getLongitude()))
                                            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                                            .setStyle(new NotificationCompat.BigTextStyle().bigText("You are at " + getCompleteAddressString(mLocation.getLatitude(), mLocation.getLongitude())));

                                    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mContext);

                                    // notificationId is a unique int for each notification that you must define
                                    notificationManager.notify(1001, builder.build());

                                    mFusedLocationClient.removeLocationUpdates(mLocationCallback);
                                } else {
                                    Log.w(TAG, "Failed to get location.");
                                    //Toast.makeText(mContext, "Failed to get location.", Toast.LENGTH_LONG ).show();

                                }
                            }
                        });
            } catch (SecurityException unlikely) {
                Log.e(TAG, "Lost location permission." + unlikely);
            }

            try {
                mFusedLocationClient.requestLocationUpdates(mLocationRequest, null);
            } catch (SecurityException unlikely) {
                //Utils.setRequestingLocationUpdates(this, false);
                Log.e(TAG, "Lost location permission. Could not request updates. " + unlikely);
            }
        } else {
            Log.d(TAG, "Time up to get location. Your time is : " + DEFAULT_START_TIME + " to " + DEFAULT_END_TIME);
        }
    } catch (ParseException ignored) {

    }

    return Result.success();
}

private String getCompleteAddressString(double LATITUDE, double LONGITUDE) {
    String strAdd = "";
    Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
    try {
        List<Address> addresses = geocoder.getFromLocation(LATITUDE, LONGITUDE, 1);
        if (addresses != null) {
            Address returnedAddress = addresses.get(0);
            StringBuilder strReturnedAddress = new StringBuilder();

            for (int i = 0; i <= returnedAddress.getMaxAddressLineIndex(); i++) {
                strReturnedAddress.append(returnedAddress.getAddressLine(i)).append("\n");
            }
            strAdd = strReturnedAddress.toString();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return strAdd;
}

class SaveTask extends AsyncTask<Void, Void, Void> {
    LocationModel locationModel;
    public SaveTask(LocationModel locationModel) {
        this.locationModel = locationModel;
    }

    @Override
    protected Void doInBackground(Void... voids) {

        DatabaseClient.getInstance(getApplicationContext()).getAppDatabase()
                .getLocationDAO()
                .insert(locationModel);
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);

    }
}

}

/ 从数据库中获取数据

public class GetTasks extends AsyncTask<Void, Void, List<LocationModel>> {

    Context mContext;
    String requestType;

    public GetTasks(Context context, String requestType) {
        this.mContext = context;
        this.requestType =requestType;
    }

    @Override
    protected List<LocationModel> doInBackground(Void... voids) {
        List<LocationModel> taskList = DatabaseClient
                .getInstance(mContext)
                .getAppDatabase()
                .getLocationDAO().getLocation();

        return taskList;
    }

    @Override
    protected void onPostExecute(List<LocationModel> tasks) {
        super.onPostExecute(tasks);


        if (tasks.size()>0) {

            LocationPostReg locationPostReg = new LocationPostReg();
            updateLocationValue(locationPostReg);
        }
    }
    public static String convertObjToString(Object clsObj) {
        //convert object  to string json
        String jsonSender = new Gson().toJson(clsObj, new TypeToken<Object>() {
        }.getType());
        return jsonSender;
    }

/ 向服务器发送数据

public void updateLocationValue(LocationPostReg locationPostReg){
        locationUpdateInterface apiService =
                ApiClient.getClient().create(locationUpdateInterface.class);




        String locationStr = convertObjToString(locationPostReg);

        RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),locationStr);

        Log.d(TAG, locationStr +"   "+ locationPostReg.getUserid()   +"  ");
        Call<LocationSuccessfull> call = apiService.doUpdateLocation(body);
        call.enqueue(new Callback<LocationSuccessfull>() {
            @Override
            public void onResponse(Call<LocationSuccessfull> call, Response<LocationSuccessfull> response) {
                int statusCode = response.code();
                LocationSuccessfull locationInfo = response.body();

                // assert locationInfo != null;
                if (locationInfo != null && locationInfo.getSuccess())
                {
                    AsyncTask.execute(() ->
                            DatabaseClient
                                    .getInstance(mContext)
                                    .getAppDatabase()
                                    .getLocationDAO().deleteAll()
                            );
                    Print.e(TAG+ " Remove Data");


                }

            }

            @Override
            public void onFailure(Call<LocationSuccessfull> call, Throwable t) {
                // Log error here since request failed
                Log.e(TAG, "error:  "+ t.toString());
            }
        });
    }
android service location
1个回答
0
投票

有限制的请求位置频繁从后台你可以在这里阅读主题。https:/developer.android.comaboutversionsoreobackground-location-limitstext。

对于频繁地从后台请求,你将不得不把你的应用程序带到前台,一个方法是启动服务作为前台服务,并使用通知,这样用户就会知道你的应用程序在前台工作,或者你可以使用访问服务,但用户将需要自己启用该permmision(你不能从你的应用程序请求该permmision)。

这是一个持久化通知的例子,它将使你的应用程序进入前台。

    fun CreateNotification(str:String,id:Int){
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
            var serviceChannel = NotificationChannel(CHANNEL_ID,"name",NotificationManager.IMPORTANCE_HIGH)
            var notificationManager= getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(serviceChannel)
        }
        var intent = Intent(this, MainActivity::class.java)
        var pendingIntent =PendingIntent.getActivity(this,0, intent,0)
        var stopIntent = Intent(this,CloseBackgroundServiceBroadCast::class.java)
        stopIntent.action= CloseBackgroundServiceBroadCast.CLOSE_BACKGROUND_LISTENTER_ACTION

        var pendingStop = PendingIntent.getBroadcast(this,30,stopIntent,0)
        var notification = NotificationCompat.Builder(this,CHANNEL_ID)
            .setContentTitle("title")
            .setContentText(str)
            .setSmallIcon(yourIcon)
            //   .addAction(com.example.autogater.R.drawable.dismiss_test,"Stop")
            .addAction(R.drawable.ic_menu_search,getString(com.callgate.autogater.R.string.stop),pendingStop)

            .setContentIntent(pendingIntent).build()

        //   notificationManager.notify(0,notification)
        startForeground(1,notification)
    }
© www.soinside.com 2019 - 2024. All rights reserved.