我正在尝试每15分钟将电话的位置发送到Firestore。
我当时在看Android中的工作程序,但是我阅读的代码无法正常工作,因为它们是同步的,并且我正在调用异步方法来调用firestore。
此外,我在工作人员内部遇到的竞赛是MultiDexApplication
类型,并且在调用mFusedLocationClient.getLastLocation()
时会抛出异常
这里是我工人的代码。
public class LocationWorker extends Worker {
private final static String TAG = "LocationWorker";
private FusedLocationProviderClient mFusedLocationClient;
private Context mApplicationContext;
private FirebaseFirestore mFireStoreRef;
private String mCurrentUserID;
public LocationWorker(@NonNull Context context, @NonNull WorkerParameters params) {
super(context, params);
mApplicationContext = getApplicationContext();
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(mApplicationContext);
mFireStoreRef = FirebaseFirestore.getInstance();
mCurrentUserID = "Patrick";
}
@NonNull
@Override
public Result doWork() {
mFusedLocationClient.getLastLocation()
.addOnSuccessListener((Activity) mApplicationContext, new OnSuccessListener<Location>() {
@Override
public void onSuccess(final Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
mFireStoreRef
.collection("locations")
.document(mCurrentUserID)
.collection(DateFormat.getDateTimeInstance().format(new Date()))
.add(location)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
@Override
public void onSuccess(DocumentReference documentReference) {
Log.d(TAG, "Location added: " + location.toString());
}
});
}
}
});
return Result.success();
}
}
我知道无法在worker内部进行异步调用。但是,我想知道如何每15分钟获得一次电话的位置以发送到Firestore?
[有一个上下文传递到Worker的构造函数中。如果您担心直接使用它,可以尝试将其存储在WeakReference中。
使用ListenableWorker时,线程取决于您。此示例在为新线程创建的Runnable内部运行所有内容,但是如果它更适合您,则可以选择其他策略:
public class MyWorker extends ListenableWorker{
private Context mContext;
private FirebaseFirestore mDb;
public MyWorker(Context context, WorkerParameters params){
super(context, params);
mContext = context; // Store the context passed into the worker
mDb = FirebaseFirestore.getInstance();
}
@NonNull
@Override
public ListenableFuture<Result> startWork(){
return CallbackToFutureAdapter.getFuture(new CallbackToFutureAdapter.Resolver<Result>() {
@Nullable
@Override
public Object attachCompleter(@NonNull final CallbackToFutureAdapter.Completer<Result> completer)
throws Exception {
Runnable runnable = new Runnable() {
@Override
public void run() {
OnCompleteListener<DocumentReference> completeListener = new OnCompleteListener<DocumentReference>() {
@Override
public void onComplete(@NonNull Task<DocumentReference> task) {
if(task.isSuccessful()){
// ...
completer.set(Result.success());
}else{
// Whether you return failure or retry here
// depends on what makes the most sense for your situation
completer.set(Result.failure());
}
}
};
Map<String, Object> data = new HashMap<>();
data.put("some_data", someData);
mDb.collection("myCollection")
.add(data)
.addOnCompleteListener(completeListener);
}
};
new Thread(runnable).start();
return runnable;
}
}
}
}