4

私は Android には比較的慣れていませんが、Java および C ベースのプログラミングの経験があり、現在、開発用に通常のツールセットを備えた Eclipse を使用しています。私はこの主題に関するほとんどの投稿を読み、すべての推奨事項とテストを含めて適用したと信じています。私は以前、FileOutputStream を使用して、内部のアプリケーション固有のファイルに書き込み、L8 用にビルドしましたが、問題はありませんでした。Build L7 for Android 2.1を使用して、SDカードのファイルに書き込もうとしています。次のコードは、基本コードをテストするために使用している 3 つのボタン (書き込み、読み取り、送信) を持つ単一のアクティビティからのものです。FileOutputStream (FOS) コンストラクターが AOK を渡すまでに含まれるすべてのテスト (exists、writeable、および createNewFile または mkdirs の IOException) が AOK に合格しますが、FOS 構成体は失敗し、FileNotFoundException をスローします。下記参照。デバッグを実行し、問題を確認しました。下部の LogCat を参照してください。これは、256kB のビルドに含まれる SD カードを使用して、ADB を介して Eclipse 標準エミュレーターで実行されます。

私の onw createExternalStorageFile() メソッドから。

File file = null;
        file = new File(Environment.getExternalStorageDirectory(), mfileName);              
        if(file != null) {
            //file.mkdirs();
            try {
                file.createNewFile();
            } catch (IOException e1) {
                Log.e(TAG, "createNewFile() failed!", e1);
                return false; 
            } 
        }
        if(!file.exists()) {
            Log.d(TAG, "file does not exist!");
        }
        if(!file.canWrite()) {
            Log.d(TAG, "cannot write to file!");
        }
        Log.d(TAG, "full file-path is: " + file.toString());

        FileOutputStream fOS = null;
        try {
            //fOS = new FileOutputStream(file);
            fOS = new FileOutputStream(file.toString());
            // *** THIS THROW THE FILENOTFOUNDEXCEPTION ***
        } catch (FileNotFoundException e1) {
            Log.e(TAG, "fOS-FileNotFoundException", e1);
            return false;
        }
        // fOS IS STILL NULL - HOW CAN THIS BE!
        if(fOS != null) {
            try {
                fOS.write(TESTDATA.getBytes());
                fOS.close();
            } catch (IOException e1) {
                Log.e(TAG, "IOException from fOS-write()!", e1);
                return false;
            }
            Log.d(TAG, "fos-fd is: " + fOS.toString());
        }
        return true;

>

私のマニフェストファイルには、次のように uses-permission 宣言が含まれています。

>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="org.eddiem.adeveloper.externalfilesend"
      android:versionCode="1" android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
        <activity android:name=".ExternalFileSendActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

>

では、これは宣言の範囲外であり、問​​題ないはずですか?

私のすべてのテストが動作することを確認しているように見えるにもかかわらず、FileOutputStream が失敗する理由のこの謎を解決するのを手伝ってくれる人はいますか?

> LogCat: 11-02 15:40:54.754: DEBUG/MediaScannerService(154): スキャン ボリューム外部 11-02 15:40:54.764: VERBOSE/MediaProvider(154): /sdcard ボリューム ID: 300427547 11-02 15: 40:54.894: INFO/System.out(202): デバッガーが解決しました (1479) 11-02 15:40:55.024: VERBOSE/MediaProvider(154): 接続されたボリューム: 外部 11-02 15:40:55.904: VERBOSE/ MediaScanner(154): pruneDeadThumbnailFiles... android.database.sqlite.SQLiteCursor@44c434f0 11-02 15:40:55.915: VERBOSE/MediaScanner(154): /pruneDeadThumbnailFiles... android.database.sqlite.SQLiteCursor@44c434f0 11- 02 15:40:55.925: DEBUG/MediaScanner(154): プレスキャン時間: 715ms 11-02 15:40:55.955: DEBUG/MediaScanner(154): スキャン時間: 4ms 11-02 15:40:55.955: DEBUG/MediaScanner (154): ポストスキャン時間: 55ms 11-02 15:40:55.955: DEBUG/MediaScanner(154): 合計時間: 774ms 11-02 15:40:55。964: DEBUG/MediaScannerService(154): スキャン ボリューム外部 11-02 15:44:50.934: DEBUG/KeyguardViewMediator(52): pokeWakelock(5000) 11-02 15:44:51.334: DEBUG/KeyguardViewMediator(52): pokeWakelock (5000) 11-02 15:44:51.384: INFO/ActivityManager(52): 表示されたアクティビティ org.eddiem.adeveloper.filesendl7/.FileSendL7Activity: 239793 ミリ秒 (合計 255760 ミリ秒) 11-02 15:44:51.394: INFO/ Armassembler(52):生成されたScanline__00000077:03545404_00000A04_00000000 [29 IPP](51 INS)の[0x46AC60:0x46AD2C]の757079 NS 11-02 15:44:51.414:INFAMESM4:414:414:414:414:414:414:414 (98 ins) 657626 ns 11-02 15:45:05.884 の [0x46ad30:0x46aeb8]: DEBUG/FileSendL7Activity(202): フル ファイル パス: /sdcard/testFile.txt 11-02 15:45:22.484:エラー/FileSendL7Activity(202): fOS-FileNotFoundException 11-02 15:45:22.484: エラー/FileSendL7Activity(202): java.io.FileNotFoundException: /sdcard/testFile.txt 11-02 15:45:22.484: エラー/FileSendL7Activity(202): org.apache.harmony.luni.platform.OSFileSystem で。オープン (OSFileSystem.java:244) 11-02 15:45:22.484: エラー/FileSendL7Activity (202): java.io.FileOutputStream で。(FileOutputStream.java:97) 11-02 15:45:22.484: エラー/FileSendL7Activity (202): java.io.FileOutputStream.(FileOutputStream.java:168) 11-02 15:45:22.484: エラー/FileSendL7Activity(202): java.io.FileOutputStream.(FileOutputStream.java:147) 11- 02 15:45:22.484: エラー/FileSendL7Activity(202): org.eddiem.adeveloper.filesendl7.FileSendL7Activity.creatExternalStorageFileOS (FileSendL7Activity.java:149) 11-02 15:45:22.484: エラー/FileSendL7Activity(202): でorg.eddiem.adeveloper.filesendl7.FileSendL7Activity.access$0(FileSendL7Activity.java:124) 11-02 15:45:22.484: エラー/FileSendL7Activity(202): org.eddiem.adeveloper.filesendl7.FileSendL7Activity$1.onClick(FileSendL7Activity.java:176) 11-02 15: 45:22.484: エラー/FileSendL7Activity(202): android.view.View.performClick (View.java:2364) で

>

ありがとう

4

2 に答える 2

4

これを読むことから学ぶべき多くの教訓があります。まず、Eclipseまたは他のIDEが完全に更新されていること、およびすべてのパッケージとツールが正しくロードされていることを確認します。次のレッスンは、すべてのツールがどのように機能するかを確実に理解することです。以下を参照してください-DDMSのFile_Explorer。これらの明らかなコーディングの問題に関連する最大の単一の問題は、Eclipseデバッグツールを介して提供されたコーディング実験の結果が、Androidのドキュメントに記載されているものとはまったく異なる画像を示していたことです。私自身のパラノイアが残りの問題を引き起こし、コードスニペットの多くのバージョンとあまりにも多くのテストに単純に含めました。

技術的な問題/回答は次のとおりです。

  1. Android 2.1(API-L7)と2.2(API-L8)は、異なるsdcardファイル構造を実装しています。したがって、getExternalStorageDirectory()は、L7の場合は/ sdcard /を返し、L8の場合は/ mnt /sdcard/を返します。

  2. http://developer.android.com/guide/topics/data/data-storage.htmlにある外部ストレージのAndroidドキュメントは正しいです。2.1(L7)+にはEnvironment.getExternalStorageDirectory()を使用し、2.2(L8)+にはContext.getExternalFilesDir(null)のみを使用します

  3. Fileオブジェクトを作成しても、指定された名前のファイルまたはディレクトリは作成されません。ルートとその中のファイルを超えて実際にディレクトリツリーを作成する場合は、mkdirs()とcreateNewFile()を使用する必要があります。ただし、FileOutputStreamを正常に開くと実際のファイルが作成されるため、多くの場合、createNewFile()を使用する必要はありません。独自のディレクトリを作成する場合は、mkdirsを使用する必要があります。

  4. Eclipseで作成され、エミュレーターで使用されるAndroid仮想デバイスは、実際にはディレクトリとファイルを作成します。これらは、デバッグ中にDDMSの[File_Explorer]タブを使用して確認できます。注:これらのディレクトリとファイルは永続的であり、自動的に削除されることはありません。コードを実行またはデバッグした後、ツールを使用して自分でファイルを削除します。

  5. 最後に、バイト配列を使用するBufferedOutputStreamは、小さなファイルや複数の書き込みに適したオプションです。FileWriteはchar配列に使用され、すべての場合にManifest.XMLに含める必要があります

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

言葉の多いQ&Aの最後の謝罪ですが、多くの人が私の痛みを読んで学んでくれることを願っています。:o)

于 2011-11-05T16:13:29.867 に答える
1

これを試して

if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        Log.e("TEST", "this is bad");
}

File file = new File(getExternalFilesDir(null), "test.csv");

try {
    FileOutputStream fos = new FileOutputStream(file);
fos.write(...);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
于 2011-11-02T00:15:03.450 に答える