将数据发送到Android中工作人员内部的Firestore中

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

我正在尝试每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?

android firebase google-cloud-firestore androidx android-workmanager
1个回答
0
投票

[有一个上下文传递到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;
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.