Tag Archives: Android

Touchpal keyboard alternative with slidedown for symbols - Multiling O

Touchpal keyboard alternative with slide down for symbols – Multiling O

Touchpal keyboard alternative

So you’ve been an Android user for several years and Touchpal keyboard seems to the best Android keyboard out there, with its killer feature – swiping down to input symbols. You can’t live without that feature, but you really hate the annoying ads in Touchpad that was recently introduced. Luckily, I’ve found the near perfect Touchpal keyboard alternative for you – Multiling O Keyboard. Continue reading

[Solved] onDataChanged not called, Android Wearable

I was doing a school project on Android Wearable for the past few days. A strange bug happened.

I used  Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq)for triggering  onDataChanged in WearableListenerService. However, I noticed that sometimes  onDataChanged is not called even though the putDataItem method has fired.

The strange thing is this bug only happens on the first call, subsequently the calls trigger normally. More interestingly, the bug only happens sometimes, once in a while, the first call will trigger normally.

Aftering debugging and getting nowhere, I decided to get help from stackoverflow. I found an answer that was relevant:

http://stackoverflow.com/a/24697312/1472186

The answer suggests adding a time field into the DataMap  so that the data is really changed every time. I did not think that was the cause of the problem, because I followed the online tutorial and had a count value in my DataMap, which increments every time. This should have caused the data to change every time.

However, after I added the time field into the DataMap, the bug disappeared. So it was true that my old implementation was not causing any changes. The count value did not work. After thinking through the process again, I figured out why.

The count did increase after each call, from 0 to 1, 2, 3, … However, those values are stored in the DataMap within the wearable device, not on the phone. So it was possible that wearable device already has a DataMap in which there is a data with count 0, although my phone app does not have the DataMap yet. When I send a new DataMap with count 0 from phone to the wearable, that DataMap is already present on the wearable, and hence no change will be detected and onDataChanged will not be triggered.

For time, since the current time is unique and always increasing, there would not be a case where the time in DataMap on the phone already exists on the wearable, hence always triggering onDataChanged.

Whatsoever – My Forth Android App

Link to the app in Play Store: https://play.google.com/store/apps/details?id=thack.ac.whatsoever

It all started out as an experiment on new views in Android L developer preview(now known as Android Lollipop). Sometime at late September, I was researching on how to Card-like views in Android and found out that CardView is part of the new Widgets introduced in Android L, together with RecyclerView.

When trying out RecyclerView(which is a replacement for old ListView), I thought of this idea to develop a Android app as a search engine for social media sites. I liked the Facebook style where each post is wrapped inside a card, so I want to build a interface where there is a RecyclerView, inside RecyclerView there would be a list of statuses/posts, each wrapped in a CardView.

For the social media site integration, I started with Twitter, and the integration with Twitter API was quite straight-forward thanks to a library called twitter4j. Everything is well-formatted and follows Java conventions and I did not have to do to much to populate the data into my CardView and RecyclerView.

Then I went on to try integrate Facebook, however, unfortunately, it appears that Facebook Graph API does not allow searching of posts/statuses. Hence, I had to give up on Facebook and try other social media sites.

The next one was Google+, there is a Google+ API client for Android, however, it requires logging in. I did not want that since I want to user to be able to search without having the trouble to log in. So in the end I used the Google APIs and parsed the json “half manually”. That is to take advantage of the pre-defined Google+ classes on Google+ provided in the Google+ API Java client, such as com.google.api.services.plus.model.Activity . This was pretty cool as all I had to do was to use response.parseAs(ActivityFeed.class).

Then I decided that Instagram should be also integrated. Instagram has a pretty well-documented API although it is a relatively new platform, however, there are no native or 3rd party libraries for Java or Android so I have to manually parse the json response. This involves some error handling but was still manageable. A good practice would be to create a Class and use  response.parseAs, but I was a bit lazy and decided to just use some local variables.

At that point of time, CardView and RecyclerView were not well-documented, in fact there were no official documentations (now they are documented). So I have to work with limited resources and try to figure out how to use them by myself, it was a painful but exciting experience for me. Of course I put in a lot of time in designing the UI and improving the UX. I also got quite a few suggestions from my friends I tried to do modifications to improve the app.

So here it is, the Android App is in Google Play Store, please do give it a try!

Life with Android Wearable – LG G Watch

It has been almost one month since I bought LG G Watch, and I am happy with how it is changing my daily life.

LG G Watch is a gadget rather than watch

The purpose of buying this watch is really just to try out how it is like to have a wearable gadget rather than getting a nice watch. And of course if I have some good ideas, I can use Android wearable API to develop apps that make use of this new technology.

Appearance wise, it really look more like a gadget-on-the-wrist rather than a watch. Wherever I go, people who notice this will instantly recognize this as something that has much more functionalities than normal watches. The watch performed beyond my expectation in terms of functionalities that it provides. In fact, my friends often joke about what happens if I wear this into exam venues.

More useful than I thought

Some functions are triggered by the events that happened to the phone, these are most likely notifications. The phone sends the notifications to the watch, and then the watch would display them in a nice way. By default, firstly, there will be a card(similar to Google Now on the phone) at the bottom of the display, swiping up will show the main message on the screen, then swiping to the left will show another screen that allows you to open the corresponding app on the phone whereas swiping to the right will dismiss the notification. This default behaviour is not very useful, so the apps that want to take advantage of the wearables need to implement more actionable screens for the users. For example, for the updated Whatsapp, the main screen shows a list of conversations, you can see the full details of each conversation if you swipe to the left once, and you can also reply via voice input by swiping to the left again. However, others told me that it looks very weird if someone is staring at the watch for longer than 3 seconds, so better check long messages on the phone.

Other than reading chat notifications, the function that I use the most is agenda.

IMAG0603

By default, today’s events on the phone will be synced to the watch and displayed as a agenda card, swiping up will show more details such as venue, additional notes. Believe it or not, this saves a lot of time and frees up my hands from taking out the phone, especially on a crowded bus or during cycling.

It also comes with a simple step counter to record how many steps you have walk everyday.

IMAG0607

You can set a goal and motivate yourself to walk more rather than taking bus. Personally, I find it pretty effective. There are times that I wanted to take a bus but decided not to after looking at the step count. (My goal is set to 10k steps every day)

Voice control system is very important for the watch, most self-initiated actions are via the voice control. Saying “Okay, Google!” will trigger the voice control. It may not be able to match Siri as a personal assistant, but there are still a lot of things that you can do, including setting up reminders, sending SMS and email, calling someone, asking a question or just simply performing a Google search. Apart from the default commands, “start XXX” will trigger apps that are specifically developed to run on the wearable device.

Other cool features are music controller for the phone, navigation(with google map).

Update: Recently in December 2014, the music controller is updated with useful functions to control volume and go to next or previous track. The UI is also pretty good.

Card Safe – My Third Android App

Link to the Android app in Play Store: https://play.google.com/store/apps/details?id=thack.ac.cardsafe (still waiting for listing as of now)

This project started off with the idea that I can take advantage of the NFC functionality in Android to read data from NUS Matric Card and develop some app to facilitate processes like registration and collection in various events.

Unfortunately, I realized that the matric number sector in the card is key-protected I believe the staff would not let me have the read/write access to the data inside. So that means I can only get my hands on the ID of the card, which is given by the manufacturer, public and most importantly unique(although there may exist techniques to duplicate the cards with the same ID illegally).

I was thinking about the card’s unique ID and necessity for NUS students. Then I suddenly got this idea, why not save some information and use the card as a key to access it. I thought this would be quite useful and relatively easy to implement, so I started working on a prototype. Setting up database and the single activity with a single layout file was quite easy for me, especially just after I have worked on a bigger Android project. The only thing that is troublesome is the different tags in different cards and their different ways to access the card. I have tried ezlink cards and DBS Debit Card, however, I was not able to get something like a unique ID from either of them. In the end, I only managed to get the NUS matric card working.

After a few hours of coding and designing, the version 1.0 with basic functionalities like setting up new “safe”, retrieving content of the safe and modifying existing safe was finished and uploaded to Google Play Store around 3am. Hope it gets good feedback and proves to be a fun and useful app for people(mostly for NUS students now).

Reflection on the development of Animol – an Android app for Chemistry

The summer, I took a job offer from a lecturer that taught me in the last semester. The task was to develop Animol – a “simple” Android app for a lecturer from Chemistry department. The main functions proposed were displaying videos and short info for different experiments, synchronising experiment data with the server, on which new experiments can be added. I was in charge of developing the Android app, there are two more students working on iOS and server respectively.

(Link to the released app in Play Store:  https://play.google.com/store/apps/details?id=ac.thack.hands_onchem.hands_onchem)

The initial UI proposed looked very simple, so I did not expecting to spend too much time on it. After all, accepting the offer would mean that I will be working on 2 programming projects this summer, the other one being the orbital. I thought that my experience in Android game development would make this an easy job. As it turned out, making a “normal” Android app is somehow harder than making a simple Android game.

I started working on the project in late May. To set up the basic structure of the app, I need to learn about ListView and ListAdapter, to be able to populate data into a list. This did not take very long. After reading a few tutorials, I managed to find a good template that includes a ListView and a ListAdapter for displaying a list of songs. After removing some extra items, the basic list layout was done. Along with the ListView I also learnt simple SQLite functions to insert and retrieve data from Android’s SQLiteDatabase.

From there I got the basic framework and started working on specific requirements of the project. The next big thing is the embedded YouTube video. This was relatively easy for me(as compared to my counterpart working on iOS version of the app) as Google provides a YouTube Android Player API. (It was only later that I found out the downsides of the API.)

As I expected, the part that took the most time is the layout/UI. I had one YouTubePlayerView, several ImageViews and  scrollable TextViews and the whole layout also needs to be scrollable. So I did some research and followed the recommended way: Wrap all the ImageViews and scrollable TextViews in a LinearLayout which is then wrapped in a ScrollView. I also need to add some codes in the Activity to prevent scrolling conflicts between the inner views and the ScrollView wrapper.

After several modifications according to the requirements, my UI for the app was accepted in the weekly meeting. Then we all started working on server communication, I had a few choices here. I can either use the DefaultHttpClient (inherited from HttpClient) from Apache for Android, or the AndroidHttpClient. Since there were several templates for DefaultHttpClient, I just followed the templates and wrote a ServiceHandler Class(just a utility Class, not inherited from Service or Handler Class) that handles the http calls. Then, I can use AsyncTasks in my activities to call methods in ServiceHandler for server communications.

It was on 1 July that things that things got a bit messy. I got my new MacBook Air and decided to shift all programming related work there. It just so happened that Android Studio had update moments ago. So it was a cross-platform and cross-version migration of an Android Studio project. This caused me several problems:

First, the Gradle version needed to be updated for the new Android Studio version, however my project was already set up for the old Gradle version and there was no way to do a straight forward upgrade of my project. So I decided to create a fresh project and copy paste my old codes into it, saving time to research on solving the compatibility issues.

The other problem was that the new build versions (version 19 and 20) does not seem to have good support for the package com.android.support:appcompat-v7. So I decided to strip the support package and made my app only compatible with devices running SDK version 15 (Android 4.0.1) or above.

The last and the most annoying one is the rendering of the ActionBarView in Android Studio. For some strange reasons, after I migrated the project, all the views stopped showing previews in Android Studio, saying that there are some problems with the ActionBarView. It worked fine on phones but lack of preview made it extremely difficult for me to design the layout as required. So I raised the issue on stack overflow. It seemed that removing the appcompat package helped to some extent but the new views created still has errors in rendering. Hence, this problem is still not solved.

Having solved most issues with the migration, I then started on more sophisticated operations involving retrieving and processing data from server and updating local database accordingly, as well as sending app usage statistics(click counts for each experiments) back to the server. There was an interesting problem regarding the timing for server communication. Initially, my implementation was to fetch new experiments and send the counts when the user opens the app (via onCreate in the splash screen activity). However, the concern was that the Android user may not have the habit to close the apps and server communication won’t happen unless the user explicitly kills the app. Then I planned to change the implementation to sending the count  and fetching new data when the app is sent to the background, but the disappointing news is that this is very hard for Android to detect sending app to background unless I use some hacks(which may not work in a long term).

So to ensure that the count is sent to the server, I created a BaseActivity that extends Activity, in which onPause will trigger AsyncTask to send count and onResume will trigger AsyncTask to fetch new data. This implementation suited the purpose, but it cost too much network traffic. This is because when user navigates from activity A to activity B, onPause in A and onResume in B are both called, effectively meaning 2 http calls will be executed for each tap on the screen.

Hence, the final decision was to add an interval of 30 seconds between any two server communications. This means after the first server communication, a timestamp is saved to the SharedPreferencesSubsequent server communications will need to go trough a check on timestamp to see if 30 seconds has passed from the previous server communication. This way, we can be sure that when the user launches the app (or relaunch from background), new data will be fetched. And for each subsequent navigation, onPause will be called before onResume, ensuring that the count will be sent in the next server communication.

The next big thing is push notification. This function was not in the original plan, but we all agreed that this should be an important part of the app in the event that we want to notify the users of new experiments or announcements. As it turned out, Google was kind enough to provide a Google Cloud Messaging(GCM) service for Android. The implementation was quite straight forward, except for the fact that it requires Google Play Services, which could be a potential problem for phones purchased in other countries that do not have Google services pre-installed.

The last problem was to dynamically refresh the view when the database gets updated by background server communications. I did not researched into how I can get a result from AsyncTask in my activity and the Android app is structured such that the views are drawn in onCreate of the activity, via setContentView(R.layout.activity_main); .  So in order to refresh the view with updated data, I need to either redraw the whole view or detect the changes to database and update the corresponding view elements. And I can either do it in onResume or set up a listener for database activities. In the end, I took the easy way out and forced a re-draw of the views in onResume (with 2 seconds delay) for each successful fetching of new data in the background.

Overall, I would say that this an awesome experience for me. I learnt a lot of things, not only on Android development but also on server communication techniques involving http request/response and database operations with SQLite. I am looking forward to working on my next Android project, or even pick up an iOS one if I have the necessary resources.

Using Java Naming Conventions and Andriod Naming Issue

This article on naming conventions is based on Java, some rules apply to other programming languages as well.

I highly recommend this article to new programmers who are yet to have their own naming styles (for functions, variables, etc).

This is especially useful if you are just starting to learn programming.

If you are a experienced programmer with your own naming styles, you may want read this and see if there is anything to improve your naming techniques.

Original article: http://java.about.com/od/javasyntax/a/nameconventions.htm

Note on meaningfulness and length:

When choosing a name for an identifier make sure it’s meaningful.

Don’t worry about the length of the name. A longer name that sums up the identifier perfectly is preferable to a shorter name that might be quick to type but ambiguous.

There are 4 types of letter cases for naming:

Lowercase is where all the letters in a word are written without any capitalization e.g.

[/crayon]
Uppercase is where all the letters in a word are written in capitals. When there are more than two words in the name use underscores to separate them e.g.

[/crayon]
CamelCase (also known as Upper CamelCase) is where each new word begins with a capital letter e.g.

[/crayon]
Mixed case (also known as Lower CamelCase) is the same as CamelCase except the first letter of the name is in lowercase e.g.

[/crayon]

Standard Java Naming Conventions:

Basically, follow the naming guidelines below when you write your programs, you will find your programming process more systematic, efficient and professional than if you don’t.

Packages: Names should be in lowercase. With small projects that only have a few packages it’s okay to just give them simple (but meaningful!) names:

[/crayon]
Continue reading