From 240a738d52ed5c149480c55827bdc664c1dfbea4 Mon Sep 17 00:00:00 2001 From: secretrobotron Date: Sat, 2 Jul 2016 11:11:26 +0300 Subject: [PATCH 1/2] Simple Analytics 1. Created Analytics class. 2. Added Analytics tracking to various places. --- .../mozilla/hackathon/kiboko/Analytics.java | 129 ++++++++++++++++++ .../kiboko/activities/DashboardActivity.java | 16 +++ .../kiboko/adapters/TopicsAdapter.java | 3 + .../kiboko/fragments/TopicsFragment.java | 3 + .../kiboko/services/ChatHeadService.java | 2 + 5 files changed, 153 insertions(+) create mode 100644 app/src/main/java/com/mozilla/hackathon/kiboko/Analytics.java diff --git a/app/src/main/java/com/mozilla/hackathon/kiboko/Analytics.java b/app/src/main/java/com/mozilla/hackathon/kiboko/Analytics.java new file mode 100644 index 0000000..14d95af --- /dev/null +++ b/app/src/main/java/com/mozilla/hackathon/kiboko/Analytics.java @@ -0,0 +1,129 @@ +package com.mozilla.hackathon.kiboko; + +import android.content.Context; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Created by secretrobotron on 7/2/16. + */ + +public class Analytics { + + private static final String ANALYTICS_FILENAME = "jisort_analytics.txt"; + private static final long TIME_BETWEEN_SAVES= 5000; + + private class AnalyticsItem { + String mName; + String mData = null; + Date mTime; + + public AnalyticsItem(String name) { + mName = name; + mTime = new Date(System.currentTimeMillis()); + } + + public AnalyticsItem(String name, String data) { + mName = name; + mData = data; + mTime = new Date(System.currentTimeMillis()); + } + + public String toString() { + String output = "[" + mTime.toString() + "] " + mName; + if (mData != null) { + output += " -> (" + mData.toString() + ")"; + } + return output; + } + } + + protected static Analytics sAnalytics = null; + + private List mItems; + + private long mLastSaveTime = 0; + + private Analytics() { + mItems = new ArrayList(); + + // Prevent from saving right away. + mLastSaveTime = System.currentTimeMillis(); + } + + private void flushItems() { + save(true); + } + + private void save() { + save(false); + } + + private void save(boolean flush) { + long now = System.currentTimeMillis(); + + if (!flush && now - mLastSaveTime < TIME_BETWEEN_SAVES) { + return; + } + + mLastSaveTime = now; + + String output = ""; + + // this should run every once in a while to save to perm memory + for (AnalyticsItem item : mItems) { + output += item.toString() + "\n"; + } + + // Replace this with save to disk functionality + FileOutputStream outputStream; + + try { + outputStream = App.getContext().openFileOutput(ANALYTICS_FILENAME, Context.MODE_PRIVATE | Context.MODE_APPEND); + + outputStream.write(output.getBytes()); + outputStream.close(); + mItems.clear(); + } + catch (Exception e) { + // Don't just consume a whole bunch of memory if something is going wrong. + if (mItems.size() > 100) { + mItems.clear(); + } + } + } + + public void addItem(String name, String data) { + mItems.add(new AnalyticsItem(name, data)); + save(); + } + + public void addItem(String name) { + mItems.add(new AnalyticsItem(name)); + save(); + } + + public static Analytics get() { + // Generate one if it doesn't exist yet. + if (sAnalytics == null) { + sAnalytics = new Analytics(); + } + return sAnalytics; + } + + public static void flush() { + Analytics.get().flushItems(); + } + + public static void add(String name, String data) { + Analytics.get().addItem(name, data); + } + + public static void add(String name) { + Analytics.get().addItem(name); + } +} diff --git a/app/src/main/java/com/mozilla/hackathon/kiboko/activities/DashboardActivity.java b/app/src/main/java/com/mozilla/hackathon/kiboko/activities/DashboardActivity.java index 094a90a..e80ccde 100644 --- a/app/src/main/java/com/mozilla/hackathon/kiboko/activities/DashboardActivity.java +++ b/app/src/main/java/com/mozilla/hackathon/kiboko/activities/DashboardActivity.java @@ -22,6 +22,8 @@ import com.mozilla.hackathon.kiboko.widgets.MessageCardView; import com.squareup.otto.Bus; import com.squareup.otto.Subscribe; +import com.mozilla.hackathon.kiboko.Analytics; + public class DashboardActivity extends DSOActivity { public static boolean active = false; public static FragmentActivity mDashboard; @@ -35,11 +37,13 @@ public class DashboardActivity extends DSOActivity { dashboard_summary = (LinearLayout) findViewById(R.id.dashboard_summary); mDashboard = DashboardActivity.this; bus.post(new NetworkStateChanged(false) ); + Analytics.add("Dashboard", "create"); } public void findIconsClicked(View view){ Intent dashboardIntent = new Intent(this, FindIconsActivity.class); startActivity(dashboardIntent); + Analytics.add("Dashboard::FindIcons", "click"); } @Override @@ -63,6 +67,8 @@ public class DashboardActivity extends DSOActivity { protected void onDestroy() { super.onDestroy(); active = false; + Analytics.add("Dashboard", "destroy"); + Analytics.flush(); } // method that will be called when the device posts an event NetworkStateChanged @@ -87,9 +93,11 @@ public class DashboardActivity extends DSOActivity { dashboard_summary.removeView(wifiCard); if(tag.equals("cancel")){ + Analytics.add("Dashboard::NetworkEvent", "dismiss"); return; } + Analytics.add("Dashboard::NetworkEvent", "learn more"); Intent dashboardIntent = new Intent(DashboardActivity.this, TutorialSlideActivity.class); dashboardIntent.putExtra("header","Wifi ni noma!"); dashboardIntent.putExtra("topic","wifi"); @@ -122,9 +130,11 @@ public class DashboardActivity extends DSOActivity { dashboard_summary.removeView(wifiCard); if(tag.equals("cancel")){ + Analytics.add("Dashboard::LowStorageEvent", "dismiss"); return; } + Analytics.add("Dashboard::LowStorageEvent", "learn more"); Intent dashboardIntent = new Intent(DashboardActivity.this, TutorialSlideActivity.class); dashboardIntent.putExtra("header","Freeing up Memory!"); dashboardIntent.putExtra("topic","storage"); @@ -156,9 +166,11 @@ public class DashboardActivity extends DSOActivity { dashboard_summary.removeView(batteryCard); if(tag.equals("cancel")){ + Analytics.add("Dashboard::BatteryEvent", "dismiss"); return; } + Analytics.add("Dashboard::BatteryEvent", "learn more"); Intent dashboardIntent = new Intent(DashboardActivity.this, TutorialSlideActivity.class); dashboardIntent.putExtra("title","Phone battery"); dashboardIntent.putExtra("topic","battery"); @@ -189,9 +201,11 @@ public class DashboardActivity extends DSOActivity { dashboard_summary.removeView(batteryCard); if(tag.equals("cancel")){ + Analytics.add("Dashboard::AirplaneModeEvent", "dismiss"); return; } + Analytics.add("Dashboard::AirplaneModeEvent", "learn more"); Intent dashboardIntent = new Intent(DashboardActivity.this, TutorialSlideActivity.class); dashboardIntent.putExtra("title","Airplane Mode"); dashboardIntent.putExtra("topic","airplane_mode"); @@ -223,9 +237,11 @@ public class DashboardActivity extends DSOActivity { dashboard_summary.removeView(locationCard); if(tag.equals("cancel")){ + Analytics.add("Dashboard::LocationEvent", "dismiss"); return; } + Analytics.add("Dashboard::AirplaneModeEvent", "learn more"); Intent dashboardIntent = new Intent(DashboardActivity.this, TutorialSlideActivity.class); dashboardIntent.putExtra("title","Using location services."); dashboardIntent.putExtra("topic","location"); diff --git a/app/src/main/java/com/mozilla/hackathon/kiboko/adapters/TopicsAdapter.java b/app/src/main/java/com/mozilla/hackathon/kiboko/adapters/TopicsAdapter.java index 159fec2..b0cd53b 100644 --- a/app/src/main/java/com/mozilla/hackathon/kiboko/adapters/TopicsAdapter.java +++ b/app/src/main/java/com/mozilla/hackathon/kiboko/adapters/TopicsAdapter.java @@ -11,6 +11,7 @@ import android.widget.Filterable; import android.widget.ImageView; import android.widget.TextView; +import com.mozilla.hackathon.kiboko.Analytics; import com.mozilla.hackathon.kiboko.R; import com.mozilla.hackathon.kiboko.activities.FindIconsActivity; import com.mozilla.hackathon.kiboko.activities.TutorialSlideActivity; @@ -94,6 +95,8 @@ public class TopicsAdapter extends BaseAdapter implements Filterable { viewItem.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + String topicTag = topic.getTag(); + Analytics.add("TopicsAdapter::Clicked", topicTag); if(topic.getTag().equals("icons")){ Intent topicIntent = new Intent(context, FindIconsActivity.class); // topicIntent.putExtra("topic", topic.getName()); diff --git a/app/src/main/java/com/mozilla/hackathon/kiboko/fragments/TopicsFragment.java b/app/src/main/java/com/mozilla/hackathon/kiboko/fragments/TopicsFragment.java index 1b4c71e..43a5c85 100644 --- a/app/src/main/java/com/mozilla/hackathon/kiboko/fragments/TopicsFragment.java +++ b/app/src/main/java/com/mozilla/hackathon/kiboko/fragments/TopicsFragment.java @@ -16,6 +16,7 @@ import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.LinearLayout; +import com.mozilla.hackathon.kiboko.Analytics; import com.mozilla.hackathon.kiboko.R; import com.mozilla.hackathon.kiboko.adapters.TopicsAdapter; import com.mozilla.hackathon.kiboko.models.Topic; @@ -98,7 +99,9 @@ public class TopicsFragment extends ListFragment implements CompoundButton.OnChe case R.id.toggleSwitch: if(!isChecked){ getContext().stopService(new Intent(getContext(), ChatHeadService.class)); + Analytics.add("TopicsFragment::FABSwitch", "off"); }else{ + Analytics.add("TopicsFragment::FABSwitch", "on"); if(!isServiceRunning()){ if(Utils.canDrawOverlays(getContext())) startOverlayService(); diff --git a/app/src/main/java/com/mozilla/hackathon/kiboko/services/ChatHeadService.java b/app/src/main/java/com/mozilla/hackathon/kiboko/services/ChatHeadService.java index 6ec4860..088c318 100644 --- a/app/src/main/java/com/mozilla/hackathon/kiboko/services/ChatHeadService.java +++ b/app/src/main/java/com/mozilla/hackathon/kiboko/services/ChatHeadService.java @@ -19,6 +19,7 @@ import android.view.View.OnTouchListener; import android.view.WindowManager; import android.widget.RelativeLayout; +import com.mozilla.hackathon.kiboko.Analytics; import com.mozilla.hackathon.kiboko.R; import com.mozilla.hackathon.kiboko.activities.DashboardActivity; import com.mozilla.hackathon.kiboko.events.BatteryStateChanged; @@ -366,6 +367,7 @@ public class ChatHeadService extends Service { * Open application */ private void openAppClicked() { + Analytics.add("ChatHeadService::Clicked"); switchToNormalHead(); Intent dashboardIntent = new Intent(this, DashboardActivity.class); dashboardIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_SINGLE_TOP); From fbb7e53a865c2cef98e097c4f1adaa626c8b0c57 Mon Sep 17 00:00:00 2001 From: secretrobotron Date: Sat, 2 Jul 2016 12:18:38 +0300 Subject: [PATCH 2/2] replaced useless local variable --- .../com/mozilla/hackathon/kiboko/adapters/TopicsAdapter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/com/mozilla/hackathon/kiboko/adapters/TopicsAdapter.java b/app/src/main/java/com/mozilla/hackathon/kiboko/adapters/TopicsAdapter.java index b0cd53b..0158ef3 100644 --- a/app/src/main/java/com/mozilla/hackathon/kiboko/adapters/TopicsAdapter.java +++ b/app/src/main/java/com/mozilla/hackathon/kiboko/adapters/TopicsAdapter.java @@ -95,8 +95,7 @@ public class TopicsAdapter extends BaseAdapter implements Filterable { viewItem.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - String topicTag = topic.getTag(); - Analytics.add("TopicsAdapter::Clicked", topicTag); + Analytics.add("TopicsAdapter::Clicked", topic.getTag()); if(topic.getTag().equals("icons")){ Intent topicIntent = new Intent(context, FindIconsActivity.class); // topicIntent.putExtra("topic", topic.getName());