Add Google Maps API V2 in a fragment

前端 未结 11 1959
误落风尘
误落风尘 2020-11-29 03:00

I\'m trying to show the map from the Google Maps API V2 in fragment. I tried with the SupportMapFragment, but I can\'t get the expected output. Also I\'m a beginner on this

相关标签:
11条回答
  • 2020-11-29 03:22

    Here is my code.

    Create project in google map concole and generate api key.

    and then add dependency to build.gradle(app level).

    compile 'com.google.android.gms:play-services-maps:10.2.1'
    compile 'com.google.android.gms:play-services-location:10.2.1'
    compile 'com.google.android.gms:play-services-places:10.2.1'
    

    remember to add permissions in Android.manifest

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-feature android:name="android.hardware.location.gps" android:required="true"/>
    

    create activity_main.xml

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        tools:ignore="MergeRootFrame">
    
        <fragment
            class="com.googlelocationmapdemo.FragmentLocation"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </FrameLayout>
    

    nothing to call from MainActivity.class

    Create fragment_location.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/linearMap"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <fragment xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/map"
            class="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
    

    Create FragmentLocation.class

    public class FragmentLocation extends Fragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.OnConnectionFailedListener, LocationListener {
    
        public static final String TAG = FragmentLocation.class.getSimpleName();
        public static final int REQUEST_CODE_FOR_PERMISSIONS = 1;
        GoogleApiClient mGoogleApiClient;
        LatLng mLatLng;
        GoogleMap mGoogleMap;
        Marker mCurrLocationMarker;
        private LinearLayout linearMap;
        Location mLastLocation;
        LocationManager locationManager;
        boolean statusOfGPS;
        private Dialog mDialogGPS;
        View view;
        LocationRequest mLocationRequest;
        SupportMapFragment mFragment;
       FragmentManager fragmentManager;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
            view=inflater.inflate(R.layout.fragment_location,container,false);
            fragmentManager=getChildFragmentManager();
            mFragment = (SupportMapFragment)fragmentManager.findFragmentById(R.id.map);
            mFragment.getMapAsync(this);
            if (!isGooglePlayServicesAvailable()) {
                Toast.makeText(getActivity(), "play services not available", Toast.LENGTH_SHORT).show();
            }
            locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
            statusOfGPS = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            return view;
        }
    
        @Override
        public void onConnected(Bundle bundle) {
            mLocationRequest = new LocationRequest();
            mLocationRequest.setInterval(1000); //5 seconds
            mLocationRequest.setFastestInterval(2000); //3 seconds
            mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
            if (ContextCompat.checkSelfPermission(getActivity(),
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) {
                LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            }
        }
    
        @Override
        public void onConnectionSuspended(int i) {
        }
    
        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {
        }
    
        @Override
        public void onLocationChanged(Location location) {
            mLastLocation = location;
            if (mCurrLocationMarker != null) {
                mCurrLocationMarker.remove();
            }
            mLatLng = new LatLng(location.getLatitude(), location.getLongitude());
            MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.position(mLatLng);
            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
            mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);
            mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(mLatLng));
            // Zoom in the Google Map
            mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(15));
    
        }
    
        @Override
        public void onMapReady(GoogleMap googleMap) {
            mGoogleMap = googleMap;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (getActivity().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED &&
                        getActivity().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
                                == PackageManager.PERMISSION_GRANTED) {
                    buildGoogleApiClient();
                    mGoogleMap.setMyLocationEnabled(true);
    
                } else {
                    requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION
                                    , Manifest.permission.ACCESS_FINE_LOCATION},
                            REQUEST_CODE_FOR_PERMISSIONS);
                }
            } else {
                buildGoogleApiClient();
                mGoogleMap.setMyLocationEnabled(true);
            }
    
            //show dialog when click on location top-right side located on map.
            mGoogleMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
                @Override
                public boolean onMyLocationButtonClick() {
                    statusOfGPS = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
                    if (!statusOfGPS) {
                        turnOnGps();
                    } else {
                        getCurrentLocation(mLastLocation);
                    }
                    return false;
                }
            });
        }
    
        private boolean isGooglePlayServicesAvailable() {
            int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
            if (ConnectionResult.SUCCESS == status) {
                return true;
            } else {
                GooglePlayServicesUtil.getErrorDialog(status, getActivity(), 0).show();
                return false;
            }
        }
    
        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            switch (requestCode) {
                case REQUEST_CODE_FOR_PERMISSIONS:
                    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        if (getActivity().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
                                == PackageManager.PERMISSION_GRANTED &&
                                getActivity().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
                                        == PackageManager.PERMISSION_GRANTED) {
                            if (mGoogleApiClient == null) {
                                buildGoogleApiClient();
                            }
                            mGoogleMap.setMyLocationEnabled(true);
                        }
    
                    } else {
                        if (!(shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION)) && (!(shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)))) {
                            Snackbar snackbar = Snackbar.make(linearMap, "Never asked"
                                    , Snackbar.LENGTH_INDEFINITE);
                            snackbar.setAction("Allow", new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    Intent intent = new Intent();
                                    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
                                    intent.setData(uri);
                                    startActivity(intent);
                                }
                            });
                            snackbar.show();
                        }
                    }
                    break;
            }
        }
    
        private void getCurrentLocation(Location location) {
    
            mLastLocation = location;
    
            if (mCurrLocationMarker != null) {
                mCurrLocationMarker.remove();
            }
            if (locationManager != null) {
                if (ContextCompat.checkSelfPermission(getActivity(),
                        Manifest.permission.ACCESS_FINE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED) {
                    mLastLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);//getting last location
                }
                if (mLastLocation != null) {
                    if (mGoogleMap != null) {
                        Log.d("activity", "LOC by Network");
                        mLatLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
                        MarkerOptions markerOptions = new MarkerOptions();
                        markerOptions.position(mLatLng);
                        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
                        mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);
                        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(mLatLng));
                        mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(15));
                    }
                }
            }
        }
    
        private void turnOnGps() {
            if (mGoogleMap != null) {
                mGoogleMap.clear();
            }
            statusOfGPS = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);//getting status of gps whether gps is on or off.
            mDialogGPS = new Dialog(getActivity(), R.style.MyDialogTheme);
            mDialogGPS.requestWindowFeature(Window.FEATURE_NO_TITLE);
            mDialogGPS.setContentView(R.layout.dialog_turnongps);
            TextView txtCancel = (TextView) mDialogGPS.findViewById(R.id.txtCancel);
            TextView txtOK = (TextView) mDialogGPS.findViewById(R.id.txtSetting);
    
            ImageView imgLocation = (ImageView) mDialogGPS.findViewById(R.id.imgLocation);
    
            imgLocation.setImageResource(R.drawable.ic_location_my);
    
            txtCancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mDialogGPS.dismiss();
                    //finish();
                    if (!statusOfGPS) {
                        getCurrentLocationByDefault();
                    } else {
                        getCurrentLocation(mLastLocation);
                    }
                }
            });
    
            txtOK.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //It is use to redirect to setting->location to turn on gps when press ok.
                    startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                    mDialogGPS.dismiss();
                    if (!statusOfGPS) {
                        getCurrentLocationByDefault();
                    } else {
                        getCurrentLocation(mLastLocation);
                    }
                }
            });
            mDialogGPS.show();
        }
    
        private void getCurrentLocationByDefault() {
            if (mCurrLocationMarker != null) {
                mCurrLocationMarker.remove();
            }
    
            if (mGoogleMap != null) {
                LatLng xFrom1 = new LatLng(0.0, 0.0);
                mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(xFrom1, (float) 0.0));
    
                MarkerOptions markerOptions = new MarkerOptions();
                markerOptions.position(xFrom1);
                markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_taxi));
                mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);
            } else {
                Log.i("MainActivity", "getCurrentLocationByDefault else");
            }
    
        }
    
        @Override
        public void onResume() {
            super.onResume();
            statusOfGPS = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            if (mDialogGPS != null) {
                if (mDialogGPS.isShowing()) {
                    mDialogGPS.dismiss();
                }
            }
            if (!statusOfGPS) {
                turnOnGps();
            } else {
                getCurrentLocation(mLastLocation);
            }
    
        }
        protected synchronized void buildGoogleApiClient() {
            if (mGoogleApiClient != null) {
                mGoogleApiClient = null;
            }
            mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
            mGoogleApiClient.connect();
        }
    }
    

    create dailog_gps.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:orientation="vertical">
    
    
        <LinearLayout
    
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <TextView
                android:id="@+id/txtPhoneNumber"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Use Location?"
                android:textColor="@android:color/black"
              android:textSize="16sp"
                />
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_marginTop="15dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="This app wants to change your \ndevice settings:"
                android:textSize="14sp" />
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_marginTop="10dp"
            android:weightSum="2"
            android:gravity="center"
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <ImageView
                android:id="@+id/imgLocation"
                android:layout_weight="1"
                android:layout_gravity="top"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
    
            <TextView
                android:layout_weight="1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Use GPS, Wi-Fi and mobile \nnetwork for location"
                android:layout_marginLeft="20dp"
                android:textSize="12sp" />
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:orientation="horizontal"
            android:layout_marginTop="20dp">
    
            <TextView
                android:id="@+id/txtCancel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="NO"
                android:layout_marginRight="30dp"
                android:textSize="16sp" />
    
            <TextView
                android:id="@+id/txtSetting"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="YES"
                android:layout_marginRight="30dp"
                android:textSize="16sp" />
    
        </LinearLayout>
    </LinearLayout>
    

    Hope this will help you :-)

    0 讨论(0)
  • 2020-11-29 03:24

    Use SupportMapFragment instead of MapFragment and use getActivity()

    This is a basic example using SupportMapFragment:

    public class MainActivity extends ActionBarActivity implements OnMapReadyCallback{
        
        private SupportMapFragment map;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);        
            map = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
            map.getMapAsync(this);//remember getMap() is deprecated!      
        }
    
        @Override
        public void onMapReady(GoogleMap map) {
            map.moveCamera(CameraUpdateFactory.newLatLngZoom(
                new LatLng(47.17, 27.5699), 16));
            map.addMarker(new MarkerOptions()
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))
                .anchor(0.0f, 1.0f) // Anchors the marker on the bottom left
                .position(new LatLng(47.17, 27.5699))); //Iasi, Romania
            map.setMyLocationEnabled(true);
        }
    }
    

    and change the reference in your layout:

    <fragment
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            class="com.google.android.gms.maps.SupportMapFragment" />
    
    0 讨论(0)
  • 2020-11-29 03:24

    For all those friends who are facing the problem:-

    java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.maps.GoogleMap com.google.android.gms.maps.SupportMapFragment.getMap()

    Please try integrate GoogleMap using code

    FragmentManager fm = getChildFragmentManager();
    googleMap = ((SupportMapFragment)fm.findFragmentById(R.id.googleMap)).getMap();
    
    0 讨论(0)
  • 2020-11-29 03:26

    Using MapView within Fragment under Google Maps Android API v2.0

    public class MapFragment extends Fragment {
    
        MapView m;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, 
                Bundle savedInstanceState) {
            // inflat and return the layout
            View v = inflater.inflate(R.layout.map_fragment, container, false);
            m = (MapView) v.findViewById(R.id.mapView);
            m.onCreate(savedInstanceState);
    
            return v;
        }
    
        @Override
        public void onResume() {
            super.onResume();
            m.onResume();
        }
    
        @Override
        public void onPause() {
            super.onPause();
            m.onPause();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            m.onDestroy();
        }
    
        @Override
        public void onLowMemory() {
            super.onLowMemory();
            m.onLowMemory();
        }
    }
    

    http://ucla.jamesyxu.com/?p=287

    0 讨论(0)
  • 2020-11-29 03:28

    This example was build from the auto generated code from android studio, you dont need to change nothing in maps activity, only the context in the layout file to match your maps Activity

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:weightSum="1">
    
    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    tools:context="com.gearwell.app.gpsmaps02.Gpsenmapa"
    
    />
    
    <LinearLayout
        android:id="@+id/layButtonH"
        android:layout_height="150dp"
        android:layout_marginTop="50dp"
        android:layout_width="fill_parent"
        android:gravity="center"
        android:layout_weight="0.15">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Obtener Ubicacion"
            android:id="@+id/btnLocation"
            android:onClick="onClick"/>
    </LinearLayout>
    </LinearLayout>
    
    0 讨论(0)
  • 2020-11-29 03:33

    Update 10/24/2014 This is all wrong. You shouldn't have a fragment in a fragment. Rather you should extend the SupportMapFragment. See this stackoverflow post for some details: https://stackoverflow.com/a/19815266/568197

    here is my onDestroyView()

    public void onDestroyView() {
        super.onDestroyView();
        if (mMap != null) {
            getFragmentManager()
                    .beginTransaction()
                    .remove(getFragmentManager().findFragmentById(R.id.map))
                    .commit();
        }
    }
    
    0 讨论(0)
提交回复
热议问题