Tips & Tricks: Happy new year!

Hi developers,

This week again no real tips and tricks from PullesSon – Android.

All we want to do with this post is wish you a happy new year and we hope you will begin the year close to your friends and family. We wish you all health, love and a lot of Android in 2012.

See you next year!

Kind regards,
PullesSon – Android.

Tips & Tricks: Merry Christmas

Hi developers,

Today no real tips and tricks from us. All we want to do is to wish you all a merry Christmas, because we don’t want you to miss gathering with family and friends while you are reading our tips and tricks or developing.

Android Snowman

Happy holidays!

Kind regards,
PullesSon – Android

Tips & Tricks: Screen sizes

Hi Android developers,

Last week was hectic, we needed to reinstall and reconfigure the backend server of Perka’s File stash.

This week we will take a little twist and we will talk about a topic that is more focused on design: Screen sizes.

When designing Android apps the best practice is to use Density-independent pixel (dp) as measure. A dp is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a “medium” density screen. At runtime, the system transparently handles any scaling of the dp units, as necessary, based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160).

Another best practice is to use wrap_content and fill_parent in XML so the layout will scale automagically. Also a RelativeLayout is a good practice, it will keep the distances the same even if the screen is bigger or smaller.

Also keep in mind of using layout and orientation qualifiers, which can be added to the /res/ directory. This will make it easy to make to make a different layout for another screen size and/or orientation.

For images used in for the different screens, you might want to use draw9patch to make image.9.png files. These files are processed by the tool and you can assign how it will be stretched.

Another good practice is to use Fragments, this will allow you to reuse designs in different layouts. You can combine the fragments in a layout or just use 1 fragment as layout.

Extended information can be found at: Supporting Multiple Screen Sizes and Android Training Multiscreen

Kind regards,
PullesSon – Android

Tips & Tricks: BugSense

Hi developers,

Last week there was no tips and tricks from PullesSon – Android, because of the workload.

This time it will be not really about code, but about bugs.

For those who found the errors overview in the Android market console useful, but almost never get errors reported, there is BugSense.

BugSense will catch all the exceptions and send it right away to your BugSense dashboard and if you have it activated, also it will send you notification to your email.

Signing up is easy and it will direct you to add an application. Be sure to remember your API Key, even it’s also in your dashboard available.
After this there has to be made some code change in your application. First you have to download and add the library file to your project, then you need to add the internet permission by adding to the android manifest file. Then in the onCreate() method you have to add: BugSenseHandler.setup(this, YOUR_API_KEY);, where YOUR_API_KEY is your API Key from your dashboard (or the one previously remembered). Also don’t forget to include import com.bugsense.trace.BugSenseHandler; else you will get compile errors.

The dashboard is really intuitive and easy to understand. A quick overview of the errors reported is shown on the first page of your dashboard with exception name, file name, line number, OS version and application version. From here you can click on the error and it will show details.

The details page will show you all that’s included in the quick overview plus the amount of occurrences, a short stacktrace, last error instance time, ip, country, phone model, screen information and communication information.

In the configuration of the app registered in the dashboard you can add project viewers, like developers that want to know the error information. Also there is an option to set the application stage between testing and production.

Besides they have twitter and a chat to talk for support.

We also got an email from BugSense, mentioning if we needed help to implement the code, because there were no errors reported.
Seems we configured all well and we did some good coding, because there were just no errors generated. After provoking an exception we received it in the dashboard.

Good service and support on the BugSense’ side and easy to implement and understand. Keep up the good work.

Regards,
PullesSon – Android

Tips & Tricks: CalendarContract

Hi Android dev’s,

Like most of you already know: We got sauce! or in normal tems, Google released the source of Android 4.0 a.k.a. Ice Cream Sandwich (ICS). For more information see: http://source.android.com/.
This is the first version with code for tablets and phones. And with the source available the carriers and custom rom developers will roll out ICS soon.
That’s why today we will talk about a new feature in the SDK of ICS.

CalendarContract is the Calendar API for Android 4.0 (SDK 14) and up.

CalendarContract provides developers an interface for the calendar URI’s and data columns.

CalendarContract.Calendars:
This table holds the calendar specific information. Each row in this table contains the details for a single calendar, such as the name, color, sync info, etc.
CalendarContract.Events:
This table holds the event specific information. Each row in this table has the info for a single event. It contains information such as event title, location, start time, end time, etc. The event can occur one-time or can recur multiple times. Attendees, reminders, and extended properties are stored on separate tables and reference the _ID to link them with the event.
CalendarContract.Instances:
This table holds the start and end time for occurrences of an event. Each row in this table represents a single occurrence. For one-time events there will be a 1:1 mapping of instances to events. For recurring events, multiple rows will automatically be generated which correspond to multiple occurrences of that event.
CalendarContract.Attendees:
This table holds the event attendee or guest information. Each row represents a single guest of an event. It specifies the type of guest they are and their attendance response for the event.
CalendarContract.Reminders:
This table holds the alert/notification data. Each row represents a single alert for an event. An event can have multiple reminders. The number of reminders per event is specified in MAX_REMINDERS which is set by the Sync Adapter that owns the given calendar. Reminders are specified in minutes before the event and have a type.
CalendarContract.ExtendedProperties:
This table hold opaque data fields used by the sync adapter. The provider takes no action with items in this table except to delete them when their related events are deleted.

Add a new event to the calendar directly:

long startMillis = 0;
long endMillis = 0;
Calendar beginTime = Calendar.getInstance();
beginTime.set(2011, 11, 14, 16, 00);    //year, month, day, hour, minute
startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2011, 11, 14, 17, 00);    //year, month, day, hour, minute
endMillis = endTime.getTimeInMillis();
 
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, startMillis);
values.put(CalendarContract.Events.DTEND, endMillis);
values.put(CalendarContract.Events.TITLE, "Ice Cream Sandwich Source Code Release");
values.put(CalendarContract.Events.DESCRIPTION, "Release the ICS source code, so all android followers are happy and will be busy with compiling their custom firmware base on the new source code.");
values.put(CalendarContract.Events.CALENDAR_ID, 3);
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);

For this method you will need the permission: android.permission.READ_CALENDAR, if you don’t want extra permissions in your app, just launch a calendar intent with the event data.

To get a list of all the calendar event, just query Calendar.Events through the ContentResolver.

Regards,
PullesSon – Android

Tips & Tricks: AsyncTask.

Hi Android developers,

This week in tips and tricks: AsyncTask.

A AsyncTask is a class that provides you an easy interface to create a new thread. It is recommended to use it by background tasks, like downloading through a internet connection.
From Honeycomb (SDK API level 11) it’s even mandatory to use Asynctask’s for internet connection downloads and if it’s not done it will force close the application. So it will be also for Ice Cream Sandwich.
Besides it’s mandatory it’s also really handy. You will take pressure from the UI Thread and it will be processed faster and parallel to the UI Thread.

You have to start with:

private class DownloadFilesTask extends AsyncTask<void, void, void>

There are five methods to implement which are:
onPreExecute:
The first method called in the AsyncTask, called on the UI thread. In this method you usually prepare the progressbar, if needed.

@Override
protected void onPreExecute() {
    super.onPreExecute();
    showDialog(DIALOG_DOWNLOAD_PROGRESS);
}

doInBackground:
This is the method where is all the action. This method executes the time consuming tasks and publish the task progress, executed in background thread.

@Override
protected String doInBackground(String... params) {
    // perform Long time consuming operation
    return null;
}

onProgressUpdate
Method that updates the progress of the AsyncTask, run on the UI thread. This is where you update the progressbar.

@Override
protected void onProgressUpdate(String... progress) {
    mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}

onPostExecute
The final method that gets called after doInBackground finishes, here we can update the UI with the results of the AsyncTask, like removing the progressbar.

@Override
protected void onPostExecute(String unused) {
    try {
        dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
    } catch (Exception e){
        Log.e("APP_NAME","Unknown exception caught: " + e.getMessage());
    }
}

onCancelled
This method gets called if the AsyncTask.cancel() methods is called, terminating the execution of the AsyncTask.

@Override
protected void onCancelled() {
    dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
}

To execute it just use:

new DownloadFilesTask().execute(param1, param2);

As you can see the AsyncTask is easy to implement and the methods are really easy to use and understand. It is highly recommended to use AsyncTask for task that doesn’t have to update the UI Thread.

We use AsyncTask in Let Me Android That For You and Perka’s File Stash.

For more information: http://developer.android.com/reference/android/os/AsyncTask.html

Regards,
PullesSon – Android

Tips and Tricks from PullesSon Android

Hi Android developers,

Starting from today we are going to (try to) blog every week some tips and tricks from our team.

The previous post about the ads can be seen as the tips and tricks for this week, but for this first post we will try to add some more information resources and the next tips and tricks will be more detailed into the code.

Websites:
Android Developers
Stack Overflow
Android Developers Google Group
Google Code Android project hosting

IRC (Internet Relay Chat):
Android Developers IRC

SDK on PC:
path-to-sdk-directory/samples/android-{sdk-version}/
path-to-sdk-directory/extras/android/compatibility/v4 or v13

And of course a good source is: Google, to search for example codes and tutorials.

Regards,
PullesSon Android

From AdMob to MobClix

Hi Android-friends,

Yesterday we decided to go from AdMob to MobClix.
In the past we had several issues with AdMob and then like a a few months ago our account was blocked, due to fraud. We don’t do fraud so we opened an issues on their website.

First of all we noticed that the website to open an issue is almost impossible to find and with some hours of looking through support pages we found the form to submit an issue. It was a half-baked form, no stylesheets, questions with half the answers and above all pointed to AdSense and not AdMob. We filled it out the best we could and we got a thank you page and a confirmation email.

Then we waited like a month and no response from AdMob, neither from AdSense, neither from Google.

So we started searching for a contact email, again searching for hours on the support pages and we found an AdSense and AdMob contact email. We decided to forward the confirmation email to both of the contact emails. Like a month later we found an email from AdSense in our inbox, if we could provide our login, so we did and all they answered was: We can’t find it in our system. And no word from AdMob. So sad to hear a Google company let us down.

That was why we started to look for an alternative, we found several, had some comparisons and decided to use MobClix. It is even more simple to implement as AdMob and all campaigns are based per app, so you can choose the ads providers on application level. Besides they use PayPal for their payments, which makes it easier for most of the people.

All are apps with ads: Call Restrictor Free and Let Me Android That For You are updated with the new ads, they look nicer as AdMob and the implementation tooks us like 10 minutes (including removing the AdMob code).
Also in the first 24h on Mobclix we have earned more then we did in 3 months with AdMob.

So F U AdMob and welcome MobClix.

Regards,
PullesSon Android