11

Google Play アプリストアは、アプリケーションを互換性のある CPU アーキテクチャを持つデバイスに自動的にフィルターします。たとえば、ARMv5 用にのみコンパイルされたライブラリがある場合、アプリは ARMv5 または ARMv7 プロセッサを搭載したデバイスに対してのみ表示されます。

Java の代替手段があり、自分のアプリを ARM 以外のデバイスでもダウンロードできるようにしたい場合はどうすればよいですか? たとえば、外部ライブラリをロードしようとすると例外をキャッチし、Dex バイトコード (Java) で実行可能な代替手段を実装します。

.apk をアップロードすると、Android 開発者コンソールに次のように表示されます。「この apk は、Google Play フィルタリングに使用される 1 つのネイティブ プラットフォームを要求します。armeabi」

x86 および MIPS 用のダミー ライブラリをコンパイルする必要がありますか? 次に、私の Java コードで、プロセッサ アーキテクチャをチェックして、ライブラリを実際に使用できるかどうかを確認します。より良い解決策があるはずです。

私の知る限り、マニフェストには CPU アーキテクチャに関する記述はなく、開発者コンソールでこのフィルタをオフにする方法が見つかりません。

Google Play のフィルタリングと NDK について、私よりも多くのことを知っている人が答えを知っていることを願っています。

4

2 に答える 2

11

loadLibrary の失敗のトラップはどのデバイスでも機能しますが (少なくとも GTV を含めて私が試したすべて)、そのプラットフォームの ABI が apk に存在しない場合、Play ストアはデバイスに表示されません。

ドキュメントから ( http://developer.android.com/guide/appendix/market-filters.html ): 特定のプラットフォーム (たとえば、ARM EABI v7 または x86) をターゲットとするネイティブ ライブラリを含むアプリケーションは、そのプラットフォームをサポートするデバイス。

理論的には、すべてのプラットフォーム向けにビルドすると、すべてのデバイスをターゲットにすることができますが、実際には、Google Tv のように ABI を報告しないデバイスがいくつかあります。つまり、ネイティブ コードを持たない apk のみが、これらのデバイスの Play ストアに表示されます。 . 複数の apk を使用できますが、1 つはネイティブ コードなしで、1 つはネイティブ コードをサポートするすべてのプラットフォームで使用できます。

ここで複数の apk のサポートについて読むことができます: http://developer.android.com/guide/market/publishing/multiple-apks.html

于 2012-06-03T03:07:32.403 に答える
6

この同じ質問に対する非常に完全な回答がここにあります: http://grokbase.com/t/gg/android-ndk/125v31e6wy/play-store-market-filtering-of-ndk-libs

私自身のソリューションを投稿させてください。これは、ここに投稿したものとほぼ同じです: Android library .so with x86 architecture missing? (ヴフォリア)

つまり、使用しているライブラリ (libExternalLibrary.so) が arm archi 用にのみ提供されているため、x86 アーキテクチャでコンパイルできない通常の Android.mk があります。このライブラリに基づいて .so (libMyLibraryBasedOnExternalLibrary.so) をビルドしたいとします。もちろん、ライブラリなしでは x86 でコンパイルすることはできません。

アイデアは、条件付きコンパイル命令を使用して、Android.mk で直接 x86 用のダミー ライブラリを生成することです。

1) 2 つのダミー .cpp ファイル Dummy0.cpp と Dummy1.cpp を作成します。例 Dummy0.cpp は次のようになります。

#include <jni.h>
#include <android/log.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <string>

#ifdef __cplusplus
extern "C"
{
#endif

int dummy0                        =  0;

#ifdef __cplusplus
}
#endif

次に、ライブラリをビルドする Android.mk を編集し、次のように変更します。

LOCAL_PATH := $(call my-dir)

ifeq ($(TARGET_ARCH_ABI), armeabi)


# In this condtion block, we're compiling for arm architecture, and the libExternalLibrary.so is avaialble
# Put every thing the original Android.mk was doing here, importing the prebuilt library, compiling the shared library, etc...
# ...
# ...

else

# In this condtion block, we're not compiling for arm architecture, and the libExternalLibrary.so is not availalble.
# So we create a dummy library instead.

include $(CLEAR_VARS)
# when LOCAL_MODULE equals to ExternalLibrary, this will create a libExternalLibrary.so, which is exactly what we want to do.
LOCAL_MODULE := ExternalLibrary
LOCAL_SRC_FILES := Dummy0.cpp
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
# This will create a libMyLibraryBasedOnExternalLibrary.so
LOCAL_MODULE := MyLibraryBasedOnExternalLibrary
# Don't forget to tell this library is based on ExternalLibrary, otherwise libExternalLibrary.so will not be copied in the libs/x86 directory
LOCAL_SHARED_LIBRARIES := ExternalLibrary
LOCAL_SRC_FILES := Dummy1.cpp
include $(BUILD_SHARED_LIBRARY)

endif

もちろん、アプリが x86 のみのデバイスで実行されている場合は、ライブラリを呼び出さないようにコードで確認してください。

if ((android.os.Build.CPU_ABI.equalsIgnoreCase("armeabi")) || (android.os.Build.CPU_ABI2.equalsIgnoreCase("armeabi"))) {
    // Good I can launch
    // Note that CPU_ABI2 is api level 8 (v2.2)
    // ...
}
于 2013-03-04T06:46:49.773 に答える