Como eu analisei o código de outra pessoa. O que é útil pode ser encontrado dentro de aplicativos de Android bem conhecidos

04.08.2017

Neste artigo eu vou falar sobre como eu analisei o código de aplicativo da outra pessoa e achei uma função indocumentada interessante para trabalhar com widgets de aplicativos.

Widget com configuração ao adicionar

A maioria de vocês já viram uma tela com configurações que aparece quando adicionam um widget para tela de aparelho. Por exemplo, widget de previsão de tempo pode perguntar: “Para que cidade você quer exibir previsão?” Desse jeito é muito fácil de ajustar vários widgets pelo apenas um aplicativo para visualizar diversas informações.

Para economizar nosso tempo nas ações de rotina, o Android Studio pode criar uma forma de padrão com widget configurado. De nós precisa-se apenas checar alguns marcadores em um assistente bem informativo. Iniciar ele assim: New – Widget – AppWidget.

Como resultado de trabalho dele, em nosso projeto vamos ver duas novas classes que automaticamente serem descritos em manifest:

<receiver android:name=".NewAppWidget">
  <intent-filter>
    <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
  </intent-filter>

  <meta-data
    android:name="android.appwidget.provider"
    android:resource="@xml/new_app_widget_info"/>
</receiver>

<activity android:name=".NewAppWidgetConfigureActivity">
  <intent-filter>
    <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
  </intent-filter>
</activity>

A primeira classe é responsável por próprio widget e segunda descreve atividades para sua configuração que vai ser iniciada no momento de sua adição. Essa atividade nós podemos iniciar nos momentos diferentes mas não seria claro qual widget está configurando. Assim este é momento perfeito e melhor não chamar essa configuração mais. Este exemplo de criação de widget está descrito em qualquer aula e documentação. O código é simples, você consegue entender facilmente.

Widgets úteis e inúteis

No começo eu apenas queria desenhar uma ícone de aplicativo em widget. A justificativa para isso é que para adicionar uma ícone para tela de trabalho deve adicionar uma permissão em manifest.

<uses-permission
  android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />

Mas os usuários não gostam muitas permissões para aplicativo e, além disso, mudando permissões em manifest, o mecanismo de atualização automática fica desligado. Eu fiz várias tentativas de desenhar uma ícone igual a original mas sem sucesso. Isso aconteceu por falta de compreensão de funcionamento do sistema. O widget não serve para copiar a funcionalidade da ícone, ele pode ser muito parecido mas desenhado de jeito diferente. Para cada firmware há próprio launcher que desenha área de trabalho com ícones e widgets como quis o desenvolvedor.

Tendo analisado o trabalho de outra pessoa, no começo eu fui desencorajado: no aplicativo o widget não possui uma tela de configurações, ele apenas copia funcionalidade de ícone iniciando aplicativo. Na primeira vista ele totalmente inútil… Mas quando eu entrei em contato com desenvolvedores de aplicativo, eles disseram que widget mostra quantidade de mensagens não lidas. Essa função havia em iOS.

Mas não é bem claro porque um widget pequeno tem essa possibilidade de mudar tamanho? Ou porque, por exemplo, não fizeram uma opção de configuração de uma caixa de entrada quando adicionam o widget?

Criamos ícones igual a farproc

Então, como eu consegui criar uma nova ícone através de widget comum. Vamos ver como fazem os outros desenvolvedores… Nisso me podem ajudar diversas ferramentas, geralmente eu uso decompilador on-line ou decompileandroid.com. Lendo manifest do aplicativo Wifi Analyzer eu não encontrei nenhuma descrição de widgets como no exemplo anterior. Mas temos um widget! E de alguma maneira ele chama uma tela com escolha de ícone!

Pelo um método de busca profunda e método de ensaios e erros, foi determinado que neste caso foi utilizada uma função indocumentada. E tem que adicionar para manifest uma nova atividade com um filtro especial:

<activity
  android:name="com.farproc.wifi.analyzer.CreateShortcutScreen"
  android:excludeFromRecents="true"
  android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
  android:noHistory="true">
  <intent-filter>
    <action android:name="android.intent.action.CREATE_SHORTCUT"/>
  </intent-filter>
</activity>

A tela necessária foi chamada, assim, temos a liberdade completa para criatividade. Aqui, por exemplo, um código completamente compreensível, “arrumado” para adicionar uma ícone:

private Intent m1641a(int i) {
  Intent intent = new Intent();
  Parcelable intent2 = new Intent(this, MainScreen.class);
  intent.putExtra("android.intent.extra.shortcut.ICON_RESOURCE", ShortcutIconResource.fromContext(this, f1149c[i]));
  intent.putExtra("android.intent.extra.shortcut.INTENT", intent2);
  intent.putExtra("android.intent.extra.shortcut.NAME", getString(R.string.app_name));
  return intent;
}

Todos os nomes reais dos métodos foram alterados mas você não pode deixar as constantes. Elas mostram para nós a essência do que está acontecendo.

Como eu realizei habilitação de dados móveis pelo um widget?

O autor mencionado acima tem um aplicativo Data Enabler Widget. Sua funcionalidade permite ativar e desativar internet móvel diretamente de área de trabalho pelo um widget sem permissões de root. Este widget eu usei no um aparelho velho de Samsung com versão de Android 2.3 mas nas versões mais recentes ele não funcionou J

Na forma decompilada, a função de habilitação de dados GPRS está apresentada assim:

private void b(Context context)
{
  if (a != null)
  {
    break MISSING_BLOCK_LABEL_56;
  }
  a = (ConnectivityManager)context.getSystemService("connectivity");
  try
  {
    b = android/net/ConnectivityManager.getMethod("setMobileDataEnabled", new Class[] {
      Boolean.TYPE
    });
  }
  // Declaração incorreta de uma variável de exceção
  catch (Context context) { }
  c = android/net/ConnectivityManager.getMethod("getMobileDataEnabled", new Class[0]);
  return;
  context;
}

Você pode encontrar essa versão aprimorada no Stack Overflow. No mesmo lugar o autor fala que funciona nas todas versões de Android e versão 5.0 somente se aplicativo é de sistema. Pelo minhas observações, pode ligar internet só até versão 4.3.

A base desse método é reflecção através de que chamado um método não público. Em termos de segurança isso é grande problema porque qualquer aplicativo pode ligar cellular e navegar a internet. Porém nas versões de Android mais recentes essa brecha foi fechada.

Usando métodos escondidos

Independentemente de todas capacidades de plataforma de Android num momento a gente vai chegar até o limite. Chamada de métodos escondidos pelo reflecção permite para nós ampliar os limites e realizar mais do que descrito na documentação. Aqui, por exemplo, um jeito de conectar aparelhos que possuem Bluetooth.

Geralmente, os limites da plataforma são determinados por segurança. Você não pode permitir que um aplicativo vai navegar a internet sem avisar usiário ou vai criar uma rede de Bluetooth do seu aparelho. Neste caso, por conveniência você não pode sacrificar segurança. Portanto o usuário cada vez vai conectar a internet manualmente. Nos projetos sérios, os métodos escondidos não serem utilizados e grandes desenvolvedores não recomendam também. Eu plenamente concordo com eles: não é garantido que o quê está funcionando hoje, vai funcionar amanhã. No mundo de Android já tem bastante dor de cabeça sem isto…

Decompiladores on-line

O quê me deixa bem animado é que cada dia aparecem mais e mais novas ferramentas para analizar aplicativos. Aqui é uma lista de três sites:

Нашли ошибку в тексте?

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *