- PVSM.RU - https://www.pvsm.ru -
На днях я сделал приложение [1] для обхода блокировки rutracker, однако уже дважды получил от Google отбой по разным надуманным причинам. Это очень огорчило, и возник вопрос — что делать? Поиск по хабру показал, что такие проблемы возникли очень у многих (пруфы: один [2], два [3], три [4], четыре [5]… Тысячи их).
А помимо бана есть ещё много причин, по которым ваше приложение может оказаться «за бортом» Google Play — например, если оно предназначено для использования только в компании, для друзей или для другого круга лиц. Так же возможно, что ваше приложение по определению не может быть выложено на Google Play — например, если оно является само по себе установщиком приложений.
Готовой статьи на эту тему я не нашёл, так что решил, что верным решением будет разобраться и написать свою. Итак, принципиальных варианта есть всего два.
Тут довольно богато. Amazon App Shop, Samsung Apps, Yandex.Store, blackmart, humble bundle, F-Droid… В общем-то неплохо. Я из них пока попробовал только Yandex.Store. Получилось зарегистрироваться и опубликовать приложение минут за 5 — оно там уже доступно. Правда, недоумение вызывает полная невозможность как-либо дать ссылку на установку приложения в Yandex.Store. Может, я слепой, но кнопочки «Share» там просто нет. Ну и никакого веб интерфейса — только мобильный. Кстати, вопрос к представителям Yandex — а Yandex.Store вообще живой? Последний пост в твиттере датируется 2014 годом.
Как ни страшно это звучит, на самом деле здесь мы приходим к аналогу обычного десктопного софта. Сама программа знает, когда и как ей обновляться, рассказывает об этом, в ней интегрированы платёжные возможности и монетизация. Рекламой и продвижением занимаетесь вы сами. Ужас, ужас! Но на самом деле, мы просто избаловались. Нужно просто находить правильные пути. Продвигать приложение можно, например, на тематических блогах и форумах — в том числе на 4pda с очень неплохим объёмом аудитории. Или прямо на хабре.
Кстати, даже если ваше приложение успешно опубликовано на Google Play — имеет смысл подстраховаться и как минимум сделать в нём свой алгоритм обновления, который активизируется, если, например, приложение давно не обновлялось. Или по проверке бана на вашем сервере или прямо на Google Play. Иначе, если вас на какое-то время забанят, пользователи не смогут обновить приложение. А если есть запасной вариант — вреда будет заметно меньше.
Ваше приложение практически невозможно заблокировать — только вместе с ресурсом, на котором вы держите обновление и информацию.
Итак, что же вам придётся делать:
На самом деле, это всего лишь означает, что вам нужно выложить APK куда-то в доверенное место. Их не так уж мало — можно использовать всё тот же 4pda, можно класть релизы прямо в github, можно на свой сайт… Вариантов уйма.
Да, привыкли мы к хорошему — Google сам поймает ошибку, всё расскажет о её месте, устройстве пользователя и так далее. Но… Никак проблем это реализовать самостоятельно. Как простейший вариант — ловим все эксепшны и отсылаем куда-то на сервер по HTTP или даже на почту.
К сожалению, никогда не интересовался статистикой приложений, но вам с очевидностью придётся реализовать как минимум статистику по скачиваниям.
Собственно придётся забыть о всех сложных и хороших вещах, которые даёт Google Play. Впрочем, то же самое касается, пускай и в чуть меньшей степени, любых магазинов приложений.
По обновлению есть принципиально три варианта:
Чтобы показать, как всё просто — покажу примитивную реализацию третьего варианта,
// releaseVersionCode 5
2. Публикуем где-то релизы приложения. У меня они так же лежат на github, в формате
String url="https://github.com/jehy/rutracker-free/releases/download/" + version+"/app-release.apk";
3. Пишем собственно алгоритм обновления:
3.1 в MainActivity.OnCreate добавляем вызов проверки:
new Updater().execute(this);
3.2 Пишем простенький класс для проверки:
class Updater extends AsyncTask<MainActivity, Void, Void> {
private Exception exception;
protected Void doInBackground(MainActivity... activity) {
checkUpdates(activity[0]);
return null;
}
Integer getLastAppVersion() {
try {
// Create a URL for the desired page
URL url = new URL("https://raw.githubusercontent.com/jehy/rutracker-free/master/app/build.gradle");
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
int f = str.indexOf("releaseVersionCode");
if (f != -1) {
str = str.substring(f + ("releaseVersionCode").length()).trim();
Log.d("Rutracker free", "Last release version: " + str);
return Integer.parseInt(str);
}
}
in.close();
Log.d("Rutracker free", "Failed to get last release version!");
} catch (Exception e) {
Log.d("Rutracker free", "Failed to get last release version:");
e.printStackTrace();
}
return null;
}
void checkUpdates(final MainActivity activity) {
final Integer lastAppVersion = getLastAppVersion();
if (lastAppVersion == null)
return;
if (lastAppVersion <= BuildConfig.VERSION_CODE) {
Log.d("Rutracker free", "App version is okay, skipping update");
return;
}
String li = SettingsManager.get(activity, "LastIgnoredUpdateVersion");
if (li != null) {
Integer liInt = Integer.parseInt(li);
if (liInt >= lastAppVersion)
return;
}
activity.Update(lastAppVersion);
}
}
3.3 Добавляем класс для хранения информации о том, что пользователь решил проигнорировать этот релиз:
public class SettingsManager {
static String get(Context mContext, String key) {
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(mContext);
String data = settings.getString(key, null);
if (data == null)
Log.d("SettingsManager", "No settings " + key + " is stored! ");
else
Log.d("SettingsManager", "Got settings " + key + " equal to " + data);
return data;
}
@SuppressLint("CommitPrefEdits")
static void put(Context mContext, String key, String value) {
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = settings.edit();
editor.putString(key, value);
Log.d("SettingsManager", "Saved setting " + key + " equal to " + value);
editor.commit();
}
}
3.4 Добавляем функцию, которая покажет пользователю диалог с предложением перехода:
public void Update(final Integer lastAppVersion) {
runOnUiThread(new Runnable() {
@Override
public void run() {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("Доступно обновление приложения rutracker free до версии " +
lastAppVersion + " - желаете обновиться? " +
"Если вы согласны - вы будете перенаправлены к скачиванию APK файла,"
+" который затем нужно будет открыть.")
.setCancelable(true)
.setPositiveButton("Да", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(Intent.ACTION_VIEW);
String apkUrl = "https://github.com/jehy/rutracker-free/releases/download/" +
lastAppVersion + "/app-release.apk";
//intent.setDataAndType(Uri.parse(apkUrl), "application/vnd.android.package-archive");
intent.setData(Uri.parse(apkUrl));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
dialog.dismiss();
}
})
.setNegativeButton("Нет", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
SettingsManager.put(MainActivity.this, "LastIgnoredUpdateVersion", lastAppVersion.toString());
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
}
Вуаля! Всё, теперь у нас обновляемое приложение. А если оно когда-нибудь появится в Google Play или в другом магазине приложений, который есть у пользователя, то оно сможет обновляться ещё и оттуда.
Что есть в сухом остатке — думаю, что без Google Play жить можно. И не только можно — нужно, минусы наличия монополиста на рынке очевидны. В том числе, если бы была хоть какая-то осмысленная конкуренция — возможно, общение с технической поддержкой было бы хоть какое-то адекватное, а не отписка пустыми шаблонами.
Так же хочу получить мнения от читателей.
Автор: jehy
Источник [13]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android/115364
Ссылки в тексте:
[1] приложение: https://habrahabr.ru/post/279267/
[2] один: https://habrahabr.ru/company/freeamp/blog/230293/
[3] два: https://habrahabr.ru/post/242885/
[4] три: https://habrahabr.ru/post/265163/
[5] четыре: https://habrahabr.ru/post/275691/
[6] без Google: https://www.daniel-ritter.de/blog/my-progress-in-using-android-without-google
[7] Пример : http://stackoverflow.com/questions/15213211/update-an-android-app-without-google-play
[8] Красивый пример: https://github.com/chu888chu888/android-autoupdater
[9] Пример: http://stackoverflow.com/questions/4308473/auto-update-for-private-android-apps
[10] Пример хитрого обновления: https://blog.vivekpanyam.com/evolve-seamlessly-deploy-android-apps-to-users/?hn
[11] сервис для авто обновления: http://www.auto-update-apk.com/
[12] Тут : http://whois.jehy.ru/
[13] Источник: https://habrahabr.ru/post/279553/
Нажмите здесь для печати.