Android SDK'yı mevcut gizli ve dahili API'ler ile nasıl oluşturabilirim?


86

Gizli ve dahili API'leri içerecek şekilde Android SDK'yı (veya daha doğrusu yalnızca android.jar'ı) yeniden oluşturmak istiyorum.

Bunun nasıl yapılacağına dair herhangi bir belge veya tartışma bulamadım. Cm7 oluşturabilen bir Ubuntu CyanogenMod oluşturma ortamım zaten var.

Şimdi, SDK'nın SDK'yı oluşturacağını okudum, ancak @hide kullanılarak gizli olarak işaretlenmiş yöntemler ve alanlar içeren bir SDK oluşturmak istiyorum. Mümkün mü?

Yapmak istediğim, gizli API kullanan bir uygulamada değişiklik yapmak ve onu yeniden oluşturmak için değiştirilmiş SDK'yı kullanmak istiyorum.


2
@Hidden sadece javadoc'u gizler, tüm bu yöntemler hala kullanılabilir
Blundell

12
@hide, bunları sınıf dosyalarından kaldırır.
Thomas Hofmann


Yansımayı kullanabileceğimi biliyorum, ancak gizli API kullanan mevcut bir uygulamayı refelction olmadan değiştirmek istiyorum ve mevcut tüm kodu refelction kullanmak için değiştirmek istemiyorum.
Thomas Hofmann

4
Sanırım @Hiddenerişmek istediğiniz API'nin etiketini kaldırabilir , ardından kendi SDK'nızı çalıştırabilir make update-apive make SDKoluşturabilirsiniz.
dreamtale

Yanıtlar:


69

Gizli api kullanmak için her zaman yaptığım şey bu.

  1. Depoyu oluşturun veya https://sites.google.com/site/hippunosource/home/android/androidnohide-apiwo-shi-yongsuru-rifurekushonha-wei-shi-yong adresinden kavanozları indirin.
  2. / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar dosyasını kopyalayın (framework_all.jar gibi bir adla yeniden adlandırmak daha iyidir)
  3. projenizi yapılandırma yolunu yapılandırın -> kitaplıklar -> bu harici kavanozları ekleyin. Sırala ve Dışa Aktar'da, yukarı ve android.jar'dan önce taşıyın

Bu benim için de çalıştı! şimdi asıl göreve
başlayabilirim

IMHO, Bu en kolay ve en hızlısı.
Patrick Cho

Bunu doğru cevap olarak işaretlemenin bir yolu yok mu?
Chris Browet

2
bu yöntem tüm cihazlarda mı yoksa sadece hedeflenen cihazda mı çalışıyor?
Hải Phong

Android stüdyosunda kitaplık sırasını tanımlamak için modülün .imldosyasını değiştirmeniz ve istediğiniz kitaplıkları Android SDK'dan<orderEntry> önce getirmeniz gerekir . Ne yazık ki bu teknik kalıcı değildir, çünkü gradle-sync düğmesine basıldığında dosyanın üzerine yazılacaktır.
waqaslam

44

Bununla ilgili biraz araştırma yaptım ve sonucum basit: Bu, epey bir çalışma olmadan yapılamaz. Bulduğum şeyle ilgili ayrıntılar için bu cevabın geri kalanını okuyun.


android.jaraslında bir "kamu API" oluşur framework.jarve core.jariçinde yer aldığı system/frameworks/cihazda. android.jarJava kitaplığı başlığı olarak adlandıracağım türden bir tür, gerçek bayt kodundaki tüm uygulamalar sadece bir throw new RuntimeException("stub");, bu size karşı geliştirme yapmanıza izin veriyor android.jar(örneğin Eclipse'de), ancak yürütme bir aygıt veya emülatörde gerçekleştirilmelidir.

Android SDK'nın genel API'si , javadoc ek açıklamasının önüne geçmeyen sınıflar / yöntemler / alanlar tarafından tanımlanır @{hide}. Yani ek açıklamalı olmayan her şey SDK'ya dahildir.

android.jar, içinde bulunan DroidDocout/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates aracı tarafından oluşturulduğu yerde bulunan kaynaklardan oluşturulmuştur build/tools/droiddoc.

DroidDoc , gerçek Android SDK belgelerini oluşturan araçtır (muhtemelen javadoc'tan uyarlanmıştır veya javadoc kullanılarak). Bir yan etki olarak ve muhtemelen tüm javadoc'u zaten ayrıştırdığı için, daha sonra android.jarSDK'da dağıtılan android saplamalarını da derleyerek ortaya çıkarır .

Bu nedenle, gizli olan şeyleri dahil etmek için, yalnızca belirli parçaları dahil etmek istiyorsanız, @hideaçıklamayı kaldırıp SDK'yı yeniden oluşturabilirsiniz.

Ancak tüm gizli parçaları dahil etmek isterseniz işler çok daha karmaşık hale gelir. Sen değiştirebilir DroidDoc (ilgili kaynak olduğu build/tools/droiddoc/src/Stubs.javagizli olarak öyle ki hiçbir şey tespit edilirse). Bu oldukça önemsiz ve bunu denedim, ancak daha sonra oluşturulan saplamalar hiç derlenmiyor.

Şimdiye kadarki sonucum, bunun mümkün olmadığıdır. DroidDoc'un gizli açıklamaları algılayan bölümünü kaldırırsanız oluşturulan saplamalar derlenemez ve doğru bir şekilde derlemek için epeyce çalışma gerektirir.

Bu yüzden sorularınıza cevabım şu: Hayır, çok çalışmadan bu yapılamaz. Afedersiniz.


Araçla ilgili bir yan not mkstubs. mkstubsBir SDK eklentisi oluşturduğunuzda kullanılır , yani satıcılardan Android SDK yöneticisinde bulabileceğiniz eklentiler, örneğin Samsung, Samsung telefonlarına özgü şeyler için size ek bir API sağlar. mkstubsDroidDoc saplama oluşturma işlemiyle hemen hemen aynı şeyi yapar, ancak @hideek açıklamaları kullanmaz, SDK eklentinize .defshangi paketleri / sınıfları / alanları dahil edeceğinizi veya hariç tutacağınızı açıklayan bir dosya kullanır .

Ancak bu Android SDK oluşturma sürece, sorunun bütün alakasız değil kullanmak mkstubsaracı. (Ne yazık ki.)


Ben de baktım. Droiddoc'un yanı sıra / development / tools / mkstubs içinde mkstubs adlı bir araç var. Derleme sırasında çağrılıyor ve gördüğüm kadarıyla sınıf dosyalarını değiştirecek ve içlerinden bir şeyler çıkacak. Build / core / tasks / sdk-addon.mk'de aşağıdaki kod vardır: tanımla stub-addon-jar $ (stub-addon-jar-file, $ (1)): $ (1) | mkstubs $ ($ (PRODUCT_SDK_ADDON_STUB_DEFS) kullanarak eklenti kavanozunu doldurma bilgisi) $ (gizle) java -jar $ (modül yüklü dosyaları çağır, mkstubs) $ (eğer $ (gizle) ,, - v) \ "$$ <" "$$ @" @ $ (PRODUCT_SDK_ADDON_STUB_DEFS) endef
Thomas Hofmann

Ne yazık ki, bu şeylerle ilgilenmiyorum ama ben de öyle görünüyor ki, hepsi hide adında bir değişkene bağlı. Yine de ayarlanmışsa bulamadım. Diğer derleme dosyalarında $ (gizle) ararsanız, çok şeyin bu değere bağlı olduğunu göreceksiniz. Aynı zamanda C kütüphanelerinin oluşturulma şeklini de etkiliyor gibi görünüyor.
Thomas Hofmann

@ThomasHofmann: Başlangıçta mkstubs aracıyla da kafam karıştı. Öğrendiğim şey, mkstub'ların yalnızca bir (satıcı) sdk eklentisi oluştururken kullanılacağı, sadece normal sdk oluşturduğunuzda kullanılmadığı. Bununla birlikte, mkstubs, DroidDoc ile hemen hemen aynı şeyi yapar, ancak @hideek açıklamaları kullanmaz , "sadece" eklentinin API'sine .defsdahil edilecek paketleri / sınıfları / alanları açıklayan bir dosya kullanır .
Bjarke Freund-Hansen

2
@ThomasHofmann: Hakkında $(hide), kafanızı karıştırıyorsunuz. $(hide)sadece makefiles içinde çalıştırılan programın gerçek komut satırını gizleyen bir önektir, başka bir şey değildir ve hemen hemen her yerde kullanılır. Android SDK veya @hidekaynak kodundaki ek açıklama ile hiçbir ilgisi yoktur .
Bjarke Freund-Hansen

yukarıdaki yolu nasıl kontrol edebilirim çıkış / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny

31

* .Jar dosyalarını Android platformundan yeniden oluşturabiliriz.

İlk önce ADB'yi cihazınıza bağlayın. O zaman koş:

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

core.jarStandart Java kütüphaneleri içerirler ( java.*) ve framework.jar(Android kütüphaneleri içerirler android.*). Gerçek dosyalar JAR formatında değil, DEX formatında olduğundan bu henüz kullanılamaz.

Biz gibi araçları kullanarak gerçek kavanozları içine bu DEX biçimli * .jars dönüştürebilirsiniz dex2jar :

dex2jar core.jar
dex2jar framework.jar

Ardından, "Harici JAR Ekle ..." seçeneğini kullanarak bu kavanozları çekin (Eclipse ADT kullandığınızı varsayarak)

  • sağ tıklayın Project → Properties → Java Build Path → Libraries → Add External JARs... → ( Yukarıdan core-dex2jar.jarve seçin framework-dex2jar.jar).

Bu, dahili ve bazı Java 7 API'lerini kullanmanızı sağlayacaktır. (Gördüğüm kadarıyla oluşturulan APK, JAR'lardan herhangi bir gerçek kod içermiyor.)


Çok teşekkür ederim, birçok yolu denedim, sadece yöntemlerin benim için işe yarıyor.
SalutonMondo

7
Bu yöntemin hala ICS ve sonraki sistemlerle çalıştığını, ancak biraz daha fazla hokkabazlık gerektirdiğini unutmamak önemlidir. İlgili dosyalardır /system/framework/core.odex, /system/framework/framework.odexmuhtemelen daha, ve. Bunlar deodexed ( java -jar baksmali-2.0.3.jar -d system.framework -x system.framework/core.odex -o core) ve reodexed ( java -jar smali-2.0.3.jar -x -o core.dex core) ve ancak bundan sonra dex2jar core.dexişini yapar.
Alex Cohn

marshmallow'da core.jar bulunamadı
mehmet6parmak

android p'de çekirdek ve çerçeve kavanozu için herhangi bir fikriniz var mı?
Prabhakaran

yukarıdaki yolu nasıl kontrol edebilirim çıkış / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny

18

android.jarGizli API'ler olarak kullanılmak üzere değiştirilenleri bu depodan indirebilirsiniz . Oradaki talimatları izleyin.


4
Bu yanıt, en basit çözüm olduğu için daha fazla oylanmalıdır. İnsanlar, eğer bir çözüm arıyorsanız - başkalarının bunu zaten yaptığını ve o github deposuna bir çözüm koyduğunu bilin. Kullanın ve tadını çıkarın! ))
Mixaz

1
API 28 için android.jar'ı kullanırken robolectric ile ilgili bir hata alıyorum. Bir sorun ortaya çıktı github.com/anggrayudi/android-hidden-api/issues/62 ve kavanozunuz için teşekkür ederim @Anggrayudi
Prabhakaran

Ben de aynısını android 10 için yaptım, benim için çalışmıyor, diğer katılımcılardan github.com/aeab13/android-jar-with-hidden-api indirdim . hdmi-
cec sınıfına

17

Lollipop için akış biraz farklıdır:

  1. Lolipop cihazından /system/framework/arm/boot.oat alın

  2. 'Java -jar oat2dex.jar boot boot.oat' komutunu kullanın

  3. İki klasör alacaksınız: dex ve odex. Dex'e gidin ve 'java -jar dex2jar.jar framework.dex' yapın
  4. Ortaya çıkan framework.jar dosyasını .zip olarak yeniden adlandırın, ihtiyacınız olan sınıfları ayıklayın ve bulun
  5. [Sdk_path] / platformlar / [target_platform] 'a gidin ve android.jar dosyasını çıkartın (önce zip olarak yeniden adlandırın).
  6. Dosyaları ayıklanan çerçeveden çıkarılan android.jar'a kopyalayın. Ardından zip olarak sıkıştırın ve .jar olarak yeniden adlandırın :)

ps: muhtemelen 'framework_classes2.dex' için 4-6. adımları tekrarlamanız gerekir


3. adımda, dex2jar.jar dosyasını bu bağlantıda bulamıyorum .... Birçok şeyi denedim ve çözemiyorum. Bunun bir yerde bağlantısı var mı? Android SDK'mda yer alıyor mu? Bulamıyorum
Dwebtron

Evet, bir github projesine gidiyor ve belki de benim, ama orada ".jar" ile biten HERHANGİ bir dosya bulamıyorum ...
Dwebtron

1
'sürümler' bölümüne bakın
sapkın

2
Görünüşe göre dex2jar'ın son sürümleri indirme biçimini değiştirmiş. İndirdiğiniz dosyayı açın ve 'java -jar ...' yerine platformunuza bağlı olarak 'd2j-dex2jar.sh' veya 'd2j-dex2jar.bat' komut dosyasını doğrudan framework.dex dosyası
CalumMcCall

1
her iki jar dosyasını da android.jar içine kopyaladım, şimdi android studio bana Hata: ': app: processDebugResources' görevi için yürütme başarısız oldu diyor. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: İşlem 'komutu' D: \ Program \ Android \ android-sdk \ build-tools \ 19.1.0 \ aapt.exe ' 'sıfır olmayan çıkış değeri 1 ile bitti
wutzebaer

15

DroidCon 2011

Sony Ericson'dan Erik Hellman, gizli Android API'lerine nasıl erişileceğini açıklıyor:

http://vimeo.com/30180393 (Hmm bağlantısı çalışmıyor gibi görünüyor).

Goto DroidCon web sayfası 2. Gün için kaydırma aşağı Gizli API'leri 10:15 kullanma ve orada izleyebilirsiniz.

Bağlantılar ölüyor!

Bunu buldum: http://skillsmatter.com/podcast/os-mobile-server/hidden-api dunno ne kadar sürecek

Android SDK'daki resmi API'ler genellikle çoğu normal uygulama için yeterlidir. Ancak, bazen bir geliştiricinin resmi API'lerde yayınlanmayan dahili sistem hizmetlerine, API'lere ve kaynaklara erişmesi gereken durumlar olabilir. Neyse ki, bu API'ler bazı akıllıca hilelerle hala kullanılabilir ve Android'in yanı sıra yeni ve yenilikçi bir çözüm geliştirirken genellikle yararlı olabilir. Bu oturumda, bu gizli ve korumalı API'lere nasıl erişeceğinizi ve bunları nasıl kullanacağınızı, kullanım sınırlamalarını ve bunların birden çok satıcı cihazında ve Android sürümünde güvenli ve kontrollü bir şekilde nasıl kullanılacağına dair bazı ipuçlarını öğreneceksiniz. Seyirci, normalde Android ile yapamayacağınız birkaç gelişmiş demo görecektir. Android platformunun iç kısımları hakkında birçok bilgi içeren oldukça gelişmiş bir oturum bekleyin.


1
İlginç ama maalesef soruma cevap vermiyor. Gizli şeyler dahil SDK'yı gerçekten yeniden inşa etmenin bir yolunu istiyordum.
Thomas Hofmann

Görünüşe göre istediğimi elde etmenin başka bir yolunu buldum. Yarın tarif edeceğim.
Thomas Hofmann

ADT'de gizli API kullanan bir projenin kaynağını derlemek istiyorsanız şunları yapabileceğinizi öğrendim: 1) Kaynak için bir Android projesi oluşturun. 2) Android sınıf yolu taşıyıcısını derleme yolundan kaldırın 3) Bir ASOP ROM derlemesinden JAR dosyalarını içeren bir kullanıcı kitaplığı tanımlayın (ayrıca sistem kitaplığı onay kutusunu işaretleyin), örneğin cm7). Hangi JAR dosyalarını kullanacağınız, neye başvurmanız gerektiğine bağlıdır. çerçeve yakınları muhtemelen bunun bir parçası olacaktır.
Thomas Hofmann

4) Proje şimdi oluşturulduğunda, kullanıcı kitaplığı sınıfları oluşturulmakta olan APK'ye dahil edilmeyecektir. Gizli API görünür ve her şey iyi bir şekilde derlenir.
Thomas Hofmann

@Blundell: Bağlantıları günceller misiniz lütfen .. onlar öldü!
zombi

12

Bakmak için deneyin bu :

Bu makalelerin nihai hedefi, geliştiricilere yansıma kullanmadan Dahili ve Gizli API'lerin gücünü vermektir. Sonraki birkaç bölümde açıklanan tüm adımları tamamlarsanız, Dahili ve Gizli API'leri herkese açık API'lermiş gibi kullanabilirsiniz. Düşünmeye gerek kalmayacak.

Ancak bu halka açık olmayan API'leri kullanıyorsanız, uygulamanızın büyük risk altında olduğunun farkında olmalısınız. Temel olarak, API'lerin bir sonraki Android işletim sistemi güncellemesiyle bozulmayacağına dair hiçbir garanti yoktur. Farklı satıcıların cihazlarında tutarlı davranış konusunda hiçbir garanti bile yoktur. Tamamen kendi başınasın.

Takip etmek isteyebileceğiniz üç senaryo vardır:

  1. Hem etkinleştirme ve gizli API'leri (senaryo A)
  2. Yalnızca gizli API'yi etkinleştirin (senaryo B)
  3. Yalnızca dahili API'yi etkinleştirin (senaryo C)

Senaryo A, B ve C'nin toplamıdır. Senaryo B en kolay olanıdır (tutulma ADT eklentisi değişikliği gerektirmez).

Senaryo A : 1 , 2 , 3 , 4 , 5 numaralı bölümleri okuyun

Senaryo B : 1 , 2 , 3 , 5 numaralı bölümleri okuyun

Senaryo C : 1 , 2 , 3 , 4 , 5 numaralı bölümleri okuyun


3
O blog girişini zaten okudum. Şundan bahsediyor: "1) Android açık kaynaklı bir projedir. Kaynak kodunu indirebilir ve derleme sistemini özelleştirebiliriz, böylece dahili ve gizli sınıfları android.jar'dan dışlamaz. Bu zor bir yoldur." Ne yazık ki ayrıntılara girmiyor.
Thomas Hofmann

3
Blog post (son bölümünde git devmaze.wordpress.com/2011/01/19/... ), bir bağlantı var ( github.com/inazaruk/android-sdk/tree/master/platforms ) Android önceden oluşturulmuş Tüm gizli ve dahili API'lere sahip API'ler.
Bob

1
Verilen bağlantılara erişilemiyor, yazarın izni gerekiyor
SHAHS

yukarıdaki yolu nasıl kontrol edebilirim çıkış / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny

1

Bir keresinde java dosyalarını http://source.android.com/ adresindeki bir repo çıkışından çıkarmak ve ardından gerekli diğer adımlar da dahil olmak üzere tüm android kaynaklarını derlemek için tam bir araç zincirine ihtiyaç duymadan derlemek için bazı Groovy komut dosyaları yazdım ( paketleme, kaynak oluşturma vb.)

Burada bulunabilirler:

https://github.com/thoutbeckers/CollectAndroid

Ancak kesinlikle bunun Gingerbread'den sonraki her şey için, çoğunlukla yapılandırma dosyasındaki (CollectConfig.groovy) "rootdirs" içinde doğru dizinleri ayarlayarak güncellenmesi gerekecektir.

O zamanlar bunu, mevcut tüm gizli API ve kaynaklarla (o sırada sorunlu olan) geliştirme için düzenli olarak kullandım.

Başka bir yerde belirtildiği gibi com / android / internal / **, eklenen erişim kuralı nedeniyle ADT'nin son sürümlerinde hala gizlenecektir.


yukarıdaki yolu nasıl kontrol edebilirim çıkış / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny

Bu depoyu, Gingerbread için son güncellendiğinden beri arşivledim . Ne yazık ki başka bir yaklaşım bulmanız gerekecek.
thoutbeckers

1

Long'un cevabı benim için işe yaradı, ancak hala ihtiyacım olan bazı dersleri, özellikle android.provider.telefonu kaçırıyordum. Bunu şöyle ekleyebildim:

  1. Framework.jar dosyasını ayıklayın

    mkdir /tmp/framework
    cp framework.jar /tmp
    cd /tmp/framework
    jar xvf ../framework.jar
    mv android classes
    
  2. Out / target / common / obj / JAVA_LIBRARIES dizinini oluşturacak Android deposu oluşturun

  3. Eksik sınıfların nerede olduğunu bulun

    $ 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. Yeni sınıfları ekleyin ve çerçeve JAR dosyasını yeniden oluşturun

    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 .
    

Ya da sadece tembel olabilir ve tüm sınıfları tek bir dev jar dosyasına dahil edebilirsiniz:

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 bu yolu nasıl bulabilirim?
Bunny

@Bunny Cevabımı daha fazla ayrıntıyla güncelledim. Ancak buradaki cevap daha kolay olabilir gibi görünüyor: stackoverflow.com/a/32626155/399105
bmaupin

Cevabınız için teşekkürler @bmaupin .. Lütfen bana bu yolu nasıl bulabilirim yardım eder misiniz / target / common / obj / JAVA_LIBRARIES framework jar almak için ... gerçekten takıldım..Bu yolu bulamıyorum veya bir şey eksik ... lütfen rehberlik edin
Bunny

0

Yorum yapamam ama bu temelde @ KennyTM'nin ( https://stackoverflow.com/a/13550030/2923406 ) mükemmel cevabına bir yorum:

Kendinizi Eclipse'de aşağıdaki hatayla bulursanız:

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

(yani, android.internal. * kullanılamaz)

O zaman olası bir çözüm aynı yöntemi /system/framework/framework2.jar için uygulamaktır. SDK19 için Android Emülatörünü kullanarak bu ekstra kavanozum var. HTC One cihazımda bir framework3.jar bile var.


yukarıdaki yolu nasıl kontrol edebilirim çıkış / target / common / obj / JAVA_LIBRARIES / framework_intermediates / classes.jar
Bunny
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.