- 投稿日:2020-10-13T23:11:26+09:00
2020年10月版ActivityResultAPIを使ってみた。
kotlinやandroidxの勉強も兼ねて、以前作った自作androidアプリケーションを一から作り直しているんですが、
Activity#startActivityForResult
は代わりにActivityResultAPIを使う事を薦められているとの事。いきなり使うのはためらうので、まずはテストプロジェクトで試してみましたが、まぁ、何ていうかその…。
トラブル解決に自信があるなら別にいいけど、そうでないならあと1年は様子見でいいよ。
テストしてみる。
とりあえずテストした結果を書いておきます。
まず、「
build.gradle
」に依存関係を書きます。dependencies { implementation "androidx.activity:activity:1.2.0-alpha08" implementation "androidx.activity:activity-ktx:1.2.0-alpha08" implementation "androidx.fragment:fragment:1.3.0-alpha06" }ここに注目。
というのも、結構新しいAPIなので、仕様が変わっていて、ネットの情報が間違っている事も多い。
ぶっちゃけ、これから書く内容も、将来的には間違いかもしれないですよ。そして、Activityのコード。
MainActivity.ktpackage com.example.test1012a import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.View import android.widget.TextView import android.content.Intent import android.app.Activity import android.util.Log import androidx.activity.result.contract.ActivityResultContracts import android.widget.Toast //private const val REQUEST_CODE = 1 class MainActivity(): AppCompatActivity(), View.OnClickListener { private val launcher = registerForActivityResult(ActivityResultContracts.CreateDocument()) { uri -> Log.d("test1012a", String.format("uri = %s.", uri.toString())) this@MainActivity.getContentResolver().openOutputStream(uri)?.writer()?.use { it.write("Hello, world!\n") } } protected override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) this.setContentView(R.layout.main) this.findViewById<View>(R.id.button1).setOnClickListener(this) } override fun onClick(view: View) { when (view.getId()) { R.id.button1 -> { // val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { // this.addCategory(Intent.CATEGORY_OPENABLE) // this.type = "*/*" // } // this.startActivityForResult(intent, REQUEST_CODE) this.launcher.launch("hoge") } } } // override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) // { // if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) { // resultData?.data?.also { // this.findViewById<TextView>(R.id.result).setText(it.toString()) // } // } // } }以下、ハマった点です。
prepareCall
ではなく、registerForActivityResult
先の公式サイトのとおりに記述したら、「
prepareCall
」でビルドエラー。
「なんでじゃー」と叫びつついろいろと探してみると、バージョン1.2.0-alpha04の変更点に以下の記述が。prepareCall() メソッドの名前が、ここの ComponentActivity と Fragment 1.3.0-alpha04 の両方で、registerForActivityResult() に変更されました。
ドキュメント直しておけよーー。
(これに限らず、最近のandroidのドキュメントはおざなりになっていない?量が膨大になってきたのはわかりますけど、わかりますけどね)「Can only use lower 16 bits for requestCode」
めでたくビルドが通って、実行してみると、ボタンを押した時点でアプリが落ちてしまいます。
ログを見てみると、「Can only use lower 16 bits for requestCode」とのエラーが出力。実は、当初依存関係に「fragment:1.3.0-alpha06」は含んでいなかったのです。いやだって、fragment使ってないし。
でも、試しに加えてみたら、エラーが発生しなくなりました。もしかすると、FragmentActivity
辺りが古いせいなのかもしれません。
- 投稿日:2020-10-13T22:23:19+09:00
【Android】WebViewで、mailto:とかtel:を開けずに詰まった話
【Android】WebViewで、mailtoとかtelを開けずに詰まった話
AndroidのWebViewで、WebView内のリンクをタップした時に、mailto:やtel:だと、schemeに対応していないというメッセージが表示されて、電話アプリやメーラーが起動できないで詰まってました。
参考
- 公式ドキュメント
- こちらを読めば、理解が深まるかと思います。
原因と対策
原因
- WebViewに対して、setWebViewClientをだけをしていたので、mailto:などのURLをWebViewでロードされるようになっていた。
- そもそもWebViewは、httpリソースを表示するようなので、mailto:やtel:などのURLスキームに対応していないみたい…(ドキュメントで明記されていたわけではないです。)
対策
- WebViewClientに、shouldOverrideUrlLoadingメソッドを実装してあげて、処理を記述する。
- 記事を調べると、メールアプリの起動や電話アプリの起動を、スキーマで判別して、暗黙的Intentで起動するとしているものが多かったけど、ただアプリを起動して値を渡すだけなら、ブラウザを起動させてurlを渡すだけで動きました。
- Intent.ACTION_VIEWのドキュメントに、mailto:、tel:に対応してアプリ起動すると記載がありました。
SampleWebViewActivity.ktpublic class SampleWebViewActivity extends FragmentActivity { private WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sample_web_view); // 仮にwebViewというidがあるとして mWebView = (WebView) findViewById(R.id.webview); mWebView.setWebViewClient(new WebViewClient(){ // 大事なのはここです! // ここで、WebView内でのurlのロード(リンクがタップされた時)を制御している @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { // ブラウザを起動しているだけ // ブラウザの方で、mailto:やtel:を制御してくれる。 val intent = new Intent(Intent.ACTION_VIEW, request.url); startActivity(intent); // trueを返さないと、webViewで、このurlをロードしてしまいます。 return true; } }); }最後に
今回の対策では、とりあえずmailto: とかtel:も対応できるようになっただけです。
そのため、電話アプリを起動する前にダイアログで知らせるとかになると、スキームで判定とかが必要かなと思います。
またdeep linkとかになると、また面倒な対応がさらに必要になります。
- 投稿日:2020-10-13T21:51:17+09:00
なぜAndroidエンジニアは少ないのか
はじめに
まずはこちらのツイートをご覧ください
(駆け出しエンジニアのみなさん、モバイル開発は結構穴場ですよ…
— どすこい@Android Engineer (@dosukoi_android) October 12, 2020
今のところはかなり需要ありますし、供給が足りてないのでかなり狙い目ですよ…
とくにAndroidエンジニアは人足りてないので、狙い目ですよ…
Kotlin楽しいですよ…
みなさん、Android始めませんか?)普段通り思ったことを呟いた結果、なぜか見事にプチバズりしました。
これにはかなり賛否両論あって、自分的にもかなり学びになったので自分の意見とみなさんの意見をまとめていきたいと思います。Androidユーザーが少ない
個人的にはこれが一番大きいと思います。
しかし調べてみると、iOSとAndroidの割合は6:4くらいなのです。(このAndroidにFireOS, HUAWEI OSを含むかは不明)あれあまり大差ないじゃん!とか思ったんですが、恐らく若者、特に10代〜20代のシェアだけ見ると7:3、もしくは8:2くらいにはなるんでしょうね
僕の周りにはAndroidはダサい、古いみたいな考えを持っている人も少なくなく、こう言ったことがAndroidユーザーが増えない理由なんだと思います
Javaを学ぶかKotlinを学ぶか迷う
僕がAndroidを学び始めたのは2018年
KotlinがAndroidの公式言語になったのは2017年のGoogle I/Oなので、情弱だった僕がAndroidを学び始めた頃はKotlinの存在すら知りませんでした。ですが現在はKotlinの日本語のリファレンスも増えたり、推奨されることも多いのでKotlinから学び始めることも多いかと思います。
しかしKotlinはAltJavaなので、Javaから学ぼうかそれとも流行っているのでKotlinから学ぼうか悩んでしまう方も少なくないのかもしれませんね。ライブラリがたくさん
こんな意見もありましたね。
これに関しては半分納得、半分疑問という感じです。
というのもJava自体ライブラリがたくさんありますし、Androidの標準APIもかなり豊富です。
去年出たJetpackだけでも数えられないくらいのライブラリがたくさんあります。しかしこれはiOSにも言えることです。しかもiOSは標準のライブラリではなくサードパーティのライブラリがめちゃくちゃあります。
Androidはほぼ公式のライブラリだけで完結するので個人的には楽なんですけどね、、育つ環境がない
この意見が一番多かったです。
確かにその通りだと思います。
実際、弊社のAndroidエンジニアは誰かに教わった経験やスクールに入った経験がありません。しかし育つ環境がないのはiOSも同じなのでは、、?という疑問を抱きました。
ですが後述する意見を見ると納得するかもしれません
コミュニティが少ない、活発じゃない
僕自身、あまりコミュニティや勉強会などに参加したことがないので、あまり感覚的にわかりませんがこういった意見もありました。
iOSでいうとiOSDCみたいなイベントはないのかなぁと思いましたが、AndroidではDroidkaigiがありますし、個人的にはあまりしっくり来ませんでした。
リファレンスが少ない
恐らく育つ環境が少ないに直結する理由がこれだと思います。
というのもAndroidは海外ではiOSよりもシェアが高いのでリファレンスがあるので、Androidエンジニアは多いのですが、如何せん僕らは日本人。
英語のリファレンスを嫌う人は山ほどいます。Androidの日本語のリファレンスが少ないからAndroidエンジニアが増えない、Androidエンジニアが増えないから日本語のリファレンスも増えない
あれ??これって卵が先か鶏が先かみたいな話になってきませんか、、、?
結論
わかりません!!
Kotlinはイケてますし、GoogleとJetBrainsはたくさんお金かけてくれてますし、かなり需要も高いと思います。
弊社の場合ですが、アプリの案件があれば必ず両OSのアプリも作ります。恐らくどの会社もそうだと思います。
なので同じ数のアプリエンジニアが必要な中、Androidエンジニアが足りていないというのは駆け出しエンジニアさんたちにとってもかなりお勧め出来るんですけどね、、、笑意見を下さったみなさん、ありがとうございました!!
余談
バズらせるつもりのなかったツイートがバズるのは結構びっくりしますね笑
僕はツイートがバズるのが初めてだったのでちょっと焦りました
- 投稿日:2020-10-13T21:40:36+09:00
Androidアプリアイコン設定
- 投稿日:2020-10-13T20:48:44+09:00
【Qiita】Qiitaにスマホから新規投稿する方法
- 投稿日:2020-10-13T19:27:24+09:00
【Qiita】Qiitaにスマホから新規投稿する方法
- 投稿日:2020-10-13T18:56:47+09:00
Android Studio 4.1に上げたらParameter 'directory' is not a directoryでBuildできない
pluginのアップデートがあるよ〜って出たのでアップデートしたらエミュレータへのinstallに失敗するようになって、試行錯誤ののち4.1以上じゃないと使えないplugin入れちゃったみたいで、勢いでAndroid Studioも4.1にしたら、
Execution failed for task ':app:dataBindingGenBaseClassesHogeDebug'.
Parameter 'directory' is not a directory: /Users/ibuse/Documents/workspace/Fuga/app/build/intermediates/data_binding_dependency_artifacts/hogeDebugですって。
cleanしてrebuildしても変化なし
Invalidate Caches/Restart...効果なし
確かにそんなディレクトリは存在しないので、強引にディレクトリを作ってあげたらBUILD SUCCESSFUL
冴えない解決を見た