开发者

Weird behaviour when using intent and BroadcastReceiver to get android battery level

I am trying to find the battery level after running an android app. When the phone starts the app completely charged the code always returns 100% battery level (even though it has drained a lot). If I start the app at 75% battery or whatever then it returns the actual battery level at the end of the test. I start my test with the phone plugged into my computer keeping its charge up then right before executing the app I unplug it. Ideally I'd like tobe able to get starting% and ending% but that read 100% on both as well. So here is what I am doing... I call this from my activity:

this.registerReceiver(this.mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));

Then in BroadcastReceiv开发者_运维技巧er I do a bunch of stuff (that takes over an hour so battery level changes). Then at the end of BoradcastReceiver I call this

int level2 = intent.getIntExtra("level", 0);    /* Ending battery level */
String end = "Ending battery level: " + String.valueOf(level2) + "%";

And then send the String end to the server.

Here is what my code looks like:

package com.mdog.datareceive;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.PowerManager;
import android.util.Log;
import android.widget.TextView;


public class Receive extends Activity {

    /* Test parameters */
    static int BYTES_TO_READ = 1024*1024*50;    /* The size of the data for each transfer */
    static int TIMES_TO_READ = 20;              /* The number of times the client will request the data */
    static int PLAYER_BUFFER_SIZE = 1638400;    /* Clients buffer size 1638400 = 1.57MB */
    static int SLEEP_TIME_MS = 5000;

    /* Display Info */
    String start = "empty";                 /* String holder for the starting battery life */
    String end = "empty2";                  /* String holder for the ending battery life */
    int allMBytes = 0;                      /* Integer holder for the total number of megabytes received during the test */
    TextView tv;                            /* The view the phone displays after completion of test */

    /* Server Info */
    String serverIP = "192.168.0.104";      /* Server IP */
    int serverPort = 11313;                 /* Server port number */



    private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){

        @Override
        public void onReceive(Context arg0, Intent intent) {

            //int level = intent.getIntExtra("level", 0);

            Socket connectionSocket = null;                         /* Socket to communicate with server */
            byte[] inputHolderByteArray = new byte[PLAYER_BUFFER_SIZE]; /* Used to read from the socket */

            int bufferBytes = 0;        /* filling the second buffer */
            int totalBytesRead = 0;     /* The total number of bytes read for this transfer round */
            int read=0;                 /* reading from stream, will contain the number of bytes read or -1 if the end has been hit */

            /* Acquire a wake lock for the phone so it does not go to sleep */
            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass().getName());

            /* Connect to Server */
            try {

                connectionSocket = new Socket(serverIP, serverPort);
                connectionSocket.setReceiveBufferSize(PLAYER_BUFFER_SIZE); //1.5ish MB
                connectionSocket.setKeepAlive(true);
                PrintWriter out = new PrintWriter(connectionSocket.getOutputStream(), true);

                out.print("Client Info: Bytes expected per transfer:" + BYTES_TO_READ + ", Number of transfer to request:" + TIMES_TO_READ+ ", Buffer size:" +PLAYER_BUFFER_SIZE+ ", Sleep time(ms):" + SLEEP_TIME_MS + "\n");
                out.flush();

                wl.acquire();

                for(int i=0; i<TIMES_TO_READ; i++){

                    out.print("Start\n");
                    out.flush();

                    while(totalBytesRead < BYTES_TO_READ){

                        /* Read at most PLAYER_BUFFER_SIZE bytes */
                        read = connectionSocket.getInputStream().read(inputHolderByteArray, 0, PLAYER_BUFFER_SIZE);

                        if(read != -1){
                            bufferBytes += read;
                            totalBytesRead  += read;
                            if(bufferBytes >= PLAYER_BUFFER_SIZE){
                                    try {
                                        Thread.sleep(SLEEP_TIME_MS);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                bufferBytes = 0;
                            }
                        }
                        else{
                            /* End of stream reached */
                            break;
                        }     
                    }

                    allMBytes += ((totalBytesRead/1024)/1024);
                    totalBytesRead = 0;

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }

                int level2 = intent.getIntExtra("level", 0);    /* Ending battery level */

                /* Put data on screen */
                start = "Starting battery level: 100%";
                end = "Ending battery level: " + String.valueOf(level2) + "%";
                out.print("Test Completed: " + start + ", " + end + ", Megabytes Read: " + allMBytes + "\n");
                out.flush();

                wl.release();

                tv.setText(start + "    \n" + end + "    \n Total MB transferred:" + allMBytes);
                setContentView(tv);

            } catch (UnknownHostException e) {
                Log.i("UnknownHost exception ", " ******************** Log Msg UHE " + e.getLocalizedMessage());
                e.printStackTrace();
            } catch (IOException e2) {
                Log.i("IO exception ", "******************** Log Msg IOE " + e2.toString());
                e2.printStackTrace();
            }
        }
    };


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {

        tv = new TextView(this);                /* The view to post text to */
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        this.registerReceiver(this.mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    }
}


First, intent.getIntExtra("level", 0); is not a percentage. intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 1) needs to be compared to intent.getIntExtra(BatteryManager.EXTRA_SCALE, 1) to get a percentage.

Second, do NOT do network I/O on the main application thread, such as onReceive() of a BroadcastReceiver.

Third, you are comparing the battery level with itself. You need to wait for the next ACTION_BATTERY_CHANGED broadcast to find out a new battery level.


You are not supposed to put your application logic in the onReceive() method. This method should only process the intent. Otherwise you will probably block intent delivery to other apps.

Your battery state does not change because you don't get intents delivered while you are blocking in this method. The passed intent itself does not change. The onReceive() method will be called whenever the battery state changes - as long as you don't block it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜