web-dev-qa-db-ja.com

Androidプログラムで外部ストレージからファイルを削除できません

パスにあるファイルを削除しようとしています

/storage/714D-160A/Xender/image/Screenshot_commando.png

これまでに行ったこと:

  try{
        String d_path = "/storage/714D-160A/Xender/image/Screenshot_commando.png";
        File file = new File(d_path);
        file.delete();

     }catch(Exception e){

        e.printStackTrace();
     }

そしてファイルはまだその場所にあります(削除されません:()

また、マニフェストファイルで許可を与えました。

<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission Android:name="Android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission Android:name="Android.permission.STORAGE" />
14
Secret
public static boolean delete(final Context context, final File file) {
    final String where = MediaStore.MediaColumns.DATA + "=?";
    final String[] selectionArgs = new String[] {
            file.getAbsolutePath()
    };
    final ContentResolver contentResolver = context.getContentResolver();
    final Uri filesUri = MediaStore.Files.getContentUri("external");

    contentResolver.delete(filesUri, where, selectionArgs);

    if (file.exists()) {

        contentResolver.delete(filesUri, where, selectionArgs);
    }
    return !file.exists();
}
11
Secret

ContentResolverを使用してメディアファイルを削除することは誤りであり、ユーザーに多くの問題を引き起こします。
Android Jelly bean(4.3)よりも大きいバージョンのContentResolverから情報を削除するだけでは、sd-card上のファイルを削除できません。
これはAndroid KitKat(4.4)より前のバージョンでのみ機能します。
そのため、Androidチームが提供した DocumentProvider です。

なぜcontentResolver.delete(...)が間違っているのですか?
1。 sd-cardを埋めます
Android 4.3よりも大きいバージョンのContentResolverによってsd-card上のメディアファイルを削除しようとすると、contentResolver.delete(...)アプローチは情報を削除するだけなので、実際のメディアファイルはそのまま残りますメディアの(名前、日付、パス...)そして、sd-cardに未登録のメディアファイルが存在することになります。ContentResolverは、それらの存在を知らなくて、ギャラリーでそれらを見ることができなかったので、 'この方法で削除されたままで、ユーザーがsd-card上のメディアファイルを削除しようとするたびにsd-cardを埋めます。

2。メディアファイル(画像、ビデオ、GIFなど)がギャラリーに返されます
これらの未登録のメディアファイルを見つけ、不要なメディアファイルがなくなったとユーザーが想定している間、通常の動作としてそれらを再度ContentResolverに追加する多くのアプリが、特にギャラリーやファイルマネージャーにあります。確かに、デモの途中で削除された画像や動画が表示されることを想定したユーザーはいないでしょう。

では、sd-cardのメディアファイルを削除する正しい方法は何ですか?
まあ、これはすでにDocumentProviderを使用して回答済みです here

11
Eftekhari

Android 4.4以降、通常の方法を使用してSDカードファイル(Appディレクトリを除く)に書き込むことはできません。DocumentFileそのため。

次のコードは私のために働きます:

private void deletefile(Uri uri, String filename) {
    DocumentFile pickedDir = DocumentFile.fromTreeUri(this, uri);
    try {
        getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    } catch (SecurityException e) {
        e.printStackTrace();
    }

    DocumentFile file = pickedDir.findFile(filename);
    if(file.delete())
        Log.d("Log ID", "Delete successful");
    else
        Log.d("Log ID", "Delete unsuccessful");
}

ここで、filenameは削除するファイルの名前、uriACTION_OPEN_DOCUMENT_TREEから返されるURIです。

private static final int LOCATION_REQUEST = 1;

private void choosePath() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    intent.addCategory(Intent.CATEGORY_DEFAULT);
    startActivityForResult(intent, LOCATION_REQUEST);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
    if (requestCode == LOCATION_REQUEST && resultCode == Activity.RESULT_OK) {
        Uri uri;
        if (resultData != null) {
            uri = resultData.getData();
            if (uri != null) {
                try {
                    getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                } catch (SecurityException e) {
                    e.printStackTrace();
                }

                /* Got the path uri */
            }
        }
    }
}
4
Spikatrix

ストレージパスをハードコーディングする代わりにEnvironment.getExternalStorageDirectory().getAbsolutePath()を使用する

String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
File f = new File(baseDir + "/714D-160A/Xender/image/Screenshot_commando.png");
boolean d = f.delete();
3
SiSa