由于运行时问题,Google Maps API无法在API 23之上运行

时间:2017-04-26 06:59:00

标签: android google-maps-markers android-6.0-marshmallow google-maps-api-2

问题:Maps API在API 23下工作正常但由于运行时问题,他们在第一次运行时无法以某种方式获得权限。他们第一次要求权限,但第一次不工作。当我第二次运行应用程序时,它也适用于23以上的API。但是对于第一次运行,它不起作用。这段代码应该做什么,并且第二次要求用户逐个放置两个标记,并使用用户选择的坐标对其进行反向地理编码。

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

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.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import java.io.IOException;
import java.util.List;
import java.util.Locale;


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

    private GoogleMap mMap;
    GoogleApiClient mGoogleApiClient;
    Location mLastLocation;
    Marker mCurrLocationMarker;
    LocationRequest mLocationRequest;
    public Button homeLocationFromPin;
    public Button officeLocationFromPin;
    public static double homeLatitude;
    public static double officeLatitude;
    public static double homeLongitude;
    public static double officeLongitude;
    public int count = 0;
    public MarkerOptions placedHomeMarker;
    public MarkerOptions placedOfficeMarker;
    public static final int LOCATION_REQUEST_CODE = 99;


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

        if (ActivityCompat.checkSelfPermission
                (this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission
                (this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            requestPermission(Manifest.permission.ACCESS_FINE_LOCATION,
                    LOCATION_REQUEST_CODE);
        }



        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(map);
        mapFragment.getMapAsync(this);

        homeLocationFromPin = (Button) findViewById(R.id.confirmHomeLocation);
        homeLocationFromPin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (String.valueOf(homeLongitude) != null && String.valueOf(homeLatitude) != null) {
                    //Get nearby Places here based on Latitude and Longitude
//                    Toast.makeText(MapsActivity.this, getAddress(homeLatitude, homeLongitude), Toast.LENGTH_LONG).show();
                    showAlertBoxForHomeLocationConfirmation(getAddress(homeLatitude, homeLongitude));
                } else {
                    Toast.makeText(MapsActivity.this, "Please drop pin to home location first", Toast.LENGTH_SHORT).show();
                }
            }
        });


        officeLocationFromPin = (Button) findViewById(R.id.confirmOfficeLocation);
        officeLocationFromPin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (String.valueOf(officeLatitude) != null && String.valueOf(officeLongitude) != null) {
                    //Get nearby Places here based on Latitude and Longitude
//                    Toast.makeText(MapsActivity.this, getAddress(homeLatitude, homeLongitude), Toast.LENGTH_LONG).show();
                    showAlertBoxForOfficeLocationConfirmation(getAddress(officeLatitude, officeLongitude));
                } else {
                    Toast.makeText(MapsActivity.this, "Please drop pin to home location first", Toast.LENGTH_SHORT).show();
                }
            }
        });


    }//End Of OnCreate

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        LatLng boston = new LatLng(42.3601, -71.0589);
        mMap.moveCamera(CameraUpdateFactory.newLatLng(boston));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(15));

        showAlertBox("Home");

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                buildGoogleApiClient();
                mMap.setMyLocationEnabled(true);
                Toast.makeText(this, "Inside Perm", Toast.LENGTH_LONG).show();
                mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
                    @Override
                    public void onMapClick(LatLng latLng) {

                        if (count == 0) {
                            //Make the confirm button available on first tap
                            homeLocationFromPin.setVisibility(View.VISIBLE);
                            //add(point);
                            mMap.clear();
                            placedHomeMarker = new MarkerOptions().position(latLng);
                            placedHomeMarker.title("Home Location");
                            mMap.addMarker(placedHomeMarker);
                            homeLatitude = latLng.latitude;
                            homeLongitude = latLng.longitude;
                            Toast.makeText(MapsActivity.this, getNameOnly(homeLatitude, homeLongitude), Toast.LENGTH_SHORT).show();
                        } else {
                            officeLocationFromPin.setVisibility(View.VISIBLE);
                            placedOfficeMarker = new MarkerOptions().position(latLng);
                            placedOfficeMarker.title("Office Location");
                            mMap.addMarker(placedOfficeMarker);
                            officeLatitude = latLng.latitude;
                            officeLongitude = latLng.longitude;
                            Toast.makeText(MapsActivity.this, getNameOnly(homeLatitude, homeLongitude), Toast.LENGTH_SHORT).show();
                            Toast.makeText(MapsActivity.this, getNameOnly(officeLatitude, officeLongitude), Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            } else {

            buildGoogleApiClient();
            mMap.setMyLocationEnabled(true);
            mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
                @Override
                public void onMapClick(LatLng latLng) {
                    if (count == 0) {
                        //Make the confirm button available on first tap
                        homeLocationFromPin.setVisibility(View.VISIBLE);
                        //add(point);
                        mMap.clear();
                        placedHomeMarker = new MarkerOptions().position(latLng);
                        placedHomeMarker.title("Home Location");
                        mMap.addMarker(placedHomeMarker);
                        homeLatitude = latLng.latitude;
                        homeLongitude = latLng.longitude;
                        Toast.makeText(MapsActivity.this, getNameOnly(homeLatitude, homeLongitude), Toast.LENGTH_SHORT).show();
                    } else {
                        officeLocationFromPin.setVisibility(View.VISIBLE);
                        placedOfficeMarker = new MarkerOptions().position(latLng);
                        placedOfficeMarker.title("Office Location");
                        mMap.addMarker(placedOfficeMarker);
                        officeLatitude = latLng.latitude;
                        officeLongitude = latLng.longitude;
                        Toast.makeText(MapsActivity.this, getNameOnly(homeLatitude, homeLongitude), Toast.LENGTH_SHORT).show();
                        Toast.makeText(MapsActivity.this, getNameOnly(officeLatitude, officeLongitude), Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
        }
    }//End of onMap Ready

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnected(Bundle bundle) {

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(1000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }


    @Override
    public void onLocationChanged(Location location) {

        mLastLocation = location;
        if (mCurrLocationMarker != null) {
            mCurrLocationMarker.remove();
        }

        //Place current location marker
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
//        markerOptions.title("Your Current Location");
//        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
//        markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.home));
//        markerOptions.draggable(true);
        mCurrLocationMarker = mMap.addMarker(markerOptions);

        //move map camera
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(15));

        //Set a marker drag listener
        mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
            @Override
            public void onMarkerDragStart(Marker marker) {

            }

            @Override
            public void onMarkerDrag(Marker marker) {

            }

            @Override
            public void onMarkerDragEnd(Marker marker) {
                mMap.animateCamera(CameraUpdateFactory.newLatLng(marker.getPosition()));
                //Get the latitude and longitude of the place where user dropped the marker
                Toast.makeText(MapsActivity.this, "Latitude:" + String.valueOf(marker.getPosition().latitude), Toast.LENGTH_LONG).show();
                homeLatitude = marker.getPosition().latitude;
                Toast.makeText(MapsActivity.this, "Longitude:" + String.valueOf(marker.getPosition().longitude), Toast.LENGTH_LONG).show();
                homeLongitude = marker.getPosition().longitude;

            }
        });


        //stop location updates
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
    }


    public void showAlertBox(String LocationName) {

        AlertDialog.Builder b1 = new AlertDialog.Builder(MapsActivity.this);
        b1.setMessage("Please select your " + LocationName + " location.\nTap anywhere on the screen to select your "
                + LocationName +
                "location and press button to confirm.");
        b1.setCancelable(false);

        b1.setPositiveButton("Ok",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                    }
                });

        AlertDialog customAlertBox = b1.create();
        customAlertBox.show();

    }


    public void showAlertBoxForHomeLocationConfirmation(String reverseGeoStr) {

        AlertDialog.Builder b1 = new AlertDialog.Builder(MapsActivity.this);
        b1.setMessage("Confirm your home location or search again\n" + reverseGeoStr);
        b1.setCancelable(false);

        b1.setPositiveButton("Confirm",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        count = 3;

                        homeLocationFromPin.setVisibility(View.GONE);
                        showAlertBox("Office");
                    }
                });

        b1.setNegativeButton("Do it again",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MapsActivity.this, "Place Pin Again", Toast.LENGTH_SHORT).show();
                    }
                });
        AlertDialog customAlertBox = b1.create();
        customAlertBox.show();

    }


    public void showAlertBoxForOfficeLocationConfirmation(String reverseGeoStr) {

        AlertDialog.Builder b1 = new AlertDialog.Builder(MapsActivity.this);
        b1.setMessage("Confirm your Office location or search again\n" + reverseGeoStr);
        b1.setCancelable(false);

        b1.setPositiveButton("Confirm",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Intent st = new Intent(MapsActivity.this, getUserName.class);
                        startActivity(st);
                        finish();
                    }
                });

        b1.setNegativeButton("Do it again",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MapsActivity.this, "Place Pin Again", Toast.LENGTH_SHORT).show();
                    }
                });
        AlertDialog customAlertBox = b1.create();
        customAlertBox.show();

    }


    private String getAddress(double latitude, double longitude) {
        if (latitude == 0.0 || longitude == 0.0) {
            //Give default values so it does not returns null
            latitude = 42.3601;
            longitude = -71.0589;
        }
        StringBuilder result = new StringBuilder();
        try {
            Geocoder geocoder = new Geocoder(this, Locale.getDefault());
            List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
            if (addresses.size() > 0) {
                Address address = addresses.get(0);
                result.append(address.getAddressLine(0)).append("\n");
                result.append(address.getLocality()).append("\n");
                result.append(address.getAdminArea()).append("\n");
                result.append(address.getPostalCode()).append("\n");
                result.append(address.getCountryName());
            }
        } catch (IOException e) {
            Log.e("tag", e.getMessage());
        }

        return result.toString();
    }

    private String getNameOnly(double latitude, double longitude) {
        if (latitude == 0.0 || longitude == 0.0) {
            //Give default values so it does not returns null
            latitude = 42.3601;
            longitude = -71.0589;
        }
        StringBuilder result = new StringBuilder();
        try {
            Geocoder geocoder = new Geocoder(this, Locale.getDefault());
            List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
            if (addresses.size() > 0) {
                Address address = addresses.get(0);
                result.append(address.getAddressLine(0)).append("\n");
                result.append(address.getLocality()).append("\n");
            }
        } catch (IOException e) {
            Log.e("tag", e.getMessage());
        }
        return result.toString();
    }


    protected void requestPermission(String permissionType, int requestCode) {
        int permission = ContextCompat.checkSelfPermission(this,
                permissionType);

        if (permission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{permissionType}, requestCode
            );
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case LOCATION_REQUEST_CODE: {

                if (grantResults.length == 0
                        || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "Unable to show location - permission required", Toast.LENGTH_LONG).show();
                }
                return;
            }
        }
    }

}

2 个答案:

答案 0 :(得分:3)

当您要求<?xml version="1.0" encoding="utf-8"?> <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.jackd.testflash_26_4_2017.MainActivity"> <Button android:text="Button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnFlash" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="124dp" /> </RelativeLayout> 中的位置更新时,您应该使用onMapReady()方法致电mapFragment.getMapAsync(this);

onRequestPermissionsResult

希望这有帮助。

答案 1 :(得分:1)

上面的解决方案使其适用于具有API&gt;的手机23但它停止使用API​​&lt; 23.所以我一直在努力。

   @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case LOCATION_REQUEST_CODE: {

                if (grantResults.length == 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "Unable to show location - permission required", Toast.LENGTH_LONG).show();
                    return;
                }

//                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//                    mapFragment.getMapAsync(this);
//                }
                else
                {
                    Toast.makeText(this,"Permission not granted",Toast.LENGTH_LONG).show();
                }
                break;
            }
        }
    }

}

和onMapReady()

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
    LatLng boston = new LatLng(42.3601, -71.0589);
    mMap.moveCamera(CameraUpdateFactory.newLatLng(boston));
    mMap.animateCamera(CameraUpdateFactory.zoomTo(15));

    showAlertBox("Home");

    if (ActivityCompat.checkSelfPermission
            (this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED

            && ActivityCompat.checkSelfPermission
            (this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

        mMap.setMyLocationEnabled(true);

    } else {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermission(Manifest.permission.ACCESS_FINE_LOCATION, LOCATION_REQUEST_CODE);
        }
    }


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

        buildGoogleApiClient();
        Toast.makeText(this, "Inside Perm", Toast.LENGTH_LONG).show();
        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {

                if (count == 0) {
                    //Make the confirm button available on first tap
                    homeLocationFromPin.setVisibility(View.VISIBLE);
                    //add(point);
                    mMap.clear();
                    placedHomeMarker = new MarkerOptions().position(latLng);
                    placedHomeMarker.title("Home Location");
                    mMap.addMarker(placedHomeMarker);
                    homeLatitude = latLng.latitude;
                    homeLongitude = latLng.longitude;
                    Toast.makeText(MapsActivity.this, getNameOnly(homeLatitude, homeLongitude), Toast.LENGTH_SHORT).show();
                } else {
                    officeLocationFromPin.setVisibility(View.VISIBLE);
                    placedOfficeMarker = new MarkerOptions().position(latLng);
                    placedOfficeMarker.title("Office Location");
                    mMap.addMarker(placedOfficeMarker);
                    officeLatitude = latLng.latitude;
                    officeLongitude = latLng.longitude;
                    Toast.makeText(MapsActivity.this, getNameOnly(homeLatitude, homeLongitude), Toast.LENGTH_SHORT).show();
                    Toast.makeText(MapsActivity.this, getNameOnly(officeLatitude, officeLongitude), Toast.LENGTH_SHORT).show();
                }
            }
        });
    } else {

        buildGoogleApiClient();
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            mMap.setMyLocationEnabled(true);
        }

        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                if (count == 0) {
                    //Make the confirm button available on first tap
                    homeLocationFromPin.setVisibility(View.VISIBLE);
                    //add(point);
                    mMap.clear();
                    placedHomeMarker = new MarkerOptions().position(latLng);
                    placedHomeMarker.title("Home Location");
                    mMap.addMarker(placedHomeMarker);
                    homeLatitude = latLng.latitude;
                    homeLongitude = latLng.longitude;
                    Toast.makeText(MapsActivity.this, getNameOnly(homeLatitude, homeLongitude), Toast.LENGTH_SHORT).show();
                } else {
                    officeLocationFromPin.setVisibility(View.VISIBLE);
                    placedOfficeMarker = new MarkerOptions().position(latLng);
                    placedOfficeMarker.title("Office Location");
                    mMap.addMarker(placedOfficeMarker);
                    officeLatitude = latLng.latitude;
                    officeLongitude = latLng.longitude;
                    Toast.makeText(MapsActivity.this, getNameOnly(homeLatitude, homeLongitude), Toast.LENGTH_SHORT).show();
                    Toast.makeText(MapsActivity.this, getNameOnly(officeLatitude, officeLongitude), Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}//End of onMap Ready