Friday, December 31, 2010

Problems updating Android to 2.3 in Ubuntu

If you were using Ubuntu 9.10 (karmic) because you wanted to avoid some issues with Eclipse and Android ADT plugin that happened on newer versions on Ubuntu, well now is time to upgrade to the latest Ubuntu 10.10 (maverick) if you want to update to the latest Android 2.3 (gingerbread).

You may have discovered this after the update finished using Android SDK and AVD Manager tool and you sadly realize that your Android development environment was turned useless without a single word of warning. Latest Android SDK version depends on GLIBC_2.11 but it's no available for previous versions of Ubuntu, so unless you want to take the risk of using a different repository trying to find an update with unknown consequences to other components, upgrading is your only possible path.
If this is not a serious bug we should reconsider the definition of the word.

The origin of the problem is that Android SDK distribution is not package based and thus no dependencies are considered before updating the software. This is clearly a nonsense. Google has taken a completely different approach with Chrome which is cleverly distributed from a package repository as we can see in this screenshot of Ubuntu Software Center.


Android SDK must be distributed as packages as Chrome does, otherwise there is no way to prevent this problems happening again and again in the future. We are only scaring people away of Android development with this poor policies. It's true that the requirements page was updated and GLIBC 2.11 is listed now as a requirement, but when you discover it, it's too late. You expect some verifications done from software doing an update that cannot easily be reverted.

This is perhaps the most important bug, but there are others after upgrading to Ubuntu 10.10 (maverick) and Android SDK 2.3 (gingerbread) some other things are still broken, for example hierarchyviewer does not run out of the box and you have to manually copy some libraries,
Android SDK and AVD Manager updates some packages again an again ignoring they are already installed and some deficiencies of the Android ADT Layout editor, to name a few.

I complained about many things about Android in this blog and it seems that in one way or another they were fixed in following releases, so I hopefully think this would be the case.

Monday, May 24, 2010

Android 2.2 changes

Android 2.2, a minor platform release, arrived last week with a bunch of changes ranging from Dalvik JIT and Kernel Memory Management Boost to a new Launcher.

You can check the highlights to get a bigger picture.
But there's one change that's almost not announced anywhere, and I consider it very important too.

With the advent of Android 2.2 you can install or upgrade the SDK and tools in Linux as root and the permissions are (almost) correct and you don't need further changes in this situation, or what is almost the same we can declare android-fixperms-updated defunct and no longer needed.

This is very good news if you are using continuos integration on Android as was described by various posts in this blog.

Great job Google.

Sunday, March 28, 2010

Android course to be held at SkillsMater in April

The Android course authored by myself and published by Ricston is to be held at SkillsMater (London, UK) again on April 14-16 2010.

There are still some seats available for those that want to attend.

Ross Mason, founder and CTO at MuleSoft who attended this Android course said:
"it provided a great introduction to developing on the Android platform. You can see that the author has crafted a well-structured course that covers the core knowledge required by developers to understand the potential of the platform and how build apps on it. Delivery was smooth, the instructor very well informed. This course provides an excellent way to get proficient in Android in a few days."

Wednesday, February 24, 2010

Android: Generate javadoc for your project

So you want to follow the best practices and generate the javadoc for your android project from Eclipse and as soon as you start you hit the first wall, messages like "package android.app does not exist" completely fill your output console.

What's wrong ?
And most important, how can you generate complete javadoc with links to android documentation ?




Find out how reading the complete article in Google Docs: http://docs.google.com/View?id=ddwc44gs_240hkc84xfd

Thursday, January 28, 2010

Android Testing: testing XML or JSON parsers

There are many occasions where your Android application relies on external XML or JSON messages or documents obtained from web services. These documents are used for data interchange between the local application and the server. There are many use cases where XML or JSON documents are generated by the local application to be sent to the server. Ideally, methods invoked by these activities have to be tested in isolation to have real unit tests and to achieve this we need to include some mock files somewhere in our APK to run the tests.
But the question is where can we include these files ?
Let's find it out.


Read the complete article in Google Docs:
http://docs.google.com/View?id=ddwc44gs_239fhchvfds

Wednesday, January 20, 2010

android-fixperms updated

Android SDK 2.1 was released including minor API changes and bug fixes. For information on changes and fixes, see the Framework API section.
If you install Android SDK in a multi-user environment or in a continuous integration server, as was showed in previous posts, you should correct the permissions after updating. That is android-fixperms's raison d'ĂȘtre and as usual, it was updated to support this new SDK version.

Find more information and examples at http://sites.codtech.com/android/android-tools.

Tuesday, January 19, 2010

Android UI: Colored dialogs


Android UI: Colored dialogs


















This document can be read in Google Docs (http://docs.google.com/View?id=ddwc44gs_232dw6nf66h), cut and paste link if you have problems accessing it.

If you have problems seeing the images, like the icon in this box don't blame me, it seems to be an issue when you publish to Blogspot from Google Docs.


















introduction


Sometimes you need a stronger visual cue for a very special situation that may arise during the lifecycle of your application.






















One approach is to copy <ANDROID-SDK>/platforms/android-2.1/data/res/drawable-mdpi/panel_background.9.png, change its color and then use it as the dialog background in your theme.



For example, extending the default Theme





















1 <style name="MyColorDialogTheme" parent="android:Theme.Dialog">


2  <item name="android:windowBackground">@drawable/color_panel_background/item>


3 </style>









This was discussed in stackoverflow, but I though there should be a better solution. Copying and changing images is not very attractive if you want to have several colors or even decide it at runtime.










colored dialogs



We will be trying to discover the simplest yet usable way of colorizing AlertDialogs.

Some standard behavior should be changed, so we need to extend AlertDialog.

MyColorDialog and Builder


What we are going to do is to extend AlertDialog to create a class that given a theme that defines the android:tint attribute then all the Views in the dialog are tinted with this specific color.

We need to iterate over the Views so a simple iterator is also defined.













  1 public static class MyColorDialog extends AlertDialog {


  2    private static int NONE = -1;


  3    private int tint = NONE;


  4  


  5    /**


  6     * @param context


  7     * @param theme


  8     */


  9    protected MyColorDialog(Context context) {


 10       super(context);


 11       init();


 12    }


 13   


 14    /**


 15     * @param context


 16     * @param theme


 17     */


 18    protected MyColorDialog(Context context, int theme) {


 19       super(context, theme);


 20       init();


 21    }


 22   


 23    /**


 24     * 


 25     */


 26    private void init() {      


 27       final Theme theme = getContext().getTheme();


 28       final TypedArray attrs = theme.obtainStyledAttributes(new int[] { android.R.attr.tint });


 29       tint = attrs.getColor(0, NONE);


 30    }


 31   


 32    /* (non-Javadoc)


 33     * @see android.app.Dialog#show()


 34     */


 35    @Override


 36    public void show() {


 37       super.show();


 38       setTint(tint);


 39    }


 40   


 41    /**


 42     * @param tint


 43     */


 44    public void setTint(int tint) {


 45       this.tint = tint;


 46       


 47       if ( tint != NONE ) {


 48          Iterator<View> vi = iterator(android.R.id.content);


 49          while ( vi.hasNext() ) {


 50             tintView(vi.next(), tint);


 51          }


 52       }


 53    }


 54   


 55    /**


 56     * Set the {@link tint} color for the {@link View}


 57     * 


 58     * @param v the {@link View} to change the tint


 59     * @param tint color tint


 60     */


 61    private static void tintView(final View v, final int tint) {


 62       if ( v != null ) {


 63          final Mode mode = PorterDuff.Mode.SRC_ATOP;


 64


 65          if ( v instanceof ImageView ) {


 66             final Drawable d = ((ImageView)v).getDrawable();


 67             if ( d != null ) {


 68                d.mutate().setColorFilter(tint, mode);


 69             }


 70          }


 71          else {


 72             final Drawable d = v.getBackground();


 73             if ( d != null ) {


 74                d.setColorFilter(tint, mode);


 75             }


 76          }


 77       }


 78    }


 79   


 80


 81    /**


 82     * @param button


 83     */


 84    public void setCancelButton(Button button) {


 85       button.setOnClickListener(new View.OnClickListener() {


 86


 87          @Override


 88          public void onClick(View v) {


 89             cancel();


 90          }


 91   


 92       });


 93    }


 94   


 95    /**


 96     * @param button


 97     */


 98    public void setPositiveButton(Button button) {


 99       button.setOnClickListener(new View.OnClickListener() {


100


101          @Override


102          public void onClick(View v) {


103             dismiss();


104          }


105   


106       });


107    }


108


109


110    /**


111     * Return a {@link ChildrenIterator} starting at the {@link ViewGroup}


112     * identified by the specified resource id.


113     *  


114     * @param res resource id of the {@link ViewGroup} to start the iteration


115     * @return iterator


116     */


117    public Iterator<View> iterator(int res) {


118       final ViewGroup vg = (ViewGroup)findViewById(res);


119       return new ChildrenIterator<View>(vg);


120    }


121


122


123    public static class Builder extends AlertDialog.Builder {


124


125       private MyColorDialog dialog;


126


127       public Builder(Context context) {


128          super(context);


129          dialog = new MyColorDialog(context);


130       }


131


132       public Builder(Context context, int theme) {


133          super(context);


134          dialog = new MyColorDialog(context, theme);


135       }


136       


137       @Override


138       public MyColorDialog create() {


139          return dialog;


140       }


141


142       @Override


143       public Builder setMessage(CharSequence message) {


144          dialog.setMessage(message);


145          return this;


146       }


147


148       @Override


149       public Builder setTitle(CharSequence title) {


150          dialog.setTitle(title);


151          return this;


152       }


153


154       @Override


155       public Builder setPositiveButton(CharSequence text,


156             OnClickListener listener) {


157          dialog.setButton(BUTTON_POSITIVE, text, listener);


158          return this;


159       }


160


161          @Override


162          public Builder setIcon(int iconId) {


163             dialog.setIcon(iconId);


164             return this;


165          }


166


167    }


168 }







Iterator






This is the iterator used in MyColorDialog.













 1 public static class ChildrenIterator<V extends View> implements Iterator<V> {


 2    ArrayList<V> list;


 3    private int i;


 4


 5    public ChildrenIterator(ViewGroup vg) {


 6       super();


 7       


 8       if ( vg == null ) {


 9          throw new RuntimeException("ChildrenIterator needs a ViewGroup != null to find its children");


10       }


11       init();


12       findChildrenAndAddToList(vg, list);


13    }


14   


15    private void init() {


16       list = new ArrayList<V>();


17       i = 0;        


18    }


19   


20    @Override


21    public boolean hasNext() {


22       return ( i < list.size() );


23    }


24


25    @Override


26    public V next() {


27       return list.get(i++);


28    }


29


30    @Override


31    public void remove() {


32       list.remove(i);


33    }


34   


35    @SuppressWarnings("unchecked")


36    private void findChildrenAndAddToList(final ViewGroup root, final ArrayList<V> list) {


37       for (int i=0; i < root.getChildCount(); i++) {


38          V v = (V)root.getChildAt(i);


39          list.add(v);


40          if ( v instanceof ViewGroup ) {


41             findChildrenAndAddToList((ViewGroup)v, list);


42          }


43       }


44    }


45   


46 }
















styles


Let's just define some styles to colorize our dialogs using android:style/Theme.Dialog as the parent.













 1 <?xml version="1.0" encoding="utf-8"?>


 2 <resources>


 3    <!-- Orange -->


 4    <style name="OrangeDialogTheme" parent="@android:style/Theme.Dialog">


 5       <item name="android:tint">@color/orange_tint</item>


 6    </style>


 7   


 8    <style name="OrangeAlertDialogTheme" parent="OrangeDialogTheme">


 9       <item name="android:windowBackground">@color/transparent</item>


10    </style>


11   


12   


13    <!-- Red -->  


14    <style name="RedDialogTheme" parent="@android:style/Theme.Dialog">


15       <item name="android:tint">@color/red_tint</item>


16    </style>


17   


18    <style name="RedAlertDialogTheme" parent="RedDialogTheme">


19       <item name="android:windowBackground">@color/transparent</item>


20    </style>


21 </resources>






colors











 1 <?xml version="1.0" encoding="utf-8"?>


 2 <resources>


 3    <color name="red_tint">#88FF0000</color>


 4    <color name="blue_tint">#880000FF</color>


 5    <color name="yellow_tint">#88FFFF00</color>


 6    <color name="purple_tint">#88995f86</color>


 7    <color name="orange_tint">#aaffbf00</color>


 8    <color name="magenta_tint">#88ff33cc</color>


 9    <color name="transparent">#0000</color>


10 </resources>





usage


From our Activities we can use MyColorDialog as any other AlertDialog, in this case we will be using a custom theme defined previously













1 dialog = (new MyColorDialog.Builder(this, R.style.RedAlertDialogTheme))


2 .setTitle("Warning")


3 .setMessage("This phone will self-destruct in five seconds.\nPlease stay back.")


4 .setPositiveButton("Dismiss", null)


5 .create();


6 dialog.show();






samples


These are some dialogs created using different color variations.













conclusion



We introduced a simple way of changing the appearance of your dialogs just from styles.

These classes are oversimplifications from the ones that are part of auito, formerly known as autoandroid. More information and samples will be provided soon.



Comments are gladly welcome.






Copyright © 2010 Diego Torres Milano. All rights reserved.