Tuesday, July 31, 2012

Android: Disabling or Blocking the back button

One of the tablet apps I've been working on is a massive data collection app. It is set up to run in vertical mode and it's easy for the user to accidentally push the back button and exit a data collection form potentially losing their work.  Luckily it is also easy to disable the back button by preventing the click action or putting a dialog up when it is touched to confirm the exit of the screen.

Here you go. Nothing to it.

@Override
public void onBackPressed() {
}

Thursday, July 26, 2012

Android logcat disappears with multiple devices attached

I was recently working on an Android project testing on multiple devices attached via USB and rotating the testing between them. After a while, all trace stopped being displayed and wouldn't come back. I disconnected devices, reset the debugging perspective, restarted Eclipse, restarted the laptop but nothing worked.  I typically have more than one Android device plugged in and in the past two years have never had any problems.  The solution was to go into DBMS perspective and select the specific device in the upper left hand panel. For whatever reason, it wasn't automatically switching based on what was running.

Monday, July 23, 2012

Data type, Android and Sqllite



When working with Android content providers and cursors, pay close attention to the datatypes you are using to pull the data from the database. If you set the data type of the sqlite field to NUMERIC and are using it to store LONG values, be sure to pull it from the database as a long and not a int. Pulling it as an Integer will lead to truncation of the long value. So for example,
Since CreateDate is a long, I need to pull it like this
data.setCreateDate(c.getLong(c.getColumnIndexOrThrow(DatabaseConstants.F_CREATEDATE)));  

and not like this

data.setCreateDate(c.getInt(c.getColumnIndexOrThrow(DatabaseConstants.F_CREATEDATE)));  

Here's the complete cursor processing.


  while (!c.isAfterLast()) { 

      MyData data = new MyData(); 

      data.setFirstName(c.getString(c.getColumnIndexOrThrow(DatabaseConstants.F_FIRSTNAME))); 

      data.setLastName(c.getString(c.getColumnIndexOrThrow(DatabaseConstants.F_LASTNAME))); 

      data.set_id(c.getInt(c.getColumnIndexOrThrow(DatabaseConstants.F__ID))); 

      data.setCreateDate(c.getLong(c.getColumnIndexOrThrow(DatabaseConstants.F_CREATEDATE))); 

      data.setIsdeleted(c.getInt(c.getColumnIndexOrThrow(DatabaseConstants.F_ISDELETED))); 

      data.setLastUpdate(c.getLong(c.getColumnIndexOrThrow(DatabaseConstants.F_LASTUPDATE))); 

      list.add(data); 

      c.moveToNext(); 

 }  


Thursday, July 19, 2012

More Android code standards

When mapping edit text fields, select boxes and other elements that have GUI interaction with the user  within Android Activity Java code, the first thing you need to know is the resource id where the data will be coming from. Flipping back and forth between the xml resources and the Activities is a pain. Be sure to put a comment in your code next to the variable that indicates the xml resource id like below. This easy piece of documentation and code commenting is invaluable to the developers who will be maintaining your code


 private EditTextView mPersonId;   //   R.id.PersonIdETV
 private Spinner mPersonJob;     //   R.id.PersonJobSPN

Friday, July 13, 2012

Randomly generating a date before or after today



I was recently building a calendar type app for a client and needed to test out the placement of items on the calendar. Unfortunately their test data returned all items with the exact same date. So I wrote a little bit of code that would randomly replace the date in the data with AM PM (the calendar data didn't have a time just whether or not it was in the morning or afternoon and randomly assign a date within a week both before and after today.



 private String generateRandomAmOrPm() {  
         final Random myRandom = new Random();  
         boolean amOrPm=        myRandom.nextBoolean();  
         if (amOrPm) {  
              return "AM";  
         } else {  
              return "PM";  
         }  
      }  
      private int generateRandomDate() {  
            final Random myRandom = new Random();  
              boolean plusOrMinus=        myRandom.nextBoolean();  
              int dateToMove = myRandom.nextInt(6); // plus or minus 6 days  
              if (plusOrMinus) {  
                   return 0-dateToMove;  
              } else {  
                   return dateToMove;  
              }  
      }  

Tuesday, July 10, 2012

Android HTTP Clients

Making a backend http call to retrieve or send data is a very common Android task.  There are a couple of different ways to do it from Apache HTTP Client to HttpURLConnection. The blog article below summarizes the advantages and disadvantages of both and is a must read.

http://android-developers.blogspot.com/2011/09/androids-http-clients.html

Tuesday, July 3, 2012

Launching settings from a button

I was recently working on an Android tablet project that needs to detect connectivity to a network. If the user wasn't connected to the Internet, I would throw up a dialog box telling them to connect. I decided to take this one step further and take them to the setting screen that would allow them to connect to wifi.

So to do this, I needed to send an intent that would launch settings. Easy enough.The Android snippet below does that.


Intent intent = new Intent(Intent.ACTION_MAIN);
 intent.setClassName("com.android.settings", "com.android.settings.Settings");
startActivity(intent);


Now that's ok, but it takes the user to settings main screen. Which is nice but a better way to do that is to send them directly to the wireless settings screen.  This can be done using the code below.


Intent intent =new Intent(Settings.ACTION_WIRELESS_SETTINGS);
startActivity(intent);



Sunday, July 1, 2012

Naming Conventions for Views

I recently worked a project as a lead developer working with several other developers on a very complex tablet app that was collecting medical history information. So lots of complex forms, widgets, and layouts.  One of the things that they worked on is setting up the xml layout files which is the first step in the Android development process. The screens looked great but we didn't have consistency on the naming of the individual layouts. For most simple apps, this isn't a big deal. But some of these forms had a dozen checkboxes, plus a dozen radiogroups plus a dozen spinners plus the text views, linear layouts and edit texts.

When I went to do the mapping to our json, I couldn't look at an R.id.field and know exactly what it it was for. For example, we had R.id.rash_field1 but that didn't tell me that it was an edit box that goes with SKIN-->Rash-->Color-->OtherValue

I would have name the resource R.id.skin_rash_color_othervalueET

This tells me a lot about what is going to be entered into the field and what the field purpose is as well as where in the data model I'm likely to be binding it to.

I try to use the following abbreviations for naming fields. This isn't an exhaustive list but will get you thinking on how you want to name the fields.

EditText: R.id.fieldnameET
TextView: R.id.fieldnameTV
Spinner: R.id.fieldnameSpn
Linearlayout: R.id.fieldnameLL
Checkbox: R.id.fieldnameCB
RadioGroup: R.id.fieldnameRG
RadioButton: R.id.fieldnameRB