【问题标题】:My Maps Activity crashes as soon as it loads [duplicate]我的地图活动在加载后立即崩溃[重复]
【发布时间】: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


【解决方案1】:

您能否检查“运行”选项卡是否有错误,而不是 Logcat。如果应用一启动就崩溃,日志可能会显示在“运行”选项卡中。

【讨论】:

  • 好的! java.lang.SecurityException:我的位置需要权限 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 我已经在 Manifest 中添加了权限,所以我不确定它为什么会抛出此消息...
  • 位置权限是危险权限。它们需要运行时权限授予。如果未给出,则会引发安全异常。您可以参考此来源。 medium.com/programming-lite/…
  • 感谢您的文章!我需要授予权限!我进入应用程序设置并手动授予权限,它工作!我需要研究如何向用户请求权限,但这就是它不起作用的原因(我实际上不记得昨天授予权限,所以我不确定它是如何工作的)。感谢您的支持!
  • 很高兴我能帮上忙。
猜你喜欢
  • 2020-07-01
  • 2018-02-06
  • 2021-08-02
  • 2015-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多