- 投稿日:2020-10-26T21:50:32+09:00
ScrollViewのぐにゃんと動くものの制御
この言葉では表現しにくい、スクロール出来るコンテンツに出てくるぐにゃんと動くものの制御方法についてです。
it's ぐにゃん
- ぐにゃんでもうにょんでもいいんですが、スクロール出来るコンポーネントをスライドしたときに出てくるこいつです。
- 正式な名称はEdgeEffectですね。(まずこの名称にたどり着かないと
)
EdgeEffect について
- APIバージョン
16
から存在している機能- 何も設定しなければ、
Theme
のcolorPrimary
に設定されている色に20%(0x33)のアルファ値を設定した値が反映されている?(バージョンによって違うかも)EdgeEffectの色を変える方法
アプリケーションの
Theme
に割り当てる方法
- 影響範囲はアプリケーション全体
ScrollView
全部がかわるので、RecyclerView
やPullToRefresh付きのWebView
も影響を受けます設定方法
- Themeに追加して利用します。
Activity
で利用しているThemeであればActivity全体が変更されます。<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> ・・・ <item name="android:colorEdgeEffect">#0000FF</item> ・・・ </style>EdgeEffectの表示をコンポーネントで切り替える
- EdgeEffectの表示切り替える設定には
overScrollMode
を利用します。overScrollMode
には3つのパラメータが用意されています。
パラメータ 動き always 常にエフェクトを表示する ifContentScrolls 表示している内容がスクロールするものの場合にのみエフェクトを表示する never エフェクトを表示しない XMLで設定する
<androidx.core.widget.NestedScrollView ・・・ android:overScrollMode="ifContentScrolls" ・・・ tools:showIn="@layout/activity_scrolling">プログラムで設定する
scrollView.overScrollMode = View.OVER_SCROLL_ALWAYS最後に
- 機能の名前を忘れるとたどりつくのが大変になりますね。
- 名前を覚えておいて、必要なときに設定を変えてあげましょう。
- 投稿日:2020-10-26T19:54:04+09:00
#20 Kotlin Koans Collections/Introduction 解説
1 はじめに
Kotlin公式リファレンスのKotlin Koans Collections/Introductionの解説記事です。
Kotlin Koansを通してKotlinを学習される人の参考になれば幸いです。
ただし、リファレンスを自力で読む力を養いたい方は、
すぐにこの記事に目を通さないで下さい!一度各自で挑戦してから、お目通し頂ければと思います
2-1 collection
colletionに関するクラスは多岐に渡ります。
コレクションには以下の3種類がある。
- List:順番が決まっている要素の集合
- Set:順番が決まっていない要素の集合
- Map:キー(key)と値(value)がペアとして入った集合
それぞれMutableとすると、コレクション生成後に要素を追加・削除することができる。
継承関係がわかっていると、コードの理解が深まるので是非参考にしてください。
2-2 toList()とtoSet()
toList():コレクションが呼び出すことで、Listとして返ってくる。
toSet():コレクションが呼び出すことで、Setとして返ってくる。
これら2種以外にもコレクションを変換するための関数は存在するので是非調べてみてください。
3 Collections/Introductionの解説
Kotlin Koans Collections/Introductionの解説です。
随時本サイトの内容を引用させていただきます。本文とコードを見てみましょう。
This part was inspired by GS Collections Kata.
Default collections in Kotlin are Java collections, but there are lots of useful extension functions for them. For example, operations that transform a collection to another one, starting with 'to': toSet or toList.
Implement an extension function Shop.getSetOfCustomers(). The class Shop and all related classes can be found at Shop.kt.
Introductionfun Shop.getSetOfCustomers(): Set<Customer> = TODO()Shop型のインスタンス(プロパティとしてString型のname、List< Customer >型のcustomers)がgetSetOfCustomers()を呼び出すとSet< Customer >型のインスタンスが返ってくるようにTODO()を実装します。
(Shopクラスのプロパティについては、Shop.ktファイルを参照してください。)
なので、戻り値ではList< Customer >型のインスタンスをset< Customer >型に変換する必要があるので、
toSet()を用いればよいですね。
解答は以下のようになります。
Introductionfun Shop.getSetOfCustomers(): Set<Customer> = customers.toSet()4 最後に
次回はKotlin Koans Collections/Filter mapの解説をします
- 投稿日:2020-10-26T09:56:39+09:00
【Android】新しいGooglePlayConsoleでアプリを任意のタイミングで手動公開する方法
はじめに
現時点でまだ従来のバージョンを使用している方には、以下の注意文が表示されていると思いますが
2020/11/01から、GooglePlayConsoleが新しいバージョンへと変更されます。タイトルの通り、アプリを手動公開する方法を記載しておきます。
※従来のバージョンでの手動公開方法はこちら手順
1.対象のアプリを選んでいる状態で、画面の左側の[公開の概要]を選択。
2.[管理対象の公開ステータス] -> [管理]を選択。
3.[管理対象の公開をオンにしました]にチェックを入れ、[保存]。
4.アプリの審査が完了し、承認されると[確認して公開]が押せるようになるので、任意のタイミングで公開。
終わりに
新しいバージョンに慣れるまでみんなでがんばりましょう!w
- 投稿日:2020-10-26T08:52:35+09:00
Redmi Note 9SにAPKがインストールできない
はじめに
XiaomiのAndroid端末
Redmi Note 9S
を入手したので開発に使ってみようと思ったところ
APKのインストールができない現象に遭遇しました。色々と調べたら解決方法がわかったのでメモっておきます。Android Studioからデバッグ実行すると...
このようなエラーが出て、APKがインストールされません。
USBからのAPKインストールが無効になっているようです
![]()
ADBコマンドでインストールしても同じ結果です
Installation did not succeed. The application could not be installed: INSTALL_FAILED_USER_RESTRICTED原因
Xiaomiの独自機能によってAPKのインストールが制限されているようです。
解決方法
開発者向けオプションの中にある
MIUIの最適化をオンにする
をオフにすると、APKをインストールできました。1.
設定
→開発者向けオプション
を開いて2. MIUIの最適化をオンにするをオフにする
注意事項
ダイアログに表示されている通り、MIUIの最適化の設定をオフにすると動作に影響があるようです。
(どの動作がどのように変わるのか具体的にはわかりませんでした。)
Redmi Note 9S
を日常使用するならこの設定は元に戻したほうが良さそうです。また、一般的なユーザーはこの設定を変更することは稀なので、Xiaomiの端末で動作確認するときは
最適化をオフにしてAPKをインストールし、オンに戻してからテストしたほうが良さそうです。
(最適化のオフ・オンでAPKの動作が変わる可能性があるため)参考
- 投稿日:2020-10-26T08:18:36+09:00
iOS/Androidアプリのセキュリティ関連の参考リンク
ちょっとしたきっかけがあって、iOS/Androidアプリのセキュリティに関して情報を収集する必要がありました。
せっかくなので私が出会った良記事をシェアしたいと思います。
OWASP Mobile Top 10
- OWASPは「Open Web Application Security Project」の略で、「オワスプ」と読むようです。
- ソフトウェアのセキュリティ環境や、セキュリティを高めるための技術を共有・普及することを目的として活動しているボランティア組織だそうです。
- WebアプリのOWASP Top 10が有名ですが、OWASP Mobile Top 10はそのモバイルアプリ版です。
- ソフトウェアを開発する上で、セキュリティとして警戒をしなければいけない項目のTOP10をレポートしています。
- 何しろ有名どころなので、まずはこれを押さえる必要があると思います。顧客や上席に対する説明ではOWASPのレポートを参考文献に記載にすると説得力が増しそうです(笑)
OWASP Mobile Top 10 - 2016 日本語訳
- OWASP Mobile Top 10の最新版レポートは2016年なのですが(ちょっと前なのですね)、有志によるその日本語訳です。
【セキュリティ】OWASP準拠の脆弱でない iOS/Androidアプリ開発を行うためのポイントを解説
- OWASP Mobile Top10カテゴリに準拠しつつ iOS/Androidアプリ開発を行うためのポイントを解説してくれている、実践的な記事です。
iOS/Android セキュリティガイドライン
- 実務/実装に即した内容になっている素晴らしい記事です。
- 投稿日:2020-10-26T05:17:46+09:00
中華アクションカメラのWiFi遠隔操作機能の中身を知る(しなさい)
前置き
お酒飲みながらだらだら書いた。いつかちゃんとまとめる。
背景
単刀直入に言うとカメラの録画と他の測定装置の記録を同期して行いたいという事情が出てきた!要するに、何らかの実験等で計測開始時に「測定器の操作もして…録画ボタンも一緒に押して…」だと手順が多すぎて時間が勿体ないしミスしやすいので、ボタン一発で時系列をそろえて動画と一緒に計測値も記録できる仕組みが必要というわけである。
昨今多機能高品質になった廉価版アクションカメラ
GoProのような高級品を
買えない荒い使い方できないし、ある程度の品質で目的を達成できれば十分というユーザーは一定数存在する。最近は4K画質や60FPSの動画に対応した機種も1万円以内で購入できるようになった。ここで特筆すべきはWiFi接続によりスマートフォンから録画ボタンの操作や、ファインダー越しの映像を確認できる機種が登場してきたことである。従来のようにカメラの筐体に触れることなく遠隔で操作できるようになったことで、危険が及ぶ場所や人の存在が介入することのない自然な環境においての録画が安価で可能となった。調べてみても、案外中華アクションカメラの遠隔操作プロトコルについて解析してる人はいない。
ということで、今回は1年ほど前から使用している怪しいメーカーのアクションカメラを使って実現できる方法を模索するぜ!
まぁぶっちゃけWifi繋いどる時点でプロトコルは絞れるしなんとかなるっしょ。しらんけど!
使用したカメラ
CrosstourというメーカーのCT9500を使用した。おそらく、異なる商品名でもこのカメラと中身は同等の商品は存在すると思われる。
https://www.amazon.co.jp/dp/B07Y1QXFLF/ref=cm_sw_r_tw_dp_dlC_x_cnCLFbKT8ABQ4また、WiFiを通じたスマートフォンからの遠隔操作にはYOUTUPROというアプリから操作を行う。名前からして動画サイトへのリスペクトを感じる。今回はこのアプリの動作を観察する。
https://play.google.com/store/apps/details?id=com.gku.yutupro&hl=jaWire shark等を使ってパケットキャプチャできないか?
結論から言うとできなかった。アクセスポイント(カメラ)側の設定の問題なのか、スマホ-カメラ間のパケットを監視することはできなかった。(使いこなせてないだけかもしれない。)(ネットワーク詳しいひと教えて…)
一方、Android用のパケットキャプチャアプリは内部でVPNを置くことにより監視しているらしく、これでは既製品のカメラ操作用アプリを使用した際にエラーが発生してしまうので従来通りの使用方法を再現できず諦めた。ダメ元でAndroid Studioのデバッグ機能を使ってログチャットを覗いてみると…?
外から見るのがダメなら中身をみちゃえばいいじゃない!ってことで開発環境のデバッグ機能を使ってみることにした。
実機でカメラ操作アプリを動かしながらログを見てみる。ご丁寧にいろんな情報が出力されていた。簡体字の文字列が目立つ。
操作メニューと思われる文字列が各言語で記述されていた。Androidアプリのフォーム記述に使うxmlっぽい?ちらほらみてると、URLが見えてきた。どうやらカメラ自身がHTTPサーバとなっており、クライアント(Androidスマホ)からCGIスクリプトを動かす仕様らしい。マジかよ。
試しにPCからカメラにWiFi接続し、Webブラウザからログの中に見えたcgiスクリプトのURLにアクセスすると、カメラの機種の情報や、設定情報がレスポンスとして帰ってきた。なんか記述がJavascriptっぽい?
スマートフォンから録画&停止ボタンを押してみると、ログにクエリ文字列が吐き出された。これでもしかしたら最低限録画の開始と停止はできるかもしれない!
見事予想的中。
スマホの既製品アプリを使わずとも録画開始&停止の操作成功!とりあえずちっちゃい目標達成となった。
おまけ1 安心の日本語対応
普段留学生と話してる時の僕はこんな感じ。
おまけ2 HTTPサーバーなら?
indexページは無く、ファイル一覧が表示される。言語設定用のファイルやらメインのバイナリが置いてあることからおそらくカメラ内部のFlash領域っぽい。
セキュリティガバガバかよ。
さらにSDカードにもアクセスできた。
おまけ3 クエリ文字列とレスポンス例
以下にログから得られたURLリクエストと帰ってきたレスポンスを示す。
機種やファームウェア情報192.168.0.1/cgi-bin/hi3510/getdeviceattr.cgivar name="Z2V2-Hi3559V2-458-RTL8189ES"; var serialnum="1"; var type="Hi3559V200"; var networkstatus="0"; var softversion="V3.1.0.1-A"; var hardversion="NewAPP"; var startdate="0"; var runtimes="3196252"; var model="3196252"; var timeout="0";
現在の撮影モードの取得?
192.168.0.1/cgi-bin/hi3510/getcurworkmode.cgivar workmode="NormalVideo"; var value="";
192.168.0.1/cgi-bin/hi3510/getcurallinfo.cgivar mode="NormalVideo"; var state="21"; var event="0"; var pasttime="0";
こちらはURLリクエストで、「通常撮影モードで撮影可能な画質一覧」と「現在の設定画質」のの取得
//192.168.0.1/cgi-bin/hi3510/getsecondmenuitem.cgi?-workmode=NormalVideo&-name=Resolutionvar item="4K50,4K30,2.7K30,1440P60,1440P30,1080P60,1080P30,720P120,720P60"; var value="1440P60";
- 投稿日:2020-10-26T01:51:59+09:00
【超初心者向け】Android入門 LinearLayout編
はじめに
今回はLinearLayoutについて解説していきたいと思います。
前回まではTextViewやButton、EditTextなどパーツについての説明をしてきましたが、今回のLinearLayoutはその複数パーツを表示するためのものになります。前回まではTextViewなどのコードをコピペして貼り付けるだけで表示できましたが、今回のLinearLayoutを学ぶと思うままにパーツを設定できて自分好みのUIが出来るようになるでしょう!
記事の対象
- Androidアプリ開発初心者
- 前回の記事を読んだ方
- Androidをこよなく愛する方
LinearLayoutとは
はじめに書きましたが前回までのパーツとは違い、今回のLinearLayoutとはパーツを並べていくためのViewになります。
パーツを並べるためのViewはいくつかあります。
- LinearLayout
- RelativeLayout
- FrameLayout
- ConstraintLayout
- etc...
今回はその中でも最も多く使うLinearLayoutについての解説です。
LinearLayoutとはパーツを横一列、または縦一列に並べるためのViewです。
早速使っていきましょう。1. activity_main.xmlを書き換える。
現在activity_main.xmlはこのようになっています。
activity_main.xml<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="30dp" android:layout_marginTop="30dp" android:layout_marginEnd="30dp" app:layout_constraintTop_toBottomOf="@id/textView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:text="Click!" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/editText" /> </androidx.constraintlayout.widget.ConstraintLayout>これを以下のように書き換えます。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> </LinearLayout>以前まではandroid:layout_widthなどの解説はしてこなかったんですが、今回はちょっと細かく解説していきます。
2. プロパティをちょっと解説
さて、前回までは一切触れてこなかったViewのプロパティ
今回は少し深堀りしていきましょうプロパティとは
ITの分野では、ソフトウェアが取り扱う対象(オブジェクト)の持つ設定や状態、属性などの情報をプロパティということが多い。
うーん、よくわからんとなる人が多いと思います。
なので今回はViewの状態だと思ってください。高さや幅、並べる順やどんなテキストを表示するかなどのことです。android:layout_widthこれは幅を指定します。
画面いっぱいに広げたい場合は、android:width="match_parent"適度なサイズで表示したい場合は
android:width="wrap_content"という感じですね。
これは数字で指定もできます。
100dpの幅で表示したい場合は、android:width="100dp"こんな感じです。
高さに関しても同じように指定できます。LinearLayoutのプロパティ
LinearLayoutは横一列、あるいは縦一列にViewを表示するものです。
それをどのように指定するかというとandroid:orientationこのプロパティを追加すればいいです。
縦に並べたいときはandroid:orientation="vertical"横一列に並べたいときは
android:orientation="horizontal"です。
3.Viewを表示してみる
ではこのLinearLayoutを使って、3つのTextViewと、1つのButtonを縦1列に並べてみましょう
activity_main.xml<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="1" android:textSize="22sp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="2" android:textSize="22sp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="3" android:textSize="22sp"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click!"/> </LinearLayout>これで3つのTextViewと1つのButtonが縦一列に表示されます。
さて実行してみましょう。と思いましたが、MainActivityの中でエラーが起きてしまうので、一旦MainActivityはこうしましょう
MainActivity.ktpackage com.example.helloworld import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.EditText import android.widget.TextView class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } }以前までMainActivityで認識させていたViewは消してしまったので、それも消しちゃいます。
4. 実行
期待通りに表示してくれましたね!
ただこれだとちょっとダサいので全て中央よせにしてみましょう。
5.中央寄せにしてみる
全てのTextViewとButtonに
android:layout_gravity="center"というプロパティを追加してみましょう。
さてこれで実行してみましょう!
6.再度実行
中央寄せになってくれましたね!
まとめ
今回はLinearLayoutの解説をしていきました。
だんだんとTodoアプリに近づいてきた気がしますね!成長のコツとして、サンプル通りにやってみるだけでなく自分なりに色々いじってみることですね
このレイアウトだとちょっとダサいから自分好みのレイアウトに変えてみる、
そのためには色々なプロパティを設定してみたり、前回の応用でButtonを押したらTextViewの表示が変わる
みたいなこともやってみると面白いですね!
- 投稿日:2020-10-26T00:44:56+09:00
【Android/Java】超シンプルなOptionMenuの作成(API非実装)
はじめに
Android開発歴1週間の超ビギナーです。
アウトプットとして簡単なOptionMenuを作成してみました。
これを実装するだけでも、かなり時間かかったので同じビギナーの方の参考になれば幸いです。
※記載量を省略すべく、stringsファイルは使用しておりません。アプリの概要
画面右上に設置した保存ボタンを押すと、表示されているメッセージが変更するという超シンプルなアプリ
![]()
各ファイルのコード
オプションメニューの表示レイアウト設定
1) オプションメニュー用のxmlファイルをres/menuフォルダ内に作成する。
2) オプションメニューの大枠はmenuタグ、メニューの要素(保存ボタン)はitemタグでつくる。
3) itemタグに必要な3つの属性
android:id : メニューファイルとjavaファイルを紐付けるための鍵
android:title : メニューに表示する文字列
app:showAsAction : アクションバーに表示するかどうか(never<ifRoom<always)option_menu.xml// 最初のデフォルト文は全て消して下記を記述 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/option_save" android:title="保存" app:showAsAction="always" /> </menu>メイン画面のレイアウト設定
android:id : レイアウトファイルとjavaファイルを紐付けるための鍵
android:text : メイン画面に表示する文字列activity_main.xml<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> // idとtextをいじるだけ <TextView android:id="@+id/text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="保存ボタンを押してみよう" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>javaファイル
※package, import 文は省略してます。(赤字になったらoption + Enterを押してください)
下記2つのメソッドはオプションメニューを実装するためのルールだと思ってください。
onCreateOptionsMenu(Menu menu)
onOptionsItemSelected(MenuItem item)MainActivity.javapublic class MainActivity extends AppCompatActivity { // デフォルトのままでok @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } // オプションメニュー(保存ボタン)の表示 @Override public boolean onCreateOptionsMenu(Menu menu) { // MenuInflater(メニューをJavaオブジェクトまでインフレートさせるためのクラス)を取得 MenuInflater inflater = getMenuInflater(); // option_menu.xmlに記述されたメニュー部品をJavaオブジェクトにインフレートする inflater .inflate(R.menu.option_menu, menu); // 戻り値をreturnする return true; } // オプションメニュー(保存ボタン)が選択されたときの処理 @Override public boolean onOptionsItemSelected(MenuItem item) // activity_main.xmlのTextViewを取得 TextView textView = findViewById(R.id.text_view); // 取得したテキストに新しい文字列を設置 textView.setText("保存ボタンが押されました"); // 戻り値をreturnする return true; } }最後に
超初心者なので違うところありましたらぜひご指摘お願いします。
参考サイト
・https://developer.android.com/guide/topics/ui/menus?hl=ja#options-menu
・https://qiita.com/watataku/items/5faad0384b54d0c53f6e
ありがとうございました!