ক্লিপডাটা.আইটেম.জেটউরির মাধ্যমে অ্যাপের বাইরেও উন্মুক্ত


104

অ্যান্ড্রয়েড ফাইল সিস্টেমে নতুন বৈশিষ্ট্য যুক্ত হওয়ার পরে আমি কোনও সমস্যার সমাধান করার চেষ্টা করছি তবে আমি এই ত্রুটিটি পেয়েছি:

android.os.FileUriExposedException: file:///storage/emulated/0/MyApp/Camera_20180105_172234.jpg exposed beyond app through ClipData.Item.getUri()

সুতরাং আমি আশা করি যে কেউ আমাকে এটি ঠিক করতে সহায়তা করতে পারে :)

ধন্যবাদ

private Uri getTempUri() {
    // Create an image file name
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
    String dt = sdf.format(new Date());
    imageFile = null;
    imageFile = new File(Environment.getExternalStorageDirectory()
            + "/MyApp/", "Camera_" + dt + ".jpg");
    AppLog.Log(
            TAG,
            "New Camera Image Path:- "
                    + Environment.getExternalStorageDirectory()
                    + "/MyApp/" + "Camera_" + dt + ".jpg");
    File file = new File(Environment.getExternalStorageDirectory() + "/MyApp");
    if (!file.exists()) {
        file.mkdir();
    }
    imagePath = Environment.getExternalStorageDirectory() + "/MyApp/"
            + "Camera_" + dt + ".jpg";
    imageUri = Uri.fromFile(imageFile);
    return imageUri;
}

উত্তর:


177

24 ডিগ্রি ও তার বেশি বয়সের জন্য, আপনার অ্যাপ্লিকেশন স্টোরেজের বাইরে কোনও ফাইলের উরি দরকার হলে আপনার এই ত্রুটি রয়েছে।
@ ইরানডা.ডেল সমাধানগুলি আপনাকে এটির অনুমতি দেওয়ার জন্য নীতি পরিবর্তন করতে দেয় এবং এটি ঠিকঠাক কাজ করে।

তবে আপনি যদি নিজের অ্যাপ্লিকেশনটির এপিআই নীতি পরিবর্তন না করেই গুগল গাইডলাইনটি অনুসরণ করতে চান তবে আপনাকে ফাইলপ্রোভাইডার ব্যবহার করতে হবে।

প্রথমে কোনও ফাইলের ইউআরআই পেতে আপনাকে ফাইলপ্রোভিডার.বিট ইউরিফোর্ড ফাইল () পদ্ধতিটি ব্যবহার করতে হবে:

Uri imageUri = FileProvider.getUriForFile(
            MainActivity.this,
            "com.example.homefolder.example.provider", //(use your app signature + ".provider" )
            imageFile);

তারপরে আপনাকে আপনার সরবরাহকারীটিকে আপনার অ্যান্ড্রয়েড ম্যানিফেস্টে কনফিগার করতে হবে:

<application>
  ...
     <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.homefolder.example.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <!-- ressource file to create -->
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths">  
        </meta-data>
    </provider>
</application>

("কর্তৃপক্ষগুলিতে" getUriForFile () পদ্ধতির দ্বিতীয় অ্যাপ্লিকেশন (অ্যাপের স্বাক্ষর + ".প্রবর্তক") এর চেয়ে একই মান ব্যবহার করে)

এবং অবশেষে আপনার রিসোর্স ফাইল তৈরি করতে হবে: "ফাইল_প্যাথস"। এই ফাইলটি রেজ / এক্সএমএল ডিরেক্টরিতে তৈরি করা দরকার (আপনার সম্ভবত এই ডিরেক্টরিটিও তৈরি করা দরকার):

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="." />
</paths>

83
"বিকাশকারীদের জীবনকে আরও সহজ করুন" - ঠিক প্রতিটি গুগলের প্রতিটি নতুন এপিআই-এর ট্যাগলাইন এটিই?
কিরিল করমাজিন

14
ব্রেন্ডনের প্রদত্ত সমাধানটি সঠিক একটি তবে এটি কপি-পেস্ট প্রস্তুত নয়, প্রাক্তন হিসাবে আপনার এটি প্রয়োজনীয়তার জন্য উপযুক্ত কিনা তা আপনার পরীক্ষা করা উচিত। <external-path ...যখন আপনি পরিবেশ.গেট এক্সটার্নালস্টোরেজডাইরেক্টরি () চান তখন ব্যবহার করা হয়। এবং <files-path ...আপনার যদি Context.getFilesDir () প্রয়োজন হয় তা ব্যবহার করুন । আপনি প্রথমে অফিসিয়াল ডক্সটি আরও ভালভাবে পরীক্ষা করে দেখতে পারেন: বিকাশকারী
অ্যান্ড্রয়েড.com/references/android/support/v4/content/…

10
আপনি যদি অ্যান্ড্রয়েডেক্স (নতুন সমর্থন নেমস্পেস) ব্যবহার করছেন তবে একটি অনুস্মারক, আপনি এখানে সঠিকভাবে ডকুমেন্টেশন ( বিকাশকারী.অ্যান্ড্রয়েড . com/references/androidx/core/content/…) খুঁজে পেতে পারেন ।
Rodrirokr

23
মনে রাখবেন যে androidxএতে রয়েছে:android:name="androidx.core.content.FileProvider"
স্মারেক্সেক্স

151

ক্যামেরা বা ফাইল ব্রাউজিং শুরু করার আগে নিম্নলিখিত কোড ব্লক যুক্ত করুন

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

দয়া করে রেফারেল লিঙ্কটি কঠোর মোডে উল্লেখ করুন এবং এতে সমস্ত ব্যবহার এবং প্রযুক্তিগত বিবরণ ব্যাখ্যা করা হয়েছে।


25
এটি সমাধানের সঠিক উপায় নয়, এটি মূলত স্ট্রাইকমড নীতিগুলি সরিয়ে দেবে। এবং সুরক্ষা সতর্কতা উপেক্ষা করবে
আহসান জহির

এটি সম্পর্কে কিছু উপকারিতা এবং কনস রয়েছে। নিম্নলিখিত আরও তথ্য পেতে যোগ করুন stackoverflow.com/questions/18100161/...
eranda.del

এটি কাজ করে, যদি কোনও ড্র ফিরে আসে তবে দয়া করে আমাকে জানান :)
হানান

কোডটি আমার জন্য ব্যতিক্রম সমাধান করেছে। তবে, এখানে শীর্ষ মন্তব্যটি বলছে যে কোড কীভাবে এটি সমাধান করার সঠিক উপায় নয়। কেউ কি জানেন যে সঠিক পদ্ধতিটি তখন কী হবে?
Shn_Android_Dev

গুগল প্রোগ্রামারদের ঘৃণা করে।
জোবার্ট ভাসকনস্লোস

0

অ্যান্ড্রয়েড ম্যানিফেস্টে কোনও প্রয়োজনীয় সরবরাহকারী কনফিগারেশন কেবল ক্যামেরা এবং স্টোরেজ অনুমতি অনুমতি দেওয়া উচিত নয়। ক্যামেরা শুরু করতে নিম্নলিখিত কোডটি ব্যবহার করুন:

final int REQUEST_ACTION_CAMERA = 9;
void openCamra() {
Intent cameraImgIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

cameraImgIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID +".provider",
                new File("your_file_name_with_dir")));
startActivityForResult(cameraImgIntent, REQUEST_ACTION_CAMERA);
}

ছবিটি ক্যাপচার করার পরে আপনি নিজের ক্যাপচার করা চিত্রটি এতে খুঁজে পেতে পারেন:

"your_file_name_with_dir"

অন্যান্য কোড দেওয়ার চেয়ে অ্যান্ড্রয়েড ম্যানিফেস্টে সরবরাহকারীর কনফিগারেশনটি ব্যাখ্যা করা ভাল।
ক্রোধ.স্লে

0

একটি কোড যুক্ত করুন

onCreate(Budle savedInstancesState){
    if (Build.VERSION.SDK_INT >= 24) {
        try {
            Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
            m.invoke(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.