Autore Topic: Generare una notifica attraverso un broadcast recievers  (Letto 1412 volte)

Offline teogrem

  • Nuovo arrivato
  • *
  • Post: 27
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Sistema operativo:
    Windows 7
Generare una notifica attraverso un broadcast recievers
« il: 30 Gennaio 2012, 14:30:16 CET »
0
Ciao a tutti, vi spiego brevemente cosa vorrei fare.
L'app che sto sviluppando mi permette di visualizzare tramite la chiamata ad un WebService un elenco di prenotazioni associate ad un utente, queste prenotazioni possono essere confermate, spostate e cancellate.
Nel caso in cui una prenotazione venisse confermata,vorrei, per esempio, che 24 ore prima del giorno della prenotazione comparisse una notifica per ricordare all'utente la prenotazione fatta.
Spero di essermi spiegato, quello che vi chiedo è un consiglio teorico su come implementare questo processo.

Grazie anticipatamente a chi mi risponderà.
« Ultima modifica: 30 Gennaio 2012, 14:51:51 CET da teogrem »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Generare una notifica attraverso un service
« Risposta #1 il: 30 Gennaio 2012, 14:52:13 CET »
0
Ciao a tutti, vi spiego brevemente cosa vorrei fare.
L'app che sto sviluppando mi permette di visualizzare tramite la chiamata ad un WebService un elenco di prenotazioni associate ad un utente, queste prenotazioni possono essere confermate, spostate e cancellate.
Nel caso in cui una prenotazione venisse confermata,vorrei, per esempio, che 24 ore prima del giorno della prenotazione comparisse una notifica per ricordare all'utente la prenotazione fatta.
Spero di essermi spiegato, quello che vi chiedo è un consiglio teorico su come implementare questo processo.

Ho fatto qualcosa di molto simile per la mia app RACE DAY, che genera una notifica 5 minuti prima della partenza della prossima gara di F1, SBK, MotoGp.

Io ho seguito questo approccio:
* All'avvio del telefono (evento BOOT_COMPLETED) l'applicazione imposta automaticamente un AlarmManager per giorno e ora voluta.
* Quando suona l'AlarmManager, creo la notifica per l'evento.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline teogrem

  • Nuovo arrivato
  • *
  • Post: 27
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Sistema operativo:
    Windows 7
Re:Generare una notifica attraverso un broadcast recievers
« Risposta #2 il: 30 Gennaio 2012, 17:15:21 CET »
0
Intanto ti ringrazio per avermi risposto, io ho provato a fare in questo modo ma non mi funziona.
Prima ho creato un BroadcastReceiver:

Codice (Java): [Seleziona]
public class MemoPrenotazione extends BroadcastReceiver {

        public static int NOTIFICATION_ID = 1;
   
        String title, note, codPaziente, nome, cognome;

        @Override
        public void onReceive(Context context, Intent intent) {
               
                Bundle extras = intent.getExtras();

                title = extras.getString("title");
                note = extras.getString("note");
                codPaziente = extras.getString("codPaziente");
                nome = extras.getString("nome");
                cognome = extras.getString("cognome");

                NotificationManager mNotificationManager = (NotificationManager) context
                                .getSystemService(Context.NOTIFICATION_SERVICE);
                NotificationManager manger = (NotificationManager) context
                                .getSystemService(Context.NOTIFICATION_SERVICE);
               
                int icon = R.drawable.icon;
                CharSequence tickerText = "Memo prenotazione" ;
                long when = System.currentTimeMillis();
               
                Notification notification = new Notification(icon, tickerText, when);
               
                Intent i = new Intent(context, HttpGetTaskActivity.class);
                Bundle b = new Bundle();
       
                b.putString("codPaziente", codPaziente);
                b.putString("nome", nome);
                b.putString("cognome", cognome);
       
                i.putExtras(b);
               
                PendingIntent contentIntent = PendingIntent
                                .getActivity(context, NOTIFICATION_ID, i, PendingIntent.FLAG_UPDATE_CURRENT);
               
                notification.setLatestEventInfo(context, note, title, contentIntent);

                notification.flags |= Notification.FLAG_AUTO_CANCEL;
               
                notification.defaults |= Notification.DEFAULT_SOUND;    //Suona
                notification.defaults |= Notification.DEFAULT_LIGHTS;   //LED
                notification.defaults |= Notification.DEFAULT_VIBRATE;  //Vibra

                manger.notify(NOTIFICATION_ID, notification);

        }
}

è nella mia MainActivity setto l'AlarmManager:

Codice (Java): [Seleziona]
                 Calendar cal = Calendar.getInstance();
         
                  cal.set(Calendar.MONTH, 1);
                  cal.set(Calendar.YEAR, 2012);                        
                  cal.set(Calendar.DAY_OF_MONTH, 30);
                  cal.set(Calendar.HOUR_OF_DAY, 16);
                  cal.set(Calendar.MINUTE, 30);
                 
                  Intent alarmintent = new Intent(getApplicationContext(), MemoPrenotazione.class);
                 
                  alarmintent.putExtra("title","Prova");
                  alarmintent.putExtra("note","Memo Prenotazione");
                  alarmintent.putExtra("codPaziente",codPaziente);
                  alarmintent.putExtra("nome",nome);
                  alarmintent.putExtra("cognome",cognome);
                 
                  PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(), NOTIFICATION_ID,
                  alarmintent,PendingIntent.FLAG_UPDATE_CURRENT|  Intent.FILL_IN_DATA);
                 
                  AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                  am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
Chiaramente ho impostato un la data di oggi e un orario tale per poterlo testare.

Mentre nel manifest ho fatto così:
Codice (XML): [Seleziona]
                <receiver android:name=".service.MemoPrenotazione">
                        <intent-filter>
                                <action android:name="android.intent.action.BOOT_COMPLETED"></action>
                               
                        </intent-filter>
                </receiver>
« Ultima modifica: 30 Gennaio 2012, 17:18:01 CET da teogrem »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Generare una notifica attraverso un broadcast recievers
« Risposta #3 il: 30 Gennaio 2012, 17:48:39 CET »
0
Nel manifest ti manca l'intent dell'alarm (quello del BOOT_COMPLETED ti servirà ma dopo, perchè ad ogni riavvio gli alarm si resettano, devi cioè reimpostarli al boot).

Devi metterci il nome dell'Intent dell'alarm. Esempio:

Codice (XML): [Seleziona]
        <receiver android:name=".MemoPrenotazione">
            <intent-filter>
                <action android:name="nome.tuo.package.ACTION_1ST_ALARM" />
            </intent-filter>
        </receiver>

Codice (Java): [Seleziona]
   public void setAlarm10sec() {
      AlarmManager al = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
      int alType = AlarmManager.RTC_WAKEUP;
      Calendar now = Calendar.getInstance();
      long triggerAtTime = now.getTimeInMillis() + 10000;
      String ALARM_ACTION = "nome.tuo.package.ACTION_1ST_ALARM";
      Intent intentToFire = new Intent(ALARM_ACTION);
      PendingIntent pendingIntent = PendingIntent.getBroadcast(this,0,intentToFire,0);
      al.set(alType,triggerAtTime,pendingIntent);
   }
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline teogrem

  • Nuovo arrivato
  • *
  • Post: 27
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Sistema operativo:
    Windows 7
Re:Generare una notifica attraverso un broadcast recievers
« Risposta #4 il: 31 Gennaio 2012, 12:12:04 CET »
0
Perfetto! adesso la notifica arriva quando voglio io...grazie.
Ti chiedo un altra cosa se puoi rispondermi; come dicevo, adesso la notifica arriva,però quando ci clicco sopra mi rimanda all'activity dove vengono visualizzate le prenotazioni, come da me richiesto del resto, ma il problema è che viene rimandata la notifica ogni volta che ci clicco sopra, non so se mi sono spiegato?
Come ultima cosa , ti vorrei chiedere come dovrei fare per far si che l'AlarmManager venga generato all'avvio del telefono.
Ti ringrazio molto per la disponibilità.

Offline teogrem

  • Nuovo arrivato
  • *
  • Post: 27
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Sistema operativo:
    Windows 7
Re:Generare una notifica attraverso un broadcast recievers
« Risposta #5 il: 02 Febbraio 2012, 12:11:32 CET »
0
Se non ho capito male, forse dovrei fare così: creare un service che mi genera un allarme nella data da me indicata, questo viene catturato dal broadcast receiver che mi genera la notifica.
Il mio dubbio adesso è su come lanciare il servizio all'avvio del telefono.

Offline teogrem

  • Nuovo arrivato
  • *
  • Post: 27
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Sistema operativo:
    Windows 7
Re:Generare una notifica attraverso un broadcast recievers
« Risposta #6 il: 02 Febbraio 2012, 18:51:18 CET »
0
Penso di esserci quasi, non si generano errori però non compare la notifica ancora.
Per prima cosa ho creatao un BroadcastReceiver che parte all'avvio del telefono in questo modo:

Codice (Java): [Seleziona]
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
 
public class BootReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
               
                Intent serviceIntent = new Intent();
                serviceIntent.setAction("com.itel.cuprecall.service.RicordaPrenotazione");
                context.startService(serviceIntent);
        }
}

Codice (XML): [Seleziona]
        <receiver android:name=".service.BootReceiver">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                    <category android:name="android.intent.category.HOME" />
                </intent-filter>
        </receiver>

Questo BroadcastReceiver lancia un service:

Codice (Java): [Seleziona]
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;

import org.json.JSONException;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;

import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;


public class RicordaPrenotazione extends Service {

        // Identificatore delle preferenze dell'applicazione
        public static final String PREFERENCES = "Pref";
        // Costanti relative al profilo utente
        public static final String PREF_CODPAZIENTE = "codice paziente";
        public static final String PREF_NOME = "nome";
        public static final String PREF_COGNOME = "cognome";
        public static final String PREF_CF = "codice fiscale";
        public static final String PREF_TS = "tessera sanitaria";
        public static final String PREF_DATA = "data scadenza";
       
        private final static String LOG_TAG = "LocalService";
       
        private static final int NOTIFICATION = 1;
       
        private NotificationManager notificationManager;
        private Notification notification;
        private PendingIntent pIntent;
        private AlarmManager alarmManager;
        private Calendar calendar;
       
        private int notificationNumber;
       
    String codPaziente, nome, cognome, codiceFiscale, tesseraSanitaria, dataScadenza,response;
    String[] codicePrenotazione,name, surname, descEsame, descSpecialita, descAmbulatorio, descAvvertenza , dataAppuntamento, oraAppuntamento, statoPrenotazione;
   
    ArrayList<HashMap<String, String>>  mylist = new ArrayList<HashMap<String, String>>();
    WebService webService = new WebService();
       
        int numPrenotazioni;
        int count;
   
    @Override  
        public void onCreate() {
                super.onCreate();
               
                SharedPreferences prefs = getSharedPreferences(PREFERENCES,0);
               
                codPaziente = prefs.getString(PREF_CODPAZIENTE, "NESSUN CODICE");
                nome = prefs.getString(PREF_NOME, "NESSUN");
                cognome = prefs.getString(PREF_COGNOME, "PROFILO");
                codiceFiscale = prefs.getString(PREF_CF, "XXXXXX00X00X000X");
                tesseraSanitaria = prefs.getString(PREF_TS, "00000000000000000000");
                dataScadenza = prefs.getString(PREF_DATA, "GG-MM-AAAA");
       
                count = 0;
       
                try {
                               
                        mylist = webService.recuperaPrenotazioni(codPaziente.trim());
                       
                } catch (JSONException e) {
                       
                        e.printStackTrace();
                }
        }  

        @Override
        public void onDestroy() {
               
                super.onDestroy();
                Log.i(LOG_TAG, "Service Destroyed");
        }

       
        @Override
        public IBinder onBind(Intent arg0) {
                // Ritorno null in quanto non si vuole permettere
                // l'accesso al servizio da una applicazione diversa
                return null;
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startid) {  

                if(mylist.isEmpty())
                {
                        Toast.makeText(getApplicationContext(),"Nessuna prenotazione trovata!", Toast.LENGTH_LONG).show();
                }
                else{
                       
                        numPrenotazioni = mylist.size();
                       
                        for(int j=0; j<numPrenotazioni; j++){
                               
                                if(mylist.get(j).get("statoPrenotazione").toString().equals("1")){
                                        count++;
                                        createAlarm(mylist.get(j).get("codicePrenotazione").toString(),mylist.get(j).get("descEsame").toString(),mylist.get(j).get("dataAppuntamento").toString(),mylist.get(j).get("oraAppuntamento").toString(),count);
                                       
                                }
                        }
                       
                }
               
                // Solo per debugging
                Log.i(LOG_TAG, "Service Started");
               
                return super.onStartCommand(intent, flags, startid);
        }

         public void createAlarm (String codicePrenotazioneA, String descEsameA, String dataAppuntamentoA, String oraAppuntamentoA, int count)
        {
               
                Calendar cal = Calendar.getInstance();
         
                String[] temp = dataAppuntamentoA.split(" ");
                String[] temp2 = oraAppuntamentoA.split(" ");
                String[] tempData = temp[0].split("-");
                String[] tempOra = temp2[1].split(":");
       
                cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(tempData[2]));
                cal.set(Calendar.MONTH, Integer.parseInt(tempData[1]));
                cal.set(Calendar.YEAR, Integer.parseInt(tempData[0]));
       
                cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(tempOra[0])-1);
                cal.set(Calendar.MINUTE, Integer.parseInt(tempOra[1]));
               
                String ALARM_ACTION = "com.itel.cuprecall.service.MemoPrenotazione";
                Intent alarmintent = new Intent(ALARM_ACTION);
               
                alarmintent.putExtra("codPaziente",codPaziente);
                alarmintent.putExtra("nome",nome);
                alarmintent.putExtra("cognome",cognome);
               
                alarmintent.putExtra("codicePrenotazione", codicePrenotazioneA);
                alarmintent.putExtra("descEsame", descEsameA);
                alarmintent.putExtra("dataAppuntamento", dataAppuntamentoA);
                alarmintent.putExtra("oraAppuntamento", oraAppuntamentoA);
                alarmintent.putExtra("count", count);
                 
                PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(), NOTIFICATION,
                alarmintent,PendingIntent.FLAG_UPDATE_CURRENT|  Intent.FILL_IN_DATA);
                 
                AlarmManager am = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
                am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
               
        }

}

Codice (XML): [Seleziona]
     <service android:name=".service.RicordaPrenotazione">
            <intent-filter>
                <action android:name="com.itel.cuprecall.service.RicordaPrenotazione" />
            </intent-filter>
     </service>

Fino a qui tutto bene, infatti all'avvio del telefono il BroadcastReceiver cattura l'evento e lancia il Service, mentre dentro il service dove setto l'AlarmManager in base all'orario della prenotazione non riesco a richiamare l'altro BroadcastReceiver che dovrebbe generare la notifica, sarebbe questo:

Codice (Java): [Seleziona]
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import android.os.Bundle;
import android.util.Log;

public class MemoPrenotazione extends BroadcastReceiver {

        public static int NOTIFICATION_ID = 1;

        String title, note, codPaziente, nome, cognome;
        String codicePrenotazione, descEsame, dataAppuntamento, oraAppuntamento;
        int count;
       
        private NotificationManager manger;
        private Notification notification;
        private PendingIntent contentIntent;
       

        @Override
        public void onReceive(Context context, Intent intent) {
               
                Bundle extras = intent.getExtras();

                codPaziente = extras.getString("codPaziente");
                nome = extras.getString("nome");
                cognome = extras.getString("cognome");

                codicePrenotazione = extras.getString("codicePrenotazione");
                descEsame = extras.getString("descEsame");
                dataAppuntamento = extras.getString("dataAppuntamento");
                oraAppuntamento = extras.getString("oraAppuntamento");
                count = extras.getInt("count");

                title = "Memo Prenotazione";
                note = descEsame + " il " + dataAppuntamento + " alle "
                                + oraAppuntamento;

                manger = (NotificationManager) context
                                .getSystemService(Context.NOTIFICATION_SERVICE);

                int icon = R.drawable.icon;
                CharSequence tickerText = "Memo prenotazione";
                long when = System.currentTimeMillis();

                notification = new Notification(icon, tickerText, when);

                Intent i = new Intent(context, HttpGetTaskActivity.class);
                Bundle b = new Bundle();

                b.putString("codPaziente", codPaziente);
                b.putString("nome", nome);
                b.putString("cognome", cognome);

                i.putExtras(b);

                contentIntent = PendingIntent.getActivity(context, NOTIFICATION_ID, i,
                                PendingIntent.FLAG_UPDATE_CURRENT);
               
                notification.setLatestEventInfo(context, title, note, contentIntent);

                notification.flags |= Notification.FLAG_AUTO_CANCEL;

                notification.defaults |= Notification.DEFAULT_SOUND; // Suona
                notification.defaults |= Notification.DEFAULT_LIGHTS; // LED
                notification.defaults |= Notification.DEFAULT_VIBRATE; // Vibra

                manger.notify(NOTIFICATION_ID, notification);

        }

}

Codice (XML): [Seleziona]
                <receiver android:name=".service.MemoPrenotazione">
                        <intent-filter>
                                <action android:name="com.itel.cuprecall.service.MemoPrenotazione" />
                        </intent-filter>
                </receiver>

Dove sbaglio? Qualcuno riesce a darmi una mano?

Offline Auron

  • Utente junior
  • **
  • Post: 104
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Motorola Milestone Android 2.2.1
  • Sistema operativo:
    Windows
Re:Generare una notifica attraverso un broadcast recievers
« Risposta #7 il: 05 Febbraio 2012, 18:26:30 CET »
0
Hai provato a far partire il debug e mettere un breakpoint nel punto in cui l'AlarmManager notifica il BroadcastReceiver e un altro breakpoint alla prima istruzione della onReceive?
È stata trovata una soluzione al tuo problema?Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato ;-)

Offline teogrem

  • Nuovo arrivato
  • *
  • Post: 27
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Sistema operativo:
    Windows 7
Re:Generare una notifica attraverso un broadcast recievers
« Risposta #8 il: 07 Febbraio 2012, 17:07:22 CET »
0
Incredibile!!! ho perso un sacco di tempo per una cavolata, caspita...praticamente non veniva lanciata la notifica perchè quando settavo l'Alarm manager gli passavo la data presa dal db dove chiaramente i mesi vengono considerati dal 1 al 12 mentre nel calendar vanno da 0 a 11, quindi io gli passavo 2 convinto che fosse febbraio invece era marzo :-)
Adesso però mi è venuto un altro dubbio...all'accensione del telefono quando viene lanciato il servizio faccio una chiamata al webservice per scaricarmi le prenotazioni confermate...ma nel caso in cui non ci fosse la connessione di rete attiva? come faccio a dirgli di lanciare il servizio quando la connessione è attiva?

Offline Auron

  • Utente junior
  • **
  • Post: 104
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Motorola Milestone Android 2.2.1
  • Sistema operativo:
    Windows
Re:Generare una notifica attraverso un broadcast recievers
« Risposta #9 il: 07 Febbraio 2012, 17:17:49 CET »
0

Codice (Java): [Seleziona]
// variabili locali
        public ConnectivityManager conn_manager;
        public NetworkInfo net_info;
        public boolean is_wifi_available = false;
        public boolean is_wifi_connected = false;
        public boolean is_mobile_available = false;
        public boolean is_mobile_connected = false;

Codice (Java): [Seleziona]
 public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        // Attenzione: bisogna mettere nel AndroidManifest.xml
        // <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        // <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  
        // <uses-permission android:name="android.permission.INTERNET" />
       
        conn_manager = (ConnectivityManager)getSystemService(getApplicationContext().CONNECTIVITY_SERVICE);
        // vediamo se c'è una connessiome dati
        Check_Network_Connection();
        // la connessione internet esiste?
        if ( is_wifi_connected == false && is_mobile_connected == false) {
                // avvertiamo l'utente
                Toast.makeText(this, "Non c'è nessuna connessione dati! Impossibile continuare!", Toast.LENGTH_SHORT).show();
                // non possiamo continuare
                return;
        }
}


Codice (Java): [Seleziona]
    //***********************************************
    public void Check_Network_Connection() {
        net_info = conn_manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        is_wifi_available = net_info.isAvailable();
        is_wifi_connected = net_info.isConnected();
       
        net_info = conn_manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        is_mobile_available = net_info.isAvailable();
        is_mobile_connected = net_info.isConnected();
    }
È stata trovata una soluzione al tuo problema?Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato ;-)