Android Open Source - retroband Content Manager






From Project

Back to project page retroband.

License

The source code is released under:

Apache License

If you think the Android project retroband listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2014 The Retro Band - Open source smart band project
 *// w ww  .  j ava  2 s  . c  o  m
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hardcopy.retroband.contents;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;

import com.hardcopy.retroband.logic.Analyzer;
import com.hardcopy.retroband.utils.Logs;

import android.content.Context;
import android.database.Cursor;
import android.text.format.Time;


public class ContentManager {
  
  private static final String TAG = "ContentManager";
  
  public static final int RESPONSE_INVALID_PARAMETER = -1;
  public static final int RESPONSE_NO_MATCHING_CONTENT = -2;
  
  public static final int RESPONSE_OBJECT_ADDED = 11;
  public static final int RESPONSE_OBJECT_UPDATED = 12;
  public static final int RESPONSE_OBJECT_DELETED = 13;
  
  public static final int REPORT_TYPE_YEAR = 1;
  public static final int REPORT_TYPE_MONTH = 2;
  public static final int REPORT_TYPE_DAY = 3;
  public static final int REPORT_TYPE_HOUR = 4;
  
  
  private static ContentManager mContentManager = null;    // Singleton pattern
  
  private Context mContext;
  private IContentManagerListener mContentManagerListener;
  private DBHelper mDB = null;
  
  private ArrayList<ContentObject> mContentList;    // Cache content objects
  
  // Time parameters
  private static final int REPORT_INTERVAL = 1000;
  private static final int REPORT_SAMPLING_TIME = 50;
  private long mPreviousProcessTime = 0;
  
  // Activity statistics
  // WARNING: Date parameter is the zero-based number
  // because we use parameters as array index
  private int mThisYear = -1;
  
  private int mThisMonth = -1;  // (in the range [0,11])
  private int[] mMonthArray = new int[12];
  
  private int mThisDay = -1;    // (in the range [0,30])
  private int[] mDayArray = new int[31];
  
  private int mThisHour = -1;    // (in the range [0,23])
  private int[] mHourArray = new int[24];
  
  private int mThisMinute = -1;  // (in the range [0,59])
  private int[] mMinuteArray = new int[60]; 
  

  /**
   * Constructor
   */
  private ContentManager(Context c, IContentManagerListener l) {
    mContext = c;
    mContentManagerListener = l;
    
    mContentList = new ArrayList<ContentObject>();
    
    //----- Make DB helper
    if(mDB == null) {
      mDB = new DBHelper(mContext).openWritable();
    }
    
    //----- Initialize activity data
    initializeActivityParams();
    getCurrentReportsFromDB();
  }
  
  /**
   * Singleton pattern
   */
  public synchronized static ContentManager getInstance(Context c, IContentManagerListener l) {
    if(mContentManager == null)
      mContentManager = new ContentManager(c, l);
    
    return mContentManager;
  }
  
  public synchronized void finalize() {
    if(mDB != null) {
      mDB.close();
      mDB = null;
    }
    if(mContentList != null)
      mContentList.clear();
    mContentManager = null;
  }

  
  /*****************************************************
   *  Private methods
   ******************************************************/
  private void initializeBuffer() {
    Arrays.fill(mMonthArray, 0x00000000);
    Arrays.fill(mDayArray, 0x00000000);
    Arrays.fill(mHourArray, 0x00000000);
    Arrays.fill(mMinuteArray, 0x00000000);
  }
  
  private void initializeActivityParams() {
    initializeBuffer();
    
    Calendar cal = Calendar.getInstance();
    mThisYear = cal.get(Calendar.YEAR);
    mThisMonth = cal.get(Calendar.MONTH);      // 0~11
    mThisDay = cal.get(Calendar.DAY_OF_MONTH) - 1;  // convert to 0~30
    mThisHour = cal.get(Calendar.HOUR_OF_DAY);    // 0~23
    mThisMinute = cal.get(Calendar.MINUTE);      // 0~59
  }
  
  /**
   * Make sum of calorie at this month, day, hour.
   */
  private void getCurrentReportsFromDB() {
    // Get month data in this year
    Cursor c = mDB.selectReportWithDate(REPORT_TYPE_MONTH, mThisYear, -1, -1, -1);
    if(c != null) {
      getDataFromCursor(MODE_CURRENT_TIME, REPORT_TYPE_MONTH, c);
      c.close();
    }
    
    // Get day data in this month
    c = mDB.selectReportWithDate(REPORT_TYPE_DAY, mThisYear, mThisMonth, -1, -1);
    if(c != null) {
      getDataFromCursor(MODE_CURRENT_TIME, REPORT_TYPE_DAY, c);
      c.close();
    }
    
    // Get hour data in this day
    c = mDB.selectReportWithDate(REPORT_TYPE_HOUR, mThisYear, mThisMonth, mThisDay, -1);
    if(c != null) {
      getDataFromCursor(MODE_CURRENT_TIME, REPORT_TYPE_HOUR, c);
      c.close();
    }
  }
  
  /**
   * Load sum of calorie from DB
   */
  private int[] getReportsFromDB(int type, int year, int month, int day, int hour) {
    int[] timeArray = null;
    // Get month data in this year
    Cursor c = mDB.selectReportWithDate(type, year, month, day, hour);
    if(c != null) {
      timeArray = getDataFromCursor(MODE_SELECTED_TIME, type, c);
      c.close();
    }
    return timeArray;
  }
  
  public static final int MODE_CURRENT_TIME = 1;
  public static final int MODE_SELECTED_TIME = 2;
  /**
   * Parse cursor and make cache
   * @param mode    Make cache based on current time or specified time
   * @param type    REPORT_TYPE_MONTH or REPORT_TYPE_DAY or REPORT_TYPE_HOUR
   * @param c      Cursor
   * @return  int[]  Parsed result array
   */
  private int[] getDataFromCursor(int mode, int type, Cursor c) {
    int[] timeArray = null;
    int columnIndex = 0;
    
    switch(type) {
    case REPORT_TYPE_MONTH:
      if(mode == MODE_CURRENT_TIME) {
        timeArray = mMonthArray;
      } else {
        timeArray = new int[12];
        Arrays.fill(timeArray, 0x00000000);
      }
      
      columnIndex = DBHelper.INDEX_ACCEL_MONTH;
      break;
      
    case REPORT_TYPE_DAY:
      if(mode == MODE_CURRENT_TIME) {
        timeArray = mDayArray;
      } else {
        timeArray = new int[31];
        Arrays.fill(timeArray, 0x00000000);
      }
      
      columnIndex = DBHelper.INDEX_ACCEL_DAY;
      break;
      
    case REPORT_TYPE_HOUR:
      if(mode == MODE_CURRENT_TIME) {
        timeArray = mHourArray;
      } else {
        timeArray = new int[24];
        Arrays.fill(timeArray, 0x00000000);
      }
      
      columnIndex = DBHelper.INDEX_ACCEL_HOUR;
      break;
    default:
      return null;
    }
    
    if(c != null && c.getCount() > 0) {
      c.moveToFirst();
      while(!c.isAfterLast()) {
        int index = c.getInt(columnIndex);
        int calorie = c.getInt(DBHelper.INDEX_ACCEL_DATA1);
        if(calorie > 0 && index > -1 && index < timeArray.length) {
          timeArray[index] = calorie;
        }
        
        c.moveToNext();
      }
    }
    
    return timeArray;
  }
  
  /**
   * Add newly received data to cache and write on DB if needed
   * @param ar  Raw accel data from remote
   */
  private void addActivityReport(ActivityReport ar) {
    if(ar != null) {
      
      boolean isTimeChanged = false;
      Calendar cal = Calendar.getInstance();
      int prevYear = mThisYear;
      int prevMonth = mThisMonth;
      int prevDay = mThisDay;
      int prevHour = mThisHour;
      
      // Add calorie to buffer
      if(mThisMonth != cal.get(Calendar.MONTH)) {
        // Push monthly report to DB
        Time tempTime = new Time();
        tempTime.set(1, 0, 0, 1, prevMonth, prevYear);  // convert day: in the range [1,31], month: in the range [0,11]
        long millis = tempTime.toMillis(true);
        pushReportToDB(REPORT_TYPE_MONTH, millis, prevYear, prevMonth, 1, 0);
        
        // Set new date
        mThisYear = cal.get(Calendar.YEAR);
        mThisMonth = cal.get(Calendar.MONTH);
        if(mThisMonth == Calendar.JANUARY)
          Arrays.fill(mMonthArray, 0x00000000);
        isTimeChanged = true;
      }
      mMonthArray[mThisMonth] += ar.mCalorie;
      
      if(mThisDay != cal.get(Calendar.DAY_OF_MONTH) - 1 || isTimeChanged) {
        // Push daily report to DB
        Time tempTime = new Time();
        tempTime.set(1, 0, 0, prevDay + 1, prevMonth, prevYear);  // convert day: in the range [1,31], month: in the range [0,11]
        long millis = tempTime.toMillis(true);
        pushReportToDB(REPORT_TYPE_DAY, millis, prevYear, prevMonth, prevDay, 0);
        
        if(isTimeChanged) {
          // Month changed !! 
          Arrays.fill(mDayArray, 0x00000000);          
        } else {
          // Month is not changed but day changed
        }
        
        mThisDay = cal.get(Calendar.DAY_OF_MONTH) - 1;
        isTimeChanged = true;
      }
      mDayArray[mThisDay] += ar.mCalorie;
      
      if(mThisHour != cal.get(Calendar.HOUR_OF_DAY) || isTimeChanged) {
        // Push hourly report to DB
        Time tempTime = new Time();
        tempTime.set(1, 0, prevHour, prevDay + 1, prevMonth, prevYear);  // convert day: in the range [1,31], month: in the range [0,11]
        long millis = tempTime.toMillis(true);
        pushReportToDB(REPORT_TYPE_HOUR, millis, prevYear, prevMonth, prevDay, prevHour);
        
        if(isTimeChanged) {
          // Day changed !! 
          Arrays.fill(mHourArray, 0x00000000);          
        } else {
          // Day is not changed but hour changed
        }
        
        mThisHour = cal.get(Calendar.HOUR_OF_DAY);
        isTimeChanged = true;
      }
      mHourArray[mThisHour] += ar.mCalorie;
      
      if(isTimeChanged || mThisMinute != cal.get(Calendar.MINUTE)) {
        if(isTimeChanged) {
          // Hour changed !! 
          Arrays.fill(mMinuteArray, 0x00000000);          
        } else {
          // Hour is not changed but minute changed
        }
        
        // Add to new minute buffer
        mThisMinute = cal.get(Calendar.MINUTE);
      }
      mMinuteArray[mThisMinute] += ar.mCalorie;
      
    }  // end of if(ar != null)
  }
  
  /**
   * Write sum of calorie on DB
   * @param type    REPORT_TYPE_YEAR, REPORT_TYPE_MONTH, REPORT_TYPE_DAY, REPORT_TYPE_HOUR
   * @param time    time in milli-second
   * @param year
   * @param month
   * @param day
   * @param hour
   */
  private void pushReportToDB(int type, long time, int year, int month, int day, int hour) {
    int calorie = 0;
    
    switch(type) {
    case REPORT_TYPE_YEAR:
      // Not available
      return;
      
    case REPORT_TYPE_MONTH:
      if(month > -1 && month < mMonthArray.length) {
        calorie = mMonthArray[month];
      } else {
        return;
      }
      break;
      
    case REPORT_TYPE_DAY:
      if(day > -1 && day < mDayArray.length) {
        calorie = mDayArray[day];
      } else {
        return;
      }
      break;
      
    case REPORT_TYPE_HOUR:
      if(hour > -1 && hour < mHourArray.length) {
        calorie = mHourArray[hour];
      } else {
        return;
      }
      break;
    }
    
    if(calorie < 1)
      return;
    
    // Make data array to save
    // We use only one information, calorie.
    int[] dataArray = new int[5];
    Arrays.fill(dataArray, 0x00000000);
    dataArray[0] = calorie;
    
    mDB.insertActivityReport(type, time, year, month, day, hour, dataArray, null);
  }
  
  
  /*****************************************************
   *  Public methods
   ******************************************************/
  
  public void setListener(IContentManagerListener l) {
    mContentManagerListener = l;
  }
  
  /**
   * Save sum of calorie cache to DB
   */
  public void saveCurrentActivityReport() {
    int prevYear = mThisYear;
    int prevMonth = mThisMonth;
    int prevDay = mThisDay;
    int prevHour = mThisHour;
    
    // Push monthly report to DB
    Time tempTime1 = new Time();
    tempTime1.set(1, 0, 0, 1, prevMonth, prevYear);  // convert day: in the range [1,31], month: in the range [0,11]
    long millis1 = tempTime1.toMillis(true);
    pushReportToDB(REPORT_TYPE_MONTH, millis1, prevYear, prevMonth, 1, 0);
    
    // Push daily report to DB
    Time tempTime2 = new Time();
    tempTime2.set(1, 0, 0, prevDay + 1, prevMonth, prevYear);  // convert day: in the range [1,31], month: in the range [0,11]
    long millis2 = tempTime2.toMillis(true);
    pushReportToDB(REPORT_TYPE_DAY, millis2, prevYear, prevMonth, prevDay, 0);
    
    // Push hourly report to DB
    Time tempTime3 = new Time();
    tempTime3.set(1, 0, prevHour, prevDay + 1, prevMonth, prevYear);  // convert day: in the range [1,31], month: in the range [0,11]
    long millis3 = tempTime3.toMillis(true);
    pushReportToDB(REPORT_TYPE_HOUR, millis3, prevYear, prevMonth, prevDay, prevHour);
  }
  
  
  /**
   * After parsing packets from remote, service calls this method with result object.
   * This method analyze accel raw data and calculate walks, calories.
   * And makes an activity report instance which has analyzed results.
   * @param co    content object which has accel raw data array
   * @return      activity report instance which has analyzed results.
   */
  public synchronized ActivityReport addContentObject(ContentObject co) {
    if(co == null) {
      return null;
    }
    
    // Caching contents
    mContentList.add(co);
    
    // Get current time
    long currentTime = System.currentTimeMillis();
    if(mPreviousProcessTime < 1)
      mPreviousProcessTime = currentTime;
    
    // Analyze cached contents
    ActivityReport ar = null;
    if(currentTime - mPreviousProcessTime > REPORT_INTERVAL) {
      Logs.d("#");
      Logs.d("# before analyzer");
      // Analyze accelerometer value and make report
      ar = Analyzer.analyzeAccel(mContentList, REPORT_SAMPLING_TIME, REPORT_INTERVAL);
      
      // Remember activity report
      if(ar != null) {
        addActivityReport(ar);
      }
      mPreviousProcessTime = currentTime;
      mContentList.clear();
    }
    
    return ar;
  }
  
  /**
   * Delete specified content object from cache and DB
   * @param co_id    content object ID
   * @return      result code
   */
  public synchronized int deleteContentObject(int co_id) {
    if(co_id < 0)
      return RESPONSE_INVALID_PARAMETER;
    // Remove from DB
    mDB.deleteReportWithID(co_id);
    // Remove cached
    int count = 0;
    for(int i = mContentList.size() - 1; i > -1; i--) {
      ContentObject temp = mContentList.get(i);
      if(temp.mId == co_id) {
        mContentList.remove(i);
        count++;
      }
    }
    if(count < 1)
      return RESPONSE_NO_MATCHING_CONTENT;
    
    return RESPONSE_OBJECT_DELETED;
  }
  
  /**
   * Delete all contents
   * @return    result code
   */
  public synchronized int deleteContentsAll() {
    // Remove from DB
    mDB.deleteReportWithType(ContentObject.CONTENT_TYPE_ACCEL);
    // Remove cached
    mContentList.clear();
    return RESPONSE_OBJECT_DELETED;
  }
  
  /**
   * Returns cached activity data
   * @param type    time period type
   * @return      array of activity data
   */
  public int[] getCurrentActivityData(int type) {
    int[] activityData = null;
    
    switch(type) {
    case REPORT_TYPE_MONTH:
      activityData = mMonthArray;
      break;
      
    case REPORT_TYPE_DAY:
      activityData = mDayArray;
      break;
      
    case REPORT_TYPE_HOUR:
      activityData = mHourArray;
      break;
      
    default:
      break;
    }  // End of switch

    return activityData;
  }
  
  /**
   * Returns activity data from DB
   * @param type    time period type
   * @param year
   * @param month
   * @param day
   * @param hour
   * @return      array of activity data
   */
  public int[] getActivityData(int type, int year, int month, int day, int hour) {
    int[] activityData = null;
    
    activityData = getReportsFromDB(type, year, month, day, hour);
    
    return activityData;
  }
  
  
}




Java Source Code List

com.hardcopy.retroband.DeviceListActivity.java
com.hardcopy.retroband.MainActivity.java
com.hardcopy.retroband.bluetooth.BluetoothManager.java
com.hardcopy.retroband.bluetooth.ConnectionInfo.java
com.hardcopy.retroband.bluetooth.TransactionBuilder.java
com.hardcopy.retroband.bluetooth.TransactionReceiver.java
com.hardcopy.retroband.contents.ActivityReport.java
com.hardcopy.retroband.contents.ContentManager.java
com.hardcopy.retroband.contents.ContentObject.java
com.hardcopy.retroband.contents.DBHelper.java
com.hardcopy.retroband.contents.IContentManagerListener.java
com.hardcopy.retroband.fragments.GraphFragment.java
com.hardcopy.retroband.fragments.IAdapterListener.java
com.hardcopy.retroband.fragments.IDialogListener.java
com.hardcopy.retroband.fragments.IFragmentListener.java
com.hardcopy.retroband.fragments.LLFragmentAdapter.java
com.hardcopy.retroband.fragments.LLSettingsFragment.java
com.hardcopy.retroband.fragments.RenderingStatistics.java
com.hardcopy.retroband.fragments.RenderingView.java
com.hardcopy.retroband.fragments.TimelineAdapter.java
com.hardcopy.retroband.fragments.TimelineFragment.java
com.hardcopy.retroband.logic.Analyzer.java
com.hardcopy.retroband.logic.PeakDetector.java
com.hardcopy.retroband.service.RetroBandService.java
com.hardcopy.retroband.service.ServiceMonitoring.java
com.hardcopy.retroband.utils.AppSettings.java
com.hardcopy.retroband.utils.Constants.java
com.hardcopy.retroband.utils.Logs.java
com.hardcopy.retroband.utils.RecycleUtils.java
com.hardcopy.retroband.utils.Utils.java