没有在设备上调用android onlocationchanged

时间:2016-05-20 17:25:40

标签: java android gps google-play-services

我正在使用谷歌播放服务为我正在制作的正在运行的应用程序。我遇到的问题是没有调用onlocationchanged。首先,虽然这是Android设备无法正常工作,但经过GPS测试测试后,设备似乎正常运行。所以一定是我的代码。 Onlocationchanged只是没有被gps_provider调用,但是当我使用network_provider时它正在运行,但更新速度非常慢且准确无法用它构建运动跑步者应用程序。

这是我的代码,我该怎么做才能解决这个问题?

这是我的清单

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="com.befitdonate.befitdonate.permission.MAPS_RECEIVE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_GPS" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />  

这是我用来跟踪地图上用户路线的片段。

public class WorkoutActivity extends Fragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener, LocationListener {


    private static String TAG = WorkoutActivity.class.getSimpleName();

    private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;

    private LocationRequest mLocationRequest;

    MapView mapView;
    GoogleMap map;
    private GoogleApiClient mGoogleApiClient;

    private SharedPreferences preferenceSettings;
    private SharedPreferences.Editor preferenceEditor;
    private static final int PREFERENCE_MODE_PRIVATE = 0;
    private static final String PREF_NAME = "UserDetails";

    public static final String POST_USEREMAIL = "username";

    MainActivity mainactivity;

    String emailUser, workoutType;

    Button stopWorkout, startWorkout;

    TextView speed, info;

    ImageView workoutImage;

    LinearLayout mapLayout, startWorkoutLayout;

    Double currentLat, currentLong;

    Double Lat, Longi;
    String latLong = "No Location Found!!!";
    LocationManager lManager;

    final private int REQUEST_CODE_ASK_PERMISSIONS = 123;

    //counter that is incremented every time a new position is received, used to calculate average speed
    int counter = 0;

    //objects to store values for current and average speed
    protected double currentSpeed;
    protected double kmphSpeed;
    protected double avgSpeed;
    protected double avgKmph;
    protected double totalSpeed;
    protected double totalKmph;

    ArrayList<LatLng> polylines;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        preferenceSettings = this.getActivity().getSharedPreferences(PREF_NAME, PREFERENCE_MODE_PRIVATE);
        preferenceEditor = preferenceSettings.edit();
        emailUser = preferenceSettings.getString("Email", null);

        Log.d("Saved user email:", "" + emailUser);

        Bundle bundle = this.getArguments();
        if (bundle != null) {

            workoutType = bundle.getString("workoutType");

        }


        mGoogleApiClient = new GoogleApiClient.Builder(this.getActivity())
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        // Create the LocationRequest object
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(1 * 1000)        // 5 seconds, in milliseconds
                .setFastestInterval(1 * 1000); // 1 second, in milliseconds


    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_workout, container, false);

        mapView = (MapView) view.findViewById(R.id.mapview);
        stopWorkout = (Button) view.findViewById(R.id.stopWorkout);
        startWorkout = (Button) view.findViewById(R.id.startWorkout);
        startWorkoutLayout = (LinearLayout) view.findViewById(R.id.startWorkoutLayout);
        mapLayout = (LinearLayout) view.findViewById(R.id.mapLayout);
        workoutImage = (ImageView) view.findViewById(R.id.workoutImage);

        speed = (TextView) view.findViewById(R.id.speed);
        info = (TextView) view.findViewById(R.id.info);

        mapView.onCreate(savedInstanceState);

        mainactivity = (MainActivity )getActivity();

        mainactivity.menuButton.setVisibility(View.GONE);
        mainactivity.mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        mainactivity.pageTitle.setText("Workout");

        mapLayout.setVisibility(View.GONE);

        polylines = new ArrayList<LatLng>();

        // Gets to GoogleMap from the MapView and does initialization stuff
        map = mapView.getMap();
        map.getUiSettings().setMyLocationButtonEnabled(false);
        map.setMyLocationEnabled(true);

        // Needs to call MapsInitializer before doing any CameraUpdateFactory calls
        MapsInitializer.initialize(this.getActivity());


        stopWorkout.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                selectOption();
            }
        });

        workoutType = "walking";

        startWorkout.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                mapLayout.setVisibility(View.VISIBLE);
                startWorkoutLayout.setVisibility(View.GONE);
            }
        });

        if(workoutType.matches("running")){

            Picasso.with(this.getActivity())
                    .load(R.drawable.newrun)
                    .fit()
                    .centerCrop()
                    .into(workoutImage);
        }

        if(workoutType.matches("cycling")){

            Picasso.with(this.getActivity())
                    .load(R.drawable.newcycling)
                    .fit()
                    .centerCrop()
                    .into(workoutImage);
        }

        if(workoutType.matches("walking")){

            Picasso.with(this.getActivity())
                    .load(R.drawable.newwalk)
                    .fit()
                    .centerCrop()
                    .into(workoutImage);
        }






        return view;

    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        mainactivity.mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);

        if (mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            mGoogleApiClient.disconnect();
        }

    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }

    @Override
    public void onResume() {
        super.onResume();
        setUpMapIfNeeded();
        mapView.onResume();
        mGoogleApiClient.connect();
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        //DO WHATEVER YOU WANT WITH GOOGLEMAP
        map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        map.setMyLocationEnabled(false);
        map.setTrafficEnabled(false);
        map.setIndoorEnabled(true);
        map.setBuildingsEnabled(true);
        map.getUiSettings().setZoomControlsEnabled(true);
    }


    @Override
    public void onLocationChanged(Location location) {
        // TODO Auto-generated method stub

        Log.d(TAG, "Location update running");

        handleNewLocation(location);
    }



    public void selectOption() {
        final CharSequence[] items = { "Workout Opslaan", "Afbreken", "Sluiten" };
        AlertDialog.Builder builder = new AlertDialog.Builder(WorkoutActivity.this.getActivity());
        builder.setTitle("Workout opties");
        builder.setItems(items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int item) {
                if (items[item].equals("Workout Opslaan")) {

                } else if (items[item].equals("Afbreken")) {

                    mapView.onDestroy();
                    mainactivity.mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);

                    mainactivity.menuButton.setVisibility(View.VISIBLE);

                    if (mGoogleApiClient.isConnected()) {
                        onDestroy();
                    }

                    Fragment fragment = new HomePage();
                    // Insert the fragment by replacing any existing fragment
                    FragmentManager fragmentManager = getFragmentManager();
                    fragmentManager.beginTransaction()
                            .replace(R.id.mainContent, fragment)
                            .commit();

                } else if (items[item].equals("Sluiten")) {
                    dialog.dismiss();
                }
            }
        });
        builder.show();
    }


    @Override
    public void onConnected(@Nullable Bundle bundle) {

        Log.i(TAG, "Location services connected.");

        Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

        if (location == null) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
        else {
            handleNewLocation(location);
        };


    }

    @Override
    public void onConnectionSuspended(int i) {

        Log.i(TAG, "Location services suspended. Please reconnect.");
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        if (connectionResult.hasResolution()) {
            try {
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(this.getActivity(), CONNECTION_FAILURE_RESOLUTION_REQUEST);
            } catch (IntentSender.SendIntentException e) {
                e.printStackTrace();
            }
        } else {
            Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
        }
    }


    private void handleNewLocation(Location location) {

        Log.d(TAG, location.toString());

        double currentLatitude = location.getLatitude();
        double currentLongitude = location.getLongitude();

        Lat = location.getLatitude();
        Longi = location.getLongitude();

        LatLng latLng = new LatLng(currentLatitude, currentLongitude);

        CameraUpdate zoom=CameraUpdateFactory.zoomTo(17);

        map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        map.animateCamera(zoom);

        counter++;

        //current speed of the gps device
        currentSpeed = round(location.getSpeed(),3, BigDecimal.ROUND_HALF_UP);
        kmphSpeed = round((currentSpeed*3.6),3,BigDecimal.ROUND_HALF_UP);

        //all speeds added together
        totalSpeed = totalSpeed + currentSpeed;
        totalKmph = totalKmph + kmphSpeed;

        //calculates average speed
        avgSpeed = round(totalSpeed/counter,3,BigDecimal.ROUND_HALF_UP);
        avgKmph = round(totalKmph/counter,3,BigDecimal.ROUND_HALF_UP);

        //gets position
        currentLatitude = round(((double) (location.getLatitude())),3,BigDecimal.ROUND_HALF_UP);
        currentLongitude = round(((double) (location.getLongitude())),3,BigDecimal.ROUND_HALF_UP);


        String infoDetails = "Afstand: "+" | Tijd: ";
        String updateSpeed = String.valueOf(kmphSpeed);

        Log.d(TAG, updateSpeed.toString());

        //info.setText();

        speed.setText("Snelheid: "+updateSpeed+" km/hr");

        buildPolyline();

    }



    //Method to round the doubles to a max of 3 decimal places
    public static double round(double unrounded, int precision, int roundingMode)
    {
        BigDecimal bd = new BigDecimal(unrounded);
        BigDecimal rounded = bd.setScale(precision, roundingMode);
        return rounded.doubleValue();
    }



    public void buildPolyline(){

        Log.d(TAG,"Adding polyline" );


        LatLng polyline;


        polyline = new LatLng(Lat, Longi);

        polylines.add(polyline);

        Log.d("Locations Array", ""+polylines);

        map.addPolyline(new PolylineOptions().addAll(polylines).width(6.0f).color(Color.BLUE));

        //map.moveCamera(CameraUpdateFactory.newLatLngZoom(Start, 14));
    }

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (map == null) {
            // Try to obtain the map from the SupportMapFragment.
            map = ((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.mapview))
                    .getMap();
            // Check if we were successful in obtaining the map.
            if (map != null) {

            }
        }
    }


}

我花了大约一个星期尝试了几个解决方案,但仍然坚持这个问题。我需要一种准确的方法来跟踪跑步者的路线。我找不到任何运动应用程序样本,但足够的其他位置样本,但似乎没有任何工作。我希望有人可以帮助我。

由于

1 个答案:

答案 0 :(得分:0)

您必须使用位置管理器并注册位置更新。 尝试添加此代码:

protected LocationManager locationManager;

在onCreate()方法中调用registerLocationUpdates();

void registerLocationUpdates() {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_HIGH);

locationManager = (LocationManager)getActivity().getSystemService(LOCATION_SERVICE);

provider = locationManager.getBestProvider(criteria, true);

// Cant get a hold of provider
if (provider == null) {
    Log.v(TAG, "Provider is null");
    showNoProvider();
    return;
} else {
    Log.v(TAG, "Provider: " + provider);
}

locationManager.requestLocationUpdates(provider, 0, 0, this);

}