Autore Topic: Broadcast receiver per eventi batteria  (Letto 568 volte)

Offline washburn

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S2 - Stock ROM (JB 4.1.2)
  • Sistema operativo:
    Windows 7
Broadcast receiver per eventi batteria
« il: 07 Ottobre 2014, 01:44:25 CEST »
0
Salve,

sto scrivendo un'app che fornisce i dati correnti della batteria (carica residua, temperatura ecc.) e vorrei anche monitorare quando viene caricata per calcolare (in percentuale) il consumo medio da ricarica a ricarica.
Per fare questo ho implementato un BroadcastReceiver che viene "registrato" dall'Activity principale tramite registerReceiver, tutto funziona e posso leggere i dati della batteria (compreso se è in carica o meno) fintanto che l'app è in funzione.
Leggendo vari tutorial ho (spero) capito che effettuando la registrazione del BroadcastReceiver sul file manifest si ottiene il funzionamento in background del receiver anche se l'app non è in esecuzione.
Ho modificato quindi il sorgente spostando il codice relativo al receiver su di un file java e modificato il file manifest:

Codice: [Seleziona]
public class BroadcastBattery extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        ScriviLog("evento ricevuto");
    }

    private void ScriviLog(String testo)
    {
        //salva su di un file di testo la stringa contenuta in "testo"
        try
        {
            String storageState = Environment.getExternalStorageState();
            String lineSep = System.getProperty("line.separator");
            String Data= DateFormat.getDateTimeInstance().format(new Date());

            //se la SD (sdcard0) è disponibile

            testo= Data+" "+testo+lineSep;

            if (storageState.equals(Environment.MEDIA_MOUNTED))
            {
                //crea il file di testo e lo riscrive

                File file = new File(Environment.getExternalStorageDirectory(), "power_Log.txt");
                FileOutputStream fos2 = new FileOutputStream(file, true);
                fos2.write(testo.getBytes());
                fos2.close();
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}


questo il file manifest

Codice: [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.prova_broadcast" >

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.BATTERY_STATS" />
   
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".BroadcastBattery" >
            <intent-filter>
                <action android:name="android.intent.action.BATTERY_CHANGED" />
            </intent-filter>
        </receiver>
    </application>

</manifest>


Naturalmente ho eliminato dall'activity la riga relativa alla registrazione del receiver e tutto il codice sorgente ad esso relativo.
Ho lanciato l'app direttamente nel telefono, ho scollegato il cavo USB (che dovrebbe generare l'evento di scollegamento della ricarica) ma il file di log che genero era assente, come se il broadcast receiver non fosse in esecuzione.
Dove sto sbagliando?

Grazie, saluti.

Roberto

Offline GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +152
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
Re:Broadcast receiver per eventi batteria
« Risposta #1 il: 07 Ottobre 2014, 11:21:14 CEST »
0
Stai sbagliando qui:

Intent | Android Developers

You can not receive this through components declared in manifests, only by explicitly registering for it with Context.registerReceiver(). See ACTION_BATTERY_LOW, ACTION_BATTERY_OKAY, ACTION_POWER_CONNECTED, and ACTION_POWER_DISCONNECTED for distinct battery-related broadcasts that are sent and can be received through manifest receivers.

Offline washburn

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S2 - Stock ROM (JB 4.1.2)
  • Sistema operativo:
    Windows 7
Re:Broadcast receiver per eventi batteria
« Risposta #2 il: 07 Ottobre 2014, 11:52:25 CEST »
0
Grazie della risposta.
Quindi se non ho capito male, l'intent "BATTERY_CHANGED" non può essere ricevuto da un receiver registrato a livello di manifest ma solamente gli intent di cui sopra.
Modifico il programma e riprovo.

Saluti,

Roberto

Offline washburn

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S2 - Stock ROM (JB 4.1.2)
  • Sistema operativo:
    Windows 7
Re:Broadcast receiver per eventi batteria
« Risposta #3 il: 29 Ottobre 2014, 10:49:37 CET »
0
Le prove effettuate dopo le modifiche fatte in accordo con i suggerimenti hanno avuto esito positivo e, già da un pò, la mia app gira senza problemi calcolando la media di consumo (in percentuale) della batteria tra una ricarica ed un'altra.
Ora vorrei aggiungere una "feature" in più ovvero calcolare il consumo (quasi) istantaneo.
Vorrei, cioè, registrare un record (mi appoggio ad un DB SQLLite) ogni volta che il livello della batteria scende di 1 punto percentuale, questa registrazione dovrebbe avvenire in background anche quando l'app non è in esecuzione.
Per fare questo ho pensato di utilizzare un Service in cui se il livello è cambiato (memorizzo l'ultima lettura, se la successiva è diversa dalla precedente salvo il nuovo livello) ma non ho capito bene come poter eseguire il servizio ad intervalli di tempo prestabiliti.
Uso un AlarmManager per attivare il servizio ogni, per esempio, 30 secondi? Ma poi non rischio che il telefono, praticamente, non vada più in deep sleep?
Oppure, come ho visto qui http://mindtherobot.com/blog/37/android-architecture-tutorial-developing-an-app-with-a-background-service-using-ipc/ un timer?
Che impatto potrebbero avere l'AlarmManager o il Timer sulla CPU e quindi sulla batteria?

Grazie, saluti.

Roberto
« Ultima modifica: 29 Ottobre 2014, 11:37:32 CET da washburn »