Автообновление для (частных) приложений Android
Я разрабатываю непубличное приложение для Android, то есть приложение не будет доступно в глобальном Android Market. Приложение будет установлено на ограниченном количестве клиентов, например, с помощью файла apk. Как включить функцию автообновления в этом приложении?
Я вижу разные потенциальные варианты (я не знаю, технически сложно или вообще невозможно реализовать или есть какие-то существующие функции, которые можно использовать повторно):
- При каждом запуске приложение проверяет, существует ли новая версия (запрашивая сервер), в этом случае загружает новый apk и заменяет себя новой версией.
- Использовать (или разрабатывать?) Отдельное приложение или сервис, который выполняет проверку обновлений и процесс замены.
- Используйте (или разработайте?) Приложение для частного рынка, у которого есть опция автообновления. Эта опция похожа на вторую, но более общая: рыночное приложение будет подключено к репозиторию, то есть будет обрабатывать произвольное количество (частных) приложений.
Я бы предпочел первый вариант, поскольку функция автообновления включена в приложение, которое требует меньше усилий для разработки.
6 ответов
janjonas, в компании, в которой я работаю, у нас была похожая проблема с Windows Mobile 6.x, и мы используем почти то же решение, на которое указывает EboMike:
Основное приложение проверяет, обновлено ли оно, с помощью WebService. Он получает текущую версию и URL-адрес, откуда скачать новую версию, если это необходимо. Затем основное приложение запускает приложение Updater, передавая URL-адрес, и завершает работу.
Updater выполняет загрузку новой программы через HTTP, показывая пользователю загруженный%. Пользователь может отменить загрузку в любое время контролируемым образом, и Updater может зарегистрировать эту отмену.
Поскольку новое приложение загружено, Updater запустит новое приложение и выйдет.
Я думаю, что первый вариант - это наименьший объем работы для вас, и на самом деле самый чистый, так как он будет проходить через соответствующий канал использования встроенного установщика пакетов Android, который включает уведомление пользователя и возможность для пользователя прервать установку, если желательно.
Вы уже обрисовали все это в общих чертах - проверьте наличие новой версии на сервере (было бы неплохо дать пользователю возможность отключить это), и, если есть новая версия, вы можете просто указать ссылку на URL с помощью APK (который, IIRC, использует менеджер загрузки браузера, чтобы загрузить его), или вы можете загрузить его вместе с приложением, а затем указать намерение на локальный файл. Использование HTTP-ссылки технически менее трудоемко и чище - чем больше вы позволяете операционной системе, тем лучше - если нет причин не делать этого.
Включение "Установить нерыночное приложение" по-прежнему необходимо для любого приложения за пределами Google Play. Если он не включен, процесс установки запросит его и перенаправит пользователя в настройки приложения, после чего пользователь сможет установить приложение.
В зависимости от ваших потребностей, вы можете делегировать третьей части lib.
Вот некоторые из разрешений, которые мы будем использовать для этого:
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Позвольте мне объяснить немного... Последнее, WRITE_EXTERNAL_STORAGE, говорит само за себя. С помощью ACCESS_SUPERUSER мы сообщим системе, что намереваемся использовать привилегии root. READ_EXTERNAL_STORAGE понадобится в будущем, чтобы приложение могло считывать файлы с SD-карты.
Предполагая, что вы загрузили файл и что все эти устройства могут быть рутированы (ограниченное количество клиентов, не на Play и т. Д.), Вы можете сделать это:
String filePath = Environment.getExternalStorageDirectory().toString() + "/your_app_directory/your_app_filename.apk";
Process installProcess = null;
int installResult = -1337;
try {
installProcess = Runtime.getRuntime().exec("su -c pm install -r " + filePath);
} catch (IOException e) {
// Handle IOException the way you like.
}
if (installProcess != null) {
try {
installResult = installProcess.waitFor();
} catch(InterruptedException e) {
// Handle InterruptedException the way you like.
}
if (installResult == 0) {
// Success!
} else {
// Failure. :-/
}
} else {
// Failure 2. :-(
}
Это может быть очень неэффективный метод, но для некоторых компаний, если вы считаете, что он применим, его может быть очень легко реализовать.
- Создайте экран пароля (passwordActivity), который запрашивает пароль для доступа к приложению.
- Как только пароль введен, поднимите флаг (установите логическое значение от false до true, используя sharedpreferences)
- Поместите файл.apk в Google Store.
- Измените пароль, как только все установят приложение, и выпустите новое обновление в Google Play Store.
Поскольку программное обеспечение собирается кешировать значение флага, экран пароля не будет отображаться даже при смене пароля. Он будет отображаться только для новых установок, поэтому может потребоваться повторить процесс.
Примечание. Этот метод может лучше подойти, если приложение не использует сотни пользователей. И не забывайте, что этот метод также не является безопасным. Подводя итог, если вы ищете способ сохранить конфиденциальность приложения и не беспокоиться о безопасности, то это то, что я рекомендую.
Обновление приложения Убедитесь, что у вас уже есть новый APK скачать на месте
void installNewVersion(String location) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(location + "app-debug.apk")),
"application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}