Android Tutorial - Hardware : Screen
Multiscreen size
//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\AppWidget.java package apt.tutorial; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build; import android.widget.RemoteViews; public class AppWidget extends AppWidgetProvider { @Override public void onUpdate(Context ctxt, AppWidgetManager mgr, int[] appWidgetIds) { if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) { onHCUpdate(ctxt, mgr, appWidgetIds); } else { ctxt.startService(new Intent(ctxt, WidgetService.class)); } } public void onHCUpdate(Context ctxt, AppWidgetManager appWidgetManager, int[] appWidgetIds) { for (int i=0; i<appWidgetIds.length; i++) { Intent svcIntent=new Intent(ctxt, ListWidgetService.class); svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME))); RemoteViews widget=new RemoteViews(ctxt.getPackageName(), R.layout.widget); widget.setRemoteAdapter(appWidgetIds[i], R.id.restaurants, svcIntent); Intent clickIntent=new Intent(ctxt, DetailForm.class); PendingIntent clickPI=PendingIntent .getActivity(ctxt, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT); widget.setPendingIntentTemplate(R.id.restaurants, clickPI); appWidgetManager.updateAppWidget(appWidgetIds[i], widget); } super.onUpdate(ctxt, appWidgetManager, appWidgetIds); } } //src\apt\tutorial\DetailForm.java package apt.tutorial; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.FragmentActivity; public class DetailForm extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.detail_activity); } @Override public void onResume() { super.onResume(); String restaurantId=getIntent().getStringExtra(LunchList.ID_EXTRA); if (restaurantId!=null) { DetailFragment details=(DetailFragment)getSupportFragmentManager() .findFragmentById(R.id.details); if (details!=null) { details.loadRestaurant(restaurantId); } } } } //src\apt\tutorial\DetailFragment.java package apt.tutorial; import android.content.Context; 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.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; public class DetailFragment extends Fragment { private static final String ARG_REST_ID="apt.tutorial.ARG_REST_ID"; 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; public static DetailFragment newInstance(long id) { DetailFragment result=new DetailFragment(); Bundle args=new Bundle(); args.putString(ARG_REST_ID, String.valueOf(id)); result.setArguments(args); return(result); } @Override public void onCreate(Bundle state) { super.onCreate(state); setHasOptionsMenu(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return(inflater.inflate(R.layout.detail_form, container, false)); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); locMgr=(LocationManager)getActivity(). getSystemService(Context.LOCATION_SERVICE); name=(EditText)getView().findViewById(R.id.name); address=(EditText)getView().findViewById(R.id.addr); notes=(EditText)getView().findViewById(R.id.notes); types=(RadioGroup)getView().findViewById(R.id.types); feed=(EditText)getView().findViewById(R.id.feed); location=(TextView)getView().findViewById(R.id.location); Bundle args=getArguments(); if (args!=null) { loadRestaurant(args.getString(ARG_REST_ID)); } } @Override public void onPause() { save(); getHelper().close(); locMgr.removeUpdates(onLocationChange); super.onPause(); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.details_option, menu); } @Override public void onPrepareOptionsMenu(Menu menu) { if (restaurantId==null) { menu.findItem(R.id.location).setEnabled(false); menu.findItem(R.id.map).setEnabled(false); } } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId()==R.id.feed) { if (isNetworkAvailable()) { Intent i=new Intent(getActivity(), FeedActivity.class); i.putExtra(FeedActivity.FEED_URL, feed.getText().toString()); startActivity(i); } else { Toast .makeText(getActivity(), "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(getActivity(), 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)); } public void loadRestaurant(String restaurantId) { this.restaurantId=restaurantId; if (restaurantId!=null) { load(); } } private boolean isNetworkAvailable() { ConnectivityManager cm=(ConnectivityManager)getActivity(). getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info=cm.getActiveNetworkInfo(); return(info!=null); } private RestaurantHelper getHelper() { if (helper==null) { helper=new RestaurantHelper(getActivity()); } return(helper); } private void load() { Cursor c=getHelper().getById(restaurantId); c.moveToFirst(); name.setText(getHelper().getName(c)); address.setText(getHelper().getAddress(c)); notes.setText(getHelper().getNotes(c)); feed.setText(getHelper().getFeed(c)); if (getHelper().getType(c).equals("sit_down")) { types.check(R.id.sit_down); } else if (getHelper().getType(c).equals("take_out")) { types.check(R.id.take_out); } else { types.check(R.id.delivery); } latitude=getHelper().getLatitude(c); longitude=getHelper().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) { getHelper().insert(name.getText().toString(), address.getText().toString(), type, notes.getText().toString(), feed.getText().toString()); } else { getHelper().update(restaurantId, name.getText().toString(), address.getText().toString(), type, notes.getText().toString(), feed.getText().toString()); } } } LocationListener onLocationChange=new LocationListener() { public void onLocationChanged(Location fix) { getHelper().updateLocation(restaurantId, fix.getLatitude(), fix.getLongitude()); location.setText(String.valueOf(fix.getLatitude()) +", " +String.valueOf(fix.getLongitude())); locMgr.removeUpdates(onLocationChange); Toast .makeText(getActivity(), "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\ListViewsFactory.java package apt.tutorial; import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.widget.RemoteViews; import android.widget.RemoteViewsService; public class ListViewsFactory implements RemoteViewsService.RemoteViewsFactory { private Context ctxt=null; private RestaurantHelper helper=null; private Cursor restaurants=null; public ListViewsFactory(Context ctxt, Intent intent) { this.ctxt=ctxt; } @Override public void onCreate() { helper=new RestaurantHelper(ctxt); restaurants=helper .getReadableDatabase() .rawQuery("SELECT _ID, name FROM restaurants", null); } @Override public void onDestroy() { restaurants.close(); helper.close(); } @Override public int getCount() { return(restaurants.getCount()); } @Override public RemoteViews getViewAt(int position) { RemoteViews row=new RemoteViews(ctxt.getPackageName(), R.layout.widget_row); restaurants.moveToPosition(position); row.setTextViewText(android.R.id.text1, restaurants.getString(1)); Intent i=new Intent(); Bundle extras=new Bundle(); extras.putString(LunchList.ID_EXTRA, String.valueOf(restaurants.getInt(0))); i.putExtras(extras); row.setOnClickFillInIntent(android.R.id.text1, i); return(row); } @Override public RemoteViews getLoadingView() { return(null); } @Override public int getViewTypeCount() { return(1); } @Override public long getItemId(int position) { restaurants.moveToPosition(position); return(restaurants.getInt(0)); } @Override public boolean hasStableIds() { return(true); } @Override public void onDataSetChanged() { // no-op } } //src\apt\tutorial\ListWidgetService.java package apt.tutorial; import android.content.Intent; import android.widget.RemoteViewsService; public class ListWidgetService extends RemoteViewsService { @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { return(new ListViewsFactory(this.getApplicationContext(), intent)); } } //src\apt\tutorial\LunchFragment.java package apt.tutorial; 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.support.v4.app.ListFragment; 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 LunchFragment extends ListFragment { public final static String ID_EXTRA="apt.tutorial._ID"; Cursor model=null; RestaurantAdapter adapter=null; RestaurantHelper helper=null; SharedPreferences prefs=null; OnRestaurantListener listener=null; @Override public void onCreate(Bundle state) { super.onCreate(state); setHasOptionsMenu(true); } @Override public void onResume() { super.onResume(); helper=new RestaurantHelper(getActivity()); prefs=PreferenceManager.getDefaultSharedPreferences(getActivity()); initList(); prefs.registerOnSharedPreferenceChangeListener(prefListener); } @Override public void onPause() { helper.close(); super.onPause(); } @Override public void onListItemClick(ListView list, View view, int position, long id) { if (listener!=null) { listener.onRestaurantSelected(id); } } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.option, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId()==R.id.add) { startActivity(new Intent(getActivity(), DetailForm.class)); return(true); } else if (item.getItemId()==R.id.prefs) { startActivity(new Intent(getActivity(), EditPreferences.class)); return(true); } return(super.onOptionsItemSelected(item)); } public void setOnRestaurantListener(OnRestaurantListener listener) { this.listener=listener; } private void initList() { if (model!=null) { model.close(); } model=helper.getAll(prefs.getString("sort_order", "name")); 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(); } } }; public interface OnRestaurantListener { void onRestaurantSelected(long id); } class RestaurantAdapter extends CursorAdapter { RestaurantAdapter(Cursor c) { super(getActivity(), 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=getActivity().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\LunchList.java package apt.tutorial; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; public class LunchList extends FragmentActivity implements LunchFragment.OnRestaurantListener { public final static String ID_EXTRA="apt.tutorial._ID"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); LunchFragment lunch =(LunchFragment)getSupportFragmentManager() .findFragmentById(R.id.lunch); lunch.setOnRestaurantListener(this); } public void onRestaurantSelected(long id) { if (findViewById(R.id.details)==null) { Intent i=new Intent(this, DetailForm.class); i.putExtra(ID_EXTRA, String.valueOf(id)); startActivity(i); } else { FragmentManager fragMgr=getSupportFragmentManager(); DetailFragment details=(DetailFragment)fragMgr.findFragmentById(R.id.details); if (details==null) { details=DetailFragment.newInstance(id); FragmentTransaction xaction=fragMgr.beginTransaction(); xaction .add(R.id.details, details) .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) .addToBackStack(null) .commit(); } else { details.loadRestaurant(String.valueOf(id)); } } } } //src\apt\tutorial\OnAlarmReceiver.java package apt.tutorial; 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.content.SharedPreferences; import android.preference.PreferenceManager; public class OnAlarmReceiver extends BroadcastReceiver { private static final int NOTIFY_ME_ID=1337; @Override public void onReceive(Context ctxt, Intent intent) { SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(ctxt); boolean useNotification=prefs.getBoolean("use_notification", true); if (useNotification) { NotificationManager mgr= (NotificationManager)ctxt.getSystemService(Context.NOTIFICATION_SERVICE); Notification note=new Notification(R.drawable.stat_notify_chat, "It's time for lunch!", System.currentTimeMillis()); PendingIntent i=PendingIntent.getActivity(ctxt, 0, new Intent(ctxt, AlarmActivity.class), 0); note.setLatestEventInfo(ctxt, "LunchList", "It's time for lunch! Aren't you hungry?", i); note.flags|=Notification.FLAG_AUTO_CANCEL; mgr.notify(NOTIFY_ME_ID, note); } else { 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); } android.util.Log.e("***OnBootReceiver", android.text.format.DateFormat.format("MM/dd/yy h:mmaa", cal).toString()); 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) { android.util.Log.e("****OnBootReceiver", "got here"); 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 onUpg<!-- Copyright (C) 2006 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. -->rade(SQLiteDatabase db, int oldVersion, int newVersion) { if (newVersion<2) { db.execSQL("ALTER TABLE restaurants ADD COLUMN feed TEXT"); } if (newVersion<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); } } //src\apt\tutorial\WidgetService.java package apt.tutorial; import android.app.IntentService; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.widget.RemoteViews; public class WidgetService extends IntentService { public WidgetService() { super("WidgetService"); } @Override public void onHandleIntent(Intent intent) { ComponentName me=new ComponentName(this, AppWidget.class); RemoteViews updateViews=new RemoteViews("apt.tutorial", R.layout.widget); RestaurantHelper helper=new RestaurantHelper(this); AppWidgetManager mgr=AppWidgetManager.getInstance(this); try { Cursor c=helper .getReadableDatabase() .rawQuery("SELECT COUNT(*) FROM restaurants", null); c.moveToFirst(); int count=c.getInt(0); c.close(); if (count>0) { int offset=(int)(count*Math.random()); String args[]={String.valueOf(offset)}; c=helper .getReadableDatabase() .rawQuery("SELECT _ID, name FROM restaurants LIMIT 1 OFFSET ?", args); c.moveToFirst(); updateViews.setTextViewText(R.id.name, c.getString(1)); Intent i=new Intent(this, DetailForm.class); i.putExtra(LunchList.ID_EXTRA, c.getString(0)); PendingIntent pi=PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT); updateViews.setOnClickPendingIntent(R.id.name, pi); } else { updateViews.setTextViewText(R.id.title, this.getString(R.string.empty)); } } finally { helper.close(); } Intent i=new Intent(this, WidgetService.class); PendingIntent pi=PendingIntent.getService(this, 0, i, 0); updateViews.setOnClickPendingIntent(R.id.next, pi); mgr.updateAppWidget(me, updateViews); } } // //res\xml-v11\widget_provider.xml <?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="220dip" android:minHeight="220dip" android:updatePeriodMillis="1800000" android:initialLayout="@layout/widget" android:previewImage="@drawable/hc_widget_preview" /> // //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" /> <CheckBoxPreference android:key="use_notification" android:title="Use a Notification" android:defaultValue="true" android:summary="Check if you want a status bar icon at lunchtime, or uncheck for a full-screen notice" android:dependency="alarm" /> </PreferenceScreen> //res\xml\widget_provider.xml <?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="300dip" android:minHeight="79dip" android:updatePeriodMillis="1800000" android:initialLayout="@layout/widget" /> // //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> <string name="empty">No restaurants!</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" android:showAsAction="ifRoom|withText" /> <item android:id="@+id/prefs" android:title="Settings" android:icon="@drawable/ic_menu_preferences" /> </menu> // //res\layout-v11\widget.xml <?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/restaurants" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="3dp" android:layout_marginLeft="3dp" android:background="@drawable/widget_frame" /> // //res\layout-large-land\main.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="fill_parent" android:orientation="horizontal" > <fragment class="apt.tutorial.LunchFragment" android:id="@+id/lunch" android:layout_width="0dip" android:layout_height="fill_parent" android:layout_weight="40" /> <FrameLayout android:id="@+id/details" android:layout_width="0dip" android:layout_height="fill_parent" android:layout_weight="60" /> </LinearLayout> // //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_activity.xml <?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" class="apt.tutorial.DetailFragment" android:id="@+id/details" android:layout_width="fill_parent" android:layout_height="fill_parent" /> //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"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" class="apt.tutorial.LunchFragment" android:id="@+id/lunch" 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> //res\layout\widget.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" android:background="@drawable/widget_frame" > <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_alignParentLeft="true" android:layout_toLeftOf="@+id/next" android:textSize="10pt" android:textColor="#FFFFFFFF" /> <ImageButton android:id="@id/next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_alignParentRight="true" android:src="@drawable/ff" /> </RelativeLayout> //res\layout\widget_row.xml <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:gravity="center_vertical" android:paddingLeft="6dip" android:minHeight="?android:attr/listPreferredItemHeight" />
Nested PreferenceScreen
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"> <PreferenceScreen android:key="meats_screen" 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" /> </PreferenceScreen> <PreferenceScreen android:key="vegi_screen" 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:summary="My favorite vegetable" /> </PreferenceScreen> </PreferenceScreen>
Get the size of Default Display Screen
package app.test; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Typeface; import android.os.Bundle; import android.widget.ImageView; public class Test extends Activity { ImageView drawingImageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); drawingImageView = (ImageView) this.findViewById(R.id.DrawingImageView); Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager() .getDefaultDisplay().getWidth(), (int) getWindowManager() .getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawingImageView.setImageBitmap(bitmap); Paint paint = new Paint(); paint.setColor(Color.GREEN); paint.setTextSize(20); paint.setTypeface(Typeface.DEFAULT); Path p = new Path(); p.moveTo(20, 20); p.lineTo(100, 150); p.lineTo(200, 220); canvas.drawTextOnPath("this is a test", p, 0, 0, paint); } }
Screen Orientation
package app.test; import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.AdapterView.OnItemSelectedListener; public class Test extends Activity { Spinner mOrientation; // Orientation spinner choices // This list must match the list found in samples/ApiDemos/res/values/arrays.xml final static int mOrientationValues[] = new int[] { ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, ActivityInfo.SCREEN_ORIENTATION_USER, ActivityInfo.SCREEN_ORIENTATION_BEHIND, ActivityInfo.SCREEN_ORIENTATION_SENSOR, ActivityInfo.SCREEN_ORIENTATION_NOSENSOR, ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE, ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT, ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE, ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT, ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR, }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOrientation = (Spinner)findViewById(R.id.orientation); ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( this, R.array.screen_orientations, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mOrientation.setAdapter(adapter); mOrientation.setOnItemSelectedListener( new OnItemSelectedListener() { public void onItemSelected( AdapterView<?> parent, View view, int position, long id) { setRequestedOrientation(mOrientationValues[position]); } public void onNothingSelected(AdapterView<?> parent) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } }); } } //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="screen_orientation_summary"/> <Spinner android:id="@+id/orientation" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawSelectorOnTop="true" > </Spinner> </LinearLayout> //arrays.xml <?xml version="1.0" encoding="utf-8"?> <resources> <!-- Used in app/Screen Orientation --> <string-array name="screen_orientations"> <item>UNSPECIFIED</item> <item>LANDSCAPE</item> <item>PORTRAIT</item> <item>USER</item> <item>BEHIND</item> <item>SENSOR</item> <item>NOSENSOR</item> <item>SENSOR_LANDSCAPE</item> <item>SENSOR_PORTRAIT</item> <item>REVERSE_LANDSCAPE</item> <item>REVERSE_PORTRAIT</item> <item>FULL_SENSOR</item> </string-array> </resources>
Rows have different number of columns and content doesn't fit on screen: column 4 of row 2 shrinks all of the other columns
package com.example.android.apis.view; import com.example.android.apis.R; import android.app.Activity; import android.os.Bundle; public class TableLayout3 extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.table_layout_3); } } <?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:shrinkColumns="2, 3"> <TableRow> <TextView android:text="@string/table_layout_3_star" android:padding="3dip" /> <TextView android:text="@string/table_layout_3_open" android:padding="3dip" /> <TextView android:text="@string/table_layout_3_open_shortcut" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:text="@string/table_layout_3_triple_star" android:padding="3dip" /> <TextView android:text="@string/table_layout_3_save" android:padding="3dip" /> <TextView android:text="@string/table_layout_3_save_shortcut" android:padding="3dip" /> <TextView android:text="@string/table_layout_3_too_long" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:text="@string/table_layout_3_star" android:padding="3dip" /> <TextView android:text="@string/table_layout_3_quit" android:padding="3dip" /> <TextView android:text="@string/table_layout_3_quit_shortcut" android:padding="3dip" /> </TableRow> </TableLayout>
Demonstrates the Tab scrolling when too many tabs are displayed to fit in the screen.
package com.example.android.apis.view; import com.example.android.apis.R; import android.app.TabActivity; import android.os.Bundle; import android.view.View; import android.widget.TabHost; import android.widget.TextView; /** * Demonstrates the Tab scrolling when too many tabs are displayed to fit in the screen. */ public class Tabs5 extends TabActivity implements TabHost.TabContentFactory { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.tabs_scroll); final TabHost tabHost = getTabHost(); for (int i=1; i <= 30; i++) { String name = "Tab " + i; tabHost.addTab(tabHost.newTabSpec(name) .setIndicator(name) .setContent(this)); } } /** {@inheritDoc} */ public View createTabContent(String tag) { final TextView tv = new TextView(this); tv.setText("Content for tab with tag " + tag); return tv; } } //layout/tabs_scroll.xml <?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp"> <HorizontalScrollView android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="none"> <TabWidget android:id="@android:id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" /> </HorizontalScrollView> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp" /> </LinearLayout> </TabHost>
Using PreferenceScreen
import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceCategory; import android.preference.PreferenceScreen; import android.preference.Preference.OnPreferenceClickListener; public class Preferences extends PreferenceActivity{ private AlertDialog skinError; @Override protected void onStart() { super.onStart(); PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this); // List preference ListPreference listPref = new ListPreference(this); File f = new File("/sdcard/ADRINK"); final List<String> skins = new ArrayList<String>(); skins.add("Default"); if(f.exists()){ skins.addAll(Arrays.asList(f.list(null))); } PreferenceCategory dialogBasedPrefCat = new PreferenceCategory(this); dialogBasedPrefCat.setTitle("aDrink Settings"); dialogBasedPrefCat.setOnPreferenceClickListener(new OnPreferenceClickListener(){ @Override public boolean onPreferenceClick(Preference preference) { if("skin".equalsIgnoreCase(preference.getKey()) && skins.size() < 1){ skinError.show(); } return false; } }); root.addPreference(dialogBasedPrefCat); String[] names = new String[skins.size()]; skins.toArray(names); listPref.setEntries(names); listPref.setEntryValues(names); listPref.setDialogTitle("Select a skin"); listPref.setKey("skin"); listPref.setTitle("Select a different texture skin"); listPref.setSummary("You must download and put additional skins in your sdcard."); listPref.setDefaultValue("Default"); // Toggle preference CheckBoxPreference gamePref = new CheckBoxPreference(this); gamePref.setKey("game"); gamePref.setTitle("Enable drunk test game"); gamePref.setSummary("Uncheck to disable the drunk test math game."); gamePref.setDefaultValue(true); dialogBasedPrefCat.addPreference(gamePref); dialogBasedPrefCat.addPreference(listPref); setPreferenceScreen(root); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); skinError = new AlertDialog.Builder(this) .setCancelable(false) .setTitle("No additional skins can be found, do you want to go to the download site?") .setPositiveButton("Ok", new OnClickListener(){ @Override public void onClick(DialogInterface dialog, int which) { Intent i = new Intent("http://www.google.com"); startActivity(i); finish(); } }) .create(); } }
Splash Screen
import android.app.Activity; import android.util.Log; import android.view.KeyEvent; import android.os.Bundle; import android.content.Intent; import android.view.MotionEvent; public class AlmanacSplash extends Activity { /** Called when the activity is first created. */ protected boolean m_bSplashActive = true; protected boolean m_bPaused = false; protected long m_dwSplashTime = 2000; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); // Very simple timer thread Thread splashTimer = new Thread() { public void run() { try { // Wait loop long ms = 0; while (m_bSplashActive && (ms < m_dwSplashTime)) { sleep(100); Log.d("OpenAlmanac:Debug", "While cicle "+ms); // Only advance the timer if we're running. if (!m_bPaused) ms += 100; } // Advance to the next screen. startActivity(new Intent( "com.google.app.splashy.CLEARSPLASH")); Log.d("Almanac:Debug", "Start: com.google.app.splashy.CLEARSPLASH"); } catch (InterruptedException e) { // Thread exception // System.out.println(e.toString()); Log.e("OpenAlmanac:Splash", e.toString()); } finally { finish(); } } }; splashTimer.start(); // setContentView(R.layout.splash); return; } // If we're stopped, make sure the splash timer stops as well. protected void onStop() { super.onStop(); } protected void onPause() { super.onPause(); m_bPaused = true; } protected void onResume() { super.onResume(); m_bPaused = false; } protected void onDestroy() { super.onDestroy(); } //When you touch a key, clear the Splash Screen public boolean onKeyDown(int keyCode, KeyEvent event) { // if we get any key, clear the Splash Screen super.onKeyDown(keyCode, event); m_bSplashActive = false; return true; } //When you touch the screen, clear the Splash Screen public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { m_bSplashActive = false; } return true; } }
Get the optimal preview size for the given screen size.
//package edu.dhbw.andar.util; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.util.Iterator; import java.util.List; import android.hardware.Camera.Size; public class GraphicsUtil { //private final static double epsilon = 0.001; //this epsilon being so large is intended, as often there will not be an adequate resolution with //the correct aspect ratio available //so we trade the correct aspect ratio for faster rendering private final static double epsilon = 0.17; /** * Make a direct NIO FloatBuffer from an array of floats * @param arr The array * @return The newly created FloatBuffer */ public static FloatBuffer makeFloatBuffer(float[] arr) { ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4); bb.order(ByteOrder.nativeOrder()); FloatBuffer fb = bb.asFloatBuffer(); fb.put(arr); fb.position(0); return fb; } /** * Make a direct NIO ByteBuffer from an array of floats * @param arr The array * @return The newly created FloatBuffer */ public static ByteBuffer makeByteBuffer(byte[] arr) { ByteBuffer bb = ByteBuffer.allocateDirect(arr.length); bb.order(ByteOrder.nativeOrder()); bb.put(arr); bb.position(0); return bb; } public static ByteBuffer makeByteBuffer(int size) { ByteBuffer bb = ByteBuffer.allocateDirect(size); bb.position(0); return bb; } /** * Get the optimal preview size for the given screen size. * @param sizes * @param screenWidth * @param screenHeight * @return */ public static Size getOptimalPreviewSize(List<Size> sizes, int screenWidth, int screenHeight) { double aspectRatio = ((double)screenWidth)/screenHeight; Size optimalSize = null; for (Iterator<Size> iterator = sizes.iterator(); iterator.hasNext();) { Size currSize = iterator.next(); double curAspectRatio = ((double)currSize.width)/currSize.height; //do the aspect ratios equal? if ( Math.abs( aspectRatio - curAspectRatio ) < epsilon ) { //they do if(optimalSize!=null) { //is the current size smaller than the one before if(optimalSize.height>currSize.height && optimalSize.width>currSize.width) { optimalSize = currSize; } } else { optimalSize = currSize; } } } if(optimalSize == null) { //did not find a size with the correct aspect ratio.. let's choose the smallest instead for (Iterator<Size> iterator = sizes.iterator(); iterator.hasNext();) { Size currSize = iterator.next(); if(optimalSize!=null) { //is the current size smaller than the one before if(optimalSize.height>currSize.height && optimalSize.width>currSize.width) { optimalSize = currSize; } else { optimalSize = currSize; } }else { optimalSize = currSize; } } } return optimalSize; } public static boolean containsSize(List<Size> sizes, Size size) { for (Iterator<Size> iterator = sizes.iterator(); iterator.hasNext();) { Size currSize = iterator.next(); if(currSize.width == size.width && currSize.height == size.height) { return true; } } return false; } public static Size getSmallestSize(List<Size> sizes) { Size optimalSize = null; for (Iterator<Size> iterator = sizes.iterator(); iterator.hasNext();) { Size currSize = iterator.next(); if(optimalSize == null) { optimalSize = currSize; } else if(optimalSize.height>currSize.height && optimalSize.width>currSize.width) { optimalSize = currSize; } } return optimalSize; } }