我正在将Java客户端库用于Google Maps API Web服务,以绘制两点之间的路线。它在Android Studio的模拟器上正常运行,但在Blue Stack和我的智能手机上崩溃。
我已经从项目模板创建了Maps Activity,仅编辑了AppGradle和MapsActivity。应用程序可以按预期运行,但只能在Android Studio的模拟器上运行。
这里是Android Studio模拟器(Android 10)中的工作图像enter image description here
所以应用程序在此行崩溃(我到目前为止发现的东西):-Directions.destination(destination).setCallback(new PendingResult.Callback(){
这是我的MapsActivity:
公共类MapsActivity扩展FragmentActivity实现OnMapReadyCallback {
private static final String TAG = "TaG";
private GoogleMap mMap;
static final int REQUEST_LOCATION_PERMISSION = 99;
double mUserlatitude, mUserlongitude;
ArrayList<PolylineData> mPolyLinesData = new ArrayList<>();
Marker marker =null;
GeoApiContext mGeoApiContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
mGeoApiContext = new GeoApiContext.Builder().apiKey("google_maps_api_key").build();
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
enableMyLocation();
mMap.getUiSettings().setZoomControlsEnabled(true);
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(31.522738, 74.358556);
marker = mMap.addMarker(new MarkerOptions().position(sydney));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 12));
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
LatLng start = new LatLng(mUserlatitude,mUserlongitude);
calculateDirections(start,marker);
return false;
}
});
}
private void enableMyLocation() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 0, locationListener);
} else {
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION_PERMISSION);
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
// Check if location permissions are granted and if so enable the
// location data layer.
switch (requestCode) {
case REQUEST_LOCATION_PERMISSION:
if (grantResults.length > 0
&& grantResults[0]
== PackageManager.PERMISSION_GRANTED) {
enableMyLocation();
}else{
enableMyLocation();
}
break;
}
}
LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
mUserlatitude = location.getLatitude();
mUserlongitude = location.getLongitude();
//Toast.makeText(MapsActivity.this, Double.toString(mUserlatitude), Toast.LENGTH_SHORT).show();
//Toast.makeText(MapsActivity.this, marker.getPosition().toString(), Toast.LENGTH_SHORT).show();
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
};
private void calculateDirections(LatLng start, Marker marker){
Log.d(TAG, "calculateDirections: calculating directions.");
com.google.maps.model.LatLng destination = new com.google.maps.model.LatLng(
marker.getPosition().latitude,
marker.getPosition().longitude
);
DirectionsApiRequest directions = new DirectionsApiRequest(mGeoApiContext);
directions.alternatives(true);
directions.origin(
new com.google.maps.model.LatLng(
start.latitude,start.longitude
)
);
//Log.d(TAG, "calculateDirections: destination: " + destination.toString());
directions.destination(destination).setCallback(new PendingResult.Callback<DirectionsResult>() {
@Override
public void onResult(DirectionsResult result) {
Log.d(TAG, "calculateDirections: routes: " + result.routes[0].toString());
Log.d(TAG, "calculateDirections: duration: " + result.routes[0].legs[0].duration);
Log.d(TAG, "calculateDirections: distance: " + result.routes[0].legs[0].distance);
Log.d(TAG, "calculateDirections: geocodedWayPoints: " + result.geocodedWaypoints[0].toString());
addPolylinesToMap(result);
}
@Override
public void onFailure(Throwable e) {
Log.e(TAG, "calculateDirections: Failed to get directions: " + e.getMessage() );
return;
}
});
}
private void addPolylinesToMap(final DirectionsResult result){
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
if(mPolyLinesData.size() > 0){
for(PolylineData polylineData: mPolyLinesData){
polylineData.getPolyline().remove();
}
mPolyLinesData.clear();
mPolyLinesData = new ArrayList<>();
}
double firstduration = 0;
for(DirectionsRoute route: result.routes){
List<com.google.maps.model.LatLng> decodedPath = PolylineEncoding.decode(route.overviewPolyline.getEncodedPath());
List<LatLng> newDecodedPath = new ArrayList<>();
// This loops through all the LatLng coordinates of ONE polyline.
for(com.google.maps.model.LatLng latLng: decodedPath){
Log.d(TAG, "run: latlng: " + latLng.toString());
newDecodedPath.add(new LatLng(
latLng.lat,
latLng.lng
));
}
Polyline polyline = mMap.addPolyline(new PolylineOptions().addAll(newDecodedPath));
polyline.setColor(ContextCompat.getColor(getApplicationContext(), R.color.quantum_grey));
polyline.setClickable(true);
mPolyLinesData.add(new PolylineData(polyline, route.legs[0]));
double thisduration = route.legs[0].duration.inSeconds;
if(firstduration == 0) {
firstduration= thisduration;
onPolylineClickListener.onPolylineClick(polyline);
}
if(thisduration < firstduration){
firstduration = thisduration;
onPolylineClickListener.onPolylineClick(polyline);
}
if(result.routes.length == 1) onPolylineClickListener.onPolylineClick(polyline);
}
}
});
}
GoogleMap.OnPolylineClickListener onPolylineClickListener = new GoogleMap.OnPolylineClickListener() {
@Override
public void onPolylineClick(Polyline polyline) {
int index = 0;
for(PolylineData polylineData: mPolyLinesData){
index++;
//Log.d(TAG, "onPolylineClick: toString: " + polylineData.toString());
if(polyline.getId().equals(polylineData.getPolyline().getId())){
polylineData.getPolyline().setColor(ContextCompat.getColor(getApplicationContext(), R.color.quantum_lightblue));
polylineData.getPolyline().setZIndex(1);
if(marker != null)marker.remove();
LatLng endlocation = new LatLng(polylineData.getLeg().endLocation.lat, polylineData.getLeg().endLocation.lng);
marker = mMap.addMarker(new MarkerOptions().position(endlocation).title("Trip # "+ index).snippet("Duration: "+polylineData.getLeg().duration));
marker.showInfoWindow();
zoomRoute(polyline.getPoints());
}
else{
polylineData.getPolyline().setColor(ContextCompat.getColor(getApplicationContext(), R.color.quantum_grey));
polylineData.getPolyline().setZIndex(0);
}
}
}
};
public void zoomRoute(List<LatLng> lstLatLngRoute) {
if (mMap == null || lstLatLngRoute == null || lstLatLngRoute.isEmpty()) return;
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
for (LatLng latLngPoint : lstLatLngRoute)
boundsBuilder.include(latLngPoint);
int routePadding = 120;
LatLngBounds latLngBounds = boundsBuilder.build();
mMap.animateCamera(
CameraUpdateFactory.newLatLngBounds(latLngBounds, routePadding),
600,
null
);
}
public static class PolylineData {
private Polyline polyline;
private DirectionsLeg leg;
public PolylineData(Polyline polyline, DirectionsLeg leg) {
this.polyline = polyline;
this.leg = leg;
}
public Polyline getPolyline() {
return polyline;
}
public void setPolyline(Polyline polyline) {
this.polyline = polyline;
}
public DirectionsLeg getLeg() {
return leg;
}
public void setLeg(DirectionsLeg leg) {
this.leg = leg;
}
@Override
public String toString() {
return "PolylineData{" +
"polyline=" + polyline +
", leg=" + leg +
'}';
}
}
}
下面是应用程序Gradle:
应用插件:“ com.android.application”套用外挂程式:'com.google.gms.google-services'
android { 编译版本29 buildToolsVersion“ 29.0.2”
defaultConfig {
applicationId "com.example.myapplication"
minSdkVersion 16
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
targetCompatibility = 1.8
sourceCompatibility = 1.8
}
}
依赖项{ 实现fileTree(dir:'libs',包括:['* .jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'com.google.firebase:firebase-auth:19.3.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.google.maps:google-maps-services:0.13.0'
implementation 'org.slf4j:slf4j-simple:1.7.25'
implementation 'com.google.android.libraries.places:places:2.2.0'
}
这解决了我的问题。
[调试我的应用程序后,我发现将其添加到应用程序级gradle文件(dependencies
)中的build.gradle(app)
中有助于解决该问题。
implementation group: 'com.github.seratch', name: 'java-time-backport', version: '1.0.0'