MediaPlayer#setDataSource のエラー対処法【Android】

つい最近 アプリを作っているとき・・・
音楽ファイルから MediaPlayer  に setDataSource  したい場面がありました。

そのとき、なぜか次みたいな 良く分からないエラー が出ます。

なにこれと思ったんですが、直し方は意外と簡単でした。

そこで この setDataSource でエラーが出てしまった時の対処法 をまとておきます。

MediaPlayer#setDataSource のエラーに遭遇した経緯

まずどういう場面でエラーに遭遇したのか、簡単に説明

自分の場合だとこういうケースでエラーが出てしまいました。

 

1.まず設定画面とかのActivityで音楽ピッカーを表示

2.その結果(URI)を onActivityResult  で取得

3.そして別ActivityでそのURIを setDataSource  するという感じ

 

そして出てきたのが冒頭のエラー

原因が分からなくて数時間くらい格闘したんですが、ようやく解決策らしきものが見つかりました。

MediaPlayer#setDataSorce のエラーの原因と解決策

主に次の2点を疑ったらエラーが発生しなくなります。(自分の場合)

1.ACTION_PICK の代わりに ACTION_OPEN_DOCUMENT を使う

まず原因として考えられるのが ACTION_GET_CONTENT  を使ってるから

ACTION_PICK  を使ってる場合も同じです。

▼ リファレンスでの ACTION_GET_CONTENT  の説明

アプリでデータの読み取りとインポートのみを行う場合は、ACTION_GET_CONTENT を使用します。この方法を使用すると、アプリは、画像ファイルなどのデータのコピーをインポートします。

引用元 : https://developer.android.com/guide/topics/providers/document-provider.html#client

単純に読み書きするだけの用途(一時的)に使うのが適してる模様

今回の場合、別Activityから音楽ファイルを参照する目的で使っていたので、エラーの温床になっていたらしいです。これは盲点でした。

 

そこで代わりに ACTION_OPEN_DOCUMENT を使うことにします。

ACTION_OPEN_DOCUMENT  についての説明

アプリからドキュメント プロバイダが所有するドキュメントへの、長期間の固定アクセスを可能にするには、ACTION_OPEN_DOCUMENT を使用します。ドキュメント プロバイダに格納されている画像をユーザーが編集するための、写真編集アプリなどの例が挙げられます。

引用元 : https://developer.android.com/guide/topics/providers/document-provider.html#client

大事なのは「長期間の固定アクセスを可能にする」という部分

この説明の通り、長期的に参照するファイルはコチラを使うのが良さそうです。
例えばBGMプレイヤーとか再生リスト系のアプリとか・・・

 

ということで、音楽ピッカーのコードを次のように置き換え ました。

単純に setAction  に渡してたアクションタイプを変えただけ

とはいえ「これでエラー解決!!」とはいかず、まだエラーが出てます・・・ orz

2.setDataSource の引数にパスではなくURIを渡す

実はエラーが出ていた原因はもう1つありました。

それは setDataSource に文字列でパスを渡してたこと

つまり先ほどの例なら、こういうコード

まあ content://  から始まるURIを渡してたので、エラーが出て当然と言えば当然ですね。

 

そこで文字列ではなく、URIを渡すことにしました。

▼ それが次のコード

まず Uri.patse( musicPath )  でパス文字列をUriオブジェクトに変換

そのあと setDataSource  にURIとして音楽ファイルを設定しているだけ

これで無事エラーが消えて、音声が再生できるようになりました。めでたしめでたし・・

ここまでのまとめ

以上、MediaPlayer#setSourceData でエラーが出るときの対処法でした。

音楽ピッカーに渡すアクションタイプを ACTION_OPEN_DOCUMENT に変更し、パスを文字列ではなくURIとして渡せば直るかもしれません。

参考までに対処法を残しておきます。