背景
主に開発時に, Android + C/C++ で fopen, std::ifstream などで実機上のファイルの読み書きをしたい.
SDK level 28 でコンパイルし, Android 10(Pixel4) で確認しています.
/sdcard
, /storage/emulated/0
Android M から, /sdcard
へは Toast などでユーザから同意取得(or Android 設定で対応)になりました.
Permission を取得していればアクセスできます.
JAVA でいくらかコード記述を書く必要があります.
開発時であれば, adb で設定することもできます.
https://github.com/TilesOrganization/support/wiki/How-to-use-ADB-to-grant-permissions
https://stackoverflow.com/questions/46658643/android-grant-permissions-through-adb
PC(ホスト)でこの領域にあるファイルをやりとりするには, adb push/pull を使います(adb sync も使えるはず)
/data/local/tmp
permission 不要で読み書きできました.
PC(ホスト)でこの領域にあるファイルをやりとりするには, adb push/pull を使います(adb sync も使えるはず)
adb shell ではそのままではファイルは ls で出てこないので注意です
ファイル容量に制限があるかもしれません.
/data/user/0/com.example.yourapp
(アプリ固有ストレージ)
/data/user/0/<appid>
も permission 不要で読み書きできました.
(/user/0
はマルチユーザを考慮したパスなので, /data/data/<appid>
でもアクセスできるはず)
PC(ホスト)でこの領域にあるファイルをやりとりするには, いったん adb shell run-as com.example.yourapp cp ...
で /sdcard or /data/local/tmp を介してファイル転送をする必要があります.
adb exec-out run-as ...
で, アプリ固有フォルダから PC 上の stdout に読み出しはできます.
adb exec-in run-as
は exec-in と run-as を組み合わせることができませんでしたのでダメでした.
ファイル容量に制限があるかもしれません.
APK の asset folder(読み込みのみ)
AAssetManager を使います. Android の構造上しかたがないですがめんどいですね...
コンテキストは JNI あたりを介して Java のレイヤーから取得する必要があります.
基本的にはシェーダファイルや, アプリからしか読めないファイルを置く場所です.
加筆: 優秀な Android 開発若人さまから, fopen, fread をエミュレートする方法をお教えいただきました. ありがとうございます. 詳細はコメントを参照ください.
相対パス
fopen("muda")
, fopen("./muda")
のようなファイルパスは(storage permission を取得したとしても)アクセス不可でした.
Android 10 以降
実行権限などに制限があります. いずれ /data/local/tmp
の読み書きも制限されてしまうかもしれません...
まとめ
デバッグ用にちょっとしたファイルを読み書きしたいのであれば, /data/local/tmp
を使うのがよいと思われます.