Cerca con Google

Translate

13 dicembre 2012

Tutorial 40 - Inviare email con allegati da App Inventor


Premessa: Questo è un tutorial abbastanza complicato, infatti App Inventor nativamente non offre la possibilità di inviare email con allegati.

Il tutorial è composto solo da testo e screenshot, l'utente deve avere una buona padronanza sia di App Inventor che dei servizi Google in generale

Detto questo, vediamo come, sfruttando uno script python caricato su Google App Engine è possibile inviare da App Inventor delle mail con anche un allegato.

Il metodo non usa activitystarter (come visto nel tutorial 14) e quindi non si aprirà il client gmail, ma usa il componente web per dialogare con il web service, volendo la mail viene mandata anche senza premere un tasto "send" visto che si usa il componente web col metodo POST.


Vediamo i requisiti richiesti:
1 - Account su Google App Engine (gratuito per il servizio base)
2 - Installazione di Python
3 - Installazione di Google App Engine per Python

Queste invece le limitazioni:
1 - Possibilità di inviare allegati di dimensione massima 1Mb
2 - Possibilità di inviare massimo 100 email al giorno
3 - Il mittente della mail è fisso ed è definito all'interno dello script python

Pagando il servizio App Engine si possono superare le limitazioni 1 e 2, il tutorial considera solo le possibilità date dall'account "base" e quindi ha tutte e 3 le limitazioni elencate sopra.

Scaricate il file sorgente per App Inventor App Inventor Source File
e il pacchetto zip contenente lo script in python App Engine Python code

Partiamo con la creazione di un account su Google App Engine


visitiamo la pagina https://developers.google.com/appengine/ e colleghiamo il nostro account google al servizio.
Poi clicchiamo su Google App Engine SDK for Python e scarichiamo il file .msi del pacchetto di installazione:


Andiamo ora a scaricare Python da http://www.python.org/download/, scegliamo l'ultima versione disponibile del branch 2.7 (versione 32 o 64 bit a seconda del vostro s.o.)


Cominciamo le installazioni partendo da Python:


In questo tutorial lascio tutte le destinazioni e tutte le opzioni di default
Installiamo ora App Engine for Python (come vedete trova la precedente installazione di Python che è prerequisito per il corretto funzionamento di App Engine)




Se tutto ha funzionato correttamente potrete eseguire "Run Launcher" (che utilizzeremo tra poco) lasciando la finestra per il momento in background...

Torniamo in App Engine e creiamo la nostra nuova applicazione, tale applicazione sarà il cuore vero e proprio della nostra app.
E' un programma scritto in Python che crea un web service per la gestione dell'invio delle mail, si ringrazia sentitamente l'autore ShivalWolf (shivalwolf@gmail.com), David Wolber (wolber@usfca.edu) e Hal Abelson per il tutorial originale che trovate qua

Non vi preoccupate ci sono solo poche righe di codice da cambiare, se conoscete un pò di Python o java forse potete anche capirci qualcosa di quel che c'è scritto li dentro ... :) io sinceramente non ho analizzato più di tanto la cosa...

Torniamo su https://appengine.google.com/ e selezioniamo Create Application:


Ora inseriamo questi dati con molta attenzione:


E facciamo particolare attenzione al campo "Application Identifier", questo dovrà essere identico a quello inserito nel file app.yaml alla voce application,
potete (e dovete) ovviamente inserire un nome qualsiasi (non quello del mio esempio!), mettetelo tutto minuscolo e senza spazi e segnatevelo da qualche parte...

Lanciamo ora Google App Engine Launcher cercandolo nel nostro menù start:


Carichiamo ora il nostro script scegliendo la directory in cui lo abbiamo precedentemente salvato (File - Add Existing Application), la directory è quella dove avrete scaricato il file python linkato all'inizio dell'articolo


Dopo aver caricato il progetto selezioniamo la voce Edit per editare il file app.yaml


Qui alla voce application dobbiamo scrivere esattamente lo stesso nome applicazione che avevamo dato come "Application Identifier" nell'interfaccia web di App Engine

Ora usando un qualsiasi text editor apriamo il file main.py (è un normale file di testo, io consiglio PSPad per l'editing dei file, freeware e molto versatile)


Qui dobbiamo indicare l'indirizzo mail da cui partiranno le email nella nostra applicazione, tale indirizzo deve essere un amministratore dell'app che gira in App Engine, quindi può essere lo stesso che avete usato per la registrazione ad AE oppure un altro a patto che venga aggiunto poi come amministratore di questa app in App Engine
Authkey è la chiave per l'autenticazione in AE, deve essere uguale a quella che poi inseriremo nel blocks editor (nell'esempio qui sopra è "randomvalue", potete lasciarla così o mettere un'altra stringa, se la cambiate ricordate di cambiarla anche in blocks editor...)

A questo punto possiamo provare a far girare lo script in locale sul nostro pc, premiamo Run e poi Logs:


Se è tutto corretto vedremo una schermata che ci dice che l'app sta girando correttamente:


Allora a questo punto possiamo fare il "deploy" della nostra app in App Engine, in pratica stiamo caricando il nostro script nei server di Google e lo rendiamo disponibile come un servizio web per la nostra app che poi andremo a scrivere:


Inseriamo le nostre credenziali di accesso a Google App Engine e premiamo ok, si aprirà un'altra finestra dopo circa 30 secondi dovremmo avere questo risultato:


In pratica ci conferma che l'app è caricata in App Engine e sta girando correttamente.

Passiamo ora a vedere rapidamente la nostra app creata in App Inventor, ovviamente io vi ho messo a disposizione un esempio solo per farvi capire il funzionamento base poi starà a voi personalizzare l'app in base alle vostre esigenze. (tra l'altro il mio esempio NON funziona perchè ho cambiato appositamente il nome dell'app e l'indirizzo email sia nello script che nell'app App Inventor...) :)

Vi consiglio di aprire a tutto schermo l'immagine del blocks editor in modo da poterla consultare più comodamente:


Ovviamente cambiamo eventualmente "AuthKey" con la chiave che abbiamo messo nel file main.py

"AppEngine_Address" deve essere uguale al nostro ApplicationIdentifier, preceduto da https:// (nel mio esempio https://seblogappemail.appspot.com)

"Attachment" può avere il valore di true o false, se è true bisogna specificare in "FiletoAttach" il path completo del file da allegare e in "FileNAME" solo il nome del file
se è false la mail viene inviata senza allegati

Il servizio in python che abbiamo creato funziona tramite il componente web ed il metodo POST e vuole la seguente sintassi:

  • 1st Field = AuthKey
  • 2nd Field = To Address
  • 3rd Field = Subject
  • 4th Field = Body
  • 5th Field = (yes/no) if you have an attachment
  • 6th Field = attachment file name
  • 7th Field = attachment ID (This is provided by the code)

Tutti questi campi vanno separati dai tre caratteri "|||" come vedete nel blocks editor

Guardiamo solo la parte di quando si clicca il pulsante Send:
prima verifica se ci sono tutti i campi compilati con la funzione TestFields,se ok controllo poi se ho attachment true o false, partiamo dal caso in cui non si abbia attachment,

in pratica vedete che basta impostare la chiamata al componente web dandogli l'url del nostro servizio App Engine con il suffisso /sendemail per dire che vogliamo mandare una mail e poi comporre la parte Post con una grossa "make text" dove passiamo tutti i parametri come abbiamo visto nelle istruzioni di poco fa, quindi in questo caso solo AuthKey, email destination, subject e body tutti separati dal testo "|||"

App Engine a questo punto analizzerà la richiesta http POST ed invierà la mail come specificato in App Inventor, senza ulteriore interazione da parte dell'utente.

L'altro grosso blocco relativo a Web1.GotText gestisce il codice di ritorno di App Engine e ci dice se la mail è stata inviata correttamente o meno andando a vedere cosa ritorna in responseContent
In realtà questo blocco gestisce anche l'eventuale allegato, è un pò complicato da spiegare ma, se si lavora con l'allegato bisogna fare due richieste POST;
prima si fa una POST con il comando /attach e si da il file da allegare,
la prima risposta nel GotText da App Engine sarà FileAttached: con un hash univoco che indica il nostro file nei server App Engine, a quel punto si rifà un'altra richiesta di POST con /sendmail ma stavolta anche con l'attach specificato però come appunto "hash" + filename che può così essere correttamente letto da App Engine (il valore dell'hash ce lo ha dato App Engine stesso alla prima richiesta POST)

Il tutto suona abbastanza complicato ma caricando voi l'app e facendo un pò di test son sicuro capirete meglio il funzionamento.

E' possibile monitorare le richieste che arrivano ad App Engine accedendo alla finestra dei log (in Admin Console)
per esempio dopo aver mandato una mail con attach vedremo una cosa di questo tipo:


Dove si possono vedere le due richieste, la prima con /attach e la seconda con /sendmail (ed i relativi parametri)
Se la richiesta non va a buon fine avremo un log con un messaggio d'errore (tipo se l'attach supera 1Mb)

Nel nostro esempio l'app mostrava questo, dopo aver premuto il tasto Send partono le richieste ad AE:


Quando scrive "Email Sent" ovviamente vuol dire che la mail è stata inviata correttamente, se ci fosse qualche errore lo visualizzerete o nell app o tramite notifier che vi compare direttamente nello smartphone (per esempio se sbagliate il path del file da mettere in allegato vedrete errore 1104)
la mail ricevuta in gmail è questa (ovviamente possiamo spedire a qualunque indirizzo mail)


Phew! abbiamo finito, come vedete la cosa non è per nulla semplice e le limitazioni sono alquanto fastidiose (ma d'altronde Google non ci può regalare proprio tutto ed App Engine è spesso dedicato ad un utenza business)
Ma potrebbe essere interessante realizzare nella nostra app una parte per l'invio delle mail in automatico usando il metodo qui esposto.
Con relativamente poche modifiche si può anche allegare alla mail una foto scattata dalla fotocamera (usando il componente camera e poi l'imagepicker e impostando correttamente il path e il nome della foto scattata)
oppure un immagine presa dalla galleria, le opzioni ovviamente sono molte e limitate quasi solo dalla nostra fantasia!!!

Per le discussioni (se mi avete letto fin qua) usate il forum o i commenti qui sotto
a presto! ormai potete fregiarvi dell'appellativo di Masters of App Inventor :)

31 commenti:

  1. Ciao,
    grazie per la tua guida.
    Ho un problema: quando provo a far girare lo script in locale sul pc, premendo Run e poi Logs trovo questo messaggio:

    run_file(__file__, globals())
    File "C:\Program Files (x86)\Google\google_appengine\dev_appserver.py", line 167, in run_file
    execfile(script_path, globals_)
    NameError: global name 'execfile' is not defined
    2013-01-24 14:47:05 (Process exited with code 1)

    Mi sapresti dire come risolverlo?

    RispondiElimina
    Risposte
    1. non sono esperto ma con una rapida ricerca ho trovato questa pagina:

      http://stackoverflow.com/questions/10227142/nameerror-global-name-execfile-is-not-defined-trying-to-run-an-app-on-google

      dice di andare nelle preferences di App Engine e specificare il percorso esatto della tua installazione di Python

      Elimina
    2. OK, ho trovato il problema.
      Non funziona con la nuova versione 3.3 di Python. Occorre installare la 2.7.3 e dopo funziona.
      Grazie per la dritta.

      Elimina
    3. Ottimo! in effetti c'era anche scritto nel tutorial...versione 2.7 :)
      cmq meglio così, ora tutto ti funziona! buon lavoro! :)

      Elimina
  2. Ciao! Grazie anche da parte mia per l'utilissimo blog che hai creato e complimenti per la tua competenza! Volevo chiederti se grazie ad app inventor è possibile creare app di livello piu' basso, accedere cioe' un po' piu' approfonditamente all'hardware del telefono. Ti faccio un esempio banale: se volessi creare un'app "torcia" (come gia' ne esistono tante) e volessi quindi accendere il flash alla pressione di un tasto, sarebbe possibile? Ci sono api documentate? Infine vorrei chiederti se farai tutorial sull'integrazione delle app in social network come facebook (vedi ruzzle ad esempio). Grazie e complimenti ancora! Fabrizio Tornaboni

    RispondiElimina
    Risposte
    1. Ciao Fabrizio, tutto quello che si può fare in AI dipende dai blocchi che il MIT mette a disposizione, ad esempio non esiste ancora un blocco "torcia" ma sarebbe possibile implementarlo (se lo volessero fare ovvio), c'è tutta una documentazione tecnica sul come aggiungere componenti ad app inventor utilizzando ovviamente java ed eclipse, ma la cosa è parecchio complicata (e per il momento non ho tempo e capacità per lavorarci sopra)

      Quindi per capire cosa si può e non si può fare con AI, il primo passo è quello di controllare nella palette del design editor gli elementi che possiamo inserire nell'applicazione.

      Esiste poi l'activitystarter che "lancia" altre app presenti sul telefono, può essere che ci sia un activity che attiva il flash ma sinceramente dovrei approfondire la cosa cercando in giro...

      Stessa cosa più o meno per l'integrazione coi social, anzi qui la cosa si fa più complicata perchè in genere c'è un'autenticazione da effettuare con il sito del social e dei token che vengono scambiati dal server web all'app,
      ad esempio in AI abbiamo il componente Twitter che si occupa dell'autenticazione e del dialogo con le api di twitter ma per fb non esiste nulla.
      Un tutorial su Twitter lo vorrei fare ed è nella "to-do" list :)

      Elimina
    2. Ok, ho iniziato personalmente a fare delle ricerche sulle api di android. In questa pagina http://developer.android.com/guide/topics/media/camera.html è descritta l'api della camera, mentre in questa http://developer.android.com/guide/topics/manifest/uses-feature-element.html#hw-features ci sono tutte le reference (sempre della camera) e come vedi e' anche contemplato il flash. E' possibile secondo te controllare queste chiamate con Activity starter? Secondo me si! Vorrei solo cercare di capire insieme a te (se vuoi ovviamente) come utilizzare queste api con l'activity starter, perche' a questo punto avremmo il controllo completo del telefono al di la' degli oggetti presenti in AI! Voglio ricordarti infine che ovviamente quello del flash e dell'applicazione "torcia" e' solo un esempio banale, il piu' facile che mi sia venuto in mente! E' chiaro che nn avrebbe senso implementare un oggetto "torcia" in AI :) complimenti ancora sebastiano! Fabrizio

      Elimina
    3. Ciao Fabrizio,complimenti per le tue ricerche, però ho qualche dubbio che con activitystarter si possano usare tutte le API di android, infatti per poterle usare bisogna che queste siano esposte al sistema tramite appunto un activity ed un intent, e dal quel che ho capito non tutti i programmi sono "aperti" al controllo tramite altre app.
      Ti consiglio di leggerti (se non lo hai già fatto) la documentazione per l'activitystarter di AI che trovi a questa pagina http://beta.appinventor.mit.edu/learn/reference/other/activitystarter.html
      per esempio è possibile lanciare l'app per la fotocamera (perchè esiste l'intent che esegue l'app fotocamera sul telefono) ma non poi controllarne il flash o altre caratteristiche.
      Ad ogni modo con logcat in esecuzione puoi vedere se lanciando la camera e poi il flash ti esce da debuglog la stringa con l'intent e la classe per l'attivazione del flash.
      Credo più semplicemente che sia possibile attivare il flash usando tramite AI altre applicazioni che si trovano sul market e che controllano solo il flash, a quel punto "basterebbe" da AI chiamare un activitystarter con i parametri giusti per l'esecuzione del programma "flash" ma la soluzione ovviamente non è ottimale perchè costringe ad avere app non di sistema installate.
      Ti lascio con questo ottimo google docs dove alcuni sviluppatori di AI hanno elencato tutte (o quasi) le possibili azioni che si possono fare con activitystarter in AI:
      https://docs.google.com/spreadsheet/ccc?key=0AmF-kDWbm3w4dHNnQWtWLUR5Nkc2TFk2ZjRPRWRqM0E&hl=en#gid=10

      Per tornare al discorso iniziale penso che fosse così semplice usare tutte le api di android in AI lo avrebbero già fatto e già documentato diffusamente
      ovviamente tutte queste sono solo mie opinioni e non è detto che io abbia per forza ragione :)

      Elimina
  3. Grande!!!! OTTIMO DOCUMENTO!!! Infatti alle riga 5 di 2.2 froyo ed alla 6 di 2.3 Gingerbread come vedi compare android.hardware.camera.flash !!!! Il mio vero problema è che ancora non riesco a capire la logica da utilizzare per effettuare queste chiamate su activitystarter, ovvero come compilarne correttamente i parameri in base alla chiamata di esempio (android.hardware.camera.flash). Se riuscissi a capirne la logica potrei poi da solo addentrarmi nelle Api per sperimentarne i vari aspetti. Io ho sempre sviluppato applicazioni desktop ma come ben sai qui la faccenda è un po' diversa....vorreo solo capire meglio la compilazione dei parametri di activity starter. Conosci delle buone guide in merito? Mi basterebbe un esempio con da una parte l'api e dall'altra activity starter compilato correttamente in base a quella chiamata e PERCHE' si compila cosi'! A me interessano i concetti...ho sempre sposato la massima "Se vuoi far del bene a chi e' affamato, non portargli del pesce, insegnagli a pescare!" :-). Ritengo che l'utilizzo delle api associato ad AI formino veramente lo strumento piu' potente per lo sviluppo su android!

    RispondiElimina
    Risposte
    1. Prova prima a leggere la parte di guida relativa agli activitystarter
      http://beta.appinventor.mit.edu/learn/reference/other/activitystarter.html
      poi si tratta di capire come compilare i campi, se vedi nello stesso gdocs al tab stock o action (https://docs.google.com/spreadsheet/ccc?key=0AmF-kDWbm3w4dHNnQWtWLUR5Nkc2TFk2ZjRPRWRqM0E&hl=en#gid=2) ci sono proprio anche tutti i campi da compilare per l'activitystarter (activityclass,package,etc...)
      Puoi fare un pò di tentativi come descrive la prima guida linkata, la cosa migliore è lavorare con il logcat aperto così vedi nel Log l'activity che viene richiamato,
      ad esempio, nell'help di AI si vede che quando si lancia un video su youtube nei log viene scritto:

      I/ActivityManager( 86): Starting activity: Intent { act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=http://www.youtube.com/watch?v=8ADwPLSFeY8 flg=0x3800000 cmp=com.google.android.youtube/.PlayerActivity }

      da cui si possono evincere i dati da mettere nell'activitystarter,
      molte volte si tratta di provare e riprovare, cercare su internet (ho provato a cercare per attivare il flash tramite AI e non ho trovato nulla di utile...) finchè non si arriva alla soluzione.
      Per il logcat invece trovi molte guide,puoi installarti Android SDK bundle e da li usi ddms.
      Buona fortuna :)

      Elimina
  4. Perfetto! Grazie! Adesso ci siamo!! Grazie, sei veramente gentile!!! Inizio a sperimentare! Continuo a seguirti costantemente!!! ;-) UP! UP! UP!

    RispondiElimina
  5. ciao! era quello che cercavo, ovvero far inviare una mail con allegato foto, ma mi manca la cosa principale, ovvero il pagamento; nel senso: gli utenti che vogliono mandare una foto con un messaggio, possono farlo soltanto pagando una quota (es 89 cent)? e soprattutto, è legale?.

    RispondiElimina
    Risposte
    1. Ciao Vale,forse non mi sono spiegato bene...con App Engine versione gratuita puoi mandare liberamente mail con allegati fino a 1Mb, se si vuole mandare allegati più grossi allora bisogna pagare una quota per App Engine (e onestamente non so neanche dove si dovrebbe pagare questa quota...)
      l'utente non paga assolutamente nulla usando questo metodo,
      ovviamente il tutto è perfettamente legale, App Engine è un servizio messo a disposizione di Google per tutti gli utenti

      Elimina
  6. CIAOOO PUOI CARICARE IL SOURCE DEL PROGETTO ?

    RispondiElimina
    Risposte
    1. Il sorgente è già caricato, lo trovi linkato a inizio articolo, leggi bene tutto il resto perché il sorgente è da modificare con dei dati tuoi perché funzioni correttamente

      Elimina
    2. ok grazie mille :D sempre gentile :D

      Elimina
    3. cosa c' è da modificare ho seguito la guida e tutto ho app engine mi serviva solo il progetto cosa bisogna modificare?

      Elimina
    4. è spiegato tutto nel tutorial ,basta che lo leggi con attenzione, è inutile che faccia copia incolla di quello che è scritto nel post ;)

      Elimina
  7. Ciao,
    complimenti veramente per tutto il tuo lavoro, ti ammiro molto e sto migliorando giorno dopo giorno la mia app grazie le tue dritte.
    Mi sorge un problema, dovrei inserire nella mia app in una screen un calendario dove però l'inserzione degli eventi la gestisco io da pc.
    Quindi per vedere il calendario sul device che avrò l'app dovrà avere internet per visualizzare gli eventi.
    Inoltre se possibile magari inserisci una notifica un tot tempo prima per avvisare che inizierà tra breve l'evento.
    Una specie di google calendar sulla mia app.!

    Grazie mille

    RispondiElimina
    Risposte
    1. Secondo me la strada migliore da percorrere è quella di incorporare il calendario tramite webview, magari google calendar può anche essere formattato per una visualizzazione ottimale su siti mobile (la cosa ti aiuterebbe parecchio)
      Per la notifica le cose sono più complicate per due motivi:
      1-dovresti riuscire a caricare gli eventi nella tua app per sapere esattamente quando ci sarà l'evento (forse col componente web e google calendar riesci a caricare gli eventi, io non ci ho mai provato e non so se sia possibile)
      2-la notifica arriverà solo se l'app è in esecuzione (infatti AI non funziona se l'applicazione è messa in background)
      insomma, la strada è lunga e in salita ma ti invito a provare e farci sapere i risultati! :)

      Elimina
  8. Salve Sebastiano,
    Senti vorrei mandare una mail di testo niente allegati però senza usare gmail

    RispondiElimina
    Risposte
    1. visto che ogni telefono può avere un client di posta diverso, non credo sia una buona soluzione perchè non è detto che l'activitystarter che usi richiami un app effettivamente installata sul telefono.
      Ad ogni modo se fosse possibile farlo (e non ne sono sicuro) bisogna usare un activitystarter che faccia partire il client email, ma a quel punto cmq non è possibile mandare la mail in automatico ma deve essere l'utente a comporla e premere il tasto invio...

      Elimina
  9. Domanda probabilmente idiota, se volessi inviare email (con la nostra applicazione) in maniera forzata del tipo (orario di inizio di uscita ecc...) senza che l'utente lo sappia a un computer esterno o cell android sarebbe possibile con questo procedura? da dove dovrei cominciare?

    RispondiElimina
    Risposte
    1. Ciao Aldo, si è possibile, con questo tutorial la mail viene inviata con un activitystarter ed uno script php, quindi come ho anche scritto, volendo anche senza l'intervento dell'utente.
      Ovviamente poi ci sarebbe la questione "etica" se è giusto fare un app che invii mail all'insaputa dell'utente...ma questa cosa la devi vedere te ;)
      Studia bene il tutorial e puoi inviare la mail con gli stessi blocchi ma non legandoli ad un tasto specifico "invia mail", buon lavoro!:)

      Elimina
  10. Salve Sebastiano io ho preso il tuo progetto e ci ho cambiato l'url e basta ma quando premo invia mi esce Unauthorized sender

    RispondiElimina
    Risposte
    1. Sicuro di aver seguito tutti i passaggi correttamente, bisogna cambiare un pò di cose nei miei file come spiegato in questo post, ad esempio mi viene in mente questa frase che trovi qui sopra:
      ---Qui dobbiamo indicare l'indirizzo mail da cui partiranno le email nella nostra applicazione, tale indirizzo deve essere un amministratore dell'app che gira in App Engine---
      Se ancora non va hai sbagliato qualcosa,ricontrolla ma dal messaggio d'errore sembra un problema di indirizzo email che non avrai specificato correttamente ed in tutte le parti in cui è necessario farlo.

      Elimina
    2. NO non è quello io ho risolto in pratica il progetto che fornisci e vecchio bisogno modificare la stringa in app.yalm quello della runtine invece di phython bisogna scrivere phython27 e tutto funziona bene secondo me dovresti aggiornare un pò il tutorial

      Elimina
    3. Comunque grazie mille sei il migliore in questo campo

      Elimina
    4. non ho più provato, ma installando sempre python 2.7 non funziona così come è scritto nel tutorial?
      appena avrò tempo proverò a verificare per bene,
      grazie per i complimenti :)

      Elimina
  11. ciao goodnight've stato interessato a fare un programma che scattare una foto e inviare la posta direttamente a una specifica, non podiod la foto è come allegato ho una possibile soluzione che viene spiegato qui: https://groups . google.com / forum / #! msg/app-inventor-developers-library/-6XI0hWHqao/1zzc0jEm0iwJ
      Il mio altro problema è che io sono nuovo al soggetto e le foto possono pesare più di 1 MB.
    potete aiutarmi vi ringrazio molto.

    RispondiElimina