2016-04-23 142 views
0

我有一个Android应用程序,当在调试模式下运行时,显示谷歌地图罚款。但是,在发布模式下运行(通过单击左下方的菜单图标并选择“生成变体” - >“发布”)不会显示地图。根据相关帖子中的其他人推荐,将硬编码的API密钥放入manifest.xml和google_maps_api.xml中,但仍然无效。尝试运行发行版时获取大量错误消息。下面是一个示例:谷歌地图仍然没有显示在Android应用程序

04-23 13:31:34.562 10519-10612/? E/b? Authentication failed on the server. 
04-23 13:31:34.563 10519-10612/? E/Google Maps Android API? Authorization failure. Please see https://developers.google.com/maps/documentation/android/start for how to correctly set up the map. 
04-23 13:31:34.568 10519-10612/? E/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: AIzaSyDRtOnaTU1Jc-zxuirnbyNojZn9uasd7eE 
    Android Application (<cert_fingerprint>;<package_name>): 1D:9A:59:E7:67:94:D0:38:80:96:35:E9:A8:90:18:17:3C:56:19:4D;owner.example.com.locator 
04-23 13:31:35.361  263-339/? E/Vold? Failed to find mounted volume for /storage/sdcard1/Android/data/com.apalon.weatherlive.free/cache/ 
04-23 13:31:35.364  263-339/? E/Vold? Failed to find mounted volume for /storage/sdcard1/Android/data/com.apalon.weatherlive.free/cache/ 
04-23 13:31:35.366  263-339/? E/Vold? Failed to find mounted volume for /storage/sdcard1/Android/data/com.apalon.weatherlive.free/cache/ 
04-23 13:31:35.572 10746-10746/? E/helpmorelib#? init 
04-23 13:31:35.583 10746-10746/? A/Adjust? PRODUCTION: Adjust is running in Production mode. Use this setting only for the build that you want to publish. Set the environment to `sandbox` if you want to test your app! 
04-23 13:31:35.720 10746-10787/? E/ActivityThread? Failed to find provider info for com.facebook.katana.provider.AttributionIdProvider 
04-23 13:31:35.832 2119-2137/? E/DataBuffer? Internal data leak within a DataBuffer object detected! Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them. (internal object: [email protected]) 
04-23 13:31:35.832 2119-2137/? E/DataBuffer? Internal data leak within a DataBuffer object detected! Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them. (internal object: [email protected]) 
04-23 13:31:35.832 2119-2137/? E/DataBuffer? Internal data leak within a DataBuffer object detected! Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them. (internal object: [email protected]) 
04-23 13:31:35.833 2119-2137/? E/DataBuffer? Internal data leak within a DataBuffer object detected! Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them. (internal object: [email protected]) 
04-23 13:31:35.833 2119-2137/? E/DataBuffer? Internal data leak within a DataBuffer object detected! Be sure to explicitly call release() on all DataBuffer extending objects when you are done with them. (internal object: [email protected]) 
04-23 13:31:35.915  263-339/? E/Vold? Failed to find mounted volume for /storage/sdcard1/Android/data/com.apalon.weatherlive.free/cache/ 
04-23 13:31:35.957  263-339/? E/Vold? Failed to find mounted volume for /storage/sdcard1/Android/data/com.apalon.weatherlive.free/cache/ 
04-23 13:31:39.320  829-1260/? E/WifiStateMachine? WifiStateMachine CMD_START_SCAN source 10022 txSuccessRate=11.27 rxSuccessRate=10.39 targetRoamBSSID=any RSSI=-29 
04-23 13:31:39.323  829-1260/? E/WifiStateMachine? [1,461,414,699,323 ms] noteScanStartWorkSource{1000} uid 10022 

15666-15666/? E/GMPM? GoogleService failed to initialize, status: 10, Missing an expected resource: 'R.string.google_app_id' for initializing Google services. Possible causes are missing google-services.json or com.google.gms.google-services gradle plugin. 

正如你会看到,如果你看一下下面的代码,错误消息引用了关键的是那里的文件。 此外,我不明白关于缺少资源的最后一条消息(上图)。

我刚刚构建了应用程序ahain,这次是在调试模式下,它工作得很好,但有趣的是我仍然得到了无数的错误消息,几乎没有一个对我有任何意义。

在调试模式下构建时,我将以下文件与相同的文件进行了比较,它们看上去完全相同。我应该做什么的任何想法?谢谢。

AndroidManifest.xml中

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

    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> 
    <!-- 
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use 
     Google Maps Android API v2, but are recommended. 
    --> 
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/earthicon" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <meta-data 
      android:name="com.google.android.gms.version" 
      android:value="@integer/google_play_services_version" /> 
     <meta-data 
      android:name="com.google.android.maps.v2.API_KEY" 
      android:value="AIzaSyDRtOnaTU1Jc-zxuirnbyNojZn9uasd7eE" /> 

     <activity 
      android:name=".LocateMe" 
      android:label="@string/title_activity_locate_me" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

主程序文件

package owner.example.com.locator; 

import android.Manifest; 
import android.annotation.TargetApi; 
import android.content.DialogInterface; 
import android.content.pm.PackageManager; 
import android.location.Criteria; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Build; 
import android.support.annotation.NonNull; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.app.FragmentActivity; 
import android.os.Bundle; 
import android.support.v7.app.AlertDialog; 
import android.widget.Toast; 
import java.math.BigDecimal; 

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.adjust.sdk.Adjust; 
//import com.adjust.sdk.AdjustConfig; 

public class LocateMe extends FragmentActivity implements OnMapReadyCallback, LocationListener { 

    private GoogleMap mMap; 

    private static final int PERMISSION_REQUEST_CODE = 1340; // can be any code you want 
    private LocationManager mLocationManager; 
    Criteria criteria = new Criteria(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     //String environment = AdjustConfig.ENVIRONMENT_SANDBOX; 
     setContentView(R.layout.activity_locate_me); 
     mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE); 
     AppData.locman = mLocationManager; 
     //Criteria criteria = new Criteria(); 
     //AppData.crit = criteria; 
     // 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); 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
    { 
     super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
     switch (requestCode) { 
      case PERMISSION_REQUEST_CODE: 
       if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
         != PackageManager.PERMISSION_GRANTED 
         && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) 
         != PackageManager.PERMISSION_GRANTED) 
       { 
        mMap.setMyLocationEnabled(true); 
       } else { 
        AlertDialog dialog = new AlertDialog.Builder(this) 
          .setTitle("Permission needed") 
          .setMessage("Sorry but we need permission to access your location") 
          .setPositiveButton("Grant", new DialogInterface.OnClickListener() { 
           @TargetApi(Build.VERSION_CODES.M) 
           @Override 
           public void onClick(DialogInterface dialog, int which) { 
            String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}; 
            requestPermissions(permissions, PERMISSION_REQUEST_CODE); 
           } 
          }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
           @Override 
           public void onClick(DialogInterface dialog, int which) { 
            finish(); 
           } 
          }).create(); 
        dialog.show(); 
       } 
     } 
    } 

    /** 
    * 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. 
    */ 
    @TargetApi(Build.VERSION_CODES.M) 
    @Override 
    public void onMapReady(GoogleMap googleMap) { 
     mMap = googleMap; 
     mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); 
     mMap.getUiSettings().setMyLocationButtonEnabled(true); 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
       != PackageManager.PERMISSION_GRANTED 
       && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) 
       != PackageManager.PERMISSION_GRANTED) 
     { 
      String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}; 
      requestPermissions(permissions, PERMISSION_REQUEST_CODE); 
      return; 
     } 
     mMap.setMyLocationEnabled(true); 
     Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
     AppData.loc = location; 
     if (location != null) { 
      LatLng myLastPosition = new LatLng(location.getLatitude(), location.getLongitude()); 
      mMap.moveCamera(CameraUpdateFactory.newLatLng(myLastPosition)); 
      mMap.animateCamera(CameraUpdateFactory.zoomTo(17)); 

      for (int i=0; i<2; i++) 
      { 
       Toast.makeText(this, 
         getFL(location.getLatitude(),location.getLongitude()) + "\n" 
           + BigDecimal.valueOf(AppData.loc.getLatitude()).setScale(5, 
           BigDecimal.ROUND_HALF_UP).toPlainString() + "  " 
           + BigDecimal.valueOf(AppData.loc.getLongitude()).setScale(5, 
           BigDecimal.ROUND_HALF_UP).toPlainString(), 
         Toast.LENGTH_LONG).show(); 
      }; 
     } 
     mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, this); 

     // Location button click listener will show Lat & Long when button clicked 
     mMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() 
     { 
      @Override 
      public boolean onMyLocationButtonClick() 
      { 
       try { 
        AppData.loc = AppData.locman.getLastKnownLocation(AppData.locman.getBestProvider 
          (criteria, false)); 
        Toast.makeText(getApplicationContext(), 
          getFL(AppData.loc.getLatitude(), AppData.loc.getLongitude()) + "\n" 
            + BigDecimal.valueOf(AppData.loc.getLatitude()).setScale(5, 
            BigDecimal.ROUND_HALF_UP).toPlainString() + "  " 
            + BigDecimal.valueOf(AppData.loc.getLongitude()).setScale(5, 
            BigDecimal.ROUND_HALF_UP).toPlainString(), 
          Toast.LENGTH_LONG).show(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
        Toast.makeText(getApplicationContext(), 
          "GPS Problem!", 
          Toast.LENGTH_LONG).show(); 
       } 
       return false; 
      } 
     }); 

    } 

    // And the following method is courtesy of 'abi', a StackOverflow contributor from Dubai 
    public static String getFL(double latitude, double longitude) 
    { 
     try { 
      int latSeconds = (int) Math.round(latitude * 3600); 
      int latDegrees = latSeconds/3600; 
      latSeconds = Math.abs(latSeconds % 3600); 
      int latMinutes = latSeconds/60; 
      latSeconds %= 60; 

      int longSeconds = (int) Math.round(longitude * 3600); 
      int longDegrees = longSeconds/3600; 
      longSeconds = Math.abs(longSeconds % 3600); 
      int longMinutes = longSeconds/60; 
      longSeconds %= 60; 
      String latDegree = latDegrees >= 0 ? "N" : "S"; 
      String lonDegree = longDegrees >= 0 ? "E" : "W"; 

      return Math.abs(latDegrees) + "° " + latMinutes + "' " + latSeconds 
        + "\"" + latDegree + " " + Math.abs(longDegrees) + "° " + longMinutes 
        + "' " + longSeconds + "\"" + lonDegree; 
     } catch (Exception e) { 

      return "" + String.format("%8.5f", latitude) + "\n" 
        + String.format("%8.5f", longitude); 
     } 
    } 



    @Override 
    public void onLocationChanged(Location location) { 
     LatLng myLastPosition = new LatLng(location.getLatitude(), location.getLongitude()); 
     mMap.moveCamera(CameraUpdateFactory.newLatLng(myLastPosition)); 
     float zoomvalue = mMap.getCameraPosition().zoom; 
     mMap.animateCamera(CameraUpdateFactory.zoomTo(zoomvalue)); 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 

    } 

    @Override 
    public void onProviderEnabled(String provider) { 

    } 

    @Override 
    public void onProviderDisabled(String provider) { 

    } 
} 

google_maps_api.xml文件

<resources> 
<!-- 
TODO: Before you run your application, you need a Google Maps API key. 

To get one, follow this link, follow the directions and press "Create" at the end: 

https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=6F:57:6E:22:FE:D8:BD:E9:C4:23:33:A9:1D:E5:C6:E9:6F:F8:5F:BD%3Bowner.example.com.locator 

You can also add your credentials to an existing key, using this line: 
6F:57:6E:22:FE:D8:BD:E9:C4:23:33:A9:1D:E5:C6:E9:6F:F8:5F:BD;owner.example.com.locator 

Once you have your key (it starts with "AIza"), replace the "google_maps_key" 
string in this file. 
--> 
<string name="google_maps_key" translatable="false" templateMergeStrategy="preserve"> 
    AIzaSyDRtOnaTU1Jc-zxuirnbyNojZn9uasd7eE 
</string> 
</resources> 

的build.gradle(模块:应用程序)文件

apply plugin: 'com.android.application' 

android { 
signingConfigs { 
    config { 
     keyAlias 'myreleasekey' 
     keyPassword 'xxxxxxxx' 
     storeFile file('C:/Users/Owner/AndroidStudioProjects/release.jks') 
     storePassword 'xxxxxxxx' 
    } 
} 
compileSdkVersion 23 
buildToolsVersion "23.0.1" 
useLibrary 'org.apache.http.legacy' 
defaultConfig { 
    applicationId "owner.example.com.locator" 
    minSdkVersion 19 
    targetSdkVersion 23 
    versionCode 1 
    versionName "1.0" 
    signingConfig signingConfigs.config 
} 
buildTypes { 
    release { 
     minifyEnabled true 
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
    } 
    debug { 
    } 
} 
productFlavors { 
} 
} 

dependencies { 
compile fileTree(include: ['*.jar'], dir: 'libs') 
compile 'com.android.support:appcompat-v7:23.0.1' 
compile 'com.google.android.gms:play-services:+' 
} 

回答

0

在我看来,你需要一个释放键。对于Google Maps API v2,您需要使用SHA-1指纹。所以:

  • 使用密钥工具创建应用的释放证明
  • 获得再次使用密钥工具释放证书SHA-1指纹;
  • 创建您的发布API密钥并将SHA-1添加到它。

所有这一切都可以发现here

+0

谢谢Iain,但build.gradle文件中的东西并不显示我已经有一个API密钥?我以为我完全按照程序进行,但必须承认并不完全了解这一过程。你是否建议我重新开始? –

+1

John先前添加的API密钥是由开发环境中使用的调试SHA-1生成的。正如@lain所说,为了释放目的,您需要释放密钥的SHA-1所产生的API密钥。 – nitinkumarp

+0

你是否设法解决它约翰? – Iain

0

除了SHA键,您应该启用地图在Google account API访问。点击“Google Maps Android API”,然后点击“启用”。

相关问题