Есть ли жизнь без Google Play? Альтернативы и обновление приложений

от автора


На днях я сделал приложение для обхода блокировки rutracker, однако уже дважды получил от Google отбой по разным надуманным причинам. Это очень огорчило, и возник вопрос — что делать? Поиск по хабру показал, что такие проблемы возникли очень у многих (пруфы: один, два, три, четыре… Тысячи их). Готовой статьи на эту тему я не нашёл, так что решил, что верным решением будет разобраться и написать свою. Итак, принципиальных варианта есть всего два.

1. Используем альтернативный магазин приложений

Тут довольно богато. Amazon App Shop, Samsung Apps, Yandex.Store, blackmart, humble bundle, F-Droid… В общем-то неплохо. Я из них пока попробовал только Yandex.Store. Получилось зарегистрироваться и опубликовать приложение минут за 5 — оно там уже доступно. Правда, недоумение вызывает полная невозможность как-либо дать ссылку на установку приложения в Yandex.Store. Может, я слепой, но кнопочки «Share» там просто нет. Ну и никакого веб интерфейса — только мобильный.

Плюсы:

  • Наличие некоторых возможностей, к которым мы привыкли в Google Play — включая автоматическое обновление, статистику и биллинг (есть не во всех указанных, конечно).
  • Хотя бы какой-то авторитет издателя — хуже, чем если бы приложение было на Google Play, но лучше, чем ничего.
  • Индивидуальные фичи — например, F-Droid публикует только приложения с открытым кодом.

Минусы:

  • Потеря в имидже. Все пользователи привыки, что приложение должно качаться с google play. Если его там нет — значит, что-то не так. Хотя вот, например, Yandex.Store на Google Play нету. И качать его приходится очень стрёмным методом…
  • Пользователю придётся устанавливать некий «левый» магазин приложений. У меня вот ничего кроме google play не было с момента появления Android, и ставить я не собирался. Устанавливать себе ещё одного «большого брата» с полными возможностями по манипуляции твоим устройством — довольно стрёмно.
  • Кажется, ни у одного из них нет информации о сбоях. Плюс другие возможности Google Play включая биллинг.

2. Самостоятельное решение

Как ни страшно это звучит, на самом деле здесь мы приходим к аналогу обычного десктопного софта. Сама программа знает, когда и как ей обновляться, рассказывает об этом, в ней интегрированы платёжные возможности и монетизация. Рекламой и продвижением занимаетесь вы сами. Ужас, ужас! Но на самом деле, мы просто избаловались. Нужно просто находить правильные пути. Продвигать приложение можно, например, на тематических блогах и форумах — в том числе на 4pda с очень неплохим объёмом аудитории. Или прямо на хабре.

Кстати, даже если ваше приложение успешно опубликовано на Google Play — имеет смысл подстраховаться и как минимум сделать в нём свой алгоритм обновления, который активизируется, если, например, приложение давно не обновлялось. Или по проверке бана на вашем сервере или прямо на Google Play. Иначе, если вас на какое-то время забанят, пользователи не смогут обновить приложение. А если есть запасной вариант — вреда будет заметно меньше.

Плюсы

Ваше приложение практически невозможно заблокировать — только вместе с ресурсом, на котором вы держите обновление и информацию.

Минусы

  • Всё, что только можно — приходится делать вручную.
  • Потеря в имидже, о которой уже было сказано ранее. Как ни странно, возможно что меньшая, чем в случае использования некоего магазина приложений.

Итак, что же вам придётся делать:

Размещение приложения для скачивания

На самом деле, это всего лишь означает, что вам нужно выложить APK куда-то в доверенное место. Их не так уж мало — можно использовать всё тот же 4pda, можно класть релизы прямо в github, можно на свой сайт… Вариантов уйма.

Отладка ошибок

Да, привыкли мы к хорошему — Google сам поймает ошибку, всё расскажет о её месте, устройстве пользователя и так далее. Но… Никак проблем это реализовать самостоятельно. Как простейший вариант — ловим все эксепшны и отсылаем куда-то на сервер по HTTP или даже на почту.

Сбор статистики

К сожалению, никогда не интересовался статистикой приложений, но вам с очевидностью придётся реализовать как минимум статистику по скачиваниям.

Сложные библиотеки

Собственно придётся забыть о всех сложных и хороших вещах, которые даёт Google Play. Впрочем, то же самое касается, пускай и в чуть меньшей степени, любых магазинов приложений.

Обновление

По обновлению есть принципиально три варианта:

  1. Автоматическое обновление при наличии прав SuperUser. Это довольно стрёмно, но понятно — не будем рассматривать подробно.
  2. Обновление вручную после автоматического скачивания. Неплохо, однако требует разрешения на запись данных. Если его у вашего приложения не запланировано, то ставить лишние разрешения — зло. Требует от пользователя разрешения на установку программ из сторонних источников.
  3. Обновление вручную при переходе по ссылке. Простой вариант, однако требует от пользователя скачать и открыть APK файл. Ну и так же как второй вариант — требует от пользователя разрешения на установку программ из сторонних источников.

Чтобы показать, как всё просто — покажу примитивную реализацию третьего варианта,

которую я сделал для своего приложения за час времени.

1. Добавляем куда-то свою актуальную версию приложения. Я засунул прямо в исходники на Github в build.gradle:

//        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 жить можно. И не только можно — нужно, минусы наличия монополиста на рынке очевидны. В том числе, если бы была хоть какая-то осмысленная конкуренция — возможно, общение с технической поддержкой было бы хоть какое-то адекватное, а не отписка пустыми шаблонами.

Так же хочу получить мнения от читателей.

  1. А как вы решаете проблемы бана приложения?
  2. Пользуетесь ли альтернативными магазинами приложений?
  3. Ставите ли приложения с каких-то других сайтов через apk?
  4. Как думаете, как мы будем ставить приложения на свои устройства лет через пять?

ссылка на оригинал статьи https://habrahabr.ru/post/279553/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *