Android 开发-电池(Battery)电量等数据的监听,用Service,Broadcaset,以及Thread的方式实现

罗绪
2023-12-01

案例介绍:

实现一个电池属性实时监听器。这些熟悉包括温度,电池电量....等等。而且,使用Service,Broadcast,以及Thread的方式来实现。

实现原理:

1.在Service中开启线程;

2.在Service中,监听

ACTION_BATTERY_CHANGED

实现一个BroadcastReceiver的

onReceive(Context ctx,Intent intent)
中,就包含了电池属性相关的值。

3.在线程中,将intent的值写入到文件。

4.在ui中,可以读取文件,进行显示。

核心代码:

MyBatteryService.java


public class MyBatteryService extends Service {

	private final static String TAG = "BatteryService";
	
	public static final String LOGFILEPATH = "BATTERYSERVICE/battery.csv";
	
	private final static String[] batteryExtraKeys = {"level", "scale", "voltage", "temperature", "plugged", "status", "health", "present", "technology", "icon-small"};

	private File mBatteryLogFile;
	private int mCount;
	private Intent mLastBatteryIntent;
    private boolean mQuitThread;
    private boolean mThreadRunning = false;

    @Override
    public void onCreate() {
    	super.onCreate();
		if (!mThreadRunning) {
			mCount = 0;
			mLastBatteryIntent = null;
			mQuitThread = false;
	        Thread thr = new Thread(null, mTaskRunnable, "BatteryService");
	        thr.start();
			registerReceiver(mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
	        Toast.makeText(this, "Battery Service started", Toast.LENGTH_SHORT).show();
		}
    }
	
	@Override
	public void onDestroy() {
    	Log.i(TAG, "onDestroy");
        mQuitThread = true;
        notifyService();
        
    	super.onDestroy();
    	unregisterReceiver(mBatInfoReceiver);
        Toast.makeText(this, "Battery Service stopped", Toast.LENGTH_SHORT).show();
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context ctx, Intent intent) {
			try {
            	mCount += 1;
				mLastBatteryIntent = (Intent) intent.clone();
				notifyService();
			}
			catch (Exception e) {
				Log.e(TAG,e.getMessage(), e);
			}
		}

	};

	private void logBattery(Intent batteryChangeIntent) {
		if (batteryChangeIntent == null)
			return;
		try {
			FileWriter out = null;
			if (mBatteryLogFile != null) {
				try {
					out = new FileWriter(mBatteryLogFile, true);
				}
				catch (Exception e) {}
			}
			if (out == null) {
				File root = FileUtils.getLogFilePath();//  Environment.getExternalStorageDirectory();
				if (root == null)
					throw new Exception("external storage dir not found");
				mBatteryLogFile = new File(root, MyBatteryService.LOGFILEPATH);
				boolean fileExists = mBatteryLogFile.exists();
				if (!fileExists) {
					mBatteryLogFile.getParentFile().mkdirs();
					mBatteryLogFile.createNewFile();
				}
				if (!mBatteryLogFile.exists()) 
					throw new Exception("creation of file '"+mBatteryLogFile.toString()+"' failed");
				if (!mBatteryLogFile.canWrite()) 
					throw new Exception("file '"+mBatteryLogFile.toString()+"' is not writable");
				out = new FileWriter(mBatteryLogFile, true);
				if (!fileExists) {
					String header = createHeadLine();
					out.write(header);
					out.write("\n");
				}
			}
			if (mLastBatteryIntent != null) {
				String extras = createBatteryInfoLine(mLastBatteryIntent);
				out.write(extras);
				out.write("\n");
			}
			out.flush();
			out.close();
		} catch (Exception e) {
			Log.e(TAG,e.getMessage(),e);
		}
	}

    private String createHeadLine() {
    	StringBuffer result = new StringBuffer();
    	result.append("Nr;TimeMillis");
    	for (String key : batteryExtraKeys)
			result.append(";").append(key);
		return result.toString();
	}

	private String createBatteryInfoLine(Intent batteryIntent) {
    	StringBuffer result = new StringBuffer();
    	result.append(Integer.toString(mCount)).append(";").append(Long.toString(System.currentTimeMillis()));
    	Bundle extras = batteryIntent.getExtras();
    	for (String key : batteryExtraKeys)
			result.append(";").append(extras.get(key));
		return result.toString();
	}

    Runnable mTaskRunnable = new Runnable() {
		public void run() {
            mThreadRunning = true;
            Log.i(TAG,"STARTING BATTERYSERVICE TASK");
            while (!mQuitThread) {
				Log.i(TAG,"STARTING BATTERYSERVICE TASK begin logfile");
				logBattery(mLastBatteryIntent);
                synchronized (MyBatteryService.this) {
                	try {
                    	MyBatteryService.this.wait();
                	} catch (Exception ignore) {}
                }
            }
            mThreadRunning = false;
			logBattery(mLastBatteryIntent);
            Log.i(TAG,"LEAVING BATTERYSERVICE TASK");
        }
    };
	
	public void notifyService() {
		synchronized (MyBatteryService.this) {
			MyBatteryService.this.notifyAll();
		}
	}
}

说明:

1. 定义MyBatteryService类,用于在后台进行电量属性的获取;

1. 在MyBatteryService中,注册BroadcastReceiver:

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

2. mBatInfoReceiver是一个BroadcastReceiver, mLastBatteryIntent保存了接收到的数据;

3. mTaskRunnable是工作线程,通过logBattery(mLastBatteryIntent);将接收到的数据写入文件;

写入的文件内容,大概如下:

Nr;TimeMillis;level;scale;voltage;temperature;plugged;status;health;present;technology;icon-small

1;1650438867518;72;100;3983;364;2;2;2;true;Li-ion;17303668

2;1650438876180;72;100;4003;363;2;2;2;true;Li-ion;17303668

3;1650438886226;72;100;4000;364;2;2;2;true;Li-ion;17303668

4;1650438896285;72;100;4011;365;2;2;2;true;Li-ion;17303668

5;1650438906325;72;100;3996;365;2;2;2;true;Li-ion;17303668

6;1650438916364;72;100;4028;364;2;2;2;true;Li-ion;17303668

7;1650438926414;72;100;4018;365;2;2;2;true;Li-ion;17303668

8;1650438936468;72;100;4026;365;2;2;2;true;Li-ion;17303668

9;1650438946513;72;100;4006;365;2;2;2;true;Li-ion;17303668

10;1650438956576;72;100;4018;365;2;2;2;true;Li-ion;17303668

另外,也可以通过系统提供的BatteryManager来实现类似的功能:

BatteryManager batteryManager = (BatteryManager)context.getSystemService(context.BATTERY_SERVICE);

int level = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);

项目传送门:

Android-电池管理-实时获取电池电量,温度...等属性。-Android文档类资源-CSDN下载


 类似资料: