Many offices today are still filling out paper time cards. Why you ask?

  1. How nefarious software integration is
  2. The learning curve
  3. Bugs or “features”

Almost everyone is guilty of it. Products are designed to work with constant support resulting in monthly or yearly fees. Upgrades, server costs etc. But most people aren’t getting paid to figure out software. They want the solution that stays the same. Not one that changes with the weather. As they sort through all the numerous buttons they passively fear that the next upgrade will change things and they will spend more time relearning. Barf.

 

But paper time cards suck!

Paper time cards take time to fill out. There is zero space to write. They get smudged and lost plus people have to hand deliver them back to the office. Someone needs to sort through them. Its not really a great solution.

 

My Solution

A compromise between the two.  This app is real easy. Two buttons to operate it and if the setup is too hard someone else can do it once and its done. Below is a screen shot from the main screen of the app. You can see the current day being shown as clocked in and below. When the user is ready to clock out just press the big red button. When the user is ready to report their time they can press the button on the bottom  labeled report time.

 

Here is the main activity below which is android class that you build your app around. Here there are a few boilerplate function to get the app onto your screen and a few more to to make dates, times or save files to your device.

This UI of this app is built within the Fragment and Dialogue Fragment classes within android library which is conveniently optimized with android studio which has great autocomplete.

Me thinking about autocomplete. Colorized. Circa 1999.

The main design of this app relies on java calendar. By using the calendar .get instance I can pull a number of int objects representing the minute, hour, day, week or month of the year. In order to build this app I created a listview showing the previous data.

I have several onClick methods calling my different methods throughout the fragment class I created.

[java] @Override
public void onClick(View view) {

switch (view.getId()){

case R.id.clockIn_Out_button:

if (CURRENT_STATUS.equals(CLOCKED_IN)) {

clockOut();

} else { clockInFromClick(view); }

break;

case R.id.report_button:

deleteOldData();

boolean infoToReport = createReport();

if (infoToReport) {
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL, recipientOfEmail);
i.putExtra(Intent.EXTRA_SUBJECT, subjectOfEmail);
i.putExtra(Intent.EXTRA_TEXT, bodyOfEmail);

try {

startActivity(Intent.createChooser(i, "Send email..."));

} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(getActivity(), "No email Client installed", Toast.LENGTH_LONG).show();
}

}else if (reportErrorExplain.equals("You must fill out your name in settings") || reportErrorExplain.equals("You must fill out an email recipient in settings")) {
Toast.makeText(getActivity(), reportErrorExplain, Toast.LENGTH_SHORT).show();

new Handler().postDelayed(new Runnable() {
@Override
public void run() {
((MainActivity)getActivity()).loadSettingsFrag();

}
}, 2000);

}
else {

Toast.makeText(getActivity(), reportErrorExplain, Toast.LENGTH_SHORT).show();
}

toReport.clear();

clearScreen();

break;

}

}
[/java]

My big mistake was not breaking down the data processing into smaller more usable methods. Instead I ended up with two lengthy methods for pulling data from the device and making a human readable list. One of these methods serves the device users list. The other serves a method which creates the email to be sent. See below!

[java]
<pre>
public void createList()
{

    eachDaysData = new String[20];
   String s;
   String[] d = new String[20];



    for (int i = 0; i < 20; i++) {


       s = ((MainActivity)getActivity()).createCalendarDate(i);

        //Log.i("createdates: ", s);

        d[i] = ((MainActivity)getActivity()).getData(s);      //at this point d has each days raw data



    }


    for (int i = 0; i < d.length; i++) {

        if (i == 0 && CURRENT_STATUS.equals(CLOCKED_IN)){
            String q = ((MainActivity)getActivity()).createCalendarDate(i);
            eachDaysData[i] = q + "\n" + "CURRENT STATUS: CLOCKED IN";
        }


        else if (!d[i].equals("")){

           String min = "";
           String myHr = "";
            String prevHour = "";
            String prevMinute = "";
            String startTime = "";
            String endTime = "";
            String timeWorked, timeBreaked;
            int pHr,pMt, Hr, Mt;
            int cumHrW = 0;
            int cumMinW = 0;
            int cumHrB = 0;
            int cumMinB = 0;
            String currLoc ="", nextLoc ="";

            boolean inEvent = true;

            Log.i("createList: ", d[i]);

            String[] e = d[i].split(DELIM_O);    //e[0] = "clockedin_13_53, e[1] = "clockedout_13_53

            for (int j = 0; j < e.length; j++) {

               String[] p = e[j].split(DELIM_I);  //p[0] = clockedin p[1] = 13 p[2] = 53 p[3] = "some location"

                if (p.length == 4) {

                    addToRecentLocations(p[3]);
                   // Log.i("location found", "true");
                }

                if (startTime.equals("")) {                                                        //this does start time

                    String marker = "am";

                    int t = Integer.valueOf(p[1]);
                    if (t > 12){  t+= -12; marker = "pm"; }
                   myHr = String.valueOf(t);

                    t = Integer.valueOf(p[2]);
                    if (t < 10){min = "0" + String.valueOf(t);}
                    else {min = String.valueOf(t);}


                    startTime += myHr + ":" + min + marker;
                }
                if (j == e.length-1){                                                               //this records endtime


                    if (p[0].equals(CLOCKED_IN)){



                    }else {


                        String marker = "am";

                        int t = Integer.valueOf(p[1]);
                        if (t > 11) {
                            marker = "pm";
                        }
                        if (t > 12) {
                            t += -12;
                        }
                        myHr = String.valueOf(t);

                        t = Integer.valueOf(p[2]);
                        if (t < 10) {
                            min = "0" + String.valueOf(t);
                        } else {
                            min = String.valueOf(t);
                        }

                        endTime += myHr + ":" + min + marker;

                    }

                }



               if (j != 0) {

                 //  Log.i(TAG, "createList: " + prevHour);
                 //  Log.i(TAG, "createList: "+ prevMinute);
                 //  Log.i(TAG, "createList: " + p[1]);
                 //  Log.i(TAG, "createList: " + p[2]);


                   pHr = Integer.parseInt(prevHour);
                   pMt = Integer.parseInt(prevMinute);
                   Hr = Integer.parseInt(p[1]);
                   Mt = Integer.parseInt(p[2]);

                   if (!inEvent) {

                       cumHrW += Hr - pHr;

                       cumMinW += Mt - pMt;
                   }else {
                       cumHrB += Hr -pHr;
                       cumMinB += Mt -pMt;

                   }


               }


                prevHour = p[1];
                prevMinute = p[2];



                inEvent = !inEvent;

            }

                   //this is where we put what we figured out into text

            if (cumMinW > 60) {

                cumHrW += cumMinW /60;
                cumMinW = cumMinW%60;
            }else if (cumMinW < 0 ){
                cumMinW = -cumMinW;
                cumHrW =cumHrW - 1-( cumMinW/60);
                cumMinW = 60 - cumMinW%60;
            }


            if (cumMinW < 10){min = "0" + String.valueOf(cumMinW);}
            else {min = String.valueOf(cumMinW);}

           timeWorked = " " + String.valueOf(cumHrW) + ":" + min + " Total Time Worked";

            if (cumMinB > 60) {

                cumHrB += cumMinB /60;
                cumMinB = cumMinB %60;
            }else if (cumMinB < 0 ){
                cumMinB = -cumMinB;
                cumHrB = cumHrB- 1 -(cumMinB /60);
                cumMinB = 60 - cumMinB%60;
            }

            if (cumMinB < 10)
            {min = "0" + String.valueOf(cumMinB);}
            else  {min = String.valueOf(cumMinB);}
               timeBreaked = " " + String.valueOf(cumHrB) + ":" + min + " Total Breaks ";

            String q = ((MainActivity)getActivity()).createCalendarDate(i);

            Log.i("createList: ", q);

            eachDaysData[i] = q + "\n" + startTime + " - " + endTime + " Start and Finish" + "\n" + timeBreaked + "\n" + timeWorked;



        }else  {


           String q = ((MainActivity)getActivity()).createCalendarDate(i);

            eachDaysData[i] = q + "\nNo work performed";


        }

    }



}
[/java]

After all said and done though its working perfectly. I’m debugging it now and tracking time on my different projects. My pan is to release it on google play store and maybe figure out a way to market it a bit better than just waiting for people to search it.

 

The post Easy Time Card appeared first on SignalHillTechnology.

Powered by WPeMatico