1

私のアプリはminSdk=5で実行するように設定されていますが、大多数のユーザーはSDK 8(FroYo)以降を使用しています。メインのアクティビティにandroid:configChanges = "uiMode"を使用できるようにしたいのですが、SDKレベル8までそのモードが導入されていなかったため、使用できません。 runtime-デバイスで実行されているSDKレベルを確認してから、リフレクションを使用してそのパラメーターを追加します。

それは可能ですか?

編集: 問題は、ユーザーの電話がドックに接続されるたびに、アプリが終了してから再作成されることです。android:configChanges = "uiMode"を含めることで、これを回避しようとしています。

4

2 に答える 2

2

Android リファレンスをよく読んだ後、実行時にマニフェストから変更できるものはほとんどありません。これはセキュリティ上の理由によるものです。これは、 を介してPackageManager、デバイス上の任意のアプリケーションに関する非常に具体的な情報を取得できるためです。特定のコンポーネントを有効/無効にするのは簡単ですが、他のほとんどの状況では、マニフェスト情報を読み取ることしかできず、書き込むことはできません。

代替案

  • API レベル 8 をサポートする別の APK を作成できる可能性があります。

  • 構成の状態を手動で確認し、コードが変更されたときにコードを実行できます。構成のオブジェクト リファレンスはこちらです。

編集:(新しい情報)

configChanges を変更することはできませんが、あなたと密接に関連するこの質問を見つけました。そうする必要がないかもしれないことがわかりました。new をサポートする場合、Android の下位互換モードを使用できることを意味しますconfigChanges。上記のリンクが壊れている場合は、次の URL を参照してください: https://stackoverflow.com/a/7893148/501932

これを使用するにはtargetSdk、元の を維持しながら新しい を設定することをお勧めしますminimumSdk。また、更新された SDK 自体が必要です。どうやら、これはその AdMob API を利用したユーザーにとって大きな取引でした。

于 2012-06-11T08:53:58.440 に答える
0

上位互換性のためのアプリ構成

私が提供した答えは、何をすべきかという単純なものですが、多くはありませんし、理由もありません。これは、答えを更新するだけでなく、無意味で会話に何も追加されなかったポスターとのスパーリングに対する SO コミュニティへの謝罪として機能するはずです。

この種の質問が多く寄せられ、開発者は急いで (私たち全員ではないでしょうか)、切り取り/コピー/貼り付けをしてその理由を心配する傾向があるため、この問題を拡大することは重要なポイントだと思います。後でそれはほとんどうまくいきますが、時折問題を追加するだけです.

Android ランタイムが実際にどのように機能するかを理解していれば、マニフェストでブロックを使用してベスト プラクティスの単純なパターンを適用し、アプリをコンパイルするときにビルド ターゲットをうまく利用し、続いていくつかの簡単なコンパイルおよび実行時のレベルでのテスト。

マニフェスト

minSdkVersion =

これは、特定のデバイスでサポートする最も低いビルド ターゲットです。これを設定しない場合、デフォルトで 1 になります。

ここでの唯一の注意点は、ビルド ターゲットが minSdkVersion よりも高い場合、デバイスに存在しない API を呼び出すことができる可能性があることです。ビルド ターゲットの下でさらに詳しく説明します。

これにより、OS サポートが低いデバイスのさまざまなマーケット/プレイ リポジトリからアプリが除外されます。

アプリをすべてのデバイスで実行する必要がある場合は、この決定をどのように行うかはあなた次第ですが、十分な情報に基づいた決定を行うため にプラットフォームの配布を確認してください。

市場の 0.9% をバイパスする意思がある場合は、2.1 をターゲットにしますが、これは合理的と思われますが、それは開発者/企業が行う決定です。市場の 25% をバイパスできる場合は、2.3 を使用します。ほとんどの汎用アプリでは飲み込みにくいです。

リンクされたチャートは随時更新されます。

targetSdk =

この値を適用しない場合は、設定した minSdkVersion がデフォルトになります。これは、より高い OS サポートを備えたデバイスで実行すると、実装されている特定の新しい外観や動作がバイパスされ、古い方法が優先されることを意味します。

たとえば、minSdkVersion に 10 を適用し、ジンジャーブレッド (11) を備えたデバイスでアプリを実行すると、holo テーマの使用や画面互換モードの無効化は試行されません。一般に、これによりアプリのルック アンド フィールが「時代遅れ」になる可能性があります。

一方、これを 11 などのより高い値に設定すると、システムは設定した値まで OS のネイティブなルック アンド フィールを使用します。ベスト プラクティスは、これを可能な限り高く設定し、エミュレータでより高いレベルのデバイスでテストして、これが許容可能であることを確認することです。

OS ジャンプ間の互換性動作に影響を与える変更の一部は、ここに記載されていますOS 間の相違点

これにより、以前のデバイスでの実行が停止したり、以前のデバイスのルック アンド フィールに影響したりすることはありません (それが目的の場合は、ActionBarSherlock と Android サポート ライブラリを参照してください)。

maxSdkVersion =

一般に、これはまさにその通りであり、Google マーケット/プレイのより高い OS レベルを持つデバイスでのアプリケーションの可用性と展開を制限します。

Android 2.0 では、apk のインストールも拒否し、デバイスがこの設定よりも高いレベルに更新された場合はアプリを削除します.その上で。

通常、この値を設定する理由はないので、空白のままにします。

ビルド ターゲット Eclipse (またはそれ以外) でビルド ターゲットを設定すると、どの API や定数などをアプリケーションに表示する必要があるかをコンパイラーに伝えます。

ここに画像の説明を入力

一般に、これらの定義/宣言をすべて含む jar ファイルが追加されますが、もちろん実際のクラス/メソッドは含まれないため、必要なターゲット OS 用にアプリケーションをコンパイルできます。

アプリがデバイスで実行されると、実際の Android OS/サポート jar ファイルにリンクされます (または、チャンクが存在しない場合はチャンクを吹き飛ばします)。

サポートするよりも高いビルド ターゲットを選択すると、存在しないメソッドや古い OS に存在しないクラスを呼び出そうとすると、もちろん悪いことが起こります。

一方、これを慎重に管理およびテストする意思がある場合は、以前のデバイスで使用しようとしない限り、新しいデバイスで新しい API を使用できるという意味で、前方互換性を得ることができます。

ベスト プラクティス – 短いバージョン これは投稿者が達成しようとしていることであり、ベスト プラクティスに従えばうまくいきます。これらは一般的に次のとおりです。

minSdkVersion    = lowest general API you will support
targetSdkVersion = highest behavioral model you are willing to allow
maxSdkVersion    = leave it blank
Build Target     = generally as high as is currently supported 

本当の注意点は、古いバージョンと新しいバージョンの間で API の不一致を回避し、アプリが新しいバージョンで適切に表示され、動作することを確認する必要があるということです。

一般に、最小ターゲット OS よりも高いメソッド/クラスは慎重に使用し、コンパイル レベルとランタイム レベルの両方でテストする必要があります。これらを安全に使用するには、ある程度の努力が必要だからです。

これが私がそれについて行く方法です

minSdkVersion    = 7 ( I can live with a 0.9% clip again your choice ) 
targetSdkVersion =15 ( highest as of this writing ) 
maxSdkVersion    = ( blank )

Build Target = 15

開発中、本当に必要でない限り、7 で利用できない API を使用することは決してありません。 API 3 のサポートが必要なので、前方互換性をサポートする必要があります。

使用できる 1 つのツールであり、ほとんどの場合、developer.android.com Web サイトの API レベルを最小限の SDK レベルに設定することはできません。これにより、開発時にサポートする必要があることを把握できます。前方互換性。

ここに画像の説明を入力

他の API 呼び出しは引き続き表示されますが、それらをサポートするには追加の作業が必要であることを示すグレー表示になります。

新しい API を使用する必要がある場合は、新しいデバイスでのみ呼び出されるように if then else を実行する必要があります。これにより、古いデバイスで強制終了することなく新しい機能をサポートできます。

したがって、一般に、より高い API レベルをサポートする場合、これらの呼び出しは次のようにラップする必要があります (.SDK_INT は API 4 以降のテストであることに注意してください)。

If ( Build.VERSION.SDK_INT  >= API11_SUPPORT ) {
    switch(newConfig.uiMode) {
        case ...
}

テスト – 手動の方法 (CI 統合方法は読者に任されています ;-)

  1. ビルド ターゲットを minSdkVersion に設定してコンパイルします。これにより、使用している新しい API でコンパイル エラーが発生します。それらをチェックして、問題なく処理できた場合は今がその時です。

ステップ 1 で確認した問題ごとに、コードに 2 つの項目を追加します (manifests/xml )。

// TODO Compatibility xxx 
if (DEBUG) Log.i(“MyApp”,” Compatibility xxx”); 

その後、eclipse TODO ペインを使用して、出荷前に互換性の問題をチェックし、OS バージョン間の最低/最高および重要なものに対してテストできます。

  1. minSDKVersion デバイス/エミュレーターでテストします。包括的なテストを行っていない場合、これは少しトリッキーです。通常、上記の手順 1 を使用して、これらのコード ブロックを確実に実行します。

  2. ビルド ターゲット デバイス/エミュレータでテストして、ルック アンド フィールが期待どおりに機能することを確認します

少し面倒だと思う場合は、それは必要ですが、必要な場合は正しく実行し、アプリが壊れないようにする必要があります。

願わくば、これが同様の状況を理解しようとしている誰かに役立つことを願っています.

アップデート:

著者が何を求めているのかはまだわかりませんが、onConfigurationChanged ハンドラーを使用して 7 以下で uiMode (ドッキングのもの) に関する構成の変更を検出する方法があるかどうかを彼が尋ねている場合、それは でのみ導入されたため、いいえAPI 8。

API 2.0+ システムで送信されるブロードキャスト イベントがありますが、明らかにいくつかの問題があり、完全に信頼できるとは思えません。

彼がアクティビティのマニフェストでフラグを設定することにより、onConfigurationChanged ハンドラーを介して API 8 以降のデバイスでそれをサポートする方法があるかどうかを尋ねている場合は、もちろんあります

もちろん、彼はまったく別のことを尋ねているのかもしれませんが、協力の精神に基づいた彼のポストを考えると、彼が何をしようとしているのかを正確に伝えることは困難です。

>= 8 のプロジェクト プロパティから API を選択します。ベスト プラクティスは、アプリを作成するときに利用可能な最高の API を使用することですが、これはまさにこの理由によるものですが、デバイスで利用できない API を呼び出さないように注意する必要があります。

次に、マニフェストで使用します(当たり前)

<activity
            android:name=".myActivity"
             android:configChanges="uiMode|orientation|keyboardHidden"

これは正常にコンパイルされます (これが実際に唯一の問題であり、Eclipse プロジェクトのプロパティでより高い API を設定する必要がある理由です)。これは 7 以下で正常に実行されます。もちろん、API 7 以下のデバイスはイベントをトリガーしません。 t は uiMode フラグを認識します (duh)

もちろん、API 8以降はそれを認識し、適切なイベントを送信するため、API 7ではログが書き込まれ、API 8以降では(ドッキングされている場合など)もちろん、発生した場合に行われる呼び出しはおそらく8+ 関連なので、呼び出す前に OS チェック ブロックが必要です。

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    Log.i("myActivity","uiMode="+newConfig.uiMode);

}

7 API エミュレーターでコンパイルして実行し、dock ブロードキャストを起動しても何も起こらず、8 API エミュレーターに変更すると動作します。

adb shell am broadcast -a android.intent.action.DOCK_EVENT --ei android.intent.extra.DOCK_STATE 2
于 2012-06-11T06:08:25.913 に答える