SlideShare a Scribd company logo
1 of 59
Android Widget

     Fabio Collini
Speaker
Fabio Collini
  @fabioCollini

Tech Leader @ OmniaGroup
  http://www.omniagroup.it

Android Developer
  Apps Organizer e Folder Organizer

Blogger
  http://android.devapp.it
  http://www.cosenonjaviste.it
Agenda


Introduzione
Esempio widget Android
Scrollable widget
Novità di Android 3.0/3.1
Widget



Cosa si intende per widget?
Il punto di vista dello sviluppatore


Package android.widget
  Contiene le view utilizzabili nelle interfacce

Package android.appwidget
  Contiene le classi per gestire gli widget nella home
Il punto di vista dell’utente
Esempi di widget
Pro e contro
Conviene aggiungere uno widget?
Si!
  interazione facilitata con l’app
  funzionalità sempre a portata di mano
  categoria widget sul market

No!
  impossibile spostare l’app sulla sd card
Esempio
Widget minimale


Xml di definizione provider
Layout
Classe AppWidgetProvider
res/xml/appwidget_provider.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android=
      "http://schemas.android.com/apk/res/android"
    android:minWidth="294dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="86400000"
    android:initialLayout="@layout/appwidget_loading"
/>
Attributi disponibili
Calcolo della dimensione
  (numero di celle * 74) - 2

updatePeriodMillis
  millisecondi fra due aggiornamenti

initialLayout
  layout iniziale widget
  può essere diverso dal layout definitivo
Android manifest
<receiver android:name=".PicturesAppWidgetProvider"
	 	 android:label="1. Normal widget">
	 <meta-data
	 	 android:name="android.appwidget.provider"
	 	 android:resource="@xml/appwidget_provider" />
	 <intent-filter>
	 	 <action android:name=
	 	 "android.appwidget.action.APPWIDGET_UPDATE" />
	 </intent-filter>
</receiver>
Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=
	 "http://schemas.android.com/apk/res/android"
	 android:id="@+id/widget_layout"
	 style="@style/widget_layout">

	   <ImageView android:id="@+id/img1"
	   	 style="@style/picture_thumbnail" />

	 <ImageView android:id="@+id/img2"
	 	 style="@style/picture_thumbnail" />
</LinearLayout>
Layout limitati
Layout:
  FrameLayout, LinearLayout e RelativeLayout

View:
  AnalogClock
  Button
  Chronometer
  ImageButton
  ImageView
  ProgressBar
  TextView
Stile layout
<style name="widget_layout">
	 <item name="android:layout_width">
	 	 fill_parent</item>
	 <item name="android:layout_height">
	 	 fill_parent</item>
	 <item name="android:orientation">horizontal</item>
	 <item name="android:gravity">center</item>
	 <item name="android:layout_marginLeft">5dip</item>
	 <item name="android:layout_marginRight">5dip</item>
	 <item name="android:background">
	 	 @drawable/background</item>
</style>
res/drawable/background.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android=
         "http://schemas.android.com/apk/res/android">
    <stroke android:width="2dp"
         android:color="#990634fd" />
    <padding android:left="2dp" android:top="2dp"
         android:right="2dp" android:bottom="2dp" />
    <corners android:radius="4dp" />
    <solid android:color="#99FFFFFF" />
</shape>
Android non è solo touch
Device con trackball
  Gli utenti blackberry sono abituati a usarla

Device con tastiera
  Possono contenere i tasti freccia

Google TV
  non avrà un telecomando touch
Stile immagini
<style name="picture_thumbnail">
	 <item name="android:layout_width">120dip</item>
	 <item name="android:layout_height">90dip</item>
	 <item name="android:layout_margin">5dip</item>
	 <item name="android:focusable">true</item>
	 <item name="android:background">
	 	 @drawable/selection</item>
</style>
StateListDrawable

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android=
"http://schemas.android.com/apk/res/android">
	 <item android:state_focused="true"
	 	 android:drawable="@drawable/background" />
	 <item android:state_pressed="true"
	 	 android:drawable="@drawable/background" />
</selector>
Widget selezionato
AppWidgetProvider
Estende BroadcastReceiver
Riscrive onReceive, mette a disposizione:
  onUpdate
  onDeleted
  onEnabled
  onDisabled

Bug su Android 1.5
  http://groups.google.com/group/android-developers/msg/
     e405ca19df2170e2
AppWidgetProvider
public class PicturesAppWidgetProvider
	 extends AppWidgetProvider {
	 @Override
	 public void onUpdate(Context context,
	 	 	 AppWidgetManager appWidgetManager,
	 	 	 int[] appWidgetIds) {
	 	 for (int i = 0; i < appWidgetIds.length; i++) {
	 	 	 int appWidgetId = appWidgetIds[i];
	 	 	 updateAppWidget(context, appWidgetManager,
	 	 	 	 appWidgetId);
	 	 }
	 }
	 //...
}
updateAppWidget
public static void updateAppWidget(Context context,
	   AppWidgetManager appWidgetManager, int appWidgetId) {

	   RemoteViews views = new RemoteViews(context.getPackageName(),
	   	   R.layout.appwidget_provider);

	   views.setImageViewResource(R.id.img1, R.drawable.img1);
	   views.setImageViewResource(R.id.img2, R.drawable.img2);

	   views.setOnClickPendingIntent(R.id.img1,
	   	   AppWidgetUtils.createPendingIntent(context, 1));
	   views.setOnClickPendingIntent(R.id.img2,
	   	   AppWidgetUtils.createPendingIntent(context, 2));

	   appWidgetManager.updateAppWidget(appWidgetId, views);
}
RemoteViews
E’ una lista di comandi da effettuare
  I comandi vengono eseguiti in un altro processo

Metodi con 3 parametri
  id di una view contenuta nel layout
  setter da richiamare
  valore da impostare

Esempi di metodi
  setInt(int viewId, String methodName, int value)
  setString(int viewId, String methodName, String value)
PendingIntent
Intent da passare a una app esterna
Creati con un metodo statico
  getActivity(Context context, int requestCode, Intent intent, int flags)
  getBroadcast(Context context, int requestCode, Intent intent, int
    flags)
  getService(Context context, int requestCode, Intent intent, int flags)

Attenzione alla cache!
  requestCode: private request code for the sender (currently not
    used).
PendingIntent

public static Intent createIntent(Context ctx, int pos) {
	 Intent intent = new Intent(ctx, PictureViewer.class);
	 intent.putExtra(PictureViewer.IMAGE, "img" + pos);
	 return intent;
}

public static PendingIntent createPendingIntent(
	 	 Context ctx, int pos) {
	 Intent intent = createIntent(ctx, pos);
	 return PendingIntent.getActivity(ctx, pos, intent, 0);
}
Demo
Activity di configurazione
Può essere configurata nel file xml
Utile quando il widget è configurabile
Alla fine aggiorna manualmente il widget
Aggiungiamo una configurazione al nostro
  esempio:
  checkbox per nascondere lo sfondo del widget
appwidget_provider_config.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android=
    "http://schemas.android.com/apk/res/android"
    android:minWidth="294dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="86400000"
    android:initialLayout="@layout/appwidget_loading"
    android:configure="org.whymca.appwidget.config.
        PicturesAppWidgetConfigure"
/>
Configurazione nel manifest
<activity
	 android:name=".config.PicturesAppWidgetConfigure"
	 android:theme="@android:style/Theme.Dialog"
	 android:label="@string/Configure_widget">
	 <intent-filter>
	 	 <action
	 	 	 android:name=
	 	 	 "android.appwidget.action.APPWIDGET_CONFIGURE"
	 	 />
	 </intent-filter>
</activity>
PicturesAppWidgetConfigure
public void save(View v) {
	 boolean checked = showBackgroundCheck.isChecked();
	 PrefsSaver.saveShowBackground(this,
	 	 mAppWidgetId, checked);

	   PicturesAppWidgetProviderConfig.updateAppWidget(
	   	 this, AppWidgetManager.getInstance(this),
	   	 mAppWidgetId, checked);

	   Intent resultValue = new Intent();
	   resultValue.putExtra(
	   	 AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
	   setResult(RESULT_OK, resultValue);
	   finish();
}
Impostazione sfondo

if (showBackground) {
	 views.setInt(R.id.widget_layout,
	 	 "setBackgroundResource",
	 	 R.drawable.background);
} else {
	 views.setInt(R.id.widget_layout,
	 	 "setBackgroundResource",
	 	 0);
}
Demo
Attenzione su Android < 2.2


05‐02
22:35:41.544:
WARN/AppWidgetHostView(108):

android.widget.RemoteViews$AcDonExcepDon:
view:

android.widget.LinearLayout
can't
use
method
with
RemoteViews:

setBackgroundResource(int)
Cambio di orientation
Home in landscape
Alcune home non hanno orientation fissa
  A differenza delle Activity non è possibile decidere l’orientation

I tablet sono in landscape
Device con tastiera
Occorre gestire i layout
  directory layout-landscape
Immagini esterne


E se prendiamo le immagini dalla scheda
  sd o dagli asset?

Se le immagini sono troppo grandi:
Errore di memoria nella RemoteViews! :(
Uri per ContentProvider
views.setImageViewUri(R.id.img1,   createUri("img1"));
views.setImageViewUri(R.id.img2,   createUri("img2"));
views.setImageViewUri(R.id.img3,   createUri("img3"));
views.setImageViewUri(R.id.img4,   createUri("img4"));


private static Uri createUri(String imageName) {
	 return Uri.parse(
	 	 "content://org.whymca.appwidget.pictures/" +
	 	 imageName);
}
ContentProvider
<provider android:name=".ImageContentProvider"
	   android:authorities="org.whymca.appwidget.pictures" />

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws
FileNotFoundException {
	   String imageName = uri.getPath().substring(1);
	   File tmpFile = getTempFile(getContext(), imageName);
	   if (!tmpFile.exists()) {
	   	   copyAssetFile(getContext(), imageName, imageName + ".JPG");
	   }

	   try {
	   	   return ParcelFileDescriptor.open(tmpFile,
	   	   	   ParcelFileDescriptor.MODE_READ_ONLY);
	   } catch (FileNotFoundException e) {
	   	   return null;
	   }
}
Timeout aggiornamento
onUpdate viene eseguito nel thread
 principale
possibili timeout
  al riavvio del device ci sono molte app in esecuzione

pratica da seguire: spostare la logica in un
  service esterno
Service
public void onUpdate(Context context,
	 	 AppWidgetManager appWidgetManager,
	 	 int[] appWidgetIds) {
	 Intent intent = new Intent(context,
	 	 PicturesAppWidgetService.class);
	 intent.putExtra("appWidgetIds", appWidgetIds);
	 context.startService(intent);
}
updatePeriodMillis
Poco flessibile
  tutti gli widget sono aggiornati insieme e con la stessa frequenza

Configurazione fissa
  è cablato in un xml

Minimo 30 minuti
  anche se nel file xml viene specificato un valore minore

Attivato anche con il telefono in stand by
  consumo eccessivo della batteria
AlarmManager
creare un nuovo alarm in onUpdate
BroadcastReceiver definito nel manifest
un alarm per ogni widget
  ogni widget viene aggiornato con frequenza diversa
  alarm non eseguito con telefono in stand by

cancellare l’alarm in onDeleted
Widget scrollable


Forum
  http://groups.google.com/group/android-appwidget-extensions



Esempio di utilizzo
  http://code.google.com/p/scrollablecontacts/
Widget scrollable
Vantaggi
  permettono di usare liste e griglie
  resize migliore

Difetti
  funzionano solo con home replacement (ADW, LauncherPro,
     GoLauncher, Home++, ...)
  su LauncherPro devono essere abilitati manualmente
  lag dovuto a un bug (o feature!) di android
      http://code.google.com/p/android/issues/detail?id=4536
Demo
Widget Honeycomb
Nuove view utilizzabili:
  ListView
  GridView
  StackView
  ViewFlipper
  AdapterViewFlipper
Provider con controllo versione
@Override
public void onUpdate(Context context, AppWidgetManager
appWidgetManager, int[] appWidgetIds) {
	 if (Build.VERSION.SDK_INT >= 11) {
	 	 for (int i = 0; i < appWidgetIds.length; i++) {
	 	 	 HoneycombUtils.onUpdateTablet(context,
	 	 	 	 appWidgetManager, appWidgetIds[i]);
	 	 }
	 } else {
	 	 super.onUpdate(context,
	 	 	 appWidgetManager, appWidgetIds);
	 }
}
HoneycombUtils
public static void onUpdateTablet(Context ctx,
	   	   AppWidgetManager appWidgetManager, int id) {
	   RemoteViews views = new RemoteViews(ctx.getPackageName(),
	   	   R.layout.scrollable_layout);

	   Intent adapterIntent = new Intent(ctx, PicturesService.class);
	   adapterIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
	   adapterIntent.setData(Uri.parse(adapterIntent.toUri(
	   	   Intent.URI_INTENT_SCHEME)));
	   views.setRemoteAdapter(id, R.id.grid, adapterIntent);

	   PendingIntent clickPending = PendingIntent.getActivity(ctx, 0,
	   	   new Intent(ctx, PictureViewer.class),
	   	   PendingIntent.FLAG_UPDATE_CURRENT);
	   views.setPendingIntentTemplate(R.id.grid, clickPending);

	   appWidgetManager.updateAppWidget(id, views);
}
scrollable_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android=
	 	 "http://schemas.android.com/apk/res/android"
	 android:id="@+id/grid"
	 android:layout_width="fill_parent"
	 android:layout_height="fill_parent"
	 android:numColumns="auto_fit"
	 android:columnWidth="120dip"
	 android:background="@drawable/background" />
PictureService
public class PicturesService
	 	 extends RemoteViewsService {
	 @Override
	 public RemoteViewsFactory onGetViewFactory(
	 	 	 Intent intent) {
	 	 return new PicturesViewsFactory(
	 	 	 this.getApplicationContext(),
	 	 	 intent);
	 }
}
PicturesViewFactory
public class PicturesViewsFactory implements
	   	   RemoteViewsService.RemoteViewsFactory {
@Override
public RemoteViews getViewAt(int position) {
	   RemoteViews row = new RemoteViews(ctxt.getPackageName(),
	   	   R.layout.scrollable_cell);

	   row.setImageViewUri(R.id.appwidget_image,
	   	   createUri("img" + (position + 1)));

	   Intent intent = new Intent();
	   intent.putExtra(PictureViewer.IMAGE, "img" + (position + 1));
	   row.setOnClickFillInIntent(R.id.appwidget_image, intent);

	   return row;
}
//...
Demo
Preview di uno widget
L’emulatore Honeycomb contiene
  l’applicazione widget preview
Configurazione preview
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android=
        "http://schemas.android.com/apk/res/android"
    android:minWidth="368dp"
    android:minHeight="368dp"
    android:updatePeriodMillis="86400000"
    android:initialLayout="@layout/appwidget_loading"
    android:previewImage="@drawable/widget_preview" />
Demo preview
Il futuro
“Nuova” feature su Android 3.1
  resize degli widget

Tablet / Google TV
  su schermi grandi hanno più spazio nella home
  molto simile a un sistema operativo desktop
Risorse
Android developer
  http://developer.android.com/guide/topics/appwidgets/
     index.html
  http://developer.android.com/guide/practices/ui_guidelines/
     widget_design.html

Scrollable widget
  http://groups.google.com/group/android-appwidget-extensions

Honeycomb
  http://developer.android.com/sdk/android-3.0-highlights.html
Thanks for your attention!
Questions?
Slide
  Presto disponibili su http://www.slideshare.net/

Sorgenti
  https://github.com/fabioCollini/whymca2011

Fabio Collini @fabioCollini
  http://www.omniagroup.it
  http://android.devapp.it
  http://www.cosenonjaviste.it

More Related Content

Viewers also liked

Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeFabio Collini
 
Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015Fabio Collini
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMFabio Collini
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaFabio Collini
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKFabio Collini
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternFabio Collini
 
MVVM with DataBinding on android
MVVM with DataBinding on androidMVVM with DataBinding on android
MVVM with DataBinding on androidRodrigo Bressan
 

Viewers also liked (7)

Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG Firenze
 
Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015Testable Android Apps DroidCon Italy 2015
Testable Android Apps DroidCon Italy 2015
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUK
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM pattern
 
MVVM with DataBinding on android
MVVM with DataBinding on androidMVVM with DataBinding on android
MVVM with DataBinding on android
 

Similar to Android Widget @ whymca 2011

Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Davide Cerbo
 
Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Ivan Gualandri
 
01 Android - Introduction
01   Android - Introduction01   Android - Introduction
01 Android - Introductionspawn150
 
Introduzione ai componenti in Angular 4
Introduzione ai componenti in Angular 4Introduzione ai componenti in Angular 4
Introduzione ai componenti in Angular 4Giovanni Buffa
 
Design pattern architetturali Model View Controller, MVP e MVVM
Design pattern architetturali   Model View Controller, MVP e MVVMDesign pattern architetturali   Model View Controller, MVP e MVVM
Design pattern architetturali Model View Controller, MVP e MVVMRiccardo Cardin
 
Web Performance Optimization
Web Performance OptimizationWeb Performance Optimization
Web Performance OptimizationAlessandro Martin
 
Sviluppare per microsoft band
Sviluppare per microsoft bandSviluppare per microsoft band
Sviluppare per microsoft bandDotNetCampus
 
SVILUPPARE PER MICROSOFT BAND
SVILUPPARE PER MICROSOFT BANDSVILUPPARE PER MICROSOFT BAND
SVILUPPARE PER MICROSOFT BANDDotNetCampus
 
Sviluppare per Microsoft Band
Sviluppare per Microsoft BandSviluppare per Microsoft Band
Sviluppare per Microsoft BandMassimo Bonanni
 
Zend Framework Workshop Parte2
Zend Framework Workshop Parte2Zend Framework Workshop Parte2
Zend Framework Workshop Parte2massimiliano.wosz
 
SkyMedia: La tecnologia al servizio dell'intrattenimento
SkyMedia: La tecnologia al servizio dell'intrattenimentoSkyMedia: La tecnologia al servizio dell'intrattenimento
SkyMedia: La tecnologia al servizio dell'intrattenimentoMavigex srl
 
Asp.net 4 Community Tour VS2010
Asp.net 4 Community Tour VS2010Asp.net 4 Community Tour VS2010
Asp.net 4 Community Tour VS2010Fabrizio Bernabei
 
Csp@scuola smarttv corso1
Csp@scuola smarttv corso1Csp@scuola smarttv corso1
Csp@scuola smarttv corso1CSP Scarl
 

Similar to Android Widget @ whymca 2011 (20)

Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)Non Conventional Android Programming (Italiano)
Non Conventional Android Programming (Italiano)
 
Ivano brogonzoli why_mca
Ivano brogonzoli why_mcaIvano brogonzoli why_mca
Ivano brogonzoli why_mca
 
Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2Introduzione alla programmazione android - Android@tulug lezione 2
Introduzione alla programmazione android - Android@tulug lezione 2
 
01 Android - Introduction
01   Android - Introduction01   Android - Introduction
01 Android - Introduction
 
Yagwto
YagwtoYagwto
Yagwto
 
MVC2: non solo tecnologia
MVC2: non solo tecnologiaMVC2: non solo tecnologia
MVC2: non solo tecnologia
 
Introduzione ai componenti in Angular 4
Introduzione ai componenti in Angular 4Introduzione ai componenti in Angular 4
Introduzione ai componenti in Angular 4
 
Design pattern architetturali Model View Controller, MVP e MVVM
Design pattern architetturali   Model View Controller, MVP e MVVMDesign pattern architetturali   Model View Controller, MVP e MVVM
Design pattern architetturali Model View Controller, MVP e MVVM
 
Xamarin.android
Xamarin.androidXamarin.android
Xamarin.android
 
ReactJS for beginners
ReactJS for beginnersReactJS for beginners
ReactJS for beginners
 
Web Performance Optimization
Web Performance OptimizationWeb Performance Optimization
Web Performance Optimization
 
Sviluppare per microsoft band
Sviluppare per microsoft bandSviluppare per microsoft band
Sviluppare per microsoft band
 
SVILUPPARE PER MICROSOFT BAND
SVILUPPARE PER MICROSOFT BANDSVILUPPARE PER MICROSOFT BAND
SVILUPPARE PER MICROSOFT BAND
 
Dojo nuovo look alle vostre applicazioni web Domino
Dojo nuovo look alle vostre applicazioni web DominoDojo nuovo look alle vostre applicazioni web Domino
Dojo nuovo look alle vostre applicazioni web Domino
 
Sviluppare per Microsoft Band
Sviluppare per Microsoft BandSviluppare per Microsoft Band
Sviluppare per Microsoft Band
 
Zend Framework Workshop Parte2
Zend Framework Workshop Parte2Zend Framework Workshop Parte2
Zend Framework Workshop Parte2
 
Zendframework Parte2
Zendframework    Parte2Zendframework    Parte2
Zendframework Parte2
 
SkyMedia: La tecnologia al servizio dell'intrattenimento
SkyMedia: La tecnologia al servizio dell'intrattenimentoSkyMedia: La tecnologia al servizio dell'intrattenimento
SkyMedia: La tecnologia al servizio dell'intrattenimento
 
Asp.net 4 Community Tour VS2010
Asp.net 4 Community Tour VS2010Asp.net 4 Community Tour VS2010
Asp.net 4 Community Tour VS2010
 
Csp@scuola smarttv corso1
Csp@scuola smarttv corso1Csp@scuola smarttv corso1
Csp@scuola smarttv corso1
 

More from Fabio Collini

Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose worldFabio Collini
 
Using hilt in a modularized project
Using hilt in a modularized projectUsing hilt in a modularized project
Using hilt in a modularized projectFabio Collini
 
Managing parallelism using coroutines
Managing parallelism using coroutinesManaging parallelism using coroutines
Managing parallelism using coroutinesFabio Collini
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confFabio Collini
 
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmFabio Collini
 
Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectFabio Collini
 
Solid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon ItalySolid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon ItalyFabio Collini
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaFabio Collini
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureFabio Collini
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFabio Collini
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinFabio Collini
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018Fabio Collini
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFabio Collini
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFabio Collini
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKFabio Collini
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Fabio Collini
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaFabio Collini
 

More from Fabio Collini (17)

Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
 
Using hilt in a modularized project
Using hilt in a modularized projectUsing hilt in a modularized project
Using hilt in a modularized project
 
Managing parallelism using coroutines
Managing parallelism using coroutinesManaging parallelism using coroutines
Managing parallelism using coroutines
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community conf
 
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere Stockholm
 
Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture project
 
Solid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon ItalySolid principles in practice the clean architecture - Droidcon Italy
Solid principles in practice the clean architecture - Droidcon Italy
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean Architecture
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night TurinAsync code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+k
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UK
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
 

Android Widget @ whymca 2011

  • 1. Android Widget Fabio Collini
  • 2. Speaker Fabio Collini @fabioCollini Tech Leader @ OmniaGroup http://www.omniagroup.it Android Developer Apps Organizer e Folder Organizer Blogger http://android.devapp.it http://www.cosenonjaviste.it
  • 3. Agenda Introduzione Esempio widget Android Scrollable widget Novità di Android 3.0/3.1
  • 5. Il punto di vista dello sviluppatore Package android.widget Contiene le view utilizzabili nelle interfacce Package android.appwidget Contiene le classi per gestire gli widget nella home
  • 6. Il punto di vista dell’utente
  • 8. Pro e contro Conviene aggiungere uno widget? Si! interazione facilitata con l’app funzionalità sempre a portata di mano categoria widget sul market No! impossibile spostare l’app sulla sd card
  • 10. Widget minimale Xml di definizione provider Layout Classe AppWidgetProvider
  • 11. res/xml/appwidget_provider.xml <?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android= "http://schemas.android.com/apk/res/android" android:minWidth="294dp" android:minHeight="72dp" android:updatePeriodMillis="86400000" android:initialLayout="@layout/appwidget_loading" />
  • 12. Attributi disponibili Calcolo della dimensione (numero di celle * 74) - 2 updatePeriodMillis millisecondi fra due aggiornamenti initialLayout layout iniziale widget può essere diverso dal layout definitivo
  • 13. Android manifest <receiver android:name=".PicturesAppWidgetProvider" android:label="1. Normal widget"> <meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_provider" /> <intent-filter> <action android:name= "android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> </receiver>
  • 14. Layout <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android" android:id="@+id/widget_layout" style="@style/widget_layout"> <ImageView android:id="@+id/img1" style="@style/picture_thumbnail" /> <ImageView android:id="@+id/img2" style="@style/picture_thumbnail" /> </LinearLayout>
  • 15. Layout limitati Layout: FrameLayout, LinearLayout e RelativeLayout View: AnalogClock Button Chronometer ImageButton ImageView ProgressBar TextView
  • 16. Stile layout <style name="widget_layout"> <item name="android:layout_width"> fill_parent</item> <item name="android:layout_height"> fill_parent</item> <item name="android:orientation">horizontal</item> <item name="android:gravity">center</item> <item name="android:layout_marginLeft">5dip</item> <item name="android:layout_marginRight">5dip</item> <item name="android:background"> @drawable/background</item> </style>
  • 17. res/drawable/background.xml <?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android= "http://schemas.android.com/apk/res/android"> <stroke android:width="2dp" android:color="#990634fd" /> <padding android:left="2dp" android:top="2dp" android:right="2dp" android:bottom="2dp" /> <corners android:radius="4dp" /> <solid android:color="#99FFFFFF" /> </shape>
  • 18. Android non è solo touch Device con trackball Gli utenti blackberry sono abituati a usarla Device con tastiera Possono contenere i tasti freccia Google TV non avrà un telecomando touch
  • 19. Stile immagini <style name="picture_thumbnail"> <item name="android:layout_width">120dip</item> <item name="android:layout_height">90dip</item> <item name="android:layout_margin">5dip</item> <item name="android:focusable">true</item> <item name="android:background"> @drawable/selection</item> </style>
  • 20. StateListDrawable <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android= "http://schemas.android.com/apk/res/android"> <item android:state_focused="true" android:drawable="@drawable/background" /> <item android:state_pressed="true" android:drawable="@drawable/background" /> </selector>
  • 22. AppWidgetProvider Estende BroadcastReceiver Riscrive onReceive, mette a disposizione: onUpdate onDeleted onEnabled onDisabled Bug su Android 1.5 http://groups.google.com/group/android-developers/msg/ e405ca19df2170e2
  • 23. AppWidgetProvider public class PicturesAppWidgetProvider extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { for (int i = 0; i < appWidgetIds.length; i++) { int appWidgetId = appWidgetIds[i]; updateAppWidget(context, appWidgetManager, appWidgetId); } } //... }
  • 24. updateAppWidget public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider); views.setImageViewResource(R.id.img1, R.drawable.img1); views.setImageViewResource(R.id.img2, R.drawable.img2); views.setOnClickPendingIntent(R.id.img1, AppWidgetUtils.createPendingIntent(context, 1)); views.setOnClickPendingIntent(R.id.img2, AppWidgetUtils.createPendingIntent(context, 2)); appWidgetManager.updateAppWidget(appWidgetId, views); }
  • 25. RemoteViews E’ una lista di comandi da effettuare I comandi vengono eseguiti in un altro processo Metodi con 3 parametri id di una view contenuta nel layout setter da richiamare valore da impostare Esempi di metodi setInt(int viewId, String methodName, int value) setString(int viewId, String methodName, String value)
  • 26. PendingIntent Intent da passare a una app esterna Creati con un metodo statico getActivity(Context context, int requestCode, Intent intent, int flags) getBroadcast(Context context, int requestCode, Intent intent, int flags) getService(Context context, int requestCode, Intent intent, int flags) Attenzione alla cache! requestCode: private request code for the sender (currently not used).
  • 27. PendingIntent public static Intent createIntent(Context ctx, int pos) { Intent intent = new Intent(ctx, PictureViewer.class); intent.putExtra(PictureViewer.IMAGE, "img" + pos); return intent; } public static PendingIntent createPendingIntent( Context ctx, int pos) { Intent intent = createIntent(ctx, pos); return PendingIntent.getActivity(ctx, pos, intent, 0); }
  • 28. Demo
  • 29. Activity di configurazione Può essere configurata nel file xml Utile quando il widget è configurabile Alla fine aggiorna manualmente il widget Aggiungiamo una configurazione al nostro esempio: checkbox per nascondere lo sfondo del widget
  • 30. appwidget_provider_config.xml <?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android= "http://schemas.android.com/apk/res/android" android:minWidth="294dp" android:minHeight="72dp" android:updatePeriodMillis="86400000" android:initialLayout="@layout/appwidget_loading" android:configure="org.whymca.appwidget.config. PicturesAppWidgetConfigure" />
  • 31. Configurazione nel manifest <activity android:name=".config.PicturesAppWidgetConfigure" android:theme="@android:style/Theme.Dialog" android:label="@string/Configure_widget"> <intent-filter> <action android:name= "android.appwidget.action.APPWIDGET_CONFIGURE" /> </intent-filter> </activity>
  • 32. PicturesAppWidgetConfigure public void save(View v) { boolean checked = showBackgroundCheck.isChecked(); PrefsSaver.saveShowBackground(this, mAppWidgetId, checked); PicturesAppWidgetProviderConfig.updateAppWidget( this, AppWidgetManager.getInstance(this), mAppWidgetId, checked); Intent resultValue = new Intent(); resultValue.putExtra( AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); setResult(RESULT_OK, resultValue); finish(); }
  • 33. Impostazione sfondo if (showBackground) { views.setInt(R.id.widget_layout, "setBackgroundResource", R.drawable.background); } else { views.setInt(R.id.widget_layout, "setBackgroundResource", 0); }
  • 34. Demo
  • 35. Attenzione su Android < 2.2 05‐02
22:35:41.544:
WARN/AppWidgetHostView(108):
 android.widget.RemoteViews$AcDonExcepDon:
view:
 android.widget.LinearLayout
can't
use
method
with
RemoteViews:
 setBackgroundResource(int)
  • 37. Home in landscape Alcune home non hanno orientation fissa A differenza delle Activity non è possibile decidere l’orientation I tablet sono in landscape Device con tastiera Occorre gestire i layout directory layout-landscape
  • 38. Immagini esterne E se prendiamo le immagini dalla scheda sd o dagli asset? Se le immagini sono troppo grandi: Errore di memoria nella RemoteViews! :(
  • 39. Uri per ContentProvider views.setImageViewUri(R.id.img1, createUri("img1")); views.setImageViewUri(R.id.img2, createUri("img2")); views.setImageViewUri(R.id.img3, createUri("img3")); views.setImageViewUri(R.id.img4, createUri("img4")); private static Uri createUri(String imageName) { return Uri.parse( "content://org.whymca.appwidget.pictures/" + imageName); }
  • 40. ContentProvider <provider android:name=".ImageContentProvider" android:authorities="org.whymca.appwidget.pictures" /> @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { String imageName = uri.getPath().substring(1); File tmpFile = getTempFile(getContext(), imageName); if (!tmpFile.exists()) { copyAssetFile(getContext(), imageName, imageName + ".JPG"); } try { return ParcelFileDescriptor.open(tmpFile, ParcelFileDescriptor.MODE_READ_ONLY); } catch (FileNotFoundException e) { return null; } }
  • 41. Timeout aggiornamento onUpdate viene eseguito nel thread principale possibili timeout al riavvio del device ci sono molte app in esecuzione pratica da seguire: spostare la logica in un service esterno
  • 42. Service public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { Intent intent = new Intent(context, PicturesAppWidgetService.class); intent.putExtra("appWidgetIds", appWidgetIds); context.startService(intent); }
  • 43. updatePeriodMillis Poco flessibile tutti gli widget sono aggiornati insieme e con la stessa frequenza Configurazione fissa è cablato in un xml Minimo 30 minuti anche se nel file xml viene specificato un valore minore Attivato anche con il telefono in stand by consumo eccessivo della batteria
  • 44. AlarmManager creare un nuovo alarm in onUpdate BroadcastReceiver definito nel manifest un alarm per ogni widget ogni widget viene aggiornato con frequenza diversa alarm non eseguito con telefono in stand by cancellare l’alarm in onDeleted
  • 45. Widget scrollable Forum http://groups.google.com/group/android-appwidget-extensions Esempio di utilizzo http://code.google.com/p/scrollablecontacts/
  • 46. Widget scrollable Vantaggi permettono di usare liste e griglie resize migliore Difetti funzionano solo con home replacement (ADW, LauncherPro, GoLauncher, Home++, ...) su LauncherPro devono essere abilitati manualmente lag dovuto a un bug (o feature!) di android http://code.google.com/p/android/issues/detail?id=4536
  • 47. Demo
  • 48. Widget Honeycomb Nuove view utilizzabili: ListView GridView StackView ViewFlipper AdapterViewFlipper
  • 49. Provider con controllo versione @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { if (Build.VERSION.SDK_INT >= 11) { for (int i = 0; i < appWidgetIds.length; i++) { HoneycombUtils.onUpdateTablet(context, appWidgetManager, appWidgetIds[i]); } } else { super.onUpdate(context, appWidgetManager, appWidgetIds); } }
  • 50. HoneycombUtils public static void onUpdateTablet(Context ctx, AppWidgetManager appWidgetManager, int id) { RemoteViews views = new RemoteViews(ctx.getPackageName(), R.layout.scrollable_layout); Intent adapterIntent = new Intent(ctx, PicturesService.class); adapterIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id); adapterIntent.setData(Uri.parse(adapterIntent.toUri( Intent.URI_INTENT_SCHEME))); views.setRemoteAdapter(id, R.id.grid, adapterIntent); PendingIntent clickPending = PendingIntent.getActivity(ctx, 0, new Intent(ctx, PictureViewer.class), PendingIntent.FLAG_UPDATE_CURRENT); views.setPendingIntentTemplate(R.id.grid, clickPending); appWidgetManager.updateAppWidget(id, views); }
  • 51. scrollable_layout.xml <?xml version="1.0" encoding="utf-8"?> <GridView xmlns:android= "http://schemas.android.com/apk/res/android" android:id="@+id/grid" android:layout_width="fill_parent" android:layout_height="fill_parent" android:numColumns="auto_fit" android:columnWidth="120dip" android:background="@drawable/background" />
  • 52. PictureService public class PicturesService extends RemoteViewsService { @Override public RemoteViewsFactory onGetViewFactory( Intent intent) { return new PicturesViewsFactory( this.getApplicationContext(), intent); } }
  • 53. PicturesViewFactory public class PicturesViewsFactory implements RemoteViewsService.RemoteViewsFactory { @Override public RemoteViews getViewAt(int position) { RemoteViews row = new RemoteViews(ctxt.getPackageName(), R.layout.scrollable_cell); row.setImageViewUri(R.id.appwidget_image, createUri("img" + (position + 1))); Intent intent = new Intent(); intent.putExtra(PictureViewer.IMAGE, "img" + (position + 1)); row.setOnClickFillInIntent(R.id.appwidget_image, intent); return row; } //...
  • 54. Demo
  • 55. Preview di uno widget L’emulatore Honeycomb contiene l’applicazione widget preview Configurazione preview <?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android= "http://schemas.android.com/apk/res/android" android:minWidth="368dp" android:minHeight="368dp" android:updatePeriodMillis="86400000" android:initialLayout="@layout/appwidget_loading" android:previewImage="@drawable/widget_preview" />
  • 57. Il futuro “Nuova” feature su Android 3.1 resize degli widget Tablet / Google TV su schermi grandi hanno più spazio nella home molto simile a un sistema operativo desktop
  • 58. Risorse Android developer http://developer.android.com/guide/topics/appwidgets/ index.html http://developer.android.com/guide/practices/ui_guidelines/ widget_design.html Scrollable widget http://groups.google.com/group/android-appwidget-extensions Honeycomb http://developer.android.com/sdk/android-3.0-highlights.html
  • 59. Thanks for your attention! Questions? Slide Presto disponibili su http://www.slideshare.net/ Sorgenti https://github.com/fabioCollini/whymca2011 Fabio Collini @fabioCollini http://www.omniagroup.it http://android.devapp.it http://www.cosenonjaviste.it

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. 10 minuti\n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n