廃止:この古い質問は廃止されたGoogle Maps v1 APIを参照しています。 v2 APIを使用する場合、1つの Google API Console エントリで複数の証明書フィンガープリントを使用できます。 APIキーはマニフェストにもコードにも保存されなくなりました。
APKの署名に使用された証明書を自動的に検出することはできますか?アプリケーションでマップ証明書のデバッグとリリースの両方を行い、有効な証明書をMapViewコンストラクターに渡したいです。
このような設定で、アプリケーションのリリース中に間違いを犯すことはありません。エミュレータとデバイスでデバッグ証明書を使用し、リリース1で署名してから、アプリをマーケットに送信します。
特定のデバイスを検出するか、デバッガが接続されているかどうかを考えていましたが、完全ではありません。たぶんいくつかのファイルマーキングはデバッグ証明書が必要ですか?もっと良い方法はありますか?
SDK Tools、Revision 17 のデバッグビルドまたはリリースビルドかどうかを判断する新しい方法があります。新機能の概要からの抜粋:
ビルドはBuildConfigというクラスを生成し、[〜#〜] debug [〜#〜]ビルドタイプに応じて自動的に設定される定数。コード内の(BuildConfig.DEBUG)定数を確認して、デバッグ専用の関数を実行できます。
だから今あなたは単にこのようなものを書くことができます:
if (BuildConfig.DEBUG)
{
//Your debug code goes here
}
else
{
//Your release code goes here
}
UPDATE:ADTでバグが発生しました:BuildConfig.DEBUG
は、アプリケーションパッケージをエクスポートした後のtrue
です。説明はこちら: http://code.google.com/p/Android/issues/detail?id=2794
APIキーで同じ手間がかかりました。上記のリンクと Bijarniの例 に基づいた完全なソリューションは次のとおりです(これはどういうわけか私には機能しませんでした)、今はこの方法を使用しています。
// 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;
}
デバッグシグネチャのhashValue()を一度確認する必要があります。sigs[i] .hashCode()を出力するだけです。
次に、MapViewを動的に追加するのではなく、xmlファイルを使用します。コードでapiキー属性を設定してxmlレイアウトを使用することはできないため、この単純な方法を使用します(ただし、xmlレイアウトをコピーすることはあまり美しくありません)。
私の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);
}
デバッグビルドであるかどうかを判断するはるかに簡単な方法は、署名ハッシュよりもアプリケーション情報のデバッグフラグをチェックすることです。
public boolean isDebugBuild() throws Exception
{
PackageManager pm = _context.getPackageManager();
PackageInfo pi = pm.getPackageInfo(_context.getPackageName(), 0);
return ((pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
}
デバッグビルドが見つかったら、別のリソースを使用して地図を表示するか、アプリ内でマップビューを作成してレイアウトに追加できます。
if(isDebugBuild())
{
_mapView = new MapView(this, getString(R.string.debugmapskey));
}
else
{
_mapView = new MapView(this, getString(R.string.releasemapskey));
}
あなたがまだ興味があるなら、私はこれを行う別の方法についてブログを書いただけです。 Androidビルドスクリプトを変更するだけで、Map APIキーやその他の必要なリリースの変更をすべて切り替えることができます。この点で私が気に入っているのは、デバッグに関連するものがリリースに含まれていないことです。 、XMLレイアウトを以前と同じように保つことができます。
http://blog.cuttleworks.com/2011/02/Android-dev-prod-builds/
Google APIのコンソールで、リリースキーとデバッグキーの両方を含むエントリ(両方とも同じパッケージへのマッピング)を作成するとうまく機能し、デバッグまたはコンパイルのどちらであるかを気にする必要がない非常に簡単な方法だと思いますリリースバージョン。ソリューションの概要 ここ
私は、APIキーをlocal.properties
に格納されているプロパティにすることで、ビルドプロセスとソース管理へのAPIキーの恐ろしい誤統合を回避しました。以下を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>
もちろん、もちろん、プロジェクトルートにmapview.xml.tpl
を作成する必要がありました(ビルドプロセスが中断するため、res/layout
にアクセスできません)。
<?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@"
/>
プリコンパイル中に、テンプレートが適切な場所にコピーされ、@ apiKey @が実際のキーに置き換えられます。残念ながら、このフェーズではデバッグビルドとリリースビルドを区別する方法が見つからなかったため、リリース用にコンパイルするには、antパラメータにリリースapiKeyを追加するだけです。
ant -DmapsApiKey=.... release
このアプローチは、SCM(キーをチェックインする必要はありません)とうまく統合でき、ビルドプロセスと十分に統合できます。
Android studioを使用している場合は、gradleを使用することをお勧めします
build.gradleで異なるキーを使用します
Android {
.. .. ...
buildTypes {
debug {
resValue "string", "google_maps_api_key", "[YOUR DEV KEY]"
}
release {
resValue "string", "google_maps_api_key", "[YOUR PROD KEY]"
}
}
}
そして、あなたのAndroidManifest.xml
<meta-data
Android:name="com.google.Android.maps.v2.API_KEY"
Android:value="@string/google_maps_api_key"/>
また、デバッグ用にいくつかのパスワードを保存して別の方法でリリースする場合は、次のようにしてください this
これが誰かに役立つかどうかはわかりませんが、他の提案のいくつかをここにマージして、次のMapViewActivityを作成しました。
この例では、R.layout.map_dbgは、これがデバッグビルドでファイルが存在する場合にのみ使用されます(このファイルを.gitignoreに追加してください)。
このアプローチの利点は次のとおりです。
このアプローチの欠点は次のとおりです。
map.xmlが更新されるたびにmap_dbg.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;
}
}
SDカード上の特別なファイルが作成されました-存在する場合は、デバッグキーを使用してください。欠落-リリース1を使用します。そしてそれは機能します。
編集:新しい承認済みの回答を参照してください。
Map V2では、Android Studio Gradleツールを使用して個別のキーを送信するのは簡単です。そのための簡単な方法を実装しました。リンク こちら を確認してください。
Apikeyをデバッグキーまたはリリースキーのいずれかに置き換えるシンプルなantターゲットを設定しました。これは本当に簡単で、コードに不要なロジックが含まれないようにします。
<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>