From f986b62f5a2fe59da8fedef1202d8a120b088f73 Mon Sep 17 00:00:00 2001 From: Francesco Gabbrielli Date: Wed, 9 Aug 2017 21:59:45 +1000 Subject: [PATCH] Changes - Settings loading in background Bugfixes - Settings (relative to permissions) were not retained in the first attempt of granting permissions - Camera opening and disposal - Error selecting some sensors in recording --- app/build.gradle | 4 +- .../sensorlogger/CameraHandlerThread.java | 10 +++- .../apps/sensorlogger/LogFTPUploader.java | 6 +- .../apps/sensorlogger/LogFileWriter.java | 6 +- .../apps/sensorlogger/LogTarget.java | 2 +- .../apps/sensorlogger/MainActivity.java | 59 +++++++++++-------- .../apps/sensorlogger/RecordingService.java | 9 ++- .../apps/sensorlogger/SettingsActivity.java | 35 +++++++---- .../apps/sensorlogger/SyncCallbackThread.java | 12 ++-- .../apps/sensorlogger/Util.java | 2 +- app/src/main/res/xml/pref_capture.xml | 4 +- app/src/main/res/xml/pref_logging.xml | 8 +-- 12 files changed, 92 insertions(+), 65 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 24b8bd2..218e20c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "it.francescogabbrielli.apps.sensorlogger" minSdkVersion 11 targetSdkVersion 25 - versionCode 5 - versionName "0.2.3" + versionCode 6 + versionName "0.2.4" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/CameraHandlerThread.java b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/CameraHandlerThread.java index bac0e79..186a477 100644 --- a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/CameraHandlerThread.java +++ b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/CameraHandlerThread.java @@ -39,20 +39,24 @@ public void openCamera(final SurfaceHolder holder, final Runnable callback) { public void run() { try { camera = Camera.open(); + Log.v(getName(), "on"); Camera.Parameters params = camera.getParameters(); params.setPreviewSize(1280,720); params.setPictureSize(1280,720); camera.setParameters(params); + Log.v(getName(), "size reset to 1280x720"); // Util.setCameraDisplayOrientation(MainActivity.this, 0, camera);XXX: rotation? camera.setPreviewDisplay(holder); + Log.v(getName(), "display"); camera.startPreview(); + Log.v(getName(), "start"); if (callback!=null) callback.run(); } catch (IOException e) { - Log.e("Camera", "Error opening camera", e); + Log.e(getName(), "Error opening camera", e); } } - }, 100); + }, 50); } public void closeCamera(){ @@ -73,7 +77,7 @@ public void run() { try { camera.startPreview(); } catch (Throwable t) { - Log.e("Camera", "Restarting preview?", t); + Log.e(getName(), "Restarting preview?", t); } } },100); diff --git a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogFTPUploader.java b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogFTPUploader.java index d070cd0..d853135 100644 --- a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogFTPUploader.java +++ b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogFTPUploader.java @@ -107,7 +107,7 @@ public void run() { * the filename to write to */ @Override - public void send(final byte[] data, final String filename, final Runnable callback) { + public void send(final byte[] data, final String filename, final SyncCallbackThread scThread) { if (client.isConnected()) exec.execute(new Runnable() { @Override @@ -116,8 +116,8 @@ public void run() { try { out = client.storeFileStream(filename); out.write(data); - if (callback!=null) - callback.run(); + if (scThread!=null) + scThread.releaseLock(); Log.d(TAG, "Data written to "+filename); } catch (Exception e) { Log.e(TAG, "Transfer Error", e); diff --git a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogFileWriter.java b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogFileWriter.java index 96c4b23..84381f4 100644 --- a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogFileWriter.java +++ b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogFileWriter.java @@ -21,7 +21,7 @@ public LogFileWriter(File folder) { } @Override - public void send(final byte[] data, final String filename, final Runnable callback) { + public void send(final byte[] data, final String filename, final SyncCallbackThread scThread) { exec.execute(new Runnable() { @Override public void run() { @@ -29,8 +29,8 @@ public void run() { try { out = new FileOutputStream(new File(folder, filename)); out.write(data); - if (callback!=null) - callback.run(); + if (scThread!=null) + scThread.releaseLock(); Log.d(TAG, "Data written to " + filename); } catch (Exception e) { Log.e(TAG, "Error writing file", e); diff --git a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogTarget.java b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogTarget.java index 6eeb6b7..f0c6bdd 100644 --- a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogTarget.java +++ b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/LogTarget.java @@ -12,7 +12,7 @@ public abstract class LogTarget { * * TODO: add a kind of listener interface support instead of single callbacks */ - public abstract void send(final byte[] data, final String filename, final Runnable callback); + public abstract void send(final byte[] data, final String filename, final SyncCallbackThread scThread); /** * Implement final cleanup diff --git a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/MainActivity.java b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/MainActivity.java index 4671fac..89cd8bc 100644 --- a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/MainActivity.java +++ b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/MainActivity.java @@ -83,6 +83,7 @@ public void onPictureTaken(final byte[] imageData, final Camera camera) { } }); } catch (Exception e) { + log(null, sensorsData, null); Log.e(TAG, "Error taking picture", e); } else @@ -133,27 +134,22 @@ public void onShutter() { /** Log data to targets */ private void log(byte[] imageData, byte[] sensorsData, final Camera camera) { - // Sync the callbacks - final SyncCallbackThread syncCallbackThread = new SyncCallbackThread(new Runnable() { + // Sync the callbacks (for restarting the camera preview) + final SyncCallbackThread syncCallbackThread = new SyncCallbackThread() { @Override - public void run() { + public void finalRun() { camera.startPreview(); } - }); - Runnable syncCallback = new Runnable() { - @Override - public void run() { - syncCallbackThread.releaseLock(); - } }; // Local file if (fileWriter != null) try { - syncCallbackThread.addLock(); fileWriter.send(sensorsData, filenameData, null); - if (imageData!=null) - fileWriter.send(imageData, filenameFrame, syncCallback); + if (imageData!=null) { + syncCallbackThread.addLock(); + fileWriter.send(imageData, filenameFrame, syncCallbackThread); + } } catch(Exception e) { Log.e(TAG, "Error writing samples to local file: " + e.getMessage(), e); } @@ -161,10 +157,11 @@ public void run() { // FTP if (ftpUploader != null) try { - syncCallbackThread.addLock(); ftpUploader.send(sensorsData, filenameData, null); - if (imageData!=null) - ftpUploader.send(imageData, filenameFrame, syncCallback); + if (imageData!=null) { + syncCallbackThread.addLock(); + ftpUploader.send(imageData, filenameFrame, syncCallbackThread); + } } catch (Exception e) { Log.e(TAG, "Error sending samples through FTP: " + e.getMessage(), e); } @@ -210,7 +207,7 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter); filenameData = defaults.getProperty("filename_data"); filenameFrame = defaults.getProperty("filename_frame"); - if (prefs.getBoolean(Util.PREF_LOGGING_SAVE, false)) { + if (prefs.getBoolean(Util.PREF_LOGGING_LOCAL, false)) { fileWriter = new LogFileWriter(new File(Environment.getExternalStorageDirectory(), getString(R.string.app_folder))); } if (prefs.getBoolean(Util.PREF_FTP, false)) { @@ -253,7 +250,7 @@ private void verifyPermissions() { requests.add(Manifest.permission.CAMERA); if(prefs.getBoolean(Util.PREF_FTP, false)) requests.add(Manifest.permission.INTERNET); - if(prefs.getBoolean(Util.PREF_LOGGING_SAVE, false)) + if(prefs.getBoolean(Util.PREF_LOGGING_LOCAL, false)) requests.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); // Check if we have requested permission @@ -296,19 +293,26 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis } protected void onPermissionGranted(String permission) { - if (Manifest.permission.CAMERA.equals(permission)) + Log.d(TAG, "Permission granted: "+permission); + if (Manifest.permission.CAMERA.equals(permission)) { setupCamera(); - else if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission)) + prefs.edit().putBoolean(Util.PREF_CAPTURE_CAMERA, true).commit(); + } else if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission)) { new File(Environment.getExternalStorageDirectory(), getString(R.string.app_folder)).mkdirs(); + prefs.edit().putBoolean(Util.PREF_LOGGING_LOCAL, true).commit(); + } else if (Manifest.permission.INTERNET.equals(permission)) { + prefs.edit().putBoolean(Util.PREF_FTP, true).commit(); + } } protected void onPermissionDenied(String permission) { + Log.d(TAG, "Permission denied: "+permission); if (Manifest.permission.CAMERA.equals(permission)) prefs.edit().putBoolean(Util.PREF_CAPTURE_CAMERA, false).commit(); else if (Manifest.permission.INTERNET.equals(permission)) prefs.edit().putBoolean(Util.PREF_FTP, false).commit(); else if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission)) - prefs.edit().putBoolean(Util.PREF_LOGGING_SAVE, false).commit(); + prefs.edit().putBoolean(Util.PREF_LOGGING_LOCAL, false).commit(); } // // ----------------------------------- ---------------------- ---------------------------------- @@ -319,6 +323,7 @@ else if (Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission)) // ---------------------------------- CAMERA SURFACE CALLBACKS --------------------------------- // public void surfaceCreated(SurfaceHolder holder) { + Log.d(TAG, "Open camera"); cameraHandlerThread.openCamera(holder, null); // new Runnable() { // @Override @@ -331,13 +336,14 @@ public void surfaceCreated(SurfaceHolder holder) { public void surfaceChanged(final SurfaceHolder holder, final int format, final int w, final int h) { Camera camera = cameraHandlerThread.getCamera(); + Log.d(TAG, "Camera change: "+camera); if (camera==null) { - cameraHandlerThread.openCamera(holder, new Runnable() { - @Override - public void run() { - surfaceChanged(holder, format, w, h); - } - }); +// cameraHandlerThread.openCamera(holder, new Runnable() { +// @Override +// public void run() { +// surfaceChanged(holder, format, w, h); +// } +// }); return; } @@ -368,6 +374,7 @@ public void run() { } public void surfaceDestroyed(SurfaceHolder holder) { + Log.d(TAG, "Close camera"); cameraHandlerThread.closeCamera(); } // diff --git a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/RecordingService.java b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/RecordingService.java index 02096ee..398fac7 100644 --- a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/RecordingService.java +++ b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/RecordingService.java @@ -14,8 +14,11 @@ import android.util.Log; import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.ListIterator; +import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeSet; @@ -127,11 +130,11 @@ public int compare(Sensor s1, Sensor s2) { if (!prefs.getBoolean(Util.PREF_RECORDING, false)) { - final SensorEvent[] readings = new SensorEvent[255]; + final Map readings = new HashMap<>(); final SensorEventListener listener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { - readings[event.sensor.getType()] = event; + readings.put(event.sensor.getType(), event); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { @@ -208,7 +211,7 @@ public void run() { if (flagTime) sb.append(String.valueOf((t - start) / 1000f)); for (Sensor s : sensors) { - SensorEvent event = readings[s.getType()]; + SensorEvent event = readings.get(s.getType()); int l = Util.getSensorMaxLength(s); for (int i=0; i sensors = Util.getSensors(getActivity()); - for (Sensor s : sensors) { - CheckBoxPreference p = new CheckBoxPreference(getActivity()); - p.setTitle(Util.getSensorName(s)); - p.setSummary(s.getName() + "/" + s.getVendor()); - p.setDefaultValue(false); - p.setKey("pref_sensor_"+s.getType()); - screen.addPreference(p); - } + new AsyncTask>() { + @Override + protected List doInBackground(Void... params) { + List sensors = Util.getSensors(getActivity()); + List list = new LinkedList<>(); + for (Sensor s : sensors) { + CheckBoxPreference p = new CheckBoxPreference(getActivity()); + p.setTitle(Util.getSensorName(s)); + p.setSummary(s.getName() + "/" + s.getVendor()); + p.setDefaultValue(false); + p.setKey("pref_sensor_" + s.getType()); + list.add(p); + } + return list; + } + @Override + protected void onPostExecute(List list) { + for (CheckBoxPreference p : list) + screen.addPreference(p); + } + }.execute(); setPreferenceScreen(screen); } diff --git a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/SyncCallbackThread.java b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/SyncCallbackThread.java index 067441a..a9b0c0d 100644 --- a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/SyncCallbackThread.java +++ b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/SyncCallbackThread.java @@ -2,16 +2,11 @@ import android.util.Log; -public class SyncCallbackThread extends Thread { +public abstract class SyncCallbackThread extends Thread { private final static long SYNC_TIMEOUT = 15000; private int locks; - private Runnable finalCallback; - - public SyncCallbackThread(Runnable callback) { - this.finalCallback = callback; - } public synchronized void addLock() { locks++; @@ -36,6 +31,9 @@ public void run() { } catch (InterruptedException ie) { //Log.e(TAG, "Log sync interrupted", ie); } - finalCallback.run(); + finalRun(); } + + protected abstract void finalRun(); + } diff --git a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/Util.java b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/Util.java index 30c4c38..b5d580c 100644 --- a/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/Util.java +++ b/app/src/main/java/it/francescogabbrielli/apps/sensorlogger/Util.java @@ -35,7 +35,7 @@ public class Util { public final static String PREF_LOGGING_HEADERS = "pref_logging_headers"; public final static String PREF_LOGGING_TIME = "pref_logging_time"; public final static String PREF_LOGGING_TIMESTAMP = "pref_logging_timestamp"; - public final static String PREF_LOGGING_SAVE = "pref_logging_save"; + public final static String PREF_LOGGING_LOCAL = "pref_logging_local"; public final static String PREF_CAPTURE_CAMERA = "pref_capture_camera"; public final static String PREF_CAPTURE_SOUND = "pref_capture_sound"; diff --git a/app/src/main/res/xml/pref_capture.xml b/app/src/main/res/xml/pref_capture.xml index 652a0b8..85e9641 100644 --- a/app/src/main/res/xml/pref_capture.xml +++ b/app/src/main/res/xml/pref_capture.xml @@ -2,13 +2,13 @@ - - - - -