- 投稿日:2021-01-16T23:42:28+09:00
AlertDialogで自作Layoutを使う(+ DataBindingも)
Dialog + 自作LayoutだとsetPositiveButtonとかできなくて、ボタンをLayoutに準備してfindViewByIdとかするのが面倒...
AlertDialogならsetPositiveButtonとかできるので、自作Layoutファイルを使って、ダイアログの表示部分だけ自作Layoutにしたかったので、調べたものの備忘録的にまとめました。
AlertDialogに自作Layoutを利用するのと、DataBindingも使いたかったので、それも調べてまとめました。DataBinding使わない場合は不必要な箇所はすっ飛ばしてください。
■ まず完成形
AlertDialogに自作レイアウトファイル(今回はTextView2つ)を差し込めるようにします。
名前だよ、の方はViewModel経由で取得するようにDataBindingしています。■ DataBinding導入
DataBinding導入でGradleに記入したり、基本があります。
導入についてはこちらの記事がわかりやすかったので、こちらを読んでみてください。■ ViewModelを作成する(使わない場合は飛ばしてOK)
DialogViewModel.kt/** * ダイアログのViewModel * */ class DialogViewModel: ViewModel() { var name = "名前だよ" }■ ダイアログのレイアウト
Bindingも使いたいので、Bindingの際の書き方でレイアウトファイルを書く。(Bindingを詳しく知りたい場合は以下のリンクをどうぞ)
Android デベロッパー
・レイアウトとバインディング式
Binding使わない場合は、AlertDiaogに入れたいレイアウトだけでOKです。
dialog_layout.xml<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="viewModel" type="パス.DialogViewModel" /> </data> <!-- 中身は適当に変えてください --> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="400dp" android:paddingTop="15dp" android:paddingLeft="25dp" android:paddingRight="25dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textStyle="bold" android:layout_marginBottom="10dp" android:text="下に名前が出るよ"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{viewModel.name}"/> </LinearLayout> </layout>■ DialogFragmentを作成する
DialogFragmentを継承したクラスを作成します。
onCreateDialogでAlertDialogを返すようにしますが、その際のsetView
に作成したLayoutファイルを入れればOKです。DataBindingしている場合は、
binding.root
を入れます。HogeDialog.ktclass HogeDialog : DialogFragment() { /** ダイアログのViewModel */ private val viewModel: DialogViewModel by viewModels( { requireActivity() } ) override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { // 使用したいレイアウトのbinding val binding = DialoglayoutBinding.inflate(requireActivity().layoutInflater) // ViewModeを使う場合 // 書かないとレイアウトにviewModel.~ と書いても何も起こらないです。 binding.viewModel = viewModel val builder = AlertDialog.Builder(requireActivity()) .setView(binding.root) // Viewにbindingのrootをセットする。(もしくは自作したレイアウトファイル) .setTitle("タイトルだよ") // タイトルが必要ならセットする .setMessage("メッセージはレイアウトより上に出るよ) //必要ならセットする .setPositiveButton("OK") { _, _ -> // ポジティブボタンタップ時の処理 } .setNegativeButton("Cancel") {_, _ -> // ネガティブボタンタップ時の処理 } return builder.create() } }■ Dialogを表示する
あとはダイアログを表示するだけです。
場所によって表示方法は異なりますが、私の場合はFragmentで呼んでいるのでその場合の書き方を書きます。Dialogを表示するval dialog = HogeDialog() dialog.show(childFragmentManager, "タグは適当にどうぞ")これで自作のレイアウトを使った(+DataBinding)ダイアログが表示されます。
メッセージを入れると、メッセージはレイアウトより上に出てくるので、そこはご注意ください。メッセージなしの場合
メッセージありの場合
■ まとめ
調べるとやりたいことに対してダイレクトな情報が中々見つからなかったのですが、まとめて見ると大した量ではなかったです。
Bindingとか詳しければそんなに分からなくならないと思いますが、これから使ってみたい場合は迷うかもしれませんので、参考になれば幸いです。(ちょっと調べていた時のサイトは忘れてしまったので、見つかったら貼っておきます)
以上です。
- 投稿日:2021-01-16T23:14:55+09:00
[Android/Kotlin]Gitに保存しないデータを扱う
なんでそんなことするの?
github等でgitを共有する時に、データベース接続用パスワード等は公開したくない
説明
.gitignoreファイルに記載されているファイルはgitに保存されなくなる
AndroidStudioでプロジェクトを作成すると、自動的に.gitignoreとlocal.propertiesが作成され、
.gitignoreの中にlocal.propertiesも入っているのでそれをそのまま使用する結論
github
この中にlocal.propertiesは入っていないコード
.gitignore
local.propertiesが入っていることを確認
.gitignore/local.properties local.propertiesbuild.gradle(:app)
ここのやり方はわからなかったら
buildConfigField
でググってくださいbuild.gradle(app)android { defaultConfig { // local.propertiesファイルを指定 def properties = new Properties() properties.load(project.rootProject.file('local.properties').newDataInputStream()) // buildConfigFieldで値を保存 def LOCAL_PROPERTIES_SAMPLE = properties.getProperty("LOCAL_PROPERTIES_SAMPLE") buildConfigField("String", "LOCAL_PROPERTIES_SAMPLE", "\"${LOCAL_PROPERTIES_SAMPLE}\"") } }local.properties
ここに隠したい値を入れる
文字列でもクォーテーションは要らない
半角スペースを使用できないlocal.propertiesLOCAL_PROPERTIES_SAMPLE=SAMPLE値を受け取る
今回はtext_viewでlocal.propertiesで指定した値を表示してみる
activity_main.xml<TextView android:id="@+id/text_view" />BuildConfigやその中の値は最初存在せず、赤くなってるけど、初回ビルド時にBuildConfig.javaが生成・更新され、使えるようになる
MainActivity.ktclass MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // BuildConfig.javaは初回ビルド時に生成される text_view.text = BuildConfig.LOCAL_PROPERTIES_SAMPLE } }
- 投稿日:2021-01-16T20:54:48+09:00
【Android】CLEARTEXT communication to xxxxxx.com not permittedが出た時
APIをRetrofitを使い取得しようとしたときにエラーになったのでメモ
CLEARTEXT communication to xxxxxxx.com not permitted by network security policy
http通信が許可されていないことからこのエラーになる。
Manifestにandroid:usesCleartextTraffic="true"を足す
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.SimpleRetrofit" //下記を足す android:usesCleartextTraffic="true" >これで通信許可ができるはず。
- 投稿日:2021-01-16T17:23:03+09:00
モバイルアプリ開発は、Flutter一択なのか?-2021版-
こんにちは! Tetsukick(菊池哲平)です。
2021年1月現在、インドネシア(PT.AQ Business Consulting Indonesia)でモバイルアプリ開発の技術顧問をしております。
iOS歴5年、Flutter歴1年半。個人でもアプリ開発してます。
本記事は、2020年11月にZennに投稿した記事の改訂版になります。
本記事の対象読者
- モバイルアプリ開発者
- Flutterの今後の可能性を知りたい方
- モバイルアプリ開発案件を検討中で技術選定をされている方
- 本記事のタイトルが気になる方
序
今回インドネシアでモバイル開発の技術顧問をさせていただく中で、Flutterの提案から導入までを実施し、実際に導入に至ることができましたので、その過程で用いた技術的根拠等々をシェアいたします。
実際に非技術者に対しても提案をしましたので、そのままお使いいただくことも可能かと思います。
PPT素材が必要な方いましたらTwitter_@tpi29までDMいただければと思います。
日本語文献や英語文献も参考にしておりますので、少しでもお役に立てばと思います。最近の更新
2021年版のDeveloperのロードマップが公開されました。
結果からお伝えすると、、
モバイル開発におけるフレームワークは、React Nativeが取り上げられております。とはいえ僕の記事を読んでもらえば少し分かるかもしれませんが、現状そこまで大差はないと思っております。結局は好きな言語を身につけるのが一番かと。。笑
ネイティブ開発とクロスプラットフォーム開発
まず、モバイルアプリ開発をするにあたって、大きく2つに分類(ネイティブ開発とクロスプラットフォーム開発)できます。
ネイティブ開発とは
iOSアプリ、Androidアプリに対してそれぞれ独自の言語を用いて開発する開発手法です。
iOSであれば、Objective-CやSwift。
Androidであれば、AndroidJavaやKotlin。
での開発を指します。モバイルアプリ開発における最も基本的な開発手法になります。
クロスプラットフォーム開発
クロスプラットフォーム開発とは、AndroidやiOS等の複数のプラットフォームにまたがって開発を行うことのできる手法になります。
具体的には、XamarinやCordova、ReactNative、Flutter、Outsystems等々、最近では、プログラミングを必要としないノーコード開発ツールもいくつか見受けられるようになりました。ネイティブ開発 VS クロスプラットフォーム開発
では、まずネイティブ開発とクロスプラットフォーム開発の比較をいたします。
以下の項目で比較いたしますが、各項目の重要度は読者様で配分頂いた上で実際に選定していただければ良いかと思います。
- 開発効率
- 保守・運用
- パフォーマンス
- 端末固有機能
- 最新機能対応
- 最新OS対応まとめ
開発効率
開発効率においてはクロスプラットフォーム開発に軍配があがります。
人的リソース
ネイテイブ開発
ネイティブ開発は各OSごとの異なる言語(iOS: Swift, Android: java, Kotlin)のエンジニアが必要(通常最低2名)
クロスプラットフォーム開発
一つの言語で開発可能。
開発環境
クロスプラットフォーム開発の多くのプラットフォームでホットリロード機能(コンパイル不要でソースコードの修正をアプリに反映させる機能)を有している。
通常ネイティブ開発では、コンパイルごとに10秒-1分程度の時間がかかるので、その時間を削減することができる。その他
ネイティブの場合、ソースコードは各OSごとに必要で基本的にロジックをあわせる必要があるが、開発者間での調整コストやソースコード間でずれが生じるリスクが発生する。
これに関してはProtocol Buffers等で極力ロジックを統一する等の対策も可能だが、すべてを補完できるわけではない。保守・運用
保守・運用面では、クロスプラットフォーム開発に軍配があがります。
人的リソース
ネイテイブ開発
ネイティブ開発は各OSごとの異なる言語(iOS: Swift, Android: java, Kotlin)のエンジニアが必要(通常最低2名)
クロスプラットフォーム開発
一つの言語で開発可能。
不具合・改修リスク
ネイティブ開発では各OSごとにソースコードが存在するため、不具合の発生リスクも増加する。
改修の際は両OSでの対応が必要になる。パフォーマンス
レンダリング(画面描画)パフォーマンス
各プラットフォームにより異なるが、クロスプラットフォームはネイティブUIを呼び出す処理を行うもの、WebViewへのレンダリングを行うもの、独自レンダリングエンジンを使用するもの、等ありますが、基本的にはネイティブのレンダリングパフォーマンスに比較すると劣ります。
以下はパフォーマンスの比較例です。
リストを表示する上でのパフォーマンスを比較しています。
端末固有機能
一般的端末固有機能
カメラ機能、プッシュ通知、GPS、生体認証等の機能はプラグインによりサポートされているため、
クロスプラットフォーム開発においても、懸念することはほとんどない。特殊な端末固有機能
ウィジェット機能、特殊端末との接続(クレジット端末など)、フィットネスAPI等の連携、センサー関連の使用(加速度センサー等)に関しては、プラットフォームにより異なるが、プラグインが提供されていなかったり、プラグインが不十分な場合があり、自作等での対応が必要になるケースがある
最新機能・最新OS対応
最新機能・最新OS対応においては、ネイティブ開発に軍配があがる。
ネイテイブ開発
最新OSのbeta版や開発用のIDEのbeta版が提供され、リリース前から検証や開発を実施し、備えることが可能。
クロスプラットフォーム開発
リリース後にオープンソース上の開発者間で対応バージョンが追ってリリースされることになり、対応を待つ必要がある。
iOSでもAndroidでも、最新OSのリリースの約一年後には、最新OSに対応していないアプリは新たに申請できなくなる風潮がある。結論(ネイティブ開発 VS クロスプラットフォーム開発)
アプリの要望や開発予算、人的リソース等の状況により、ネイティブ開発、クロスプラットフォーム開発の選定の大きな要因となる。
アプリの要望
特殊なネイティブ機能や最新機能を使用するアプリでは、ネイティブ開発が好ましい。
一般的な機能にとどまるアプリに関しては、クロスプラットフォーム開発が好ましい。開発予算、人的リソース
開発予算、人的リソースが豊富な場合は、ネイティブ開発が好ましい。
予算や人的リソースに懸念がある場合は、クロスプラットフォーム開発が好ましい。クロスプラットフォーム開発
まとめ
クロスプラットフォーム開発分類
上記のようにクロスプラットフォーム開発は主に3つの種類に分類されます
ネイテイブUI型
単一言語をネイティブのUIに変換して表示、パフォーマンスは比較的に高いが、変換にかかる時間だけパフォーマンスが若干落ちる。各ネイティブのUIを使用できるため、単一言語で各OSに合わせたUIを作成可能
オリジナルUI型
プラットフォーム固有のレンダリングエンジンを用いているため、ゲームアプリなど自由度の高いグラフィック表現が可能。パフォーマンスは各プラットフォーム次第だが、こちらも比較的高い。Unityもこちらに分類される。
WebUI型
WebView上に描画を行うため、パフォーマンスが低い。Webと同じリソースを活用できるため、Webサイトのアプリ化等に優れている。ネイティブの機能との連携もやや困難
ReactNative VS Flutter
本記事では、私自身の経験があり、クロスプラットフォーム開発でもよく比較されるReactNativeとFlutterの比較を行います。
まとめ
以下の項目で比較をいたします。
- 言語
- 生産性
- UI自由度
- 開発頻度
言語
言語に関して、ReactNativeで採用されているJavascriptの方が開発者数や情報量などで大いに優勢。
下記のサイトでは、かなりの大差ですね。
ランキング 言語 Share率 3位 Javascript 8.44% 21位 Dart 0.56% 生産性
生産性に関しては、ホットリロード機能はどちらもサポートされているが、インタフェースの作成において、XDから正式に変換プラグインのサポートやアニメーションフォーマットのサポート(RIVE)などインタフェースの開発効率が高い
UI自由度
UI自由度に関しては、ネイティブコンポーネントだけでなく、独自のUIコンポーネントライブラリを保有するFlutterの方が優れている。
開発頻度
OSSとして、言語の改良速度がFlutterが非常に活発な状態にあります。
質問投稿サイト(StackOverFlow)の質問数やGoogle検索の数に関してもFlutterが優れている。
github_flutter
github_reactnative結論(クロスプラットフォーム開発比較)
プラットフォームの選定には、開発者の習熟言語、アプリの要望にも起因する。
アプリの要望
既にWebサイト構築済みで、特異な機能のないアプリ開発であれば、Cordova等のWebリソースを使用できる開発が好ましい。
OSごとのネイティブUIの表現を重視する場合は、ReactNativeでの開発が好ましい。
ユーザの要望などUIの変更への対応、開発速度が求められる場合はFlutterでの開発が好ましい。個人的所見
ここ最近の動向を見ても、ReactNativeは、Facebookのネイティブ化などの流れがあることに反して、Flutterは、各種GoogleのアプリがFlutterに変更されたり、中国系のAlibabaやBaidu,TencentなどがFlutterでの開発をしていたり(Flutter showcase)、そういった面でも信頼ができるのではと思います。
また実際に、私がインドネシアで比較的容易に導入できた背景としては、約9割のスマホユーザがAndroidユーザである背景から、ユーザに広く普及しているUIがMaterial Designであるため、その開発においての優位性があるなども別途決め手の一つにはなっていたかと思います。
参考記事
- 投稿日:2021-01-16T14:10:16+09:00
NFCタグで遠隔PC起動_スマホでWake on lan(ラズペリーパイ経由)
NFCタグで遠隔PC起動_スマホでWake on lan(ラズペリーパイ経由)
作成背景
①NFCタグで何か便利にできることがないか?
②デスクトップPCをwifi経由でなくLAN接続に最近変えたWake on lan でPCを起動しよう。
材料
①NFCタグ1枚100円
②NFC対応スマホ(android)
③NFC tools (アプリ)
④ラズベリーパイzero (☆wake on lan アプリでもOK)実践
①デスクトップPCの設定(wake on lan)ができるようにする。
マジックパケットをLANに流すことで、PCが起動できる。
*マザーボード上で通電している状態にする、Wakeonlanを利用可能にする必要
https://www.atmarkit.co.jp/ait/articles/2004/20/news021.html
☆macアドレスを取得しておきます。 ifconig/all②ラズベリーパイzeroからマジックパケットを出す
xx:xx:xx:xx:xx:xx ①で調べたMACアドレス
apt-get install wakeonlan wakeonlan xx:xx:xx:xx:xx:xxwakeonlan.shを作成しておく(後で起動するよう)
vi wakeonlan.sh wakeonlan xx:xx:xx:xx:xx:xx該当のPCの電源がonになることを確認する。
③ラズベリーパイzeroをrestapiサーバーにする(flask利用)
材料④でラズベリーパイを利用している理由
・余計なアプリを入れたくない。
・違う起動方法にした際に、応用が利く
今回restapiサーバとしてURLをたたく形で実装pip install Flask cd 適当なフォルダーへindex.pyという名前でpythonファイルを作成する。
#!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Flask import subprocess app = Flask(__name__) @app.route("/") def hello(): subprocess.call('./wakeonlan.sh',shell=True) return "wake on lan!" if __name__ == "__main__": app.run('0.0.0.0', debug=True)python起動する。ssh経由での接続後、切断しも切れないように下記コマンドを実行
nohup python index.pyhttp://xxx.xxx.xxx.xxx:5000/ にアクセスして、PCが起動することを確認する
NFCタグに、http://xxx.xxx.xxx.xxx:5000/にアクセスする指示を書き込む
☆tasktoolsの方で、設定ができるので割愛
最終結果
ちょっとQoLが上がった気がします。
NFCタグは、部屋中のあらゆる場所にスイッチがつけれる魔法の道具だと気付いたので、思いついたらやってみようと思います。
* 自宅Iotはやりすぎると、かえって面倒なことが多発します。なのでほどほどが一番
- 投稿日:2021-01-16T13:27:03+09:00
【Android】MediaPlayerで音楽を一時停止して途中から再生する方法
プログラミング勉強日記
2021年1月16日
MediaPlayerで音楽を一時停止して、止めたところから再生する方法を簡単にまとめる。MediaPlayerで音楽を再生する方法
MainActivity.javamp = MediaPlayer.create(this, R.raw.musicFile); // 音楽ファイルを読み込み mp.start(); // 再生開始MediaPlayerで音楽を一時停止する方法
MainActivity.javamp.pause();サンプルプログラム
ポイントはstartする際にMediaPlayerのインスタンスを生成しないこと。そのまえにonResumeの中でインスタンスを生成することで、一時停止してその途中からまた再生することができる。
public class Sample20120802Activity extends Activity { MediaPlayer mp = null; Button[] btn = new Button[3]; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout ll = new LinearLayout(this); ll.setOrientation(LinearLayout.VERTICAL); setContentView(ll); btn[0] = new Button(this); btn[1] = new Button(this); btn[2] = new Button(this); btn[0].setText("再生"); btn[1].setText("一時停止"); btn[2].setText("停止"); btn[0].setEnabled(true); btn[1].setEnabled(false); btn[2].setEnabled(false); ll.addView(btn[0]); ll.addView(btn[1]); ll.addView(btn[2]); btn[0].setOnClickListener( new sampleClickListener() ); btn[1].setOnClickListener( new sampleClickListener() ); btn[2].setOnClickListener( new sampleClickListener() ); } public void onResume(){ super.onResume(); mp = MediaPlayer.create(this, R.raw.musicFile); mp.setOnCompletionListener( new SampleCompListener() ); } public void onPause(){ super.onPause(); mp.release(); } class SampleCompListener implements OnCompletionListener{ @Override public void onCompletion(MediaPlayer mp) { btn[0].setEnabled(true); btn[1].setEnabled(false); btn[2].setEnabled(false); } } class sampleClickListener implements OnClickListener{ @Override public void onClick(View v) { if( v == btn[0] ){ btn[0].setEnabled(false); btn[1].setEnabled(true); btn[2].setEnabled(true); try{ mp.prepare(); } catch ( Exception e ){ } mp.start(); }else if( v == btn[1] ){ btn[0].setEnabled(false); btn[1].setEnabled(true); btn[2].setEnabled(true); if( mp.isPlaying() ){ mp.pause(); } else { mp.start(); } } else { btn[0].setEnabled(true); btn[1].setEnabled(false); btn[2].setEnabled(false); mp.pause(); mp.seekTo(0); } } } }参考文献
- 投稿日:2021-01-16T04:19:41+09:00
Androidアプリの手動公開(管理対象の公開)【2021年1月12日時点】
こちらの記事を参考にしてGoogle Pay Consoleで時間指定公開機能で手動でアプリリリースしていたのですが。
いつの間にか時間指定公開が「管理対象の公開」という機能に変わっていたので手順残します。Google公式ドキュメント
管理対象の公開機能を使ってアプリの変更を公開するタイミングを管理する
こちらに書いてあるはずなのですが(個人的に)情報過多でいまいちピンとこなかったです。管理対象の公開とは?
以前の「時間指定公開」と同じことができるのですが、どうやら機能改善してるようです。
- 保留中や審査中の変更時でも管理対象の公開オンオフを切り替えることができる
- 時間指定公開オンの設定中で保留中の変更があった場合、承認されないと公開できないが管理対象では審査中の変更があっても承認済の変更は公開することができるつまり、公開する項目を審査単位でわけて公開することができるようになったということのようです。
手順
リリースの作成
まだ公開ボタンは押さない。
管理対象の公開をオンにする
左のメニューから公開の概要をクリックし、管理対象のステータスの[管理]をクリック
「管理対象の公開をオンにしました」のラジオボタンを選択して[保存]をクリック
審査に出す
右下の[製品版としての公開を開始]をクリックすると公開しますか?のポップアップが起動するので勇気を出して公開ボタンをクリック
審査通過