I am trying to get location a update it in server in every 30 minutes android

强颜欢笑 提交于 2020-07-23 06:01:30

问题


I am trying to send user location in server. Fast i get the location and save in RoomDatabase and get data from RoomDatabase send to server. but i can't get location every 30 minutes when app in background.

//Calling in mainactivity

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

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

// worker class

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

    }
}

}

// get data form database

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

// send data to server

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

回答1:


there are limits on requesting location frequently from the background you can read theme here https://developer.android.com/about/versions/oreo/background-location-limitstext

for requesting from the background frequently, you will have to bring your app to the foreground, a way to do so is to start the service as foreground service and use notification so that the user will know that your app is working on the foreground, or you can use an accessbility service but the user will need to enable that permmision himself (you cant request that permmision from your app)

this is an example of persistence notification that will bring your app to the foreground

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


来源:https://stackoverflow.com/questions/61672347/i-am-trying-to-get-location-a-update-it-in-server-in-every-30-minutes-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!