Furyu
[フリュー公式]

Tech Blog

フリュー株式会社の技術ブログです

2018年12月5日

araki

AndroidのIn-app Billing APIのバージョンについて

この記事は フリューAdvent Calendar 2018 の12/05分です。

はじめに

こんにちは。ピクトリンク事業部開発部の荒木です。普段はピクトリンクというアプリのAndroid版を開発しています。携帯は、Googleブランドの最新スマートフォンPixel3を使っています。非の打ち所がない良い端末なので、みなさん買いましょう。

今回の記事では、Androidの課金APIである In-app Billing API のバージョンについて書きたいと思います。

In-app Billing API とは

公式ドキュメントは以下です。日本語ドキュメントは情報が古かったので、英語ドキュメントを貼ってあります。2018/12/05現在、日本語ドキュメントの最終更新日は2018/4/25、英語ドキュメントの最終更新日は2018/7/17でした。

https://developer.android.com/google/play/billing/api?hl=en

ひとことで言うと、AndroidアプリでGoogle Play課金を実施するためのAPIです。AIDL(Android Interface Definition Language) と呼ばれるインターフェース定義言語によって定義されるAPIで、 .aidl ファイルから生成されるJavaのインターフェースによって利用することができます。

In-app Billing API は、 Google SamplesのIabHelper や Play Billing Library  のように上手くラップしたものがあり、それらを使う分には基本的に意識する必要はないのですが、バージョンごとに使えるメソッドが異なります。日本語ドキュメントや日本語の記事では単に In-app Billing API version 3 と書かれていることが多いので、一度整理してみようというのがこの記事のモチベーションです。

各バージョンで利用できるメソッド

https://developer.android.com/google/play/billing/billing_reference?hl=en

上記のドキュメントを参考に、In-app Billing API version 3 以降のバージョンについて、各バージョンでどのようなメソッドが利用できるかを説明します。

 

 バージョン  メソッド  説明
 3以降  isBillingSupported()  端末がIn-app Billing APIの特定バージョンに対応しているかを調べるためのメソッドです。
 3以降  getSkuDetails()  商品(SKU)の詳細情報を入手できます。
 3以降  getBuyIntent()  このメソッドを利用することで、Google Playによる購入フローを開始するための PendingIntent が取得できます。
 3以降  consumePurchase()  アプリ内アイテムの消費を実施します。たとえば、ゲームなどで有料のアイテムを消費して効果を得た時にこのメソッドを呼びます。
 3以降  getPurchases()  ユーザーが所有する商品(未消費の商品、有効期間内の定期購読)を返します。
 5以降  getBuyIntentToReplaceSkus()  定期購入のアップグレード/ダウングレードに利用されるメソッドです。購読したい商品に加えて、購読解除したい商品を指定することで、新しい商品の購読と、古い商品の購読解除を同時に実施します。
 6以降  getBuyIntentExtraParams()  getBuyIntent() に追加のパラメータを渡せるメソッドです。getBuyIntentToReplaceSkus() と同様に購読解除したい商品を追加パラメータで指定できるので、実質 getBuyIntentToReplaceSkus() のバージョンアップ版と考えられます。
 6以降  getPurchaseHistory()  ユーザーの購入履歴を返します。期限切れの定期購読や、キャンセルされた購入、消費済みの商品も含まれます。
 7以降  isBillingSupportedExtraParams()  isBillingSupported() に加えてアプリ課金のタイプについても調べることができるメソッドです。アプリ課金のタイプとして VR の購入フローを指定して、サポートしているかを調べられます。

 

Play Billing Libraryについて

Googleから提供されている課金のライブラリ Play Billing Library と In-app Billing API のバージョンについても言及しておきます。

2018/12/05 現在リリースされている Play Billing Library の最新バージョン 1.2 の課金周りのコードを見てみましょう。

このコードにあるように、Play Billing Library は、現在 In-app Billing API のバージョン3〜8に対応しているようです。現在の最新APIに対応できていると思われます。

さいごに

この記事では、In-app Billing API のバージョンについて書きました。普段ラップされていて意識しない部分ですが、内部のAPIを調べてみると意外と知らなかったパラメータがあったので、興味深かったです。アプリ課金に関する情報は定期的にアップデートされる印象があるので、しっかりとキャッチアップしていきたいと思います。


2018年12月3日

furusin

TextInputLayoutの導入方法と、導入による効果考察

こんにちは。ピクトリンク事業部の古川です。

この記事はフリューAdvent Calendar 2018の12/03分となります。

AndroidのTextInputLayoutについて触れていきます。

 

TextInputLayoutとは

AndroidのText入力欄をリッチにしてくれるもので、Support Library に含まれています。

Material Design Guidelineはこちら

 

上の動画のように、入力のヒントがアニメーションして常に表示されるようになってくれます。リッチですよね。

最近だと、オミカレさんAndroidアプリがTextInputLayoutに対応しています。

 

導入方法

非常に簡単です。

Support Libraryをimplementする

まずはSuport Libraryを入れます。

これで準備は完了です。

では実際に使っていきましょう。

レイアウトのXMLを作る

TextInputLayoutを入れる

リッチな入力欄を作るには、TextInputLayoutと一緒にTextInputEditTextを利用します。

導入はこれだけです。

ログイン画面風に入力画面を作ると以下のようになります(レイアウトXML全体)

実行すると以下のような画面になりました。

textinputlayoutsample-MainActivity-12032018102340

 

導入のまとめ

いかがでしたか?

非常に簡単に導入する事ができました。

入力欄の色はデフォルトで入っていますが、themeをStyleで作成することで自由に変更することも可能です。

色を自由に変えることで、アプリのデザインに違和感なく導入することができます。

 

導入における効果の考察

以下の2点が大きいと思います。

  1. デザインがかっこよくなる
  2. 入力ミスが低減される

それぞれ見ていきます。

デザインがかっこよくなる

これは言わずもがな、とは思います。

通常のEditTextだとアニメーションも何もなく、少し固い印象です。

TextInputLayoutの小さなアニメーションを入れることで「かっこいい」「なんか動いてる!」といった体験をユーザーへ与える事ができます。

アニメーションがあると、アプリに対するユーザーの感じ方は大きく変化(向上)します。

これだけでも導入する価値は大きいのではないでしょうか。

入力ミスが低減される

TextInputLayoutとTextInputEditTextを組み合わせることで、ヒントが入力欄上部に常に表示されることになります。

そのため、例えばパスワードのような「入力ルール」を常に見られる状態になります。

結果、「半角英数字8文字以上、大文字含む」といったような複雑なルールを忘れずに、スムーズに入力してもらうことが可能になります。

スムーズ入力できるということは、アプリがストレスフリーで利用できることになります。

ストレスフリーなアプリは評価が向上します。

ちょっとしたデメリット

入力欄を全てTextInputLayout+TextInputEditTextにする…となると、その分コードは長くなりますし、

実装関係者が知らずにEditTextをそのまま使ってしまう場合があります。

TextInputLayout+TextInputEditTextを使った独自レイアウトを作っておき、

その独自レイアウトを使うようにルール化すべきなのかもしれません。

 

まとめ

TextInputLayoutの簡単な導入方法と、導入することにおけるメリットをまとめました。

アニメーションやストレスフリーなアプリはユーザー体験を向上させ、アプリの評価も向上させます。

改善は小さなことからコツコツと!

これからも改善活動を続けていきたいと思います。

 


2018年11月7日

furusin

Androidエンジニア以外にも知ってほしいAndroidアプリ用語-UI部品編-

こんにちは。ピクトリンク事業部の古川です。

この記事はZaimの@akatsuki174さんの記事「iOSエンジニア以外にも知ってほしいiOSアプリ用語-UI部品編-」に感化されて書きました、Android版となります。

AndroidとiOSは似たような画面を実装する事は可能です。

しかしUIの部品の名称が異なっている事が少なくありません。

また、それぞれ独特の部品もあります。

その辺りを明確にし、まとめていこうと思います。

重要度★★★

AppBar(もしくはToolBar)

toolbar

Android Material Design Guidelines:AppBars:top

iOSではナビゲーションバーと呼びます。

現在表示している画面のタイトルといった情報や、関連するアクションを表示する領域です。

画面の最上部に表示されます。

基本的に常時表示されているものですが、スクロールして下の方にある情報を表示したい際には隠すことも可能です。

 

また、画面上に大きく表示していたタイトルをToolbarに入れるようなアニメーションを作ることも可能です。

Android Support Library 22.2.0 で追加されたCoordinatorLayoutを利用します。

 

NavigationDrawer

activities-NonLoginMainActivity-10232018181213

Androidアプリの大きな特徴です。

Android Material Design Guidelines:Navigation drawer

ツールバーの左部に「≡」マーク(ハンバーガーマークと読んだりします)がある場合は、NavigationDrawerがある場合が多いです。

主な用途は画面の切り替えです。

Google系のアプリであればアカウントの切り替え機能を提供したりします。

FloatingActionButton

activities-BootstrapActivity-11062018140659

Androidアプリの特徴です。

Android Material Design Guidelines:Buttons: floating action button

通常は画面の右下に表示し、現在表示している画面で行いたいメインのアクションを提供します。

Toast

toast

Androidの初期から存在する、メッセージを表示するためのものです。

主にエラーメッセージを表示したり、ログインの成功などで使います。

TabLayout

tabs

iOSではタブバーと呼びます。

Android Material Design Guidelines:Tabs

複数の画面を1画面に用意し、ユーザーのアクションによって画面を行き来できるようにするものです。

タブ名は文字だけかアイコン付きが一般的です。

AndroidだとTabLayoutは画面上部に設置するのが一般的でしたが、近年では下部に設置するようiOSに近づいてきている印象があります。

私個人的には、上部にあると片手で端末を持っている場合に指が届かないので、下部に設置されるのは良い傾向だなと感じています。

BottomNavigationView

 

bn

Android Material Design Guidelines:Bottom navigation

iOSのタブバーと似たレイアウトになります。

TabLayoutにも似ていますが、BottomNavigationViewは完全に異なるメイン機能間を切り替えるためのナビゲーションを提供します。

アイテムの数も3〜5と制限があります。

近年、画面下部にBottomNavigationView+画面上部にTabLayoutを設置するといったアプリが増えてきました。

(例えばGoogle I/0 2018)

 

重要度★★

Dialogs

activities-NonLoginMainActivity-10232018190023

Android Material Design Guidelines:Dialogs

Androidでは、上記図のようなダイアログが一般的です。

ボタンは基本的に2つです。

・ネガティブボタン:キャンセルといったネガティブな動作を割り当てます。

・ポジティブボタン:OKや実行といったポジティブな動作を割り当てます。

「ニュートラルボタン」と第三のボタンを設置することができますが、あまりオススメしません。

ボタンが増えるとユーザビリティが下がる(ユーザーが正常な判断ができなくなる)ため、2つがよいかと思います。

 

CardView

browser-ChromeTabbedActivity-10232018190358

Android Material Design Guidelines:Cards

最近のGoogle検索結果もCardViewになっていたのをご存知でしたか?

各アイテムがまるでカードのようなViewになっていて、ひとつの物体として認識できます。

影が映っているように見えるのも特徴で、フラットデザインからマテリアルデザインに変わった時の大きな特徴です。

SnackBar

 

 

snackbar_button

Android Material Design Guidelines:Snackbars

簡単なメッセージを画面下部に表示するためのものです。

Toastにも似ていますが、Toastはメッセージを表示するだけのものでしたが

SnackBarはボタンを設置することが可能です。

例えばGoogleフォトだと画像を削除すると「ゴミ箱に移動しました」とSnackBarが出ますが、そこに「もとに戻す」ボタンも用意されています。

メッセージととにユーザーに何らかの行動をさせたい場合、便利です。(メール送信の取消しなど)

 

Swipe-to-Refresh(Pull-to-Refresh)

「引っ張って更新」と呼んだりします。

一度通信して情報を読み込んだ後に更新をかけたい時に使います。

WebブラウザやTwitterアプリにも使われています。

重要度★

ChromeCustomTabs

performance

通常はWebブラウザを立ち上げたり、WebViewを用いてWebページを表示していましたが、

ChromeCustomTabsを使うとアプリ内のWebページ読み込みを大幅に高速化できます。

ChromeCustomTabsはアプリ内に組み込まれたWebViewのような動作をするため、同一アプリ内での表示だとユーザーへ認識させることができます。

 

まとめ

いかがだったでしょうか。

AndroidにはiOSとは異なるViewがたくさんあり、似たものも使い方が多少異なっていたりします。

もっとたくさんありますが、また少しずつ触れていけたらと思います。

 

 


2018年09月18日

furusin

Android Support Library28.0.0-alpha1で追加されたChipGroupを試してみる

こんにちは。ピクトリンク事業部の古川です。

今回は、Android Support Library28.0.0(Alpha1)で追加された、Chip/ChipGroupについて解説します。

Chip/ChipGroupとは?

タグのようなものを指すViewです。

例えば、以下のようにスキルセットの一覧を表示するために使ったりします。

top crop

それでは具体的に見ていきましょう。

Chip/ChipGroupの導入

まずはbuild.gradleにAndroidXの情報を追加します。

2018年9月5日時点ではRC02が最新です。

実際に使ってみる

感覚的には、RadioButtonの実装に非常に似ています。

それでは実際に使ってみましょう。

ViewのXMLに情報を追加します。

 

head

 

これだけでもシンプルなChip/ChipGroupが設置できました。

ひとつずつ見ていきます。

Chipは独立しても使えますが、RadioButtonのようにChipGroupの子要素としてセットします。

8行目、Chipにはいくつかのスタイルが事前に用意されており、XMLで指定できるようになっています。

styleによって設定できるものは以下のものがあります。

  • チップ(チェックマーク)
  • クリック(選択状態)
  • 閉じるアイコン

上記3点をStyleの種別によって設定できます。

種類 概要 イメージ
@style/Widget.MaterialComponents.Chip.Filter
  • チップ:オプション
  • クリック:常に有効
  • 閉じるアイコン:オプション

通常、ChipGroupに属したChipとして利用する際に指定します。

filter

filter_filtered

@style/Widget.MaterialComponents.Chip.Action styleを設定しなかった場合、これがデフォルトとなる。

  • チップ:オプション
  • クリック:不可
  • 閉じるアイコン:不可

通常、ChipGroupに属したChipとして利用する際に指定します。

 action
@style/Widget.MaterialComponents.Chip.Choice
  • チップ:オプション
  • クリック:常に有効
  • 閉じるアイコン:不可

ユーザーが「選択している」ことをわかりやすく表示してくれる。

通常、ChipGroupに属したChipとして利用する際に指定します。

choice

choice_selected

@style/Widget.MaterialComponents.Chip.Entry
  • チップ:オプション
  • クリック:オプション
  • 閉じるアイコン:オプション

通常、ChipGroupではなく独立したChipDrawableとして利用する際に指定します。

entryentry_filtered

最後に android:textAppearance をセットしていますが、これはSupportLibraryの時はセットしなくても問題なかったので、今後正式リリース版が出る場合には不要になるかと思います。

(セットしなかった場合、IllegalArgumentExceptionがコールされます。)

11行目、android:textについては、SupportLibraryでは app:chipText(setChipText) でしたがdeprecated になっています。

通常のandroid:text(setText)を使うようにしましょう。

 

リスナーも豊富に用意されておりsetOnClickListener, setOnCheckedChangeListener, setOnCloseIconClickListenerと、チェックや閉じるボタンに対応したリスナーが用意されています。

なお、setOnCloseIconClickListenerについては、コード中の実態はOnClickListenerとなっており、XMLから指定はできませんのでご注意ください。

試しに実装してみます。

次のような画面になります。

activity-MainActivity-09052018123549

setOnCloseIconClickListenerもKotlinのコード上で実装してみましょう

閉じるボタン(✕ボタン)をタップすると、ちゃんとViewがGONEになりました。

まとめ

実装自体はRadioButtonに形が似ていて、直感的で使いやすいものになっていました。

Chip/ChipGroupはまだ正式リリースはされていませんが、タグの表示など、活用できるシーンは多いかと思いますので、正式リリースが楽しみですね!


2018年09月3日

furusin

AndroidでKotlin Coroutinesを使ってみる

こんにちは。ピクトリンク事業部の古川です。

Androidでは従来ReactiveXが主流ですが、最近話題になっているCoroutinesを使った非同期処理の実装について解説します。

Coroutinesとは?

よく誤解されますが、CoroutinesとReactiveXは全くの別物です。

ReactiveXは非同期処理をストリームで実施するためのものですが、

Coroutinesは、「特定のスレッドに束縛されない、中断可能な計算処理インスタンス」です。

「特例のスレッドに束縛されない」ため、Androidでは非同期処理に用いられることが多いです。

そのためReactiveXとの比較で語られることが多いですが、性質が異なることを意識しておいてください。

Kotlinの公式ドキュメントに

「Coroutines simplify asynchronous programming by putting the complications into libraries.」(コルーチンは非同期処理をシンプルに書けるようにする)

と書いているのも誤解を呼ぶ要因の一つかと思います…

 

Kotlin Coroutinesを導入する

利用するにはbuild.gradleに情報を追加します。

また、Experimentalですので、その情報も追加します。

使い方

今回はサンプルとして、GitHubのAPIをRetrofitでコールしたレスポンスを画面に表示するアプリを作ってみます。

事前準備

RetforitでAPIを叩くために、InterfaceとModelを準備します。

実際に使ってみる

次に、このAPIを叩くメソッドを用意します。今回はViewModelに実装します。

fetchUserメソッドの1行目が最も重要な部分です。

まず返却値の型としてUserをDeferredで返します。ReactiveXだとSingle<User>になると思います。

async(CommonPool)はコルーチン内をスレッドプールで実行する、という理解でいいと思います(こちらを参考に)

後は通常通り、userを返却してあげているだけです。

それでは、このメソッドを呼び出してみます。

単純に「処理開始時にダイアログを表示し、終わったら画面に反映して閉じるだけ」の処理をしています。

launch(UI)は「UIスレッドで実行してね」という意味になります。

ここで .await() を呼んでいますが、これは「この処理が終わるまで続きの処理は awaitする(待つ)」という意味です。

最後に、画面に表示するXMLと画面イメージです。

activity-MainActivity-08302018161310

まとめ

非常に簡単ではありますが、以上でCoroutinesを試してみることができました。

完全にReactiveXをCoroutinesに置き換えることはまだまだ難しいとは思いますが、ReactiveXよりも考えることが比較的少なく、実装も容易ですので

今後はCoroutinesも選択肢のひとつになっていくと思います。