【问题标题】:App Crashes while Implementing Google Api Client and Location Listener实施 Google Api 客户端和位置侦听器时应用程序崩溃
【发布时间】:2017-05-02 02:27:33
【问题描述】:

我正在尝试制作一个应用程序,使用 public void onLocationChanged(Location location) 在谷歌地图上跟踪用户的路径,但每次我尝试实现位置监听器时,我的应用程序都会崩溃。这是我的代码..如果您看到任何需要修复的内容,请告诉我。谢谢!

Android 清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edu.carthage.haag.jacob.homework_application_android">

    <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
    <!--
             The API key for Google Maps-based APIs is defined as a string resource.
             (See the file "res/values/google_maps_api.xml").
             Note that the API key is linked to the encryption key used to sign the APK.
             You need a different API key for each encryption key, including the release key that is used to
             sign the APK for publishing.
             You can define the keys for the debug and release targets in src/debug/ and src/release/.
        -->


    <meta-data android:name="com.google.android.geo.API_KEY" android:value="AIzaSyD-2jUwPWvPzHmsdIiYuW9tLarxYe6AQwE" />

    <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name="edu.carthage.haag.jacob.homework_application_android.MapsActivity"
        android:label="@string/title_activity_maps">

    </activity>

</application>

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

</manifest>

这是我的 MapsActivity.java 文件

package edu.carthage.haag.jacob.homework_application_android;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener, LocationListener {

    private GoogleMap mMap;
    private final static int MY_PERMISSION_FINE_LOCATION = 101;
    GoogleApiClient mGoogleApiClient;
    private ArrayList<LatLng> points; //added
    Polyline line; //added
    private Context context;
    private static final long INTERVAL = 5000; //1 minute
    private static final long FASTEST_INTERVAL = 1000; // 1 minute
    private static final float SMALLEST_DISPLACEMENT = 0.05F; //quarter of a meter
    private LocationRequest mLocationRequest;

    private LocationManager mLocationManager;
    private float LOCATION_REFRESH_DISTANCE = 1;
    private long LOCATION_REFRESH_TIME = 100;
    //gets the initial gps coordinates
    private Location mLastLocation;

    String locationProvider;

    protected void createLocationRequest() {

//        LocationServices.FusedLocationApi.requestLocationUpdates(
//                mGoogleApiClient, mLocationRequest, this);
//
//        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
//            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
//        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);

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

        mapFragment.getMapAsync(this);
        points = new ArrayList<LatLng>(); //added
        context = MapsActivity.this;

        //createLocationRequest();
    }

    @Override
    protected void onStart() {

        super.onStart();
        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        mLocationRequest.setSmallestDisplacement(SMALLEST_DISPLACEMENT); //added
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add a marker in Sydney and move the camer
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            mMap.setMyLocationEnabled(true);
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_FINE_LOCATION);
            }
        }


    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case MY_PERMISSION_FINE_LOCATION:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        mMap.setMyLocationEnabled(true);
                    }

                } else {
                    Toast.makeText(getApplicationContext(), "This app requires location permissions to be granted", Toast.LENGTH_LONG).show();
                    finish();
                }
                break;
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
        LatLng latLng = new LatLng(latitude, longitude); //you already have this

        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.title("New Position");
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
        //move map camera
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(11));

        points.add(latLng); //added

        redrawLine(); //added
    }

    private void redrawLine() {

        mMap.clear();  //clears all Markers and Polylines

        PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
        for (int i = 0; i < points.size(); i++) {
            LatLng point = points.get(i);
            options.add(point);
        }
        //addMarker(); //add Marker in current position
        line = mMap.addPolyline(options); //add Polyline
    }

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

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    //    @Override
//    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//        switch (requestCode) {
//            case MY_PERMISSION_FINE_LOCATION:
//                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
//                        mMap.setMyLocationEnabled(true);
//                    }
//
//                } else {
//                    Toast.makeText(getApplicationContext(), "This app requires location permissions to be granted", Toast.LENGTH_LONG).show();
//                    finish();
//                }
//                break;
//        }
//    }

}

【问题讨论】:

  • 它在哪里以及如何崩溃 - 我认为非常重要的信息
  • 为什么会被标记为 javascript?
  • 在遇到此崩溃时发布您的堆栈跟踪..
  • 程序崩溃在.....
  • if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); }

标签: java android location


【解决方案1】:

试试这个。 在onstart()而不是oncreate ()中连接google api客户端

@Override
    protected void onStart() {
        super.onStart();
        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }
    }

并使用此方法在oncreate()中初始化googleApi客户端并调用onCreate()

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

希望对你有帮助

【讨论】:

  • 我添加了 mGoogleApiClient.connect();到我的 onStart() 方法,然后尝试调用 LocationServices.FusedLocationApi.requestLocationUpdates(mGo‌​ogleApiClient, mLocationRequest, this);应用程序再次崩溃。我已经用新的堆栈跟踪和 MapsActivity.java 文件更新了我的代码。让我知道你的想法
  • 请添加logcat
【解决方案2】:

感谢大家的帮助,我能够找出我的问题。问题是我没有使用 onConnected() 方法,其中 ocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);叫做。现在我进行了更改,一切正常!

【讨论】:

    【解决方案3】:

    根据堆栈跟踪,您似乎正在尝试在连接 GoogleAPI 客户端之前访问位置。

    因此,您应该在连接时请求位置。同样可以实现:

        if(mGoogleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            }
    

    或者您可以请求位置更新onConnected方法。

    @Override
    public void onConnected(@Nullable Bundle bundle) {
         LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }
    

    你还没有按照我说的做,找到我测试的完整代码: 查看第 103 行第 179 行

    package edu.carthage.haag.jacob.homework_application_android;
    import android.Manifest;
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.graphics.Color;
    import android.location.Location;
    import android.location.LocationManager;
    import android.os.Build;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.content.ContextCompat;
    import android.widget.Toast;
    
    import com.devop.aashish.androiddemo.R;
    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.location.LocationListener;
    import com.google.android.gms.location.LocationRequest;
    import com.google.android.gms.location.LocationServices;
    import com.google.android.gms.maps.CameraUpdateFactory;
    import com.google.android.gms.maps.GoogleMap;
    import com.google.android.gms.maps.OnMapReadyCallback;
    import com.google.android.gms.maps.SupportMapFragment;
    import com.google.android.gms.maps.model.BitmapDescriptorFactory;
    import com.google.android.gms.maps.model.LatLng;
    import com.google.android.gms.maps.model.MarkerOptions;
    import com.google.android.gms.maps.model.Polyline;
    import com.google.android.gms.maps.model.PolylineOptions;
    
    import java.util.ArrayList;
    
    public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, LocationListener, GoogleApiClient.OnConnectionFailedListener {
    
        private final static int MY_PERMISSION_FINE_LOCATION = 101;
        private static final long INTERVAL = 5000; //1 minute
        private static final long FASTEST_INTERVAL = 1000; // 1 minute
        private static final float SMALLEST_DISPLACEMENT = 0.05F; //quarter of a meter
        GoogleApiClient mGoogleApiClient;
        Polyline line; //added
        String locationProvider;
        private GoogleMap mMap;
        private ArrayList<LatLng> points; //added
        private Context context;
        private LocationRequest mLocationRequest;
        private LocationManager mLocationManager;
        private float LOCATION_REFRESH_DISTANCE = 1;
        private long LOCATION_REFRESH_TIME = 100;
        //gets the initial gps coordinates
        private Location mLastLocation;
    
        protected void createLocationRequest() {
    
    //        LocationServices.FusedLocationApi.requestLocationUpdates(
    //                mGoogleApiClient, mLocationRequest, this);
    //
    //        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
    //            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    //        }
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_maps);
            SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map);
    
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .build();
    
            mapFragment.getMapAsync(this);
            points = new ArrayList<LatLng>(); //added
            context = MapsActivity.this;
    
            //createLocationRequest();
        }
    
        @Override
        protected void onStart() {
    
            super.onStart();
            if (mGoogleApiClient != null) {
                mGoogleApiClient.connect();
            }
    
            mLocationRequest = new LocationRequest();
            mLocationRequest.setInterval(INTERVAL);
            mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
            mLocationRequest.setSmallestDisplacement(SMALLEST_DISPLACEMENT); //added
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) {
    //            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
                if (mGoogleApiClient.isConnected()) {
                    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
                } else {
                    Toast.makeText(context, "Google API not connected yet", Toast.LENGTH_SHORT).show();
                }
            }
        }
    
        @Override
        public void onMapReady(GoogleMap googleMap) {
            mMap = googleMap;
    
            // Add a marker in Sydney and move the camera
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                mMap.setMyLocationEnabled(true);
            } else {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_FINE_LOCATION);
                }
            }
    
    
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            switch (requestCode) {
                case MY_PERMISSION_FINE_LOCATION:
                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                            mMap.setMyLocationEnabled(true);
                        }
    
                    } else {
                        Toast.makeText(getApplicationContext(), "This app requires location permissions to be granted", Toast.LENGTH_LONG).show();
                        finish();
                    }
                    break;
            }
        }
    
        @Override
        public void onLocationChanged(Location location) {
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            LatLng latLng = new LatLng(latitude, longitude); //you already have this
    
            MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.position(latLng);
            markerOptions.title("New Position");
            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
            //move map camera
            mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
            mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
    
            points.add(latLng); //added
    
            redrawLine(); //added
        }
    
        private void redrawLine() {
    
            mMap.clear();  //clears all Markers and Polylines
    
            PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
            for (int i = 0; i < points.size(); i++) {
                LatLng point = points.get(i);
                options.add(point);
            }
            //addMarker(); //add Marker in current position
            line = mMap.addPolyline(options); //add Polyline
        }
    
        @Override
        public void onConnected(@Nullable Bundle bundle) {
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) {
                if (mGoogleApiClient.isConnected()) {
                    Toast.makeText(context, "Google API connected", Toast.LENGTH_SHORT).show();
                    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
                } else {
                    Toast.makeText(context, "Google API not connected yet", Toast.LENGTH_SHORT).show();
                }
            }
        }
    
        @Override
        public void onConnectionSuspended(int i) {
            mGoogleApiClient.connect();
        }
    
        @Override
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    
        }
    
        //    @Override
    //    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    //        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    //        switch (requestCode) {
    //            case MY_PERMISSION_FINE_LOCATION:
    //                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    //                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
    //                        mMap.setMyLocationEnabled(true);
    //                    }
    //
    //                } else {
    //                    Toast.makeText(getApplicationContext(), "This app requires location permissions to be granted", Toast.LENGTH_LONG).show();
    //                    finish();
    //                }
    //                break;
    //        }
    //    }
    }
    

    【讨论】:

    • 我添加了 mGoogleApiClient.connect();到我的 onStart() 方法,然后尝试调用 LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);应用程序再次崩溃。我已经用新的堆栈跟踪和 MapsActivity.java 文件更新了我的代码。让我知道你的想法!
    • 您是否在 onConnected 方法中请求了 FusedLocation.requestLocationUpdates ?如果您的应用仍然崩溃,请将完整的崩溃日志作为评论。
    • 是的,我在 onConnected 方法中请求 FusedLocation.requestLocationUpdates .. 我的崩溃日志在下面的评论中
    • 我也无法将我的崩溃日志添加到许多字符中以供评论
    • 我已经用完整的代码修改了我的答案。我测试了你的代码,我也遇到了同样的崩溃,然后我在请求位置更新之前结合了 if 条件来检查 google api 客户端的连接状态,并在 onConnected 方法中做了同样的事情。希望对你有效。如果您遇到任何问题,请恢复。
    猜你喜欢
    • 2018-10-26
    • 2021-11-18
    • 1970-01-01
    • 2014-05-27
    • 2021-12-27
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多