android.os.FileUriExposedException: file.jpg wird durch ClipData.Item.getUri() über die App hinaus exponiert

Lesezeit: 6 Minuten

Omers Benutzeravatar
Omer

Ich versuche, eine Taste zu machen, die die Kamera öffnet und ein Bild macht. Mein Code ist hier

//for imports check on bottom of this code block

public class HomeProfileActivity extends AppCompatActivity {
//Button camera
public static final String TAG = HomeProfileActivity.class.getSimpleName();
public static final int REQUEST_TAKE_PHOTO = 0;
public static final int REQUEST_TAKE_VIDEO = 1;
public static final int REQUEST_PICK_PHOTO = 2;
public static final int REQUEST_PICK_VIDEO = 3;
public static final int MEDIA_TYPE_IMAGE = 4;
public static final int MEDIA_TYPE_VIDEO = 5;

private Uri mMediaUri;
private ImageView photobutton;
private Button buttonUploadImage, buttonTakeImage;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home_profile);
    ButterKnife.bind(this);
}

@OnClick(R.id.buttonTakeImage)
void takePhoto() {
    mMediaUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
    if (mMediaUri == null) {
        Toast.makeText(this,
                "There was a problem accessing your device's external storage.",
                Toast.LENGTH_LONG).show();
    }
    else {
        Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, mMediaUri);
        startActivityForResult(takePhotoIntent, REQUEST_TAKE_PHOTO);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK){
        if (requestCode == REQUEST_TAKE_PHOTO) {
            Intent intent = new Intent(this, ViewImageActivity.class);
            intent.setData(mMediaUri);
            startActivity(intent);
        }
    }
    else if (resultCode != RESULT_CANCELED){
        Toast.makeText(this, "Sorry, there was an error", Toast.LENGTH_SHORT).show();
    }
}

private Uri getOutputMediaFileUri(int mediaType) {
    // check for external storage
    if (isExternalStorageAvailable()) {
        // get the URI

        // 1. Get the external storage directory
        File mediaStorageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);

        // 2. Create a unique file name
        String fileName = "";
        String fileType = "";
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

        if (mediaType == MEDIA_TYPE_IMAGE) {
            fileName = "IMG_" + timeStamp;
            fileType = ".jpg";
        } else if (mediaType == MEDIA_TYPE_VIDEO) {
            fileName = "VID_" + timeStamp;
            fileType = ".mp4";
        } else {
            return null;
        }
        // 3. Create the file
        File mediaFile;
        try {
            mediaFile = File.createTempFile(fileName, fileType, mediaStorageDir);
            Log.i(TAG, "File: " + Uri.fromFile(mediaFile));

            // 4. Return the file's URI
            return Uri.fromFile(mediaFile);
        }
        catch (IOException e) {
                Log.e(TAG, "Error creating file: " +
                        mediaStorageDir.getAbsolutePath() + fileName + fileType);
            }
        }

        // something went wrong
        return null;
    }

private boolean isExternalStorageAvailable(){
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)){
        return true;
    }
    else {
        return false;
    }
}

import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import butterknife.ButterKnife;
import butterknife.OnClick;

Ich habe auch ein Problem mit startActivityForResult in der Methode onclick und dem Import java.text.SimpleDateFormat; Springe auch in die Ausnahmelaufzeit, ich arbeite mit buildtoolsversion sdk 25

  • Uri.fromFile() funktioniert nicht auf Android 7.0+, mit a targetSdkVersion von 24 oder höher. Verwenden FileProvider stattdessen, wie ich in demonstriere diese Beispiel-App. Siehe auch diesen Blogbeitrag Und diesen Blogbeitrag.

    – CommonsWare

    15. Februar 2017 um 14:30 Uhr


  • Bitte sehen Sie sich die Antwort in dieser Frage an: stackoverflow.com/questions/38200282/…

    – Spark.Bao

    16. Februar 2017 um 3:12 Uhr

  • Einfache Erklärung hier verfügbar: Verknüpfung

    – Treffen Sie Vora

    2. März 2017 um 11:35 Uhr

Benutzeravatar von rahul sondarva
rahul sondarva

Neben der Lösung über den FileProvider gibt es noch eine andere Möglichkeit, dies zu umgehen. Einfach gesagt

 StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
 StrictMode.setVmPolicy(builder.build());

in der Methode Application.onCreate(). Auf diese Weise ignoriert die VM die Offenlegung des Datei-URI.

  • Das hat bei mir funktioniert, danke, alles, was ich für ein mögliches zukünftiges Problem wissen sollte, oder ich bin für eine Weile gut?

    – Thiago Queiroz

    17. August 2017 um 11:48 Uhr

  • StrictMode ist standardmäßig deaktiviert, und Benutzer müssen in ihrem Android den „Entwicklermodus“ aufrufen, um ihn zu aktivieren. Das macht die Lösung der Verwendung von StrictMode irrelevant.

    – Tamtom

    26. Dezember 2017 um 10:32 Uhr

  • Danke, arbeite für mich. Testgerät Android: 7.0 targetSdkVersion 26

    – DILSHAD AHMAD

    21. Juni 2018 um 18:59 Uhr

  • Lief wie am Schnürchen!

    – GeekWithGlasses

    7. August 2019 um 17:48 Uhr

  • Soll ich dies nur mit SDK-Version 24 oder höher umschließen

    – Abu Nayem

    18. Mai 2020 um 6:13 Uhr

Benutzeravatar von Jared
Jared

Diese Informationen stammen von:
FileUriExposedException

Dies wird nur für Anwendungen ausgelöst, die auf N oder höher abzielen. Anwendungen, die auf frühere SDK-Versionen abzielen, dürfen file:// Uri freigeben, es wird jedoch dringend davon abgeraten.

Also, wenn Ihr app/build.gradle Datei compileSdkVersion (Build-Ziel) Android N (API-Level 24) oder höher ist, wird dieser Fehler ausgegeben, wenn Sie eine Datei schreiben, auf die möglicherweise andere Apps zugreifen können. Am wichtigsten ist, wie Sie es in Zukunft tun sollten:

von hier genommen:
FileProvider

Ändern:

return Uri.fromFile(mediaFile);

sein

return FileProvider.getUriForFile(getApplicationContext(), getPackageName()+".fileprovider", mediaFile);

Hinweis: Wenn Sie kontrollieren mydomain.com könntest du auch ersetzen getPackageName()+".fileprovider" mit "com.mydomain.fileprovider" (dasselbe gilt für deine AndroidManifest.xml unter.

Außerdem müssen Sie Folgendes zu Ihrer hinzufügen AndroidManifest.xml Datei direkt vor Ihrer </application> Schild

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:grantUriPermissions="true"
        android:exported="false">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepaths" />
    </provider>

Dann müssen Sie eine Datei mit dem Namen hinzufügen filepaths.xml zu deinem app/src/main/res/xml Verzeichnis mit folgendem Inhalt

<paths>
    <external-files-path name="Pictures" path="Pictures" />
</paths>

Hinweis: Für alle anderen haben wir verwendet external-files-path oben, da Omer verwendet getExternalFilesDir(Environment.DIRECTORY_PICTURES) im Code. Für jeden anderen Standort überprüfen Sie bitte FileProvider unter dem Abschnitt “Verfügbare Dateien angeben” und ändern external-files-path zu einem der folgenden, je nachdem, wo sich Ihre Dateien befinden:

files-path
cache-path
external-path
external-files-path
external-cache-path

Auch überarbeiten Pictures oben als Ihr Ordnername.

Ein wichtiges Anti-Pattern, das Sie vermeiden sollten, ist Sie sollten NICHT verwenden if (Build.VERSION.SDK_INT < 24) { Ihnen zu erlauben, es auf die alte Weise zu tun, weil es nicht ihre ist Android-Version das erfordert dies, es ist dein Build-Version (Das habe ich beim ersten Programmieren übersehen).

Ich weiß, dass dies mehr Arbeit ist, aber dadurch kann Android nur der anderen App, mit der Sie teilen, temporären Zugriff auf die Datei gewähren, was für die Privatsphäre des Benutzers sicherer ist.

  • Nur schnell bearbeiten: Beim Pfad = “Bilder” wird zwischen Groß- und Kleinschreibung unterschieden. Bei der Verwendung von Environment.DIRECTORY_PICTURES an meinem Ende musste ich es als path=”Pictures” großschreiben, sonst konnte es keinen Pfad herausfinden.

    – David Sanders

    10. November 2017 um 22:59 Uhr

  • @DaveSanders Vielen Dank, dass Sie das bemerkt haben. Ich habe meine Antwort aktualisiert, um den Fall von Environment.DIRECTORY_PICTURES widerzuspiegeln, der zu “Bilder” (Titelfall) ausgewertet wird.

    – Jared

    15. Dezember 2017 um 2:51 Uhr


  • Bitte nicht die AndroidX-Version von FileProvider Paket hat androidx.core.content.FileProvider

    – hornet2319

    22. April 2021 um 11:04 Uhr

Add the below code where the SharingIntent called:-

if(Build.VERSION.SDK_INT>=24){
                    try{
                        Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
                        m.invoke(null);
                        shareImage(Uri.fromFile(new File(Path)));
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                }

1442950cookie-checkandroid.os.FileUriExposedException: file.jpg wird durch ClipData.Item.getUri() über die App hinaus exponiert

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy