Привет, друзья! Некоторое время назад я писал статью про App Intro (Onboarding Experience), с помощью которого мы можем дать юзеру нашего приложения ознакомительный материал при первом запуске.
Теперь же я хочу рассказать и показать, как можно реализовать App Intro c помощью видео из YouTube.
Допустим, что вы делаете супер-мега крутой проект и у вас есть его промо-ролик. Наша цель показать это видео внутри вашего приложения, как ознакомительное и дать понять пользователю, что он сделал правильный выбор.
Intro (вводное информационное активити, запускающее при первом старте приложения на девайсе) на базе видео с YouTube может быть весьма полезно, чтобы показать юзеру все фичи в реальном видео. Или это может быть рекламный ролик — не столько фичи, сколько реклама того какой апп интересный, полезный, прикольный и т.п.
Итак приступим к реалзации:
1) Для начала нам нужно создать проект и получить API Key в Google Developer Console:
a) создаем проект и активируем YouTube Data API:
b) Создаем API Key для Android приложения: даем название (произвольное), пакет своего проекта и генерируем SHA-1
После этих шагов вы получите API Key, такого плана: AIzaSyCKQSxрJFAHFHj9r2wfwfqkagkhFFa
Сохраните его, мы будем его использовать.
2) Создаем новый проект в Android Studio:
a) добавляем в strings.xml:
b) в colors.xml:
c) в dimens.xml:
d) создадим директорию color и в ней файл intro_text_link.xml (будем применять этот стиль в layouts):
На данном этапе нам нужно подключить библиотеку для просмотра видео-роликов.
Скачиваем архив библиотеки YouTube по этой ссылке.
Далее, нужно скопировать и вставить файл YouTubeAndroidPlayerApi.jar в app/libs (в студии переключиться на Project), и нажать кнопку Sync на панеле инструментов (или в меню: Tools > Android > Sync Project with Gradle Files)
3) Теперь создадим Java класс Config, в котором будем хранить Google API Key и id для видео, которое мы будем использовать в нашем Intro (в URL следует после "?v=", например, для видео www.youtube.com/watch?v=aScEqSidNf8 id будет aScEqSidNf8):
4) Создадим теперь xml файлы внутри папке drawable, которые будут отвечать за background нашего Intro и за скругление углов:
a) intro_gradient.xml:
b) intro_rounded_corners.xml:
5) Теперь создадим layout файл activity_intro.xml для нашего Intro (вертикальная ориентация):
И для горизонтальной ориентации (создаем директорию layout-land, в которую помещаем идентичный файл activity_intro.xml):
6) Создаем класс YouTubeFailureRecoveryActivity. Выносим его в отдельный класс, поскольку в случае наличия YouTube-функционала в других частях приложение, используется этот же класс:
7) Создаем IntroActivity.java:
Последним шагом в реализации данного функционала остается добавление permissions в Manifest и декларация IntroActivity:
Так выглядит результат проделанной работы в вертикальной и горизонтальной ориентации:
Я постарался в этой статье рассказать полезную вещь, которая надеюсь пригодится вам для создания интересных проектов и будет полезна. Если у вас остались вопросы, то попробую ответить на них.
Теперь же я хочу рассказать и показать, как можно реализовать App Intro c помощью видео из YouTube.
Допустим, что вы делаете супер-мега крутой проект и у вас есть его промо-ролик. Наша цель показать это видео внутри вашего приложения, как ознакомительное и дать понять пользователю, что он сделал правильный выбор.
Intro (вводное информационное активити, запускающее при первом старте приложения на девайсе) на базе видео с YouTube может быть весьма полезно, чтобы показать юзеру все фичи в реальном видео. Или это может быть рекламный ролик — не столько фичи, сколько реклама того какой апп интересный, полезный, прикольный и т.п.
Итак приступим к реалзации:
1) Для начала нам нужно создать проект и получить API Key в Google Developer Console:
a) создаем проект и активируем YouTube Data API:
b) Создаем API Key для Android приложения: даем название (произвольное), пакет своего проекта и генерируем SHA-1
После этих шагов вы получите API Key, такого плана: AIzaSyCKQSxрJFAHFHj9r2wfwfqkagkhFFa
Сохраните его, мы будем его использовать.
2) Создаем новый проект в Android Studio:
a) добавляем в strings.xml:
<string name="intro_header">Introduction</string>
<string name="skip_intro">Skip Intro</string>
<string name="error_player">Error initializing Youtube player: %1$s</string>
b) в colors.xml:
<!-- Intro Youtube video -->
<color name="intro_skip_normal">#9e9e9e</color>
<color name="intro_skip_active">#616161</color>
c) в dimens.xml:
<!-- Additional margins including ones for Intro Youtube video -->
<dimen name="middle_margin">8dp</dimen>
<dimen name="bottom_text_margin">40dp</dimen>
d) создадим директорию color и в ней файл intro_text_link.xml (будем применять этот стиль в layouts):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="@color/intro_skip_active" />
<item android:state_focused="true"
android:color="@color/intro_skip_active" />
<item android:color="@color/intro_skip_normal" /> <!-- default -->
</selector>
На данном этапе нам нужно подключить библиотеку для просмотра видео-роликов.
Скачиваем архив библиотеки YouTube по этой ссылке.
Далее, нужно скопировать и вставить файл YouTubeAndroidPlayerApi.jar в app/libs (в студии переключиться на Project), и нажать кнопку Sync на панеле инструментов (или в меню: Tools > Android > Sync Project with Gradle Files)
3) Теперь создадим Java класс Config, в котором будем хранить Google API Key и id для видео, которое мы будем использовать в нашем Intro (в URL следует после "?v=", например, для видео www.youtube.com/watch?v=aScEqSidNf8 id будет aScEqSidNf8):
public class Config {
//Google API Key
static final String API_KEY = "AIzaSyCKQSxрJFAHFHj9r2wfwfqkagkhFFa";
//YouTube video id for intro
static final String YOUTUBE_INTRO_ID = "aScEqSidNf8";
}
4) Создадим теперь xml файлы внутри папке drawable, которые будут отвечать за background нашего Intro и за скругление углов:
a) intro_gradient.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="@color/colorPrimaryDark"
android:centerColor="@color/colorPrimary"
android:endColor="@color/colorPrimary"
android:angle="270" />
</shape>
b) intro_rounded_corners.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<solid android:color="@android:color/white" />
<corners android:radius="8dp" />
</shape>
</item>
</layer-list>
5) Теперь создадим layout файл activity_intro.xml для нашего Intro (вертикальная ориентация):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/intro_gradient">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:orientation="vertical"
android:background="@drawable/intro_rounded_corner">
<TextView
android:text="@string/intro_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textAppearance="@style/TextAppearance.AppCompat.Headline" />
<com.google.android.youtube.player.YouTubePlayerView
android:id="@+id/youtube_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/middle_margin" />
<ImageView
android:src="@mipmap/ic_launcher"
android:contentDescription="@string/app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/middle_margin" />
<TextView
android:text="@string/app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/bottom_text_margin"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />
<TextView
android:id="@+id/skip_intro"
android:text="@string/skip_intro"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:textColor="@color/intro_text_link" />
</LinearLayout>
</LinearLayout>
И для горизонтальной ориентации (создаем директорию layout-land, в которую помещаем идентичный файл activity_intro.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/intro_gradient">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/intro_rounded_corner"
android:layout_gravity="center"
android:gravity="center_vertical"
android:baselineAligned="false"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:layout_marginTop="@dimen/activity_vertical_margin">
<ImageView
android:src="@mipmap/ic_launcher"
android:contentDescription="@string/app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="@dimen/middle_margin" />
<TextView
android:text="@string/app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="@dimen/bottom_text_margin"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />
<TextView
android:id="@+id/skip_intro"
android:text="@string/skip_intro"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:textColor="@color/intro_text_link" />
</LinearLayout>
<com.google.android.youtube.player.YouTubePlayerView
android:id="@+id/youtube_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3" />
</LinearLayout>
</LinearLayout>
6) Создаем класс YouTubeFailureRecoveryActivity. Выносим его в отдельный класс, поскольку в случае наличия YouTube-функционала в других частях приложение, используется этот же класс:
public abstract class YouTubeFailureRecoveryActivity extends YouTubeBaseActivity implements
YouTubePlayer.OnInitializedListener {
private static final int RECOVERY_DIALOG_REQUEST = 1;
@Override
public void onInitializationFailure(YouTubePlayer.Provider provider,
YouTubeInitializationResult errorReason) {
if (errorReason.isUserRecoverableError()) {
errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST).show();
} else {
String errorMessage = String.format(getString(R.string.error_player), errorReason.toString());
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RECOVERY_DIALOG_REQUEST) {
// Retry initialization if user performed a recovery action
getYouTubePlayerProvider().initialize(Config.API_KEY, this);
}
}
protected abstract YouTubePlayer.Provider getYouTubePlayerProvider();
}
7) Создаем IntroActivity.java:
public class IntroActivity extends YouTubeFailureRecoveryActivity {
YouTubePlayerView youTubeView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_intro);
youTubeView = (YouTubePlayerView) findViewById(R.id.youtube_view);
youTubeView.initialize(Config.API_KEY, this);
// Закрываем Intro при клике на ссылку Skip Intro
TextView skipIntro = (TextView) findViewById(R.id.skip_intro);
skipIntro.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
/* Чтобы Intro можно было посмотреть позже, например, из главного активити
* и чтобы это активити не открывалось повторно при закрытии Intro, добавим
* экстра к интенту вызывающего активити: intent.putExtra(EXTRA_TEXT, "MainActivity").
* А здесь проверяем: если есть экстра - значит Intro было запущено из
* активити - тогда при клике на Skip Intro просто закрываем Intro.
* А если нет экстра - значит Intro было запущено при первом открытии аппа -
* сначала открываем главное активити, и затем закрываем Intro. */
Intent intent = getIntent();
String extra = intent.getStringExtra(MainActivity.EXTRA_TEXT);
if (extra == null) {
intent.setClass(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
finish();
}
});
}
@Override
protected YouTubePlayer.Provider getYouTubePlayerProvider() {
return youTubeView;
}
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean b) {
if (!b) {
youTubePlayer.cueVideo(Config.YOUTUBE_INTRO_ID);
}
}
}
Последним шагом в реализации данного функционала остается добавление permissions в Manifest и декларация IntroActivity:
<uses-permission android:name="android.permission.INTERNET"/>
...
<activity android:name=".IntroActivity" />
Так выглядит результат проделанной работы в вертикальной и горизонтальной ориентации:
Я постарался в этой статье рассказать полезную вещь, которая надеюсь пригодится вам для создания интересных проектов и будет полезна. Если у вас остались вопросы, то попробую ответить на них.
Поделиться с друзьями
Комментарии (5)
Goodkat
24.07.2016 15:31+1А Youtube рекламу не вставит перед роликом?
А после ролика не появятся «похожие видео» про собачек?StanZakharov
24.07.2016 15:40+1Если вы используете свое видео и у вас нет монетизации — не вставит. Про собачек ничего не появится, если вы читали статью, то мы жестко указываем id одного видео, поэтому других видео — не будет.
enginegl
26.07.2016 19:43Важный момент: для корректной обработки поворота экрана в манифесте необходимо добавить
android:configChanges="keyboardHidden|orientation|screenSize"
kaftanati
А если устройство offline — вывалится стандартная ошибка отсутствия сети? Есть ли план Б? Или пример следует понимать именно как пример проигрыша youtube ролика?
StanZakharov
тут все стандартно. Если нет сети, то будет в окне с роликом написанно: «Нет подключения к сети. Повторите попытку». Можно реализовать проверку на internet connection, если есть — показывать Intro, а если нет — показывать когда будет.