2011/03/20

Gmailの送信済みメール取得とメーラ一覧の起動

Gmailの送信済みメールを再送信するAndroidアプリの作成を始めて約10日。
やりたい事が出来る目処がついたので、ここまでの道程とソースを公開。
アプリとしては、
・Android標準のGmailにContentProviderで繋げて、データを取得。
・Intentでメーラを起動して、取得したデータを渡す。
これだけ。


まず、「Gmail.java」と関連する「Lists.java」、「Maps.java」、「Sets.java」、「Regex.java」、「BaseColumns.java」、「Uri.java」をここからダウンロードしてアプリケーションのプロジェクトにインポート。
※このファイルたちを探すのに苦労した、、、最新のAndroidソースには含まれていないようだ。

次に、ここを参考にすれば簡単に受信メールを取得できるようになった。(実機でないと動作しないので注意)
だが、送信済みメールを取得する方法が分からず途方にくれる、、、gmail.javaのコード読んでqueryに「label:<label>」をセットすればラベルのついたメールを抽出できそうな事に気付く。

Intentでメーラを起動の方は、ここを参考にすれば直ぐ出来た。

で、出来たコードが下記。

今後の課題、
・Gmailアカウントを設定出来るようにする。
・見た目の改善。
・UIの改善

ソース
package net.taku1974.GmailResender;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.ContentObserver;
import android.os.Handler;
import android.provider.Gmail;
import android.provider.Gmail.BecomeActiveNetworkCursor;
import android.provider.Gmail.ConversationCursor;
import android.provider.Gmail.LabelMap;
import android.provider.Gmail.MessageCursor;


public class GmailResenderActivity extends Activity {
 
 private static String account = "hoge.android.test@gmail.com"; // GMailアカウント
 private static String LOGTAG = "GmailResenderLog";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // Gmailからメッセージ取得
        ContentResolver contentResolver = this.getContentResolver();
        Gmail gmail = new Gmail(contentResolver); // Gmailクラス生成
        ContentObserver gmailObserver = new ContentObserver(new Handler()){}; // Gmail用コンテンツオブザーバ生成
        contentResolver.registerContentObserver(Gmail.BASE_URI, true, gmailObserver); // Gmail用コンテンツオブザーバを登録
     LabelMap lm = gmail.getLabelMap(account);  // ラベルマップ取得
     long labelId=lm.getLabelIdSent();    // 送信済みラベルID
     String query = "label:"+lm.getName(labelId); // ラベル:送信済みを抽出
        Log.d(LOGTAG, "DBG:" + query);
        ConversationCursor cc =  gmail.getConversationCursorForQuery(account, query, BecomeActiveNetworkCursor.YES); // 送信済みラベルを含む会話を取得
        ArrayAdapter adapterM = new ArrayAdapter(this,android.R.layout.simple_list_item_1); // リストビュー用アダプタ
        for (int i=0; i<10; i++){ // とりあえず10件取得
         if (cc.next()){
          MessageCursor mc = gmail.getMessageCursorForConversationId(account, cc.getConversationId());
          while (mc.next()) {
           if(mc.getLabelIds().contains(labelId)){  // 送信済みラベルIDを含むなら
                  Log.d(LOGTAG, "DBG:"+ mc.getSubject());
             adapterM.add(new GmailMessage(mc.getToAddresses() , mc.getSubject(), mc.getBody())); // アダプタに追加
           }
          }
         }else{
          break;
         }
     }
        // メッセージ一覧
        final ListView listview = (ListView) findViewById(R.id.listViewMail); // リストビュー生成
        listview.setAdapter(adapterM);  // アダブターセット
        listview.setOnItemClickListener( // クリックリスナー登録
         new AdapterView.OnItemClickListener() {
          public void onItemClick(AdapterView parent,View view, int position, long id) {
           setSelectedMessage(parent, position);
           }
         }
        );
        listview.setOnItemLongClickListener( // ロングクリックリスナー登録
         new AdapterView.OnItemLongClickListener() {
             public boolean onItemLongClick(AdapterView parent,View view, int position, long id) {
              setResendMessage(parent, position);
              return false;
             }   
   }
        );
    }
    // メッセージ一覧からクリックしたときの処理
 protected void setSelectedMessage(AdapterView parent, int position) {
  GmailMessage gmess = (GmailMessage) parent.getAdapter().getItem(position);
  final TextView selecteditem = (TextView) findViewById(R.id.textViewBody);
  CharSequence csBody = Html.fromHtml(gmess.getBody()); // メール本文(HTML)をCharSequenceに変換
  selecteditem.setText("Body:" + "\n" + csBody);
 }
 
 // メッセージ一覧からロングクリックしたときの処理
 protected void setResendMessage(AdapterView parent, int position) {
  GmailMessage gmess = (GmailMessage) parent.getAdapter().getItem(position);
  // メーラー起動インテントの作成
  Intent mailIntent = new Intent(Intent.ACTION_SEND);
  mailIntent.putExtra(Intent.EXTRA_EMAIL, gmess.getTo()); // 宛先(To)
  // mailIntent.putExtra(Intent.EXTRA_CC, new String[] {"bbb@xxxx.co.jp", "bbb@xxxx.co.jp"});
  mailIntent.putExtra(Intent.EXTRA_SUBJECT, gmess.getSubject()); // 件名
  mailIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(gmess.getBody())); // 本文
  // mailIntent.setType("image/png"); // 添付ファイル
  // Uri attachments = Uri.parse("file://" + selectedImageFileName); //<-- 画像へのパス
  // mailIntent.putExtra(Intent.EXTRA_STREAM, attachments);
  mailIntent.setType("message/rfc822"); // 送信データタイプ
  try {
   // システムにインストールされているメーラーを起動
   startActivity(Intent.createChooser(mailIntent, getString(R.string.app_name)));
  } catch (ActivityNotFoundException e ) {
    Log.e(LOGTAG, e.getMessage());
    String errorMsg = String.format("%s\n(%s)", getString(R.string.app_name), e.getMessage());
    // アラートダイアログ 
    AlertDialog.Builder errorDialog = new AlertDialog.Builder(this);
    errorDialog.setTitle("GmailResenderErr");
    errorDialog.setMessage(errorMsg);
    errorDialog.setPositiveButton(R.string.button_close, new DialogInterface.OnClickListener() {
     public void onClick(DialogInterface dialog, int which) {
      // ダイアログを閉じるだけ
     }
    });
    errorDialog.show();
  }

 }


 private class GmailMessage {
  String[] strTo;
  String strSubject;
  String strBody;
  GmailMessage(String[] To, String Subject, String Body) {
   strTo = To;
   strSubject = Subject;
   strBody = Body;
  }
  public String toString() {
   return "TO:" + strTo[0] + "\n" + "Subject:" + strSubject;
  }
  public String[] getTo() {
   return strTo;
  }
  public String getSubject() {
   return strSubject;
  }
  public String getBody() {
   return strBody;
  }
 }
}
マニフェスト
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="net.taku1974.GmailResender"
      android:versionCode="1"
      android:versionName="1.0">


    <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
        <activity android:name=".GmailResenderActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
    <!-- GmailProviderアクセス -->
    <uses-permission android:name="com.google.android.providers.gmail.permission.READ_GMAIL" />
</manifest>

0 件のコメント:

コメントを投稿