package cn.zadui.reader.service; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.UUID; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Build; import android.telephony.TelephonyManager; import android.util.Log; import cn.zadui.reader.helper.FAQCalendar; import cn.zadui.reader.helper.NetHelper; import cn.zadui.reader.helper.Settings; /** * Used for collecting app usage. * @author david * */ public class UsageCollector { public static final String HOUR_PREFER_STR="000000000000000000000000"; public static final String INI_USAGE_STR="0"; static final String TAG="UsageCollector"; public static void openApp(Context ctx){ long currentTime=System.currentTimeMillis(); long lastOpenTS=Settings.getLongPreferenceValue(ctx, Settings.PRE_LAST_OPENED_AT, currentTime); //long interval=currentTime-lastOpenTS; // Return if the interval to last opened less than 15 minutes. //if (interval<15*60*1000) return; String oldUsageStr=Settings.getStringPreferenceValue(ctx, Settings.PRE_USAGE,INI_USAGE_STR); Log.d(TAG,oldUsageStr); FAQCalendar lastOpened=new FAQCalendar(lastOpenTS); FAQCalendar now=new FAQCalendar(currentTime); if (now.getUnixDay()>lastOpened.getUnixDay()){ long distance=now.getUnixDay()-lastOpened.getUnixDay(); StringBuilder sb=new StringBuilder(); sb.append(oldUsageStr); for(long i=0;i<distance-1;i++) sb.append("0"); sb.append("1"); Settings.updateStringPreferenceValue(ctx, Settings.PRE_USAGE, sb.toString()); }else{ Log.i(TAG,oldUsageStr); char[] usageChars=oldUsageStr.toCharArray(); int count=Character.getNumericValue(usageChars[usageChars.length-1]); usageChars[usageChars.length-1]=numberToChar(count+1); Settings.updateStringPreferenceValue(ctx, Settings.PRE_USAGE, new String(usageChars)); } Settings.updateLongPreferenceValue(ctx, Settings.PRE_LAST_OPENED_AT, System.currentTimeMillis()); // update hour prefer usage string String old=Settings.getStringPreferenceValue(ctx, Settings.PRE_HOUR_PREFER_USAGE,HOUR_PREFER_STR); Settings.updateStringPreferenceValue(ctx, Settings.PRE_HOUR_PREFER_USAGE, updateHourPreferUsageString(now,old)); } public static String updateHourPreferUsageString(Calendar now,String old){ char[] preferUsageChars=old.toCharArray(); int whichHour=now.get(Calendar.HOUR_OF_DAY); preferUsageChars[whichHour]=numberToChar(Character.getNumericValue(preferUsageChars[whichHour])+1); return new String(preferUsageChars); } public static void resetCollectedData(Context ctx){ Settings.updateStringPreferenceValue(ctx, Settings.PRE_USAGE, INI_USAGE_STR); Settings.updateStringPreferenceValue(ctx, Settings.PRE_HOUR_PREFER_USAGE,HOUR_PREFER_STR); Settings.updateLongPreferenceValue(ctx, Settings.PRE_COLLECTION_STARTED_AT, System.currentTimeMillis()); } /** * TODO The upload process should be in a thread and started by an Activity or Service. * @param ctx */ public static void uploadCollectedUsageDate(Context ctx){ String usageStr=Settings.getStringPreferenceValue(ctx, Settings.PRE_USAGE,INI_USAGE_STR); if (usageStr.length()<3) return; URL url; try { url = new URL(NetHelper.webPath("http", "/ping")); //"http://172.29.1.67:3389/collector"); HttpURLConnection uc = (HttpURLConnection) url.openConnection(); uc.setDoInput(true); uc.setDoOutput(true); uc.setRequestMethod("POST"); String data=generateHttpPostData(ctx); Log.d(TAG,"upload data is => "+data); uc.getOutputStream().write(data.getBytes("UTF-8")); uc.getOutputStream().close(); if (uc.getResponseCode()==HttpURLConnection.HTTP_CREATED){ resetCollectedData(ctx); } uc.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void uploadUserComment(Context ctx){ String comment=Settings.getStringPreferenceValue(ctx, Settings.PRE_USER_COMMENTS, ""); if(comment.length()<10){ Settings.updateStringPreferenceValue(ctx, Settings.PRE_USER_COMMENTS, ""); return; } URL url; try { url = new URL(NetHelper.webPath("http", "/comments")); //"http://172.29.1.67:3389/collector"); HttpURLConnection uc = (HttpURLConnection) url.openConnection(); uc.setDoInput(true); uc.setDoOutput(true); uc.setRequestMethod("POST"); StringBuilder sb=new StringBuilder(); sb.append("comment[uid]="); sb.append(getDeviceId(ctx)); sb.append("&comment[content]="); sb.append(comment); String data=sb.toString(); Log.d(TAG,"user comment is => "+data); uc.getOutputStream().write(data.getBytes("UTF-8")); uc.getOutputStream().close(); if (uc.getResponseCode()==HttpURLConnection.HTTP_CREATED){ Settings.updateStringPreferenceValue(ctx, Settings.PRE_USER_COMMENTS, ""); } uc.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void nofityInstalled(Context ctx){ URL url; try { url = new URL(NetHelper.webPath("http", "/activate")); //"http://172.29.1.67:3389/collector"); Log.d(TAG,url.toString()); HttpURLConnection http = (HttpURLConnection) url.openConnection(); http.setDoInput(true); http.setDoOutput(true); http.setRequestMethod("POST"); StringBuilder sb=new StringBuilder(); sb.append("uid="+getDeviceId(ctx)); SimpleDateFormat df=new SimpleDateFormat("yyyyMMdd'T'HH:mm"); Date installed=new Date(Settings.getLongPreferenceValue(ctx, Settings.PRE_INSTALLED_AT, 0)); sb.append("&installed_at="+df.format(installed)); try { PackageInfo pi = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0); sb.append("&build="+String.valueOf(pi.versionCode)); } catch (NameNotFoundException e) { e.printStackTrace(); } String data=sb.toString(); Log.d(TAG,"POST User Active Date => "+data); http.getOutputStream().write(data.getBytes("UTF-8")); http.getOutputStream().close(); http.getOutputStream().close(); if (http.getResponseCode()==HttpURLConnection.HTTP_CREATED){ Log.d(TAG,"Activate response is=> " + String.valueOf(http.getResponseCode())); //Settings.updateStringPreferenceValue(ctx, Settings.PRE_USER_COMMENTS, ""); } http.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception ee){ ee.printStackTrace(); } } /** * Ping string includes: * uid * this collection started at * device information: os type and version; app version etc. * usage string * hour prefer usage string * @param ctx * @return */ public static String generateHttpPostData(Context ctx){ StringBuilder sb=new StringBuilder(); sb.append("pv=2"); sb.append("&uid="+getDeviceId(ctx)); SimpleDateFormat df=new SimpleDateFormat("yyyyMMdd'T'HH:mm"); Date d=new Date(Settings.getLongPreferenceValue(ctx, Settings.PRE_COLLECTION_STARTED_AT, 0)); Date installed=new Date(Settings.getLongPreferenceValue(ctx, Settings.PRE_INSTALLED_AT, 0)); sb.append("&installed_at="+df.format(installed)); sb.append("&from="+df.format(d)); sb.append("&dev[os][name]="+"android"); sb.append("&dev[os][codename]="+Build.VERSION.CODENAME); sb.append("&dev[os][incremental]="+Build.VERSION.INCREMENTAL); sb.append("&dev[os][release]="+Build.VERSION.RELEASE); sb.append("&dev[os][sdk]="+String.valueOf(Build.VERSION.SDK_INT)); sb.append("&dev[model]="+Build.MODEL); sb.append("&dev[device]="+Build.DEVICE); sb.append("&app[package_name]="+ctx.getPackageName()); boolean testBuild=(ctx.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)!=0; sb.append("&app[debug]="+String.valueOf(testBuild)); PackageInfo pi=null; try { pi = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0); } catch (NameNotFoundException e) { e.printStackTrace(); } sb.append("&app[version_code]="+String.valueOf(pi.versionCode)); //sb.append("&dev[device]="+Build.DEVICE); //DisplayMetrics displaymetrics = new DisplayMetrics(); sb.append("&usage="+Settings.getStringPreferenceValue(ctx, Settings.PRE_USAGE, INI_USAGE_STR)); sb.append("&hour="+Settings.getStringPreferenceValue(ctx, Settings.PRE_HOUR_PREFER_USAGE, HOUR_PREFER_STR)); return sb.toString(); } public static char numberToChar(int value){ if (value>9){ return (char)(value-9+64); }else{ return Character.forDigit(value, 10); } } public static String getDeviceId(Context ctx){ final TelephonyManager tm = (TelephonyManager)ctx.getSystemService(Context.TELEPHONY_SERVICE); String tmDevice, tmSerial, tmPhone, androidId; tmDevice = "" + tm.getDeviceId(); tmSerial = "" + tm.getSimSerialNumber(); androidId = "" + android.provider.Settings.Secure.getString(ctx.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode()); //String deviceId = deviceUuid.toString(); return deviceUuid.toString(); } private static final SimpleDateFormat RFC822 = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", java.util.Locale.ENGLISH); }