20210715のAndroidに関する記事は4件です。

AppDistributionでAPKの代わりにAABを使う

TL;DR 既にfirebase-appdistribution-gradleでAppDistributionに対してAPKをアップロードしている人の変更点です いまからプロジェクトを作るならCodeLaboやったほうが良いと思います artifactTypeにABBを指定する artifactType には AAB と APK が指定できます。AABを指定しましょう。 詳しくはここを参照してください。 firebaseAppDistribution { artifactType = "AAB" } Firebase プロジェクトを Google Play アカウントに接続する AABはデバイスに応じたAPKを配布する仕組みなので、GooglePlayStore経由でインストールすることになるようです。なので、FirebaseとGooglePlayStoreをリンクさせる必要があります。これをしないと This project is not linked to a Google Play account というエラーが表示されて失敗します。 詳しくはここを参照してください a. 自分が Firebase プロジェクトのオーナーであること、および Google Play アカウントの管理者アカウントまたはオーナーであることを確認します。 b. Firebase プロジェクトで settings(設定)に移動し、[プロジェクト設定] > [統合] の順にクリックします。 c. まだ行っていない場合は、Google アナリティクス カードを使用して Google アナリティクスを有効にします。これは、プロジェクトを Google Play にリンクするために必要です。 d. Google Play カードの [リンク] をクリックします。 終わり 上記を行った状態でAABを作成した後にAppDistributionに配布するtaskを起動すればアップロードされます。GooglePlayStore経由で更新されるので初回だけダイアログが出ますが、手順に沿って内部アプリ共有をONにすれば次回からは問題なくダウンロードできるようになります。 GooglePlayStore経由でダウンロードするなら内部テスト版のリリースと一緒じゃないかなと感じましたが、自由にダウングレードすることができるのは便利ですね。ただGooglePlayStoreに登録していない開発環境のアプリの配布などは難しいのかなと感じました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AndroidのWorkManagerでWorkerにデータが渡らない?

Androidはころころ変わるし、ユーザ的にもUpdateはよくない。そこで、Androidの深いところは使わず、なるべくWebに処理を持ちたい。しかし一方で、普及したハードは利用したい。そこで、AndroidのAPIは最低限だけ使おうと思う。で、KotlinのCoroutineでは書けないことがあって、Background処理のため、WorkManagerを使おうとして。 そこで3日以上はまったので、似たようなことで困っている方のために首記Titleで、残しておきます。 Androidの開発者向けの解説Sample通りに書いても、Workerにデータが渡せない。 何度コードを見直して、ドキュメントを見て、同じことをやるいろいろな書き方を試しても、うまくデータが渡らない。 WorkerにわたったデータをPrintして、ようやく気付いた。 昔書きかけで実行したみたWorkerプロセスが、延々と再試行されていて、その時の結果をDumpさせていた。 今起動した処理は、Queueの後ろにあるのか、まだ実行されていない模様。 新しくQueueにデバッグ済みのWorkerを入れる前に、以前のWorker再試行を全部キャンセルする処理を入れたら、データがちゃんとわたっていましたよ。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

QiChat MANIAX(1) Topicファイルのルールについてイントロ編

はじめに 前回のあとがきでも書きましたが、今回からはPepper SDK入門とは別に、QiChat MANIAXとしてTopicファイルのルールを詳述していきます? さて、Pepper SDK入門(24)で触れたように、Topicファイルには先頭にファイルの名前を記述するなどのルールがありました。例としては次のようなものです。 topic: ~introduction () u:(ソルトちゃんこんにちは) ぼくPepperですけど 今回はQiChat MANIAXのイントロダクションとして、このTopicファイルのルールの概要を見ていきます⛵️ ルール事始め〜郷に入った場合の郷を知る〜 ここで言うルールとは、ユーザー入力とPepperの返答を関連づけるものです。 区切り文字、ルールの機能や特徴が様々なケースに対応してくれます。恢恢! ルールにはユーザールール、ユーザーのサブルール、Proposalの三種類があります。 ユーザーとPepperとルールの相関図?(三角関係ではない) ユーザーの入力部分は括弧で区切り、Pepperが理解できるメッセージを記述しましょう。(この括弧内のメッセージを音声認識します) ユーザー入力を認識した時にルールに続く処理が実行され、該当ルールを含むTopicがフォーカスされます。上の例で言うと、"ソルトちゃんこんにちは"がユーザーの音声認識がされる部分であり、"ぼくPepperですけど"がPepperの発話する部分です。 conceptのコンセプト(概念)について? conceptとは、関連するワードやフレーズのことです。国のリスト、名前のリスト、類義語などですね。マジカルバナナは始まりません? コンセプトには二種類あり、ユーザー入力でもPepperの返答でも使えます。 タイプ スコープ 実行時 構成要素 Static global 変更できない Choice: [ ]Optional part: { }concepts (staticとdynamic)functions (^rand, ^first)Variable: $とConditions: == > <> < Dynamic global プログラム上で設定が必要 Choice: [ ]内のワードとフレーズのリスト …これだけでは何の話かまるで分からないと思いますので、もう少し詳しく説明すると、 concept:(want) [仏の御石の鉢 蓬莱の玉の枝 龍の首の珠 火鼠の裘 燕の産んだ子安貝] staticというのはこのようにTopic上で全て記述され、プログラムから変更されません。 dynamic:want QiChatbot qiChatbot = ...; EditablePhraseSet editablePhraseSet = qiChatbot.dynamicConcept("want"); List<Phrase> phrases = new ArrayList<>(); phrases.add(new Phrase("仏の御石の鉢")); phrases.add(new Phrase("蓬莱の玉の枝")); phrases.add(new Phrase("龍の首の珠")); editablePhraseSet.addPhrases(phrases); dynamicの方はTopicファイルではなくプログラム上で内容を記述する、ということです。上記に人魚の肉や猿の手を後出しすることも可能になります?? 表にある未知の単語については次回以降順番に紹介しますので、あまり気にせず読み進めてください?‍♂️ オンオフをスイッチする?? Topicとルールは、Dialogエンジンで利用されます。 Topicのオンオフは、会話のコンテキストを作成しメモリ上のルール管理の量を減らすために切り替えることが可能です。無効になっているTopicのルールは機能しません。 次の場合、Topicは有効であってもルールが機能しないので注意しましょう。 親のルールが実行されていないサブルール。サブルールについては別途説明予定のため、名前だけ覚えておいてください 一度実行されたProposal 機能しないBookmarkが含まれている ルールに^privateがついており、Topicにフォーカスが当たっていない場合 また、TopicはTopicStatusのオブジェクトによって管理されます。 詳しくはPepper SDK入門(24)を参照してみてください。 フォーカスという名のスポットライト?✨ いくつかのTopicは同時に利用できますが、Focusを持てるのは常に一つの選ばれしTopicだけです。 Focusは、^noStay以外のルールを含むTopicへ与えられます。 もし複数のルールがTopic同士で被っている場合、Focusを持つTopicが優先されます。それ以外の場合はランダムに選択され、DialogエンジンがTopicにフォーカスを与えて先頭のProposalが実行されるケースもあります。 ちなみに次回の内容を少しだけ先取りすると、^noPickはその自動選択を阻止してくれるものです?詳しくは次回以降、他の関連するルールと共に解説しますね? Topicの優先順位? Topicが複数存在する場合、ルールは次の順番で考慮されます。 順番 ルールの位置 Focus Focusを持っているTopic すべてのTopic ^fallbackを持っているTopic以外のすべてのTopic複数の場合はランダム Fallback ^fallbackを持っているTopic 複数の場合はガンダムランダム これはマトリョーシカではなく背の順に並ぶPepperです。 ユーザー入力を使い回す? ユーザーの入力を受け取って、Pepperの返答に利用することができます? Skin(皮膚ではない) Skinというのはメタルールで、なんとPepperの返答を季節や時間帯などの条件によって返答させることができます!青葉闇の下で日足が短足になりましたなどと話しかけられたら怖いので、機械にも季節感を知っていて欲しいですね?? ゲームのスキンのようにPepperを着せ替えしたりする機能ではないので注意してください⭕️ あとがき 今回もPepperSDKforAndroidを参考に書かせていただきました。 次回からのQiChat MANIAXでは、順番にQiChatの構文を見ていきます!高聞に達して欲しい?? それでは!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

動画サービスをFirestore+CloudFunctionsで勝手に設計してみる ~ NobodySurf編

こんにちは。もぐめっとです。 最近本当に自分の写真のネタがなさすぎるので昔の写真を引っ張り出したりしてます。普通に滑ってるように見えますが、実は浮いてます。目の錯覚ショットですね。 今回は、昨日apple storeをみたらTodayで紹介されていたNobodySurfという超イケてるサーフィン動画をたくさん見れる超イケてるアプリが掲載されていたので、こちらのアプリをもしfirestoreでシステム構築したらどんな構成になるのか?という題材で勝手に設計してみたので僕が考えた設計を紹介します。 アプリ概要 アプリについて紹介します。 トップからは主にカテゴリ別の動画が見れ、動画詳細で動画をチェックし、気に入れば自分のプレイリストを作って保存することができます。 TOP 動画詳細 マイページ 検索はサーファー名、カテゴリ、フィン、波の大きさ、スタンス、性別などなどいろんな角度から検索をすることができます。 検索TOP 検索結果 Firestore設計 こんな構造を考えてみました movies: サーフィン動画 surfers: サーファー一覧 news: お知らせ users: アプリを使うユーザ情報 playlists: ユーザ保存したプレイリスト情報 movies: 実際に保存したmovieのコピー billingTransactions: 購入したときのレシートを保管 subscriptions: ユーザのサブスク状況 movies movie情報です。 movieのidからストリーミングするURLは生成することとします。 /movies/{movieId} movieId: 自動生成 Field Type Description 関連CloudFunctions createdAt Timestamp 登録日 updatedAt Timestamp 更新日 movieTitle String 動画タイトル surfers Map[String: DocumentReference] サーファー名とそのリファレンス filmers Map[String: DocumentReference] 撮影者名とそのリファレンス editors Map[String: DocumentReference] 編集者名とそのリファレンス filmEditors Map[String: DocumentReference] 撮影者兼編集者名とそのリファレンス presenters Map[String: DocumentReference] プレゼンター名とそのリファレンス producers Map[String: DocumentReference] プロデューサ名とそのリファレンス supporters Map[String: DocumentReference] サポーター名とそのリファレンス narrators Map[String: DocumentReference] ナレーション名とそのリファレンス writers Map[String: DocumentReference] ライター名とそのリファレンス musics Array[String] 使われてる音楽名 droneFootager [String] ドローン映像名 countries [String] 撮影された国 locations [String] 撮影された場所 series String シリーズ名 runTime Int 動画時間 years Array[Int] 撮影年代 surfboards Array[String] enum: shortboard, longboard, midLength, fish, softTop, gun fins Array[String] enum: finless, singleFin, twinFin, triFin, Bonzer waveSizes Array[String] enum: small, chestHead, overhead, big, huge stances Array[String] enum: regular, goofy genders Array[String] enum: man, woman, unknown otherCategories Array[String] enum: youth, legend relatedLinks Map[String: String] リンク名とURL surfers サーファー情報の管理です。 /surfers/{surferId} movieId: 自動生成 Field Type Description 関連CloudFunctions createdAt Timestamp 登録日 updatedAt Timestamp 更新日 surferName String 名前 surferTypes Array[String] サーファーだったり、撮影者だったり様々な肩書があるので配列で持ちます。enum: surfer, filmer, editor, fimEditor, presenter, producer, supporter, narrator, writer surfboards Array[String] enum: shortboard, longboard, midLength, fish, softTop, gun fins Array[String] enum: finless, singleFin, twinFin, triFin, Bonzer waveSizes Array[String] enum: small, chestHead, overhead, big, huge stances Array[String] enum: regular, goofy genders Array[String] enum: man, woman, unknown otherCategories Array[String] enum: youth, legend relatedLinks Map[String: String] リンク名とURL news 新着情報の表示用 /news/{newsId} newsId: 自動生成 Field Type Description 関連CloudFunctions createdAt Timestamp 登録日 updatedAt Timestamp 更新日 deletedAt Timestamp nullの場合は表示しない newsTitle String お知らせのタイトル movieTitle String? 動画タイトル playlistTitle String? プレイリストタイトル playlistReference DocumentReference? プレイリストのリファレンス message String? bannerの場合に表示するメッセージ url String? bannerの場合に遷移するURL viewType String? enum: card, banner どんな形式でお知らせを見せるか newsの取得は deletedAt != nullで表示するものだけ取得します。 users アプリを使うユーザ管理 下記はそれぞれFirebase Authenticationで解決できるのでここでは管理しません。 認証方法: Firebase Authenticationで管理 ユーザロール: Firebase Authenticationのcustom claimsで管理 Firestore側でなるべく個人情報などのsecureな情報は持たないように設計します。 /users/{userId} userId: firebase authenticationで認証したuid Field Type Description 関連CloudFunctions createdAt Timestamp 登録日 updatedAt Timestamp 更新日 needsNewsNotification Boolean お知らせ通知を送るかどうか favoriteSurfStyle String 好みのサーフスタイル enum: shortboard, longboard, alternative fcmTokens Array[String] 通知用のfcmToken配列。これを使ってpush通知を行う fcmTokenは今回はユーザ同士の読み取りがないためusersにもたせていますが、本来であればsecureな情報にあたるので、交流するようなSNS的なサービスであれば別途collectionを定義してやったほうがいいです。 users/playlists ユーザが保存したプレイリスト /users/{userId}/playlists/{playlistId} playlistId: 自動生成 Field Type Description 関連CloudFunctions createdAt Timestamp 登録日 updatedAt Timestamp 更新日 playlistTitle String プレイリスト名 movieCount Number 保存した動画数 onCreatePlaylistMovie, onDeletePlaylistMovie users/playlists/movies 保存した動画一覧。内容はmoviesと一緒 /users/{userId}/playlists/{playlistId}/movies/{movieId} movieId: 元のmovieのidと同等 users/billingTransactions ユーザが課金処理をしてwebhookからレシートを発行されたら保管する。 処理に失敗しても辿れるように必ず最初に保存だけしておく。 /users/{userId}/billingTransactions/{billingTransactionId} - billingTransactionId: Apple: originalTransactionId, Google: orderId Field Type Description 関連CloudFunctions createdAt Timestamp 登録日 onRequestSubscriptionApple,onRequestSubscriptionGoogle updatedAt Timestamp 更新日 onRequestSubscriptionApple,onRequestSubscriptionGoogle purchasedAt Timestamp 購入日 onRequestSubscriptionApple,onRequestSubscriptionGoogle platform String 購入したプラットフォームenum: apple, google onRequestSubscriptionApple,onRequestSubscriptionGoogle receipt String Apple: レシート, Google: json onRequestSubscriptionApple,onRequestSubscriptionGoogle productId String 商品ID onRequestSubscriptionApple,onRequestSubscriptionGoogle userReference DocumentReference コレクショングループで調べるよう onRequestSubscriptionApple,onRequestSubscriptionGoogle validatedData Map[String: any] レシートの検証結果の情報をいれておく onRequestSubscriptionApple,onRequestSubscriptionGoogle users/subscriptions /users/{userId}/subscriptions/{subscriptionId} - subscriptionId: Apple: originalTransactionId, Google: orderId platformからのwebhookを受け取ってサブスクリプション情報を更新する。 stripeのこの辺を参考にしてだいたい一緒だろうというのりで作った。 Field Type Description 関連CloudFunctions createdAt Timestamp 登録日 onRequestSubscriptionApple,onRequestSubscriptionGoogle updatedAt Timestamp 更新日 onRequestSubscriptionApple,onRequestSubscriptionGoogle cancelAt Timestamp? キャンセル日 onRequestSubscriptionApple,onRequestSubscriptionGoogle canceledAt Timestamp? キャンセルした日 onRequestSubscriptionApple,onRequestSubscriptionGoogle currentPeriodStart Timestamp サブスク開始日 onRequestSubscriptionApple,onRequestSubscriptionGoogle currentPeriodEnd Timestamp サブスク終了日 onRequestSubscriptionApple,onRequestSubscriptionGoogle endedAt Timestamp? サブスクを終了した日 onRequestSubscriptionApple,onRequestSubscriptionGoogle trialStart Timestamp? お試し開始日 onRequestSubscriptionApple,onRequestSubscriptionGoogle trialEnd Timestamp? お試し終了日 onRequestSubscriptionApple,onRequestSubscriptionGoogle price Number 金額 onRequestSubscriptionApple,onRequestSubscriptionGoogle productId String 商品ID onRequestSubscriptionApple,onRequestSubscriptionGoogle status String enum: active, canceled, incomplete, incompleteExpired, pastDue, trialing, unpaid onRequestSubscriptionApple,onRequestSubscriptionGoogle ただ、status周りはストアごとにもあったりするのでもう少し精査の必要性あり CloudFunctions設計 onRequestSubscriptionApple / onRequestSubscriptionGoogle Requestで実装。 Apple/Googleからsubscriptionの更新があった時に発火されるwebhook先のURL。 受け取ったレシートを検証し、subscriptionsやbillingTransactionsレコードを管理する また、userのclamsもサブスクの状態を見て更新します。 onCreatePlaylistMovie, onDeletePlaylistMovie ユーザがプレイリストを追加したり、削除した時に発火。プレイリスト数を増減させる。 ユースケースを考える 動画のストリーミングについて 動画はcloud storageに保管すればストリーミング再生ができそうな雰囲気は醸し出してます。 検索について 検索条件がたくさんあるので全部algoriaにお任せです。 ただ、検索キーとして、movieのsurfersやfilmersなどで使ってる名前を別途配列として定義してしまえばalgoriaを使わなくても検索をすることは可能です。(フィールドは検索用にたくさん増えてはしまいますが、algoria使わなくていいので実装コストは下がる) ただ、最近extensionも出たので、algoriaの実装難易度も大分下がりました。 まとめ ユーザ同士の交流といった機能はないので、実装コストは大きく削れそうです。 そう考えるとユーザ交流させるサービスのコストって結構高いんだなぁと改めて感じました。 私はスノボが好きなのですが、いずれNobody Snowみたいな雪山版のイケてるサービスも作れたらいいなと密かに思ったりしています。 最後に、ワンナイト人狼オンラインというゲームを作ってます!よかったら遊んでね! 他にもCameconやOffchaといったサービスも作ってるのでよかったら使ってね! また、チームビルディングや技術顧問、Firebaseの設計やアドバイスといったお話も受け付けてますので御用の方は弊社までお問い合わせください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む