非表示の内部APIを使用してAndroidSDKを構築するにはどうすればよいですか?


85

Android SDK(またはandroid.jarのみ)を再構築して、非表示の内部APIを含めたいと思います。

これをどうやって行うかについてのドキュメントや議論は見つかりませんでした。cm7をビルドできるUbuntuCyanogenModビルド環境がすでにセットアップされています。

ここで、make SDKがSDKをビルドすることを読みましたが、@ hideを使用して非表示としてマークされたメソッドとフィールドを含むSDKをビルドしたいと思います。これは可能ですか?

私がやりたいのは、非表示のAPIを使用するアプリケーションに変更を加えることです。それを再構築するために、変更されたSDKを使用したいと思います。


2
@Hiddenはjavadocを非表示にするだけで、これらのメソッドはすべて引き続き使用できます
Blundell

12
@hideは、それらをクラスファイルから削除します。
トーマスホフマン2011年


リフレクションを使用できることは知っていますが、リフレクションなしで非表示のAPIを使用する既存のアプリケーションを変更したいので、リフレクションを使用するように既存のすべてのコードを変更したくありません。
トーマスホフマン2011年

4
@HiddenアクセスしたいAPIのラベルを削除してから、実行make update-apimake SDKて独自のSDKを構築できると思います。
ドリームテイル2012年

回答:


68

これは私が隠しAPIを使用するためにいつも行うことです。

  1. リポジトリをビルドするか、からjarをダウンロードします https:ます
  2. out / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jarをコピーします(framework_all.jarのような名前に変更することをお勧めします)
  3. プロジェクトのビルドパスを構成します->ライブラリ->この外部jarを追加します。Order and Exportで、android.jarの前に上に移動します

これは私にとってもうまくいきました!今、私は実際のタスクに
取り掛かる

私見、これは最も簡単で最速です。
Patrick Cho

これを正しい答えとしてマークする方法はありませんか?
Chris Browet 2014年

2
この方法はすべてのデバイスで機能しますか、それともターゲットデバイスでのみ機能しますか?
ハイフォン

android studioでライブラリの順序を定義するには、モジュールの.imlファイルを変更し、AndroidSDKの<orderEntry>前に目的のライブラリを持ってくる必要があります。残念ながら、gradle-syncボタンを押すとファイルが上書きされるため、この手法は永続的ではありません。
waqaslam

44

私はこれについていくつかの調査を行いましたが、私の結論は単純です。これは、かなりの作業なしでは実行できません。私が見つけたものの詳細については、この回答の残りを読んでください。


android.jar実際の「パブリックAPI」で構成されているframework.jarと、core.jar中に発見されたsystem/frameworks/デバイス上で。android.jarこれは、私がJavaライブラリヘッダーと呼ぶものの一種です。実際のバイトコードでのすべての実装は単なるでありthrow new RuntimeException("stub");、これにより、に対して構築することができます。android.jar(Eclipseなどで)が、実行はデバイスまたはエミュレーターで実行する必要があります。

Android SDKのパブリックAPIは、javadocアノテーションのプレフィックスが付いていないクラス/メソッド/フィールドによって定義されます@{hide}。つまり、注釈が付けられていないものはすべてSDKに含まれています。

android.jarout/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediatesあるツールDroidDocによってそれ自体が生成されるソースから構築されbuild/tools/droiddocます。

DroidDocは、実際のAndroid SDKドキュメントを生成するツールです(おそらくjavadocから適応されているか、javadocを使用しています)。副作用として、そしておそらくそれはすでにすべてのjavadocを解析しているため、Androidスタブを吐き出し、それがコンパイルされてandroid.jar、SDKで配布ます。

したがって、非表示になっているものを含めるには、特定の部分のみを含めたい場合は、@hide注釈を削除してSDKを再構築するだけです。

ただし、すべての非表示部分を含めたい場合は、さらに複雑になります。DroidDocを変更できます(関連するソースはbuild/tools/droiddoc/src/Stubs.java)、非表示として何も検出されないようにます。これは非常に簡単で、私はこれを試しましたが、生成されるスタブはまったくコンパイルされません。

今までの私の結論は、これは単に実現可能ではないということです。非表示の注釈を検出するDroidDocの部分を削除すると生成されるスタブは、単にコンパイルできず、正しくコンパイルするにはかなりの作業が必要になります。

ですから、あなたの質問に対する私の答えは次のとおりです。いいえ、これは多くの作業を行わずに行うことはできません。ごめんなさい。


mkstubsツールに関する補足。SDKアドオンmkstubsを構築するときに使用されます。つまり、ベンダーのAndroid SDKマネージャーにあるアドオンです。たとえば、Samsungは、Samsung電話に固有のもの用の追加のAPIを提供します。DroidDocスタブ生成プロセスとほとんど同じですが、アノテーションを使用せず、SDKアドオンに含めるまたは除外するパッケージ/クラス/フィールドを説明するファイルを使用します。mkstubs@hide.defs

ただし、Android SDKビルドはツールを使用しないため、これはすべて質問とは無関係mkstubsです。(残念ながら。)


私も見てみました。Droiddocの他に、/ development / tools / mkstubsにmkstubsというツールがあります。それはビルド中に呼び出され、私が見た限りでは、クラスファイルを変更してそれらからものをスタブします。build / core / tasks / sdk-addon.mkには、次のコードがあります。definestack-addon-jar $(call stack-addon-jar-file、$(1)):$(1)| mkstubs $(info $(PRODUCT_SDK_ADDON_STUB_DEFS)を使用したスタブアドオンjar)$(hide)java -jar $(call module-installed-files、mkstubs)$(if $(hide),,-v)\ "$$ <" "$$ @" @ $(PRODUCT_SDK_ADDON_STUB_DEFS)endef
Thomas Hofmann

残念ながら、私はこのようなことに興味がありませんが、私もそれがすべてhideと呼ばれる変数に依存しているように見えます。私はそれが設定されているかどうかはわかりませんでした。他のビルドファイルで$(hide)を検索すると、この値に大きく依存していることがわかります。また、Cライブラリの構築方法にも影響を与えるようです。
Thomas Hofmann 2012年

@ThomasHofmann:最初はmkstubsツールにも混乱しました。私が学んだことは、mkstubsは、通常のsdkをビルドするときではなく、(ベンダーの)sdkアドオンをビルドするときにのみ使用されるということです。ただし、mkstubsは、@hideアノテーションを使用しないことを除いて、DroidDocとほとんど同じ.defsです。アドオンのAPIに含めるパッケージ/クラス/フィールドを記述したファイルを「使用するだけ」です。
ビャルケフロイント-ハンセン2012

2
@ThomasHofmann:について$(hide)、あなたは自分自身を混乱させています。$(hide)は、実行中のプログラムの実際のコマンドラインを非表示にするためのメイクファイル内の単なるプレフィックスであり、それ以上のものではなく、ほぼすべての場所で使用されます。AndroidSDKや@hideソースコードの注釈とは何の関係もありません。
ビャルケフロイント-ハンセン2012

上記のパスout / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jarをチェックする方法
バニー

31

Androidプラットフォームから* .jarファイルを再構築できます。

まず、ADBをデバイスに接続します。次に、以下を実行します。

adb pull /system/framework/core.jar .
adb pull /system/framework/framework.jar .

core.jar(標準のJavaライブラリが含まれているjava.*)と、framework.jar(Androidのライブラリが含まれていますandroid.*)。実際のファイルはJAR形式ではなくDEX形式であるため、これはまだ使用できません。

私たちは、次のようなツールを使用して実際のJARファイルにこれらのDEX-フォーマットされた* .jarsを変換することができdex2jarを

dex2jar core.jar
dex2jar framework.jar

次に、「Add External JARs ...」を使用してこれらのjarをプルします(Eclipse ADTを使用していると仮定します)

  • Project → Properties → Java Build Path → Libraries → Add External JARs...→(上からcore-dex2jar.jarframework-dex2jar.jarを選択)を右クリックします。

これにより、内部APIと一部のJava 7APIを使用できるようになります。(生成されたAPKには、私が見る限り、JARからの実際のコードは含まれていません。)


どうもありがとうございました、私はあなたの方法だけが私のために働く多くの多くの方法を試しました。
SalutonMondo 2014年

7
この方法はICS以降のシステムでも機能しますが、さらにジャグリングが必要であることに注意することが重要です。関連するファイルはあり/system/framework/core.odex/system/framework/framework.odexおそらくより、と。これらはdeodexed(java -jar baksmali-2.0.3.jar -d system.framework -x system.framework/core.odex -o core)およびreodexed(java -jar smali-2.0.3.jar -x -o core.dex core)することができ、その後でのみその役割を果たしdex2jar core.dexます。
Alex Cohn 2014

マシュマロでcore.jarが見つかりません
mehmet6parmak 2015

android pのコアとフレームワークのjarについて何かアイデアはありますか?
プラバカラン

上記のパスout / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jarをチェックする方法
バニー

17

ロリポップの場合、フローは少し異なります。

  1. ロリポップデバイスから/system/framework/arm/boot.oatを取得します

  2. 'java -jar oat2dex.jar bootboot.oat'を使用します

  3. dexとodexの2つのフォルダがあります。dexに移動し、「java -jar dex2jar.jarframework.dex」を作成します。
  4. 結果のframework.jarの名前を.zipに変更し、必要なクラスを抽出して検索します
  5. [sdk_path] / platform / [target_platform]に移動し、android.jarを抽出します(最初に名前をzipに変更します)。
  6. 抽出されたフレームワークから抽出されたandroid.jarにファイルをコピーします。次に、圧縮してzipし、名前を.jarに変更します:)

ps:おそらく「framework_classes2.dex」に対して手順4〜6を繰り返す必要があります


ステップ3では、そのリンクでdex2jar.jarが見つかりません。...多くのことを試しましたが、理解できません。どこかにそれへのリンクはありますか?それは私のAndroidSDKにありますか?見つかりません。
dwebtron 2015年

ええ、それはgithubプロジェクトに行きます、そして多分それは私です、しかし私はそこに「.jar」で終わるファイルを見つけることができません...
Dwebtron 2015年

1
「リリース」セクションを参照してください
2015年

2
したがって、最近のバージョンのdex2jarでダウンロードの形式が変更されたようです。ダウンロードを解凍し、「java -jar ...」の代わりに、プラットフォームに応じて、framework.dexファイルで直接スクリプト「d2j-dex2jar.sh」または「d2j-dex2jar.bat」を実行します
CalumMcCall

1
両方のjarファイルをandroid.jarにコピーしましたが、android studioから、タスク ':app:processDebugResources'のエラー:実行に失敗しましたと表示されます。> com.android.ide.common.process.ProcessException:org.gradle.process.internal.ExecException:Process 'コマンド' D:\ Programme \ Android \ android-sdk \ build-tools \ 19.1.0 \ aapt.exe ' 'ゼロ以外の終了値1で終了
wutzebaer 2016年

15

DroidCon 2011

ここでは、SonyEricsonのErikHellmanが、非表示のAndroidAPIにアクセスする方法について説明しています。

http://vimeo.com/30180393 (うーんリンクが機能していないようです)。

DroidCon Webページの2日目に移動し[ Hidden APIの使用10:15]まで下にスクロールすると、そこで見ることができます。

リンクが切れています!

私はこれを見つけました:http://skillsmatter.com/podcast/os-mobile-server/hidden-apidunnoそれがどれくらい続くか

通常、Android SDKの公式APIは、ほとんどの通常のアプリケーションで十分です。ただし、開発者が公式APIで公開されていない内部システムサービス、API、およびリソースにアクセスする必要がある場合があります。幸いなことに、これらのAPIは、いくつかの巧妙なトリックを通じて引き続き利用可能であり、Android上で新しく革新的なソリューションを開発するときに役立つことがよくあります。このセッションでは、これらの非表示および保護されたAPIにアクセスして使用する方法、それらの使用の制限、および複数のベンダーのデバイスとAndroidバージョン間で安全かつ制御された方法でそれらを使用する方法に関するいくつかのヒントを学びます。視聴者には、Androidでは通常は実行できないいくつかの高度なデモが表示されます。Androidプラットフォームの内部に関する多くの洞察を備えた、かなり高度なセッションを期待してください。


1
面白いですが、残念ながら私の質問には答えられません。隠されたものを含めて実際にSDKを再構築する方法を探していました。
トーマスホフマン2011年

私が望むことを達成するための別の方法を見つけたようです。明日説明します。
トーマスホフマン2011年

ADTで非表示のAPIを使用するプロジェクトのソースをコンパイルする場合は、次のことができることがわかりました。1)ソース用のAndroidプロジェクトを作成します。2)ビルドパスからAndroidクラスパスコンテナを削除します。3)ASOP ROMビルドのJARファイル(cm7など)を含むユーザーライブラリを定義します(システムライブラリのチェックボックスもオンにします)。使用するJARファイルは、参照する必要があるものによって異なります。フレームワーク-イミディエイトはおそらくその一部になるでしょう。
トーマスホフマン2011年

4)プロジェクトがビルドされると、ユーザーライブラリクラスは作成中のAPKに含まれなくなります。非表示のAPIが表示され、すべてが正常にコンパイルされます。
トーマスホフマン2011年

@Blundell:リンクを更新していただけませんか..それらは死んでいます!
ゾンビ2012年

15

このリポジトリandroid.jarから、非表示のAPIとして使用するように変更されたものをダウンロードできます。そこにある指示に従ってください。


4
この答えは最も単純な解決策であるため、もっと賛成する必要があります。人々、あなたが解決策を探しているなら-他の人々がすでにそれをして、そのgithubリポジトリに解決策を置いたことを知っています。それを使って楽しんでください!))
Mixaz 2016

1
API 28にandroid.jarを使用しているときに、robolectricでエラーが発生します。問題提起github.com/anggrayudi/android-hidden-api/issues/62をし、あなたのjarファイル@Anggrayudiをありがとう
Prabhakaran

12

これを見てみてください:

これらの記事の最終的な目標は、リフレクションを使用せずに、開発者に内部APIと非表示APIの能力を提供することです。次のいくつかのパートで説明するすべての手順を完了すると、内部APIと非表示APIをパブリックオープンAPIであるかのように使用できるようになります。振り返る必要はありません。

ただし、これらの非公開APIを使用している場合は、アプリケーションが大きなリスクにさらされていることに注意する必要があります。基本的に、AndroidOSへの次のアップデートでAPIが壊れないという保証はありません。さまざまなベンダーのデバイス間で一貫した動作が保証されることすらありません。あなたは完全にあなた自身です。

あなたが従うことを望むかもしれない3つのシナリオがあります:

  1. 内部APIと非表示APIの両方を有効にする(シナリオA)
  2. 非表示のAPIのみを有効にする(シナリオB)
  3. 内部APIのみを有効にする(シナリオC)

シナリオAはBとCの合計です。シナリオBは最も簡単なシナリオです(Eclipse ADTプラグインの変更は必要ありません)。

シナリオA:読み取り部12345

シナリオB:読み取り部1235

シナリオC:読み取り部12345


3
私はすでにそのブログエントリを読みました。「1)Androidはオープンソースプロジェクトです。Android.jarから内部クラスと非表示クラスが除外されないように、ソースコードをダウンロードしてビルドシステムをカスタマイズできます。これは難しい方法です。」残念ながら、詳細には触れていません。
トーマスホフマン2011年

3
ブログ投稿の最後の部分(devmaze.wordpress.com/2011/01/19/…)に移動し、リンクがあります( github.com/inazaruk/android-sdk/tree/master/platforms)するには、Android事前に構築されましたすべての非表示および内部APIを備えたAPI。
ボブ

1
指定されたリンクにアクセスできません。
作成

上記のパスout / target / common / obj / JAVA_LIBRARIES / framework_intermediates /classes.jarをチェックする方法
バニー

1

私はかつて、http: //source.android.com/のリポジトリチェックアウトからJavaファイルを抽出し、必要な他の手順を含むすべてのAndroidソースをコンパイルするための完全なツールチェーンを必要とせずにそれらをコンパイルするためのGroovyスクリプトをいくつか作成しました(パッケージング、リソースの生成など)。

それらはここで見つけることができます:

https://github.com/thoutbeckers/CollectAndroid

しかし確かに、これはGingerbreadの後、ほとんどの場合、構成ファイル(CollectConfig.groovy)の「rootdirs」に正しいディレクトリを設定することによって更新する必要があります。

当時、私はこれを開発に定期的に使用し、すべての非表示のAPIとソース(当時は問題もありました)を利用できました。

他の場所で述べたように、com / android / internal / **は、アクセスルールが追加されているため、最近のバージョンのADTでは引き続き非表示になります。


上記のパスout / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jarをチェックする方法
バニー

Gingerbread用に最後に更新されてから、そのリポジトリをアーカイブしました。残念ながら、別のアプローチを見つける必要があります。
thoutbeckers

1

ロングの答えは私にとってはうまくいきましたが、私はまだ必要ないくつかのクラス、特にandroid.provider.Telephonyを欠いていました。私はそれを次のように追加することができました:

  1. framework.jarファイルを抽出します

    mkdir /tmp/framework
    cp framework.jar /tmp
    cd /tmp/framework
    jar xvf ../framework.jar
    mv android classes
    
  2. Androidリポジトリをビルドします。これにより、out / target / common / obj / JAVA_LIBRARIESディレクトリが作成されます。

  3. 不足しているクラスがどこにあるかを見つける

    $ cd /path/to/out/target/common/obj/JAVA_LIBRARIES
    $ find . | grep "/Telephony.class"
    ./telephony-common_intermediates/classes/android/provider/Telephony.class
    ./android_stubs_current_intermediates/classes/android/provider/Telephony.class
    
  4. 新しいクラスを追加し、フレームワークJARファイルを再構築します

    cd /tmp/framework
    cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes .
    cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/classes .
    cd classes
    jar cvf ../framework.jar .
    

または、怠惰になって、すべてのクラスを1つの巨大なjarファイルに含めることもできます。

cd /tmp/framework
cp -r /path/to/out/target/common/obj/JAVA_LIBRARIES/*/classes .
cd classes
jar cvf ../framework.jar .

out / target / common / obj / JAVA_LIBRARIESこのパスを見つける方法は?
バニー

@Bunny回答を詳細に更新しました。しかし、ここでの答えはもっと簡単かもしれないようです:stackoverflow.com/a/32626155/399105
bmaupin

返信ありがとうございます@bmaupin ..フレームワークjarを取得するためにこのパスout / target / common / obj / JAVA_LIBRARIESを見つける方法を教えてください...本当に行き詰まりました..このパスを見つけることができませんまたは何かが足りない...ガイドしてください
バニー

0

コメントはできませんが、これは基本的に@KennyTM(https://stackoverflow.com/a/13550030/2923406)の優れた回答へのコメントです。

Eclipseで次のエラーが発生した場合:

The type com.android.internal.util.Predicate cannot be resolved. It is indirectly referenced from required .class   files

(つまり、android.internal。*は使用できません)

次に、考えられる解決策の1つは、同じメソッドを/system/framework/framework2.jarに適用することです。SDK19用のAndroidエミュレーターを使用すると、この追加のjarファイルがあります。私のHTCOneには、framework3.jarもあります。


上記のパスout / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jarをチェックする方法
バニー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.