Android data analysis and error handling

The featured picture for this post is actually a cnc project where my end mill broke moments before completing. But if you’re an android developer you probably have had the little gear icon in your email inbox or more recently emails from fabric.

Scroll down to the bold title to skip my rambling musings.

These are amazing tools but I ran into a problem that I couldn’t handle with these tools. I was creating a new revised method/function within my app that generates a string for the user to read.  I wanted the new method to produce the exact same result as the old method when handling old type situations, plus it needed to handle some new situations as well. After building it and debugging I found that it produced the exact same string 99.996% of the time. This variation appears to unavoidable. Even better I can use the old method 99% of the time thus making the chances that the user encounter this error non-existent.

Not foolish enough to make assumptions I deployed my new method invisible to the user and using fabric waited for my “events” to register showing a similar match rate. Once I had confidence that th match rate matched my testing I would make the switch visible to the user.

Much to my surprise the match rate was way lower. .. around 50%. I went through and made sure that everything was right. I then added a custom attribute to show me both strings. This is where my problem arose. Fabric truncates strings and custom attributes from the same event are split up in the online review area. The data was almost useless.

—  So I decided to make my own poor mans version. Here’s  how i did it. —

On the android side I used the Volley Network. Once imported I made the standard volley pattern which can be accessed statically. Volley is awesome.


public class VolleyNetwork {

    private static VolleyNetwork mInstance;
    private RequestQueue mRequestQueue;
    private static Context context;


    private VolleyNetwork(Context contex)
    {
        context = contex;
        mRequestQueue = getRequestQueue();


    }


    public static synchronized VolleyNetwork getmInstance(Context context){
        if (mInstance == null){
            mInstance = new VolleyNetwork(context);
        }
        return mInstance;

    }



    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null){

            mRequestQueue = Volley.newRequestQueue(context.getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQue(Request<T> req)
    {
        req.setShouldCache(false);
        getRequestQueue().add(req);
    }





}

I was already using the volley class above to make reports to my server. Now I added a new class for my “home brewed version of fabric”.  As you can see this static method report_Mismatch() has all the data needed to use volley and make a report to your server. I’m using a simple password because the worst a hacker could do with this info is post irrelevant strings to the server .txt file.  The “key1” attribute is how my server knows what type of data is coming in. Is it a custom error report? Or is this for some other process completely.


public class Reporting {


    private final static String TAG = "Reporting";
    public static String MY_PREF = "com.yourname.yourapp";

    final public static  String SERVERADD = "http://yourserver.com/server/";
    final static private String typeOne = "passwordp1";


    //report clock in/out status by updating my row - no feedback
    public static void report_MisMatch(final Context context, final String myReportData )
    {
        Log.d(TAG, "report_MistMatch: ");
        final String mTag = "report_MisMatch";  //if frequently use volley network to post different things the origination of the response needs to be tracked


        StringRequest postRequest = new StringRequest(Request.Method.POST, SERVERADD,  new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.d(TAG, mTag + "onResponse: " + response);
               
                Log.d(TAG, "onResponse: sent");

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                                
                Log.d(TAG, "onErrorResponse: error");
            }
        })

        {
            @Override
            protected Map<String, String> getParams()
            {
                Map<String, String>  params = new HashMap<String, String>();
                params.put("key1", "somedata");
                params.put("report", myReportData);
                params.put("gentypeone", getLoginCredentials(context));


                return params;
            }
        };



        VolleyNetwork.getmInstance(context).addToRequestQue(postRequest);

    }


    //These will be retreived for all functions
    private static String getLoginCredentials(Context context)
    {
        String[] data = new String[4];

        SharedPreferences myPref = context.getSharedPreferences(MY_PREF, Activity.MODE_PRIVATE);

        return new String(typeOne + "randomly_generated_passkey");


    }



}

On the server side my code was already written due to other server feature. Its php because for literally no money you can setup a server/web address to provide back end app support. These type of low cost servers usually always have php/mysql. Im thinking of transitioning to digital ocean but it seems like a lot of work and I’m lazy.
 

 

 

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *