投稿

1月, 2024の投稿を表示しています

KeyguardManager によるメモリリークはグーグルのバグらしい

イメージ
 KeygurardManagerによるメモリリークが確認された。どうやってこれを解消すればいいか検討したが、結論からいうと、どうやらこれはグーグルのバグで、解消できない可能性が高そうだ。(もし詳しい方がおられたら教えてください) ----------------------------  アプリを作ったら、メモリリークがないか確認しなければならない。  メモリリークとは、アプリが確保したメモリが不要になっても解放されないままになることで、使えるメモリが減ってしまい不具合の原因となる。その確認のためにリークキャナリー(LeakCanary)を入れて確認することが広く行われている。  リークキャナリーの入れ方についてはこちら。非常に簡単である。 https://zenn.dev/yass97/articles/e25960d5511c30  ただ、その読み方はちょっと難しい。今回確認されたリークは次のようなもの。  これを見ていくと、上から1/3くらいのところにKeyguardManager とあり、また、下から1/3くらいのところにAlarmActivityとある。さらにそのすぐ下にLeakinng:YES とあるので、結局、AlarmActivityというアクティビティの中にある、KeyguardManagerのインスタンスにリークがあるということなのだ。  ちなみに、KeyguardManager とは、スマホのロックを管理するクラスで、私は目覚まし時計を作る際に、スマホがロックされていてもアラームの画面だけは表示できるようにするために使ったのだ。  さて、ではどうやってこのメモリリークを解消するか。  メモリリークは多くの場合、アクティビティ等を閉じる段階(onPauseやonDestroy)において、リークの原因となっているオブジェクトを解放し、nullにしてやることで解消できる。このブログでも次のような例について、メモリリークが解消できたことを報告した。 https://marsh-mashro.blogspot.com/2023/08/broadcastreceiver.html https://marsh-mashro.blogspot.com/2023/08/handler.html  しかしKeyguardManagerのメモリリークはこのような方

ボタンの重なりとelevation

elevationで画面要素のz軸方向の高さを決めるが、そのときの発見。 ボタンが重なった時、どう反応するかということ。 結論からいくと、重なったボタンがあるとき、上(elevationの値が大きいほう)のボタンが反応するときと、そうでないときがある。 両方のボタン下のボタンのelevationを0dp、上のボタンのelevationを2dpとすれば意図どおり上が反応するが、それ以外のときはよくわからない。 なぜこういうことを考えたかというと、「画面のどこでもタップすればヘルプに飛ぶ」というようなアプリを作ろうと考えて、画面全体を覆うような透明なボタンを作った。そのうえで、一時的に画面に普通のボタンを表示して、それはまた別の機能を持つようにしようと思ったところ、後者のボタンを押すと前者の透明なボタンが反応してしまう。 そこで、elevagionを操作すればこの問題が解決できるのでは、と考え、透明なボタンを10dp、一時的な普通のボタンを20dpに設定し、これならより上にある後者のボタンが反応するだろう、と思ったのだが、うまくいかず、やっぱり前者の透明なボタンが先に反応してしまう。で、いつものように悩んでいた。 この問題は、たまたま、透明なボタンのelevationを0dp、一時的なボタンのelevationを2dpとすることで解決できた。0dpと1dpではうまくいかないときがあり、また、3dp以上でもうまくいかないことがあった。 なお、ImageViewやTextViewはこれとは関係なく、それらが上にあってsetOnClickListenerが設定されていても、下にあるボタンのほうが優先的に機能するみたいだ。 「ようだ」とか「みたいだ」が多い記事ですみません。今度時間のあるときにちゃんと検証しようと思います。

固定電話がわりのSkype

固定電話がわりに050番号を使う  固定電話を置きたいが費用やスペースや配線の手間等の点で二の足を踏んでいる場合、一つの選択肢は「スマホで使える050番号サービスを契約し、古いスマホなどSIMの入ってないスマホにそのアプリを入れて家に置いておく」というものです。  費用が安い、スペースをとらない、配線の手間は不要、などのメリットがあります。 しかし多くの050番号サービスは撤退。使えるのは(多分)Skypeのみ  ところが、2023年夏頃、なぜか、OCNが提供している050プラスを初め多くの個人向け050番号サービスが軒並み撤退してしまいました。私が把握している限り、現在この用途で使えるのはSkypeの「Skype番号」というサービスのみです。受信だけなら費用は月300円(長期契約割引あり)です(発信するためには別途前払いのクレジットを購入するか、月額プラン(現時点で867円/月、無料通話枠あり)に入る必要があります)。 Skype番号を使うには  Skype番号を使うには、運転免許などの個人を証明する書類とスマホで自撮りした顔写真をアップするなどして認証を受ける必要があります。その過程でMicrosoftのAuthenticatorを使うので、申込の前にAuthenticatorがインストールされていなければインストールし、パスワードを確認しておく必要があります。この部分は結構面倒でした。また、私だけかもしれませんが、確認ボタンがスマホの下のほう(いつもは広告が表示されるので無視する場所)に表示されるので、気づかずに確認の制限時間をオーバーしてしまうということがありました。(スマホの画面全部に注意を払いましょう) Skype番号の特徴  Skype番号には、複数のスマホにアプリを入れて都合のよいスマホで通話できるという、他の050番号サービスになかった特徴があります。なお、留守電機能はありますが、応答の音声は英語です。 使うときの工夫  電話の着信を受けるためには基本的にはSkypeアプリを立ち上げて前面に置いておかなければなりませんが、スマホの設定のところで、「アプリ→Skype→詳細設定」として(機種による違いあり)、「通知」「他のアプリの上に重ねて表示」を許可しておくと、Skypeアプリがバックグラウンドにあったり画面消灯しているときでも着信を受けることがで

SDK34におけるForegroundServiceの問題

 これまで動いていたアプリのTargetSDKを33から34に変えたところ、ForegroundServiceを立ち上げるところでいきなりエラー。その理由と対処法がわかった。  今回のバージョンアップで、ForegroundServiceには「サービスタイプ」を指定しなければならなくなった。  サービスタイプとは、そのフォアグラウンドサービスが、例えばメディア再生を行うものなのか、外部との通信を行うものなのか、といった種別のこと。次を参照。 https://developer.android.com/about/versions/14/changes/fgs-types-required?hl=ja 例えば、サービスがメディア再生を行うものであった場合は、マニフェストで、 パーミッションのところに、これまでは次の1文があれば良かった。 <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> 今後はそれに加えて、次の文を入れる必要がある。   <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" /> さらに、<service・・・></service>の・・・の部分に  android:foregroundServiceType="mediaPlayback" を追記することも必要。 この2点を追記すると、以前と同様に動くようになった。

ビルドエラー:Attempt to create a global synthetic for 'Record desugaring' without a global-synthetics consumer の解決

このエラーで苦労している人は他にはいないでしょうか。他の原因もあるかもしれないけど、私の場合はこれで解決できたので報告します。   【問題発生の経緯】 Aというアプリを複製してBというアプリを作った(複製の方法は、以前このブログで書いた次の方法)。 https://marsh-mashro.blogspot.com/2023/08/androidstudio.html ところが、次のエラーが出てビルドができない。 Attempt to create a global synthetic for 'Record desugaring' without a global-synthetics consumer 直し方はおろか、エラーの意味すらわからず途方に暮れた。そもそも、複製前のアプリと複製後のアプリはアプリ名を除いて全く同じなのに、なぜこんなことが起きるのか・・・。 検索すると次のようなページが出てくるが、読んでもよくわからない。ただ、どうやらJavaのバージョンに関係ありそうだということがわかった。 https://www.mongodb.com/community/forums/t/how-to-properly-connect-my-kotlin-android-app-with-mongodb-atlas-cluster/196264 https://stackoverflow.com/questions/75043114/android-build-produces-error-attempt-to-create-a-global-synthetic-for-record-d そこで、build.gradleの中のJavaのバージョンを表していそうなところだとか、Project Structureだとか、今まで触ったこともないようなところを闇雲に変更したり古いバージョンを使ってみたりしたが、もちろんエラーはなくならない。 【何とか解決】 結構絶望的な気分になっていたのだが、Bのもとになった空っぽのアプリはビルドができることに気づいた。ということはGradleの問題ではない。そこで、部分的にAアプリのコピーをしてBアプリにペーストし、そのたびにビルドを試す、ということをやって