Sunday 25 December 2011

A few simple ways to manage "Low on space" on HTC Desire

HTC Desire is a great Android phone providing a rich user experience with it's Sense UI. It runs smooth and fast. Several cool features made me love this phone at first sight. That was until I get the "Low on space" notification. HTC was so stingy that it had included just 576 MB of ROM of which around 430 MB is consumed by Android, HTC Sense and HTC's bundled apps. This leaves just around 140 MB of space for the user to use for installing his downloaded apps. This is very meagre and soon every HTC Desire owner hits the dreaded "Low on space" notification. This handicaps the expandability of the phone which is the core strength of any Android phone. Nevertheless I still love my phone. I had come up with a few techniques to "manage" this problem as shown below.

  • Move to SD: The first and the most obvious choice is to move apps to SD card. It's not possible to move every app to SD. Also, the apps for which there is a widget available and you use it, should not be moved to SD card.
  • Contacts Storage: Contacts storage may increase from around 10Mb to 80Mb, due to facebook contacts. Hence don't add facebook contacts to phone contacts (People), though you can link them. 
  • Clear Cache: Cache of several applications (like Market) can increase over time. Clear cache by selecting the app in Settings->"Manage Applications"->"Downloaded" tab and clicking the "Clear Cache" button. The easier way to do is by using the app Android System Cleaner - Cache Clean tab.
  • Low storage Apps: The beauty of Android is, there are several apps offering the same functionality and hence the user has a lot of freedom to pick and choose. Hence you can always find an app for a particular functionality that uses lesser storage than the one that you currently have on your phone. Look out for such apps and replace your current one. (I replaced Aldiko with Moon-reader and Rock Player with Mobo player, on this principle)
  • Adobe Flash: Adobe Flash (updates) normally consumes around 10MB of space. Uninstall the updates, you will not loose much on the functionality.
  • Internet Cache: Keep your stock Internet App's cache size at a minimum. I keep it at 2 MB.  You can do this by launching the internet app, choose settings and then selecting cache size. This is internal cache and is different from app cache. App cache size is over and above this setting, which we cannot control. Any amount less than 2 MB may increase the app cache size to mammoth proportions.
  • App Data: Periodically, you can delete all the data in social networking apps like, facebook, linked in/droidin etc. To do this,go to Settings->"Manage Applications". Click on those apps and click "Clear Data". The only trouble is, when you launch them now you will be prompted to enter your userid and password again.
  • Uninstall Apps: Finally, if you are not using any of your apps, uninstall them.

Thursday 8 December 2011

Android - ListView without ListActivity


ListView is easier to use and straight forward if we extend ListActivity. But what happens if the activity already extends some other activity. Unfortunately , we do not have an option to extend two activities.

No issues, we could still create our customized list without extending ListActivity.

In the below example 'selectprofile.xml', a list called profilelist is declared as below.








<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/LinearLayout01"
android:layout_width="fill_parent" android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="@color/bgcolor">
    

<TextView 
 android:id="@+id/header"
 android:layout_width="fill_parent"
 android:layout_height="50dp"
 android:textColor="@color/headtxtcolor"
 android:text="Select Profile"
 android:textSize="20dp"
 android:textStyle="bold"
 android:gravity="center"
 android:layout_gravity="center_horizontal"
 android:background="@drawable/button_image"
/>


<ListView 
android:id="@+id/profilelist"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false"
android:layout_weight="1"
android:dividerHeight="1dp">
</ListView>


</LinearLayout>


In the code

 static final ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();

 public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.selectprofile);
       ...
       ...
       initializeList();
       getProfData();
       lv.setAdapter(adapter);
}

protected void initializeList(){
    
    
     lv = (ListView)findViewById(R.id.profilelist);
    
     adapter = new SimpleAdapter(this,list,
  R.layout.selectprofile_row,
   new String[] {"id","name","sex","year","date"},     
 new int[]{R.id.profid,R.id.name,R.id.sex,R.id.year,R.id.crdatevalue}
   );

  list.clear();    
 
}

Here 'selectprofile_row' defines the layout of the list row.
After populating the array list in getProfData() , set adapter to the list view. You can also add listener to the list item , if needed.

Android - Why not use alert dialog instead of spinner?

Spinner in android is more confusing to use. It is also hard to customize it for our needs. Based on the purpose, a simple alert dialog could be used as a replacement for spinner.
In my requirement, I had a button. When the button is clicked, the options should be listed. Based on the selected options, the value of the button is set.
Here is the code for the above requirement.

In the Xml, define the button layout.
<Button
android:id="@+id/annualButton1"
        android:layout_width="50dp"
        android:layout_height="40dp"
        android:layout_toRightOf="@id/totincome"
        android:layout_marginLeft ="10dp"
        android:layout_marginRight="5dp"
        android:layout_alignTop="@id/totincome"
        android:background="@android:drawable/btn_default"
        android:textSize="15dp"/>


In the code, alert dialog is called when the button is clicked.  Based on the option selected, button value is set.

annualButton1.setOnClickListener(new OnClickListener()
{
              public void onClick(View v)
              {
                    sButtonClicked = "button1";
                    showSpinner();
                                   
                }
        });
 
 
protected void showSpinner()
    {
            AlertDialog.Builder b = new Builder(this);
            String[] options = {sItem1,sItem2};
                 
            b.setTitle("Select an option" );
                  b.setSingleChoiceItems(options, -1,new DialogInterface.OnClickListener(){
                        public void onClick(DialogInterface dialog, int which)
                        {
 
                     dialog.dismiss();
                     switch(which){
                     case 0:
                     {
                           annualButton.setText("p.a");;
                           sAnnual = sItem1;
                         break;
                     }
                     case 1:
                     {
                           annualButton.setText("p.m");
                           sAnnual = sItem2;
                         break;
                     }
                                 
                 }}
 
                        });
                  b.setPositiveButton("CANCEL", new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int id) {
                   
                      dialog.dismiss();
                
                      }
             });
                 
                 
                  b.show();}
          
It is much simpler than using a spinner. Isn’t it?

Android - Generic declaration of colours


It is very important that we declare background colours and layouts generically. I made this mistake of hardcoding the colours in the individual xml files. It became really hectic every time I wanted to try different colours. Then finally, I decided to declare them generically. Here is how you do it.

Declare mycustomcolors.xml in the values folder. Define all the colour codes here.


<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="bgcolor">#F8F8F8</color>
<color name="headtxtcolor">#e69b28</color>
<color name="othertxtcolor">#000000</color>
<color name="headerEnd">#999999</color>
<color name="headerStart">#000000</color>
<color name="profileEnd">#E69B28</color>
<color name="profileStart">#FFAE33</color>
<color name="sectionEnd">#FFFFFF</color>
<color name="sectionStart">#CCCCCC</color>
</resources>

   
The above colour codes can be used in shapes and other layouts. This is for a gradient colour button profile_band.xml in drawable-hdpi. 

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<gradient
    android:startColor="@color/profileStart"
    android:endColor="@color/profileEnd"    
    android:angle="90" /> 
    
</shape>
Text colours used in an xml..

 <TextView
        android:id="@+id/profName"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/header"
        android:paddingLeft="10dp"
        android:text="profile name"
        android:textColor="@color/othertxtcolor"
        android:textSize="14dp"
        android:layout_gravity="center_vertical"
       />


As mobile apps should have good screen appearance , it is very important that you have the flexibility to try various options.