Android

update create

最近はAndroid Studioで開発するのが主流っぽい。
URL

ショートカット

AndroidStudioの状態
* Android Studio -> About Android Studio * File -> Project Structure
Modulesなどで、Javaのバージョン指定ができる * File -> Other Settings -> Default Project Structure.

Google Cloud Messaging (GCM) APIは2019年4月11日付けで廃止

  • Android Studio
    • HAXM
      home-brewでもインストール可能。
      最近は、studioインストール時にインストールされる。
      システム環境設定 -> 一般 に許可を求めてくるので、解除する必要がある。
  • gradle

Editor

  • Alt + Shift + click: マルチカーソル
    keyboardだけで操作がわからん、、??
  • Alt + Enter import追加

Resource

DPI scale dp px example dpi
ldpi x0.75 4dp 3px 36x36 <=120
mdpi x1 4dp 4px 48x48 <=160
hdpi x1.5 4dp 6px 72x72 <=240
xhdpi x2 4dp 8px 96x96 <=320
xxhdpi x3 4dp 12px 144x144 <=480
xxxhdpi x4 4dp 16px 192x192 <=640
  • dpi
    https://developer.android.com/training/multiscreen/screendensities
  • ldpiは必要なさそう
    https://stackoverflow.com/questions/18213668/are-android-ldpi-assets-icons-still-needed

Log

  • https://elinux.org/Android_Logging_System
  • https://proandroiddev.com/managing-logging-in-a-multi-module-android-application-eb966fb7fedc

Emulator

wipe

Sign

keytool -printcert -jarfile app/release/app-release.apk 
keytool -v -list -keystore keystore.jks 

署名が古いと警告が出る

keytool -v -importkeystore -srckeystore keystore.jks  -srcalias alias_name -destkeystore 出力用p12ファイル名 -deststoretype PKCS1
keytool -importkeystore -srckeystore old_keystore.jks -destkeystore new_keystore.jks -deststoretype pkcs12

netowrk

Update

Google Playストアアプリが検知する方法
Google I/O 2019にて正式版がリリース

HTMLをparseしてversionを取得する方法

仕組み

アプリの更新を管理する
ユーザーのデバイスのアプリを常に更新することでユーザーは最新の機能を利用できるようになり、アプリのセキュリティや安定性も向上します。
この記事では、IT 管理者が組織の管理対象デバイスにインストールされているアプリを最新のバージョンに保つ手順を説明します。

デフォルトの更新動作
デフォルトでは、次の条件を満たしている場合にアプリが自動的に更新されます。

* デバイスが Wi-Fi ネットワークに接続されている。
* デバイスが充電中である。
* デバイスがアイドル状態である(操作を行っていない)。
* 更新対象のアプリがフォアグラウンドで実行されていない。

一般に、Google Play では 1 日に 1 回、アプリのアップデートを確認しています。
そのため、アプリのアップデートが更新キューに追加されるまで最長で 24 時間ほどかかることがあります。
キューに追加されたアプリは、上記の条件を次回満たしたときに自動的に更新されます。

FullScreen

SYSTEM_UI_FLAG_IMMERSIVE_STICKY
SYSTEM_UI_FLAG_FULLSCREEN
SYSTEM_UI_FLAG_HIDE_NAVIGATION

proguardメモ

  • http://yuki312.blogspot.com/2012/03/androidproguard_09.html
  • https://qiita.com/samuraijap/items/100b2e679fbd6972e499
    デフォルト設定を忘れずに

keymapping

Keymap → Main menu → Code → Completion → Basic
xcodeに近づける

Push通知

Dozeモードに関する注意
Android 6.0以降
バッテリーが長持ちする反面、バッググラウンドが制限される。

https://firebase.google.com/docs/android/setup?hl=ja

運用

curl -X POST https://fcm.googleapis.com/fcm/send -H 'Authorization: key=<APIキー>' -H 'Content-Type: application/json' -d '{
"notification" : { 
"title": "title",
"body": "message",
"sound":"default",
"icon":"@android:drawable/sym_action_chat",
"color":"#FF8000"
} , 
"to" : "<トークン>",
"priority":"high"
}'

lint

  • https://developer.android.com/studio/write/lint?hl=ja
  • https://www.lifull.blog/entry/2015/01/07/104745

Site

  • https://play.google.com/apps/publish/signup/

$25

Sign

Gradle https://developer.android.com/studio/build/build-variants?hl=ja

Version

  • versioning
    versionCode is 2100000000
  • https://stackoverflow.com/questions/4616095/how-to-get-the-build-version-number-of-your-android-application

PackageManager, BuildConfigとか、 Build.VERSION.SDK_INT

Gradle

  • https://developer.android.com/studio/build/gradle-tips.html

Intentのflg

FLAG_ACTIVITY_NEW_TASK  新しいタスクでActivityを起動
FLAG_ACTIVITY_SINGLE_TOP    現在のActivityと同じアクティビティは起動しない
FLAG_ACTIVITY_CLEAR_TOP 該当のActivity上にスタックされたタスクをクリアしてから起動
FLAG_ACTIVITY_NO_ANIMATION  トランジションアニメーション無し
FLAG_ACTIVITY_NO_HISTORY    起動時にスタックに追加しない
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY スタック内のActivityを使いまわす
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS  履歴内のActivityを使いまわす
FLAG_ACTIVITY_PREVIOUS_IS_TOP   元のActivityをタスクのトップとして起動する
FLAG_ACTIVITY_REORDER_TO_FRONT  スタック内の同一Activityを最前面へ移動させる

update

  • https://qiita.com/kurun_pan/items/0e4d916d106f64942195

SSL

https://developer.android.com/training/articles/security-ssl?hl=ja

openssl s_client -connect test.com:443 | openssl x509 -noout -subject -issuer

基本doc
https://developer.android.com/studio/publish/app-signing?authuser=1#generate-key

keytool -v -list -keystore ./keystore/file.keystore

の情報を貼り付けておけばok
https://coderwall.com/p/r09hoq/android-generate-release-debug-keystores

keytool -genkeypair -dname "CN=xxx, OU=xxx, O=xxx, L=xxx, ST=xxx, C=JP" \
-alias aliaskey \
-keypass passwd \
-keystore ./keystore/file.keystore \
-validity 9125 \
-keyalg RSA \
-keysize 2048

keytool - 鍵と証明書の管理ツール

opensslで上記を再現しようと思ったけど、CAがよくわからん。
keytoolでサーバーに送られてsignされていると思われる。(未確認)

opensslではsubjを使用し、セパレータはスラッシュ。

パスワード変更

keytool -storepasswd -keystore file.keystore
keytool -keypasswd -alias myalias -keystore file.keystore

AutoBackup

https://toconakis.tech/androidautobackup/

Debuger

https://github.com/facebook/stetho

Adb

adb version
adb devices
adb shell pm list package
adb install xxxx.apk
adb install -r xxxx.apk
adb uninstall [package name]
adb push ~/temp.png /sdcard/Download/

インストール済みのパッケージ情報

adb shell dumpsys package [packagename]

pm: package manager.
am: application manager.
activityを起動したりとか

# Activityの起動(ACTION_VIEW + URL)
am start -a android.intent.action.VIEW -d http://google.com
# Activityの起動(クラス名を指定)
am start -n com.hoge.app/.FugaActivity
# サービスの起動
am startservice ... # Intentの指定方法はActivityと同じ
# ブロードキャストの送信
am broadcast ... # Intentの指定方法はActivityと同じ

fileの転送だと、pull, push. logcatコマンドでログの表示

aapt

macosだと

/System/Volumes/Data/Users/[user name]/Library/Android/sdk/build-tools/[version]/ にあったりするので、PATHを通す.

aapt l -a app.apk | grep "A: package"
aapt l -a app.apk | grep "android:version"
aapt d badging app.apk | grep "application:"

名称

  • ドロワー (cf.アプリ一覧)
  • フォルダー
  • クイック設定パネル *ドック
  • ナビゲーションバー(戻るボタン、ホームボタン、マルチタスクボタン)

アプリ画面

  • アプリバー、アクションバー
  • ボトムナビゲーション
  • Floating Action Button(FAB)
  • タブ
  • ナビゲーションドロワー、サイドメニュー
  • スナックバー
  • ダイアログ
  • ボトムシート

ConstraintLayout vs Coordinator layout?

  • CoordinatorLayoutは、 Behaviors を管理するアクティビティのトップレベルレイアウトとなることを目的としています
  • ConstraintLayoutの主な目標は、複数の子を持つフラットレイアウトを作成する便利な方法を提供することです(より強力なRelativeLayout)。

MATERIAL DESIGN

開発メモ

赤線
File -> 'Invalidate Caches / Restart'

Image

res/drawable/ などのリソースを実行デバイスの解像度に合わせて、 拡大・縮小を行うようだ(未確認)。 dip(density-independent pixels) の考え方にしがたい上記の処理を行うので、
その処理を省くには、drawable-hdpi のフォルダを作成することで、
多分、該当dpiフォルダを探し、なければdrawableの画像を処理という流れだと思う?ビルド時にaaptツールが変更している模様(要調査)。

mipmap はアプリケーション(Android4.2以降)内での拡大・縮小が発生した時に切り替えてくれるリソースとなる。
基本API経由で使用する。 bitstreamとして読み込む場合は、res/raw/ に画像をおく。
assetsフォルダに置いた場合は、idは生成されない。
rawは、Resources、assetsは、AssetManager. (App resources overviewより)

Android の画像リソース(アイコンも)にはJPEG形式を使うこともできますが、JPEG は写真のような画像の圧縮には向いているものの、アプリで使用するアイコンやUI画像の圧縮には向いていません。アイコンやUI 画像の圧縮にはPNG、特にPNG8(8bitPNG) が向いています。ただし、PNG8を使う場合は、高画質で減色できるツールを使う必要があります。

Memo

final GestureDetector gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
    public void onLongPress(MotionEvent e) {
        Log.e("", "Longpress detected");
    }
});

public boolean onTouchEvent(MotionEvent event) {
    return gestureDetector.onTouchEvent(event);
};

https://material.io/components/bottom-navigation#placement

UI Flag

http://y-anz-m.blogspot.com/2013/11/kitkat-android-44-ui.html

TableLayout

https://developer.android.com/guide/topics/ui/layout/grid

Notification

Notification Dot Color

Applicationアイコンにより色が自動的に決定するとのこと。
今のところ変更できる余地はない。

setting

android:configChanges=“orientation|screenSize” 回転時のActivityの再生成を抑止。
https://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange

layout

android:fitsSystemWindows="true"

AndroidX

support-v7-appcompat はdeprecated.
androidxに移行しているので注意。

Navigation

https://developer.android.com/guide/navigation/navigation-ui?hl=ja

Design

https://material.io/
https://material.io/develop/android/docs/getting-started
FullScreen Dialog https://material.io/components/dialogs#actions

DataBinding

alt(opt) + enter

SSL関連

http://www.jssec.org/dl/android_securecoding_20180201/5_how_to_use_security_functions.html

めも

  android:text="Hi&#10;Hello"

Data Binding

  • XML -> select "parent element"
  • option + Enter
  • Convert to date binding layout

XMLにbindさせる場合は、Stringであること。

android:text="@{`` + mode.intValue}"
android:text="@{Integer.toString(mode.intValue)}"

Dialog

回転が絡むと、ライフサイクルが絡むので注意。

Snippet

        // navigation bar
        Resources resources = getContext().getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        int navigationBar = 0;
        if (resourceId > 0) {
            logger.info(String.format("resourceId=%s", resourceId));
            navigationBar = resources.getDimensionPixelSize(resourceId);
            logger.info(String.format("navigationBar=%s", navigationBar));
            rowHeightSpacer =  navigationBar + 48;
        }
        logger.info(String.format("rowHeightSpacer=%s", rowHeightSpacer));
            DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
            int spaceHeight = (int) (48 * metrics.density);
            logger.info(String.format("spaceHeight=%s", spaceHeight));
Drawable drawable = ResourcesCompat.getDrawable(res, R.drawable.circle_progress, null);
        ProgressBar progressBar = new ProgressBar(getContext(), null, android.R.attr.progressBarStyleHorizontal);
        progressBar.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.circle_progress_bg, null));
        progressBar.setProgressDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.circle_progress_fg01, null));
        progressBar.setLayoutParams(new TableRow.LayoutParams(cellSize, cellSize));
        progressBar.setMax(100);
        progressBar.setProgress(10 * 3);
        progressBar.setTag(rec);

XML

android:checked
android:focusable
を取得する場合

TypedArray a = context.obtainStyledAttributes(
        attrs, 
        new int [] { android.R.attr.focusable, android.R.attr.checked });
boolean focusable = a.getBoolean(0, true);
boolean checked = a.getBoolean(1, false);

※int配列はソート済みだとダメとの情報。

resource

android.resource://[package]/[resource_id]
android.resource://[package]/[res type]/[res name]
So the following would be managable.

String pkgName = getApplicationContext().getPackageName();
Uri path = Uri.parse("android.resource://"+pkgName+"/" + R.drawable.icon);
Uri otherPath = Uri.parse("android.resource://"+pkgName+"/drawable/icon");

Alerm

ここが有用
https://akira-watson.com/android/alarmmanager-timer.html

inflate

ハマったので、、

  • attachToRootがtrueの場合は、addViewされる(記述は必要ない)。
  • attachToRootがtrueの場合、親View、falseの場合はlayout Viewで挙動が異なる
  • mergeタグのlayoutをinflateする場合は、attachToRootはtrue

Icon

https://github.com/konifar/Android-material-design-icon-generator-plugin

https://github.com/google/material-design-icons

https://material.io/resources/icons/?style=baseline 上記でsvg取得して、AndroidStudioで取り込む方法を採用

ID

JWT

https://github.com/auth0/JWTDecode.Android https://github.com/auth0/java-jwt

Animation

遷移時
* https://developer.android.com/guide/components/intents-common?hl=ja * https://developers.cyberagent.co.jp/blog/archives/9291/

アニメーション入門 * https://qiita.com/suzukihr/items/7d5caa32eb0bdb22bb23

Releaseに向けて

GPC(Google Play Console)

公開の概要 -> 管理対象の公開のステータス
管理対象の公開をオフにすると自動公開
手動公開にする場合は、変更する。

手動公開にした場合
公開の概要 -> 確認して公開 ボタンが表示される

SharedPreferences

All shared prefs are stored in /data/data/[package name]/shared_prefs/[app name].xml, so i think there's no limit based on architecture.

Strage

Device File Explorer
* [View] > [Tool Windows] > [Device File Explorer] * ツール ウィンドウ バーにある Device File Explorer アイコン

Android: /data/data配下にadb push

# ファイルを一時領域へコピー 
$ adb push hoge /data/local/tmp 

# アプリユーザに切り替え 
$ adb shell 
$ adb run-as <Application ID>

# ファイルコピー 
$ cp /data/local/tmp/hoge /data/data/<ApplicationID>/hoge

## ↑でエラーが出た場合はcatリダイレクトする
$ cat /data/local/tmp/hohe > /data/data/<Application ID>/hoge

ファイルのコピー関連うまくいかなかったんだよな、、また変わったのかな?

 adb shell pm grant <PACKAGE_NAME> <PERMISSION>
adb shell pm revoke <PACKAGE_NAME> <PERMISSION>
adb shell pm list packages
adb shell pm list permissions -g

movie

Logcatに動画アイコンボタンがあるので押す。(webm)

ffmpeg -i test.webm -pix_fmt yuv420p test.mp4

LogCat

制限があるので注意
* adb logcatでログを書き出すときに、長いmessageだと途中で切れてしまう問題

adb logcat -g
main: ring buffer is 2 MiB (191 KiB consumed), max entry is 5120 B, max payload is 4068 B
system: ring buffer is 2 MiB (2 KiB consumed), max entry is 5120 B, max payload is 4068 B
crash: ring buffer is 2 MiB (0 B consumed), max entry is 5120 B, max payload is 4068 B
kernel: ring buffer is 2 MiB (0 B consumed), max entry is 5120 B, max payload is 4068 B

これ以上の文字列を表示しようとすると、切り取られる。

Spell, Dictionary

AndroidStudioのPreferenceから Editor -> Inspections -> Typoを選択 in All Scopesを任意で作成したscopeを指定し調整する。(例えば、xmlは除外するなど) Scopeは別途作成

Sample Source https://github.com/android/views-widgets-samples

戻るアクション https://developer.android.com/guide/navigation/navigation-custom-back?hl=ja