O Android tem dois tipos de APIs que não são acessíveis via SDK.
O primeiro está localizado no pacote com.android.internal. O segundo tipo de API é uma coleção de classes e métodos marcados com o atributo @hide Javadoc .
A partir do Android 9 (API nível 28), o Google introduz novas restrições ao uso de interfaces não SDK , seja diretamente, via reflexão ou via JNI. Essas restrições são aplicadas sempre que um aplicativo faz referência a uma interface não SDK ou tenta obter seu identificador usando reflexão ou JNI.
Porém, antes do nível 28 da API, os métodos ocultos ainda podiam ser acessados via reflexão de Java. O @hideatributo é apenas parte do Javadoc (droiddoc também), portanto, @hidesignifica simplesmente que o método / classe / campo é excluído dos documentos da API.
Por exemplo, o checkUidPermission()método em ActivityManager.javausa @hide:
/** @hide */publicstaticint checkUidPermission(String permission,int uid){try{returnAppGlobals.getPackageManager().checkUidPermission(permission, uid);}catch(RemoteException e){// Should never happen, but if it does... deny!Slog.e(TAG,"PackageManager is dead?!?", e);}returnPackageManager.PERMISSION_DENIED;}
No entanto, podemos chamá-lo por reflexão:
Class c;
c =Class.forName("android.app.ActivityManager");Method m = c.getMethod("checkUidPermission",newClass[]{String.class,int.class});Object o = m.invoke(null,newObject[]{"android.permission.READ_CONTACTS",10010});
Olá, @StarPinkER, posso conceder permissão "android.permission.CHANGE_COMPONENT_ENABLED_STATE" usando API oculta ou interna ou por reflexão?
Hardik
1
Verifique esta resposta primeiro. Essa permissão é uma assinatura / permissão do sistema. Na maioria dos casos, você não pode obter essa permissão, a menos que sejam aplicativos do sistema. Isso significa que você precisa modificar a Fonte Android para aceitar seu aplicativo ou torná-lo um aplicativo de sistema e assiná-lo. No entanto, você não poderá fazer isso a menos que esteja criando seu próprio sistema Android. O Reflection pode lidar com "ocultação", mas não pode alterar a lógica do sistema de segurança Android. Você pode imaginar como podemos atacar facilmente um dispositivo Android, se pudermos fazer isso. @Hardik
StarPinkER
2
Obrigado pela resposta, mas acho que há dois problemas na resposta, corrija-me se estiver errado. Eu recebo um erro sem classe se tentar encontrá-lo por "ActivityManager" em vez de "android.app.ActivityManager" e "m.invoke (c," parece ser "m.invoke (null", "para métodos estáticos" e "m. invoke (o, ", onde o é um objeto do tipo c, por métodos dinâmicos Desculpem a minha gramática polaca :).
lindenrovio
3
Apenas uma observação sobre a reflexão: como esses métodos / campos não fazem parte do SDK oficial, não há garantia de que eles estarão presentes em qualquer futura revisão do Android.
sstn
2
Se a anotação remove apenas o método da documentação, por que ainda não posso usá-lo no código?
Javier Delgado
25
@hideé usado para itens que precisam estar visíveis por vários motivos, mas não fazem parte da API publicada. Eles não serão incluídos na documentação quando extrair automaticamente a API da fonte.
Você está certo, você não pode substituí-lo. Isso é normal, é por design, pois está marcado como final. Você deve poder usá- lo, embora um editor não o mostre como uma das opções em qualquer intelecto que ele usa porque está marcado com @hide, e você deve tomar nota do ponto 3 abaixo.
Você não deve usá-lo, pois não faz parte da API e os desenvolvedores podem removê-la sempre que desejarem. Eles estariam dentro dos seus direitos, se eles estivessem sadicamente inclinados, para substituí-lo por uma função que bloqueava o dispositivo em que ele era executado (embora talvez não em um sentido legal estrito).
Oh sim ... é finalclaro que não posso substituí-lo. Desculpe, esse é o meu erro: x
midnite
Você quer dizer, é publicatravés de todas as classes durante o estágio de desenvolvimento. Mas ele age como privateou /*package*/para usuários como nós?
midnite
Hmm ... Isso é apenas um comentário. eu entendo seus significados. Mas o que e onde aplicar esse comportamento no nível do código?
midnite
1
Por que é público, não posso realmente comentar. Talvez a implementação do código Activityesteja espalhada por várias classes e todas elas precisem acessar esse membro. Resumindo, é público, mas não faz parte da API, o que significa que você a utiliza por seu próprio risco.
paxdiablo
1
@ midnite, o Eclipse tem seu próprio compilador Java, que sem dúvida é integrado ao material do intellisense. Eu sugeriria que se você compilasse isso com o Java SDK, ele seria bem compilado. Não que eu estou sugerindo isso, claro, ver o ponto 3.
paxdiablo
4
A @hideanotação significa que essa interface não faz parte da API pública e não deve ser usada no seu código. Os métodos são apenas para uso interno do AOSP.
light-greylist: métodos / campos não SDK que ainda estão acessíveis.
greylist escuro:
Para aplicativos cujo SDK de destino está abaixo do nível 28 da API: é permitido o uso de uma interface de lista cinza escura.
Para aplicativos cujo SDK de destino é API nível 28 ou superior: mesmo comportamento da lista negra
lista negra: restrita, independentemente do SDK de destino. A plataforma se comportará como se a interface estivesse ausente. Por exemplo, ele lançará NoSuchMethodError / NoSuchFieldException sempre que o aplicativo estiver tentando usá-lo e não o incluirá quando o aplicativo quiser conhecer a lista de campos / métodos de uma classe específica.
@hide
é usado para itens que precisam estar visíveis por vários motivos, mas não fazem parte da API publicada. Eles não serão incluídos na documentação quando extrair automaticamente a API da fonte.Você está certo, você não pode substituí-lo. Isso é normal, é por design, pois está marcado como
final
. Você deve poder usá- lo, embora um editor não o mostre como uma das opções em qualquer intelecto que ele usa porque está marcado com@hide
, e você deve tomar nota do ponto 3 abaixo.Você não deve usá-lo, pois não faz parte da API e os desenvolvedores podem removê-la sempre que desejarem. Eles estariam dentro dos seus direitos, se eles estivessem sadicamente inclinados, para substituí-lo por uma função que bloqueava o dispositivo em que ele era executado (embora talvez não em um sentido legal estrito).
fonte
final
claro que não posso substituí-lo. Desculpe, esse é o meu erro: xpublic
através de todas as classes durante o estágio de desenvolvimento. Mas ele age comoprivate
ou/*package*/
para usuários como nós?Activity
esteja espalhada por várias classes e todas elas precisem acessar esse membro. Resumindo, é público, mas não faz parte da API, o que significa que você a utiliza por seu próprio risco.A
@hide
anotação significa que essa interface não faz parte da API pública e não deve ser usada no seu código. Os métodos são apenas para uso interno do AOSP.O Google começou a restringir o uso de interfaces não sdk . Isso inclui interfaces marcadas com
@hide
Os métodos são classificados em quatro listas:
As listas podem ser encontradas aqui: https://android.googlesource.com/platform/prebuilts/runtime/+/master/appcompat
fonte