Установите системное приложение Android, беззвучное обновление без Google play на рутированном устройстве.
Я пытаюсь заставить мое приложение загрузить обновление с ftp-сайта в виде новой версии apk. После загрузки apk должен быть установлен в автоматическом режиме, без какого-либо подтверждения от пользователя. У меня есть часть загрузки под контролем. Я также могу сделать это с подтверждением от пользователя. Проблема в тихой части обновления.
Из того, что я могу сказать, единственный способ сделать это - установить приложение как системное приложение. Здесь мне нужна помощь.
Я перепробовал много вещей. Наибольший успех у меня был следующий:
- Рут устройства.
- Добавление *android:sharedUserId="android.uid.system" в манифест.
Добавление следующих разрешений в манифест:
android.permission.ACCESS_SUPERUSER и android.permission.INSTALL_PACKAGES
Подписание apk с помощью Android Studio->Build->Generate Signed APK... используя подпись, сгенерированную следующим образом:
./keytool-importkeypair -k google_certificate.keystore -p android -pk8 platform.pk8 -cert platform.x509.pem -alias платформа
где я получил файлы pk8 и pem из исходного зеркала Android на GitHub.
- Переместите подписанный apk в system/app на устройстве и нажмите "Установить на нем".
Первое, что я получаю, это огромный список разрешений, которые запрашивает приложение, чего я никогда не делал. Так что я думаю, что это права доступа, которые есть у системного приложения.
Сразу после того, как я получаю сообщение:
Приложение не установлено.
Google не мог сказать, почему эта ошибка происходит, поэтому я спрашиваю здесь.
Я на правильном пути?
Почему приложение не было установлено?
2 ответа
Так что через пару лет я снова добрался до этой проблемы, и мне удалось ее решить. Таким образом, наиболее важной частью является правильная рутировка телефона: это было сделано с помощью приложения SuperSU.
После загрузки файла.apk для установки обновления используется метод, аналогичный следующему:
private Boolean Install(String path)
{
File file = new File(path);
if(file.exists()){
try {
Process proc = Runtime.getRuntime().exec(new String[]{"su","-c","pm install -r -d " + path});
proc.waitFor();
BufferedReader input = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
String line;
Boolean hasError = false;
while ((line = input.readLine()) != null) {
if(line.contains("Failure")){
hasError = true;
}
}
if(proc.exitValue() != 0 || hasError){
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
return false;
}
Если ваше устройство имеет root-права, вы можете выполнить эту команду:
pm install com.example.myapp
Как выполнить эту команду?
Есть два способа:
Способ № 1:
использование RootTools
библиотека:
Command command = new Command(0, "pm install com.example.myapp") {
@Override
public void commandCompleted(int arg0, int arg1) {
Log.i(TAG, "App installation is completed");
}
@Override
public void commandOutput(int arg0, String line) {
}
@Override
public void commandTerminated(int arg0, String arg1) {
}
}
RootTools.getShell(true).add(command);
Способ № 2:
Этот способ не требует библиотек, но он сложнее, чем первый.
//Start a new process with root privileges
Process process = Runtime.getRuntime().exec("su");
//Get OutputStream of su to write commands to su process
OutputStream out = process.getOutputStream();
//Your command
String cmd = "pm install com.example.myapp";
//Write the command to su process
out.write(cmd.getBytes());
//Flush the OutputStream
out.flush();
//Close the OutputStream
out.close();
//Wait until command
process.waitFor();
Log.i(TAG, "App installation is completed");