Детский лаунчер 2.Х и единый премиум-аккаунт



    Что нового


    После публикации первой версии приложения к нам поступило большое количество отзывов. Собрав воедино пожелания пользователей и наши собственные идеи, мы начали работу над второй версией. Спустя два месяца упорного труда обновленные приложения Детский Лаунчер и Родительский Контроль доступны для скачивания в Google Play.

    Шестизначный пин-код

    Приятно удивили юные пользователи приложения, которые запросто подбирали пин-код. Пришлось увеличить его до 6 знаков.

    Возможность смены обоев

    Одним из самых частых обращений была просьба включить возможность менять обои. Мы пошли чуть дальше и решили предоставить эту возможность не только родителям, но и детям — теперь можно сделать так, чтобы ребенок сам устанавливал обои. При необходимости эта опция отключается.

    Расписание, будни и выходные

    Как быть, если ребенок играет по ночам или во время уроков? Как настроить временные ограничения так, чтобы в воскресенье можно было поиграть дольше, чем в понедельник? Очевидно, что требуется расширенная настройка временных ограничений с созданием собственного расписания.
    В новой версии можно устанавливать временной промежуток, когда можно запускать приложение или категорию приложений. Например: приложения категории “Игры” можно запускать с 15:00 до 20:00.

    Также появилась возможность настраивать временные ограничения для будней и выходных отдельно, причем пользователь сам назначает, какие дни недели являются выходными: суббота и воскресенье, или только воскресенье, или какие-то другие дни.

    Помимо отдельных приложений и категорий, можно настроить временные ограничения и для всего устройства. Например: устройство можно запускать по будням с 15:00 до 20:00, разрешенное время работы — 2 часа; по выходным — с 13:00 до 21:00, разрешенное время работы — 4 часа. В данном случае разрешенное время работы — это совокупное время работы любых приложений. По истечении разрешенного времени работы, либо вне разрешенного временного интервала, запрещается запуск любых приложений, кроме звонков и смс.

    Эта функция доступна только с премиум-аккаунтом.

    История перемещений ребенка

    Если раньше можно было посмотреть текущее местоположение ребенка, то теперь приложение показывает историю перемещений за последние 12 часов. Как и раньше, координаты обновляются каждые 15 минут, точка фиксируется на карте. Информация о перемещениях ребенка может быть полезна даже без использования приложения “Родительский контроль” — например, родители могут взять устройство ребенка и в разделе “Отслеживание” посмотреть, где и в какое время он находился.

    Данная функция также является премиумной. Отслеживание текущего местоположения ребенка по-прежнему остается бесплатным.



    Премиум-подписка


    Для монетизации приложения мы решили использовать премиум-аккаунт, который открывает недоступные простому пользователю функции. Покупается премиум-функционал через подписки в Google Play In-App Billing. Рассмотрим коротко, что представляет собой подписка, и какие у нее ограничения.

    Введение

    При оформлении подписки у пользователя периодически списывается со счета определенная сумма денег — цена подписки. Она ограничена минимальной ценой в 30 рублей и максимальной в 6000 рублей и аналогичными размерами в долларовом эквиваленте. Google позволяет устанавливать только 2 типа периодичности: ежемесячная подписка и ежегодная. Есть возможность добавлять триальный период от 7 до 999 дней. Что касается отмены подписки, пользователь может отменить ее в любой момент, но деньги за текущий период ему не возвращаются. После отмены подписки пользователь может пользоваться всеми премиум-функциями до конца оплаченного периода. При удалении приложения с подпиской, подписка не отменяется, но Google Play выдает нотификацию о том, что вы удалили приложение, но деньги с вас все равно будут снимать пока вы не отмените подписку.

    Единый премиум для разных приложений

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

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

    Реализация

    Для покупки подписки на клиенте мы использовали классы из TrivialDrive. TrivialDrive — это классическое мобильное приложение с in-app purchase sample, который идет вместе с Google Play Billing Library. Описывать детально как и что делать для покупки in-app purchases мы не будем, но та часть, которой коснемся, будет в терминах классов утилит из TrivialDrive.

    Проверка при авторизации

    Первый раз мы проверяем, активен ли премиум при авторизации, и если он активен и его время не вышло, то мы включаем премиум-функционал на клиенте. Это самый простой вариант.

    Покупка премиум-подписки

    Другой вариант — у пользователя при авторизации премиума нет.



    Шаг 1.
    При нажатии на кнопку “Купить премиум” идет запрос на сервер, чтобы узнать, а не куплен ли премиум на другом устройстве этого же пользователя. Если премиум был куплен ранее и не закончился, включаем премиум-функционал на клиенте.

    Шаг 2.
    Если же премиум куплен не был, то запускаем процесс покупки подписки через IabHelper.launchPurchaseFlow. Помимо прочих параметров в функцию передается payload. Payload — это строка, определяемая разработчиком и однозначно связывающая пользователя с этой покупкой. Мы в этот параметр передаем имя аккаунта пользователя.

    Далее управление на себя берет google services и по завершению покупки, удачному или не очень, вызывает наш callback. Сейчас рассмотрим удачное стечение обстоятельств, когда у пользователя не был куплен премиум до этого и не возникло никаких ошибок. В этом случае в callback возвращается объект Purchase, в котором содержатся необходимые нам поля: payload, purchaseTime, productId, orderId и purchaseToken. Все эти данные, а так же идентификатор устройства мы оправляем на серверную часть (Шаг 3) для верификации покупки.

    Шаг 3.
    Сервер, в лице Parse, использует Google Play Developer API для получения данных о только что купленной подписке. Для использования Google Play Developer API нужно создать приложение в Google Cloud Console, включить Google Play Developer API и получить access_token (он, к сожалению, не вечен, но об этом позже). Узнать информацию о подписке можно, отправив GET запрос на https адрес вида: «www.googleapis.com/androidpublisher/v1/applications{packageName}/subscriptions/{productId}/purchases/{purchaseToken}?accessToken={accessToken}»
    В ответ приходит JSON с информацией о датах начала и окончания подписки, а так же о том, продлится ли автоматически подписка, когда выйдет время (видимо, отменил пользователь подписку или нет — нам это поле не понадобилось). Документация по запросам небольшая, потому что писать там особо и нечего — developers.google.com/android-publisher/v1/purchases

    Если API вернул корректные данные и время окончания подписки больше текущего времени, то пользователь оплатил премиум, и мы можем включить ему премиум-функционал. Нам нужно запомнить лишь время окончания подписки, чтобы знать, когда проверять подписку в следующий раз.

    Шаг 4.
    Информация о подписке возвращается на устройство. Мы рассматриваем ситуацию, когда никаких проблем не возникает, и пользователь действительно купил подписку, и срок ее действия закончится не мог, т.е. на клиент приходят данные об активированном премиум-аккаунте и о дате окончания.

    Пользоваться Детским Лаунчером можно в offline-режиме, значит нужно иметь возможность верифицировать премиум-аккаунт без интернета. Для этого мы сохраняем данные о премиум-аккаунте (дату окончания, идентификатор подписки и пр.) локально в SharedPreference в зашифрованном виде. Проверяем состояние премиум-аккаунта каждый раз при входе в родительский режим. Если интернет есть, то после успешной локальной проверки мы обращаемся на Parse за подтверждением; если Parse подтверждает премиум-аккаунт, то мы перезаписываем локальные данные (возможно, обновилось время окончания подписки). Если нет соединения с сетью, то мы ничего не делаем и считаем премиум активным, т.к. локальная проверка подтверждает факт покупки премиум-аккаунта. Факт продления подписки без соединения с сетью проверить не удастся, поэтому, даже если локально хранимое время подписки закончилось, премиум-аккаунт остается активированным.

    Возможные ситуации



    Обновление токена.
    На третьем шаге используется приложение в Google Cloud Console со включенным Google Play Developer API. Про создание приложения и получение токенов (access_token и refresh_token) можно почитать здесь — developers.google.com/android-publisher/authorization. Скажу лишь только, что для всех вызовов API используется access_token, а он не вечен и довольно быстро умирает. Как только время действия access_token закончится, API вернет 401 ошибку, и, используя refresh_token, мы сможем получить новый access_token. Т.е. шаг 3 может немного растянуться, если время действия access_token закончится.

    Продление премиум-подписки.
    На этапе авторизации или на этапе проверки премиума может возникнуть ситуация, что пользователь активировал премиум ранее, но сохраненное на сервере время окончания подписки прошло; в таком случае сервер снова обращается к Google Play Developer API за получением новых данных о подписке — узнать, продлилась подписка или нет. Если подписка продлилась, сервер перезаписывает у себя данные об окончании времени подписки и отправляет их на устройство. Если же подписку отменили, то также сервер сообщает об этом устройству, и устройство затирает информацию о подписке в SharedPreference.

    Подписка уже куплена.
    На этапе покупки подписки может возникнуть такая ситуация, что у пользователя уже куплена эта подписка. Сообщит нам об этом Google Services через callback, переданный в функцию IabHelper.launchPurchaseFlow. В этот callback вернется ошибка с кодом BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED, и в этом случае нужно будет снова обратиться к Google Services за списком всех купленных внутренних покупок/подписок. Делается это через функцию IabHelper.queryInventoryAsync, в которую передается очередной callback. Из полученного списка всех совершенных покупок (Inventory) мы достаем нужную нам подписку по идентификатору и смотрим ее payload; если payload не совпадает с аккаунтом текущего пользователя (а других ситуаций быть не должно, если наш механизм работает корректно), то мы сообщаем пользователю, что подписка у него уже куплена, но для другого аккаунта. Если всё же payload совпадает с текущим аккаунтом пользователя (не, ну а вдруг?), то в google service мы выполняем все те же действия, что и при обычной покупке, но уже с Purchase, который до этого вернулся в callback.

    Что дальше


    • Интервалы отдыха.
    • Создание собственных категорий приложений.
    • Фильтрация входящих, исходящих звонков и SMS.

    Дальше — больше. Ждём ваших комментариев и предложений. Спасибо.

    P.S. Статья написана совместно с хабраюзером belozerow
    Appgranula
    Компания

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 24

      +1
      Отличное приложение. Жаль, что мне оно понадобится лет через 5 только. :)
      Как понимаю вы только на Android сейчас. Планируется ли выпуск на других платформах, в частности Windows?
        0
        Спасибо.
        Возможно будет Родительский Контроль на других платформах, но Детский Лаунчер будет только под Android.
          0
          Если не секрет, с чем связано такое ограничение?

          Как возможный дополнительный функционал:
          — Отслеживание СМС-переписки.
          — Отслеживание звонков
          Суть в том, что копия СМС-сообщения, номер абонента отправляется родителю. Подключать функцию и следить за ребенком родитель решает сам.
            0
            Мы сразу ориентировались только на мобильные устройства, а из мобильных ОС такой функционал возможно реализовать только под Android, да и тут механизм блокировки приложений весьма костыльный.
            Мы не рассматривали вариант разработки под Windows, но у вас ещё целых 5 лет, может мы успеем к тому времени:)
        0
        Выглядит как очень качественное приложение!

        А вы его уже начали раскручивать на мировом рынке?
          0
          Спасибо, мы старались, чтобы оно и работало качественно)
          Пока особо не раскручивали, основную массу клиентов дала статьи на хабре и 4pda. Но вообще планируем, конечно.
            0
            А на какие языки уже переведено кроме рус и англ?

        +2
        Любопытный аспект: обнаружилась новая игра.

        Необходимо сёрфиться по разделу игр гуглобазара и инсталлировать все с яркими иконками и/или иллюстрациями. В этом суть и интерес игры.

        Можно ли как-то сделать так, чтобы оболочка позволяла сёрфиться по бесплатным приложениям, скажем, educational и games, но инсталлировать не более (например) 20 в сумме? То есть для инсталляции новой надо выбрать какую нть старую и деинсталлировать.

        В таком разе как-то разделить софт, инсталлированный или зафиксированный 0дмином, — стирать нельзя — и софт, инсталлированный юзателем — стирать можно. Не?
          0
          В Google Play есть настройки фильтрации приложений, вы можете установить ограничения на возрастную группу и добавить Google Play в список разрешенных приложений в Детском Лаунчере.
          А идея ограничения количества установок приложений ребенком интересная, теоретически реализуемая, но надо обдумать ее более детально.
            0
            Спасибо!
            А как отфильтровывать платные?
              0
              Вот платные, как я понял, отключить не получится. Но есть пароль аккаунта, который Google Play спрашивает при покупке(если не поставить галочку «Больше не спрашивать»). Ребенок уже не сможет, не зная пароля, купить приложения или In-App покупки.
          0
          Выглядит очень достойно.

          А когда выложили на гугл плей? А то что-то загрузок больно мало.
            +2
            Спасибо.
            Выложили мы ещё в июне, но пока активно не рекламировали приложение.
            +3
            Я извиняюсь. Прежде чем испытывать ваше приложение (на текущий момент использую Kid's shell, — а есть ли у вас возможность удаленно администрировать оболочку для добавления программ (игр), иметь фильтр на ролики в ютубе (это то, что ребенок находит в легкую) — не блокировать, а фильтровать, пусть хотя бы и пофакту, запрещая уже просмотренное, смотря какой-нить лог-отчет)?
            Как опция — контролировать уровень звука (Язьь на всю громкость в 100500 раз может нервировать).
            Чтобы не было мысли, что ребенку дали девайс и забыли скажу что нет, есть здоровый баланс. Но когда спиногрыза 3, а ты остался один на один с ними — очень не плохо некоторых занять чем-нить, и игры на сотовом лучший вариант (сотовый в защитный ган… дончик и чехол), плюс усиленная батарея с беспроводной зарядкой. На счету уже 2 убитых планшета за 2 года.
              0
              Удаленное администрирование позволяет разрешать уже установленные приложения, устанавливать временные ограничения/блокировки.
              Удалённо устанавливать приложения на устройство без root нельзя — нужно будет пересылать на детское устройство .apk и спрашивать разрешение на установку у ребенка. Остается только установка с сайта Google Play, потом перенос приложения в разрешенную категорию.
              С Youtube мы ещё не разбирались и на данный момент в приложении никакой фильтрации контента не предусмотрено. А что-то подобное есть в Kid's shell?
              Уровень звука мы тоже пока никак не ограничиваем, но обязательно учтем это, спасибо за идею.
                +1
                Вы ответили на мой вопрос. Так что поэкспериментирую с вашей оболочкой. Удаленно я и подразумевал через Google Play.
                Не знаю как с фильтрацией в Кидс шелле, там тоже есть премиум аккаунт, хотел купить, но посмотрел те функции что он добавляет — они не были мне так уж нужны. Но по факту вещь нужная, так как контента много, не всякий хочется чтобы был доступен ребенку, а что-то вообще хочется заблокировать (даже может кажущееся безобидным). То есть белые и черные списки уже были бы хороши (возможно по названию в ролике.)
                Уровень звука тоже немаловажно. Ребенок любит включить погромче (когда догадывается как), — не всегда это приятно для окружающих.
                  +1
                  И кстати, не поймите неправильно, но логотип программы не интуитивно понятный.
                  Мой ребенок сам включает кидс шелл. выбирая оранжевого медвежонка. так как понимает что там Игры! И папа все равно его включит. Хотя она еще даже не говорит. и объяснить ей, что вот нажимай сюда всегда нельзя. Подумайте за это.
                  Например Теже мама и ребенок. но в виде погремушко очереченных образах. или цвета по ярче.
                    –1
                    А мы только что поменяли иконку и нам она нравится)
                    Вообще мы предполагали 2 варианта использования приложения:
                    — Постоянное использование лаунчера на устройстве ребенка.
                    — Родитель включает Детский Лаунчер на своем устройстве и отдает его ребенку поиграть.
                    В каждом из этих случаев родитель сам запускает приложение, т.е. ребенок никогда не имеет доступа к основному функционалу устройства. Мы как-то не подумали, что ребенок сам будет запускать детский лаунчер.
                      +2
                      Иконка не плоха, и если вы так считаете, то я не настаиваю. Практика покажет на сколько она удачна.
                      Надо сказать дети не плохо запоминают нужные им иконки, и как правило не ошибаются, запуская лаунчер или игру.
                      А по поводу того что родитель заранее включает иконку — это верно, но и ребенок осознает что ее все равно включат, иначе игрушку заберут.
                      0
                      +1 насчет медвежонка.
                      У меня сын тоже давным-давно знает правило, что можно запускать только иконку с медвежонком. Даже если сам берет телефон, первым делом запускает Kid's Shell.
                  0
                  Поддерживаю. Сам также пользуюсь Kid's Shell. Нравится его простота и работа. Не нужно где-то регистрироваться и что-то настраивать. Запустил и все.
                    0
                    К слову — запустил Этот детский лаунчер вчера. минут 5-10 потратил на настройки, регистрации. Потом программа повесила телефон и перезагрузила… Ладно. Дам второй шанс — дал ребенку. Минут через 5 ребенок сует обратно типа, на посмотри, не работает (не нашла где игры). Показал. Еще через 5 оболочка подвисла, с чем-то на фоне… Снес оболочку, включил кидс шелл… (телефон S4 Андроид 4.30)
                  0
                  В нашем случае недостаточно стандартного варианта подписки, который предлагается Google, потому что у нас есть два приложения, и при покупке премиума в одном из них он должен появиться и во втором. К тому же дети имеют свойство быть не в единственном экземпляре...
                  да, именно так дело и обстоит; к тому же у детей должны быть свои учётные записи в Google Play Market и платёжные средства, если уж на но пошло. В любом случае, оставлять ребёнку свою кредитку, как того требует Google, я не желаю. Возможность купить одну прем-подписку и распространить её на все ведомые устройства — это просто супер. Купил на год.

                  Есть пара хотелок: автоматическая инвентаризация приложений и ограничение трансляции (google cast).

                  Автоматическая инвентаризация приложений: по метаданным приложения через Google Play Market можно автоматически распознавать игры (и не только). И кто-то из ваших конкурентов это точно делает. Просто экономит время: если на устройстве установлены игры, автоматически их закинуть в нужную категорию.

                  По поводу трансляции: набирают популярность устройства типа Chromecast (родственник Apple TV, втыкается в HDMI-разъём телевизора, любое Android-устройство затем через WiFi выдаёт картинку со звуком прямо в телевизор, причём в нормальном разрешении и практически не расходуя энергию батареи).

                  habrahabr.ru/post/209022/
                  habrahabr.ru/post/210742/
                  Т.е. вместо того, чтобы тянуть в детскую провода и ставить тяжёлую ТВ-приставку, я просто втыкаю в детский телевизор беспроводной HDMI-донгл Chromecast, а ребёнок со своего устройства уже сам выбирает, что ему смотреть (ну или я помогаю выбрать). Смартфон или планшет остаётся в руках, как пульт. Уже есть много приложений, транслирующих бесплатные и платные каналы и т.п. Хотелось бы эту функцию (cast, трансляцию) тоже ограничить по времени, если Google это предусмотрел в своём API. Проблема учёта здесь в том, что трансляция продолжается даже при неактивном приложении. Повторяю, для начала хватило бы простых суточных квот, т.е. «трансляция разрешена не более двух часов в день». Далее можно расширить функцию: «трансляция разрешена только с таких-то приложений». Фильтрация содержимого пусть определяется самим приложением, по-другому вряд ли вообще возможно.

                  Что касается самой фильтрации содержимого, это в любом случае компромисс. Рекомендую посмотреть в сторону YouTube for schools и/или внешних (облачных) URL-фильтров. Пишите в личку, я попробую помочь консультацией.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое