2

I have a "Track Walk" page that counts the step of a user. My intention is to accumulate these steps and then display the "Total" in another Activity. The Track walk page includes a button to "End Walk". It would be nice to reset the counter to 0 upon clicking, and then add the total steps to the Total Counter.

I will be working on a solution of my own, but wanted to post this here for some guidance as well. Thank you!

Here is the Track Walk activity:

public class trackWalk extends AppCompatActivity implements SensorEventListener {

                SensorManager sensorManager;
                TextView tv_steps;
                boolean running = false;
                SQLiteDatabase db;
     @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_track_walk);

    db=openOrCreateDatabase("STEPSTAKEN", Context.MODE_PRIVATE, null);
    db.execSQL("CREATE TABLE IF NOT EXISTS STEPS_TABLE(steps INTEGER);");

    tv_steps = (TextView) findViewById(R.id.steps);
    sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);


    button = findViewById(R.id.trackWalk);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           //Reset counter and Populate Total Value in "Walk History"
        }
    });

}

        @Override
        protected void onResume() {
            super.onResume();
            running=true;
            Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
            if(countSensor != null) {
                sensorManager.registerListener(this, countSensor, SensorManager.SENSOR_DELAY_UI);
            }
            else {
                Toast.makeText(this, "Please enable Sensor!", Toast.LENGTH_SHORT).show();
            }

        }



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

        // Unregistering will stop steps
       //  sensorManager.unregisterListener(this);
        }

        @Override
        public void onSensorChanged(SensorEvent event) {
        if(running) {
            tv_steps.setText(String.valueOf(event.values[0]));
            db.execSQL("INSERT INTO STEPS_TABLE VALUES('"+tv_steps.getText()+"');");
        }
        }

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

        }
    }

Here is the "Walk History" Page where the accumulative value should be:

package edu.phoenix.mbl402.walkmypup;

import android.support.v7.app.AppCompatActivity; import android.os.Bundle;

public class walkHistory extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_walk_history);
    }
}
ttattini
  • 196
  • 1
  • 17
  • have you tried passing value using intents https://stackoverflow.com/questions/14017720/how-to-pass-value-using-intent-between-activity-in-android – A.D Jun 04 '18 at 23:37

3 Answers3

1

You can do this with Intents. Pass the value with required parameters and get them in the next activity.

Mbuodile Obiosio
  • 1,463
  • 1
  • 15
  • 19
1

I'd suggest a minor modification, that would likely allow you to make better use of the data.

That is instead of using

db.execSQL("CREATE TABLE IF NOT EXISTS STEPS_TABLE(steps INTEGER);");

.........

db.execSQL("INSERT INTO STEPS_TABLE VALUES('"+tv_steps.getText()+"');");

use

db.execSQL("CREATE TABLE IF NOT EXISTS STEPS_TABLE(steps INTEGER, timestamp TEXT DEFAULT CURRENT_TIMESTAMP);");

.........

db.execSQL("INSERT INTO STEPS_TABLE (steps) VALUES('"+tv_steps.getText()+"');");

also changing :-

As such instead of then having data such as :-

enter image description here

You would (without any extra work other than the two changes) get data such as :-

enter image description here

  • Note the above data for both was randomly generated but over a short time period hence the dates/times being the same.

This, for instance, would allow you to very easily extract say steps per day.

With regard to passing information to another activity there is no need as basically the tables contains everything, so just query the table in the new activity.


Working Example

The following example is based upon your code. For my convenience I've added a button and method to mimic a sensor change which will add a random number of steps when the button is clicked.

Comments within the code hopefully explain the code.

TrackWalk**

public class TrackWalk extends AppCompatActivity implements SensorEventListener {

    //<<<<<<<<<< Use single source (constants) for DB related names
    public static final String DBNAME = "STEPSTAKEN";
    public static final String TB_STEPSTAKEN = "stepstaken";
    public static final String COL_STEPSTAKEN_STEPS = "steps";
    public static final String COl_STEPSTAKEN_TIMESTAMP = "timestamp";

    SensorManager sensorManager;
    TextView tv_steps;
    boolean running = false;
    SQLiteDatabase db;
    Button button, sensor; //<<<< Added another button to mimic sensor change
    Random rnd; //<<<<< For creating random number of steps

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

        //<<<<<<<<<< Note changes to use constants
        db=openOrCreateDatabase(DBNAME, Context.MODE_PRIVATE, null); //
        db.execSQL(
                "CREATE TABLE IF NOT EXISTS " +
                        TB_STEPSTAKEN +
                        "(" +
                        COL_STEPSTAKEN_STEPS + " INTEGER, " +
                        COl_STEPSTAKEN_TIMESTAMP + " TEXT DEFAULT CURRENT_TIMESTAMP" +
                        ")"
        );

        tv_steps = (TextView) findViewById(R.id.steps);
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

        //<<<<<<<<<< Added to mimic sensor change at button click
        sensor = this.findViewById(R.id.sensor);
        sensor.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                noSensor(); //<<<< Mimic sensor change

            }
        });


        button = findViewById(R.id.trackWalk);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Reset counter and Populate Total Value in "Walk History"
                Intent i = new Intent(getBaseContext(),WalkHistory.class); //<<<< ready to start activity
                startActivity(i); // start the WalkHistory Activity
            }
        });

    }

    @Override
    protected void onResume() {
        super.onResume();
        running=true;
        Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
        if(countSensor != null) {
            sensorManager.registerListener(this, countSensor, SensorManager.SENSOR_DELAY_UI);
        }
        else {
            Toast.makeText(this, "Please enable Sensor!", Toast.LENGTH_SHORT).show();
        }
    }

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

        // Unregistering will stop steps
        //  sensorManager.unregisterListener(this);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if(running) {
            tv_steps.setText(String.valueOf(event.values[0]));
            db.execSQL("INSERT INTO STEPS_TABLE VALUES('"+tv_steps.getText()+"');");
        }
    }

    //<<<<<<<<<< MIMIC SENSOR for testing >>>>>>>>>>
    public void noSensor() {
        db.execSQL("INSERT INTO " + TB_STEPSTAKEN +
                "(" + COL_STEPSTAKEN_STEPS + ")" +
                "VALUES("+String.valueOf(rnd.nextInt(10000-1 + 1)+1) +");");
    }

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

activity_walk_history.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".WalkHistory"
    tools:showIn="@layout/activity_walk_history">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Total Steps "
        />
    <TextView
        android:id="@+id/totalsteps"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <ListView
        android:id="@+id/walkhistorylist"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>
</LinearLayout>

WalkHistory

public class WalkHistory extends AppCompatActivity {

    Cursor mCsr;
    SQLiteDatabase mDB;
    SimpleCursorAdapter mSCA;
    ListView mLV;
    TextView mTotalSteps;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_walk_history);
        mLV = this.findViewById(R.id.walkhistorylist);
        mTotalSteps = this.findViewById(R.id.totalsteps);
        String total_steps_column_name = "total_steps";

        // As Cursor Adpaters need _id column grab an alias of thr rowid as _id
        String[] columns = new String[]{"rowid AS " + BaseColumns._ID + ",*"};

        // Get the database
        mDB = this.openOrCreateDatabase(TrackWalk.DBNAME, MODE_PRIVATE,null);

        // Extract Data (all) into a Cursor)
        mCsr = mDB.query(
                TrackWalk.TB_STEPSTAKEN,
                columns,
                null,
                null,
                null,
                null,
                TrackWalk.COl_STEPSTAKEN_TIMESTAMP + " DESC"
        );
        // Setup the Adapter for the ListView
        mSCA = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_2,mCsr,
                new String[]{"timestamp","steps"},
                new int[]{android.R.id.text1, android.R.id.text2},
                0
        );
        // Tie the Adapter to the Listview
        mLV.setAdapter(mSCA);

        // Get the sum of the Steps (note would use the same WHERE clause as the ListView Cursor)
        Cursor csr = mDB.query(
                TrackWalk.TB_STEPSTAKEN,
                new String[]{
                        "sum(steps) AS " + total_steps_column_name
                },
                null,
                null,
                null,
                null,
                null
        );
        // Apply the sum of the steps to the TextView
        if (csr.moveToFirst()) {
            mTotalSteps.setText(csr.getString(csr.getColumnIndex(total_steps_column_name)));
        }
    }
}

Result

The following is an example of the result of clicking the button to go to the WalkHistory activity (after some data has been added). The entries are listed. The list is preceded by the total number of steps.

enter image description here

As can be seen there is no need to pass any information from the TrackWalk activity to the WalkHistory activity.

Additional Multiple Walks/reset counter (sort of)

If you wanted to keep a historical record and the History Button were the Walk Ended button. Then perhaps the following could suffice (at least perhaps as a starting point). Basically this works on the concept of a "Current Walk", start the App and a "Current Walk" is assumed and assumed ended when History button is clicked, when only those steps for that walk are displayed along with the total for that Walk.

Upon returning (back button) a new Walk is assumed and so on.

This utilises a 2nd table for the walks with 3 columns id date/time when started date/time when ended BUT IMPORTANTLY blank until ended.

The first table has another column added, the walk column which is the id of the respective walk.

When the App is started or resumed (return from WalkHistory activity) if there are any walks (should only be 1) that do no have a date/time in the walkended column then that walk is considered the current walk. Otherwise a current walk row is inserted (with the walkended column being blank). In both cases the mCurrentWalk variable is set to the respective id.

Each record includes the owning walkid. When the History button is clicked the mCurrentlWalk value is sent, via an intent extra to the WalkHistory activity. The WalkHistory activity obtains this and set's an equivalent like named variable accordingly and uses this to select the appropriate rows shown in the list and also when determining the total. new is a call that updates the walks row with the current datetime, thus effectively marking the row (aka walk) as ended.

So here's the changed TrackWalk activity " :-

public class TrackWalk extends AppCompatActivity implements SensorEventListener {

    //<<<<<<<<<< Use single source (constants) for DB related names
    public static final String DBNAME = "STEPSTAKEN";
    public static final String TB_STEPSTAKEN = "stepstaken";
    public static final String COL_STEPSTAKEN_STEPS = "steps";
    public static final String COl_STEPSTAKEN_TIMESTAMP = "timestamp";
    public static final String COL_STEPSTAKEN_WALK = "walk";
    public static final String TB_WALKS = "walks";
    public static final String COL_WALKID = "walkid";
    public static final String COL_WALKSTARTED = "walkstarted";
    public static final String COL_WALKENDED = "walkended";

    // used for passing data
    public static final String INTENTEXTRA_WALKID = "ie_walkid";

    SensorManager sensorManager;
    TextView tv_steps;
    boolean running = false;
    SQLiteDatabase db;
    Button button, sensor; //<<<< Added another button to mimic sensor change
    Random rnd; //<<<<< For creating random number of steps
    long mCurrentWalk;

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

        //<<<<<<<<<< Note changes to use constants
        db=openOrCreateDatabase(DBNAME, Context.MODE_PRIVATE, null); //
        db.execSQL(
                "CREATE TABLE IF NOT EXISTS " +
                        TB_STEPSTAKEN +
                        "(" +
                        COL_STEPSTAKEN_STEPS + " INTEGER, " +
                        COl_STEPSTAKEN_TIMESTAMP + " TEXT DEFAULT CURRENT_TIMESTAMP," +
                        COL_STEPSTAKEN_WALK + " INTEGER " + //<<<< ADDED FOR multiple walks
                        ")"
        );

        // Create a Walks table
        String crt_walks_table = "CREATE TABLE IF NOT EXISTS " +
                TB_WALKS +
                "(" +
                COL_WALKID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COL_WALKSTARTED + " TEXT DEFAULT CURRENT_TIMESTAMP, " +
                COL_WALKENDED + " TEXT DEFAULT ''" +
                ")";
        db.execSQL(crt_walks_table);

        tv_steps = (TextView) findViewById(R.id.steps);
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

        //<<<<<<<<<< Added to mimic sensor change at button click
        sensor = this.findViewById(R.id.sensor);
        sensor.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                noSensor(); //<<<< Mimic sensor change
            }
        });

        button = findViewById(R.id.trackWalk);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Reset counter and Populate Total Value in "Walk History"
                Intent i = new Intent(getBaseContext(),WalkHistory.class); //<<<< ready to start activity
                i.putExtra(INTENTEXTRA_WALKID,mCurrentWalk);
                startActivity(i); // start the WalkHistory Activity
            }
        });
        setCurrentWalk(); //<<<< Set the current walk (utilises last if not ended)
    }

    @Override
    protected void onResume() {
        super.onResume();
        running=true;
        Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
        if(countSensor != null) {
            sensorManager.registerListener(this, countSensor, SensorManager.SENSOR_DELAY_UI);
        }
        else {
            Toast.makeText(this, "Please enable Sensor!", Toast.LENGTH_SHORT).show();
        }
        setCurrentWalk();
    }

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

        // Unregistering will stop steps
        //  sensorManager.unregisterListener(this);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if(running) {
            tv_steps.setText(String.valueOf(event.values[0]));
            db.execSQL("INSERT INTO STEPS_TABLE VALUES('"+tv_steps.getText()+"');");
        }
    }

    //<<<<<<<<<< MIMIC SENSOR for testing >>>>>>>>>>
    public void noSensor() {
        db.execSQL("INSERT INTO " + TB_STEPSTAKEN +
                "(" +
                COL_STEPSTAKEN_STEPS +
                "," +
                COL_STEPSTAKEN_WALK +
                ")" +
                "VALUES(" +
                String.valueOf(rnd.nextInt(10000-1 + 1)+1)
                +
                "," +
                String.valueOf(mCurrentWalk) +
                ");");
    }

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

    private void setCurrentWalk() {
        mCurrentWalk = -1;
        String whereclause = "length(" + COL_WALKENDED + ") < 1"; // Only walks that haven't been ended
        // Is there an unfished walk?? if so use that
        Cursor csr = db.query(TB_WALKS,null,whereclause,null,null,null,COL_WALKID + " DESC");
        if (csr.moveToFirst()) {
            mCurrentWalk = csr.getLong(csr.getColumnIndex(COL_WALKID)); //<<<< use incomplete walk
        }
        csr.close();
        // If there is no unfinished walk then create a new walk
        if (mCurrentWalk < 1) {
            String insrtsql = "INSERT INTO " + TB_WALKS +
                    " (" +
                    COL_WALKID +
                    ") VALUES(null)";
            db.execSQL(insrtsql);
            mCurrentWalk = DatabaseUtils.longForQuery(db,"SELECT last_insert_rowid()",null);
        }
    }
}

And here's the changed WalkHistory Activity :-

public class WalkHistory extends AppCompatActivity {

    Cursor mCsr;
    SQLiteDatabase mDB;
    SimpleCursorAdapter mSCA;
    ListView mLV;
    TextView mTotalSteps;
    long mCurrentWalk;

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

        // Get the current walk id
        mCurrentWalk =  this.getIntent().getLongExtra(TrackWalk.INTENTEXTRA_WALKID,-1);

        mLV = this.findViewById(R.id.walkhistorylist);
        mTotalSteps = this.findViewById(R.id.totalsteps);
        String total_steps_column_name = "total_steps";

        // As Cursor Adpaters need _id column grab an alias of thr rowid as _id
        String[] columns = new String[]{"rowid AS " + BaseColumns._ID + ",*"};

        // Get the database
        mDB = this.openOrCreateDatabase(TrackWalk.DBNAME, MODE_PRIVATE,null);

        // Set the current walk as ended
        setCurrentWalkEnded();

        String whereclause = TrackWalk.COL_STEPSTAKEN_WALK + "=?";
        String[] whereargs = new String[]{String.valueOf(mCurrentWalk)};

        // Extract Data for this walk
        mCsr = mDB.query(
                TrackWalk.TB_STEPSTAKEN,
                columns,
                whereclause,
                whereargs,
                null,
                null,
                TrackWalk.COl_STEPSTAKEN_TIMESTAMP + " DESC"
        );
        // Setup the Adapter for the ListView
        mSCA = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_2,mCsr,
                new String[]{"timestamp","steps"},
                new int[]{android.R.id.text1, android.R.id.text2},
                0
        );
        // Tie the Adapter to the Listview
        mLV.setAdapter(mSCA);

        // Get the sum of the Steps (note would use the same WHERE clause as the ListView Cursor)
        Cursor csr = mDB.query(
                TrackWalk.TB_STEPSTAKEN,
                new String[]{
                        "sum(steps) AS " + total_steps_column_name
                },
                whereclause,
                whereargs,
                null,
                null,
                null
        );
        // Apply the sum of the steps to the TextView
        if (csr.moveToFirst()) {
            mTotalSteps.setText(csr.getString(csr.getColumnIndex(total_steps_column_name)));
        }
    }

    /**
     * Set the current walk as ended, but only if some records exist
     */
    private void setCurrentWalkEnded() {

        String whereclause1 = TrackWalk.COL_STEPSTAKEN_WALK + "=?";
        String[] whereargs = new String[]{String.valueOf(mCurrentWalk)};
        Cursor csr = mDB.query(TrackWalk.TB_STEPSTAKEN,null,whereclause1,whereargs,null,null,null);
        String whereclause2 = TrackWalk.COL_WALKID + "=?";
        if (csr.getCount() > 0 ) {
            String updtsql = "UPDATE " + TrackWalk.TB_WALKS + " SET " + TrackWalk.COL_WALKENDED + " = datetime('now') WHERE " + whereclause2;
            mDB.execSQL(updtsql, whereargs);
        }
        csr.close();
    }
}
  • Note this hasn't been extensively tested and is pretty rudimentary.
MikeT
  • 51,415
  • 16
  • 49
  • 68
0

You could use intents to achieve this, as mentioned in the comments above. However you could also retrieve the data through SQLite.

So when the button to end walk is finished you can start a new activity:

Intent intent = new Intent(trackWalk.this,walkHistory.class);
startActivity(intent); 

Then on your class that handles SQLite:

public Cursor fetchData() {
    Cursor c = this.database.query(SQLiteHelper.YOUR_TABLE_NAME,new String[]{SQLiteHelper.YOR_COLUMN}, null, null, null, null, null);
    if (c != null) {
         c.moveToFirst();
    }

    return c;
}

You can use this function to retrieve the data on your preferred class.

Using intents this could be sth like:

Intent intent = new Intent(trackWalk.this,walkHistory.class);
intent.putExtra("MYDATA",//your data here);
startActivity(intent);

On walkHistory class on onCreate:

//(or another type of variable, it also works for integers)
String steps = getIntent().getStringExtra("MYDATA");
//manage your data here
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459