Android Tutorial - Core Class : Example 1

 Using AccountManager

    
//package gr.atc.epart;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;

class AccountUtil {
  public static String getAccountName(Context context) {
    String email = getEmail(context);
    String name = getNameFromEmail(email);
    return name;
  }

  public static String getEmail(Context context) {
    AccountManager accountManager = AccountManager.get(context);
    Account account = getAccount(accountManager);

    if (account == null) {
      return null;
    } else {
      return account.name;
    }
  }

  public static Account getAccount(AccountManager accountManager) {
    Account[] accounts = accountManager.getAccountsByType("com.google");
    Account account;
    if (accounts.length > 0) {
      account = accounts[0];

    } else {
      account = null;
    }
    return account;
  }

  private static String getNameFromEmail(String email) {

    if (email==null) {
      return null;
    }
    
    String name = "";
    int i = email.lastIndexOf('@');

    if (i > 0 && i < email.length() - 1) {

      name = email.substring(0, i);
    }
    return name;

  }
}

Get User name

    
//package com.fedorvlasov.lazylist;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;

class Utils {
  private static Account getAccount(AccountManager accountManager) {
    Account[] accounts = accountManager.getAccountsByType("com.google");
    Account account;
    if (accounts.length > 0) {
      account = accounts[0];
    } else {
      account = null;
    }
    return account;
  }

  public String getEmail(Context context) {
    AccountManager accountManager = AccountManager.get(context);
    Account account = getAccount(accountManager);

    if (account == null) {
      return null;
    } else {
      return account.name;
    }
  }

  public String getUsername(Context context) {
    // String email;
    AccountManager manager = AccountManager.get(context);
    Account account = getAccount(manager);
    if (account == null) {
      return "";
    } else {
      String email = account.name;
      String[] parts = email.split("@");
      if (parts.length > 0 && parts[0] != null)
        return parts[0];
      else
        return "";
    }
  }
}

Set user permission in AndroidManifest

  
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.androidbook.services.applicationex"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name"
        android:name="ApplicationEx" >
        <activity android:name=".HttpActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
    <uses-sdk android:minSdkVersion="4" />

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest> 

Get Android Info

    

//package org.mortbay.ijetty.util;

import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;

public final class AndroidInfo
{
    private static final String EMULATOR_ID = "ffffffffffffffff";

    public static CharSequence getApplicationLabel(Context context)
    {
        try
        {
            PackageManager pm = context.getPackageManager();
            ApplicationInfo ai = pm.getApplicationInfo(context.getPackageName(),0);
            return pm.getApplicationLabel(ai);
        }
        catch (NameNotFoundException e)
        {
            return "AnonDroid";
        }
    }

    public static String getApplicationVersion(Context context)
    {
        try
        {
            PackageManager pm = context.getPackageManager();
            return pm.getPackageInfo(context.getPackageName(),0).versionName;
        }
        catch (NameNotFoundException e)
        {
            return "";
        }
    }

    public static boolean isOnEmulator(Context context)
    {
        if ("sdk".equals(Build.MODEL) && "sdk".equals(Build.PRODUCT))
        {
            return true;
        }

        return getUniqueDeviceID(context).equals(EMULATOR_ID);
    }

    public static String getDeviceModel()
    {
        StringBuilder ret = new StringBuilder();

        if ("sdk".equals(Build.MODEL) && "sdk".equals(Build.PRODUCT))
        {
            return "SDK Emulator";
        }

        ret.append(Build.MODEL).append(" [");
        ret.append(Build.MANUFACTURER).append(" ");
        ret.append(Build.PRODUCT).append("]");

        return ret.toString();
    }

    public static String getOSVersion()
    {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.CUR_DEVELOPMENT)
        {
            return "DEV";
        }
        return Build.VERSION.RELEASE;
    }

    public static String getUniqueDeviceID(Context context)
    {
        ContentResolver contentResolver = context.getContentResolver();
        String id = android.provider.Settings.System.getString(contentResolver,android.provider.Settings.System.ANDROID_ID);
        if (id == null)
        {
            id = EMULATOR_ID; // running on emulator.
        }
        return id;
    }

    /**
     * Build an HTTP User-Agent suitable enough to identify this application + version + handset
     */
    public static String getUserAgent(Context context)
    {
        StringBuilder ua = new StringBuilder();
        ua.append(AndroidInfo.getApplicationLabel(context)).append("/");
        ua.append(AndroidInfo.getApplicationVersion(context));
        ua.append(" (Android ").append(AndroidInfo.getOSVersion());
        ua.append("/").append(AndroidInfo.getDeviceModel()).append(")");
        return ua.toString();
    }

    private AndroidInfo()
    {
        /* prevent instantiation */
    }
}

extends AsyncQueryHandler

//package ch.racic.android.linuxtag.util;

import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.database.Cursor;

import java.lang.ref.WeakReference;

public class NotifyingQueryHandler extends AsyncQueryHandler {
    private WeakReference<OnQueryComplete> mListener;

    public interface OnQueryComplete {
        public void onQueryComplete(int token, Object cookie, Cursor cursor);
    }

    public NotifyingQueryHandler(ContentResolver cr, OnQueryComplete listener) {
        super(cr);
        mListener = new WeakReference<OnQueryComplete>(listener);
    }

    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
        OnQueryComplete listener = mListener.get();
        if (listener != null) {
            listener.onQueryComplete(token, cookie, cursor);
        } else {
            cursor.close();
        }
    }
}

Backup restore

package com.example.android.backuprestore;

import android.app.Activity;
import android.app.backup.BackupManager;
import android.app.backup.RestoreObserver;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.RadioGroup;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;


public class BackupRestoreActivity extends Activity {
    static final String TAG = "BRActivity";

    static final Object[] sDataLock = new Object[0];

    /** Also supply a global standard file name for everyone to use */
    static final String DATA_FILE_NAME = "saved_data";

    /** The various bits of UI that the user can manipulate */
    RadioGroup mFillingGroup;
    CheckBox mAddMayoCheckbox;
    CheckBox mAddTomatoCheckbox;

    /** Cache a reference to our persistent data file */
    File mDataFile;

    /** Also cache a reference to the Backup Manager */
    BackupManager mBackupManager;

    /** Set up the activity and populate its UI from the persistent data. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /** Establish the activity's UI */
        setContentView(R.layout.backup_restore);

        /** Once the UI has been inflated, cache the controls for later */
        mFillingGroup = (RadioGroup) findViewById(R.id.filling_group);
        mAddMayoCheckbox = (CheckBox) findViewById(R.id.mayo);
        mAddTomatoCheckbox = (CheckBox) findViewById(R.id.tomato);

        /** Set up our file bookkeeping */
        mDataFile = new File(getFilesDir(), BackupRestoreActivity.DATA_FILE_NAME);

        /** It is handy to keep a BackupManager cached */
        mBackupManager = new BackupManager(this);

        /**
         * Finally, build the UI from the persistent store
         */
        populateUI();
    }

    /**
     * Configure the UI based on our persistent data, creating the
     * data file and establishing defaults if necessary.
     */
    void populateUI() {
        RandomAccessFile file;

        // Default values in case there's no data file yet
        int whichFilling = R.id.pastrami;
        boolean addMayo = false;
        boolean addTomato = false;

        /** Hold the data-access lock around access to the file */
        synchronized (BackupRestoreActivity.sDataLock) {
            boolean exists = mDataFile.exists();
            try {
                file = new RandomAccessFile(mDataFile, "rw");
                if (exists) {
                    Log.v(TAG, "datafile exists");
                    whichFilling = file.readInt();
                    addMayo = file.readBoolean();
                    addTomato = file.readBoolean();
                    Log.v(TAG, "  mayo=" + addMayo
                            + " tomato=" + addTomato
                            + " filling=" + whichFilling);
                } else {
                    // The default values were configured above: write them
                    // to the newly-created file.
                    Log.v(TAG, "creating default datafile");
                    writeDataToFileLocked(file,
                            addMayo, addTomato, whichFilling);

                    // We also need to perform an initial backup; ask for one
                    mBackupManager.dataChanged();
                }
            } catch (IOException ioe) {
                
            }
        }

        /** Now that we've processed the file, build the UI outside the lock */
        mFillingGroup.check(whichFilling);
        mAddMayoCheckbox.setChecked(addMayo);
        mAddTomatoCheckbox.setChecked(addTomato);

        /**
         * We also want to record the new state when the user makes changes,
         * so install simple observers that do this
         */
        mFillingGroup.setOnCheckedChangeListener(
                new RadioGroup.OnCheckedChangeListener() {
                    public void onCheckedChanged(RadioGroup group,
                            int checkedId) {
                        // As with the checkbox listeners, rewrite the
                        // entire state file
                        Log.v(TAG, "New radio item selected: " + checkedId);
                        recordNewUIState();
                    }
                });

        CompoundButton.OnCheckedChangeListener checkListener
                = new CompoundButton.OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                // Whichever one is altered, we rewrite the entire UI state
                Log.v(TAG, "Checkbox toggled: " + buttonView);
                recordNewUIState();
            }
        };
        mAddMayoCheckbox.setOnCheckedChangeListener(checkListener);
        mAddTomatoCheckbox.setOnCheckedChangeListener(checkListener);
    }

    /**
     * Handy helper routine to write the UI data to a file.
     */
    void writeDataToFileLocked(RandomAccessFile file,
            boolean addMayo, boolean addTomato, int whichFilling)
        throws IOException {
            file.setLength(0L);
            file.writeInt(whichFilling);
            file.writeBoolean(addMayo);
            file.writeBoolean(addTomato);
            Log.v(TAG, "NEW STATE: mayo=" + addMayo
                    + " tomato=" + addTomato
                    + " filling=" + whichFilling);
    }

    /**
     * Another helper; this one reads the current UI state and writes that
     * to the persistent store, then tells the backup manager that we need
     * a backup.
     */
    void recordNewUIState() {
        boolean addMayo = mAddMayoCheckbox.isChecked();
        boolean addTomato = mAddTomatoCheckbox.isChecked();
        int whichFilling = mFillingGroup.getCheckedRadioButtonId();
        try {
            synchronized (BackupRestoreActivity.sDataLock) {
                RandomAccessFile file = new RandomAccessFile(mDataFile, "rw");
                writeDataToFileLocked(file, addMayo, addTomato, whichFilling);
            }
        } catch (IOException e) {
            Log.e(TAG, "Unable to record new UI state");
        }

        mBackupManager.dataChanged();
    }

    /**
     * Click handler, designated in the layout, that runs a restore of the app's
     * most recent data when the button is pressed.
     */
    public void onRestoreButtonClick(View v) {
        Log.v(TAG, "Requesting restore of our most recent data");
        mBackupManager.requestRestore(
                new RestoreObserver() {
                    public void restoreFinished(int error) {
                        /** Done with the restore!  Now draw the new state of our data */
                        Log.v(TAG, "Restore finished, error = " + error);
                        populateUI();
                    }
                }
        );
    }
}



//src\com\example\android\backuprestore\ExampleAgent.java


package com.example.android.backuprestore;

import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.os.ParcelFileDescriptor;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;


public class ExampleAgent extends BackupAgent {
 
    static final int AGENT_VERSION = 1;


    static final String APP_DATA_KEY = "alldata";

    /** The app's current data, read from the live disk file */
    boolean mAddMayo;
    boolean mAddTomato;
    int mFilling;

    /** The location of the application's persistent data file */
    File mDataFile;

    /** For convenience, we set up the File object for the app's data on creation */
    @Override
    public void onCreate() {
        mDataFile = new File(getFilesDir(), BackupRestoreActivity.DATA_FILE_NAME);
    }


    @Override
    public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
            ParcelFileDescriptor newState) throws IOException {

        synchronized (BackupRestoreActivity.sDataLock) {
            RandomAccessFile file = new RandomAccessFile(mDataFile, "r");
            mFilling = file.readInt();
            mAddMayo = file.readBoolean();
            mAddTomato = file.readBoolean();
        }

        boolean doBackup = (oldState == null);
        if (!doBackup) {
            doBackup = compareStateFile(oldState);
        }


        if (doBackup) {
            ByteArrayOutputStream bufStream = new ByteArrayOutputStream();

            // We use a DataOutputStream to write structured data into
            // the buffering stream
            DataOutputStream outWriter = new DataOutputStream(bufStream);
            outWriter.writeInt(mFilling);
            outWriter.writeBoolean(mAddMayo);
            outWriter.writeBoolean(mAddTomato);

            // Okay, we've flattened the data for transmission.  Pull it
            // out of the buffering stream object and send it off.
            byte[] buffer = bufStream.toByteArray();
            int len = buffer.length;
            data.writeEntityHeader(APP_DATA_KEY, len);
            data.writeEntityData(buffer, len);
        }

        // Finally, in all cases, we need to write the new state blob
        writeStateFile(newState);
    }


    boolean compareStateFile(ParcelFileDescriptor oldState) {
        FileInputStream instream = new FileInputStream(oldState.getFileDescriptor());
        DataInputStream in = new DataInputStream(instream);

        try {
            int stateVersion = in.readInt();
            if (stateVersion > AGENT_VERSION) {
         
                return true;
            }

            // The state data we store is just a mirror of the app's data;
            // read it from the state file then return 'true' if any of
            // it differs from the current data.
            int lastFilling = in.readInt();
            boolean lastMayo = in.readBoolean();
            boolean lastTomato = in.readBoolean();

            return (lastFilling != mFilling)
                    || (lastTomato != mAddTomato)
                    || (lastMayo != mAddMayo);
        } catch (IOException e) {
            // If something went wrong reading the state file, be safe
            // and back up the data again.
            return true;
        }
    }

    /**
     * Write out the new state file:  the version number, followed by the
     * three bits of data as we sent them off to the backup transport.
     */
    void writeStateFile(ParcelFileDescriptor stateFile) throws IOException {
        FileOutputStream outstream = new FileOutputStream(stateFile.getFileDescriptor());
        DataOutputStream out = new DataOutputStream(outstream);

        out.writeInt(AGENT_VERSION);
        out.writeInt(mFilling);
        out.writeBoolean(mAddMayo);
        out.writeBoolean(mAddTomato);
    }


    @Override
    public void onRestore(BackupDataInput data, int appVersionCode,
            ParcelFileDescriptor newState) throws IOException {
        // We should only see one entity in the data stream, but the safest
        // way to consume it is using a while() loop
        while (data.readNextHeader()) {
            String key = data.getKey();
            int dataSize = data.getDataSize();

            if (APP_DATA_KEY.equals(key)) {
                // It's our saved data, a flattened chunk of data all in
                // one buffer.  Use some handy structured I/O classes to
                // extract it.
                byte[] dataBuf = new byte[dataSize];
                data.readEntityData(dataBuf, 0, dataSize);
                ByteArrayInputStream baStream = new ByteArrayInputStream(dataBuf);
                DataInputStream in = new DataInputStream(baStream);

                mFilling = in.readInt();
                mAddMayo = in.readBoolean();
                mAddTomato = in.readBoolean();

                // Now we are ready to construct the app's data file based
                // on the data we are restoring from.
                synchronized (BackupRestoreActivity.sDataLock) {
                    RandomAccessFile file = new RandomAccessFile(mDataFile, "rw");
                    file.setLength(0L);
                    file.writeInt(mFilling);
                    file.writeBoolean(mAddMayo);
                    file.writeBoolean(mAddTomato);
                }
            } else {
                // Curious!  This entity is data under a key we do not
                // understand how to process.  Just skip it.
                data.skipEntityData();
            }
        }

        // The last thing to do is write the state blob that describes the
        // app's data as restored from backup.
        writeStateFile(newState);
    }
}



//src\com\example\android\backuprestore\FileHelperExampleAgent.java


package com.example.android.backuprestore;

import java.io.IOException;

import android.app.backup.BackupAgentHelper;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.FileBackupHelper;
import android.os.ParcelFileDescriptor;

public class FileHelperExampleAgent extends BackupAgentHelper {

    static final String FILE_HELPER_KEY = "the_file";


    @Override
    public void onCreate() {
        // All we need to do when working within the BackupAgentHelper mechanism
        // is to install the helper that will process and back up the files we
        // care about.  In this case, it's just one file.
        FileBackupHelper helper = new FileBackupHelper(this, BackupRestoreActivity.DATA_FILE_NAME);
        addHelper(FILE_HELPER_KEY, helper);
    }

    /**
     * We want to ensure that the UI is not trying to rewrite the data file
     * while we're reading it for backup, so we override this method to
     * supply the necessary locking.
     */
    @Override
    public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
             ParcelFileDescriptor newState) throws IOException {
        // Hold the lock while the FileBackupHelper performs the backup operation
        synchronized (BackupRestoreActivity.sDataLock) {
            super.onBackup(oldState, data, newState);
        }
    }

    /**
     * Adding locking around the file rewrite that happens during restore is
     * similarly straightforward.
     */
    @Override
    public void onRestore(BackupDataInput data, int appVersionCode,
            ParcelFileDescriptor newState) throws IOException {
        // Hold the lock while the FileBackupHelper restores the file from
        // the data provided here.
        synchronized (BackupRestoreActivity.sDataLock) {
            super.onRestore(data, appVersionCode, newState);
        }
    }
}



//src\com\example\android\backuprestore\MultiRecordExampleAgent.java


package com.example.android.backuprestore;

import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;

import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.os.ParcelFileDescriptor;


public class MultiRecordExampleAgent extends BackupAgent {
    // Key strings for each record in the backup set
    static final String FILLING_KEY = "filling";
    static final String MAYO_KEY = "mayo";
    static final String TOMATO_KEY = "tomato";

    // Current live data, read from the application's data file
    int mFilling;
    boolean mAddMayo;
    boolean mAddTomato;

    /** The location of the application's persistent data file */
    File mDataFile;

    @Override
    public void onCreate() {
        // Cache a File for the app's data
        mDataFile = new File(getFilesDir(), BackupRestoreActivity.DATA_FILE_NAME);
    }

    @Override
    public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
            ParcelFileDescriptor newState) throws IOException {

        synchronized (BackupRestoreActivity.sDataLock) {
            RandomAccessFile file = new RandomAccessFile(mDataFile, "r");
            mFilling = file.readInt();
            mAddMayo = file.readBoolean();
            mAddTomato = file.readBoolean();
        }

        // If this is the first backup ever, we have to back up everything
        boolean forceBackup = (oldState == null);

        // Now read the state as of the previous backup pass, if any
        int lastFilling = 0;
        boolean lastMayo = false;
        boolean lastTomato = false;

        if (!forceBackup) {

            FileInputStream instream = new FileInputStream(oldState.getFileDescriptor());
            DataInputStream in = new DataInputStream(instream);

            try {
                // Read the state as of the last backup
                lastFilling = in.readInt();
                lastMayo = in.readBoolean();
                lastTomato = in.readBoolean();
            } catch (IOException e) {
                // If something went wrong reading the state file, be safe and
                // force a backup of all the data again.
                forceBackup = true;
            }
        }

     
        ByteArrayOutputStream bufStream = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(bufStream);

        if (forceBackup || (mFilling != lastFilling)) {
            // bufStream.reset();   // not necessary the first time, but good to remember
            out.writeInt(mFilling);
            writeBackupEntity(data, bufStream, FILLING_KEY);
        }

        if (forceBackup || (mAddMayo != lastMayo)) {
            bufStream.reset();
            out.writeBoolean(mAddMayo);
            writeBackupEntity(data, bufStream, MAYO_KEY);
        }

        if (forceBackup || (mAddTomato != lastTomato)) {
            bufStream.reset();
            out.writeBoolean(mAddTomato);
            writeBackupEntity(data, bufStream, TOMATO_KEY);
        }

        // Finally, write the state file that describes our data as of this backup pass
        writeStateFile(newState);
    }

    /**
     * Write out the new state file:  the version number, followed by the
     * three bits of data as we sent them off to the backup transport.
     */
    void writeStateFile(ParcelFileDescriptor stateFile) throws IOException {
        FileOutputStream outstream = new FileOutputStream(stateFile.getFileDescriptor());
        DataOutputStream out = new DataOutputStream(outstream);

        out.writeInt(mFilling);
        out.writeBoolean(mAddMayo);
        out.writeBoolean(mAddTomato);
    }

    // Helper: write the boolean 'value' as a backup record under the given 'key',
    // reusing the given buffering stream & data writer objects to do so.
    void writeBackupEntity(BackupDataOutput data, ByteArrayOutputStream bufStream, String key)
            throws IOException {
        byte[] buf = bufStream.toByteArray();
        data.writeEntityHeader(key, buf.length);
        data.writeEntityData(buf, buf.length);
    }

    @Override
    public void onRestore(BackupDataInput data, int appVersionCode,
            ParcelFileDescriptor newState) throws IOException {

        // Consume the restore data set, remembering each bit of application state
        // that we see along the way
        while (data.readNextHeader()) {
            String key = data.getKey();
            int dataSize = data.getDataSize();

       
            byte[] dataBuf = new byte[dataSize];
            data.readEntityData(dataBuf, 0, dataSize);
            ByteArrayInputStream instream = new ByteArrayInputStream(dataBuf);
            DataInputStream in = new DataInputStream(instream);

            if (FILLING_KEY.equals(key)) {
                mFilling = in.readInt();
            } else if (MAYO_KEY.equals(key)) {
                mAddMayo = in.readBoolean();
            } else if (TOMATO_KEY.equals(key)) {
                mAddTomato = in.readBoolean();
            }
        }

       
        synchronized (BackupRestoreActivity.sDataLock) {
            RandomAccessFile file = new RandomAccessFile(mDataFile, "rw");
            file.setLength(0L);
            file.writeInt(mFilling);
            file.writeBoolean(mAddMayo);
            file.writeBoolean(mAddTomato);
        }

        // Finally, write the state file that describes our data as of this restore pass.
        writeStateFile(newState);
    }
}



//res\layout\backup_restore.xml
<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ScrollView
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView android:text="@string/filling_text"
                android:textSize="20dp"
                android:layout_marginTop="20dp"
                android:layout_marginBottom="10dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

            <RadioGroup android:id="@+id/filling_group"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp"
                android:orientation="vertical">

                <RadioButton android:id="@+id/bacon"
                    android:text="@string/bacon_label"/>
                <RadioButton android:id="@+id/pastrami"
                    android:text="@string/pastrami_label"/>
                <RadioButton android:id="@+id/hummus"
                    android:text="@string/hummus_label"/>

            </RadioGroup>

            <TextView android:text="@string/extras_text"
                android:textSize="20dp"
                android:layout_marginTop="20dp"
                android:layout_marginBottom="10dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

            <CheckBox android:id="@+id/mayo"
                android:text="@string/mayo_text"
                android:layout_marginLeft="20dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

            <CheckBox android:id="@+id/tomato"
                android:text="@string/tomato_text"
                android:layout_marginLeft="20dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

        </LinearLayout>

    </ScrollView>

    <Button android:id="@+id/restore_button"
        android:text="@string/restore_text"
        android:onClick="onRestoreButtonClick"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_weight="0" />

</LinearLayout>




//res\values\strings.xml
<?xml version="1.0" encoding="utf-8"?>


<resources>
  <string name="filling_text">Choose a sandwich filling:</string>
  <string name="bacon_label">Bacon</string>
  <string name="pastrami_label">Pastrami</string>
  <string name="hummus_label">Hummus</string>

  <string name="extras_text">Extras:</string>
  <string name="mayo_text">Mayonnaise\?</string>
  <string name="tomato_text">Tomato\?</string>

  <string name="restore_text">Restore last data</string>
</resources>

Use Intent to open a browser

  
package app.Test;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;

public class appTest extends Activity {
  private EditText urlText;
  private Button goButton;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // Get a handle to all user interface elements
    urlText = (EditText) findViewById(R.id.url_field);
    goButton = (Button) findViewById(R.id.go_button);

    // Setup event handlers
    goButton.setOnClickListener(new OnClickListener() {
      public void onClick(View view) {
        openBrowser();
      }
    });
    urlText.setOnKeyListener(new OnKeyListener() {
      public boolean onKey(View view, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_ENTER) {
          openBrowser();
          return true;
        }
        return false;
      }
    });
  }

  /** Open a browser on the URL specified in the text box */
  private void openBrowser() {
    Uri uri = Uri.parse(urlText.getText().toString());
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(intent);
  }

}

//main.xml

<?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">
   <LinearLayout
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content">
      <EditText
         android:id="@+id/url_field"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_weight="1.0"
         android:lines="1" />
      <Button
         android:id="@+id/go_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="@string/go_button" />
   </LinearLayout>
   <WebView
      android:id="@+id/web_view"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:layout_weight="1.0" />
</LinearLayout>

Launch browser

  

package app.test;

import java.io.File;
import java.util.ArrayList;

import android.app.Activity;
import android.app.SearchManager;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Contacts;
import android.view.Menu;

public class Test extends Activity {

    private Intent browserIntent, phoneIntent, mapIntent, mailIntent, contactIntent, marketIntent, smsIntent;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        browserIntent = new Intent();
        browserIntent.setAction(Intent.ACTION_VIEW);
        browserIntent.setData(Uri.parse("http://www.google.com"));
        browserIntent.setAction(Intent.ACTION_WEB_SEARCH);
        browserIntent.putExtra(SearchManager.QUERY, "puppies");

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add("Browser").setIntent(browserIntent);
        menu.add("Phone").setIntent(phoneIntent);
        menu.add("Map").setIntent(mapIntent);
        menu.add("Mail").setIntent(Intent.createChooser(mailIntent, "Mail Client"));
        menu.add("SMS").setIntent(smsIntent);
        menu.add("Contacts").setIntent(contactIntent);
        menu.add("Market").setIntent(marketIntent);
        return true;
    }
}

Audio Browser

  

package app.test;

import java.io.File;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class Test extends ListActivity {
  Cursor cursor;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    String[] columns = { android.provider.MediaStore.Audio.Albums._ID,
        android.provider.MediaStore.Audio.Albums.ALBUM };

    cursor = managedQuery(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
        columns, null, null, null);

    String[] displayFields = new String[] { MediaStore.Audio.Albums.ALBUM };
    int[] displayViews = new int[] { android.R.id.text1 };
    setListAdapter(new SimpleCursorAdapter(this,
        android.R.layout.simple_list_item_1, cursor, displayFields,
        displayViews));

  }

  protected void onListItemClick(ListView l, View v, int position, long id) {
    if (cursor.moveToPosition(position)) {

      String[] columns = { MediaStore.Audio.Media.DATA,
          MediaStore.Audio.Media._ID,
          MediaStore.Audio.Media.TITLE,
          MediaStore.Audio.Media.DISPLAY_NAME,
          MediaStore.Audio.Media.MIME_TYPE, };

      String where = android.provider.MediaStore.Audio.Media.ALBUM
          + "=?";

      String whereVal[] = { cursor.getString(cursor
          .getColumnIndex(MediaStore.Audio.Albums.ALBUM)) };

      String orderBy = android.provider.MediaStore.Audio.Media.TITLE;

      cursor = managedQuery(
          MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, columns,
          where, whereVal, orderBy);

      String[] displayFields = new String[] { MediaStore.Audio.Media.DISPLAY_NAME };
      int[] displayViews = new int[] { android.R.id.text1 };
      setListAdapter(new SimpleCursorAdapter(this,
          android.R.layout.simple_list_item_1, cursor,
          displayFields, displayViews));

    }
  }
}

Launch web browser

  

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.widget.Toast;
import android.app.AlertDialog;

 class Tools {

     /**
     * Launch web browser
     */
    static public void launchBrowser(Context ctx, String url) {
      ctx.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));   
    }
}  

Browser Launch

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class BareBonesBrowserLaunch {

    public static void openURL(String url) {
        try {
            browse(url);
        } catch (Exception e) {
           // JOptionPane.showMessageDialog(null, "Error attempting to launch web browser:\n" + e.getLocalizedMessage());
        }
    }

    private static void browse(String url) throws ClassNotFoundException, IllegalAccessException,
            IllegalArgumentException, InterruptedException, InvocationTargetException, IOException,
            NoSuchMethodException {
        String osName = System.getProperty("os.name", "");
        if (osName.startsWith("Mac OS")) {
            Class fileMgr = Class.forName("com.apple.eio.FileManager");
            Method openURL = fileMgr.getDeclaredMethod("openURL", new Class[] { String.class });
            openURL.invoke(null, new Object[] { url });
        } else if (osName.startsWith("Windows")) {
            Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
        } else { // assume Unix or Linux
            String[] browsers = { "firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" };
            String browser = null;
            for (int count = 0; count < browsers.length && browser == null; count++)
                if (Runtime.getRuntime().exec(new String[] { "which", browsers[count] }).waitFor() == 0)
                    browser = browsers[count];
            if (browser == null)
                throw new NoSuchMethodException("Could not find web browser");
            else
                Runtime.getRuntime().exec(new String[] { browser, url });
        }
    }
   
}

Clipboard Sample

   


package com.example.android.apis.content;

import com.example.android.apis.R;

import android.app.Activity;
import android.content.ClipboardManager;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.AdapterView.OnItemSelectedListener;

public class ClipboardSample extends Activity {
    ClipboardManager mClipboard;

    Spinner mSpinner;
    TextView mMimeTypes;
    EditText mEditText;

    CharSequence mStyledText;
    String mPlainText;

    ClipboardManager.OnPrimaryClipChangedListener mPrimaryChangeListener
            = new ClipboardManager.OnPrimaryClipChangedListener() {
        public void onPrimaryClipChanged() {
            updateClipData();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mClipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);

        // See res/any/layout/resources.xml for this view layout definition.
        setContentView(R.layout.clipboard);

        TextView tv;

        mStyledText = getText(R.string.styled_text);
        tv = (TextView)findViewById(R.id.styled_text);
        tv.setText(mStyledText);

        mPlainText = mStyledText.toString();
        tv = (TextView)findViewById(R.id.plain_text);
        tv.setText(mPlainText);

        mSpinner = (Spinner) findViewById(R.id.clip_type);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                this, R.array.clip_data_types, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mSpinner.setAdapter(adapter);
        mSpinner.setOnItemSelectedListener(
                new OnItemSelectedListener() {
                    public void onItemSelected(
                            AdapterView<?> parent, View view, int position, long id) {
                    }
                    public void onNothingSelected(AdapterView<?> parent) {
                    }
                });

        mMimeTypes = (TextView)findViewById(R.id.clip_mime_types);
        mEditText = (EditText)findViewById(R.id.clip_text);

        mClipboard.addPrimaryClipChangedListener(mPrimaryChangeListener);
        updateClipData();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mClipboard.removePrimaryClipChangedListener(mPrimaryChangeListener);
    }

    public void pasteStyledText(View button) {
        mClipboard.setPrimaryClip(ClipData.newPlainText("Styled Text", mStyledText));
    }

    public void pastePlainText(View button) {
        mClipboard.setPrimaryClip(ClipData.newPlainText("Styled Text", mPlainText));
    }

    public void pasteIntent(View button) {
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.android.com/"));
        mClipboard.setPrimaryClip(ClipData.newIntent("VIEW intent", intent));
    }

    public void pasteUri(View button) {
        mClipboard.setPrimaryClip(ClipData.newRawUri("URI", Uri.parse("http://www.android.com/")));
    }

    void updateClipData() {
        ClipData clip = mClipboard.getPrimaryClip();
        String[] mimeTypes = clip != null ? clip.getDescription().filterMimeTypes("*/*") : null;
        mMimeTypes.setText("");
        if (mimeTypes != null) {
            for (int i=0; i<mimeTypes.length; i++) {
                mMimeTypes.append(mimeTypes[i]);
                mMimeTypes.append("\n");
            }
        }
        if (clip == null) {
            mSpinner.setSelection(0);
            mEditText.setText("");
        } else if (clip.getItemAt(0).getText() != null) {
            mSpinner.setSelection(1);
            mEditText.setText(clip.getItemAt(0).getText());
        } else if (clip.getItemAt(0).getIntent() != null) {
            mSpinner.setSelection(2);
            mEditText.setText(clip.getItemAt(0).getIntent().toUri(0));
        } else if (clip.getItemAt(0).getUri() != null) {
            mSpinner.setSelection(3);
            mEditText.setText(clip.getItemAt(0).getUri().toString());
        } else {
            mSpinner.setSelection(0);
            mEditText.setText("Clip containing no data");
        }
    }
}
//layout/clipboard.xml


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


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button android:id="@+id/copy_styled_text"
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:onClick="pasteStyledText"
            android:text="@string/copy_text" />

        <TextView
            android:id="@+id/styled_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:textStyle="normal" />

    </LinearLayout>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button android:id="@+id/copy_plain_text"
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:onClick="pastePlainText"
            android:text="@string/copy_text" />

        <TextView
            android:id="@+id/plain_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:textStyle="normal" />

    </LinearLayout>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button android:id="@+id/copy_intent"
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:onClick="pasteIntent"
            android:text="@string/copy_intent" />

        <Button android:id="@+id/copy_uri"
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:onClick="pasteUri"
            android:text="@string/copy_uri" />

    </LinearLayout>

    <Spinner android:id="@+id/clip_type"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:drawSelectorOnTop="true"
        android:prompt="@string/clip_type_prompt"
    />

    <TextView
        android:id="@+id/clip_mime_types"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:textStyle="normal"
        />

    <EditText
        android:id="@+id/clip_text"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="1"
        android:textStyle="normal"
        />

</LinearLayout>

Configuration changed event

package com.commonsware.android.rotation.three;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.view.View;
import android.widget.Button;
import android.util.Log;

public class RotationThreeDemo extends Activity {
  static final int PICK_REQUEST=1337;
  Button viewButton=null;
  Uri contact=null;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    setupViews();
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode,
                                    Intent data) {
    if (requestCode==PICK_REQUEST) {
      if (resultCode==RESULT_OK) {
        contact=data.getData();
        viewButton.setEnabled(true);
      }
    }
  }

  public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    
    setupViews();
  }
  
  private void setupViews() {
    setContentView(R.layout.main);
    
    Button btn=(Button)findViewById(R.id.pick);
    
    btn.setOnClickListener(new View.OnClickListener() {
      public void onClick(View view) {
        Intent i=new Intent(Intent.ACTION_PICK,
                            Contacts.CONTENT_URI);

        startActivityForResult(i, PICK_REQUEST);
      }
    });
    
    viewButton=(Button)findViewById(R.id.view);
    
    viewButton.setOnClickListener(new View.OnClickListener() {
      public void onClick(View view) {
        startActivity(new Intent(Intent.ACTION_VIEW, contact));
      }
    });
    
    viewButton.setEnabled(contact!=null);
  }
}


//res\layout\main.xml
<?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"
  >
  <Button android:id="@+id/pick"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:text="Pick"
    android:enabled="true"
  />
  <Button android:id="@+id/view"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:text="View"
    android:enabled="false"
  />
</LinearLayout>




//res\layout-land\main.xml
<?xml version="1.0" encoding="utf-8"?>
<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/pick"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:text="Pick"
    android:enabled="true"
  />
  <Button android:id="@+id/view"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:text="View"
    android:enabled="false"
  />
</LinearLayout>
extends ContentProvider
package app.test;

import java.util.HashMap;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.UriMatcher;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;

class Provider extends ContentProvider {
  private static final String DATABASE_NAME = "constants.db";
  private static final int CONSTANTS = 1;
  private static final int CONSTANT_ID = 2;
  private static final UriMatcher MATCHER;
  private static HashMap<String, String> CONSTANTS_LIST_PROJECTION;

  public static final class Constants implements BaseColumns {
    public static final Uri CONTENT_URI = Uri
        .parse("content://com.commonsware.android.constants.Provider/constants");
    public static final String DEFAULT_SORT_ORDER = "title";
    public static final String TITLE = "title";
    public static final String VALUE = "value";
  }

  static {
    MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
    MATCHER.addURI("com.commonsware.android.constants.Provider",
        "constants", CONSTANTS);
    MATCHER.addURI("com.commonsware.android.constants.Provider",
        "constants/#", CONSTANT_ID);

    CONSTANTS_LIST_PROJECTION = new HashMap<String, String>();
    CONSTANTS_LIST_PROJECTION.put(Provider.Constants._ID,
        Provider.Constants._ID);
    CONSTANTS_LIST_PROJECTION.put(Provider.Constants.TITLE,
        Provider.Constants.TITLE);
    CONSTANTS_LIST_PROJECTION.put(Provider.Constants.VALUE,
        Provider.Constants.VALUE);
  }

  public String getDbName() {
    return (DATABASE_NAME);
  }

  public int getDbVersion() {
    return (1);
  }

  private class DatabaseHelper extends SQLiteOpenHelper {
    public DatabaseHelper(Context context) {
      super(context, DATABASE_NAME, null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
      Cursor c = db
          .rawQuery(
              "SELECT name FROM sqlite_master WHERE type='table' AND name='constants'",
              null);

      try {
        if (c.getCount() == 0) {
          db.execSQL("CREATE TABLE constants (_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, value REAL);");

          ContentValues cv = new ContentValues();

          cv.put(Constants.TITLE, "Gravity, Death Star I");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_DEATH_STAR_I);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, Earth");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_EARTH);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, Jupiter");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_JUPITER);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, Mars");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_MARS);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, Mercury");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_MERCURY);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, Moon");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_MOON);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, Neptune");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_NEPTUNE);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, Pluto");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_PLUTO);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, Saturn");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_SATURN);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, Sun");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_SUN);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, The Island");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_THE_ISLAND);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, Uranus");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_URANUS);
          db.insert("constants", getNullColumnHack(), cv);

          cv.put(Constants.TITLE, "Gravity, Venus");
          cv.put(Constants.VALUE, SensorManager.GRAVITY_VENUS);
          db.insert("constants", getNullColumnHack(), cv);
        }
      } finally {
        c.close();
      }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
      android.util.Log.w("Constants",
          "Upgrading database, which will destroy all old data");
      db.execSQL("DROP TABLE IF EXISTS constants");
      onCreate(db);
    }
  }

  private SQLiteDatabase db;

  @Override
  public boolean onCreate() {
    db = (new DatabaseHelper(getContext())).getWritableDatabase();

    return (db == null) ? false : true;
  }

  @Override
  public Cursor query(Uri url, String[] projection, String selection,
      String[] selectionArgs, String sort) {
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

    qb.setTables(getTableName());

    if (isCollectionUri(url)) {
      qb.setProjectionMap(getDefaultProjection());
    } else {
      qb.appendWhere(getIdColumnName() + "="
          + url.getPathSegments().get(1));
    }

    String orderBy;

    if (TextUtils.isEmpty(sort)) {
      orderBy = getDefaultSortOrder();
    } else {
      orderBy = sort;
    }

    Cursor c = qb.query(db, projection, selection, selectionArgs, null,
        null, orderBy);
    c.setNotificationUri(getContext().getContentResolver(), url);
    return c;
  }

  @Override
  public String getType(Uri url) {
    if (isCollectionUri(url)) {
      return (getCollectionType());
    }

    return (getSingleType());
  }

  @Override
  public Uri insert(Uri url, ContentValues initialValues) {
    long rowID;
    ContentValues values;

    if (initialValues != null) {
      values = new ContentValues(initialValues);
    } else {
      values = new ContentValues();
    }

    if (!isCollectionUri(url)) {
      throw new IllegalArgumentException("Unknown URL " + url);
    }

    for (String colName : getRequiredColumns()) {
      if (values.containsKey(colName) == false) {
        throw new IllegalArgumentException("Missing column: " + colName);
      }
    }

    populateDefaultValues(values);

    rowID = db.insert(getTableName(), getNullColumnHack(), values);
    if (rowID > 0) {
      Uri uri = ContentUris.withAppendedId(getContentUri(), rowID);
      getContext().getContentResolver().notifyChange(uri, null);
      return uri;
    }

    throw new SQLException("Failed to insert row into " + url);
  }

  @Override
  public int delete(Uri url, String where, String[] whereArgs) {
    int count;
    long rowId = 0;

    if (isCollectionUri(url)) {
      count = db.delete(getTableName(), where, whereArgs);
    } else {
      String segment = url.getPathSegments().get(1);
      rowId = Long.parseLong(segment);
      count = db.delete(
          getTableName(),
          getIdColumnName()
              + "="
              + segment
              + (!TextUtils.isEmpty(where) ? " AND (" + where
                  + ')' : ""), whereArgs);
    }

    getContext().getContentResolver().notifyChange(url, null);
    return count;
  }

  @Override
  public int update(Uri url, ContentValues values, String where,
      String[] whereArgs) {
    int count;

    if (isCollectionUri(url)) {
      count = db.update(getTableName(), values, where, whereArgs);
    } else {
      String segment = url.getPathSegments().get(1);
      count = db.update(
          getTableName(),
          values,
          getIdColumnName()
              + "="
              + segment
              + (!TextUtils.isEmpty(where) ? " AND (" + where
                  + ')' : ""), whereArgs);
    }

    getContext().getContentResolver().notifyChange(url, null);
    return count;
  }

  private boolean isCollectionUri(Uri url) {
    return (MATCHER.match(url) == CONSTANTS);
  }

  private HashMap<String, String> getDefaultProjection() {
    return (CONSTANTS_LIST_PROJECTION);
  }

  private String getTableName() {
    return ("constants");
  }

  private String getIdColumnName() {
    return ("_id");
  }

  private String getDefaultSortOrder() {
    return ("title");
  }

  private String getCollectionType() {
    return ("vnd.android.cursor.dir/vnd.commonsware.constant");
  }

  private String getSingleType() {
    return ("vnd.android.cursor.item/vnd.commonsware.constant");
  }

  private String[] getRequiredColumns() {
    return (new String[] { "title" });
  }

  private void populateDefaultValues(ContentValues values) {
    Long now = Long.valueOf(System.currentTimeMillis());
    Resources r = Resources.getSystem();

    if (values.containsKey(Provider.Constants.VALUE) == false) {
      values.put(Provider.Constants.VALUE, 0.0f);
    }
  }

  private String getNullColumnHack() {
    return ("title");
  }

  private Uri getContentUri() {
    return (Provider.Constants.CONTENT_URI);
  }
}

public class Test extends ListActivity {
  private static final int ADD_ID = Menu.FIRST + 1;
  private static final int EDIT_ID = Menu.FIRST + 2;
  private static final int DELETE_ID = Menu.FIRST + 3;
  private static final int CLOSE_ID = Menu.FIRST + 4;
  private static final String[] PROJECTION = new String[] {
      Provider.Constants._ID, Provider.Constants.TITLE,
      Provider.Constants.VALUE };
  private Cursor constantsCursor;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    constantsCursor = managedQuery(Provider.Constants.CONTENT_URI,
        PROJECTION, null, null, null);

    ListAdapter adapter = new SimpleCursorAdapter(this, R.layout.row,
        constantsCursor, new String[] { Provider.Constants.TITLE,
            Provider.Constants.VALUE }, new int[] { R.id.title,
            R.id.value });

    setListAdapter(adapter);
    registerForContextMenu(getListView());
  }

  @Override
  public void onDestroy() {
    super.onDestroy();

    constantsCursor.close();
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(Menu.NONE, ADD_ID, Menu.NONE, "Add").setIcon(R.drawable.icon)
        .setAlphabeticShortcut('a');
    menu.add(Menu.NONE, CLOSE_ID, Menu.NONE, "Close")
        .setIcon(R.drawable.icon).setAlphabeticShortcut('c');

    return (super.onCreateOptionsMenu(menu));
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case ADD_ID:
      add();
      return (true);

    case CLOSE_ID:
      finish();
      return (true);
    }

    return (super.onOptionsItemSelected(item));
  }

  @Override
  public void onCreateContextMenu(ContextMenu menu, View v,
      ContextMenu.ContextMenuInfo menuInfo) {
    menu.add(Menu.NONE, DELETE_ID, Menu.NONE, "Delete")
        .setIcon(R.drawable.icon).setAlphabeticShortcut('d');
  }

  @Override
  public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case DELETE_ID:
      AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
          .getMenuInfo();

      delete(info.id);
      return (true);
    }

    return (super.onOptionsItemSelected(item));
  }

  private void add() {
    LayoutInflater inflater = LayoutInflater.from(this);
    View addView = inflater.inflate(R.layout.add_edit, null);
    final DialogWrapper wrapper = new DialogWrapper(addView);

    new AlertDialog.Builder(this)
        .setTitle(R.string.add_title)
        .setView(addView)
        .setPositiveButton(R.string.ok,
            new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog,
                  int whichButton) {
                processAdd(wrapper);
              }
            })
        .setNegativeButton(R.string.cancel,
            new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog,
                  int whichButton) {
                // ignore, just dismiss
              }
            }).show();
  }

  private void delete(final long rowId) {
    if (rowId > 0) {
      new AlertDialog.Builder(this)
          .setTitle(R.string.delete_title)
          .setPositiveButton(R.string.ok,
              new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog,
                    int whichButton) {
                  processDelete(rowId);
                }
              })
          .setNegativeButton(R.string.cancel,
              new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog,
                    int whichButton) {
                  // ignore, just dismiss
                }
              }).show();
    }
  }

  private void processAdd(DialogWrapper wrapper) {
    ContentValues values = new ContentValues(2);

    values.put(Provider.Constants.TITLE, wrapper.getTitle());
    values.put(Provider.Constants.VALUE, wrapper.getValue());

    getContentResolver().insert(Provider.Constants.CONTENT_URI, values);
    constantsCursor.requery();
  }

  private void processDelete(long rowId) {
    Uri uri = ContentUris.withAppendedId(Provider.Constants.CONTENT_URI,
        rowId);
    getContentResolver().delete(uri, null, null);
    constantsCursor.requery();
  }

  class DialogWrapper {
    EditText titleField = null;
    EditText valueField = null;
    View base = null;

    DialogWrapper(View base) {
      this.base = base;
      valueField = (EditText) base.findViewById(R.id.value);
    }

    String getTitle() {
      return (getTitleField().getText().toString());
    }

    float getValue() {
      return (new Float(getValueField().getText().toString())
          .floatValue());
    }

    private EditText getTitleField() {
      if (titleField == null) {
        titleField = (EditText) base.findViewById(R.id.title);
      }

      return (titleField);
    }

    private EditText getValueField() {
      if (valueField == null) {
        valueField = (EditText) base.findViewById(R.id.value);
      }

      return (valueField);
    }
  }
}

//main.xml

<?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"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Hello World, ConstantsBrowser"
    />
</LinearLayout>

//add_edit.xml

<?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"
    >
  <LinearLayout
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      >
    <TextView
        android:text="Display Name:"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        />
    <EditText
        android:id="@+id/title"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:layout_alignParentRight="true"
        />
  </LinearLayout>
  <LinearLayout
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      >
    <TextView
        android:text="Value:"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        />
    <EditText
        android:id="@+id/value"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:layout_alignParentRight="true"
        />
  </LinearLayout>
</LinearLayout>

//row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <TextView
      android:id="@+id/title"
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content"
      android:layout_alignParentLeft="true"
      />
  <TextView
      android:id="@+id/value"
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentRight="true"
      />
</RelativeLayout>

//strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">ConstantsBrowser</string>
    <string name="ok">OK</string>
    <string name="cancel">Cancel</string>
    <string name="add_title">Add Constant</string>
    <string name="delete_title">Delete Constant: Are You Sure?</string>
</resources>
A comprehensive UI for exploring and operating the DevicePolicyManager api.
package com.example.android.apis.app;

import com.example.android.apis.R;

import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.admin.DeviceAdminReceiver;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import java.util.List;


public class DeviceAdminSample extends PreferenceActivity {

    // Miscellaneous utilities and definitions
    private static final String TAG = "DeviceAdminSample";

    private static final int REQUEST_CODE_ENABLE_ADMIN = 1;
    private static final int REQUEST_CODE_START_ENCRYPTION = 2;

    private static final long MS_PER_MINUTE = 60 * 1000;
    private static final long MS_PER_HOUR = 60 * MS_PER_MINUTE;
    private static final long MS_PER_DAY = 24 * MS_PER_HOUR;

    // The following keys are used to find each preference item
    private static final String KEY_ENABLE_ADMIN = "key_enable_admin";

    private static final String KEY_CATEGORY_QUALITY = "key_category_quality";
    private static final String KEY_SET_PASSWORD = "key_set_password";
    private static final String KEY_RESET_PASSWORD = "key_reset_password";
    private static final String KEY_QUALITY = "key_quality";
    private static final String KEY_MIN_LENGTH = "key_minimum_length";
    private static final String KEY_MIN_LETTERS = "key_minimum_letters";
    private static final String KEY_MIN_NUMERIC = "key_minimum_numeric";
    private static final String KEY_MIN_LOWER_CASE = "key_minimum_lower_case";
    private static final String KEY_MIN_UPPER_CASE = "key_minimum_upper_case";
    private static final String KEY_MIN_SYMBOLS = "key_minimum_symbols";
    private static final String KEY_MIN_NON_LETTER = "key_minimum_non_letter";

    private static final String KEY_CATEGORY_EXPIRATION = "key_category_expiration";
    private static final String KEY_HISTORY = "key_history";
    private static final String KEY_EXPIRATION_TIMEOUT = "key_expiration_timeout";
    private static final String KEY_EXPIRATION_STATUS = "key_expiration_status";

    private static final String KEY_CATEGORY_LOCK_WIPE = "key_category_lock_wipe";
    private static final String KEY_MAX_TIME_SCREEN_LOCK = "key_max_time_screen_lock";
    private static final String KEY_MAX_FAILS_BEFORE_WIPE = "key_max_fails_before_wipe";
    private static final String KEY_LOCK_SCREEN = "key_lock_screen";
    private static final String KEY_WIPE_DATA = "key_wipe_data";
    private static final String KEY_WIP_DATA_ALL = "key_wipe_data_all";

    private static final String KEY_CATEGORY_ENCRYPTION = "key_category_encryption";
    private static final String KEY_REQUIRE_ENCRYPTION = "key_require_encryption";
    private static final String KEY_ACTIVATE_ENCRYPTION = "key_activate_encryption";

    // Interaction with the DevicePolicyManager
    DevicePolicyManager mDPM;
    ComponentName mDeviceAdminSample;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Prepare to work with the DPM
        mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
        mDeviceAdminSample = new ComponentName(this, DeviceAdminSampleReceiver.class);
    }

    /**
     * We override this method to provide PreferenceActivity with the top-level preference headers.
     */
    @Override
    public void onBuildHeaders(List<Header> target) {
        loadHeadersFromResource(R.xml.device_admin_headers, target);
    }

    /**
     * Helper to determine if we are an active admin
     */
    private boolean isActiveAdmin() {
        return mDPM.isAdminActive(mDeviceAdminSample);
    }

    /**
     * Common fragment code for DevicePolicyManager access.  Provides two shared elements:
     *
     *   1.  Provides instance variables to access activity/context, DevicePolicyManager, etc.
     *   2.  Provides support for the "set password" button(s) shared by multiple fragments.
     */
    public static class AdminSampleFragment extends PreferenceFragment
            implements OnPreferenceChangeListener, OnPreferenceClickListener{

        // Useful instance variables
        protected DeviceAdminSample mActivity;
        protected DevicePolicyManager mDPM;
        protected ComponentName mDeviceAdminSample;
        protected boolean mAdminActive;

        // Optional shared UI
        private PreferenceScreen mSetPassword;
        private EditTextPreference mResetPassword;

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

            // Retrieve the useful instance variables
            mActivity = (DeviceAdminSample) getActivity();
            mDPM = mActivity.mDPM;
            mDeviceAdminSample = mActivity.mDeviceAdminSample;
            mAdminActive = mActivity.isActiveAdmin();

            // Configure the shared UI elements (if they exist)
            mResetPassword = (EditTextPreference) findPreference(KEY_RESET_PASSWORD);
            mSetPassword = (PreferenceScreen) findPreference(KEY_SET_PASSWORD);

            if (mResetPassword != null) {
                mResetPassword.setOnPreferenceChangeListener(this);
            }
            if (mSetPassword != null) {
                mSetPassword.setOnPreferenceClickListener(this);
            }
        }

        @Override
        public void onResume() {
            super.onResume();
            mAdminActive = mActivity.isActiveAdmin();
            reloadSummaries();
            // Resetting the password via API is available only to active admins
            if (mResetPassword != null) {
                mResetPassword.setEnabled(mAdminActive);
            }
        }

        /**
         * Called automatically at every onResume.  Should also call explicitly any time a
         * policy changes that may affect other policy values.
         */
        protected void reloadSummaries() {
            if (mSetPassword != null) {
                if (mAdminActive) {
                    // Show password-sufficient status under Set Password button
                    boolean sufficient = mDPM.isActivePasswordSufficient();
                    mSetPassword.setSummary(sufficient ?
                            R.string.password_sufficient : R.string.password_insufficient);
                } else {
                    mSetPassword.setSummary(null);
                }
            }
        }

        @Override
        public boolean onPreferenceClick(Preference preference) {
            if (mSetPassword != null && preference == mSetPassword) {
                Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
                startActivity(intent);
                return true;
            }
            return false;
        }

        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (mResetPassword != null && preference == mResetPassword) {
                doResetPassword((String)newValue);
                return true;
            }
            return false;
        }

        /**
         * This is dangerous, so we prevent automated tests from doing it, and we
         * remind the user after we do it.
         */
        private void doResetPassword(String newPassword) {
            if (alertIfMonkey(mActivity, R.string.monkey_reset_password)) {
                return;
            }
            mDPM.resetPassword(newPassword, DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
            AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
            String message = mActivity.getString(R.string.reset_password_warning, newPassword);
            builder.setMessage(message);
            builder.setPositiveButton(R.string.reset_password_ok, null);
            builder.show();
        }

        /**
         * Simple helper for summaries showing local & global (aggregate) policy settings
         */
        protected String localGlobalSummary(Object local, Object global) {
            return getString(R.string.status_local_global, local, global);
        }
    }

    /**
     * PreferenceFragment for "general" preferences.
     */
    public static class GeneralFragment extends AdminSampleFragment
            implements OnPreferenceChangeListener {
        // UI elements
        private CheckBoxPreference mEnableCheckbox;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.device_admin_general);
            mEnableCheckbox = (CheckBoxPreference) findPreference(KEY_ENABLE_ADMIN);
            mEnableCheckbox.setOnPreferenceChangeListener(this);
        }

        // At onResume time, reload UI with current values as required
        @Override
        public void onResume() {
            super.onResume();
            mEnableCheckbox.setChecked(mAdminActive);
        }

        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (super.onPreferenceChange(preference, newValue)) {
                return true;
            }
            if (preference == mEnableCheckbox) {
                boolean newActive = (Boolean) newValue;
                if (newActive != mAdminActive) {
                    if (newActive) {
                        // Launch the activity to have the user enable our admin.
                        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
                        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mDeviceAdminSample);
                        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                                mActivity.getString(R.string.add_admin_extra_app_text));
                        startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
                        // return false - don't update checkbox until we're really active
                        return false;
                    } else {
                        mDPM.removeActiveAdmin(mDeviceAdminSample);
                        mAdminActive = false;
                    }
                }
            }
            return true;
        }
    }

    /**
     * PreferenceFragment for "password quality" preferences.
     */
    public static class QualityFragment extends AdminSampleFragment
            implements OnPreferenceChangeListener {

        // Password quality values
        // This list must match the list found in samples/ApiDemos/res/values/arrays.xml
        final static int[] mPasswordQualityValues = new int[] {
            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
            DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
            DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
            DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC,
            DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
            DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
        };

        // Password quality values (as strings, for the ListPreference entryValues)
        // This list must match the list found in samples/ApiDemos/res/values/arrays.xml
        final static String[] mPasswordQualityValueStrings = new String[] {
            String.valueOf(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED),
            String.valueOf(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING),
            String.valueOf(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC),
            String.valueOf(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC),
            String.valueOf(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC),
            String.valueOf(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX)
        };

        // UI elements
        private PreferenceCategory mQualityCategory;
        private ListPreference mPasswordQuality;
        private EditTextPreference mMinLength;
        private EditTextPreference mMinLetters;
        private EditTextPreference mMinNumeric;
        private EditTextPreference mMinLowerCase;
        private EditTextPreference mMinUpperCase;
        private EditTextPreference mMinSymbols;
        private EditTextPreference mMinNonLetter;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.device_admin_quality);

            mQualityCategory = (PreferenceCategory) findPreference(KEY_CATEGORY_QUALITY);
            mPasswordQuality = (ListPreference) findPreference(KEY_QUALITY);
            mMinLength = (EditTextPreference) findPreference(KEY_MIN_LENGTH);
            mMinLetters = (EditTextPreference) findPreference(KEY_MIN_LETTERS);
            mMinNumeric = (EditTextPreference) findPreference(KEY_MIN_NUMERIC);
            mMinLowerCase = (EditTextPreference) findPreference(KEY_MIN_LOWER_CASE);
            mMinUpperCase = (EditTextPreference) findPreference(KEY_MIN_UPPER_CASE);
            mMinSymbols = (EditTextPreference) findPreference(KEY_MIN_SYMBOLS);
            mMinNonLetter = (EditTextPreference) findPreference(KEY_MIN_NON_LETTER);

            mPasswordQuality.setOnPreferenceChangeListener(this);
            mMinLength.setOnPreferenceChangeListener(this);
            mMinLetters.setOnPreferenceChangeListener(this);
            mMinNumeric.setOnPreferenceChangeListener(this);
            mMinLowerCase.setOnPreferenceChangeListener(this);
            mMinUpperCase.setOnPreferenceChangeListener(this);
            mMinSymbols.setOnPreferenceChangeListener(this);
            mMinNonLetter.setOnPreferenceChangeListener(this);

            // Finish setup of the quality dropdown
            mPasswordQuality.setEntryValues(mPasswordQualityValueStrings);
        }

        @Override
        public void onResume() {
            super.onResume();
            mQualityCategory.setEnabled(mAdminActive);
        }

        /**
         * Update the summaries of each item to show the local setting and the global setting.
         */
        @Override
        protected void reloadSummaries() {
            super.reloadSummaries();
            // Show numeric settings for each policy API
            int local, global;
            local = mDPM.getPasswordQuality(mDeviceAdminSample);
            global = mDPM.getPasswordQuality(null);
            mPasswordQuality.setSummary(
                    localGlobalSummary(qualityValueToString(local), qualityValueToString(global)));
            local = mDPM.getPasswordMinimumLength(mDeviceAdminSample);
            global = mDPM.getPasswordMinimumLength(null);
            mMinLength.setSummary(localGlobalSummary(local, global));
            local = mDPM.getPasswordMinimumLetters(mDeviceAdminSample);
            global = mDPM.getPasswordMinimumLetters(null);
            mMinLetters.setSummary(localGlobalSummary(local, global));
            local = mDPM.getPasswordMinimumNumeric(mDeviceAdminSample);
            global = mDPM.getPasswordMinimumNumeric(null);
            mMinNumeric.setSummary(localGlobalSummary(local, global));
            local = mDPM.getPasswordMinimumLowerCase(mDeviceAdminSample);
            global = mDPM.getPasswordMinimumLowerCase(null);
            mMinLowerCase.setSummary(localGlobalSummary(local, global));
            local = mDPM.getPasswordMinimumUpperCase(mDeviceAdminSample);
            global = mDPM.getPasswordMinimumUpperCase(null);
            mMinUpperCase.setSummary(localGlobalSummary(local, global));
            local = mDPM.getPasswordMinimumSymbols(mDeviceAdminSample);
            global = mDPM.getPasswordMinimumSymbols(null);
            mMinSymbols.setSummary(localGlobalSummary(local, global));
            local = mDPM.getPasswordMinimumNonLetter(mDeviceAdminSample);
            global = mDPM.getPasswordMinimumNonLetter(null);
            mMinNonLetter.setSummary(localGlobalSummary(local, global));
        }

        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (super.onPreferenceChange(preference, newValue)) {
                return true;
            }
            String valueString = (String)newValue;
            if (TextUtils.isEmpty(valueString)) {
                return false;
            }
            int value = 0;
            try {
                value = Integer.parseInt(valueString);
            } catch (NumberFormatException nfe) {
                String warning = mActivity.getString(R.string.number_format_warning, valueString);
                Toast.makeText(mActivity, warning, Toast.LENGTH_SHORT).show();
            }
            if (preference == mPasswordQuality) {
                mDPM.setPasswordQuality(mDeviceAdminSample, value);
            } else if (preference == mMinLength) {
                mDPM.setPasswordMinimumLength(mDeviceAdminSample, value);
            } else if (preference == mMinLetters) {
                mDPM.setPasswordMinimumLetters(mDeviceAdminSample, value);
            } else if (preference == mMinNumeric) {
                mDPM.setPasswordMinimumNumeric(mDeviceAdminSample, value);
            } else if (preference == mMinLowerCase) {
                mDPM.setPasswordMinimumLowerCase(mDeviceAdminSample, value);
            } else if (preference == mMinUpperCase) {
                mDPM.setPasswordMinimumUpperCase(mDeviceAdminSample, value);
            } else if (preference == mMinSymbols) {
                mDPM.setPasswordMinimumSymbols(mDeviceAdminSample, value);
            } else if (preference == mMinNonLetter) {
                mDPM.setPasswordMinimumNonLetter(mDeviceAdminSample, value);
            }
            reloadSummaries();
            return true;
        }

        private String qualityValueToString(int quality) {
            for (int i=  0; i < mPasswordQualityValues.length; i++) {
                if (mPasswordQualityValues[i] == quality) {
                    String[] qualities =
                        mActivity.getResources().getStringArray(R.array.password_qualities);
                    return qualities[i];
                }
            }
            return "(0x" + Integer.toString(quality, 16) + ")";
        }
    }

    /**
     * PreferenceFragment for "password expiration" preferences.
     */
    public static class ExpirationFragment extends AdminSampleFragment
            implements OnPreferenceChangeListener, OnPreferenceClickListener {
        private PreferenceCategory mExpirationCategory;
        private EditTextPreference mHistory;
        private EditTextPreference mExpirationTimeout;
        private PreferenceScreen mExpirationStatus;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.device_admin_expiration);

            mExpirationCategory = (PreferenceCategory) findPreference(KEY_CATEGORY_EXPIRATION);
            mHistory = (EditTextPreference) findPreference(KEY_HISTORY);
            mExpirationTimeout = (EditTextPreference) findPreference(KEY_EXPIRATION_TIMEOUT);
            mExpirationStatus = (PreferenceScreen) findPreference(KEY_EXPIRATION_STATUS);

            mHistory.setOnPreferenceChangeListener(this);
            mExpirationTimeout.setOnPreferenceChangeListener(this);
            mExpirationStatus.setOnPreferenceClickListener(this);
        }

        @Override
        public void onResume() {
            super.onResume();
            mExpirationCategory.setEnabled(mAdminActive);
        }

        /**
         * Update the summaries of each item to show the local setting and the global setting.
         */
        @Override
        protected void reloadSummaries() {
            super.reloadSummaries();

            int local, global;
            local = mDPM.getPasswordHistoryLength(mDeviceAdminSample);
            global = mDPM.getPasswordHistoryLength(null);
            mHistory.setSummary(localGlobalSummary(local, global));

            long localLong, globalLong;
            localLong = mDPM.getPasswordExpirationTimeout(mDeviceAdminSample);
            globalLong = mDPM.getPasswordExpirationTimeout(null);
            mExpirationTimeout.setSummary(localGlobalSummary(
                    localLong / MS_PER_MINUTE, globalLong / MS_PER_MINUTE));

            String expirationStatus = getExpirationStatus();
            mExpirationStatus.setSummary(expirationStatus);
        }

        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (super.onPreferenceChange(preference, newValue)) {
                return true;
            }
            String valueString = (String)newValue;
            if (TextUtils.isEmpty(valueString)) {
                return false;
            }
            int value = 0;
            try {
                value = Integer.parseInt(valueString);
            } catch (NumberFormatException nfe) {
                String warning = mActivity.getString(R.string.number_format_warning, valueString);
                Toast.makeText(mActivity, warning, Toast.LENGTH_SHORT).show();
            }
            if (preference == mHistory) {
                mDPM.setPasswordHistoryLength(mDeviceAdminSample, value);
            } else if (preference == mExpirationTimeout) {
                mDPM.setPasswordExpirationTimeout(mDeviceAdminSample, value * MS_PER_MINUTE);
            }
            reloadSummaries();
            return true;
        }

        @Override
        public boolean onPreferenceClick(Preference preference) {
            if (super.onPreferenceClick(preference)) {
                return true;
            }
            if (preference == mExpirationStatus) {
                String expirationStatus = getExpirationStatus();
                mExpirationStatus.setSummary(expirationStatus);
                return true;
            }
            return false;
        }

        /**
         * Create a summary string describing the expiration status for the sample app,
         * as well as the global (aggregate) status.
         */
        private String getExpirationStatus() {
            // expirations are absolute;  convert to relative for display
            long localExpiration = mDPM.getPasswordExpiration(mDeviceAdminSample);
            long globalExpiration = mDPM.getPasswordExpiration(null);
            long now = System.currentTimeMillis();

            // local expiration
            String local;
            if (localExpiration == 0) {
                local = mActivity.getString(R.string.expiration_status_none);
            } else {
                localExpiration -= now;
                String dms = timeToDaysMinutesSeconds(mActivity, Math.abs(localExpiration));
                if (localExpiration >= 0) {
                    local = mActivity.getString(R.string.expiration_status_future, dms);
                } else {
                    local = mActivity.getString(R.string.expiration_status_past, dms);
                }
            }

            // global expiration
            String global;
            if (globalExpiration == 0) {
                global = mActivity.getString(R.string.expiration_status_none);
            } else {
                globalExpiration -= now;
                String dms = timeToDaysMinutesSeconds(mActivity, Math.abs(globalExpiration));
                if (globalExpiration >= 0) {
                    global = mActivity.getString(R.string.expiration_status_future, dms);
                } else {
                    global = mActivity.getString(R.string.expiration_status_past, dms);
                }
            }
            return mActivity.getString(R.string.status_local_global, local, global);
        }
    }

    /**
     * PreferenceFragment for "lock screen & wipe" preferences.
     */
    public static class LockWipeFragment extends AdminSampleFragment
            implements OnPreferenceChangeListener, OnPreferenceClickListener {
        private PreferenceCategory mLockWipeCategory;
        private EditTextPreference mMaxTimeScreenLock;
        private EditTextPreference mMaxFailures;
        private PreferenceScreen mLockScreen;
        private PreferenceScreen mWipeData;
        private PreferenceScreen mWipeAppData;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.device_admin_lock_wipe);

            mLockWipeCategory = (PreferenceCategory) findPreference(KEY_CATEGORY_LOCK_WIPE);
            mMaxTimeScreenLock = (EditTextPreference) findPreference(KEY_MAX_TIME_SCREEN_LOCK);
            mMaxFailures = (EditTextPreference) findPreference(KEY_MAX_FAILS_BEFORE_WIPE);
            mLockScreen = (PreferenceScreen) findPreference(KEY_LOCK_SCREEN);
            mWipeData = (PreferenceScreen) findPreference(KEY_WIPE_DATA);
            mWipeAppData = (PreferenceScreen) findPreference(KEY_WIP_DATA_ALL);

            mMaxTimeScreenLock.setOnPreferenceChangeListener(this);
            mMaxFailures.setOnPreferenceChangeListener(this);
            mLockScreen.setOnPreferenceClickListener(this);
            mWipeData.setOnPreferenceClickListener(this);
            mWipeAppData.setOnPreferenceClickListener(this);
        }

        @Override
        public void onResume() {
            super.onResume();
            mLockWipeCategory.setEnabled(mAdminActive);
        }

        /**
         * Update the summaries of each item to show the local setting and the global setting.
         */
        @Override
        protected void reloadSummaries() {
            super.reloadSummaries();

            long localLong, globalLong;
            localLong = mDPM.getMaximumTimeToLock(mDeviceAdminSample);
            globalLong = mDPM.getMaximumTimeToLock(null);
            mMaxTimeScreenLock.setSummary(localGlobalSummary(
                    localLong / MS_PER_MINUTE, globalLong / MS_PER_MINUTE));

            int local, global;
            local = mDPM.getMaximumFailedPasswordsForWipe(mDeviceAdminSample);
            global = mDPM.getMaximumFailedPasswordsForWipe(null);
            mMaxFailures.setSummary(localGlobalSummary(local, global));
        }

        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (super.onPreferenceChange(preference, newValue)) {
                return true;
            }
            String valueString = (String)newValue;
            if (TextUtils.isEmpty(valueString)) {
                return false;
            }
            int value = 0;
            try {
                value = Integer.parseInt(valueString);
            } catch (NumberFormatException nfe) {
                String warning = mActivity.getString(R.string.number_format_warning, valueString);
                Toast.makeText(mActivity, warning, Toast.LENGTH_SHORT).show();
            }
            if (preference == mMaxTimeScreenLock) {
                mDPM.setMaximumTimeToLock(mDeviceAdminSample, value * MS_PER_MINUTE);
            } else if (preference == mMaxFailures) {
                if (alertIfMonkey(mActivity, R.string.monkey_wipe_data)) {
                    return true;
                }
                mDPM.setMaximumFailedPasswordsForWipe(mDeviceAdminSample, value);
            }
            reloadSummaries();
            return true;
        }

        @Override
        public boolean onPreferenceClick(Preference preference) {
            if (super.onPreferenceClick(preference)) {
                return true;
            }
            if (preference == mLockScreen) {
                if (alertIfMonkey(mActivity, R.string.monkey_lock_screen)) {
                    return true;
                }
                mDPM.lockNow();
                return true;
            } else if (preference == mWipeData || preference == mWipeAppData) {
                if (alertIfMonkey(mActivity, R.string.monkey_wipe_data)) {
                    return true;
                }
                promptForRealDeviceWipe(preference == mWipeAppData);
                return true;
            }
            return false;
        }

        /**
         * Wiping data is real, so we don't want it to be easy.  Show two alerts before wiping.
         */
        private void promptForRealDeviceWipe(final boolean wipeAllData) {
            final DeviceAdminSample activity = mActivity;

            AlertDialog.Builder builder = new AlertDialog.Builder(activity);
            builder.setMessage(R.string.wipe_warning_first);
            builder.setPositiveButton(R.string.wipe_warning_first_ok,
                    new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(activity);
                    if (wipeAllData) {
                        builder.setMessage(R.string.wipe_warning_second_full);
                    } else {
                        builder.setMessage(R.string.wipe_warning_second);
                    }
                    builder.setPositiveButton(R.string.wipe_warning_second_ok,
                            new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            boolean stillActive = mActivity.isActiveAdmin();
                            if (stillActive) {
                                mDPM.wipeData(wipeAllData
                                        ? DevicePolicyManager.WIPE_EXTERNAL_STORAGE : 0);
                            }
                        }
                    });
                    builder.setNegativeButton(R.string.wipe_warning_second_no, null);
                    builder.show();
                }
            });
            builder.setNegativeButton(R.string.wipe_warning_first_no, null);
            builder.show();
        }
    }

    /**
     * PreferenceFragment for "encryption" preferences.
     */
    public static class EncryptionFragment extends AdminSampleFragment
            implements OnPreferenceChangeListener, OnPreferenceClickListener {
        private PreferenceCategory mEncryptionCategory;
        private CheckBoxPreference mRequireEncryption;
        private PreferenceScreen mActivateEncryption;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.device_admin_encryption);

            mEncryptionCategory = (PreferenceCategory) findPreference(KEY_CATEGORY_ENCRYPTION);
            mRequireEncryption = (CheckBoxPreference) findPreference(KEY_REQUIRE_ENCRYPTION);
            mActivateEncryption = (PreferenceScreen) findPreference(KEY_ACTIVATE_ENCRYPTION);

            mRequireEncryption.setOnPreferenceChangeListener(this);
            mActivateEncryption.setOnPreferenceClickListener(this);
        }

        @Override
        public void onResume() {
            super.onResume();
            mEncryptionCategory.setEnabled(mAdminActive);
            mRequireEncryption.setChecked(mDPM.getStorageEncryption(mDeviceAdminSample));
        }

        /**
         * Update the summaries of each item to show the local setting and the global setting.
         */
        @Override
        protected void reloadSummaries() {
            super.reloadSummaries();

            boolean local, global;
            local = mDPM.getStorageEncryption(mDeviceAdminSample);
            global = mDPM.getStorageEncryption(null);
            mRequireEncryption.setSummary(localGlobalSummary(local, global));

            int deviceStatusCode = mDPM.getStorageEncryptionStatus();
            String deviceStatus = statusCodeToString(deviceStatusCode);
            String status = mActivity.getString(R.string.status_device_encryption, deviceStatus);
            mActivateEncryption.setSummary(status);
        }

        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            if (super.onPreferenceChange(preference, newValue)) {
                return true;
            }
            if (preference == mRequireEncryption) {
                boolean newActive = (Boolean) newValue;
                mDPM.setStorageEncryption(mDeviceAdminSample, newActive);
                reloadSummaries();
                return true;
            }
            return true;
        }

        @Override
        public boolean onPreferenceClick(Preference preference) {
            if (super.onPreferenceClick(preference)) {
                return true;
            }
            if (preference == mActivateEncryption) {
                if (alertIfMonkey(mActivity, R.string.monkey_encryption)) {
                    return true;
                }
                // Check to see if encryption is even supported on this device (it's optional).
                if (mDPM.getStorageEncryptionStatus() ==
                        DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
                    builder.setMessage(R.string.encryption_not_supported);
                    builder.setPositiveButton(R.string.encryption_not_supported_ok, null);
                    builder.show();
                    return true;
                }
                // Launch the activity to activate encryption.  May or may not return!
                Intent intent = new Intent(DevicePolicyManager.ACTION_START_ENCRYPTION);
                startActivityForResult(intent, REQUEST_CODE_START_ENCRYPTION);
                return true;
            }
            return false;
        }

        private String statusCodeToString(int newStatusCode) {
            int newStatus = R.string.encryption_status_unknown;
            switch (newStatusCode) {
                case DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED:
                    newStatus = R.string.encryption_status_unsupported;
                    break;
                case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE:
                    newStatus = R.string.encryption_status_inactive;
                    break;
                case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING:
                    newStatus = R.string.encryption_status_activating;
                    break;
                case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
                    newStatus = R.string.encryption_status_active;
                    break;
            }
            return mActivity.getString(newStatus);
        }
    }

    /**
     * Simple converter used for long expiration times reported in mSec.
     */
    private static String timeToDaysMinutesSeconds(Context context, long time) {
        long days = time / MS_PER_DAY;
        long hours = (time / MS_PER_HOUR) % 24;
        long minutes = (time / MS_PER_MINUTE) % 60;
        return context.getString(R.string.status_days_hours_minutes, days, hours, minutes);
    }

    /**
     * If the "user" is a monkey, post an alert and notify the caller.  This prevents automated
     * test frameworks from stumbling into annoying or dangerous operations.
     */
    private static boolean alertIfMonkey(Context context, int stringId) {
        if (ActivityManager.isUserAMonkey()) {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setMessage(stringId);
            builder.setPositiveButton(R.string.monkey_ok, null);
            builder.show();
            return true;
        } else {
            return false;
        }
    }


    public static class DeviceAdminSampleReceiver extends DeviceAdminReceiver {
        void showToast(Context context, String msg) {
            String status = context.getString(R.string.admin_receiver_status, msg);
            Toast.makeText(context, status, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onEnabled(Context context, Intent intent) {
            showToast(context, context.getString(R.string.admin_receiver_status_enabled));
        }

        @Override
        public CharSequence onDisableRequested(Context context, Intent intent) {
            return context.getString(R.string.admin_receiver_status_disable_warning);
        }

        @Override
        public void onDisabled(Context context, Intent intent) {
            showToast(context, context.getString(R.string.admin_receiver_status_disabled));
        }

        @Override
        public void onPasswordChanged(Context context, Intent intent) {
            showToast(context, context.getString(R.string.admin_receiver_status_pw_changed));
        }

        @Override
        public void onPasswordFailed(Context context, Intent intent) {
            showToast(context, context.getString(R.string.admin_receiver_status_pw_failed));
        }

        @Override
        public void onPasswordSucceeded(Context context, Intent intent) {
            showToast(context, context.getString(R.string.admin_receiver_status_pw_succeeded));
        }

        @Override
        public void onPasswordExpiring(Context context, Intent intent) {
            DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                    Context.DEVICE_POLICY_SERVICE);
            long expr = dpm.getPasswordExpiration(
                    new ComponentName(context, DeviceAdminSampleReceiver.class));
            long delta = expr - System.currentTimeMillis();
            boolean expired = delta < 0L;
            String message = context.getString(expired ?
                    R.string.expiration_status_past : R.string.expiration_status_future);
            showToast(context, message);
            Log.v(TAG, message);
        }
    }
}
//
//xml\device_admin_encryption.xml
<?xml version="1.0" encoding="utf-8"?>

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

    <PreferenceCategory
        android:key="key_category_encryption"
        android:title="@string/encryption_category" >

        <CheckBoxPreference
            android:key="key_require_encryption"
            android:title="@string/require_encryption" />
        <PreferenceScreen
            android:key="key_activate_encryption"
            android:title="@string/activate_encryption" />
    </PreferenceCategory>

</PreferenceScreen>



//xml\device_admin_expiration.xml
<?xml version="1.0" encoding="utf-8"?>

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

    <PreferenceCategory
        android:title="@string/password_controls_category" >

        <PreferenceScreen
            android:key="key_set_password"
            android:title="@string/set_password_user" />
        <EditTextPreference
            android:key="key_reset_password"
            android:title="@string/set_password_api"
            android:dialogTitle="@string/set_password_api_dialog" />
    </PreferenceCategory>

    <PreferenceCategory
        android:key="key_category_expiration"
        android:title="@string/password_expiration_category" >

        <EditTextPreference
            android:key="key_history"
            android:title="@string/password_history_depth"
            android:dialogTitle="@string/password_history_depth"
            android:inputType="number" />
        <EditTextPreference
            android:key="key_expiration_timeout"
            android:title="@string/password_expiration_timeout"
            android:dialogTitle="@string/password_expiration_timeout"
            android:inputType="number" />
        <PreferenceScreen
            android:key="key_expiration_status"
            android:title="@string/password_expiration_status" />
    </PreferenceCategory>

</PreferenceScreen>



//xml\device_admin_general.xml
<?xml version="1.0" encoding="utf-8"?>

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

    <PreferenceCategory
        android:title="@string/enable_admin" >

        <CheckBoxPreference
            android:key="key_enable_admin"
            android:title="@string/enable_admin" />

    </PreferenceCategory>

</PreferenceScreen>



//xml\device_admin_headers.xml
<?xml version="1.0" encoding="utf-8"?>

<preference-headers
    xmlns:android="http://schemas.android.com/apk/res/android" >

    <header
        android:fragment="com.example.android.apis.app.DeviceAdminSample$GeneralFragment"
        android:title="@string/header_general" />

    <header
        android:fragment="com.example.android.apis.app.DeviceAdminSample$QualityFragment"
        android:title="@string/header_quality" />

    <header
        android:fragment="com.example.android.apis.app.DeviceAdminSample$ExpirationFragment"
        android:title="@string/header_expiration" />

    <header
        android:fragment="com.example.android.apis.app.DeviceAdminSample$LockWipeFragment"
        android:title="@string/header_lock_wipe" />

    <header
        android:fragment="com.example.android.apis.app.DeviceAdminSample$EncryptionFragment"
        android:title="@string/header_encryption" />

</preference-headers>



//xml\device_admin_lock_wipe.xml
<?xml version="1.0" encoding="utf-8"?>

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

    <PreferenceCategory
        android:key="key_category_lock_wipe"
        android:title="@string/lock_wipe_category" >

        <EditTextPreference
            android:key="key_max_time_screen_lock"
            android:title="@string/maximum_lock_time"
            android:dialogTitle="@string/maximum_lock_time"
            android:inputType="number" />
        <EditTextPreference
            android:key="key_max_fails_before_wipe"
            android:title="@string/maximum_password_fails"
            android:dialogTitle="@string/maximum_password_fails"
            android:inputType="number" />
        <PreferenceScreen
            android:key="key_lock_screen"
            android:title="@string/lock_screen" />
        <PreferenceScreen
            android:key="key_wipe_data"
            android:title="@string/wipe_data"
            android:summary="@string/wipe_data_summary" />
        <PreferenceScreen
            android:key="key_wipe_data_all"
            android:title="@string/wipe_all_data"
            android:summary="@string/wipe_all_data_summary" />

    </PreferenceCategory>

</PreferenceScreen>



//xml\device_admin_quality.xml
<?xml version="1.0" encoding="utf-8"?>

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

    <PreferenceCategory
        android:title="@string/password_controls_category" >

        <PreferenceScreen
            android:key="key_set_password"
            android:title="@string/set_password_user" />
        <EditTextPreference
            android:key="key_reset_password"
            android:title="@string/set_password_api"
            android:dialogTitle="@string/set_password_api_dialog" />
    </PreferenceCategory>

    <PreferenceCategory
        android:key="key_category_quality"
        android:title="@string/password_quality_category" >

        <ListPreference
            android:key="key_quality"
            android:title="@string/password_quality"
            android:entries="@array/password_qualities"
            android:dialogTitle="@string/password_quality" />
        <EditTextPreference
            android:key="key_minimum_length"
            android:title="@string/password_minimum_length"
            android:dialogTitle="@string/password_minimum_length"
            android:inputType="number" />
        <EditTextPreference
            android:key="key_minimum_letters"
            android:title="@string/password_minimum_letters"
            android:dialogTitle="@string/password_minimum_letters" />
        <EditTextPreference
            android:key="key_minimum_numeric"
            android:title="@string/password_minimum_numeric"
            android:dialogTitle="@string/password_minimum_numeric"
            android:inputType="number"  />
        <EditTextPreference
            android:key="key_minimum_lower_case"
            android:title="@string/password_minimum_lower_case"
            android:dialogTitle="@string/password_minimum_lower_case"
            android:inputType="number"  />
        <EditTextPreference
            android:key="key_minimum_upper_case"
            android:title="@string/password_minimum_upper_case"
            android:dialogTitle="@string/password_minimum_upper_case"
            android:inputType="number"  />
        <EditTextPreference
            android:key="key_minimum_symbols"
            android:title="@string/password_minimum_symbols"
            android:dialogTitle="@string/password_minimum_symbols"
            android:inputType="number"  />
        <EditTextPreference
            android:key="key_minimum_non_letter"
            android:title="@string/password_minimum_non_letter"
            android:dialogTitle="@string/password_minimum_non_letter"
            android:inputType="number"  />
    </PreferenceCategory>

</PreferenceScreen>



//xml\device_admin_sample.xml
<?xml version="1.0" encoding="utf-8"?>


<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <limit-password />
        <watch-login />
        <reset-password />
        <force-lock />
        <wipe-data />
        <expire-password />
        <encrypted-storage />
    </uses-policies>
</device-admin>

Using DoBackgroundTask

   
package app.test;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.IntentService;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

class MyIntentService extends IntentService {

  public MyIntentService() {
    super("MyIntentServiceName");
  }
  @Override
  protected void onHandleIntent(Intent intent) {
    try {
      int result = DownloadFile(new URL("http://a.com/b.pdf"));
      Log.d("IntentService", "Downloaded " + result + " bytes");
      Intent broadcastIntent = new Intent();
      broadcastIntent.setAction("FILE_DOWNLOADED_ACTION");
      getBaseContext().sendBroadcast(broadcastIntent);

    } catch (MalformedURLException e) {
      e.printStackTrace();
    }
  }

  private int DownloadFile(URL url) {
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    return 100;
  }
}

class MyService extends Service {
  int counter = 0;
  public URL[] urls;

  static final int UPDATE_INTERVAL = 1000;
  private Timer timer = new Timer();

  private final IBinder binder = new MyBinder();

  public class MyBinder extends Binder {
    MyService getService() {
      return MyService.this;
    }
  }

  @Override
  public IBinder onBind(Intent arg0) {
    return binder;
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();

    try {
      int result = DownloadFile(new URL("http://amazon.com"));
      Toast.makeText(getBaseContext(), "Downloaded " + result + " bytes",
          Toast.LENGTH_LONG).show();
    } catch (MalformedURLException e) {
      e.printStackTrace();
    }

    try {
      new DoBackgroundTask().execute(new URL("http://a.com/a.pdf"),
          new URL("http://b.com/b.pdf"),
          new URL("http://c.com/c.pdf"),
          new URL("http://d.net/d.pdf"));

    } catch (MalformedURLException e) {
      e.printStackTrace();
    }
    doSomethingRepeatedly();

    Object[] objUrls = (Object[]) intent.getExtras().get("URLs");
    URL[] urls = new URL[objUrls.length];
    for (int i = 0; i < objUrls.length - 1; i++) {
      urls[i] = (URL) objUrls[i];
    }
    new DoBackgroundTask().execute(urls);

    return START_STICKY;
  }

  private void doSomethingRepeatedly() {
    timer.scheduleAtFixedRate(new TimerTask() {
      public void run() {
        Log.d("MyService", String.valueOf(++counter));
        try {
          Thread.sleep(4000);
          Log.d("MyService", counter + " Finished");

        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }, 0, UPDATE_INTERVAL);
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    if (timer != null) {
      timer.cancel();
    }
    Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
  }

  private int DownloadFile(URL url) {
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    return 100;
  }

  private class DoBackgroundTask extends AsyncTask<URL, Integer, Long> {
    protected Long doInBackground(URL... urls) {
      int count = urls.length;
      long totalBytesDownloaded = 0;
      for (int i = 0; i < count; i++) {
        totalBytesDownloaded += DownloadFile(urls[i]);
        publishProgress((int) (((i + 1) / (float) count) * 100));
      }
      return totalBytesDownloaded;
    }

    protected void onProgressUpdate(Integer... progress) {
      Log.d("Downloading files", String.valueOf(progress[0])
          + "% downloaded");
      Toast.makeText(getBaseContext(),
          String.valueOf(progress[0]) + "% downloaded",
          Toast.LENGTH_LONG).show();
    }

    protected void onPostExecute(Long result) {
      Toast.makeText(getBaseContext(), "Downloaded " + result + " bytes",
          Toast.LENGTH_LONG).show();
      stopSelf();
    }
  }
}

public class Test extends Activity {
  IntentFilter intentFilter;
  private MyService serviceBinder;
  Intent i;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    intentFilter = new IntentFilter();
    intentFilter.addAction("FILE_DOWNLOADED_ACTION");
    registerReceiver(intentReceiver, intentFilter);

    Button btnStart = (Button) findViewById(R.id.btnStartService);
    btnStart.setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {

        Intent intent = new Intent(getBaseContext(), MyService.class);
        try {
          URL[] urls = new URL[] { new URL("http://a.com/a.pdf"),
              new URL("http://b.com/b.pdf"),
              new URL("http://c.com/c.pdf"),
              new URL("http://d.com/d.pdf") };
          intent.putExtra("URLs", urls);

        } catch (MalformedURLException e) {
          e.printStackTrace();
        }
        startService(intent);

        startService(new Intent(getBaseContext(), MyService.class));
        startService(new Intent("app.test.MyService"));
        startService(new Intent(getBaseContext(), MyIntentService.class));

        i = new Intent(Test.this, MyService.class);
        bindService(i, connection, Context.BIND_AUTO_CREATE);
      }
    });

    Button btnStop = (Button) findViewById(R.id.btnStopService);
    btnStop.setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
        stopService(new Intent(getBaseContext(), MyService.class));
      }
    });
  }

  private ServiceConnection connection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
      serviceBinder = ((MyService.MyBinder) service).getService();
      try {
        URL[] urls = new URL[] { new URL("http://a.com/a.pdf"),
            new URL("http://b.com/b.pdf"),
            new URL("http://c.com/c.pdf"),
            new URL("http://d.net/d.pdf") };
        serviceBinder.urls = urls;
      } catch (MalformedURLException e) {
        e.printStackTrace();
      }
      startService(i);
    }

    public void onServiceDisconnected(ComponentName className) {
      serviceBinder = null;
    }
  };
  private BroadcastReceiver intentReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
      Toast.makeText(getBaseContext(), "File downloaded!",
          Toast.LENGTH_LONG).show();
    }
  };
}

//main.xml

<?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"
    >
<Button android:id="@+id/btnStartService"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:text="Start Service" />
        
<Button android:id="@+id/btnStopService"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:text="Stop Service" />
        
</LinearLayout>

Using android.os.Handler

package app.test;

import java.io.ByteArrayOutputStream;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

/**
 * PurgeableBitmap demonstrates the effects of setting Bitmaps as being
 * purgeable.
 * 
 * In the NonPurgeable case, an encoded bitstream is decoded to a different
 * Bitmap over and over again up to 200 times until out-of-memory occurs. In
 * contrast, the Purgeable case shows that the system can complete decoding the
 * encoded bitstream 200 times without hitting the out-of-memory case.
 */
public class Test extends GraphicsActivity {

  private PurgeableBitmapView mView;
  private final RefreshHandler mRedrawHandler = new RefreshHandler();

  class RefreshHandler extends Handler {

    @Override
    public void handleMessage(Message msg) {
      int index = mView.update(this);
      if (index > 0) {
        showAlertDialog(getDialogMessage(true, index));
      } else if (index < 0) {
        mView.invalidate();
        showAlertDialog(getDialogMessage(false, -index));
      } else {
        mView.invalidate();
      }
    }

    public void sleep(long delayMillis) {
      this.removeMessages(0);
      sendMessageDelayed(obtainMessage(0), delayMillis);
    }
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mView = new PurgeableBitmapView(this, detectIfPurgeableRequest());
    mRedrawHandler.sleep(0);
    setContentView(mView);
  }

  private boolean detectIfPurgeableRequest() {
    PackageManager pm = getPackageManager();
    CharSequence labelSeq = null;
    try {
      ActivityInfo info = pm.getActivityInfo(this.getComponentName(),
          PackageManager.GET_META_DATA);
      labelSeq = info.loadLabel(pm);
    } catch (NameNotFoundException e) {
      e.printStackTrace();
      return false;
    }

    String[] components = labelSeq.toString().split("/");
    if (components[components.length - 1].equals("Purgeable")) {
      return true;
    } else {
      return false;
    }
  }

  private String getDialogMessage(boolean isOutOfMemory, int index) {
    StringBuilder sb = new StringBuilder();
    if (isOutOfMemory) {
      sb.append("Out of memery occurs when the ");
      sb.append(index);
      sb.append("th Bitmap is decoded.");
    } else {
      sb.append("Complete decoding ").append(index)
          .append(" bitmaps without running out of memory.");
    }
    return sb.toString();
  }

  private void showAlertDialog(String message) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(message)
        .setCancelable(false)
        .setPositiveButton("Yes",
            new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int id) {
              }
            });
    AlertDialog alert = builder.create();
    alert.show();
  }

}

/**
 * PurgeableBitmapView works with PurgeableBitmap to demonstrate the effects of
 * setting Bitmaps as being purgeable.
 * 
 * PurgeableBitmapView decodes an encoded bitstream to a Bitmap each time
 * update() is invoked(), and its onDraw() draws the Bitmap and a number to
 * screen. The number is used to indicate the number of Bitmaps that has been
 * decoded.
 */
class PurgeableBitmapView extends View {
  private final byte[] bitstream;

  private Bitmap mBitmap;
  private final int mArraySize = 200;
  private final Bitmap[] mBitmapArray = new Bitmap[mArraySize];
  private final Options mOptions = new Options();
  private static final int WIDTH = 150;
  private static final int HEIGHT = 450;
  private static final int STRIDE = 320; // must be >= WIDTH
  private int mDecodingCount = 0;
  private final Paint mPaint = new Paint();
  private final int textSize = 32;
  private static int delay = 100;

  public PurgeableBitmapView(Context context, boolean isPurgeable) {
    super(context);
    setFocusable(true);
    mOptions.inPurgeable = isPurgeable;

    int[] colors = createColors();
    Bitmap src = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT,
        Bitmap.Config.ARGB_8888);
    bitstream = generateBitstream(src, Bitmap.CompressFormat.JPEG, 80);

    mPaint.setTextSize(textSize);
    mPaint.setColor(Color.GRAY);
  }

  private int[] createColors() {
    int[] colors = new int[STRIDE * HEIGHT];
    for (int y = 0; y < HEIGHT; y++) {
      for (int x = 0; x < WIDTH; x++) {
        int r = x * 255 / (WIDTH - 1);
        int g = y * 255 / (HEIGHT - 1);
        int b = 255 - Math.min(r, g);
        int a = Math.max(r, g);
        colors[y * STRIDE + x] = (a << 24) | (r << 16) | (g << 8) | b;
      }
    }
    return colors;
  }

  public int update(Test.RefreshHandler handler) {
    try {
      mBitmapArray[mDecodingCount] = BitmapFactory.decodeByteArray(
          bitstream, 0, bitstream.length, mOptions);
      mBitmap = mBitmapArray[mDecodingCount];
      mDecodingCount++;
      if (mDecodingCount < mArraySize) {
        handler.sleep(delay);
        return 0;
      } else {
        return -mDecodingCount;
      }

    } catch (OutOfMemoryError error) {
      for (int i = 0; i < mDecodingCount; i++) {
        mBitmapArray[i].recycle();
      }
      return mDecodingCount + 1;
    }
  }

  @Override
  protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.WHITE);
    canvas.drawBitmap(mBitmap, 0, 0, null);
    canvas.drawText(String.valueOf(mDecodingCount), WIDTH / 2 - 20,
        HEIGHT / 2, mPaint);
  }

  private byte[] generateBitstream(Bitmap src, Bitmap.CompressFormat format,
      int quality) {
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    src.compress(format, quality, os);
    return os.toByteArray();
  }

}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}

IME Demo 1

  

package com.commonsware.android.imf.one;

import android.app.Activity;
import android.os.Bundle;

public class IMEDemo1 extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}


//res\layout\main.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:stretchColumns="1"
  >
  <TableRow>  
    <TextView  
      android:text="No special rules:"
    />
    <EditText  
    />
  </TableRow>
  <TableRow>  
    <TextView  
      android:text="Email address:"
    />
    <EditText  
      android:inputType="text|textEmailAddress"
    />
  </TableRow>
  <TableRow>  
    <TextView  
      android:text="Signed decimal number:"
    />
    <EditText  
      android:inputType="number|numberSigned|numberDecimal"
    />
  </TableRow>
  <TableRow>  
    <TextView  
      android:text="Date:"
    />
    <EditText  
      android:inputType="date"
    />
  </TableRow>
  <TableRow>  
    <TextView  
      android:text="Multi-line text:"
    />
    <EditText  
      android:inputType="text|textMultiLine|textAutoCorrect"
      android:minLines="3"
      android:gravity="top"
    />
  </TableRow>
</TableLayout>

IME Demo 2

  


package com.commonsware.android.imf.two;

import android.app.Activity;
import android.os.Bundle;

public class IMEDemo2 extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}


//res\layout\main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
>  
  <TableLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:stretchColumns="1"
    >
    <TableRow>  
      <TextView  
        android:text="No special rules:"
      />
      <EditText
      />
    </TableRow>
    <TableRow>  
      <TextView  
        android:text="Email address:"
      />
      <EditText  
        android:inputType="text|textEmailAddress"
        android:imeOptions="actionSend"
      />
    </TableRow>
    <TableRow>  
      <TextView  
        android:text="Signed decimal number:"
      />
      <EditText  
        android:inputType="number|numberSigned|numberDecimal"
        android:imeOptions="actionDone"
      />
    </TableRow>
    <TableRow>  
      <TextView  
        android:text="Date:"
      />
      <EditText  
        android:inputType="date"
      />
    </TableRow>
    <TableRow>  
      <TextView  
        android:text="Multi-line text:"
      />
      <EditText  
        android:inputType="text|textMultiLine|textAutoCorrect"
        android:minLines="3"
        android:gravity="top"
      />
    </TableRow>
  </TableLayout>
</ScrollView>

Service

  

package apt.tutorial;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

public class DetailForm extends Activity {
  EditText name=null;
  EditText address=null;
  EditText notes=null;
  EditText feed=null;
  RadioGroup types=null;
  RestaurantHelper helper=null;
  String restaurantId=null;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.detail_form);
    
    helper=new RestaurantHelper(this);
    
    name=(EditText)findViewById(R.id.name);
    address=(EditText)findViewById(R.id.addr);
    notes=(EditText)findViewById(R.id.notes);
    types=(RadioGroup)findViewById(R.id.types);
    feed=(EditText)findViewById(R.id.feed);
    
    Button save=(Button)findViewById(R.id.save);
    
    save.setOnClickListener(onSave);
    
    restaurantId=getIntent().getStringExtra(LunchList.ID_EXTRA);
    
    if (restaurantId!=null) {
      load();
    }
  }
  
  @Override
  public void onDestroy() {
    super.onDestroy();
  
    helper.close();
  }
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    new MenuInflater(this).inflate(R.menu.details_option, menu);

    return(super.onCreateOptionsMenu(menu));
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId()==R.id.feed) {
      if (isNetworkAvailable()) {
        Intent i=new Intent(this, FeedActivity.class);
        
        i.putExtra(FeedActivity.FEED_URL, feed.getText().toString());
        startActivity(i);
      }
      else {
        Toast
          .makeText(this, "Sorry, the Internet is not available",
                    Toast.LENGTH_LONG)
          .show();
      }
    
      return(true);
    }

    return(super.onOptionsItemSelected(item));
  }
  
  private boolean isNetworkAvailable() {
    ConnectivityManager cm=(ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);
    NetworkInfo info=cm.getActiveNetworkInfo();
    
    return(info!=null);
  }
  
  private void load() {
    Cursor c=helper.getById(restaurantId);

    c.moveToFirst();    
    name.setText(helper.getName(c));
    address.setText(helper.getAddress(c));
    notes.setText(helper.getNotes(c));
    feed.setText(helper.getFeed(c));
    
    if (helper.getType(c).equals("sit_down")) {
      types.check(R.id.sit_down);
    }
    else if (helper.getType(c).equals("take_out")) {
      types.check(R.id.take_out);
    }
    else {
      types.check(R.id.delivery);
    }
    
    c.close();
  }
  
  private View.OnClickListener onSave=new View.OnClickListener() {
    public void onClick(View v) {
      String type=null;
      
      switch (types.getCheckedRadioButtonId()) {
        case R.id.sit_down:
          type="sit_down";
          break;
        case R.id.take_out:
          type="take_out";
          break;
        case R.id.delivery:
          type="delivery";
          break;
      }

      if (restaurantId==null) {
        helper.insert(name.getText().toString(),
                      address.getText().toString(), type,
                      notes.getText().toString(),
                      feed.getText().toString());
      }
      else {
        helper.update(restaurantId, name.getText().toString(),
                      address.getText().toString(), type,
                      notes.getText().toString(),
                      feed.getText().toString());
      }
      
      finish();
    }
  };
}



package apt.tutorial;

import android.app.Activity;
import android.os.Bundle;
import android.preference.PreferenceActivity;

public class EditPreferences extends PreferenceActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    addPreferencesFromResource(R.xml.preferences);
  }
}



package apt.tutorial;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import org.mcsoxford.rss.RSSItem;
import org.mcsoxford.rss.RSSFeed;

public class FeedActivity extends ListActivity {
  public static final String FEED_URL="apt.tutorial.FEED_URL";
  private InstanceState state=null;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    state=(InstanceState)getLastNonConfigurationInstance();
    
    if (state==null) {
      state=new InstanceState();
      state.handler=new FeedHandler(this);
      
      Intent i=new Intent(this, FeedService.class);
      
      i.putExtra(FeedService.EXTRA_URL,
                 getIntent().getStringExtra(FEED_URL));
      i.putExtra(FeedService.EXTRA_MESSENGER,
                 new Messenger(state.handler));
      
      startService(i);
    }
    else {
      if (state.handler!=null) {
        state.handler.attach(this);
      }
      
      if (state.feed!=null) {
        setFeed(state.feed);
      }
    }
  }
  
  @Override
  public Object onRetainNonConfigurationInstance() {
    if (state.handler!=null) {
      state.handler.detach();
    }
    
    return(state);
  }
  
  private void setFeed(RSSFeed feed) {
    state.feed=feed;
    setListAdapter(new FeedAdapter(feed));
  }
  
  private void goBlooey(Throwable t) {
    AlertDialog.Builder builder=new AlertDialog.Builder(this);
    
    builder
      .setTitle("Exception!")
      .setMessage(t.toString())
      .setPositiveButton("OK", null)
      .show();
  }
  
  private static class InstanceState {
    RSSFeed feed=null;
    FeedHandler handler=null;
  }
  
  private class FeedAdapter extends BaseAdapter {
    RSSFeed feed=null;
    
    FeedAdapter(RSSFeed feed) {
      super();
      
      this.feed=feed;
    }
    
    @Override
    public int getCount() {
      return(feed.getItems().size());
    }
    
    @Override
    public Object getItem(int position) {
      return(feed.getItems().get(position));
    }
    
    @Override
    public long getItemId(int position) {
      return(position);
    }
    
    @Override
    public View getView(int position, View convertView,
                        ViewGroup parent) {
      View row=convertView;
      
      if (row==null) {                          
        LayoutInflater inflater=getLayoutInflater();
        
        row=inflater.inflate(android.R.layout.simple_list_item_1,
                             parent, false);
      }
      
      RSSItem item=(RSSItem)getItem(position);
      
      ((TextView)row).setText(item.getTitle());
      
      return(row);
    }
  }
  
  private static class FeedHandler extends Handler {
    FeedActivity activity=null;
    
    FeedHandler(FeedActivity activity) {
      attach(activity);
    }
    
    void attach(FeedActivity activity) {
      this.activity=activity;
    }
    
    void detach() {
      this.activity=null;
    }
    
    @Override
    public void handleMessage(Message msg) {
      if (msg.arg1==RESULT_OK) {
        activity.setFeed((RSSFeed)msg.obj);
      }
      else {
        activity.goBlooey((Exception)msg.obj);
      }
    }
  }
}



package apt.tutorial;

import android.app.Activity;
import android.app.IntentService;
import android.content.Intent;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;
import org.mcsoxford.rss.RSSItem;
import org.mcsoxford.rss.RSSFeed;
import org.mcsoxford.rss.RSSReader;

public class FeedService extends IntentService {
  public static final String EXTRA_URL="apt.tutorial.EXTRA_URL";
  public static final String EXTRA_MESSENGER="apt.tutorial.EXTRA_MESSENGER";

  public FeedService() {
    super("FeedService");
  }
  
  @Override
  public void onHandleIntent(Intent i) {
    RSSReader reader=new RSSReader();
    Messenger messenger=(Messenger)i.getExtras().get(EXTRA_MESSENGER);
    Message msg=Message.obtain();
    
    try {
      RSSFeed result=reader.load(i.getStringExtra(EXTRA_URL));
      
      msg.arg1=Activity.RESULT_OK;
      msg.obj=result;
    }
    catch (Exception e) {
      Log.e("LunchList", "Exception parsing feed", e);
      msg.arg1=Activity.RESULT_CANCELED;
      msg.obj=e;
    }
    
    try {
      messenger.send(msg);
    }
    catch (Exception e) {
      Log.w("LunchList", "Exception sending results to activity", e);
    }
  }
}




package apt.tutorial;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.widget.AdapterView;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class LunchList extends ListActivity {
  public final static String ID_EXTRA="apt.tutorial._ID";
  Cursor model=null;
  RestaurantAdapter adapter=null;
  RestaurantHelper helper=null;
  SharedPreferences prefs=null;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    helper=new RestaurantHelper(this);
    prefs=PreferenceManager.getDefaultSharedPreferences(this);
    initList();
    prefs.registerOnSharedPreferenceChangeListener(prefListener);
  }
  
  @Override
  public void onDestroy() {
    super.onDestroy();
    
    helper.close();
  }
  
  @Override
  public void onListItemClick(ListView list, View view,
                              int position, long id) {
    Intent i=new Intent(LunchList.this, DetailForm.class);

    i.putExtra(ID_EXTRA, String.valueOf(id));
    startActivity(i);
  }
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    new MenuInflater(this).inflate(R.menu.option, menu);

    return(super.onCreateOptionsMenu(menu));
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId()==R.id.add) {
      startActivity(new Intent(LunchList.this, DetailForm.class));
      
      return(true);
    }
    else if (item.getItemId()==R.id.prefs) {
      startActivity(new Intent(this, EditPreferences.class));
    
      return(true);
    }

    return(super.onOptionsItemSelected(item));
  }
  
  private void initList() {
    if (model!=null) {
      stopManagingCursor(model);
      model.close();
    }
    
    model=helper.getAll(prefs.getString("sort_order", "name"));
    startManagingCursor(model);
    adapter=new RestaurantAdapter(model);
    setListAdapter(adapter);
  }
  
  private SharedPreferences.OnSharedPreferenceChangeListener prefListener=
   new SharedPreferences.OnSharedPreferenceChangeListener() {
    public void onSharedPreferenceChanged(SharedPreferences sharedPrefs,
                                          String key) {
      if (key.equals("sort_order")) {
        initList();
      }
    }
  };
  
  class RestaurantAdapter extends CursorAdapter {
    RestaurantAdapter(Cursor c) {
      super(LunchList.this, c);
    }
    
    @Override
    public void bindView(View row, Context ctxt,
                         Cursor c) {
      RestaurantHolder holder=(RestaurantHolder)row.getTag();
      
      holder.populateFrom(c, helper);
    }
    
    @Override
    public View newView(Context ctxt, Cursor c,
                         ViewGroup parent) {
      LayoutInflater inflater=getLayoutInflater();
      View row=inflater.inflate(R.layout.row, parent, false);
      RestaurantHolder holder=new RestaurantHolder(row);
      
      row.setTag(holder);
      
      return(row);
    }
  }
  
  static class RestaurantHolder {
    private TextView name=null;
    private TextView address=null;
    private ImageView icon=null;
    
    RestaurantHolder(View row) {
      name=(TextView)row.findViewById(R.id.title);
      address=(TextView)row.findViewById(R.id.address);
      icon=(ImageView)row.findViewById(R.id.icon);
    }
    
    void populateFrom(Cursor c, RestaurantHelper helper) {
      name.setText(helper.getName(c));
      address.setText(helper.getAddress(c));
  
      if (helper.getType(c).equals("sit_down")) {
        icon.setImageResource(R.drawable.ball_red);
      }
      else if (helper.getType(c).equals("take_out")) {
        icon.setImageResource(R.drawable.ball_yellow);
      }
      else {
        icon.setImageResource(R.drawable.ball_green);
      }
    }
  }
}




package apt.tutorial;

import android.content.Context;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;

class RestaurantHelper extends SQLiteOpenHelper {
  private static final String DATABASE_NAME="lunchlist.db";
  private static final int SCHEMA_VERSION=2;
  
  public RestaurantHelper(Context context) {
    super(context, DATABASE_NAME, null, SCHEMA_VERSION);
  }
  
  @Override
  public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE restaurants (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, address TEXT, type TEXT, notes TEXT, feed TEXT);");
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("ALTER TABLE restaurants ADD COLUMN feed TEXT");
  }

  public Cursor getAll(String orderBy) {
    return(getReadableDatabase()
            .rawQuery("SELECT _id, name, address, type, notes FROM restaurants ORDER BY "+orderBy,
                      null));
  }
  
  public Cursor getById(String id) {
    String[] args={id};

    return(getReadableDatabase()
            .rawQuery("SELECT _id, name, address, type, notes, feed FROM restaurants WHERE _ID=?",
                      args));
  }
  
  public void insert(String name, String address,
                     String type, String notes,
                     String feed) {
    ContentValues cv=new ContentValues();
          
    cv.put("name", name);
    cv.put("address", address);
    cv.put("type", type);
    cv.put("notes", notes);
    cv.put("feed", feed);
    
    getWritableDatabase().insert("restaurants", "name", cv);
  }
  
  public void update(String id, String name, String address,
                     String type, String notes, String feed) {
    ContentValues cv=new ContentValues();
    String[] args={id};
    
    cv.put("name", name);
    cv.put("address", address);
    cv.put("type", type);
    cv.put("notes", notes);
    cv.put("feed", feed);
    
    getWritableDatabase().update("restaurants", cv, "_ID=?",
                                 args);
  }
  
  public String getName(Cursor c) {
    return(c.getString(1));
  }
  
  public String getAddress(Cursor c) {
    return(c.getString(2));
  }
  
  public String getType(Cursor c) {
    return(c.getString(3));
  }
  
  public String getNotes(Cursor c) {
    return(c.getString(4));
  }
  
  public String getFeed(Cursor c) {
    return(c.getString(5));
  }
}



//res\xml\preferences.xml
<PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android">
  <ListPreference
    android:key="sort_order"
    android:title="Sort Order"
    android:summary="Choose the order the list uses"
    android:entries="@array/sort_names"
    android:entryValues="@array/sort_clauses"
    android:dialogTitle="Choose a sort order" />
</PreferenceScreen>



//res\values\arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string-array name="sort_names">
    <item>By Name, Ascending</item>
    <item>By Name, Descending</item>
    <item>By Type</item>
    <item>By Address, Ascending</item>
    <item>By Address, Descending</item>
  </string-array>
  <string-array name="sort_clauses">
    <item>name ASC</item>
    <item>name DESC</item>
    <item>type, name ASC</item>
    <item>address ASC</item>
    <item>address DESC</item>
  </string-array>
</resources>



//res\values\strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">LunchList</string>
</resources>



//res\menu\details_option.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@+id/feed"
    android:title="RSS Feed"
    android:icon="@drawable/ic_menu_friendslist"
  />
</menu>



//res\menu\option.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@+id/add"
    android:title="Add"
    android:icon="@drawable/ic_menu_add"
  />
  <item android:id="@+id/prefs"
    android:title="Settings"
    android:icon="@drawable/ic_menu_preferences"
  />
</menu>



//res\layout-land\detail_form.xml
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:stretchColumns="2"
  >
  <TableRow>
    <TextView android:text="Name:" />
    <EditText android:id="@+id/name"
      android:layout_span="2"
    />
  </TableRow>
  <TableRow>
    <TextView android:text="Address:" />
    <EditText android:id="@+id/addr"
      android:layout_span="2"
    />
  </TableRow>
  <TableRow>
    <TextView android:text="Type:" />
    <RadioGroup android:id="@+id/types">
      <RadioButton android:id="@+id/take_out"
        android:text="Take-Out"
      />
      <RadioButton android:id="@+id/sit_down"
        android:text="Sit-Down"
      />
      <RadioButton android:id="@+id/delivery"
        android:text="Delivery"
      />
    </RadioGroup>
    <LinearLayout android:orientation="vertical">
      <EditText android:id="@+id/notes"
        android:singleLine="false"
        android:gravity="top"
        android:lines="2"
        android:scrollHorizontally="false"
        android:maxLines="2"
        android:maxWidth="140sp"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Notes"
      />
      <EditText android:id="@+id/feed"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Feed URL"
      />
      <Button android:id="@+id/save"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Save"
      />
    </LinearLayout>
  </TableRow>
</TableLayout>



//res\layout\detail_form.xml
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:stretchColumns="1"
  >
  <TableRow>
    <TextView android:text="Name:" />
    <EditText android:id="@+id/name" />
  </TableRow>
  <TableRow>
    <TextView android:text="Address:" />
    <EditText android:id="@+id/addr" />
  </TableRow>
  <TableRow>
    <TextView android:text="Type:" />
    <RadioGroup android:id="@+id/types">
      <RadioButton android:id="@+id/take_out"
        android:text="Take-Out"
      />
      <RadioButton android:id="@+id/sit_down"
        android:text="Sit-Down"
      />
      <RadioButton android:id="@+id/delivery"
        android:text="Delivery"
      />
    </RadioGroup>
  </TableRow>
  <EditText android:id="@+id/notes"
    android:singleLine="false"
    android:gravity="top"
    android:lines="2"
    android:scrollHorizontally="false"
    android:maxLines="2"
    android:maxWidth="200sp"
    android:layout_span="2"
    android:hint="Notes"
  />
  <EditText android:id="@+id/feed"
    android:layout_span="2"
    android:hint="Feed URL"
  />
  <Button android:id="@+id/save"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Save"
  />
</TableLayout>



//res\layout\main.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@android:id/list"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
/>



//res\layout\row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal"
  android:padding="4dip"
  >
  <ImageView android:id="@+id/icon"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_alignParentTop="true"
    android:layout_alignParentBottom="true"
    android:layout_marginRight="4dip"
  />
  <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    >  
    <TextView android:id="@+id/title"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:gravity="center_vertical"
      android:textStyle="bold"
      android:singleLine="true"
      android:ellipsize="end"
    />
    <TextView android:id="@+id/address"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:gravity="center_vertical"
      android:singleLine="true"
      android:ellipsize="end"
    />
  </LinearLayout>
</LinearLayout>

Using MapActivity

package com.commonsware.android.maps;

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.graphics.Canvas;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MapView.LayoutParams;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;
import java.util.ArrayList;
import java.util.List;

public class NooYawk extends MapActivity {
  private MapView map=null;
  private MyLocationOverlay me=null;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    map=(MapView)findViewById(R.id.map);
    
    map.getController().setCenter(getPoint(40.76793169992044,
                                            -73.98180484771729));
    map.getController().setZoom(17);
    map.setBuiltInZoomControls(true);
    
    Drawable marker=getResources().getDrawable(R.drawable.marker);
    
    marker.setBounds(0, 0, marker.getIntrinsicWidth(),
                            marker.getIntrinsicHeight());
    
    map.getOverlays().add(new SitesOverlay(marker));
    
    me=new MyLocationOverlay(this, map);
    map.getOverlays().add(me);
  }
  
  @Override
  public void onResume() {
    super.onResume();
    
    me.enableCompass();
  }    
  
  @Override
  public void onPause() {
    super.onPause();
    
    me.disableCompass();
  }    
  
   @Override
  protected boolean isRouteDisplayed() {
    return(false);
  }
  
   @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_S) {
      map.setSatellite(!map.isSatellite());
      return(true);
    }
    else if (keyCode == KeyEvent.KEYCODE_Z) {
      map.displayZoomControls(true);
      return(true);
    }
    
    return(super.onKeyDown(keyCode, event));
  }

  private GeoPoint getPoint(double lat, double lon) {
    return(new GeoPoint((int)(lat*1000000.0),
                          (int)(lon*1000000.0)));
  }
    
  private class SitesOverlay extends ItemizedOverlay<OverlayItem> {
    private List<OverlayItem> items=new ArrayList<OverlayItem>();
    private Drawable marker=null;
    
    public SitesOverlay(Drawable marker) {
      super(marker);
      this.marker=marker;
      
      items.add(new OverlayItem(getPoint(40.748963847316034,
                                          -73.96807193756104),
                                "UN", "United Nations"));
      items.add(new OverlayItem(getPoint(40.76866299974387,
                                          -73.98268461227417),
                                "Lincoln Center",
                                "Home of Jazz at Lincoln Center"));
      items.add(new OverlayItem(getPoint(40.765136435316755,
                                          -73.97989511489868),
                                "Carnegie Hall",
              "Where you go with practice, practice, practice"));
      items.add(new OverlayItem(getPoint(40.70686417491799,
                                          -74.01572942733765),
                                "The Downtown Club",
                        "Original home of the Heisman Trophy"));

      populate();
    }
    
    @Override
    protected OverlayItem createItem(int i) {
      return(items.get(i));
    }
    
    @Override
    public void draw(Canvas canvas, MapView mapView,
                      boolean shadow) {
      super.draw(canvas, mapView, shadow);
      
      boundCenterBottom(marker);
    }
     
    @Override
    protected boolean onTap(int i) {
      Toast.makeText(NooYawk.this,
                      items.get(i).getSnippet(),
                      Toast.LENGTH_SHORT).show();
      
      return(true);
    }
    
    @Override
    public int size() {
      return(items.size());
    }
  }
}



//res\layout\main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <com.google.android.maps.MapView android:id="@+id/map"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:apiKey="00yHj0k7_7vzHbUFXzY2j94lYYCqW3NAIW8EEEw"
    android:clickable="true" />
</RelativeLayout>

Proximity Alert Demo

   
package app.test;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

 class ProximityReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context arg0, Intent intent) {
    if(intent.getData() != null)
      Log.v(TAG, intent.getData().toString());
    Bundle extras = intent.getExtras();
    if(extras != null) {
      Log.v("", "Message: " + extras.getString("message"));
      Log.v("", "Entering? " + extras.getBoolean(LocationManager.KEY_PROXIMITY_ENTERING));
    }
  }
}

public class ProximityActivity extends Activity {
  private final String PROX_ALERT = "app.test.PROXIMITY_ALERT";
  private ProximityReceiver proxReceiver = null;
  private LocationManager locMgr = null;
  PendingIntent pIntent1 = null;
  PendingIntent pIntent2 = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        double lat = 31.334954;    
        double lon = -80.5625;
        float radius = 5.0f * 1609.0f; 
        String geo = "geo:"+lat+","+lon;
        Intent intent = new Intent(PROX_ALERT, Uri.parse(geo));
        intent.putExtra("message", "Jacksonville, FL");
        pIntent1 = PendingIntent.getBroadcast(getApplicationContext(), 0, intent,
            PendingIntent.FLAG_CANCEL_CURRENT);

        locMgr = (LocationManager) this.getSystemService(LOCATION_SERVICE);
        locMgr.addProximityAlert(lat, lon, radius, 2000L, pIntent1);

        lat = 38.54;    
        lon = -80.38;
        geo = "geo:"+lat+","+lon;

        intent = new Intent(PROX_ALERT, Uri.parse(geo));
        intent.putExtra("message", "Orlando, FL");

        pIntent2 = PendingIntent.getBroadcast(getApplicationContext(), 0, intent,
            PendingIntent.FLAG_CANCEL_CURRENT);

        locMgr.addProximityAlert(lat, lon, radius, 60000L, pIntent2);

        proxReceiver = new ProximityReceiver();

        IntentFilter iFilter = new IntentFilter(PROX_ALERT);
        iFilter.addDataScheme("geo");

        registerReceiver(proxReceiver, iFilter);
    }
    
    protected void onDestroy() {
      super.onDestroy();
      unregisterReceiver(proxReceiver);
      locMgr.removeProximityAlert(pIntent1);
      locMgr.removeProximityAlert(pIntent2);
    }
}

//main.xml

<?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"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
</LinearLayout>

Using PreferenceCategory

  

package app.test;

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class Test extends PreferenceActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.main);
    }
}

//xml/main.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
        xmlns:android="http://schemas.android.com/apk/res/android"
                android:key="using_categories_in_root_screen"
                android:title="Categories"
                android:summary="Using Preference Categories">

    <PreferenceCategory
                android:key="meats_category"
                android:title="Meats"
                android:summary="Preferences related to Meats">

        <CheckBoxPreference
                android:key="fish_selection_pref"
                android:title="Fish"
                android:summary="Fish is great for the healthy" />
        <CheckBoxPreference
                android:key="chicken_selection_pref"
                android:title="Chicken"
                android:summary="A common type of poultry" />
        <CheckBoxPreference
                android:key="lamb_selection_pref"
                android:title="Lamb"
                android:summary="Lamb is a young sheep" />

    </PreferenceCategory>
    <PreferenceCategory
                android:key="vegi_category"
                android:title="Vegetables"
                android:summary="Preferences related to vegetable">
        <CheckBoxPreference
                android:key="tomato_selection_pref"
                android:title="Tomato "
                android:summary="It's actually a fruit" />
        <CheckBoxPreference
                android:key="potato_selection_pref"
                android:title="Potato"
                android:summaryOff="Yeah!"
                android:summaryOn="My favorite vegetable" />

    </PreferenceCategory>

</PreferenceScreen>

   

NetworkDetector: uses android.telephony.TelephonyManager to obtain telephony parameters like network state, phone type and SIM state.

package com.example.android.apis.telephony;

import android.app.Activity;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.widget.TextView;


/**
 * Activity that uses {@link android.telephony.TelephonyManager} to obtain
 * telephony parameters like network state, phone type and SIM state.
 */
public class NetworkDetector extends Activity {

    /*
     * SIM state constants
     */
    public static final String SIM_ABSENT = "Absent";
    public static final String SIM_READY = "Ready";
    public static final String SIM_PIN_REQUIRED = "PIN required";
    public static final String SIM_PUK_REQUIRED = "PUK required";
    public static final String SIM_NETWORK_LOCKED = "Network locked";
    public static final String SIM_UNKNOWN = "Unknown";

    /*
     * Network type constants
     */
    public static final String NETWORK_CDMA = "CDMA: Either IS95A or IS95B (2G)";
    public static final String NETWORK_EDGE = "EDGE (2.75G)";
    public static final String NETWORK_GPRS = "GPRS (2.5G)";
    public static final String NETWORK_UMTS = "UMTS (3G)";
    public static final String NETWORK_EVDO_0 = "EVDO revision 0 (3G)";
    public static final String NETWORK_EVDO_A = "EVDO revision A (3G - Transitional)";
    public static final String NETWORK_EVDO_B = "EVDO revision B (3G - Transitional)";
    public static final String NETWORK_1X_RTT = "1xRTT  (2G - Transitional)";
    public static final String NETWORK_HSDPA = "HSDPA (3G - Transitional)";
    public static final String NETWORK_HSUPA = "HSUPA (3G - Transitional)";
    public static final String NETWORK_HSPA = "HSPA (3G - Transitional)";
    public static final String NETWORK_IDEN = "iDen (2G)";
    public static final String NETWORK_LTE = "LTE (4G)";
    public static final String NETWORK_EHRPD = "EHRPD (3G)";
    public static final String NETWORK_HSPAP = "HSPAP (3G)";
    public static final String NETWORK_UNKOWN = "Unknown";

    /*
     * Phone type constants
     */
    public static final String PHONE_CDMA = "CDMA";
    public static final String PHONE_GSM = "GSM";
    public static final String PHONE_SIP = "SIP";
    public static final String PHONE_NONE = "No radio";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Get the telephony system service to find out network details
        final TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

        // Update text views with readable values.
        updateViews(tm);

        // Since these attributes can change, we will register a
        // {@code PhoneStateListener} to listen for these changes and
        // update the view.
        tm.listen(new PhoneStateListener() {
            @Override
            public void onServiceStateChanged(ServiceState serviceState) {
                // Update our TextViews
                updateViews(tm);
            }

            @Override
            public void onDataConnectionStateChanged(int state) {
                // A change in data connection state may be due to availability
                // of a different network type
                updateViews(tm);
            }

        }, PhoneStateListener.LISTEN_SERVICE_STATE
                | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        final TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

        // Update text views with readable values.
        updateViews(tm);
    }

    /**
     * Update text views with telephony attributes.
     */
    private final void updateViews(TelephonyManager tm) {

        // The telephony system service returns integer constants for various
        // telephony attributes.
        TextView view = null;

        view = (TextView) findViewById(R.id.sim_state);
        view.setText("SIM State: " + mapSimStateToName(tm.getSimState()));

        view = (TextView) findViewById(R.id.network_type);
        view.setText("Network Type: " + mapNetworkTypeToName(tm.getNetworkType()));

        view = (TextView) findViewById(R.id.phone_type);
        view.setText("Phone Type: " + mapDeviceTypeToName(tm.getPhoneType()));

        view = (TextView) findViewById(R.id.network_name);
        view.setText("Network Operator: " + tm.getNetworkOperatorName());
    }

    /**
     * Returns a string describing the current SIM state.
     */
    private static String mapSimStateToName(int simState) {
        switch (simState) {
            case TelephonyManager.SIM_STATE_ABSENT:
                return SIM_ABSENT;
            case TelephonyManager.SIM_STATE_READY:
                return SIM_READY;
            case TelephonyManager.SIM_STATE_PIN_REQUIRED:
                return SIM_PIN_REQUIRED;
            case TelephonyManager.SIM_STATE_PUK_REQUIRED:
                return SIM_PUK_REQUIRED;
            case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
                return SIM_NETWORK_LOCKED;
            case TelephonyManager.SIM_STATE_UNKNOWN:
                return SIM_UNKNOWN;
            default:
                // shouldn't happen.
                return null;
        }
    }

    /**
     * Returns a string indicating the phone radio type.
     */
    private static String mapDeviceTypeToName(int device) {

        switch (device) {
            case TelephonyManager.PHONE_TYPE_CDMA:
                return PHONE_CDMA;
            case TelephonyManager.PHONE_TYPE_GSM:
                return PHONE_GSM;
            case TelephonyManager.PHONE_TYPE_SIP:
               return PHONE_SIP;
            case TelephonyManager.PHONE_TYPE_NONE:
                return PHONE_NONE;
            default:
                // shouldn't happen.
                return null;
        }
    }

    /**
     * Returns a string describing the network type.
     */
    public static String mapNetworkTypeToName(int networkType) {

        switch (networkType) {
            case TelephonyManager.NETWORK_TYPE_CDMA:
                return NETWORK_CDMA;
            case TelephonyManager.NETWORK_TYPE_EDGE:
                return NETWORK_EDGE;
            case TelephonyManager.NETWORK_TYPE_GPRS:
                return NETWORK_EDGE;
            case TelephonyManager.NETWORK_TYPE_UMTS:
                return NETWORK_UMTS;
            case TelephonyManager.NETWORK_TYPE_EVDO_0:
                return NETWORK_EVDO_0;
            case TelephonyManager.NETWORK_TYPE_EVDO_A:
                return NETWORK_EVDO_A;
            case TelephonyManager.NETWORK_TYPE_EVDO_B:
                return NETWORK_EVDO_B;
            case TelephonyManager.NETWORK_TYPE_1xRTT:
                return NETWORK_1X_RTT;
            case TelephonyManager.NETWORK_TYPE_HSDPA:
                return NETWORK_HSDPA;
            case TelephonyManager.NETWORK_TYPE_HSPA:
                return NETWORK_HSPA;
            case TelephonyManager.NETWORK_TYPE_HSUPA:
                return NETWORK_HSUPA;
            case TelephonyManager.NETWORK_TYPE_IDEN:
                return NETWORK_IDEN;
            case TelephonyManager.NETWORK_TYPE_LTE:
                return NETWORK_LTE;
            case TelephonyManager.NETWORK_TYPE_EHRPD:
                return NETWORK_EHRPD;
//            case TelephonyManager.NETWORK_TYPE_HSPAP:
  //              return NETWORK_HSPAP;
            case TelephonyManager.NETWORK_TYPE_UNKNOWN:
            default:
                return NETWORK_UNKOWN;
        }
    }
}
//main.xml
<?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"
    >
    <TextView android:id="@+id/phone_type"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <TextView android:id="@+id/network_name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <TextView android:id="@+id/sim_state"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <TextView android:id="@+id/network_type"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Check Network Type with TelephonyManager

   
//package uk.me.kjs.android.helloworld;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.telephony.*;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;


public class Init extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
          String str = new String();
            String net = new String(); 
            
            switch(tm.getNetworkType())
            {
              case TelephonyManager.NETWORK_TYPE_1xRTT:
                net = "CDMA - 2000";
                break;
              case TelephonyManager.NETWORK_TYPE_CDMA:
                net = "CDMA";
                break;
              case TelephonyManager.NETWORK_TYPE_EDGE:
                net = "GSM - EDGE";
                break;
              case TelephonyManager.NETWORK_TYPE_EVDO_0:
                net = "CDMA - EVDO A";
                break;
              case TelephonyManager.NETWORK_TYPE_EVDO_A:
                net = "CDMA - EVDO A";
                break;
              case TelephonyManager.NETWORK_TYPE_GPRS:
                net = "GSM - GPRS";
                break;
              case TelephonyManager.NETWORK_TYPE_UMTS:
                net = "UMTS";
                break;
              case 8:
                net = "UMTS - HSDPA ";
                break;
              case 9:
                net = "UMTS - HSUPA ";
                break;
              case 10:
                net = "UMTS - HSPA ";
                break;
              case TelephonyManager.NETWORK_TYPE_UNKNOWN:
              default:
                net = "Unknown";
            }
            
            String home = new String();
            if (  tm.isNetworkRoaming()  == true)
            {
              home = "Roaming";
            }
            else
            {
              home = "Home";
            }

            
            
            
        str = "SIM Information";
        str += "\nName : " + tm.getSimOperatorName();
        str += "\nCode : " + tm.getSimOperator() + " (" + tm.getSimCountryIso() + ")";
        str += "\n";    
        str += "\nConnected Network";
        str += "\nName : " + tm.getNetworkOperatorName();
        str += "\nRoaming : " + home;
        str += "\nCode : " + tm.getNetworkOperator() + " (" + tm.getNetworkCountryIso() + ")";
        str += "\nType : " + net;
     
        
        tv.setTextSize(20);
        tv.setText(str);
        setContentView(tv);
        
        Context context = getApplicationContext();
        CharSequence text = "Hello toast!";
        int duration = Toast.LENGTH_SHORT;

        Toast toast = Toast.makeText(context, text, duration);
        toast.show();
     
    }
}

Returns the DeviceId according to the TelephonyManager.

   
//package org.acra.util;

import java.io.File;


import android.content.Context;
import android.content.res.Configuration;
import android.os.Environment;
import android.os.StatFs;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;

/**
 * Responsible for providing base utilities used when constructing the report.
 * <p/>
 * @author William Ferguson
 * @since 4.3.0
 */
public final class ReportUtils {
    /**
     * Returns the DeviceId according to the TelephonyManager.
     *
     * @param context   Context for the application being reported.
     * @return Returns the DeviceId according to the TelephonyManager or null if there is no TelephonyManager.
     */
    public static String getDeviceId(Context context) {
        try {
            final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            return tm.getDeviceId();
        } catch (RuntimeException e) {
          //  Log.w(ACRA.LOG_TAG, "Couldn't retrieve DeviceId for : " + context.getPackageName(), e);
            return null;
        }
    }


}

Get TelephonyManager.getSubscriberId()

   
import android.content.Context;
import android.telephony.TelephonyManager;

class Main {
  public static String getIMSI(Context ctx) {
    TelephonyManager tm = (TelephonyManager) ctx
        .getSystemService(Context.TELEPHONY_SERVICE);
    return tm.getSubscriberId();
  }

}
Phone Dialer
package com.commonsware.android.dialer;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class DialerDemo extends Activity {
  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);
  
    final EditText number=(EditText)findViewById(R.id.number);
    Button dial=(Button)findViewById(R.id.dial);
  
    dial.setOnClickListener(new Button.OnClickListener() {
      public void onClick(View v) {
        String toDial="tel:"+number.getText().toString();
        
        startActivity(new Intent(Intent.ACTION_DIAL,
                                  Uri.parse(toDial)));
      }
    });
  }
}

//res\layout\main.xml
<?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"
    >
  <LinearLayout 
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    <TextView  
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Number to dial:"
      />
    <EditText android:id="@+id/number"
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content"
      android:cursorVisible="true"
      android:editable="true"
      android:singleLine="true"
    />
  </LinearLayout>
  <Button android:id="@+id/dial"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:text="Dial It!"
  />
</LinearLayout>

Timer Table

   

import java.util.HashMap;

class MyTimer {
  // WARNING: HashMap is not thread-safe (not syncronized)
  static private HashMap<String, MyTimer> timers = new HashMap<String, MyTimer>();
  
  private String name = null;

  private long startedAt;
  private long elapsedTimeInMS = 0;
  
  
  static public MyTimer get(String name) {
    MyTimer timer;
    if (timers.containsKey(name)) {
      timer = timers.get(name);
    } else {
      timer = new MyTimer(name);
      timers.put(name, timer);
    }
    return timer;
  }
  
  
  /**
   * If given a name the timer will be save in the list
   * @param name
   * @return
   */
  static public MyTimer start(String name) {
    MyTimer timer = get(name);
    timer.start();
    return timer;
  }
  
  static public MyTimer resume(String name) {
    MyTimer timer = get(name);
    timer.resume();
    return timer;
  }
  
  static public MyTimer stop(String name) {
    MyTimer timer = get(name);
    timer.stop();
    return timer;
  }
  
  static public MyTimer remove(String name) {
    return timers.remove(name);
  }

  
  // Private constructor prevents instantiation
  private MyTimer(String name) {
    this.name = name;
  }
  
  public void start() {
    this.elapsedTimeInMS = 0;
    this.startedAt = System.currentTimeMillis();
  }
  
  public void resume() {
    this.startedAt = System.currentTimeMillis();
  }
  
  /**
   * @return elapsedTimeInMS
   */
  public long stop() {
    this.elapsedTimeInMS += (System.currentTimeMillis() - this.startedAt);
    return this.elapsedTimeInMS;
  }
  
  public long ms() {
    return this.elapsedTimeInMS;
  }
  
  public float seconds() {
    return this.elapsedTimeInMS / 1000F;
  }
  
  public String name() { return this.name; }
  
  /**
   * Adds the value of another timer to this one
   * @param otherTimer
   */
  public MyTimer add(MyTimer otherTimer) {
    this.elapsedTimeInMS += otherTimer.ms();
    return this;
  }
  
  public MyTimer add(String name) {
    this.elapsedTimeInMS += get(name).ms();
    return this;
  }
  
  public String toString() {
    return Float.toString(seconds()) + "s";
  }
}

Voice recognition demo

   

package app.test;

import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.widget.TextView;
import android.widget.Toast;

public class Test extends Activity {
    private static final int REQUEST_RECOGNIZE = 100;
    TextView tv;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tv = new TextView(this);
        setContentView(tv);
        
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Tell Me Your Name");
        try {
            startActivityForResult(intent, REQUEST_RECOGNIZE);
        } catch (ActivityNotFoundException e) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Not Available");
            builder.setMessage("No recognition software installed.Download one?");
            builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Intent marketIntent = new Intent(Intent.ACTION_VIEW);
                    marketIntent.setData(Uri.parse("market://details?id=com.google.android.voicesearch"));
                }
            });
            builder.setNegativeButton("No", null);
            builder.create().show();
        }
    }
   
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == REQUEST_RECOGNIZE && resultCode == Activity.RESULT_OK) {
            ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
            StringBuilder sb = new StringBuilder();
            for(String piece : matches) {
                sb.append(piece);
                sb.append('\n');
            }
            tv.setText(sb.toString());
        } else {
            Toast.makeText(this, "Operation Canceled", Toast.LENGTH_SHORT).show();
        }
    }
}
Alarm system
//src\apt\tutorial\AlarmActivity.java
package apt.tutorial;

import android.app.Activity;
import android.os.Bundle;

public class AlarmActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.alarm);
  }
}



//src\apt\tutorial\DetailForm.java
package apt.tutorial;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

public class DetailForm extends Activity {
  EditText name=null;
  EditText address=null;
  EditText notes=null;
  EditText feed=null;
  RadioGroup types=null;
  RestaurantHelper helper=null;
  String restaurantId=null;
  TextView location=null;
  LocationManager locMgr=null;
  double latitude=0.0d;
  double longitude=0.0d;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.detail_form);
    
    locMgr=(LocationManager)getSystemService(LOCATION_SERVICE);
    helper=new RestaurantHelper(this);
    
    name=(EditText)findViewById(R.id.name);
    address=(EditText)findViewById(R.id.addr);
    notes=(EditText)findViewById(R.id.notes);
    types=(RadioGroup)findViewById(R.id.types);
    feed=(EditText)findViewById(R.id.feed);
    location=(TextView)findViewById(R.id.location);
    
    restaurantId=getIntent().getStringExtra(LunchList.ID_EXTRA);
    
    if (restaurantId!=null) {
      load();
    }
  }
  
  @Override
  public void onPause() {
    save();
    
    super.onPause();
  }
  
  @Override
  public void onDestroy() {
    helper.close();
    locMgr.removeUpdates(onLocationChange);
    
    super.onDestroy();
  }
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    new MenuInflater(this).inflate(R.menu.details_option, menu);

    return(super.onCreateOptionsMenu(menu));
  }

  @Override
  public boolean onPrepareOptionsMenu(Menu menu) {
    if (restaurantId==null) {
      menu.findItem(R.id.location).setEnabled(false);
      menu.findItem(R.id.map).setEnabled(false);
    }

    return(super.onPrepareOptionsMenu(menu));
  }
  
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId()==R.id.feed) {
      if (isNetworkAvailable()) {
        Intent i=new Intent(this, FeedActivity.class);
        
        i.putExtra(FeedActivity.FEED_URL, feed.getText().toString());
        startActivity(i);
      }
      else {
        Toast
          .makeText(this, "Sorry, the Internet is not available",
                    Toast.LENGTH_LONG)
          .show();
      }
    
      return(true);
    }
    else if (item.getItemId()==R.id.location) {
      locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                                    0, 0, onLocationChange);
      
      return(true);
    }
    else if (item.getItemId()==R.id.map) {
      Intent i=new Intent(this, RestaurantMap.class);
      
      i.putExtra(RestaurantMap.EXTRA_LATITUDE, latitude);
      i.putExtra(RestaurantMap.EXTRA_LONGITUDE, longitude);
      i.putExtra(RestaurantMap.EXTRA_NAME, name.getText().toString());
      
      startActivity(i);
      
      return(true);
    }

    return(super.onOptionsItemSelected(item));
  }
  
  private boolean isNetworkAvailable() {
    ConnectivityManager cm=(ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);
    NetworkInfo info=cm.getActiveNetworkInfo();
    
    return(info!=null);
  }
  
  private void load() {
    Cursor c=helper.getById(restaurantId);

    c.moveToFirst();    
    name.setText(helper.getName(c));
    address.setText(helper.getAddress(c));
    notes.setText(helper.getNotes(c));
    feed.setText(helper.getFeed(c));
    
    if (helper.getType(c).equals("sit_down")) {
      types.check(R.id.sit_down);
    }
    else if (helper.getType(c).equals("take_out")) {
      types.check(R.id.take_out);
    }
    else {
      types.check(R.id.delivery);
    }
    
    latitude=helper.getLatitude(c);
    longitude=helper.getLongitude(c);
    
    location.setText(String.valueOf(latitude)
                      +", "
                      +String.valueOf(longitude));
    
    c.close();
  }
  
  private void save() {
    if (name.getText().toString().length()>0) {
      String type=null;
      
      switch (types.getCheckedRadioButtonId()) {
        case R.id.sit_down:
          type="sit_down";
          break;
        case R.id.take_out:
          type="take_out";
          break;
        default:
          type="delivery";
          break;
      }
  
      if (restaurantId==null) {
        helper.insert(name.getText().toString(),
                      address.getText().toString(), type,
                      notes.getText().toString(),
                      feed.getText().toString());
      }
      else {
        helper.update(restaurantId, name.getText().toString(),
                      address.getText().toString(), type,
                      notes.getText().toString(),
                      feed.getText().toString());
      }
    }
  }
  
  LocationListener onLocationChange=new LocationListener() {
    public void onLocationChanged(Location fix) {
      helper.updateLocation(restaurantId, fix.getLatitude(),
                            fix.getLongitude());
      location.setText(String.valueOf(fix.getLatitude())
                      +", "
                      +String.valueOf(fix.getLongitude()));
      locMgr.removeUpdates(onLocationChange);
      
      Toast
        .makeText(DetailForm.this, "Location saved",
                  Toast.LENGTH_LONG)
        .show();
    }
    
    public void onProviderDisabled(String provider) {
      // required for interface, not used
    }
    
    public void onProviderEnabled(String provider) {
      // required for interface, not used
    }
    
    public void onStatusChanged(String provider, int status,
                                  Bundle extras) {
      // required for interface, not used
    }
  };
}



//src\apt\tutorial\EditPreferences.java
package apt.tutorial;

import android.app.Activity;
import android.content.ComponentName;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;

public class EditPreferences extends PreferenceActivity {
  SharedPreferences prefs=null;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    addPreferencesFromResource(R.xml.preferences);
  }
  
  @Override
  public void onResume() {
    super.onResume();
    
    prefs=PreferenceManager.getDefaultSharedPreferences(this);
    prefs.registerOnSharedPreferenceChangeListener(onChange);
  }
  
  @Override
  public void onPause() {
    prefs.unregisterOnSharedPreferenceChangeListener(onChange);
    
    super.onPause();
  }
  
  SharedPreferences.OnSharedPreferenceChangeListener onChange=
    new SharedPreferences.OnSharedPreferenceChangeListener() {
    public void onSharedPreferenceChanged(SharedPreferences prefs,
                                          String key) {
      if ("alarm".equals(key)) {
        boolean enabled=prefs.getBoolean(key, false);
        int flag=(enabled ?
                    PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
        ComponentName component=new ComponentName(EditPreferences.this,
                                                  OnBootReceiver.class);
        
        getPackageManager()
          .setComponentEnabledSetting(component,
                                      flag,
                                      PackageManager.DONT_KILL_APP);
          
        if (enabled) {
          OnBootReceiver.setAlarm(EditPreferences.this);
        }
        else {
          OnBootReceiver.cancelAlarm(EditPreferences.this);
        }
      }
      else if ("alarm_time".equals(key)) {
        OnBootReceiver.cancelAlarm(EditPreferences.this);
        OnBootReceiver.setAlarm(EditPreferences.this);
      }
    }
  };
}



//src\apt\tutorial\FeedActivity.java
package apt.tutorial;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import org.mcsoxford.rss.RSSItem;
import org.mcsoxford.rss.RSSFeed;

public class FeedActivity extends ListActivity {
  public static final String FEED_URL="apt.tutorial.FEED_URL";
  private InstanceState state=null;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    state=(InstanceState)getLastNonConfigurationInstance();
    
    if (state==null) {
      state=new InstanceState();
      state.handler=new FeedHandler(this);
      
      Intent i=new Intent(this, FeedService.class);
      
      i.putExtra(FeedService.EXTRA_URL,
                 getIntent().getStringExtra(FEED_URL));
      i.putExtra(FeedService.EXTRA_MESSENGER,
                 new Messenger(state.handler));
      
      startService(i);
    }
    else {
      if (state.handler!=null) {
        state.handler.attach(this);
      }
      
      if (state.feed!=null) {
        setFeed(state.feed);
      }
    }
  }
  
  @Override
  public Object onRetainNonConfigurationInstance() {
    if (state.handler!=null) {
      state.handler.detach();
    }
    
    return(state);
  }
  
  private void setFeed(RSSFeed feed) {
    state.feed=feed;
    setListAdapter(new FeedAdapter(feed));
  }
  
  private void goBlooey(Throwable t) {
    AlertDialog.Builder builder=new AlertDialog.Builder(this);
    
    builder
      .setTitle("Exception!")
      .setMessage(t.toString())
      .setPositiveButton("OK", null)
      .show();
  }
  
  private static class InstanceState {
    RSSFeed feed=null;
    FeedHandler handler=null;
  }
  
  private class FeedAdapter extends BaseAdapter {
    RSSFeed feed=null;
    
    FeedAdapter(RSSFeed feed) {
      super();
      
      this.feed=feed;
    }
    
    @Override
    public int getCount() {
      return(feed.getItems().size());
    }
    
    @Override
    public Object getItem(int position) {
      return(feed.getItems().get(position));
    }
    
    @Override
    public long getItemId(int position) {
      return(position);
    }
    
    @Override
    public View getView(int position, View convertView,
                        ViewGroup parent) {
      View row=convertView;
      
      if (row==null) {                          
        LayoutInflater inflater=getLayoutInflater();
        
        row=inflater.inflate(android.R.layout.simple_list_item_1,
                             parent, false);
      }
      
      RSSItem item=(RSSItem)getItem(position);
      
      ((TextView)row).setText(item.getTitle());
      
      return(row);
    }
  }
  
  private static class FeedHandler extends Handler {
    FeedActivity activity=null;
    
    FeedHandler(FeedActivity activity) {
      attach(activity);
    }
    
    void attach(FeedActivity activity) {
      this.activity=activity;
    }
    
    void detach() {
      this.activity=null;
    }
    
    @Override
    public void handleMessage(Message msg) {
      if (msg.arg1==RESULT_OK) {
        activity.setFeed((RSSFeed)msg.obj);
      }
      else {
        activity.goBlooey((Exception)msg.obj);
      }
    }
  };
}



//src\apt\tutorial\FeedService.java
package apt.tutorial;

import android.app.Activity;
import android.app.IntentService;
import android.content.Intent;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;
import org.mcsoxford.rss.RSSItem;
import org.mcsoxford.rss.RSSFeed;
import org.mcsoxford.rss.RSSReader;

public class FeedService extends IntentService {
  public static final String EXTRA_URL="apt.tutorial.EXTRA_URL";
  public static final String EXTRA_MESSENGER="apt.tutorial.EXTRA_MESSENGER";

  public FeedService() {
    super("FeedService");
  }
  
  @Override
  public void onHandleIntent(Intent i) {
    RSSReader reader=new RSSReader();
    Messenger messenger=(Messenger)i.getExtras().get(EXTRA_MESSENGER);
    Message msg=Message.obtain();
    
    try {
      RSSFeed result=reader.load(i.getStringExtra(EXTRA_URL));
      
      msg.arg1=Activity.RESULT_OK;
      msg.obj=result;
    }
    catch (Exception e) {
      Log.e("LunchList", "Exception parsing feed", e);
      msg.arg1=Activity.RESULT_CANCELED;
      msg.obj=e;
    }
    
    try {
      messenger.send(msg);
    }
    catch (Exception e) {
      Log.w("LunchList", "Exception sending results to activity", e);
    }
  }
}




//src\apt\tutorial\LunchList.java
package apt.tutorial;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.widget.AdapterView;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class LunchList extends ListActivity {
  public final static String ID_EXTRA="apt.tutorial._ID";
  Cursor model=null;
  RestaurantAdapter adapter=null;
  RestaurantHelper helper=null;
  SharedPreferences prefs=null;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    helper=new RestaurantHelper(this);
    prefs=PreferenceManager.getDefaultSharedPreferences(this);
    initList();
    prefs.registerOnSharedPreferenceChangeListener(prefListener);
  }
  
  @Override
  public void onDestroy() {
    super.onDestroy();
    
    helper.close();
  }
  
  @Override
  public void onListItemClick(ListView list, View view,
                              int position, long id) {
    Intent i=new Intent(LunchList.this, DetailForm.class);

    i.putExtra(ID_EXTRA, String.valueOf(id));
    startActivity(i);
  }
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    new MenuInflater(this).inflate(R.menu.option, menu);

    return(super.onCreateOptionsMenu(menu));
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId()==R.id.add) {
      startActivity(new Intent(LunchList.this, DetailForm.class));
      
      return(true);
    }
    else if (item.getItemId()==R.id.prefs) {
      startActivity(new Intent(this, EditPreferences.class));
    
      return(true);
    }

    return(super.onOptionsItemSelected(item));
  }
  
  private void initList() {
    if (model!=null) {
      stopManagingCursor(model);
      model.close();
    }
    
    model=helper.getAll(prefs.getString("sort_order", "name"));
    startManagingCursor(model);
    adapter=new RestaurantAdapter(model);
    setListAdapter(adapter);
  }
  
  private SharedPreferences.OnSharedPreferenceChangeListener prefListener=
   new SharedPreferences.OnSharedPreferenceChangeListener() {
    public void onSharedPreferenceChanged(SharedPreferences sharedPrefs,
                                          String key) {
      if (key.equals("sort_order")) {
        initList();
      }
    }
  };
  
  class RestaurantAdapter extends CursorAdapter {
    RestaurantAdapter(Cursor c) {
      super(LunchList.this, c);
    }
    
    @Override
    public void bindView(View row, Context ctxt,
                         Cursor c) {
      RestaurantHolder holder=(RestaurantHolder)row.getTag();
      
      holder.populateFrom(c, helper);
    }
    
    @Override
    public View newView(Context ctxt, Cursor c,
                         ViewGroup parent) {
      LayoutInflater inflater=getLayoutInflater();
      View row=inflater.inflate(R.layout.row, parent, false);
      RestaurantHolder holder=new RestaurantHolder(row);
      
      row.setTag(holder);
      
      return(row);
    }
  }
  
  static class RestaurantHolder {
    private TextView name=null;
    private TextView address=null;
    private ImageView icon=null;
    
    RestaurantHolder(View row) {
      name=(TextView)row.findViewById(R.id.title);
      address=(TextView)row.findViewById(R.id.address);
      icon=(ImageView)row.findViewById(R.id.icon);
    }
    
    void populateFrom(Cursor c, RestaurantHelper helper) {
      name.setText(helper.getName(c));
      address.setText(helper.getAddress(c));
  
      if (helper.getType(c).equals("sit_down")) {
        icon.setImageResource(R.drawable.ball_red);
      }
      else if (helper.getType(c).equals("take_out")) {
        icon.setImageResource(R.drawable.ball_yellow);
      }
      else {
        icon.setImageResource(R.drawable.ball_green);
      }
    }
  }
}



//src\apt\tutorial\OnAlarmReceiver.java
package apt.tutorial;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class OnAlarmReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context ctxt, Intent intent) {
    Intent i=new Intent(ctxt, AlarmActivity.class);
    
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    
    ctxt.startActivity(i);
  }
}



//src\apt\tutorial\OnBootReceiver.java
package apt.tutorial;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import java.util.Calendar;

public class OnBootReceiver extends BroadcastReceiver {
  public static void setAlarm(Context ctxt) {
    AlarmManager mgr=(AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);
    Calendar cal=Calendar.getInstance();
    SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(ctxt);
    String time=prefs.getString("alarm_time", "12:00");
    
    cal.set(Calendar.HOUR_OF_DAY, TimePreference.getHour(time));
    cal.set(Calendar.MINUTE, TimePreference.getMinute(time));
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    
    if (cal.getTimeInMillis()<System.currentTimeMillis()) {
      cal.add(Calendar.DAY_OF_YEAR, 1);
    }
    
    mgr.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
                      AlarmManager.INTERVAL_DAY,
                      getPendingIntent(ctxt));
  }
  
  public static void cancelAlarm(Context ctxt) {
    AlarmManager mgr=(AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);

    mgr.cancel(getPendingIntent(ctxt));
  }
  
  private static PendingIntent getPendingIntent(Context ctxt) {
    Intent i=new Intent(ctxt, OnAlarmReceiver.class);
    
    return(PendingIntent.getBroadcast(ctxt, 0, i, 0));
  }
  
  @Override
  public void onReceive(Context ctxt, Intent intent) {
    setAlarm(ctxt);
  }
}



//src\apt\tutorial\RestaurantHelper.java
package apt.tutorial;

import android.content.Context;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;

class RestaurantHelper extends SQLiteOpenHelper {
  private static final String DATABASE_NAME="lunchlist.db";
  private static final int SCHEMA_VERSION=3;
  
  public RestaurantHelper(Context context) {
    super(context, DATABASE_NAME, null, SCHEMA_VERSION);
  }
  
  @Override
  public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE restaurants (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, address TEXT, type TEXT, notes TEXT, feed TEXT, lat REAL, lon REAL);");
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (oldVersion<2) {
      db.execSQL("ALTER TABLE restaurants ADD COLUMN feed TEXT");
    }
    
    if (oldVersion<3) {
      db.execSQL("ALTER TABLE restaurants ADD COLUMN lat REAL");
      db.execSQL("ALTER TABLE restaurants ADD COLUMN lon REAL");
    }
  }

  public Cursor getAll(String orderBy) {
    return(getReadableDatabase()
            .rawQuery("SELECT _id, name, address, type, notes, lat, lon FROM restaurants ORDER BY "+orderBy,
                      null));
  }
  
  public Cursor getById(String id) {
    String[] args={id};

    return(getReadableDatabase()
            .rawQuery("SELECT _id, name, address, type, notes, feed, lat, lon FROM restaurants WHERE _ID=?",
                      args));
  }
  
  public void insert(String name, String address,
                     String type, String notes,
                     String feed) {
    ContentValues cv=new ContentValues();
          
    cv.put("name", name);
    cv.put("address", address);
    cv.put("type", type);
    cv.put("notes", notes);
    cv.put("feed", feed);
    
    getWritableDatabase().insert("restaurants", "name", cv);
  }
  
  public void update(String id, String name, String address,
                     String type, String notes, String feed) {
    ContentValues cv=new ContentValues();
    String[] args={id};
    
    cv.put("name", name);
    cv.put("address", address);
    cv.put("type", type);
    cv.put("notes", notes);
    cv.put("feed", feed);
    
    getWritableDatabase().update("restaurants", cv, "_ID=?",
                                 args);
  }
  
  public void updateLocation(String id, double lat, double lon) {
    ContentValues cv=new ContentValues();
    String[] args={id};
    
    cv.put("lat", lat);
    cv.put("lon", lon);
    
    getWritableDatabase().update("restaurants", cv, "_ID=?",
                                 args);
  }
  
  public String getName(Cursor c) {
    return(c.getString(1));
  }
  
  public String getAddress(Cursor c) {
    return(c.getString(2));
  }
  
  public String getType(Cursor c) {
    return(c.getString(3));
  }
  
  public String getNotes(Cursor c) {
    return(c.getString(4));
  }
  
  public String getFeed(Cursor c) {
    return(c.getString(5));
  }
  
  public double getLatitude(Cursor c) {
    return(c.getDouble(6));
  }
  
  public double getLongitude(Cursor c) {
    return(c.getDouble(7));
  }
}



//src\apt\tutorial\RestaurantMap.java
package apt.tutorial;

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

public class RestaurantMap extends MapActivity {
  public static final String EXTRA_LATITUDE="apt.tutorial.EXTRA_LATITUDE";
  public static final String EXTRA_LONGITUDE="apt.tutorial.EXTRA_LONGITUDE";
  public static final String EXTRA_NAME="apt.tutorial.EXTRA_NAME";
  private MapView map=null;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.map);
    
    double lat=getIntent().getDoubleExtra(EXTRA_LATITUDE, 0);
    double lon=getIntent().getDoubleExtra(EXTRA_LONGITUDE, 0);
    
    map=(MapView)findViewById(R.id.map);
    
    map.getController().setZoom(17);
    
    GeoPoint status=new GeoPoint((int)(lat*1000000.0),
                                  (int)(lon*1000000.0));
    
    map.getController().setCenter(status);
    map.setBuiltInZoomControls(true);
    
    Drawable marker=getResources().getDrawable(R.drawable.marker);
    
    marker.setBounds(0, 0, marker.getIntrinsicWidth(),
                      marker.getIntrinsicHeight());
    
    map
      .getOverlays()
      .add(new RestaurantOverlay(marker, status,
                                  getIntent().getStringExtra(EXTRA_NAME)));
  }
  
   @Override
  protected boolean isRouteDisplayed() {
    return(false);
  }
    
  private class RestaurantOverlay extends ItemizedOverlay<OverlayItem> {
    private OverlayItem item=null;
    
    public RestaurantOverlay(Drawable marker, GeoPoint point,
                              String name) {
      super(marker);
      
      boundCenterBottom(marker);
      
      item=new OverlayItem(point, name, name);

      populate();
    }
    
    @Override
    protected OverlayItem createItem(int i) {
      return(item);
    }
     
    @Override
    protected boolean onTap(int i) {
      Toast.makeText(RestaurantMap.this,
                      item.getSnippet(),
                      Toast.LENGTH_SHORT).show();
      
      return(true);
    }
    
    @Override
    public int size() {
      return(1);
    }
  }
}



//src\apt\tutorial\TimePreference.java
package apt.tutorial;

import android.content.Context;
import android.content.res.TypedArray;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TimePicker;

public class TimePreference extends DialogPreference {
  private int lastHour=0;
  private int lastMinute=0;
  private TimePicker picker=null;
  
  public static int getHour(String time) {
    String[] pieces=time.split(":");
    
    return(Integer.parseInt(pieces[0]));
  }

  public static int getMinute(String time) {
    String[] pieces=time.split(":");
    
    return(Integer.parseInt(pieces[1]));
  }

  public TimePreference(Context ctxt, AttributeSet attrs) {
    super(ctxt, attrs);
    
    setPositiveButtonText("Set");
    setNegativeButtonText("Cancel");
  }

  @Override
  protected View onCreateDialogView() {
    picker=new TimePicker(getContext());
    
    return(picker);
  }
  
  @Override
  protected void onBindDialogView(View v) {
    super.onBindDialogView(v);
    
    picker.setCurrentHour(lastHour);
    picker.setCurrentMinute(lastMinute);
  }
  
  @Override
  protected void onDialogClosed(boolean positiveResult) {
    super.onDialogClosed(positiveResult);

    if (positiveResult) {
      lastHour=picker.getCurrentHour();
      lastMinute=picker.getCurrentMinute();
      
      String time=String.valueOf(lastHour)+":"+String.valueOf(lastMinute);
      
      if (callChangeListener(time)) {
        persistString(time);
      }
    }
  }

  @Override
  protected Object onGetDefaultValue(TypedArray a, int index) {
    return(a.getString(index));
  }

  @Override
  protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
    String time=null;
    
    if (restoreValue) {
      if (defaultValue==null) {
        time=getPersistedString("00:00");
      }
      else {
        time=getPersistedString(defaultValue.toString());
      }
    }
    else {
      time=defaultValue.toString();
    }
    
    lastHour=getHour(time);
    lastMinute=getMinute(time);
  }
}



//res\xml\preferences.xml
<PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android">
  <ListPreference
    android:key="sort_order"
    android:title="Sort Order"
    android:summary="Choose the order the list uses"
    android:entries="@array/sort_names"
    android:entryValues="@array/sort_clauses"
    android:dialogTitle="Choose a sort order" />
  <CheckBoxPreference
    android:key="alarm"
    android:title="Sound a Lunch Alarm"
    android:summary="Check if you want to know when it is time for lunch" />
  <apt.tutorial.TimePreference
    android:key="alarm_time"
    android:title="Lunch Alarm Time"
    android:defaultValue="12:00"
    android:summary="Set your desired time for the lunch alarm"
    android:dependency="alarm" />
</PreferenceScreen>



//res\values\arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string-array name="sort_names">
    <item>By Name, Ascending</item>
    <item>By Name, Descending</item>
    <item>By Type</item>
    <item>By Address, Ascending</item>
    <item>By Address, Descending</item>
  </string-array>
  <string-array name="sort_clauses">
    <item>name ASC</item>
    <item>name DESC</item>
    <item>type, name ASC</item>
    <item>address ASC</item>
    <item>address DESC</item>
  </string-array>
</resources>



//res\values\strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">LunchList</string>
</resources>



//res\menu\details_option.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@+id/feed"
    android:title="RSS Feed"
    android:icon="@drawable/ic_menu_friendslist"
  />
  <item android:id="@+id/location"
    android:title="Save Location"
    android:icon="@drawable/ic_menu_compass"
  />
  <item android:id="@+id/map"
    android:title="Show on Map"
    android:icon="@drawable/ic_menu_mapmode"
  />
</menu>



//res\menu\option.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@+id/add"
    android:title="Add"
    android:icon="@drawable/ic_menu_add"
  />
  <item android:id="@+id/prefs"
    android:title="Settings"
    android:icon="@drawable/ic_menu_preferences"
  />
</menu>



//res\layout-land\detail_form.xml
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:stretchColumns="2"
  >
  <TableRow>
    <TextView android:text="Name:" />
    <EditText android:id="@+id/name"
      android:layout_span="2"
    />
  </TableRow>
  <TableRow>
    <TextView android:text="Address:" />
    <EditText android:id="@+id/addr"
      android:layout_span="2"
    />
  </TableRow>
  <TableRow>
    <TextView android:text="Type:" />
    <RadioGroup android:id="@+id/types">
      <RadioButton android:id="@+id/take_out"
        android:text="Take-Out"
      />
      <RadioButton android:id="@+id/sit_down"
        android:text="Sit-Down"
      />
      <RadioButton android:id="@+id/delivery"
        android:text="Delivery"
      />
    </RadioGroup>
    <LinearLayout android:orientation="vertical">
      <EditText android:id="@+id/notes"
        android:singleLine="false"
        android:gravity="top"
        android:lines="2"
        android:scrollHorizontally="false"
        android:maxLines="2"
        android:maxWidth="140sp"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Notes"
      />
      <EditText android:id="@+id/feed"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Feed URL"
      />
      <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <TextView android:text="Location:"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
        />
        <TextView android:id="@+id/location"
          android:text="(not set)"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
        />
      </LinearLayout>
    </LinearLayout>
  </TableRow>
</TableLayout>



//res\layout\alarm.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="It's time for lunch!"
  android:textSize="30sp"
  android:textStyle="bold"
/>



//res\layout\detail_form.xml
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:stretchColumns="1"
  >
  <TableRow>
    <TextView android:text="Name:" />
    <EditText android:id="@+id/name" />
  </TableRow>
  <TableRow>
    <TextView android:text="Address:" />
    <EditText android:id="@+id/addr" />
  </TableRow>
  <TableRow>
    <TextView android:text="Type:" />
    <RadioGroup android:id="@+id/types">
      <RadioButton android:id="@+id/take_out"
        android:text="Take-Out"
      />
      <RadioButton android:id="@+id/sit_down"
        android:text="Sit-Down"
      />
      <RadioButton android:id="@+id/delivery"
        android:text="Delivery"
      />
    </RadioGroup>
  </TableRow>
  <TableRow>
    <TextView android:text="Location:" />
    <TextView android:id="@+id/location" android:text="(not set)" />
  </TableRow>
  <EditText android:id="@+id/notes"
    android:singleLine="false"
    android:gravity="top"
    android:lines="2"
    android:scrollHorizontally="false"
    android:maxLines="2"
    android:maxWidth="200sp"
    android:layout_span="2"
    android:hint="Notes"
    android:layout_marginTop="4dip"
  />
  <EditText android:id="@+id/feed"
    android:layout_span="2"
    android:hint="Feed URL"
  />
</TableLayout>



//res\layout\main.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@android:id/list"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
/>



//res\layout\map.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.maps.MapView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/map"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:apiKey="00yHj0k7_7vxbuQ9zwyXI4bNMJrAjYrJ9KKHgbQ"
  android:clickable="true" />



//res\layout\row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal"
  android:padding="4dip"
  >
  <ImageView android:id="@+id/icon"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_alignParentTop="true"
    android:layout_alignParentBottom="true"
    android:layout_marginRight="4dip"
  />
  <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    >  
    <TextView android:id="@+id/title"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:gravity="center_vertical"
      android:textStyle="bold"
      android:singleLine="true"
      android:ellipsize="end"
    />
    <TextView android:id="@+id/address"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:gravity="center_vertical"
      android:singleLine="true"
      android:ellipsize="end"
    />
  </LinearLayout>
</LinearLayout>

Alarm demo

<?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">
  <Button
    android:id="@+id/start"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Start Alarm"
  />
  <Button
    android:id="@+id/stop"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Cancel Alarm"
  />
</LinearLayout>
package app.test;

import java.util.Calendar;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.Toast;

public class AlarmActivity extends Activity implements View.OnClickListener {
    
    private PendingIntent mAlarmIntent;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.start).setOnClickListener(this);
        findViewById(R.id.stop).setOnClickListener(this);
        Intent launchIntent = new Intent(this, AlarmReceiver.class);
        mAlarmIntent = PendingIntent.getBroadcast(this, 0, launchIntent, 0);
    }

    @Override
    public void onClick(View v) {
        AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        long interval = 5*1000; //5 seconds
        
        switch(v.getId()) {
        case R.id.start:
            Toast.makeText(this, "Scheduled", Toast.LENGTH_SHORT).show();
            manager.setRepeating(AlarmManager.ELAPSED_REALTIME,
                    SystemClock.elapsedRealtime()+interval,
                    interval,
                    mAlarmIntent);
            break;
        case R.id.stop:
            Toast.makeText(this, "Canceled", Toast.LENGTH_SHORT).show();
            manager.cancel(mAlarmIntent);
            break;
        default:
            break;
        }
    }
    
    private long nextStartTime() {
        long oneDay = 24*3600*1000; //24 hours
        //Set the time to 09:00:00
        Calendar startTime = Calendar.getInstance();
        startTime.set(Calendar.HOUR_OF_DAY, 9);
        startTime.set(Calendar.MINUTE, 0);
        startTime.set(Calendar.SECOND, 0);
        
        Calendar now = Calendar.getInstance();
        if(now.before(startTime)) {
            return startTime.getTimeInMillis();
        } else {
            startTime.add(Calendar.DATE, 1);
            return startTime.getTimeInMillis();
        }
    }
}


package app.test;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Calendar now = Calendar.getInstance();
        DateFormat formatter = SimpleDateFormat.getTimeInstance();
        Toast.makeText(context, formatter.format(now.getTime()), Toast.LENGTH_SHORT).show();
    }
}

Example of scheduling one-shot and repeating alarms.

package app.test;

import java.util.Calendar;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;


public class Test extends Activity {
  Toast mToast;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // Watch for button clicks.
    Button button = (Button) findViewById(R.id.one_shot);
    button.setOnClickListener(mOneShotListener);
    button = (Button) findViewById(R.id.start_repeating);
    button.setOnClickListener(mStartRepeatingListener);
    button = (Button) findViewById(R.id.stop_repeating);
    button.setOnClickListener(mStopRepeatingListener);
  }

  private OnClickListener mOneShotListener = new OnClickListener() {
    public void onClick(View v) {
      // When the alarm goes off, we want to broadcast an Intent to our
      // BroadcastReceiver. Here we make an Intent with an explicit class
      // name to have our own receiver (which has been published in
      // AndroidManifest.xml) instantiated and called, and then create an
      // IntentSender to have the intent executed as a broadcast.
      Intent intent = new Intent(Test.this, OneShotAlarm.class);
      PendingIntent sender = PendingIntent.getBroadcast(Test.this, 0,
          intent, 0);

      // We want the alarm to go off 30 seconds from now.
      Calendar calendar = Calendar.getInstance();
      calendar.setTimeInMillis(System.currentTimeMillis());
      calendar.add(Calendar.SECOND, 30);

      // Schedule the alarm!
      AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
      am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);

      // Tell the user about what we did.
      if (mToast != null) {
        mToast.cancel();
      }
      mToast = Toast.makeText(Test.this, "one_shot_scheduled",
          Toast.LENGTH_LONG);
      mToast.show();
    }
  };

  private OnClickListener mStartRepeatingListener = new OnClickListener() {
    public void onClick(View v) {
      // When the alarm goes off, we want to broadcast an Intent to our
      // BroadcastReceiver. Here we make an Intent with an explicit class
      // name to have our own receiver (which has been published in
      // AndroidManifest.xml) instantiated and called, and then create an
      // IntentSender to have the intent executed as a broadcast.
      // Note that unlike above, this IntentSender is configured to
      // allow itself to be sent multiple times.
      Intent intent = new Intent(Test.this, RepeatingAlarm.class);
      PendingIntent sender = PendingIntent.getBroadcast(Test.this, 0,
          intent, 0);

      // We want the alarm to go off 30 seconds from now.
      long firstTime = SystemClock.elapsedRealtime();
      firstTime += 15 * 1000;

      // Schedule the alarm!
      AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
      am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime,
          15 * 1000, sender);

      // Tell the user about what we did.
      if (mToast != null) {
        mToast.cancel();
      }
      mToast = Toast.makeText(Test.this, "repeating_scheduled",
          Toast.LENGTH_LONG);
      mToast.show();
    }
  };

  private OnClickListener mStopRepeatingListener = new OnClickListener() {
    public void onClick(View v) {
      // Create the same intent, and thus a matching IntentSender, for
      // the one that was scheduled.
      Intent intent = new Intent(Test.this, RepeatingAlarm.class);
      PendingIntent sender = PendingIntent.getBroadcast(Test.this, 0,
          intent, 0);

      // And cancel the alarm.
      AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
      am.cancel(sender);

      // Tell the user about what we did.
      if (mToast != null) {
        mToast.cancel();
      }
      mToast = Toast.makeText(Test.this, "repeating_unscheduled",
          Toast.LENGTH_LONG);
      mToast.show();
    }
  };
}

/**
 * This is an example of implement an {@link BroadcastReceiver} for an alarm that
 * should occur once.
 * <p>
 * When the alarm goes off, we show a <i>Toast</i>, a quick message.
 */
 class OneShotAlarm extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        Toast.makeText(context, "one_shot_received", Toast.LENGTH_SHORT).show();
    }
}


/**
 * This is an example of implement an {@link BroadcastReceiver} for an alarm
 * that should occur once.
 */
class RepeatingAlarm extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
    Toast.makeText(context, "repeating_received", Toast.LENGTH_SHORT)
        .show();
  }
}
//main.xml

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


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
    android:gravity="center_horizontal"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <TextView 
        android:layout_width="match_parent" android:layout_height="wrap_content"
        android:layout_weight="0"
        android:paddingBottom="4dip"
        android:text="alarm_controller"/>

    <Button android:id="@+id/one_shot"
        android:layout_width="wrap_content" android:layout_height="wrap_content" 
        android:text="one_shot_alarm">
        <requestFocus />
    </Button>

    <Button android:id="@+id/start_repeating"
        android:layout_width="wrap_content" android:layout_height="wrap_content" 
        android:text="start_repeating_alarm" />

    <Button android:id="@+id/stop_repeating"
        android:layout_width="wrap_content" android:layout_height="wrap_content" 
        android:text="stop_repeating_alarm" />

</LinearLayout>

Alarm Activity

     
package apt.tutorial;

import android.app.Activity;
import android.os.Bundle;

public class AlarmActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.alarm);    
  }
}

Open file with AssetManager

    

package app.test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.StringTokenizer;

import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.widget.TextView;

public class Test extends Activity {
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        setContentView(tv);
        try {
            AssetManager manager = getAssets();
            InputStream mInput = manager.open("data.csv");
            byte[] data = new byte[128];
            mInput.read(data);
            mInput.close();
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    
    }

}

Assets Helper

     
//package org.alldroid.forum.utils;

import java.io.IOException;
import java.io.InputStream;

import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;

public class AssetsHelper {
  private static final String  TAG      = AssetsHelper.class.getSimpleName ();

  private Context              context  = null;
  private AssetManager        assets  = null;

  public static AssetsHelper create ( Context context ) {
    return new AssetsHelper ( context );
  }

  private AssetsHelper ( Context context ) {
    this.setContext ( context );
    this.setAssets ( this.getContext ().getAssets () );
  }

  public StringBuilder read ( String asset ) {
    try {
      InputStream stream = getAssets ().open ( asset, AssetManager.ACCESS_BUFFER );
      int bytesRead = 0;
      byte[] buffer = new byte[256];
      StringBuilder data = new StringBuilder ();
      while ( (bytesRead = stream.read ( buffer, 0, buffer.length )) > 0 ) {
        data.append ( new String ( buffer, 0, bytesRead ) );
      }

      return data;
    } catch ( IOException ex ) {
      Log.e ( TAG, ex.getMessage (), ex );
    } catch ( Exception ex ) {
      Log.e ( TAG, ex.getMessage (), ex );
    }
    return null;
  }

  /**
   * @param context
   *          the context to set
   */
  public void setContext ( Context context ) {
    this.context = context;
  }

  /**
   * @return the context
   */
  public Context getContext ( ) {
    return context;
  }

  /**
   * @param assets
   *          the assets to set
   */
  public void setAssets ( AssetManager assets ) {
    this.assets = assets;
  }

  /**
   * @return the assets
   */
  public AssetManager getAssets ( ) {
    return assets;
  }
}

Read Asset Files

    
package app.test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.widget.TextView;

public class Test extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TextView textView = new TextView(this);
    setContentView(textView);
    AssetManager assetManager = getAssets();
    InputStream inputStream = null;
    try {
      inputStream = assetManager.open("/text.txt");
      String text = loadTextFile(inputStream);
      textView.setText(text);
    } catch (IOException e) {
      textView.setText("Couldn't load file");
    } finally {
      if (inputStream != null)
        try {
          inputStream.close();
        } catch (IOException e) {
          textView.setText("Couldn't close file");
        }
    }
  }

  public String loadTextFile(InputStream inputStream) throws IOException {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    byte[] bytes = new byte[4096];
    int len = 0;
    while ((len = inputStream.read(bytes)) > 0)
      byteStream.write(bytes, 0, len);
    return new String(byteStream.toByteArray(), "UTF8");
  }
}

Progress of AsyncTask

  
package app.test;

import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

class CustomHttpClient {
  private static HttpClient customHttpClient;

  public static synchronized HttpClient getHttpClient() {
    if (customHttpClient != null) {
      return customHttpClient;
    }
    HttpParams params = new BasicHttpParams();
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params,
        HTTP.DEFAULT_CONTENT_CHARSET);
    HttpProtocolParams.setUseExpectContinue(params, true);

    ConnManagerParams.setTimeout(params, 1000);

    HttpConnectionParams.setConnectionTimeout(params, 5000);
    HttpConnectionParams.setSoTimeout(params, 10000);

    SchemeRegistry schReg = new SchemeRegistry();
    schReg.register(new Scheme("http", PlainSocketFactory
        .getSocketFactory(), 80));
    schReg.register(new Scheme("https",
        SSLSocketFactory.getSocketFactory(), 443));
    ClientConnectionManager conMgr = new ThreadSafeClientConnManager(
        params, schReg);

    customHttpClient = new DefaultHttpClient(conMgr, params);

    return customHttpClient;
  }
}

class DownloadImageTask extends AsyncTask<String, Integer, Bitmap> {
  Context mContext;
  int progress = -1;
  Bitmap downloadedImage = null;

  DownloadImageTask(Context context) {
    mContext = context;
  }

  protected void setContext(Context context) {
    mContext = context;
    if (progress >= 0) {
      publishProgress(this.progress);
    }
  }

  protected void onPreExecute() {
    progress = 0;
  }

  protected Bitmap doInBackground(String... urls) {
    Log.v("doInBackground", "doing download of image...");
    return downloadImage(urls);
  }

  protected void onProgressUpdate(Integer... progress) {
    Log.v("onProgressUpdate", "Progress so far: " + progress[0]);
  }

  protected void onPostExecute(Bitmap result) {
    if (result != null) {
      downloadedImage = result;
      setImageInView();
    } else {
      Log.v("onPostExecute",
          "Problem downloading image. Please try later.");
    }
  }

  public Bitmap downloadImage(String... urls) {
    HttpClient httpClient = CustomHttpClient.getHttpClient();
    try {
      HttpGet request = new HttpGet(urls[0]);
      HttpParams params = new BasicHttpParams();
      HttpConnectionParams.setSoTimeout(params, 60000); // 1 minute
      request.setParams(params);
      HttpResponse response = httpClient.execute(request);
      setProgress(50);
      byte[] image = EntityUtils.toByteArray(response.getEntity());
      setProgress(75);
      Bitmap mBitmap = BitmapFactory.decodeByteArray(image, 0,
          image.length);
      setProgress(100);
      return mBitmap;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  private void setProgress(int progress) {
    this.progress = progress;
    publishProgress(this.progress);
  }

  protected void setImageInView() {
    if (downloadedImage != null) {
      ImageView mImage = (ImageView) ((Activity) mContext)
          .findViewById(R.id.image);
      mImage.setImageBitmap(downloadedImage);
    }
  }

  private void sleepFor(long msecs) {
    try {
      Thread.sleep(msecs);
    } catch (InterruptedException e) {
      Log.v("sleep", "interrupted");
    }
  }
}

public class Test extends Activity {
  private DownloadImageTask diTask;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    if ((diTask = (DownloadImageTask) getLastNonConfigurationInstance()) != null) {
      diTask.setContext(this);
      if (diTask.getStatus() == AsyncTask.Status.FINISHED)
        diTask.setImageInView();
    }
  }

  public void doClick(View view) {
    if (diTask != null) {
      AsyncTask.Status diStatus = diTask.getStatus();
      Log.v("doClick", "diTask status is " + diStatus);
      if (diStatus != AsyncTask.Status.FINISHED) {
        Log.v("doClick", "... no need to start a new task");
        return;
      }
    }
    diTask = new DownloadImageTask(this);
    diTask.execute("http://aBigFile");
  }

  @Override
  public Object onRetainNonConfigurationInstance() {
    return diTask;
  }
}

extends BroadcastReceiver

   
package app.test;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

 class AndroidReceiver1 extends BroadcastReceiver {
  Context context;
  public static int NOTIFICATION_ID = 21321;

  @Override
  public void onReceive(Context context, Intent intent) {
    this.context = context;
    showNotification();
  }

  private void showNotification() {

    NotificationManager notificationManager = (NotificationManager) context
        .getSystemService(android.content.Context.NOTIFICATION_SERVICE);
    Notification notification = new Notification(R.drawable.icon,
        "EoeAndroidReceiver1", System.currentTimeMillis());

    PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
        new Intent(context, Test.class), 0);
    notification.setLatestEventInfo(context, "EoeAndroidReceiver1", null,
        contentIntent);
    notificationManager.notify(NOTIFICATION_ID, notification);
  }
}
class AndroidReceiver2 extends BroadcastReceiver {
  Context context;
  @Override
  public void onReceive(Context context, Intent intent) {
    this.context = context;
    DeleteNotification();
  }
  private void DeleteNotification() {
    NotificationManager notificationManager = (NotificationManager) context
        .getSystemService(android.content.Context.NOTIFICATION_SERVICE);
    notificationManager.cancel(AndroidReceiver1.NOTIFICATION_ID);
  }
}

public class Test extends Activity {
  public static final int ITEM0 = Menu.FIRST;
  public static final int ITEM1 = Menu.FIRST + 1;

  static final String ACTION_1 = "com.eoeandroid.action.NEW_BROADCAST_1";
  static final String ACTION_2 = "com.eoeandroid.action.NEW_BROADCAST_2";

  @Override
  protected void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);
  }
  public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    menu.add(0, ITEM0, 0, "Notification");
    menu.add(0, ITEM1, 0, "1Notification");
    menu.findItem(ITEM1);
    return true;
  }

  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case ITEM0:
      actionClickMenuItem1();
      break;
    case ITEM1:
      actionClickMenuItem2();
      break;
    }
    return true;
  }
  private void actionClickMenuItem1() {
    Intent intent = new Intent(ACTION_1);
    sendBroadcast(intent);
  }
  private void actionClickMenuItem2() {
    Intent intent = new Intent(ACTION_2);
    sendBroadcast(intent);
  }
}


//main.xml

<?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">
  <TextView android:layout_width="fill_parent"
    android:layout_height="wrap_content" android:text="Start" />
</LinearLayout>

Scan SDReceiver extends BroadcastReceiver

   
//package com.never.util;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.provider.MediaStore;


 class ScanSDReceiver extends BroadcastReceiver {

  private AlertDialog.Builder alertdialogbuilder = null;
  private AlertDialog alertdialog = null;
  private Cursor cursor;

  @Override
  public void onReceive(Context arg0, Intent arg1) {
    // TODO Auto-generated method stub
    String receiveaction = arg1.getAction();
    if (Intent.ACTION_MEDIA_SCANNER_STARTED.equals(receiveaction)) {
      alertdialogbuilder = new AlertDialog.Builder(arg0);
      alertdialogbuilder.setMessage("Message......");
      alertdialog = alertdialogbuilder.create();
      alertdialog.show();
      cursor = arg0.getContentResolver().query(
          MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
          new String[] { MediaStore.Audio.Media.TITLE,
              MediaStore.Audio.Media.DURATION,
              MediaStore.Audio.Media.ARTIST,
              MediaStore.Audio.Media._ID,
              MediaStore.Audio.Media.DISPLAY_NAME }, null, null,
          null);
    } else if (Intent.ACTION_MEDIA_SCANNER_FINISHED.equals(receiveaction)) {
      alertdialog.cancel();
    }

  }

}

Handles all calling, receiving calls, and UI interaction in the WalkieTalkie app

package app.test;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.*;
import android.net.sip.*;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.ToggleButton;

import java.text.ParseException;

import android.os.Bundle;
import android.preference.PreferenceActivity;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.sip.*;
import android.util.Log;

/**
 * Listens for incoming SIP calls, intercepts and hands them off to WalkieTalkieActivity.
 */
 class IncomingCallReceiver extends BroadcastReceiver {
    /**
     * Processes the incoming call, answers it, and hands it over to the
     * WalkieTalkieActivity.
     * @param context The context under which the receiver is running.
     * @param intent The intent being received.
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        SipAudioCall incomingCall = null;
        try {

            SipAudioCall.Listener listener = new SipAudioCall.Listener() {
                @Override
                public void onRinging(SipAudioCall call, SipProfile caller) {
                    try {
                        call.answerCall(30);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };

            WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;

            incomingCall = wtActivity.manager.takeAudioCall(intent, listener);
            incomingCall.answerCall(30);
            incomingCall.startAudio();
            incomingCall.setSpeakerMode(true);
            if(incomingCall.isMuted()) {
                incomingCall.toggleMute();
            }

            wtActivity.call = incomingCall;

            wtActivity.updateStatus(incomingCall);

        } catch (Exception e) {
            if (incomingCall != null) {
                incomingCall.close();
            }
        }
    }

}

/**
 * Handles SIP authentication settings for the Walkie Talkie app.
 */
 class SipSettings extends PreferenceActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // Note that none of the preferences are actually defined here.
        // They're all in the XML file res/xml/preferences.xml.
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }
}

/**
 * Handles all calling, receiving calls, and UI interaction in the WalkieTalkie app.
 */
public class Test extends Activity implements View.OnTouchListener {

    public String sipAddress = null;

    public SipManager manager = null;
    public SipProfile me = null;
    public SipAudioCall call = null;
    public IncomingCallReceiver callReceiver;

    private static final int CALL_ADDRESS = 1;
    private static final int SET_AUTH_INFO = 2;
    private static final int UPDATE_SETTINGS_DIALOG = 3;
    private static final int HANG_UP = 4;


    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.walkietalkie);

        ToggleButton pushToTalkButton = (ToggleButton) findViewById(R.id.pushToTalk);
        pushToTalkButton.setOnTouchListener(this);

        // Set up the intent filter.  This will be used to fire an
        // IncomingCallReceiver when someone calls the SIP address used by this
        // application.
        IntentFilter filter = new IntentFilter();
        filter.addAction("android.SipDemo.INCOMING_CALL");
        callReceiver = new IncomingCallReceiver();
        this.registerReceiver(callReceiver, filter);

        // "Push to talk" can be a serious pain when the screen keeps turning off.
        // Let's prevent that.
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        initializeManager();
    }

    @Override
    public void onStart() {
        super.onStart();
        // When we get back from the preference setting Activity, assume
        // settings have changed, and re-login with new auth info.
        initializeManager();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (call != null) {
            call.close();
        }

        closeLocalProfile();

        if (callReceiver != null) {
            this.unregisterReceiver(callReceiver);
        }
    }

    public void initializeManager() {
        if(manager == null) {
          manager = SipManager.newInstance(this);
        }

        initializeLocalProfile();
    }

    /**
     * Logs you into your SIP provider, registering this device as the location to
     * send SIP calls to for your SIP address.
     */
    public void initializeLocalProfile() {
        if (manager == null) {
            return;
        }

        if (me != null) {
            closeLocalProfile();
        }

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        String username = prefs.getString("namePref", "");
        String domain = prefs.getString("domainPref", "");
        String password = prefs.getString("passPref", "");

        if (username.length() == 0 || domain.length() == 0 || password.length() == 0) {
            showDialog(UPDATE_SETTINGS_DIALOG);
            return;
        }

        try {
            SipProfile.Builder builder = new SipProfile.Builder(username, domain);
            builder.setPassword(password);
            me = builder.build();

            Intent i = new Intent();
            i.setAction("android.SipDemo.INCOMING_CALL");
            PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);
            manager.open(me, pi, null);


            // This listener must be added AFTER manager.open is called,
            // Otherwise the methods aren't guaranteed to fire.

            manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() {
                    public void onRegistering(String localProfileUri) {
                        updateStatus("Registering with SIP Server...");
                    }

                    public void onRegistrationDone(String localProfileUri, long expiryTime) {
                        updateStatus("Ready");
                    }

                    public void onRegistrationFailed(String localProfileUri, int errorCode,
                            String errorMessage) {
                        updateStatus("Registration failed.  Please check settings.");
                    }
                });
        } catch (ParseException pe) {
            updateStatus("Connection Error.");
        } catch (SipException se) {
            updateStatus("Connection error.");
        }
    }

    /**
     * Closes out your local profile, freeing associated objects into memory
     * and unregistering your device from the server.
     */
    public void closeLocalProfile() {
        if (manager == null) {
            return;
        }
        try {
            if (me != null) {
                manager.close(me.getUriString());
            }
        } catch (Exception ee) {
            Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
        }
    }

    /**
     * Make an outgoing call.
     */
    public void initiateCall() {

        updateStatus(sipAddress);

        try {
            SipAudioCall.Listener listener = new SipAudioCall.Listener() {
                // Much of the client's interaction with the SIP Stack will
                // happen via listeners.  Even making an outgoing call, don't
                // forget to set up a listener to set things up once the call is established.
                @Override
                public void onCallEstablished(SipAudioCall call) {
                    call.startAudio();
                    call.setSpeakerMode(true);
                    call.toggleMute();
                    updateStatus(call);
                }

                @Override
                public void onCallEnded(SipAudioCall call) {
                    updateStatus("Ready.");
                }
            };

            call = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30);

        }
        catch (Exception e) {
            Log.i("WalkieTalkieActivity/InitiateCall", "Error when trying to close manager.", e);
            if (me != null) {
                try {
                    manager.close(me.getUriString());
                } catch (Exception ee) {
                    Log.i("WalkieTalkieActivity/InitiateCall",
                            "Error when trying to close manager.", ee);
                    ee.printStackTrace();
                }
            }
            if (call != null) {
                call.close();
            }
        }
    }

    /**
     * Updates the status box at the top of the UI with a messege of your choice.
     * @param status The String to display in the status box.
     */
    public void updateStatus(final String status) {
        // Be a good citizen.  Make sure UI changes fire on the UI thread.
        this.runOnUiThread(new Runnable() {
            public void run() {
                TextView labelView = (TextView) findViewById(R.id.sipLabel);
                labelView.setText(status);
            }
        });
    }

    /**
     * Updates the status box with the SIP address of the current call.
     * @param call The current, active call.
     */
    public void updateStatus(SipAudioCall call) {
        String useName = call.getPeerProfile().getDisplayName();
        if(useName == null) {
          useName = call.getPeerProfile().getUserName();
        }
        updateStatus(useName + "@" + call.getPeerProfile().getSipDomain());
    }

    /**
     * Updates whether or not the user's voice is muted, depending on whether the button is pressed.
     * @param v The View where the touch event is being fired.
     * @param event The motion to act on.
     * @return boolean Returns false to indicate that the parent view should handle the touch event
     * as it normally would.
     */
    public boolean onTouch(View v, MotionEvent event) {
        if (call == null) {
            return false;
        } else if (event.getAction() == MotionEvent.ACTION_DOWN && call != null && call.isMuted()) {
            call.toggleMute();
        } else if (event.getAction() == MotionEvent.ACTION_UP && !call.isMuted()) {
            call.toggleMute();
        }
        return false;
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, CALL_ADDRESS, 0, "Call someone");
        menu.add(0, SET_AUTH_INFO, 0, "Edit your SIP Info.");
        menu.add(0, HANG_UP, 0, "End Current Call.");

        return true;
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case CALL_ADDRESS:
                showDialog(CALL_ADDRESS);
                break;
            case SET_AUTH_INFO:
                updatePreferences();
                break;
            case HANG_UP:
                if(call != null) {
                    try {
                      call.endCall();
                    } catch (SipException se) {
                        Log.d("WalkieTalkieActivity/onOptionsItemSelected",
                                "Error ending call.", se);
                    }
                    call.close();
                }
                break;
        }
        return true;
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case CALL_ADDRESS:

                LayoutInflater factory = LayoutInflater.from(this);
                final View textBoxView = factory.inflate(R.layout.call_address_dialog, null);
                return new AlertDialog.Builder(this)
                        .setTitle("Call Someone.")
                        .setView(textBoxView)
                        .setPositiveButton(
                                android.R.string.ok, new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int whichButton) {
                                        EditText textField = (EditText)
                                                (textBoxView.findViewById(R.id.calladdress_edit));
                                        sipAddress = textField.getText().toString();
                                        initiateCall();

                                    }
                        })
                        .setNegativeButton(
                                android.R.string.cancel, new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int whichButton) {
                                        // Noop.
                                    }
                        })
                        .create();

            case UPDATE_SETTINGS_DIALOG:
                return new AlertDialog.Builder(this)
                        .setMessage("Please update your SIP Account Settings.")
                        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {
                                updatePreferences();
                            }
                        })
                        .setNegativeButton(
                                android.R.string.cancel, new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int whichButton) {
                                        // Noop.
                                    }
                        })
                        .create();
        }
        return null;
    }

    public void updatePreferences() {
        Intent settingsActivity = new Intent(getBaseContext(),
                SipSettings.class);
        startActivity(settingsActivity);
    }
}
//
//res\layout\call_address_dialog.xml
<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical">

  <TextView
      android:id="@+id/calladdress_view"
      android:layout_height="wrap_content"
      android:layout_width="wrap_content"
      android:layout_marginLeft="20dip"
      android:layout_marginRight="20dip"
      android:text="@+string/contactAddress"
      android:gravity="left"
      android:textAppearance="?android:attr/textAppearanceMedium" />

  <EditText
      android:id="@+id/calladdress_edit"
      android:layout_height="wrap_content"
      android:layout_width="fill_parent"
      android:layout_marginLeft="20dip"
      android:layout_marginRight="20dip"
      android:scrollHorizontally="true"
      android:autoText="false"
      android:capitalize="none"
      android:gravity="fill_horizontal"
      android:textAppearance="?android:attr/textAppearanceMedium" />

</LinearLayout>



//res\layout\walkietalkie.xml
<?xml version="1.0" encoding="utf-8"?>


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
  <RelativeLayout android:padding="12dp"
      android:id="@+id/mainlayout"
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent">

      <TextView
          android:id="@+id/sipLabel"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:layout_centerHorizontal="true"
          android:textAppearance="?android:attr/textAppearanceLarge"
      />

      <ToggleButton
          android:layout_height="400dp"
          android:layout_width="400dp"
          android:text="@+string/talk"
          android:id="@+id/pushToTalk"

          android:layout_centerHorizontal="true"
          android:layout_centerVertical="true"
          android:background="@drawable/btn_record"
          android:textOff=""
          android:textOn=""
          android:layout_marginTop="-20dp" />

  </RelativeLayout>
</FrameLayout>



//
//res\values\strings.xml
<?xml version="1.0" encoding="utf-8"?>


<resources>
  <string name="app_name">SIP Demo</string>
  <string name="contactAddress">SIP Address to contact</string>
  <string name="talk">Talk</string>
</resources>



//
//res\xml\preferences.xml
<?xml version="1.0" encoding="utf-8"?>



<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
  <EditTextPreference
      android:name="SIP Username"
      android:summary="Username for your SIP Account"
      android:defaultValue=""
      android:title="Enter Username"
      android:key="namePref" />
  <EditTextPreference
      android:name="SIP Domain"
      android:summary="Domain for your SIP Account"
      android:defaultValue=""
      android:title="Enter Domain"
      android:key="domainPref" />
  <EditTextPreference
      android:name="SIP Password"
      android:summary="Password for your SIP Account"
      android:defaultValue=""
      android:title="Enter Password"
      android:key="passPref"
      android:password="true" />
</PreferenceScreen>
Set and get tag
package app.test;

import java.util.Date;
import java.util.HashMap;

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class Test extends Activity {
  private static final String LOG_KEY = "Tagger";

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    TextView view = (TextView) findViewById(R.id.test);

    setTag(view, R.id.test, new Date());

    view.setText(getTag(view, R.id.test).toString());
  }

  public void setTag(View v, int key, Object value) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
      v.setTag(key, value);
    } else {
      HashMap<Integer, Object> meta = (HashMap<Integer, Object>) v
          .getTag();

      if (meta == null) {
        meta = new HashMap<Integer, Object>();
      }

      meta.put(key, value);
    }
  }

  public Object getTag(View v, int key) {
    Object result = null;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
      result = v.getTag(key);
    } else {
      HashMap<Integer, Object> meta = (HashMap<Integer, Object>) v
          .getTag();

      if (meta == null) {
        meta = new HashMap<Integer, Object>();
      }

      result = meta.get(key);
    }

    return (result);
  }
}
//main.xml

<?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"
    >
<TextView android:id="@+id/test"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />
</LinearLayout>

Platform Checker

//package it.gerdavax.android.bluetooth.util;

import android.os.Build;
import android.util.Log;

class PlatformChecker {
  private static final int ANDROID_1_0 = 1;
  private static final int ANDROID_1_1 = 2;
  private static final int ANDROID_1_5 = 3;
  private static final int ANDROID_1_6 = 4;
  private static final String TAG = "BluetoothAPI";
  
  private PlatformChecker() {
    
  }
  
  public static boolean isThisPlatformSupported() {
    printPlatformDescription();
    
    int platform = Integer.parseInt(Build.VERSION.SDK);
    
    boolean supported = false;
    
    switch (platform) {
      case ANDROID_1_0:
        // never tested!
        supported = false;
        break;
      case ANDROID_1_1:
        // hopefully it can be only an HTC Dream
        supported = true;
        break;
      case ANDROID_1_5:
        supported = true;
        break;
      case ANDROID_1_6:
        // not yet tested
        break;
    }
    return supported;
  }
  
  public static void printPlatformDescription() {
    System.out.println("Android Bluetooth API - Platform checker");
    System.out.println("SDK: " + Build.VERSION.SDK);
    System.out.println("Board: " + Build.BOARD);
    System.out.println("Brand: " + Build.BRAND);
    System.out.println("Device: " + Build.DEVICE);
    System.out.println("Display: " + Build.DISPLAY);
    System.out.println("Fingerprint: " + Build.FINGERPRINT);
    System.out.println("Host: " + Build.HOST);
    System.out.println("ID: " + Build.ID);
    System.out.println("Model: " + Build.MODEL);
    System.out.println("Product: " + Build.PRODUCT);
    System.out.println("Tags: " + Build.TAGS);
    System.out.println("Time: " + Build.TIME);
    System.out.println("Type: " + Build.TYPE);
    System.out.println("User: " + Build.USER);
  }
}
Using Android Config class
package app.test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Config;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class  Test extends GraphicsActivity {

    private static final String TAG = "Compass";

    private SensorManager mSensorManager;
    private Sensor mSensor;
    private SampleView mView;
    private float[] mValues;

    private final SensorEventListener mListener = new SensorEventListener() {
        public void onSensorChanged(SensorEvent event) {
            if (Config.DEBUG) Log.d(TAG,
                    "sensorChanged (" + event.values[0] + ", " + event.values[1] + ", " + event.values[2] + ")");
            mValues = event.values;
            if (mView != null) {
                mView.invalidate();
            }
        }

        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    };

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        mView = new SampleView(this);
        setContentView(mView);
    }

    @Override
    protected void onResume()
    {
        if (Config.DEBUG) Log.d(TAG, "onResume");
        super.onResume();

        mSensorManager.registerListener(mListener, mSensor,
                SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    protected void onStop()
    {
        if (Config.DEBUG) Log.d(TAG, "onStop");
        mSensorManager.unregisterListener(mListener);
        super.onStop();
    }

    private class SampleView extends View {
        private Paint   mPaint = new Paint();
        private Path    mPath = new Path();
        private boolean mAnimate;

        public SampleView(Context context) {
            super(context);

            // Construct a wedge-shaped path
            mPath.moveTo(0, -50);
            mPath.lineTo(-20, 60);
            mPath.lineTo(0, 50);
            mPath.lineTo(20, 60);
            mPath.close();
        }

        @Override protected void onDraw(Canvas canvas) {
            Paint paint = mPaint;

            canvas.drawColor(Color.WHITE);

            paint.setAntiAlias(true);
            paint.setColor(Color.BLACK);
            paint.setStyle(Paint.Style.FILL);

            int w = canvas.getWidth();
            int h = canvas.getHeight();
            int cx = w / 2;
            int cy = h / 2;

            canvas.translate(cx, cy);
            if (mValues != null) {
                canvas.rotate(-mValues[0]);
            }
            canvas.drawPath(mPath, mPaint);
        }

        @Override
        protected void onAttachedToWindow() {
            mAnimate = true;
            if (Config.DEBUG) Log.d(TAG, "onAttachedToWindow. mAnimate=" + mAnimate);
            super.onAttachedToWindow();
        }

        @Override
        protected void onDetachedFromWindow() {
            mAnimate = false;
            if (Config.DEBUG) Log.d(TAG, "onDetachedFromWindow. mAnimate=" + mAnimate);
            super.onDetachedFromWindow();
        }
    }
}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}
Using ContentResolver
package app.test;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AutoCompleteTextView;
import android.widget.CursorAdapter;
import android.widget.FilterQueryProvider;
import android.widget.Filterable;
import android.widget.TextView;

public class Test extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ContentResolver content = getContentResolver();
    Cursor cursor = content.query(Contacts.CONTENT_URI,
        CONTACT_PROJECTION, null, null, null);
    ContactListAdapter adapter = new ContactListAdapter(
        this, cursor);

    AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.edit);
    textView.setAdapter(adapter);
  }

  // XXX compiler bug in javac 1.5.0_07-164, we need to implement Filterable
  // to make compilation work
  public static class ContactListAdapter extends CursorAdapter implements
      Filterable {
    public ContactListAdapter(Context context, Cursor c) {
      super(context, c);
      mContent = context.getContentResolver();
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
      final LayoutInflater inflater = LayoutInflater.from(context);
      final TextView view = (TextView) inflater.inflate(
          android.R.layout.simple_dropdown_item_1line, parent, false);
      view.setText(cursor.getString(COLUMN_DISPLAY_NAME));
      return view;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
      ((TextView) view).setText(cursor.getString(COLUMN_DISPLAY_NAME));
    }

    @Override
    public String convertToString(Cursor cursor) {
      return cursor.getString(COLUMN_DISPLAY_NAME);
    }

    @Override
    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
      FilterQueryProvider filter = getFilterQueryProvider();
      if (filter != null) {
        return filter.runQuery(constraint);
      }

      Uri uri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
          Uri.encode(constraint.toString()));
      return mContent.query(uri, CONTACT_PROJECTION, null, null, null);
    }

    private ContentResolver mContent;
  }

  public static final String[] CONTACT_PROJECTION = new String[] {
      Contacts._ID, Contacts.DISPLAY_NAME };

  private static final int COLUMN_DISPLAY_NAME = 1;
}

//main.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
  
          http://www.apache.org/licenses/LICENSE-2.0
  
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="autocomplete_5_instructions" />

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="autocomplete_5_name" />

        <AutoCompleteTextView android:id="@+id/edit"
            android:completionThreshold="1"
            android:completionHint="autocomplete_5_hint"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </LinearLayout>

</LinearLayout>

Get Path from Uri and ContentResolver

   

import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;

 class PathFromUri
{
    public static String retrieve(ContentResolver resolver, Uri uri)
    {
        if (uri.getScheme().equals("file"))
        {
            return uri.getPath();
        }
        final Cursor cursor = resolver.query(uri, new String[]{"_data"}, null, null, null);
        if (cursor.moveToFirst())
        {
            return cursor.getString(0);
        }
        throw new RuntimeException("Can't retrieve path from uri: " + uri.toString());
    }
}

get Content Name

    
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;

class Main {
  public static String getContentName(ContentResolver resolver, Uri uri) {
    Cursor cursor = resolver.query(uri, null, null, null, null);
    cursor.moveToFirst();
    int nameIndex = cursor
        .getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
    if (nameIndex >= 0) {
      return cursor.getString(nameIndex);
    } else {
      return null;
    }
  }
}

Load Heap

    

//package com.escobaro;

import java.io.File;
import java.text.DecimalFormat;

import android.os.Debug;
import android.util.Log;

class Utilities {

  public static String TAG = "Utilities";

  
    public static void logHeap(Class clazz) {
        Double allocated = new Double(Debug.getNativeHeapAllocatedSize())/new Double((1048576));
        Double available = (new Double(Debug.getNativeHeapSize())/1048576.0);
        Double free = (new Double(Debug.getNativeHeapFreeSize())/1048576.0);
        DecimalFormat df = new DecimalFormat();
        df.setMaximumFractionDigits(2);
        df.setMinimumFractionDigits(2);

        Log.d(TAG, "debug.heap native: allocated " + df.format(allocated) + "MB of " + df.format(available) + "MB (" + df.format(free) + "MB free) in [" + clazz.getName().replaceAll("com.myapp.android.","") + "]");
        Log.d(TAG, "debug.memory: allocated: " + df.format(new Double(Runtime.getRuntime().totalMemory()/1048576)) + "MB of " + df.format(new Double(Runtime.getRuntime().maxMemory()/1048576))+ "MB (" + df.format(new Double(Runtime.getRuntime().freeMemory()/1048576)) +"MB free)");
        System.gc();
        System.gc();

    }
    

}

get Display Metrics

    
//package com.anoshenko.android.mahjongg;

import android.content.Context;
import android.util.DisplayMetrics;
import android.view.WindowManager;

class Utils {
  static public DisplayMetrics getDisplayMetrics(Context context) {
    DisplayMetrics metrics = new DisplayMetrics();
    WindowManager wm = (WindowManager) context
        .getSystemService(Context.WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(metrics);

    return metrics;
  }
}

Using Geocoder

   

package app.test;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;

public class Test extends Activity {

  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);

    LocationManager locationManager;
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);

    String provider = locationManager.getBestProvider(criteria, true);

    Location location = locationManager.getLastKnownLocation(provider);
    updateWithNewLocation(location);

    locationManager.requestLocationUpdates(provider, 2000, 10,
        locationListener);
  }

  private final LocationListener locationListener = new LocationListener() {
    public void onLocationChanged(Location location) {
      updateWithNewLocation(location);
    }

    public void onProviderDisabled(String provider) {
      updateWithNewLocation(null);
    }

    public void onProviderEnabled(String provider) {
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
  };

  private void updateWithNewLocation(Location location) {
    TextView myLocationText = (TextView) findViewById(R.id.myLocationText);

    String latLongString;
    String addressString = "No address found";

    if (location != null) {
      double lat = location.getLatitude();
      double lng = location.getLongitude();
      latLongString = "Lat:" + lat + "\nLong:" + lng;

      Geocoder gc = new Geocoder(this, Locale.getDefault());
      try {
        List<Address> addresses = gc.getFromLocation(lat, lng, 1);
        StringBuilder sb = new StringBuilder();
        if (addresses.size() > 0) {
          Address address = addresses.get(0);

          for (int i = 0; i < address.getMaxAddressLineIndex(); i++)
            sb.append(address.getAddressLine(i)).append("\n");

          sb.append(address.getLocality()).append("\n");
          sb.append(address.getPostalCode()).append("\n");
          sb.append(address.getCountryName());
        }
        addressString = sb.toString();
      } catch (IOException e) {
      }
    } else {
      latLongString = "No location found";
    }
    myLocationText.setText("Your Current Position is:\n" + latLongString
        + "\n" + addressString);
  }

}


//main.xml

<?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">
  <TextView  
    android:id="@+id/myLocationText"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
  />
</LinearLayout>

   

Private and debugging Binder APIs.

package com.android.internal.os;

import java.lang.ref.WeakReference;

import android.os.IBinder;
import android.os.SystemClock;
import android.util.EventLog;

/**
 * Private and debugging Binder APIs.
 * 
 * @see IBinder
 */
public class BinderInternal {
    static WeakReference<GcWatcher> mGcWatcher
            = new WeakReference<GcWatcher>(new GcWatcher());
    static long mLastGcTime;
    
    static final class GcWatcher {
        @Override
        protected void finalize() throws Throwable {
            handleGc();
            mLastGcTime = SystemClock.uptimeMillis();
            mGcWatcher = new WeakReference<GcWatcher>(new GcWatcher());
        }
    }
    
    /**
     * Add the calling thread to the IPC thread pool.  This function does
     * not return until the current process is exiting.
     */
    public static final native void joinThreadPool();
    
    /**
     * Return the system time (as reported by {@link SystemClock#uptimeMillis
     * SystemClock.uptimeMillis()}) that the last garbage collection occurred
     * in this process.  This is not for general application use, and the
     * meaning of "when a garbage collection occurred" will change as the
     * garbage collector evolves.
     * 
     * @return Returns the time as per {@link SystemClock#uptimeMillis
     * SystemClock.uptimeMillis()} of the last garbage collection.
     */
    public static long getLastGcTime() {
        return mLastGcTime;
    }

    /**
     * Return the global "context object" of the system.  This is usually
     * an implementation of IServiceManager, which you can use to find
     * other services.
     */
    public static final native IBinder getContextObject();
    
    static native final void handleGc();
    
    public static void forceGc(String reason) {
        EventLog.writeEvent(2741, reason);
        Runtime.getRuntime().gc();
    }
    
    static void forceBinderGc() {
        forceGc("Binder");
    }
}

Provider criteria

     


package app.test;

import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;

public class Test extends Activity {
  
  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);

    LocationManager locationManager;
    locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);

    String provider = locationManager.getBestProvider(criteria, true);

    Location location = locationManager.getLastKnownLocation(provider);

    updateWithNewLocation(location);

    locationManager.requestLocationUpdates(provider, 2000, 10, locationListener);
  }
  
  private final LocationListener locationListener = new LocationListener() {
    public void onLocationChanged(Location location) {
      updateWithNewLocation(location);
    }
     
    public void onProviderDisabled(String provider){
      updateWithNewLocation(null);
    }

    public void onProviderEnabled(String provider){}

    public void onStatusChanged(String provider, int status, Bundle extras) {}
  };
  
  private void updateWithNewLocation(Location location) {
    TextView myLocationText = (TextView)findViewById(R.id.myLocationText);
    
    String latLongString;
     
    if (location != null) {
      double lat = location.getLatitude();
      double lng = location.getLongitude();
      latLongString = "Lat:" + lat + "\nLong:" + lng;
    } else {
      latLongString = "No location found"; 
    }
    
    myLocationText.setText("Your Current Position is:\n" + latLongString);  
  }
  
}
//main.xml

<?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">
  <TextView  
    android:id="@+id/myLocationText"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
  />
</LinearLayout>

Get Distance between two GeoPoint

     

package test.easytask.geo;

import android.location.Location;

import com.google.android.maps.GeoPoint;

public class GeoUtil {
  public static double getDistance(GeoPoint pointStart, GeoPoint pointEnd) {
    final double DEG_RATE = 1E6;

    double startLatitude = pointStart.getLatitudeE6() / DEG_RATE;
    double startLongitude= pointStart.getLongitudeE6() / DEG_RATE;
    double endLatitude = pointEnd.getLatitudeE6() / DEG_RATE;
    double endLongitude= pointEnd.getLongitudeE6() / DEG_RATE;
    float[] result = new float[1];
    Location.distanceBetween(startLatitude, startLongitude, endLatitude, endLongitude, result);

    return result[0];

  }
}

latitude longitude math

package com.google.android.radar;

import com.google.android.maps.GeoPoint;

/**
 * Library for some use useful latitude/longitude math
 */
public class GeoUtils {
    private static int EARTH_RADIUS_KM = 6371;

    public static int MILLION = 1000000;

    /**
     * Computes the distance in kilometers between two points on Earth.
     * 
     * @param lat1 Latitude of the first point
     * @param lon1 Longitude of the first point
     * @param lat2 Latitude of the second point
     * @param lon2 Longitude of the second point
     * @return Distance between the two points in kilometers.
     */
    public static double distanceKm(double lat1, double lon1, double lat2, double lon2) {
        double lat1Rad = Math.toRadians(lat1);
        double lat2Rad = Math.toRadians(lat2);
        double deltaLonRad = Math.toRadians(lon2 - lon1);
        
        return Math.acos(Math.sin(lat1Rad) * Math.sin(lat2Rad) + Math.cos(lat1Rad) * Math.cos(lat2Rad)
                * Math.cos(deltaLonRad))
                * EARTH_RADIUS_KM;
    }
    
    /**
     * Computes the distance in kilometers between two points on Earth.
     * 
     * @param p1 First point
     * @param p2 Second point
     * @return Distance between the two points in kilometers.
     */
    public static double distanceKm(GeoPoint p1, GeoPoint p2) {
        double lat1 = p1.getLatitudeE6() / (double)MILLION;
        double lon1 = p1.getLongitudeE6() / (double)MILLION;
        double lat2 = p2.getLatitudeE6() / (double)MILLION;
        double lon2 = p2.getLongitudeE6() / (double)MILLION;

        return distanceKm(lat1, lon1, lat2, lon2);
    }
    
    /**
     * Computes the bearing in degrees between two points on Earth.
     * 
     * @param p1 First point
     * @param p2 Second point
     * @return Bearing between the two points in degrees. A value of 0 means due
     *         north.
     */
    public static double bearing(GeoPoint p1, GeoPoint p2) {
        double lat1 = p1.getLatitudeE6() / (double) MILLION;
        double lon1 = p1.getLongitudeE6() / (double) MILLION;
        double lat2 = p2.getLatitudeE6() / (double) MILLION;
        double lon2 = p2.getLongitudeE6() / (double) MILLION;

        return bearing(lat1, lon1, lat2, lon2);
    }
    
    /**
     * Computes the bearing in degrees between two points on Earth.
     * 
     * @param lat1 Latitude of the first point
     * @param lon1 Longitude of the first point
     * @param lat2 Latitude of the second point
     * @param lon2 Longitude of the second point
     * @return Bearing between the two points in degrees. A value of 0 means due
     *         north.
     */
    public static double bearing(double lat1, double lon1, double lat2, double lon2) {
        double lat1Rad = Math.toRadians(lat1);
        double lat2Rad = Math.toRadians(lat2);
        double deltaLonRad = Math.toRadians(lon2 - lon1);

        double y = Math.sin(deltaLonRad) * Math.cos(lat2Rad);
        double x = Math.cos(lat1Rad) * Math.sin(lat2Rad) - Math.sin(lat1Rad) * Math.cos(lat2Rad)
                * Math.cos(deltaLonRad);
        return radToBearing(Math.atan2(y, x));
    }
    
    /**
     * Converts an angle in radians to degrees
     */
    public static double radToBearing(double rad) {
        return (Math.toDegrees(rad) + 360) % 360;
    }
}

Location Update Demo Activity

     
package app.test;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.Toast;

public class Test extends Activity
{
  LocationManager locMgr = null;
  LocationListener locListener = null;
  
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        locMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        locListener = new LocationListener()
        {
            public void  onLocationChanged(Location location)
            {
                if (location != null)
                {
                    Toast.makeText(getBaseContext(),
                        "New location latitude [" + 
                        location.getLatitude() +
                        "] longitude [" + 
                        location.getLongitude()+"]",
                        Toast.LENGTH_SHORT).show();
                }
            }

            public void  onProviderDisabled(String provider)
            {
            }

            public void  onProviderEnabled(String provider)
            {
            }

            public void  onStatusChanged(String provider, 
                            int status, Bundle extras)
            {
            }
        };
    }

    @Override
    public void onResume() {
      super.onResume();

        locMgr.requestLocationUpdates(
            LocationManager.GPS_PROVIDER,
            0,      // minTime in ms
            0,      // minDistance in meters
            locListener);
    }

    @Override
    public void onPause() {
      super.onPause();
      locMgr.removeUpdates(locListener);
    }
}

Using Google Map

   
//AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.examples.mapper"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="3" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MyActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <uses-library android:name="com.google.android.maps"></uses-library>

    </application>
</manifest>

//main.xml

<?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">
  <TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:text="Map Of Your Location"
  />
  <com.google.android.maps.MapView
    android:id="@+id/map"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:enabled="true"
    android:clickable="true"
    android:apiKey="YOUR_API_KEY_HERE"
  />
</LinearLayout>

package app.test;

import android.os.Bundle;

import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

public class MyActivity extends MapActivity {

    MapView map;
    MapController controller;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        map = (MapView)findViewById(R.id.map);
        controller = map.getController();
        
        LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        Location location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        int lat, lng;
        if(location != null) {
            //Convert to microdegrees
            lat = (int)(location.getLatitude() * 1000000);
            lng = (int)(location.getLongitude() * 1000000);
        } else {
            //Default to Google HQ
            lat = 37427222;
            lng = -122099167;
        }
        GeoPoint mapCenter = new GeoPoint(lat,lng);
        controller.setCenter(mapCenter);
        controller.setZoom(15);
    }
    
    //Required abstract method, return false
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
}

   

Street view map

   

package app.test;

import android.os.Bundle;
import android.view.View;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

class ClickReceiver extends Overlay{
  private static final String TAG = "ClickReceiver";
  private Context mContext;

  public ClickReceiver(Context context) {
        mContext = context;
  }
  
  @Override
  public boolean onTap(GeoPoint p, MapView mapView) {
    Log.v(TAG, "Received a click at this point: " + p);
    if(mapView.isStreetView()) {
            Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse
            ("google.streetview:cbll=" +
            (float)p.getLatitudeE6() / 1000000f +
            "," + (float)p.getLongitudeE6() / 1000000f
              +"&cbp=1,180,,0,1.0"
                ));
        mContext.startActivity(myIntent);
        return true;
    }
      return false;
  }
}

public class MainActivity extends MapActivity
{
    private MapView mapView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mapView = (MapView)findViewById(R.id.mapview);
        ClickReceiver clickRecvr = new ClickReceiver(this);
        mapView.getOverlays().add(clickRecvr);
        mapView.invalidate();
    }

    public void myClickHandler(View target) {
        switch(target.getId()) {
        case R.id.zoomin:
          mapView.getController().zoomIn();
          break;
        case R.id.zoomout:
          mapView.getController().zoomOut();
          break;
        case R.id.sat:
          mapView.setSatellite(true);
          break;
        case R.id.street:
          mapView.setStreetView(true);
          break;
        case R.id.traffic:
          mapView.setTraffic(true);
          break;
        case R.id.normal:
          mapView.setSatellite(false);
          mapView.setStreetView(false);
          mapView.setTraffic(false);
          break;
        }
        mapView.postInvalidateDelayed(2000);
    }
    @Override
    protected boolean isLocationDisplayed() {
        return false;
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
}

//main.xml

<?xml version="1.0" encoding="utf-8"?>
  <!-- This file is /res/layout/mapview.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" android:layout_width="fill_parent"
  android:layout_height="fill_parent">

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <Button android:id="@+id/zoomin" android:layout_width="wrap_content"
      android:layout_height="wrap_content" android:text="+"
      android:onClick="myClickHandler" android:padding="12px" />

    <Button android:id="@+id/zoomout" android:layout_width="wrap_content"
      android:layout_height="wrap_content" android:text="-"
      android:onClick="myClickHandler" android:padding="12px" />

    <Button android:id="@+id/sat" android:layout_width="wrap_content"
      android:layout_height="wrap_content" android:text="Satellite"
      android:onClick="myClickHandler" android:padding="8px" />

    <Button android:id="@+id/street" android:layout_width="wrap_content"
      android:layout_height="wrap_content" android:text="Street"
      android:onClick="myClickHandler" android:padding="8px" />

    <Button android:id="@+id/traffic" android:layout_width="wrap_content"
      android:layout_height="wrap_content" android:text="Traffic"
      android:onClick="myClickHandler" android:padding="8px" />

    <Button android:id="@+id/normal" android:layout_width="wrap_content"
      android:layout_height="wrap_content" android:text="Normal"
      android:onClick="myClickHandler" android:padding="8px" />

  </LinearLayout>

  <com.google.android.maps.MapView
    android:id="@+id/mapview" android:layout_width="fill_parent"
    android:layout_height="wrap_content" android:clickable="true"
    android:apiKey="YourKey" />

</LinearLayout>

Street view map pinch zoom

   


package app.test;

import android.os.Bundle;
import android.view.View;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

 class ClickReceiver extends Overlay {
  private static final float ZOOMJUMP = 75f;
  private Context mContext;
  private boolean inZoomMode = false;
  private boolean ignoreLastFinger = false;
  private float mOrigSeparation;

  public ClickReceiver(Context context) {
        mContext = context;
  }

  @Override
  public boolean onTap(GeoPoint p, MapView mapView) {
    if(mapView.isStreetView()) {
            Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse
            ("google.streetview:cbll=" +
            (float)p.getLatitudeE6() / 1000000f +
            "," + (float)p.getLongitudeE6() / 1000000f
              +"&cbp=1,180,,0,1.0"
                ));
        mContext.startActivity(myIntent);
        return true;
    }
      return false;
  }
  
  public boolean onTouchEvent(MotionEvent e, MapView mapView) {
      int action = e.getAction() & MotionEvent.ACTION_MASK;

      if(e.getPointerCount() == 2) {
          inZoomMode = true;
        }
        else {
          inZoomMode = false;
        }
        
        if(inZoomMode) {
          switch(action) {
          case MotionEvent.ACTION_POINTER_DOWN:
            mOrigSeparation = calculateSeparation(e);
            break;
          case MotionEvent.ACTION_POINTER_UP:
            ignoreLastFinger  = true;
            break;
          case MotionEvent.ACTION_MOVE:
            float newSeparation = calculateSeparation(e);
            if(newSeparation - mOrigSeparation > ZOOMJUMP) {
              mapView.getController().zoomIn();
              mOrigSeparation = newSeparation;
            }
            else if (mOrigSeparation - newSeparation > ZOOMJUMP) {
              mapView.getController().zoomOut();
              mOrigSeparation = newSeparation;
            }
            break;
          }
          return true;
        }
        if(ignoreLastFinger) {
            if(action == MotionEvent.ACTION_UP)
              ignoreLastFinger = false;
          return true;
        }
    return super.onTouchEvent(e, mapView);
  }
  private float calculateSeparation(MotionEvent e) {
    float x = e.getX(0) - e.getX(1);
    float y = e.getY(0) - e.getY(1);
    return FloatMath.sqrt(x * x + y * y);
  }
}

public class MainActivity extends MapActivity
{
  private MapView mapView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mapView = (MapView)findViewById(R.id.mapview);

        ClickReceiver clickRecvr = new ClickReceiver(this);
        mapView.getOverlays().add(clickRecvr);
        mapView.invalidate();
    }

    public void myClickHandler(View target) {
        switch(target.getId()) {
        case R.id.zoomin:
          mapView.getController().zoomIn();
          break;
        case R.id.zoomout:
          mapView.getController().zoomOut();
          break;
        case R.id.sat:
          mapView.setSatellite(true);
          break;
        case R.id.street:
          mapView.setStreetView(true);
          break;
        case R.id.traffic:
          mapView.setTraffic(true);
          break;
        case R.id.normal:
          mapView.setSatellite(false);
          mapView.setStreetView(false);
          mapView.setTraffic(false);
          break;
        }
        mapView.postInvalidateDelayed(2000);
    }

    @Override
    protected boolean isLocationDisplayed() {
        return false;
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
}
<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/layout/mapview.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="fill_parent"
android:layout_height="wrap_content">

<Button android:id="@+id/zoomin" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:text="+"
  android:onClick="myClickHandler" android:padding="12px" />

<Button android:id="@+id/zoomout" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:text="-"
  android:onClick="myClickHandler" android:padding="12px" />

<Button android:id="@+id/sat" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:text="Satellite"
  android:onClick="myClickHandler" android:padding="8px" />

<Button android:id="@+id/street" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:text="Street"
  android:onClick="myClickHandler" android:padding="8px" />

<Button android:id="@+id/traffic" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:text="Traffic"
  android:onClick="myClickHandler" android:padding="8px" />

<Button android:id="@+id/normal" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:text="Normal"
  android:onClick="myClickHandler" android:padding="8px" />

</LinearLayout>

<com.google.android.maps.MapView
android:id="@+id/mapview" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:clickable="true"
android:apiKey="YourKey" />

</LinearLayout>

extends ItemizedOverlay

   



package app.test;

import java.util.ArrayList;
import java.util.Iterator;

import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

public class MappingOverlayActivity extends MapActivity {
    private MapView mapView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.mapview);

        mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);

        Drawable marker=getResources().getDrawable(R.drawable.mapmarker); 
        marker.setBounds((int)(-marker.getIntrinsicWidth()/2),
            -marker.getIntrinsicHeight(),
            (int) (marker.getIntrinsicWidth()/2), 
            0);
        
        InterestingLocations funPlaces = new InterestingLocations(marker);
        mapView.getOverlays().add(funPlaces);
        
        GeoPoint pt = funPlaces.getCenterPt();
        int latSpan = funPlaces.getLatSpanE6();
        int lonSpan = funPlaces.getLonSpanE6();
        Log.v("Overlays", "Lat span is " + latSpan);
        Log.v("Overlays", "Lon span is " + lonSpan);

        MapController mc = mapView.getController();
        mc.setCenter(pt);
        mc.zoomToSpan((int)(latSpan*1.5), (int)(lonSpan*1.5));
    }

    @Override
    protected boolean isLocationDisplayed() {
        return false;
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

    class InterestingLocations extends ItemizedOverlay {
        private ArrayList<OverlayItem> locations = new ArrayList<OverlayItem>();
        private GeoPoint center = null;

        public InterestingLocations(Drawable marker)
        {
            super(marker);
            GeoPoint a = new GeoPoint((int)(38.418971*1000000),(int)(-11.581436*1000000));
            GeoPoint b = new GeoPoint((int)(38.410067*1000000),(int)(-11.583699*1000000));

            locations.add(new OverlayItem(a,"A", "A"));
            locations.add(new OverlayItem(b,"B", "B"));

            populate();
        }
        public GeoPoint getCenterPt() {
            if(center == null) {
                int northEdge = -90000000;   // i.e., -90E6 microdegrees
                int southEdge = 90000000;
                int eastEdge = -180000000;
                int westEdge = 180000000;
                Iterator<OverlayItem> iter = locations.iterator();
                while(iter.hasNext()) {
                    GeoPoint pt = iter.next().getPoint();
                    if(pt.getLatitudeE6() > northEdge) northEdge = pt.getLatitudeE6();
                    if(pt.getLatitudeE6() < southEdge) southEdge = pt.getLatitudeE6();
                    if(pt.getLongitudeE6() > eastEdge) eastEdge = pt.getLongitudeE6();
                    if(pt.getLongitudeE6() < westEdge) westEdge = pt.getLongitudeE6();
                }
                center = new GeoPoint((int)((northEdge + southEdge)/2),
                        (int)((westEdge + eastEdge)/2));
            }
            return center;
        }

        @Override
        public void draw(Canvas canvas, MapView mapview, boolean shadow) {
          // Here is where we can eliminate shadows by setting to false
          super.draw(canvas, mapview, shadow);
        }

        @Override
        protected OverlayItem createItem(int i) {
            return locations.get(i);
        }

        @Override
        public int size() {
            return locations.size();
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<!-- This file is /res/layout/mapview.xml -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="fill_parent"
        android:layout_height="fill_parent">

     <com.google.android.maps.MapView android:id="@+id/mapview"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent"
             android:clickable="true"
             android:apiKey="yourMapKey"
             />
</RelativeLayout>

My Position Overlay

   
package app.test;

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;


import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.location.Location;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

class MyPositionOverlay extends Overlay {
  public Location getLocation() {
    return location;
  }
  public void setLocation(Location location) {
    this.location = location;
  }  
    Location location;
    private final int mRadius = 5;
  @Override
  public void draw(Canvas canvas, MapView mapView, boolean shadow) {
    Projection projection = mapView.getProjection();

    if (shadow == false) {
      // Get the current location
      Double latitude = location.getLatitude()*1E6;
      Double longitude = location.getLongitude()*1E6;
      GeoPoint geoPoint = new GeoPoint(latitude.intValue(),longitude.intValue());

      // Convert the location to screen pixels 
      Point point = new Point();
      projection.toPixels(geoPoint, point);

      RectF oval = new RectF(point.x - mRadius, point.y - mRadius, 
                             point.x + mRadius, point.y + mRadius);

      // Setup the paint
      Paint paint = new Paint();
      paint.setARGB(255, 255, 255, 255);
      paint.setAntiAlias(true);
      paint.setFakeBoldText(true);

      Paint backPaint = new Paint();
      backPaint.setARGB(180, 50, 50, 50);
      backPaint.setAntiAlias(true);

      RectF backRect = new RectF(point.x + 2 + mRadius, point.y - 3*mRadius,
                                 point.x + 65, point.y + mRadius);

      // Draw the marker
      canvas.drawOval(oval, paint);
      canvas.drawRoundRect(backRect, 5, 5, backPaint);
      canvas.drawText("Here I Am", point.x + 2*mRadius, point.y, paint);
    }
    super.draw(canvas, mapView, shadow);
  }
    
  @Override
  public boolean onTap(GeoPoint point, MapView mapView) {
    return false;
  }
}
public class Test extends MapActivity {

  MapController mapController;
  MyPositionOverlay positionOverlay;
   
  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);

    MapView myMapView = (MapView)findViewById(R.id.myMapView);
    mapController = myMapView.getController();
    
    // Configure the map display options
    myMapView.setSatellite(true);
    myMapView.setStreetView(true);
    
    // Zoom in
    mapController.setZoom(17);
    
    // Add the MyPositionOverlay
    positionOverlay = new MyPositionOverlay();
    List<Overlay> overlays = myMapView.getOverlays();
    overlays.add(positionOverlay);

    LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    String provider = locationManager.getBestProvider(criteria, true);

    Location location = locationManager.getLastKnownLocation(provider);

    updateWithNewLocation(location);

    locationManager.requestLocationUpdates(provider, 2000, 10, locationListener);
  }

  private final LocationListener locationListener = new LocationListener() {
    public void onLocationChanged(Location location) {
      updateWithNewLocation(location);
    }
   
    public void onProviderDisabled(String provider){
      updateWithNewLocation(null);
    }

    public void onProviderEnabled(String provider) {}

    public void onStatusChanged(String provider, int status, Bundle extras) {}
  };
  
  /** Update the map with a new location */
  private void updateWithNewLocation(Location location) {
    TextView myLocationText = (TextView)findViewById(R.id.myLocationText);

    String latLongString;
    String addressString = "No address found";

    if (location != null) {
      positionOverlay.setLocation(location);

      Double geoLat = location.getLatitude()*1E6;
      Double geoLng = location.getLongitude()*1E6;
      GeoPoint point = new GeoPoint(geoLat.intValue(), geoLng.intValue());

      mapController.animateTo(point);

      double lat = location.getLatitude();
      double lng = location.getLongitude();
      latLongString = "Lat:" + lat + "\nLong:" + lng;

      Geocoder gc = new Geocoder(this, Locale.getDefault());
      try {
        List<Address> addresses = gc.getFromLocation(lat, lng, 1);
        StringBuilder sb = new StringBuilder();
        if (addresses.size() > 0) {
          Address address = addresses.get(0);

          for (int i = 0; i < address.getMaxAddressLineIndex(); i++)
            sb.append(address.getAddressLine(i)).append("\n");

          sb.append(address.getLocality()).append("\n");
          sb.append(address.getPostalCode()).append("\n");
          sb.append(address.getCountryName());
        }
        addressString = sb.toString();
      } catch (IOException e) {}
    } else {
      latLongString = "No location found";
    }
    myLocationText.setText("Your Current Position is:\n" + latLongString + "\n" + addressString);
  }

  @Override
  protected boolean isRouteDisplayed() {
    return false;
  }
}
//layout/main.xml

<?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">
  <TextView  
    android:id="@+id/myLocationText"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
  />
  <com.google.android.maps.MapView
    android:id="@+id/myMapView"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:enabled="true"
    android:clickable="true"
    android:apiKey="IsEmptyBsluf"
  />
</LinearLayout>
An example of how to use the NFC foreground dispatch APIs.
package com.example.android.apis.nfc;

import com.example.android.apis.R;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.nfc.NfcAdapter;
import android.nfc.tech.NfcF;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

/**
 * An example of how to use the NFC foreground dispatch APIs. This will intercept any MIME data
 * based NDEF dispatch as well as all dispatched for NfcF tags.
 */
public class Test extends Activity {
    private NfcAdapter mAdapter;
    private PendingIntent mPendingIntent;
    private IntentFilter[] mFilters;
    private String[][] mTechLists;
    private TextView mText;
    private int mCount = 0;

    @Override
    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        setContentView(R.layout.main);
        mText = (TextView) findViewById(R.id.text);
        mText.setText("Scan a tag");

        mAdapter = NfcAdapter.getDefaultAdapter(this);

        // Create a generic PendingIntent that will be deliver to this activity. The NFC stack
        // will fill in the intent with the details of the discovered tag before delivering to
        // this activity.
        mPendingIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

        // Setup an intent filter for all MIME based dispatches
        IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        try {
            ndef.addDataType("*/*");
        } catch (MalformedMimeTypeException e) {
            throw new RuntimeException("fail", e);
        }
        mFilters = new IntentFilter[] {
                ndef,
        };

        // Setup a tech list for all NfcF tags
        mTechLists = new String[][] { new String[] { NfcF.class.getName() } };
    }

    @Override
    public void onResume() {
        super.onResume();
        mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists);
    }

    @Override
    public void onNewIntent(Intent intent) {
        Log.i("Foreground dispatch", "Discovered tag with intent: " + intent);
        mText.setText("Discovered tag " + ++mCount + " with intent: " + intent);
    }

    @Override
    public void onPause() {
        super.onPause();
        //mAdapter.disableForegroundDispatch(this);
        throw new RuntimeException("onPause not implemented to fix build");
    }
}
//main.xml

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


<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:gravity="center_vertical|center_horizontal"
    android:textAppearance="?android:attr/textAppearanceMedium"
/>
An example of how to use the NFC foreground NDEF push APIs.
package com.example.android.apis.nfc;

import com.example.android.apis.R;

import android.app.Activity;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.widget.TextView;

import java.nio.charset.Charset;
import java.util.Locale;

/**
 * An example of how to use the NFC foreground NDEF push APIs.
 */
public class ForegroundNdefPush extends Activity {
    private NfcAdapter mAdapter;
    private TextView mText;
    private NdefMessage mMessage;

    public static NdefRecord newTextRecord(String text, Locale locale, boolean encodeInUtf8) {
        byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));

        Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
        byte[] textBytes = text.getBytes(utfEncoding);

        int utfBit = encodeInUtf8 ? 0 : (1 << 7);
        char status = (char) (utfBit + langBytes.length);

        byte[] data = new byte[1 + langBytes.length + textBytes.length]; 
        data[0] = (byte) status;
        System.arraycopy(langBytes, 0, data, 1, langBytes.length);
        System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);

        return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
    }

    @Override
    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        mAdapter = NfcAdapter.getDefaultAdapter(this);

        setContentView(R.layout.main);
        mText = (TextView) findViewById(R.id.text);
        if (mAdapter != null) {
            mText.setText("Tap another Android phone with NFC to push 'NDEF Push Sample'");
        } else {
            mText.setText("This phone is not NFC enabled.");
        }

        // Create an NDEF message with some sample text
        mMessage = new NdefMessage(
                new NdefRecord[] { newTextRecord("NDEF Push Sample", Locale.ENGLISH, true)});        
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mAdapter != null) mAdapter.enableForegroundNdefPush(this, mMessage);
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mAdapter != null) mAdapter.disableForegroundNdefPush(this);
    }
}

//main.xml

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


<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:gravity="center_vertical|center_horizontal"
    android:textAppearance="?android:attr/textAppearanceMedium"
/>
NfcAdapter.ACTION_TECH_DISCOVERED
package com.example.android.apis.nfc;

import com.example.android.apis.R;

import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.widget.TextView;

public class TechFilter extends Activity {
    private TextView mText;
    private int mCount = 0;

    @Override
    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        setContentView(R.layout.main);
        mText = (TextView) findViewById(R.id.text);

        Intent intent = getIntent();
        String action = intent.getAction();
        if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
            mText.setText("Discovered tag " + ++mCount + " with intent: " + intent);
        } else {
            mText.setText("Scan a tag");
        }
    }

    @Override
    public void onNewIntent(Intent intent) {
        mText.setText("Discovered tag " + ++mCount + " with intent: " + intent);
    }
}

//main.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:gravity="center_vertical|center_horizontal"
    android:textAppearance="?android:attr/textAppearanceMedium"
/>

Responsible for wrapping calls to PackageManager to ensure that they always complete without throwing RuntimeExceptions.

    
//package org.acra.util;

//import static org.acra.ACRA.LOG_TAG;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;


public final class PackageManagerWrapper {

    private final Context context;

    public PackageManagerWrapper(Context context) {
        this.context = context;
    }

    /**
     * @param permission    Manifest.permission to check whether it has been granted.
     * @return true if the permission has been granted to the app, false if it hasn't been granted or the PackageManager could not be contacted.
     */
    public boolean hasPermission(String permission) {
        final PackageManager pm = context.getPackageManager();
        if (pm == null) {
            return false;
        }

        try {
            return pm.checkPermission(permission, context.getPackageName()) == PackageManager.PERMISSION_GRANTED;
        } catch (RuntimeException e) {
            // To catch RuntimeException("Package manager has died") that can occur on some version of Android,
            // when the remote PackageManager is unavailable. I suspect this sometimes occurs when the App is being reinstalled.
            return false;
        }
    }

    /**
     * @return PackageInfo for the current application or null if the PackageManager could not be contacted.
     */
    public PackageInfo getPackageInfo() {
        final PackageManager pm = context.getPackageManager();
        if (pm == null) {
            return null;
        }

        try {
            return pm.getPackageInfo(context.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
          //  Log.v(LOG_TAG, "Failed to find PackageInfo for current App : " + context.getPackageName());
            return null;
        } catch (RuntimeException e) {
            // To catch RuntimeException("Package manager has died") that can occur on some version of Android,
            // when the remote PackageManager is unavailable. I suspect this sometimes occurs when the App is being reinstalled.
            return null;
        }
    }
}

Is package installed

    
//package com.chinaandroiddev.adfreedetector;

import java.net.InetAddress;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.ConnectivityManager;


public class Detector {

    /*
     * com.bigtincan.android.adfree/.FreeMe
     */
    private static final String ADFREE_PACKAGE_NAME = "com.bigtincan.android.adfree";
    private static final String ADFREE_MAIN_ACTIVITY = "com.bigtincan.android.adfree.FreeMe";
    
    public static boolean isAdFreeInstalled(Context context) {
        PackageManager pm = context.getPackageManager();        
        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        mainIntent.setClassName(ADFREE_PACKAGE_NAME, ADFREE_MAIN_ACTIVITY);
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        List<ResolveInfo> apps = pm.queryIntentActivities(mainIntent, 0);
        if (apps.size() == 1) {
            return true;
        } else {
            return false;
        }
    }
    
    public static boolean isHostAltered(Context context, String hostname) {
        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm.getActiveNetworkInfo().isConnected()) {
            try {
                /*
                 * 127.0.0.1 analytics.admob.com
                 * 127.0.0.1 analytics.live.com
127.0.0.1 analytics.msn.com
127.0.0.1 c.googleanalitics.net
127.0.0.1 feedads.googleadservices.com
127.0.0.1 googleads.g.doubleclick.net
127.0.0.1 googleads2.g.doubleclick.net
                 */
                InetAddress addr = null;
                if (hostname != null && hostname.length() > 0) {
                    addr = InetAddress.getByName(hostname);
                } else {
                    addr = InetAddress.getByName("googleads.g.doubleclick.net");
                }
                if (addr.getHostAddress().equals("127.0.0.1")) {
                    return true;
                } else {
                    return false;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        } else { // no network connection, we dont care
            return false;
        }
    }
}

Check System Feature

    
//package org.anddev.andengine.util;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Scanner;
import java.util.regex.MatchResult;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;

/**
 * (c) 2010 Nicolas Gramlich 
 * (c) 2011 Zynga Inc.
 * 
 * @author Nicolas Gramlich
 * @since 15:50:31 - 14.07.2010
 */
class SystemUtils {
  private static final String BOGOMIPS_PATTERN = "BogoMIPS[\\s]*:[\\s]*(\\d+\\.\\d+)[\\s]*\n";
  private static final String MEMTOTAL_PATTERN = "MemTotal[\\s]*:[\\s]*(\\d+)[\\s]*kB\n";
  private static final String MEMFREE_PATTERN = "MemFree[\\s]*:[\\s]*(\\d+)[\\s]*kB\n";

  public static boolean hasSystemFeature(final Context pContext, final String pFeature) {
    try {
      final Method PackageManager_hasSystemFeatures = PackageManager.class.getMethod("hasSystemFeature", new Class[] { String.class });
      return (PackageManager_hasSystemFeatures == null) ? false : (Boolean) PackageManager_hasSystemFeatures.invoke(pContext.getPackageManager(), pFeature);
    } catch (final Throwable t) {
      return false;
    }
  }
}

show Installed App Details

//package com.googlecode.securitywatch;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.net.Uri;
import android.os.Build;

/**
 * Utility class
 */
class Utils {
    private static final String SCHEME = "package";

    private static final String APP_PKG_NAME_21 = "com.android.settings.ApplicationPkgName";

    private static final String APP_PKG_NAME_22 = "pkg";

    private static final String APP_DETAILS_PACKAGE_NAME = "com.android.settings";

    private static final String APP_DETAILS_CLASS_NAME = "com.android.settings.InstalledAppDetails";

    public static void showInstalledAppDetails(Context context, String packageName) {
        Intent intent = new Intent();
        final int apiLevel = Build.VERSION.SDK_INT;
        if (apiLevel >= 9) { // above 2.3
            intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
            Uri uri = Uri.fromParts(SCHEME, packageName, null);
            intent.setData(uri);
        } else { // below 2.3
            final String appPkgName = (apiLevel == 8 ? APP_PKG_NAME_22
                    : APP_PKG_NAME_21);
            intent.setAction(Intent.ACTION_VIEW);
            intent.setClassName(APP_DETAILS_PACKAGE_NAME, APP_DETAILS_CLASS_NAME);
            intent.putExtra(appPkgName, packageName);
        }
        context.startActivity(intent);
    }

}

get Permissions For Package

//package com.mojodroid.permissionwatchdog;

import java.util.ArrayList;

import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.Log;

class Utils
{
    private final static String TAG = "WatchdogUtils";

    public static final Iterable<PermissionInfo> getPermissionsForPackage(PackageManager pm, String packageName)
    {
        ArrayList<PermissionInfo> retval = new ArrayList<PermissionInfo>();
        try
        {
            PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);

            if (packageInfo.requestedPermissions != null)
            {
                for (String permName : packageInfo.requestedPermissions)
                {
                    try
                    {
                        retval.add(pm.getPermissionInfo(permName, PackageManager.GET_META_DATA));
                    }
                    catch (NameNotFoundException e)
                    {
                        // Not an official android permission... no big deal
                    }
                }
            }
        }
        catch (NameNotFoundException e)
        {
            Log.e(TAG, "That's odd package: " + packageName + " should be here but isn't");
        }
        return retval;
    }

    public static final boolean getFlaggedDangerous(SharedPreferences prefs, PermissionInfo permInfo)
    {
        // User wants to override defaults
        if (prefs.getBoolean("Prefs.PREFS_MANUAL_DANGER", false))
            return prefs.getBoolean(permInfo.name, (permInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS));
        else
            return (permInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS);
    }
}
A custom preference type. The preference counts the number of clicks it has received and stores/retrieves it from the storage.
package com.example.android.apis.preference;

import com.example.android.apis.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

/**
 * This is an example of a custom preference type. The preference counts the
 * number of clicks it has received and stores/retrieves it from the storage.
 */
public class MyPreference extends Preference {
    private int mClickCounter;

    // This is the constructor called by the inflater
    public MyPreference(Context context, AttributeSet attrs) {
        super(context, attrs);

        setWidgetLayoutResource(R.layout.preference_widget_mypreference);
    }

    @Override
    protected void onBindView(View view) {
        super.onBindView(view);

        // Set our custom views inside the layout
        final TextView myTextView = (TextView) view.findViewById(R.id.mypreference_widget);
        if (myTextView != null) {
            myTextView.setText(String.valueOf(mClickCounter));
        }
    }

    @Override
    protected void onClick() {
        int newValue = mClickCounter + 1;
        // Give the client a chance to ignore this change if they deem it
        // invalid
        if (!callChangeListener(newValue)) {
            // They don't want the value to be set
            return;
        }

        // Increment counter
        mClickCounter = newValue;

        // Save to persistent storage (this method will make sure this
        // preference should be persistent, along with other useful checks)
        persistInt(mClickCounter);

        // Data has changed, notify so UI can be refreshed!
        notifyChanged();
    }

    @Override
    protected Object onGetDefaultValue(TypedArray a, int index) {
        // This preference type's value type is Integer, so we read the default
        // value from the attributes as an Integer.
        return a.getInteger(index, 0);
    }

    @Override
    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
        if (restoreValue) {
            // Restore state
            mClickCounter = getPersistedInt(mClickCounter);
        } else {
            // Set state
            int value = (Integer) defaultValue;
            mClickCounter = value;
            persistInt(value);
        }
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        /*
         * Suppose a client uses this preference type without persisting. We
         * must save the instance state so it is able to, for example, survive
         * orientation changes.
         */

        final Parcelable superState = super.onSaveInstanceState();
        if (isPersistent()) {
            // No need to save instance state since it's persistent
            return superState;
        }

        // Save the instance state
        final SavedState myState = new SavedState(superState);
        myState.clickCounter = mClickCounter;
        return myState;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (!state.getClass().equals(SavedState.class)) {
            // Didn't save state for us in onSaveInstanceState
            super.onRestoreInstanceState(state);
            return;
        }

        // Restore the instance state
        SavedState myState = (SavedState) state;
        super.onRestoreInstanceState(myState.getSuperState());
        mClickCounter = myState.clickCounter;
        notifyChanged();
    }

    /**
     * SavedState, a subclass of {@link BaseSavedState}, will store the state
     * of MyPreference, a subclass of Preference.
     * <p>
     * It is important to always call through to super methods.
     */
    private static class SavedState extends BaseSavedState {
        int clickCounter;

        public SavedState(Parcel source) {
            super(source);

            // Restore the click counter
            clickCounter = source.readInt();
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);

            // Save the click counter
            dest.writeInt(clickCounter);
        }

        public SavedState(Parcelable superState) {
            super(superState);
        }

        public static final Parcelable.Creator<SavedState> CREATOR =
                new Parcelable.Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }

}


//layout/preference_widget_mypreference.xml

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

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mypreference_widget" 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:layout_marginRight="6sp"
    android:focusable="false"
    android:clickable="false" />
Preference Dependencies
package com.example.android.apis.preference;

import com.example.android.apis.R;

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class PreferenceDependencies extends PreferenceActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.preference_dependencies);
    }

}

//xml/preference_dependencies.xml



<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
        xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory
            android:title="@string/example_preference_dependency">
            
        <CheckBoxPreference
                android:key="wifi"
                android:title="@string/title_wifi" />
            
        <EditTextPreference
                android:layout="?android:attr/preferenceLayoutChild"
                android:title="@string/title_wifi_settings"
                android:dependency="wifi" />
            
    </PreferenceCategory>
                
</PreferenceScreen>

check Handset Locale

    
import java.util.Locale;

import android.content.Context;
import android.provider.Settings;
import android.telephony.TelephonyManager;

public class Utils {
  private static final String TAG = "Utils";

  public static Locale checkHandsetLocale(Context ctx) {
    boolean EMULATOR = false;

    // Disable this block to disable EMULATOR use of this app (enabling is
    // useful for testing)
    EMULATOR = (Settings.Secure.getString(ctx.getContentResolver(),
        android.provider.Settings.Secure.ANDROID_ID) == null);

    Locale locale = Locale.getDefault();
    String lo = locale.getCountry().toLowerCase();
    // Check country: show network country is not the same as locale country
    TelephonyManager mTelephonyMgr = (TelephonyManager) ctx
        .getSystemService(Context.TELEPHONY_SERVICE);
    String country = mTelephonyMgr.getNetworkCountryIso().toLowerCase();
    if (country.matches(lo) && !EMULATOR)
      return locale;
  }
}

get Unique ID from android.provider.Settings.Secure.ANDROID_ID

    
//package com.omareitti;

import java.util.List;
import java.util.UUID;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;

public class Utils {

    
    public static String getUniqueID(Context context) {
        final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

        final String tmDevice, tmSerial, tmPhone, androidId;
        tmDevice = "" + tm.getDeviceId();
        tmSerial = "" + tm.getSimSerialNumber();
        androidId = "" + android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);

        UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
        String deviceId = deviceUuid.toString();
        return deviceId;
    }



}

Send Message

    

import android.telephony.SmsManager;
 class Tools {
  public static void sendMsg(String tel, String s) {
    SmsManager smsManager = SmsManager.getDefault();
    smsManager.sendTextMessage(tel, null, s, null, null);
  }
}

Demonstrates text-to-speech (TTS)

package app.test;

import android.app.Activity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.util.Locale;
import java.util.Random;


public class Test extends Activity implements TextToSpeech.OnInitListener {

    private static final String TAG = "TextToSpeechDemo";

    private TextToSpeech mTts;
    private Button mAgainButton;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Initialize text-to-speech. This is an asynchronous operation.
        // The OnInitListener (second argument) is called after initialization completes.
        mTts = new TextToSpeech(this,
            this  // TextToSpeech.OnInitListener
            );

        // The button is disabled in the layout.
        // It will be enabled upon initialization of the TTS engine.
        mAgainButton = (Button) findViewById(R.id.again_button);

        mAgainButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                sayHello();
            }
        });
    }

    @Override
    public void onDestroy() {
        // Don't forget to shutdown!
        if (mTts != null) {
            mTts.stop();
            mTts.shutdown();
        }

        super.onDestroy();
    }

    // Implements TextToSpeech.OnInitListener.
    public void onInit(int status) {
        // status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR.
        if (status == TextToSpeech.SUCCESS) {
            // Set preferred language to US english.
            // Note that a language may not be available, and the result will indicate this.
            int result = mTts.setLanguage(Locale.US);
            // Try this someday for some interesting results.
            // int result mTts.setLanguage(Locale.FRANCE);
            if (result == TextToSpeech.LANG_MISSING_DATA ||
                result == TextToSpeech.LANG_NOT_SUPPORTED) {
               // Lanuage data is missing or the language is not supported.
                Log.e(TAG, "Language is not available.");
            } else {
                // Check the documentation for other possible result codes.
                // For example, the language may be available for the locale,
                // but not for the specified country and variant.

                // The TTS engine has been successfully initialized.
                // Allow the user to press the button for the app to speak again.
                mAgainButton.setEnabled(true);
                // Greet the user.
                sayHello();
            }
        } else {
            // Initialization failed.
            Log.e(TAG, "Could not initialize TextToSpeech.");
        }
    }

    private static final Random RANDOM = new Random();
    private static final String[] HELLOS = {
      "Hello",
      "Salutations",
      "Greetings",
      "Howdy",
      "What's crack-a-lackin?",
      "That explains the stench!"
    };

    private void sayHello() {
        // Select a random hello.
        int helloLength = HELLOS.length;
        String hello = HELLOS[RANDOM.nextInt(helloLength)];
        mTts.speak(hello,
            TextToSpeech.QUEUE_FLUSH,  // Drop all pending entries in the playback queue.
            null);
    }

}
//main.xml

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <Button android:id="@+id/again_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:enabled="false"
        android:text="again" />
</LinearLayout>

Text to speech demo

   

package app.test;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class Test extends Activity implements OnInitListener {
  private EditText words = null;
  private Button speakBtn = null;
    private static final int REQ_TTS_STATUS_CHECK = 0;
  private static final String TAG = "TTS Demo";
    private TextToSpeech mTts;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        words = (EditText)findViewById(R.id.wordsToSpeak);
        speakBtn = (Button)findViewById(R.id.speak);

        Intent checkIntent = new Intent();
        checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        startActivityForResult(checkIntent, REQ_TTS_STATUS_CHECK);
    }
    
    public void doSpeak(View view) {
    mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
  };
  
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQ_TTS_STATUS_CHECK) {
            switch (resultCode) {
            case TextToSpeech.Engine.CHECK_VOICE_DATA_PASS:
                mTts = new TextToSpeech(this, this);
                break;
            case TextToSpeech.Engine.CHECK_VOICE_DATA_BAD_DATA:
            case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_DATA:
            case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_VOLUME:
                Intent installIntent = new Intent();
                installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                startActivity(installIntent);
                break;
            case TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL:
            default:
                Log.e(TAG, "Got a failure.");
            }
        }
    }
  public void onInit(int status) {
    if( status == TextToSpeech.SUCCESS) {
      speakBtn.setEnabled(true);
    }
  }
  @Override
  public void onPause(){
    super.onPause();
    if( mTts != null)
      mTts.stop();
  }
  @Override
    public void onDestroy(){
        super.onDestroy();
        mTts.shutdown();
    }
}

//main.xml

<?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">

  <EditText android:id="@+id/wordsToSpeak"
    android:hint="Type words to speak here"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"/>

  <Button android:id="@+id/speak"
    android:text="Speak"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:onClick="doSpeak"
  android:enabled="false" />

</LinearLayout>

Check Text To Speech Engine Status

   
package app.test;

import java.util.HashMap;
import java.util.StringTokenizer;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class Test extends Activity implements OnInitListener, OnUtteranceCompletedListener {
  private EditText words = null;
  private Button speakBtn = null;
    private static final int REQ_TTS_STATUS_CHECK = 0;
  private static final String TAG = "TTS Demo";
    private TextToSpeech mTts;
    private int uttCount = 0;
    private int lastUtterance = -1;
  private HashMap<String, String> params = new HashMap<String, String>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        words = (EditText)findViewById(R.id.wordsToSpeak);
        speakBtn = (Button)findViewById(R.id.speak);
        Intent checkIntent = new Intent();
        checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        startActivityForResult(checkIntent, REQ_TTS_STATUS_CHECK);
    }
    
  public void doSpeak(View view) {
    StringTokenizer st = new StringTokenizer(words.getText().toString(),",.");
    while (st.hasMoreTokens()) {
        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,String.valueOf(uttCount++));
      mTts.speak(st.nextToken(), TextToSpeech.QUEUE_ADD, params);
       }
  }

  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQ_TTS_STATUS_CHECK) {
            switch (resultCode) {
            case TextToSpeech.Engine.CHECK_VOICE_DATA_PASS:
                mTts = new TextToSpeech(this, this);
                break;
            case TextToSpeech.Engine.CHECK_VOICE_DATA_BAD_DATA:
            case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_DATA:
            case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_VOLUME:
                Intent installIntent = new Intent();
                installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                startActivity(installIntent);
                break;
            case TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL:
            default:
                Log.e(TAG, "Got a failure. TTS not available");
            }
        }
    }

  public void onInit(int status) {
    if( status == TextToSpeech.SUCCESS) {
      speakBtn.setEnabled(true);
      mTts.setOnUtteranceCompletedListener(this);
    }
  }
  @Override
  public void onPause()
  {
    super.onPause();
    if( mTts != null)
      mTts.stop();
  }

  @Override
    public void onDestroy()
  {
        super.onDestroy();
        mTts.shutdown();
    }

  public void onUtteranceCompleted(String uttId) {
    lastUtterance = Integer.parseInt(uttId);
  }
}

//main.xml

<?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">

  <EditText android:id="@+id/wordsToSpeak"
    android:hint="Type words to speak here"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"/>

  <Button android:id="@+id/speak"
    android:text="Speak"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:onClick="doSpeak"
  android:enabled="false" />

</LinearLayout>

Handler different languages

   
package app.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.StringTokenizer;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class Test extends Activity implements OnInitListener, OnUtteranceCompletedListener {
  private EditText words = null;
  private Button speakBtn = null;
    private static final int REQ_TTS_STATUS_CHECK = 0;
  private static final String TAG = "TTS Demo";
    private TextToSpeech mTts;

    private int uttCount = 0;
    private int lastUtterance = -1;
  private HashMap<String, String> params = new HashMap<String, String>();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        words = (EditText)findViewById(R.id.wordsToSpeak);
        speakBtn = (Button)findViewById(R.id.speak);
        Intent checkIntent = new Intent();
        checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        startActivityForResult(checkIntent, REQ_TTS_STATUS_CHECK);
    }
  public void doSpeak(View view) {
    StringTokenizer st = new StringTokenizer(words.getText().toString(),",.");
    while (st.hasMoreTokens()) {
        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,
                    String.valueOf(uttCount++));
      mTts.speak(st.nextToken(), TextToSpeech.QUEUE_ADD, params);
       }
  }

  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQ_TTS_STATUS_CHECK) {
            switch (resultCode) {
            case TextToSpeech.Engine.CHECK_VOICE_DATA_PASS:
                mTts = new TextToSpeech(this, this);
                Log.v(TAG, "Pico is installed okay");
                break;
            case TextToSpeech.Engine.CHECK_VOICE_DATA_BAD_DATA:
            case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_DATA:
            case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_VOLUME:
                Intent installIntent = new Intent();
                installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                startActivity(installIntent);
                break;
            case TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL:
            default:
                Log.e(TAG, "Got a failure.");
            }
            ArrayList<String> available = data.getStringArrayListExtra("availableVoices");
            Log.v("languages count", String.valueOf(available.size()));
            Iterator<String> iter = available.iterator();
            while(iter.hasNext()) {
              String lang = iter.next();
              Locale locale = new Locale(lang);
                Log.v(TAG, "language: " + lang);
                Log.v(TAG, "language locale: " + locale.toString());
            }
            Locale[] locales = Locale.getAvailableLocales();
            Log.v(TAG, "available locales:");
            for(int i=0;i<locales.length;i++)
              Log.v(TAG, "locale: " + locales[i].getDisplayName());
            
            Locale defloc = Locale.getDefault();
            Log.v(TAG, "current locale: " + defloc.getDisplayName());
        }
    }

  public void onInit(int status) {
    if( status == TextToSpeech.SUCCESS) {
      speakBtn.setEnabled(true);
      Locale loc = mTts.getLanguage();
            Log.v(TAG, "default engine: " + mTts.getDefaultEngine());
            Log.v(TAG, "current language/locale: " + loc.getDisplayName());
            Log.v(TAG, "current ISO3 language: " + loc.getISO3Language());
            Log.v(TAG, "current ISO3 country: " + loc.getISO3Country());
            Log.v(TAG, "current language: " + loc.getLanguage());
            Log.v(TAG, "current country: " + loc.getCountry());
      mTts.setOnUtteranceCompletedListener(this);
    }
  }
  @Override
  public void onPause()
  {
    super.onPause();
    if( mTts != null)
      mTts.stop();
  }
  @Override
    public void onDestroy()
  {
        super.onDestroy();
        mTts.shutdown();
    }
  public void onUtteranceCompleted(String uttId) {
    Log.v(TAG, "Got completed message for uttId: " + uttId);
    lastUtterance = Integer.parseInt(uttId);
  }
}

//main.xml


<?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">

  <EditText android:id="@+id/wordsToSpeak"
    android:hint="Type words to speak here"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"/>

  <Button android:id="@+id/speak"
    android:text="Speak"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:onClick="doSpeak"
  android:enabled="false" />

</LinearLayout>

Get Pixel From Dpi

//package com.mediaportal.ampdroid.utils;

import android.content.Context;
import android.util.TypedValue;

public class DpiUtils {
   public static int getPxFromDpi(Context _context, int _px){
      int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 
            (float) _px, _context.getResources().getDisplayMetrics());
      return value;

   }
}

This animated wallpaper draws a rotating wireframe cube.

package app.test;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.os.SystemClock;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

/*
 * This animated wallpaper draws a rotating wireframe cube.
 */
public class CubeWallpaper1 extends WallpaperService {

    private final Handler mHandler = new Handler();

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public Engine onCreateEngine() {
        return new CubeEngine();
    }

    class CubeEngine extends Engine {

        private final Paint mPaint = new Paint();
        private float mOffset;
        private float mTouchX = -1;
        private float mTouchY = -1;
        private long mStartTime;
        private float mCenterX;
        private float mCenterY;

        private final Runnable mDrawCube = new Runnable() {
            public void run() {
                drawFrame();
            }
        };
        private boolean mVisible;

        CubeEngine() {
            // Create a Paint to draw the lines for our cube
            final Paint paint = mPaint;
            paint.setColor(0xffffffff);
            paint.setAntiAlias(true);
            paint.setStrokeWidth(2);
            paint.setStrokeCap(Paint.Cap.ROUND);
            paint.setStyle(Paint.Style.STROKE);

            mStartTime = SystemClock.elapsedRealtime();
        }

        @Override
        public void onCreate(SurfaceHolder surfaceHolder) {
            super.onCreate(surfaceHolder);

            // By default we don't get touch events, so enable them.
            setTouchEventsEnabled(true);
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            mHandler.removeCallbacks(mDrawCube);
        }

        @Override
        public void onVisibilityChanged(boolean visible) {
            mVisible = visible;
            if (visible) {
                drawFrame();
            } else {
                mHandler.removeCallbacks(mDrawCube);
            }
        }

        @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            super.onSurfaceChanged(holder, format, width, height);
            // store the center of the surface, so we can draw the cube in the right spot
            mCenterX = width/2.0f;
            mCenterY = height/2.0f;
            drawFrame();
        }

        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
            super.onSurfaceCreated(holder);
        }

        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            mVisible = false;
            mHandler.removeCallbacks(mDrawCube);
        }

        @Override
        public void onOffsetsChanged(float xOffset, float yOffset,
                float xStep, float yStep, int xPixels, int yPixels) {
            mOffset = xOffset;
            drawFrame();
        }

        /*
         * Store the position of the touch event so we can use it for drawing later
         */
        @Override
        public void onTouchEvent(MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_MOVE) {
                mTouchX = event.getX();
                mTouchY = event.getY();
            } else {
                mTouchX = -1;
                mTouchY = -1;
            }
            super.onTouchEvent(event);
        }

        /*
         * Draw one frame of the animation. This method gets called repeatedly
         * by posting a delayed Runnable. You can do any drawing you want in
         * here. This example draws a wireframe cube.
         */
        void drawFrame() {
            final SurfaceHolder holder = getSurfaceHolder();

            Canvas c = null;
            try {
                c = holder.lockCanvas();
                if (c != null) {
                    // draw something
                    drawCube(c);
                    drawTouchPoint(c);
                }
            } finally {
                if (c != null) holder.unlockCanvasAndPost(c);
            }

            // Reschedule the next redraw
            mHandler.removeCallbacks(mDrawCube);
            if (mVisible) {
                mHandler.postDelayed(mDrawCube, 1000 / 25);
            }
        }

        /*
         * Draw a wireframe cube by drawing 12 3 dimensional lines between
         * adjacent corners of the cube
         */
        void drawCube(Canvas c) {
            c.save();
            c.translate(mCenterX, mCenterY);
            c.drawColor(0xff000000);
            drawLine(c, -400, -400, -400,  400, -400, -400);
            drawLine(c,  400, -400, -400,  400,  400, -400);
            drawLine(c,  400,  400, -400, -400,  400, -400);
            drawLine(c, -400,  400, -400, -400, -400, -400);

            drawLine(c, -400, -400,  400,  400, -400,  400);
            drawLine(c,  400, -400,  400,  400,  400,  400);
            drawLine(c,  400,  400,  400, -400,  400,  400);
            drawLine(c, -400,  400,  400, -400, -400,  400);

            drawLine(c, -400, -400,  400, -400, -400, -400);
            drawLine(c,  400, -400,  400,  400, -400, -400);
            drawLine(c,  400,  400,  400,  400,  400, -400);
            drawLine(c, -400,  400,  400, -400,  400, -400);
            c.restore();
        }

        /*
         * Draw a 3 dimensional line on to the screen
         */
        void drawLine(Canvas c, int x1, int y1, int z1, int x2, int y2, int z2) {
            long now = SystemClock.elapsedRealtime();
            float xrot = ((float)(now - mStartTime)) / 1000;
            float yrot = (0.5f - mOffset) * 2.0f;
            float zrot = 0;

            // 3D transformations

            // rotation around X-axis
            float newy1 = (float)(Math.sin(xrot) * z1 + Math.cos(xrot) * y1);
            float newy2 = (float)(Math.sin(xrot) * z2 + Math.cos(xrot) * y2);
            float newz1 = (float)(Math.cos(xrot) * z1 - Math.sin(xrot) * y1);
            float newz2 = (float)(Math.cos(xrot) * z2 - Math.sin(xrot) * y2);

            // rotation around Y-axis
            float newx1 = (float)(Math.sin(yrot) * newz1 + Math.cos(yrot) * x1);
            float newx2 = (float)(Math.sin(yrot) * newz2 + Math.cos(yrot) * x2);
            newz1 = (float)(Math.cos(yrot) * newz1 - Math.sin(yrot) * x1);
            newz2 = (float)(Math.cos(yrot) * newz2 - Math.sin(yrot) * x2);

            // 3D-to-2D projection
            float startX = newx1 / (4 - newz1 / 400);
            float startY = newy1 / (4 - newz1 / 400);
            float stopX =  newx2 / (4 - newz2 / 400);
            float stopY =  newy2 / (4 - newz2 / 400);

            c.drawLine(startX, startY, stopX, stopY, mPaint);
        }

        /*
         * Draw a circle around the current touch point, if any.
         */
        void drawTouchPoint(Canvas c) {
            if (mTouchX >=0 && mTouchY >= 0) {
                c.drawCircle(mTouchX, mTouchY, 80, mPaint);
            }
        }

    }
}