Java tutorial
// Copyright 2015 The Vanadium Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package io.v.android.apps.reader; import android.content.Context; import android.util.Log; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; import java.io.Closeable; import java.io.File; import java.io.FileWriter; import java.io.IOException; import io.v.android.apps.reader.model.DeviceInfoFactory; /** * A utility class for logging user actions, such as touch gestures and button presses. * Writes the user actions into a CSV file. * * This class implements {@link Closeable} interface, but closing this logger is not necessary to * get the full logs, because the log printing streams are flushed right after each row is written. */ public class UserActionLogger implements Closeable { private static final String TAG = GestureListener.class.getSimpleName(); private static volatile UserActionLogger instance; private String mDeviceId; private CSVPrinter mTouchPrinter; private CSVPrinter mNavigationPrinter; /** * Singleton accessor of the UserActionLogger class. */ public static UserActionLogger getInstance(Context context) { UserActionLogger result = instance; if (instance == null) { synchronized (UserActionLogger.class) { result = instance; if (result == null) { instance = result = new UserActionLogger(context); } } } return result; } private UserActionLogger(Context context) { mDeviceId = DeviceInfoFactory.getDeviceId(context); if (Utils.hasExternalStoragePermission(context)) { initPrinters(); } } public void initPrinters() { File dir = Utils.getLogDirectory(); Log.i(TAG, "User action logs are saved at: " + dir.getAbsolutePath()); String startTime = Utils.getTimeString(); File touchLogFile = new File(dir, String.format("reader-%s-touch-%s.log", mDeviceId, startTime)); File navigationLogFile = new File(dir, String.format("reader-%s-navigation-%s.log", mDeviceId, startTime)); try { mTouchPrinter = CSVFormat.DEFAULT.withHeader("ACTION", "TIMESTAMP").print(new FileWriter(touchLogFile)); mNavigationPrinter = CSVFormat.DEFAULT.withHeader("ACTION", "VALUE", "TIMESTAMP") .print(new FileWriter(navigationLogFile)); } catch (IOException e) { handleException(e); try { close(); } catch (IOException e2) { // Nothing to do here. } } } @Override public void close() throws IOException { IOException ex = null; if (mTouchPrinter != null) { try { mTouchPrinter.close(); } catch (IOException e) { ex = e; } finally { mTouchPrinter = null; } } if (mNavigationPrinter != null) { try { mNavigationPrinter.close(); } catch (IOException e) { if (ex != null) { ex.addSuppressed(e); } else { ex = e; } } finally { mNavigationPrinter = null; } } if (ex != null) { throw ex; } } /** * Writes the given touch action to the CSV file. * * @param action name of the touch action. */ public void writeTouchAction(String action) { if (mTouchPrinter == null) { return; } try { mTouchPrinter.printRecord(action, timestamp()); mTouchPrinter.flush(); } catch (IOException e) { handleException(e); } } /** * Writes the given navigation action to the CSV file. * * @param action name of the navigation action. * @param value the value associated with the action. */ public void writeNavigationAction(String action, int value) { if (mNavigationPrinter == null) { return; } try { mNavigationPrinter.printRecord(action, value, timestamp()); mNavigationPrinter.flush(); } catch (IOException e) { handleException(e); } } private String timestamp() { return Long.toString(System.currentTimeMillis()); } private static void handleException(Exception e) { Log.e(TAG, e.getMessage(), e); } }