Наверно, многие задумывались над тем, как можно реализовать свои знания в готовом продукте. Кто-то больше, кто-то меньше потратил на это времени. Хочу поделиться с сообществом своим опытом и видением, как это надо делать правильно, но не всегда получается.
Поиск идеи
На этом этапе надо определиться с тем, что же мы будем создавать.
Для этого генерим идеи, записываем их (например, в trello), делаем обзор конкурентов — гуглением и поиском по магазину приложений.
Далее стараемся трезво оценить свои возможности как по времени, возможным финансовым вложениям, так и по необходимым знаниям. Т.е. делать убийцу Eventbrite или Uber будет не лучшей идеей.
Исследования
Они подразделяются на качественные и количественные такие, как исследования рынка, A/B тесты, аналитика, опросы. Для проверки своей идеи на уровне домашнего проекта самым доступными являются опросы.
Я выбрал идею по напоминалке о перевороте матраса, т.к. сам сплю на таковом, и ребенок вырос из детской кровати и тоже переехал в свою кровать.
В опросе главное правильная постановка вопроса, он не должен содержать подсказку или быть предвзятым. Желательно точным и кратким.
Не верно: Как часто вы переворачиваете матрас?
Верно: Вы переворачиваете матрас?
Никогда не спрашивайте респондента, будет ли он чем-либо пользоваться: "Вы будете пользоваться приложением напоминающем о перевороте матраса?"
В большинстве случаев вы получите ложноположительный ответ.
Опросил 10 человек на работе, 4 человека сказали что переворачивают матрас и точно не помнят когда это надо сделать в следующий раз и в каком направлении перевернуть. Не самый лучший результат, но 40% уже что-то. Решаю делать.
Качественные исследования состоят из
UX тестирования
Самый простой и доступный способ, это сделать наброски всех экранов на бумаге и запрототипировать их в marvel app или, если есть опыт, то в figma — эти инструменты позволяют создать действующий прототип приложения без программирования, путем выделения активных областей экрана (кнопок) и описания того экрана, что должен открыться.
Customer development
Данный метод нацелен на выявление проблемы или нужды клиента до того, как начнется разработка. Состоит в составлении правильных опросников и проведении интервью.
Данный метод помогает сформулировать востребованность приложения.
Для прототипирования интерфейса я ограничился набросками экранов на стикерах и оживлением их в марвеле. После чего попросил своего коллегу на работе побегать по экранам и поделиться впечатлениями.
Описание идеи
На основании вышеперечисленных исследований мы пытаемся ответить на вопросы:
Какую пользу приносит приложение?
Помогает людям, заботящимся о своем здоровье, дольше пользоваться исправным матрасом.
Какие проблемы помогает решить?
Напоминать о перевороте матраса.
Напоминать ненавязчиво.
Понять, зачем надо переворачивать.
Понять, как именно переворачивать, ничего не разбить и не надорваться при этом.
Понять, как выбрать матрас.
Узнать, когда матрас надо поменять (5-10 лет).
Как почистить матрас в экстренной ситуации (пролили, испачкали и т.д.).
В каких ситуациях используется?
В магазине продавец показывает, как переворачивать.
Дома хочешь перевернуть.
На работе надо регулярно переворачивать.
Случилась экстренная ситуация.
Определиться с минимум функционала, который сделает запуск возможным
MVP
Список матрасов, напоминание о перевороте, авторизация для переноса истории (матрас живет дольше телефона), краткая инструкция.
Реализация
Тут хочу рассказать вкратце о примененных технологиях.
В качестве базы данных был выбран Realm по причине моего с ним давнего знакомства, а также таких удобных фич из коробки, как наличие асинхронных методов записи/чтения и хорошего быстродействия.
public RealmResults<RealmModelMattress> getAllMattressAsync(){
realm = getRealm();
return realm.where(RealmModelMattress.class)
.equalTo("deleted", false)
.sort("id", Sort.ASCENDING)
.findAllAsync();
}
private Realm getRealm() {
if (mConfig==null) {
mConfig = new RealmConfiguration.Builder()
.build();
}
realm = mRealm.get();
if (realm == null) {
try {
realm = Realm.getInstance(mConfig);
mRealm.set(realm);
} catch (Exception e) {
closeConnection();
Realm.deleteRealm(mConfig);
realm = Realm.getInstance(mConfig);
mRealm.set(realm);
}
}
return realm;
}
Также легкость отображения данных в recyclerView при их изменении: достаточно подключить RealmChangeListener:
private RealmChangeListener<RealmResults<RealmModelMattress>> realmChangeListener = data->{
refreshData(data);
};
Для удаления элементов recyclerView использовал ItemTouchHelper, вот тут достаточно подробно про его использование написано.
Достаточно создать класс, расширяющий ItemTouchHelper.SimpleCallback и описать действия, которые должны происходить при свайпе(onSwiped) или перемещении(onMove).
И подключить его к ресайклеру:
rv = view.findViewById(R.id.recyclerViewMattress);
rv.setLayoutManager(new LinearLayoutManager(context));
adapter = new MattressListAdapter(data, clickListener, getContext());
rv.setAdapter(adapter);
ItemTouchHelper itemTouchHelper = new
ItemTouchHelper(new SwipeToDeleteCallback(adapter));
itemTouchHelper.attachToRecyclerView(rv);
Локальные уведомления о том, что надо перевернуть матрас, реализованы посредством notificationManager, так как в настоящий момент это один из самых правильных и одобренных гуглом методов для создания оповещений.
private void sendNotification(String title, String text, int id) {
String DBEventIDTag= "Mattress" + id;
int DBEventID = id;
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(DBEventIDTag, DBEventID);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
NotificationManager notificationManager = (NotificationManager)getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("default", "Default", NotificationManager.IMPORTANCE_DEFAULT);
Objects.requireNonNull(notificationManager).createNotificationChannel(channel);
}
NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext(), "default")
.setContentTitle(title)
.setContentText(text)
.setContentIntent(pendingIntent)
.setSmallIcon(R.mipmap.ic_launcher)
.setAutoCancel(true);
Objects.requireNonNull(notificationManager).notify(id, notification.build());
}
Авторизация в приложении сделана 2 способами:
Можно указать свою почту и ввести пароль — на сервере будет создана соответствующая учетная запись и данные из приложения о матрасах и времени переворота будут к ней привязаны. Что обеспечивает возможность получить их залогинившись в приложении, после смены телефона.
Второй способ авторизации: facebook, с использованием его API.
Для реализации этого метода, первое что нужно сделать, это зарегистрировать свое приложение в фейсбуке, на сервере реализовать проверку access token https://graph.facebook.com/me?fields=id&access_token=accToken, где id — идентификатор пользователя фейсбук, а accToken временный токен доступа подтверждающий что это действительно тот самый человек отправил запрос на авторизацию.
Публикация результата
Создаем аккаунт разработчика.
Оплачиваем регистрационный сбор 25$ единоразово.
Публикуем приложение Переверни матрас.
Определяем контент рейтинг, стоимость и дистрибьюцию (те страны, где приложение будет доступно). Так так приложение локализовано для двух языков, то делаем 2 описания на русском и английском, а также скриншоты.
Надеюсь кому-то будет полезно не свернуть с пути и добиться цели.
lingvo
Какая-то скомканная спецификация задачи получилась. И какой ROI данной разработки в итоге?
1C_LAN Автор
Окупаемость инвестиций пока рано оценивать, скорее всего даже в долгосрочной перспективе она будет около нулевой, хотя и есть идеи продвижения приложения, через производителей матрасов.
Но в любом случае, личный опыт, полученный с применением такого структурированного подхода для меня очень большой.
lingvo
То есть я что хотел сказать — вы-то указали основные этапы подхода к разработке начиная от идеи до концепции, разработки и прототипа, но забыли указать, что при переходе с этапа на этап следует обязательно проводить Gate Review — хотя бы для себя мысленно, одним из чек-пунктов которого должна быть оценка ROI, готовность проекта к переходу на следующий этап, наличие рисков и неопределенностей и т.д.
То есть в принципе я бы еще на этапе исследования вам бы запретил переходить на описание идеи из-за недостаточности данных, а после идеи зарубил бы этот проект на корню, так как ROI показало бы 0 — т.е. тратить ресурсы на дальнейшую разработку просто бессмысленно и дешевле отказаться от ее продолжения сейчас, чем потом.
Т.е. абстрагировавшись от конкретно этого проекта — такие репперные точки, где принимаются иногда тяжелые и неприятные для разработчика решения, необходимы — это тоже часть правильно структурированного подхода к разработке.
1C_LAN Автор
Полностью согласен, при разработке в компании, цель которой получить прибыль, а не обанкротиться — mast have.
В home проекте, для понимания, какие этапы проект должен пройти — имеет место быть.