Tuesday, April 23, 2013

List View - How to avoid black selected items

  Twice I faced the same problem. I had used listview. If you drag on the view it would show all the list elements.

Solution:

   In the code, use
listview.setCacheColorHint(Color.TRANSPARENT).

Your problem is solved

Simple. Isn't it?

Monday, April 22, 2013

Activity in android

      Activity is important ui unit of android application.

To start an activity from another, you have to use an intent by sending the new activity class as parameter.

e.g.
         Intent i = new Intent(this, NewActivity.class);


Next you call startActivity method

     startActivity(i);

You can pass extra data to the new actiivity by using putExtra method.


   i.putExtra( "Title",mTitle);


In the new activity, you can extract this information using getExtra methods

   Intent i = getIntent();
   String t = i.getStringExtra("Title");

      

Saturday, April 20, 2013

Threads in Android

Many of the network activities delay the program and the screen looks unresponsive. And ultimately you will get ANR.
  You can overcome this with a thread


class MyThread extends Thread{

      public MyThread(){
          //initialise your variables
      }
      public void run(){
         //write your expensive code here
     }
};

  In your ui therad you instantiate this thread


    MyThread myt = new MyThread(a,b,c);
    myt.start();

User will not notice the delay as myt is not in ui thread

Friday, April 19, 2013

Show a progress dialog when a thread is running

  We can easily show a progress dialog with Async task. But asyn task has its own drawbacks. There can be no ui's and the task can be executed only once.
   Better way is to use a thread for lengthy processing and show a progess dialog in the ui thread. (I struggled quite a bit. My progress dialog would keep on spinning infinitely :-( )

e.g.

//this is your main activity thread
handler = new FeedReadHandler();
....
.....

pd = ProgessDialog.show(context,"Loading","Loading the file. please wait...");
Thread background = new Thread(new Runnable(){     

                        @Override
                        public void run() {
                            readFeed(nameUrl);
                            Message msg = handler.obtainMessage();
                            msg.arg1=FEED_LOAD_FINISHED;
                            handler.sendMessage(msg);
                           
                        }
                       
                    });
                    background.start();
                    -.....
......

  Now you are starting a progress dialog and then starting the thread called background to run the function readFeed. When the function is completed, the thread sends a message to the handler.

Here is the handler code
 public class FeedReadHandler extends Handler{
       @Override
       public void handleMessage(Message msg){
           Log.d("SHOWRSS","i think i received a message");
           if(msg.arg1==FEED_LOAD_FINISHED){
               pd.dismiss();
               .....

               .....
              
           }
          
       }
   }

So the handler when receives the message from our background thread, on receiving this message it closes the progress- dialog.

How to use a DatePickerDialog

You do not have a direct widget for date entry. You should use an edittext and enter the date in yyyy-mm-dd format. Instead you can use a datepicker dialog. This dialog can be displayed when user types on the editText which should store the date

If your edit text is etDialogDate,

etDialogDate.setOnClickListener(new OnClickListener() {
          
            @Override
            public void onClick(View v) {
                String dateText = ((TextView)v).getText().toString();
                int year,month,day;
                String temp[]=dateText.split("-");
                year = Integer.valueOf(temp[0]);
                month = Integer.valueOf(temp[1]);
                day= Integer.valueOf(temp[2]);
                DatePickerDialog dtpkrdlg = new 
                     DatePickerDialog(ExpenseList.this, 0, 
                      new  DateSetListener(), year, month-1, day);
                dtpkrdlg.show();
              
            }});

Now this will show the datepicker dialog with initial value as date shown in edittext.

Once the date is set in the dialog it will call the callback function using DateSetListener. Let us define this DateSetListener class as follows

class DateSetListener implements DatePickerDialog.OnDateSetListener{

        @Override
        public void onDateSet(DatePicker view, 
                              int year, int monthOfYear,
                               int dayOfMonth) {
           
             etDialogDate.setText(""+year+"-"+
               (monthOfYear+1)+"-"+dayOfMonth);
           
        }
       
    }

Now any date set in the dialog is displayed back in our edittext widget.

Observe that we have used monthOfYear+1 because in Android Jan is 0 not 1.

Thursday, April 18, 2013

How to access sqlite table from emulator

You can see the contents of text files by exporting it from emulator, but what about sqlite tables? You can use sqlite3 as explained below.
You need to access the adb shell first.
If you are using Linux system, it is simple enough. Just give the command

    adb shell

But for windows xp system, the path might not be properly set. If that is the case, go to the folder where android sdk is installed

If android sdk is installed in f:\android-sdk-windows, then go there and then goto subdirectory tools in that.
Now give the command

     adb shell

Next you need to go to directory which has your sqlite database. For that you use command
     cd /data/data
     cd com.pkg.pkg1

Here com.pkg.pkg1 must be replaced by your packagename of android project.

     cd databases
     dir

At this point, dir must show you the name of your database file. If your database name is mydb, then to open it using sqlite, give the command

    sqlite3 mydb

Now you can use any sql command like select, insert , update etc.

     .tables
     select * from expenses;

Do not forget to end your sql commands with a semicolon.


Be careful if you give a wrong database name, instead of prompting sqlite just shows empty db.
Here is a list of some other useful commands
.schema table
Gives the create statement for that table so you will come to know the columns of the table

.headers on
Shows your select statement with column name headers.

.quit
Terminate sqlite

.help

To obtain a list of sqlite3 commands you can use




Wednesday, April 17, 2013

Tabs with different background colors

For past 3 days I was trying to have different colors for android tabs instead of normal grey and whitish grey. I got an articles from net android tabs like iphone. Now I am unable to find the article now. Anyways, here is the code

View view = new MyView(this, R.drawable.custombutton, R.drawable.custombutton, "Channels");
       //         channelTabSpec = tabhost.newTabSpec("channels").setIndicator(view)
        .setContent(intent);
 tabhost.addTab(channelTabSpec);
---
----
---

Similarly I created two more tabs Newspapers and Techsites. The class MyView used above is 

private class MyView extends LinearLayout {
          ImageView iv;
          TextView tv;
          public MyView(Context c, int drawable, int drawableselec, String label) {
           super(c);
         
           tv = new TextView(c);
           tv.setText(label);
          
           tv.setGravity(Gravity.CENTER);
           tv.setBackgroundColor(Color.TRANSPARENT);
           tv.setTextColor(Color.WHITE);
           tv.setTextSize(14);
          
           tv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
             LayoutParams.WRAP_CONTENT, (float) 1.0));
           setOrientation(LinearLayout.VERTICAL);
           Drawable d = getResources().getDrawable(drawableselec);
           tv.setBackgroundDrawable(d);
          
            addView(tv);
        
          }
         }

I have created a file custombutton.xml in the folder /res/drawable for having different appearances for the normal tab and selected tab. Here is the file



   
       
                            android:endColor="@color/darkblue" android:angle="270" />
           
            
                            android:right="1dp" android:bottom="20dp" />
       

   

   
       
                            android:startColor="@color/blue" android:angle="270" android:type="radial" />
               
           
           
                            android:right="1dp" android:bottom="20dp" />
       

   

   


First item is for non-selected tab and second for selected. In selected tab we are using radial gradient with start color and end color. In non-selected tab we are using linear gradient with start color, center color and end color and angle as 270. Angle can be 90, 180, and 270. Other values for angle will crash the program. Center color is optional.


You can get more info about custom shapes in this android tutorial http://developer.android.com/guide/topics/resources/drawable-resource.html
At the end, my tabs look like this. Well don't bother about color combination, I know I am not so good in that.



The gradient type can be linear, radial or sweep - linear is default. For selected tab I am using radial gradient. 

Notice one more thing here, I am defining two shapes - one for selected and another for not selected - using selector. If you want to use this for button you can use android:state_pressed and android:state_focused and define different shapes for these.
Look at another example where I am defining different drawable pngs for different states

 
             android:drawable="@drawable/lightbtn" >
        
   

            android:drawable="@drawable/darkbtn">
        
   
 
    


This xml file is stored as mybutton.xml in /res/drawable-hdpi and I use the following line in my layout file
----
----

I have lightbtn.png and darkbtn.png in my /res/drawable-hdpi . Now when I touch the button darkbtn is displayed else lightbtn is displayed

Tuesday, April 16, 2013

Using samsung android phone with windows xp

I have a Samsung galaxy 551. I tried connecting it to the pc. I am supposed to install the driver for it. The installation cd had keis on it. Anyway I tried installing it. It should one or two errors, but completed installing,
  When I ran this Keis, it is not showing my phone even though I have connected the phone using usb.  Nor am I seeing it in "my computers". I tried tethering usb from the phone. The windows usb wizard would say " New device found" and give installation instruction. But it will finally say installation failed as there is no driver  samsung android. I tried uninstalling and reinstalling keiss 2-3 times.
  Now I remembered one of the errors I got during installation of Keiss was "unable to find samsung usb driver for android.exe or something of that type. So I googled for that file and downloaded it from the site http://fr.gsmlibrary.com/Products+Support/Z3X/Samsung+files/Samsung+Box/SAMSUNG_USB_Driver_for_Mobile_Phones.exe.html
and installed it.
and then as if my magic, the keiss start showing the dialog, connecting to the device and windows desktop showed the icon "Found the samsung device..." and then " installation success". So finally my pc was able to detect my phone. Eureka.
Then.... then I went to kitchen to finish my little bit of cooking, when I came back, the phone was asking me to connect to keis. And I could explore all the files of my phone and transfer files to the phone. I copied one of my programs - apk files and then clicked it on the phone. Phone installed the apk file. Double Eureka.!!!!

Monday, April 15, 2013

ViewSwitcher in Android - switching layouts for activity

Let us say you want to change the layout in same activity e.g. you want to show a list of urls and when one of them is clicked, you want to show webview on the entire screen. One solution could be to use a dialog, but a dialog will not use the screen area effectively.
In such cases you can use ViewSwitcher.  A viewswitcher can have two child views and only one of them is shown at a time.
The two views you want to use must be wrapped in the viewswitcher  as shown in the xml file below.


   xmlns:android="http://schemas.android.com/apk/res/android"
       android:id = "@+id/viewswitcher"
   ---
   -----
>
 
    android:layout_width="fill_parent"
    ------->
   
   
        android:layout_width="fill_parent"
         -------------------
        ------------------->
         


    android:layout_width="fill_parent"
     ------------------>
   
   
    android:layout_width="fill_parent"
   ---------------------->
   

 
 

In this xml file, the two linear layouts are child views of view switcher. One of them has a gridview and the other has a webview.

Add this line in your onCreate function of the activity to get the viewSwitcher from xml

mViewSwitcher = (ViewSwitcher)findViewById(R.id.viewSwitcher1);

To start with, first child view will be shown. Now you can display the other child view, in this case webview by calling viewswitcher.showNext() and viewswitcher.showPrevious()

        public void onItemClick(AdapterView arg0, View arg1, int arg2,long arg3) {
            -------
            mViewSwitcher.showNext();
                               -------
        }
@Override
    public void onBackPressed(){
        if(mWebView.isShown()){
             mViewSwitcher.showPrevious();
           ---------
        }
    }


Sunday, April 14, 2013

How to publish your android app in Android market

I faced some difficulties when trying to publish my app. So I thought this post may help others.
First you need to have a google account. Then you should pay 25$ (US dollars 25) fees for registration with your credit card.
Next step will be creation of your android app. That is relatively easy. ;-)
But remember your app must have version code and version name. 
Next step is signing your app. This must be done by creating a cryptographic key for your app. To do this you can use the java command keytool.
Again this command at command prompt may give a problem. May be class path variable is not set properly. No problem. You can still go to your jdk directory, then bin subdirectory within  that. Now you have your keytool command. 
You can use the keytool command like
keytool -genkey -v -keystore your-keystore-name -alias your-alias-name -keyalg RSA -keysize 2048 -validity 10000
You must provide a password for the keystore.
Once key is generated, you can go to eclipse IDE and use the option EXPORT in the context menu of project (right click on project name) . You will be prompted for project name, keystore name and location and its password. You should also give the alias name and password and apk file name and location. The apk thus generated is the signed app which can be published into market.
Funnily for me I used to get the error saying the key is not valid till future. I tried many times without much success. Then I realized the reason could because of time zone in India is the cause. So I changed my system date to 1 day in past. Then created the key again. This hack worked. 
You should also upload two screen shots of the app.
Finished all these steps? Published also? Now keep your fingers crossed and pray that people will download and install your app. :-) 

Saturday, April 13, 2013

Generate Random Numbers in Android

In your apps (especially in game apps) , you may come across the need to generate random numbers. For generation of psuedo random numbers you can use random class from package java.util

First of all you can construct a random number generator using this

        mRandom = new Random(seed);

The seed should be unique for better results. You can use current time for that

                    Time t = new Time();
        t.setToNow();
        mRandom = new Random(t.toMillis(false));

Now to generate a random number from 0 to n, you can use mRandom.nextInt(n). Make sure that n is not zero.
          int rand = mRandom.nextInt(10);

The above line generates a random number between 0 to 9.

Random class also provides other functions such as nextFloat(), nextDouble, nextLong.

Thursday, April 11, 2013

Simple ListView Adapter and list item select

When you are using a listview in your applications many a times you will write your own adapter to display items in a listview. But if your list is very simple showing a list of strings, you can use inbuilt adapters like ArrayAdapter, SimpleCursorAdapter etc.

ArrayAdapter
Let us look at an example



android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" 
> 

android:layout_height="wrap_content" 
android:id="@+id/listView1" 
android:layout_width="match_parent"
 
android:layout_margin="20dp"
>


And the oncreate function of activity reads like this

       super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String []s = new String[]{"Lorem","Ipsum","dolor","sit","amet"};
        ListView lv = (ListView)findViewById(R.id.listView1);
        lv.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1,s));

So this arrayadapter just needs the array to be displayed in the list, the context and the textview resource id. Instead of defining another resource id, I have used in built resource. Now our list looks like this

If you want to change the appearance of your list, you can define your own list view as shown.
Add another xml file with just a textview . Do not use any layout.
tv.xml


android:background="#0489B1"
android:textColor="#000000"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_margin="20dp"
android:padding="5dp">

Now use this as layout in arrayadpter
 lv.setAdapter(new ArrayAdapter(this, R.layout.tv,s));


And after you set the background color of linear layout in main to blue, this is how your list looks like


Next step will be write a listener to the list. You should attach an OnItemClickListener to this listview.

 lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView arg0, View arg1, int arg2,
long arg3) {
 ListView lv = (ListView) arg0;
 TextView tv = (TextView) lv.getChildAt(arg2);
 String s = tv.getText().toString();
 Toast.makeText(SamplesActivity.this, "Clicked item is"+s, Toast.LENGTH_LONG).show();
} });
Instead of Toasting, you can perform any required processing. 
What if you want to use the list for selecting one of the items? Again the simplest way to use this is to use android.R.layout.simple_list_item_single_choic

       lv.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_single_choice,s));
        lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);   
Now our list lets us select exactly one item
I did change the background color of linear layout to blue in main.xml because the builtin android layouts show list elements in white text which will be invisible if the background is also white.
How do you find out which item is selected from the listview? 
Let us use a button, on click of which we will display the selected item of the list
Modified main.xml is



android:background="#0489B1" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">



android:layout_width="match_parent" android:divider="#00ffffff"
android:dividerHeight="10dp" android:layout_margin="20dp">





Let us add the button and onclicklistener to it.

        btn =(Button) findViewById(R.id.button1);
        btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int p =  lv.getCheckedItemPosition();
String s = ((TextView) lv.getChildAt(p)).getText().toString(); Toast.makeText(SamplesActivity.this, "Selected item is "+s, Toast.LENGTH_LONG).show();
}
});
So now our list looks like this.




Finally let us see how to select multiple elements from the list. 
First of all change the list mode multiple select


lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);


Then we should use lv.setCheckedItemPositions() which returns a sparseboolean array. The array elements are true if that item is selected



btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
SparseBooleanArray sp = lv.getCheckedItemPositions();
StringBuffer str = new StringBuffer();
for(int i=0;i
if(sp.valueAt(i)==true){
String s = ((TextView) lv.getChildAt(i)).getText().toString();
str = str.append(" "+s);
}
}  
Toast.makeText(SamplesActivity.this, "Selected items are "+str.toString(), Toast.LENGTH_LONG).show();
}
});
And, our multi select list is ready!

How to install custom (kannada e.g.) font in your Samsung phone

I was struggling to install the kannada font in my Samsung galaxy 551 since 3-4 days and today I finally succeeded.

First and foremost, you need to root your android phone. Rooting means you should get super user access. Without superuser access, you can not copy your ttf file to /systems/fonts folder.

There are many free apps available to root your android phone. The one I used is,  SuperOneClick. You should download and unzip the program to your pc. And then connect your android phone with usb cable.  Enable usb debugging mode.  Then start SuperOneClick.exe  and click on the root button. The program will root your phone.
For more detailed instruction on how to install superoneclick please go through this link 
I suspect, once rooted, the phone needs to be rebooted again.
You can be sure if you are rooted if when you type su in terminal on phone , superoneclick will ask your permission for root access to terminal program.

Next your terminal will show # instead of $

Next set of commands can be given from terminal emulator or adb on your computer.


Next you need to remount /system folder in read write mode.





mount -o remount /dev/mtdblock4 /system
mount -o remount /dev/mmcblk0 /sdcard

Next backup your DroidSansFallback.ttf

cd /system/fonts
cp DroidSansFallback.ttf /sdcard
Delete this file
rm DroidSansFallback.ttf
Now copy your kannada/required font file to DroidSansFallback.ttf. I have used Sampige.ttf


cat /sdcard/Sampige.ttf > DroidSansFallback.ttf


Mount the system folder back in read only mode
 
mount -o ro,remount /dev/mtdblock4 /system

Enjoy your favorite news or other contents  in your custom font.

 Thanks to the article
How to install custom fonts on rooted droid phone