/* * (C) Copyright 2015 by fr3ts0n <erwin.scheuch-heilig@gmx.at> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package com.fr3ts0n.ecu.gui.androbd; import android.app.ProgressDialog; import android.content.Context; import android.net.Uri; import android.os.Environment; import android.os.Handler; import android.os.Looper; import android.util.Log; import android.widget.Toast; import com.fr3ts0n.ecu.prot.obd.ElmProt; import com.fr3ts0n.ecu.prot.obd.ObdProt; import com.fr3ts0n.pvs.PvList; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.text.SimpleDateFormat; /** * Task to save measurements * * @author Erwin Scheuch-Heilig */ class FileHelper { /** Date Formatter used to generate file name */ private static final SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy.MM.dd-HH.mm.ss"); private static ProgressDialog progress; private Context context; private ElmProt elm; /** * Initialize static data for static calls * * @param context APP context * @param elm Elm protocol data to be stored */ public FileHelper(Context context, ElmProt elm) { this.context = context; this.elm = elm; } /** * get default path for load/store operation * * path is based on configured <user data location>/<package name> * * @return default path for current app context */ public static String getPath(Context context) { // generate file name return Environment.getExternalStorageDirectory() + File.separator + context.getPackageName(); } /** * get filename (w/o extension) based on current date & time * * @return file name */ public static String getFileName() { return dateFmt.format(System.currentTimeMillis()); } /** * Save all data in a independent thread */ public void saveDataThreaded() { // generate file name final String mPath = getPath(context); final String mFileName = mPath + File.separator + getFileName() + ".obd"; // create progress dialog progress = ProgressDialog.show(context, context.getString(R.string.saving_data), mFileName, true); Thread saveTask = new Thread() { public void run() { Looper.prepare(); saveData(mPath, mFileName); progress.dismiss(); Looper.loop(); } }; saveTask.start(); } /** * Save all data */ public synchronized void saveData(String mPath, String mFileName) { File outFile; // ensure the path is created new File(mPath).mkdirs(); outFile = new File(mFileName); // prevent data updates for saving period ObdItemAdapter.allowDataUpdates = false; try { outFile.createNewFile(); FileOutputStream fStr = new FileOutputStream(outFile); ObjectOutputStream oStr = new ObjectOutputStream(fStr); oStr.writeInt(elm.getService()); oStr.writeObject(ObdProt.PidPvs); oStr.writeObject(ObdProt.VidPvs); oStr.writeObject(ObdProt.tCodes); oStr.close(); fStr.close(); String msg = String.format("%s %d Bytes to %s", context.getString(R.string.saved), outFile.length(), mPath); Log.i(context.getString(R.string.saved), msg); Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); } catch (Exception e) { Toast.makeText(context, e.toString(), Toast.LENGTH_SHORT).show(); e.printStackTrace(); } // we are done saving, allow data updates again ObdItemAdapter.allowDataUpdates = true; } /** * Load all data in a independent thread * @param uri Uri of ile to be loaded */ public synchronized void loadDataThreaded(final Uri uri, final Handler reportTo, final int reportMessage) { // create progress dialog progress = ProgressDialog.show(context, context.getString(R.string.loading_data), uri.getPath(), true); Thread loadTask = new Thread() { public void run() { Looper.prepare(); loadData(uri); progress.dismiss(); reportTo.sendMessage(reportTo.obtainMessage(reportMessage)); Looper.loop(); } }; loadTask.start(); } /** * Load data from file into data sructures * * @param uri URI of file to be loaded */ public synchronized int loadData(final Uri uri) { int numBytesLoaded = 0; String msg; InputStream inStr; try { inStr = context.getContentResolver().openInputStream(uri); numBytesLoaded = inStr.available(); msg = String.format("%d Bytes", numBytesLoaded); ObjectInputStream oIn = new ObjectInputStream(inStr); /* ensure that measurement page is activated to avoid deletion of loaded data afterwards */ int currService = oIn.readInt(); /* if data was saved in mode 0, keep current mode */ if(currService != 0) elm.setService(currService, false); /* read in the data */ ObdProt.PidPvs = (PvList) oIn.readObject(); ObdProt.VidPvs = (PvList) oIn.readObject(); ObdProt.tCodes = (PvList) oIn.readObject(); oIn.close(); Log.i(context.getString(R.string.load), context.getString(R.string.loaded).concat(" ").concat(msg)); Toast.makeText(context, context.getString(R.string.loaded).concat(" ").concat(msg), Toast.LENGTH_SHORT).show(); } catch (Exception ex) { Toast.makeText(context, ex.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); Log.e(context.getString(R.string.load), ex.getMessage()); } return numBytesLoaded; } }