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.
Friday, December 31, 2010
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.
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:
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
Find out how reading the complete article in Google Docs: http://docs.google.com/View?id=ddwc44gs_240hkc84xfd
Labels:
android,
continuous integration,
eclipse,
java,
javadoc
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
http://docs.google.com/View?id=ddwc44gs_239fhchvfds
Labels:
android,
continuous integration,
java,
junit,
TDD,
test driven development,
Web services
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.
Subscribe to:
Posts (Atom)