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>
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>
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(); } }
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(); } } }
//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>
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); } }
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()); } } } }
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>
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" />
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" />
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); } }
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" />
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); } } } }