投稿

アンドロイドアプリ「相撲目覚まし」更新しました。

10月末に公開していた「相撲目覚まし」の新しいバージョンを公開しました。何とか今年中にできました。 画面を長押しすれば操作ガイドが現れたり、アラームをキャンセルしたときの音声をすぐにストップできるようにしたなど、使いやすくなったと思うので、インストールしている方はどうぞ更新してください。 https://play.google.com/store/apps/details?id=mashro.com.wixsite.mashro.dc06 です。 その後、スマホを画面オフにしてもアラームが鳴るよう改良したバージョンを別のアプリ「相撲目覚まし2」として公開しました。据え置きとしてではなくモバイルとして使用する場合にはこちらがおすすめです。 https://note.com/mashro/n/ncc9dc5302949

画面回転で苦労した話(原因はわかった)

画面を回転させると、なぜかレイアウトが崩れてしまう。 https://qiita.com/QiitaD/items/7d405e93f39a4a3c9d95 などを参考にさせていただいて、ちゃんと縦用の画面と横用の画面を作って、それぞれ layout と layout-land のフォルダに入れているのに、縦で立ち上げた画面を回転させても横用の画面にならず、縦用のレイアウトを無理やり横に合わせた形になってしまう。その逆も同じ。横で立ち上げた画面を縦にするときもうまくいかない。つまり、レイアウトの切り替えをやってくれないのである。その理由がわからず、ずいぶん悩んだ。 今度やっとその原因がわかったのだが、画面回転を検知するための設定に問題があった。具体的には、マニフェストの当該Activityに "android:configChanges="orientation|screenSize" を追記したとき、この問題が起きるようだ。 原因はわかったがまだ問題は残る。上記の追記は画面回転を検知するためには必要。 今回は、アプリの立ち上げ時にメッセージを出すにあたって、画面回転するたびに同じメッセージが出てはうるさいので、回転の後すぐはそれが出ないようにするために、この機能を使っていたのだった。 しかしこれをやると、画面のレイアウトが崩れてしまう・・・この両立をする方法はないのか。 (ちなみに、無理やり縦用と横用のレイアウトに違う名前を付けて、アクティビティ上で画面の向きを検知して 、 縦の時はsetContentView(縦用レイアウト)、横の時はsetContentView(横用レイアウト)としてみたが、 やはりレイアウトは切りかわらなかった。) 参考までに、画面回転の検知には、上記の追加を行ったうえで、以下のようなコードを AppCompatActivityの中に書く。この場合、画面が回転したらsharedPreferenceの"Rotated"がtrueになるので検知できる。 override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(new...

目覚まし時計アプリを公開します

 約1年かけて作っていたアプリ(アンドロイド用)が一応完成しました。昨日、グーグルの審査で承認されて、晴れて公開できるようになりました。  充電中のスマホや使用済みの古いスマホをアラーム付き置時計として使うアプリで、威勢のいい相撲の掛け声で目覚めて睡眠リズムを整えようとするものです。  タイトル:「相撲目覚まし-睡眠リズムを整える」 https://play.google.com/store/apps/details?id=mashro.com.wixsite.mashro.dc06   (アプリの特色) ①文字の色、背景の画像をお好みに応じて設定できます。ユーザーの撮影した写真などを背景とすることもできます。 ②最小限の動作でアラームの設定や解除などを行うことができます。 ③2種類のアラーム(相撲の掛け声/鳥の声とベルの音)を使用できます。いずれも音を止めた際に、あいさつ 、 日付、時刻、占いによる朝のメッセージを聞くことができます。 ④夜間は自動的に、ブルーレイが少ないなどリラックスできる画面(リラックス画面)となるように設定できます。就寝時にはさらに暗い画面(星空の画面など)とできます。 ⑤消灯予定時刻を知らせる音楽を流すことができます。 ⑥消灯時刻と起床時刻を記録することができます。 ※電源をつないだ状態での使用を想定しています。 ※設定できるアラームは24時間以内、1回に限ります。 ※スマホをオフにするとアラームは鳴りません。 ※個人情報を取得することはありません。外部との通信も一切行いません。 ※無料で、広告もありません。 (プライバシーポリシー)  ・本アプリは個人情報を取得することはありません。外部との通信も一切行いません。  ・スマホに保存されている画像を表示する機能がありますが、画像データへのリンクはアプリを終了すると消去されます。すなわち、後で同じ画像を表示するためには再度画像を選択する必要があります。   ※2023年12月30日に新バージョンに更新しました。 ※2025年12月20日に、画面をオフにしてもアラームが鳴るよう改良したものを、「相撲目覚まし2」として公開しました。↓ https://play.google.com/store/apps/details?id=mashro.com.wi...

エミュレーターのバグ?

イメージ
 現在作っている時計アプリについて、自分の実機以外の機種でも動くのか試しにエミュレーターを使って試してみた。新しい機種、新しいAPIでも動くかやってみようと、Pixel 6 Pro API 31を使った。  そしたら何と!変な時間が出るではないか。今までこんな経験はしたことがなかった。これまでも時差で9時間ずれていて一瞬驚いたことはあったが、今度はそうではない。半端にずれた時刻が表示されている。一方、エミュレーターのデフォルトの時計アプリは正しい時刻を指している。もしかして、今作っているアプリは最新機種には適合してないのか・・・。そこで、非常に簡単な、時間だけを表示するアプリを作ってみた。 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) setContentView(R.layout. activity_main ) findViewById<Button>(R.id. button ).setOnClickListener { val now = Calendar.getInstance() val nowYear = now.get(Calendar. YEAR ) val nowMonth = now.get(Calendar. MONTH )+ 1 val nowDay = now.get(Calendar. DAY_OF_MONTH ) val nowHour=now.get(Calendar. HOUR_OF_DAY ) val nowMinute = now.get(Calendar. MINUTE ) findViewById<TextView>(R.id. tvDate ). text = " $ nowYear 年  $ nowMonth 月  $ nowDay 日 " ...

AndroidStudioのプロジェクトをコピーする

 コーディングがある程度進んだところで、プロジェクトをコピーする必要が出てきました。今までのプログラムは一応動いているのでとっておきたいが、新しいアイディアを加えることも試してみたいので。  AndroidStudioにはプロジェクトをコピーする機能がないので、自分でやらなければなりません。ネットを検索すると、プロジェクトフォルダを複製してそれに手を加える方法がいくつか出てきましたが、私は次のような方法でこれをやりました。これでも、今のところ問題なく動いています。 ----------------------  まず、新しいプロジェクトを新しい名前で作ります。今までのプロジェクトを「myApp」、新しいのを「myNewApp」としておきましょう。  まず、コピーです。  myApp の AndroidManifest を開いてそのテキストを全てコピーします。そしてmyNewApp のマニフェストファイルを開き、そこにペーストします。すなわち、myNewAppのマニフェストの内容を全て、myAppの内容に置き換えます。  同様に、MainActivityの内容を全て置き換えます。  MainActivity以外のActivityやServiceを、myAppのプロジェクトツールウィンドウからコピーして、myNewAppの同じフォルダにペーストします。  myAppのプロジェクトツールウィンドウから、resの配下にあるフォルダを全てコピーして、myNewAppのresフォルダにペーストします。  次に置換です。  myNewAppのマニフェストを開いて、ctrl+Rを使って「myApp」を「myNewApp」に置換します。  myNewAppのアクティビティやサービスを一つずつ開いて、「myApp」を「myNewApp」に置換します。通常は各アクティビティの最初の行に一つあるだけだと思います。  myNewAppのresの中のthemesを開いて(複数ある場合は順に開いて)、「myApp」を「myNewApp」に置換します。  【後で付け加え。時期によってはこれをやらないとうまくいかないことがあります】myAppとmyNewAppのbuild.Gradle(Project・・・)を開いて比較し、アプリ名以外の違いがあったら、myNewAppのほうをmyAppと同じ内容に...

BroadcastReceiverによるメモリリークが修正できた件。

  時計アプリを作っていて、アラーム時刻をサービスに送ろうとしてBroadcastReceiverを使ったら、メモリリークが発生。しかしそれを何とか修正した件。 最初に作った送信側のActivityがこれ。 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_zoperation) //MyReceiverの登録 val filter1 = IntentFilter() filter1.addAction("this_is_alarm_time") registerReceiver(MyReceiver(), filter1) //ボタンを押すと findViewById(R.id.button).setOnClickListener{ //目覚まし時刻の入力(4桁の数字を入力) val alarmTime:String = findViewById(R.id.inputAlarmTime) .text.toString() val intent = Intent("this_is_alarm_time").apply { putExtra("alarmTime", alarmTime) } sendBroadcast(intent) } } } 受け側はこんな感じ。 var alarmTime2: String = "" class MyService : Service() { //MyReceiverをここに置く。 class MyReceiv...

Handlerによるメモリリークが修正できた件

  時計アプリを作っていた際に遭遇したメモリリーク。1秒ごとに、現在時刻をtvTimeNowというTextViewに表示するような簡単なプログラムだが、LeakCanaryで調べるとメモリリークがあることが判明した。 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_zmain) val handler = Handler(Looper.getMainLooper()) val refresh = object : Runnable { override fun run() { //時刻を表示 val now = Calendar.getInstance() tvTimeNow.text= "${now.get(Calendar.HOUR_OF_DAY)}:${String.format("%02d", now.get(Calendar.MINUTE))}" handler.postDelayed(this, 1000) } } handler.post(refresh) } }  メモリリークについてよくわかっているとは言えないのだが、LeakCanaryによるとこのrefreshのところでリークがあるらしい。それで、これを解放するコードを書けばいいのか・・・?と試行錯誤してつぎのようになった。 class MainActivity : AppCompatActivity() { latein...