20201009のAndroidに関する記事は10件です。

TermuxでFirebaseを使いたい

背景

※執筆時点のfirebase-toolsは8.12.0です。

TermuxFirebaseのエミュレータを起動したかった。

Termuxでもfirebase-toolsが入れられるので、firebase emulatorsも当然使えると思ったがそうはいかなかった。
firestoreとdatabaseのエミュレータはJavaで実装されているが、TermuxにはJavaが用意されていないため起動できない。

そこで、Javaのインストールからfirebase emulators:start --only firestoreを起動できるまでの手順を紹介する。

手順

0. 準備

既に一通り済んでいる場合は飛ばす。

Termux

PlayストアからTermuxをインストールする。

Termuxパッケージ

最低限以下のパッケージが必要になるので、Termux上でインストールする。

  • proot
  • wget
  • vimなどのテキストエディタ
  • nodejsまたはnodejs-lts
    • firebase-tools

1. Javaのインストール

前述の通り、Javaが用意されておらずパッケージもない。
しかし、Termux-Javaと言うスクリプトを使えば一応Javaが使えるようになる(一応とした理由は後述する)。

$ wget https://raw.githubusercontent.com/MasterDevX/java/master/installjava && bash installjava

これでJavaが使えるようになる…はずだが、筆者の環境ではBad system callと言うログとともにJavaがkillされた。
Issueによればroot権限が必要なようなので、prootを併用して起動するか確認する1

$ proot java

2. firebase-tools(firestoreエミュレータ)の修正

firestore及びdatabaseのエミュレータはjarファイルで提供されており、javaコマンドで実行するようになっている。
この時、javaコマンドはchildProcess.spawn()を使って実行しているが、PATHからjavaコマンドを探して実行するため、仮にaliasでproot javaに設定していたとしても関係なく素のjavaコマンドを実行し、Bad system callで起動に失敗する。

なので、ここは少し強引だがfirebase-toolsのソースコードを直接編集して対応する。

編集対象となるファイルはdownloadableEmulators.tsなので、ローカル環境でこのファイルを捜索してテキストエディタで開く。

firebase-toolsをグローバルにインストールしている場合は、デフォルトでは

/data/data/com.termux/files/usr/lib/node_modules/firebase-tools/lib/emulator/downloadableEmulators.js

として存在している(はず)。

118行目、124行目あたりを以下の通りに修正する。

Line: 118
      database: {
-         binary: "java",
-         args: ["-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.DATABASE)],
+         binary: "proot",
+         args: ["java", "-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.DATABASE)],

Line: 124
      firestore: {
-         binary: "java",
-         args: ["-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.FIRESTORE)],
+         binary: "proot",
+         args: ["java", "-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.FIRESTORE)],

要するに、javaではなくprootを実行し、引数としてjavaを渡すように変更する。

3. 確認

これでエミュレータが動作するはずなので、プロジェクトディレクトリに戻ってエミュレータを起動する。

$ firebase emulators:start --only firestore

問題点

エミュレータ終了時にjavaのプロセスが残る

エミュレータの終了に失敗し、firebaseプロセスの子プロセスであるはずのjavaが残り続けてしまう。
このjavaプロセスは8080ポートを占有しており、続けてエミュレータを起動しようとすると8080ポートが空いていないことによってエミュレータが起動できなくなってしまう。

現時点では原因がわかっていないため、都度プロセスをkillして対応する2

$ lsof -i:8080
# -> 8080を占有するjavaプロセスのpidがわかるはずである。プロセスがない場合は問題が発生していないので、そのままエミュレータを起動できる。
$ kill javaプロセスのpid

firebase-toolsのコードを編集している

編集せずにうまいことやる方法があったら教えてください。

ブラウザの開発ツールがない

この記事の主題とは直接関係ないが、hostingエミュレータを使えば作ったソースコードをlocalhostで閲覧できる。
しかし、閲覧に使用するブラウザはAndroidアプリなので開発ツールがなく、デバッグできない。

参考

解決に時間がかかったので、残っていたタブから抜粋。実際にはもっとたくさんのページを閲覧した。


  1. 本用途の他にもjavaコマンドを直接使う用があるなら、aliasを設定しておくと便利。 

  2. prootだけがSIGINTを受け取り、javaは受け取っていない? 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Android]PUSH通知

概要

ローカル通知について結構前に勉強したことがあった(リモート通知はどうすればいいのか知らなかった)のだが、
だいぶ忘れた状態で、リモート通知のコード見ててどういうことなの・・・・となって、
なるほどねとなるまでにかなり時間がかかったのでメモ

PUSH通知とは

  • PUSH通知はその発火トリガーによってローカル通知とリモート通知に分類されている。
    • ローカル通知:発火トリガーがローカルのなにかの処理
    • リモート通知:発火トリガーがFCMからのメッセージ受信
  • PUSH通知の本質的な処理・・・すなわち「通知領域への表示」〜「通知タップ時の画面遷移処理」のやり方は全く同じ ←ここがわかってなかった
  • なお、単純にPUSH通知という場合はリモート通知のことを指すことが多い。 ←さらにここでやられた
  • FCMメッセージ送信=PUSH通知と捉えている記事が世にめちゃくちゃ多いが、コレ多分嘘で、ここが理解を妨げていたんだと思う。
    Qiita記事とかでFirebaseからPUSH通知を送信!みたいな図をよく見かけてたせいで、完全にだまされた。 ←こいつが主原因!!!
    Firebase公式でPUSH通知なんていう言葉出てこないもの。送るのはあくまでFCMメッセージだっていってるもの。

リモート通知

  • FCMから受けたメッセージを処理するには、FirebaseMessagingService() を継承したクラスを作成する必要あり。
  • FCMから通知が来た時に呼ばれるのは onMessageReceived(remoteMessage: RemoteMessage) っぽい。
    • ここを起点にPUSH通知の処理を書けばOK
    • remoteMessage.getData()で、PUSH通知に含まれていたペイロード(※)データ(Map型)を取得できる

※ペイロード:ヘッダを抜いたデータ本体のこと。httpレスポンスでいうところのbodyだと理解。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Android]scrcpy でミラーリングすると画面が見切れる問題の対処方法

はじめに

scrcpy は Android 端末をミラーリング、画面操作をUSBまたはTCP/IP経由で行うアプリケーションです。Windows・Linux・Macで利用できるアプリケーションなので全てのAndroid開発環境で利用できます。scrcpy はかなり便利なツールでバグも少ないのですが次の問題があったので解決方法を共有します。

問題

解像度が 1920x1200 のを scrcpy でミラーリングすると、なぜか 1920x1080 の解像度でミラーリングされ画面が見切れて表示されてしまう。本来であれば scrcpy ではタップ操作もサポートしているが、この状態になるとタップ操作もできなくなる。

$ scrcpy 
2020-10-09 15:40:18.220 scrcpy[7021:244757] INFO: scrcpy 1.10 <https://github.com/Genymobile/scrcpy>
/usr/local/Cellar/scrcpy/1.10/share/scrcpy/scrcpy-server.jar: 1 file pushed. 1.3 MB/s (22662 bytes in 0.017s)
2020-10-09 15:40:19.995 scrcpy[7021:244757] INFO: Initial texture: 1920x1200
2020-10-09 15:40:20.488 scrcpy[7021:244757] INFO: New texture: 1920x1080

Screen Shot 2020-10-09 at 15.47.15.png
※ 画面下部のナビゲーションバーとボタンが切れて表示されてしまっている。

解決方法

scrcpy でミラーリングする際に 1280x800 の解像度で小さく表示するようにしてやる。ミラーリングの解像度は -m オプションで設定できるようになっています。なので次のように -m オプションを設定してやると見きれずに表示してくれます。また -m オプションを設定することでタッチ操作も正常に動作するようになります。

$ scrcpy -m 1280
2020-10-09 15:52:08.956 scrcpy[7177:254315] INFO: scrcpy 1.10 <https://github.com/Genymobile/scrcpy>
/usr/local/Cellar/scrcpy/1.10/share/sc...shed. 2.0 MB/s (22662 bytes in 0.011s)
2020-10-09 15:52:09.897 scrcpy[7177:254315] INFO: Initial texture: 1280x800

Screen Shot 2020-10-09 at 15.46.41.png
※ 画面下部のナビゲーションバーとボタンが切れずに表示できている。

おわりに

scrcpy は便利なツールで殆どの端末で正常に動作するのですが、稀に手く動作しない端末があるみたいです。動作しない端末に遭遇した場合は本記事で紹介した解決方法を試してみると良いかなと思います。

参考記事

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

新しい Google Play Console では「サービスとAPI」というメニューは別の名前になっています

概要

今までの GooglePlayConsole は 2020年11月2日 をもってサービスを終了し、新しい GooglePlayConsole になります。

最近は新しい方の GooglePlayConsole に使っていました。

新しいと言ってもまあだいたい雰囲気で問題なく使えていたのですが、従来の GooglePlayConsole でいうところの以下のメニューが行方不明に…

開発ツール - サービスとAPI

どこにいったのかわからず、調べようにも検索ワードが微妙すぎてうまく検索できず、
ドキュメントを見ても従来の GooglePlayConsole のスクリーンショットがはられており困っていたのですが、
さっきたまたまメニューをポチポチしてたら見つけることができました。

めんどくさがらずに、最初から全部のメニューをポチポチしておけばよかった…

ちなみに、一度新しい GooglePlayConsole に切り替えたとしても、サービス終了するまでは
「従来の Play コンソールを使用」というところから今までの GooglePlayConsole を使うことはできます。

しかし従来の GooglePlayConsole が使えなくなったら「どこから設定するのかわからない!」となってしまうのでどうしても見つけたかった次第です。

場所

従来の GooglePlayConsole の「サービスとAPI」には以下の4項目がありました。

  • ライセンスとアプリ内課金
  • リアルタイム デベロッパー通知
  • Google Play ゲーム サービス
  • Google 検索のインデックスにアプリを登録

それぞれ新しい GooglePlayConsole ではどこにあるのかを書いておきます。

ライセンスとアプリ内課金、リアルタイム デベロッパー通知

こちらの2つは同じ画面内にあります。

収益化 - 収益化のセットアップ

Google Play ゲーム サービス

検索ボックスに「ゲーム」と入力 - Play ゲームサービスの設定
(こちらはメニューから遷移する方法がわかりませんでした…)

Google 検索のインデックスにアプリを登録

設定 - 詳細設定 - アプリのインデックス登録

スクリーンショット 2020-10-09 13.07.00.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

新しい Google Play Console では「サービスとAPI」というメニューは別の名前になっていた

概要

今までの GooglePlayConsole は 2020年11月2日 をもってサービスを終了し、新しい GooglePlayConsole になります。

最近は新しい方の GooglePlayConsole に使っていました。

新しいと言ってもまあだいたい雰囲気で問題なく使えていたのですが、従来の GooglePlayConsole でいうところの以下のメニューが行方不明に…

開発ツール - サービスとAPI

どこにいったのかわからず、調べようにも検索ワードが微妙すぎてうまく検索できず、
ドキュメントを見ても従来の GooglePlayConsole のスクリーンショットがはられており困っていたのですが、
さっきたまたまメニューをポチポチしてたら見つけることができました。

めんどくさがらずに、最初から全部のメニューをポチポチしておけばよかった…

ちなみに、一度新しい GooglePlayConsole に切り替えたとしても、サービス終了するまでは
「従来の Play コンソールを使用」というところから今までの GooglePlayConsole を使うことはできます。

しかし従来の GooglePlayConsole が使えなくなったら「どこから設定するのかわからない!」となってしまうのでどうしても見つけたかった次第です。

場所

従来の GooglePlayConsole の「サービスとAPI」には以下の4項目がありました。

  • ライセンスとアプリ内課金
  • リアルタイム デベロッパー通知
  • Google Play ゲーム サービス
  • Google 検索のインデックスにアプリを登録

それぞれ新しい GooglePlayConsole ではどこにあるのかを書いておきます。

ライセンスとアプリ内課金、リアルタイム デベロッパー通知

こちらの2つは同じ画面内にあります。

収益化 - 収益化のセットアップ

Google Play ゲーム サービス

検索ボックスに「ゲーム」と入力 - Play ゲームサービスの設定
(こちらはメニューから遷移する方法がわかりませんでした…)

Google 検索のインデックスにアプリを登録

設定 - 詳細設定 - アプリのインデックス登録

スクリーンショット 2020-10-09 13.07.00.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

新しい Google Play Console では「サービスとAPI」というメニューは別の名前になっていた件

概要

今までの GooglePlayConsole は 2020年11月2日 をもってサービスを終了し、新しい GooglePlayConsole になります。

最近は新しい方の GooglePlayConsole に使っていました。

新しいと言ってもまあだいたい雰囲気で問題なく使えていたのですが、従来の GooglePlayConsole でいうところの以下のメニューが行方不明に…

開発ツール - サービスとAPI

どこにいったのかわからず、調べようにも検索ワードが微妙すぎてうまく検索できず、
ドキュメントを見ても従来の GooglePlayConsole のスクリーンショットがはられており困っていたのですが、
さっきたまたまメニューをポチポチしてたら見つけることができました。

めんどくさがらずに、最初から全部のメニューをポチポチしておけばよかった…

ちなみに、一度新しい GooglePlayConsole に切り替えたとしても、サービス終了するまでは
「従来の Play コンソールを使用」というところから今までの GooglePlayConsole を使うことはできます。

しかし従来の GooglePlayConsole が使えなくなったら「どこから設定するのかわからない!」となってしまうのでどうしても見つけたかった次第です。

場所

従来の GooglePlayConsole の「サービスとAPI」には以下の4項目がありました。

  • ライセンスとアプリ内課金
  • リアルタイム デベロッパー通知
  • Google Play ゲーム サービス
  • Google 検索のインデックスにアプリを登録

それぞれ新しい GooglePlayConsole ではどこにあるのかを書いておきます。

ライセンスとアプリ内課金、リアルタイム デベロッパー通知

こちらの2つは同じ画面内にあります。

収益化 - 収益化のセットアップ

Google Play ゲーム サービス

検索ボックスに「ゲーム」と入力 - Play ゲームサービスの設定
(メニューから遷移する方法がわかりませんでした…)

Google 検索のインデックスにアプリを登録

設定 - 詳細設定 - アプリのインデックス登録

スクリーンショット 2020-10-09 13.07.00.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Kotlin Multiplatform Mobile がアルファ段階に移行したので、チュートリアルを試す

背景

最近、Kotlin Multiplatform Mobile(KMM)がアルファ段階に移行したようです。

Kotlin Multiplatform Mobile がアルファ段階に移行 – Kotlin Blog | JetBrains

KMM とは、JetBrains が提供するクロスプラットフォーム対応のモバイル開発用 SDK です。
Kotlin のマルチプラットフォーム対応能力を駆使し、モバイルアプリケーションの構築体験を可能な限り楽しく効率的にするように設計されたさまざまなツールや機能を含んでいます。

見ていて面白そうだったので、試しにチュートリアルをやってみました。
※2020 年 10 月時点の情報なので、今後のアップデートにより変わる可能性があります。

開発環境

開発環境は以下の通りです。

  • Android Studio 4.1 RC 3 以降
  • Xcode 11.3 以降
  • Kotlin 1.4.0 以降
  • Java 1.8.0_73 以降
  • macOS Catalina バージョン 10.15.6

環境構築

以下をベースに進めていきます。

Getting started - Help | Kotlin Multiplatform Mobile Docs

Android Studio version 4.1 RC 3 以降をインストール

Android Studio Previewから、4.1 RC 3 か 4.2 CANARY 13 のいずれかをインストールします。
どちらでも大丈夫です。

1.png

Kotlin のバージョンを 1.4.0 以降にアップデート

Configure->Pluginsから、Kotlin を 1.4.0 以降にアップデートします。

2.png

Kotlin Multiplatform Mobile をインストール

Configure->Pluginsから、Kotlin Multiplatform Mobile をインストールします。

3.png

インストール後、Android Studio を再起動します。

はじめてのマルチプラットフォームアプリ作成

以下をベースに進めていきます。

Create your first multiplatform application - Help | Kotlin Multiplatform Mobile Docs

プロジェクト作成

Create New Projectから新規でプロジェクトを作成します。

4.png

Select a Project Templateより、KMM Applicationを選択し、Nextをクリックします。

5.png

各項目を以下の通り入力します。

項目 名称
Name KMM Application
Package name com.example.kmmapplication
Save location 任意のフォルダ

6.png

Configure ActivityではデフォルトのままFinishをクリックします。

7.png

ビルド

早速ビルドしてみます。
まずは Android から。

androidAppを選択してから、ビルド対象の端末を設定してビルドします。

8.png

すると、以下のように起動します。

9.png

次に iOS を試してみます。
iosAppを選択し、Edit Confiugrations...をクリックします。

10.png

Execution targetで端末を設定し、ビルドします。

11.png

すると、以下のように起動します。

12.png

テストコード

各プラットフォームごとにテストコードが用意されており、それぞれ以下のようにファイルを開いて実行できます。

13.png

Android のほうは、shared/src/androidTest/kotlin/com.example.kmmapplication.sharedandroidTest.ktにあります。

package com.example.kmmapplication.shared

import org.junit.Assert.assertTrue
import org.junit.Test

class AndroidGreetingTest {

    @Test
    fun testExample() {
        assertTrue("Check Android is mentioned", Greeting().greeting().contains("Android"))
    }
}

iOS のほうは、shared/src/iosTest/kotlin/com.example.kmmapplication.sharediosTest.ktにあります。

package com.example.kmmapplication.shared

import kotlin.test.Test
import kotlin.test.assertTrue

class IosGreetingTest {

    @Test
    fun testExample() {
        assertTrue(Greeting().greeting().contains("iOS"), "Check iOS is mentioned")
    }
}

どちらもGreeting().greeting()が出力する文字列にプラットフォーム名が含まれているかのテストをしています。
shared/src/commonTest/kotlinという共通用のテストフォルダも用意されているようですが、デフォルトでは何も入っていませんでした。

アプリケーションの更新

画面上では「Hello, [プラットフォーム名とバージョン]」という文字列が表示されていました。この文字列を生成しているクラスがshared/src/commonMain/kotlin/com.example.kmmapplication.sharedGreeting.ktにあります。

package com.example.kmmapplication.shared


class Greeting {
    fun greeting(): String {
        return "Hello, ${Platform().platform}!"
    }
}

このディレクトリには、Android と iOS の両方のプラットフォームの共有コードが保存されます。共有コードに変更を加えると、両方のアプリケーションに変更が表示されます。
試しに以下のように変更してみます。

class Greeting {
    fun greeting(): String {
        return "Guess what it is! > ${Platform().platform.reversed()}!"
    }
}

変更後、各プラットフォームでビルドしてみます。
いずれも変更が反映されていることを確認しました。

Android iOS
14.png 15.png

最後に、Platform クラスについても確認してみます。
commonMain/kotlin/com.example.kmmapplication.sharedPlatform.ktです。

package com.example.kmmapplication.shared

expect class Platform() {
    val platform: String
}

expectキーワードはマルチプラットフォーム専用のインタフェースにて使われるキーワードで、あるプラットフォームのクラスを使いたい場合に使うキーワードです。
androidMainiosMainにもそれぞれPlatform.ktがあります。

Android のほうは、androidMain/kotlin/com.example.kmmapplication.sharedPlatform.ktです。

package com.example.kmmapplication.shared

actual class Platform actual constructor() {
    actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}"
}

iOS のほうは、iosMain/kotlin/com.example.kmmapplication.sharedPlatform.ktです。

package com.example.kmmapplication.shared


import platform.UIKit.UIDevice

actual class Platform actual constructor() {
    actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}

それぞれactualキーワードが使われています。プラットフォームごとに、expectクラスをactualで実装する必要があります。
interfaceとそれをimplementするclassの関係に似ています。

まとめ

Kotlin Multiplatform Mobile(KMM)がアルファ段階に移行したことを受けて、試しにチュートリアルをやってみました。
どうやら共通化するのはロジックのみで、UI は各プラットフォームごとに独自で実装する必要がありそうです。
さらに以下のようなハンズオンも用意されているので、時間があるときにまた試してみます。

Hands-on: Networking and Data storage - Help | Kotlin Multiplatform Mobile Docs

参考 URL

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

#3 Kotlin Koans Introduction/Default arguments 解説

1.はじめに

Kotlin公式リファレンスのKotlin Koans/Default argumentsの解説記事です。

Kotlin Koansを通してKotlinを学習される人の参考になれば幸いです。

ただし、リファレンスを自力で読む力を養いたい方は、
すぐにこの記事に目を通さないで下さい!

一度各自で挑戦してから、お目通し頂ければと思います:sunny:

2-1.Default引数とnamed引数

#2 Kotlin Koans Introduction/Named arguments 解説 の記事で説明しておりますので、ご覧ください。

2-2.toUpperCase()

右側の本文中に出てくる、toUpperCase()関数をKotlin公式リファレンスで見てみましょう。

fun String.toUpperCase(locale: Locale):String

Returns a copy of this string converted to upper case using the rules of the specified locale.

つまり、String型のインスタンスがtoUpperCase()関数を呼び出すと、インスタンスが大文字になって返ってくる。

ということになります。

(※本Koansのなかには、Boolean型のパラメータとしてもtoUpperCaseが出てきます。)

3.Introduction/Default argumentsの解説

Kotlin Koans Introduction/Default argumentsの解説です。
随時本サイトの内容を引用させていただきます。

右側の本文を見てみましょう。

There are several overloads of 'foo()' in Java:

public String foo(String name, int number, boolean toUpperCase) {
    return (toUpperCase ? name.toUpperCase() : name) + number;
}
public String foo(String name, int number) {
    return foo(name, number, false);
}
public String foo(String name, boolean toUpperCase) {
    return foo(name, 42, toUpperCase);
}
public String foo(String name) {
    return foo(name, 42);
}

All these Java overloads can be replaced with one function in Kotlin. Change the declaration of the function foo in a way that makes the code using foo compile. Use default and named arguments.

上記4種のオーバーロードされたfoo()関数(Javaで定義されている。)を、Kotlinを用いることで4種の関数の機能を1種の関数でまとめることができる。default引数、named引数を用いてfoo()関数を定義しなさい。

といった内容になります。

以下から具体的な解説です。

まず、一番上のfoo()関数の

toUpperCase ? name.toUpperCase() : name

は、toUpperCaseがtrueならname.toUpperCase()をfalseならnameを値として指定するといった意味です(Javaの内容なので解説は省略します。)。

4種のfoo()関数を見てみましょう。

下3種のfoo()関数は戻り値のなかで1番上のfoo()関数を呼び出しているのがわかります。
(正確には1番下のfoo()関数は下から3番目のfoo()関数を間に挟んでいます。)

このとき下3種いずれのfoo()関数を呼び出したときでも、1番上のfoo()関数の引数numberに42を引数toUpperCaseにfalseを渡しています。

そして、1番上のfoo()関数がtoUpperCaseの真偽値(trueかfalse)に対応する値を返しています。

つまり、foo()関数の呼び出しもとが
引数numberとtoUpperCaseに値を渡さなければ、デフォルトで42とfalseが渡されることになっているといるわけです。

「デフォルトで渡される引数が決まっているのなら、初めに設定しておこう!」ということで、

Kotlinでfoo()関数を書き換えるときに、Default引数を利用して

number : Int = 42,toUpperCase : Boolean = falseと書き加えればいいわけですね。

そうすることで、

foo("a")
foo("b",number = 1)
foo("c",toUpperCase = true)
foo(name = "d",number = 2,toUpperCase = true)

いずれのfoo()関数の呼び出し側にも対応できます。

4 最後に

次回はKotlin Koans Introducion/Lambdasの解説をします:muscle:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

#2 Kotlin Koans Introduction/Named arguments 解説

1.はじめに

Kotlin公式リファレンスのKotlin Koans/Named argumentsの解説記事です。

Kotlin Koansを通してKotlinを学習される人の参考になれば幸いです。

ただし、リファレンスを自力で読む力を養いたい方は、
すぐにこの記事に目を通さないで下さい!

一度各自で挑戦してから、お目通し頂ければと思います:grinning:

2-1.Default引数とnamed引数

Default引数:デフォルトで値が指定されている引数

named引数:名前がついた引数

Default引数は関数を呼び出す際、引数に値を指定しなくても良い、
named引数は、引数が複数あるとき、関数の呼び出し側が引数の順序を気にせず値を渡せる、
といったメリットがあります。

Default引数とnamed引数の詳細(公式レファレンスの引用)

2-2.関数定義の略記

fun joinOptions(options: Collection<String>) = options.joinToString(TODO())

を見てみると、関数の実行内容を記述する{}と、(options: Collection<String>)=の間にあるはずの戻り値の型が省略されています。

じつは、Kotlinでは関数の戻り値を=の後に記述し、{}の表現を省略できるというルールがあります。

また戻り値の型の指定が省略されているのは、Kotlinの型推論という機能が働き、自動的に戻り値の値から型を判断しているのです。

以上のことから、Kotlinの関数定義の略記は

fun 関数名(引数名:引数の型) = 戻り値

となります。

3.Introduction/Named argumentsの解説

Kotiln Koans Introduction/Named argumentsの解説です。
随時本サイトの内容を引用させていただきます。

まずは、右側の本文を見てみましょう。

Default and named arguments help to minimize the number of overloads and improve the

readability of the function invocation. The library function joinToString is declared with

default values for parameters:

fun joinToString(
    separator: String = ", ",
    prefix: String = "",
    postfix: String = "",
        /* ... */
): String

It can be called on a collection of Strings. Specifying only two arguments make the function

joinOptions() return the list in a JSON format (e.g., "[a, b, c]")

default引数とnamed引数はオーバーロードの数を最少化し、関数実行の際の可読性を高める。
ライブラリのjoinToString()関数は、デフォルトの値が引数に設定されて宣言されている。
この関数はString型のコレクションから呼び出すことができる。
2個の引数を設定してjoinOptions()関数がlistをJSONフォーマットで返すようにしなさい。

と書かれています。

つまり、左側の

fun joinOptions(options: Collection<String>) = options.joinToString(TODO())

という式のTODO()部分に適切な引数を渡し、listをJSONフォーマットで返すようにしなさい。

ということになります。

joinToString()関数は、

  • 引数separatorには,
  • 引数prefixとpostfixには空文字

指定されています。

(いずれの引数も名前があり値が入っていますので、default引数かつnamed引数ですね。)

本文中の例のようなJSONフォーマット[a, b, c]をつくるには、引数として[]を指定する必要があります。

ですので、

TODO()の箇所を

prefix = "[",postfix = "]"

とすればいいですね。

最後に

次回はKotlin Koans Introducion/Defalut argumentsの解説をします:muscle:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Quick Appの開発方法

前書き

日本ではQuick Appがあまり知られていません。しかし、Quick Appはすでに170ヶ国以上展開されています。本稿はQuick Appの特徴と開発手順を紹介するものです。

Quick Appの概要

ユーザーがAndroid上で動かすサービスが主に2つあります。

  • ネイティブアプリ(Androidアプリ)
  • ウェブアプリ(ブラウザでウェブサイトを開く)

さらにQuick Appを加えれば、合計3つあります。

Quick Appの開発方法を述べる前に、ネイティブアプリとウェブアプリとQuick Appの特徴を比べてみたいです。

ネイティブアプリの特徴

  • インストールが必要
  • デバイス機能が使用可能
  • リリース時の審査あり
  • iOS同時対応不可
  • 開発言語(Java、Kotlin)
  • APKの容量が大きい(数十MB以上のアプリが多く、100MBを超えるアプリも少なくない)

ウェブアプリの特徴

  • インストールが不要
  • デバイス機能が使用不可
  • リリース時の審査なし
  • iOS同時対応可
  • 開発言語(HTML、CSS、JS)
  • 容量が小さい

Quick Appの特徴

  • インストールが不要
  • デバイス機能が使用可能
  • リリース時の審査あり
  • iOS同時対応不可
  • 開発言語(HTML、CSS、JS)
  • 容量が4MBまで

性能比較

ネイティブアプリ、ウェブアプリ、Quick Appの性能調査結果が次の通りです。
スクリーンショット 2020-10-08 144822.png

まとめ

ネイティブアプリ ウェブアプリ Quick App
インストールの有無 必要 不要 不要
デバイス機能の使用 可能 不可 可能
リリース時の審査 あり なし あり
iOS同時対応 不可 可能 不可
アプリのサイズ 大きい 小さい 小さい
起動時間 遅い 速い 速い
操作性 良い 普通 良い
メモリ使用量 少ない 多い 少ない

AppGalleryのQuick Appの紹介

Quick AppはAppGalleryで検索できます。AppGalleryがインストールされていない方は、こちらのページ(AppGallery をインストールするにはどうすればよいでしょうか)を参考に、AppGalleryをダウンロードし、インストールしておいてください。

AppGalleryを開き、QuickAppをタップします。
image.png

ここでさらに検索をかけます。実行したいQuick Appは”開く”ボタンをタップして実行します。
image.png

例として、”楽天市場”を開いてみましょう。
image.png

Quick App終了時に、そのQuick Appを追加しておくと、次回起動するときに便利です。
image.png

Quick Appの開発手順

Quick Appの開発手順はAndroidアプリのとほとんど同じです。それでは、詳しい手順を説明しましょう。

Quick Appの開発環境

Quick Appを開発するのに、以下のものが必要です。それらをダウンロードしてインストールしてください。

AppGallery Connect側の作業

AppGallery Connect側の作業はHMS Account Kit実装入門の前準備をご参照ください。ただ、注意しなければならないのは、アプリの追加画面でQuick Appを選ぶことです。
image.png

Huawei quick app IDE

Huawei quick app IDEを起動し、“New Project”をクリックします。
image.png

“App Name”と“Package Name”を設定します。
簡単なQuick Appの作り方を示したいので、Templateでは今回はHTML5 Appを選びます。
image.png

OKボタンをクリックしたら、プロジェクトが生成され、次のような画面に遷移します。
コーディングに入る前に、指紋ボタンをクリックし、署名を設定しておきます。
image.png

署名が作成されたら、証明書が/sign/releaseに格納されます。
image.png

スクリーンショット 2020-10-08 233351.png

ここでさらに/sign/debugフォルダを作り、/sign/releaseにあるcertificate.pemとprivate.pemをここにコピーします。
スクリーンショット 2020-10-08 233533.png

もう一度指紋ボタンをクリックします。クリックしたら、Fingerprint(公開鍵暗号)が表示されます。それをコピーします。
image.png

AppGallery Connectの[My Projects] -> [General information] -> [App information] -> [SHA-256 certificate fingerprint]に、コピーした公開鍵暗号をセットします。
スクリーンショット 2020-10-08 234731.png

Quick Appのコーディング

Quick Appはウェブアプリと同じく、HTML、CSS、JSで開発します。ウェブアプリの開発経験がある方なら、すぐ慣れると思います。

プロジェクトの構成

プロジェクトは次のパーツより構成されます。

  • manifest.json
  • app.ux
  • /Common/[リソースファイル]
  • /[ページ名]/[ページ名のuxファイル]

詳しくはこちらをご参照ください。
Quick App Reference

manifest.json

基本的にAndroidManifest.xmlと同じものだと考えればよいです。
スクリーンショット 2020-10-09 000313.png

app.uxファイル

すべてのページ(app.ux以外のuxファイル)に使われるものはここで定義します。

uxファイル

uxファイルはtemplateとstyleとscriptで構成されます。それぞれのブロックのプログラミング言語が違います。templateはhtml5、styleはcss、scriptはjavaScriptになります。

スクリーンショット 2020-10-09 001731.png

Quick Appのサンプル

試しに楽天市場のQuick Appを作ってみましょう。

まずloadUrlの値を "https://www.rakuten.co.jp/" に変えます。
スクリーンショット 2020-10-09 002458.png

デバッグボタンをクリックします。
スクリーンショット 2020-10-09 002805.png

Huawei Quick App LoaderがAndroid端末にインストールされていない場合はダイアログが出ます。ここでインストールします。
スクリーンショット 2020-10-09 003650.png

楽天市場が出てきました。右上のフローティング操作ボタンをドラッグして別の場所に移動できます。
image.png

終わり

Quick Appは高いポテンシャルを秘めているので、皆さんもぜひ試してみてください。

参考ページ

Quick Appの概要
Quick Appのガイド
Quick AppのAPI

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む