Основной Java-приложение Android для регистрации компьютерных данных в базе данных SQLite


Это довольно простой приложение, которое я сделал, чтобы собрать необходимые данные для отдельного проекта. Однако это также мой первый идти на любой Android программирование, поэтому я знаю, что есть наверняка проблемы с ним (сам код является функциональной и делает то, что я хочу это делать, я имею в виду вопросы, как в неэффективности, синтаксис и тому подобное). Что я могу сделать, чтобы улучшить код и сделать его более эффективным?

Эти четыре исходных файлов проекта:

MainActivity.java:

package com.test.batterytemperaturelogger;

import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

import java.io.File;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /* Obtains necessary permissions. */
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            requestPermissions(new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
        }

        /* Implements functionality for the data logging buttons. */
        OnClickListener listenerLoggerButtons = new OnClickListener(){
            @Override
            public void onClick(View view){
                Intent intent = new Intent(MainActivity.this, TemperatureLoggerService.class);
                switch (view.getId()){
                    case R.id.startLogger:
                        // Start service
                        startService(intent);
                        break;
                    case R.id.stopLogger:
                        stopService(intent);
                        break;
                }
            }
        };
        findViewById(R.id.startLogger).setOnClickListener(listenerLoggerButtons);
        findViewById(R.id.stopLogger).setOnClickListener(listenerLoggerButtons);

        /* Implements functionality for the email data button. */
        OnClickListener listenerEmail = new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent emailIntent = new Intent(Intent.ACTION_SEND);
                emailIntent.setType("text/plain");
                emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"test1234@gmail.com"});
                emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Battery Temperature Logger Data");
                emailIntent.putExtra(Intent.EXTRA_TEXT, "This email contains the battery temperature database attached.");
                File root = Environment.getExternalStorageDirectory();
                String pathToAttachedFile = TemperatureDBHelper.DATABASE_NAME;
                File file = new File(root, pathToAttachedFile);
                if (!file.exists()){
                    return;
                }
                Uri uri = Uri.fromFile(file);
                emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
                startActivity(Intent.createChooser(emailIntent, "Pick an email provider."));
            }
        };
        findViewById(R.id.emailDB).setOnClickListener(listenerEmail);
    }
}

TemperatureLoggerService.java

package com.test.batterytemperaturelogger;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.widget.Toast;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class TemperatureLoggerService extends Service{
    private TemperatureDBHelper temperatureDatabase;
    private Context context;
    public static final String TAG = "TempLoggerService";
    private boolean isRunning = false;
    private TemperatureLoggerServiceHandler TemperatureLoggerServiceHandler;
    DecimalFormat decimalFormat = new DecimalFormat("0.00");
    DecimalFormat decimalFormat2 = new DecimalFormat("0.0000");
    @SuppressLint("SimpleDateFormat")
    DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

    @Override
    public void onCreate(){
        HandlerThread handlerThread = new HandlerThread("TemperatureLoggerThread", Process.THREAD_PRIORITY_BACKGROUND);
        handlerThread.start();
        Looper looper = handlerThread.getLooper();
        TemperatureLoggerServiceHandler = new TemperatureLoggerServiceHandler(looper);
        isRunning = true;
        context = getApplicationContext();
        this.temperatureDatabase = new TemperatureDBHelper(context);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        Message message = TemperatureLoggerServiceHandler.obtainMessage();
        message.arg1 = startId;
        TemperatureLoggerServiceHandler.sendMessage(message);
        Toast.makeText(this, "Temperature logging started.", Toast.LENGTH_SHORT).show();

        // If service is killed while starting, it restarts
        return START_STICKY;
    }

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

    @Override
    public void onDestroy(){
        isRunning = false;
        Toast.makeText(this, "Temperature logging stopped.", Toast.LENGTH_SHORT).show();
        temperatureDatabase.exportDB();
        temperatureDatabase.clearDB();
    }

    /* Calculates and returns battery temperature. */
    public double getBatteryTemperature(){
        Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        assert intent != null;
        double celsius = ((double)intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE,0)) / 10;
        return Double.valueOf(decimalFormat.format(((celsius * 9) / 5) + 32));
    }

    /* Returns battery level. */
    private double getBatteryLevel(){
        Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        assert intent != null;
        return (double)intent.getIntExtra(BatteryManager.EXTRA_LEVEL,0);
    }

    /* Returns battery voltage. */
    private double getBatteryVoltage(){
        Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        assert intent != null;
        double batteryVoltage = (double)intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE,0);
        batteryVoltage = Double.valueOf(decimalFormat2.format(batteryVoltage / 1000));     /* Convert from millivolts to volts. */
        return batteryVoltage;
    }

    /* Returns instantaneous battery current. */
    private double getBatteryCurrent(){
        BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
        assert batteryManager != null;
        double batteryCurrent = (double)batteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW);
        batteryCurrent = Double.valueOf(decimalFormat2.format(batteryCurrent*Math.pow(10, -6)));   /* Convert from microamps to amps. */
        return batteryCurrent;
    }

    /* Returns available memory as a percent value. */
    private double getAvailMemory(){
        ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
        ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        assert activityManager != null;
        activityManager.getMemoryInfo(memoryInfo);
        double availPercent;
        availPercent = Double.valueOf(decimalFormat2.format(memoryInfo.availMem / (double)memoryInfo.totalMem * 100.0));
        return availPercent;
    }

    /* Calculates and returns the CPU usage. */
    private float getCPULoad() {
        try {
            RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
            String load = reader.readLine();

            String[] toks = load.split(" +");  // Split on one or more spaces

            long idle1 = Long.parseLong(toks[4]);
            long cpu1 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[5])
                    + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);

            try {
                Thread.sleep(400);
            } catch (Exception e) {
                e.printStackTrace();
            }

            reader.seek(0);
            load = reader.readLine();
            reader.close();

            toks = load.split(" +");

            long idle2 = Long.parseLong(toks[4]);
            long cpu2 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[5])
                    + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);

            float raw_load = (float)(Math.abs(cpu2 - cpu1)) / Math.abs((cpu2 + idle2) - (cpu1 + idle1));
            if (Float.isNaN(raw_load)){
                raw_load = (float)0.0;
            }
            return Float.valueOf(decimalFormat2.format(raw_load*100));

        } catch (IOException e) {
            e.printStackTrace();
        }

        return 0;
    }

    private final class TemperatureLoggerServiceHandler extends Handler{
        TemperatureLoggerServiceHandler(Looper looper){
            super(looper);
        }

        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void handleMessage(Message message){
            synchronized (this){
                while(isRunning){
                    try {
                        Date currentTime = Calendar.getInstance().getTime();
                        String currentTimeString = dateFormat.format(currentTime);
                        double battery_temp = getBatteryTemperature();
                        double battery_level = getBatteryLevel();
                        double battery_voltage = getBatteryVoltage();
                        double battery_current = getBatteryCurrent();
                        double avail_memory = getAvailMemory();
                        float cpu_load = getCPULoad();
                        temperatureDatabase.insertEntry(currentTimeString, battery_temp, battery_level, battery_voltage, battery_current, avail_memory, cpu_load);
                        Log.i(TAG, "TemperatureLoggerService running! " +currentTimeString+ " " +battery_temp+ " " +battery_level+ " "
                                +battery_voltage+ " " +battery_current+ " " +avail_memory+ " " +cpu_load);
                        Thread.sleep(500);
                    }
                    catch(Exception e){
                        Log.i(TAG, e.getMessage());
                    }
                }
            }
            // Stops the service for the start Id
            stopSelfResult(message.arg1);
        }
    }
}

TemperatureDBHelper.java

package com.test.batterytemperaturelogger;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class TemperatureDBHelper extends SQLiteOpenHelper{
    private static final int DATABASE_VERSION = 1;
    static final String DATABASE_NAME = "BatteryTemperatures.db";
    private static final String SQL_CREATE_ENTRIES =
        "CREATE TABLE " + TemperatureContract.TemperatureEntry.TABLE_NAME + " (" +
        TemperatureContract.TemperatureEntry._ID + " INTEGER PRIMARY KEY," +
        TemperatureContract.TemperatureEntry.COLUMN_TIME + " TEXT," +
        TemperatureContract.TemperatureEntry.COLUMN_TEMPERATURE + " REAL," +
        TemperatureContract.TemperatureEntry.COLUMN_LEVEL + " REAL," +
        TemperatureContract.TemperatureEntry.COLUMN_VOLTAGE + " REAL," +
        TemperatureContract.TemperatureEntry.COLUMN_CURRENT + " REAL," +
        TemperatureContract.TemperatureEntry.COLUMN_MEMORY + " REAL," +
        TemperatureContract.TemperatureEntry.COLUMN_CPU + " REAL)";

    private static final String SQL_DELETE_ENTRIES =
        "DROP TABLE IF EXISTS " + TemperatureContract.TemperatureEntry.TABLE_NAME;

    TemperatureDBHelper(Context context){
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        Log.d("Database operations", "Database created!");
    }

    public void onCreate(SQLiteDatabase db){
        db.execSQL(SQL_CREATE_ENTRIES);
        Log.d("Database operations", "Database created!");
    }

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
        // For now the upgrade process just deletes the old database and creates
        // a new one
        db.execSQL(SQL_DELETE_ENTRIES);
        onCreate(db);
        Log.d("Database operations", "Database upgraded!");
    }

    long insertEntry(String time, double temperature, double level, double voltage, double current, double memory, float cpu_load){
        SQLiteDatabase database = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(TemperatureContract.TemperatureEntry.COLUMN_TIME, time);
        values.put(TemperatureContract.TemperatureEntry.COLUMN_TEMPERATURE, temperature);
        values.put(TemperatureContract.TemperatureEntry.COLUMN_LEVEL, level);
        values.put(TemperatureContract.TemperatureEntry.COLUMN_VOLTAGE, voltage);
        values.put(TemperatureContract.TemperatureEntry.COLUMN_CURRENT, current);
        values.put(TemperatureContract.TemperatureEntry.COLUMN_MEMORY, memory);
        values.put(TemperatureContract.TemperatureEntry.COLUMN_CPU, cpu_load);
        long newRowId = database.insert(TemperatureContract.TemperatureEntry.TABLE_NAME, null, values);

        Log.d("Database operations", "Row inserted!");
        return newRowId;
    }

    public Cursor getEntry(long id){
        SQLiteDatabase database = this.getReadableDatabase();
        Cursor res = database.rawQuery( " SELECT * FROM " + TemperatureContract.TemperatureEntry.TABLE_NAME + " WHERE " +
            TemperatureContract.TemperatureEntry._ID + "=?", new String[]{Long.toString(id)});
        Log.d("Database operations", "Row returned!");
        return res;
    }

    void clearDB(){
        SQLiteDatabase database = this.getWritableDatabase();
        database.delete(TemperatureContract.TemperatureEntry.TABLE_NAME, null, null);
        database.close();
    }

    void exportDB(){
        File sd = Environment.getExternalStorageDirectory();
        File data = Environment.getDataDirectory();
        FileChannel source;
        FileChannel destination;
        String currentDBPath = "/data/" + "com.test.batterytemperaturelogger" + "/databases/" + DATABASE_NAME;
        File currentDB = new File(data, currentDBPath);
        File backupDB = new File(sd, DATABASE_NAME);
        try{
            source = new FileInputStream(currentDB).getChannel();
            destination = new FileOutputStream(backupDB).getChannel();
            destination.transferFrom(source, 0, source.size());
            source.close();
            destination.close();
        } catch(IOException e){
            e.printStackTrace();
        }

    }
}

TemperatureContract.java

package com.test.batterytemperaturelogger;

import android.provider.BaseColumns;

final class TemperatureContract {
    // Prevent someone from accidentally instantiating the contract class; make
    // constructor private.
    private TemperatureContract(){
    }

    /* Inner class that defines the table contents */
    static class TemperatureEntry implements BaseColumns{
        static final String TABLE_NAME = "temperature_database";
        static final String COLUMN_TIME = "time";
        static final String COLUMN_TEMPERATURE = "battery_temperature";
        static final String COLUMN_LEVEL = "battery_level";
        static final String COLUMN_VOLTAGE = "battery_voltage";
        static final String COLUMN_CURRENT = "battery_current";
        static final String COLUMN_MEMORY = "avail_memory";
        static final String COLUMN_CPU = "cpu_load";
    }
}


113
1
задан 11 марта 2018 в 05:03 Источник Поделиться
Комментарии