{"id":11605,"date":"2016-03-07T15:48:05","date_gmt":"2016-03-07T14:48:05","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=11605"},"modified":"2016-06-07T14:53:17","modified_gmt":"2016-06-07T12:53:17","slug":"come-integrare-google-calendar-nelle-applicazioni-android","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/come-integrare-google-calendar-nelle-applicazioni-android\/","title":{"rendered":"Come integrare Google Calendar nelle applicazioni Android"},"content":{"rendered":"<p>Google Calendar \u00e8 probabilmente uno dei servizi di Mountain View pi\u00f9 utilizzati al mondo, non solo dall&#8217;utenza Android. Si tratta di uno dei primi strumenti che ha permesso a chiunque &#8211; anche se dotato di\u00a0capacit\u00e0 informatiche praticamente nulle &#8211; di memorizzare in maniera dettagliata i propri impegni, esperienze e attivit\u00e0 in una banca dati remota, sicura e utilizzabile in qualunque luogo.<\/p>\n<p>Non a caso, una delle curiosit\u00e0 che anima i <strong>programmatori Android<\/strong>,\u00a0ad ogni livello\u00a0di esperienza, \u00e8 proprio apprendere come integrare una semplice app Android con questo servizio in modo da renderlo un vero e proprio <em>backend<\/em> finalizzato allo scopo.<\/p>\n<p>In questo articolo vedremo come farlo, ne capiremo gli strumenti fondamentali e ne otterremo una dimostrazione con un semplice esempio.<\/p>\n<h2>Primo passo: impostiamo un progetto Google<\/h2>\n<p>Molti concetti che incontreremo nel corso del tutorial rappresentano i fondamenti comuni per l&#8217;accesso a tutti i\u00a0servizi Google. Uno di questi \u00e8 la configurazione di un &#8220;progetto&#8221;, la controparte remota con cui la nostra app dialogher\u00e0. Questo deve essere fatto all&#8217;interno di un pannello web chiamato\u00a0<a href=\"https:\/\/console.developers.google.com\" target=\"_blank\">Google Developers Console <\/a>cui potremo accedere\u00a0con un normalissimo account Gmail che probabilmente gi\u00e0 stiamo usando\u00a0da tempo per la posta elettronica.<\/p>\n<p>L&#8217;interfaccia che ci ospiter\u00e0\u00a0serve a gestire l&#8217;insieme dei progetti Google che fanno da backend alle nostre applicazioni\u00a0e se saremo al\u00a0nostro primo accesso alla console probabilmente sar\u00e0 vuoto.<strong> Creeremo il progetto<\/strong> tramite il pulsanse <em>Create Project<\/em> e la finestra di dialogo che si aprir\u00e0 non chieder\u00e0 altro che il nome da\u00a0assegnargli. Tale identificativo \u00e8 esclusivamente per uso &#8220;interno&#8221; alla console pertanto possiamo sceglierlo liberamente purch\u00e8 abbia per noi un significato preciso.<\/p>\n<p>Fatto ci\u00f2 avremo accesso direttamente ad un pannello in cui potremo gestire le risorse che fanno parte del singolo progetto. Abbiamo bisogno di fare due cose qui:<\/p>\n<ul>\n<li>abilitare le API per Google Calendar;<\/li>\n<li>definire una chiave di accesso che permetter\u00e0 alla nostra app il dialogo.<\/li>\n<\/ul>\n<p>Per <strong>abilitare le API<\/strong>, apriremo una sezione denominata API Manager e cercheremo, come mostrato in figura, le Calendar API. Una volta trovate sar\u00e0 sufficiente cliccarvi sopra e poi il tasto <em>Enable API<\/em> che apparir\u00e0 immediatamente.<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_01.jpg\" rel=\"attachment wp-att-11606\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11606\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_01.jpg\" alt=\"android-integrare-app-con-google-calendar_01\" width=\"1013\" height=\"370\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_01.jpg 1013w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_01-300x110.jpg 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_01-768x281.jpg 768w\" sizes=\"auto, (max-width: 1013px) 100vw, 1013px\" \/><\/a><\/p>\n<p>Per <strong>creare le chiavi di accesso<\/strong>\u00a0apriremo\u00a0il pannello <em>Credentials<\/em> dal menu laterale sinistro e chiederemo di avere un OAuth Client ID che fornir\u00e0 un tipo di autenticazione in grado di concedere\u00a0l&#8217;accesso agli account Google.<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_02.jpg\" rel=\"attachment wp-att-11607\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11607\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_02.jpg\" alt=\"android-integrare-app-con-google-calendar_02\" width=\"859\" height=\"618\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_02.jpg 859w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_02-300x216.jpg 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_02-768x553.jpg 768w\" sizes=\"auto, (max-width: 859px) 100vw, 859px\" \/><\/a><\/p>\n<p>Osservando la figura vediamo che i dati da fornire sono:<\/p>\n<ul>\n<li>il tipo di <strong>client ID<\/strong> che desideriamo: ovviamente, nel nostro caso sar\u00e0 di tipo Android;<\/li>\n<li>una<strong> chiave SHA1<\/strong> che come spiegato nel pannello stesso potr\u00e0 essere richiesta con il comando <em>keytool<\/em> fornendo come password android. L&#8217;output del programma conterr\u00e0 una chiave etichettata con il nome SHA1 e quello sar\u00e0 il valore da copiare nel campo di testo:<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_03.jpg\" rel=\"attachment wp-att-11608\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11608\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_03.jpg\" alt=\"android-integrare-app-con-google-calendar_03\" width=\"670\" height=\"125\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_03.jpg 670w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_03-300x56.jpg 300w\" sizes=\"auto, (max-width: 670px) 100vw, 670px\" \/><\/a><\/li>\n<li>il <strong>package Java<\/strong> che useremo nella nostra app Android.<\/li>\n<\/ul>\n<p>A questo punto potr\u00e0 essere creato il nostro client ID. Fondamentale ricordare che qualora il package realmente usato nel codice Java dell&#8217;app fosse diverso da quello inserito nella definizione delle credenziali Google, sar\u00e0 necessario cambiarlo o creare un altro client ID OAuth2.<\/p>\n<h2>Configurazione del progetto Android<\/h2>\n<p>La configurazione del nostro progetto in Android Studio passer\u00e0 invece per una corretta definizione del file <strong>build.gradle<\/strong>. Creando un nuovo progetto andr\u00e0 benissimo quello fornito dall&#8217;IDE ma il blocco delle dipendenze dovr\u00e0 richiedere il corretto set di librerie per la connessione ai servizi Google:<\/p>\n<pre class=\"lang:java decode:true \">...\r\n...\r\ndependencies {\r\n    compile fileTree(dir: 'libs', include: ['*.jar'])\r\n    compile 'com.android.support:appcompat-v7:23.0.1'\r\n    compile 'com.google.android.gms:play-services-identity:7.8.0'\r\n    compile('com.google.api-client:google-api-client-android:1.20.0') {\r\n        exclude group: 'org.apache.httpcomponents'\r\n    }\r\n    compile('com.google.apis:google-api-services-calendar:v3-rev125-1.20.0') {\r\n        exclude group: 'org.apache.httpcomponents'\r\n    }\r\n\r\n}\r\n...\r\n...<\/pre>\n<p>Anche il file <strong>AndroidManifest.xml<\/strong> sar\u00e0 piuttosto semplice ma dovremo fare attenzione a rispettare due regole:<\/p>\n<ul>\n<li>al di fuori del nodo &lt;application&gt; predisporremo le giuste<strong> permission<\/strong> per l&#8217;accesso a Internet, la consultazione dello stato di Rete e la gestione di credenziali e account;<\/li>\n<li>all&#8217;interno del nodo &lt;application&gt; inseriremo un blocco di tipo &lt;meta-data&gt; in cui sar\u00e0 specificata, tramite una costante, la <strong>versione dei Google Play Services<\/strong> che stiamo utilizzando.<\/li>\n<\/ul>\n<pre class=\"lang:xhtml decode:true\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\r\n&lt;manifest xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\r\n    package=\"it.devapp.googlecalendarintegration\" &gt;\r\n\r\n    &lt;uses-permission android:name=\"android.permission.INTERNET\" \/&gt;\r\n    &lt;uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" \/&gt;\r\n    &lt;uses-permission android:name=\"android.permission.GET_ACCOUNTS\" \/&gt;\r\n    &lt;uses-permission android:name=\"android.permission.MANAGE_ACCOUNTS\" \/&gt;\r\n    &lt;uses-permission android:name=\"android.permission.USE_CREDENTIALS\" \/&gt;\r\n\r\n    &lt;application\r\n        android:allowBackup=\"true\"\r\n        android:icon=\"@mipmap\/ic_launcher\"\r\n        android:label=\"@string\/app_name\"\r\n        android:supportsRtl=\"true\"\r\n        android:theme=\"@style\/AppTheme\" &gt;\r\n        &lt;meta-data\r\n            android:name=\"com.google.android.gms.version\"\r\n            android:value=\"@integer\/google_play_services_version\" \/&gt;\r\n\r\n        &lt;activity android:name=\".MainActivity\" &gt;\r\n            &lt;intent-filter&gt;\r\n                &lt;action android:name=\"android.intent.action.MAIN\" \/&gt;\r\n\r\n                &lt;category android:name=\"android.intent.category.LAUNCHER\" \/&gt;\r\n            &lt;\/intent-filter&gt;\r\n        &lt;\/activity&gt;\r\n    &lt;\/application&gt;\r\n\r\n&lt;\/manifest&gt;<\/pre>\n<h2>Struttura dell&#8217;esempio<\/h2>\n<p>Lo scopo del nostro esempio \u00e8 vedere le fasi di accesso al Google Calendar da app Android. Lo faremo inserendo degli eventi in un calendario manualmente, ad esempio tramite il nostro smartphone, e recuperando dall&#8217;app gli eventi di un dato periodo e mostrandoli in una\u00a0normale ListView. Non mostreremo nell&#8217;esempio le fasi dell&#8217;inserimento tramite codice ma, come accenneremo, useranno gli stessi strumenti della lettura.<\/p>\n<p>Queste le fasi dell&#8217;esperimento:<\/p>\n<ul>\n<li>nel metodo <em>onCreate<\/em> inizializzeremo Adapter e ListView che ci serviranno per mostrare i risultati dell&#8217;elaborazione e, successivamente, invocheremo la classe <em>GoogleAccountCredential<\/em> per l&#8217;accesso tramite OAuth2;<\/li>\n<li>in <em>onResume<\/em> verificheremo la disponibilit\u00e0 dei Google Play Services nel dispositivo ed in caso affermativo invocheremo un Intent che mostrer\u00e0 all&#8217;utente una finestra di dialogo per la scelta dell&#8217;account che possiede il calendario da gestire. Ovviamente se l&#8217;account non fosse ancora configurato sul dispositivo verr\u00e0 richiesto all&#8217;utente di inserire le corrette credenziali;<\/li>\n<li>effettuato l&#8217;accesso potremo svolgere la vera interrogazione a Google Calendar e lo faremo in background creando una derivazione della classe <em>AsyncTask<\/em>.<\/li>\n<\/ul>\n<p>La query che effettueremo sul calendario restituir\u00e0 una lista di oggetti <em>Event<\/em> ognuno dei quali contenente\u00a0i soliti dati che siamo abituati ad inserire registrando a mano i nostri impegni.<\/p>\n<h2>Il nostro Adapter<\/h2>\n<p>Per visualizzare gli eventi, creeremo un nostro adapter che estende\u00a0la classe <em>ArrayAdapter<\/em>. Di ogni evento verranno visualizzati solo due campi: il summary e la data di inizio dell&#8217;evento. Ovviamente sulla falsa riga di quanto faremo qui insieme l&#8217;esempio pu\u00f2 essere espanso a volont\u00e0.<\/p>\n<p>Questa la classe EventAdapter:<\/p>\n<pre class=\"lang:java decode:true \">public class EventAdapter extends ArrayAdapter&lt;Event&gt;\r\n{\r\n    private List&lt;Event&gt; events;\r\n    private Context context;\r\n    private int layoutId;\r\n    private SimpleDateFormat simple=new SimpleDateFormat(\"dd\/MM\/yyyy\");\r\n\r\n    public EventAdapter(Context context, int resource) {\r\n        super(context, resource);\r\n        this.context=context;\r\n        layoutId=resource;\r\n    }\r\n\r\n    @Override\r\n    public void addAll(Collection&lt;? extends Event&gt; collection) {\r\n        clear();\r\n        super.addAll(collection);\r\n    }\r\n\r\n    @Override\r\n    public View getView(int position, View convertView, ViewGroup parent) {\r\n        Event e=getItem(position);\r\n        \r\n        View v= LayoutInflater.from(context).inflate(layoutId, null);\r\n        TextView txt_event= (TextView) v.findViewById(R.id.event);\r\n        TextView txt_date= (TextView) v.findViewById(R.id.date);\r\n\r\n        Calendar cal=Calendar.getInstance();\r\n        DateTime dt=e.getStart().getDateTime();\r\n        if (dt==null)\r\n            dt=e.getStart().getDate();\r\n        cal.setTimeInMillis(dt.getValue());\r\n\r\n        txt_event.setText(e.getSummary());\r\n        txt_date.setText(simple.format(cal.getTime()));\r\n        return v;\r\n    }\r\n}\r\n<\/pre>\n<p>Il metodo <em>getView<\/em> presente in ogni Adapter \u00e8 stato sottoposto a <em>override<\/em> per personalizzare la visualizzazione. Si noti che si controlla se il metodo <em>getDateTime<\/em> ha restituito un valore null in quanto ci\u00f2 si verifica quando\u00a0l&#8217;evento copre l&#8217;intera giornata e non solo alcune ore.<\/p>\n<p>Il layout che da forma alle singole righe della ListView \u00e8 molto semplice &#8211; due TextView in un LinearLayout &#8211; e verr\u00e0 posto nel file di risorse <strong>\/res\/layout\/row.xml<\/strong>:<\/p>\n<pre class=\"lang:xhtml decode:true \">&lt;LinearLayout xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:padding=\"15dp\"\r\n    android:background=\"#48B1F7\"\r\n    android:orientation=\"vertical\"&gt;\r\n    &lt;TextView\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:textColor=\"#FFFFFF\"\r\n        android:textSize=\"20dp\"\r\n        android:textStyle=\"bold\"\r\n        android:id=\"@+id\/event\"\/&gt;\r\n    &lt;TextView\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:textColor=\"#FFFFFF\"\r\n        android:textSize=\"15dp\"\r\n        android:id=\"@+id\/date\"\/&gt;\r\n&lt;\/LinearLayout&gt;<\/pre>\n<p>&nbsp;<\/p>\n<h2>L&#8217;Activity<\/h2>\n<p>Infine arriviamo alla nostra Activity:<\/p>\n<pre class=\"lang:java decode:true\">public class MainActivity extends ListActivity {\r\n    static final int REQUEST_ACCOUNT_PICKER = 101;\r\n    static final int REQUEST_GOOGLE_PLAY_SERVICES = 102;\r\n\r\n    GoogleAccountCredential login;\r\n\r\n    private static final String[] SCOPES = { CalendarScopes.CALENDAR_READONLY };\r\n\r\n    private EventAdapter adapter;\r\n\r\n    @Override\r\n    protected void onCreate(Bundle savedInstanceState) {\r\n        super.onCreate(savedInstanceState);\r\n        adapter=new EventAdapter(this, R.layout.row);\r\n        setListAdapter(adapter);\r\n        getListView().setDividerHeight(10);\r\n\r\n        login = GoogleAccountCredential.usingOAuth2(\r\n                getApplicationContext(), Arrays.asList(SCOPES))\r\n                .setBackOff(new ExponentialBackOff())\r\n                .setSelectedAccountName(null);\r\n    }\r\n\r\n    @Override\r\n    protected void onResume() {\r\n        super.onResume();\r\n        if (isGooglePlayServicesAvailable()) {\r\n            if (login.getSelectedAccountName() == null) {\r\n                startActivityForResult(login.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);\r\n            } else {\r\n                if (isConnected()) {\r\n                    new CalendarQueryTask(login).execute();\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    @Override\r\n    protected void onActivityResult(\r\n            int requestCode, int resultCode, Intent data) {\r\n        super.onActivityResult(requestCode, resultCode, data);\r\n        switch(requestCode) {\r\n            case REQUEST_GOOGLE_PLAY_SERVICES:\r\n                if (resultCode != RESULT_OK) {\r\n                    isGooglePlayServicesAvailable();\r\n                }\r\n                break;\r\n            case REQUEST_ACCOUNT_PICKER:\r\n                if (resultCode == RESULT_OK &amp;&amp; data != null &amp;&amp;\r\n                        data.getExtras() != null) {\r\n                    String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);\r\n                    if (accountName != null) {\r\n                        login.setSelectedAccountName(accountName);\r\n                    }\r\n                }\r\n        }\r\n\r\n        super.onActivityResult(requestCode, resultCode, data);\r\n    }\r\n\r\n    private boolean isConnected() {\r\n        ConnectivityManager connMgr =\r\n                (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);\r\n        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();\r\n        return (networkInfo != null &amp;&amp; networkInfo.isConnected());\r\n    }\r\n\r\n    private boolean isGooglePlayServicesAvailable() {\r\n        final int connectionStatusCode =\r\n                GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);\r\n        if (GooglePlayServicesUtil.isUserRecoverableError(connectionStatusCode)) {\r\n            GooglePlayServicesUtil.getErrorDialog(\r\n                    connectionStatusCode,\r\n                    this,\r\n                    REQUEST_GOOGLE_PLAY_SERVICES).show();\r\n            return false;\r\n        } else if (connectionStatusCode != ConnectionResult.SUCCESS ) {\r\n            return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    private class CalendarQueryTask extends AsyncTask&lt;Void, Void, List&lt;Event&gt;&gt; {\r\n        private com.google.api.services.calendar.Calendar mService = null;\r\n        private ProgressDialog progress=null;\r\n\r\n        public CalendarQueryTask(GoogleAccountCredential credential) {\r\n            HttpTransport client = AndroidHttp.newCompatibleTransport();\r\n            JsonFactory json = JacksonFactory.getDefaultInstance();\r\n            mService = new com.google.api.services.calendar.Calendar.Builder(\r\n                    client, json, credential)\r\n                    .build();\r\n        }\r\n\r\n        @Override\r\n        protected List&lt;Event&gt; doInBackground(Void... params) {\r\n            try {\r\n                DateTime now = new DateTime(System.currentTimeMillis());\r\n\r\n                Events events = mService.events()\r\n                        .list(\"primary\")\r\n                        .setMaxResults(10).setTimeMin(now).setOrderBy(\"startTime\")\r\n                        .setSingleEvents(true)\r\n                        .execute();\r\n                return events.getItems();\r\n            } catch (Exception e) {\r\n                \/\/ gestione dell'errore\r\n                return null;\r\n            }\r\n        }\r\n\r\n        @Override\r\n        protected void onPreExecute() {\r\n\r\n            progress=ProgressDialog.show(MainActivity.this,\"Google Calendar\", \"Collegamento in corso...\",true);\r\n            progress.show();\r\n        }\r\n\r\n        @Override\r\n        protected void onPostExecute(List&lt;Event&gt; output) {\r\n            if (progress!=null)\r\n                progress.dismiss();\r\n            adapter.addAll(output);\r\n        }\r\n    }\r\n}<\/pre>\n<p>Buona parte del funzionamento gira attorno\u00a0al metodo <em>onResume<\/em>. In esso si controlla se \u00e8 gi\u00e0 stato associato un nome di account all&#8217;oggetto di classe GoogleAccountCredential che si occuper\u00e0 del login presso il servizio. Se \u00e8 ancora nullo si far\u00e0 apparire una finestra con cui Android chieder\u00e0 di selezionare un account presente\u00a0nel\u00a0sistema o di\u00a0registrarne uno nuovo. Pronte le credenziali\u00a0si eseguir\u00e0 il task in background rappresentato dalla classe <em>CalendarQueryTask<\/em>. Questo richieder\u00e0 i dati nel metodo\u00a0<em>doInBackground<\/em> che agisce su un thread secondario mentre i metodi <em>onPreExecute<\/em> e <em>onPostExecute<\/em> si occuperanno, rispettivamente, di far apparire la finestra con la barra di progresso e di farla scomparire con contestuale aggiornamento dell&#8217;adapter.<\/p>\n<p>Da notare che all&#8217;interno del costruttore di CalendarQueryTask viene allocato un oggetto Calendar che costituir\u00e0 il nostro collegamento al servizio. Tramite questo potremo fare varie operazioni. Noi effettueremo una query con il metodo <em>list <\/em>invocato sulla collezione di eventi<em> events\u00a0<\/em>e nello specifico chiederemo dieci eventi a partire dalla data di oggi.<\/p>\n<p>I passi indicati nel codice come l&#8217;accesso tramite credenziali e la verifica della disponibilit\u00e0 dei\u00a0Google Play Services nel terminale (metodo isGooglePlayServicesAvailable) incontrati\u00a0nell&#8217;esempio sono utili sia in altri tipi di interazione con Calendar API sia nel dialogo con altri servizi di Big G.<\/p>\n<p>Per effettuare la vera sperimentazione, potremo aprire l&#8217;app Calendar nel nostro dispositivo Android ed inserire manualmente un paio di eventi.<\/p>\n<p>Uno per il 31 dicembre:<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_04.jpg\" rel=\"attachment wp-att-11631\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11631\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_04.jpg\" alt=\"android-integrare-app-con-google-calendar_04\" width=\"426\" height=\"300\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_04.jpg 426w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_04-300x211.jpg 300w\" sizes=\"auto, (max-width: 426px) 100vw, 426px\" \/><\/a><\/p>\n<p>e l&#8217;altro per l&#8217;8 gennaio:<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_05.jpg\" rel=\"attachment wp-att-11632\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11632\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_05.jpg\" alt=\"android-integrare-app-con-google-calendar_05\" width=\"433\" height=\"311\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_05.jpg 433w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_05-300x215.jpg 300w\" sizes=\"auto, (max-width: 433px) 100vw, 433px\" \/><\/a><\/p>\n<p>La nostra app mostrer\u00e0 il seguente layout:<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_06.jpg\" rel=\"attachment wp-att-11633\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11633\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_06.jpg\" alt=\"android-integrare-app-con-google-calendar_06\" width=\"480\" height=\"300\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_06.jpg 480w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2015\/12\/android-integrare-app-con-google-calendar_06-300x188.jpg 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h2>Conclusioni<\/h2>\n<p>Quello che abbiamo visto in questo tutorial ha una sua utilit\u00e0 ma non \u00e8 che l&#8217;inizio. Consultando la\u00a0<a href=\"https:\/\/developers.google.com\/google-apps\/calendar\/\" target=\"_blank\">documentazione delle API<\/a>\u00a0si potr\u00e0 vedere come aggiungere tante altre funzionalit\u00e0\u00a0partendo comunque dagli stessi fondamenti: creazione di un progetto Google, gestione delle credenziali, collegamento al servizio ed infine invocazione dei metodi necessari.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Google Calendar \u00e8 probabilmente uno dei servizi di Mountain View pi\u00f9 utilizzati al mondo, non solo dall&#8217;utenza&#8230;<\/p>\n","protected":false},"author":561,"featured_media":11848,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[1535,1279,1635,1583,969],"class_list":["post-11605","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorial-pratici","tag-android-developers","tag-api-google","tag-google-calendar-android","tag-google-play-services","tag-programmatori-android"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11605","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/561"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=11605"}],"version-history":[{"count":12,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11605\/revisions"}],"predecessor-version":[{"id":12093,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11605\/revisions\/12093"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media\/11848"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=11605"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=11605"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=11605"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}