Я пытаюсь отправить местоположение пользователя на сервере. Я быстро получаю местоположение и сохраняю в RoomDatabase и получаю данные из RoomDatabase, отправляемые на сервер. но я не могу получать данные о местоположении каждые 30 минут, когда приложение работает в фоновом режиме.
// Вызов в режиме mainactivity
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());
}
});
}