- 0.0.1. 【Android】Test dynamic delivery offline のやり方
- 0.0.2. 【Android】ConstraintLayout Attribute まとめ
- 0.0.3. Androidで”storage/emulated/0/”直下にアクセスしてファイルを保存
- 0.0.4. ConstraintLayoutを使ったフラットなレイアウトでもタッチイベントをInterceptしたい
- 0.0.5. 2年かけて個人で全く新しいSNSアプリを作ったお話し
- 0.0.6. 【続】Codelabsの通知機能の実装をViewModelを使って書き換えてみた
- 0.0.7. Reverse Geocoder(逆ジオコーダー) android × kotlin
- 1. Reverse Geocoder(逆ジオコーダー)
- 1.1. 環境
- 1.2. やり方
- 1.2.1. 買い切りアイテム用にGoogle Play Billing Library v3のラッパーライブラリを作成
- 1.2.2. 【Fiddler Everyone】 Android端末のブラウザの通信キャプチャの方法
- 1.2.3. 【Kotlin】Glideの画像データキャッシュを更新したい
- 1.2.4. Androidアプリのクラッシュ対策にやったこと
- 1.2.5. [Android]Vector Assetに枠線をつける方法
- 1.2.6. [Android]テストって何のためにやるのか分からないよね!(初心者の叫び)
- 1.2.7. Codelabsの通知機能の実装をViewModelを使って書き換えてみた
- 1.2.8. エラー Couldn’t inline method call ‘userProfileChangeRequest’ into
- 1.2.9. Kotlinのタップで画面遷移、長押しでクリップボードにコピー
- 1.2.10. Kotlinで◯日前という表記をスマートに実装
- 1.2.11. ActivityResultAPIのテストを書く
- 1.2.12. Flutter アプリ内課金(サブスクリプリプション)の実装
- 1.2.13. ListView用のカスタムアダプターの中身を逆順にするときにおこった問題について
【Android】Test dynamic delivery offline のやり方
# はじめに
Android AppではDynamic Feature Modules(DFM)を用いて、リリース後に必要な機能を追加でインストールすることができます。これにより開発者がアプリのサイズを小さくできたり、ユーザも使わない機能はそもそもインストールしないことでストレージの節約にもなるという便利なものです。
今回はこちらのDFMのインストール状況をユーザへと通知するテストを、内部テストを使用することなく完全オフラインで実施できるようにしていきます。# FakeSplitInstallManagerの実装
https://developer.android.com/reference/com/google/android/play/core/splitinstall/testing/FakeSplitInstallManager
こちらを使っていきます。
通常のDFMのリクエストやインストールをするにはSplitInstallManagerを使いますが、そのFakeバージョンになります。
まずはSplitInstallManagerやSplitInstallManage
【Android】ConstraintLayout Attribute まとめ
# はじめに
この記事は[公式リファレンス](https://developer.android.com/reference/androidx/constraintlayout/widget/ConstraintLayout?hl=ja)の内容をまとめたものになります。
ConstraintLayoutのAttributeってどんなのあるの? という方向けのまとめです。
自分の備忘録も兼任していたり…# [Relative positioning](https://developer.android.com/reference/androidx/constraintlayout/widget/ConstraintLayout#RelativePositioning)
Viewを別Viewに対して相対的に設置する。
|
Androidで”storage/emulated/0/”直下にアクセスしてファイルを保存
#はじめに
androidでファイルを保存したいとき、ユーザーがアクセス可能なルートディレクトリ(”storage/emulated/0/”)に保存すると何かと便利。
そこでファイルアクセス方法を調べてみた。#現在は非推奨
以前(Android10以前)ではEnvironment.getExternalStorageDirectory()を使用して外部パブリックストレージへのパスを取得できた。
しかし現在では非推奨となり使用できない。
http://blog.lciel.jp/blog/2014/02/08/android-about-storage/#推奨方法
1. Context#getExternalFilesDir(String)
1. MediaStore
1. Intent#ACTION_OPEN_DOCUMENT.
ConstraintLayoutを使ったフラットなレイアウトでもタッチイベントをInterceptしたい
AndroidではConstraintLayoutが登場してから、より一層Viewのネストが少なく、フラットな階層のレイアウトを作れるようになりました。しかし、イベントのハンドリングなど、Viewにネストがあれば簡単だったことが難しくなっている部分も存在します。
例えば、以下のように上下にスクロールするシートと、横スクロールするカルーセルがあるとします。
横スクロールのカルーセルは横方向の操作しか消費しません。一方シートは縦方向の操作だけが必要です。
こういった場合で、特にシートの大きさが十分でない等の場合、カルーセル部分を触った場合でも、操作が上下方向だった場合、動かないカルーセルではなく、シートの操作に反映した方がユーザビリティが高い場合があります。# 親子関係がある場合
このような要求がある場合、シート
2年かけて個人で全く新しいSNSアプリを作ったお話し
こんにちは。歴10年のアプリエンジニア(Best of AppStore?受賞歴あり)です。
**neeboor?**という位置情報を使った新しいSNSアプリを作りました。
toC向け&コンテンツ系&モバイルアプリというサービスの特性上、**最初からある程度高い完成度のサービスを提供しないとユーザーの手に取ってもらえないな**と思い、UI/UX中心にかなりこだわって開発した結果、**開発に2年以上**かかってしまいました。今回はサービスの紹介をしつつ、開発で苦労した点や工数をかけた点について記事にしたいと思います。
# サービスの紹介
neeboor?は、「**あなたの生活圏をもっとおもしろくするSNS** (Make your living area hackable)」というコンセプトの位置情報系SNSアプリです。従来のローカル系サービス(=地域情報サイト、半径◯メートルでお店や友達探す系、出会い系、ナビ系、トラッキング系など)とは異なり、**場所を演出要素としてオープンでカジュアルなコミュニティを作れる**ところがユニークな点になっています。### 機能 / こんな使
【続】Codelabsの通知機能の実装をViewModelを使って書き換えてみた
[前回](https://qiita.com/kilalabu/items/ca420f2346635efe19a8)の続き
[タスク2:通知を更新またはキャンセルする](https://developer.android.com/codelabs/android-training-notifications#3)を参考に通知機能を実装してみた。|update|cancel|
|—-|—-|
|![update.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670405/ddf7246f-4f77-603f-5f7c-55e59e389192.gif)|![cancel.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670405/8e69d8c0-2261-e0aa-f122-5104baf70390.gif)|## 実装
### layout
`android:enabled`でボタン操作をコントロール
Reverse Geocoder(逆ジオコーダー) android × kotlin
Reverse Geocoder(逆ジオコーダー)
kotlinで書いている記事が少なかったので書き残して起きます。
逆ジオコーデイングする上で少し沼ってしまったので
誰かの参考になればいいかなと思っています。
*自分は実務経験がない開発者なので間違っている場合があると思いますが
そこら辺はご容赦ください。
環境
- 言語
- kotlin
- フレームワーク
- Android Studio 4.1.2
やり方
事前準備
経度緯度を取得しておく
latitude(緯度)とlongitude(経度)
逆ジオコーダー
“`kotlin.MapActivity.kt
fun getAddress(latitude: Double, longitute: Double) {
val strAddr
買い切りアイテム用にGoogle Play Billing Library v3のラッパーライブラリを作成
# はじめに
Androidの課金ライブラリ(Google Play Billing Library)をv3に上げる必要が出てきました。
期限は新規アプリの場合は2021年8月1日、アプリ更新の場合は2021年11月1日です。
かなり古くから自作アプリの課金システムを放置していたので思い切って作り直してみました。eclipseからAndroidStudioに変わってからまともに触ったことがなかったので、
AndroidStudioやGradleの勉強も兼ねて作成したので構成がおかしかったらすみません。# 公開リポジトリ
– [AndroidBillingTest – GitHub](https://github.com/taiki-f/AndroidBillingTest)**※ライセンス表記をしております。ライセンスの範囲内でご自由にご使用ください。**
**※買い切りアイテム用に作成した物ですので定期購入アイテムや消費アイテムには対応しておりません。**# ライブラリの簡単な使い方
最初にアイテムリストを作ります。
第1引数が課金の結果を受け取るクラス、
第2
【Fiddler Everyone】 Android端末のブラウザの通信キャプチャの方法
## Android端末でのブラウザの通信をFiddler Everyoneで取得する
####①Fiddler Everyoneを起動する
####②設定のConnectionsを開く
ポートは初期設定のままにし(変更したい場合はしておく)、Allow remote computers to connectにチェックを入れる
![fid_everywhere_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/94320f56-c107-4f2f-7ffb-88bdc1fd2334.jpeg)
SAVEを押すと、ファイアウォールの設定がされていない場合に確認が入るが、アクセスを許可する
#### ③Androidのプロキシ設定を行う
Fiddler Everywhereとandroidのwi-fiを同じに設定する
wi-fiの設定から使用しているwi-fiの設定アイコンを選択
![fid_everywhere_3.jpg](https://qiita-image-store.s3.ap-
【Kotlin】Glideの画像データキャッシュを更新したい
#Glideは同じURLからの読み込みだとキャッシュを利用する
Glideのキャッシュ機能は読み込み回数を減らせて便利です。
しかしサーバーのデータを更新してもURLが同じなら、キャッシュから読み込んじゃうので、更新したデータが反映されずに困ることがあります。
以下に回避方法を2種類記載します。##回避策1:キャッシュからの読み込みをスキップする
“`Kotlin
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.NONE) //ディスクキャッシュをスキップ
.skipMemoryCache(true) //メモリキャッシュをスキップ
.into(view)
“`この方法でキャッシュをスキップして更新されたデータを読み込むことはできます。
しかし元々保存されているキャッシュが更新されるわけではないので、毎回キャッシュをスキップしないと古いデータが表示されてしまします。##回避策2:キャッシュを全削除する
“`Kotlin
//ディスクキャッシュをクリア
//バックグラウ
Androidアプリのクラッシュ対策にやったこと
先日GooglePlayにAndroidアプリをリリースしたのですが、1週間でおよそ20件のクラッシュレポートが上がってきました
レポートは20件ほどありましたが、およそ2件の対策をしましたのでメモしておきます解決の保証はできませんので悪しからず
# やったこと
### TextInputEditTextの実装修正
* noExcludeDescendantsを追加
* hint属性はTextinputLayoutにつける
* setOnEditorActionListenerを削除### MapViewのnullチェックを追加
“`MapActivity.kt
override fun onDestroy() {
try {
binder?.mapView?.onDestroy()
} catch (e : NullPointerException) {
// Send report exception..
}
super.onDestroy()
}
[Android]Vector Assetに枠線をつける方法
初めに
===
AndroidのVectorDrawableを利用することであらかじめ用意されている画像を簡単に利用できます。
そのVectorDrawableに枠線をつける方法をまとめていきます。VectorDrawableの作成
===
Android StudioのVector Assetでデフォルトで作成されるのは以下のようなxmlになります。“`xml
[Android]テストって何のためにやるのか分からないよね!(初心者の叫び) # 取り敢えず、分からんけども、テスト書いてみるか!!しかし・・・
最近、企業さんからいただいたアプリ作成の課題でテストをする必要があり、(別に書かなくても良いのですが、テストコードを書いたほうが品質に気を使っているのだなと評価されるので)
テストの学習を始めました。
早速、Android全書やその他記事諸々を読み始める。
しかし、それらは前提知識がないと読めないので、かなり難しい…
取り敢えず、クラス名の上にカーソルを合わせて、右クリックすると「Show Context Actions」と表示されるので、クリックし、そして、「Create Test」みないなものが出てくると思うので、それもクリックすると、そのクラスに対応したテストクラスができます。
超入門以外の記事を読んで、分かることはこれくらい笑
でもでも、諦めず自分に適したレベルの記事を読み漁りながら、この記事を完成させたいと思います。
### 実機テストで良くね?
まず、ここっすね。色々と記事を読み漁っていると、「なぜ、テストを書くのか?」「弊社では、テストを書く必要性がますます高まっています。」という文
Codelabsの通知機能の実装をViewModelを使って書き換えてみた
## はじめに
[Codelabs タスク1:基本的な通知を作成する](https://developer.android.com/codelabs/android-training-notifications#2)を参考に通知機能を実装してみた。
![notification.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670405/cde8bdd6-3beb-e4a8-3cb4-fff7d5b40f28.gif)## 通知機能の実装ポイント
### ①通知チャネルを作成する
* チャネルIDを用意
* 通知チャネルのカスタマイズ初期設定(APIレベル26以上に対して)
* チャネルの設定名称
* 通知の優先度(他にも通知が複数あったときの表示位置の優先度)
* バイブ、LEDの色設定
* チャネルの説明文
* 注意事項
* Android8.0(APIレベル26)より古いデバイスはカスタマイズできない。
* Android8.0(APIレベル26
エラー Couldn’t inline method call ‘userProfileChangeRequest’ into
#FirebaseのAuthenticationでユーザープロフィール更新時に謎のバグ
Kotlinでfirebaseのプロフィール更新時に“`
Couldn’t inline method call ‘userProfileChangeRequest’ into
“`っ出てビルドが通らない。
理由は不明だけど、下記でビルドが通ったので、もしものときに誰かの役に立てばと思って書き残します。##バグの出たコード
“`Kotlin
val profileUpdates = userProfileChangeRequest {
displayName = “ユーザー名”
}
“`##バグが回避できたコード
“`Kotlinval profileUpdates = UserProfileChangeRequest.Builder()
.setDisplayName(“ユーザー名”)
.build()
“`
Kotlinのタップで画面遷移、長押しでクリップボードにコピー
###タップでブラウザに画面遷移
“`kotlin:click
view.setOnItemClickListener() { parent, view, position, id ->
var uri = “https://something”
var intent = Intent(Intent.ACTION_VIEW, Uri.parse(uri))
startActivity(intent)
true
}
“`###長押しでテキストコピー
“`kotlin:longClick
var clipboard: ClipboardManager = applicationContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
view.setOnItemLongClickListener() { parent, view, position, id ->
var copyText: String
Kotlinで◯日前という表記をスマートに実装
#Kotlinで時間差を表示したい
Twitterなどで見る、「◯時間前」とか「◯日前」などの表記を簡単に実装したいと思います。
ちなみにこの方法なら、スマホの言語設定に合わせて勝手にローカライズされ、「◯ days ago」といった表記に変わりますので、配信する地域を気にせず使えます。“`Kotlin
var hoge = DateUtils.getRelativeTimeSpanString(指定時刻のミリ秒, 現在時刻のミリ秒, 0)
“`
で◯日前、◯時間前といった表記を取得できます。##現在時刻のミリ秒を取得
ちなみに現在時刻のミリ秒は下記で取得します。“`Kotlin
val now_milisec = System.currentTimeMillis()
“`
ActivityResultAPIのテストを書く
# 概要
`startActivityForResult`と`onActivityResult`が非推奨になったので、`ActivityResultAPI`を使って書き直しました。
で、公式に`Fragment`向けの`ActivityResultRegistry`を置き換えてテストできる方法について触れている箇所があったのですが、https://developer.android.com/training/basics/intents/result?hl=ja#test
`Activity`でテストする場合のことが書いてなかったので調べて対応しました。
# 環境
|ツールなど|バージョンなど|
|:–|:–|
| MacbookPro |macOS Catalina 10.15.7|
|Android Studio |4.1.2|
|Java(JDK) | openjdk version “11.0.10” |
| Koin |2.2.2|
| activity-ktx | 1.2.1|# 対応方法
**Koin**というDIライブラリを使って実現しました。
Flutter アプリ内課金(サブスクリプリプション)の実装
#内容
今回初めて、アプリ内課金(サブスクリプション、以下サブスク)の実装をしたので、忘却録として書きます。
2021/3/12 時点のサンプルコードを使用。
サブスク導入でつまずいた部分のみを記載(2021/03/26時点ではiOSのつまずき集のみ)。実装は気が向いたら書く予定。テスト中に何回も購入処理をして、トランザクションが残っていると色々と大変らしいので、[YuKiOさんの記事](https://qiita.com/YuKiO-OO/items/a0fe8e0a256afbb69fc7#%E9%87%8D%E8%A6%81%E8%AA%B2%E9%87%91%E6%A9%9F%E8%83%BD%E3%81%A7%E3%83%8F%E3%83%9E%E3%81%A3%E3%81%9F%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88)を先に読んでおくことをおすすめします。
#前提条件
●App Store, Google Play側の準備ができている(サブスクアイテム作成)
●今回はサブスクのみなので、consumable(消耗品)関係は未対応以
ListView用のカスタムアダプターの中身を逆順にするときにおこった問題について
#問題のコード
“`ListWorkActivity.java
public class ListWorkActivity extends AppCompatActivity implements View.OnClickListener {
private ArrayListlistItems = new ArrayList<>();
private DateArrayAdapter arrayAdapter;
private ListView listView;protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
//listViewにlistItemsをセットしたい
listView = findViewById(R.id.listView);
{…}
/