[Android] クリックしたタイムスタンプを保存して、メールで送信する ================================================================================ ちょっと必要があって、標記のアプリを作った。 メールの送信先のアドレスも固定(リソースで定義)。 タイムスタンプは long 型なので、それらの値を List<Long> で保持したいところ。でも、 onSaveInstanceState()、onRestoreInstanceState() でインスタンス間の受け渡しを行う にしても、残念ながら Bundle クラスには、putLongArrayList() というメソッドはない。 しょうがないので、long 型のタイムスタンプを上位 4 バイトと下位 4 バイトに分けて、 上位 4 バイトは long 型、下位 4 バイトは int 型のリスト(正確には Integer 型のリ スト)に保存することにした。そうすることで、putIntegerArrayList() メソッドが使え る。 しかし、putLongArrayList() がないのは、int が整数の標準の型なのでしょうがないと して、putIntegerArray() がないというのは、納得がいかない気がする。というよりも、 putIntegerCollection() というのがあってもよさそうだと思う。 ■ アクティビティ □ TimestampLoggerActivity.java --- package jp.marunomaruno.android.timestamplogger; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.TextView; /** * クリックしたタイムスタンプを保存して、メールで送信する。 * メールの送信先のアドレスも固定。 * * @author marunomaruno * @version 1.0, 2012-06-20 */ public class TimestampLoggerActivity extends Activity { private static final String TEMP_FILE_NAME = "data.dat"; private static final long TIMESTAMP_HEIGHT_BYTES_MASK = 0xFFFFFFFF00000000L; // long型の上位4バイトを取得するマスク // (1) private static final String TIMESTAMP_LIST = "timestampList"; private static final String TIMESTAMP_HEIGHT_BYTES = "timestampHightBytes"; private ArrayList<Integer> timestampList; // タイムスタンプの下位4バイト分のリスト // (2) private long timestampHightBytes = 0; // タイムスタンプの上位4バイト // (3) /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); timestampList = new ArrayList<Integer>(); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); timestampHightBytes = savedInstanceState .getLong(TIMESTAMP_HEIGHT_BYTES); timestampList = savedInstanceState.getIntegerArrayList(TIMESTAMP_LIST); System.out.println("onRestoreInstanceState: " + timestampList); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putLong(TIMESTAMP_HEIGHT_BYTES, timestampHightBytes); outState.putIntegerArrayList(TIMESTAMP_LIST, timestampList); System.out.println("onSaveInstanceState: " + timestampList); } @Override protected void onPause() { super.onPause(); try { write(); } catch (IOException e) { e.printStackTrace(); } System.out.println("onPause: " + timestampList); } @Override protected void onRestart() { super.onRestart(); try { read(); } catch (FileNotFoundException e) { assert true; } catch (IOException e) { e.printStackTrace(); } System.out.println("onRestart: " + timestampList); } /** * タイムスタンプを取得するボタンのクリック・ハンドラー * * @param view */ public void onStampButtonClick(View view) { // リストの最初のタイムスタンプの上位4バイトを保持する if (timestampHightBytes == 0) { timestampHightBytes = System.currentTimeMillis() & TIMESTAMP_HEIGHT_BYTES_MASK; // (4) } // タイムスタンプの下位4バイトをリストに追加する timestampList.add((int) System.currentTimeMillis()); // (5) TextView stampView = (TextView) findViewById(R.id.stampView); stampView.setText(toTimestampStrings()); } /** * タイムスタンプのリストをクリアするボタンのクリック・ハンドラー * * @param view */ public void onClearButtonClick(View view) { timestampList.clear(); TextView stampView = (TextView) findViewById(R.id.stampView); stampView.setText(""); } /** * タイムスタンプを送信するボタンのクリック・ハンドラー * * @param view */ public void onEmailButtonClick(View view) { if (timestampList.size() == 0) { TextView stampView = (TextView) findViewById(R.id.stampView); stampView.setText(R.string.noTimestamp); return; } Uri uri = Uri.parse("mailto:" + getString(R.string.emailAddress)); // (6) Intent intent = new Intent(Intent.ACTION_SENDTO, uri); // (7) intent.putExtra(Intent.EXTRA_SUBJECT, String.format( "timestamp %1$tF %1$tT", (timestampHightBytes | timestampList.get(0)))); // (8) intent.putExtra(Intent.EXTRA_TEXT, toTimestampStrings()); // (9) startActivity(intent); // (10) } /** * タイムスタンプのリストを文字列化する。 * タイムスタンプは、JISの日時の文字列(yyyy-mm-dd hh:mm:ss)であらわし、 * これをリストとして並べたもの。 * * @return タイムスタンプのリストの文字列 */ private String toTimestampStrings() { StringBuilder sb = new StringBuilder(); for (int timestamp : timestampList) { sb.append(String.format("[%1$tF %1$tT]%n", (timestampHightBytes | timestamp))); } return sb.toString(); } /** * データをファイルに一時保存のため書き出す。 * * @throws IOException */ public void write() throws IOException { DataOutputStream out = new DataOutputStream(openFileOutput(TEMP_FILE_NAME, MODE_PRIVATE)); out.writeLong(timestampHightBytes); for (int timestamp : timestampList) { out.writeInt(timestamp); } out.close(); } /** * 一時保存されたデータをファイルから読み出す。 * * @throws IOException */ public void read() throws IOException { DataInputStream in = new DataInputStream(openFileInput(TEMP_FILE_NAME)); timestampList.clear(); try { timestampHightBytes = in.readLong(); while (true) { timestampList.add(in.readInt()); } } catch (EOFException e) { // (10) assert true; } in.close(); } } --- (1) long型の上位4バイトを取得するマスク long 型のタイムスタンプを上位 4 バイトと下位 4 バイトに分けるためのマスク。 private static final long TIMESTAMP_HEIGHT_BYTES_MASK = 0xFFFFFFFF00000000L; // (1) (2) タイムスタンプの下位4バイト分のリスト private ArrayList<Integer> timestampList; // (2) (3) タイムスタンプの上位4バイト private long timestampHightBytes = 0; // (3) (4) リストの最初のタイムスタンプの上位 4 バイトを保持する TIMESTAMP_HEIGHT_BYTES_MASK と AND を取ることで、上位 4 バイト分を確保する。 timestampHightBytes = System.currentTimeMillis() & TIMESTAMP_HEIGHT_BYTES_MASK; // (4) (5) タイムスタンプの下位4バイトをリストに追加する 下位 4 バイトは、int 型にキャストすればよい。 timestampList.add((int) System.currentTimeMillis()); // (5) (6)-(10) タイムスタンプをメールで送信する メールのあて先アドレスを Uri インスタンスとして組み立てる。 Uri uri = Uri.parse("mailto:" + getString(R.string.emailAddress)); // (6) メールを送るためのインテント・インスタンスを生成する Intent intent = new Intent(Intent.ACTION_SENDTO, uri); // (7) メールの件名を設定する。このとき、件名に最初のタイムスタンプを入れるので、タイム スタンプを組み立ても行う。 上位 4 バイトと下位 4 バイトに分かれているものを、OR することで、ふたたび long 型にする。 intent.putExtra(Intent.EXTRA_SUBJECT, String.format( "timestamp %1$tF %1$tT", (timestampHightBytes | timestampList.get(0)))); // (8) 本文に、タイムスタンプを文字列化して並べる。 intent.putExtra(Intent.EXTRA_TEXT, toTimestampStrings()); // (9) メール送信のアクティビティを起動する。 startActivity(intent); // (10) (11) EOF の検知 DataInputStream の readInt() メソッドを使っているので、EOF は EOFException を使 って検知する。 } catch (EOFException e) { // (11) ■ レイアウト タイムスタンプの表示は、今回のわたしの使い方としては、せいぜい 10 件程度なので、 ListView などを使わずに、単純に TextView を使っている。 □ res/values/strings.xml --- <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/stamp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onStampButtonClick" android:text="@string/stampButtonLabel" android:textAppearance="?android:attr/textAppearanceLarge" /> <Button android:id="@+id/clear" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClearButtonClick" android:text="@string/clearButtonLabel" android:textAppearance="?android:attr/textAppearanceLarge" /> <Button android:id="@+id/email" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onEmailButtonClick" android:text="@string/emailButtonLabel" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout> <TextView android:id="@+id/stampView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" /> </LinearLayout> --- ■ リソース 【emailアドレス】部分に、タイムスタンプを送信したいあて先を指定する。 □ res/values/strings.xml --- <?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, TimestampLoggerActivity!</string> <string name="app_name">TimestampLogger</string> <string name="stampButtonLabel">クリック</string> <string name="clearButtonLabel">クリア</string> <string name="emailButtonLabel">email</string> <string name="noTimestamp">タイムスタンプがありません。メール送信はしません。</string> <string name="emailAddress">【emailアドレス】</string> </resources> --- 以上
最新の画像[もっと見る]
- あけましておめでとうございます 11年前
- 今年もよろしくお願いいたします 12年前
- あけましておめでとうございます 13年前
- あけましておめでとうございます 16年前
※コメント投稿者のブログIDはブログ作成者のみに通知されます