片段导航后,Android谷歌地图崩溃

时间:2016-02-27 13:29:33

标签: android android-fragments google-maps-android-api-2 android-maps-v2 android-navigation

我有一个带导航抽屉的应用程序,并在用户选择导航项后使用片段显示新屏幕

我的MainActivity类中处理它的部分如下所示:

public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_new) {
            addFragment(new NewFragment(), id);
        } else if (id == R.id.nav_start) {
            addFragment(new StartFragment(), id);
        } else if (id == R.id.nav_delete) {
            addFragment(new DeleteFragment(), id);
        } else if (id == R.id.nav_gps) {
            addFragment(new GPSFragment(), id);
        }
...

addFragment方法如下所示:

public void addFragment(Fragment fragment, int id) {
        if (fragment != null) {
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

            if (fragmentManager.getFragments() == null) {
                fragmentTransaction.replace(R.id.fragment_container, fragment, fragment.getClass().getSimpleName())
                        .commit();
            } else {
                fragmentTransaction.replace(R.id.fragment_container, fragment, fragment.getClass().getSimpleName())
                        .addToBackStack(Integer.toString(id))
                        .commit();
            }
        }
    }

其中一个片段是GPS,我实施了谷歌地图。它有效,但有两个主要问题,我不知道发生了什么:

  1. 当我导航到GPS,然后导航到另一个片段,然后使用导航抽屉导航到GPS(重复多次),最终屏幕将变黑并完全重新加载MainActivity
  2. 当我使用后退按钮(从GPS到另一个片段,返回GPS,重复多次)导航时,或使用主页按钮暂停应用并将其恢复(重复多次)应用获取非常慢,大约需要一分钟来响应任何用户输入
  3. 这必须归功于我实施谷歌地图的方式,或者更具体地说是我处理不同州(可能)之间转换的方式。我认为,按照我实施代码的方式,每当我使用导航抽屉,或按后退按钮,或按回家离开GPS片段时,gmaps将断开连接,片段将被暂停。

    我不确定为什么会导致这种速度减慢,或者将应用重新启动回MainActivity。也许是记忆问题?我不知道如果我总是从gmaps断开连接并在我离开时删除片段会导致什么。在添加代码以使mMapView.getMapAsync(this)正常工作之前,我不认为这是一个问题,所以它可能与mapready事件及其与导航的交互方式有关吗?

    GPS片段只是监听lat,lon位置的变化,并移动摄像机和标记以使用户位置居中。这是GPSFragment类:

    public class GPSFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.OnConnectionFailedListener, LocationListener, OnMapReadyCallback {
    
        private GoogleMap googleMap;
        private GoogleApiClient mGoogleApiClient;
        double lat, lon;
        LocationRequest mLocationRequest;
        CoordinatorLayout coordinatorLayout;
        UiSettings mapSettings;
        CameraPosition cameraPosition;
        MarkerOptions markerOptions;
        Marker marker;
        Location mLastLocation;
        MapView mMapView;
    
        public GPSFragment() {
            // Required empty public constructor
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
    
            coordinatorLayout = (CoordinatorLayout) getActivity().findViewById(R.id.coordinator_layout);
    
            // Inflate the layout for this fragment
            View view = inflater.inflate(R.layout.fragment_gps, container, false);
    
            //Set the nav drawer item highlight
            MainActivity mainActivity = (MainActivity) getActivity();
            mainActivity.navigationView.setCheckedItem(R.id.nav_gps);
    
            //Set actionbar title
            mainActivity.setTitle("GPS");
    
            //Create api connector and map
            buildGoogleApiClient();
    
            mMapView = (MapView) view.findViewById(R.id.mapView);
            mMapView.onCreate(savedInstanceState);
            //mMapView.onResume();
    
            //When map is ready, set it up with a onMapReady callback
            mMapView.getMapAsync(this);
    
            return view;
        }
    
        @Override
        public void onResume() {
            super.onResume();
    
            if (mGoogleApiClient.isConnected()) {
                mMapView.onResume();
            } else {
                mGoogleApiClient.connect();
                mMapView.onResume();
            }
    
        }
    
        @Override
        public void onPause() {
            super.onPause();
    
            if (mGoogleApiClient.isConnected()) {
                mMapView.onPause();
                mGoogleApiClient.disconnect();
            }
    
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
    
            if (mGoogleApiClient.isConnected()) {
                mMapView.onDestroy();
                mGoogleApiClient.disconnect();
            }
    
        }
    
        @Override
        public void onLowMemory() {
            super.onLowMemory();
    
            if (mGoogleApiClient.isConnected()) {
                mMapView.onLowMemory();
                mGoogleApiClient.disconnect();
            }
    
        }
    
        @Override
        public void onConnected(Bundle bundle) {
            mLocationRequest = LocationRequest.create();
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            mLocationRequest.setInterval(100); // Update location every second
    
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    
            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            if (mLastLocation != null) {
                lat = mLastLocation.getLatitude();
                lon = mLastLocation.getLongitude();
            }
        }
    
        @Override
        public void onConnectionSuspended(int i) {
    
        }
    
        @Override
        public void onLocationChanged(Location location) {
            lat = location.getLatitude();
            lon = location.getLongitude();
    
            marker.setPosition(new LatLng(lat, lon));
    
            googleMap.animateCamera(CameraUpdateFactory
                    .newLatLng(new LatLng(lat, lon)));
        }
    
        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {
            buildGoogleApiClient();
        }
    
        synchronized void buildGoogleApiClient() {
            //Request permission for location data
            if (ContextCompat.checkSelfPermission(getActivity(),
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) {
    
                //If permission has not been granted
                if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                        Manifest.permission.ACCESS_FINE_LOCATION)) {
                    //If they have previously declined permission, show explanation
                    Snackbar.make(coordinatorLayout, R.string.permission_explain_gps,
                            Snackbar.LENGTH_INDEFINITE).setAction(R.string.request_permission, new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            ActivityCompat.requestPermissions(getActivity(),
                                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                    0);
                        }
                    }).show();
                } else {
                    //If no previous declines
                    ActivityCompat.requestPermissions(getActivity(),
                            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                            0);
                }
            } else {
                //If permission has been granted
                mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                        .addConnectionCallbacks(this)
                        .addOnConnectionFailedListener(this)
                        .addApi(LocationServices.API)
                        .build();
                mGoogleApiClient.connect();
            }
    
        }
    
        @Override
        public void onMapReady(GoogleMap mMapView) {
            googleMap = mMapView;
            setupMap();
        }
    
        public void setupMap() {
            mapSettings = googleMap.getUiSettings();
            mapSettings.setZoomGesturesEnabled(true);
            mapSettings.setZoomControlsEnabled(true);
            mapSettings.setScrollGesturesEnabled(true);
            mapSettings.setTiltGesturesEnabled(true);
            mapSettings.setRotateGesturesEnabled(true);
    
            markerOptions = new MarkerOptions().position(new LatLng(lat, lon));
            marker = googleMap.addMarker(markerOptions);
    
            cameraPosition = new CameraPosition.Builder()
                    .target(new LatLng(lat, lon)).zoom(12).build();
            googleMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(cameraPosition));
    
        }
    }
    
    编辑:还注意到,在关闭并从手机上卸载应用程序后,地图标记图标仍然位于我顶部的状态栏中,我认为只有在手机当前请求位置信息时才会显示...

0 个答案:

没有答案