Rx Java Subscriber永远不会从位置更新中获取onNext事件

时间:2016-09-19 17:11:55

标签: java android location rx-java rx-android

我正在尝试使用此库:https://android-arsenal.com/details/1/3291来获取用户的位置。我做了我认为样本显示的所有内容,但我的Observable / Subscriber永远不会触发。

这是我的活动:

public class GpsActivity extends AppCompatActivity/* implements LocationListener*/ {

final android.location.Location[] lastKnown = new android.location.Location[2];
LocationManager manager;
boolean exitLoop = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.no_gps);
    ButterKnife.bind(this);
    manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    getLocation();
}

private void getLocation() {
    //TODO zmienić UI
    boolean gpsPermission = checkPermissions();
    if (!gpsPermission) {
        Log.d(getClass().getSimpleName(), "No GPS permissions!");

        //TODO Handle permissions result
        requestPemissions();
        return;
    }
    boolean gpsEnabled = checkSettings();
    if (!gpsEnabled) {
        Log.d(getClass().getSimpleName(), "GPS not enabled!");

        //TODO Handle settings result
        buildAlertMessageNoGps();
        return;
    }
    subscribeForLocation(25f, this);

}

private void requestPemissions() {
    Log.d(getClass().getSimpleName(), "Requesting permissions...");

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, IntentHelper.PERMISSION_GPS);
    }

    Log.d(getClass().getSimpleName(), "Done.");

}

private boolean checkSettings() {
    Log.d(getClass().getSimpleName(), "Checking settings...");
    return !manager.isProviderEnabled(LocationManager.GPS_PROVIDER);

}

private boolean checkPermissions() {
    Log.d(getClass().getSimpleName(), "Checking permissions...");
    return ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}

private void buildAlertMessageNoGps() {
    Log.d(getClass().getSimpleName(), "Showing GPS settings alert...");

    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Your GPS seems to be disabled, do you want to enable it?")
            .setCancelable(false)
            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                    startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), IntentHelper.GPS_SETTINGS);
                }
            })
            .setNegativeButton("No", new DialogInterface.OnClickListener() {
                public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
                    dialog.cancel();
                }
            });
    final AlertDialog alert = builder.create();
    alert.show();
}


public void subscribeForLocation(float accuracy, final Context context) {
    Log.d(getClass().getSimpleName(), "Subscribing for updates...");

    final LocationRequestBuilder locationRequestBuilder = new LocationRequestBuilder(this);

    locationRequestBuilder.addLastLocation(LocationManager.GPS_PROVIDER, new LocationTime(30, TimeUnit.SECONDS), false)
            .addRequestLocation(LocationManager.GPS_PROVIDER, new LocationTime(10, TimeUnit.SECONDS))
            .create().subscribe(new Subscriber<android.location.Location>() {
        @Override
        public void onCompleted() {
            saveLocation();
        }

        @Override
        public void onError(Throwable e) {
            Log.d(getClass().getSimpleName(), e.toString());
        }

        @Override
        public void onNext(android.location.Location location) {
            final String name = Thread.currentThread().getName();
            Log.d(getClass().getSimpleName(), location != null ? location.toString() : "Location is empty =(");
        }
    });
}

我从日志中获得的输出是:

 D/GpsActivity: Checking permissions...
 D/GpsActivity: Checking settings...
 D/GpsActivity: Subscribing for updates...

然后它只是坐在那里什么都不做。这是我第一次使用Rx,所以不确定在这种情况下应该做些什么。

1 个答案:

答案 0 :(得分:0)

首先,如果声明你有错误 - 双重否定。

boolean gpsEnabled = checkSettings();
if (!gpsEnabled) {
    Log.d(getClass().getSimpleName(), "GPS not enabled!");

    //TODO Handle settings result
    buildAlertMessageNoGps();
    return;
}

请记住,订阅后您将只收到一个结果,因为observable会在第一次收到位置后发出onCompleted,因为:

return result.firstOrDefault(defaultLocation)
            .observeOn(scheduler);

请注意,在用户授予权限后不会发生任何事情,因为如果未授予权限,则您正在执行“返回”功能。您可以通过覆盖以下方法授予权限后处理订阅:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

取决于您的需求,您可能希望不断收到有关当前位置的通知。其中一个解决方案是简单地修改您正在使用的库(更优选的解决方案)和“修复”Observable发出的onCompleted事件。另一种方式是订阅每个时间段:

Observable.interval(5, TimeUnit.SECONDS)
        .compose(this.<Long>bindToLifecycle()) //google rx trello github
        .subscribe(new Action1<Long>() {
               @Override
               public void call(Long aLong) {
                     subscribeForLocation(25f, GpsActivity.this);
               }
        });