2015-01-15 4 views
8

पर फ़ाइल संलग्न करने का प्रयास कर रहा है यह प्रश्न पहले पोस्ट किया गया है, लेकिन कोई स्पष्ट या स्वीकार्य उत्तर नहीं था और प्रदान किए गए सभी समाधान "काम" मेरे लिए नहीं था यहां देखें: Gmail 5.0 app fails with "Permission denied for the attachment" when it receives ACTION_SEND intent"अनुलग्नक के लिए अनुमति अस्वीकार की गई है" (जीमेल 5.0 पर) ईमेल इरादे

मेरे पास एक ऐप है जो टेक्स्ट फ़ाइल में डेटा बनाता है और उसे स्वचालित रूप से संलग्न करने वाले ईमेल में टेक्स्ट फ़ाइल भेजने की आवश्यकता होती है। मैंने इसे संलग्न करने के कई तरीकों का प्रयास किया है, और यह स्पष्ट रूप से जीमेल 4.9 और नीचे के लिए काम करता है लेकिन 5.0 में कुछ नई अनुमति सुविधाएं हैं जो इसे मेरी इच्छा से करने में अक्षम बनाती हैं।

Intent i = new Intent(Intent.ACTION_SEND); 

    String to = emailRecipient.getText().toString(); 

    i.setType("message/rfc822"); 
    i.putExtra(Intent.EXTRA_EMAIL, new String[] { to }); 
    i.putExtra(Intent.EXTRA_SUBJECT, "Pebble Accelerometer Data"); 
    i.putExtra(Intent.EXTRA_TEXT, "Attached are files containing accelerometer data captured by SmokeBeat Pebble app."); 
    String[] dataPieces = fileManager.getListOfData(getApplicationContext()); 
    for(int i2 = 0; i2 < dataPieces.length; i2++){ 
     i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(getApplicationContext().getFilesDir() + File.separator + dataPieces[i2]))); 
    } 
    i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(getApplicationContext().getFilesDir() + File.separator + fileManager.getCurrentFileName(getApplicationContext())))); 
    Log.e("file loc", getApplicationContext().getFilesDir() + File.separator + fileManager.getCurrentFileName(getApplicationContext())); 
    try { 
     startActivity(Intent.createChooser(i, "Send Email")); 
    } catch (android.content.ActivityNotFoundException ex) { 
     Toast.makeText(Main.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show(); 
    } 

datapieces खाली हाँ हो सकता है लेकिन पाश के लिए नीचे दिए गए वर्तमान फ़ाइल पंक्ति हमेशा विश्वसनीय है और हमेशा कुछ जुड़ जाता है।

मैं

Uri.parse() 

को

Uri.fromFile() 

बदलते कोशिश की है जब मैं उस, यह देता है, लेकिन फिर Gmail दुर्घटनाओं और जब मैं logcat जाँच यह एक अशक्त सूचक के कारण है। यह सबसे अधिक संभावना है क्योंकि जीमेल के पास फ़ाइल तक कोई पहुंच नहीं है और इसलिए नल के परिणामस्वरूप।

मैं भी का उपयोग कर

getFilesDir() 

के बजाय

getCacheDir() 

की कोशिश की है और यह एक ही परिणाम है।

मैं यहां क्या गलत कर रहा हूं, और इसे ठीक करने के बारे में मुझे कैसे जाना चाहिए? कुछ उदाहरण कोड वास्तव में, वास्तव में आसान होंगे क्योंकि मैं एंड्रॉइड विकास के लिए नया हूं और समझाता हूं कि मुझे कुछ प्रकार के पुश के बिना क्या करने की ज़रूरत है, शायद मदद समाप्त नहीं होगी।

बहुत बहुत धन्यवाद।

उत्तर

6

ठीक है दोस्तों। एक ब्रेक ले लिया और वापस आ गया, यह पता लगाया।

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

फिर, अपनी फ़ाइल को अपने ऐप्लिकेशन के आंतरिक भंडारण निर्देशिका से कॉपी करने के लिए किया गया है:

यह ऐसे काम करता है, तो आप बाहरी संग्रहण में लिखने/पढ़ने अनुमतियाँ, तो आपके प्रकट करने के लिए इन अनुमतियों को जोड़ने की आवश्यकता है ऐप की बाहरी निर्देशिका में। मैं आपको आंतरिक भंडारण का उपयोग करने की सलाह देता हूं, और यही वह है जो मैं यहां कर रहा हूं ताकि आप एसडी कार्ड स्वयं को समझ सकें।

यहां कोड का ब्लॉक है जो जादू करता है। लॉग शामिल हैं लेकिन आप उन्हें हर तरह से हटा सकते हैं।

public void writeToExternal(Context context, String filename){ 
    try { 
     File file = new File(context.getExternalFilesDir(null), filename); //Get file location from external source 
     InputStream is = new FileInputStream(context.getFilesDir() + File.separator + filename); //get file location from internal 
     OutputStream os = new FileOutputStream(file); //Open your OutputStream and pass in the file you want to write to 
     byte[] toWrite = new byte[is.available()]; //Init a byte array for handing data transfer 
     Log.i("Available ", is.available() + ""); 
     int result = is.read(toWrite); //Read the data from the byte array 
     Log.i("Result", result + ""); 
     os.write(toWrite); //Write it to the output stream 
     is.close(); //Close it 
     os.close(); //Close it 
     Log.i("Copying to", "" + context.getExternalFilesDir(null) + File.separator + filename); 
     Log.i("Copying from", context.getFilesDir() + File.separator + filename + ""); 
    } catch (Exception e) { 
     Toast.makeText(context, "File write failed: " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); //if there's an error, make a piece of toast and serve it up 
    } 
} 
+4

प्रश्न और समाधान में बहुत बड़ा अंतर नहीं है - प्रश्न (context.getFiles() से) एप्लिकेशन के निजी फ़ाइलों को साझा करने के बारे में था, और जवाब में यह सामान्य भंडारण से बन गया (~ context.getExternalFilesDir()) ... एक ही बात नहीं ... – Felix

+0

क्या ऐसे उपकरणों के लिए एक अच्छा सामान्य समाधान है जिसमें बाहरी संग्रहण नहीं हो सकता है? या वह परिदृश्य भी अब चिंता का विषय है? – dylansturg

+0

एंड्रॉइड एपीआई 23 और इसकी नई अनुमति प्रणाली के बाद से अटैचमेंट को स्टोर करने के लिए बाहरी स्टोरेज का उपयोग करना एक बुरा अभ्यास बन गया है। यदि आप रनटाइम पर WRITE_EXTERNAL_STORAGE अनुमति के लिए उपयोगकर्ता से नहीं पूछते हैं, तो यह असफल हो जाएगा। –

1

उसी अनुलग्नक को अस्वीकार कर दिया गया। मैनिफेस्ट में अनुमतियों का कोई प्रभाव नहीं पड़ा, बल्कि एपीआई 23 के बाद से कोई प्रभाव नहीं पड़ा। आखिरकार इसे हल किया गया।

रन-टाइम पर प्रदान करने की अनुमतियों की जाँच करें और करने के लिए 1 की जरूरत है, मैं अपने मुख्य गतिविधि में यह किया:

public static final int MY_PERMISSIONS_REQUEST_READ_STORAGE=10001; 
private void checkPermission(){ 
    if (this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { 
     // Should we show an explanation? 
     if (this.shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) { 
      // Show an explanation to the user asynchronously 
     } else { 
      // No explanation needed, we can request the permission. 
      this.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
        MY_PERMISSIONS_REQUEST_READ_STORAGE); 
     } 
    } 
} 

अब जब भेजने, सार्वजनिक निर्देशिका (मेरे एप्लिकेशन फ़ोल्डर में बचत करने की कोशिश की में एक फ़ाइल बना सकते हैं - एक ही इनकार समस्या)

public File createFile(){ 
String htmlStr="<!DOCTYPE html>\n<html>\n<body>\n<p>my html file</p></body></html>"; 
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "aimexplorersummary.html"); 
try { 
     FileWriter writer = new FileWriter(file ,false); 
     writer.write(htmlStr); 
     } 
     writer.flush(); 
     writer.close(); 
    } catch (IOException e) { 
    e.printStackTrace(); 
    return null; 
    } 
return file; 
} 

अब अपनी फ़ाइल जो जनता के भंडारण कि उपयोगकर्ता के लिए अनुमति प्रदान करनी होगी में है और वह कोई समस्या नहीं अब

का कारण बनता है के लिए uri के साथ आशय और putExtra भेजने रचना
संबंधित मुद्दे