android.os.FileUriE ExpusedException: ফাইল: ///storage/emulated/0/test.txt অ্যাপ্লিকেশন ছাড়িয়ে Intent.getData () এর মাধ্যমে উন্মুক্ত


735

আমি যখন কোনও ফাইল খোলার চেষ্টা করছি তখন অ্যাপটি ক্রাশ হচ্ছে। এটি অ্যান্ড্রয়েড নওগাতের নীচে কাজ করে তবে অ্যান্ড্রয়েড নওগাতে এটি ক্র্যাশ হয়ে গেছে। এটি কেবলমাত্র তখনই ক্র্যাশ হয় যখন আমি সিস্টেম বিভাজন থেকে নয় এসডি কার্ড থেকে কোনও ফাইল খোলার চেষ্টা করি। কিছু অনুমতি সমস্যা?

কোডের উদাহরণ:

File file = new File("/storage/emulated/0/test.txt");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "text/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent); // Crashes on this line

লগইন করুন:

android.os.FileUriE ExpusedException: ফাইল: ///storage/emulated/0/test.txt অ্যাপ্লিকেশন ছাড়িয়ে Intent.getData () এর মাধ্যমে উন্মুক্ত

সম্পাদনা:

অ্যান্ড্রয়েড নওগাতকে লক্ষ্য করার সময়, ইউআরআইগুলিকে file://আর অনুমতি দেওয়া হয় না। content://পরিবর্তে আমাদের ইউআরআই ব্যবহার করা উচিত । তবে, আমার অ্যাপ্লিকেশনটিকে রুট ডিরেক্টরিতে ফাইলগুলি খুলতে হবে। কোন ধারনা?


20
আমার মনে হচ্ছে এটি একটি ভুল ছিল যা অ্যাপ বিকাশকারীদের জন্য অযথা জীবনকে কঠিন করে তোলে। প্রতিটি অ্যাপ্লিকেশনের সাথে একটি "ফাইলপ্রোভিডার" এবং "কর্তৃপক্ষ" বান্ডিল করা, এন্টারপ্রাইজ বয়লারপ্লেটের মতো মনে হয়। প্রতিটি ফাইলের অভিপ্রায় একটি পতাকা যুক্ত করা বিশ্রী এবং সম্ভবত অপ্রয়োজনীয় বলে মনে হয়। "পথ" এর মার্জিত ধারণাটি ভঙ্গ করা অপ্রীতিকর। আর লাভ কী? অ্যাপ্লিকেশনগুলিতে বাছাই করে স্টোরেজ অ্যাক্সেস মঞ্জুর করুন (বেশিরভাগ অ্যাপ্লিকেশনগুলিতে পুরো এসডকার্ড অ্যাক্সেস রয়েছে, বিশেষত ফাইলগুলিতে কাজ করে এমনটি রয়েছে)?
nyanpasu64

2
এটি চেষ্টা করুন, ছোট এবং নিখুঁত কোড স্ট্যাকওভারফ্লো.com
a/

উত্তর:


1314

যদি আপনার হয় তবে নির্দিষ্ট অ্যাপ্লিকেশনগুলির জন্য অ্যাক্সেসযোগ্য করে তুলতে আমাদের নির্দিষ্ট ফাইল বা ফোল্ডারে অ্যাক্সেস দিতে ক্লাস targetSdkVersion >= 24ব্যবহার FileProviderকরতে হবে। এখানেFileProvider বর্ণিত হিসাবে আমদানি করা নির্ভরতাগুলিতে ঘোষিত ফাইলপ্রভাইডারগুলির সাথে আমাদের ফাইলপ্রভাইডার বিরোধী না হয় তা নিশ্চিত করার জন্য আমরা আমাদের নিজস্ব শ্রেণি উত্তরাধিকারসূত্রে তৈরি করি ।

file://ইউআরআই দিয়ে content://ইউআরআই প্রতিস্থাপনের পদক্ষেপ :

  • একটি বর্ধিত শ্রেণি যুক্ত করুন FileProvider

    public class GenericFileProvider extends FileProvider {}
  • <provider>ট্যাগের AndroidManifest.xmlআওতায় একটি ফাইলপ্রভাইডার ট্যাগ যুক্ত করুন <application>android:authoritiesদ্বন্দ্ব এড়ানোর জন্য বৈশিষ্ট্যের জন্য একটি অনন্য কর্তৃপক্ষ নির্দিষ্ট করুন , আমদানি করা নির্ভরতাগুলি ${applicationId}.providerএবং অন্যান্য সাধারণভাবে ব্যবহৃত কর্তৃপক্ষ নির্দিষ্ট করতে পারে ।

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    <application
        ...
        <provider
            android:name=".GenericFileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
    </application>
</manifest>
  • তারপরে ফোল্ডারে একটি provider_paths.xmlফাইল তৈরি করুন res/xml। ফোল্ডারটি উপস্থিত না থাকলে তৈরি করার প্রয়োজন হতে পারে। ফাইলটির বিষয়বস্তু নীচে দেখানো হয়েছে। এটা তোলে বর্ণনা যে আমরা রুট ফোল্ডার এ এক্সটারনাল স্টোরেজে এক্সেস ভাগ করে নিতে চাই (path=".")নামের সঙ্গে external_files
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>
  • চূড়ান্ত পদক্ষেপটি নীচে কোডের লাইনটি পরিবর্তন করা

    Uri photoURI = Uri.fromFile(createImageFile());

    প্রতি

    Uri photoURI = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", createImageFile());
  • সম্পাদনা: আপনি যদি সিস্টেমটিকে আপনার ফাইলটি খোলার জন্য কোনও উদ্দেশ্য ব্যবহার করে থাকেন তবে আপনাকে নিম্নলিখিত কোডের লাইন যুক্ত করতে হবে:

    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

দয়া করে উল্লেখ করুন, সম্পূর্ণ কোড এবং সমাধান এখানে ব্যাখ্যা করা হয়েছে।


62
আমার সবেমাত্র ইন্টেন্ট.সেটফ্লেগগুলি যুক্ত করার দরকার ছিল (ইনটেন্ট.এফএলএজি_জিআরএনT_READ_URI_PERMISSION);
অ্যালোরমা

24
এটি কি সমস্ত অ্যান্ড্রয়েড সংস্করণগুলির জন্য, বা কেবল এপিআই 24 থেকে কাজ করবে?
অ্যান্ড্রয়েড বিকাশকারী

9
এই নিবন্ধটি সাহায্য করেছে আমাকে medium.com/@ali.muzaffar/...
AbdulMomen عبدالمؤمن

11
@ রকহ্যামার আমি কেবল এটিকে অ্যান্ড্রয়েড 5.0, 6.0, 7.1 এবং 8.1 দিয়ে পরীক্ষা করেছি, এটি সব ক্ষেত্রেই কাজ করে। সুতরাং (Build.VERSION.SDK_INT > M)শর্তটি অকেজো।
সেবাস্টিয়ান

66
FileProviderশুধুমাত্র আপনি ডিফল্ট আচরণ কোনো ওভাররাইড করতে চান বাড়ানো উচিত, অন্যথায় ব্যবহার android:name="android.support.v4.content.FileProvider"বিকাশকারী.অ্যান্ড্রয়েড.
জেপি ভেন্টুরা

312

সমাধানটি ব্যবহারের পাশাপাশি FileProvider, এটিকে ঘিরে কাজ করার আরও একটি উপায় রয়েছে। সহজভাবে করা

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

মধ্যে Application.onCreate()। এই ভাবে ভিএম ফাইলের URIএক্সপোজার উপেক্ষা করে ।

পদ্ধতি

builder.detectFileUriExposure()

ফাইল এক্সপোজার চেক সক্ষম করে, এটি একটি ডিফল্ট আচরণ যা আমরা যদি কোনও ভিএমপলিসি সেটআপ না করি।

আমি একটি সমস্যার মুখোমুখি হয়েছি যে আমি content:// URIযদি কিছু প্রেরণের জন্য একটি ব্যবহার করি তবে কিছু অ্যাপ্লিকেশন কেবল এটি বুঝতে পারে না। এবং target SDKসংস্করণটি ডাউনগ্রেড করার অনুমতি নেই। এই ক্ষেত্রে আমার সমাধান দরকারী।

হালনাগাদ:

মন্তব্যে উল্লিখিত হিসাবে, স্ট্রাইকডমড ডায়াগোনস্টিক সরঞ্জাম, এবং এই সমস্যার জন্য এটি ব্যবহার করার কথা নয়। যখন আমি এই উত্তরটি এক বছর আগে পোস্ট করেছি, তখন অনেকগুলি অ্যাপ্লিকেশন কেবল ফাইল ইউরিস পেতে পারে। আমি যখন তাদের কাছে ফাইলপ্রোভিডার ইউরি প্রেরণ করার চেষ্টা করেছি তখন এগুলি ক্র্যাশ হয়। এটি এখন বেশিরভাগ অ্যাপ্লিকেশনগুলিতে স্থির হয়ে গেছে, সুতরাং আমাদের ফাইলপ্রোভাডার সমাধানের সাথে যাওয়া উচিত।


1
@ লৌরিনাসজি এপিআই 18 থেকে 23 পর্যন্ত, অ্যান্ড্রয়েড ডিফল্টরূপে ফাইল ইউরি এক্সপোজারের জন্য যাচাই করে না। এই পদ্ধতিতে কল করা এই চেকটিকে সক্ষম করে। এপিআই 24 থেকে, অ্যান্ড্রয়েড ডিফল্টরূপে এই চেকটি করে। তবে আমরা একটি নতুন সেট করে এটি অক্ষম করতে পারি VmPolicy
hqzxzwb

এটি কাজ করার জন্য কি অন্য কোনও পদক্ষেপের দরকার আছে? এটি আমার মোটো জি চলমান অ্যান্ড্রয়েড .0.০ হিসাবে কাজ করে না।
CKP78

3
এটি কীভাবে এই সমস্যার সমাধান করতে পারে তবে স্ট্রাইকডমড একটি ডায়াগনস্টিক সরঞ্জাম যা বিকাশকারী মোডে সক্ষম হওয়া উচিত মুক্তির মোডে নয় ???
Imene Noomene

1
@ আইমেননুমেন প্রকৃতপক্ষে আমরা এখানে স্ট্রাইকমোড অক্ষম করছি। এটি যুক্তিসঙ্গত বলে মনে হয় যে স্ট্রাইকডমডটি রিলিজ মোডে সক্ষম করা উচিত নয়, তবে প্রকৃতপক্ষে অ্যান্ড্রয়েড ডিবাগ মোড বা রিলিজ মোড নির্বিশেষে ডিফল্টরূপে কিছু স্ট্রাইকমোড বিকল্প সক্ষম করে। তবে একরকম বা অন্য কোনওভাবে, এই উত্তরটি কেবলমাত্র কাজের ব্যয় হিসাবে বোঝানো হয়েছিল যখন কিছু টার্গেট অ্যাপস সামগ্রী সামগ্রী ইউরিস পাওয়ার জন্য প্রস্তুত ছিল না। এখন যেহেতু বেশিরভাগ অ্যাপ্লিকেশনগুলি সামগ্রী ইউরিসের জন্য সমর্থন যোগ করেছে, আমাদের ফাইলপ্রোভাডার প্যাটার্নটি ব্যবহার করা উচিত।
hqzxzwb

3
@ ইমেননিওমেন আপনার ক্ষোভের সাথে আমি পুরোপুরি তোমার সাথে আছি। আপনি ঠিক বলেছেন, এটি একটি ডায়াগোনস্টিক টুল বা কমপক্ষে এটি আমার প্রকল্পগুলিতে যুক্ত করার পরে বহু বছর আগে। এটাই হতাশার! StrictMode.enableDefaults();, যা আমি কেবল আমার উন্নয়নের ভিত্তিতে চালিত করি তা এই ক্র্যাশটি ঘটতে বাধা দেয় I সুতরাং আমার কাছে এখন একটি প্রযোজনার অ্যাপ্লিকেশন রয়েছে যা ক্র্যাশ হয়ে যায় তবে বিকাশের সময়ে এটি ক্রাশ হয় না। সুতরাং মূলত, এখানে একটি ডায়াগনস্টিক সরঞ্জাম সক্ষম করা একটি গুরুতর সমস্যা লুকায়। আমাকে এটিকে নির্মূল করতে সহায়তা করার জন্য @ hqzxzwb ধন্যবাদ।
জন

174

যদি 24 এরtargetSdkVersion চেয়ে বেশি হয় , তবে ফাইলপ্রভাইডার অ্যাক্সেস দেওয়ার জন্য ব্যবহৃত হয়।

একটি এক্সএমএল ফাইল তৈরি করুন (পথ: রেস \ এক্সএমএল) প্রদানকারী_ paths.xML

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


একটি যোগ করুন প্রোভাইডার মধ্যে Andro আইডি

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

আপনি যদি অ্যান্ড্রয়েডক্স ব্যবহার করে থাকেন তবে ফাইলপ্রভাইডার পথটি হওয়া উচিত:

 android:name="androidx.core.content.FileProvider"

এবং প্রতিস্থাপন

Uri uri = Uri.fromFile(fileImagePath);

প্রতি

Uri uri = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider",fileImagePath);

সম্পাদনা করুন: আপনি যখন ইউআরআই অন্তর্ভুক্ত করছেন তখন Intentনীচের লাইনের সাথে যুক্ত করার বিষয়টি নিশ্চিত করুন:

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

এবং আপনি যেতে ভাল। আশা করি এটা সাহায্য করবে.


2
@ মাকসিমকনিয়াজভ আপনি কি নিজের ত্রুটি সংক্ষেপে বর্ণনা করতে পারবেন? যাতে আমি আপনাকে সাহায্য করতে পারি।
পঙ্কজ লিলান

1
@ পঙ্কজলিলান, আপনি যা বলেছেন তা আমি ঠিক করেছি did তবে যতবারই আমি অন্য অ্যাপ্লিকেশনটিতে আমার পিডিএফ খুলি তা ফাঁকা প্রদর্শিত হয় (এটির সঠিকভাবে সঞ্চয় করা)। আমার কি এক্সএমএল সম্পাদনা করা উচিত? আমি ইতিমধ্যে FLAG_GRANT_READ_URI_PERMISSION পাশাপাশি যুক্ত করেছি;
ফিলিপ ক্যাসটিলহোস

1
আমার ভুল, আমি ভুল অভিপ্রায়টিতে অনুমতিটি যুক্ত করছিলাম। এটি সেরা এবং সরলতম সঠিক উত্তর। ধন্যবাদ!
ফিলিপ ক্যাসটিলহোস

2
এটি java.lang.IllegalArgumentException ব্যতিক্রম করে: কনফিগার করা মূলগুলি খুঁজে পেতে ব্যর্থ হয়েছে / আমার ফাইলের পথটি হল / স্টোরেজ / মেমুলেটেড / জিএসএমএনএজ_ডিসিআইএম / ডকুমেন্টস / ডিভাইস 7298file_74.pdf। আপনি দয়া করে সাহায্য করতে পারেন?
জগদীশ ভাবসার 13

1
কেন জানি না তবে আমাকে আরআরএডি এবং রাইট উভয়ই অনুমতি যুক্ত করতে হয়েছিল: টার্গেট.এডিডিএফএলএইচএইচএস (ইনটেন্ট.এফএলজি_গ্রান_আআআআআআআডিআরআইআরআইআরআইপিআরএমআইএসআইএসএন) টার্গেট.এডিএফএফ্ল্যাগস (ইনটেন্ট.এফএলএজি_আরআরআইএনআরআইআরআইআইপিআইআরএমএসআইএসএন)
বক্স

160

যদি আপনার অ্যাপ্লিকেশনটি এপিআই 24+ কে টার্গেট করে এবং আপনি এখনও ফাইল: // ইন্টেন্ট ব্যবহার করতে চান তবে রানটাইম চেকটি অক্ষম করতে আপনি হ্যাকি উপায়টি ব্যবহার করতে পারেন:

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

পদ্ধতিটি StrictMode.disableDeathOnFileUriExposureলুকানো এবং নথিভুক্ত রয়েছে:

/**
* Used by lame internal apps that haven't done the hard work to get
* themselves off file:// Uris yet.
*/

সমস্যাটি হ'ল আমার অ্যাপটি খোঁড়া নয়, বরং সামগ্রী: // ইন্টেন্টগুলি ব্যবহার করে পঙ্গু হতে চায় না যা এখানকার অনেক অ্যাপ্লিকেশন বুঝতে পারে না। উদাহরণস্বরূপ, লিখিত সামগ্রী: // স্কিম সহ এমপি 3 ফাইলটি খোলার সময় একই ওভার ফাইল: // স্কিম খোলার চেয়ে অনেক কম অ্যাপ্লিকেশন সরবরাহ করা হয়। আমি আমার অ্যাপ্লিকেশনটির কার্যকারিতা সীমাবদ্ধ করে গুগলের ডিজাইন ত্রুটিগুলির জন্য অর্থ দিতে চাই না।

গুগল বিকাশকারীদের কন্টেন্ট স্কিম ব্যবহার করতে চায় তবে সিস্টেমটি এর জন্য প্রস্তুত নয়, বছরের পর বছর ধরে অ্যাপ্লিকেশনগুলিকে ফাইলগুলি "বিষয়বস্তু" নয় ব্যবহার করা হয়েছিল, ফাইলগুলি সম্পাদনা করে আবার সংরক্ষণ করা যায়, যখন সামগ্রীতে স্কিমের উপর দেওয়া ফাইলগুলি হতে পারে না (পারে তারা?)।


3
"কন্টেন্ট স্কিমের মাধ্যমে পরিবেশন করা ফাইলগুলি (তারা কি পারবে না) হতে পারে?" - অবশ্যই, যদি আপনার লিখিত সামগ্রীতে লিখিত অ্যাক্সেস থাকে। ContentResolverউভয় openInputStream()এবং আছে openOutputStream()। এটি করার একটি কম-হ্যাকি উপায় হ'ল কেবল নিজের ভিএম নিয়মগুলি কনফিগার করা , এবং file Uriনিয়মটি সক্ষম করে না ।
কমন্সওয়ের

1
যথাযথভাবে। আপনার সম্পূর্ণ অ্যাপটি তৈরি করার সময় এটি কঠোর কাজ, তারপরে আপনার ক্যামেরার সমস্ত পদ্ধতি ভেঙে 25 টার্গেট করার পরে এটি সন্ধান করুন। এটি সঠিকভাবে করার সময় না পাওয়া পর্যন্ত এটি আমার পক্ষে কাজ করে।
ম্যাট ডাব্লু

5
অ্যান্ড্রয়েডে কাজ করে 7.. ধন্যবাদ
আন্তন কিজেমা

4
অ্যান্ড্রয়েড 8 এও কাজ করে, হুয়াওয়ে নেক্সাস 6 পি-তে পরীক্ষিত।
গনজালো লেদেজমা টরেস

4
আমি নিশ্চিত করি যে এটি উত্পাদনে কাজ করছে (আমার আরও 500,000 জন ব্যবহারকারী রয়েছে), বর্তমানে সংস্করণ 8.1 সর্বোচ্চ সংস্করণ, এবং এটি এতে কাজ করে।
এলি

90

যদি আপনার targetSdkVersion24 বা তার বেশি হয় তবে আপনি Android 7.0+ ডিভাইসগুলিতে file: Uriমানগুলি ব্যবহার করতে পারবেন নাIntents

আপনার পছন্দগুলি হ'ল:

  1. আপনার targetSdkVersion23 বা নিম্নে ছেড়ে দিন, বা

  2. আপনার সামগ্রীটি অভ্যন্তরীণ স্টোরেজে রাখুন, তারপরে এটি অন্য অ্যাপ্লিকেশনগুলিতে বেছে বেছে উপলব্ধ করতে ব্যবহার করুনFileProvider

উদাহরণ স্বরূপ:

Intent i=new Intent(Intent.ACTION_VIEW, FileProvider.getUriForFile(this, AUTHORITY, f));

i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(i);

( এই নমুনা প্রকল্প থেকে )


উত্তরের জন্য ধন্যবাদ. আমি /systemপার্টিশনে ফাইলগুলি ব্যবহার করে কী ঘটে ? প্রতিটি অ্যাপ্লিকেশন রুট ছাড়াই এই পার্টিশন অ্যাক্সেস করতে সক্ষম হওয়া উচিত।
টমাস ভোস

2
@ সুপার থমাসল্যাব: /systemবিশ্ব-পঠনযোগ্য হিসাবে আমি সমস্ত কিছুর উপর নির্ভর করি না । বলা হচ্ছে, আমার অনুমান যে আপনি এখনও এই ব্যতিক্রম পাবেন। আমার সন্দেহ হয় যে তারা কেবল স্কিমটি পরীক্ষা করছে এবং ফাইলটি সত্যই বিশ্ব-পাঠযোগ্য কিনা তা নির্ধারণের চেষ্টা করছে না। তবে, FileProviderআপনাকে সাহায্য করবে না, কারণ আপনি এটিকে পরিবেশন করতে শেখাতে পারবেন না /system। সমস্যাটি কাটিয়ে উঠতে আপনি আমার জন্য একটি কাস্টম কৌশল তৈরিStreamProvider করতে পারেন , বা আপনার নিজস্ব রোল ContentProviderকরতে পারেন।
কমন্সওয়্যার 13

আমি কীভাবে এটিকে সমাধান করব তা এখনও ভাবছি .. অ্যানড্রয়েড এন সাপোর্টের সাথে আমি যে অ্যাপ্লিকেশনটি আপডেট করছি তা হ'ল মূল ব্রাউজার। তবে এখন আপনি রুট ডিরেক্টরিতে কোনও ফাইল খুলতে পারবেন না। ( /data, /system), এই "ভাল পরিবর্তন" এর কারণে।
টমাস ভস

1
টার্গেটএসডিভি ভার্সনকে 23 এ নামানোর সবচেয়ে গুরুত্বপূর্ণ কমতিগুলি কী কী? thnx
rommex

2
@ ক্রোমেক্স: "সর্বাধিক গুরুত্বপূর্ণ" হিসাবে কী যোগ্যতা অর্জন করেছে তা আমি জানি না। উদাহরণস্বরূপ, ব্যবহারকারীরা যারা স্প্লিট-স্ক্রিন মোডে বা ফ্রিফর্ম মাল্টি-উইন্ডো ডিভাইসগুলিতে (ক্রোমবুকস, স্যামসাং ডিএক্স) কাজ করেন তাদের বলা হবে যে আপনার অ্যাপ্লিকেশনটি মাল্টি-উইন্ডোতে কাজ না করে। তা গুরুত্বপূর্ণ কিনা তা আপনার উপর নির্ভর করে।
কমন্সওয়্যার

47

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

  <application
    ...>
    <activity>
    .... 
    </activity>
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.your.package.fileProvider"
        android:grantUriPermissions="true"
        android:exported="false">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
  </application>

এখন এক্সএমএল রিসোর্স ফোল্ডারে একটি ফাইল তৈরি করুন (যদি অ্যান্ড্রয়েড স্টুডিও ব্যবহার করে থাকেন তবে ফাইল_প্যাথগুলি হাইলাইট করার পরে আপনি Alt + এন্টার টিপুন এবং একটি এক্সএমএল রিসোর্স বিকল্পটি নির্বাচন করতে পারেন)

File_paths ফাইলের পরে এন্টার দিন

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <external-path path="Android/data/com.your.package/" name="files_root" />
  <external-path path="." name="external_storage_root" />
</paths>

এই উদাহরণটি বাহ্যিক পথের জন্য আপনি আরও বিকল্পের জন্য এখানে উল্লেখ করতে পারেন । এটি আপনাকে সেই ফোল্ডার এবং এর উপ-ফোল্ডারে থাকা ফাইলগুলি ভাগ করে নেওয়ার অনুমতি দেবে।

এখন যা বাকি আছে তা হ'ল নিম্নরূপ উদ্দেশ্যটি তৈরি করা:

    MimeTypeMap mime = MimeTypeMap.getSingleton();
    String ext = newFile.getName().substring(newFile.getName().lastIndexOf(".") + 1);
    String type = mime.getMimeTypeFromExtension(ext);
    try {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(getContext(), "com.your.package.fileProvider", newFile);
            intent.setDataAndType(contentUri, type);
        } else {
            intent.setDataAndType(Uri.fromFile(newFile), type);
        }
        startActivityForResult(intent, ACTIVITY_VIEW_ATTACHMENT);
    } catch (ActivityNotFoundException anfe) {
        Toast.makeText(getContext(), "No activity found to open this attachment.", Toast.LENGTH_LONG).show();
    }

সম্পাদনা : আমি ফাইল_প্যাথগুলিতে এসডি কার্ডের মূল ফোল্ডারটি যুক্ত করেছি। আমি এই কোডটি পরীক্ষা করেছি এবং এটি কাজ করে।


1
এই জন্য আপনাকে ধন্যবাদ. ফাইল এক্সটেনশান পাওয়ার আরও ভাল উপায় আছে তাও আমি আপনাকে জানাতে চাই। String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString()); এছাড়াও, আমি প্রথমে ফাইলপ্রোভাইডারটি পড়ার জন্য উত্তরগুলির সন্ধানের জন্য এবং অ্যান্ড্রয়েড এন এবং উপরের ফাইলের অনুমতি সহ আপনি এখানে কী কী আচরণ করছেন তা বোঝার পরামর্শ দিচ্ছি । অভ্যন্তরীণ স্টোরেজ বনাম বাহ্যিক স্টোরেজ এবং নিয়মিত ফাইল-পাথ বনাম ক্যাশে-পাথের জন্য বিকল্প রয়েছে।
paneetloke

2
আমি নিম্নলিখিত ব্যতিক্রম পাচ্ছিলাম: java.lang.IllegalArgumentException: Failed to find configured root ...এবং কেবলমাত্র কাজটিই ছিল <files-path path="." name="files_root" />xML ফাইলের পরিবর্তে <external-path ...। আমার ফাইলটি অভ্যন্তরীণ স্টোরেজে সংরক্ষণ করা হয়েছিল।
স্টিলিওসফ

26

@ পলাশ কে উত্তরটি সঠিক এবং অভ্যন্তরীণ স্টোরেজ ফাইলগুলির জন্য কাজ করেছে, তবে আমার ক্ষেত্রে আমি বাহ্যিক স্টোরেজ থেকেও ফাইলগুলি খুলতে চাই, এসডকার্ড এবং ইউএসবির মতো বাহ্যিক স্টোরেজ থেকে খোলার ফাইলটি আমার অ্যাপ্লিকেশনটি ক্র্যাশ হয়ে গেছে তবে আমি সংশোধন করে সমস্যাটি সমাধান করতে পরিচালনা করি প্রদানকারী_প্যাথস.এক্সএমএল গৃহীত উত্তর থেকে

নীচের মত প্রদানকারী_প্যাথস.এক্সএমএল পরিবর্তন করুন

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

<external-path path="Android/data/${applicationId}/" name="files_root" />

<root-path
    name="root"
    path="/" />

</paths>

এবং জাভা শ্রেণিতে (স্বল্প উত্তর হিসাবে স্বীকৃত উত্তর হিসাবে পরিবর্তন করা হবে না)

Uri uri=FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID+".provider", File)

এটি আমাকে বাহ্যিক স্টোরগুলি থেকে ফাইলগুলির ক্র্যাশ ঠিক করতে সহায়তা করে, আশা করি এটি আমার মতো সমস্যাযুক্ত কাউকে সহায়তা করবে :)


1
<root-pathদয়া করে আপনি কোথায় খুঁজে পেয়েছেন ? ইহা কাজ করছে. <external-path path="Android/data/${applicationId}/" name="files_root" />বাহ্যিক স্টোরেজ থেকে খোলা ফাইলগুলির জন্য কোনও প্রভাব ফেলেনি।
t0m

আমি এটি বিভিন্ন অনুসন্ধানের ফলাফল থেকে পেয়েছি, আমাকে আবার যাচাই করে আবার
রমজ

আপনার উল্লেখ করা বাহ্যিক স্টোরেজটি কি এসডি কার্ড বা ইনবিল্ট স্টোরেজ?
রমজ

অসম্পূর্ণতার জন্য দুঃখিত। আমি Android/data/${applicationId}/এসডিকার্ডে বোঝাতে চাইছি ।
t0m

1
এটিকে অভিপ্রায় যুক্ত করতে হবে: intent.addFlags (Intent.FLAG_GRANT_READ_URI_PERMISSION);
এস-শিকারি

26

আমার সমাধানটি Uri.fromFile () ব্যবহারের পরিবর্তে স্ট্রিং হিসাবে ফাইল পাথ 'Uri.parse' করা ছিল।

String storage = Environment.getExternalStorageDirectory().toString() + "/test.txt";
File file = new File(storage);
Uri uri;
if (Build.VERSION.SDK_INT < 24) {
    uri = Uri.fromFile(file);
} else {
    uri = Uri.parse(file.getPath()); // My work-around for new SDKs, doesn't work in Android 10.
}
Intent viewFile = new Intent(Intent.ACTION_VIEW);
viewFile.setDataAndType(uri, "text/plain");
startActivity(viewFile);

দেখে মনে হচ্ছে যে ফাইলে () কোনও ফাইল পয়েন্টার ব্যবহার করে, যা আমি মনে করি যখন সমস্ত অ্যাপ্লিকেশনে মেমরির ঠিকানা প্রকাশিত হয় তখন এটি নিরাপত্তাহীন হতে পারে। তবে একটি ফাইল পাথ স্ট্রিং কখনই কাউকে আঘাত করে না, সুতরাং এটি ফাইলUriExpisedException নিক্ষেপ না করে কাজ করে।

9 থেকে 27 স্তরের এপিআই স্তরে পরীক্ষিত! অন্য অ্যাপ্লিকেশনটিতে সম্পাদনা করার জন্য সাফল্যের সাথে পাঠ্য ফাইলটি খোলে। ফাইলপ্রোভাইডার বা অ্যান্ড্রয়েড সমর্থন লাইব্রেরি মোটেও প্রয়োজন হয় না।


আমি আশা করি আমি এটি আগে দেখতে পেতাম। আমি প্রমাণ করি নি যে এটি আমার পক্ষে কাজ করেছে তবে এটি ফাইলপ্রোভাইডার তুলনায় এত কম জটিল।
ডেল

এটি কেন কাজ করে তা সম্পর্কে একটি নোট: এটি ফাইল পয়েন্টার যা সমস্যাটিকে উদ্বেগ দেয় তা নয়, তবে ব্যতিক্রমটি কেবল তখনই ঘটে যখন আপনার 'ফাইল: //' দিয়ে একটি পথ থাকে, যা ফাইলে থেকে স্বয়ংক্রিয়ভাবে চাপানো হয় তবে পার্স দিয়ে নয় ।
এক্সমিস্টার

3
এটি ব্যতিক্রম পায় না, তবে এটি ফাইলটি সম্পর্কিত অ্যাপে প্রেরণ করতে পারে না। সুতরাং, আমার জন্য কাজ হয়নি।
সর্দার সমানসিওলু

1
এটি অ্যান্ড্রয়েড 10 এবং উচ্চতরতে ব্যর্থ হবে, কারণ আপনি ধরে নিতে পারবেন না যে অন্য অ্যাপ্লিকেশনটির ফাইল সিস্টেমের মাধ্যমে বাহ্যিক স্টোরেজে অ্যাক্সেস রয়েছে।
কমন্সওয়্যার

24

ক্রিয়েট () তে ক্রিয়াকলাপে কেবল নীচের কোডটি পেস্ট করুন

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

এটি ইউআরআই এক্সপোজারকে উপেক্ষা করবে


1
এটি সমাধানগুলির মধ্যে একটি তবে মানকটি নয়। স্টিল লোকেরা যারা উত্তরগুলিকে নীচে নামিয়েছে তারা ভুল কারণ এটি কার্যনির্বাহী সমাধানের সাথে কোডও কাজ করে।
স্যাকশাম

23

ক্রিয়াকলাপে কেবল নীচের কোডটি পেস্ট করুন onCreate()

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

এটি ইউআরআই এক্সপোজারকে উপেক্ষা করবে।

শুভ কোডিং :-)


1
এই ডাউনসাইডস কি?
জেমস এফ

1
এটি অ্যান্ড্রয়েড 10 এবং উচ্চতরতে ব্যর্থ হবে, কারণ আপনি ধরে নিতে পারবেন না যে অন্য অ্যাপ্লিকেশনটির ফাইল সিস্টেমের মাধ্যমে বাহ্যিক স্টোরেজে অ্যাক্সেস রয়েছে।
কমন্সওয়্যার

18

ফাইলপ্রভাইডার ব্যবহার করার উপায়। তবে আপনি এই সাধারণ কাজটি ব্যবহার করতে পারেন:

সতর্কতা : এটি পরবর্তী অ্যান্ড্রয়েড প্রকাশে স্থির করা হবে - https://issuetracker.google.com/issues/37122890#comment4

প্রতিস্থাপন করুন:

startActivity(intent);

দ্বারা

startActivity(Intent.createChooser(intent, "Your title"));

7
গুগল কর্তৃক একই চেক থাকতে শীঘ্রই চয়নকারীকে প্যাচ করা হবে। এটি কোনও সমাধান নয়।
পয়েন্টার নুল

এটি কাজ করে তবে ভবিষ্যতের অ্যান্ড্রয়েড সংস্করণগুলিতে কাজ করবে না।
দিলজিৎ

13

আমি উপরে দেওয়া পলাশের উত্তরটি ব্যবহার করেছি তবে এটি কিছুটা অসম্পূর্ণ ছিল, আমাকে এই জাতীয় অনুমতি প্রদান করতে হয়েছিল

Intent intent = new Intent(Intent.ACTION_VIEW);
    Uri uri;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        uri = FileProvider.getUriForFile(this, getPackageName() + ".provider", new File(path));

        List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList) {
            String packageName = resolveInfo.activityInfo.packageName;
            grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
    }else {
        uri = Uri.fromFile(new File(path));
    }

    intent.setDataAndType(uri, "application/vnd.android.package-archive");

    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    startActivity(intent);

11

ক্রিয়েট () তে ক্রিয়াকলাপে কেবল নীচের কোডটি পেস্ট করুন

স্ট্রিক্টমোড.ভিএমপলিসি.বিল্ডার বিল্ডার = নতুন স্ট্রিক্টমোড.ভিএমপলিসি.বিল্ডার (); StrictMode.setVmPolicy (builder.build ());

এটি ইউআরআই এক্সপোজারকে উপেক্ষা করবে


এটি, এটি স্ট্রিমড নীতিগুলি সরিয়ে দেবে। এবং সুরক্ষা সতর্কতা উপেক্ষা করবে। ভাল সমাধান নয়।
অনুপ্রেরণা_ কোডিং

এটি অ্যান্ড্রয়েড 10 এবং উচ্চতরতেও ব্যর্থ হবে, কারণ আপনি ধরে নিতে পারবেন না যে অন্য অ্যাপ্লিকেশনটির ফাইল সিস্টেমের মাধ্যমে বাহ্যিক স্টোরেজে অ্যাক্সেস রয়েছে।
কমন্সওয়্যার

7

এই দুটি লাইনটি অনক্রিটে যুক্ত করুন

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

শেয়ার পদ্ধতি

File dir = new File(Environment.getExternalStorageDirectory(), "ColorStory");
File imgFile = new File(dir, "0.png");
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.setType("image/*");
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + imgFile));
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(sendIntent, "Share images..."));

এটি অ্যান্ড্রয়েড 10 এবং উচ্চতরতে ব্যর্থ হবে, কারণ আপনি ধরে নিতে পারবেন না যে অন্য অ্যাপ্লিকেশনটির ফাইল সিস্টেমের মাধ্যমে বাহ্যিক স্টোরেজে অ্যাক্সেস রয়েছে।
কমন্সওয়্যার

7

এখানে আমার সমাধান:

মধ্যে Manifest.xml

<application
            android:name=".main.MainApp"
            android:allowBackup="true"
            android:icon="@drawable/ic_app"
            android:label="@string/application_name"
            android:logo="@drawable/ic_app_logo"
            android:theme="@style/MainAppBaseTheme">

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

মধ্যে মাঝামাঝি / XML / provider_paths.xml

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

আমার খণ্ডে আমার পরবর্তী কোড রয়েছে:

 Uri myPhotoFileUri = FileProvider.getUriForFile(getActivity(), getActivity().getApplicationContext().getPackageName() + ".provider", myPhotoFile);               
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, myPhotoFileUri);

এই যে আপনার প্রয়োজন।

এছাড়াও তৈরি করার প্রয়োজন নেই

public class GenericFileProvider extends FileProvider {}

আমি অ্যান্ড্রয়েড 5.0, 6.0 এবং অ্যান্ড্রয়েড 9.0 এ পরীক্ষা করেছি এবং এটি সাফল্যের কাজ।


আমি এই সমাধানটি পরীক্ষা করে দেখেছি এবং এটি একটি ছোট পরিবর্তন দ্বারা সূক্ষ্মভাবে কাজ করে: intent.flags = ইন্টেন্ট.এফএলএজি_এসিটিভিটি_নিউজ_টাস্ক ইন্টেন্ট.পুটেক্সট্রা (ইন্টেন্ট.অ্যাক্টরাসিপিআরএম, মাইফোটো ফাইলেউরি) ইন্টেন্ট.টাইপ = "ইমেজ / পিএনজি" স্টার্টঅ্যাক্টিভিটি (ইনটেন্ট। ক্রিয়েট ক্রুজার (অভিপ্রায়, " মাধ্যমে ") ভাগ চিত্র) এটা অ্যান্ড্রয়েড 7 এবং 8 পাখনা কাজ করে
inspire_coding

4

সার্ভার থেকে পিডিএফ ডাউনলোড করার জন্য, আপনার পরিষেবা শ্রেণিতে কোডের নীচে যুক্ত করুন। আশা করি এটি আপনার জন্য সহায়ক।

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName + ".pdf");
    intent = new Intent(Intent.ACTION_VIEW);
    //Log.e("pathOpen", file.getPath());

    Uri contentUri;
    contentUri = Uri.fromFile(file);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);

    if (Build.VERSION.SDK_INT >= 24) {

        Uri apkURI = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", file);
        intent.setDataAndType(apkURI, "application/pdf");
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    } else {

        intent.setDataAndType(contentUri, "application/pdf");
    }

এবং হ্যাঁ, আপনার ম্যানিফেস্টে অনুমতি এবং সরবরাহকারী যুক্ত করতে ভুলবেন না।

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

<application

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

</application>

1
কি @xml/provider_paths?
adityasnl

1
@Heisenberg URL থেকে রাহুল উপাধ্যায় পোস্ট পড়ুন দয়া করে: stackoverflow.com/questions/38555301/...
Bhoomika চৌহান

3

কেন জানি না, আমি পকোস্তার ( https://stackoverflow.com/a/38858040 ) মতো ঠিক সবকিছুই করেছি তবে ত্রুটি পেতেই থাকলাম :

java.lang.SecurityException: Permission Denial: opening provider redacted from ProcessRecord{redacted} (redacted) that is not exported from uid redacted

আমি এই ইস্যুতে ঘন্টা নষ্ট করেছি। অভিযুক্ত ব্যক্তি? Kotlin।

val playIntent = Intent(Intent.ACTION_VIEW, uri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

intentgetIntent().addFlagsআমার সদ্য ঘোষিত প্লে ইন্টেন্টের পরিবর্তে প্রকৃতপক্ষে সেট করা হয়েছিল ।


2

আমি এই পদ্ধতিটি রেখেছি যাতে চিত্রের পথটি সহজেই সামগ্রীতে আসে।

enter code here
public Uri getImageUri(Context context, Bitmap inImage)
{
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.PNG, 100, bytes);
    String path = MediaStore.Images.Media.insertImage(context.getContentResolver(), 
    inImage, "Title", null);
    return Uri.parse(path);
}

2
As of Android N, in order to work around this issue, you need to use the FileProvider API

নীচে উল্লিখিত হিসাবে এখানে 3 টি প্রধান পদক্ষেপ রয়েছে

পদক্ষেপ 1: ম্যানিফেস্ট এন্ট্রি

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

পদক্ষেপ 2: এক্সএমএল ফাইল তৈরি করুন / এক্সএমএল / সরবরাহকারী_পথ.এক্সএমএল

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

পদক্ষেপ 3: কোড পরিবর্তন

File file = ...;
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
// Old Approach
    install.setDataAndType(Uri.fromFile(file), mimeType);
// End Old approach
// New Approach
    Uri apkURI = FileProvider.getUriForFile(
                             context, 
                             context.getApplicationContext()
                             .getPackageName() + ".provider", file);
    install.setDataAndType(apkURI, mimeType);
    install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// End New Approach
    context.startActivity(install);

1

আমি জানি এটি একটি পুরানো প্রশ্ন তবে এই উত্তরটি ভবিষ্যতের দর্শকদের জন্য। সুতরাং আমি একটি অনুরূপ সমস্যার মুখোমুখি হয়েছি এবং গবেষণা করার পরে, আমি এই পদ্ধতির বিকল্প খুঁজে পেয়েছি।

আপনার উদ্দেশ্য এখানে যেমন: কোটলিনে আপনার পথ থেকে আপনার চিত্রটি দেখতে

 val intent = Intent()
 intent.setAction(Intent.ACTION_VIEW)
 val file = File(currentUri)
 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
 val contentURI = getContentUri(context!!, file.absolutePath)
 intent.setDataAndType(contentURI,"image/*")
 startActivity(intent)

নীচে মূল ফাংশন

private fun getContentUri(context:Context, absPath:String):Uri? {
        val cursor = context.getContentResolver().query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            arrayOf<String>(MediaStore.Images.Media._ID),
            MediaStore.Images.Media.DATA + "=? ",
            arrayOf<String>(absPath), null)
        if (cursor != null && cursor.moveToFirst())
        {
            val id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID))
            return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, Integer.toString(id))
        }
        else if (!absPath.isEmpty())
        {
            val values = ContentValues()
            values.put(MediaStore.Images.Media.DATA, absPath)
            return context.getContentResolver().insert(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
        }
        else
        {
            return null
        }
    }

অনুরূপভাবে, কোনও চিত্রের পরিবর্তে, আপনি পিডিএফ এর মতো অন্য কোনও ফাইল ফর্ম্যাট ব্যবহার করতে পারেন এবং আমার ক্ষেত্রে এটি ঠিক কাজ করেছে


-1

https://stackoverflow.com/a/38858040/395097 এই উত্তরটি সম্পূর্ণ।

এই উত্তরটির জন্য - আপনার কাছে ইতিমধ্যে একটি অ্যাপ রয়েছে যা 24 এর নিচে লক্ষ্যবস্তু ছিল এবং এখন আপনি টার্গেট এসডিকেভার্সন> = 24 এ আপগ্রেড করছেন।

অ্যান্ড্রয়েড এন-তে, কেবল তৃতীয় পক্ষের অ্যাপের সংস্পর্শে থাকা ইউরি ফাইলটি পরিবর্তন করা হয়েছে। (আমরা আগে এটি যেভাবে ব্যবহার করছিলাম তা নয়)। সুতরাং যেখানে আপনি তৃতীয় পক্ষের অ্যাপের সাথে পথটি ভাগ করছেন কেবলমাত্র সেই জায়গাগুলি পরিবর্তন করুন (আমার ক্ষেত্রে ক্যামেরা)

আমাদের অ্যাপে আমরা ক্যামেরা অ্যাপে ইউরি প্রেরণ করছিলাম, সেই স্থানে আমরা ক্যামেরা অ্যাপটি ক্যাপচার হওয়া চিত্রটি সঞ্চয় করার প্রত্যাশা করছি।

  1. অ্যান্ড্রয়েড এন এর জন্য, আমরা নতুন সামগ্রী তৈরি করি: // ইউরি ভিত্তিক ইউআরএল ফাইলের দিকে নির্দেশ করে।
  2. আমরা এটির জন্য সাধারণ ফাইল এপিআই ভিত্তিক পথ তৈরি করি (পুরানো পদ্ধতিটি ব্যবহার করে)।

এখন আমাদের কাছে একই ফাইলের জন্য 2 টি আলাদা ইউরি রয়েছে। # 1 ক্যামেরা অ্যাপের সাথে ভাগ করা হয়েছে। যদি ক্যামেরা অভিপ্রায়টি সাফল্য হয় তবে আমরা # 2 থেকে চিত্রটি অ্যাক্সেস করতে পারি।

আশাকরি এটা সাহায্য করবে.


1
আপনি ইতিমধ্যে এখানে পোস্ট করা একটি উত্তর উল্লেখ করছেন, আপনার যদি এটি পূরণ করার প্রয়োজন হয় তবে উত্তর plz এ মন্তব্য করুন।
IgniteCoders

1
@ ইগনিট কোডারস যেমন আমি বার্তায় স্পষ্টভাবে উল্লেখ করেছি, আমার উত্তর সম্পর্কিত ব্যবহারের ক্ষেত্রে কভার করে।
আরম

-1

Xamarin.Android

দ্রষ্টব্য: পথ এক্সএমএল / সরবরাহকারী_পথস.এমএমএল (.axML) সমাধান করা যায়নি, এমনকি সংস্থানসমূহের অধীনে এক্সএমএল ফোল্ডার তৈরি করার পরেও (সম্ভবত এটি মান হিসাবে বিদ্যমান অবস্থানে স্থাপন করা যেতে পারে , চেষ্টা করা হয়নি), তাই আমি অবলম্বন করেছি এই এখন জন্য কাজ করে। পরীক্ষায় দেখা গেছে যে কেবলমাত্র অ্যাপ্লিকেশন চালানোর সময় এটি একবার কল করা প্রয়োজন (এটি যে হোস্ট ভিএমের অপারেশনাল অবস্থার পরিবর্তন করে তা বোঝা যায়)।

দ্রষ্টব্য: এক্সএমএলকে মূলধন করা দরকার, সুতরাং সংস্থানসমূহ / এক্সএমএল / সরবরাহকারী_পথ.এক্সএমএল

Java.Lang.ClassLoader cl = _this.Context.ClassLoader;
Java.Lang.Class strictMode = cl.LoadClass("android.os.StrictMode");                
System.IntPtr ptrStrictMode = JNIEnv.FindClass("android/os/StrictMode");
var method = JNIEnv.GetStaticMethodID(ptrStrictMode, "disableDeathOnFileUriExposure", "()V");                
JNIEnv.CallStaticVoidMethod(strictMode.Handle, method);

-1

@ পকোস্তার উত্তর এটি করার একটি উপায়।

ব্যবহারের পাশাপাশি FileProvider, আপনি ফাইলটি MediaStore(বিশেষত চিত্র এবং ভিডিও ফাইলগুলির জন্য) এর মধ্যে sertোকাতেও পারেন, কারণ মিডিয়াস্টোরের ফাইলগুলি প্রতিটি অ্যাপ্লিকেশনে অ্যাক্সেসযোগ্য:

মিডিয়াস্টোরটি মূলত ভিডিও, অডিও এবং চিত্র এমআইএমআই টাইপগুলিকে লক্ষ্য করে, তবে অ্যান্ড্রয়েড 3.0.০ (এপিআই স্তর ১১) দিয়ে এটি নন-মিডিয়া প্রকারগুলিও সঞ্চয় করতে পারে (আরও তথ্যের জন্য মিডিয়াস্টোর.ফায়ারগুলি দেখুন)। ফাইলগুলি স্ক্যানফিল () ব্যবহার করে মিডিয়াস্টোরের মধ্যে .োকানো যেতে পারে যার পরে একটি সামগ্রী: // শৈলীর উরি ভাগ করে নেওয়ার জন্য সরবরাহিত স্ক্যান কমপ্লিটড () কলব্যাকটি দেওয়া হয়। নোট করুন যে একবার সিস্টেমে মিডিয়াস্টোর যুক্ত করা হয়েছে সামগ্রীটি ডিভাইসের যে কোনও অ্যাপের অ্যাক্সেসযোগ্য।

উদাহরণস্বরূপ, আপনি মিডিয়াস্টোরগুলিতে একটি ভিডিও ফাইল এটি sertোকাতে পারেন:

ContentValues values = new ContentValues();
values.put(MediaStore.Video.Media.DATA, videoFilePath);
Uri contentUri = context.getContentResolver().insert(
      MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);

contentUriএটির মতো content://media/external/video/media/183473, যা সরাসরি এখানে দেওয়া যেতে পারে Intent.putExtra:

intent.setType("video/*");
intent.putExtra(Intent.EXTRA_STREAM, contentUri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivity(intent);

এটি আমার পক্ষে কাজ করে এবং ব্যবহারের ঝামেলা বাঁচায় FileProvider


-1

কেবল এটি ইউআরআই এক্সপোজার উপেক্ষা করুন ... তৈরির পরে এটি যুক্ত করুন

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

এটি অ্যান্ড্রয়েড 10 এবং উচ্চতরতে ব্যর্থ হবে, কারণ আপনি ধরে নিতে পারবেন না যে অন্য অ্যাপ্লিকেশনটির ফাইল সিস্টেমের মাধ্যমে বাহ্যিক স্টোরেজে অ্যাক্সেস রয়েছে।
কমন্সওয়্যার

এই ডোনটি অবশ্যই একটি প্রোডাকশন অ্যাপ্লিকেশন ব্যবহার করা উচিত।
জর্জেসিস

-1

এই সমাধান চেষ্টা করুন

ম্যানিফেসে এই অনুমতিগুলি রাখুন

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

ইমেজ ক্যাপচার ইন্টেন্ট

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
                }

অ্যাক্টিভিটিরিয়েস্টগুলিতে ক্যাপচারড ইমেজ পান

@Override
            protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                super.onActivityResult(requestCode, resultCode, data);
                if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
                    Bundle extras = data.getExtras();
                    Bitmap imageBitmap = (Bitmap) extras.get("data");
                    // CALL THIS METHOD TO GET THE URI FROM THE BITMAP
                    Uri tempUri = getImageUri(getApplicationContext(), imageBitmap);
                    //DO SOMETHING WITH URI
                }
            } 

ইমেজ ইউআরআই পাওয়ার পদ্ধতি

public Uri getImageUri(Context inContext, Bitmap inImage) {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
        return Uri.parse(path);
    }

কেউ আমাকে কেন ভোট ডাউন বলতে পারেন। এটি 100% কার্যনির্বাহী সমাধান।
আব্দুল বাসিত

এটি কেবল আপনাকে থাম্বনেইল দেয় পুরো ছবি নয়।
বিল্ড

-2

আমার ক্ষেত্রে আমি প্রতিস্থাপন ব্যতিক্রম পরিত্রাণ SetDataAndTypeশুধু সঙ্গে SetData

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.