Autore Topic: Problema Receiver  (Letto 596 volte)

Offline GregWildfire

  • Nuovo arrivato
  • *
  • Post: 13
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    HTC Wildfire
  • Sistema operativo:
    Windows XP
Problema Receiver
« il: 05 Gennaio 2012, 23:40:44 CET »
0
Salve,
non so se sia questa la sezione più corretta in cui postare. Ho deciso di postare qui perchè comunque ho a che fare con gli intent.

Dunque, volevo realizzare una semplice applicazione che setti ad una certa ora la modalità aereoplano.

Quindi mi sono creato una classe che ho chiamato MyAlarm che dopo un certo tempo impostato esegue una certa operazione:

Codice (Java): [Seleziona]
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

        public class MyAlarm extends BroadcastReceiver {
            private final String REMINDER_BUNDLE = "MyReminderBundle";

            // this constructor is called by the alarm manager.
            public MyAlarm(){ }

            // you can use this constructor to create the alarm.
            //  Just pass in the main activity as the context,
            //  any extras you'd like to get later when triggered
            //  and the timeout
             public MyAlarm(Context context, Bundle extras, int timeoutInSeconds){
                 AlarmManager alarmMgr =
                     (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
                 Intent intent = new Intent(context, MyAlarm.class);
                 intent.putExtra(REMINDER_BUNDLE, extras);
                 PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
                 Calendar time = Calendar.getInstance();
                 time.setTimeInMillis(System.currentTimeMillis());
                 time.add(Calendar.SECOND, timeoutInSeconds);

                 alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
                              pendingIntent);
                 
             }
             
              @Override
             public void onReceive(Context context, Intent intent) {
                 // here you can get the extras you passed in when creating the alarm
                 //intent.getBundleExtra(REMINDER_BUNDLE));
                 
                   /**
                  AirplaneModeManagerActivity amm;
                  amm = new AirplaneModeManagerActivity();
                  amm.setAirplaneMode(); */

                 
                 Toast.makeText(context, "AirplaneMode Changed", Toast.LENGTH_SHORT).show();
             }
             
           
        }  

e all'android manifest ho aggiunto:
<receiver android:name=".MyAlarm" />

Richiamando il tutto dall'onCreate così com'è, funziona a dovere. Lo richiamo con:
       Bundle bundle = new Bundle();
       MyAlarm alarm = new MyAlarm(this, bundle, 3); //3 sono i secondi dopo i quali il programma esegue l'operazione impostata


Quindi dopo 3 secondi mostra correttamente il messaggio.

Poi sempre nel file java principale ho creato un metodo setAirplaneMode che se richiamato nell'onCreate funziona correttamente:
Codice (Java): [Seleziona]
 public void setAirplaneMode() {
       
        //Controllo se è abilitata la modalità aereo
         boolean isEnabled = Settings.System.getInt(this.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 1;
       
        //Se è attiva la disattivo, altrimenti l'attivo
        Settings.System.putInt(this.getContentResolver(),Settings.System.AIRPLANE_MODE_ON, isEnabled ? 0 : 1);
     
        //Settings.System.putInt(this.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 1);
       
       
        // Post an intent to reload
        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        intent.putExtra("state", !isEnabled);
        sendBroadcast(intent);
        IntentFilter intentFilter = new IntentFilter("android.intent.action.SERVICE_STATE");
       
       
        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                  Log.d("AirplaneMode", "Service state changed");
            }
      };
         
      this.registerReceiver(receiver, intentFilter);    
    }

Il problema arriva adesso, nella parte finale. Infatti, non mi resta che richiamare dall'onCreate la classe myAlarm e nel metodo onReceive il metodo setAirplaneMode();

Quindi ho scritto:
Codice (Java): [Seleziona]
              @Override
             public void onReceive(Context context, Intent intent) {
                 // here you can get the extras you passed in when creating the alarm
                 //intent.getBundleExtra(REMINDER_BUNDLE));
                 
                  AirplaneModeManagerActivity amm;
                  amm = new AirplaneModeManagerActivity();
                  amm.setAirplaneMode();
                 
                 Toast.makeText(context, "AirplaneMode Changed", Toast.LENGTH_SHORT).show();
             }

Risultato? Dopo tre secondi mi viene il messaggio "force close"

Ecco il LogCat che dice:
FATAL EXCEPTION: main
01-05 22:36:39.161: E/AndroidRuntime(722): java.lang.RuntimeException: Unable to start receiver greg.AirplaneModeManager.MyAlarm: java.lang.NullPointerException
ecc..

La colpa è del metodo setAirplaneMode perchè se vedete oltre che nella classe MyAlarm anche nel metodo setAirplaneMode creo un metodo onReceive, quindi c'è una sorta di contrasto fra i due, e dato che ho specificato nell'android manifest che il receiver era MyAlarm forse tenta di rieseguire l'onReceive di MyAlarm andando in una sorta di cliclo infinito?

Come posso risolvere?

EDIT:
Ho appena fatto una prova mettendo una variabile booleana in modo tale che il metodo onReceive potesse essere eseguito solo una volta, però mi da lo stesso errore  :-(
« Ultima modifica: 05 Gennaio 2012, 23:46:22 CET da GregWildfire »

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:Problema Receiver
« Risposta #1 il: 06 Gennaio 2012, 09:25:41 CET »
0
una domanda: come mai nel receiver crei una istanza di una activity? non puoi direttamente mettere il codice per impostare il modo airplane?
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline GregWildfire

  • Nuovo arrivato
  • *
  • Post: 13
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    HTC Wildfire
  • Sistema operativo:
    Windows XP
Re:Problema Receiver
« Risposta #2 il: 06 Gennaio 2012, 20:20:38 CET »
0
bè era un esempio che avevo visto su intrnet... comunque tu mi stai chiedendo perchè non metto direttamente solo il seguente codice?

Codice (Java): [Seleziona]
Settings.System.putInt(this.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 1);
giusto?

Comunque ci ho provato a mettere solo questa riga di codice che setta la modalità aereo, solo che mi da sempre errore dicendo tipo che gli manca il receiver, era qualcosa del tipo "unable receiver.." ed era l'eccezione java.lang.NullPointerException