Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reset Value of an Integer at A Specific Time of Day

I currently have a Fragment that has several Buttons and contains an onClickListener. Each time one of those buttons are clicked, a counter variable is incremented by 1, and is set as the text for a TextView in another Fragment, using SharedPreferences.

The counter will stay the same even after the app is completely closed, and will appear in subsequent runs of the app.

My new goal is to reset the counters back to 0 at the end of each day (23:59:00 for the time, to be exact).

I decided to avoid a Google search to figure this out, and found TimerTask, Calendar, Timer, and Date APIs on the Android Developer docs; I tried to get this to work with those APIs. Unfortunately it's not working out the way I planned. The variables are set back to 0, but they stay at zero and will only increment up to 1, and go back to 0 every time I exit the app.

Is there a better way to approach this? Or is my method sufficient, and I just need to adjust/change some of the code?

One of the problems might be where I'm changing the counter variable reference as well (and if so, where should I change it)?

Here is what I attempted:

FirstFragment

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflating the layout
        View v = inflater.inflate(R.layout.starting_fragment, container, false);

        //Instantiate new Timer
        Timer timer = new Timer();
        // Creates a Calendar object that specifies a specific time of day
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        cal.set(Calendar.HOUR_OF_DAY, 20);
        cal.set(Calendar.MINUTE, 57);
        cal.set(Calendar.SECOND, 00);
        cal.set(Calendar.MILLISECOND, 00);

        // Instantiate a day object and use the time of day from cal object as its data
        Date date = cal.getTime();

        TimerTask tt = new TimerTask() {
            // Sets the counter variables back to 0
            @Override
            public void run() {
                COUNT_OOL = 0;
                COUNT_WTE = 0;
                COUNT_BLO = 0;
                COUNT_BLK = 0;
                COUNT_HBL = 0;
                COUNT_GRN = 0;
                COUNT_MTE = 0;

            }
        };
        // Resets the counter variables (to 0) at the time specified by the date object
        timer.schedule(tt, date);

        // Stores count for each button back into their respective count variable
        // Initializes the value from previous runs of app to subsequent runs of app
        // This way, count variables will never get set back to 0 after onDestroy()
        COUNT_OOL = getActivity().getSharedPreferences("keyname", Context.MODE_PRIVATE).getInt("oolongCount", 0);
        COUNT_WTE = getActivity().getSharedPreferences("keyname", Context.MODE_PRIVATE).getInt("whiteCount", 0);
        COUNT_BLO = getActivity().getSharedPreferences("keyname", Context.MODE_PRIVATE).getInt("bloomingCount", 0);
        COUNT_BLK = getActivity().getSharedPreferences("keyname", Context.MODE_PRIVATE).getInt("blackCount", 0);
        COUNT_HBL = getActivity().getSharedPreferences("keyname", Context.MODE_PRIVATE).getInt("herbalCount", 0);
        COUNT_GRN = getActivity().getSharedPreferences("keyname", Context.MODE_PRIVATE).getInt("greenCount", 0);
        COUNT_MTE = getActivity().getSharedPreferences("keyname", Context.MODE_PRIVATE).getInt("mateCount", 0);

The onClick method that increments the counter variables:

 @Override
    public void onClick(View view) {
        int id = view.getId();
        /*
         * Use the View interface with OnClickListener to get the Button ID's
         * Then you can run a switch on the Buttons (because normally switches
         * cannot be run on buttons
         */

        if (id == R.id.tea_type1) {
            Builder oolongBuilder = new AlertDialog.Builder(StartingFragment.this.getActivity(),
                    AlertDialog.THEME_HOLO_LIGHT);

            oolongBuilder.setPositiveButton("Hot",
                    //Starts OolongTeaActivity for hot tea when clicked
                    new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface arg0, int arg1) {
                            Intent i = new Intent(StartingFragment.this.getActivity(),
                                    OolongTeaActivity.class);
                            StartingFragment.this.getActivity().startActivity(i);
                        }
                    });

            oolongBuilder.setNeutralButton("Iced",

                    new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Intent i = new Intent(StartingFragment.this.getActivity(),
                                    ColdOolongTeaActivity.class);
                            StartingFragment.this.getActivity().startActivity(i);

                        }
                    });

            oolongBuilder.setTitle("Oolong Tea");
            oolongBuilder.setMessage("How Do You Like Your Tea?");

            AlertDialog oolongDialog = oolongBuilder.create();
            oolongDialog.show();

            COUNT_OOL++;
            SharedPreferences pref1 = getActivity().getSharedPreferences("keyname", Context.MODE_PRIVATE);
            SharedPreferences.Editor editor1 = pref1.edit();
            editor1.putInt("oolongCount", COUNT_OOL);
            editor1.commit();

        }

SecondFragment (sets the counters as the text for TextViews):

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_tea_counter, container, false);

        oolongCounterText = (TextView) rootView.findViewById(R.id.oolong_counter_tv);

        SharedPreferences pref1 = getActivity().getSharedPreferences("keyname", Context.MODE_PRIVATE);
        Integer counter1 = pref1.getInt("oolongCount", 0);
        String s1 = String.valueOf(counter1);
        oolongCounterText.setText(s1);
like image 851
freddiev4 Avatar asked Jan 10 '15 02:01

freddiev4


1 Answers

I would personally look at using the AlarmManager with the Calendar to set the time. You will then fire off a Service to do everything you need to do.

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 0);
PendingIntent pi = PendingIntent.getService(context, 0,
            new Intent(context, MyService.class),PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                                AlarmManager.INTERVAL_DAY, pi);

Replace MyService with an actual Service, When the service starts it can: 1) Reset the number back to 0 2) Check if the app is running to see if you need to update the textboxes immediately or if it okay to wait for the user to launch the app 3) stop the service

Things to investigate before you follow this code:

Make sure the AlarmManager is right for you, a repeating alarm will NOT run after a reboot (Thanks to Jawnnypoo for clarifying this) Please see his comment below in which he links to a BroadcastReceiver so that the AlarmManager will run after a reboot.

like image 200
apmartin1991 Avatar answered Oct 14 '22 10:10

apmartin1991