使用locationListener切换到加载器

时间:2018-09-28 14:01:20

标签: java android loader locationlistener

我正在上一本Udacity Android基础课程,并试图更改我的应用程序以使用Loader而不是AsyncTask。我的应用程序使用locationListener生成一个自定义URL,然后将其传递给加载程序,加载程序调用ChargePointLoader类,该类将初始化HTTP请求并返回chargePoints列表,加载后应填充适配器。

但是我的屏幕上什么也没有出现。我的加载器顺序是否错误,或者locationListener干扰了加载器?感谢您的帮助

以下是旧的异步项目的链接:https://github.com/Kovah101/ChargeMyCarBareBones/blob/master/app/src/main/java/com/example/android/chargemycar/MainActivity.java

这是我的主要活动

public class MainActivity extends AppCompatActivity implements LoaderCallbacks<List<ChargePoint>> {

public static final String LOG_TAG = MainActivity.class.getName();

public static double myLat;
public static double myLong;

private static  String ChargePoint_REQUEST_URL = "http://chargepoints.dft.gov.uk/api/retrieve/registry/postcode/SW15+5QS/dist/7/format/json/limit/10";

private ChargePointAdapter adapter;

private LocationManager locationManager;
private LocationListener locationListener;

private static final int CHARGEPOINT_LOADER_ID = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Find a reference to the {@link ListView} in the layout
   final ListView chargePointListView = (ListView) findViewById(R.id.list);

    // Create a ChargingPointAdapter, whose data source is a list of ChargePoints, which creates listview items for each item
    adapter = new ChargePointAdapter(this, new ArrayList<ChargePoint>());

    //possible error with order of loaders or inside listener
    final LoaderManager loaderManager = getLoaderManager();

    locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
    locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            //set lat & long variables
            myLat = location.getLatitude();
            myLong = location.getLongitude();
            String myLatString = Double.toString(myLat);
            String myLongString = Double.toString(myLong);

            //test with toast
            Context context = getApplicationContext();
            CharSequence text = " my latitude=" +myLatString +"\nmy longitude=" +myLongString ;
            int duration = Toast.LENGTH_LONG;
            Toast toast = Toast.makeText(context, text, duration);
            toast.show();

            //create request URL using live location
            ChargePoint_REQUEST_URL = "http://chargepoints.dft.gov.uk/api/retrieve/registry/lat/" +myLat + "/long/" +myLong +"/dist/10/format/json/limit/10";

            // Set the adapter on the {@link ListView}
            // so the list can be populated in the user interface
            chargePointListView.setAdapter(adapter);


            loaderManager.initLoader(CHARGEPOINT_LOADER_ID, null, MainActivity.this );

        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }

        @Override
        public void onProviderEnabled(String provider) {
        }

        @Override
        public void onProviderDisabled(String provider) {
        }
    };


    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, 1);
    }else{
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 100, locationListener);
        //time in milliseconds
        //distance in meters
    }

    // On click take to maps
    chargePointListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String myLatString = Double.toString(myLat);
            String myLongString = Double.toString(myLong);

            ChargePoint currentChargePoint = (ChargePoint) chargePointListView.getItemAtPosition(position);
            double destinationLatitude = currentChargePoint.getLatitude();
            double destinationLongitude = currentChargePoint.getLongitude();
            String destLatString = Double.toString(destinationLatitude);
            String destLongString = Double.toString(destinationLongitude);


            //create uri for map intent
            String url = "http://maps.google.com/maps?saddr="+myLatString+","+myLongString+"&daddr="+destLatString+","+destLongString+"&travelmode=driving";
            Intent mapIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(url));
                mapIntent.setPackage("com.google.android.apps.maps");
                if (mapIntent.resolveActivity(getPackageManager()) != null) {
                    startActivity(mapIntent);
                }
        }
    });


}

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

    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED){
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 25, locationListener);
            //time in ms, distance in meters
        }
    }
}

@Override
public Loader<List<ChargePoint>> onCreateLoader(int i, Bundle bundle) {
    return new ChargePointLoader(this, ChargePoint_REQUEST_URL);
}

@Override
public void onLoadFinished(Loader<List<ChargePoint>> loader, List<ChargePoint> chargePoints) {
    // Clear the adapter of previous data
    adapter.clear();
    //check for null charge point list, return early if that is the case, if there is a valid list then add to the adapter
    if (chargePoints != null && !chargePoints.isEmpty()){
        adapter.addAll(chargePoints);
    }
}

@Override
public void onLoaderReset(Loader<List<ChargePoint>> loader) {
    // TODO: Loader reset, so we can clear out our existing data.
    adapter.clear();
}

}

1 个答案:

答案 0 :(得分:0)

现在不建议使用加载程序,将Android体系结构组件(LiveData和ViewModel)与旧的AsyncTask结合使用。它比装载机更有效,更快,更清洁。这也使您的AsyncTask具有生命周期意识。从某种意义上说具有生命周期意识,无论您调用onCreate()多少次,都不会在一次之后再次提出网络请求,因为它会自动缓存下载的数据。配置更改不会影响您的应用。有关将AsyncTask与LiveData和ViewModel结合使用的更多信息,请访问https://medium.com/androiddevelopers/lifecycle-aware-data-loading-with-android-architecture-components-f95484159de4