android।


736

जब मैं एक फ़ाइल खोलने की कोशिश कर रहा हूँ तो ऐप क्रैश हो रहा है। यह Android Nougat के नीचे काम करता है, लेकिन Android Nougat पर यह क्रैश हो जाता है। यह केवल क्रैश होता है जब मैं एसडी कार्ड से फाइल खोलने की कोशिश करता हूं, सिस्टम विभाजन से नहीं। कुछ अनुमति समस्या?

नमूना कोड:

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।

संपादित करें:

Android Nougat को लक्षित करते समय, file://URI को अनुमति नहीं दी जाती है। हमें content://इसके बजाय यूआरआई का उपयोग करना चाहिए । हालाँकि, मेरे ऐप को रूट डायरेक्टरीज़ में फाइल खोलने की जरूरत है। कोई विचार?


20
मुझे ऐसा लगता है कि यह एक गलती थी जो ऐप डेवलपर्स के लिए जीवन को अनावश्यक रूप से कठिन बना देती है। प्रत्येक ऐप के साथ एक "FileProvider" और "प्राधिकरण" बंडल करने के लिए, Enterprisey बॉयलरप्लेट की तरह लगता है। हर फ़ाइल के इरादे के लिए एक ध्वज जोड़ने के लिए अजीब और संभवतः अनावश्यक लगता है। "पथ" की सुरुचिपूर्ण अवधारणा को तोड़ना अप्रिय है। और क्या लाभ है? ऐप्स को चुनिंदा रूप से स्टोरेज एक्सेस देना (जबकि ज्यादातर ऐप्स में फुल sdcard एक्सेस है, खासकर जो फाइलों पर काम करते हैं)?
nyanpasu64

2
यह प्रयास करें, छोटे और सही कोड stackoverflow.com/a/52695444/4997704
Binesh Kumar

जवाबों:


1314

यदि आपका है targetSdkVersion >= 24, तो हमें FileProviderअन्य एप्लिकेशन के लिए उन्हें सुलभ बनाने के लिए विशेष फ़ाइल या फ़ोल्डर तक पहुंच देने के लिए कक्षा का उपयोग करना होगा। हम FileProviderयह सुनिश्चित करने के लिए अपने स्वयं के वर्ग का निर्माण कर रहे हैं कि हमारे FileProvider यहाँ वर्णित के रूप में आयातित निर्भरता में घोषित FileProviders के साथ संघर्ष नहीं करता है

file://URI को content://URI से बदलने के लिए कदम :

  • एक क्लास बढ़ाएँ जोड़ें FileProvider

    public class GenericFileProvider extends FileProvider {}
  • एक 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=".") नाम से साझा करना चाहते हैं ।
<?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
मुझे सिर्फ आशय जोड़ने की आवश्यकता थी। ऑफसेट (Intent.FLAG_GRANT_READ_URI_PERMISSION);
alorma

24
क्या यह सभी Android संस्करणों के लिए काम करेगा, या सिर्फ एपीआई 24 से?
एंड्रॉयड डेवलपर

9
इस लेख में मदद मिली मुझे medium.com/@ali.muzaffar/...
AbdulMomen عبدالمؤمن

11
@rockhammer मैंने अभी Android 5.0, 6.0, 7.1 और 8.1 के साथ इसका परीक्षण किया है, यह सभी मामलों में काम करता है। इसलिए (Build.VERSION.SDK_INT > M)हालत बेकार है।
सेबास्टियन

66
FileProviderकेवल तभी बढ़ाया जाना चाहिए जब आप किसी भी डिफ़ॉल्ट व्यवहार को ओवरराइड करना चाहते हैं, अन्यथा उपयोग करें android:name="android.support.v4.content.FileProvider"डेवलपर
JP Ventura

312

समाधान का उपयोग करने के अलावा, इसके FileProviderचारों ओर काम करने का एक और तरीका है। सीधे शब्दों में कहें

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

में है Application.onCreate()। इस तरह वीएम फाइल URIएक्सपोजर को नजरअंदाज कर देता है ।

तरीका

builder.detectFileUriExposure()

यदि हम VmPolicy सेटअप नहीं करते हैं, तो फ़ाइल एक्सपोज़र चेक को सक्षम करता है, जो कि डिफ़ॉल्ट व्यवहार भी है।

मुझे एक समस्या का सामना करना पड़ा कि अगर मैं content:// URIकुछ भेजने के लिए एक का उपयोग करता हूं , तो कुछ एप्लिकेशन इसे समझ नहीं सकते हैं। और target SDKसंस्करण को डाउनग्रेड करने की अनुमति नहीं है। इस मामले में मेरा समाधान उपयोगी है।

अपडेट करें:

जैसा कि टिप्पणी में उल्लेख किया गया है, स्ट्रिक्टमोड नैदानिक ​​उपकरण है, और इस समस्या के लिए उपयोग नहीं किया जाना चाहिए। जब मैंने एक साल पहले यह उत्तर पोस्ट किया था, तो कई ऐप केवल फ़ाइल यूरिस प्राप्त कर सकते हैं। वे तभी दुर्घटनाग्रस्त हो जाते हैं जब मैंने उनके लिए फाइलप्रॉइडर यूरी भेजने की कोशिश की। यह अब अधिकांश ऐप्स में तय हो गया है, इसलिए हमें FileProvider समाधान के साथ जाना चाहिए।


1
@LaurynasG एपीआई 18 से 23 तक, एंड्रॉइड डिफॉल्ट रूप से फाइल यूरी एक्सपोजर की जांच नहीं करता है। इस विधि को कॉल करना इस चेक को सक्षम करता है। एपीआई 24 से, एंड्रॉइड इस चेक को डिफ़ॉल्ट रूप से करता है। लेकिन हम एक नया सेटिंग करके इसे अक्षम कर सकते हैं VmPolicy
hqzxzwb

क्या इसके लिए किसी अन्य कदम की आवश्यकता है? काम नहीं करता क्योंकि यह एंड्रॉइड 7.0 पर चलने वाले मेरे मोटो जी के लिए है।
CKP78

3
हालांकि यह इस समस्या को कैसे हल कर सकता है, स्ट्रिक्टमोड एक नैदानिक ​​उपकरण है जिसे डेवलपर मोड में सक्षम किया जाना चाहिए रिलीज़ मोड नहीं ???
इमेने नोओमेने

1
@ImeneNoomene वास्तव में हम यहां स्ट्रिक्टमोड को निष्क्रिय कर रहे हैं। यह उचित प्रतीत होता है कि स्ट्रिक्टमोड को रिलीज़ मोड में सक्षम नहीं किया जाना चाहिए, लेकिन वास्तव में एंड्रॉइड डिबग मोड या रिलीज़ मोड की परवाह किए बिना डिफ़ॉल्ट रूप से कुछ स्ट्रिक्टमोड विकल्पों को सक्षम करता है। लेकिन एक तरह से या किसी अन्य, यह जवाब केवल एक वर्कअराउंड बैक होने के लिए था जब कुछ लक्ष्य एप्लिकेशन सामग्री यूरिस प्राप्त करने के लिए तैयार नहीं थे। अब जबकि अधिकांश ऐप्स ने सामग्री uris के लिए समर्थन जोड़ दिया है, हमें FileProvider पैटर्न का उपयोग करना चाहिए।
hqzxzwb

3
@ImeneNoomene मैं आपकी नाराजगी में पूरी तरह से आपके साथ हूं। आप सही हैं, यह एक नैदानिक ​​उपकरण है, या कम से कम यह पहले की उम्र थी जब मैंने इसे अपनी परियोजनाओं में जोड़ा था। यह सुपर निराशाजनक है! StrictMode.enableDefaults();, जो मैं केवल अपने विकास के आधार पर चलाता हूं, इस दुर्घटना को होने से रोकता है - इसलिए मेरे पास अब एक उत्पादन अनुप्रयोग है जो दुर्घटनाग्रस्त हो जाता है लेकिन यह विकास में दुर्घटनाग्रस्त नहीं होता है। तो मूल रूप से, एक नैदानिक ​​उपकरण को सक्षम करना यहां एक गंभीर मुद्दा छुपाता है। धन्यवाद @hqzxzwb मेरी मदद करने के लिए इसे ध्वस्त करने के लिए।
जॉन

174

यदि 24targetSdkVersion से अधिक है , तो एक्सेस प्रदान करने के लिए FileProvider का उपयोग किया जाता है।

एक xml फ़ाइल (पथ: रेस \ 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>


AndroidManifest.xml में एक प्रदाता जोड़ें

    <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>

यदि आप androidx का उपयोग कर रहे हैं , तो FileProvider पथ होना चाहिए:

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

और प्रतिस्थापित करें

Uri uri = Uri.fromFile(fileImagePath);

सेवा

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

संपादित करें: जब आप Intentनीचे पंक्ति जोड़ने के लिए सुनिश्चित करें कि URI शामिल हैं :

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

और आप जाने के लिए अच्छे हैं। आशा है ये मदद करेगा।


2
@MaksimKniazev क्या आप अपनी त्रुटि का संक्षेप में वर्णन कर सकते हैं? ताकि मैं आपकी मदद कर सकूं।
पंकज लीलण

1
@PankajLilan, मैंने वही किया जो आपने कहा था। लेकिन हर बार जब मैं अपने पीडीएफ को दूसरे एप्लिकेशन में खोलता हूं तो यह खाली दिखाई देता है (इसकी बचत सही तरीके से)। क्या मुझे xml को संपादित करने की आवश्यकता है? मैंने पहले ही FLAG_GRANT_READ_URI_PERMISSION जोड़ दिया;
फेलिप कैस्टिलहोस

1
मेरी गलती, मैं गलत इरादे की अनुमति जोड़ रहा था। यह सबसे अच्छा और सरलतम सही उत्तर है। धन्यवाद!
फेलिप कैस्टिलोस

2
यह अपवाद java.lang.IllegalArgumentException को फेंकता है: कॉन्फ़िगर रूट को खोजने में विफल रहता है जिसमें / मेरा फ़ाइल पथ /storage/emulated/0/GSMManage_DCIM/Documents/Device4298file_74.pdf है। क्या आप मदद कर सकते हैं?
जगदीश भावसार

1
पता नहीं क्यों, लेकिन मैं दोनों पढ़ने और लिखने अनुमतियां जोड़ने के लिए किया था: (Intent.FLAG_GRANT_READ_URI_PERMISSION) target.addFlags (Intent.FLAG_GRANT_WRITE_URI_PERMISSION) target.addFlags
बॉक्स

160

यदि आपका ऐप API 24+ को लक्षित करता है, और आप अभी भी चाहते हैं / फ़ाइल का उपयोग करने की आवश्यकता है: // intents, तो आप रनटाइम चेक को अक्षम करने के लिए हैक करने के तरीके का उपयोग कर सकते हैं:

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 फ़ाइल खोलना: // योजना एक ही ओवर फ़ाइल खोलने पर की तुलना में बहुत कम ऐप्स प्रदान करती है: // योजना। मैं अपने ऐप की कार्यक्षमता को सीमित करके Google के डिज़ाइन दोषों के लिए भुगतान नहीं करना चाहता।

Google चाहता है कि डेवलपर्स कंटेंट स्कीम का उपयोग करें, लेकिन सिस्टम इसके लिए तैयार नहीं है, क्योंकि सालों से ऐप्स का उपयोग "कंटेंट" नहीं करने के लिए किया गया था, फ़ाइलों को संपादित किया जा सकता है और उन्हें वापस सहेजा जा सकता है, जबकि कंटेंट स्कीम में दी गई फाइलें (नहीं हो सकती हैं) वे?)।


3
"जबकि सामग्री योजना में सेवा की गई फाइलें नहीं हो सकती हैं (क्या वे?)।" - यकीन है, अगर आपके पास सामग्री तक पहुंच है। ContentResolverदोनों openInputStream()और है openOutputStream()। ऐसा करने का एक कम-हैक करने का तरीका सिर्फ VM नियमों को स्वयं कॉन्फ़िगर करना है, और file Uriनियम को सक्षम नहीं करना है ।
कॉमन्सवेयर

1
बिल्कुल सही। यह कठिन काम है जब आपने अपना संपूर्ण ऐप बनाया था, तब पता करें कि आपके सभी कैमरा तरीकों के 25 लक्ष्य क्या हैं। यह मेरे लिए तब तक काम करता है जब तक मुझे इसे सही तरीके से करने का समय नहीं मिलता।
मैट डब्ल्यू

5
एंड्रॉइड 7 पर काम करता है। धन्यवाद
एंटोन किजिमा

4
Android 8 पर भी काम करता है, Huawei Nexus 6P पर परीक्षण किया गया है।
गोंजालो लेदिज़मा टॉरेस

4
मैं पुष्टि करता हूं कि यह उत्पादन पर काम कर रहा है (मेरे पास तब 500,000 से अधिक उपयोगकर्ता हैं), वर्तमान में संस्करण 8.1 उच्चतम संस्करण है, और यह इस पर काम करता है।
एली

90

यदि आपकी targetSdkVersionसंख्या 24 या अधिक है, तो आप एंड्रॉइड 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
@SuperThomasLab: मैं /systemविश्व-पठनीय होने की हर चीज पर भरोसा नहीं करता । यह कहा जा रहा है, मेरा अनुमान है कि आपको अभी भी यह अपवाद मिलेगा। मुझे संदेह है कि वे सिर्फ योजना की जांच कर रहे हैं और यह निर्धारित करने की कोशिश नहीं कर रहे हैं कि क्या फ़ाइल वास्तव में विश्व-पठनीय है। हालाँकि, FileProviderआपकी मदद नहीं करेगा, क्योंकि आप इसे सेवा नहीं दे सकते /system। आप समस्या के अतीत के बारे में जानने के लिए मेरे लिए एक कस्टम रणनीति बनाStreamProvider सकते हैं या अपना स्वयं का रोल बना सकते हैं ContentProvider
कॉमन्सवेयर जूल

फिर भी सोच रहा हूं कि मैं इसे कैसे हल करने जा रहा हूं .. एंड्रॉइड एन सपोर्ट के साथ मैं जिस ऐप को अपडेट कर रहा हूं वह रूट ब्राउजर है। लेकिन अब आप किसी भी फाइल को रूट डाइरेक्टरी में नहीं खोल सकते हैं। ( /data, /system), इस "अच्छे बदलाव" के कारण।
थॉमस वोस

1
लक्ष्य को छोड़ने के लिए सबसे महत्वपूर्ण कमियां क्या हैं। thnx
rommex

2
@rommex: मुझे नहीं पता कि "सबसे महत्वपूर्ण" के रूप में क्या योग्यता है। उदाहरण के लिए, जो उपयोगकर्ता विभाजित-स्क्रीन मोड या फ्रीफ़ॉर्म मल्टी-विंडो डिवाइस (Chromebook, Samsung DeX) में काम करते हैं, उन्हें बताया जाएगा कि आपका ऐप मल्टी-विंडो के साथ काम नहीं कर सकता है। चाहे वह महत्वपूर्ण हो या न हो, आप पर निर्भर है।
कॉमन्सवेअर

47

सबसे पहले आपको एक प्रदाता को अपने AndroidManifest में जोड़ना होगा

  <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>

अब xml संसाधन फ़ोल्डर में एक फ़ाइल बनाएं (यदि Android स्टूडियो का उपयोग करके आप Alt_ Enter को हाइलाइट कर सकते हैं तो file_paths हाइलाइट करने के बाद xml संसाधन विकल्प बनाएँ)

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();
    }

EDIT : मैंने sd कार्ड के रूट फ़ोल्डर को file_paths में जोड़ा। मैंने इस कोड का परीक्षण किया है और यह काम करता है।


1
इसके लिए शुक्रिया। मैं आपको यह भी बताना चाहता हूं कि फ़ाइल एक्सटेंशन प्राप्त करने का एक बेहतर तरीका है। String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString()); इसके अलावा, मैं किसी को भी पहले FileProvider के माध्यम से पढ़ने के जवाब की तलाश करने की सलाह देता हूं और समझता हूं कि आप यहां Android N और उससे ऊपर की फ़ाइल अनुमतियों के साथ क्या व्यवहार कर रहे हैं। आंतरिक भंडारण बनाम बाहरी भंडारण के लिए और नियमित रूप से फ़ाइलों-पथ बनाम कैश-पथ के लिए विकल्प हैं।
प्रणीतलोके

2
मुझे निम्नलिखित अपवाद मिल रहा था: java.lang.IllegalArgumentException: Failed to find configured root ...और केवल एक चीज जो काम करती थी <files-path path="." name="files_root" />वह xml फ़ाइल पर थी <external-path ...। मेरी फ़ाइल आंतरिक संग्रहण में सहेजी गई थी।
20-18 को स्टेलियोसेफ

26

@palash k का उत्तर सही है और आंतरिक संग्रहण फ़ाइलों के लिए काम किया है, लेकिन मेरे मामले में मैं बाह्य भंडारण से भी फाइलें खोलना चाहता हूं, जब sdcard और usb जैसे बाहरी भंडारण से खुली फ़ाइल को क्रैश करने पर मेरा ऐप क्रैश हो गया, लेकिन मैं संशोधित करके इस मुद्दे को हल करने का प्रबंधन करता हूं provider_paths.xml स्वीकृत उत्तर से

नीचे की तरह प्रदाता_पथ / xml बदलें

<?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

मैं इसे विभिन्न खोज परिणामों से प्राप्त करता हूं, मुझे फिर से जांच करने और यू asap पर वापस जाने के लिए
Ramz

आपके द्वारा उल्लिखित बाह्य संग्रहण भी एसडी कार्ड या इनबिल्ट स्टोरेज है?
रमज़

अशुद्धि के लिए क्षमा करें। मेरा मतलब Android/data/${applicationId}/एसडीकार्ड में था।
t0m

1
इसे इरादे से जोड़ने की आवश्यकता है: इरादे ।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);

लगता है कि fromFile () एक फ़ाइल पॉइंटर का उपयोग करता है, जो मुझे लगता है कि असुरक्षित हो सकता है जब मेमोरी पते सभी ऐप के संपर्क में आते हैं। लेकिन ए फ़ाइल पथ स्ट्रिंग स्ट्रिंग ने कभी किसी को चोट नहीं पहुंचाई, इसलिए यह FileUriExposedException को फेंकने के बिना काम करता है।

एपीआई स्तर 9 से 27 पर परीक्षण किया गया! किसी अन्य ऐप में संपादन के लिए पाठ फ़ाइल को सफलतापूर्वक खोलता है। FileProvider की आवश्यकता नहीं है, न ही Android समर्थन लाइब्रेरी बिल्कुल भी नहीं।


काश मैं यह पहली बार देखा होता। मैंने साबित नहीं किया कि यह मेरे लिए काम करता है, लेकिन यह FileProvider की तुलना में बहुत कम बोझिल है।
डेल

इस पर ध्यान दें कि यह वास्तव में क्यों काम करता है: यह फ़ाइल पॉइंटर नहीं है जो इस मुद्दे को बढ़ाता है, लेकिन यह तथ्य कि अपवाद केवल तब होता है जब आपके पास 'फ़ाइल: //' के साथ एक पथ होता है, जो स्वचालित रूप से फ़्रीइल के साथ पूर्वनिर्मित होता है, लेकिन पार्स के साथ नहीं ।
Xmister

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

FileProvider का उपयोग करने का तरीका है। लेकिन आप इस सरल वर्कअराउंड का उपयोग कर सकते हैं:

चेतावनी : इसे अगले Android रिलीज़ में ठीक किया जाएगा - https://issuetracker.google.com/issues/37122890#comb4

बदलने के:

startActivity(intent);

द्वारा

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

7
Google द्वारा समान जांच शामिल करने के लिए चयनकर्ता को जल्द ही पैच किया जाएगा। यह कोई हल नहीं है।
सूचक नल

यह काम करता है लेकिन भविष्य के एंड्रॉइड संस्करणों में काम नहीं करेगा।
दिलजीत

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.VmPolicy.Builder बिल्डर = new StrictMode.VmPolicy.Builder (); StrictMode.setVmPolicy (builder.build ());

यह यूआरआई एक्सपोज़र की अनदेखी करेगा


यह, यह सख्त नीतियों को हटा देगा। और सुरक्षा चेतावनी की अनदेखी करेगा। अच्छा समाधान नहीं।
इंस्पायर_कोडिंग

यह एंड्रॉइड 10 और उच्चतर पर भी विफल हो जाएगा, क्योंकि आप यह नहीं मान सकते कि दूसरे ऐप में फाइल सिस्टम के माध्यम से बाहरी भंडारण तक पहुंच है।
कॉमन्सवेयर

7

इस दो लाइन onCreate में जोड़ें

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 पर परीक्षण करता हूं और यह सफलता का काम है।


मैंने इस समाधान का परीक्षण किया है, और यह एक छोटे से परिवर्तन के साथ ठीक काम करता है: इरादे। flags = Intent.FLAG_ACTIVITY_NEW_TASK आशय ।putExtra (Intent.EXTRA_STREAM, myPhotoFrUri) आशय। टाइप करें = "image / png" startActivity (Intent.createChooser) शेयर इमेज "" के माध्यम से) यह एंड्रॉइड 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?
आदित्यसनल ३०'१l

1
@ हाइजेनबर्ग कृपया राहुल उपाध्याय पोस्ट को url से देखें: stackoverflow.com/questions/38555301/…
Bhoomika Chauhan

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)

intentवास्तव में getIntent().addFlagsमेरे नए घोषित playIntent पर काम करने के बजाय सेटिंग कर रहा था।


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 फ़ाइल Res / 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>

चरण 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
        }
    }

इसी तरह, एक छवि के बजाय, आप किसी भी अन्य फ़ाइल प्रारूप का उपयोग कर सकते हैं जैसे कि पीडीएफ और मेरे मामले में, यह ठीक काम किया


0

मैंने लगभग एक दिन यह जानने की कोशिश में बिताया कि मुझे यह अपवाद क्यों मिल रहा है। बहुत संघर्ष के बाद, इस कॉन्फिग ने पूरी तरह से काम किया ( कोटलिन ):

AndroidManifest.xml

<provider
  android:name="androidx.core.content.FileProvider"
  android:authorities="com.lomza.moviesroom.fileprovider"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/file_paths" />
</provider>

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <files-path name="movies_csv_files" path="."/>
</paths>

आशय है

fun goToFileIntent(context: Context, file: File): Intent {
    val intent = Intent(Intent.ACTION_VIEW)
    val contentUri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
    val mimeType = context.contentResolver.getType(contentUri)
    intent.setDataAndType(contentUri, mimeType)
    intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION

    return intent
}

मैं यहां पूरी प्रक्रिया समझाता हूं ।


-1

https://stackoverflow.com/a/38858040/395097 यह उत्तर पूर्ण है।

यह उत्तर है - आपके पास पहले से ही एक ऐप है जो 24 से नीचे का लक्ष्य कर रहा था, और अब आप targetSDKVersion> = 24 पर अपग्रेड कर रहे हैं।

एंड्रॉइड एन में, केवल 3 पार्टी ऐप के संपर्क में आने वाली फ़ाइल उड़ी को बदल दिया जाता है। (जिस तरह से हम पहले इसका इस्तेमाल नहीं कर रहे थे)। इसलिए केवल उन स्थानों को बदलें जहां आप तृतीय पक्ष ऐप के साथ पथ साझा कर रहे हैं (मेरे मामले में कैमरा)

हमारे ऐप में हम कैमरा ऐप के लिए uri भेज रहे थे, उस स्थान पर हम कैमरा ऐप से कैप्चर की गई छवि को स्टोर करने की उम्मीद कर रहे हैं।

  1. Android N के लिए, हम फ़ाइल के लिए नई सामग्री: // uri आधारित url इंगित करते हैं।
  2. हम समान (पुरानी विधि का उपयोग करके) के लिए सामान्य रूप से फ़ाइल एपीआई आधारित पथ उत्पन्न करते हैं।

अब हमारे पास एक ही फाइल के लिए 2 अलग-अलग uri हैं। # 1 कैमरा ऐप के साथ साझा किया गया है। यदि कैमरा का इरादा सफल होता है, तो हम छवि को # 2 से एक्सेस कर सकते हैं।

उम्मीद है की यह मदद करेगा।


1
आप यहां पहले से पोस्ट किए गए उत्तर का उल्लेख कर रहे हैं, यदि आपको इसे पूरा करने की आवश्यकता है, तो उत्तर plz में टिप्पणी करें।
इग्नाइटेकोडर्स

1
@IgniteCoders जैसा कि मैंने संदेश में स्पष्ट रूप से उल्लेख किया है, मेरा उत्तर संबंधित उपयोग के मामले को कवर करता है।
अराम

-1

Xamarin.Android

नोट: संसाधन के तहत xml फ़ोल्डर बनाने के बाद भी पथ xml / provider_paths.xml (.axml) को हल नहीं किया जा सकता है, (शायद इसे किसी मौजूदा स्थान जैसे मानों में रखा जा सकता है , कोशिश नहीं की गई), इसलिए मैंने इसका सहारा लिया यह अब के लिए काम करता है। परीक्षण से पता चला कि इसे केवल एक बार आवेदन चलाने के लिए कहा जाना चाहिए (जो समझ में आता है कि यह मेजबान वीएम की परिचालन स्थिति को बदल देता है)।

नोट: xml को बड़ा करने की आवश्यकता है, इसलिए संसाधन / Xml / provider_paths.xml

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

@Pkosta का उत्तर ऐसा करने का एक तरीका है।

उपयोग करने के अलावा FileProvider, आप फ़ाइल को MediaStore(विशेष रूप से छवि और वीडियो फ़ाइलों के लिए) भी सम्मिलित कर सकते हैं , क्योंकि MediaStore में फ़ाइलें हर ऐप के लिए सुलभ हैं:

MediaStore मुख्य रूप से वीडियो, ऑडियो और छवि MIME प्रकारों के लिए लक्षित है, हालांकि Android 3.0 (API स्तर 11) के साथ शुरुआत करके यह गैर-मीडिया प्रकारों को भी संग्रहीत कर सकता है (अधिक जानकारी के लिए MediaStore.Files देखें)। फ़ाइलें स्कैनफाइल () का उपयोग करके मीडियास्टोर में डाली जा सकती हैं जिसके बाद साझा करने के लिए उपयुक्त एक सामग्री: // शैली उरी को प्रदान की गई ऑनस्कैनप्लेक्टेड () कॉलबैक को पास किया जाता है। ध्यान दें कि एक बार सिस्टम MediaStore में जोड़ा जाने के बाद सामग्री डिवाइस पर किसी भी ऐप के लिए सुलभ है।

उदाहरण के लिए, आप इस तरह MediaStore में एक वीडियो फ़ाइल सम्मिलित कर सकते हैं:

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

बस इसे URI एक्सपोज़र को अनदेखा करने दें ... इसे बनाने के बाद जोड़ें

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

यह एंड्रॉइड 10 और उच्चतर पर विफल हो जाएगा, क्योंकि आप यह नहीं मान सकते कि दूसरे ऐप में फाइल सिस्टम के माध्यम से बाहरी भंडारण तक पहुंच है।
कॉमन्सवेयर

यह नहींं एक producction अनुप्रयोग में इस्तेमाल किया जाना चाहिए।
जोर्जेस

-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);
                }

ONACTIVITYRESULT में संग्रहीत छवि प्राप्त करें

@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
                }
            } 

METHOD TO GET IMAGE 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% काम कर समाधान है।
अब्दुल बासित ऋषि

यह केवल आपको थंबनेल मिलता है पूरी तस्वीर नहीं।
बिल्ड 3 आर

-2

मेरे मामले में मुझे SetDataAndTypeसिर्फ जगह देकर अपवाद से छुटकारा मिला SetData

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.