【问题标题】:Showing white screen on maps fragment but running perfectly on Emulator在地图片段上显示白屏但在模拟器上完美运行
【发布时间】:2018-08-18 16:17:11
【问题描述】:

当我在 Android 设备上运行应用程序时,我在我的应用程序中使用 Google 地图,显示左下方带有 Google 徽标的白屏。但是当我在模拟器上运行它时,可以完美地显示地图

这里是 MapsActivity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:id="@+id/appBarLayout">

    <include layout="@layout/main_app_bar_layout"
        android:id="@+id/main_page_toolbar" />

</android.support.design.widget.AppBarLayout>

<android.support.v4.widget.DrawerLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/drawerLayout"
    android:layout_marginTop="@dimen/cast_libraries_material_featurehighlight_inner_radius">

    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_below="@id/main_page_toolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MapsActivity"
        tools:ignore="NotSibling" />



    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_home"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        app:menu="@menu/navigation_menu"
        android:layout_gravity="start"
        app:headerLayout="@layout/navigation_header_layout">

    </android.support.design.widget.NavigationView>

</android.support.v4.widget.DrawerLayout>

</RelativeLayout>

这里是 MapsActivity.java

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

// toolbar instance
private android.support.v7.widget.Toolbar mToolbar;
RelativeLayout rootLayout;
private DrawerLayout mDrawerlayout;
private ActionBarDrawerToggle mToggle;
private NavigationView mNavigationView;


//Request code
private static final int PERMISSION_REQUEST_CODE = 1998;
private static final int PLAY_SERVICES_REQUEST_CODE = 1999;

//Google APi client
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private Location mLastLocation;
Marker mCurrentMarker;
private GoogleMap mMap;
double lattitude, longitude;

//Map intervals
private static int UPDATE_INTERVAL = 5000;
private static int FASTEST_INTERVAL = 3000;
private static int DISPLACEMENT = 10;

//Firebase
DatabaseReference mUserDatabase, locationDatabaseRef;
private FirebaseAuth mAuth;


@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_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);


    //Custom Toolbar
    mToolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.main_page_toolbar);
    setSupportActionBar(mToolbar);
    getSupportActionBar().setTitle("Control Child");

    mDrawerlayout = (DrawerLayout) findViewById(R.id.drawerLayout);
    mToggle = new ActionBarDrawerToggle(this, mDrawerlayout, R.string.open, R.string.close);
    mDrawerlayout.addDrawerListener(mToggle);
    mToggle.syncState();
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    // Firebase initialization
    mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
    locationDatabaseRef = FirebaseDatabase.getInstance().getReference().child("Locations");

    mNavigationView = (NavigationView) findViewById(R.id.navigation_home);

    mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {

            if (menuItem.getItemId() == R.id.navigationAccount) {

                Intent profileIntent = new Intent(MapsActivity.this, ProfileActivity.class);
                startActivity(profileIntent);
                mDrawerlayout.closeDrawers();
            }
            if (menuItem.getItemId() == R.id.navigationSettings) {

                Intent settingsIntent = new Intent(MapsActivity.this, SettingsActivity.class);
                startActivity(settingsIntent);
                mDrawerlayout.closeDrawers();
            }
            if (menuItem.getItemId() == R.id.navigationContact) {

            }

            return false;
        }
    });

    mAuth = FirebaseAuth.getInstance();

    //set contentView
    CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
            .setDefaultFontPath("fonts/Arkhip_font.ttf")
            .setFontAttrId(R.attr.fontPath)
            .build()
    );

    setUpLocation();

}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    switch (requestCode) {

        case PERMISSION_REQUEST_CODE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                if (checkPlayServices()) {

                    buildGoogleApiClient();
                    createLocationRequest();
                    displayLocation();

                }
            }

            break;

    }
}

private void setUpLocation() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        requestRuntimePermission();
    } else {
        if (checkPlayServices()) {
            buildGoogleApiClient();
            createLocationRequest();
            displayLocation();
        }
    }
}

private void displayLocation() {

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

    if (mLastLocation != null) {
        lattitude = mLastLocation.getLatitude();
        longitude = mLastLocation.getLongitude();

        //Updating to firebase

        locationDatabaseRef.child(mAuth.getCurrentUser().getUid())
                .setValue(new Tracking(mAuth.getCurrentUser().getEmail(),
                        mAuth.getCurrentUser().getUid(),
                        String.valueOf(mLastLocation.getLatitude()),
                        String.valueOf(mLastLocation.getLongitude())));


        mMap.clear();
        mCurrentMarker = mMap.addMarker(new MarkerOptions()
                .position(new LatLng(lattitude, longitude))
                .title("You are Here"));
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lattitude, longitude), 12.02f));


        /*if(!hasAnimated){
            hasAnimated = true;
        }else {
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lattitude, longitude), 12.02f));
        }*/
    }

}

private void createLocationRequest() {

    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}

protected synchronized void buildGoogleApiClient() {

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();

}

private boolean checkPlayServices() {

    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    if (resultCode != ConnectionResult.SUCCESS) {
        if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {

            GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_REQUEST_CODE).show();

        } else {

            Toast.makeText(this, "This device is not supported", Toast.LENGTH_SHORT).show();
            finish();

        }
        return false;
    }
    return true;

}

private void requestRuntimePermission() {

    ActivityCompat.requestPermissions(this, new String[]{
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION
    }, PERMISSION_REQUEST_CODE);

}

private void startLocationUpdates() {

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

    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}


@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    mMap.getUiSettings().setMapToolbarEnabled(false);

    mMap.getUiSettings().setMyLocationButtonEnabled(true);

}

@Override
public void onConnected(@Nullable Bundle bundle) {
    displayLocation();
    startLocationUpdates();
}

@Override
public void onConnectionSuspended(int i) {
    mGoogleApiClient.connect();
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

@Override
public void onLocationChanged(Location location) {

    mLastLocation = location;
    displayLocation();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    getMenuInflater().inflate(R.menu.main_menu, menu);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    super.onOptionsItemSelected(item);

    if (item.getItemId() == R.id.connect_item) {

        AlertDialog.Builder dialog = new AlertDialog.Builder(this);
        dialog.setTitle("Make Connection");
        dialog.setMessage("Please use ID shown in profile");

        LayoutInflater inflater = LayoutInflater.from(this);
        final View connect_layout = inflater.inflate(R.layout.connect_layout, null);

        final MaterialEditText connectID = connect_layout.findViewById(R.id.connect_id);

        dialog.setView(connect_layout);

        dialog.setPositiveButton("Connect", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();

                //validation
                if (TextUtils.isEmpty(connectID.getText().toString())) {
                    Snackbar.make(rootLayout, "Please enter ID", Snackbar.LENGTH_SHORT)
                            .show();
                    return;
                }

                mUserDatabase.orderByChild("uniqueID").equalTo(connectID.getText().toString())
                        .addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                if (dataSnapshot.exists()) {


                                    // giving connected user data Log.d("QueryLog",dataSnapshot.getValue().toString());
                                    // Getting lattitude and longitude
                                    //Log.d("userLoc", dataSnapshot.getValue().);
                                    //Log.d("LocationIser", locationDatabaseRef.child(dataSnapshot.getValue().toString()) + "/" +  );
                                    Toast.makeText(MapsActivity.this, "Yo ! Connected Successfully", Toast.LENGTH_SHORT).show();

                                } else {

                                    Toast.makeText(MapsActivity.this, "User Not Exist", Toast.LENGTH_SHORT).show();

                                }
                            }

                            @Override
                            public void onCancelled(DatabaseError databaseError) {

                            }
                        });
            }
        });


        // this is cancel btn for dialog
        dialog.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

        dialog.show();

    }

    // Logout is here

    if (item.getItemId() == R.id.logout) {
        FirebaseAuth.getInstance().signOut();
        Intent MainIntent = new Intent(MapsActivity.this, StartActivity.class);
        startActivity(MainIntent);
        finish();
    }

    if (mToggle.onOptionsItemSelected(item)) {
        return true;
    }

    return true;

}

}

这里是 Android Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="MY_PACKAGE_NAME">

<!--
     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" />

<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=".StartActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <!--
         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=".MapsActivity"
        android:label="@string/title_activity_maps" />
    <activity
        android:name=".ProfileActivity"
        android:parentActivityName=".MapsActivity"/>
    <activity android:name=".SettingsActivity"
        android:parentActivityName=".MapsActivity">
    </activity>
</application>

</manifest>

这里我附上了两个条件的截图

  1. 当应用在 Android 设备上运行时:设备映像

[Device Image]

  1. 当应用在模拟器上运行时:模拟器图像

[Emulator Image]

这是在模拟器中使用 Signed Release Apk 时出现的 Logcat 错误:

Google Maps Android API: Authorization failure.  Please see https://developers.google.com/maps/documentation/android-api/start for how to correctly set up the map.
Google Maps Android API: In the Google Developer Console (https://console.developers.google.com)
Ensure that the "Google Maps Android API v2" is enabled.
Ensure that the following Android Key exists:
    API Key: YOUR_KEY_HERE

我已启用“Google Maps Android API”。并且 API 密钥存在。 但是,我没有找到“Google Maps Android API v2”。和“Google Maps Android API”一样吗?

【问题讨论】:

  • 设备上是否安装了 Google Play 服务?
  • 不是这一定是答案,但是您是否在 Android 清单 XML 文件中声明了您的 Google API 密钥?
  • @ArthurAttout Play 服务已安装
  • @TimBiegeleisen 谢谢,我在 Android Manifest 中声明了 API KEY 并尝试重新生成新的 API 密钥。但错误未解决
  • 发布你的 manifest.xml

标签: android google-maps firebase


【解决方案1】:

在您的 Manifest.xml 中,您必须像这样重命名活动:

android:name="com.project.me.appname.Activitys.MapsActivity"

【讨论】:

  • 感谢您在这里回答。你的观点是正确的,我已经按照你所说的做了,并且还在 Manifest.xml 中粘贴了 GOOGLE_MAPS_API_KEY。之后,我在 Google Developer Console -> Credentials ->“API 限制”中为调试和发布的 apk 添加了 SHA-1。而且,这解决了我的问题。
【解决方案2】:

在 google maps api 仪表板上为 signed Apk 添加 SHA-1 指纹解决了我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 2018-02-16
    • 2022-10-05
    • 2021-06-04
    • 2012-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多