Wednesday, October 31, 2012

Barcode Integration.

Luckily, in some cases, I plan stuff out a bit in advance:

I integrated barcode scanning for the Youth Impact Mobile app, that the staff will have to carry on them.

Below are some screenshots and a couple great starting reference pages.  In total, it really took me no time to integrate barcode scanning via Intent.  I'd say 30 minutes.

This is ZXing's page for their Intent Integrator:

http://code.google.com/p/zxing/wiki/ScanningViaIntent

What they left out on the page (and I requested them to add to their page), was a link to this class:

http://code.google.com/p/zxing/source/browse/trunk/android-integration/src/com/google/zxing/integration/android/IntentResult.java?r=1273



Obviously, the first image is taken from my tablet.. the application itself is pretty plain right now, Haven't added in any of the fragments to modify the participants information, but I have a couple fragments for that in my other project that I'll migrate over.


  This is what the barcode looks like when it is captured by the Barcode app.

Saturday, October 27, 2012

Working with JSON and ListPreferences! Wooo Doggy, exciting!

So today, I made a preference screen, that dynamically pulled down JSON data.. and displayed it.

The issue with the Kiosks that it is resolving is pretty simple.  At read and respond, the person in charge wants to be able to see how long someone has been clocked in at their station.  Well, the current app didn't have any way really to give that information.  So, I added a web service method that would return that information for a given kiosk.  In .NET this was easy.  On the android side it took a little reading, and fiddling though.

This is how I do my HTTP requests.  I changed the URL to protect the innocent,
and it should allow me to use certificates in the headers eventually, so that only clients with
the right signature have access to the web service.

StringBuilder builder = new StringBuilder()
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://#####"+String.valueOf(arg0[0]));try {
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
    HttpEntity entity = response.getEntity();
    InputStream content = entity.getContent();
    BufferedReader reader = new BufferedReader(new InputStreamReader(content));
    String line;
    while ((line = reader.readLine()) != null) {
    builder.append(line);
   }
} else {
       }
} 
catch (ClientProtocolException e) {
 e.printStackTrace();
} 
catch (IOException e) {
e.printStackTrace();
}
return builder.toString();

This code, combined with this:

JSONArray jsonObject = new JSONArray(data);
ListPreference l = (ListPreference) findPreference("clocktimes");
CharSequence[] entries = new CharSequence[jsonObject.length()]
CharSequence[] entryValues = new CharSequence[jsonObject.length()];
for(int i = 0; i < jsonObject.length(); i++)
{
  JSONObject j = jsonObject.getJSONObject(i);
  entries[i] = (CharSequence) j.get("message");
  entryValues[i] = (CharSequence) String.valueOf(i);
}
l.setEntries(entries);
l.setEntryValues(entryValues);


Allowed me to customize a PreferenceScreen with a ListPreference inside to dynamically display data.

Keep in mind, there are going to be a lot of try / catches in there.. and you'll want to use that ASync task, that I mentioned in my post earlier.

Like so:


Monday, October 22, 2012

Start Application at Boot-up

So, I needed to add an autostart for the application for these Kiosks.

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

This goes below your <application> tag.

<receiver
        android:name=".StartMyServiceAtBootReceiver"
        android:enabled="true"
        android:exported="true"
        android:label="StartMyServiceAtBootReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
</receiver>

Then you add a class named "StartMyServiceAtBootReceiver" in your src folder of your Android Application project.  This is the code you should add for it.. assuming your main activity class is named: "MainActivity".

public class StartMyServiceAtBootReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
            Intent i = new Intent(context, MainActivity.class);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        }
    }
}

Saturday, October 13, 2012

Background threads in Android.

Frequently, in Android, you need your application to actually "do" something.  Hey, it's an application, it's to be expected.  In Android, best practice dictates you don't use the main UI thread to do this. It makes your application non-responsive until the task completes.  In fact, a default Android Project won't even allow you to run things on the main thread. 

This is where your friendly ASyncTask comes in.   

This task below, takes an integer as input, and then the background thread then returns a string, the void method is where you can update your UI etc for the result, the string that is considered input for that method, is in fact the same string returned in the "doInBackground" method.

This code can be customized to take in whatever initial variable type, and whatever end variable type. (I.E. Modify "Integer" to "String")


private class task extends AsyncTask<Integer, Void, String> {

private Exception exception;

protected String doInBackground(Integer... arg0) 
{
   StringBuilder builder = new StringBuilder();
            
           
   return builder.toString();
}
protected void onPostExecute(String feed) throws NullPointerException 
{
            
}

}