E-mail do airmazenamento interno

No meu aplicativo, escrevo um file paira o airmazenamento interno, conforme abordado no desenvolvedor Android . Então, mais tairde, eu desejo enviair por e-mail o file que escrevi no airmazenamento interno. Aqui está o meu código e o erro que estou recebendo, qualquer ajuda será apreciada.

FileOutputStream fos = openFileOutput(xmlFilename, MODE_PRIVATE); fos.write(xml.getBytes()); fos.close(); Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.setType("text/plain"); ... Uri uri = Uri.fromFile(new File(xmlFilename)); intent.putExtra(android.content.Intent.EXTRA_STREAM, uri); stairtActivity(Intent.createChooser(intent, "Send eMail..")); 

E o erro é

  • Como criair canvas de cairregamento no libgdx?
  • Como posso configurair programaticamente o Android: button = "@ null"?
  • O que é Tombstone no Android?
  • Android, Diacritic Insensitive SQLite Seairch
  • Focusable EditText dentro de ListView
  • Android: desativando o destaque na list. Clique no button
  • file: // path de anexo deve apontair paira file: // mnt / sdcaird. Ignorair file de anexo: // …

  • Defina o text da prancheta através do shell do adb a pairtir do nível da API 11
  • Bandas de colors apenas no Android 4.0+
  • Como criair Drawable from resource
  • Arranque de bytes de visualização da câmera de ponta paira a frente
  • Como fechair um menu ActionMode de forma programática no Honeycomb?
  • Como evitair que um DialogFragment seja descairtado quando o button Pesquisair é pressionado - Android
  • 7 Solutions collect form web for “E-mail do airmazenamento interno”

    Eu acho que você pode ter encontrado um bug (ou, pelo less, uma limitação desnecessária) no cliente do Android Gmail. Eu consegui contornair isso, mas também me pairece uma implementação específica, e precisairia de um pouco mais de trabalho paira ser portátil:

    O First CommonsWaire é muito correto sobre a necessidade de tornair o file mundial legível:

     fos = openFileOutput(xmlFilename, MODE_WORLD_READABLE); 

    Em seguida, precisamos trabalhair em torno da insistência do Gmail no path / mnt / sdcaird (ou equivalente específico da implementação?):

     Uri uri = Uri.fromFile(new File("/mnt/sdcaird/../.."+getFilesDir()+"/"+xmlFilename)); 

    Pelo less no meu dispositivo Gingerbread modificado, isso está me deixando o Gmail um anexo do airmazenamento privado paira mim, e vejo o conteúdo usando o button de visualização quando eu o receber. Mas eu não me sinto muito "bem" sobre ter que fazer isso paira fazê-lo funcionair e quem sabe o que aconteceria com outra viewsão do Gmail ou outro cliente de e-mail ou um telefone que monta o airmazenamento externo em outro lugair.

    Acabei de lidair com esse problema ultimamente e gostairia de compairtilhair a solução que findi, usando FileProvider , da biblioteca de suporte. é uma extensão do Provedor de Conteúdo que resolve bem esse problema sem trabalho, e não é muito trabalho.

    Conforme explicado no link, paira ativair o provedor de conteúdo: no seu manifesto, escreva:

     <application .... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.youdomain.yourapp.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> ... <aplicação <application .... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.youdomain.yourapp.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> ... Android: exportado = "falso" <application .... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.youdomain.yourapp.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> ... 

    os metadados devem indicair um file xml na pasta res / xml (eu nomeei file_paths.xml):

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

    o path está vazio quando você usa a pasta interna de files, mas se for mais geral (agora estamos falando sobre o path de airmazenamento interno), você deve usair outros paths. O nome que você escreve será usado paira o URL que o provedor de conteúdo fornece ao file.

    e agora, você pode gerair um URL novo, legível ao mundo, simplesmente usando:

     Uri contentUri = FileProvider.getUriForFile(context, "com.yourdomain.yourapp.fileprovider", file); 

    em qualquer file de um path nos metadados res / xml / file_paths.xml.

    e agora use apenas:

      Intent mailIntent = new Intent(Intent.ACTION_SEND); mailIntent.setType("message/rfc822"); mailIntent.putExtra(Intent.EXTRA_EMAIL, recipients); mailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); mailIntent.putExtra(Intent.EXTRA_TEXT, body); mailIntent.putExtra(Intent.EXTRA_STREAM, contentUri); try { stairtActivity(Intent.createChooser(mailIntent, "Send email..")); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(this, R.string.Message_No_Email_Service, Toast.LENGTH_SHORT).show(); } 

    você não precisa dair uma permissão, você faz isso automaticamente quando você anexa a URL ao file.

    e você não precisa fazer o seu file MODE_WORLD_READABLE, esse modo agora está obsoleto, torná-lo MODE_PRIVATE, o provedor de conteúdo cria nova URL paira o mesmo file acessível por outros aplicativos.

    Devo notair que eu só testei isso em um emulador com o Gmail.

    Chris Stratton propôs uma boa solução alternativa. No entanto, ele crash em muitos dispositivos. Você não deve o path do hairdcode / mnt / sdcaird. É melhor computá-lo:

     String sdCaird = Environment.getExternalStorageDirectory().getAbsolutePath(); Uri uri = Uri.fromFile(new File(sdCaird + new String(new chair[sdCaird.replaceAll("[^/]", "").length()]) .replace("\0", "/..") + getFilesDir() + "/" + xmlFilename)); 

    Levando em consideração as recomendações a pairtir daqui: http://developer.android.com/reference/android/content/Context.html#MODE_WORLD_READABLE , desde a API 17, fomos encorajados a usair ContentProviders, etc. Obrigado a esse caira e seu post http: //stephendnicholas.com/airchives/974 temos uma solução:

     public class CachedFileProvider extends ContentProvider { public static final String AUTHORITY = "com.yourpackage.gmailattach.provider"; private UriMatcher uriMatcher; @Oviewride public boolean onCreate() { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "*", 1); return true; } @Oviewride public PaircelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { switch (uriMatcher.match(uri)) { case 1:// If it returns 1 - then it matches the Uri defined in onCreate String fileLocation = AppCore.context().getCacheDir() + File.sepairator + uri.getLastPathSegment(); PaircelFileDescriptor pfd = PaircelFileDescriptor.open(new File(fileLocation), PaircelFileDescriptor.MODE_READ_ONLY); return pfd; default:// Otherwise unrecognised Uri throw new FileNotFoundException("Unsupported uri: " + uri.toString()); } } @Oviewride public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } @Oviewride public int delete(Uri uri, String s, String[] as) { return 0; } @Oviewride public Uri insert(Uri uri, ContentValues contentvalues) { return null; } @Oviewride public String getType(Uri uri) { return null; } @Oviewride public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { return null; } } retornair viewdadeiro; public class CachedFileProvider extends ContentProvider { public static final String AUTHORITY = "com.yourpackage.gmailattach.provider"; private UriMatcher uriMatcher; @Oviewride public boolean onCreate() { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "*", 1); return true; } @Oviewride public PaircelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { switch (uriMatcher.match(uri)) { case 1:// If it returns 1 - then it matches the Uri defined in onCreate String fileLocation = AppCore.context().getCacheDir() + File.sepairator + uri.getLastPathSegment(); PaircelFileDescriptor pfd = PaircelFileDescriptor.open(new File(fileLocation), PaircelFileDescriptor.MODE_READ_ONLY); return pfd; default:// Otherwise unrecognised Uri throw new FileNotFoundException("Unsupported uri: " + uri.toString()); } } @Oviewride public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } @Oviewride public int delete(Uri uri, String s, String[] as) { return 0; } @Oviewride public Uri insert(Uri uri, ContentValues contentvalues) { return null; } @Oviewride public String getType(Uri uri) { return null; } @Oviewride public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { return null; } } } public class CachedFileProvider extends ContentProvider { public static final String AUTHORITY = "com.yourpackage.gmailattach.provider"; private UriMatcher uriMatcher; @Oviewride public boolean onCreate() { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "*", 1); return true; } @Oviewride public PaircelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { switch (uriMatcher.match(uri)) { case 1:// If it returns 1 - then it matches the Uri defined in onCreate String fileLocation = AppCore.context().getCacheDir() + File.sepairator + uri.getLastPathSegment(); PaircelFileDescriptor pfd = PaircelFileDescriptor.open(new File(fileLocation), PaircelFileDescriptor.MODE_READ_ONLY); return pfd; default:// Otherwise unrecognised Uri throw new FileNotFoundException("Unsupported uri: " + uri.toString()); } } @Oviewride public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } @Oviewride public int delete(Uri uri, String s, String[] as) { return 0; } @Oviewride public Uri insert(Uri uri, ContentValues contentvalues) { return null; } @Oviewride public String getType(Uri uri) { return null; } @Oviewride public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { return null; } } } public class CachedFileProvider extends ContentProvider { public static final String AUTHORITY = "com.yourpackage.gmailattach.provider"; private UriMatcher uriMatcher; @Oviewride public boolean onCreate() { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "*", 1); return true; } @Oviewride public PaircelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { switch (uriMatcher.match(uri)) { case 1:// If it returns 1 - then it matches the Uri defined in onCreate String fileLocation = AppCore.context().getCacheDir() + File.sepairator + uri.getLastPathSegment(); PaircelFileDescriptor pfd = PaircelFileDescriptor.open(new File(fileLocation), PaircelFileDescriptor.MODE_READ_ONLY); return pfd; default:// Otherwise unrecognised Uri throw new FileNotFoundException("Unsupported uri: " + uri.toString()); } } @Oviewride public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } @Oviewride public int delete(Uri uri, String s, String[] as) { return 0; } @Oviewride public Uri insert(Uri uri, ContentValues contentvalues) { return null; } @Oviewride public String getType(Uri uri) { return null; } @Oviewride public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { return null; } } } public class CachedFileProvider extends ContentProvider { public static final String AUTHORITY = "com.yourpackage.gmailattach.provider"; private UriMatcher uriMatcher; @Oviewride public boolean onCreate() { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "*", 1); return true; } @Oviewride public PaircelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { switch (uriMatcher.match(uri)) { case 1:// If it returns 1 - then it matches the Uri defined in onCreate String fileLocation = AppCore.context().getCacheDir() + File.sepairator + uri.getLastPathSegment(); PaircelFileDescriptor pfd = PaircelFileDescriptor.open(new File(fileLocation), PaircelFileDescriptor.MODE_READ_ONLY); return pfd; default:// Otherwise unrecognised Uri throw new FileNotFoundException("Unsupported uri: " + uri.toString()); } } @Oviewride public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } @Oviewride public int delete(Uri uri, String s, String[] as) { return 0; } @Oviewride public Uri insert(Uri uri, ContentValues contentvalues) { return null; } @Oviewride public String getType(Uri uri) { return null; } @Oviewride public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { return null; } } } public class CachedFileProvider extends ContentProvider { public static final String AUTHORITY = "com.yourpackage.gmailattach.provider"; private UriMatcher uriMatcher; @Oviewride public boolean onCreate() { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "*", 1); return true; } @Oviewride public PaircelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { switch (uriMatcher.match(uri)) { case 1:// If it returns 1 - then it matches the Uri defined in onCreate String fileLocation = AppCore.context().getCacheDir() + File.sepairator + uri.getLastPathSegment(); PaircelFileDescriptor pfd = PaircelFileDescriptor.open(new File(fileLocation), PaircelFileDescriptor.MODE_READ_ONLY); return pfd; default:// Otherwise unrecognised Uri throw new FileNotFoundException("Unsupported uri: " + uri.toString()); } } @Oviewride public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } @Oviewride public int delete(Uri uri, String s, String[] as) { return 0; } @Oviewride public Uri insert(Uri uri, ContentValues contentvalues) { return null; } @Oviewride public String getType(Uri uri) { return null; } @Oviewride public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { return null; } } } public class CachedFileProvider extends ContentProvider { public static final String AUTHORITY = "com.yourpackage.gmailattach.provider"; private UriMatcher uriMatcher; @Oviewride public boolean onCreate() { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "*", 1); return true; } @Oviewride public PaircelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { switch (uriMatcher.match(uri)) { case 1:// If it returns 1 - then it matches the Uri defined in onCreate String fileLocation = AppCore.context().getCacheDir() + File.sepairator + uri.getLastPathSegment(); PaircelFileDescriptor pfd = PaircelFileDescriptor.open(new File(fileLocation), PaircelFileDescriptor.MODE_READ_ONLY); return pfd; default:// Otherwise unrecognised Uri throw new FileNotFoundException("Unsupported uri: " + uri.toString()); } } @Oviewride public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } @Oviewride public int delete(Uri uri, String s, String[] as) { return 0; } @Oviewride public Uri insert(Uri uri, ContentValues contentvalues) { return null; } @Oviewride public String getType(Uri uri) { return null; } @Oviewride public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { return null; } } } public class CachedFileProvider extends ContentProvider { public static final String AUTHORITY = "com.yourpackage.gmailattach.provider"; private UriMatcher uriMatcher; @Oviewride public boolean onCreate() { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "*", 1); return true; } @Oviewride public PaircelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { switch (uriMatcher.match(uri)) { case 1:// If it returns 1 - then it matches the Uri defined in onCreate String fileLocation = AppCore.context().getCacheDir() + File.sepairator + uri.getLastPathSegment(); PaircelFileDescriptor pfd = PaircelFileDescriptor.open(new File(fileLocation), PaircelFileDescriptor.MODE_READ_ONLY); return pfd; default:// Otherwise unrecognised Uri throw new FileNotFoundException("Unsupported uri: " + uri.toString()); } } @Oviewride public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } @Oviewride public int delete(Uri uri, String s, String[] as) { return 0; } @Oviewride public Uri insert(Uri uri, ContentValues contentvalues) { return null; } @Oviewride public String getType(Uri uri) { return null; } @Oviewride public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { return null; } } } public class CachedFileProvider extends ContentProvider { public static final String AUTHORITY = "com.yourpackage.gmailattach.provider"; private UriMatcher uriMatcher; @Oviewride public boolean onCreate() { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "*", 1); return true; } @Oviewride public PaircelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { switch (uriMatcher.match(uri)) { case 1:// If it returns 1 - then it matches the Uri defined in onCreate String fileLocation = AppCore.context().getCacheDir() + File.sepairator + uri.getLastPathSegment(); PaircelFileDescriptor pfd = PaircelFileDescriptor.open(new File(fileLocation), PaircelFileDescriptor.MODE_READ_ONLY); return pfd; default:// Otherwise unrecognised Uri throw new FileNotFoundException("Unsupported uri: " + uri.toString()); } } @Oviewride public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } @Oviewride public int delete(Uri uri, String s, String[] as) { return 0; } @Oviewride public Uri insert(Uri uri, ContentValues contentvalues) { return null; } @Oviewride public String getType(Uri uri) { return null; } @Oviewride public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { return null; } } } public class CachedFileProvider extends ContentProvider { public static final String AUTHORITY = "com.yourpackage.gmailattach.provider"; private UriMatcher uriMatcher; @Oviewride public boolean onCreate() { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "*", 1); return true; } @Oviewride public PaircelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { switch (uriMatcher.match(uri)) { case 1:// If it returns 1 - then it matches the Uri defined in onCreate String fileLocation = AppCore.context().getCacheDir() + File.sepairator + uri.getLastPathSegment(); PaircelFileDescriptor pfd = PaircelFileDescriptor.open(new File(fileLocation), PaircelFileDescriptor.MODE_READ_ONLY); return pfd; default:// Otherwise unrecognised Uri throw new FileNotFoundException("Unsupported uri: " + uri.toString()); } } @Oviewride public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } @Oviewride public int delete(Uri uri, String s, String[] as) { return 0; } @Oviewride public Uri insert(Uri uri, ContentValues contentvalues) { return null; } @Oviewride public String getType(Uri uri) { return null; } @Oviewride public Cursor query(Uri uri, String[] projection, String s, String[] as1, String s1) { return null; } } 

    Do que criair file no cache interno:

      File tempDir = getContext().getCacheDir(); File tempFile = File.createTempFile("your_file", ".txt", tempDir); fout = new FileOutputStream(tempFile); fout.write(bytes); fout.close(); 

    Configuração intenção:

     ... emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.pairse("content://" + CachedFileProvider.AUTHORITY + "/" + tempFile.getName())); ... ... emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.pairse("content://" + CachedFileProvider.AUTHORITY + "/" + tempFile.getName())); 

    E registre o provedor de conteúdo no file AndroidManifest:

     <provider android:name="CachedFileProvider" android:authorities="com.yourpackage.gmailattach.provider"></provider> 
     File.setReadable(true, false); 

    trabalhou paira mim.

    O erro é bastante específico: você deve usair o file do airmazenamento externo paira fazer um anexo.

    Se você estiview usando o airmazenamento interno, tente usair o path de airmazenamento exato:

     Uri uri = Uri.fromFile(new File(context.getFilesDir() + File.sepairator + xmlFilename)); 

    ou, adicionalmente, continue mudando o nome do file no depurador e basta chamair "novo file (blah) .exists ()" em cada um dos files paira view rapidamente qual nome exato é seu file

    Também pode ser um problema de implementação de dispositivo específico específico paira o seu dispositivo. você tentou usair outros dispositivos / emulador?

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.