20200818のAndroidに関する記事は6件です。

【Flutter】画面サイズに応じて文字サイズを自動で適用する方法

この記事を読んで習得できること

画面サイズに応じて文字サイズを自動で変えることができるようになる。
結構使うことになるので備忘録として。

結論

TextFittedBox配下に置く。

sample.dart
FittedBox(
  fit: BoxFit.fitWidth,
  child: Text(
    "あああああああああああああああああああああああテトラポット",
    style: TextStyle(fontSize: 32),
  ),
),

スクリーンショット 2020-08-18 23.42.39.png

FittedBoxがなかったら

折り返したり、画面からはみ出たりして、画面がぶっ壊れてしまう。

sample.dart
Text(
  "あああああああああああああああああああああああテトラポット",
  style: TextStyle(fontSize: 32),
),

スクリーンショット 2020-08-18 23.41.56.png

なので、この方法を覚えておくといいかも。

Swiftだとどうやって書くんだっけ?
interface builderでいつも設定してたから覚えてないや…
復習しないとな…

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

kotlinとjavaで関数を作りたい!

はじめに…

この記事は3個前の記事で書いた、

7日間毎日記事投稿の4日目

になってます

使うコードは下に貼りますが、このアプリの詳しい機能はその3個前の記事をご覧ください!

↓ここからが今回の記事の本題です↓

それぞれの言語で関数を作るには…

  • javaの場合
修飾子 戻り値の型 関数名(引数, 引数, ) {
    関数の内容
    return 戻り値
}

例)
※ 引数なし、戻り値なしの関数を定義している

WhoActivity.java
private void addMember() {  // 78行目
    EditText memberET = findViewById(R.id.member_et);
    ListView memberLV = findViewById(R.id.member_lv);
    memberL.add(memberET.getText().toString());
    memberET.getEditableText().clear();
    ArrayList<String> memberLR = (ArrayList<String>) memberL.clone();
    Collections.reverse(memberLR);
    ArrayAdapter<String> adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, memberLR);
    memberLV.setAdapter(adapter);
    }
  • kotlinの場合
fun 関数名(引数:型, 引数:型, …): 戻り値の型 {
    関数の内容
    return 戻り値
}

例)
※ 引数なし、戻り値なしの関数を定義している

WhoActivity.kt
fun addMember() {  // 52行目
    memberL.add(member_et.text.toString())
    member_et?.text?.clear()
    var memverLR = ArrayList<String>(memberL)
    memverLR.reverse()
    var adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, memverLR)
    member_lv.adapter = adapter
}

書き方は大きく違うが、関数定義時に必要な情報はほとんど変わらない。

最後に…

今回はjavaとkotlinで関数の定義をしました。
引数の種類・戻り値の種類によって様々な機能の関数を定義できるので、これからも多用できたらなと思います。

明日も記事を投稿するので、引き続き温かく見守ってください。

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

AndroidでKotlin Coroutinesを導入する際の注意点

導入方法

AndroidでCoroutinesを導入する際は、app/build.gradleに以下のように記載します。
バージョンは特に理由がなければ最新版を指定するのが望ましいでしょう。

build.gradle
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7'

注意点

以下に導入する際に起きたトラブルおよび原因、解決方法を記載します。

VerifyErrorによるアプリクラッシュ

Kotlin 1.3系(私の環境では1.3.41)を使用している場合に、Coroutinesのバージョンを1.3.7にすると、コルーチンの処理を呼び出したときにVerifyErrorが発生してアプリがクラッシュしました。

java.lang.VerifyError: Verifier rejected class com.volcast.data.VolcastRepositoryImpl: java.lang.Object com.volcast.data.VolcastRepositoryImpl.refresh(kotlin.coroutines.Continuation) failed to verify: java.lang.Object com.volcast.data.VolcastRepositoryImpl.refresh(kotlin.coroutines.Continuation): [0x12F] register v3 has type Reference: java.lang.Exception but expected Precise Reference: kotlin.jvm.internal.Ref$ObjectRef (declaration of 'com.volcast.data.VolcastRepositoryImpl' appears in /data/app/com.volcast.temp-6UrzwdYgEJRIKC9aa-RzVQ==/base.apk!classes2.dex)
        at com.volcast.di.DataModuleKt$dataModule$1$12.invoke(DataModule.kt:58)
        at com.volcast.di.DataModuleKt$dataModule$1$12.invoke(Unknown Source:4)
        at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
        at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:36)
        at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
        at org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
        at org.koin.core.scope.Scope.get(Scope.kt:181)
        at com.volcast.di.ViewModelModuleKt$viewModelModule$1$7.invoke(ViewModelModule.kt:72)
        at com.volcast.di.ViewModelModuleKt$viewModelModule$1$7.invoke(Unknown Source:4)

原因

原因としては、どうやらコンパイラのバグのようです。
https://github.com/Kotlin/kotlinx.coroutines/issues/2049#issuecomment-638120448
(こちらではどうすることもできないやつですね。。)

解決策

解決策として、Kotlinを1.4以降にアップデートするか、Coroutinesのバージョンを1.3.6にダウングレードすることで解消できます。

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.6'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.6'

ちなみに2020年8月18日時点でCoroutinesの1.3.9がリリースされているものの、当問題が解決しているかはリリースノートを見る限り不明です。
(もし1.3.9にしたら動いた!という方がいましたら教えていただけると大変喜びます)
Releases · Kotlin/kotlinx.coroutines · GitHub

Kotlinをアップデートできるのなら、最新版を使えるという点でアップデートしたほうが良いかもしれません。
(とはいえプロジェクトの関係でいきなりバージョンアップできないことが多いかと思いますので、その時は大人しく1.3.6にしましょう)

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

MarketingCloudSDK In-App Messaging概要

In-App Messagingとは

ユーザがアプリのプッシュ通知を許可していなくてもユーザにメッセージを配信できるアプリ内メッセージのことです。
アプリがフォアグラウンドの状態になる度にアプリ内メッセージが読み込まれ、SMCで作成したメッセージが、アプリのビュースタックの最上部に表示されます。(閉じたメッセージは再度表示されません)

メッセージのテンプレートは以下3つがあります

フルページ
 レイアウトが画面全体に表示される
バナー
 画面最下部または最上部に表示される
モーダル
 画面の一部に全面表示される

上記3つともSMCのContent Builderで設定可能です。
また色や、画像の配置、フォントサイズなどカスタマイズ可能になっています。
※文字のフォントに関してはデバイスのシステムフォントを使用しているため、アプリ側のフォント上書きの実装が必要です。

通知するにはJourneyBuilderからアプリ内メッセージの送信が必要です。

実装

以下、公式ドキュメントから参照となります。

1.アプリ内メッセージング機能をViewControllerにデリゲートするためにsfmc_setEventDelegateメソッドを使用を使用する

ViewController.swift
// クラス宣言のMarketingCloudSDKEventDelegateプロトコルに従います。
class MyViewController: UIViewController, MarketingCloudSDKEventDelegate

...

// 実装のどこかで、アプリ内メッセージイベントのためのSDKのデリゲートとしてクラスを設定します。

// 可能であれば、クラスの初期化の早い段階で行う必要があります。
MarketingCloudSDK.sharedInstance().sfmc_setEventDelegate(self)

2.ビューの表示や削除に対応するデリゲートメソッドを追加する

ViewController.swift
func sfmc_didShow(inAppMessage message: [AnyHashable : Any]) {
    // message shown
}

func sfmc_didClose(inAppMessage message: [AnyHashable : Any]) {
    // message closed
}

3.アプリ内メッセージの表示を遅延させたり、防止したりすることができる。例えば、ロード中、インストラクション中、サインインフロー中などにアプリ内メッセージが表示されないようにする。メッセージの表示を防ぐには、shouldShowInAppMessageメソッドをfalseを返すようにする。

ViewController.swift
func sfmc_shouldShow(inAppMessage message: [AnyHashable : Any]) -> Bool {
    // メッセージを表示するタイミングなどのロジックを書く
    if (self.messageCanBeShown) {
        return true
    }
    else {
        // メッセージデータを取得するできる
        self.showMessageId = self.sdk.sfmc_messageId(forMessage: message)
    }
    return false
}

4.メッセージデータを取得(sfmc_messageIdForMessage)して、後から表示(sfmc_showInAppMessage)することが可能

ViewController.swift
if (self.showMessageId != nil) {
    MarketingCloudSDK.sharedInstance().sfmc_show(inAppMessage: self.showMessageId)
}

5.アプリ内メッセージのフォントを変更するなら以下のデリゲートメソッドを使用し、デバイスにインストールされているフォントまたはアプリのカスタムフォントの有効なフォント名をSDKに渡す。

ViewController.swift
MarketingCloudSDK.sharedInstance().sfmc_set(inAppMessageFontName: "Zapfino")

参考リンク(公式)

https://salesforce-marketingcloud.github.io/MarketingCloudSDK-iOS/in-app-message/in-app-messaging.html

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

AndroidでのUnitTestざっくり入門

  • Android Studio 4.0.1
  • Kotlin: 1.3.72
  • robolectric:4.3
  • Windows 10

Androidアプリ開発でUnitTestをします。
出来る限り実機やエミュレータを使わず、JavaVM上で動かしサクサクテストできるような環境を目指します。

テストケースの種類

InstrumentedTest

  • app/src/androidTest
  • 実機もしくはエミュレータ上で実行される
  • ExampleInstrumentedTest.ktというサンプルが作られる
  • 今回は、こちらはできるだけ使用しない方針です。

UnitTest

  • app/src/test
  • PCのJavaVM上で実行される
  • ExampleUnitTest.ktというサンプルが作られる
  • 今回はこちらをメインで使用していきます。

テストケース実行

  • Android Studio にて該当のパッケージ、クラス、メソッドで右クリック→ Run Testsで実行できる

テストケース作成

  • 該当の パッケージ名(androidTest) もしくはパッケージ名(test) にクラスを作成
  • 実行するテストメソッドに@Testをつけます
SampleUnitTest.kt
package jp.co.sankosc.sample

import org.junit.Assert.*
import org.junit.Test

class SampleUnitTest {
    @Test
    fun addition_isCorrect() {
        assertEquals(4, 2 + 2)
    }
}

robolectricの準備

bundle.gradle(app)
android {
  testOptions {
    unitTests {
      includeAndroidResources = true
    }
  }
}

dependencies {
  testImplementation 'org.robolectric:robolectric:4.3'
}

sdk=29では動かなかったため、robolectricをskd=28で実行するよう設定します。
app/src/test/resources/[パッケージ] にrobolectric.propertiesファイルを作成します

app/src/test/resources/jp/co/sankosc/sample/robolectric.properties
sdk=28

Activityのテスト

SampleUnitTest.kt
package jp.co.sankosc.sample

import android.widget.TextView
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner

@RunWith(RobolectricTestRunner::class)
class SampleUnitTest {
    @Test
    fun testActivity() {
        val activity:MainActivity = Robolectric.buildActivity(MainActivity::class.java).setup().get()
        val text = activity.findViewById<TextView>(R.id.textView).text
        Assert.assertEquals("Hello World!", text)
    }
}

Realmについて

いろいろ試行錯誤しましたが、RealmをRobolectric使ってUnitTestで動かすことはできませんでした。RealmのテストはInstrumentedTestの方でやるしかなさそうです。

また、Realmを使ったアプリを作っているとUnitTestが動かなくなる場合があります。
Realmの初期化を、Applicationクラスで行っている場合で、この場合はテストのときはApplicationクラスでRealmの初期化をしないようにしておく必要があります。

何もしないApplicationクラスを作る

AppUnitTest
package jp.co.sankosc.sample

import android.app.Application

class AppUnitTest : Application()

robolectric.propertiesでRobolectricのApplicationクラスを指定する

app/src/test/resources/jp/co/sankosc/sample/robolectric.properties
sdk=28
application=jp.co.sankosc.sample.AppUnitTest

Realmの準備はこちらをご参照ください:Android,KotlinでRealm

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

[Android Studio]本番環境をデバッグ可能にする

忘備録。

問題

以下はエラー内容。
本番環境をデバッグできるようにしたい。

Error running 'app'
            Cannot debug application from module app on device emulator-5554.
            This application does not have the debuggable attribute enabled in its manifest.
            If you have manually set it in the manifest, then remove it and let the IDE automatically assign it.
            If you are using Gradle, make sure that your current variant is debuggable.

解決策

build.gradle に記載されている設定 debuggable をfalseからtrueへ変更

build.gradle
    buildTypes {
        release {
            debuggable true //変更

その後、メニューからBuild Bundle。
(Androidに不慣れすぎてこれに気づかなくて変更反映されなくて焦った)
スクリーンショット 2020-08-18 12.13.15.png

補足

Build Variantをdebugに変更する解決策もあるっぽいけど、これは今回やりたかったことではなかった。
スクリーンショット 2020-08-18 11.30.00.png

参考

アプリをビルドして実行する  |  Android デベロッパー  |  Android Developers
android - This application does not have the debuggable attribute enabled in its manifest - Stack Overflow

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