他のアプリケーションのデータを利用する

他のアプリケーションのファイルにアクセスするには、以下の方法がある。

アプリケーションが所有するファイルを、他のアプリケーションからアクセス可能にするには以下の方法がある。

  • 他のアプリケーション(ユーザ)がアクセスできるように、ファイルのアクセスモード(アクセス権)を指定する。
  • アプリケーション間で同一のLinuxユーザIDを指定する。

ファイルのアクセスモードの指定

「data」デレクトリ内のアプリケーション専用のファイルへのアクセス

ファイルアクセス」で説明したように、アプリケーションの「data」デレクトリ内にアプリケーション専用のファイルを作成して、 そのファイルに対して読み書きをおこなうことができる。

このファイルの作成時に、ファイルのアクセスモードを指定することができる。

アクセスモードは通常、MODE_PRIVATEを指定するが、MODE_WORLD_READABLE,MODE_WORLD_WRITEABLEを指定すると、 他のアプリケーションからもファイルにアクセスできるようになる。

まず、他のアプリケーションから利用できるようにアクセスモードを指定してファイルを作成、 自アプリケーションから読み書きする例を示す。

リスト1(1)-他のアプリケーションからもアクセスできるファイルを作成(OtherFileSampleActivity.java)

作成されたファイルの属性を、DDMパースペクティブのファイルエクスプローラで確認してみると、 他のユーザにもアクセス権が与えられているのが確認できる。

 

 

このMODE_WORLD_READABLE,MODE_WORLD_WRITEABLEで指定されたファイルに、他のアプリケーションからアクセスをおこなうには、 他のアプリケーションのContextオブジェクトを取得して、そのContextオブジェクトをとおしてアクセスをおこなう。

リスト1(1)で作成したファイルを、他のアプリケーションから読み書きする例を以下に示す。

eclipseに新しいプロジェクトを作成、Activityに以下のようなコードを記述する。

リスト1(2)-他のアプリケーションのファイルにアクセス(UseOtherFileActivity.java)

45,74行目で、利用したいファイルを所有するアプリケーションのパッケージ名(21行目で定数定義)を指定して、 ContextWrapper#createPackageContextメソッドを呼び出すことにより、 他のアプリケーションのContextオブジェクトを取得している。

createPackageContextメソッドの第2引数の意味は、正直なところよく理解できていない。

この引数の意味については、「 Y.A.M の 雑記帳 Android 別々のアプリで SharedPreferences を共有」を参照。

このContextのopenFileOutputメソッド(46行目),openFileInputメソッド(75行目)を使う事により、 自アプリケーションと同様に、他のアプリケーションのファイルにアクセスできる。

リスト1(1)のコードとリスト1(2)のコードを比較すると、他のアプリケーションのコンテキストを使うところが異なるだけで、 同じコードが使えることになる。

リスト1(1)とリスト1(2)のプログラムを交互に実行して、データを読み書きおこなうと、お互いのデータがやりとりできるのが確認できる。

Preferenceファイルへのアクセス

Preference(5)-SharedPreferencesオブジェクトを使ってPreferenceデータにアクセス」 でみてきたように、getPreferencesメソッドおよびgetSharedPreferencesメソッドを使って、 設定データを保存するxmlファイルのアクセスモードを指定できる。

次の例は、他のアプリケーションからもファイルを利用できるようにアクセスモードを指定してPreferenceファイルを作成する例である。

リスト2(1)-他のアプリケーションからもアクセスできるPreferenceファイルを作成(OtherFileSampleActivity.java)

上記のプログラムで作成されたPreferenceファイルを、他アプリケーションからアクセスするには、 以下のコードで示すとおり、dataデレクトリへのファイルアクセスと同様、createPackageContextメソッドにより、 他のアプリケーションのContextオブジェクトを取得して、 そのContextオブジェクトのgetSharedPreferencesメソッドを利用すればすれば良いように思われる。

リスト2(2)-他のアプリケーションのPreferenceファイルにアクセス(UseOtherPreference1Activity.java)

しかしこのプログラムを実行すると、ファイルのアクセス権は変更され,データの読み書きは出来るのだが、何故かしら書込んだデータがxmlファイルに反映されない。

私の調査不足なのかも知れないが、どうもPreferenceファイルについては、他のアプリケーションから読込みはできるのだが、書き込みはできないようである。

 

では、PreferenceActivity画面を使って書き込んだデータを、他のアプリケーションから利用するにはどうしたら良いのだろうか。

PreferenceActivityの使用するxmlファイルのファイル名を変更する。」 のリスト15のプログラムを修正して、 PreferenceActivityが使用するPreferenceファイルの、ファイル名とアクセスモードを変更すると以下のようになる。

リスト3-PreferenceActivityのPreferenceファイルのアクセスモードを変更する()

ここで、16行目のsetSharedPreferencesNameメソッドを使って、Preferenceファイルのファイル名を変更する必要は 無いように思われる。

しかし、PreferenceActivityがデフォルトで使用するPreferenceファイルのアクセスモードは固定のようで、変更できなかった。

setSharedPreferencesNameメソッドを使って、Preferenceファイルのファイル名を変更する事で、ファイルのアクセスモードの変更が可能になるようである。

また、やはりこの場合も、データの読み書きは出来るのだが、書込んだデータがxmlファイルに反映されなかった。

アプリケーション間で同一のLinuxユーザIDを指定

異なるアプリケーション間で同一のLinuxユーザIDを指定する事で、 同じユーザIDを持つ他のアプリケーションのファイルにアクセスする事ができる。

ファイルのアクセスモードを、MODE_WORLD_READABLE,MODE_WORLD_WRITEABLEに指定した場合には、 すべてのユーザ(すべてのアプリケーション)からそのファイルはアクセス可能となってしまうが、 この方法では、同一のLinuxユーザIDを持つアプリケーションでなければアクセスできない事になる。

つまり、特定のアプリケーション以外からはアクセスさせたくない場合に、この方法を使えば良い事になる。

異なるアプリケーション間で同一のLinuxユーザIDを割り当てるには、以下のように 異なるアプリケーションのAndroidManifest.xmlのmanifestタグのsharedUserId属性に同じ値(文字列)を指定する。

また、デバッグ時にはeclipseが処理してくれるので問題にならないが、アプリケーション は、同一の証明書で署名されている必要がある。

リスト4-manifestタグのsharedUserId属性を指定(AndroidManifest.xml)

リスト1~3のプログラムの、ファイルのアクセスモードをMODE_PRIVATEに変更して、 アプリケーション間で同一のLinuxユーザIDを指定して、 プログラムを実行してみると同じ結果となる。(実行前に以前のプログラムをアンインストールしておくこと)

この場合も、Preferenceについては、書込んだデータがxmlファイルに反映されなかった。

他のアプリケーションのリソースを利用する。

ファイルと同様、他のアプリケーションのContextオブジェクトを取得する事により、 他のアプリケーションの所有するリソースにアクセスする事ができる。

以下のプログラムは、他のアプリケーションの文字列リソース,assetsデレクトリのファイル,rawデレクトリのファイル,Drawableリソースに、 アクセスする例である。

リスト1-他のアプリケーションのリソースに利用(UseOtherResourceActivity.java)

このプログラムは、他のアプリケーションのR.javaに定義されている定数を利用している(59,104,128行目)ため、 プロジェクトのビルドパスに利用するプロジェクトを指定する必要がある。

eclipseのパッケージ・エクスプローラーより、プロジェクトを選択して、右クリックにて 表示されるメニューより「ビルド・パス(B)」→「ビルド・パスの構成(c)...」を選択。

表示されるダイアログボックスにて、右側のペインの「プロジェクト(p)」タブを選択して、「追加ボタン(A)...」を押下し、 参照先のプロジェクトを選択する。

 

 

確認はしていないが、同様の方法で、他のアプリケーションのresデレクトリ配下のすべてのリソースが利用できるものと思われる。

他のアプリケーションのデータベースを利用。

ContextWrapper#openOrCreateDatabaseメソッドを使うと、 SQLiteデータベースファイルのアクセスモードを指定する事ができるようだ。

でも、SQLiteOpenHelperクラスから、 データベースファイルのアクセスモードを指定する方法が見当たらない。

ググッてみると、こんな記事(「 sharedUserIdを使って他のアプリケーションデータにアクセスする « Tech Booster 」と「 android - SqliteOpenHelper for Mode_World_Readable, how - Stack Overflow 」)も見つかった。

SharedUserIDを使うとできるらしい?

 

しかし、他のアプリケーションのデータベースのデータを利用するには、多少実装に手間がかかるが、 コンテンツプロパイダを使うのが最もオーソドックスな方法だと思う。

 

ページのトップへ戻る