-2

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

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; 
      } 
     } 
    } 

} 

回答

3

正如你在onMapReady()请求位置更新,你应该叫mapFragment.getMapAsync(this);onRequestPermissionsResult方法:

public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
     switch (requestCode) { 
      case LOCATION_REQUEST_CODE: { 
       // If request is cancelled, the result arrays are empty. 
       if (grantResults.length > 0 
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

        mapFragment.getMapAsync(this); 


       } else { 
        Toast.makeText(getApplicationContext(), "Please provide the permission", Toast.LENGTH_LONG).show(); 
       } 
       break; 
      } 
     } 
} 

希望这有助于。

+1

看着逻辑和工作中。谢谢。这么小的事情让我感到头痛,好几个小时。非常感谢。 –

+0

真的很高兴它有帮助。 :) – tahsinRupam

1

以上soluion使得它与API> 23手机工作,但它停止与API工作< 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 
+0

是的,上面的解决方案是专门针对您提到的问题。预计额外的修改将由问题制作者根据需要完成。这不会使答案错误。虽然有许多方法可以为所有'API'版本编写上述代码,但您的代码非常好,最后的投票也是我的。干杯! – tahsinRupam

+0

我不是说错了。我非常感谢你的帮助。我也提出了你的答案。再次感谢。 –