Quantcast
Channel: Google Developers Japan
Viewing all 2204 articles
Browse latest View live

Rocro 株式会社の導入事例:GAE + GKE をフル活用し、高品質な開発者向け SaaS サービスをソニーグループである Rocro 株式会社が少数精鋭で開発・運用

$
0
0
独 Travis CI 社など、シリコンバレー以外の企業が大きな存在感を示しているソフトウェア開発者向け SaaS 市場に、この秋、新鋭スタートアップが 3 つの画期的サービスで参戦し話題を呼んでいます。そして、そのサービスの実現には Google Cloud Platform が採用されているとのこと。数ある選択肢の中から、なぜ Google Cloud が選ばれたのか、その理由を聞いてきました。




■写真左から
Rocro株式会社
代表取締役社長
小早川 知昭氏(写真左)


Rocro株式会社
代表取締役 CTO
峯尾 嘉征氏(写真右)


■ 利用している Google Cloud Platform サービス
Google Container EngineGoogle App Engineなど


Rocro株式会社
2017 年 9 月、ソニーネットワークコミュニケーションズ株式会社の子会社として事業開始。世界中のソフトウェア開発者がより本質的な開発に集中できるようにすべく、開発者向け SaaS 事業を『Rocro』のサービスブランドで展開する。初期サービスは『Inspecode』『Docstand』『Loadroid』の 3 種。これらのサービスはパブリックベータ版として、当面無償で提供される(『Loadroid』は後日提供開始予定)。


ソニーグループの開発者向けサービスがいよいよ一般公開


規模の大きなソフトウェア開発において、今や必要不可欠なものになりつつあるソフトウェア開発者向け SaaS。ソースコードのバージョン管理サービス「GitHub」などは、定番中の定番と言えるでしょう。Rocro が目指すのは、ここに新たな定番の座を築くこと。まずは 3 つのサービスをこの秋から順次提供開始。その詳細について、同社 代表取締役社長 小早川 知昭さんが説明してくれました。

「Rocro の開発者向け SaaS 第 1 弾となる『Inspecode(インスペコード)』は、自動コードレビューサービス。Checkstyle や golint、pyflakes など、50 種以上のツールでコード解析を行うほか、強力な自動修正機能も提供しています。中でもとりわけ大きなアドバンテージが処理の並列化による高速解析。多数のツールを自動的に、同時に走らせてくれるので、ユーザーが素早く結果を得ることができます。ケースによって異なりますが、従来ツールをシーケンシャルに実行するのと比べて数倍は早くなっているのではないでしょうか。」(小早川さん)

加えて『Inspecode』では、レビュー開始前の手間も大幅軽減。従来ツールでは静的解析を始めるために、ツールごとに面倒なセットアップが必要になっていましたが、『Inspecode』ではこれらも全て自動化してくれるのだそうです。その上さらに間違ったコードを自動的に正しい記述に改めてくれる自動修正機能も搭載。「ここまで高性能、多機能なコードレビューサービスは『Inspecode』だけのはず。」と小早川さんは胸を張ります。

『Inspecode』の見やすいダッシュボード。


ソースコード解析実行時にオンデマンドでサーバーを割り当て、解析を並列実行。


そして、それと同時に API ドキュメント生成&ホスティングサービス『Docstand(ドックスタンド)』もサービスを開始。これは面倒なドキュメントの生成・維持・管理・公開を自動化してくれるというもので、やはり作業の自動化が大きな売りとなっています。さらに近日中には、自動負荷試験サービス『Loadroid(ロードロイド)』も投入予定。これは、手間のかかる負荷試験を簡単なシナリオを書くだけで実施できるようにするというものです。社内のテストでは、これまで 2 週間かかっていた負荷試験(準備期間含む)が、わずか 4 時間で終わってしまったというケースもあるのだとか。

ちなみにこれらのサービスは全て、元々はソニー社内で利用していたもの。それを社外に向けて提供するために Rocro が立ち上げられました。その開発背景について、3 つのサービス全てで開発を主導する代表取締役 CTO 峯尾 嘉征さんは次のように当時をふり返ります。

「ソニー社内でプロジェクトが立ち上がったのは 2015 年春。当時、ソニーでは数多くの Web サービスの開発を行っており、それを効率的に進めるため、最先端の開発ツールや、SaaS、PaaS を最大限に活用していました。しかし、実際に使ってみるとそこにはまだまだ改善の余地がある。中でも特に大きな不満を感じていた点を解消すべく作りあげたのが、この 3 つのサービスとなります。」(峯尾さん)

「実は、当初からこれらの外部提供は意識していました。と言うか、そのレベルのものにならなければ、社内でも使ってもらえません。開発の手法は企業によってそこまで大きくは変わりません。最も効率の良い手法を追求していくと、結局同じような結論に行き着くからです。我々はこれらのサービスを提供することで、そのトップランナーの 1 人になりたいと考えています。」(小早川さん)

サービスの開発・運用に Google Cloud Platform の先端テクノロジーが活躍


Rocro の 3 つのサービスには GCP の最新テクノロジーを積極活用。 GCP を選んだ理由を聞いたところ、「料金が安いということも大きな魅力だったのですが、何より大きかったのが、Google App Engine(GAE)の存在。プロジェクトが始まった当初はチームの規模も小さく、専任のインフラエンジニアを置く余裕がなかったのですが、インフラストラクチャ周りが完全に抽象化されたフルマネージドなプラットフォームであるGAE ならその必要がありません。むしろ、それぞれの開発者が好きなときにデプロイできるため、開発効率が向上したほど。結果、チーム規模が数倍になった現在でも、専任のインフラエンジニアは存在しないんですよ。」(峯尾さん)

ちなみに現在、Rocro の 3 つのサービスは GAE と Google Container Engine(GKE)の組みあわせで運用中(ほか、ストレージは Google Cloud Storage、データベースは Google Cloud Datastore を利用)。後者についても、数ある Docker 環境の中から、Google Cloud でなければならない理由があるそうです。

「GKE は、kubernetes をマネージドで提供していることがとても魅力的。『Inspecode』と『Docstand』は、kubernetes の Job という機能を使っており、Git がプッシュされるたびに新たな Job が実行されるという仕組みになっています。この Job がそれぞれアイソレートされた環境で動作すること、使い終わったら簡単に破棄できる点が便利。また、kubernetes は Job 単位で CPU の利用を制限できるので、特定のユーザーがものすごい負荷のかかる Job を走らせても他のユーザーに悪影響がでません。マルチテナントなサービスを安定的に運用するためには必須の機能と言えるでしょう。」(峯尾さん)

Rocro 構成図


アップデートが早く、最新のテクノロジーを比較的早く試せるようになることも、Google の美点だと言う峯尾さん。今、注目しているのはずばり Google Cloud Functions。最近流行りのサーバーレステクノロジーを使うことで、利用頻度の低い機能のためにインスタンスを立ち上げっぱなしにしておくコストを削減できるのではないかと期待しているそうです。

「今回発表した 3 つのサービスに共通しているのは、エンジニアの手間を軽減し、よりクリエイティブな面に注力できるようにすること。どれも一度使っていただければ、その便利さを実感していただけるはず。サービス開始当初は β 版と言うことで当面無料でお使いいただけます。β 期間が終了した後も、リーズナブルに使っていただけるようにすることをお約束します。ぜひ、お試しください。」(小早川さん)

Rocro株式会社の導入事例 PDFはこちらをご覧ください。
GCP のその他の導入事例はこちらをご覧ください。



Posted by Rumi Oku, Google Cloud Team

TensorFlow の Dataset と Estimator の紹介

$
0
0
この記事は TensorFlow チームによる Google Developers Blog の記事 "Introduction to TensorFlow Datasets and Estimators" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

TensorFlow 1.3 では次の 2 つの重要な機能が導入されました。
  • Dataset: 入力パイプライン(プログラムにデータを読み込む部分)を作成する新しい API です
  • Estimator: TensorFlow モデルを作成する高レベル API です。一般的な機械学習タスク用に事前に作成されたモデルを提供します。独自のカスタムモデルも作成できます

以下の図は、TensorFlow アーキテクチャにおけるこれらの機能の位置付けを示します。この 2 つを組み合わせると、簡単な作業で TensorFlow モデルを作成して学習を行えます。




サンプルモデル


Dataset と Estimator の使い方の例として、簡単なモデルを作成するためのサンプルコードを紹介します。学習とテスト用のファイルの取得方法を含むコード全体はこちらで入手できます(なお、このコードは Dataset と Estimator がどのように機能するか示すためのもので、性能の最適化は考慮されていません)。

このモデルの学習を行うと、アヤメの花を 4 つの特徴(がく片の長さ、がく片の幅、花弁の長さ、花弁の幅)に基づいて分類するモデルが得られます。4 つの特徴の値をモデルに与えると、以下の 3 種類の変種のうちどれかを推論します。


左から順番にヒオウギアヤメRadomilより、CC BY-SA 3.0)、ブルーフラッグDlangloisより、CC BY-SA 3.0)、ヴァージニアアイリスFrank Mayfieldより、CC BY-SA 2.0)

ここでは、以下の構造のモデルを使い、ディープ ニューラル ネットワークによる分類器の学習を行います。すべての入力値と出力値は float32 となり、出力値の合計は 1 になります(個々のアヤメの種類についてその確率を予測するため)。


たとえば、ヒオウギアヤメの出力結果が 0.05、ブルーフラッグが 0.9、ヴァージニアアイリスが 0.05 という結果が得られた場合、アヤメがブルーフラッグである確率が 90% という意味になります。

これでモデルの定義が完了です。次に、Dataset と Estimator を使ってこのモデルによる学習と推論を行う方法を説明します。

Dataset の概要


Dataset は、TensorFlow モデルへの入力パイプラインを作成する新しい方法です。この API は feed_dict や Queue によるパイプラインより高性能で、より分かりやすく簡単に使用できます。TensorFlow 1.3 では Dataset はまだ tf.contrib.data にあり、コア API ではありませんが、1.4 ではコア API に昇格する予定です。Dataset を試し始めるには今がよい時機です。

Dataset は次のクラスで構成されます。


各クラスの説明は次のとおりです。
  • Dataset: Dataset を作成して変換するメソッドを含む基底クラスです。メモリ内のデータ、または Python ジェネレータから Dataset を初期化する機能を提供します
  • TextLineDataset: テキスト ファイルから行を読み取ります
  • TFRecordDataset: TFRecord ファイルからデータを読み取ります
  • FixedLengthRecordDataset: バイナリ ファイルから固定サイズのデータを読み取ります
  • Iterator: Dataset の各要素にひとつずつアクセスするために使います

サンプルコードのデータセット


まずはモデルの学習に使用するデータセットを見てみましょう。以下のような CSV ファイルを用います。各行には 5 つの値(4 つの入力値とラベル)が含まれます。

ラベルの定義は以下の通りです。
  • ヒオウギアヤメは 0
  • ブルーフラッグは 1
  • ヴァージニアアイリスは 2

Dataset を定義する


Dataset を定義するには、まず特徴量のリストを作成します。
feature_names = [
'SepalLength',
'SepalWidth',
'PetalLength',
'PetalWidth']

一方、モデルの学習を行うときは、入力ファイルを読み取って特徴量とラベルを返す入力関数が必要になります。次の形式の関数を作成し、Estimator に渡します。
def input_fn():
...<code>...
return ({ 'SepalLength':[values], ..<etc>.., 'PetalWidth':[values] },
[IrisFlowerType])

戻り値は、次の 2 要素のタプルである必要があります。
  • 最初の要素には辞書(dict)を返します。各入力特徴量のキーと、学習バッチの値のリストのペアです
  • 2 番目の要素は、学習バッチのラベルのリストとします

Estimator は、この return 文で返された値のリストとラベルのリストを用いて学習を行います。よって、これらはいずれも同じ長さとします。ちなみに、ここでいう「リスト」とは、1 次元の TensorFlow テンソルを指します。

この input_fn 関数を後から簡単に再利用できるように、いくつかの引数を追加します。これにより、設定を変えるだけで様々な入力関数を作成できます。これらの引数の意味は簡単です。
  • file_path: 読み取るデータファイルです
  • perform_shuffle: データをシャッフルするかどうかを指定します
  • repeat_count: Dataset の行の読み取りを繰り返す回数を指定します。たとえば 1 を指定すると、各行を 1 回だけ読みとる Dataset となります。None を指定すると、各行を繰り返し読み取り可能な Dataset となります

この入力関数を Dataset API で実装する方法を以下に示します。なお、この後で Estimator に入力関数を渡すとき、以下の関数をそのまま使わず、ラップした関数を使います。

def my_input_fn(file_path, perform_shuffle=False, repeat_count=1):
def decode_csv(line):
parsed_line = tf.decode_csv(line, [[0.], [0.], [0.], [0.], [0]])
label = parsed_line[-1:] # Last element is the label
del parsed_line[-1] # Delete last element
features = parsed_line # Everything (but last element) are the features
d = dict(zip(feature_names, features)), label
return d

dataset = (tf.contrib.data.TextLineDataset(file_path) # Read text file
.skip(1) # Skip header row
.map(decode_csv)) # Transform each elem by applying decode_csv fn
if perform_shuffle:
# Randomizes input using a window of 256 elements (read into memory)
dataset = dataset.shuffle(buffer_size=256)
dataset = dataset.repeat(repeat_count) # Repeats dataset this # times
dataset = dataset.batch(32) # Batch size to use
iterator = dataset.make_one_shot_iterator()
batch_features, batch_labels = iterator.get_next()
return batch_features, batch_labels

ここでの要点は以下の通りです。
  • TextLineDataset: この Dataset API は、ファイルベースのデータセットを使用する際に必要となる様々なメモリ管理を行います。たとえば、メモリよりも大幅に大きいデータセットを読み込んだり、リストを引数として指定した複数のファイルを読み込んだりできます
  • shuffle: buffer_size で指定した数の要素を読み取り、その順番をシャッフルします
  • map: データセットの個々の要素を引数として decode_csv関数を呼び出します(この例では TextLineDataset を使用するため、つまり CSV テキストの各行を decode_csv に渡すことを意味します)。
  • decode_csv: 各行をフィールドに分割し、必要に応じてデフォルト値を指定します。つづいて、フィールドのキーと値の辞書を返します。上述の map 関数は、この辞書を使って各要素(行)を書き換えます

これで Dataset API の概要の説明は終わりです。この関数を使用して、学習バッチの冒頭部分を試してみましょう。

next_batch = my_input_fn(FILE, True) # Will return 32 random elements

# Now let's try it out, retrieving and printing one batch of data.
# Although this code looks strange, you don't need to understand
# the details.
with tf.Session() as sess:
first_batch = sess.run(next_batch)
print(first_batch)

# Output
({'SepalLength': array([ 5.4000001, ...<repeat to 32 elems>], dtype=float32),
'PetalWidth': array([ 0.40000001, ...<repeat to 32 elems>], dtype=float32),
...
},
[array([[2], ...<repeat to 32 elems>], dtype=int32) # Labels
)

このサンプルコードにおける Dataset の機能は以上です。Dataset API にはさらに多くの機能があります。詳細については、この記事の最後にあるリンク先をご覧ください。

Estimator の概要


Estimator は、TensorFlow モデルの学習時にこれまで必要だった手間のかかるコーディングが不要となる高レベル API です。柔軟性も高く、個々のモデルの要件に合わせてデフォルトの動作をオーバーライドできます。

Estimator は以下の 2 つの方法で作成できます。
  • 定義済み Estimator を使う - 特定の種類のモデルを生成するために事前に定義された Estimator です。この記事では、そのひとつである DNNClassifier を使う例を紹介します
  • Estimator クラス(基底クラス)を使う - model_fn 関数を使用して、モデルの作成方法をカスタマイズできる方法です。この方法については、また別の機会に紹介します
Estimator クラスの概要を以下に示します。


TensorFlow の今後のリリースでは、さらに多くの種類の定義済み Estimator を提供する予定です。

上図に示すように、いずれの Estimator も input_fn 関数を使用してデータを受け取ります。

以下のコードは、アヤメの種類を予測する Estimator を作成する例です。

# Create the feature_columns, which specifies the input to our model.
# All our input features are numeric, so use numeric_column for each one.
feature_columns = [tf.feature_column.numeric_column(k) for k in feature_names]

# Create a deep neural network regression classifier.
# Use the DNNClassifier pre-made estimator
classifier = tf.estimator.DNNClassifier(
feature_columns=feature_columns, # The input features to our model
hidden_units=[10, 10], # Two layers, each with 10 neurons
n_classes=3,
model_dir=PATH) # Path to where checkpoints etc are stored

では、ここで作成した Estimator の学習を行いましょう。

モデルのトレーニング


以下のように一行書くだけで学習を行えます。

# Train our model, use the previously function my_input_fn
# Input to training is a file with training example
# Stop training after 8 iterations of train data (epochs)
classifier.train(
input_fn=lambda: my_input_fn(FILE_TRAIN, True, 8))

この「lambda: my_input_fn(FILE_TRAIN, True, 8)」という部分で、先程作成した Dataset とこの Estimator を結びつけています。Estimator は、モデルの学習と評価、推論に必要な入力データを input_fn 関数を介して取得します。この input_fn 関数としては、引数なしの関数を渡す必要があります。そこで、my_input_fn 関数の引数 file_path、shuffle setting、repeat_count として以下の値を指定する input_fn 関数を lambda で新たに作成し、Estimator に渡しています。
  • FILE_TRAIN: 学習用のデータファイルのパスです
  • True: データのシャッフルを指定します
  • 8: データセットを 8 回繰り返すよう指定します

学習したモデルの評価


これで、モデルの学習が終わりました。Estimator の evaluate メソッドを呼び出すと、モデルの精度を評価できます。

# Evaluate our model using the examples contained in FILE_TEST
# Return value will contain evaluation_metrics such as: loss & average_loss
evaluate_result = estimator.evaluate(
input_fn=lambda: my_input_fn(FILE_TEST, False, 4)
print("Evaluation results")
for key in evaluate_result:
print(" {}, was: {}".format(key, evaluate_result[key]))

今回のサンプルコードの例では、最大で約 93% の精度が得られます。この精度を高めるにはいろいろな方法が考えられますが、そのひとつは、単にこのコードを繰り返し実行することです。モデルの状態は上記で指定した model_dir=PATH に保存されるので、繰り返し学習を行うことで、モデルの精度は収束しながら向上していきます。

もう 1 つの方法は、モデルの隠れ層の数や各層のノード数を調整することです。これらの方法を自由に試せますが、変更すると DNNClassifierのモデルの構造が変化するため model_dir=PATHで指定したディレクトリを削除する必要があることに注意してください。

トレーニングされたモデルを使用した予測


ここまでの作業で、モデルの学習を行い、その精度も十分なものであることを評価しました。さっそくこのモデルを使い、アヤメの分類を試しましょう。学習や評価の場合と同様に、predict メソッドを呼び出すだけで予測が可能です。

# Predict the type of some Iris flowers.
# Let's predict the examples in FILE_TEST, repeat only once.
predict_results = classifier.predict(
input_fn=lambda: my_input_fn(FILE_TEST, False, 1))
print("Predictions on test file")
for prediction in predict_results:
# Will print the predicted class, i.e: 0, 1, or 2 if the prediction
# is Iris Sentosa, Vericolor, Virginica, respectively.
print prediction["class_ids"][0]

オンメモリのデータで予測

上記のコードでは、FILE_TESTを指定してファイル保存されたデータに対して予測を行いました。一方、オンメモリのデータなど、他の場所にあるデータに対して予測を行うにはどうすればよいでしょうか。この場合も、predict メソッドの呼び出しは変更する必要がありません。以下のように、オンメモリのデータを参照するように Dataset API を設定します。
# Let create a memory dataset for prediction.
# We've taken the first 3 examples in FILE_TEST.
prediction_input = [[5.9, 3.0, 4.2, 1.5], # -> 1, Iris Versicolor
[6.9, 3.1, 5.4, 2.1], # -> 2, Iris Virginica
[5.1, 3.3, 1.7, 0.5]] # -> 0, Iris Sentosa
def new_input_fn():
def decode(x):
x = tf.split(x, 4) # Need to split into our 4 features
# When predicting, we don't need (or have) any labels
return dict(zip(feature_names, x)) # Then build a dict from them

# The from_tensor_slices function will use a memory structure as input
dataset = tf.contrib.data.Dataset.from_tensor_slices(prediction_input)
dataset = dataset.map(decode)
iterator = dataset.make_one_shot_iterator()
next_feature_batch = iterator.get_next()
return next_feature_batch, None # In prediction, we have no labels

# Predict all our prediction_input
predict_results = classifier.predict(input_fn=new_input_fn)

# Print results
print("Predictions on memory data")
for idx, prediction in enumerate(predict_results):
type = prediction["class_ids"][0] # Get the predicted class (index)
if type == 0:
print("I think: {}, is Iris Sentosa".format(prediction_input[idx]))
elif type == 1:
print("I think: {}, is Iris Versicolor".format(prediction_input[idx]))
else:
print("I think: {}, is Iris Virginica".format(prediction_input[idx])

Dataset.from_tensor_slides()は、オンメモリで保存できる小規模なデータセット用に設計されています。一方で、モデルの学習と評価の場合と同様に TextLineDatasetを使用すると、シャッフル用のバッファと学習バッチがメモリサイズに収まる限り、任意の大きなファイルを使って予測を行えます。

TensorBoard で可視化


ここまで見てきたとおり、DNNClassifier などの定義済み Estimator はその使いやすさなど大きなメリットを提供します。加えて、各種の評価値の計測機能も備えており、TensorBoard によるサマリー表示が可能です。このサマリーレポートを表示するには、コマンドラインから次のコードを実行して TensorBoard を起動します。

# Replace PATH with the actual path passed as model_dir argument when the
# DNNRegressor estimator was created.
tensorboard --logdir=PATH

TensorBoard には次のような評価値が表示されます。


まとめ


この記事では、TensorFlow の新しい API である Dataset と Estimator について説明しました。これらは入力データのストリームを定義してモデルを作成できる重要な API であり、その習得に必要なコストを大きく上回るメリットを提供します。

詳細については、次の各ページをご覧ください。

これで終わりではありません。これらの API がどのように動作するかを説明した投稿を間もなく公開しますので、ご期待ください。

それまで、TensorFlow のコーディングをお楽しみください。



Reviewed by Kaz Sato - Staff Developer Advocate, Google Cloud

Google Play Billing Library 1.0 をリリース

$
0
0
この記事はデベロッパー アドボケート、Neto Marin による Android Developers Blog の記事 "Android Developers Blog: Google Play Billing Library 1.0 released" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

6 月に、新しい Google Play Billing Library のデベロッパー プレビューについてお知らせしました。そして本日(*原文公開当時)は、Play Billing Library 1.0 の公式リリースについてお知らせいたします。このライブラリは、デベロッパーの皆さんがアプリの作業に集中できるよう、Google Play Billing の開発プロセスを簡単にするものです。

貴重なフィードバックや提案をありがとうございました。そのおかげで、今回の 1.0 リリースを実現することができました。ライブラリの特徴については、概要を紹介している次の動画をご覧ください。

始める前に

Play Billing を使うと、信頼されている支払いシステム経由で世界中のユーザーからの支払いを受け取ったり、Play Console の機能やレポートを活用して管理を行い、収益を高めることができます。

アプリ内課金を実装したことがない方や、Play Billing Library で何を提供できるか知りたいという方は、アプリ内課金の概要に目を通して概念や用語を把握しておくと、Play Billing Library によるアプリ内課金の実装がしやすくなります。

はじめに

Play Billing Library は Maven レポジトリで公開されており、アプリの build.gradleファイルに次の依存関係を追加するだけで、プロジェクトに Play Billing Library を追加できます。
dependencies {
...
compile 'com.android.billingclient:billing:1.0'
}

Play Billing Library 1.0 を追加すると、APK には自動的に com.android.vending.BILLINGパーミッションが追加されます。つまり、アプリのモジュールのマニフェストに手動でパーミッションを追加する必要はありません。

BillingClient と PurchasesUpdatedListener

これらのクラスは、ライブラリを Android アプリに組み込む際にもっとも重要なパーツとなります。BillingClientは、アプリと Google Play の橋渡しを行います。このクラスを使うと、利用できるアイテムリストの取得、アプリ内アイテムや定期購入のための課金フローの開始(支払いインターフェースのオープン)、ユーザーの購入履歴の取得、定期購入の作成や変更ができます。

BillingClientインスタンスを作成する際には、PurchasesUpdatedListenerを設定する必要があります。これによって、アプリは課金フロー後のトランザクションの結果やアプリ外での購入履歴(利用したプロモーション コードや別の端末で購入したアイテムなど)を含む In-app Billing API からのアップデートを受信できるようになります。

次のコードは、PurchasesUpdatedListeneronPurchasesUpdated()メソッドをオーバーライドする例を示しています。

@Override
void onPurchasesUpdated(@BillingResponse int responseCode,
List<Purchase> purchases) {
if (responseCode == BillingResponse.OK
&& purchases != null) {
for (Purchase purchase : purchases) {
handlePurchase(purchase);
}
} else if (responseCode == BillingResponse.USER_CANCELED) {
// Handle an error caused by a user canceling the purchase flow.
} else {
// Handle any other error codes.
}
}

PurchasesUpdatedListenerは、アプリのアーキテクチャに応じて、Activity や任意のクラスで実装することができます。次に示すのは、BillingClientインスタンスを作成し、PurchasesUpdatedListenerを設定するコードです。

mBillingClient = BillingClient.newBuilder(mContext)
.setListener(mPurchasesUpdatedListener)
.build();

アイテム一覧と販売

アプリ内でアイテムを販売するには、まず Play Console にアイテムを追加する必要があります。詳しいアプリ内アイテムの追加方法は、アプリ内課金の管理をご覧ください。

: 新しいアプリにアイテムを追加する場合は、あらかじめアルファ版またはベータ版の配信チャンネルに公開する必要があります。詳細については、ドラフト版アプリのサポート終了をご覧ください。

現在のユーザーに対する価格を含むアイテムの詳細リストを取得するには、querySkuDetailsAsync()を呼び出します。その際に、SkuDetailsResponseListenerインターフェースを実装したリスナーを指定する必要があります。次のサンプルコードに示すように、クエリが終了した際にリスナーに通知する onSkuDetailsResponse()メソッドをオーバーライドすることができます。

List<String> skuList = new ArrayList<> ();
skuList.add("premiumUpgrade");
skuList.add("gas");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
mBillingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(SkuDetailsResult result) {
// Process the result.
}
})

ユーザーが購入するアイテムを選択したら、課金フローを開始してトランザクションの結果を処理する必要があります。アプリで購入リクエストを開始するには、Play Billing Library クライアントの launchBillingFlow()メソッドを呼び出します。launchBillingFlow()メソッド(BillingClientのその他のメソッドも同様)は、UI スレッドから呼び出す必要があります。

launchBillingFlow()メソッドの呼び出しには、購入するアイテムの商品 ID や商品タイプ(このケースでは、SkuType.INAPP)など、購入の完了に必要なデータを含む BillingFlowParamsオブジェクトが必要です。BillingFlowParamsのインスタンスは、newBuilder()メソッドを呼び出して取得します。

BillingFlowParams.Builder builder = BillingFlowParams
.newBuilder()
.setSku(skuId).setType(SkuType.INAPP);
int responseCode = mBillingClient.launchBillingFlow(builder.build());

前述のように、トランザクションの結果は onPurchasesUpdated()メソッドに送信されます。onPurchasesUpdated()で受信したデータや購入の詳しい処理方法については、トレーニング ガイドのアイテムの購入セクションをご覧ください。

アイテムを消費する

デフォルトでは、すべてのアプリ内アイテムは管理されています。つまり、Google Play はアイテムの所有者を追跡しており、複数回購入することは認めていません。同じアイテムを再購入できるようにするには、再度アイテムを有効にする前にアイテムが消費される必要があります。

よくある例としては、ユーザーが何度も購入を希望するような(ゲーム内の通貨や品物など)形でアプリ内アイテムの消費を可能にするケースが考えられます。また一般的には、一度しか購入しないアプリ内アイテムについては消費という形をとらず、永続的な効果があるサービス(プレミアム アップグレードなど)を提供します。

アイテムを消費するには、Play Billing Library クライアントで購入した際に返される purchaseToken文字列値を渡して consumeAsync()メソッドを呼び出します。結果は、ConsumeResponseListenerインターフェースの onConsumeResponse()メソッドから返されます。この結果を処理するには、メソッドをオーバーライドする必要があります。

アイテムに関連付けられている purchaseTokenを使ってアイテムを消費する例を次に示します。

ConsumeResponseListener listener = new ConsumeResponseListener() {
@Override
public void onConsumeResponse(@BillingResponse int responseCode,
String outToken) {
if (responseCode == BillingResponse.OK) {
// Handle the success of the consume operation.
// For example, increase the number of player's coins,
// that provide temporary benefits
}
}
};
mBillingClient.consumeAsync(purchaseToken, listener);

サンプルのアップデート: Trivial Drive V2

新しいライブラリには、新しいサンプルが付属しています。新しい Play Billing Library を使ったアプリ内課金を実装する方法を理解してもらうために、Trivial Driveサンプルを一から書き直しています。

2013 年に Trivial Drive がリリースされてから、Android エコシステムには多くの新機能や端末、プラットフォームが追加されています。その進化を反映して、Trivial Drive v2サンプルは Android TV や Android Wear でも動作するようになっています。

次のステップ

アプリに統合する前に、Google I/O 2017 で公開されたコードラボで Play Billing Library を試してみることもできます。購入と定期購入: Google Play でアプリを収益化するをご覧ください。

このコードラボでは、ユーザーが「車を運転」する簡易版 Trivial Drive V2 にアプリ内購入を追加します。購入や定期購入をアプリに組み込む方法や、購入を処理する信頼性の高いアプリを開発するためのベスト プラクティスを学ぶことができます。

詳しい情報は、Play Billing Libraryに記載されています。また、Android Developers ウェブサイトには、クラスやメソッドが掲載された公式リファレンスが公開されています。プロジェクトで Play Billing Library を実装する方法をステップごとに説明したガイドは、ライブラリのトレーニング クラスをご覧ください。

今後もフィードバックをお願いします

問題や質問がある方は、Google Issue Tracker にバグレポートを送信してください。サンプルに関する問題や提案(バグや新機能など)については、Trivial Drive の問題ページからご連絡ください。

実装やライブラリの使用方法、ベスト プラクティスに関する技術的な質問は、google-playおよび play-billing-libraryのタグをつけて StackOverflowに質問するか、Google+ ページのコミュニティにアクセスしてください。



Reviewed by Hak Matsuda - Developer Relations Team

HSTS を拡大し、ウェブのセキュリティを向上させる

$
0
0
この記事は Google Registry、Ben McIlwain による Google Security Blog の記事 "Broadening HSTS to secure more of the Web" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

Google がもっとも重視しているのはウェブのセキュリティです。ウェブのセキュリティ ツールボックスの中でも特に強力なツールの 1 つがウェブサイトへの接続を HTTPS で暗号化することです。これによって、ウェブの通信トラフィックの盗聴、改変、誤配信などを防げるようになります。私たちは、Google 内部でも、さらに広いインターネットの世界でも、HTTPS の利用をさらに広げるためにさまざまなアクションをとってきました。

2010 年には Gmail のデフォルトが HTTPS になり、デフォルトで検索の通信も暗号化されました。2014 年には、Google 検索で保護されたウェブサイトのランキングを上げることを通して、HTTPS の利用が推奨されるようになりました。また、2016 年には、無料で簡単に使える SSL 証明書を提供する Let’s Encryptの主要スポンサーになりました。今年には、Chrome が保護されていないサイトで警告を表示するようになることをお知らせし、少し前には、App Engine にフル マネージド SSL 証明書が導入されました。そして本日は、私たちのツールボックスに、HTTPS Strict Transport Security(HSTS)プリロード リストというもう 1 つの強力なツールが新たに加わったことをお知らせします。

HSTS プリロード リストは、すべての主要ブラウザ(Chrome、Firefox、Safari、Internet Explorer/Edge、Opera)に組み込まれています。これは、ブラウザが自動的に HTTPS で保護された接続を強制するホスト名のリストです。たとえば、リストに gmail.com が含まれている場合、前述の各ブラウザは Gmail に対して保護されていない接続を利用しません。ユーザーが http://gmail.comと入力すると、リクエストを送信する前にブラウザが https://gmail.comに書き換えます。http から https にリダイレクトするページは盗聴される恐れがありますが、この対応によってブラウザがそのページを読み込まなくなるので、セキュリティは大きく向上します。

HSTS プリロード リストには、個々のドメイン、サブドメイン、トップレベル ドメイン(TLD)を含めることができます。リストへの追加は、HSTS のウェブサイトから行うことができます。TLD とは、.com、.net、.org など、ドメイン名の最後の部分です。Google は 45 個の TLD を管理しており、その中には .google、.how、.soy などが含まれています。2015 年、Google は .google を HSTS プリロード リストに追加し、初めて安全な TLD を作成しました。今後、.foo と .dev を皮切りに、Google が管理する多数の TLD を HSTS に追加していく予定です。

TLD レベルの HSTS を利用することで、その名前空間をデフォルトで保護することができます。登録者は、ウェブサイトに保護された TLD を使用し、SSL 証明書を設定するだけで、個々のドメインやサブドメインを HSTS プリロード リストに追加することなく確実に自身やユーザーを保護できます。また、通常は、ドメイン名がリストに追加されてから、ブラウザのアップグレードが大半のユーザーに行き渡るまでには、数か月を要します。そのため、既に保護されている TLD を使用すると、待たされることなく、すぐにサイトを保護することができます。TLD 全体を HSTS プリロード リストに追加すると、その TLD に属するすべてのドメインが保護され、それぞれのドメインを個別に追加する必要がなくなるので、効率も上がります。

近々、これらの安全な TLD のうちいくつかに登録できるようにしたいと考えています。TLD 全体を含む HSTS が、新しい TLD のセキュリティ標準になることを期待しています。


Reviewed by Eiji Kitamura - Developer Relations Team

サンフランシスコで開催された Indie Games Festival の受賞者を発表

$
0
0
この記事は Google Play デベロッパー マーケティング、Kacey Fahey による Android Developers Blog の記事 "Announcing the Winners from the Indie Games Festival in San Francisco" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

先日サンフランシスコで開催された Google Play Indie Games Festival では、多くの参加者がインディー コミュニティから生まれたさまざまな素晴らしいゲームを楽しみました。コンテストは白熱したものとなり、最終的に、3 組の勝者が選ばれました。
  • Flipping Legend(デベロッパー: Hiding Spot)
  • Slayaway Camp(デベロッパー: Blue Wizard Digital)
  • Tiny Bubbles(デベロッパー: Pine Street Codeworks、 近日公開!)

その他 10 組のトップ デベロッパーと、すべての決勝進出者の皆さんにもお祝いの言葉を贈ります。皆さんのゲームのおかげで、イベントは楽しく興奮に満ちたものになりました。この 10 作は、Google Play のゲーム コレクションで公開されています。

ここでは、トップ 10 に入賞した他の 7 作のゲームを紹介します。

当日は、参加者が決勝進出者 20 組のゲームをプレイするところから始まりました。さまざまなジャンルやスタイルのゲームをプレイして、作品について、またモバイルゲーム開発で生計を立てる生活についてデベロッパーに尋ねることもできました。イベントでは、子どもも大人も、ゲームのファンもゲームをしない人も一堂に会し、モバイルゲームが生み出す楽しさが満ちあふれていました。

午後には参加者による投票が行われ、上位 10 組のデベロッパーがプレゼンテーション ラウンドに進みました。各デベロッパーは 3 分間で審査員に最高のアピールを行い、審査員による投票の結果、3 組の勝者と 7 組の入賞者が発表されました。

Google おすすめのインディー ゲームを見てみたいというファンの方は、Google Play のインディーズ コーナーにアクセスしてみてください。

このブログ投稿はどのくらい役に立ちましたか?

Reviewed by Hak Matsuda - Developer Relations Team

キーストアの鍵の構成証明

$
0
0
この記事は ソフトウェア エンジニア、Shawn Willden による Android Developers Blog の記事 "Keystore Key Attestation" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

アプリのデベロッパーは、認証や暗号化用の暗号鍵を使う方法として何年も前から Android のキーストアを利用できます。キーストアによって、アプリのプロセス空間からキーマテリアルを分離できます。そのため、意図せずにアプリでユーザーに鍵が公開され、フィッシングに使われたり、他のチャンネルによって漏洩したり、アプリの欠陥を通して鍵が危険にさらされることはなくなります。多くの端末では、キーストアの鍵はハードウェア ベースのセキュリティで保護されており、セキュア ハードウェア上に格納されています。キーマテリアルは完全に Android システムの外にあるため、たとえ Linux カーネルに欠陥があったとしても、キーマテリアルが漏洩することはありません。セキュア ハードウェアとは、大半の Android 端末では Linux カーネルと Android ユーザー空間からハードウェアによって強制的に隔離されているメイン CPU の特殊なモードを指しています。端末によっては、保護された別のマイクロプロセッサを利用しているものもあります。

Android では、アプリで指定されたキーストアの鍵がセキュア ハードウェアに格納されているかどうかを判断できる API が提供されています。しかし、オペレーティング システムに欠陥がある場合、これらの API は信頼できないかもしれません。鍵の構成証明は、非対称な鍵がセキュア ハードウェアに格納されており、Android OS の欠陥から保護されていることを端末のセキュア ハードウェアによって検証する方法です。

キーストアの歴史


キーストアは Android 4.0 で初めて導入され、鍵がユーザーのパスコードで暗号化されるようになりました。Android 4.1 では、端末のセキュア ハードウェアを使うためのインフラストラクチャが追加されました。

Android 6.0 までは、キーストアでは RSA と ECDSA がサポートされていましたが、Android 6.0 でキーストアが大幅に強化され、AES と HMAC がサポートされるようになりました。さらに、RSA パディング1や AES ブロック チェーン2モードなどの暗号操作に欠かせない要素もセキュア ハードウェアに移動しました。

Android 6.0 では、特定の鍵の用途を制限する機能もキーストアに追加されています。適用される制限のうち、もっともわかりやすいのが ユーザー認証バインドです。これは、鍵の用途をユーザーのパスコード(PIN、パターン、パスワード)や指紋に「バインド」するものです。パスコード認証バインドでは、アプリのデベロッパーはタイムアウトを秒数で指定できます。ユーザーが最後にパスコードを入力してから指定された時間以上が経過すると、セキュア ハードウェアがその鍵を利用するすべてのリクエストを拒否します。指紋にバインドされた鍵では、鍵を使うたびに新しいユーザー認証が要求されます。

その他の技術的な制限は、Android 6.0 以上の鍵にも適用されます。特に重要なのは、鍵の作成やインポートの時点で、鍵を利用できる暗号学的な目的(暗号化、復号化、署名、検証)、パディングやブロックモード、ダイジェスト、初期化ベクトルのエントロピーのソース(nonce)、その他の暗号操作の詳細を指定する必要がある点です。指定された情報は永久的かつ暗号学的にキーマテリアルにバインドされるため、キーストアはその鍵を別の方法に使うことを許可しません。そのため、攻撃者がアプリやシステムを制御したとしても、鍵を悪用することはできません。攻撃を防ぐため、デベロッパーは鍵にできるだけ狭い範囲の用途を指定する必要があります。

Android キーストアで特に重要な変更は、Android 7.0 で導入されました。Android 7.0 以上がインストールされた状態でリリースされ、安全なロック画面が搭載される新端末では、セキュア ハードウェアに加え、ハードウェア ベースのパスコード認証およびキーストアの鍵が必須になりました。セキュア ハードウェアのサポートは Android 7.0 より前から広がっていましたが、これは今後数年間で一般的になるでしょう。

Android 8.0 では、Google Play がインストールされた状態で出荷されるすべての新端末で、鍵の構成証明が必須になりました。

鍵の構成証明を使用する理由


銀行の顧客に対して、残高、取引記録、請求支払いシステムにアクセスできるアプリを開発する場合を考えてみましょう。セキュリティは重要です。スマートフォンを拾った人がそのユーザーの銀行口座にアクセスできるようにしたいとは誰も思いません。それを防ぐアプローチの 1 つは、ユーザーのウェブサイトのパスワードを使う方法です。しかし、ウェブサイトでは、小さなタッチスクリーンでの入力に不向きな長く複雑なパスワードが求められることが多いため、不便に感じるユーザーが多いでしょう。

Android のキーストアを使うと、256 ビット ECDSA 鍵などの非対称な認証鍵を生成できます。各ユーザーは、一度だけ複雑なウェブのパスワードを使ってログインし、銀行の顧客口座データベースに公開鍵を登録できます。そして、ユーザーがアプリを開くたびに、ECDSA 鍵を使ったチャレンジ レスポンス認証プロトコルを実行します。さらに、鍵を認証用にバインドすれば、ユーザーはアプリを開くたびにロック画面のパスコードや指紋を使って認証できるようになります。これにより、スマートフォンでシンプルで便利な認証メカニズムが実現できます。

鍵はセキュアハードウェア内に格納されているため、攻撃者が Android の欠陥を悪用して鍵を抽出することはできません。

アプリのデベロッパーが鍵の構成証明を利用すると、アプリがリクエストした ECDSA 鍵が実際にセキュア ハードウェア内に格納されているかをサーバー側で検証することができます。アプリ自身が構成証明を使ってもあまり意味がありませんので注意してください。Android OS に欠陥がなく、信頼できる場合は、6.0 で導入された KeyInfoクラスを使うだけで鍵がセキュア ハードウェアに格納されているかどうかを検出できます。欠陥がある場合、この API も端末上で行う構成証明の検証結果も信頼できません。

なお、鍵の構成証明は SafetyNet 構成証明とは異なるものです。考え方は同じですが、これらは異なる場所で行われる異なるものに対する構成証明です。キーストアの鍵の構成証明は、暗号鍵がセキュア ハードウェアに格納されており、特別な特徴を持っていることを証明するものです。SafetyNet 構成証明は、端末が本物(エミュレータでない)で既知のソフトウェアが実行されていることを証明するものです。SafetyNet は、内部的にキーストアの鍵の構成証明を利用しています。端末の整合性について知りたい場合はこれを使うようにし、鍵がセキュア ハードウェアに格納されていることを確認したい場合は鍵の構成証明を使います。

詳細やサンプルコードについては、developer.android.com の鍵の構成証明のトレーニング記事をご覧ください。



  1. キーストアでは、RSA による暗号化には OAEP、署名には PSS パディング モードが推奨されます。また、古い PKCS#1 v1.5 モードもサポートされています。 

  2. キーストアは GCM、CBC、ECB の各ブロック チェーンモードをサポートしています。 
Reviewed by Yuichi Araki - Developer Relations Team

Apps Script を使ってイメージから Google スライドを生成する

$
0
0
この記事は G Suite デベロッパーアドボケート、Wesley Chun(@wescpy)による Google Developers Blog の記事 "Generating Google Slides from Images using Apps Script" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

本日(*原文公開当時)は、いくつかの Google スライドの新機能についてお知らせします。中でも重要なのが、Google Apps Script のサポートです。これにより、Apps Script for Slidesを使ってプログラムからスライドを作成、変更するだけでなく、ユーザー インターフェースのメニューやダイアログ ボックス、サイドバーのカスタマイズもできるようになります。

Apps Script でプレゼンテーションをプログラミングする


プレゼンテーションという行為自体には長い歴史があります。古代、洞窟で火と手を使って影絵を映すところから始まり、投影技術の発展(幻灯機)を経て、 35mm スライドショーへと大きく発展しました。そして最近では、Google スライドのようなプレゼンテーション ソフトウェアの登場により、デベロッパーはプレゼンテーションを作成または更新するアプリケーションを記述できるようになりました。Apps Script が新しく Google スライドをサポートしたことによって、その作業ははるかに簡単になります。最新の G Suite Dev Show エピソードでは、イメージのコレクションからスライドショーを自動的に作成するという簡単な例を使って、この新しいサービスのデモを紹介しています。





今回は簡潔に説明するため、イメージは選択済みで既にオンライン上に存在し、URL でアクセスできるものとします。イメージごとに、新しい(ブランクの)スライドを追加してそこにイメージを挿入します。このスクリプトで鍵となるのは、2 行の JavaScript です(既存の presentation と、各イメージへの link が渡されています)。
      var slide = presentation.appendSlide(SlidesApp.PredefinedLayout.BLANK);
var image = slide.insertImage(link);

1 行目のコードで新しいスライドを追加し、2 行目でそのスライドにイメージを挿入します。この 2 行をイメージのコレクションに対して繰り返します。この基本的なソリューションはきちんと動作しますが、作成されるプレゼンテーションのスライドは十分なものとは言えません。アプリケーションを もっと便利にするには、さらに数行を追加する必要があります。詳細については動画をご覧ください。

スタートガイド


開始方法については、ドキュメントを確認して Apps Scripts for Slides の詳細を学習するか、サンプルの翻訳アドオンやプログレスバーアドオンをご覧ください。動画のコードサンプルについてもっと詳しく知りたい方は、関連チュートリアルをご覧ください。また、動画のほうがいいという方は、Apps Script 動画ライブラリや、その他の G Suite Dev Show エピソードをご覧ください。自身の開発ツールを使って Apps Script 以外の環境から Google スライド アプリケーションを作成したい場合は、Slides(REST)API を使うことができます。詳しくは、ドキュメント動画ライブラリをご覧ください。

これらのオプションと Google スライドを使って開発者の皆さんが作るアプリケーションを楽しみにしています。



Reviewed by Takuo Suzuki - Developer Relations Team

第 2 回 Google Cloud INSIDE Games & Apps 開催のお知らせ

$
0
0


Google Cloud では、ゲーム・アプリ業界で活躍するインフラエンジニア、サーバーアプリケーションエンジニア、テクニカルリーダーの皆さまを対象に、11 月 22 日(水)18 : 30 より「第 2 回 Google Cloud INSIDE Games & Apps 」を開催します。

第 1 部 セッションパートでは、“データアナリティクス” をテーマに、より実践的なデータ分析基盤を構築する技術を、事例を通してゲストスピーカーの方々にご紹介いただきます。また Google 社員から、データ分析に関連するプロダクトを解説します。

第 2 部は、Google 社員や同じ業界で働く参加者と交流を深めていただく懇親会を予定しています。ぜひ、ご参加ください。

《 開催概要 》

  • 名 称:第 2 回 Google Cloud INSIDE Games & Apps
  • 会 期: 2017 年 11 月 22 日(水)18 : 30 - 22 : 00 
  • 会 場:グーグル本社
       〒106‐­6108 東京都港区六本木6-11-10 六本木ヒルズ森タワー
  • スピーカー
    • 株式会社プレイド エンジニア 牧野 祐己 氏
    • 株式会社リクルートライフスタイル データエンジニア 南谷 和毅 氏
    • Google Cloud カスタマーエンジニア 
  • プログラム: 無料(事前登録制)
    • 18 : 30 受付開始
    • 19 : 05 - 19 : 40 セッション1 
    • 19 : 40 - 20 : 15 セッション2
    • 20 : 15 - 20 : 50 セッション3
    • 休憩
    • 21 : 15 - 22 : 00 懇親会
  • 主 催: グーグル・クラウド・ジャパン合同会社
  • 定員:200 名

《 お申し込み 》
https://goo.gl/GEdxMi
こちらのリンクからお申し込みください。
※ お申込み締め切り: 2017 年 11 月 13 日 ( 月 ) 15 : 00まで
競合他社様からのお申し込みはお断りさせていただくことがございます
※ ビジネス向けのイベントとなっております。学生の方のご参加はご遠慮ください。
※ お申し込み多数の場合は抽選を行います。参加いただける方には、後日、ご登録されたメールアドレスに参加のご案内をお送りします。


Posted by Takuo Suzuki - Developer Relations Team

Cloud Functions シェルを使ってローカルで Functions をテストする

$
0
0
この記事は デベロッパー アドボケート、Doug Stevenson による The Firebase Blog の記事 "Testing Functions Locally with the Cloud Functions Shell" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

Cloud Functions for Firebaseをお使いの方なら、おそらく Functions を使った開発をスピードアップさせるにはどうしたらよいかと悩んだことがあるでしょう。HTTPS タイプの関数であれば、Firebase CLI の firebase serve を使ってそれを実現できますが、その他のタイプの関数ではこの方法は使えませんでした。しかし、Firebase CLI を使って簡単にローカルで Functions をテストできる方法が登場しました。Cloud Functions にデプロイする前にコードを動かしてみたい場合は、バージョン 3.11.0 以降の Firebase CLI に搭載されている Cloud Functions シェルを使うことができます。

その仕組みを簡単に説明しましょう。ここでは、例として Realtime Database トリガーを取り上げます。

既存のプロジェクトに makeUppercase という 1 つの関数があるとします。これはまだデプロイされておらず、index.js で次のように定義されています。
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original').onCreate(event => {
const original = event.data.val()
console.log('Uppercasing', event.params.pushId, original)
const uppercase = original.toUpperCase()
return event.data.ref.parent.child('uppercase').set(uppercase)
})

この onCreate データベース トリガーは、original という子要素を持つ新しいメッセージが /messages の下にプッシュされた場合に実行され、uppercase という新しい子要素に、大文字化したオリジナルのメッセージの値を書き込みます。

では、Firebase CLI を使ってコマンドラインからエミュレータ シェルを起動してみましょう。
$ cd your_project_dir
$ firebase experimental:functions:shell

すると、次のように表示されます。
i  functions: Preparing to emulate functions.
✔ functions: makeUppercase
firebase>

firebase というプロンプトが表示され、makeUppercase 関数を起動するコマンドが発行されるのを待つ状態になります。データベース トリガーのテストについて記載されたドキュメントによると、次の構文を使うと、入力データを伴うイベントを記述して関数を実行できます。
makeUppercase('foo')

これによって、文字列値 "foo" が設定された、original という子要素を持つ新しいメッセージ オブジェクトが /messages の下にプッシュされた際に生成されるイベントのトリガーがエミュレートされます。シェルでこのコマンドを実行すると、コンソールには次のように出力されます。
info: User function triggered, starting execution
info: Uppercasing pushId1 foo
info: Execution took 892 ms, user function completed successfully

関数内のコンソール ログが出力され、データベース パス内にあるワイルドカードである pushId には、pushId1 という値が 自動的に割り当てられていることがわかります。とても便利ですね!さらに、必要に応じて、ワイルドカードの値を自分で指定することもできます。
makeUppercase('foo', {params: {pushId: 'custom_push_id'}})

関数をエミュレーションした後でデータベースの内部を見てみると、表示された関数の結果を確認できます。/messages/{pushId}/uppercase には、大文字化された文字列値 "FOO" が設定されています。

この方法を使うと、すべてのデータベース イベント(onCreate、onDelete、onUpdate、onWrite)をシミュレートすることができます。各イベントを正しく起動する方法については、ドキュメントをご覧ください。

データベース トリガーだけでなく、HTTPS 関数PubSub 関数Analytics 関数Storage 関数Auth 関数のエミュレーションも実行でき、それぞれ独自の構文が存在します。

Cloud Functions シェルは、現在試験運用版として提供されているため、不十分な点もあるかもしれません。問題を発見した場合は、バグレポートを送信してお知らせください。Firebase Slackの #functions チャンネルで他の Cloud Functions ユーザーと話すこともできます。

シェルを活用するにあたってのヒント


毎回関数を起動するコマンドを打ち込むのは苦痛です。そのため、シェルのコマンドラインの履歴を表示するのと同じように、矢印キーで起動履歴を表示して再利用しましょう。

また、このシェルは、任意の JavaScript コードを実行したり、特殊な REPL コマンドやキーを利用したりできる完全な node REPLであることも覚えておきましょう。これは、テストコードのスクリプトを記述する際に役立つかもしれません。

任意のコードを実行できるので、おなじみの require() 関数を使ってコードを別のファイルから動的に読み込んで実行することもできます。

最後に、私のように VS Codeなどのプログラマー用エディタで JavaScript を書いている方は、Firebase CLI に実行したいコードを送信して簡単に関数をエミュレートすることができます。次のコマンドは、標準入力を通してリダイレクトされるファイルからテストコードを実行します。
$ firebase experimental:functions:shell < tests.js

ぜひ活用してみてください。


Reviewed by Khanh LeViet - Developer Relations Team

第 2 回 INEVITABLE ja night を開催します

$
0
0



Google Cloud に代表されるクラウド技術の進化の先にある世界を、機械学習、VR / AR、IoT などの領域で活躍されているスタートアップの方々と一緒に議論するイベント「INEVITABLE ja night」。第 2 回目は「AI とビジネスに起こる不可避な流れ」をテーマに、機械学習 / 人工知能技術にフォーカスをあて、実際にこれらの技術を活用して新たなビジネスを展開している方々をお招きし、ご講演いただきます。

【開催概要】
イベント名 : INEVITABLE ja night ― “インターネットの次にくるもの”
                       第 2 回 AI とビジネスに起こる不可避な流れ
日程 : 2017 年 11 月 14 日 (火) 19 : 00 - 22 : 00(開場 18:30 より)
会場 : グーグル合同会社
定員 : 200 名
参加登録 : 事前登録制(10 月 31 日まで)
ハッシュタグ : #inevitable2017

プログラム:

■ゲームチェンジャーか、バズワードか。AI、機械学習のビジネスインパクトを探る
クラウド、ソーシャル、スマホの普及で一気に実用段階への進みつつある機械学習、AI 関連のテクノロジー。果たして、この流れがビジネスに大きな変化をもたらすのかについて、ソーシャル、スマホ時代のビジネスのフロントラインを経験してきた株式会社 gumi の國光宏尚氏に起業家、投資家の観点からお話しいただきます。

スピーカー:國光 宏尚 氏 株式会社 gumi 代表取締役社長
聞き手:小島 英揮 氏(パラレルマーケター・エバンジェリスト)


 Retty における機械学習の活用事例
月間 3,000 万人のユーザーが利用する実名グルメサービスでは、早くから Deep Learning (深層学習)を使って、ユーザーが投稿する写真画像を分類してきました。ユーザーからの投稿をデータベースにしたさらなるサービス向上のため、エンジニアリングの現場で起こっている取り組みを CTO が語ります。機械学習を使ったエンジニアリング業務に興味がある方には必見です。

スピーカー:樽石 将人 氏 Retty 株式会社 CTO


■低コストでサービスに組み込む機械学習事例
機械学習を支援するアプリケーションや SaaS は増えてきているが、限られた人的・金銭的・時間的リソースの中で、機械学習を用いたサービスをプロダクトに追加するためにはどうしたらよいか。RoomClip を運営する Tunnel 株式会社の CTO が話します。事業の課題が機械学習そのものにはないものの、どうしても「触っておかなければならない」状況に置かれている方、必見です。

スピーカー:平山 知宏 氏 Tunnel 株式会社 開発担当執行役員


■ Google テクノロジーアップデート - Tensorflow -

スピーカー:大薮 勇輝 グーグル・クラウド・ジャパン合同会社 Google Cloud・マシンラーニングスペシャリスト


講演後は講師や参加者の皆さんとの交流や情報交換をお楽しみください。
プログラムの詳細および参加希望の方は、イベントサイトをご覧ください。

参加登録は10月31日(火)までです。皆様のご参加をお待ちしております。

Posted by Takuo Suzuki - Developer Relations Team

Google アシスタント対応アプリを日本語で開発してみよう

$
0
0
Google アシスタント搭載のスマートスピーカー「Google Home」 と「 Google Home Mini」 の日本発売開始に合わせて、Google アシスタント対応アプリの開発環境も日本語でのアプリ開発に対応しました。そして、本日より、すべてのユーザーが日本語のアシスタントに対応したアプリを利用できるようになりました。


アシスタント対応アプリと Actions on Google


Actions on Googleは、サードパーティ デベロッパー向けの開かれたプラットフォームです。このプラットフォーム上で Google アシスタントに対応したアプリの開発が可能になります。これらのアプリは、Google アシスタント を通じて、Google Home や Android、また iOSなど多くの環境でのサービス提供を実現します。

Actions on Google はこれまで英語環境(en_US, en_GB, en_AU)でのみ動作していましたが、日本語環境での利用も本日より対応を開始しました。[1]

日本語で利用できるようになったアシスタント対応アプリを是非お試しください(五十音順)。
  • Ameba
  • SUUMO
  • 絶対音感オーケストラ
  • 食べログ
  • トクバイ
  • なみある?
  • 日本史語呂合わせ
  • ベストティーチャー
  • ホットペッパーグルメ
  • Yahoo! MAP
  • 楽天レシピ 


アシスタント対応アプリの動作


アシスタントに対応したアプリは次のような流れで動作します(次の図はアシスタント対応アプリを Dialogflow をメインにして実装し、フォールバックを用意している場合)。



Google アシスタントで「OK Google, (アプリ名)と話す」と呼びかけたり入力すると、Actions on Google によって外部のアプリが起動します。起動後は、Google アシスタントがユーザーの入力情報を Google アシスタント対応アプリのエンドポイントに HTTP リクエストとして送ります(音声入力の場合は、Google アシスタントが音声認識したあとのテキストを送ります)。

Google アシスタントからのリクエストは JSON 形式で送られてくるので、受け取った入力情報を適宜サーバー側で処理し、JSON 形式でレスポンスを返すことで、ユーザーに情報を返すことができます。

アシスタント対応アプリの実装


この処理を見ると自前で JSON データの解析を行ったり、抽出したユーザーの入力情報を形態素解析して、それに応じた条件分岐を書く必要があることがわかります。それらを自前で実装するのはなかなかに大変な作業です。そこでその作業を軽減するために、いくつかのツールを用意しました[2]

  • Dialogflow(旧 api.ai)を利用する
  • Actions SDK を利用する

Dialogflow を利用すると自分でサーバーを用意することなく、アシスタント対応のアプリを作成できます。開発者はユーザの入力とそれに対応する応答のパターンを GUI 上で登録していくことで、簡単な会話型のアプリを作ることができます。またパターンに漏れたものや Dialogflow 上だけでは処理できない情報も、その後ろにフォールバック サーバーを設けることで対応できます。会話型エージェントシステムを作成する際に肝となる形態素解析の大部分を Dialogflow に任せることで、アプリの開発をより速く進めることが可能となります。

Actions SDK は Google アシスタントとの直接連携や Dialogflow のフォールバックを作成する際に必要な HTTP での JSON のやり取りを用意にするためのクライアント ライブラリです。現状では node.js 版が提供されています。定型句だけの対応であれば 直接 Actions SDK で連携して構いません。Dialogflow を利用する場合にも認証などが必要なときは Dialogflow のフォールバック先に Actions SDK を利用することで実装が容易になります。多くのサンプルも用意していますので、自分のユースケースにあったものを参考にしてください。

実装の詳細は Actions on Google の開発者向けドキュメントを参照してください。

アシスタント対応アプリの登録


アシスタントに対応したアプリの実装ができたら Actions on Google 開発者コンソールから登録してください。アプリ名、説明やアイコンなどのメタデータの登録が終わったら、シミュレーターや実機でテストができるようになります。詳細な手順は Registering and Publishing Your Appのドキュメントでご確認ください。

開発アカウントでログインしている Google アシスタントであれば、テスト起動している間はシミュレーターだけでなく、実機でもアプリを起動できます。シミュレーターでは気が付かなかったようなユーザビリティ向上のためのヒントが見つかりますので、公開前には実機テストを行うことを強くおすすめします。

アプリの公開の準備が整ったら、開発者コンソール上にある「SUBMIT DRAFT FOR REVIEW」ボタンを押し提出してください。レビューが終わり、Versions の項目にある Status が「Published」となれば晴れて公開です。



一般公開されたアシスタント対応のアプリは Assistant directoryから検索することができます。英語版ではすでにたくさんのアプリが公開されています。みなさんのアプリのヒントになるものもあるかと思います。

アプリを開発する中で不明点などありましたら、こちらのフォームにて日本語での問い合わせください。同フォームの説明は英語ですが、日本語で入力いただけます。








[1]ドイツ語(de-DE)、 フランス語(fr-FR)、日本語(ja-JP)、韓国語(kr-KR)、カナダでの英語とフランス語(en-CA、fr-CA)が同時に対応となりました。
[2]テンプレートからの作成については、日本語対応していません。



Posted by 山口 能迪, Developer Advocate - Developer Relations

Android Excellence: 2017 年秋に新たに受賞したアプリとゲームの紹介

$
0
0
この記事は Google Play デベロッパー マーケティング、Kacey Fahey による Android Developers Blog の記事 "Android Excellence: congratulations to the new apps and games for Fall 2017" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

Android Excellence は、Google Play で特に品質の高いアプリやゲームを認定するものです。すばらしいデザイン、魅力的なユーザー エクスペリエンス、優れたパフォーマンスに主眼が置かれている以下のアプリゲームから、Google Play コンテンツの多様性がわかります。Money Loverで個人資産を管理したい、スリルあふれるレースゲーム アスファルト 8で迫力のグラフィックとリアルタイムの挑戦を経験したいなど、どんな方でも楽しめるものがあります。

新たに受賞したのは、簡単なアプリで食品リストを管理できる Bring!です。既存の品目カタログを使うか、独自に商品の写真を撮影してリストを共有し、買い物に行くタイミングをアプリ内で通知しましょう。ゲームをお探しなら、「とても奇妙で謎が満載されたインディー アドベンチャー ゲーム」の Karma.Incarnation 1.がおすすめです。美しい手描きアートの世界で主人公を操作し、愛する人と再会するためにユーモアと困難にあふれた時間を過ごすことができます。

2017 年秋に新しく Android Excellence に選ばれたアプリやゲームのデベロッパーの皆さん、おめでとうございます。

新しい Android Excellence アプリ新しい Android Excellence ゲーム
Agodaアスファルト 8
アラームモンバブルウィッチ 3
Bring!Castle Creeps
CastBoxかに戦争
Email by Edisonクラッシュオブカーズ
EveDan the Man
FotorDawn of Titans
MintDream Defense
Money Lover鉄の海兵隊
OnefootballKarma. Incarnation 1.
RobinhoodPostknight
VikiSky Force Reloaded
Zombie Age 3

すばらしいアプリやゲームは、他にも Google Play のエディターのおすすめセクションに掲載されています。
このブログ投稿はどのくらい役に立ちましたか?



Reviewed by Hak Matsuda - Developer Relations Team

Realtime Database デベロッパーのための Cloud Firestore

$
0
0
この記事は デベロッパー アドボケート、Todd Kerpelman による The Firebase Blog の記事 "Cloud Firestore for Realtime Database Developers" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

皆さんはもうこのビッグニュースを聞きましたか?なんと先日、Cloud Firestore のベータ版がリリースされました。これは、アプリのデータを簡単にクラウドに保存して同期できる新しいデータベースで、リアルタイムにも対応しています!

ここで、既視感のようなものを感じる方もいらっしゃるかもしれません。皆さんが既に使っているかもしれない別の製品、Firebase Realtime Databaseにとてもよく似た響きですね。ですから、既視感を感じるのも自然です。

では、なぜ別のデータベースができたのでしょうか。そして、どんなときにどちらを選べばよいのでしょうか。ここでは、Cloud Firestore の新機能と特徴、そして皆さんが次のアプリでこれを使ってみたくなる理由について説明します。

Cloud Firestore の特徴


ドキュメントには、Realtime Database と Cloud Firestore の相違点がすべて詳しく記載されていますが、ここでは、この 2 つの製品の主な相違点について見てみましょう。まず、1 点目です。

データがより構造化されており、クエリが得意


Firebase Realtime Database は基本的に巨大な JSON ツリーで、いわば何でもありの無法地帯でしたが1、一方の Cloud Firestore はデータがより構造化されています。Cloud Firestore はドキュメントモデルのデータベースなので、すべてのデータはキーと値のペアの集まりでできた ドキュメントと呼ばれるオブジェクトに格納されます。値には、文字列、浮動小数点数、バイナリデータ、JSON のように見える マップと呼ばれるオブジェクトなどをいくつでも格納できます。こういったドキュメントは、グループごとに コレクションと呼ばれるオブジェクトなどをいくつでも格納できます。
Cloud Firestore データベースの中にいくつかのコレクションがあり、その中にサブコレクションを持つドキュメントが含まれるという構造にすることもできます。こういったサブコレクションには、別のサブコレクションを持つドキュメントなどを含めることができます。


この新しい構造によって、データに対してクエリを実行する際に重要になるいくつかのメリットが得られます。

まず、すべてのクエリは 浅くなります。つまり、ドキュメント配下のサブコレクションに紐付くデータをすべて取得せずに、そのドキュメントだけを取得することができます。これによって、不必要なデータを大量にダウンロードすることを心配せずに、論理的に妥当な形でデータ階層を格納することができるようになります。
この例では、サブコレクションに属するドキュメントを取得せずに、上のドキュメントだけを取得できる

次に、Cloud Firestore には Realtime Database よりも強力なクエリ機能が搭載されています。Realtime Database では、複数の項目にまたがるクエリを作成するには多くの作業が必要で、通常はデータを非正規化しなければなりません。

たとえば、都市の一覧があり、カリフォルニア州にある人口 50 万人を超えるすべての都市を探したいとしましょう。


Realtime Database に格納された都市


Realtime Database では、「州(state)+人口(population)」という項目を作成し、その項目に対してクエリを実行しなければなりませんでした。

クエリのためだけに state_and_pop という組み合わせ項目を作成


Cloud Firestore では、その作業は不要になります。場合によっては、Cloud Firestore は自動的に複数の項目を検索してくれます。今回の都市の例はそれには該当しませんが、そのような場合でも、Cloud Firestore はクエリを実現するために必要になるインデックスの構築を自動的に提示してくれます。


それさえ済めば、あとは複数の項目を使って検索するだけです。

Cloud Firestore は、アプリが有効である間、このインデックスを自動的にメンテナンスしてくれます。もう項目を組み合わせる必要はなくなります。

大規模に対応したデザイン


Realtime Database は ほとんどのアプリのニーズを満たす規模に拡大できますが、アプリの人気が非常に高まったり、データセットが巨大になると、問題が起こり始めることもあります。

一方の Cloud Firestore は、絶大な人気を誇るいくつかのアプリを支えているのと同じ Google Cloud インフラストラクチャ上に構築されています。そのため、スケールアップがはるかに簡単で、容量も Realtime Database よりはるかに大きくなります。

また、クエリの構造が新しくなっているため、すべての Cloud Firestore クエリは、データのサイズではなく結果セットのサイズに対応します。つまり、レストランのレビューアプリでシカゴのトップ 10 レストランを検索する場合、データベース内にあるレストランが 300 店であっても、30 万店であっても、3000 万店であっても、かかる時間は同じです。あるエンジニアは、「Cloud Firestore で遅いクエリを作るのは基本的に不可能だ」と述べています。

ベータ版期間が始まる時点で、Cloud Firestore は既に Realtime Database を超える規模にスケールアップできるようになっています。ただし、実際の用途に近い使われ方をした際のデータベース性能を監視できるように、いくつかの制限も設けられています。しかし、ベータ版期間が終了し、一般提供版のリリースが近づく頃には、Cloud Firestore は途方もないレベル2にまで自動的に拡張できるようになりますので、ご期待ください。

データの手動取得が簡単


Realtime Database のリアルタイム性は、チャットなどの機能や魔法のような共同作業体験を提供する際にとても役立つというデベロッパーがいます。しかし一方で、「必要なときにデータを取得する」的な従来型の単純なサービスに Realtime Database を利用しているデベロッパーも多いことがわかっています。

Realtime Database で .onceを呼び出すとこのようなユースケースに対応できますが、これを使うのは少しばかり不自然であり、SDK でもこの機能はストリーミング メソッドの補助的な役割を提供するものになっています。Cloud Firestore では、単純な一度きりの取得クエリがより自然な形で書けるようになり、それが Firestore API のプライマリ ユースケースになっています。

もちろん、リスナーもサポートされているので、データベース内のデータが変更されたときにアップデートを受信する機能をクライアントに持たせることもできます。つまり、好きな方法でデータを取得できる柔軟性が追加されています。

信頼性を向上させるマルチリージョン サポート


Cloud Firestore は、マルチリージョン データベースです。つまり、データは地理的に独立した別々のリージョンに自動で即時コピーされます。そのため、予期せぬ災害が発生してデータセンターやリージョン全体がオフラインになったとしても、データは安全であることが保証されます。

また、データベース ファンの皆さん向けにお伝えすると、このマルチリージョン データベースは(Cloud Spanner のような)強い整合性を備えています。つまり、マルチリージョンをサポートしつつ、いつ読み取りを行っても最新版のデータを取得できるというメリットがあります。

異なる価格モデル


この 2 つのデータベースには、まったく異なる価格モデルが設定されています。Realtime Database の費用は、主にダウンロードされたデータの とデータベースに格納しているデータの量によって決まります。

Cloud Firestore もこれらの量に応じて課金されるものの、Realtime Database に比べて 非常に 低い額になっています3。その代わり、Cloud Firestore の料金は、主に読み取りと書き込みの 実行回数によって決まります。

つまり、クライアントがデータベースから大量のデータをたまにリクエストするだけの従来型のモバイルアプリの場合、同じアプリでも Realtime Database の価格モデルより Cloud Firestore の方が有利かもしれません。たとえば、ニュースアプリや出会い系アプリ、ターン制のマルチプレーヤー型ゲームなどがこれにあたるでしょう。

一方で、1 秒間に行うクライアント当たりの読み込み数や書き込み数が非常に多いアプリ(たとえば、全員の書き込みが 1 秒間に何度もブロードキャストされる可能性があるホワイトボード共有アプリ)では、おそらく Cloud Firestore の方が高価になるでしょう。4少なくとも、アプリのその部分については、ここに記載した説明が当てはまります。ただし、両方のデータベースを併用することができ、そうすることには何の問題もありません。

もちろん、ここに記したのは大まかなガイドラインです。Cloud Firestore の詳しい価格設定については、ドキュメントの価格セクションをご覧ください。

Realtime Database を使い続ける方がよい場合


以上のような変更点だけを聞くと、単純に Realtime Database よりも Cloud Firestore の方が優れているという印象を受けるかもしれません。実際、Cloud Firestore には Realtime Database を改善した点もかなり多く含まれていますが、Realtime Database を使うことを考慮した方がよいデータもあります。具体的には、次のような場合です。
  • レイテンシの面では、Realtime Database の方がわずかに優れているようです。通常は大きな差が出ることはありませんが(データベースからクライアントまでで数百ミリ秒程度)、即時性重視のアプリで、安定した低レイテンシでアップデートできるデータベースが必要な場合は、Realtime Database の方が適しているかもしれません。
  • Realtime Database は、 プレゼンスをネイティブ サポートしています。これは、ユーザーがオンラインになった場合やオフラインになった場合に通知してくれる機能です。Cloud Firestore で同じことを行うソリューションもありますが、あまり簡単とは言えない方法です。
  • 前述のように、Cloud Firestore の価格モデルでは、1 秒間に行われるクライアント当たりの読み取り数や書き込み数が非常に多く、それぞれが小さなものである場合、同じ操作を行う Realtime Database アプリよりも大幅に高価になる場合があります。
  • 現在、Cloud Firestore はベータ版の製品です。Realtime Database は 4 年にわたって何十万もの本番環境向けアプリで利用されている歴戦のデータベースです。Cloud Firestore は、ここ数か月間で数十個のアプリによって限定的に本番利用されています。こういったアプリの中には、HomeAwayHawkin Dynamicsのように実際に公開され、優れたパフォーマンスを発揮しているものもあります。しかし、Cloud Firestore にはまだ見つかっていない問題やエッジケースが存在する可能性もあります。

長すぎて読めないという皆さん、使い方を教えてください!


一般的には、 新しいアプリには Cloud Firestore を使ってみることをおすすめしています。ただし、Realtime Database を使う方が望ましい前述のような特別なニーズがある場合は除きます。

一方で、Realtime Database で問題なく動作している 既存のデータベースがある場合は、それを使い続ける方がよいでしょう。Cloud Firestore がとても役立ったという問題を見つけた方は、データベースの切り替えを行うか、データの一部を Cloud Firestore に移行して両方のデータベースを併用してください。しかし、切り替えのための切り替えは行うべきではありません。

なお、「データベースを Realtime Database から Cloud Firestore に変換する」魔法のボタンは探しても見つかりませんので、あしからず5。率直なところ、今後もそのような機能が実現されるかはわかりません。この 2 つのデータベースやクエリ、価格構造の違いを考えると、Realtime Database に最適化されているデータベースを単純に Cloud Firestore に変換しても、必ずしも優れたエクスペリエンスは提供できないでしょう。この種の変更を行う場合は、ぜひじっくりと考えるようにしてください。

試してみたい方へ


Cloud Firestore を試してみたいという方向けに、さまざまなものが準備されています。ドキュメントGoogleサンプルアプリインタラクティブ コードラボスタートガイド動画などをご覧ください。

皆さんが Cloud Firestore を使ってできることはたくさんあるはずです。皆さんがこれを使って作るアプリを楽しみにしています。いつものように、質問がある方はいずれかのサポート チャンネルを通してご連絡ください。または、google-cloud-firestoreおよび firebaseタグをつけて Stack Overflow に投稿してください。ぜひお楽しみください。グッドラック!



  1. もちろん、セキュリティ ルールには従います 

  2. これは公式なデータベース用語ではありません。今のところは... 

  3. データ ストレージは 27 分の 1 ほどの価格です 

  4. 余談ですが、個人的には新しい価格構造の方がはるかに費用の見積もりがしやすいので、すばらしいと感じています。 

  5. ただし、とても便利な移行ガイドが提供されています。 


Reviewed by Khanh LeViet - Developer Relations Team

AMP の新機能: ポジション オブザーバ、fluid 広告、動画アナリティクスの改善など

$
0
0
この記事は AMP Project プロダクト マネージャー、Lisa Wang による Accelerated Mobile Pages Project の記事 "New in AMP: Position observers, fluid ads and improved analytics for video & beyond" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

今回の投稿は、定期的な AMP ロードマップのアップデートに代わる、新たな試みです。この新しい「AMP の新機能」フォーマットでは、すぐに試すことができるアップデートを重点的に紹介します。進捗を反映するため、AMP ロードマップのアップデートも引き続きお伝えします。直近の目標を取り上げているこの投稿でも、そのためのセクションを設けています。まずは、以下のアップデートについてお伝えします。

スクロールと連動した柔軟なアニメーションを実現する <amp-position-observer>


scrollable

amp-position-observerを使うと、AMP でスクロールと連動する柔軟かつ高パフォーマンスなアニメーションを実現できます。このコンポーネントは、さまざまな機能に利用できます。たとえば、視差効果を出したり、イメージをわずかにズームやフェードさせたり、ビューポートを通過する際にアニメーションを開始または停止したりできます。詳しくは、ドキュメントをご覧ください。また、サンプルやテンプレートも紹介する予定です。

レスポンシブ デザインを強化する <amp-sidebar>


sidebar


簡単に使えるレスポンシブ レイアウトsrcsetなどの機能を搭載した AMP は、レスポンシブにデザインされています。改善された amp-sidebarがリリースされ、ビューポートの幅に応じて表示フォーマットを変えられるようになったため、レスポンシブなページがさらに作りやすくなっています。たとえば、モバイルでは表示と非表示を切り替えられるサイドバーを、PC では固定位置のヘッダーを表示できるようになります。

AMP でのネイティブ動画アナリティクス


video_snippet


AMP で動画アナリティクスがネイティブ サポートされました。それとともに、amp-analytics 内で amp-video と併用してエンゲージメント データを収集できるいくつかの新しい動画トリガーと動画変数もリリースされています。詳しくは、ドキュメントをご覧ください。

現在のところ、サポートは amp-video コンポーネントに限られていますが、動画プレーヤー ベンダーの皆さんは、動画インターフェースを使ってそれぞれの動画プレーヤー実装のサポートを AMP に組み込むことができます。この方法に興味がある動画プレーヤー ベンダーの方は、GitHub からご連絡ください

クライアント ID の改善により、AMP と非 AMP 間の移動を把握


最近 AMP ビューアーに、より直接的にクライアント ID を管理できる機能を追加しました。これにより、デベロッパーがページに含めたベンダー識別子や API キーを AMP ビューアーが受け取れるようになるため、AMP ビューアーでクライアント ID 情報のリクエスト元を識別できるようになります。

この改善された機能を使えば、たとえば AMP ページと非 AMP ページ間で一貫性のある ID を提供したりできるようになります。最近 Google は、この変更点を活用して AMP トラフィックを詳しく理解できるようにする Google アナリティクス プロダクトのアップデートについてお知らせしました。AMP ページで Google アナリティクスを利用している方は、ぜひご確認ください。

サイトオーナーがサイズを指定せずに広告をリクエストできる fluid 広告


fluid_ad


AMP コンテンツにリフロー ポリシーを設定した場合、リクエスト時にサイズがわからない広告をリクエストできないという声がサイトオーナーから寄せられています。この問題を解決するため、fluid 広告のサポートをリリースしました。この機能は現在、オープン アルファ版テストとして利用できます。

その他の主な新機能: トラッキングの拡張、<amp-ima-video>、データ鮮度の改善


今後のロードマップ

前回のアップデートでお知らせしたいくつかの機能は、第 4 四半期にリリースしたいと考えています。これには、以下の機能が含まれています。 

今後のアナリティクスについて、現在集中的に取り組んでいる分野は以下の通りです。
  • エラー ロギング: エラーのログを有効にするトリガーを追加する予定です。これにより、ユーザーが AMP ページとのインタラクションを行う際に発生する問題を把握しやすくなります。 
  • 一括アナリティクス: 状況によっては、多数のアナリティクス ping を収集して一括で送信できる方が便利な場合があります。この機能では、AMP に一括アナリティクスのサポートを追加します。
最後になりますが、多くのサイトオーナーは、広告リクエストを作成する前に、対象などを表す Cookie レベルの情報で広告リクエストを拡張する必要があります。これを、RTC(Real Time Config)と呼ぶ方法で簡単に行えるようにします。RTC を利用すると、サイトオーナーは、プライマリ広告サーバーに対してリクエストを行う前に最大 5 つのエンドポイントを定義して広告リクエストを拡張できるようになります。実装案は GitHub に掲載していますので、フィードバックをお待ちしています。

*  *  *

作業したりフィードバックを寄せてくださっている AMP 開発コミュニティの方々に感謝いたします。いつものように、問題や機能リクエストがありましたら遠慮なく GitHubからお知らせください


Reviewed by Yoshifumi Yamaguchi - Developer Relations Team

複数の JobService を活用する

$
0
0
この記事は Android DA ソフトウェア エンジニア、Isai Damier による Android Developers Blog の記事 "Working with Multiple JobServices" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

複数の JobService を活用する


ユーザー エクスペリエンスを改善する努力が続けられる中、API レベル 26 で Android プラットフォームにバックグラウンド サービスに対する厳しい制限が導入されました。基本的に、アプリがフォアグラウンドで実行されている場合を除き、アプリのバックグラウンド サービスはシステムによって数分以内に停止されます。

このバックグラウンド サービスの制限の結果、JobSchedulerのジョブがバックグラウンド タスクを実行する際のデファクト ソリューションになっています。サービスに詳しい方は、JobSchedulerを簡単に使うことができます。ただし、そこにはいくつかの例外的なケースもあります。ここではその 1 つをご紹介します。

Android TV アプリを作っているところをイメージしてください。TV アプリではチャンネルが非常に重要です。アプリは、チャンネルに対して少なくとも 5 種類のバックグラウンド操作を行える必要があります。それは、チャンネルのパブリッシュ、チャンネルへのプログラムの追加、チャンネル ログのリモート サーバーへの送信、チャンネルのメタデータのアップデート、そしてチャンネルの削除です。Android 8.0(Oreo)より前では、この 5 つの操作をバックグラウンド サービスとして実装できました。しかし、API 26 以降では、どれを旧来のバックグラウンド Serviceにするか、どれを JobServiceにするかをよく考えた上で決めなければなりません。

TV アプリのケースでは、前述の 5 つの操作のうち、旧来のバックグラウンド サービスとして実装できるのはチャンネルのパブリッシュのみです。状況にもよりますが、チャンネルのパブリッシュには 3 つの手順が必要となります。まず、ユーザーが処理を開始するボタンを押します。次に、アプリがバックグラウンド操作を開始してパブリッシュを行います。そして最後に、サブスクリプションを確認する UI がユーザーに提示されます。おわかりのように、チャンネルのパブリッシュにはユーザーのインタラクション、つまり目に見える Activity が必要です。そのため、ChannelPublisherService はバックグラウンド部分を扱う IntentServiceにすることもできるかもしれません。ここで JobServiceを使うべきでない理由は、JobServiceを使うと実行時に遅延が生じる点にあります。通常、ユーザーのインタラクションにはアプリからの即時的なレスポンスが必要です。

一方、その他の 4 つの操作には JobServiceを使うべきです。この 4 つはすべて、アプリがバックグラウンド状態にあるときに実行されるからです。そのため、この 4 つの操作には、それぞれ ChannelProgramsJobServiceChannelLoggerJobServiceChannelMetadataJobServiceChannelDeletionJobServiceを使うべきです。

jobId の衝突を防止する


上記の 4 つの JobServiceChannelオブジェクトを扱うため、それぞれの channelIdjobIdとして使えると便利です。しかし、Android Framework 内での JobServiceの設計手法の関係で、そうすることはできなくなっています。次に示すのは、jobId についての公式説明です。

Application-provided id for this job. Subsequent calls to cancel, 
or jobs created with the same jobId, will update the pre-existing
job with the same id. This ID must be unique across all clients
of the same uid (not just the same package). You will want to
make sure this is a stable id across app updates, so probably not
based on a resource ID.

この説明に書かれているのは、たとえ 4 つの異なる Java オブジェクト(-JobService)を使っていたとしても、jobIdに同じ channelIdを使うことはできないということです。つまり、クラスレベルの名前空間を使うことはできません。

これは確かに大きな問題です。channelIdを一連の jobIdに関連付ける安定的で拡張可能な方法が必要になります。一番やってはいけないのは、jobIdの衝突により、関係ないチャンネルの操作を互いに上書きしてしまうことです。jobIdが Integer 型ではなく String 型であれば、この問題は簡単に解決できます。その場合、ChannelProgramsJobService jobId= "ChannelPrograms" + channelIdを使い、ChannelLoggerJobServicejobId= "ChannelLogs" + channelIdを使うなどの方法が考えられます。しかし、jobIdは String 型ではなく Integer 型なので、ジョブに対して再利用可能な jobIdを生成する適切な仕組みを考える必要があります。これには、次に示す JobIdManagerのような仕組みを利用できます。

JobIdManagerクラスは、アプリのニーズに応じて微調整することができます。今回の TV アプリにおける基本的な考え方は、Channelを扱うすべてのジョブに対して単一の channelIdを使うというものです。理解を早めるため、まずはこのサンプル JobIdManagerクラスのコードを見てみましょう。その後、説明を行います。
public class JobIdManager {

public static final int JOB_TYPE_CHANNEL_PROGRAMS = 1;
public static final int JOB_TYPE_CHANNEL_METADATA = 2;
public static final int JOB_TYPE_CHANNEL_DELETION = 3;
public static final int JOB_TYPE_CHANNEL_LOGGER = 4;

public static final int JOB_TYPE_USER_PREFS = 11;
public static final int JOB_TYPE_USER_BEHAVIOR = 21;

@IntDef(value = {
JOB_TYPE_CHANNEL_PROGRAMS,
JOB_TYPE_CHANNEL_METADATA,
JOB_TYPE_CHANNEL_DELETION,
JOB_TYPE_CHANNEL_LOGGER,
JOB_TYPE_USER_PREFS,
JOB_TYPE_USER_BEHAVIOR
})
@Retention(RetentionPolicy.SOURCE)
public @interface JobType {
}

//16-1 for short. Adjust per your needs
private static final int JOB_TYPE_SHIFTS = 15;

public static int getJobId(@JobType int jobType, int objectId) {
if ( 0 < objectId && objectId < (1<< JOB_TYPE_SHIFTS) ) {
return (jobType << JOB_TYPE_SHIFTS) + objectId;
} else {
String err = String.format("objectId %s must be between %s and %s",
objectId,0,(1<<JOB_TYPE_SHIFTS));
throw new IllegalArgumentException(err);
}
}
}

おわかりのように、JobIdManagerは単に接頭辞と channelIdを組み合わせて jobIdを作成しているだけです。しかし、このエレガントなシンプルさは、氷山の一角でしかありません。前提条件と以下のポイントについて考えてみましょう。

1 つ目のポイント: channelIdと接頭辞を組み合わせても有効な Java の Integer 型の範囲内に収まるようにするために、channelIdを Short 型に強制する必要があります。もちろん、厳密に言うなら、必ずしも Short 型である必要はありません。接頭辞と channelIdを組み合わせてオーバーフローしない Integer 型を得られさえすればよいのです。しかし、健全なエンジニアリングにはマージンが欠かせません。そのため、どうしても他に選択肢がない場合以外は、Short 型を強制するとよいでしょう。実際に、リモート サーバー上に大きな ID を持つオブジェクトに対してこれを行うには、ローカル データベースやコンテンツ プロバイダでキーを定義し、そのキーを使って jobIdを生成します。

2 つ目のポイント: アプリ全体で 1 つの JobIdManagerクラスを使う必要があります。そのクラスで、アプリのすべてのジョブの jobIdを生成します。ジョブが Channelを扱うのか Userを扱うのか、それとも CatDogを扱うのかは関係ありません。サンプルの JobIdManagerクラスは、この点に対処しています。すべての JOB_TYPEChannel操作が関係しているわけではありません。ジョブタイプの 1 つはユーザー プリファレンスを扱っており、別の 1 つはユーザーの動作を扱っています。JobIdManagerは、ジョブタイプごとに別の接頭辞を割り当てることによって、それらすべてに対応しています。

3 つ目のポイント: アプリ内の各 -JobServiceについて、一意かつ final な JOB_TYPE_接頭辞が必要です。ここでも、網羅的な 1 対 1 の関係が存在する必要があります。

JobIdManager の使用


次に示す ChannelProgramsJobServiceのコード スニペットは、プロジェクトで JobIdManagerを使用する方法の一例です。新しいジョブをスケジュールする必要がある場合は、常に jobIdを生成する必要があります。その際に、JobIdManager.getJobId(...)を使用します。
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
import android.os.PersistableBundle;

public class ChannelProgramsJobService extends JobService {

private static final String CHANNEL_ID = "channelId";
. . .

public static void schedulePeriodicJob(Context context,
final int channelId,
String channelName,
long intervalMillis,
long flexMillis)
{
JobInfo.Builder builder = scheduleJob(context, channelId);
builder.setPeriodic(intervalMillis, flexMillis);

JobScheduler scheduler =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
if (JobScheduler.RESULT_SUCCESS != scheduler.schedule(builder.build())) {
//todo what? log to server as analytics maybe?
Log.d(TAG, "could not schedule program updates for channel " + channelName);
}
}

private static JobInfo.Builder scheduleJob(Context context,final int channelId){
ComponentName componentName =
new ComponentName(context, ChannelProgramsJobService.class);
final int jobId = JobIdManager
.getJobId(JobIdManager.JOB_TYPE_CHANNEL_PROGRAMS, channelId);
PersistableBundle bundle = new PersistableBundle();
bundle.putInt(CHANNEL_ID, channelId);
JobInfo.Builder builder = new JobInfo.Builder(jobId, componentName);
builder.setPersisted(true);
builder.setExtras(bundle);
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
return builder;
}

...
}

脚注: 貴重なフィードバックを寄せてくれた Christopher Tate と Trevor Johns に感謝いたします


Reviewed by Yuichi Araki - Developer Relations Team

Playtime 2017: 新しくなった Play Console でビジネスを成長させ、Google Play で成功を収めましょう

$
0
0
この記事は Vineet Buch, Director of Product Management, Google Play Apps & Games による Android Developers Blog の記事 "Playtime 2017: Find success on Google Play and grow your business with new Play Console features" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

本日(*原文公開当時)、2017 年の Playtime シリーズがベルリンとサンフランシスコで開幕しました。2017 年は、Google Play にとってもデベロッパーの皆さまにとっても素晴らしい 1 年になっています。今月から来月にかけて世界各地を訪れ、デベロッパーの皆さまの声を伺いたいと思っています。2017 年は、全世界での 1 か月のインストール数が 80 億回を超えました。

Google では、この素晴らしい機会を引き続き皆様にご活用いただけるよう、Google Play の革新と Play Console の機能拡充に努めてまいります。また Mediumには、今回のプレゼンターたちが、戦略、おすすめの方法、事例などを投稿しています。ぜひフォローして、ビジネス目標の達成にお役立てください。Google では、急成長が続く Google Play についても皆さまにご理解いただきたいと考え、State of Play 2017(Play の現況 2017)というレポートを発行いたしました。このレポートを毎年更新し、Google Play がどう進化して、デベロッパーの皆様の成功をどのような形で支援しているかをお伝えしていく予定です。
スマートフォン、タブレット、Wear デバイス、テレビ、Daydream、Chromebooks、そして新しい Google Pixelbook。Google Play は、あらゆるタイプのデバイスに生命を吹き込みます。ユーザーがコンテンツをもっと簡単に見つけられるよう、Play ストアの素晴らしいコンテンツでユーザーを何度も魅了できるよう、たゆまぬ努力を続けています。

優れたアプリやゲームを紹介


Google Play では、質の高いアプリやゲームを厳選し、世界中のユーザーに紹介することに力を入れています。最近では、エディターのおすすめを刷新して対象を 17 か国に広げ、Android Excellence を開催して新しいアプリやゲームを世界中に紹介しました。インディー ゲームの紹介とサポートも継続的に行っており、サンフランシスコでインディー ゲーム フェスティバルの受賞作品を発表しました。また、欧州で開催する第 2 回インディー ゲーム コンテストの参加作品の募集も開始しました。

魅力的なゲームを見つける

ゲームの掲載情報ページを刷新し、予告編やゲームプレイのスクリーンショットを掲載できるようにしました。新たな閲覧先として、有料ゲームを集めた「プレミアム」と、公開予定や人気急上昇中のゲームを集めた「新作」の 2 つも追加する予定です。

インストールの先にあるもの

Play ストアでは、「ライブ オペレーション」のバナーやカードを活用し、ユーザーに主なゲーム内イベントを通知できる機能を展開しています。また、Android Instant Appsの Google ストアへの統合も進めています。ストアの掲載情報に [今すぐ試す] ボタンが表示された場合は、タップするだけでインストールなしでアプリを楽しめます。

新しいゲーム体験を
Google Play で
Google Play Console には、アプリのライフサイクルに応じて活用できる便利なツールが揃っています。アプリの品質の改善、正確なリリース管理、ビジネスの業績改善にお役立てください。

品質重視

I/O 2017 において Android Vitals を発表しましたが、すでに 65% のトップ デベロッパーが Android Vitals を利用してアプリのパフォーマンスを把握しています。このたび、新たに 5 つの Android Vitals を追加し、対象となる端末も増やしました。電池使用量、クラッシュ、表示時間などの問題の解決にお役立てください。なお、Google Play の検索や発見のアルゴリズムでは、パフォーマンスの優れたアプリが高く評価されます。

リリース前レポートを改善し、すべてのデベロッパーがオプトインなしで利用できるようにしました。Firebase Test Lab には、テスト用に幅広い端末が用意されています。アルファ版またはベータ版の APK をアップロードするだけで、アプリが自動的に物理的な端末にインストールされてテストが行われます。リリース前レポートでは、クラッシュ、表示の問題、セキュリティ上の脆弱性などに加え、パフォーマンスの問題も把握できるようになりました。

すべてのユーザーは、新しいアプリをインストールしたら問題なく動作することを期待しています。Google Play では、インストールしたアプリやゲームをユーザーが快適に利用できるよう、多くの端末で快適に動作しないアプリ(​クラッシュ、​終了、​​フリーズ​​​などの​​異常​​な動作が発生するアプリ)の公開を禁止するポリシーを導入することにしています。このポリシーによって Google Play の信頼性が向上し、デベロッパーの皆様にも恩恵をもたらすことができるものと確信しております。詳しくは、ポリシー センターをご覧ください。

自信を持ってリリース

ベータ版テストを実施すると、製品版に移行する前のアプリやゲームを、信頼できるユーザーに試してもらうことができます。さまざまなアイデアを繰り返し試し、ユーザーからフィードバックを受けることも可能です。アルファ版やベータ版のテストを、特定の国を対象に実施することも可能になりました。たとえば、ある国で製品版としてリリースしているアプリを、別の国で新たにベータ版としてテストすることもできます。近日中に、国を指定した段階的な公開も可能にする予定です。

端末カタログにも改良を加えました。トップ デベロッパーの 66% 以上が端末カタログを利用し、多種多様な端末に合わせて優れたユーザー エクスペリエンスを提供しています。このたび、端末カタログでの端末検索を保存できるようになったほか、アプリが特定の端末でサポートされない理由も確認できるようになりました。利用規約をご確認のうえ、端末カタログをぜひお試しください。

定期購入ビジネスを成長させる

I/O 2017 において、Play の定期購入数と定期購入ビジネスの収益が、どちらも前年比で 2 倍になったことを報告しましたが、このたび Play Billing Libraryを追加して、定期購入サービスをさらに簡単にセットアップし管理できるようにしました。また、新しいテスト方法を導入し、支払いプロセスが正常に完了するかどうかを簡単にテストできるようになりました。

定期購入者の獲得、維持に役立つ機能も追加しました。短期間の無料試用(最低 3 日)を提供できるようになったほか、不正使用を防ぐため、無料試用の回数をアプリレベルで 1 回に制限しました。現時点で、ユーザーが定期購入を解約したときに通知が届くように設定できますが、解約した定期購入を簡単に再開できるようにすることも検討しています。また、アカウントの一時停止機能を公開し、更新料の支払いの問題が解決するまでアクセスをブロックできるようになりました。さらに 2018 年 1 月からは、定期購入を 12 か月以上継続したユーザーの手数料を改定する予定です。


Google Play Security Reward Program を開始

Google では長きにわたって、セキュリティ研究コミュニティとの緊密な関係を築いてきました。そしてこのたび、Google Play Security Reward Programを開始し、人気の Android アプリ(Google 独自のアプリを含む)のセキュリティ研究を報奨金制にすることにしました。このプログラムを通じて見つかったセキュリティの脆弱性は、解決方法とともにデベロッパーに通知します。これまで Google が実施してきた他の報奨金プログラムと同様、デベロッパーやセキュリティ研究コミュニティの皆様のお力を借りながら、Google Play エコシステムのセキュリティ向上に積極的に取り組んでまいります。ご協力のほどよろしくお願いいたします。

Google Play の最新のニュースやヒントを手に入れよう


このブログ記事はお役に立ちましたか



Reviewed by Takuo Suzuki - Developer Relations Team

2017 年 10 月の Firebase Test Lab のアップデート

$
0
0
この記事はデベロッパー アドボケート、Doug Stevenson による The Firebase Blog の記事 "Firebase Test Lab October 2017 Update" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

10 月です。もうすぐハロウィンですね!多くの皆さんが恐ろしい仮装の準備をしていることでしょう。しかし、凝った仮装は考えていないという方は、Firebase Test Lab for Androidで利用できるいくつかの新機能を確認してみましょう。

Robo テストの改善


Test Lab の自動テストである Robo テストがレベルアップしており、アプリをクロールする際のカバレッジが以前の 2 倍になっています。つまり、多くの画面に到達して多くのアクションを行えるようになっており、アプリのクラッシュを発見する機能が進化しています。実際、クラッシュの発見率は約 62% 増加しています。Robo は、皆さんのユーザーを怖がらせる前に、このような恐ろしいバグを積極的に見つけてくれます。まだアプリに対して Robo テストを実行していない方は、Firebase Console の Test Lab に APK をアップロードすれば、無償でお試しいただけます。Robo テストは、Play Console のリリース前レポートからも行うことができます。

テストの高速化


gcloud コマンドラインで多くのテストを実行しており、まずテストが成功したか失敗したかだけを知りたいという方は、Test Lab が収集する追加情報の一部を無効化することによって、テストを高速化することができます。--no-record-videoフラグを渡すとアプリの動画取得を、--no-performance-metricsを渡すとゲームループ テストでのパフォーマンス データの収集を無効化できます。これらのオプションを使うと、長期にわたってテストに高速な有酸素運動をさせることができます。これは、ゾンビから逃げる際に欠かせません。

Android Test Orchestrator のサポート


最近、Android Testing Support Libraryには、Android アプリのテストに使えるいくつかの機能強化が行われています。このアップデートによって、Android テストケースを分離してより安定なテスト結果を得られる Android Test Orchestratorを活用できるようになりました。Test Lab がこの便利なユーティリティをサポートするようになったため、皆さんのテスト工程でこれの活用をご検討ください。

Test Lab チームや、コミュニティ内のアプリのテストを愛する人たちと話してみたいという方は、Firebase Slackの #test-lab チャンネルに参加してください。いたずらされることはありません。おやつがもらえるだけですよ。


Reviewed by Khanh LeViet - Developer Relations Team

Machine Learning Developer Meetup を開催します

$
0
0
Google では、2017 年11 月 29 日(水)に Machine Learning Developer Meetup を開催します。
Googleでは、Google Brain チームを率いるエンジニアを招き、機械学習や TensorFlow の最新情報のシェアや意見交換を行う場として、11 月 29 日 (水) 13:00 より、「Machine Learning Developer Meetup」 を開催します。

本イベントでは、Google のスピーカーに加えて、TensorFlow User Group などのデベロッパーコミュニティの紹介なども行います。

Machine Learning に興味のあるエンジニアの方はぜひご参加ください。

イベント概要

イベント名: Machine Learning Developer Meetup
日程: 2017 年 11 月 29 日(水) 13:00 - 14:45 (開場: 12:30)
場所:グーグル合同会社
定員 :200 名
タイムテーブル:

 12 : 30 受付開始
 13:00 - 13:10 開会のご挨拶
 13:10 - 13:40 AI at Google
 13:40 - 14:10 TFUG Community session
 14:10 - 14:40 Fireside Chat (Q&A)
 14:40 - 14:45 閉会のご挨拶


申込方法

本イベントへの申し込み、詳細につきましてはこちらのサイトをご覧ください。
 ※ 参加可能な方には後日参加証を送付いたします。


Posted by Takuo Suzuki - Developer Relations Team

効果的な電話番号確認

$
0
0
この記事は ID プロダクト マネージャー、Steven Soneff による Android Developers Blog の記事 "Effective phone number verification" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

電話番号を活用するアプリを開発する際には、ユーザーが実際にその電話番号を所有していることを確認する手続きが欠かせません。UX の視点から考えると、これはなかなか厄介なことです。さまざまな地域の電話番号の形式を理解する必要もあるうえに、ユーザーのすべての SMS を読み取るような過度な端末パーミッションを使わずに、手間のかからない確認メカニズムを提供しなければなりません。

効果的に電話番号認証を行うビルド済みのライブラリも多数存在します。その一例が Firebase Phone Authです。しかし、この機能を自作する必要がある高度なデベロッパーのために、ユーザーの電話番号を取得して SMS 経由で確認する 2 つの新しい API、Phone SelectorSMS Retrieverが Google Play Services で提供されるようになりました。端末にパーミッションを追加する必要はありません。Flipkartのようなアプリでは、この API を用いた電話番号によるサインアップ フローを導入することにより、成功率が 12% 増加しています。

次の図に、この API とサーバーを利用する際の手順を示します。

本投稿で紹介するコードでは、まずユーザーに電話番号選択画面を提示します。次に、SMS 取得 API を利用してサーバーから確認コードをリクエストします。ユーザーが何も入力しなくても Android 端末が SMS を自動的に受信し、解析できます。

注: 利用するにあたって、SMS を受信できる電話番号があり、Google Play Services 10.2.x 以上が搭載されている端末でビルドおよびテストする必要があります。

Phone Selector を使って番号を取得する


最初の手順として、ユーザーにアプリから SMS 確認機能を起動してもらいます。次のようなコードを使うと、ユーザーに電話番号の入力を促す際に、Phone Selector を使って入力の手間を減らすことができます。
// Construct a request for phone numbers and show the picker
private void requestHint() {
HintRequest hintRequest = new HintRequest.Builder()
.setPhoneNumberIdentifierSupported(true)
.build();

PendingIntent intent = Auth.CredentialsApi.getHintPickerIntent(
apiClient, hintRequest);
startIntentSenderForResult(intent.getIntentSender(),
RESOLVE_HINT, null, 0, 0, 0);
}

HintRequest ビルダーは、電話番号による識別子が必要であることを Play Services に伝えます。その後、これを使って intent を作成して開始します。すると、Play Service のダイアログが表示され、選択された電話番号がアプリに共有されます。この API には、何のパーミッションも必要ありません。表示される選択肢は、スマートフォンまたは Google アカウントで利用できる電話番号です。

最新版の Play Services を実行している端末では、ユーザーが選んだ電話番号がアプリの onActivityResult に返されます。その際の形式は、E164 フォーマットです。なお、スマートフォンによっては、電話番号を取得できない場合もありますので、資格情報が null でないことを確認するようにしてください。電話番号がない場合は、ユーザーが手動で入力できる方法を提供する必要があります。
// Obtain the phone number from the result
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESOLVE_HINT) {
if (resultCode == RESULT_OK) {
Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
// credential.getId(); <-- E.164 format phone number on 10.2.+ devices
}
}
}

この時点で、ユーザーの電話番号を文字列で入手することになります。これは便利な方法ですが、ユーザーが実際にこの番号を所有しているかどうかを確認したいこともあるでしょう。たとえば、他のユーザーとのメッセージの送受信を許可したり、電話番号を使って身分証明を行う場合などです。

SMS Verification API を使って番号を確認する


電話番号を所有しているかどうかを確認する簡単な方法として、その番号にワンタイムの確認コードを含む SMS を送り、それをアプリに入力してもらう方法があります。SMS Verification API は、アプリで着信する SMS を監視し、自動で解析してコードを取得します。

これを使うには、次のようなコードでアプリに SmsRetrieverClientを追加します。
SmsRetrieverClient client = SmsRetriever.getClient(this /* context */);

Task<Void> task = client.startSmsRetriever();

task.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
// successfully started an SMS Retriever for one SMS message
}
});

task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
});
);

とてもシンプルで、SMS Retriever クライアントを取得してタスクを開始するだけです。タスクには成功と失敗のリスナーがあり、オーバーライドできるようになっています。SMS Retriever を開始すると、ユーザーの電話番号がサーバーに送信され、サーバーでワークフローが開始されます。その中でメッセージが生成され、指定された電話番号に送信されます。

このメッセージは、特殊な方法で作成する必要があります。SMS メッセージに収まらなければならないため、140 バイトを超えてはいけません。さらに、「<#>」または 2 文字のゼロ幅スペース(U+200B)という特殊な接頭辞で始める必要があります。詳細については、ドキュメントをご覧ください。また、末尾はアプリを識別できる 11 文字のハッシュにする必要があります。

次に例を示します。

<#> Use 123456 as your verification code in Example App!
FA+9qCX9VSu

ワンタイム確認コードは、任意の文字列で構いません。単純に乱数を生成することもできます。メッセージの末尾は、こちらの手続きにしたがって決まるハッシュにする必要があります。Google Play Services は、このハッシュを使って確認メッセージがどのアプリのものかを判断します。ハッシュは、アプリのパッケージと署名証明書を使って一度だけ生成します。これは変更されることはなく、クライアント アプリで提供してはいけません。

サーバーは、既存の SMS インフラストラクチャやサービスを利用してスマートフォンにメッセージを送信します。メッセージを受信すると、Google Play Services がメッセージのテキストを含む intent をブロードキャストします。次にコードを示します。
public class MySMSBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);

switch(status.getStatusCode()) {
case CommonStatusCodes.SUCCESS:
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
break;
case CommonStatusCodes.TIMEOUT:
break;
}
}
}
}

ブロードキャスト レシーバーの onReceive でエクストラを取得し、そこからステータスを取得しています。ステータスがメッセージの受信が成功したことを示す場合、エクストラからメッセージを取得できます。そこから確認コードを解析してサーバーに送り返し、電話番号の所有権を確認します。

詳しくは、完全版のドキュメントや今年の Google I/O セッションをご覧ください。

アーリー アダプターの証言


既にこれを利用しているアーリー パートナーは、この API をとても気に入っています。そのいくつかの声を紹介しましょう。

Twilioは、ここまで簡単な Android SMS 確認はこれまでなかったとブログに書いています。

「Android で電話番号を使ってユーザー アカウントを登録、確認するモバイルアプリを開発しているデベロッパーの皆さんは、ぜひ Twilio Verification SDK for Android をご利用ください。スムーズで安全かつ簡単なサインアップ フローを提供するという問題を、最短の時間で解決できます」 - Twilio プロダクト オーナー、Simon Thorpe 氏

Authyは、彼らの既存 SMS インフラストラクチャを大きく変更しなくてもこの API が動作する点を気に入っています。

「Phone Selector + SMS Retriever を Authy 2FA アプリと組み合わせれば、魔法のような UX をユーザーに提供できます。さらに、アプリに必要な高度なセキュリティも維持できます」 -- Authy Engineering 責任者、Serge Kruppa 氏

Telesignは、同じバックエンド フレームワークを使いつつ、UX の進化、向上したセキュリティ、そして高いコンバージョン率を実現できました。

「この確認モードの大きなメリットは、負担が少なく、サインアップや登録の際のユーザーのコンバージョン率の向上が見込めることです。

Google Play Services が SMS メッセージ内にあるハッシュに基づいて対象のアプリのみにアクセスを提供しているので、高度なセキュリティを実現できることも魅力です」 -- Priyesh Jain 氏(記事投稿者)



Reviewed by Yuichi Araki - Developer Relations Team

インサイド AdMob : 広告を iPhone X に対応させましょう

$
0
0
この記事は AdMob プロダクト マネージャー、Pablo Alvarez による の記事 "Inside AdMob: Get your ads ready for iPhone X" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。

ユーザーとアプリの間のインタラクションはすべて重要です。そのため、私たちは広告に関する推奨事項やポリシーを常に改善し、ユーザーがどこでどんな端末でアプリを使っても快適な体験ができることを保証しています。

iPhone X がリリースされ、アプリのデベロッパーは新しいデザインを検討しなければならなくなります。iPhone X は四隅が丸く、画面が広くなっており、ノッチとホームインジケーターがついています。そういった場所に広告が配置されると、コンテンツがはっきり見えなくなり、広告のユーザー エクスペリエンスが悪化する可能性があります。

iPhone X の「セーフエリア」外に表示される広告の例
そこで、広告戦略を iPhone X に対応させるための手助けとして、ガイドをまとめました。ここには、バナーやネイティブ広告を iPhone X の「セーフエリア」に配置する方法についての説明などが掲載されています。

さらに、ポリシーもアップデートされました。たとえば、iPhone X のホームインジケーターの下など、ユーザーが広告やアプリに対して行う一般的なインタラクションを妨げる場所に広告を配置してはいけないことが明記されています。

ポリシーのアップデートや推奨実装ガイドを確認し、11 月 20 日までに準拠するようにしてください。

質問がある方は、AdMob ヘルプセンターを参照するか、Google アカウント チームまでご連絡ください。

Reviewed by Rikako Katayama - AdMob Team
Viewing all 2204 articles
Browse latest View live