Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

暗黙的Intent その3 Chromeの「共有」から送られてきた文字列を受け取る!

 どうも!LSSです!

 

 AndroidStudio+Kotlinでアプリ開発の勉強中です。

 

 なんとなくやってみたくなった
Chromeの共有の候補に自作アプリを入れて、Intentを受け取るシリーズ」
ですが、前回の「その2」では
「AndroidManifest.xmlに数行コピペするだけで共有候補に出てきた!」
事であっさりと目的の大半は達成してしまいましたw

 

とはいえ、「共有候補に出てくるだけで何もしてくれないアプリ」だとクソ詐欺アプリなので、今回はしっかりと
「送られてきたデータを受け取って、自作アプリの画面上にとりあえず表示」
するところまでやってみます!

 

 

こういうのを作ります!

f:id:little_strange:20191222122421p:plain

 

 ReceivedActivity.kt

package jp.littlestrangesoftware.feedtest

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_received.*


class ReceivedActivity : AppCompatActivity() {

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

// EXTRA_TEXT は、URL
tv0.text = if (intent.getStringExtra("android.intent.extra.TEXT") == null) ""
else intent.getStringExtra("android.intent.extra.TEXT")

// EXTRA_SUBJECT は、Webページタイトル
tv1.text = if (intent.getStringExtra("android.intent.extra.SUBJECT") == null) ""
else intent.getStringExtra("android.intent.extra.SUBJECT")


// 他にどんな EXTRA があるのかを調査
val extras = intent.extras
var a = ""
for (key in extras!!.keySet()) {
a = a + key + "\n" + extras[key].toString() + "\n\n"
}
tv2.text = a
}
}

 

まず、xmlを変更!

 

f:id:little_strange:20191222122935p:plain

↑こんな風に、TextViewを縦に3つ並べて、それぞれidを「tv0」「tv1」「tv2」としました。

 また、それぞれに適当に背景色をつけて、どれがどれか見分けられるようにしてます。

 

 

普通のIntentデータの受け取り方でOKでした^^

 最初、暗黙的Intentについて調べていた時に、
「BroadcastReceiverクラスを継承したクラスを作成する必要がある」とか
「BroadcastReceiverは扱いが面倒」みたいな記事を見かけていましたが、
今回の場合はBroadcastReceiverに関わらずに済みました!w

 

 明示的Intentで「別の画面に画面遷移する際にデータを送る」ことができるんですが、それは入門書にもさらっと書かれている程度に難易度は低いものです。
(自分はまだそれでも試していませんでしたがw)

 

で、明示的Intentも暗黙的Intentも「Intentである事に変わりない」んで、更に色々調べつつ、結局は…

 

intent.getStringExtra("android.intent.extra.TEXT")

でWebページのURLを文字列(String)型で、

intent.getStringExtra("android.intent.extra.SUBJECT")

でWebページのタイトルを同じく文字列(String)型で受け取れます^^

 

 まず最初のintentですが、Javaの場合はIntent型の変数を用意して…という手順が必要なのに対し、Kotlinはいきなりintentって書くだけで、それが受け取ったIntentを示すものとして使えるようです。

 自分のような面倒くさがりに優しい、Kotlinのこういうところが好き💛

 

 次にgetStringExtraですが、このStringの部分は送られてくるデータ型によって何種類かあります。
 今回は文字列なのでStringですね。

 ExtraっていうのがIntentの送受信に使われてる仕組みで、
「複数の『キーと値のペア』をまとめて一括で送る」
のに利用されているようです。

 

 そんで、そのあとの()の中にキーを指定する事で、そのキーに応じた値が取り出せます。

 

 今回の「Chromeの共有から送られてきたデータ」の場合は、

"android.intent.extra.TEXT"

っていうキーに対応する値として、そのWebページのURLが入っていて、

"android.intent.extra.TEXT"

っていうキーに対応する値として、そのWebページのタイトルがでてくるんですね。

 

 コードとしては、

// EXTRA_TEXT は、URL
tv0.text = if (intent.getStringExtra("android.intent.extra.TEXT") == null) ""
else intent.getStringExtra("android.intent.extra.TEXT")

のように、一応nullだった場合の対策をとった書き方をしています。
(そうしないとAndroidStudioちゃんが気にするのでw)

 

f:id:little_strange:20191222122421p:plain

↑この水色のところがURL(extra.TEXT)、黄緑色のところがタイトル(extra.SUBJECT)です。

 

 

URLとタイトルは取り出せたけどさ、

「他にもなんか面白そうなデータが入ってるかも知れへんけど、キーが分からないと取り出せへんやん?入ってるデータ全部一覧で見られへんのん?」

って疑問が湧きましたw

 

 将来的に、Chromeの共有以外にも暗黙的Intentを使いたい場面がでてきた時なんかに、ググっても情報が出てこないと困りますし^^;

 

という事で、Extraの中身を全部洗いだす方法をまた調べて、見つけてきたコードに少し手を加えてみました。

 

// 他にどんな EXTRA があるのかを調査
val extras = intent.extras
var a = ""
for (key in extras!!.keySet()) {
a = a + key + "\n" + extras[key].toString() + "\n\n"
}
tv2.text = a

 

intent.extrasで、まず送られてきたデータ全体を取得(Bundle型?っていうのになるみたいです)、それに対してforループで順次「キーと値」を取り出していく、っていうコードですね。

 

 値は型が色々あるので、とりあえずtoString()で文字列型に変換しています。

 

で、中身を文字列化したものをtv2に代入したものがこちら!

f:id:little_strange:20191222133445p:plain

 

 今回使ったextra.SUBJECTとextra.TEXTの他に、

org.chromium.chrome.extra.TASK_ID

share_screenshot_as_stream

というデータがある事が分かりました。

 

…分かったのはいいですがこれ、ググっても何を意味してるかは分からなかったんですけどねwww
(後者はキーの名前から推測するに、画面イメージ?正しく取得すれば画像データを取り出せるのかも?)

 

 

あとは更新日時を取得できれば…

  このシリーズの最初の記事のコメントでいただいたようなRSS(っぽい事)ができそうかも?と思って試みたのですが(キーワード:lastModified)、やり方を見つけて、さらに苦戦しつつ(HTTPリクエスト初体験💛)やっと動いた!のに取得できなかったという状態です^^;

 

 サイトによってはhtmlファイルじゃなくPHPとかで都度、記事表示してる場合なんかにlastmodifiedでは取り出せないかな?と思い、自分のむかーし作った個人サイトのhtmlファイルを試してもみましたが、それでも取得できませんでした💦

 

 

てなとこで、今回はこのへんで!

 次回もまた、よろしくお願いします^^