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

Wi-Fi接続状況を監視するのにCONNECTIVITY_ACTIONが廃止予定なので、requestNetworkで監視してみた

はじめに

タイトル通り、今までWi-Fi接続状況を監視するのに、ConnectivityManager#CONNECTIVITY_ACTIONをBroadcastReceiverに登録して監視していましたが、公式を見るとAPIレベル28で廃止されるとのことなので、ConnectivityManager#requestNetworkを使用して監視してみました。

ConnectivityManager#CONNECTIVITY_ACTION

CONNECTIVITY_ACTION.kt
// Receiver登録
IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).also {
    registerReceiver(wifiBroadcastReceiver, it)
}

// Receiver
val wifiBroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        context ?: return
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val activeNetwork = cm.activeNetworkInfo
        activeNetwork.also { info ->
            val isConnected = info.isConnectedOrConnecting
            val isWifi = info.type == ConnectivityManager.TYPE_WIFI
            val isMobile = info.type == ConnectivityManager.TYPE_MOBILE
        }
    }
}

ConnectivityManager#requestNetwork

requestNetwork.kt
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

val request = NetworkRequest
    .Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
    .build()

val networkCallback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network?) {
        super.onAvailable(network)
        // ネットワークが使用可能になったときの処理
        val capabilities = cm.getNetworkCapabilities(network)
        val isWifi = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
        val isMobile = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
    }

    override fun onLost(network: Network?) {
        super.onLost(network)
        // ネットワークの接続が切れたときの処理
    }

    override fun onUnavailable() {
        super.onUnavailable()
        // ネットワークが使用不可になったときの処理
    }
}

cm.requestNetwork(request, networkCallback)

おわりに

ConnectivityManager#requestNetworkはWi-Fiだけでなく、様々なネットワークと状態を監視できます。より汎用的になった、ということでしょうか。

参考

ConnectivityManager
Android Q の機能と API

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

SpekでLifecycleを利用したテストをする方法

例えば val liveData: LiveData<Int> みたいな値があってそれのライフサイクルに応じた変化をテストしたい場合

なぜこんなことをしたいかというと、RxJava→LiveDataの変換をした際に、初期値が正しく設定されるかなどのテストをしたかったので、Lifecycleを利用する方法を調べた。

全体のテストコード

object LifecycleTest : Spek({
    Feature("hoge機能") {
        val lifeCycleObserver: LifecycleObserver by memoized { mockk<LifecycleObserver>() }
        val lifeCycleOwner: LifecycleOwner by memoized { mockk<LifecycleOwner>() }
        val lifeCycle: LifecycleRegistry by memoized { LifecycleRegistry(lifeCycleOwner) }

        val observer: Observer<Int> by memoized { mockk<Observer<Int>>(relaxed = true) }


        beforeEachTest {
            every {
                lifeCycleOwner.lifecycle
            } returns lifeCycle

            lifeCycle.addObserver(lifeCycleObserver)
        }

        Scenario("開始状態") {

            Given("LiveDataを購読") {
                liveData.observe(lifeCycleOwner, observer)
            }

            When("ライフサイクルを開始状態にする") {
                lifeCycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
                lifeCycle.handleLifecycleEvent(Lifecycle.Event.ON_START)
            }

            Then("期待値") {
                verifySequence {
                    observer.onChanged(1)
                }
            }
        }

    }
})

Lifecycleの設定

Lifecycle関連のコード
val lifeCycleObserver: LifecycleObserver by memoized { mockk<LifecycleObserver>() }
val lifeCycleOwner: LifecycleOwner by memoized { mockk<LifecycleOwner>() }
val lifeCycle: LifecycleRegistry by memoized { LifecycleRegistry(lifeCycleOwner) }

beforeEachTest {
    every {
        lifeCycleOwner.lifecycle
    } returns lifeCycle

    lifeCycle.addObserver(lifeCycleObserver)
}

lifeCycleOwnerをLiveDataにわたすOwnerにし、 mockkで lifeCycleOwner.lifecycle の戻り値を LifecycleRegistry になるようにモック化

LifecycleRegistry にObserverが1件も無いステータスを変化するロジックで以下のコード部分で mObserverMap.sizeが0になり、更新されなくなってしまうのでダミーで lifeCycle.addObserver(lifeCycleObserver) している。

LifecycleRegistry.kt
    private boolean isSynced() {
        if (mObserverMap.size() == 0) {
            return true;
        }
        State eldestObserverState = mObserverMap.eldest().getValue().mState;
        State newestObserverState = mObserverMap.newest().getValue().mState;
        return eldestObserverState == newestObserverState && mState == newestObserverState;
    }

Lifecycleの設定

lifeCycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
lifeCycle.handleLifecycleEvent(Lifecycle.Event.ON_START)

こんな感じで lifeCycle.handleLifecycleEvent を呼ぶことで状態遷移を起こすことができる。

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

【Android / Glide】Glideで角を丸くする

こんにちは。
電車が遅延してるので記事書くことにしました。

本題

Glideで角を丸くしたい。

Glideとは

https://github.com/bumptech/glide
ImageViewに画像を表示させるときによくお世話になるライブラリ。
主にインターネットの画像を表示させたりGIF画像を表示させたいときに使う。便利

導入する

詳しくはいませんが
appの中のbuild.gradleを開いて以下一行追加

dependencies {
    implementation 'com.github.bumptech.glide:glide:4.9.0' //これ
}

build.gradleを開いて同じように一行追加

repositories {
   mavenCentral()  //これ
}

あとは同期して完了です。

実装する

今回はKotlinで書きます!
読み込むリンクが私のアイコンになってるので適宜書き換えてください。
一行追加すれば角が丸くなるはずです。

MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        //Glide
        Glide.with(imageView)
            .load("https://media.best-friends.chat/accounts/avatars/000/020/498/static/bc0bd14abb0bb063.png")
            .apply(RequestOptions.bitmapTransform(RoundedCorners(30))) //←この一行追加
            .into(imageView)

    }
}

どうしてもJavaがほしい方はどぞ

apply(RequestOptions.bitmapTransform(RoundedCorners(30)))

レイアウトですが、親?のLinearLayoutの背景を灰色にして(見やすくするため)
Gravityを真ん中にして
ImageViewをおいてるだけです。

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:gravity="center"
        android:background="@android:color/darker_gray"
        android:layout_height="match_parent"
        tools:context=".MainActivity" android:orientation="vertical">


    <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:id="@+id/imageView"/>
</LinearLayout>

これで動きます!

完成品

Screenshot_20190719-084941.png

しっかり角が丸くなってますね!おめでとうございます!

おまけ

この一行でも動いたので動かない方はどうぞ。
違いはよくわかりません。ごめん
Kotlin

transform(CenterCrop(),RoundedCorners(30))

Java

transform(new CenterCrop(),new RoundedCorners(10))

おつかれさまです

前から丸くしたかったので今回できて嬉しいです。

参考にしました。

https://stackoverflow.com/questions/45186181/glide-rounded-corner-transform-issue

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

【Programming News】Qiitaまとめ記事 July 18, 2019 Vol.4

筆者が昨日2019/7/18(木)に気になったQiitaの記事をまとめました。昨日のまとめ記事はこちら

Java

Python

Node.js

Nuxt.js

Swift

Laravel

MySQL

Git

Visual Studio

AWS

Docker

Google Apps Script

Develop

Raspberry

UML

Go言語

R言語

awk

LaTex

Redmine

更新情報

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