布団の中にいたい

Elasticsearchいじったり、Androidアプリ書いたり。最近は数学の勉強が楽しくなってきました。

onKeyDownじゃなくて,onBackPressedでよかったみたい

以前に戻るボタンの動作をhandlingするには,onKeyDownを使うみたいな記事を書いたが,戻るボタンだけでいいなら,onBackPressedをoverrideするだけで良いみたい.

onBackPressedの方がメソッド名が明確でわかりやすいので,戻るボタンだけの用途ならonBackPressedを使ったほうがよさそう.

onKeyDownのときの実装

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    // 戻るボタンが押される かつ webviewで前に戻ることができるとき
    if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
        // 前のページに戻る
        webView.goBack()
        return true
    }

    return super.onKeyDown(keyCode, event)
}

onBackPressedのときの実装

override fun onBackPressed() {
    super.onBackPressed()

    if (webView.canGoBack) {
        webView.goBack()
    }
}

AndroidのToolbarに戻るボタンをつける

Listの要素をタップしたら別のActivityに遷移してWebViewを表示する,みたいな挙動な挙動を実装しようとしているが,前回端末の戻るボタンを押したときにページバックするという実装を行ったせいでどんどんリンク先に進んでいくと前のActivityに戻りづらくなってしまいました.今回はToolbarに戻るボタンを表示して,戻るボタンがタップされたときに,前のActivityに戻るという挙動を実装しました.

やることはかなり単純.そもそもToolbar自体に戻るボタン(Home)を表示するかどうかというメソッドがあるので,それをtrueにして,戻るボタンがタップされたときに,現在のActivityを終了するというだけ.以下はそのコード.だいたい簡略化してますが.

class SampleActivity : AppCompatActivity() {

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

        val toolBar = findViewById(R.id.toolBar) as Toolbar
        val webView = findViewById(R.id.webView) as WebView

        setSupportActionBar(toolBar)

        // Toolbarに戻るボタンを表示する
        supportActionBar!!.setDisplayHomeAsUpEnabled(true)
        webView.loadUrl(url)
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        when (item!!.itemId) {
            // 戻るボタンが押されたら
            android.R.id.home -> {
                // 現在のActivityを終了する
                finish()
            }
        }

        return super.onOptionsItemSelected(item)
    }
}

WebViewで戻るボタンを押したときに前のページに戻るようにする

AndroidでWebViewを使用して端末の戻るボタンをおした時,前のページに戻るのではなく,前のActivityに戻ってしまう状況になって色々困ったのでメモ.

このような状況で「前のページに戻る」という挙動を実装するには戻るボタンが押されたというイベントをフックする必要がある.Androidでは端末のボタンが押されたときに,onKeyDownというメソッドが呼ばれるので,onKeyDownをoverrideして,戻るボタンが押されたときに前のページに戻るという動作を差し込んでしまえばいい.以下がそのコード.

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    // 戻るボタンが押される かつ webviewで前に戻ることができるとき
    if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
        // 前のページに戻る
        webView.goBack()
        return true
    }

    return super.onKeyDown(keyCode, event)
}

今回は戻るボタンでしたが,他のボタンが押されたときでもKeyEventで指定してしまえばいいので,汎用性はありそうだなーという印象.

AndroidアプリからURLスキームでTwitterアプリに飛ばす

自分で実装中のアプリでTwitterの検索に飛ばす必要があったときに調べた内容です.

やったこととしては以下の2つです.

  • Twitterのアプリがインストールされているかを確認
  • インストールされていればTwitterアプリに,されてなければブラウザに飛ばす.

Twitterのアプリがインストールされているかを確認

アプリがインストールされているかはPackageManagerのgetPackInfoで調べられます.

PackageManager | Android Developers

class Utils {
    companion object {
        fun isApplicationInstalled(context: Context, uri: String): Boolean {
            val pm = context.packageManager

            try {
                pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
                return true
            } catch (e: PackageManager.NameNotFoundException) {
                return false
            }
        }
    }
}

getPackageInfoで指定されたアプリがなければ,PackageManager.NameNotFoundExceptionが投げられるので,そこでfalseを入れてreturnしてあげればアプリの有無を判定できます.ちなみにTwitterのpackageはcom.twitter.androidです.google playのアプリページのurlのquery stringのidパラメータを見ればわかります.

インストールされていればTwitterアプリに,されてなければブラウザに飛ばす

アプリの存在判定ができたので,後はそれで分岐させてインストールされていればアプリに,なければブラウザに飛ばすだけです.

画面遷移は普通にintentで実現できます.今回の場合,遷移先のActivityが明示的ではないので,俗に言う暗黙的intentってやつになります.暗黙的intentの場合,intentの第一引数にActionに設定します.Actionはデータ表示や電話をかけたりなど幾つかのActionがあるみたいです.今回の場合,どちらにしろデータ表示するだけなので,Intent.ACTION_VIEWを使用します.今回は以下みたいな感じでやりました.

val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)

まとめ

まだAndroidの勉強を初めて間もないですが,割りと使用していたのはActivity間の遷移だったので,今回のような暗黙的intentみたいなのはなかなかよく分からず大変でした.こういう知見を少しずつ貯めていきたいと思います.

WebViewでlinkタップ時にブラウザに飛ばないようにする

WebViewでlinkやボタンをタップすると,何もしていない場合だとWebViewからデフォルトのブラウザに飛ばされます.今回はWebViewからブラウザに飛ばすのではなく,WebView内で完結させたかったので,そのやり方を調べました.

やり方は簡単で以下でできるようです.

webView.setWebViewClient(object : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
        return false
    }
})

WebViewClient | Android Developers

shouldOverrideUrlLoadingはWebViewで新しいurlに対してloadingが走ったときに呼ばれるメソッドです.ブラウザに飛ばないようにするためにはWebViewに設定するWebViewClientでshouldOverrideUrlLoadingでfalseを返してあげればいいです.

「基礎からのWebアプリケーション開発入門」を読んだ

年末年始に書けて積んでいた本の一冊を読んだので感想を.

今回読んだのは「基礎からのWebアプリケーション開発入門」です.

前評判で,httpの詳細から入るという話を聞いていたので読みましたが,個人的には色々勉強になった本でした.以下に簡単な感想を.

  • よくある「色々ツールを組み合わせて作ってみました」みたいなやつではなく,HTTP・RFCの説明から入り,「なぜそのようなことをやる必要があるのか」が明確に記述されていたので納得がいった.
  • Webアプリケーションなどの開発をしてはいるが,「どこに」「どのように」データが入っているかを特に理解していなかったが,headerの説明でなんとなくわかった.
  • Cookie・Sessionなど使いつつも「こういうもの」だとしてどうなっているかを把握できていなかったものに対する説明が細かったので勉強になった
  • 「6章Webアプリ開発に必要なその他の知識」の内容は学生時代に授業でやった内容に近かったので復習になってよかった

総合的に見て,Webアプリを作ってみようと考えてる人にはおすすめな一冊だと思います.

ブログ移行

元々github.ioで勉強になったことなんかを書いていたのだけど,手元に新しい端末が来るたびにその環境を作るのが面倒くさくなってしまったので,はてなブログへ移行します.

興味のあるトピックとしては

ぐらいですかね.最近はAndroidの勉強をしていることが多いので,その辺のログが多くなると思います.

では.