it-swarm.com.de

android.os.FileUriExposedException: file.jpg über ClipData.Item.getUri () über App hinaus verfügbar gemacht

Ich versuche einen Knopf zu machen, der die Kamera öffnet und ein Foto 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 der Import Java.text.SimpleDateFormat; springt auch in der Ausnahmelaufzeit .__

28
Omer

Neben der Lösung mit dem FileProvider gibt es eine andere Möglichkeit, dies zu umgehen. Einfach gesagt

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

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

108
rahul sondarva

Diese Informationen stammen von: FileUriExposedException

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

Wenn also die compileSdkVersion (Build-Ziel) app/build.gradle-Datei 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. Am wichtigsten ist hier, wie Sie es vorwärts machen sollen:

von hier aus genommen: FileProvider

Veränderung:

return Uri.fromFile(mediaFile);

sein

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

Hinweis: Wenn Sie mydomain.com steuern, können Sie getPackageName()+".fileprovider" auch durch "com.mydomain.fileprovider" ersetzen (das gleiche gilt für Ihren AndroidManifest.xml unten).

Außerdem müssen Sie der AndroidManifest.xml-Datei unmittelbar vor Ihrem </application>-Tag Folgendes hinzufügen

    <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 filepaths.xml zu Ihrem app/src/main/res/xml-Verzeichnis mit folgendem Inhalt hinzufügen

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

Hinweis: Für alle anderen haben wir external-files-path verwendet, da Omer getExternalFilesDir(Environment.DIRECTORY_PICTURES) im Code verwendet hat. Überprüfen Sie für jeden anderen Speicherort FileProvider im Abschnitt "Angeben verfügbarer Dateien" und ändern Sie external-files-path in einen der folgenden Werte, je nachdem, wo sich Ihre Dateien befinden:

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

Überarbeiten Sie auch Pictures oben als Ihren Ordnernamen.

Ein wichtiges Anti-Pattern, das Sie vermeiden sollten, ist, dass Sie NICHTif (Build.VERSION.SDK_INT < 24) { verwenden sollten, um es Ihnen auf die alte Art und Weise zu ermöglichen, da dies nicht ihre Android-Version ist, die dies erfordert. Es ist Ihre build version (Ich habe dies beim ersten Codieren vermisst).

Ich weiß, dass dies mehr Arbeit bedeutet, jedoch ermöglicht Android es, nur der anderen App, mit der Sie gemeinsam arbeiten, temporären Zugriff auf die Datei zu gewähren, was für die Privatsphäre des Benutzers sicherer ist.

23
Jared
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();
                    }
                }
0
MEGHA DOBARIYA