地图片段在 Android 中不工作
Map Fragment not working in Android
我已经尝试了一千种配置和代码,但我的地图 activity 坚持不工作。我尝试过的事情:
AndroidManifest.xml
- 启用访问权限(互联网、ACCESS_FINE_LOCATION、READ_GSERVICES 等);
- 启用 OpenGL(android:glEsVersion="0x00020000" 等);
- 提供了两个密钥(com.google.android.geo.API_KEY 和 com.google.android.maps.v2.API_KEY),直接键入 AndroidManifest 并在调试中通过 xml 值引用它释放文件夹 (@string/map_api);
- 尝试使用地图库(uses-library android:name="com.google.android.maps");
- 试图包含权限标签 uses-permission (...permission.MAPS_RECEIVE);
- 已尝试通知服务版本 (android:name="com.google.android.gms.version");
- 试图在 .android 文件夹下为自己的证书和 android.keystore 生成密钥;
文件:
<manifest package="com.myapp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:anrdroid="http://schemas.android.com/apk/res-auto">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="@drawable/logo"
android:label="@string/name"
android:supportsRtl="true"
android:name="android.support.multidex.MultiDexApplication"
android:theme="@style/Default">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key"/>
<activity
android:name=".view.MainActivity"
android:icon="@drawable/logo"
android:label="@string/name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".view.ActivityMap"
android:icon="@drawable/logo_row"
android:label="@string/name">
</activity>
...
</application>
</manifest>
build.gradle
- 尝试了不同的编译和构建配置(23、22、19 等);
- 尝试了不同的库版本(8.4.0、7.80 等);
- 为 appcompat 库尝试了不同的库版本(23.2.1、22.2.1 等);
- 仅对映射和依赖项使用选择性编译或Google服务完成;
- 尝试使用相同和不同的密钥签署调试和发布;
文件:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion '23.0.2'
defaultConfig {
applicationId "com.myapp"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "0.0.1"
multiDexEnabled true
}
signingConfigs {
keystore {
storeFile file("path_to_keystore")
storePassword "my_password"
keyAlias "my_key_alias"
keyPassword "my_password"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.keystore
}
}
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
exclude 'META-INF/io.netty.versions.properties'
exclude 'META-INF/INDEX.LIST'
}
dexOptions {
javaMaxHeapSize "2g"
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
compile 'com.google.android.gms:play-services-maps:8.4.0'
compile 'com.datastax.cassandra:cassandra-driver-mapping:3.0.0'
compile 'com.fasterxml.jackson.core:jackson-core:2.5.4'
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.4'
}
代码
- 试图扩展 AppCompat、FragmentActivity;
- 试图在 api 6 中使用 ActivityCompat.requestPermissions();
请求许可
- 尝试调用 MapsInitializer.initialize() 并检查 return;
- 尝试在布局文件中仅使用片段,通知上下文等;
- 尝试在 FragmentLayout 中使用片段;
个文件:
public class ActivityMap extends FragmentActivity implements OnMapReadyCallback
{
private GoogleMap map;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.activityMapID);
fragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap)
{
map = googleMap;
map.addMarker(new MarkerOptions().position(new LatLng(-34, 151)).title("Marker in Sydney"));
}
}
activity_map.xml:
<fragment android:id="@+id/activityMapID"
android:name="com.google.android.gms.maps.SupportMapFragment"
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"/>
其他
- 检查了我的网络连接和防火墙;
- 检查密钥是否可用并在 Google 控制台中工作;
- 多次尝试为 Android Studio 清理、重建项目和使缓存无效;
- 尝试擦除数据、重启和清理设备(并在不止一台设备上测试过);
- 使用 "adb shell pm clear ...";
通过 adb 删除了应用程序
- 没有空指针,onMapReady return是一个有效的地图和调试代码,一切正常;
- 如果我使用 Android Studio 创建一个新的地图应用程序,一切正常;
在第一次通话中,我有这个日志:
03-21 09:34:28.478 25570-26174/com.myapp I/LoadedApk: connected(), package name=com.google.android.gms ,class name=com.google.android.gms.maps.auth.ApiTokenService
03-21 09:34:29.770 25570-25570/com.myapp I/Choreographer: Skipped 127 frames! The application may be doing too much work on its main thread.
03-21 09:34:30.020 25570-27391/com.myapp I/b: Sending API token request.
03-21 09:34:30.090 25570-25633/com.myapp I/LoadedApk: connected(), package name=com.google.android.gms ,class name=com.google.android.location.internal.GoogleLocationManagerService
03-21 09:34:31.231 25570-27391/com.myapp I/b: Received API Token: AH0uPGGIx9Ygap4ZXq8T8vK7qcPxgyDi5NRIaIPyPauG4xWFn1lI7KQF9IuY2yqbpYMhWitKnTUiU-sZD9tFdJvr1naCVhz3c9APmLbueopuhcD6K5LHpZKnkYCQDEefhrTeGPNOR0fdz0QmC4WD8rkgQTbLmfbnOIA7cvZZBOmn7hFmcyavIVRQZlaY9_OLaPMFxIVFVBml / Expires in: 432000000ms
03-21 09:34:31.241 25570-27391/com.myapp I/c: Scheduling next attempt in 431700 seconds.
03-21 09:34:31.251 25570-27391/com.myapp I/d: Saved auth token
03-21 09:34:31.832 25570-25582/com.myapp I/LoadedApk: connected(), package name=com.google.android.gms ,class name=com.google.android.gms.clearcut.service.ClearcutLoggerService
然后在第二次调用后,我收到消息说我的密钥无效:
03-21 09:35:22.596 25570-25633/com.myapp I/LoadedApk: connected(), package name=com.google.android.gms ,class name=com.google.android.gms.clearcut.service.ClearcutLoggerService
03-21 09:35:37.762 25570-25570/com.myapp I/Google Maps Android API: Google Play services package version: 8703034
03-21 09:35:37.973 25570-28472/com.myapp E/Google Maps Android API: Failed to load map. Error contacting Google servers. This is probably an authentication issue (but could be due to network errors).
03-21 09:35:38.363 25570-25582/com.myapp I/LoadedApk: connected(), package name=com.google.android.gms ,class name=com.google.android.location.internal.GoogleLocationManagerService
我真的不知道该怎么办了。有人知道会发生什么吗?
提前致谢。
尝试在 build.radle
的末尾添加这一行
apply plugin: 'com.google.gms.google-services'
将其添加到 manifest
标签内:
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" >
</uses-feature>
终于找到问题了
在我的代码的另一部分,我正在调用
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
为了简化我为 HTTPS 所做的所有调用。问题是当 Google 地图试图调用其服务器时:它使用的是我之前设置的相同 SSL 上下文,因此它无法连接到地图服务器。
我刚刚评论了那行并将我的代码更改为:
URLConnection urlConn = new URL(myAddress).openConnection();
HttpsURLConnection https = (HttpsURLConnection) urlConn;
https.setSSLSocketFactory(sslContext.getSocketFactory());
一切都像变魔术一样有效!
谢谢大家!
我已经尝试了一千种配置和代码,但我的地图 activity 坚持不工作。我尝试过的事情:
AndroidManifest.xml
- 启用访问权限(互联网、ACCESS_FINE_LOCATION、READ_GSERVICES 等);
- 启用 OpenGL(android:glEsVersion="0x00020000" 等);
- 提供了两个密钥(com.google.android.geo.API_KEY 和 com.google.android.maps.v2.API_KEY),直接键入 AndroidManifest 并在调试中通过 xml 值引用它释放文件夹 (@string/map_api);
- 尝试使用地图库(uses-library android:name="com.google.android.maps");
- 试图包含权限标签 uses-permission (...permission.MAPS_RECEIVE);
- 已尝试通知服务版本 (android:name="com.google.android.gms.version");
- 试图在 .android 文件夹下为自己的证书和 android.keystore 生成密钥;
文件:
<manifest package="com.myapp" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:anrdroid="http://schemas.android.com/apk/res-auto"> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <application android:allowBackup="true" android:icon="@drawable/logo" android:label="@string/name" android:supportsRtl="true" android:name="android.support.multidex.MultiDexApplication" android:theme="@style/Default"> <meta-data android:name="com.google.android.geo.API_KEY" android:value="@string/google_maps_key"/> <activity android:name=".view.MainActivity" android:icon="@drawable/logo" android:label="@string/name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".view.ActivityMap" android:icon="@drawable/logo_row" android:label="@string/name"> </activity> ... </application> </manifest>
build.gradle
- 尝试了不同的编译和构建配置(23、22、19 等);
- 尝试了不同的库版本(8.4.0、7.80 等);
- 为 appcompat 库尝试了不同的库版本(23.2.1、22.2.1 等);
- 仅对映射和依赖项使用选择性编译或Google服务完成;
- 尝试使用相同和不同的密钥签署调试和发布;
文件:
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion '23.0.2' defaultConfig { applicationId "com.myapp" minSdkVersion 16 targetSdkVersion 23 versionCode 1 versionName "0.0.1" multiDexEnabled true } signingConfigs { keystore { storeFile file("path_to_keystore") storePassword "my_password" keyAlias "my_key_alias" keyPassword "my_password" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.keystore } } packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' exclude 'META-INF/io.netty.versions.properties' exclude 'META-INF/INDEX.LIST' } dexOptions { javaMaxHeapSize "2g" } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.2.1' compile 'com.android.support:design:23.2.1' compile 'com.google.android.gms:play-services-maps:8.4.0' compile 'com.datastax.cassandra:cassandra-driver-mapping:3.0.0' compile 'com.fasterxml.jackson.core:jackson-core:2.5.4' compile 'com.fasterxml.jackson.core:jackson-databind:2.5.4' }
代码
- 试图扩展 AppCompat、FragmentActivity;
- 试图在 api 6 中使用 ActivityCompat.requestPermissions(); 请求许可
- 尝试调用 MapsInitializer.initialize() 并检查 return;
- 尝试在布局文件中仅使用片段,通知上下文等;
- 尝试在 FragmentLayout 中使用片段;
个文件:
public class ActivityMap extends FragmentActivity implements OnMapReadyCallback { private GoogleMap map; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map); SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.activityMapID); fragment.getMapAsync(this); } @Override public void onMapReady(GoogleMap googleMap) { map = googleMap; map.addMarker(new MarkerOptions().position(new LatLng(-34, 151)).title("Marker in Sydney")); } }
activity_map.xml:
<fragment android:id="@+id/activityMapID"
android:name="com.google.android.gms.maps.SupportMapFragment"
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"/>
其他
- 检查了我的网络连接和防火墙;
- 检查密钥是否可用并在 Google 控制台中工作;
- 多次尝试为 Android Studio 清理、重建项目和使缓存无效;
- 尝试擦除数据、重启和清理设备(并在不止一台设备上测试过);
- 使用 "adb shell pm clear ..."; 通过 adb 删除了应用程序
- 没有空指针,onMapReady return是一个有效的地图和调试代码,一切正常;
- 如果我使用 Android Studio 创建一个新的地图应用程序,一切正常;
在第一次通话中,我有这个日志:
03-21 09:34:28.478 25570-26174/com.myapp I/LoadedApk: connected(), package name=com.google.android.gms ,class name=com.google.android.gms.maps.auth.ApiTokenService
03-21 09:34:29.770 25570-25570/com.myapp I/Choreographer: Skipped 127 frames! The application may be doing too much work on its main thread.
03-21 09:34:30.020 25570-27391/com.myapp I/b: Sending API token request.
03-21 09:34:30.090 25570-25633/com.myapp I/LoadedApk: connected(), package name=com.google.android.gms ,class name=com.google.android.location.internal.GoogleLocationManagerService
03-21 09:34:31.231 25570-27391/com.myapp I/b: Received API Token: AH0uPGGIx9Ygap4ZXq8T8vK7qcPxgyDi5NRIaIPyPauG4xWFn1lI7KQF9IuY2yqbpYMhWitKnTUiU-sZD9tFdJvr1naCVhz3c9APmLbueopuhcD6K5LHpZKnkYCQDEefhrTeGPNOR0fdz0QmC4WD8rkgQTbLmfbnOIA7cvZZBOmn7hFmcyavIVRQZlaY9_OLaPMFxIVFVBml / Expires in: 432000000ms
03-21 09:34:31.241 25570-27391/com.myapp I/c: Scheduling next attempt in 431700 seconds.
03-21 09:34:31.251 25570-27391/com.myapp I/d: Saved auth token
03-21 09:34:31.832 25570-25582/com.myapp I/LoadedApk: connected(), package name=com.google.android.gms ,class name=com.google.android.gms.clearcut.service.ClearcutLoggerService
然后在第二次调用后,我收到消息说我的密钥无效:
03-21 09:35:22.596 25570-25633/com.myapp I/LoadedApk: connected(), package name=com.google.android.gms ,class name=com.google.android.gms.clearcut.service.ClearcutLoggerService
03-21 09:35:37.762 25570-25570/com.myapp I/Google Maps Android API: Google Play services package version: 8703034
03-21 09:35:37.973 25570-28472/com.myapp E/Google Maps Android API: Failed to load map. Error contacting Google servers. This is probably an authentication issue (but could be due to network errors).
03-21 09:35:38.363 25570-25582/com.myapp I/LoadedApk: connected(), package name=com.google.android.gms ,class name=com.google.android.location.internal.GoogleLocationManagerService
我真的不知道该怎么办了。有人知道会发生什么吗?
提前致谢。
尝试在 build.radle
apply plugin: 'com.google.gms.google-services'
将其添加到 manifest
标签内:
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" >
</uses-feature>
终于找到问题了
在我的代码的另一部分,我正在调用
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
为了简化我为 HTTPS 所做的所有调用。问题是当 Google 地图试图调用其服务器时:它使用的是我之前设置的相同 SSL 上下文,因此它无法连接到地图服务器。
我刚刚评论了那行并将我的代码更改为:
URLConnection urlConn = new URL(myAddress).openConnection();
HttpsURLConnection https = (HttpsURLConnection) urlConn;
https.setSSLSocketFactory(sslContext.getSocketFactory());
一切都像变魔术一样有效!
谢谢大家!