Итак, после долгой борьбы я разобрался с некоторыми своими проблемами.Я поделюсь своим кодом и объясню (насколько мне известно), что я делал неправильно и как я решил это для тех из вас, кто может пытаться сделать что-то подобное.
Во-первых, мой код местоположения!
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.annotation.RequiresPermission;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.Task;
import com.google.android.libraries.places.api.model.Place;
import com.google.android.libraries.places.api.model.PlaceLikelihood;
import com.google.android.libraries.places.api.net.FindCurrentPlaceRequest;
import com.google.android.libraries.places.api.net.FindCurrentPlaceResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.Manifest.permission.ACCESS_WIFI_STATE;
import static com.bettertime.MainActivity.placesClient;
public class BetterLocation {
private List<Place.Field> placeList = new ArrayList<>();
private static String TAG = "Location: ";
public static Map<String, Object> places = new HashMap<>();
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_WIFI_STATE
};
public void findCurrentPlace(Context context, Activity activity) {
if(ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, ACCESS_WIFI_STATE) == PackageManager.PERMISSION_GRANTED) {
findCurrentPlaceWithPermissions(context);
}
else {
ActivityCompat.requestPermissions(activity, PERMISSIONS, PERMISSION_ALL);
}
}
@RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
public void findCurrentPlaceWithPermissions(Context context) {
placeList.add(Place.Field.NAME);
placeList.add(Place.Field.ADDRESS);
placeList.add(Place.Field.LAT_LNG);
placeList.add(Place.Field.TYPES);
FindCurrentPlaceRequest currentPlaceRequest =
FindCurrentPlaceRequest.builder(placeList).build();
if(ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, ACCESS_WIFI_STATE) == PackageManager.PERMISSION_GRANTED) {
Task<FindCurrentPlaceResponse> currentPlaceTask =
placesClient.findCurrentPlace(currentPlaceRequest);
currentPlaceTask.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
places.clear();
FindCurrentPlaceResponse response = task.getResult();
assert response != null;
for (PlaceLikelihood placeLikelihood : response.getPlaceLikelihoods()) {
Log.d(TAG, "findCurrentPlace: "
+ placeLikelihood.getPlace().getName() + "\n"
+ placeLikelihood.getPlace().getAddress() + "\n"
+ placeLikelihood.getPlace().getLatLng() + "\n"
+ placeLikelihood.getPlace().getTypes() + "\n"
+ placeLikelihood.getLikelihood());
PlaceObj placeObj = new PlaceObj(
placeLikelihood.getPlace().getName(),
placeLikelihood.getPlace().getAddress(),
placeLikelihood.getPlace().getLatLng(),
placeLikelihood.getPlace().getTypes(),
placeLikelihood.getLikelihood());
places.put(placeObj.Name, placeObj);
}
} else {
Exception exception = task.getException();
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
Log.e(TAG, "findCurrentPlaceWithPermissions: " + apiException.getStatusCode() + apiException.getLocalizedMessage());
}
}
});
}
}
}
До: Я использовал этот класс в качестве AppCompatActivity, который испортил объекты контекста и действия, которые я передавал методам.
После: Я изменил метод, чтобы включить действие и контекст.Я проверил это в своей функции MainActivity, передав ей контекст и действие MainActivity, и это сработало!
Далее мои прослушиваемые рабочие / классы потоков!
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.util.Log;
import com.bettertime.MainActivity;
import com.bettertime.betterLocation.BetterLocation;
import com.bettertime.packages.NativeUsageEvents;
import com.bettertime.timePackage.NativeTime;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import com.google.firebase.firestore.FirebaseFirestore;
import java.util.HashMap;
import java.util.Map;
import androidx.work.ListenableWorker;
import androidx.work.WorkerParameters;
import static com.bettertime.betterLocation.BetterLocation.places;
class LocThread implements Runnable {
public static LocThread sInstance;
public static LocThread getInstance(Context context) {
if (sInstance == null) {
//Always pass in the Application Context
sInstance = new LocThread(context.getApplicationContext());
}
return sInstance;
}
private Context mContext;
public LocThread(Context context) {
mContext = context;
}
private BetterLocation betterLocation = new BetterLocation();
private Activity activity = new MainActivity().mActivity;
private String TAG = "LocThread: ";
@Override
public void run() {
try {
Looper.prepare();
betterLocation.findCurrentPlace(mContext, activity);
Looper.loop();
} catch (NullPointerException e) {
Log.d(TAG, "run: " + e.getLocalizedMessage());
}
}
}
public class FitPlaceWorker extends ListenableWorker {
private static final String TAG = "FitPlace Worker: ";
private Thread locThread;
public FitPlaceWorker(Context context, WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public ListenableFuture<Result> startWork(){
SettableFuture<Result> result = SettableFuture.create();
Log.d(TAG, "doWork - FitPlace fired");
fitPlaceStamp();
result.set(Result.success());
return result;
}
private void fitPlaceStamp(){
locThread = new Thread(new LocThread(getApplicationContext()));
locThread.start();
//log methods
Log.d(TAG, "placeData: " + places.toString());
}
}
До этого: Честно говоря, очень мало знал о многопоточности Android, поэтому я не уверен, что я делал в примере с вопросом.
После: Однажды, потратив некоторое время на изучение потоков, я понял, как создать свой собственный класс Thread.Я использую контекстную оболочку для захвата контекста и использую действие MainActivity для перехода в мой метод.Следующим шагом было внедрение ListenableWorker вместо базового Worker, который позволяет вам обрабатывать собственные потоки и иметь возможность запускать асинхронные задачи.Я вытащил некоторый код, чтобы сделать его немного более универсальным, чтобы он мог быть немного странным, но после тестирования я смог записать ответ Google Места на logcat всякий раз, когда рабочий увольнялся!У меня есть некоторые небольшие изгибы, чтобы работать, но, кажется, работает довольно хорошо!
Пожалуйста, дайте мне знать, если это может быть улучшено, или если у вас есть более глубокое понимание и, возможно, может объяснить лучше.