com.abajeli.wearable.gesturecadabra.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.abajeli.wearable.gesturecadabra.MainActivity.java

Source

/*
 * Copyright (C) 2014 Google Inc. All Rights Reserved.
 *
 * 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.abajeli.wearable.gesturecadabra;

import com.abajeli.wearable.gesturecadabra.fragments.CounterFragment;
import com.abajeli.wearable.gesturecadabra.fragments.SettingsFragment;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.WindowManager;
import android.widget.ImageView;

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

/**
 * The main activity for the Jumping Jack application. This activity registers itself to receive
 * sensor values. Since on wearable devices a full screen activity is very short-lived, we set the
 * FLAG_KEEP_SCREEN_ON to give user adequate time for taking actions but since we don't want to
 * keep screen on for an extended period of time, there is a SCREEN_ON_TIMEOUT_MS that is enforced
 * if no interaction is discovered.
 *
 * This activity includes a {@link android.support.v4.view.ViewPager} with two pages, one that
 * shows the current count and one that allows user to reset the counter. the current value of the
 * counter is persisted so that upon re-launch, the counter picks up from the last value. At any
 * stage, user can set this counter to 0.
 */
public class MainActivity extends Activity implements SensorEventListener, BeaconConsumer {

    private static final String TAG = "gcMainActivity";

    /** How long to keep the screen on when no activity is happening **/
    private static final long SCREEN_ON_TIMEOUT_MS = 20000; // in milliseconds

    /** an up-down movement that takes more than this will not be registered as such **/
    private static final long TIME_THRESHOLD_NS = 2000000000; // in nanoseconds (= 2sec)

    /**
     * Earth gravity is around 9.8 m/s^2 but user may not completely direct his/her hand vertical
     * during the exercise so we leave some room. Basically if the x-component of gravity, as
     * measured by the Gravity sensor, changes with a variation (delta) > GRAVITY_THRESHOLD,
     * we consider that a successful count.
     */
    private static final float GRAVITY_THRESHOLD = 7.0f;

    private SensorManager mSensorManager;
    private Sensor mSensor;
    private long mLastTime = 0;
    private boolean mUp = false;
    private int mJumpCounter = 0;
    private ViewPager mPager;
    private CounterFragment mCounterPage;
    private SettingsFragment mSettingPage;
    private ImageView mSecondIndicator;
    private ImageView mFirstIndicator;
    private Timer mTimer;
    private TimerTask mTimerTask;
    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.jj_layout);
        setupViews();
        mHandler = new Handler();
        mJumpCounter = Utils.getCounterFromPreference(this);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        //renewTimer();
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
    }

    private void setupViews() {
        mPager = (ViewPager) findViewById(R.id.pager);
        mFirstIndicator = (ImageView) findViewById(R.id.indicator_0);
        mSecondIndicator = (ImageView) findViewById(R.id.indicator_1);
        final PagerAdapter adapter = new PagerAdapter(getFragmentManager());
        mCounterPage = new CounterFragment();
        mSettingPage = new SettingsFragment();
        adapter.addFragment(mCounterPage);
        adapter.addFragment(mSettingPage);
        setIndicator(0);
        mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int i, float v, int i2) {
            }

            @Override
            public void onPageSelected(int i) {
                setIndicator(i);
                //renewTimer();
            }

            @Override
            public void onPageScrollStateChanged(int i) {
            }
        });

        mPager.setAdapter(adapter);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL)) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Successfully registered for the sensor updates");
            }
        }
    }

    /**
     * This will save battery
     */
    @Override
    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this);
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Unregistered for sensor events");
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        detectJump(event.values[0], event.timestamp);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    /**
     * A simple algorithm to detect a successful up-down movement of hand(s). The algorithm is
     * based on the assumption that when a person is wearing the watch, the x-component of gravity
     * as measured by the Gravity Sensor is +9.8 when the hand is downward and -9.8 when the hand
     * is upward (signs are reversed if the watch is worn on the right hand). Since the upward or
     * downward may not be completely accurate, we leave some room and instead of 9.8, we use
     * GRAVITY_THRESHOLD. We also consider the up <-> down movement successful if it takes less than
     * TIME_THRESHOLD_NS.
     */
    private void detectJump(float xValue, long timestamp) {
        if ((Math.abs(xValue) > GRAVITY_THRESHOLD)) {
            if (timestamp - mLastTime < TIME_THRESHOLD_NS && mUp != (xValue > 0)) {
                onOpenDirectiveDetected(!mUp);
            }
            mUp = xValue > 0;
            mLastTime = timestamp;
        }
    }

    /**
     * Called on detection of a successful down -> up or up -> down movement of hand.
     */
    private void onOpenDirectiveDetected(boolean up) {
        // we only count a pair of up and down as one successful movement
        if (up) {
            return;
        }
        mJumpCounter++;
        setCounter(mJumpCounter);
        //renewTimer();
    }

    /**
     * Updates the counter on UI, saves it to preferences and vibrates the watch when counter
     * reaches a multiple of 10.
     */
    private void setCounter(int i) {
        mCounterPage.setCounter(i);
        Utils.saveCounterToPreference(this, i);
        if (i > 0 && i % 10 == 0) {
            Utils.vibrate(this, 0);
        }
    }

    /*
        public void resetCounter() {
    setCounter(0);
    renewTimer();
        }
    */

    /**
     * Starts a timer to clear the flag FLAG_KEEP_SCREEN_ON.
     */
    /*
    private void renewTimer() {
    if (null != mTimer) {
        mTimer.cancel();
    }
    mTimerTask = new TimerTask() {
        @Override
        public void run() {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG,
                        "Removing the FLAG_KEEP_SCREEN_ON flag to allow going to background");
            }
            resetFlag();
        }
    };
    mTimer = new Timer();
    mTimer.schedule(mTimerTask, SCREEN_ON_TIMEOUT_MS);
    }
    */

    /**
     * Resets the FLAG_KEEP_SCREEN_ON flag so activity can go into background.
     */
    /*
    private void resetFlag() {
    mHandler.post(new Runnable() {
        @Override
        public void run() {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Resetting FLAG_KEEP_SCREEN_ON flag to allow going to background");
            }
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            finish();
        }
    });
    }*/

    /**
     * Sets the page indicator for the ViewPager.
     */
    private void setIndicator(int i) {
        switch (i) {
        case 0:
            mFirstIndicator.setImageResource(R.drawable.full_10);
            mSecondIndicator.setImageResource(R.drawable.empty_10);
            break;
        case 1:
            mFirstIndicator.setImageResource(R.drawable.empty_10);
            mSecondIndicator.setImageResource(R.drawable.full_10);
            break;
        }
    }

    //static Context mContext;
    public void parla(String txt) {
        //ttobj.speak(txt, TextToSpeech.QUEUE_FLUSH, null);

        try {
            Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

            long[] vibrationPattern = { 0, 100, 0, 0 };
            final int indexInPatternToRepeat = -1;
            Utils.vibratePattern(this, vibrationPattern, indexInPatternToRepeat);

            //Ringtone r = RingtoneManager.getRingtone(baseContext, notification);
            //r.play();
        } catch (Exception e) {
            e.printStackTrace();
        }

        /*
                Intent viewIntent = new Intent(mContext, NotificationActivity.class);
                viewIntent.putExtra(EXTRA_EVENT_ID, NOTIFICATION_ID);
                PendingIntent viewPendingIntent =
            PendingIntent.getActivity(mContext, 0, viewIntent, 0);
            
        // Create a WearableExtender to add functionality for wearables
                NotificationCompat.WearableExtender wearableExtender =
            new NotificationCompat.WearableExtender()
                    .setHintHideIcon(true);
                //.setBackground(mBitmap);
            
        // Create a NotificationCompat.Builder to build a standard notification
        // then extend it with the WearableExtender
                NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(mContext)
                    //.setSmallIcon(R.drawable.ic_event)
                    .setContentTitle("eventTitle")
                    .setContentText("eventLocation")
                    .extend(wearableExtender)
                    .setContentIntent(viewPendingIntent);
            
            
            
            
            
            
                // Get an instance of the NotificationManager service
                NotificationManagerCompat notificationManager =
            NotificationManagerCompat.from(mContext);
            
        // Issue the notification with notification manager.
                notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
            
                */

    }

}