Android in practice
-
Upload
jose-manuel-ortega-candel -
Category
Software
-
view
234 -
download
7
description
Transcript of Android in practice
![Page 1: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/1.jpg)
Android in Practice
José Manuel Ortega
Techfest uc3m February 2014
![Page 2: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/2.jpg)
Index
DEVELOPMENT ENVIRONMENT / SDK / TOOLS / ADB
UI DESIGN /ANDROID ASSET STUDIO
GOOGLE PLAY SERVICES / GOOGLE MAPS V2 / MAP FRAGMENTS
ACTION BAR / SEARCH VIEW / NOTIFICATIONS / ACCESSIBILITY / CONTEXTUAL MENU
WEBVIEW / NETWORK CONNECTIONS / ASYNCTASK
SINGLETON / ADAPTER PATTERN / VIEW HOLDER PATTERN
FRAGMENTS / MASTER-DETAIL / DIALOG FRAGMENTS
NAVIGATION DRAWER / ACTION BAR DRAWER TOOGLE /TABS
ACTION SHARE / CONTACTS / LOADERS
HTTP REQUEST /VOLLEY / INSTAGRAM API
GEOLOCATION / SHARED PREFERENCES / SQLITE DATABASE
LIBRARIES
![Page 3: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/3.jpg)
Development environment
JAVA JDK+ANDROID SDK
http://www.oracle.com/technetwork/es/java/javasebusiness/downlo
ads/index.html
http://developer.android.com/sdk/index.html
https://developer.android.com/intl/es/reference/android/app/package-summary.html
Android SDK Starter Package
![Page 4: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/4.jpg)
Development process
![Page 5: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/5.jpg)
Tools
Tools directory
http://developer.android.com/tools/help/index.html
Support libraries and compatibility In recent updates of Eclipse and the Android SDK android-support-V4.jar is added by default in the libs folder when new project is created http://developer.android.com/tools/support-library/index.html Adb commands Process for communicating the device(real or emulated) with
hardware development
adb devices adb install aplicación.apk –r[update] adb uninstall aplicación.apk –k[dont clean application/cache data]
![Page 6: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/6.jpg)
Project
![Page 7: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/7.jpg)
Spain Computing University
![Page 8: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/8.jpg)
UI Design
http://developer.android.com/design/index.html
Ways to specify the size of an item:
dp/dip: Density independent pixel.
sp/sip: Scale independent pixel. Used in font sizes.
pt: Point.
px: Pixel. Not use
Ancho y alto
match_parent:takes all the space available.
wrap_content: uses the space needed
fill_parent:equivalent to match_parent
![Page 9: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/9.jpg)
Android Asset Studio
Generate icons and graphic elements for each resolution http://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html
![Page 10: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/10.jpg)
Android manifest.xml
Define the components and application permissions <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <!-- Permisos --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <application android:allowBackup="true" android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/Theme.Styled" android:configChanges="locale|keyboard|keyboardHidden|orientation" android:name="com.proyecto.spaincomputing.singleton.MySingleton" android:hardwareAccelerated="true" > <activity android:name="com.proyecto.spaincomputing.SplashScreenActivity« android:label="@string/app_name" android:theme="@style/TransparentTheme" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ListadoActivity" android:configChanges="locale|keyboard|keyboardHidden|orientation" android:hardwareAccelerated="true"/> </application>
http://developer.android.com/reference/android/Manifest.permission.html
![Page 11: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/11.jpg)
Resources /Screen support
External elements you want to include and reference in the application. Declaratively include in /res ,accesing by @<type>/<nname> Are programmatically accessible via the R class (compiled with Android Asset Packaging Tool)
Android automatically selects the resource that adapts to the environment
Each resource type in a folder / res.
drawable: Images, Icons. layout: Layout to organize views. values: string.xml: Text strings colors.xml dimens.xml: font sizes anim: Animations raw: Other resources like audio or video menu: Menus and dialogs xml: Other xml (preferences, app widget, …)
<supports-screens android:anyDensity="true" android:xlargeScreens="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" />
![Page 12: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/12.jpg)
Google play services
![Page 13: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/13.jpg)
Google play services
Check if the service is available
import com.google.android.gms.common.GooglePlayServicesUtil; int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable (getApplicationContext()); Can return the constants: ConnectionResult.SUCCESS: ConnectionResult.DEVELOPER_ERROR: ConnectionResult.INTERNAL_ERROR: ConnectionResult.INVALID_ACCOUNT: ConnectionResult.NETWORK_ERROR: ConnectionResult.RESOLUTION_REQUIRED: ConnectionResult.SERVICE_DISABLED: ConnectionResult.SERVICE_INVALID: ConnectionResult.SERVICE_MISSING: ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED: ConnectionResult.SIGN_IN_REQUIRED:
![Page 14: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/14.jpg)
OPENGL 2.0 SUPPORT
Google Maps Android API v2 only supports devices with OpenGL ES 2.0 and above.
Check if the system supports OpenGL ES 2.0
final ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo(); final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;
![Page 15: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/15.jpg)
GoogleMaps v2
The maps are integrated into Google services play Obtain key
https://developers.google.com/maps/documentation/android/start#the_goo
gle_maps_api_key
Get signed certificate using the keytool command Google APIS Console https://code.google.com/apis/console/ Google CLOUD Console
https://cloud.google.com/console
keytool -list -v -keystore "%USERPROFILE%/.android/debug.keystore"
![Page 16: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/16.jpg)
GoogleMaps v2
Windowpreferencesandroidbuild
![Page 17: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/17.jpg)
GoogleMaps v2
![Page 18: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/18.jpg)
Permissions /Features Google Mapsv2 <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <!-- Localizacion --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<permission android:name="com.proyecto.spaincomputing.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> <uses-permission android:name="com.proyecto.spaincomputing.permission.MAPS_RECEIVE"/>
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="YOUR_API_KEY"/>
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
![Page 19: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/19.jpg)
Map fragments
layout/fragment_mapa.xml <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.SupportMapFragment"/>
MapaActivity. FragmentActivity from android.support.v4 import android.support.v4.app.FragmentActivity; public class MapaActivity extends FragmentActivity{ private GoogleMap mapa=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_mapa); mapa = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) .getMap();
}}
![Page 20: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/20.jpg)
Markers/InfoWindow
public class MapaActivity extends FragmentActivity implements OnMapLongClickListener, InfoWindowAdapter{ @Override public void onMapLongClick(LatLng location) { MarkerOptions options = new MarkerOptions() .position(location) //location mandatory .title(title) .snippet(snippet); Marker marker = mapa.addMarker(options); } @Override public View getInfoContents(Marker marker) { View window = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE).inflate(R.layout.info_window, null); txt_title.setText(marker.getTitle()); txt_snippet.setText(marker.getSnippet()); return window; }
}
![Page 21: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/21.jpg)
Markers/InfoWindow
![Page 22: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/22.jpg)
OPENGL / DISTANCE POLYGON
![Page 23: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/23.jpg)
Action Bar
ActionBArSherlock.
It is an extension of functionality implemented in the support library
http://actionbarsherlock.com/
ActionBarCompat
Create a new project with API 18 and add the project in the folder
sdk\extras\android\support\v7\appcompat.
![Page 24: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/24.jpg)
Action Bar search view
![Page 25: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/25.jpg)
Action Bar search view
Implement interface OnQueryTextListener
Override methods onQueryTextSubmit, onQueryTextChange
@Override public boolean onQueryTextSubmit(String query) { UniversityListFragment fragmentList = (UniversityListFragment)getSupportFragmentManager().findFragmentByTag("list_fragment"); fragmentList.searchData(query); return true; } @Override public boolean onQueryTextChange(String query) { return true; }
![Page 26: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/26.jpg)
Action Bar search view
@Override public boolean onCreateOptionsMenu(Menu menu) { mSearchView = (SearchView) searchItem.getActionView(); mSearchView.setQueryHint("Search..."); mSearchView.setOnQueryTextListener(this); return true; }
<item android:id="@+id/action_search" android:showAsAction="always" android:title="@string/search" android:icon="@android:drawable/ic_menu_search" android:actionViewClass= "android.support.v7.widget.SearchView" />
private SearchView mSearchView;
![Page 27: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/27.jpg)
ACTION BAR
Icon to go back in Action Bar
ActionBar ab = getSupportActionBar(); ab.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE |ActionBar.DISPLAY_SHOW_HOME|ActionBar.DISPLAY_HOME_AS_UP);
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: this.finish(); break; } return super.onOptionsItemSelected(item); }
Action Bar in fragments
setHasOptionsMenu(true)
onCreateOptionsMenu: to inflate the menu provided by the fragment.
onOptionsItemSelected: to respond to the user touch in an item provided by the fragment menu.
![Page 28: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/28.jpg)
ACTION BAR PROGRESS
Progress bar in Action Bar
private Activity activity = this; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS); ActionBar ab = getSupportActionBar(); ……… }
activity.setProgressBarIndeterminateVisibility(true);
viewer.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
activity.setProgressBarIndeterminateVisibility(false);
}
Show the progress bar to start loading and hide when finished.
![Page 29: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/29.jpg)
Notifications
To generate notifications in the status bar of the system we use a class included in library compatibility android-support-v4.jar.
The class is NotificationCompat.Builder and we have to create a new object passing by parameter application context and assign all the properties you want through their set () methods.
import android.support.v4.app.NotificationCompat; import android.support.v4.app.TaskStackBuilder;
NotificationCompat.Builder myNotification = new NotificationCompat.Builder(context) .setContentTitle(titulo) .setContentText(texto) .setTicker(aviso) .setWhen(System.currentTimeMillis()) .setContentIntent(contentIntent) .setDefaults(Notification.DEFAULT_SOUND) .setAutoCancel(true) .setSmallIcon(R.drawable.favorito) .setLargeIcon(largeIcon);
![Page 30: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/30.jpg)
Notifications Create and launch notification via object NotificationManager
TaskStackBuilder stackBuilder=TaskStackBuilder.create(context); stackBuilder.addParentStack(PrincipalActivity.class); stackBuilder.addNextIntent(notificationIntent); PendingIntent resultPendingIntent=stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
Associating action to notification
NotificationManager notificationManager; notificationManager =(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); /*Create notification with builder*/ Notification notification=myNotification.build(); notificationManager.notify((int) System.currentTimeMillis(), notification);
![Page 31: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/31.jpg)
Accessibility
http://developer.android.com/training/accessibility/index.html
<Button android:id="@+id/pause_button" android:src="@drawable/pause" android:contentDescription="@string/pause"/>
Through layout
Through code
String contentDescription = "Select " + strValues[position]; label.setContentDescription(contentDescription);
![Page 32: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/32.jpg)
Contextual menu
![Page 33: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/33.jpg)
Contextual menu
Add menu items by code @Override public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) { if(listado.size()>0){ menu.setHeaderTitle(R.string.accion); if(!favoritos){ menu.add(0, Constants.MENU_FAVORITO, 3, getResources().getText(R.string.anyadir_favorito)); }else{ menu.add(0, Constants.MENU_FAVORITO, 3, getResources().getText(R.string.eliminar_favorito)); } }}
lstListado.setAdapter(new UniversidadAdapter(this)); registerForContextMenu(lstListado); //view register
Floating list at long press on a View row
![Page 34: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/34.jpg)
Contextual menu
Add options menu with xml (recommended option) <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/mapa" android:title="@string/mapa" android:showAsAction="ifRoom|withText" android:icon="@drawable/location" /> <item android:id="@+id/rutaGoogle" android:title="@string/ruta_google" android:showAsAction="ifRoom|withText" android:icon="@drawable/google_map" /> </menu> @Override public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater=getActivity().getMenuInflater(); if(listado.size()>0){ inflater.inflate(R.menu.menu_mostrar, menu); }}
![Page 35: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/35.jpg)
Contextual menu
//Manage touch in contextual menu @Override public boolean onContextItemSelected(android.view.MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); //selected row UniversidadBean ub = (UniversidadBean) getUniversidad((int) info.id); switch (item.getItemId()) { case Constants.MENU_ENLACE: if(ub.getEnlace()!=null){ listener.onUniversidadLink(ub.getEnlace()); } return true; default: return super.onContextItemSelected(item); } }
![Page 36: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/36.jpg)
WebView
![Page 37: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/37.jpg)
WebView
<WebView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/visorWebView"> </WebView>
import android.webkit.WebView; import android.webkit.WebViewClient; WebView viewer; viewer = (WebView) findViewById(R.id.visorWebView); viewer.setWebViewClient(new myWebClient()); viewer.getSettings().setJavaScriptEnabled(true); viewer.getSettings().setBuiltInZoomControls(true); viewer.loadUrl(content);
![Page 38: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/38.jpg)
WebView
public class myWebClient extends WebViewClient{ @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); } }
![Page 39: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/39.jpg)
Network connection
import android.net.ConnectivityManager; import android.net.NetworkInfo; ConnectivityManager connectivityManager; connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); Boolean connected = networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected();
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
![Page 40: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/40.jpg)
Network connection Enable Wifi / Check connection type
NetworkInfo wifiInfo=connectivityManager.getNetworkInfo (ConnectivityManager.TYPE_WIFI); NetworkInfo mobileInfo=connectivityManager.getNetworkInfo (ConnectivityManager.TYPE_MOBILE); if(wifiInfo.isConnected()){ Toast.makeText(context, "Wifi is connected", Toast.LENGTH_LONG).show(); } if(mobileInfo.isConnected()){ Toast.makeText(context, "3G/4G is connected", Toast.LENGTH_LONG).show(); }
WifiManager wifiManager=(WifiManager) context.getSystemService(Context.WIFI_SERVICE); wifiManager.setWifiEnabled(true);
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
![Page 41: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/41.jpg)
Asynctask This class will allow us to perform background tasks without using neither
directly nor Handlers Threads, trying these elements in a fully transparent way to the programmer.
When we define a AsyncTask class must define the type of three elements, the input parameters, its progress and outcome.
Override onPreExecute(),doInBackground(),onPostExecute(),onProgressUpdate()
class RequestTask extends AsyncTask<String, String, String>{ @Override protected void onPreExecute() { } @Override protected void onProgressUpdate(Integer... values) { } @Override protected String doInBackground(String... uri) { } @Override protected void onPostExecute(String result) { super.onPostExecute(result); }
new RequestTask(). execute(url);
![Page 42: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/42.jpg)
Asynctask onPreExecute, run before executing our task and we can use it to initialize
tasks as displaying a progress bar.
doInBackground(Params...), here we schedule our background task. Params in the case discussed earlier will be an array of Strings that are passed when calling the execute method. Being a process that can take an indefinite time to complete, we can give feedback to the user thanks to percent complete in publishProgress(Progress. ..) method.
publishProgress receives an integer parameter and make the execution of onProgressUpdate method to indicate the user the task percentage.
onPostExecute(Result), runs to finish the process in the background.
The problem of doInBackground method is blocking the UI, so while this method is running can not get anything in the ui, but if we have no choice ,we can use this code for debug.
runOnUiThread(new Runnable() { public void run() { Toast.makeText(getApplicationContext(), "Example for Toast",Toast.LENGTH_SHORT).show();} });
![Page 43: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/43.jpg)
Singleton
Only one instance Application class
<application android:allowBackup="true" android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/Theme.Styled" android:name= "com.proyecto.spaincomputing.singleton.MySingleton">
public class MySingleton extends Application { private static MySingleton instance; public static Context context; @Override public void onCreate() { super.onCreate(); context = getApplicationContext(); } }
![Page 44: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/44.jpg)
Navigation Pattern
import android.support.v4.app.NavUtils; NavUtils.navigateUpTo(this, new Intent(this, ListadoActivity.class));
http://developer.android.com/design/patterns/navigation.html
Intent intent = NavUtils.getParentActivityIntent(this); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_SINGLE_TOP); NavUtils.navigateUpTo(this, intent);
NavUtils.navigateUpFromSameTask(this);
<activity android:name=".DetalleUniversidadActivity" android:parentActivityName=".ListadoActivity" <!-- Parent activity meta-data to support 4.0 and lower --> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".ListadoActivity" /> </activity>
![Page 45: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/45.jpg)
Adapter Pattern
Link between the source data and the view It works with ListView or GridView There are many types of adapter You can perform a custom adaptar The most used ArrayAdapter / CursorAdapter The Adapter interacts with a collection of data objects for display in
View
ArrayList<UniversidadBean> listado=newArrayList<UniversidadBean>(); private ListView lstListado; lstListado=(ListView)getView().findViewById (R.id.LstListado); lstListado.setAdapter (new UniversidadAdapter(this,listado));
![Page 46: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/46.jpg)
View Holder/View Container Pattern
ViewContainer
static class ViewContainer{
public ImageView imagen;
public TextView nombre;
public TextView descripcion;
}
Improve the performance of listview
The viewholder is used to avoid calling findViewById whenever prompted a new row to the adapter. Thus, instead of calling findViewById each time you use the references to the fields you have stored in the viewholder.
This pattern will help us to limit the number of calls to findViewById method. The idea would be to call it once, and then save the view daughter that refers to the instance of ViewHolder to be associated with the object by the method convertView View.setTag ()
Its recommend using a static class to store the items of each row in the view, functioning as a kind of cache for our view.
![Page 47: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/47.jpg)
View Holder/View Container Pattern @Override
public View getView(int position, View convertView,ViewGroup parent) {
ViewContainer viewContainer;
//si es la primera vez que se imprime la fila
if(convertView==null){
LayoutInflater inflater = context.getLayoutInflater();
convertView = inflater.inflate(R.layout.row, null,true);
//crea una vista para el objeto contenedor
viewContainer=new ViewContainer()
//obtiene una referencia a todas las vistas de la fila
viewContainer.nombre=(TextView)convertView.findViewById(R.id.textView_superior);
viewContainer.descripcion=(TextView)convertView.findViewById(R.id.textView_inferior);
viewContainer.imagen=(ImageView)convertView.findViewById(R.id.imageView_imagen);
//asigna el contenedor de la vista a rowView
convertView.setTag(viewContainer);
}else{
viewContainer=(ViewContainer) convertView.getTag(); //recicling }
//personaliza el contenido de cada fila basándone en su posición
viewContainer.nombre.setText(listado.get(position).getNombre());
viewContainer.descripcion.setText(listado.get(position).getDescripcion());
viewContainer.imagen.setImageResource(listado.get(position).getIdImagen());
return(convertView);
}
![Page 48: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/48.jpg)
View Holder/View Container Pattern
Debug
![Page 49: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/49.jpg)
Fragments
A fragment represents a certain behavior or a portion of a user interface activity.
Multiple fragments can be combined. A fragment must always be part of an activity. They emerged to provide greater flexibility to build the user interface Override methods
@Override //called when finish onCreate method in activity public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onCreate(Bundle savedInstanceState) {//inicializar componentes super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle
savedInstanceState) { }
http://developer.android.com/guide/components/fragments.html
![Page 50: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/50.jpg)
Fragments
Add a fragment to view by layout 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="com.proyecto.spaincomputing.fragment.UniversidadesFragment"
android:id="@+id/FrgListado"
android:layout_width="375dp"
android:layout_height="match_parent"/>
<fragment
class="com.proyecto.spaincomputing.fragment.FragmentDetalle"
android:id="@+id/FrgDetalle"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
![Page 51: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/51.jpg)
Fragments
Add a fragment to view
By code //Fragments array Fragment[] fragments = new Fragment[]{new PortadaFragment(), new UniversityListFragment(),new UniversidadesImagesFragment()}; FragmentManager manager = getSupportFragmentManager(); manager.beginTransaction() .add(R.id.contentFrame, fragments[0]) .add(R.id.contentFrame, fragments[1]) .add(R.id.contentFrame, fragments[2]) .commit(); //show/hide manager.beginTransaction().show(fragments[0]).commit(); manager.beginTransaction().hide(fragments[1]).commit(); manager.beginTransaction().hide(fragments[2]).commit();
![Page 52: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/52.jpg)
Fragments/ Master-detail
PORTRAIT LANDSCAPE
![Page 53: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/53.jpg)
Fragments/ Master-detail
PORTRAIT
LANDSCAPE
![Page 54: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/54.jpg)
Fragments/ Master-detail
2 layout layout\fragment_universidades_list.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" > <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </LinearLayout>
![Page 55: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/55.jpg)
Fragments/ Master-detail
2 layout layout-land\fragment_universidades_list.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:baselineAligned="false" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="horizontal" tools:context=".TabsActivity" > <ListView android:id="@+id/listView" android:layout_width="0px" android:layout_height="wrap_content" android:layout_weight="1.5"> </ListView> <fragment android:id="@+id/fragmentUniversidadInfo" android:name="com.proyecto.spaincomputing.fragment.UniversidadInfoFragment" android:layout_width="0px" android:layout_height="wrap_content" android:layout_weight="4" tools:layout="@layout/fragment_universidad_info" /> </LinearLayout>
![Page 56: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/56.jpg)
Fragments/ Master-detail
Check orientation to display the detail page UniversidadBean ub=listado.get(position); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { FragmentManager manager = getActivity().getSupportFragmentManager(); UniversidadInfoFragment fragment = (UniversidadInfoFragment) manager.findFragmentById(R.id.fragmentUniversidadInfo); fragment.loadWebViewContent(ub.getEnlace()); getActivity().invalidateOptionsMenu(); } else { Intent intent = new Intent(getActivity().getApplicationContext(), UniversityDetailActivity.class); intent.putExtra(UniversityDetailActivity.URL, ub.getEnlace()); url=ub.getEnlace(); intent.putExtra(UniversityDetailActivity.UNIVERSIDAD, ub.getNombre()); startActivity(intent); }
![Page 57: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/57.jpg)
Dialog Fragment
The DialogFragment class provides all the controls you need to create a dialogue and change its appearance. It was introduced in Android 3.0 (API 11) and is available in the support library, so that it can be used without problems with older versions.
Use the class you DialogFragment ensures proper management of events that may occur, such as clicking the Back button or rotate the screen. Furthermore, using this class we can reuse the interface dialogues as a larger component interface.
To create a dialogue create a class that inherits from the DialogFragment class and create an AlertDialog object in the onCreateDialog() method
import android.support.v4.app.DialogFragment; public class LinkDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle(getText(R.string.title).toString()); .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { listener.onDialogNegativeClick(LinkDialogFragment.this); } }); return builder.create(); }}
![Page 58: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/58.jpg)
Dialog Fragment
To display the dialog we just created we have to create an instance of the class in our business and invoke the show () method so that the dialog appears.
With getSupportFragmentManager() call method get access to FragmentManager that is responsible for managing the fragments of the application.
//LinkDialogFragment object LinkDialogFragment linkDialogFragment=new LinkDialogFragment(); //fragment parameters Bundle args = new Bundle(); args.putString("ENLACE", enlace); linkDialogFragment.setArguments(args); linkDialogFragment.show(getSupportFragmentManager(), "");
![Page 59: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/59.jpg)
Navigation Drawer
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/drawerLayout"> <!-- The main content view --> <FrameLayout android:id="@+id/contentFrame" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- The navigation drawer --> <ListView android:id="@+id/left_drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:choiceMode="singleChoice" android:divider="@android:color/transparent" android:dividerHeight="0dp" android:background="#111"/> </android.support.v4.widget.DrawerLayout>
http://developer.android.com/training/implementing-navigation/nav-drawer.html
![Page 60: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/60.jpg)
Navigation Drawer
private ListView drawerList; private String[] drawerOptions; private DrawerLayout drawerLayout; drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); drawerList = (ListView) findViewById(R.id.left_drawer); drawerOptions = getResources().getStringArray(R.array.drawer_options); // Set the adapter for the list view drawerList.setAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.drawer_list_item,drawerOptions)); // Set the list's click listener drawerList.setOnItemClickListener(new DrawerItemClickListener()); private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position,long id)
{ setContent(position); } }
![Page 61: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/61.jpg)
Navigation Drawer/ ActionBarDrawerToogle
private ActionBarDrawerToggle drawerToggle; drawerToggle = new ActionBarDrawerToggle( this, drawerLayout, R.drawable.ic_drawer, R.string.drawer_open, //accesibility text string R.string.drawer_close ) { public void onDrawerClosed(View view) { ActivityCompat.invalidateOptionsMenu(PrincipalActivity.this); } public void onDrawerOpened(View drawerView) { ActivityCompat.invalidateOptionsMenu(PrincipalActivity.this); } } //listener drawerLayout.setDrawerListener(drawerToggle); drawerToggle.setDrawerIndicatorEnabled(true);
Open/close sidebar by Icon ActionBar Through ActionBarDrawerToogle object in support library
![Page 62: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/62.jpg)
Navigation Drawer/ ActionBarDrawerToogle
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); drawerToggle.onConfigurationChanged(newConfig); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); drawerToggle.syncState(); //sincronize drawer toogle state } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { if (drawerLayout.isDrawerOpen(drawerList)) { drawerLayout.closeDrawer(drawerList); } else { drawerLayout.openDrawer(drawerList); } return true; } }
We allow the use of the icon in Action Bar
![Page 63: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/63.jpg)
Tabs
![Page 64: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/64.jpg)
Tabs Implement interface TabListener
Override methods in TabListener
@Override public void onTabUnselected(Tab arg0, FragmentTransaction arg1) { } @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { setContent(tab.getPosition()); }
import com.actionbarsherlock.app.ActionBar.Tab; import com.actionbarsherlock.app.ActionBar.TabListener; public class TabsActivity extends SherlockFragmentActivity implements TabListener { }
![Page 65: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/65.jpg)
Tabs Reference obtain ActionBar
final ActionBar actionBar = getSupportActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Add tabs
actionBar.addTab( actionBar.newTab() .setText(getResources().getString(R.string.listado)) .setTabListener(this)); actionBar.addTab( actionBar.newTab() .setText(getResources().getString(R.string.imagenes)) .setTabListener(this));
![Page 66: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/66.jpg)
Action Share / Share Action Provider
![Page 67: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/67.jpg)
Action Share Launch an intent of type "ACTION_SEND" to be received by the applications you have installed public void mostrarShare(UniversidadBean ubBean){ List<Intent> targetedShareIntents = new ArrayList<Intent>(); Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND); shareIntent.setType("text/html"); List<ResolveInfo> resInfo = getActivity().getPackageManager().queryIntentActivities(shareIntent, 0); if (!resInfo.isEmpty()){ for (ResolveInfo resolveInfo : resInfo) { String packageName = resolveInfo.activityInfo.packageName; Intent targetedShareIntent = new Intent(android.content.Intent.ACTION_SEND); targetedShareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); targetedShareIntent.setType("text/html"); targetedShareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Spain COmputing UNiversity"); targetedShareIntent.setPackage(packageName); targetedShareIntents.add(targetedShareIntent); } Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(targetedShareIntents.size()-1), getText(R.string.compartir)); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{})); startActivity(chooserIntent); } }
![Page 68: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/68.jpg)
Share Action Provider
<item android:id="@+id/action_share" android:title="@string/compartir" spaincomputing:showAsAction="ifRoom" spaincomputing:actionProviderClass= "android.support.v7.widget.ShareActionProvider"/>
private Intent createShareIntent() { Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("text/html"); shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Spain COmputing UNiversity"); UniversidadBean ub=new UniversidadBean(id, idImagen, nombre, descripcion, enlace, tipo, grado, latitud, longitud); shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, Html.fromHtml(ub.getNombre()+"\n"+ub.getDescripcion()+"\n"+ub.getGrado()+"\n\n"+ub.getEnlace()+"\n\n"+ub.getLatitud()+"\n"+ub.getLongitud())); return shareIntent; }
private ShareActionProvider mShareActionProvider; MenuItem shareItem = menu.findItem(R.id.action_share); mShareActionProvider = (ShareActionProvider)MenuItemCompat.getActionProvider(shareItem); mShareActionProvider.setShareIntent(createShareIntent());
![Page 69: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/69.jpg)
Contacts
import android.provider.ContactsContract; //CONTACTS PROVIDER Cursor mCursor; // acceder al content provider de contactos mCursor = getContentResolver().query(Data.CONTENT_URI, new String[] { Data._ID, Data.DISPLAY_NAME, Email.DATA1, Phone.TYPE }, Data.MIMETYPE + "='" + Email.CONTENT_ITEM_TYPE + "' AND " + Email.DATA1 + " IS NOT NULL", null,Data.DISPLAY_NAME + " ASC"); ListAdapter adapter = new SimpleCursorAdapter(this, // context android.R.layout.simple_list_item_2, // Layout para las filas mCursor, // cursor new String[] { Data.DISPLAY_NAME, Phone.NUMBER }, //COLUMNS new int[] { android.R.id.text1, android.R.id.text2 }, //views ); setListAdapter(adapter);
<uses-permission android:name="android.permission.READ_CONTACTS" />
android.os.Build.VERSION.SDK_INT<11 //before honeycomb
![Page 70: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/70.jpg)
Contacts
CursorLoader cursorLoader=new CursorLoader(this, Data.CONTENT_URI, new String[] { Data._ID, Data.DISPLAY_NAME, Email.DATA1,Phone.TYPE }, Data.MIMETYPE + "='" + Email.CONTENT_ITEM_TYPE + "' AND "+ Email.DATA1 + " IS NOT NULL", null,Data.DISPLAY_NAME + " ASC"); mCursor=cursorLoader.loadInBackground(); ListAdapter adapter = new SimpleCursorAdapter(this, // context android.R.layout.simple_list_item_2, // Layout para las filas mCursor, // cursor new String[] { Data.DISPLAY_NAME, Phone.NUMBER }, //COLUMNS new int[] { android.R.id.text1, android.R.id.text2 }, //views CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); //flag ); setListAdapter(adapter);
android.os.Build.VERSION.SDK_INT>=11 //after honeycomb
Using CursorLoader allows the query cursor executing on a separate thread
![Page 71: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/71.jpg)
Loaders in contacts public class ContactsListFragment implements LoaderManager.LoaderCallbacks<Cursor> { }
@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); getLoaderManager().initLoader(ContactsQuery.QUERY_ID, null, this);}}
Inicializar loader
@Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader(getActivity(),contentUri,ContactsQuery.PROJECTION, ContactsQuery.SELECTION,null,ContactsQuery.SORT_ORDER);} }
@Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // This swaps the new cursor into the adapter. if (loader.getId() == ContactsQuery.QUERY_ID) { mAdapter.swapCursor(data); } } @Override public void onLoaderReset(Loader<Cursor> loader) {}
![Page 72: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/72.jpg)
HTTP Request org.apache.http
// Create HTTP Client HttpParams httpParameters = new BasicHttpParams(); // 3s max for connection HttpConnectionParams.setConnectionTimeout (httpParameters,3000); // 4s max to get data HttpConnectionParams.setSoTimeout(httpParameters, 4000); HttpClient httpclient = new DefaultHttpClient(httpParameters); HttpResponse response; String responseString = null; try {response = httpclient.execute(new HttpGet(uri[0]));//Execute uri StatusLine statusLine = response.getStatusLine(); if(statusLine.getStatusCode() == HttpStatus.SC_OK){ ByteArrayOutputStream out = new ByteArrayOutputStream(); response.getEntity().writeTo(out); out.close(); responseString = out.toString(); } else{ //Closes the connection. response.getEntity().getContent().close(); throw new IOException(statusLine.getReasonPhrase()); }} catch (ClientProtocolException e) {//TODO Handle problems.. } catch (IOException e) {//TODO Handle problems..}
![Page 73: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/73.jpg)
API INSTAGRAM
.Developer register
New client register
http://instagram.com/developer/clients/manage/
http://instagram.com/developer/
![Page 74: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/74.jpg)
API INSTAGRAM
![Page 75: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/75.jpg)
API INSTAGRAM
Endpoint tag media recent http://instagram.com/developer/endpoints/tags/#get_tags_media_recent
![Page 76: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/76.jpg)
VOLLEY
https://android.googlesource.com/platform/frameworks/volley https://github.com/mcxiaoke/android-volley
Unzip and import from Eclipse as a new project with code available. Export the project as Java Volley / jar checking only the "src" folder.
Volley is a library that facilitates and speeds up the creation of applications
that make use of networking in Android handling concurrency and network requests.
The advantage is that volley is responsible for managing the request threads
transparently to the developer.
libs\volley.jar Objects RequestQueue
Request: Contains all the necessary details of API calls to Web. For example,
the method to use (GET or POST), application data, listeners, error listeners.
![Page 77: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/77.jpg)
VOLLEY REQUEST
import com.android.volley.*; public static RequestQueue requestQueue; @Override protected void onCreate(Bundle savedInstanceState) { requestQueue = Volley.newRequestQueue(this); }
JSON Request with volley.Request object
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, url, null, successListener,null); requestQueue.add(jsObjRequest);
Instagram Activity
![Page 78: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/78.jpg)
VOLLEY RESPONSE
//Callback that is executed once the request has completed Response.Listener<JSONObject> successListener = new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { } }
JSON Response by volley.Response object
More volley examples https://github.com/PareshMayani/Android-Volley-Example
![Page 79: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/79.jpg)
Geolocation
LocationManager / android.location package ACCESS_COARSE_LOCATION/ACCESS_FINE_LOCATION
//Obtenemos el Location Manager del sistema LocationManager locationManager = (LocationManager)this.getSystemService (Context.LOCATION_SERVICE); // Definimos el Listener que gestionará los eventos LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { if (location != null) { Toast.makeText(getBaseContext(), "Location changed : Lat: " + location.getLatitude() + " Lng: " + location.getLongitude(),Toast.LENGTH_SHORT).show(); } }
// Registramos el Listener en el Location Manager para recibir actualizaciones locationManager. requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
![Page 80: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/80.jpg)
Geolocation
Implement interface ConnectionCallbacks
import com.google.android.gms.common.GooglePlayServicesClient. ConnectionCallbacks;
Override onConnected / User location
@Override public void onConnected(Bundle arg0) { updateLocation(locationClient.getLastLocation()); locationClient.requestLocationUpdates(locationRequest, this); }
import com.google.android.gms.location.LocationClient; import com.google.android.gms.location.LocationRequest; locationClient = new LocationClient(this, this, this); locationRequest = LocationRequest.create();
![Page 81: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/81.jpg)
Reverse Geolocation
Geocoder geoCoder = new Geocoder(context, Locale.getDefault()); List<Address> addresses = null; try { addresses = geoCoder.getFromLocation(gp.latitude , gp.longitude , 1); if (addresses!=null && addresses.size() > 0) { Address address = addresses.get(0); if(address.getMaxAddressLineIndex() > 0 ){ addressText =address.getAddressLine(0); } if(address.getLocality()!=null){ addressText = addressText+" / "+address.getLocality(); } if(address.getCountryName()!=null){ addressText = addressText+" / "+address.getCountryName(); } } } catch (IOException e) { }
Obtain place address from latidude and longitude
![Page 82: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/82.jpg)
Restore state in activity
@Override public void onSaveInstanceState(Bundle savedInstanceState) { // Always call the superclass so it can save the view hierarchy state super.onSaveInstanceState(savedInstanceState); }
Save the Activity state before being destroyed
Restore the Activity state after being created
public void onRestoreInstanceState(Bundle savedInstanceState) { // Always call the superclass so it can restore the view hierarchy super.onRestoreInstanceState(savedInstanceState); }
![Page 83: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/83.jpg)
SEND EMAIL
![Page 84: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/84.jpg)
SEND EMAIL ACTION_SEND INTENT
Intent intent = new Intent(android.content.Intent.ACTION_SEND); intent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{destino}); //colocamos la imagen adjunta en el stream intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("android.resource://" + getPackageName() + "/" +R.drawable.image)); startActivity(Intent.createChooser(intent, "Send email"));
libs https://code.google.com/p/javamail-android/downloads/list
Java mail API / Gmail SMTP /GMAILSender
Gmail authentication Configure SMTP SERVER
![Page 85: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/85.jpg)
Shared Preferences
Key/value dictionary res/xml/preferencias.xml
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="@string/pref_notificaciones"> <CheckBoxPreference android:key="pref_notificaciones_favoritos" android:title="@string/pref_notificaciones_favoritos" android:summary="@string/pref_notificaciones_favoritos" android:defaultValue="true" /> </PreferenceCategory> </PreferenceScreen>
PreferenceScreen is the entire screen that will show us where the other elements are displayed, and PreferenceCategory will allow us to create categories or groupings within our screen. The common element in different items is the key property. This will be the key that is stored in SharedPreferences and later retrieve the stored values by this key.
![Page 86: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/86.jpg)
Shared Preferences
![Page 87: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/87.jpg)
Shared Preferences Preferences Activity
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { onCreatePreferenceActivity(); } else { onCreatePreferenceFragment(); } } private void onCreatePreferenceActivity() { PreferenceManager prefManager=getPreferenceManager(); prefManager.setSharedPreferencesName("appPreferences"); addPreferencesFromResource(R.xml.preferencias); } private void onCreatePreferenceFragment() { getFragmentManager().beginTransaction() .replace(android.R.id.content, new MyPreferenceFragment ()) .commit(); }
![Page 88: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/88.jpg)
Shared Preferences
PreferenciasActivity
public static class MyPreferenceFragment extends PreferenceFragment { @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); PreferenceManager prefManager=getPreferenceManager(); prefManager.setSharedPreferencesName("appPreferences"); addPreferencesFromResource(R.xml.preferencias); } }
Get Preferences values SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("appPreferences", MODE_PRIVATE); //Launch favorites notification depending preferences value if(sharedPreferences.getBoolean("pref_notificaciones_favoritos",true)){ com.proyecto.spaincomputing.utils.StatusBarNotify.getInstance( getApplicationContext()).statusBarNotify("eliminado_favorito", nombre,descripcion); }
![Page 89: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/89.jpg)
SQLITE DATABASE
![Page 90: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/90.jpg)
SQLITE DATABASE import android.database.sqlite.*;
Create class that extends SQLiteOpenHelper and override onCreate()
method to create database
public class DBHelper extends SQLiteOpenHelper { //constructor public DBAdapter (Context context){ dbHelper = new DBHelper(context, DATABASE_NAME, null, DATABASE_VERSION); } private final static String DATABASE_CREATE = "CREATE TABLE ..“; @Override public void onCreate(SQLiteDatabase db) { db.execSQL(DATABASE_CREATE); } }
Emulator /root /data/data/<package>/databases
![Page 91: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/91.jpg)
SQLITE DATABASE INSERT,UPDATE,DELETE
SQLiteDatabase db = dbHelper.getWritableDatabase();
QUERY
SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor= myDatabase.query(DATABASE_TABLE, null, where,null, null, null, order);
// Create a new row of values to insert.
ContentValues newValues = new ContentValues();
// Assign values for each row.
newValues.put(COLUMN_NAME, newValue);
[ ... Repeat for each column ... ]
// Insert
myDatabase.insert(DATABASE_TABLE, null, newValues);
// Update
myDatabase.update(DATABASE_TABLE, updatedValues, where,
null);
// Delete
myDatabase.delete(DATABASE_TABLE, null, null);
![Page 92: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/92.jpg)
Developer libraries in google play
![Page 93: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/93.jpg)
Libraries
Indicator in ViewPager http://viewpagerindicator.com/
https://github.com/chrisbanes/ActionBar-PullToRefresh
Pager Sliding Tabstrip https://github.com/astuetz/PagerSlidingTabStrip Show routes in map. https://github.com/tyczj/MapNavigator
![Page 94: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/94.jpg)
Sliding Menu
Library to implement a sliding flyout with similar behavior to navigation drawer
https://github.com/jfeinstein10/SlidingMenu
MessageBar
Library to improve toast messages http://simonvt.github.io/MessageBar/
![Page 95: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/95.jpg)
Fading Action Bar
Used in Google play music https://github.com/ManuelPeinado/FadingActionBar
+
http://www.androidviews.net/
![Page 96: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/96.jpg)
About me
https://github.com/jmortega/apps https://github.com/jmortega/android
https://www.linkedin.com/in/jmortega1
https://play.google.com/store/apps/developer?id=Jos%C3%A9+Manuel+Ortega+Candel
![Page 97: Android in practice](https://reader031.fdocuments.us/reader031/viewer/2022020800/557b6233d8b42a78238b52c2/html5/thumbnails/97.jpg)
Google play