2015-01-15 7 views
8

この質問は以前に投稿されましたが、私のためではなかった。ここをクリックしてください:Gmail 5.0 app fails with "Permission denied for the attachment" when it receives ACTION_SEND intent"添付ファイルのアクセスが拒否されました"(Gmail 5.0上)メールにファイルを添付しようとしています

テキストファイルにデータを構築し、テキストファイルをメールに添付して自動的に添付する必要があるアプリがあります。私はこれを接続するために多くの方法を試しました。それは明らかにGmail 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は空はいかもしれないがループの下に現在のファイルの行は、常に信頼性が高く、常に何かを添付する。

私は私はそれが原因NULLポインタのだlogcatをチェックするとき、それは添付しますが、Gmailは、その後クラッシュし、それを行うとき

Uri.parse() 

Uri.fromFile() 

を変更しようとしています。これは、Gmailがファイルへのアクセス権を持たず、したがってnullになるためです。

私も

getCacheDir() 

代わりの

getFilesDir() 

を使用してみたのだが、同じ結果を有します。

私はここで間違っていますが、どのように修正する必要がありますか?いくつかのサンプルコードはとなるでしょう。本当に便利なのはです。なぜなら私はAndroidの開発には新しく、何らかのプッシュなしでやる必要があることを説明することはおそらく助けに終わらないからです。

ありがとうございます。

答えて

6

申し訳ありません。休憩して戻って来た、それを考え出した。ここで

は、あなたが外部ストレージに書き込み/読み取り権限を持っているので、あなたのマニフェストにこれらの権限を追加する必要があり、それがどのように動作するかです:

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

次に、あなたのファイルは、アプリケーションの内部ストレージのディレクトリからコピーする必要がありますアプリの外部ディレクトリに移動します。私は内部ストレージを使用することをお勧めします。これが私がここでやっていることですので、SDカードを自分で見つけることができます。

ここでは、魔法を行うコードブロックを示します。ログは含まれていますが、忘れずに削除することもできます。

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

外部ストレージを使用して添付ファイルを保存することは、Android API 23とその新しいアクセス許可システム以降、悪い習慣になっています。実行時にWRITE_EXTERNAL_STORAGE権限をユーザーに要求しないと、失敗します。 –

1

同じ添付ファイルが拒否されました。マニフェストのパーミッションは何の効果もなく、API 23以降はそれ以上の効果はありません。最後に、以下のように解決しました。

実行時にパーミッションをチェックし、助成する第一の必要性、私は私のメインの活動でそれをやった:

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ディレクトリ内のファイルを作成します - 同じ拒否の問題)

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を送信する構成と、それは今

問題ありません
関連する問題