tag:blogger.com,1999:blog-26389916560985560852024-03-17T20:03:45.609-07:00Android AdviceAndroid tutorials, examples and sample code. Come and get it!tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.comBlogger15125tag:blogger.com,1999:blog-2638991656098556085.post-55933849631139649692011-03-04T09:09:00.000-08:002011-03-04T10:25:10.207-08:00Nook Color rooting options<img src="http://sites.google.com/site/tom29lk/android/nook-color.jpg" style="float:right;height:200px;" />
Many Android enthusiasts are well aware that the Barnes & Noble Nook Color 7-inch "e-Reader" has the potential to be so much more--namely a full-blown Android tablet device. Several talented developers and hackers are working on 3 different projects aimed at helping the Nook Color realize its full potential. So, what are the projects, what are your options and which should you choose?
<a name='more'></a>
<br /><br />
<div style="border:solid 2px #cc0000;background-color:#ffbbaa;color:#000000;padding:4px;float:left;margin:10px 0px;">Whenever dealing with rooting, I have to provide a warning. 1) I am not responsible for breaking your device. 2) This may void your warranty. 3) Only proceed if you are comfortable and have fully researched the process.</div>
<br /><br />
<b>Option 1: Standard Root</b><br />
The standard root is the process of unlocking your device so that you have access to the Android Market and the thousands of great apps available such as GMail, YouTube, Google Maps, Angry Birds, etc. The look and feel of your device is the same--you'll just have some new icons and apps in the "Extras" section. This method keeps your Barnes & Noble e-Reader experience, while adding some Android goodies.<br /><br />
<span style="font-weight:bold;color:#4e9f1e;">» Instructions:</span> <a target="_new" href="http://theunlockr.com/2011/02/05/how-to-root-the-nook-color-autonooter-method/">http://theunlockr.com/2011/02/05/how-to-root-the-nook-color-autonooter-method/</a>
<br /><br /><br />
<b>Option 2: Install Android 2.2 (Froyo)</b><br />
This method actually replaces the operating system on your device, meaning the look and feel will change completely. If you have a lot of books and/or magazines downloaded, this is probably not for you as they will be gone. If, though, you are looking for more of a tablet experience, this will load the full Android OS on your Nook and once again give you access to the Android Market and all of the apps.<br /><br />
<span style="font-weight:bold;color:#4e9f1e;">» Instructions:</span> <a target="_new" href="http://theunlockr.com/2011/02/06/how-to-load-a-custom-rom-on-the-nook-color/">http://theunlockr.com/2011/02/06/how-to-load-a-custom-rom-on-the-nook-color/</a><br />
<span style="font-weight:bold;color:#4e9f1e;">» Choose this ROM:</span> <a target="_new" href="http://theunlockr.com/2011/02/06/nookie-froyo-rom/">http://theunlockr.com/2011/02/06/nookie-froyo-rom/</a>
<br /><br /><br />
<b>Option 3: Install Android 3.0 (Honeycomb for tablets)</b><br />
This method also replaces the operating system on your Nook in the same way as option 2, but loads a different version of Android--Honeycomb. Honeycomb, or Android 3, is Google's latest operating system and is optimized for tablets. At the writing of this, it is currently in a more experimental mode on the Nook, but will definitely become more stable as time passes.<br /><br />
<span style="font-weight:bold;color:#4e9f1e;">» Instructions:</span> <a target="_new" href="http://theunlockr.com/2011/02/06/how-to-load-a-custom-rom-on-the-nook-color/">http://theunlockr.com/2011/02/06/how-to-load-a-custom-rom-on-the-nook-color/</a><br />
<span style="font-weight:bold;color:#4e9f1e;">» Choose this ROM:</span> <a target="_new" href="http://theunlockr.com/2011/02/10/honeycomb-nook-emmc-rom/">http://theunlockr.com/2011/02/10/honeycomb-nook-emmc-rom/</a>
<br /><br /><br />
I would suggest if interested in rooting, start out with Option 1 (you have to do that anyway for the other 2 to work). It is the most stable and still keeps your Barnes & Noble experience. If you are not too interested in the B&N software and purchased the Nook Color for a cheap Android tablet (and at $250 it's got some very good hardware for the price), options 2 and 3 will be for you. Just realize that since these are technically hacks, I would advise you to keep up-to-date with forums at <a target="_new" href="http://www.xda-developers.com/">XDA Developers</a> for updates, warnings and other user experiences. One thing to watch out for is system updates coming from Barnse & Noble. Some may cause you to have to re-root your device. They are different each time, however and it's best to check the forums for the latest info.
<br /><br />
Here are some other links from YouTube:
<ul>
<li><a target="_new" href="http://www.youtube.com/watch?v=MUoHALWvPts">How to Root a Nook Color (PC Version)</a></li>
<li><a target="_new" href="http://www.youtube.com/watch?v=heUwp4svM7M">How to Root a Nook Color (Mac Version)</a></li>
<li><a target="_new" href="http://www.youtube.com/watch?v=U_gNvZGSJD4">How to Unroot a Nook Color</a></li>
<li><a target="_new" href="http://www.youtube.com/watch?v=4CEC0fcfbpM">Android 3.0 (Honeycomb) on Nook Color</a></li>
</ul>
<br /><br />tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com13tag:blogger.com,1999:blog-2638991656098556085.post-45483088979443010372011-02-18T13:28:00.000-08:002011-02-18T13:37:55.461-08:00App Inventor sample project: Voice to Text and vice-versaI'm back with another App Inventor tutorial for you. This time around, I have a simple tutorial that demonstrates an app that is able to convert your voice to text and, in turn, that text back to voice. Google does all of the heavy lifting in regards to converting voice and text, and thankfully makes it very easy to tap into those resources.<br />
<br />
Let's get started...<br />
<br />
1. Click on My Projects, then create a new project. I called mine VoiceApp.<br />
<br />
2. You will now see the layout screen with Palette, Viewer, Components, Media and Properties boxes. Adding components is easy by dragging objects from the Palette box onto the Viewer.<br />
<a name='more'></a><br />
3. Now drag a <b>Button</b> from the left column under <b>Basic</b> onto the palette. Select the button in the <b>Components</b> column and click <i>Rename</i> to change the name to <b>VoiceToTextButton</b>. Then, in the <b>Properties</b> column, set the Text to "Voice to Text."<br />
<br />
4. Next, drag in a <b>Label</b> and place below the VoiceToTextButton. Rename the label to <b>ResultLabel</b> and set the Text field to "".<br />
<br />
5. Drag in another <b>Button</b> and place below ResultLabel. Rename to <b>TextToVoiceButton</b> and set Text field to "Text to voice."<br />
<br />
6. Now, expand the <b>Other Stuff</b> tab in the left column and drag two final components onto the palette: <b>SpeechRecognizer</b> and <b>TextToSpeech</b>. NOTE: These are non-visible components and so will appear below the palette.<br />
<br />
Your screen should now look like this:<br />
<img src="http://sites.google.com/site/tom29lk/graphics/voice_layout.png" /><br />
<br />
7. Now connect your Android phone via usb. On your phone, go to Settings-->Applications-->Development. Enable USB debugging and Stay awake.<br />
<br />
8. On the layout screen click the button to Open the Blocks Editor. This will open a Java applet that contains all of the logic blocks/action handlers and interfaces with your phone.<br />
<br />
9. In the Blocks Editor, create the following code:<br />
<img src="http://sites.google.com/site/tom29lk/graphics/voice_blocks.png" /><br />
We need to handle the Voice to text button click event first. In this, we simply tell the <b>SpeechRecognizer1</b> to start listening. The BeforeGettingText function clears our label so the words spoken can be displayed there. The AfterGettingText function sets our label to the words spoken.<br />
<br />
10. To go the other way--text to voice--we handle the click event of the other button. <b>TextToSpeech1.Speak</b> has an output parameter that we set to our label.text field.<br />
<br />
<span style="color:#ff0000">In order for this component to work, the device must have the TTS Extended Service app by Eyes-Free Project installed. You can download this from http://code.google.com/p/eyes-free/downloads/list</span><br />
<br />
So there's the code (layout and blocks) required for building a simple voice-to-text and text-to-voice application.<br />
<br />
Download this application onto your phone by scanning this code:<br />
<img src="http://sites.google.com/site/tom29lk/android/androidadvice_voiceapp_qrcode.png" />tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com47tag:blogger.com,1999:blog-2638991656098556085.post-33946584834930389312010-10-26T07:57:00.000-07:002010-10-26T07:58:56.356-07:00Soft keyboard next button not working?I recently ran across a problem with the soft keyboard's next button not advancing focus to the next EditText. In my case I implemented a RelativeLayout in which the EditText boxes were side-by-side, instead of the usual stacked approach. It seems the Next button always tries to focus the next line, not taking into account additional objects on the same line (at least in my particular layout). Luckily, Android provides a method for overriding this behavior with custom instructions.<br />
<b><a target="_new" href="http://developer.android.com/reference/android/view/View.html#attr_android:nextFocusDown">android:nextFocusDown</a></b><br />
<a name='more'></a><br />
You have to be careful about setting <b>android:nextFocusDown</b> in your XML layout because errors will be thrown if the objects you are referencing haven't been created yet. I ran into that situation, so I set the references programmatically.<br />
<br />
In this instance, I have three side-by-side-by-side EditText objects inside of a RelativeLayout: et1, et2 and et3. Pressing the next button in et1 should focus et2. Pressing the next button in et2 should focus et3. Finally, a "Done" button is in place for et3 so we can stop there. The code to accomplish this is listed below:<br />
<pre class="brush:java">// Get references to layout objects
EditText et1=(EditText)findViewById(R.id.et1);
EditText et2=(EditText)findViewById(R.id.et2);
EditText et3=(EditText)findViewById(R.id.et3);
// Set keyboard next buttons
et1.setNextFocusDownId(R.id.et2);
et2.setNextFocusDownId(R.id.et3);
</pre>tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com2tag:blogger.com,1999:blog-2638991656098556085.post-67128818152480469132010-10-20T08:39:00.000-07:002010-10-20T08:39:07.959-07:00Get Android device screen widthQuick tip on how to get the width of your device in code. Don't use View.getWidth() -- gives the wrong result.<br />
<br />
<pre class="brush:java">Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int screenWidth = display.getWidth();
</pre>tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com0tag:blogger.com,1999:blog-2638991656098556085.post-3396715690322133362010-10-15T13:49:00.000-07:002010-10-15T14:15:45.373-07:00Angry Birds now on Android<img src="http://sites.google.com/site/tom29lk/android/angrybirds_big.jpg"><br />
<br />
The runaway hit game that started on iOS, then migrated to webOS has finally made it to Android. It is currently exclusively available for free on <a href="http://www.getjar.com/mobile/43600/angry-birds/" target="_new">GetJar - Angry Birds (12.33 MB)</a>. (Note, the site is overwhelmed at this point--I was able to download it from the mobile version of the site <a href="http://m.getjar.com" target="_new">GetJar Mobile</a>.) <a href="http://www.rovio.com" target="_new">Rovio</a>, the developer, promises the game will be available via the Android Market very soon, which should alleviate the download issues. <br />
<br />
This is big news for a platform that has struggled to gain any footing in the gaming market. Will this be the start of a push for good gaming on Android or will the likes of Apple, Nintendo, Sony and HP-Palm continue to lead the way? Time will tell. For now, enjoy Angry Birds!<br />
<br />
<b>Update:</b><br />
Looks like Rovio meant "very soon" as the app is now available in the Android Market.<br />
<br />
Video after the break...<br />
<a name='more'></a><br />
<br />
<object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/bNNzRyd1xz0?fs=1&hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/bNNzRyd1xz0?fs=1&hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object>tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com0tag:blogger.com,1999:blog-2638991656098556085.post-35057082255829316662010-10-13T08:03:00.000-07:002010-10-13T08:24:28.445-07:00Favorite Apps: Productivity<h1 style="color:#666666;"><img src="http://sites.google.com/site/tom29lk/android/android_icon_astrofilemanager.png"> ASTRO File Manager</h1><span style="color:#FF6633;font-weight:bold;">Price: <i>FREE</i></span><br />
I'm sure most people have heard of <b>ASTRO File Manager</b> by now and a large percentage probably have it installed on their device. For those not falling into either of those categories, it's time to join the party. OK, it's not a party, but it's an incredibly useful app that allows you to browse the contents of your SD card and file system. This functionality <i>should</i> be built-in to Android, but since it's not, this is the next best thing. The instances in which you'd want or need to view the contents of your SD card are countless (flash drive functionality, music, videos, etc) and this gives you the access you need to do so. This is the first app I install when I get a new Android device.<br />
<div style="background-color:#E6E0C3;border:1px solid #CFC9AF;padding:4px;color:#665F3D;">Download Links: <a href="http://www.androidapps.com/finance/apps/288913-astro-file-manager-metago" target="_new">Appolicous</a> | <a href="http://www.appbrain.com/app/astro-file-manager/com.metago.astro" target="_new">App Brain</a> | <a href="http://www.cyrket.com/p/android/com.metago.astro/" target="_new">Cyrket</a><br />
</div><br />
<a name='more'></a><br />
<h1 style="color:#666666;"><img src="http://sites.google.com/site/tom29lk/android/android_icon_batterywidget.png"> Battery Widget</h1><span style="color:#FF6633;font-weight:bold;">Price: <i>FREE</i></span><br />
The little green battery icon next to the clock in the top bar does nothing for me. Basically, I can tell if the battery is full or empty--anything else is guess-work. The <b>Battery Widget</b> app is a simple icon that sits on one of your homescreens and simply displays your remaining battery life--IN A PERCENTAGE! What a novel concept. Simple pleasures, I know, but it's one of those apps that is incredibly useful and would have trouble living without at this point.<br />
<div style="background-color:#E6E0C3;border:1px solid #CFC9AF;padding:4px;color:#665F3D;">Download Links: <a href="http://www.androidapps.com/finance/apps/290721-battery-widget-geekyouup" target="_new">Appolicous</a> | <a href="http://www.appbrain.com/app/battery-widget/com.geekyouup.android.widgets.battery" target="_new">App Brain</a> | <a href="http://www.cyrket.com/p/android/com.geekyouup.android.widgets.battery/" target="_new">Cyrket</a><br />
</div><br /><br />
<br />
<h1 style="color:#666666;"><img src="http://sites.google.com/site/tom29lk/android/android_icon_mobislenotes.png"> Mobisle Notes</h1><span style="color:#FF6633;font-weight:bold;">Price: <i>FREE</i></span><br />
There are a lot of note-taking apps in the Market, and a lot of good ones too. Some include calendars, to-do lists, pictures, online-sync, etc. The notes app that I've been using for some time is <b>Mobisle Notes</b>. You could call it barebones in that it doesn't have online-sync, calendars or allow for image upload. The reasons I like and use this app are:<br />
<ul><li>Clean, appealing interface that scales perfectly on any size screen</li>
<li>Fast and responsive</li>
<li>Customizable with sorting, language and security options</li>
<li>Ability to create local backups (with restore functionality also, of course)</li>
<li>Notes or To-Do list functionality</li>
<li>Email notes/lists</li>
<li>Smart 1-click recognition of phone numbers, addresses and email addresses</li>
</ul>Yes, it's simplified, but that's what to-do lists and notes are all about--to quickly jot something down. Mobisle Notes works very well for my purposes.<br />
<div style="background-color:#E6E0C3;border:1px solid #CFC9AF;padding:4px;color:#665F3D;">Download Links: <a href="http://www.androidapps.com/finance/apps/287345-mobisle-notes-to-do-mobisleapps" target="_new">Appolicous</a> | <a href="http://www.appbrain.com/app/mobisle-notes-to-do/mobisle.mobisleNotesADC" target="_new">App Brain</a> | <a href="http://www.cyrket.com/p/android/mobisle.mobisleNotesADC/" target="_new">Cyrket</a><br />
</div><br /><br />tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com1tag:blogger.com,1999:blog-2638991656098556085.post-39621448484387222922010-10-12T14:07:00.000-07:002010-10-12T14:11:39.638-07:00HttpPost requestMost times an HTTP Get request is all that is required for your data gathering needs. Occasionally, though, you'll need to send an HTTP Post request. It's fairly simple, just different. Here's the code:<br />
<br />
<pre class="brush: java">HttpConnectionParams.setConnectionTimeout(httpParameters, Constants.connectionTimeout);
HttpConnectionParams.setSoTimeout(httpParameters, Constants.socketTimeout);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpPost httppost = new HttpPost(Constants.MAIN_URL);
List<namevaluepair> nameValuePairs = new ArrayList<namevaluepair>(2);
nameValuePairs.add(new BasicNameValuePair("u", eUsername));
nameValuePairs.add(new BasicNameValuePair("p", ePassword));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Create a response handler
ResponseHandler<string> responseHandler = new BasicResponseHandler();
strResponseSaveGoal = httpclient.execute(httppost, responseHandler);
</pre><br />
<a name='more'></a><br />
We need to make sure that <b>nameValuePairs</b> is set to the correct size of the list (in this case 2, because we have 2 parameters, u and p). Also, be sure to remember the ResponseHandler so that you can process the returned data.tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com0tag:blogger.com,1999:blog-2638991656098556085.post-67370335132949174642010-10-12T13:27:00.000-07:002010-10-12T13:40:40.330-07:00TableLayout columns equal widthSomething easy like columns of equal width in a TableLayout shouldn't be difficult. It's not, but there is a trick to getting the desired layout. <b>layout_width="0dip"</b> and <b>layout_weight="1"</b> tags must be set in your XML layout. Here's an example:<br />
<br />
<pre class="brush: xml"><tablelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1">
<TableRow>
<!-- Column 1 -->
<TextView
android:id="@+id/tbl_txt1"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:background="@color/red"
android:textColor="@color/white"
android:padding="10dip"
android:layout_margin="4dip"
android:layout_weight="1"
android:text="Column 1" />
<!-- Column 2 -->
<TextView
android:id="@+id/tbl_txt2"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:background="@color/red"
android:textColor="@color/white"
android:padding="10dip"
android:layout_margin="4dip"
android:layout_weight="1"
android:text="Column 2" />
<!-- Column 3 -->
<TextView
android:id="@+id/tbl_txt3"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:background="@color/red"
android:textColor="@color/white"
android:padding="10dip"
android:layout_margin="4dip"
android:layout_weight="1"
android:text="Column 3" />
</TableRow>
</TableLayout>
</pre>tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com37tag:blogger.com,1999:blog-2638991656098556085.post-47439119818430078552010-10-01T10:40:00.000-07:002010-10-12T13:46:44.569-07:00Position two buttons on each side of the screenWorking with layouts in Android can sometimes be extremely simple and other times extremely difficult to accomplish seemingly simple tasks. I fought for a while with how to position two buttons on each side of the screen with a space between them. I'll spare all of my trials and tribulations, and get right to the code that makes it work...<br />
<a name='more'></a><br />
The trick is to use a <b>RelativeLayout</b> and implement the following button layout properties:<br />
<ul><li>android:layout_alignParentLeft="true"</li>
<li>android:layout_alignParentRight="true"</li>
</ul><pre class="brush: xml"><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:background="@color/white" >
<Button
android:id="@+id/back_btn"
android:layout_width="100px"
android:layout_height="wrap_content"
android:text="Prev"
android:layout_alignParentLeft="true"
android:padding="10dip"
android:background="@drawable/button"
android:textColor="@color/white" />
<Button
android:id="@+id/forward_btn"
android:layout_width="100px"
android:layout_height="wrap_content"
android:text="Next"
android:layout_alignParentRight="true"
android:background="@drawable/button"
android:textColor="@color/white"
android:padding="10dip" />
</RelativeLayout>
</pre>tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com1tag:blogger.com,1999:blog-2638991656098556085.post-27013810509167939032010-09-24T07:47:00.000-07:002010-09-24T07:47:46.755-07:00App Inventor sample project: List PickersThis sample project using Google's App Inventor demonstrates how to use ListPickers (data lists). Some of the items I'll highlight include:<br />
<ul><li>Implementing ListPickers</li>
<li>Introduce ActivityStarter</li>
<li>Creating and working with list data objects</li>
<li>Hooking into Google Maps app and Browser app</li>
</ul><br />
Let's get started...<br />
<a name='more'></a><br />
<br />
1. Click on <i>My Projects</i>, then create a new project. I called mine ConferenceApp because I'm going to create an app that displays keynote speakers and a conference and shows their speaking locations on the map.<br />
<br />
<br />
<br />
2. You will now see the layout screen with Palette, Viewer, Components, Media and Properties boxes. Adding components is easy by dragging objects from the Palette box onto the Viewer.<br />
<br />
<br />
<br />
3. Drag 3 HorizontalArrangement objects from the Palette onto the Viewer. Set all widths to "Fill Parent." The height of the first should by "Automatic" and the height of the other two below should be "20px."<br />
<br />
<br />
<br />
4. Add the logo. Drag (2) VerticalArrangement objects inside the top HorizontalArrangement. Set the widths of each of these to "Fill Parent." Then, drag an image in between the (2) VerticalArrangements. Including the VerticalArrangements on either side of the image allows us to center the logo.<br />
<br />
<br />
<br />
5. Add the first ListPicker. Below the second HorizontalArrangement, drag in a ListPicker object and name it <b>keynoteListPicker</b>. Set the width to "Fill Parent" and text to "View Keynote Speakers."<br />
<br />
<br />
<br />
6. Add the second ListPicker. Below the third HorizontalArrangement, drag in a ListPicker object and name it <b>placeListPicker</b>. Set the width to "Fill Parent" and text to "View Locations."<br />
<br />
<br />
<br />
7. Before we can move on to the Blocks Editor, we must add two additional non-visible components. These components will launch the built-in Google Maps application and Browser based on the input we send to them. In the left-column, expand "Other stuff" and drag two <b>ActivityStarter</b> objects onto your layout. (Note: they will be placed below the screen under the Non-visible components text.) Rename one to <b>MapActivityStarter</b> and the other to <b>BrowserActivityStarter</b>.<br />
<br />
<br />
<br />
8. Set <b>MapActivityStarter</b> properties. In the right-column, Properties, set the following properties, while leaving all other blank:<br />
<ul><li><b>Action: </b>android.intent.action.VIEW</li>
<li><b>ActivityPackage: </b>com.google.android.apps.maps</li>
<li><b>ActivityClass: </b>com.google.android.maps.MapsActivity</li>
</ul><br />
<br />
<br />
9. Set <b>BrowserActivityStarter</b> properties. In the right-column, Properties, set the following properties, while leaving all other blank:<br />
<ul><li><b>Action: </b>android.intent.action.VIEW</li>
</ul><br />
10. At this point, our basic layout is complete. Your screen should look like this:<br />
<br />
<img src="http://sites.google.com/site/tom29lk/graphics/conf_layout.png" /><br />
<br />
<br />
11. Now connect your Android phone via usb. On your phone, go to Settings-->Applications-->Development. Enable USB debugging and Stay awake.<br />
<br />
<br />
<br />
12. On the layout screen click the button to Open the Blocks Editor. This will open a Java applet that contains all of the logic blocks/action handlers and interfaces with your phone. <br />
<br />
<br />
<br />
13. First, we will create two list variables that will correspond to the <b>keynoteListPicker</b>: <b>speakerNameList</b> and <b>speakerURLList</b>. When a user selects the keynote speaker's name in the list, the app will launch the Browser to an informational page. To get variables in Blocks Editor, go to Built-In, then Definition and drag "def variable" onto the screen. Select the red text box attached to each variable and delete as these variables will be of type list and not text. To set each of these to type list, go to Built-In, Lists, and attach (by dragging) the <i>make a list</i> block to each of the variables. Now, to add data to our lists, we add text fields from Built-In, Text. (Drag and drop the first box in the list labeled "text.") Once in place, click on the text block to change the value. Notice that after you add one text block to the yellow <i>make a list</i> block another open puzzle piece appears below indicating that you can add another item. Continue adding text blocks to each variable list to match the image below.<br />
<img src="http://sites.google.com/site/tom29lk/graphics/conf_blocks1.png" /><br />
<br />
<br />
<br />
14. Next, create two more list variables that correspond to <b>placeListPicker</b>: <b>placeNameList</b> and <b>placeAddressList</b>. When a user selects the place name from the list, the app will launch the Google Maps app to the specified address. Follow the same approach in the previous step, using the data in the image below.<br />
<img src="http://sites.google.com/site/tom29lk/graphics/conf_blocks3.png" /><br />
<br />
<br />
<br />
15. Once all of our data is created and added to the lists, we need to inform each ListPicker which data sets they should use. To do that, go to My Blocks-->Screen1 and drag <i>when</i> <b>Screen1.Initialize</b> <i>do</i> onto the palette. This is called when the app starts. Inside of this block, place the <i>set</i> <b>keynoteListPicker.Elements</b> <i>to</i> block, which is found under My Blocks-->keynoteListPicker. Add the <b>speakerNameList</b> variable to the open puzzle piece, which is found under My Blocks-->My Definitions.<br />Then do the same for <b>placeListPicker</b> and <b>placeNameList</b> as shown below.<br />
<img src="http://sites.google.com/site/tom29lk/graphics/conf_blocks5.png" /><br />
<br />
<br />
<br />
16. At this point, our app is setup so that it will run and our data lists will be displayed when the user presses the ListPicker buttons on the main screen. The only piece left is to tell the app what to do when the user chooses one of the items in the list.<br />
<br />
<br />
<br />
17. Starting with the <b>keynoteListPicker</b>, drag <i>when</i> <b>keynoteListPicker.AfterPicking</b> <i>do</i> onto the screen. Since we want this to launch the Browser, we need to first set the URL to send--the one that corresponds to the chosen item in the list. We do that by using My Blocks-->BrowserActivityStarter--><i>set</i> <b>BrowserActivityStarter.DataUri</b> <i>to</i>. The index, or place in the list, that the user chose is determined by using the <i>position in list</i> block, which is then fed into the <i>index</i> opening of a <i>select list item</i> block of our <b>spearkersURLList</b> list. All of this will set the URL of the browser. Now we just have to launch the browser with <b>BrowserActivityStarter.StartActivity</b>. Blocks shown below.<br />
<img src="http://sites.google.com/site/tom29lk/graphics/conf_blocks2.png" /><br />
<br />
<br />
<br />
18. We need to do the same thing to launch the maps. The only difference here, is that we need to prepend some text onto the address text that we send to the map. This is accomplished with the <i>make text</i> block by setting the first text block to "geo:0,0?q=" and setting the second text block in the same was a above (just using the other two lists). Shown below.<br />
<img src="http://sites.google.com/site/tom29lk/graphics/conf_blocks4.png" /><br />
<br />
So there's the code (layout and blocks) required for building a ListPicker app that implements Browser and Google Maps launching capabilities. <br />
<br />
<br />
Download this application onto your phone by scanning this code:<br />
<img src="http://sites.google.com/site/tom29lk/android/androidadvice_listpicker_qrcode.png" />tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com4tag:blogger.com,1999:blog-2638991656098556085.post-51210464139477579372010-09-24T06:05:00.000-07:002010-09-24T06:21:51.714-07:00App Inventor sample project: Loan CalculatorOur next sample project using Google's App Inventor is the classic Loan Calculator. Some of the items I'll highlight include:<br />
<ul><li>Layout design techniques</li>
<li>Adding images</li>
<li>Math functions</li>
<li>Button actions</li>
</ul><br />
Let's get started...<br />
<a name='more'></a><br />
<br />
1. Click on <i>My Projects</i>, then create a new project. I called mine MortgageCalculatorApp.<br />
<br />
<br />
<br />
2. You will now see the layout screen with Palette, Viewer, Components, Media and Properties boxes. Adding components is easy by dragging objects from the Palette box onto the Viewer.<br />
<br />
<br />
<br />
3. Drag 4 HorizontalArrangement objects from the Palette onto the Viewer and name them (in order): <br />
<br />
<ul><li>logoHorizontalArrangement</li>
<li>principalHorizontalArrangement</li>
<li>rateHorizontalArrangement</li>
<li>monthsHorizontalArrangement</li>
</ul><br />
<br />
4. Below <b>monthsHorizontalArrangement</b>, add a Button named <b>calculateButton</b>. Set the width of this button to "Fill Parent."<br />
<br />
<br />
<br />
5. Below <b>calculateButton</b>, add a Label named <b>resultLabel</b>. Set the width to "Fill Parent," color to Red, make Bold and center the text.<br />
<br />
<br />
<br />
6. At this point, our basic layout is complete. We now have to add our components into the layout.<br />
<ul><li>Set the width of <b>logoHorizontalArrangement</b> to "Fill Parent." Then, drag (2) VerticalArrangement objects into it. Set the widths of each of these to "Fill Parent" as well. Finally, drag an image in between the (2) VerticalArrangements. Including the VerticalArrangements on either side of the image allows us to center the logo.</li>
<li>Drag a Label into principalHorizontalArrangement, name it <b>principalLabel</b>, set the text to "Loan Amount," and set the width to 100px.</li>
<li>Drag a TextBox into principalHorizontalArrangment to the right of <b>principalLabel</b> and name it <b>principalTextBox</b></li>
<li>Drag a Label into rateHorizontalArrangement, name it <b>rateLabel</b>, set the text to "Rate," and set the width to 100px.</li>
<li>Drag a TextBox into rateHorizontalArrangment to the right of <b>rateLabel</b> and name it <b>rateTextBox</b><br />
</li>
<li>Drag a Label into monthsHorizontalArrangement, name it <b>monthsLabel</b>, set the text to "Months," and set the width to 100px.</li>
<li>Drag a TextBox into monthsHorizontalArrangment to the right of <b>monthsLabel</b> and name it <b>monthsTextBox</b></li>
</ul>At this point, your screen should look like this:<br /><br />
<img src="http://sites.google.com/site/tom29lk/graphics/lc_layout.png" /><br />
<br />
<br />
7. Now connect your Android phone via usb. On your phone, go to Settings-->Applications-->Development. Enable USB debugging and Stay awake.<br />
<br />
<br />
<br />
8. On the layout screen click the button to Open the Blocks Editor. This will open a Java applet that contains all of the logic blocks/action handlers and interfaces with your phone. <br />
<br />
<br />
<br />
9. We will be calculating the following equation with the code blocks:<br /><br />
<img src="http://sites.google.com/site/tom29lk/graphics/lc_formula.png" /><br />
<br />
<br />
<br />
10. The code for this app requires several variables: To get variables in Blocks Editor, go to Built-In, then Definition and drag "def variable" onto the screen. All of our variables will be numeric so initialize them to 0 by attaching the number block from Built-In-->Math and changing 123 to 0.<br /><br />
<img src="http://sites.google.com/site/tom29lk/graphics/lc_blocks1.png" /><br />
<br />
<br />
<br />
11. The only other code block we need for this app is a responder to the button click: <i>when</i> <b>calculateButton.Click</b> <i>do</i> action. This is called when the button is clicked and will take care of the math in the app. This block is found under My Blocks-->calculateButton.<br />
<br />
<br />
<br />
12. Inside the <i>when</i> <b>calculateButton.Click</b> <i>do</i> action, all of the variables are set to their corresponding values from our loan equation above. You will get a lot of use out of the Built In-->Math blocks when constructing the equation elements. The last set of blocks sets the label with the calculated monthly payment amount rounded to 2 decimal places. <img src="http://sites.google.com/site/tom29lk/graphics/lc_blocks2.png" /><br />
<br />
<br />
So there's the code (layout and blocks) required for building a loan calculator.<br />
<br />
<br />
Download this application onto your phone by scanning this code:<br />
<img src="http://sites.google.com/site/tom29lk/android/androidadvice_loancalculator_qrcode.png" />tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com20tag:blogger.com,1999:blog-2638991656098556085.post-57450006977386859852010-09-03T14:46:00.000-07:002010-09-09T11:10:40.886-07:00App Inventor sample project: Barcode ScannerUp until now, I've created all Android apps in Eclipse with Java and XML code. While I will continue to do that, Google has released a very promising new web tool called <a href="http://appinventor.googlelabs.com/">App Inventor</a>. This tool allows you to create simple Android apps in the browser all while requiring the developer to have exactly zero (0) knowledge of Java or XML. I've played around with the tool a bit and found that it is indeed easy and intuitive to create simple, 1-screen apps (as of now, it doesn't allow multiple screen apps so that really limits the complexity). For anything even remotely advanced, you'll still have to use the old methods (writing code).<br />
<br />
In order to test it out, I decided to build an app--after all, that's the best way to learn, right? I wanted something simple, yet at least a little interesting so I went with a barcode scanner. I know, the app already exists, but this would be fun to see what I could accomplish in about 30 minutes. The app scans a barcode or QRcode and either searches Google with the result or opens the URL in a browser (if the QRCode is a URL, obviously).<br />
<br />
So away we go...<br />
<br />
<a name='more'></a><br />
1. Click on <i>My Projects</i>, then create a new project. I called mine AndroidScanner.<br />
<br />
2. You will now see the layout screen with Palette, Viewer, Components, Media and Properties boxes. Adding components is easy by dragging objects from the Palette box onto the Viewer.<br />
<br />
3. Drag 5 objects from the Palette onto the Viewer: <br />
<ul><li>a <b>Button</b> to launch the scanner [rename to "scanButton"]</li>
<li>a <b>Label</b> to display the scan result [rename to "resultLabel"]</li>
<li>another <b>Button</b> to launch the browser [rename to "resultActionButton"]</li>
<li>an <b>ActivityStarter</b> (non-visible)</li>
<li>and finally the <b>BarcodeScanner</b> (non-visible)</li>
</ul>Your screen should look like this:<br />
<img src="http://sites.google.com/site/tom29lk/graphics/screenLayout.jpg" /><br />
<br />
4. Now connect your Android phone via usb. On your phone, go to Settings-->Applications-->Development. Enable USB debugging and Stay awake.<br />
<br />
5. On the layout screen click the button to Open the Blocks Editor. This will open a Java applet that contains all of the logic blocks/action handlers and interfaces with your phone.<br />
<br />
6. For this app, we're first going to need 2 variables: <b>buttonAction</b> (value equals 2 if url is scanned, 1 otherwise) and <b>barcodeResult</b> (value is the resulting string from the barcode scan). To get variables in Blocks Editor, go to Built-In, then Definition and drag "def variable" onto the screen. Set buttonAction as type number by attaching the number block from Built-In-->Math. Likewise, set barcodeResult as type text by attaching the text block from Built-In-->Text.<br />
<img src="http://sites.google.com/site/tom29lk/graphics/variables.jpg" /><br />
<br />
7. The rest of the code blocks respond to actions. The first of these is the <i>when</i> <b>scanButton.Click</b> <i>do</i> action. This is simply a call to start the barcode scanner. This block is found under My Blocks-->scanButton.<br />
<img src="http://sites.google.com/site/tom29lk/graphics/scanButtonClick.jpg" /><br />
<br />
8. The next action to handle is the barcode scanner result. So grab the <i>when</i> <b>BarcodeScanner1.AfterScan</b> <i>do</i> and place it on the screen. Here, I first check to see if the result is a number. If so, I have a good idea it's a standard barcode and so I set the text of the <b>resultActionButton</b> to "Search Google for product" and set the variable <b>buttonAction</b> to 1. If the result is not a number, I then check to see if it is a URL by looking for "http://". If it is a URL, I set the text of <b>resultActionButton</b> to "Visit URL in browser" and set the variable <b>buttonAction</b> to 2. Finally, if the result is not a number or URL, I set the text of <b>resultActionButton</b> to a generic "Search Google for result" and set the variable <b>buttonAction</b> to 1. After all of the conditional statements, I set the <b>barcodeResult</b> variable to the result of the scan so I can use it later.<br />
<img src="http://sites.google.com/site/tom29lk/graphics/barcodeScannerAfterScan.jpg" /><br />
<br />
9. The final action to handle is the resultActionButton handler. So grab the <i>when</i> <b>resultActionButton.Click</b> <i>do</i> and place it on the screen. Here I determine if I should search Google with the result or open the browser and load a URL. I accomplish this by checking the <b>buttonAction</b> variable. If it's 1, search Google, otherwise, open the URL in the browser.<br />
<img src="http://sites.google.com/site/tom29lk/graphics/resultActionButtonClick.jpg" /><br />
<br />
And there ya have it. A simple, functioning barcode scanner app. <br />
Go ahead and test it out by creating your own QRCodes with the <a href="http://http://zxing.appspot.com/generator/">QR Code Generator</a> from ZXing. You can scan the codes directly from your computer screen.<br />
Hope you enjoy!<br />
<br />
Download this application onto your phone by scanning this code:<br />
<img src="http://sites.google.com/site/tom29lk/android/androidadvice_barcodescanner_qrcode.png" />tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com31tag:blogger.com,1999:blog-2638991656098556085.post-83112185889768785672010-09-03T08:34:00.000-07:002010-09-03T08:34:57.654-07:00Check Android network connection sample codeChances are if you're building an Android app, you're going to be using the device's data connection. After all, the beauty of these things is having the power of the internet at your fingertips. You have to be careful though when building apps to always for the existence of an active connection. Failure to do so and then trying to fetch data could result in a negative user experience or possibly even crash.<br />
<br />
Luckily, there's an easy way to check for data connections prior to making calls so you can either proceed or handle gracefully. The sample class below provides everything you need. Just insert into your project and call when necessary...<br />
<br />
<a name='more'></a><br />
<br />
<pre class="brush: java">public class Networking {
/*
*@return boolean return true if the application can access the internet
*/
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
return false;
}
}
</pre>tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com6tag:blogger.com,1999:blog-2638991656098556085.post-10487090589946468902010-09-02T21:26:00.000-07:002010-09-02T21:28:00.903-07:00Asynchronous web requestMany good Android apps pull in some kind of external data to keep everything current. When making web requests for data, it is important to use asynchronous calls on a new thread so that the UI remains responsive to the user. Asynchronous calls do require a bit more code than synchronous calls, but it is a minimal amount and pays big dividends to the polish of the app.<br />
<br />
There are 2 functions required for the call: 1) makeHTTPRequest and 2) handleHTTPResponse. Sample code for each of these is provided below.<br />
<br />
<a name='more'></a><br />
<b>makeHTTPRequest</b><br />
<pre class="brush: java">private void makeHTTPRequest() {
// Increment counter so we don't try infinite number of http requests
// httpTryCount declared as a private class variable: private int httpTryCount = 0;
httpTryCount++;
// Show dialog
// progressDialog1 declared as class variable: private ProgressDialog progressDialog1 = null;
progressDialog1 = ProgressDialog.show(FoodDetail.this, "", "Loading...", true, false);
// Fire off a thread to do some work that we shouldn't do directly in the UI thread
Thread t = new Thread() {
public void run() {
try {
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, Constants.connectionTimeout);
HttpConnectionParams.setSoTimeout(httpParameters, Constants.socketTimeout);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
String requestURL = "http://www.yoursite.com/data_feed.php?id=5";
//Log.d(TAG,requestURL);
HttpGet httpget = new HttpGet(requestURL);
// Create a response handler
ResponseHandler<string> responseHandler = new BasicResponseHandler();
strResponse = httpclient.execute(httpget, responseHandler);
handler.sendEmptyMessage(0);
} catch (Exception e) {
//Log.d(TAG, "Error occurred during load "+ e);
handler.sendEmptyMessage(-1);
} //try
} //run()
}; //thread
t.start();
}
</pre><br />
<b>handleHTTPResponse</b><br />
<pre class="brush: java">private Handler handler = new Handler() {
@Override
public void handleHTTPResponse(Message msg) {
// close loading progress dialog
progressDialog1.dismiss();
// If timeout, try again -- try maximum of 2 times
if(msg.what == -1 && httpTryCount < 2) makeHTTPRequest();
else if(msg.what == -1 && httpTryCount >= 2) {
// If 2 failed attempts, show error message
Builder builder = new AlertDialog.Builder(FoodDetail.this);
builder.setTitle("Oops");
builder.setMessage("An error occurred. Please make sure you are connected and try again.");
builder.setPositiveButton("ok", null);
builder.show();
} else if(msg.what == 0) {
httpTryCount = 0;
// Do something with your returned data, strResponse, here
}
Log.d(TAG, "response handler: "+msg);
Log.d(TAG, "response text: "+strResponse);
};
};
</pre><br />
The inline comments should give you an idea of what is going on in each function. (Several class variables are described in the comments.)<br />
<br />
Enjoy your new UI-friendly asynchronous web requests.tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com3tag:blogger.com,1999:blog-2638991656098556085.post-12523085751853125552010-09-01T14:35:00.000-07:002010-09-02T21:29:52.889-07:00Welcome to Android AdviceThis blog is meant to be a resource for Android developers. As someone who has created a few Android apps, I want to share some of the knowledge I've gained throughout the process as well as gain feedback from my readers. I will focus a lot on simple tasks, accomplished programmatically and offer sample code. Often times sites provide assistance that is either too beginner focused or too advanced for most people's needs. I hope to fall somewhere in the middle to provide information that is helpful to a wide-ranging group of people.<br />
<br />
Enjoy Android Advice!tkhttp://www.blogger.com/profile/06390051897876600373noreply@blogger.com0