Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Ricevere notifiche push: il client

Implementare la ricezione delle notifiche push direttamente all'interno di un'app Android: ecco come fare.
Implementare la ricezione delle notifiche push direttamente all'interno di un'app Android: ecco come fare.
Link copiato negli appunti

Dopo che le lezioni precedenti hanno mostrato l'impostazione di massima dell'esempio e della parte server, vedremo finalmente la vera e propria app che
riceverà e gestirà le notifiche push da parte del server.

È costituita da due componenti:

  • l'Activity che si occupa della registrazione a GCM;
  • il Broadcast Receiver che aspetta l'arrivo della notifica push.

Osserviamo, per prima cosa, il file AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="it.html.googleservices.push" >
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <permission android:name="it.html.googleservices.push.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="it.html.googleservices.push.permission.C2D_MESSAGE" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity" >
        ...
        </activity>
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <receiver
            android:name=".NotificationReceiver">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="it.html.googleservices.push" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

Notiamo che:

  • all'interno del nodo <application> ci sono le due componenti configurate. Il Broadcast Receiver è collegato ad un IntentFilter legato
    all'azione com.google.android.c2dm.intent.RECEIVE, che indica la ricezione di una notifica push;
  • all'interno di <application> c'è anche il nodo <metadata> che specifica la versione dei Google Play Services;
  • al di fuori di <application> ci sono le permission: INTERNET per il collegamento in Rete, com.google.android.c2dm.permission.RECEIVE per ricevere
    le notifiche push ed infine ce n'è una personalizzata, che deve corrispondere al nome del package più il suffisso .permission.C2D_MESSAGE. Lo scopo di
    quest'ultima è impedire che altre applicazioni possano registrarsi alle notifiche push della nostra. Il nome deve necessariamente combaciare con il formato
    previsto, altrimenti l'app non sarà in grado di ricevere notifiche.

Il codice che viene presentato di seguito, per funzionare, ha bisogno che di un paio di parametri:

  • l'URL della pagina PHP nella costante BACKEND_URL;
  • il Project Number del progetto Google in SENDER_ID.

L'Activity è composta da tre metodi:

public class MainActivity extends Activity {
    // inserire l'url della pagina PHP
    private static final String BACKEND_URL="http://.......";
    // nella stringa SENDER_ID inserire il Project Number del proprio progetto Google
    String SENDER_ID = "…...";
    TextView mDisplay;
    GoogleCloudMessaging gcm;
    Context context;
    String regid;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context=this;
        mDisplay = (TextView) findViewById(R.id.display);
        gcm = GoogleCloudMessaging.getInstance(this);
        registerInBackground();
    }
    private void registerInBackground()
    {
        new AsyncTask<Void, Void, String>()
        {
            private ProgressDialog dialog=null;
            protected void onPreExecute()
            {
                dialog=ProgressDialog.show(context, "Registrazione presso GCM", "Tentativo in corso...", true, false);
            };
            @Override
            protected String doInBackground(Void... params)
            {
                String msg = "";
                try {
                    if (gcm == null)
                    {
                        gcm = GoogleCloudMessaging.getInstance(context);
                    }
                    regid = gcm.register(SENDER_ID);
                }
                catch (IOException ex)
                {
                    return null;
                }
                return regid;
            }
            @Override
            protected void onPostExecute(String regid)
            {
                dialog.dismiss();
                if (regid!=null) {
                    sendIDToApplication(regid);
                    mDisplay.setText(regid);
                }
                else
                    Toast.makeText(context,"Errore: registrazione su GCM non riuscita!",Toast.LENGTH_LONG).toString();
            }
        }.execute();
    }
    private void sendIDToApplication(String regid)
    {
        new AsyncTask<String, Void, Void>()
        {
           @Override
            protected Void doInBackground(String... params)
            {
                String regid=params[0];
                HttpClient client=new DefaultHttpClient();
                HttpPost request=new HttpPost(BACKEND_URL);
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                nameValuePairs.add(new BasicNameValuePair("regid", regid));
                try {
                    request.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                    HttpResponse response=client.execute(request);
                    int status=response.getStatusLine().getStatusCode();
                } catch (UnsupportedEncodingException e) {
                    return null;
                } catch (ClientProtocolException e) {
                    return null;
                } catch (IOException e) {
                   return null;
                }
                return null;
            }
        }.execute(regid);
    }
}

Nel metodo onCreate vengono effettuate le prime configurazioni e viene invocato il metodo registerInBackground che
effettua la registrazione del client presso GCM.

La registrazione a GCM richiede in sé pochissimo codice. Un'istanza della classe GoogleCloudMessaging invierà in remoto il SENDER ID (ovvero il Project Number del progetto Google, come già detto) e riceverà una stringa contenente il REGISTRATION ID.

In onPostExecute, oltre alla dismissione della ProgressDialog, viene anche invocato il metodo sendIdToApplication che si occupa
dell'inoltro del REGISTRATION ID alla pagina PHP che abbiamo visto nella lezione precedente. Questo compito viene svolto in background grazie ad
AsyncTask, e sfrutta gli oggetti della classe HttpClient inviando una richiesta POST.

Si noti che il REGISTRATION ID è stato collocato in un elemento della richiesta POST di nome regid. Quest’ultimo deve coincidere con il nome del
parametro usato nello script PHP, spiegato nella lezione precedente.

Il BroadcastReceiver è così costituito:

public class NotificationReceiver extends BroadcastReceiver
{
    public static final int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;
    public NotificationReceiver() {
    }
    @Override
    public void onReceive(Context context, Intent intent)
    {
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
        Bundle extras = intent.getExtras();
        String messageType = gcm.getMessageType(intent);
        if (!extras.isEmpty())
        {
            if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType))
            {
                // emette una notifica sul dispositivo
                sendNotification(context,"E' arrivata la tua prima notifica attraverso GCM!");
            }
        }
    }
    private void sendNotification(Context ctx,String msg)
    {
        mNotificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
        // scelta suoneria per notifica
        Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(ctx)
                        .setSmallIcon(R.drawable.gcm_img)
                        .setContentTitle("Push Notifications: primo esperimento")
                        .setContentText(msg)
                        .setSound(sound);
        // effettua la notifica
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    }
}

Anche in questo caso troviamo la classe GoogleCloudMessaging, che viene impiegata per riconoscere se il tipo di messaggio contenuto nell'Intent è
compatibile con una notifica push.

La reazione alla ricezione della notifica push è implementata nel metodo sendNotification, che produce una comunicazione nel Notification Drawer
come quella visibile in figura:

Con questa lezione si conclude il percorso che ha portato a conoscere come le notifiche push funzionino su Android. Sebbene la loro implementazione può apparire inizialmente complicata, spesso questo meccanismo fornisce risposta a molte domande che i programmatori si pongono su tempistiche e modalità di sincronizzazione di app e applicazioni remote. Inoltre è bene non trascurare il grande contributo di efficienza che queste notifiche portano con sé: riduzione degli accessi in Rete, ottimizzazione del traffico, minore sovraccarico di richieste sui server remoti che forniscono i dati.

Ti consigliamo anche