2

Android 앱을 실행 한 후 배터리 잔량을 찾으려고합니다. 휴대 전화가 앱을 완전히 시작하면 코드는 항상 100 % 배터리 수준을 반환합니다 (코드가 많이 소모 되었음에도 불구하고). 75 % 배터리로 앱을 시작하면 테스트가 끝나면 실제 배터리 잔량이 반환됩니다. 내 컴퓨터에 플러그를 꽂은 상태에서 충전을 유지 한 채로 테스트를 시작합니다. 앱을 실행하기 전에 플러그를 뽑습니다. 이상적으로 나는 % 시작과 끝 %를 얻을 수 있기를 원하지만 그것도 모두 100 %를 읽는다. 그래서 여기에 내가 뭐하는 거지입니다 ... 내 활동에서이 전화 : 인 텐트 및 BroadcastReceiver를 사용하여 배터리 잔량을 얻으려면 이상한 행동이 있습니다

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

그런 다음 브로드 캐스트 리시버에서 나는 (즉, 배터리 레벨 변경 때문에 시간 이상 소요) 잔뜩 않습니다. 그런 다음 BoradcastReceiver의 끝에서이 내용을 호출합니다.

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

그런 다음 String End를 서버로 보냅니다. 여기

내 코드 같은 모습입니다 :

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)); 
    } 
} 
+0

일반적인주의 사항 : 레벨의 최대 값을 포함하는 여분의 EXTRA_SCALE ("스케일")이 있습니다. 최대 값은 100 인 것으로 보이므로 퍼센트에 대한 가정은 정확합니다. 그러나 항상 그렇다고 생각하지는 않습니다. – sstn

답변

1

먼저 intent.getIntExtra("level", 0);은 백분율이 아닙니다. 백분율을 얻으려면 intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 1)intent.getIntExtra(BatteryManager.EXTRA_SCALE, 1)과 비교해야합니다.

둘째, 이러한 BroadcastReceiveronReceive()로, 기본 응용 프로그램 스레드에서 네트워크 I/O를 하지을해야합니까.

셋째, 배터리 잔량을 비교하고 있습니다. 다음ACTION_BATTERY_CHANGED 브로드 캐스트를 기다려야 새 배터리 레벨을 알 수 있습니다.

+0

@CommonsWare, 감사합니다. 의도가 방송되기를 어떻게 기다리나요? 얼마나 자주 방송됩니까? 네트워크 IO를 수행하도록 권장되는 특정 장소가 있습니까? 이것은 내 앱이하는 유일한 작업이며, 임의의 바이트를 다운로드하고 배터리 잔량이 얼마나 사용되었는지 확인합니다. – Michael

+0

@ 마이클 : "의도를 방송 할 때까지 어떻게 기다려야합니까?" -'onReceive()'에서 반환. 결국,'onReceive()'가 다시 호출 될 것입니다. https://github.com/commonsguy/cw-advandroid/tree/master/SystemEvents/OnBattery "네트워크 IO를 수행하는 것이 권장되는 특정 장소가 있습니까?" - 백그라운드 스레드 (예 : AsyncTask). "이것은 내 앱이하는 유일한 것입니다. 무작위 바이트를 다운로드하고 사용 된 배터리 양을 확인하십시오." - 음, 좋아. – CommonsWare

+0

@CommonsWare 몇 가지 사항을 변경했습니다 ... 어떻게 보이나요? https://homepage.usask.ca/~mcb394/Receive.java (미안하지만 일부 지역에서는 올바르게 포맷되지 않았습니다). 내 AsyncTask 내부 클래스 메서드에서 BroadcastReceiver가 포함 된 메서드를 안정적으로 호출 할 수 있습니까?더 중요한 것은 지금 정확하게하고있는 것인가? – Michael

0

당신은 onReceive() 메소드에서 응용 프로그램 로직을 넣어 안된다. 이 메소드는 의도 만 처리해야합니다. 그렇지 않으면 다른 앱에 인 텐트를 전달하는 것을 차단할 수 있습니다.

이 방법으로 차단하는 동안 의도가 전달되지 않기 때문에 배터리 상태가 변경되지 않습니다. 전달 된 인 텐트 자체는 변경되지 않습니다. onReceive() 메서드는 배터리 상태가 변경 될 때마다 호출됩니다 (차단하지 않는 한).

+0

죄송합니다, 나는 android를 처음 사용하고 있습니다. BroadcastReceiver에 전화하는 방법에 대해 알려주시겠습니까? BroadcastReceiver 내부에서 또 다른 방법을 만들어 코드를 작성합니까? 그런 다음 그 방법 전후에 BroadcastReceiver에 전화를 걸어 레벨을 얻으시겠습니까? – Michael

관련 문제