【发布时间】:2020-05-17 06:22:54
【问题描述】:
访问地图活动时,它会崩溃。我尝试使用通用的 Maps Activity 来切换 Activity,它确实有效,但我已经回滚到以前的版本,但我知道该版本无济于事。
这是 Android Java:
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentActivity;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Camera;
import android.location.Location;
import com.firebase.geofire.GeoFire;
import com.firebase.geofire.GeoLocation;
import com.google.android.gms.location.LocationListener;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApi;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.internal.GoogleApiAvailabilityCache;
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.MarkerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
public class DriverMapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleMap mMap;
GoogleApiClient mGoogleApiClient;
Location driverLastLocation;
LocationRequest driverLocationRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_driver_maps);
// 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);
Button buttonLogout = findViewById(R.id.buttonLogout);
buttonLogout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FirebaseAuth.getInstance().signOut();
Intent intent = new Intent(DriverMapsActivity.this, MainActivity.class);
startActivity(intent);
finish();
return;
}
});
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
protected synchronized void buildGoogleApiClient(){
mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
mGoogleApiClient.connect();
}
@Override
public void onLocationChanged(Location location) {
driverLastLocation = location;
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
String userID = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("driversClear");
GeoFire geoFire = new GeoFire(ref);
geoFire.setLocation(userID, new GeoLocation(location.getLatitude(), location.getLongitude()));
}
@Override
public void onConnected(@Nullable Bundle bundle) {
driverLocationRequest = new LocationRequest();
driverLocationRequest.setInterval(1000);
driverLocationRequest.setFastestInterval(2000);
driverLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, driverLocationRequest, (com.google.android.gms.location.LocationListener) this);
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onStop(){
super.onStop();
String userID = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("driversClear");
GeoFire geoFire = new GeoFire(ref);
geoFire.removeLocation(userID);
}
}
我是 Android Dev 的新手,所以我不确定它是否对调试这类问题特别重要,但这是布局 XML 的事情
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DriverMapsActivity" >
<Button
android:id="@+id/buttonLogout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Logout" />
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
我不确定是否应该分享 AndroidManifest,但我觉得它很重要
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".CustomerMapsActivity" >
</activity>
<activity android:name=".TestClass" />
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".DriverMapsActivity"
android:label="@string/title_activity_driver_maps" />
<activity android:name=".DriverLogin" />
<activity android:name=".DriverRegistration" />
<activity android:name=".CustomerLogin" />
<activity android:name=".CustomerRegistration" />
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
另外,如果有人能告诉我为什么内置调试器没有通知我这个错误,我会很感激(因为我需要切换设置或安装额外的东西吗?)
谢谢
【问题讨论】:
-
logcat 中的错误是什么?
-
您尝试在Logcat中查看是否有crash的错误日志?
-
@MMG java.lang.SecurityException: 我的位置需要权限 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 这是错误,但我已经在清单中拥有此权限...
-
好的,看我的回答
-
@MMG 感谢您有兴趣帮助我,解决方案是未授予应用程序权限(我没有为用户编写代码来授予权限)。当我在应用程序设置中手动授予权限时,它可以工作。再次感谢您的支持!
标签: java android firebase android-studio google-maps