SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

MBaaSと連携するAndroidアプリを作る

MBaaSのクエリと集計処理を実装する

MBaaSと連携するAndroidアプリを作る 第5回

  • X ポスト
  • このエントリーをはてなブックマークに追加

クエリを組み立てる

 SumActivityは、MainActivityから呼びされる集計処理用アクティビティです。レイアウトファイルはactivity_sum.xmlです(1)

リスト8 SumActivity.java onCreateメソッドまで(抜粋)
public class SumActivity extends Activity {
    private TextView mTextFrom;
    private TextView mTextTo;
    private RadioGroup mRgSum;
    private List<SumLog> dataList = new ArrayList<SumLog>();
    private SumLogAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO 自動生成されたメソッド・スタブ
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sum);(1)

        mTextFrom = (TextView)findViewById(R.id.textViewFrom);
        mTextTo = (TextView) findViewById(R.id.textViewTo);
        mRgSum = (RadioGroup) findViewById(R.id.rgSum);
        ListView listView = (ListView) findViewById(R.id.listView1);
        adapter = new SumLogAdapter();
        listView.setAdapter(adapter);(a)

        Calendar calendar = Calendar.getInstance();(2)
        final int year = calendar.get(Calendar.YEAR);
        final int month = calendar.get(Calendar.MONTH);
        final int day = calendar.get(Calendar.DAY_OF_MONTH);

        // 開始日付を選択
        Button btnFrom = (Button) findViewById(R.id.buttonFrom);
        btnFrom.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // DatePickerDialogを表示
                DatePickerDialog datePickerDialog = new DatePickerDialog(
                    SumActivity.this,
                    new DatePickerDialog.OnDateSetListener() {
                        @Override
                        public void onDateSet(DatePicker picker, int year, int month, int day) {
                            mTextFrom.setText(String.format("%04d",year) + "-" + (3)
                                    String.format("%02d",month + 1) + "-" +
                                    String.format("%02d",day));
                        }
                    },
                    year,
                    month,
                    day);
                datePickerDialog.show();

            }
        });

 onCreateメソッドでは、それぞれのボタンが押されたときの処理を指定しています。ざっと、みていきましょう。Calendar.getInstance()でCalendarオブジェクトを取得します(2)。Calendarオブジェクトには現在の日時が入っていますので、年、月、日を取り出します。

 開始日付を選択のボタンが押されたら、DatePickerDialogを生成します。引数はcontext、callBack、year(年の初期値)、monthOfYear(月の初期値)、dayOfMonth(日の初期値)です。callBackには、OnDateSetListenerを指定します。ダイアログ上の設定ボタンを押したときにonDateSetメソッドが呼び出されます。onDateSetメソッドでは、年を4桁、月を2桁、日を2桁に0埋めし、ハイフンで接続します(3)

 終了日付の選択処理も同様です。

リスト9 SumActivity.java onCreateメソッドまで(抜粋)
// 終了日付を選択
Button btnTo = (Button) findViewById(R.id.buttonTo);
btnTo.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // DatePickerDialogを表示
        DatePickerDialog datePickerDialog = new DatePickerDialog(
            SumActivity.this,
            new DatePickerDialog.OnDateSetListener() {
                @Override
                public void onDateSet(DatePicker picker, int year, int month, int day) {
                    mTextTo.setText(String.format("%04d",year) + "-" +
                            String.format("%02d",month + 1) + "-" +
                            String.format("%02d",day));
                }
            },
            year,
            month,
            day);
        datePickerDialog.show();

    }
});

 集計実行ボタンが押された場合の処理をみていきましょう(4)

リスト10 SumActivity.java onCreateメソッドまで(抜粋)
Button btnSum = (Button) findViewById(R.id.buttonSum);
btnSum.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {(4)
        dataList.clear();

        int id = mRgSum.getCheckedRadioButtonId();(5)

        // LogClassの読み込み
        NCMBQuery<NCMBObject> query = NCMBQuery.getQuery("LogClass");(6)
        query.orderByAscending("task");
        if (id == R.id.rbMeOnly) {(7)
            //自分だけ
            NCMBUser currentUser = NCMBUser.getCurrentUser();
            query.whereEqualTo("UserName", currentUser.getUsername());
        }

 RadioGroupオブジェクトのmRgSumのgetCheckedRadioButtonIdメソッドで、チェックされているRadioButtonを取得します(5)

 NCMBQuery.getQueryメソッドでLogClassに対するクエリを作成します(6)。query.orderByAscendingでtaskフィールドの昇順に並び替えます。

 逆に降順で並び替えたいときはorderByDescendingを指定します。複数の並び替え条件を指定したいときは、addAscendingOrderやaddDescendingOrderを使います。

1つのフィールドで並び替えるとき
昇順で並び替え orderByAscending("フィールド名")
降順で並び替え orderByDescending("フィールド名")
並び替えるフィールドを追加したいとき
昇順の条件追加 addAscendingOrder("フィールド名")
降順の条件追加 addDescendingOrder("フィールド名")

 チェックされているRadioButtonのIDが自分(R.id.rbMeOnly)のときは(7)、ログインしているユーザーを取得し、ユーザー名をクエリのwhereEqualTo条件に指定しています。whereEqualToは指定した値と等しいフィールド値を持つレコードを抽出する条件です。

 さて、その次の日付の処理には注意が必要です。

LogClass
LogClass

 LogClassのstartTimeフィールドなどをみるとわかるようにNCMBのデータストアオブジェクトの日付はyyyy-mm-ddTHH:MM:ss.SSSZ形式(SSSはミリ秒、Zはタイムゾーン)のUTC(世界協定時)の日付です。タイムゾーンはUTC以外を設定することはできません。ですから、日本時間とは9時間ずれています。

リスト11 SumActivity.java onCreateメソッドまで(抜粋)
// 開始日付が入力されていたら
if (mTextFrom.getText().length() > 9) {
    String strFrDate = mTextFrom.getText().toString();(8)
    String strFrTime = "T00:00:00.000";
    Date fromDate = cvtStringToDate(strFrDate + strFrTime);
    query.whereGreaterThanOrEqualTo("startTime", fromDate);(9)
}

 開始日付が入力されている場合は、TextViewから日付を取得します(8)。先ほど説明したようにTextViewの日付はyyyy-mm-ddという形式になっています。これにTをはさんで、開始時間ですから、00:00:00.000を連結して、cvtStringToDate関数に渡します。

リスト12 cvtStringToDate関数
static public final String DATE_PATTERN ="yyyy-MM-dd'T'HH:mm:ss";

// String型のオブジェクトをDate型に変換します.
public Date cvtStringToDate(String strDate) {
    try {
    return (new SimpleDateFormat(DATE_PATTERN,Locale.JAPAN)).parse(strDate);
    } catch (ParseException e) {
    return null;
    }
}

 cvtStringToDateは、SimpleDateFormat関数にDATE_PATTERNとロケールにJAPANを指定して、引数として渡した日付文字列を日付に変換します。

 この日付をstartTimeにwhereGreaterThanOrEqualTo条件で指定します(9)

 以下の表のように、whereGreaterThanOrEqualToは大きいか、等しいなので「以上」を意味します。

検索条件
等しい whereEqualTo("フィールド名",値)
等しくない whereNotEqualTo("フィールド名",値)
小さい whereLessThan("フィールド名",値)
以下 whereLessThanOrEqualTo("フィールド名",値)
大きい whereGreaterThan("フィールド名",値)
以上 whereGreaterThanOrEqualTo("フィールド名",値)

 終了日付が入力されている場合は、その逆です。

リスト13 SumActivity.java onCreateメソッドまで(抜粋)
// 終了日付が入力されていたら
if (mTextTo.getText().length() > 9) {
    String strToDate = mTextTo.getText().toString();
    String strToTime = "T23:59:59.999";(10)
    Date toDate = cvtStringToDate(strToDate + strToTime);
    query.whereLessThanOrEqualTo("startTime", toDate);(11)
}

 一日の終わりの時間を文字列として指定して(10)、TextViewの日付文字列に連結して日付に変換します。そして、whereLessThanOrEqualTo(以下)条件に指定します(11)

 検索条件が整ったら、findInBackgroundメソッドで非同期にレコードを取得します(12)

リスト14 SumActivity.java onCreateメソッドまで(抜粋)
query.findInBackground(new FindCallback<NCMBObject>() {(12)
    @Override
    public void done(List<NCMBObject> result, NCMBException e){
        String new_key="";
        String old_key="";
        int sumTime =0;
        for (int i =0 ,n = result.size(); i < n; i++ ) {
            NCMBObject logdata = result.get(i);(13)
            // ObjectIdだけなら以下でも取れる
            NCMBObject task = logdata.getNCMBObject("task");
            new_key=task.getObjectId();(14)
            if (i==0) {
                old_key = new_key;
            }

            if (!new_key.equals(old_key)) {
                getTaskName(old_key,sumTime);(15)

                old_key = new_key;
                sumTime=0;
            }
            sumTime += logdata.getInt("elapsedTime");
        }
        getTaskName(old_key,sumTime);(16)

    }

});

 条件に合うレコードが取得できたら、doneメソッドが呼び出されます。

 取得したレコードはNCMBObject型のListであるresultに格納されていますので、result.get(i)で一つずつ取り出して(13)、キーブレイク処理で経過時間(elapsedTime)を集計します。

 キーに指定しているのは関連オブジェクトtaskのObjectIdです。通常、関連オブジェクトのフィールド値はfetchIfNeededInBackgroundメソッドなどで別途取得する必要があるのですが、ObjectIdはtask.getObjectId()のように取得することができます(14)

 キーが割れたら、getTaskNameメソッドを呼び出すだけでなく、最後のレコードを処理した後でもgetTaskNameメソッドを呼び出します(15)(16)

次のページ
ListViewで表示する

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
MBaaSと連携するAndroidアプリを作る連載記事一覧

もっと読む

この記事の著者

金宏 和實(カネヒロ カズミ)

 富山県高岡市出身で在住。ソフトウェア開発者兼ライター。株式会社イーザー関西学院大学文学部仏文科卒。第一種情報処理技術者(今で言うと、応用情報技術者。第一種→ソフ開→応用と変遷したようだ)主な著書『作ればわかる!Androidプログラミング第2版 -SDK4対応-』『VS 2010で作る Web-DB アプリ入門』『ベテランが丁寧に教えてくれるデータベースの知識と実務』『はじめてのAndroidアプリ作成 センサー活用とクラウド連携』『はじめてのAndroidアプリ作成 基本プログラミング』Web連載『VB2008で楽々Webプログラミング』『再発見!VB2005快適プログラミング』 『こうしろうのMindStroms日記』 個人的なブログはこちらです。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/8217 2014/10/28 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング