4

ファイル ストレージに関連するドキュメントに最も近いのはこの投稿(アクセスできない場合は以下を参照) ですが、いくつか疑問が残ります。

ここで、どのパスがどのストレージにマップされているか、どのようにハードコードする必要があるか、どのくらい正確にアクセスする必要があるかを見て、本当に、本当に、本当に本当に知りたい. 実際のコード サンプルは最高です。これをいじってからの私の最善の推測は次のとおりです。

  • /sdcard-> は内部 eMMC スロットにマップされ、アクセスが制限されます。Environment.getExternalStorageDirectory(); ...まだこれを返します。
  • /media -> 内部 8GB メモリにマップします (これに書き込むことができます)
  • /データ -> ?
  • ? -> オプションの microSD カードにマッピング

/sdcard が代わりに制限付きストレージにマップされている場合、外部 (オプション、追加、ポップアウトできるもの) SD カードにアクセスするにはどうすればよいですか?

ここで、Nook 開発者ドキュメントを引用します。

背景 現在市場に出回っている NOOK Color デバイスには 2 つの異なるパーティション スキームがあり、1 つは /data パーティションのアプリケーションで 250MB しか使用できず、もう 1 つは /data パーティションのアプリケーションで 4GB を使用できます。その結果、スペースを効果的に管理するような方法でアプリケーションを設計および開発することが不可欠です。ご記入いただけない場合は、ショップでの配布はお受けできません。

アプリケーションが大量のデータ (画像、オーディオ、またはビデオ コンテンツを含むがこれらに限定されない) を必要とする場合は、実行時にそれらのリソースをダウンロードし、デバイスのより大きなパーティションに保存する必要があります。アプリケーションが 100MB を超えるデータまたはリソースを要求して保存する場合は、次の制限に従う必要があります。

大量のデータがアプリケーションによって使用/配信される場合、アプリケーションは説明に明確かつ明示的に記載する必要があります。リソースとデータを適切なパーティションに書き込む必要があります。次のように、デバイスの /data パーティションが拡大されているかどうかを検出できます。

StatFs stat = new StatFs("/data"); 
long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount(); 
long megAvailable = bytesAvailable / 1048576; 
if (megAvailable > 1000){   
... write your resources in /data
} else {  
... write your resources on /mnt/media ... 
} 

/data 上のアプリケーションのプライベート スペースにデータを書き込むには

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_WORLD_READABLE); 

アプリケーションは、デバイスに SD カードが存在することを前提とすべきではありませんが、次の呼び出しを介してテストできます。

Environment.getExternalStorageState(); SD カードが見つからない場合、アプリケーションは正常に終了し、終了の理由をユーザーに通知する必要があります。

/media パーティションと ExternalStorage にアクセスするには、マニフェストで宣言する必要があることに注意してください。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
</uses-permission>
4

2 に答える 2

4

さて、これが私が過去数週間で学んだことです。

内部SD カードに書き込みたい場合は、 Context.getFilesDir()を使用します。アプリケーションのプライベート ディレクトリが返されます。内部フラッシュ ストレージ (別名「/data」) に独自のディレクトリを作成することはできません。アプリケーションが割り当てられるフォルダー以外の場所に書き込む権限がありません。「/data」と「/media」の 2 つの内部パーティションがあると思われますが、「/media」にアクセスできず、命を救うことができません。

外部フラッシュメモリ「/sdcard」が利用可能な場合は、それを使用できます。これは、デバイスから飛び出すことができるカードです。これには 2 つの方法があります。

  • アプリに割り当てられたフォルダーに物を保存します (そのため、アプリケーションがアンインストールされると削除されます)。そのフォルダーはContext.getExternalFilesDir()で見つけることができます 。
  • 「/sdcard/foo/bar」の下のハードコードされたパスまたは Environment.getExternalStorageDirectory() /何でも、どこにでも物を保存します。

B&N の担当者によるこの投稿(私の質問で参照したもの) は、ちょっとしたニシンであることが判明しました。"/sdcard" は eMMC スロットにマップされません。内部 eMMC へ」という意味です。

この B&N の投稿では、「/media」は内部的なものであると書かれていますが、適切なマニフェスト アクセス許可を持っていても書き込めません。

これは私のテスト デバイスのスクリーン キャプチャで、アクセスできるものとできないものを示しています。 ここに画像の説明を入力

そのためのコード (FileUtils はデフォルトで SDK に含まれていないことに注意してください。これは org.apache.commons.io ライブラリからのものです):

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    TextView dataView = (TextView) findViewById(R.id.data);
    dataView.setText(testIt("/data"));

    TextView mediaView = (TextView) findViewById(R.id.media);
    mediaView.setText(testIt("/media"));

    TextView mntMediaView = (TextView) findViewById(R.id.mntMedia);
    mntMediaView.setText(testIt("/mnt/media"));

try {
        File fd = this.getFilesDir();
        if(fd != null) {
            TextView fdView = (TextView) findViewById(R.id.filesDir);
            fdView.setText("getFilesDir(): " + testIt(fd.toString()));
        }
} catch (Exception e) {
    e.printStackTrace();
}

try {
        File efd = this.getExternalFilesDir(null);
        if(efd != null) {
            TextView efdView = (TextView) findViewById(R.id.externalFilesDir);
            efdView.setText("getExternalFilesDir(): " + testIt(efd.toString()));
        }
} catch (Exception e) {
    e.printStackTrace();
}

try {
    File esd = Environment.getExternalStorageDirectory();
        if(esd != null) {
            TextView esdView = (TextView) findViewById(R.id.externalStorageDirectory);
            esdView.setText("getExternalStorageDirectory(): " + testIt(esd.toString()));
        }
} catch (Exception e) {
    e.printStackTrace();
}

try {
    File espd = Environment.getExternalStoragePublicDirectory(null);
        if(espd != null) {
            TextView espdView = (TextView) findViewById(R.id.externalStoragePublicDirectory);
            espdView.setText("getExternalStoragePublicDirectory(): " + testIt(espd.toString()));
        }
} catch (Exception e) {
    e.printStackTrace();
}
}

public String testIt(String dir){
    StatFs stat = new StatFs(dir);
        long bytesAvailable = (long) stat.getBlockSize() * (long) stat.getBlockCount();
        long megAvailable = bytesAvailable / FileUtils.ONE_MB;
        File dirFile = new File(dir + "/test/");
        dirFile.mkdir();

        return dir + "/test \n canRead() " + dirFile.canRead() + ", \n canWrite() " + dirFile.canWrite() + " with " + megAvailable + "MB available";
}
于 2011-10-22T22:39:30.530 に答える
0

まずは以下の方法を試してみてください。

どちらも書き込み可能なディレクトリを返さない場合は、次のgoogle-groups スレッドを確認し、最後の回答で提供されたコードを使用して、現在のすべてのマウント ポイントを列挙します。

Galaxy Sでも同じ問題があります。これまで、入手したすべてのAndroidデバイスで
「マウント」コマンドを使用できました。利用可能なボリューム解析「マウント」応答のリストを作成します。これは完璧ではありませんが、Android ストレージ API よりも巧妙です。

String cmd = "/system/bin/mount"; 
try { 
   Runtime rt = Runtime.getRuntime(); 
   Process ps = rt.exec(cmd); 

   BufferedReader rd = new BufferedReader( new InputStreamReader(ps.getInputStream()) ); 
   String rs; 
   while ((rs = rd.readLine()) != null) 
   { 
       //check what you need! 
       Log.i("MOUNT_CMD", rs); 
   } 
   rd.close(); 
   ps.waitFor(); 
} catch(Exception e) { 
//...
}

Nook デバイスの実行中に microSD カードを挿入できる場合は、次のことも試してみてください。

mVolumeManagerReceiver = new BroadcastReceiver() { 
  public void onReceive(Context context, Intent intent) { 
    Log.i("MediaMounter", "Storage: " + intent.getData()); 
  } 
}; 

IntentFilter filter = new IntentFilter(); 
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 
filter.addAction(Intent.ACTION_MEDIA_REMOVED); 
filter.addDataScheme("file"); 
context.registerReceiver(mVolumeManagerReceiver, filter);
于 2011-10-16T15:33:14.577 に答える