Instalar / desinstalar do comando shell no Android
Eu quero implementar um silencioso installer-from-apk-file e unistaller-package no Android. O tópico foi amplamente discutido no SO e em outros lugares, mas não posso aplicar nenhum por algum motivo que esteja faltando. O escopo é obviamente difícil de alcançar porque, se for bem-sucedido, seria uma séria falha de segurança no Android. MAS, preciso implementá-lo para um projeto especial, não para o mercado consumidor. Existem duas abordagens:
para gerar uma ROM personalizada a partir de um código-fonte (AOSP ou Cyanogen mod, por exemplo), ajustando o instalador do PackageManager (na verdade apenas para remover as caixas de diálogo de aceitação do usuário).para fazer isso programaticamente, criando um processo como superusuário e executando um 'adb shell pm install'. Eu instalei anteriormente 'su' em / system / xbin e testei durante o tempo de execução que RootTools.rootIsAvailable ().No primeiro caso, eu mergulhei no código-fonte do Froyo, mas entrei num beco sem saída com um método marcado pelo @hide. Para o segundo eu tentei pela primeira vez os comandos do terminal
adb shell pm install /mnt/sdcard/HelloAndroid.apk
e
adb shell pm uninstall com.example.helloandroid
Ambos funcionam bem. Então, usei o seguinte código, o desenvolvimento sendo testado em um emulador enraizado (2.2 - Froyo):
@Override
public void onClick(View v) {
switch (v.getId())
{
case R.id.btnInstall:
try {
install = Runtime.getRuntime().exec("su\n");
DataOutputStream os = new DataOutputStream(install.getOutputStream());
os.writeBytes("pm install /mnt/sdcard/HelloAndroid.apk\n");
os.writeBytes("exit\n");
os.flush();
install.waitFor();
if (install.exitValue() == 0) {
Toast.makeText(MainActivity.this, "Success!", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(MainActivity.this, "Failure. Exit code: "+String.valueOf(install.exitValue()), Toast.LENGTH_LONG).show();
}
}
catch (InterruptedException e) {
logError(e);
}
catch (IOException e) {
logError(e);
}
break;
case R.id.btnUninstall:
try {
install = Runtime.getRuntime().exec("su\n");
install=Runtime.getRuntime().exec("pm uninstall "+txtPackageName.getText().toString()+"\n");
} catch (Exception e) {
logError(e);
}
break;
}
}
Para evitar erros de digitação e outros ajustes, codifiquei o parâmetro do arquivo apk do comando para a instalação; no caso 'R.id.btnInstall' o comando não é executado e a saída está em "Failure" com o valor de saída 1, significando que "a classe não pode ser encontrada"; Não sei o que isso significa ... Eu agradeço a sua ajuda!
EDITADO: Eu tenho a solução limpa, vou postar a resposta de A-Z, assim que eu tiver o tempo e o código na forma correta !!