http://eagle.phys.utk.edu/guidry/android/simpleDialer.html


Previous | Next | Home

 Simple Dialer Application


 

The projects to this point have emphasized that Android devices are highly-connected computers and data processors. But smartphones are also phones, so in this project we show how we can use an application to implement a phone call by loading the Android phone dialer with a number pre-inserted. Of course, you could do the same thing manually by opening the dialer screen and typing in the desired phone number, or invoking the number from a stored contacts list. So what is the advantage of having the computer do it?

The primary advantage of having the computer do it is that it can deal automatically with a dynamically-updated list of phone numbers, which need not be in the contacts list for the particular phone. Let's give two representative examples.

  • Consider an application that displays a list of your friends, with contact data updated automatically from a social networking site. With the approach that we illustrate here, you can dial the number of a friend appearing in that list without knowing whether the number is in your contacts list, or whether it has been changed since you entered it into your contacts (assuming that the information supplied by the social networking site is current).

  • As another example, consider a list of emergency phone numbers supplied to employees of a company. Those might change over time and it is problematic to assume that all employees will have the correct numbers stored in their phone contacts or otherwise easily accessible. But if each employee had a phone with an app developed along the lines of the present example, you only have to ensure that the server supplying the contact information is current to ensure that each employee has the resources to report an emergency immediately to the correct contact.

Both examples have the disadvantage that they require network data access. But even that issue can be dealt with by having the system cache its most recently acquired data, so that if the data network is down it is still likely that correct data will be used for the phone call. (Of course, if the voice wireless network is also down, you'll have to communicate by other means like landline phones or smoke signals.)

 

Creating the Project

We will deal in separate projects with the issue of accessing data over the network and concentrate in this project on how to get an app to dial numbers, assuming that the numbers and associated data already are stored in arrays on the device. Begin by creating a new project in Eclipse:

  • Project name: SimpleDialer

  • Build Target: Android 2.1

  • Application name: Simple Dialer

  • Package name: com.lightcone.simpledialer

  • Create Activity: SimpleDialer

  • Min SDK Version: 3

except substitute your namespace for com.lightcone.

 

Inserting the Code

In the project that you have just created, open res/values/strings.xml and edit it to read


    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="hello">SimpleDialer</string>
        <string name="app_name">Simple Dialer</string>
        <string name="main_label">My Friends</string>
    </resources>

Then edit res/layout/main.xml to read


    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="15dip" >
        
        <TextView  
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="@string/main_label"
            android:layout_gravity="center"
            android:layout_marginBottom="25dip"
            android:textSize="22sp" /> 
        <Button
            android:id="@+id/button1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="18sp" />
        <Button
            android:id="@+id/button2"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="18sp" />
        <Button
            android:id="@+id/button3"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="18sp" />
        <Button
            android:id="@+id/button4"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="18sp" />
        <Button
            android:id="@+id/button5"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="18sp" />
        <Button
            android:id="@+id/button6"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="18sp" />
                    
    </LinearLayout>

Finally, open src/com.lightcone.simpledialer/SimpleDialer.java and edit it to read


    package com.lightcone.simpledialer;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    
    public class SimpleDialer extends Activity implements OnClickListener {
            
        private int entries = 6;
        private String phoneNum[];
        private String buttonLabels[];
            
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            
            phoneNum = new String[entries];
            buttonLabels = new String[entries];
            
            // Populate the data arrays
            populateArrays();
            
            // Set up buttons and attach click listeners
            
            Button button1 = (Button)findViewById(R.id.button1);
            button1.setText(buttonLabels[0]);
            button1.setOnClickListener(this);
            
            Button button2 = (Button)findViewById(R.id.button2);
            button2.setText(buttonLabels[1]);
            button2.setOnClickListener(this);
            
            Button button3 = (Button)findViewById(R.id.button3);
            button3.setText(buttonLabels[2]);
            button3.setOnClickListener(this);
            
            Button button4 = (Button)findViewById(R.id.button4);
            button4.setText(buttonLabels[3]);
            button4.setOnClickListener(this);
            
            Button button5 = (Button)findViewById(R.id.button5);
            button5.setText(buttonLabels[4]);
            button5.setOnClickListener(this);
            
            Button button6 = (Button)findViewById(R.id.button6);
            button6.setText(buttonLabels[5]);
            button6.setOnClickListener(this);
        }
        
        // Launch the phone dialer
        
        public void launchDialer(String number){
            String numberToDial = "tel:"+number;
            startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse(numberToDial)));
        }
        
        
        /** Method to populate the data arrays */
        
        public void populateArrays(){
            
            /** In a practical application the arrays phoneNum and buttonLabels could be 
            * updated dynamically from the Web in this method.  For this project we just 
            * hard-wire in some values to illustrate how to use such data, once obtained,
            * to make phone calls.*/
            
            phoneNum[0] = "000-000-0001";
            phoneNum[1] = "000-000-0002";
            phoneNum[2] = "000-000-0003";
            phoneNum[3] = "000-000-0004";
            phoneNum[4] = "000-000-0005";
            phoneNum[5] = "000-000-0006";
            
            buttonLabels[0] = "Jane D. Arc";
            buttonLabels[1] = "John Doe";
            buttonLabels[2] = "Jane Doe";
            buttonLabels[3] = "Abraham Linking";
            buttonLabels[4] = "Mona Liza";
            buttonLabels[5] = "Issac Nuton";
        }
        
        /** Process button events */
        
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            
                case R.id.button1:
                    launchDialer(phoneNum[0]);
                    break;
                        
                case R.id.button2:
                    launchDialer(phoneNum[1]);
                    break;
                        
                case R.id.button3:
                    launchDialer(phoneNum[2]);
                    break;
                        
                case R.id.button4:
                    launchDialer(phoneNum[3]);
                    break;
                        
                case R.id.button5:
                    launchDialer(phoneNum[4]);
                    break;
                        
                case R.id.button6:
                    launchDialer(phoneNum[5]);
                    break;
            }
        } 
    }

 

What It Does

Most of the above should be familiar: the layout in main.xml, attaching click listeners to the buttons in SimpleDialer.java, and processing the corresponding events are all tasks that we have implemented in previous examples. Thus we reserve our comments for how the dialer works, and even these can be rather brief.

As noted above, the approach described here is most useful in dealing with a list of phone numbers updated dynamically over the network. We will discuss methods for accessing data over the network in other projects (one example is given in the Mapping Demo project). Here we just have populateArrays() fill the arrays phoneNum[] and buttonLabels[] with some hardwired pseudo-data to illustrate how to make phone calls using the data contained in the arrays. The methodlaunchDialer(String) initiates the phone call.

  • Its key statement is startActivity(Intent intent), which is inherited by Activity from Context.

  • For the argument of startActivity(Intent) we create an Intent using the constructor Intent (String action, Uri uri), which takes two arguments:

    1. The string action specifies the action associated with the Intent. In this case it is set to the Intent class constant ACTION_DIAL, which indicates that the Intent is to dial a number as specified by the data (the second argument).

    2. The second argument uri is a Uri (Uniform Resource Identifier) in the form of a string"tel:"+ telephone number that supplies the telephone number for the Intent actionACTION_DIAL..

If you try this out on a device or emulator you should get the left screen below as the initial screen, and clicking on say the third button should give you something like (depending on the device) the screen below on the right.



At this point, the user has only to hit the phone symbol at the bottom of the right screen to initiate the call (and also has an option with a button near the top to add the number to her list of contacts).

 

Making the Button Display Orientation-Friendly

Before quitting, let's make one final improvement. If you flip the phone to horizontal display mode while the button menu is being displayed, it is likely that some of the six buttons will be off the screen. Following the discussion in the Animal Sounds project, let's specify alternative resources so that the menu of buttons displays better in horizontal mode:

  1. Right-click on res, select New > Folder, give the new folder the name layout-land, and click Finish.

  2. Right-click on res/layout/main.xml, copy it, and paste it into the new res/layout-land folder.

  3. Edit the new res/layout-land/main.xml file so that the buttons are now displayed in two rows of three each:
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="15dip" >
        
        <TextView  
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="@string/main_label"
            android:layout_gravity="center"
            android:layout_marginBottom="25dip"
            android:textSize="22sp" /> 
    
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >    
            <Button
                android:id="@+id/button1"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textSize="18sp" 
                android:layout_weight="1" />
            <Button
                android:id="@+id/button2"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textSize="18sp"
                android:layout_weight="1" />
            <Button
                android:id="@+id/button3"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textSize="18sp"
                android:layout_weight="1" />
        </LinearLayout>
                    
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" > 	
            <Button
                android:id="@+id/button4"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textSize="18sp" 
                android:layout_weight="1"/>
            <Button
                android:id="@+id/button5"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textSize="18sp"
                android:layout_weight="1" />
            <Button
                android:id="@+id/button6"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textSize="18sp"
                android:layout_weight="1" />
        </LinearLayout>
                    
    </LinearLayout>
    
    

Now if you flip the phone horizontal when the menu is showing, Android should switch automatically to the following display.



When you click a button and go to the dialer though, whether it is displayed in vertical or horizontal mode depends on the device and Android. On my Samsung Galaxy S phone the dialer always displays in vertical mode, but on my Motorola Backflip the dialer switches between vertical and horizontal mode if the phone is rotated or the keyboad opened or closed.


The complete project for the application described above is archived at the linkSimpleDialer.



Previous | Next | Home