标签:
布局battery_dog.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center_horizontal" > <Button android:id="@+id/btStart" android:layout_width= "120px" android:layout_height="80px" android:text="START Battery Dog Service"></Button> <Button android:id="@+id/btStop" android:layout_width= "120px" android:layout_height="80px" android:textSize="14px" android:text="STOP Battery Dog Service"></Button> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/btRawFormat" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Raw Format"></Button> <Button android:id="@+id/btShowFormated" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Show Formated"></Button> <Button android:id="@+id/btGraph" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Graph"></Button> </LinearLayout> <EditText android:id="@+id/output" android:layout_width="fill_parent" android:autoText="true" android:capitalize="sentences" android:layout_weight="1" android:freezesText="true" android:layout_height="0dip" android:text="[press refresh]"> <requestFocus /> </EditText> </LinearLayout>
BatteryGraph(Graph图表状态):
package net.sf.andbatdog.batterydog; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.ArrayList; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.os.Environment; import android.view.Display; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; public class BatteryGraph extends Activity { private final static String TAG = "BATDOG.graph"; private final static int MENU_8H = 1; private final static int MENU_24H = 2; private final static int MENU_7DAYS = 3; private final static int MENU_ALL = 4; private final static int margXLeft = 5; private final static int margXRight = 5; private final static int margYTop = 60; private final static int margYBottom = 5; private long width = 300; private long height = 300; private long w = width - margXLeft - margXRight; private long h = height - margYTop - margYBottom; private long mDeltaTime = 24*60*60*1000; private long mOffset = 0; private GraphView mGraphView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGraphView = new GraphView(this); setContentView(mGraphView); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(Menu.NONE, MENU_8H, Menu.NONE, "8h"); menu.add(Menu.NONE, MENU_24H, Menu.NONE, "24h"); menu.add(Menu.NONE, MENU_7DAYS, Menu.NONE, "7 days"); menu.add(Menu.NONE, MENU_ALL, Menu.NONE, "all"); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == MENU_8H) { mDeltaTime = 8*60*60*1000; mOffset = 0; mGraphView.invalidate(); } else if (item.getItemId() == MENU_24H) { mDeltaTime = 24*60*60*1000; mOffset = 0; mGraphView.invalidate(); } else if (item.getItemId() == MENU_7DAYS) { mDeltaTime = 7*24*60*60*1000; mOffset = 0; mGraphView.invalidate(); } else if (item.getItemId() == MENU_ALL) { mDeltaTime = 0; mOffset = 0; mGraphView.invalidate(); } return true; } @Override public boolean onTrackballEvent(MotionEvent event) { super.onTrackballEvent(event); if (event.getAction() == MotionEvent.ACTION_DOWN) { mOffset = 0; mGraphView.invalidate(); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { float x = event.getRawX(); if (x < 0) { mOffset -= mDeltaTime/5; mGraphView.invalidate(); } else if (x>0) { mOffset += mDeltaTime/5; if (mOffset > 0) mOffset = 0; mGraphView.invalidate(); } } return true; } private class GraphView extends View { private Paint mPaint = new Paint(); private BatteryRecord[] mRecords; private float mLastX; private void readRecords() { try { mRecords = readLog(); } catch (Exception e) { Log.e(TAG,e.getMessage(), e); } } @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); if (event.getAction() == MotionEvent.ACTION_DOWN) { mLastX = event.getRawX(); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { float x = event.getRawX(); float dx = x-mLastX; mLastX = x; long ldx = (long)(mDeltaTime*dx/width); mOffset -= ldx; if (mOffset > 0) mOffset = 0; mGraphView.invalidate(); } return true; } public GraphView(Context context) { super(context); readRecords(); Display display = ((WindowManager) context.getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); width = display.getWidth(); height = display.getHeight(); w = width - margXLeft - margXRight; h = height - margYTop - margYBottom; } @Override protected void onDraw(Canvas canvas) { Paint paint = mPaint; paint.setStrokeWidth(0); Paint paintP = new Paint(); paintP.setStrokeWidth(0); paintP.setColor(Color.YELLOW); Paint paintV = new Paint(); paintV.setStrokeWidth(0); paintV.setColor(Color.RED); Paint paintT = new Paint(); paintT.setStrokeWidth(0); paintT.setColor(Color.GREEN); canvas.drawColor(Color.BLACK); if ((mRecords == null) || (mRecords.length == 0)) { paint.setColor(Color.WHITE); canvas.drawText("no data found", 10, 50, paint); return; } drawMarker(canvas, paintP, paintV, paintT); int maxRec = mRecords.length; long minTime = mRecords[0].timestamp; long maxTime = mRecords[maxRec-1].timestamp; long dTime = maxTime-minTime; if (mDeltaTime != 0) { dTime = mDeltaTime; minTime = maxTime-dTime+mOffset; } BatteryRecord rec; BatteryRecord oldRec; for (int i = 0; i <= maxRec; i++) { if (i == 0) oldRec = new BatteryRecord(0, minTime, 0, 100, 0, 0); else oldRec = mRecords[i-1]; if (i == maxRec) rec = new BatteryRecord(0, maxTime, 0, 100, 0, 0); else rec = mRecords[i]; drawRecordLine(canvas, rec, oldRec, minTime, dTime, paintP, paintV, paintT); } } private void drawMarker(Canvas canvas, Paint paintP, Paint paintV, Paint paintT) { Paint paint = new Paint(); for (int i = 0; i <= 10; i++) { if (i == 5) paint.setColor(Color.GRAY); else paint.setColor(Color.DKGRAY); float x = margXLeft; float y = margYBottom+h*(10-i)/10; canvas.drawLine(x, y, x+w, y, paint); } canvas.drawText("100%", margXLeft, margYBottom+13, paintP); canvas.drawText("4V", margXLeft, margYBottom+h*6/10+13, paintV); canvas.drawText("100%", margXLeft+w-20, margYBottom+13, paintP); canvas.drawText("4V", margXLeft+w-20, margYBottom+h*6/10+13, paintV); } private void drawRecordLine(Canvas canvas, BatteryRecord rec, BatteryRecord oldRec, long minTime, long dTime, Paint paintP, Paint paintV, Paint paintT ) { float x1 = margXLeft+(w*(oldRec.timestamp-minTime)) / dTime; float yP1 = margYBottom+h-(h*oldRec.level) / rec.scale; float yV1 = margYBottom+h-(h*oldRec.voltage) / 10000; float yT1 = margYBottom+h-(h*oldRec.temperature) / 1000; float x2 = margXLeft+(w*( rec.timestamp-minTime)) / dTime; float yP2 = margYBottom+h-(h* rec.level) / rec.scale; float yV2 = margYBottom+h-(h* rec.voltage) / 10000; float yT2 = margYBottom+h-(h* rec.temperature) / 1000; if (rec.count == 1) { canvas.drawLine(x1, yP1, x1, margYBottom+h, paintP); canvas.drawLine(x1, yV1, x1, margYBottom+h, paintV); canvas.drawLine(x1, yT1, x1, margYBottom+h, paintT); canvas.drawLine(x2, yP2, x2, margYBottom+h, paintP); canvas.drawLine(x2, yV2, x2, margYBottom+h, paintV); canvas.drawLine(x2, yT2, x2, margYBottom+h, paintT); } else { canvas.drawLine(x1, yP1, x2, yP2, paintP); canvas.drawLine(x1, yV1, x2, yV2, paintV); canvas.drawLine(x1, yT1, x2, yT2, paintT); } } } class BatteryRecord { int count; long timestamp; int level; int scale; int voltage; int temperature; public BatteryRecord(int count, long timestamp, int level, int scale, int voltage, int temperature) { this.count = count; this.timestamp = timestamp; this.level = level; this.scale = scale; this.voltage = voltage; this.temperature = temperature; } } private BatteryRecord[] readLog() throws Exception { ArrayList<BatteryRecord> result = new ArrayList<BatteryRecord>(); File root = Environment.getExternalStorageDirectory(); if (root == null) throw new Exception("external storage dir not found"); File batteryLogFile = new File(root,BatteryDog_Service.LOGFILEPATH); if (!batteryLogFile.exists()) throw new Exception("logfile ‘"+batteryLogFile+"‘ not found"); if (!batteryLogFile.canRead()) throw new Exception("logfile ‘"+batteryLogFile+"‘ not readable"); FileReader reader = new FileReader(batteryLogFile); BufferedReader in = new BufferedReader(reader); String line = in.readLine(); while (line != null) { BatteryRecord rec = parseLine(line); if (rec == null) Log.e(TAG, "could not parse line: ‘"+line+"‘"); else result.add(rec); line = in.readLine(); } in.close(); return (BatteryRecord[]) result.toArray(new BatteryRecord[result.size()]); } private BatteryRecord parseLine(String line) { if (line == null) return null; String[] split = line.split("[;]"); if (split.length < 6) return null; if (split[0].equals("Nr")) return null; try { int count = Integer.parseInt(split[0]); long timestamp = Long.parseLong(split[1]); int level = Integer.parseInt(split[2]); int scale = Integer.parseInt(split[3]); int voltage = Integer.parseInt(split[4]); int temperature = Integer.parseInt(split[5]); return new BatteryRecord(count, timestamp, level, scale, voltage, temperature); } catch (Exception e) { Log.e(TAG,"Invalid format in line ‘"+line+"‘"); return null; } } }
BatteryDog主体类:
package net.sf.andbatdog.batterydog; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Date; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class BatteryDog extends Activity { private static final int OUTPUT_LINES = 100; private static final int LINE_LENGTH = 50; private static final String TAG = "BATDOG"; private Button btStart; private Button btStop; private Button btRawFormat; private Button btShowFormated; private Button btGraph; private EditText mOutput; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.battery_dog); mOutput= (EditText) findViewById(R.id.output); // find buttons in view btStart = ((Button) findViewById(R.id.btStart)); btStop = ((Button) findViewById(R.id.btStop)); btRawFormat= ((Button) findViewById(R.id.btRawFormat)); btShowFormated= ((Button) findViewById(R.id.btShowFormated)); btGraph = ((Button) findViewById(R.id.btGraph)); // set actions for buttons btStart.setOnClickListener(StartServiceListener); btStop.setOnClickListener(StopServiceListener); btRawFormat.setOnClickListener(RawFormatListener); btShowFormated.setOnClickListener(ShowFormatedListener); btGraph.setOnClickListener(GraphListener); } OnClickListener StartServiceListener = new OnClickListener() { public void onClick(View v) { try { startService(new Intent(BatteryDog.this, BatteryDog_Service.class)); } catch (Exception e) { Log.e(TAG, e.getMessage(), e); Toast.makeText(BatteryDog.this, "Start Service failed: "+e.getMessage(), Toast.LENGTH_SHORT).show(); } } }; OnClickListener StopServiceListener = new OnClickListener() { public void onClick(View v) { try { stopService(new Intent(BatteryDog.this, BatteryDog_Service.class)); } catch (Exception e) { Log.e(TAG, e.getMessage(), e); Toast.makeText(BatteryDog.this, "Stop Service failed: "+e.getMessage(), Toast.LENGTH_SHORT).show(); } } }; OnClickListener RawFormatListener = new OnClickListener() { public void onClick(View v) { updateLog(false); } }; OnClickListener ShowFormatedListener = new OnClickListener() { public void onClick(View v) { updateLog(true); } }; OnClickListener GraphListener = new OnClickListener() { public void onClick(View v) { startActivity(new Intent(BatteryDog.this, BatteryGraph.class)); } }; private void updateLog(boolean doFormat) { try { File root = Environment.getExternalStorageDirectory(); if (root == null) throw new Exception("external storage dir not found"); File batteryLogFile = new File(root,BatteryDog_Service.LOGFILEPATH); if (!batteryLogFile.exists()) throw new Exception("logfile ‘"+batteryLogFile+"‘ not found"); if (!batteryLogFile.canRead()) throw new Exception("logfile ‘"+batteryLogFile+"‘ not readable"); long len = batteryLogFile.length(); int size = (int)Math.min((long)OUTPUT_LINES*LINE_LENGTH, len); StringBuffer text = new StringBuffer(size); FileReader reader = new FileReader(batteryLogFile); BufferedReader in = new BufferedReader(reader); if (doFormat) { text.append(in.readLine()).append("\n"); } if (len > OUTPUT_LINES*LINE_LENGTH) { in.skip(len-OUTPUT_LINES*LINE_LENGTH); // skip incomplete line in.readLine(); } String line = in.readLine(); while (line != null) { if (doFormat) { line = parseLine(line); } if (line != null) text.append(line).append("\n"); line = in.readLine(); } in.close(); mOutput.setText(text.toString()); } catch (Exception e) { Log.e(TAG,e.getMessage(),e); mOutput.setText(e.getMessage()); } } private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); private DecimalFormat dfT = new DecimalFormat("###.#"); private DecimalFormat dfV = new DecimalFormat("##.###"); private String parseLine(String line) { if (line == null) return line; String[] split = line.split("[;]"); if (split.length < 6) return line; if (split[0].equals("Nr")) return line; try { int count = Integer.parseInt(split[0]); long time = Long.parseLong(split[1]); int level = Integer.parseInt(split[2]); int scale = Integer.parseInt(split[3]); int percent = level*100/scale; int voltage = Integer.parseInt(split[4]); int temperature = Integer.parseInt(split[5]); double v = 0.001*voltage; double t = 0.1*temperature; String timestamp = sdf.format(new Date(time)); StringBuffer result = new StringBuffer(); result.append(Integer.toString(count)).append(". ") .append(timestamp).append(" ") .append(percent).append("% ") .append(dfV.format(v)).append("V ") .append(dfT.format(t)).append("%") ; // for (int i = 6; i < split.length; i++) { // result.append(" ").append(split[i]); // } return result.toString(); } catch (Exception e) { Log.e(TAG, e.getMessage(), e); return line; } } }
BatteryDog_Service:
package net.sf.andbatdog.batterydog; import java.io.File; import java.io.FileWriter; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.Environment; import android.os.IBinder; import android.widget.Toast; public class BatteryDog_Service extends Service { private final static String TAG = "BATDOG.service"; public static final String LOGFILEPATH = "BatteryDog/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; @Override public void onCreate() { super.onCreate(); if (!mThreadRunning) { mCount = 0; mLastBatteryIntent = null; mQuitThread = false; Thread thr = new Thread(null, mTask, "BatteryDog_Service"); thr.start(); registerReceiver(mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); Toast.makeText(this, "BatteryDog Service started", Toast.LENGTH_SHORT).show(); } } @Override public void onDestroy() { Log.i(TAG, "onDestroy"); mQuitThread = true; notifyService(); super.onDestroy(); unregisterReceiver(mBatInfoReceiver); Toast.makeText(this, "BatteryDog 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 = Environment.getExternalStorageDirectory(); if (root == null) throw new Exception("external storage dir not found"); mBatteryLogFile = new File(root,BatteryDog_Service.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(); } /** * The function that runs in our worker thread */ Runnable mTask = new Runnable() { public void run() { mThreadRunning = true; Log.i(TAG,"STARTING BATTERYDOG TASK"); while (!mQuitThread) { logBattery(mLastBatteryIntent); synchronized (BatteryDog_Service.this) { try { BatteryDog_Service.this.wait(); } catch (Exception ignore) {} } } mThreadRunning = false; logBattery(mLastBatteryIntent); Log.i(TAG,"LEAVING BATTERYDOG TASK"); } }; public void notifyService() { synchronized (BatteryDog_Service.this) { BatteryDog_Service.this.notifyAll(); } } }
run:
标签:
原文地址:http://www.cnblogs.com/caidupingblogs/p/5510995.html