studio - Android: ¿elige automáticamente la clave de API de depuración/liberación?
map fragment android studio (11)
Configuré un objetivo ant sencillo que reemplaza el apikey con una clave de depuración o una clave de liberación. Esto es realmente simple y mantiene el código libre de lógica no deseada.
<target name="apikey">
<!-- Location of target layout file -->
<first id="first">
<fileset dir="." includes="res/layout/kondi_training_templates.xml" />
</first>
<property name="layout-file" value="${toString:first}"/>
<echo>template-file: ${template-file}</echo>
<replaceregexp file="${template-file}"
match="android:apiKey=.*"
replace=''android:apiKey="${mapview.apikey}"''
byline="true"
/>
</target>
OBSOLETADO: esta vieja pregunta se refiere a la API obsoleta de Google Maps v1. Al usar la API v2, puede usar múltiples huellas dactilares de certificados en una entrada de la Consola API de Google . La clave API ya no se almacena en Manifiesto ni en el código.
¿Es posible detectar automáticamente qué certificado se utilizó para firmar APK? Me gustaría tener certificados de depuración y liberación de Mapas en la aplicación y pasar uno válido al constructor de MapView.
Con tal configuración no cometeré ningún error mientras lanzo la aplicación: estoy usando un certificado de depuración en el emulador y mi dispositivo, luego firmo con la versión uno antes de enviar la aplicación a Market.
Estaba pensando en detectar mi dispositivo en particular o si el depurador está conectado, pero no es perfecto. Tal vez alguna necesidad de marcado de archivos para el certificado de depuración? ¿Hay alguna forma mejor?
Creo que crear una entrada en la consola de la API de Google que incluya tanto su clave de liberación como su clave de depuración (ambas asignadas al mismo paquete) funciona muy bien y es una forma mucho más simple de no tener que preocuparse de si está depurando o compilando versión de lanzamiento. La solución se resume here
En Map V2 Es fácil enviar claves separadas con la herramienta Android Studio Gradle. He implementado una manera fácil para eso. por favor revisa el enlace here .
Hay una nueva forma de determinar si es una compilación de depuración o versión uno en SDK Tools, Revisión 17 . Un extracto de la nueva descripción de las características:
Las compilaciones ahora generan una clase llamada BuildConfig que contiene una constante DEBUG que se establece automáticamente de acuerdo con su tipo de compilación. Puede verificar la constante ( BuildConfig.DEBUG ) en su código para ejecutar funciones de solo depuración.
Así que ahora puedes simplemente escribir algo como esto:
if (BuildConfig.DEBUG)
{
//Your debug code goes here
}
else
{
//Your release code goes here
}
ACTUALIZACIÓN: He encontrado un error en ADT: a veces BuildConfig.DEBUG
es true
después de exportar el paquete de la aplicación. La descripción está aquí: http://code.google.com/p/android/issues/detail?id=27940
He trabajado en torno a la espantosa integración errónea de las claves api en el proceso de compilación y el control de la fuente al convertirla en una propiedad almacenada en local.properties
. Tuve que agregar lo siguiente a build.xml
:
<property name="mapviewxml" value="res/layout/mapview.xml" />
<target name="-pre-build">
<fail unless="mapsApiKey">You need to add mapsApiKey=... to local.properties</fail>
<copy file="mapview.xml.tpl" tofile="${mapviewxml}" overwrite="true">
<filterchain>
<replacetokens>
<token key="apiKey" value="${mapsApiKey}"/>
</replacetokens>
</filterchain>
</copy>
</target>
Ahora, por supuesto, tuve que crear mapview.xml.tpl
en mi raíz de proyectos (no puede ir a res/layout
porque romperá el proceso de compilación):
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="@apiKey@"
/>
Durante la precompilación, la plantilla se copia en el lugar correcto y @apiKey @ se reemplaza por la clave real. Lamentablemente, no he encontrado una manera de distinguir entre compilaciones de depuración y lanzamiento en esta fase, así que para compilar para el lanzamiento, simplemente agrego la clave api de lanzamiento a los parámetros de hormiga:
ant -DmapsApiKey=.... release
Este enfoque se integra bien con SCM (no es necesario que verifique las claves) y de manera aceptable con el proceso de compilación.
No sé si esto ayuda a alguien pero he combinado algunas de las otras sugerencias aquí para producir la siguiente MapViewActivity.
En este ejemplo R.layout.map_dbg solo se usa si se trata de una compilación de depuración y el archivo existe (agregue este archivo a su .gitignore).
Las ventajas de este enfoque son:
- no necesitas escribir un objetivo ant (bueno si usas eclipse)
- la clave de liberación correcta siempre está en map.xml (con suerte una clave de depuración no se registrará por error)
- la clave de liberación siempre se usa para una versión de lanzamiento
- se pueden usar múltiples claves de depuración
Las desventajas de este enfoque son:
debe recordar actualizar map_dbg.xml cada vez que se actualice map.xml
public class MapViewActivity extends MapActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // // copy the map.xml to map_dbg.xml and update the api key. // int id = getLayoutId("map_dbg"); if(id ==0) id = R.layout.map; setContentView(id); } int getLayoutId(String name) { return isDebugBuild() ? getResources().getIdentifier(name, "layout", getPackageName()) : 0; } public boolean isDebugBuild() { boolean dbg = false; try { PackageManager pm = getPackageManager(); PackageInfo pi = pm.getPackageInfo(getPackageName(), 0); dbg = ((pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0); } catch (Exception e) { } return dbg; } }
Si todavía estás interesado, acabo de escribir en mi blog sobre otra forma de hacer esto. Con un simple cambio en la secuencia de comandos de compilación de Android, puede cambiar la clave de Map API, así como todos los demás cambios de versión necesarios. Lo que me gusta de esto es que no hay nada relacionado con la depuración en el lanzamiento, y puede mantener los diseños XML tal como estaban antes.
http://blog.cuttleworks.com/2011/02/android-dev-prod-builds/
Terminé con el archivo especial en la tarjeta SD; si está presente, use la clave de depuración; faltante: use la versión uno. Y funciona.
EDITAR: ver nueva respuesta aceptada, funciona mejor
Todas las respuestas aquí parecen obsoletas, si estás usando android studio, entonces gradle es el camino a seguir
Utiliza diferentes claves en tu build.gradle
android {
.. .. ...
buildTypes {
debug {
resValue "string", "google_maps_api_key", "[YOUR DEV KEY]"
}
release {
resValue "string", "google_maps_api_key", "[YOUR PROD KEY]"
}
}
}
Y en su AndroidManifest.xml
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="@string/google_maps_api_key"/>
source
Y si quiere guardar algunas contraseñas para depuración y liberación de forma diferente, entonces debe seguir this
Tuvo la misma molestia con la clave API. Aquí hay una solución completa, basada en el enlace de arriba y ejemplo de Bijarni (que de alguna manera no funcionó para mí), uso ahora este método:
// Define the debug signature hash (Android default debug cert). Code from sigs[i].hashCode()
protected final static int DEBUG_SIGNATURE_HASH = <your hash value>;
// Checks if this apk was built using the debug certificate
// Used e.g. for Google Maps API key determination (from: http://whereblogger.klaki.net/2009/10/choosing-android-maps-api-key-at-run.html)
public static Boolean isDebugBuild(Context context) {
if (_isDebugBuild == null) {
try {
_isDebugBuild = false;
Signature [] sigs = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
for (int i = 0; i < sigs.length; i++) {
if (sigs[i].hashCode() == DEBUG_SIGNATURE_HASH) {
Log.d(TAG, "This is a debug build!");
_isDebugBuild = true;
break;
}
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
return _isDebugBuild;
}
Debe encontrar el hashValue () de su firma de depuración una vez, simplemente generar sigs [i] .hashCode ().
Entonces, no quería agregar dinámicamente MapView, sino usar el archivo xml. No puede establecer el atributo de clave api en el código y usar un diseño xml, por lo que utilizo este método simple (aunque copiar el diseño xml no es tan hermoso):
En mi MapActivity:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Select the proper xml layout file which includes the matching Google API Key
if (isDebugBuild(this)) {
setContentView(R.layout.map_activity_debug);
} else {
setContentView(R.layout.map_activity_release);
}
Una manera mucho más fácil de determinar si se trata de una compilación de depuración es verificar el indicador de depuración en la información de la aplicación que el hash de la firma.
public boolean isDebugBuild() throws Exception
{
PackageManager pm = _context.getPackageManager();
PackageInfo pi = pm.getPackageInfo(_context.getPackageName(), 0);
return ((pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
}
Una vez que se encuentra la compilación de depuración, puede usar un recurso diferente para mostrar el mapa o crear la vista de mapa dentro de la aplicación y agregarla a un diseño.
if(isDebugBuild())
{
_mapView = new MapView(this, getString(R.string.debugmapskey));
}
else
{
_mapView = new MapView(this, getString(R.string.releasemapskey));
}