○まずはIntentを試してみるか
自分で作ってるAndroidアプリのバージョンアップとして、
検索した画像と情報をメールに添付しようと考えた。
これが地味にハマってしまったので、自分と誰かしらのために、メモしておく。
文章は割と楽に送れた。
実装はこんな感じ。
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
// TOアドレス
intent.setData(Uri.parse("mailto:hoge@hage.com"));
// 宛先を指定
intent.putExtra(Intent.EXTRA_EMAIL, "FROM");
// CCを指定
intent.putExtra(Intent.EXTRA_CC, "CC");
// BCCを指定
intent.putExtra(Intent.EXTRA_BCC, "bcc");
// 件名を指定
intent.putExtra(Intent.EXTRA_SUBJECT, "件名");
// 本文を指定
intent.putExtra(Intent.EXTRA_TEXT, "本文");
// 画像を添付
intent.setType("image/jpeg");
File file = this.getFilesDir();
intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("ファイルの絶対パス"));
try {
startActivityForResult(intent, 0);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(this, "client not found", Toast.LENGTH_LONG).show();
}
intent.startActivity(Intent.createChooser(intent, null))を使って、アプリケーションを選ばせるのも手。
○画像の添付はどうやるの?
ただ、画像がなかなかうまくいかない。
出来るなら、端末に画像を保存せずに添付できないものかと思ったけど、
どうやら出来ないらしい。
ファイルとして保存したデータしか引数として渡せないようだ。
一度Bitmapデータを保存する必要がある。
ということでBitmapの保存処理。
実装はこんな感じ。
/** * ImageViewをファイルとして格納する。 * */ public void savePicture(ImageView view, String fileName) throws IOException { // ImageViewをビットマップにキャスト BitmapDrawable bd = (BitmapDrawable) view.getDrawable(); // getBitmapメソッドでビットマップファイルを取り出す。 Bitmap data = bd.getBitmap(); FileOutputStream output = openFileOutput(fileName, Context.MODE_WORLD_READABLE); data.compress(Bitmap.CompressFormat.PNG, 100, output); }
保存はどうやらうまく出来たようだ。DDMSで見ても確かにファイルは存在している。
エミュレータでは画像添付成功。
意気揚々と自分の端末でも確認してみる。
が、しかし画像添付に失敗する。なんでよ。
○画像の添付はSDから?
色々、ネットで調べあさった結果、
画像データをSDカードに保存しないと添付できない仕様らしい(おそらく権限の問題?)
ということで、今度はパスを変えてSDの保存しよう。
/**
*
* 画像を端末のsdに保存します。<br>
* @param fileName String
* @param view ImageView
* @param context Context
*/
public void savePicture(String fileName, ImageView view, Context context) throws IOException {
// ImageViewをビットマップにキャスト
BitmapDrawable bd = (BitmapDrawable) view.getDrawable();
// getBitmapメソッドでビットマップファイルを取り出す。
Bitmap data = bd.getBitmap();
// 画像データがなかったらnullを返す
if (data == null) {
return null;
}
// SDカードのパス取得
File root = Environment.getExternalStorageDirectory();
FileOutputStream out = null;
// 画像をバイト配列に変換する
ByteArrayOutputStream os = new ByteArrayOutputStream();
data.compress(CompressFormat.JPEG, 100, os);
os.flush();
byte[] w = os.toByteArray();
os.close();
// バイト配列をファイルとしてSDカードに書き出す
out = new FileOutputStream(root + File.separator + "AppName" + File.separator + fileName);
out.write(w, 0, w.length);
out.flush();
}
しかし、例外発生。なんでなんで?
○SDのパスって端末依存なの?
しばらく悩む
またしても、色々調べた結果、端末によってはSDパスの取得の仕方が違うらしい。
実装で、SDのパスの分岐をする。
こんな感じ。
public void savePicture(String fileName, ImageView view, Context context) throws IOException {
// (略)
// 端末メーカによってパスが異なることがあるらしい
File standard = Environment.getExternalStorageDirectory();
File sd = new File(standard, "sd");
File ext = new File(standard, "external_sd");
String fileFullPath = "";
if (sd.exists() && sd.isDirectory()) {
fileFullPath = sd + File.separator + "AppName" + File.separator + fileName;
} else if (ext.exists() && ext.isDirectory()) {
fileFullPath = ext + File.separator + "AppName" + File.separator + fileName;
} else {
fileFullPath = standard + File.separator + "AppName" + File.separator + fileName;
}
// (略)
}
でもできない。。。なぜ。。。
○エミュレーターの設定?
なんか、エミュレータが怪しいぞ・・・。
eclipseから 「ウィンドウ>AVD Manager>編集」 で
「ハードウェア」のプロパティを確認したら、
「SD card support yes」になってない!アウチ!
あと、「SDカード」のところの「サイズ」も設定しないと駄目だからな!!!(自戒)
これで、余裕っしょ、フゥー♪
、と思いきや、まだ例外出るじゃないですか・・。
○肝心なこと忘れてました
あ、SD使用のパーミッションが無かった。。。。
マニフェストに記入
<!-- SDカード仕様許可 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
うし、パーミッションは取れたみたい。だけど例外が発生するなぁ。
あ、もしかして。。。。
○ディレクトリ作ってないじゃん
public void savePicture(String fileName, ImageView view, Context context) throws IOException {
// ImageViewをビットマップにキャスト
BitmapDrawable bd = (BitmapDrawable) view.getDrawable();
// getBitmapメソッドでビットマップファイルを取り出す。
Bitmap data = bd.getBitmap();
// 画像データがなかったらnullを返す
if (data == null) {
return null;
}
// 端末メーカによってパスが異なることがあるらしい
File standard = Environment.getExternalStorageDirectory();
File sd = new File(standard, "sd");
File ext = new File(standard, "external_sd");
String fileFullPath = "";
if (sd.exists() && sd.isDirectory()) {
fileFullPath = sd + File.separator + "TourPlus" + File.separator + fileName;
} else if (ext.exists() && ext.isDirectory()) {
fileFullPath = ext + File.separator + "TourPlus" + File.separator + fileName;
} else {
fileFullPath = standard + File.separator + "TourPlus" + File.separator + fileName;
}
// アプリ用にディレクトリを作る
new File(fileFullPath).getParentFile().mkdir();
FileOutputStream out = null;
// 画像をバイト配列に変換する
ByteArrayOutputStream os = new ByteArrayOutputStream();
data.compress(CompressFormat.JPEG, 100, os);
os.flush();
byte[] w = os.toByteArray();
os.close();
// バイト配列をファイルとしてSDカードに書き出す
out = new FileOutputStream(fileFullPath);
out.write(w, 0, w.length);
out.flush();
}
やっとこさ成功。
○まとめ
以上です。今後のために簡単なチェックシートを一応作った。
- マニフェストにパーミッションは設定しているか。
- DDMSで確認して画像は保存されているか
- SDのパスは正しいか
- エミュレータは正しく設定されているか
- 保存先の絶対パスは存在するディレクトリか
- Intentの起動メソッドは適格か
※なお、基本的にI/Oというかストリーム的なものを使うときは、当然finallyでclose処理しないと駄目です。
このエントリではソースを簡潔にするため、はしょっています(言い訳)



0 件のコメント:
コメントを投稿