com.kyakujin.android.autoeco.ui.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.kyakujin.android.autoeco.ui.MainActivity.java

Source

/*
 * Copyright 2013 Yoshihiro Miyama
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.kyakujin.android.autoeco.ui;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.TimePickerDialog;
import android.content.ComponentName;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.text.Html;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import com.google.ads.AdRequest;
import com.google.ads.AdSize;
import com.google.ads.AdView;
import com.kyakujin.android.autoeco.BuildConfig;
import com.kyakujin.android.autoeco.Conf;
import com.kyakujin.android.autoeco.Conf.EcoExecFrom;
import com.kyakujin.android.autoeco.Conf.EcoExecSwitch;
import com.kyakujin.android.autoeco.Logger;
import com.kyakujin.android.autoeco.R;
import com.kyakujin.android.autoeco.db.AutoEcoContract.BatteryQuery;
import com.kyakujin.android.autoeco.db.AutoEcoContract.BatteryTbl;
import com.kyakujin.android.autoeco.db.AutoEcoContract.ManualQuery;
import com.kyakujin.android.autoeco.db.AutoEcoContract.ManualTbl;
import com.kyakujin.android.autoeco.db.AutoEcoContract.SchedQuery;
import com.kyakujin.android.autoeco.db.AutoEcoContract.SchedTbl;
import com.kyakujin.android.autoeco.db.dao.SchedDAO;
import com.kyakujin.android.autoeco.db.dao.SchedModel;
import com.kyakujin.android.autoeco.eco.EcoThread;
import com.kyakujin.android.autoeco.service.BatteryService;
import com.kyakujin.android.autoeco.service.SchedAlarmManager;

/**
 * ???<br>
 * ?????DB????UI???
 */
public class MainActivity extends FragmentActivity
        implements OnClickListener, LoaderCallbacks<Cursor>, OnItemClickListener {

    private final String TAG = Conf.APP_NAME + ":" + this.getClass().getSimpleName();

    private Activity mActivity;
    private LinearLayout mBattery;
    private Button mAddSched;
    private LinearLayout mManual;
    private CustomTimePickerDialog timePickerDialog;
    private TimeData mTimeData;
    private Uri mCurrentSchedUri;
    private int mBatteryId;
    private LoaderManager mLoaderManager;
    private SchedListAdapter mSchedListAdapter;
    private ListView mSchedListView;
    private TextView mBatteryDisabled;
    private TextView mBatteryAccount;
    private LinearLayout mCurrentBattery;
    private TextView mCurrentBatteryLevel;
    private TextView mCurrentThreshold;
    private ImageButton mAbout;
    private int mSchedCount;
    private static final int MAX_SCHED = 5;

    public static boolean mIsForeground;
    // DBG
    private Button mStart;
    private Button mStop;
    private int mManualId;
    private AdView adView;

    // ????????View???????
    private class SetCurrentBatteryTask extends AsyncTask<Void, Void, Integer> {

        TextView mView;

        private SetCurrentBatteryTask(TextView view) {
            super();
            mView = view;
        }

        @Override
        protected Integer doInBackground(Void... params) {
            return BatteryService.getCurrentBatteryLevel();
        }

        @Override
        protected void onPostExecute(Integer result) {
            if (mView.isShown()) {
                String desc;
                if (result == 0) {
                    desc = getResources().getString(R.string.desc_measureing);
                } else {
                    desc = getResources().getString(R.string.desc_current_batterylevel) + result + "%";
                }
                mView.setText(desc);
            }

        }

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mActivity = this;

        mAbout = (ImageButton) findViewById(R.id.buttonAbout);
        mAbout.setOnClickListener(this);
        if (Build.VERSION.SDK_INT >= 13) {
            mAbout.setVisibility(View.VISIBLE);
        } else {
            mAbout.setVisibility(View.INVISIBLE);
        }

        mTimeData = TimeData.getInstance();
        mTimeData.setHour(0);
        mTimeData.setMinute(0);

        mBattery = (LinearLayout) findViewById(R.id.batteryRoot);
        mBattery.setOnClickListener(this);
        mAddSched = (Button) findViewById(R.id.btnAddSched);
        mAddSched.setOnClickListener(this);
        mManual = (LinearLayout) findViewById(R.id.manualRoot);
        mManual.setOnClickListener(this);

        mBatteryDisabled = (TextView) findViewById(R.id.textBatteryDisabledInFrame);
        mBatteryAccount = (TextView) findViewById(R.id.textSetThresholdInFrame);
        mCurrentBattery = (LinearLayout) findViewById(R.id.layoutCurrentBattery);
        mCurrentBatteryLevel = (TextView) findViewById(R.id.textCurrentLevelInFrame);
        mCurrentThreshold = (TextView) findViewById(R.id.textThresholdInFrame);

        mSchedListView = (ListView) findViewById(android.R.id.list);
        mSchedListView.setOnItemClickListener(this);

        mSchedListAdapter = new SchedListAdapter(this, R.layout.list_item_sched, null,
                new String[] { SchedTbl.HOUR_MINUTE_STRING, }, new int[] { R.id.textHourMinute, }, 0);

        mSchedListView.setAdapter(mSchedListAdapter);
        registerForContextMenu(mSchedListView);

        mIsForeground = true;
        Timer timer = new Timer(false);
        // ????????
        timer.schedule(new TimerTask() {

            public void run() {
                // ??????(Timer???UI?????)
                runOnUiThread(new Runnable() {
                    public void run() {
                        if (mIsForeground) {
                            Logger.d(TAG, "timertask.");
                            SetCurrentBatteryTask task = new SetCurrentBatteryTask(mCurrentBatteryLevel);
                            task.execute();
                        }

                    }
                });
            }
        }, 0, 3000);

        mLoaderManager = getSupportLoaderManager();
        mLoaderManager.restartLoader(SchedQuery.LOADER_ID, null, this);
        mLoaderManager.restartLoader(ManualQuery.LOADER_ID, null, this);
        mLoaderManager.restartLoader(BatteryQuery.LOADER_ID, null, this);

        addAD();
    }

    /**
     * AdView
     */
    private void addAD() {
        // for adView
        //
        adView = new AdView(this, AdSize.BANNER, Conf.MY_AD_UNIT_ID);

        LinearLayout layout = (LinearLayout) findViewById(R.id.admobspace);

        // adView? --- ???
        layout.addView(adView);

        // ???
        AdRequest adRequest = new AdRequest();
        if (BuildConfig.DEBUG) {
            // ??? - ?????
            // 
            adRequest.addTestDevice(AdRequest.TEST_EMULATOR);
            // Android
            // "XXXXXX...XX"????ID(??ID???????)
            adRequest.addTestDevice("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
            // ????
        }
        adView.loadAd(adRequest);
        // adView? --- ????

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        boolean ret = true;
        switch (item.getItemId()) {
        case R.id.menu_about:
            showAboutDialog();
            return ret;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // TODO ?????????????
        // aidl?????
        mIsForeground = true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        mIsForeground = false;
    }

    @Override
    protected void onStop() {
        super.onStop();
        mIsForeground = false;
    }

    public void setCurrentBattery() {
        if (mCurrentBattery.isShown()) {
            String desc;
            int level = BatteryService.getCurrentBatteryLevel();
            if (level == 0) {
                desc = getResources().getString(R.string.desc_measureing);
            } else {
                desc = getResources().getString(R.string.desc_current_batterylevel) + level + "%";
            }
            mCurrentBatteryLevel.setText(desc);
        }

    }

    @Override
    public void onClick(View v) {
        if (v == mBattery) {
            if (mBatteryId == 0) {
                mBatteryId = createBatteryData();
            }
            transitionToBatterySetting(mBatteryId);
        } else if (v == mAddSched) {
            if (mSchedCount >= MAX_SCHED) {
                Toast.makeText(mActivity,
                        getResources().getString(R.string.alert_max_sched_header) + MAX_SCHED
                                + getResources().getString(R.string.alert_max_sched_footer),
                        Toast.LENGTH_LONG).show();
                return;
            }
            setTime();
        } else if (v == mManual) {
            if (mManualId == 0) {
                mManualId = createManualData();
            }
            transitionToManualSetting(mManualId);
        } else if (v == mStart) {
            EcoThread thr = new EcoThread(this, EcoExecFrom.SCHED,
                    Integer.valueOf(mCurrentSchedUri.getLastPathSegment()), EcoExecSwitch.ECO_ON);
            thr.start();

        } else if (v == mStop) {
            EcoThread thr = new EcoThread(this, EcoExecFrom.SCHED,
                    Integer.valueOf(mCurrentSchedUri.getLastPathSegment()), EcoExecSwitch.ECO_OFF);
            thr.start();
        } else if (v == mAbout) {
            showAboutDialog();
        }
    }

    private int createBatteryData() {
        ContentValues cv = new ContentValues();
        cv.put(BatteryTbl.ENABLED, 1);
        cv.put(BatteryTbl.THRESHOLD, 30);
        Uri uri = getContentResolver().insert(BatteryTbl.CONTENT_URI, cv);
        if (uri == null)
            return 0;
        mBatteryId = Integer.valueOf(uri.getLastPathSegment());
        return mBatteryId;
    }

    private int createManualData() {
        ContentValues cv = new ContentValues();
        cv.put(ManualTbl.NAME, Conf.NONE);
        Uri uri = getContentResolver().insert(ManualTbl.CONTENT_URI, cv);
        if (uri == null)
            return 0;
        mManualId = Integer.valueOf(uri.getLastPathSegment());
        return mManualId;
    }

    private void setTime() {
        // CustomTimePickerDialog?????
        TimePickerDialog.OnTimeSetListener listener = new TimePickerDialog.OnTimeSetListener() {
            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                /** DO NOTHING */
            }
        };

        // ?????????????
        if (mCurrentSchedUri != null) {
            SchedDAO dao = new SchedDAO(mActivity);
            SchedModel model = new SchedModel();
            model = dao.readToSchedModelById(Integer.valueOf(mCurrentSchedUri.getLastPathSegment()));

            if (model != null) {
                mTimeData.setHour(model.getHour());
                mTimeData.setMinute(model.getMinute());
                Logger.d(TAG, "get timedata hour=" + model.getHour() + ", minute=" + model.getMinute());
            }
        }
        timePickerDialog = new CustomTimePickerDialog(this, listener, mTimeData.getHour(), mTimeData.getMinute(),
                true);
        timePickerDialog.setTimeData(mTimeData);

        timePickerDialog.setTitle(getResources().getString(R.string.alert_title_settime));
        // ?
        timePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel",
                new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int which) {
                        return;
                    } // end of onclick
                } // end of listener
        );

        timePickerDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int which) {
                // ????
                if (mTimeData == null)
                    return;

                int hour = mTimeData.getHour();
                int minute = mTimeData.getMinute();
                Logger.v("Time", String.format("%02d:%02d", hour, minute));

                SchedModel model = new SchedModel();
                model.setHour(hour);
                model.setMinute(minute);
                model.setHour_minute_string(String.format("%02d:%02d", hour, minute));
                SchedDAO dao = new SchedDAO(mActivity);
                // ?????
                if (mCurrentSchedUri != null) {
                    model.setId(Integer.valueOf(mCurrentSchedUri.getLastPathSegment()));
                    dao.updateTime(model);
                    activityRestart();
                    // ???
                } else {
                    // ?????
                    if (dao.countSchedFromTime(hour, minute) > 0)
                        return;

                    model.setEnabled(true);
                    model.setPattern(Conf.DEFAULT_REPEAT_PATTERN);
                    Uri uri = dao.insertSched(model);
                    if (uri == null)
                        return;

                    model.setId(Integer.valueOf(uri.getLastPathSegment()));

                    // mSchedListAdapter.notifyDataSetChanged();
                    transitionToSchedSetting(Integer.valueOf(uri.getLastPathSegment()));
                }
                SchedAlarmManager am = new SchedAlarmManager(mActivity);
                am.addAlarm(model);

                // ?
                mCurrentSchedUri = null;
                mTimeData.setHour(0);
                mTimeData.setMinute(0);

            } // end of onclick
        } // end of listener
        );

        timePickerDialog.show();
    }

    // private void transitionToTestActivity() {
    // Intent i = new Intent(getApplicationContext(), TestActivity.class);
    // startActivity(i);
    // }

    private void transitionToBatterySetting(int id) {
        Intent i = new Intent(getApplicationContext(), BatterySettingActivity.class);
        i.putExtra(Conf.SHARED_BATTERYID, id);
        startActivity(i);
    }

    private void transitionToManualSetting(int id) {
        Intent i = new Intent(getApplicationContext(), ManualSettingActivity.class);
        i.putExtra(Conf.SHARED_MANUALID, id);
        startActivity(i);
    }

    private void transitionToSchedSetting(int id) {
        Intent i = new Intent(getApplicationContext(), SchedSettingActivity.class);
        i.putExtra(Conf.SHARED_SCHEDID, id);
        startActivity(i);
    }

    private void activityRestart() {
        // Intent intent = new Intent();
        // intent.setClass(mActivity, mActivity.getClass());
        // mActivity.startActivity(intent);
        // mActivity.finish();
    }

    public CustomTimePickerDialog testGetDialog() {
        return timePickerDialog;
    }

    public TimePicker testGetTimePicker() {
        return timePickerDialog.testGetTimePicker();
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
        switch (id) {
        case SchedQuery.LOADER_ID:
            String order = SchedTbl._ID;
            return new CursorLoader(this, SchedTbl.CONTENT_URI, SchedQuery.PROJECTION, null, null, order);
        case BatteryQuery.LOADER_ID:
            return new CursorLoader(this, BatteryTbl.CONTENT_URI, BatteryQuery.PROJECTION, null, null, null);
        case ManualQuery.LOADER_ID:
            return new CursorLoader(this, ManualTbl.CONTENT_URI, ManualQuery.PROJECTION, null, null, null);
        default:
            break;
        }
        return null;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        switch (loader.getId()) {
        case SchedQuery.LOADER_ID:

            mSchedCount = data.getCount();

            // ????
            mSchedListAdapter.swapCursor(data);
            // mSchedListAdapter.notifyDataSetChanged();

            break;
        case BatteryQuery.LOADER_ID:
            if (data.moveToFirst()) {
                mBatteryId = data.getInt(BatteryQuery.Idx._ID.ordinal());
                mBatteryAccount.setVisibility(View.INVISIBLE);
                if (data.getInt(BatteryQuery.Idx.ENABLED.ordinal()) == 1) {
                    mBatteryDisabled.setVisibility(View.INVISIBLE);
                    mCurrentBattery.setVisibility(View.VISIBLE);
                    String desc;
                    int level = BatteryService.getCurrentBatteryLevel();
                    if (level == 0) {
                        desc = getResources().getString(R.string.desc_measureing);
                    } else {
                        desc = getResources().getString(R.string.desc_current_batterylevel) + level + "%";
                    }
                    mCurrentBatteryLevel.setText(desc);
                    mCurrentThreshold.setText(getResources().getString(R.string.desc_threshold)
                            + data.getInt(BatteryQuery.Idx.THRESHOLD.ordinal()) + "%");
                } else {
                    mBatteryDisabled.setVisibility(View.VISIBLE);
                    mCurrentBattery.setVisibility(View.INVISIBLE);
                }
            } else {
                mBatteryDisabled.setVisibility(View.INVISIBLE);
                mCurrentBattery.setVisibility(View.INVISIBLE);
                mBatteryAccount.setVisibility(View.VISIBLE);
            }

            break;
        case ManualQuery.LOADER_ID:
            if (data.moveToFirst()) {
                mManualId = data.getInt(ManualQuery.Idx._ID.ordinal());
            }

            break;

        default:
            break;
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> arg0) {
        mSchedListAdapter.swapCursor(null);

    }

    // 
    @Override
    public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
        transitionToSchedSetting((int) id);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);

        AdapterView.AdapterContextMenuInfo info;
        try {
            info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        } catch (ClassCastException e) {
            Log.e(TAG, "bad AdapterContextMenuInfo", e);
            return;
        }

        android.view.MenuInflater inflater = this.getMenuInflater();
        inflater.inflate(R.menu.context_menu_schedlist, menu);

        menu.setHeaderTitle(getResources().getString(R.string.label_menu));

        Intent intent = new Intent(null, ContentUris.withAppendedId(SchedTbl.CONTENT_URI, (int) info.id));
        intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

        menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, new ComponentName(mActivity, MainActivity.class),
                null, intent, 0, null);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterView.AdapterContextMenuInfo info;
        try {
            info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        } catch (ClassCastException e) {
            Log.e(TAG, "bad AdapterContextMenuInfo", e);
            return false;
        }

        mCurrentSchedUri = ContentUris.withAppendedId(SchedTbl.CONTENT_URI, info.id);
        switch (item.getItemId()) {
        case R.id.context_delete:
            // ?
            AlertDialog dlg = new AlertDialog.Builder(this).setTitle(R.string.alert_title_delete)
                    .setIcon(android.R.drawable.ic_dialog_alert).setMessage(R.string.alert_message_delete_sched)
                    .setPositiveButton("YES", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // ???
                            SchedModel model = new SchedModel();
                            model.setId(Integer.valueOf(mCurrentSchedUri.getLastPathSegment()));
                            SchedAlarmManager am = new SchedAlarmManager(mActivity);
                            am.cancelAlarm(model);

                            // DB??
                            SchedDAO dao = new SchedDAO(mActivity);
                            dao.deleteSchedById(Integer.valueOf(mCurrentSchedUri.getLastPathSegment()));

                            mCurrentSchedUri = null;

                            // ????
                            // NOTE:?????????
                            activityRestart();
                        }
                    }).setNegativeButton("NO", null).setInverseBackgroundForced(true).create();
            dlg.show();
            return true;
        case R.id.context_edit:
            setTime();
            // mManager.restartLoader(Query.LOADER_ID, null, this);
            return true;
        default:
            return super.onContextItemSelected(item);
        }
    }

    /**
     * About
     */
    private void showAboutDialog() {
        PackageManager pm = this.getPackageManager();
        String packageName = this.getPackageName();
        String versionName;
        try {
            PackageInfo info = pm.getPackageInfo(packageName, 0);
            versionName = info.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            versionName = "N/A";
        }

        SpannableStringBuilder aboutBody = new SpannableStringBuilder();

        SpannableString mailAddress = new SpannableString(getString(R.string.mailto));
        mailAddress.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_SENDTO);
                intent.setData(Uri.parse(getString(R.string.description_mailto)));
                intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.description_mail_subject));
                startActivity(intent);
            }
        }, 0, mailAddress.length(), 0);

        aboutBody.append(Html.fromHtml(getString(R.string.about_body, versionName)));
        aboutBody.append("\n");
        aboutBody.append(mailAddress);

        LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        TextView aboutBodyView = (TextView) layoutInflater.inflate(R.layout.fragment_about_dialog, null);
        aboutBodyView.setText(aboutBody);
        aboutBodyView.setMovementMethod(LinkMovementMethod.getInstance());

        AlertDialog dlg = new AlertDialog.Builder(this).setTitle(R.string.alert_title_about).setView(aboutBodyView)
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                }).create();
        dlg.show();
    }

}