Medoly Ver. 2.3.5

2015-10-17 Ver. 2.3.5
– Android 5.0以降におけるSDカード書き込み対応
– 歌詞取得プラグイン対応
– 歌詞フォルダ検索機能追加
– 再生予約解除機能追加
– シャッフル再生時、再生キュー完了で再シャッフルする機能追加
– ロック画面に画像を表示しないオプション追加
– その他細かい修正

Android 5.0以降におけるSDカード書き込み対応


Android 5.0以降でSDカード書き込みに対応させました。「設定」→「その他」→「外部ストレージの空き込み」を実行し、表示されるフォルダから対象のSDカード(外部ストレージ)のルートフォルダを選択してください。
Androidは、4.4以降では従来と同様にSDカード等の外部ストレージに書き込むことができなくなりました(読込は可能)。少し混乱があるようですが、ここで言うSDカードとは、携帯に後から追加する本当のSDカードのことで、最初から内蔵されているストレージのことではありません(フォルダ名がsdcardとなっているかどうかは無関係です)。内蔵ストレージは従来と同様に書き込みが可能です。
Android 4.4以降では、SDカードへの書き込みは、Googleが用意した特定の機能を使用するようになりました。SDカードの書き込みを行う場合、以下のような画面を表示させる必要があります。これは、ユーザに「この場所に書き込みますよ」と確認させるための共通画面で、これによりプログラムがバックグラウンドで勝手に書き込みを行うことができなくなります。これは、セキュリティ上の安全性を考慮した仕様変更のようです。
ここで問題になるのは、プログラムからSDカードに勝手に書き込みを行う処理を作成したい場合です。上記画面を選択した後、書き込み先を示すURIが取得できるため、これを保持しておくことで、プログラム上から同じ場所に何度も書き込むことはできます。
ところが、「指定フォルダ以下に自由に書き込みを行いたい」場合は少し話が変わります。 フォルダを示すURIを取得し、そのURIを基準にしてサブフォルダを検索する処理を作成する必要があります。ところが、このフォルダを選択する処理はAndroid 4.4には存在しません。Android 4.4はファイルの選択のみです。そのため、Android 4.4ではプログラムからSDカードへの書き込みが著しく制限されます。Android 5.0からはフォルダ選択が可能となり、そのフォルダ以下への書き込み操作ができるようになりました。SDカードへの書き込みが必要なファイラ等のアプリの多くで、最初にこの画面でSDカードを指定させているのは、そういう理由によるものです。
今回の変更ではこの機能を使用し、Android 5.0以降でもSDカードへの書き込みが行えるようにしました。SDカードの書き込みが必要となるのは、以下の3つの処理です。

・ M3Uプレイリストファイル出力処理
・歌詞取得プラグインの書き込み処理 (新規追加)

・設定のエクスポート処理

このうち、設定のエクスポートは単純にファイルを出力する画面を呼び出しているだけなので、Android 4.4でも可能です。ついでに言えば、Google Driveがインストールされていると、Google Driveへの書き込みもできるようになります(そういう仕様です)。以前から、Google Driveを介して複数の端末で設定を共有する機能が欲しいと思っていたのですが、思いがけず実現できてしまった形です。
残る2つについてですが、 この2点については、メディアファイルとの相対パスが必要になるため、単純にファイル書き込みを行うだけというわけにはいきませんでした。そこでSDカードを利用する場合は、最初にユーザにSDカードのルートディレクトリのURIを画面から指定してもらいます。指定されたパスがSDカードのルートディレクトリであると認識できた場合、アプリはそのURIを保持します。その上で、書き込み時はURIからパスを辿って書き込ませる、という手法を採ってます。ちょっと無理矢理な処理ですが、これぐらいしか思いつきませんでした。

余談ですが、画面から指定されたURIが「SDカードのルートディレクトリである」と判別する確実な手法が無いため、指定されたディレクトリ内にあるファイルの内容と更新日時を比較して判定しています。そのため、SDカードのルートディレクトリと同じファイル構成・同じファイル日時のファイルを用意したディレクトリを用意し、そこを指定してもルートディレクトリと誤認します。ご勘弁ください…。

ちなみに、先頭に「.」(ドット)を含む隠しフォルダへの書き込みはできない可能性があるので、使わないでください…。原因がよく分かってないのですが、新しい方式がそれをサブフォルダとしてうまく認識してくれません。現在のところ問題として認識はしていますが、解決できるかどうか不明。
長々と解説してみましたが、この辺は本当に苦労しました。この苦労でよく分かったのは、「Androidでストレージ扱うの、超めんどくせぇ」です。

歌詞取得プラグイン対応

従来、Twitterに自動的にツイートしたりするプラグインはありましたが、新たに歌詞取得プラグインというものをこさえてみました。これは、現在選択されているメディアに対する歌詞を余所から取得するというものです。(プラグインの詳細は別のエントリにて)
取得した歌詞は画面上に表示されますが、ファイルとして書き込むことも出来ます。書き込み先は、 メディアファイルと同一フォルダと、今回新たに追加した歌詞検索フォルダの2カ所です。メディアファイルへのタグ書き込みは今のところ考えていません。ファイル名はメディアファイルと同一名称で固定です…今のところは。書き込みタイプは、ファイルが存在しない場合のみ新規保存、または常に上書きの2種類があります。
イベント動作で、メディアが選択された時に自動的に読み込みに行くような動きも可能です。ただし、以下の2つの条件を満たす必要があります。
・Medoly側で歌詞が読み込まれていない、または歌詞が強制的に読み込まれる設定になっている
・プラグイン側がイベントに対応し、自動読み込みが行われる設定になっている。
歌詞のあるボーカルではなく、インストを主体にして聞く人も多いかと思うので、基本的に勝手には読みにいかない事が標準動作となることが望ましいと考えています。

2つ以上のプラグインが存在した場合の動作も設定できるようにしていますが、プラグインがまだ2つも無いので 意味がありません。

ちなみに、歌詞取得という事は、アルバムアートの取得もあるのかという話になりますが、まぁ、機能的にはほぼ同じなので作れます。機能的には大体埋まってますので、そのうち作ります。作ってないのは、単純に時間の問題です。というか、このプラグイン開発に時間割きすぎて飽きてしまったので、少しインターバル挟みます。疲れた。

歌詞フォルダ検索機能追加

こちらはユーザ様からの要望となります。従来、外部ファイルの歌詞を読み込むのは、メディアファイルと同一フォルダにある歌詞のみでしたが、今回、設定画面からフォルダを指定することで、そのサブフォルダにある歌詞ファイルを検索するようになりました。
この機能では、タグの内容から歌詞ファイルを探しに行くことができます。設定画面で検索対象のタグにチェックを入れると、チェックされたタグの値が全て含まれるファイル名のファイルを探しに行きます。なお、メディアファイルのファイル名は標準で検索対象に含まれます。そのため「01.mp3」等と単純なファイル名の場合、歌詞が誤爆する可能性が高まります。
ちなみに、歌詞は必ず全てのフォルダを探しに行き、対象となるファイルをリストアップしてから対象を決定します。これは歌詞の誤爆の可能性を下げるためです。単純に最初に発見したファイルを選択してしまうと、例えば、「サンプル歌.txt」と「サンプル歌 (アレンジバージョン).txt」という2つのファイルがあった場合、本来欲しいのは「サンプル歌.txt」なのに、「サンプル歌 (アレンジバージョン).txt」が選択されてしまう可能性があります。より目的のファイル名に近いファイルを選択する必要があると考えられるため、このような動作となっています。
注意点としては、対象フォルダにある全サブフォルダを探しに行くため、 ファイルが大量にあったり、深い階層があるフォルダを検索すると毎回歌詞の検索に時間がかかる可能性があります。こればっかりは仕方ないと思うので、運用でカバーしていただけると助かります。
ちなみに、歌詞の優先度は、メディアファイルと同一フォルダにある歌詞 → 内蔵歌詞 → 歌詞検索フォルダの歌詞 となっています。この優先度の根拠は、メディアファイルと同一フォルダにある歌詞は、表示させたい意思が一番強い歌詞であると考えられるため最優先、検索フォルダは誤爆の可能性が高いため、優先度を低くしてあります。ちなみに、今回の変更で各歌詞を読み込まない設定を追加しています。
そんな感じで、とりあえず思いつく限り誤爆を避ける実装をしてみましたが、イマイチ自信がありません。
私自身はこの機能をあまり利用していないため、この機能を使用している方は、この歌詞検索ルーチンについて、何か意見を頂けると助かります。「こんな風に間違った歌詞が表示された」といった、実際のファイル名を提示してくれると嬉しいです。

余談ですが、この機能を作成している途中で、「歌詞検索フォルダを作ろう」→「歌詞検索プラグインで取得した歌詞を保存できるようにしよう」→「SDカードに書き込みできるようにしよう」という感じで、各機能を連鎖的に作るハメになったので、作るまでに異様に時間がかかっています。

再生予約解除機能追加


再生キューを長押ししたメニューから、次に再生する曲を予約することができますが、同じ曲で再度長押しすると、予約を解除できるメニューが表示されるようにしました。予約を取りやめたい場合に使用してください。

シャッフル再生時、再生キュー完了で再シャッフルする機能追加

これはユーザ様からの要望です。
シャッフル再生の際、再生キューは固定された再生順を保持します。これは、再生キューを更新したり、再生順を切り替えるまでずっと保持していたのですが、再生キューの内容が全部再生完了した時点で、再シャッフルしてほしいという要望がありましたので、そのように実装しました。
一応、従来の動作もできるように再生順を保持する設定項目も追加しています。

ロック画面に画像を表示しないオプション追加


音楽再生時、ロック画面からの操作コントローラは欲しいけど、画像はあまり人に見られたくないという人も多いと思いますので、画像だけ表示しない設定を追加しました。
特にLollipopは、ロック画面にアルバムアートを表示させると、画像が画面全体に引き伸ばされて表示され、かなり目立ちますので、こういう設定は結構需要があるかな…と。

その他細かい修正

その他、多数の変更やバグ修正が加えられています。
目立ったところでは、最近のバージョンのAndroidだと、同一プレイリストが保存できなくなってたりしてるようなので、その辺の挙動を少し変更したりとか。