commit 43d5d6d9e8485c91cdb136bbb6372fcdc99066aa Author: Trevor Slocum Date: Tue Oct 13 18:09:33 2015 -0700 Initial open source release diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4edfb05 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +build/ +captures/ +*/captures/ + +# built application files +*.apk +*.ap_ +*.bar +*.wrn + + +# files for the dex VM +*.dex + +# Java class files +*.class + +# generated files +bin/ +gen/ + +# Local configuration file (sdk path, etc) +local.properties + +# Eclipse project files +.classpath +.project + +# Android Studio +.idea/ +.gradle +/*/local.properties +/*/out +/*/*/build +*/build +/*/*/production +*.iml +*.iws +*.ipr +*~ +*.swp + diff --git a/MeditationAssistant/.gitignore b/MeditationAssistant/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/MeditationAssistant/.gitignore @@ -0,0 +1 @@ +/build diff --git a/MeditationAssistant/google-services.json b/MeditationAssistant/google-services.json new file mode 100644 index 0000000..e1a464f --- /dev/null +++ b/MeditationAssistant/google-services.json @@ -0,0 +1 @@ +{"project_info":{"project_id":"api-project-163346957857","project_number":"163346957857","name":"Meditation Assistant Free"},"client":[{"client_info":{"client_id":"android:sh.ftp.rocketninelabs.meditationassistant","client_type":1,"android_client_info":{"package_name":"sh.ftp.rocketninelabs.meditationassistant"}},"oauth_client":[{"client_id":"163346957857.apps.googleusercontent.com","client_type":1,"android_info":{"package_name":"sh.ftp.rocketninelabs.meditationassistant","certificate_hash":"f5f29854d4bac9d7ccf5d98a8a4b88f3beca47ff"}}],"services":{"analytics_service":{"status":2,"analytics_property":{"tracking_id":"UA-71983-51"}},"cloud_messaging_service":{"status":1,"apns_config":[]},"appinvite_service":{"status":2,"other_platform_oauth_client":[]},"google_signin_service":{"status":2},"ads_service":{"status":1}}}],"ARTIFACT_VERSION":"1"} \ No newline at end of file diff --git a/MeditationAssistant/lint.xml b/MeditationAssistant/lint.xml new file mode 100644 index 0000000..287f5a2 --- /dev/null +++ b/MeditationAssistant/lint.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/MeditationAssistant/proguard-project.txt b/MeditationAssistant/proguard-project.txt new file mode 100644 index 0000000..f46bf01 --- /dev/null +++ b/MeditationAssistant/proguard-project.txt @@ -0,0 +1,216 @@ +-verbose + +# Begin optimizeproguard-optimize.txt: + +-optimizations !code/simplification/cast,!field/*,!class/merging/* +-optimizationpasses 25 +-allowaccessmodification +-dontpreverify + +-dontwarn android.webkit.** + +-keep class com.google.android.gms.analytics.** +-keep class com.google.analytics.tracking.** +-dontwarn com.google.android.gms.analytics.** +-dontwarn com.google.analytics.tracking.** + +-dontwarn com.google.android.gms.** + +-keep class android.support.** { *; } + +-keep interface android.support.** { *; } + +-keep class com.actionbarsherlock.** { *; } + +-keep interface com.actionbarsherlock.** { *; } + +-keep class com.actionbarsherlock.** {*;} +-keep class org.holoeverywhere.** {*;} + +-keep class * extends java.util.ListResourceBundle { + protected Object[][] getContents(); +} + +-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { + public static final *** NULL; +} + +-keepnames @com.google.android.gms.common.annotation.KeepName class * +-keepclassmembernames class * { + @com.google.android.gms.common.annotation.KeepName *; +} + +-keepnames class * implements android.os.Parcelable { + public static final ** CREATOR; +} +-keepclassmembers class * extends com.actionbarsherlock.ActionBarSherlock { + (android.app.Activity, int); +} + + + +# Keep line numbers to alleviate debugging stack traces + +# -renamesourcefileattribute SourceFile + +-keepattributes SourceFile,LineNumberTable + +# The remainder of this file is identical to the non-optimized version +# of the Proguard configuration file (except that the other file has +# flags to turn off optimization). + +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses + +-keepattributes *Annotation* +-keep public class com.google.vending.licensing.ILicensingService +-keep public class com.android.vending.licensing.ILicensingService + +# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native +-keepclasseswithmembernames class * { + native ; +} + +# keep setters in Views so that animations can still work. +# see http://proguard.sourceforge.net/manual/examples.html#beans +-keepclassmembers public class * extends android.view.View { + void set*(***); + *** get*(); +} + +# We want to keep methods in Activity that could be used in the XML attribute onClick +-keepclassmembers class * extends android.app.Activity { + public void *(android.view.View); +} + +# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} + +-keepclassmembers class **.R$* { + public static ; +} + +# The support library contains references to newer platform versions. +# Don't warn about those in case this app is linking against an older +# platform version. We know about them, and they are safe. +-dontwarn android.support.** + + +# End optimize + + +-keepattributes JavascriptInterface +-overloadaggressively +-allowaccessmodification + +-keep public class sh.ftp.rocketninelabs.meditationassistant.JavascriptCallback +-keep public class * implements sh.ftp.rocketninelabs.meditationassistant.JavascriptCallback +-keepclassmembers class * implements sh.ftp.rocketninelabs.meditationassistant.JavascriptCallback { + ; +} + +-keep class android.support.v4.app.** { *; } +-keep interface android.support.v4.app.** { *; } +-keep class com.actionbarsherlock.** { *; } +-keep interface com.actionbarsherlock.** { *; } + +-keep public class com.crittercism.** +-keepclassmembers public class com.crittercism.* { *; } + +# HoloEverywhere +-keep,allowshrinking,allowoptimization public class * extends ListView + +-keep,allowoptimization class org.holoeverywhere.** { + public *; + protected *; +} + +-keepclasseswithmembernames class org.holoeverywhere.internal.** { + public *; + protected *; +} + +-keepclasseswithmembernames class org.holoeverywhere.internal.AlertController +-keep public class org.holoeverywhere.internal.AlertController.RecycleListView { *; } + +-keep,allowshrinking,allowoptimization class org.holoeverywhere.** { *; } +-keep,allowshrinking,allowoptimization interface org.holoeverywhere.** { *; } + + + + +-keep,allowshrinking,allowoptimization public class * extends android.app.Application +-keep,allowshrinking,allowoptimization public class * extends android.app.Service +-keep,allowshrinking,allowoptimization public class * extends android.content.BroadcastReceiver +-keep,allowshrinking,allowoptimization public class * extends android.content.ContentProvider +-keep,allowshrinking,allowoptimization public class * extends android.app.backup.BackupAgentHelper +-keep,allowshrinking,allowoptimization public class * extends android.preference.Preference +-keep,allowshrinking,allowoptimization public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembers class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembers class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers class * extends android.app.Activity { + public void *(android.view.View); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} + +-keep,allowshrinking,allowoptimization class * { ; } + +-keepclasseswithmembernames,allowshrinking class * { + native ; +} + +-keepclasseswithmembers,allowshrinking class * { + public (android.content.Context,android.util.AttributeSet); + public (android.content.Context,android.util.AttributeSet,int); +} + +-keepclassmembers class * { + public (android.content.Context,android.util.AttributeSet); + public (android.content.Context,android.util.AttributeSet,int); +} + + + +# Google API Client + +-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault + +-keepclassmembers class * { + @com.google.api.client.util.Key ; +} + +# Needed by google-http-client-android when linking against an older platform version + +-dontwarn com.google.api.client.extensions.android.** + +# Needed by google-api-client-android when linking against an older platform version + +-dontwarn com.google.api.client.googleapis.extensions.android.** + +# End Google API Client \ No newline at end of file diff --git a/MeditationAssistant/src/main/AndroidManifest.xml b/MeditationAssistant/src/main/AndroidManifest.xml new file mode 100644 index 0000000..ce97886 --- /dev/null +++ b/MeditationAssistant/src/main/AndroidManifest.xml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/AboutActivity.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/AboutActivity.java new file mode 100644 index 0000000..f2fc714 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/AboutActivity.java @@ -0,0 +1,157 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.app.Activity; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.NavUtils; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.animation.AnimationUtils; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.google.android.gms.analytics.GoogleAnalytics; +import com.google.android.gms.appinvite.AppInviteInvitation; + +public class AboutActivity extends Activity { + + public String license = ""; + private MeditationAssistant ma = null; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(getMeditationAssistant().getMATheme()); + getActionBar().setDisplayHomeAsUpEnabled(true); + setContentView(R.layout.activity_about); + + TextView txtAboutAppName = (TextView) findViewById(R.id.txtAboutAppName); + TextView txtAboutAppVersion = (TextView) findViewById(R.id.txtAboutAppVersion); + + if (getPackageName().equals( + "sh.ftp.rocketninelabs.meditationassistant")) { + txtAboutAppName.setText(getString(R.string.appName)); + } else { + txtAboutAppName.setText(getString(R.string.appNameShort)); + } + + PackageInfo pInfo; + try { + pInfo = getPackageManager().getPackageInfo(getPackageName(), 0); + txtAboutAppVersion.setText(String.format(getString(R.string.version), pInfo.versionName)); + } catch (PackageManager.NameNotFoundException e) { + txtAboutAppVersion.setVisibility(View.GONE); + e.printStackTrace(); + } + + LinearLayout layAbout = (LinearLayout) findViewById(R.id.layAbout); + layAbout.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View arg0) { + ImageView charis = (ImageView) findViewById(R.id.charis); + charis.setVisibility(View.VISIBLE); + charis.startAnimation(AnimationUtils.loadAnimation( + getApplicationContext(), R.anim.spin)); + return true; + } + }); + + if (getMeditationAssistant().sendUsageReports()) { + getMeditationAssistant().getTracker(MeditationAssistant.TrackerName.APP_TRACKER); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.about, menu); + + if (getMeditationAssistant().getIsBB() || !MeditationAssistant.getMarketName().equals("google")) { + MenuItem share = menu.findItem(R.id.action_share_app); + share.setVisible(false); + invalidateOptionsMenu(); + } + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int i = item.getItemId(); + if (i == android.R.id.home) { + NavUtils.navigateUpFromSameTask(this); + return true; + } else if (i == R.id.action_share_app) { + Intent intent = new AppInviteInvitation.IntentBuilder(getString(R.string.appNameShort)) + .setMessage(getString(R.string.invitationBlurb)) + .build(); + startActivityForResult(intent, 1337); + } else if (i == R.id.action_rate) { + getMeditationAssistant().askToRateApp(); + return true; + } + + return super.onOptionsItemSelected(item); + } + + @Override + public void onStart() { + super.onStart(); + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStart(this); + } + } + + @Override + protected void onStop() { + super.onStop(); + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStop(this); + } + } + + public void sendMeEmail(View view) { + Log.d("MeditationAssistant", "Open about"); + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("plain/text"); + intent.putExtra(Intent.EXTRA_EMAIL, + new String[]{"tslocum@gmail.com"}); + try { + PackageInfo pInfo = getPackageManager().getPackageInfo( + getPackageName(), 0); + intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.appNameShort) + " " + + pInfo.versionName); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.appNameShort)); + } + intent.putExtra(android.content.Intent.EXTRA_TEXT, ""); + + startActivity(Intent.createChooser(intent, getString(R.string.sendEmail))); + } + + public void openHowToMeditate(View view) { + startActivity(new Intent( + Intent.ACTION_VIEW, + Uri.parse("http://medinet.ftp.sh/howtomeditate")).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } + + public void openTranslate(View view) { + startActivity(new Intent( + Intent.ACTION_VIEW, + Uri.parse("http://medinet.ftp.sh/translate")).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } + + public MeditationAssistant getMeditationAssistant() { + if (ma == null) { + ma = (MeditationAssistant) this.getApplication(); + } + return ma; + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/CalendarFragment.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/CalendarFragment.java new file mode 100644 index 0000000..a2a4b1c --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/CalendarFragment.java @@ -0,0 +1,304 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.text.TextUtils; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; +import android.widget.GridView; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TableLayout; +import android.widget.TextView; + +import java.util.Calendar; +import java.util.Locale; + +public class CalendarFragment extends Fragment { + GridView gridCalendar = null; + TextView txtCurrentMonth = null; + TextView txtCurrentYear = null; + MonthAdapter monthadapter = null; + Calendar mCalendar = null; + ImageButton nextMonth = null; + private MeditationAssistant ma = null; + SharedPreferences.OnSharedPreferenceChangeListener sharedPrefslistener = new SharedPreferences.OnSharedPreferenceChangeListener() { + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + if (key.equals("sessionsupdate")) { + Log.d("MeditationAssistant", "Got sessions update, refreshing CalendarFragment"); + refreshMonthDisplay(); + } + } + }; + + public MeditationAssistant getMeditationAssistant() { + if (ma == null) { + ma = (MeditationAssistant) getActivity().getApplication(); + } + return ma; + } + + private MonthAdapter getMonthAdapter() { + final DisplayMetrics metrics = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay() + .getMetrics(metrics); + updatecurrentDate(); + + return new MonthAdapter(getActivity(), mCalendar.get(Calendar.MONTH), + mCalendar.get(Calendar.YEAR), metrics, (ProgressActivity) getActivity(), getMeditationAssistant()); + } + + public void refreshMonthDisplay() { + gridCalendar.setAdapter(getMonthAdapter()); + } + + @SuppressWarnings("deprecation") + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getMeditationAssistant().getPrefs().registerOnSharedPreferenceChangeListener(sharedPrefslistener); + + int color_primary = getResources().getColor(getMeditationAssistant().getMATextColor(true)); + int color_primary_disabled = getResources().getColor(getMeditationAssistant().getMATextColor(false)); + + /* Getting resource not found errors here */ + try { + color_primary = getResources().getColor( + getMeditationAssistant() + .getTheme() + .obtainStyledAttributes( + getMeditationAssistant().getMATheme(), + new int[]{android.R.attr.textColorPrimary}) + .getResourceId(0, 0) + ); + color_primary_disabled = getResources() + .getColor( + getMeditationAssistant() + .getTheme() + .obtainStyledAttributes( + getMeditationAssistant() + .getMATheme(), + new int[]{android.R.attr.textColorPrimaryDisableOnly} + ) + .getResourceId(0, 0) + ); + } catch (Exception e) { + Log.d("MeditationAssistant", "Unable to get color resources in CalendarFragment:"); + e.printStackTrace(); + } + + txtCurrentMonth = new TextView(getActivity()); + txtCurrentYear = new TextView(getActivity()); + mCalendar = Calendar.getInstance(); + + txtCurrentMonth.setTextSize(22); + txtCurrentYear.setTextSize(12); + + txtCurrentMonth.setTextColor(color_primary); + txtCurrentMonth + .setTextColor(color_primary_disabled); + + txtCurrentMonth.setSingleLine(true); + txtCurrentMonth.setEllipsize(TextUtils.TruncateAt.END); + + txtCurrentYear.setSingleLine(true); + txtCurrentYear.setEllipsize(TextUtils.TruncateAt.END); + + gridCalendar = new GridView(getActivity()); + gridCalendar.setNumColumns(7); + gridCalendar.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT)); + gridCalendar.setVerticalSpacing(2); + gridCalendar.setHorizontalSpacing(2); + gridCalendar.setAdapter(getMonthAdapter()); + } + + @SuppressWarnings("deprecation") + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + Context ctx = getActivity().getApplicationContext(); + + LinearLayout lcontainer = new LinearLayout(ctx); + lcontainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT)); + lcontainer.setOrientation(LinearLayout.VERTICAL); + + LinearLayout lmain = new LinearLayout(ctx); + lmain.setOrientation(LinearLayout.VERTICAL); + lmain.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.FILL_PARENT)); + + lmain.setWeightSum(0.5f); + + LinearLayout lhoriz = new LinearLayout(ctx); + lhoriz.setOrientation(LinearLayout.HORIZONTAL); + lhoriz.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.WRAP_CONTENT)); + + lmain.addView(gridCalendar); + + ImageButton prevMonth = new ImageButton(getActivity()); + prevMonth.setImageDrawable(getResources().getDrawable( + getMeditationAssistant() + .getTheme() + .obtainStyledAttributes( + getMeditationAssistant().getMATheme(), + new int[]{R.attr.actionIconPreviousItem}) + .getResourceId(0, 0) + )); + + nextMonth = new ImageButton(getActivity()); + nextMonth.setImageDrawable(getResources().getDrawable( + getMeditationAssistant() + .getTheme() + .obtainStyledAttributes( + getMeditationAssistant().getMATheme(), + new int[]{R.attr.actionIconNextItem}) + .getResourceId(0, 0) + )); + + /*TableLayout.LayoutParams monthbuttonslp = new TableLayout.LayoutParams( + LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1f);*/ + TableLayout.LayoutParams monthbuttonslp = new TableLayout.LayoutParams( + LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, 1f); + monthbuttonslp.setMargins(0, MeditationAssistant.dpToPixels(7, ctx), 0, + MeditationAssistant.dpToPixels(7, ctx)); + prevMonth.setLayoutParams(monthbuttonslp); + nextMonth.setLayoutParams(monthbuttonslp); + + prevMonth.setBackgroundColor(getActivity().getResources().getColor( + android.R.color.transparent)); + nextMonth.setBackgroundColor(getActivity().getResources().getColor( + android.R.color.transparent)); + + prevMonth.setBackgroundResource(getMeditationAssistant() + .getTheme() + .obtainStyledAttributes( + getMeditationAssistant().getMATheme(), + new int[]{android.R.attr.selectableItemBackground}) + .getResourceId(0, 0)); + nextMonth.setBackgroundResource(getMeditationAssistant() + .getTheme() + .obtainStyledAttributes( + getMeditationAssistant().getMATheme(), + new int[]{android.R.attr.selectableItemBackground}) + .getResourceId(0, 0)); + + prevMonth.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + mCalendar.add(Calendar.MONTH, -1); + gridCalendar.setAdapter(getMonthAdapter()); + + updateMonthScroll(); + } + }); + + nextMonth.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mCalendar.add(Calendar.MONTH, 1); + gridCalendar.setAdapter(getMonthAdapter()); + + updateMonthScroll(); + } + }); + + LinearLayout ldate = new LinearLayout(ctx); + ldate.setOrientation(LinearLayout.VERTICAL); + + LinearLayout.LayoutParams lp_horiz = new LinearLayout.LayoutParams( + LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1f); + prevMonth.setLayoutParams(lp_horiz); + ldate.setLayoutParams(lp_horiz); + nextMonth.setLayoutParams(lp_horiz); + + ldate.setGravity(Gravity.CENTER | Gravity.CENTER_VERTICAL); + txtCurrentMonth.setGravity(Gravity.CENTER | Gravity.CENTER_VERTICAL); + txtCurrentYear.setGravity(Gravity.CENTER | Gravity.CENTER_VERTICAL); + + ldate.addView(txtCurrentMonth); + ldate.addView(txtCurrentYear); + + lhoriz.setMinimumHeight(MeditationAssistant.dpToPixels(48, ctx)); + lhoriz.addView(prevMonth); + lhoriz.addView(ldate); + lhoriz.addView(nextMonth); + + LinearLayout lbottom = new LinearLayout(ctx); + lmain.setOrientation(LinearLayout.VERTICAL); + lbottom.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.WRAP_CONTENT)); + lbottom.setWeightSum(0.5f); + lbottom.setMinimumHeight(MeditationAssistant.dpToPixels(48, ctx)); + lbottom.addView(lhoriz); + + lmain.setGravity(Gravity.BOTTOM); + + View divBottom = new View(ctx); + + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + LayoutParams.FILL_PARENT, + MeditationAssistant.dpToPixels(1, ctx)); + lp.setMargins(MeditationAssistant.dpToPixels(7, ctx), 0, + MeditationAssistant.dpToPixels(7, ctx), 0); + divBottom.setLayoutParams(lp); + + divBottom.setPadding(7, 0, 7, 0); + divBottom.setBackgroundDrawable(getResources().getDrawable( + getMeditationAssistant() + .getTheme() + .obtainStyledAttributes( + getMeditationAssistant().getMATheme(), + new int[]{android.R.attr.listDividerAlertDialog}) + .getResourceId(0, 0) + )); + + lcontainer.addView(lbottom); + lcontainer.addView(divBottom); + lcontainer.addView(lmain); + + updateMonthScroll(); + return lcontainer; + } + + public void updatecurrentDate() { + txtCurrentMonth.setText(String.format(Locale.getDefault(), "%tB", mCalendar)); + txtCurrentYear.setText(String.format(Locale.getDefault(), "%tY", mCalendar)); + } + + private void updateMonthScroll() { + Calendar nowCalendar = Calendar.getInstance(); + if (mCalendar.get(Calendar.MONTH) == nowCalendar.get(Calendar.MONTH) + && mCalendar.get(Calendar.YEAR) == nowCalendar + .get(Calendar.YEAR)) { + nextMonth.setClickable(false); + nextMonth.setVisibility(View.INVISIBLE); + } else { + nextMonth.setClickable(true); + nextMonth.setVisibility(View.VISIBLE); + } + } + + @Override + public void onPause() { + getMeditationAssistant().getPrefs().unregisterOnSharedPreferenceChangeListener(sharedPrefslistener); + super.onPause(); + } + + @Override + public void onResume() { + getMeditationAssistant().getPrefs().registerOnSharedPreferenceChangeListener(sharedPrefslistener); + super.onResume(); + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/CompleteActivity.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/CompleteActivity.java new file mode 100644 index 0000000..d41d1ee --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/CompleteActivity.java @@ -0,0 +1,421 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.WindowManager; +import android.widget.EditText; +import android.widget.TextView; + +import com.google.android.gms.ads.AdView; +import com.google.android.gms.analytics.GoogleAnalytics; + +public class CompleteActivity extends Activity { + private AdView av = null; + private MediaPlayer mMediaPlayer; + private MeditationAssistant ma; + private Handler handler = new Handler(); + private Runnable runnable = new Runnable() { + @Override + public void run() { + handler.removeCallbacks(this); + + if (getMeditationAssistant().getMediNET().result.equals("posted")) { + getMeditationAssistant() + .shortToast(getString(R.string.sessionPosted)); + finish(); + } else if (getMeditationAssistant().getMediNET().result + .equals("alreadyposted")) { + getMeditationAssistant().longToast(getString(R.string.sessionAlreadyPosted)); + } else if (getMeditationAssistant().getMediNET().status + .equals("failure") + && getMeditationAssistant().getMediNET().result + .equals("corrupt")) { + getMeditationAssistant() + .longToast( + getString(R.string.sessionNotPosted)); + } else { + handler.postDelayed(this, 2000); + } + } + }; + private Runnable clearWakeLock = new Runnable() { + public void run() { + handler.removeCallbacks(clearWakeLock); + + WakeLocker.release(); + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(getMeditationAssistant().getMATheme()); + setContentView(R.layout.activity_complete); + + getMeditationAssistant().hideNotification(); // Called twice because it seems to help + + long timestamp = System.currentTimeMillis() / 1000; + if (getMeditationAssistant().getTimeStartMeditate() == 0 + || (timestamp - getMeditationAssistant().getTimeStartMeditate()) <= 0) { + // Reset timestamps for current session + getMeditationAssistant().setTimeStartMeditate(0); + getMeditationAssistant().setTimeToStopMeditate(0); + + finish(); + return; + } + + setTheme(getMeditationAssistant().getMATheme()); + /*if (getMeditationAssistant().getMATheme() != R.style.MADark) { + getWindow().setBackgroundDrawable( + getResources().getDrawable( + android.R.drawable.screen_background_light)); + }*/ + + setContentView(R.layout.activity_complete); + + getWindow().setWindowAnimations(0); + + getWindow().addFlags( + WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD + | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON + ); + + Boolean manual = false; + if (getIntent().hasExtra("manual")) { + if (getIntent().getBooleanExtra("manual", false)) { + manual = true; + } + } + + getMeditationAssistant().unsetNotificationControl(); + getMeditationAssistant().hideNotification(); // Called twice because it seems to help + + if (getPackageName().equals("sh.ftp.rocketninelabs.meditationassistant")) { + Log.d("MeditationAssistant", "Fetching ad"); + + av = (AdView) findViewById(R.id.adViewSessionComplete); + av.setVisibility(View.VISIBLE); + com.google.android.gms.ads.AdRequest adRequest = new com.google.android.gms.ads.AdRequest.Builder() + .addTestDevice(com.google.android.gms.ads.AdRequest.DEVICE_ID_EMULATOR) + .build(); + av.loadAd(adRequest); + } + + EditText editSessionMessage = (EditText) findViewById(R.id.editSessionMessage); + if (editSessionMessage.getText().toString().equals("") + && getMeditationAssistant().getPrefs().getBoolean("pref_remembermessage", false)) { + editSessionMessage.setText(getMeditationAssistant().getPrefs().getString("lastmessage", "")); + } + + editSessionMessage + .setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + EditText editSessionMessage = (EditText) findViewById(R.id.editSessionMessage); + TextView editSessionMessageInfo = (TextView) findViewById(R.id.editSessionMessageInfo); + if (hasFocus) { + editSessionMessageInfo.setText(String + .valueOf(editSessionMessage.getText() + .length()) + + " / 160"); + editSessionMessageInfo.setVisibility(View.VISIBLE); + } else { + editSessionMessageInfo.setVisibility(View.GONE); + } + } + }); + editSessionMessage.addTextChangedListener(new TextWatcher() { + @Override + public void afterTextChanged(Editable s) { + TextView editSessionMessageInfo = (TextView) findViewById(R.id.editSessionMessageInfo); + editSessionMessageInfo.setText(String.valueOf(s.length()) + + " / 160"); + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, + int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, + int count) { + + } + }); + + if (getMeditationAssistant() + .getTimeStartMeditate() == 0) { + /* Getting null pointers on getTimeStartMeditate() */ + Log.d("MeditationAssistant", "getTimeStartMeditate() was 0! Exiting AlarmReceiverActivity..."); + finish(); + return; + } + + // Meditation Session + getMeditationAssistant().getMediNET().resetSession(); + getMeditationAssistant().getMediNET().session.started = getMeditationAssistant() + .getTimeStartMeditate(); + if (getMeditationAssistant().getTimerMode().equals("endat")) { + Log.d("MeditationAssistant", String.valueOf(Math.min(timestamp, getMeditationAssistant().getTimeToStopMeditate())) + " - " + + String.valueOf(getMeditationAssistant().getTimeStartMeditate()) + " - " + String.valueOf(getMeditationAssistant().pausetime)); + getMeditationAssistant().getMediNET().session.length = Math.min(timestamp, getMeditationAssistant().getTimeToStopMeditate()) + - getMeditationAssistant().getTimeStartMeditate() - getMeditationAssistant().pausetime; + } else { + Log.d("MeditationAssistant", String.valueOf(timestamp) + " - " + + String.valueOf(getMeditationAssistant().getTimeStartMeditate()) + " - " + String.valueOf(getMeditationAssistant().pausetime)); + getMeditationAssistant().getMediNET().session.length = timestamp + - getMeditationAssistant().getTimeStartMeditate() - getMeditationAssistant().pausetime; + } + getMeditationAssistant().getMediNET().session.length += 7; // Add seven seconds to account for slow wake-ups + getMeditationAssistant().getMediNET().session.completed = timestamp; + + // Reset timestamps for current session + getMeditationAssistant().setTimeStartMeditate(0); + getMeditationAssistant().setTimeToStopMeditate(0); + + Log.d("MeditationAssistant", + "Session length: " + + String.valueOf(getMeditationAssistant().getMediNET().session.length) + ); + if (getMeditationAssistant().getMediNET().session.length > 0) { + TextView txtDuration = (TextView) findViewById(R.id.txtDuration); + txtDuration.setText(MediNET + .durationToTimerString(getMeditationAssistant() + .getMediNET().session.length, false)); + + String text_size = getMeditationAssistant().getPrefs().getString("pref_text_size", "normal"); + if (text_size.equals("tiny")) { + txtDuration.setTextSize(85); + } else if (text_size.equals("small")) { + txtDuration.setTextSize(115); + } else if (text_size.equals("large")) { + txtDuration.setTextSize(175); + } else if (text_size.equals("extralarge")) { + txtDuration.setTextSize(200); + } else { // Normal + txtDuration.setTextSize(153); + } + + if (!manual + && !getMeditationAssistant().getPrefs().getString("pref_meditation_sound_finish", "") + .equals("none")) { + + mMediaPlayer = null; + if (getMeditationAssistant().getPrefs().getString("pref_meditation_sound_finish", "").equals( + "custom")) { + String soundpath = getMeditationAssistant().getPrefs().getString( + "pref_meditation_sound_finish_custom", ""); + if (!soundpath.equals("")) { + try { + mMediaPlayer = MediaPlayer.create(this, + Uri.parse(soundpath)); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else { + mMediaPlayer = MediaPlayer.create(this, MeditationSounds + .getMeditationSound(getMeditationAssistant().getPrefs().getString( + "pref_meditation_sound_finish", ""))); + } + + if (mMediaPlayer != null) { + mMediaPlayer + .setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + + @Override + public void onCompletion(MediaPlayer mp) { + WakeLocker.release(); + mp.release(); + } + }); + mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + mMediaPlayer + .setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared( + MediaPlayer mp) { + mp.start(); + } + }); + //mMediaPlayer.prepareAsync(); + } else { + handler.postDelayed(clearWakeLock, 5000); + } + } + } + + if (getMeditationAssistant().sendUsageReports()) { + getMeditationAssistant().getTracker(MeditationAssistant.TrackerName.APP_TRACKER); + } + + if (!manual) { + getMeditationAssistant().vibrateDevice(); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.complete, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + if (item.getItemId() == R.id.action_settings) { + return true; + } + return super.onOptionsItemSelected(item); + } + + public void askDismiss() { + new AlertDialog.Builder(this) + .setIcon(android.R.drawable.ic_dialog_alert) + .setMessage(getString(R.string.askDiscardText)) + .setPositiveButton(getString(R.string.discard), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int which) { + finish(); + } + } + ).setNegativeButton(getString(R.string.cancel), null) + .show(); + } + + public void dismiss(View view) { + if (getMeditationAssistant().getPrefs().getBoolean("pref_askdismiss", true)) { + askDismiss(); + } else { + finish(); + } + } + + public MeditationAssistant getMeditationAssistant() { + if (ma == null) { + ma = (MeditationAssistant) this.getApplication(); + } + return ma; + } + + private String getSessionMessage() { + EditText editSessionMessage = (EditText) findViewById(R.id.editSessionMessage); + return editSessionMessage.getText().toString().trim(); + } + + @Override + public void onBackPressed() { + if (getMeditationAssistant().getPrefs().getBoolean("pref_askdismiss", true)) { + askDismiss(); + } else { + super.onBackPressed(); + } + } + + @Override + public void onDestroy() { + if (av != null) { + av.destroy(); + } + if (mMediaPlayer != null) { + try { + mMediaPlayer.release(); + } catch (Exception e) { + e.printStackTrace(); + } + } + try { + WakeLocker.release(); + } catch (Exception e) { + e.printStackTrace(); + } + + handler.removeCallbacks(runnable); + super.onDestroy(); + } + + @Override + public void onPause() { + if (av != null) { + av.pause(); + } + super.onPause(); + } + + @Override + public void onResume() { + super.onResume(); + if (av != null) { + av.resume(); + } + } + + @Override + public void onStart() { + super.onStart(); + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStart(this); + } + } + + @Override + protected void onStop() { + super.onStop(); + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStop(this); + } + } + + public void postMediNET(View view) { + if (getMeditationAssistant().getMediNETKey() == "") { + getMeditationAssistant().showSignInDialog(this); + return; + } + + saveLastMessage(); + + getMeditationAssistant().shortToast(getString(R.string.sessionPosting)); + getMeditationAssistant().getMediNET().session.message = getSessionMessage(); + getMeditationAssistant().getMediNET().postSession(); + + handler.removeCallbacks(runnable); + handler.postDelayed(runnable, 5); + } + + private void saveLastMessage() { + SharedPreferences.Editor editor = getMeditationAssistant().getPrefs().edit(); + editor.putString("lastmessage", getSessionMessage()); + editor.apply(); + } + + public void saveMediNET(View view) { + saveLastMessage(); + + getMeditationAssistant().getMediNET().session.message = getSessionMessage(); + getMeditationAssistant().getMediNET().saveSession(false, false); + getMeditationAssistant().shortToast(getString(R.string.sessionSaved)); + finish(); + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/Crypt.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/Crypt.java new file mode 100644 index 0000000..4806800 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/Crypt.java @@ -0,0 +1,123 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import java.security.NoSuchAlgorithmException; + +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +//import org.apache.commons.codec.binary.Base64; + +public class Crypt { + + private IvParameterSpec ivspec; + private SecretKeySpec keyspec; + private Cipher cipher; + + public Crypt() { + ivspec = new IvParameterSpec("fzsznzsjh2asdr7e".getBytes()); + + keyspec = new SecretKeySpec("jqx82h4ad6fzb4dk".getBytes(), "AES"); + + try { + cipher = Cipher.getInstance("AES/CBC/NoPadding"); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + } + } + + public static String bytesToHex(byte[] data) { + if (data == null) { + return null; + } + + int len = data.length; + String str = ""; + for (int i = 0; i < len; i++) { + if ((data[i] & 0xFF) < 16) + str = str + "0" + java.lang.Integer.toHexString(data[i] & 0xFF); + else + str = str + java.lang.Integer.toHexString(data[i] & 0xFF); + } + return str; + } + + public static byte[] hexToBytes(String str) { + if (str == null) { + return null; + } else if (str.length() < 2) { + return null; + } else { + int len = str.length() / 2; + byte[] buffer = new byte[len]; + for (int i = 0; i < len; i++) { + buffer[i] = (byte) Integer.parseInt( + str.substring(i * 2, i * 2 + 2), 16); + } + return buffer; + } + } + + private static String padString(String source) { + char paddingChar = ' '; + int size = 16; + int x = source.length() % size; + int padLength = size - x; + + for (int i = 0; i < padLength; i++) { + source += paddingChar; + } + + return source; + } + + public byte[] decrypt(String code) throws Exception { + if (code == null || code.length() == 0) + throw new Exception("Empty string"); + + byte[] decrypted = null; + + try { + cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec); + + decrypted = cipher.doFinal(hexToBytes(code)); + } catch (Exception e) { + throw new Exception("[decrypt] " + e.getMessage()); + } + return decrypted; + } + + public String decryptToString(String code) throws Exception { + if (code == null || code.length() == 0) + throw new Exception("Empty string"); + + String decryptedstr = null; + + try { + decryptedstr = new String(decrypt(code)).trim(); + } catch (Exception e) { + throw new Exception("[decrypt] " + e.getMessage()); + } + return decryptedstr; + } + + public byte[] encrypt(String text) throws Exception { + if (text == null || text.length() == 0) + throw new Exception("Empty string"); + + byte[] encrypted = null; + + try { + cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec); + + encrypted = cipher.doFinal(padString(text).getBytes()); + } catch (Exception e) { + throw new Exception("[encrypt] " + e.getMessage()); + } + + return encrypted; + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/DailyNotification.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/DailyNotification.java new file mode 100644 index 0000000..6dbd14d --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/DailyNotification.java @@ -0,0 +1,163 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.app.AlarmManager; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.provider.Settings; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.TaskStackBuilder; +import android.util.Log; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; + +public class DailyNotification extends BroadcastReceiver { + MeditationAssistant ma = null; + + @Override + public void onReceive(Context context, Intent intent) { + try { + ma = (MeditationAssistant) context.getApplicationContext(); + } catch (Exception e) { + e.printStackTrace(); + return; + } + + if (!getMeditationAssistant().getPrefs().getBoolean("pref_daily_reminder", false)) { + cancelReminder(context); + return; // The user has not enabled the daily reminder + } + Log.d("MeditationAssistant", "onReceive in DailyNotification"); + + if (intent != null && intent.getAction() != null && intent.getAction().equals(MeditationAssistant.ACTION_REMINDER)) { // otherwise, it was just an update + Log.d("MeditationAssistant", "Daily notification intent!"); + + SimpleDateFormat sdf = new SimpleDateFormat("d-M-yyyy", Locale.US); + if (getMeditationAssistant().getTimeToStopMeditate() != 0) { + Log.d("MeditationAssistant", "Skipping daily notification today, session in progress..."); + } else if (getMeditationAssistant().db.numSessionsByDate(sdf.format(Calendar.getInstance().getTime())) > 0) { + Log.d("MeditationAssistant", "Skipping daily notification today, there has already been a session recorded..."); + } else { + long last_reminder = getMeditationAssistant().getPrefs().getLong("last_reminder", 0); + if (last_reminder == 0 || getMeditationAssistant().getTimestamp() - last_reminder > 120) { + getMeditationAssistant().getPrefs().edit().putLong("last_reminder", getMeditationAssistant().getTimestamp()).apply(); + + String reminderText = getMeditationAssistant().getPrefs().getString("pref_daily_reminder_text", "").trim(); + if (reminderText.equals("")) { + reminderText = context.getString(R.string.reminderText); + } + + NotificationCompat.Builder notificationBuilder = + new NotificationCompat.Builder(context) + .setSmallIcon(R.drawable.ic_notification) + .setContentTitle(context.getString(R.string.meditate)) + .setContentText(reminderText) + .setTicker(reminderText) + .setAutoCancel(true); + + if (getMeditationAssistant().getPrefs().getBoolean("pref_vibrate_reminder", true)) { + long[] vibrationPattern = {0, 200, 500, 200, 500}; + notificationBuilder.setVibrate(vibrationPattern); + } else { + long[] vibrationPattern = {0, 0}; + notificationBuilder.setVibrate(vibrationPattern); + } + + if (getMeditationAssistant().getPrefs().getBoolean("pref_sound_reminder", true)) { + notificationBuilder.setSound(Settings.System.DEFAULT_NOTIFICATION_URI); + } + + Intent notificationIntent = new Intent(context, MainActivity.class); + TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); + stackBuilder.addParentStack(MainActivity.class); + stackBuilder.addNextIntent(notificationIntent); + PendingIntent resultPendingIntent = + stackBuilder.getPendingIntent( + 0, + PendingIntent.FLAG_UPDATE_CURRENT + ); + + //Intent launchMain = new Intent(context, MainActivity.class); + //PendingIntent launchNotification = PendingIntent.getActivity(context, 1008, launchMain, PendingIntent.FLAG_UPDATE_CURRENT); + notificationBuilder.setContentIntent(resultPendingIntent); + + Notification notification = notificationBuilder.build(); + + NotificationManager notificationManager = + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.notify(1946, notification); + } + } + } + + String reminderTime = ma.getPrefs().getString("pref_daily_reminder_time", "19:00"); + String[] reminderTimeSplit = ((reminderTime != null && reminderTime != "") ? reminderTime : "19:00").split(":"); + Integer reminderHour = Integer.valueOf(reminderTimeSplit[0]); + Integer reminderMinute = Integer.valueOf(reminderTimeSplit[1]); + + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.HOUR_OF_DAY, reminderHour); + calendar.set(Calendar.MINUTE, reminderMinute); + calendar.set(Calendar.SECOND, 0); + + if (Calendar.getInstance().getTimeInMillis() > calendar.getTimeInMillis()) { + calendar.add(Calendar.DATE, 1); // Tomorrow + } + + cancelReminder(context); + + getMeditationAssistant().reminderPendingIntent = PendingIntent + .getBroadcast( + context, + 1946, + new Intent( + MeditationAssistant.ACTION_REMINDER), + PendingIntent.FLAG_CANCEL_CURRENT + ); + + if (Build.VERSION.SDK_INT >= 19) { + getMeditationAssistant().reminderAlarmManager.setExact(AlarmManager.RTC_WAKEUP, + calendar.getTimeInMillis(), + getMeditationAssistant().reminderPendingIntent); + } else { + getMeditationAssistant().reminderAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, + calendar.getTimeInMillis(), 1000, + getMeditationAssistant().reminderPendingIntent); + } + + Log.d("MeditationAssistant", "Set daily reminder alarm for " + calendar.toString()); + } + + private void cancelReminder(Context context) { + if (getMeditationAssistant().reminderPendingIntent != null) { + try { + getMeditationAssistant().reminderAlarmManager.cancel(getMeditationAssistant().reminderPendingIntent); + } catch (Exception e) { + Log.e("MeditationAssistant", "AlarmManager update was not canceled. " + e.toString()); + } + try { + PendingIntent.getBroadcast(context, 0, new Intent( + MeditationAssistant.ACTION_REMINDER), + PendingIntent.FLAG_CANCEL_CURRENT + ).cancel(); + } catch (Exception e) { + Log.e("MeditationAssistant", "PendingIntent broadcast was not canceled. " + e.toString()); + } + try { + getMeditationAssistant().reminderPendingIntent.cancel(); + } catch (Exception e) { + Log.e("MeditationAssistant", "PendingIntent was not canceled. " + e.toString()); + } + } + } + + public MeditationAssistant getMeditationAssistant() { + return ma; + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/DatabaseHandler.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/DatabaseHandler.java new file mode 100644 index 0000000..3eb8123 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/DatabaseHandler.java @@ -0,0 +1,374 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; + +public class DatabaseHandler extends SQLiteOpenHelper { + private static final int DATABASE_VERSION = 4; + private static final String DATABASE_NAME = "meditationassistant"; + private static final String TABLE_SESSIONS = "sessions"; + + // Column names + private static final String KEY_ID = "id"; + private static final String KEY_ACCOUNT = "account"; + private static final String KEY_STARTED = "started"; + private static final String KEY_COMPLETED = "completed"; + private static final String KEY_LENGTH = "length"; + private static final String KEY_MESSAGE = "message"; + private static final String KEY_DATE = "date"; + private static final String KEY_ISPOSTED = "isposted"; + private static final String KEY_STREAKDAY = "streakday"; + private static DatabaseHandler databaseHandler; + + private SQLiteDatabase db = null; + private MeditationAssistant ma = null; + + public DatabaseHandler(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + ma = (MeditationAssistant) context; + db = this.getWritableDatabase(); + } + + public static synchronized DatabaseHandler getInstance(Context context) { + if (databaseHandler == null) { + databaseHandler = new DatabaseHandler(context.getApplicationContext()); + } + return databaseHandler; + } + + void addSession(SessionSQL session) { + ContentValues values = new ContentValues(); + values.put(KEY_STARTED, session._started); + values.put(KEY_COMPLETED, session._completed); + values.put(KEY_LENGTH, session._length); + values.put(KEY_MESSAGE, session._message); + values.put(KEY_DATE, sessionToAPIDate(session)); + values.put(KEY_ISPOSTED, session._isposted); + values.put(KEY_STREAKDAY, session._streakday); + + db.insert(TABLE_SESSIONS, null, values); + + getMeditationAssistant().recalculateMeditationStreak(); + getMeditationAssistant().notifySessionsUpdated(); + } + + public String sessionToAPIDate(SessionSQL session) { + if (session._completed != null) { + return timestampToAPIDate(session._completed * 1000); + } else { + return timestampToAPIDate((session._started + session._length) * 1000); + } + } + + public String timestampToAPIDate(long timestamp) { + SimpleDateFormat sdf = new SimpleDateFormat("d-M-yyyy", Locale.US); + + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(timestamp); + Date api_date = cal.getTime(); + + return sdf.format(api_date); + } + + public MeditationAssistant getMeditationAssistant() { + return ma; + } + + public void deleteSession(SessionSQL session) { + db.delete(TABLE_SESSIONS, KEY_ID + " = ?", + new String[]{String.valueOf(session.getID())}); + + getMeditationAssistant().notifySessionsUpdated(); + } + + public ArrayList getAllSessions() { + ArrayList sessionList = new ArrayList(); + + String selectQuery = "SELECT * FROM `" + TABLE_SESSIONS + "` ORDER BY " + + "`" + KEY_COMPLETED + "` DESC"; + + Cursor cursor = db.rawQuery(selectQuery, null); + + if (cursor.moveToFirst()) { + do { + SessionSQL session = new SessionSQL(cursor.getLong(cursor + .getColumnIndex(KEY_ID)), cursor.getLong(cursor + .getColumnIndex(KEY_STARTED)), cursor.getLong(cursor + .getColumnIndex(KEY_COMPLETED)), cursor.getLong(cursor + .getColumnIndex(KEY_LENGTH)), cursor.getString(cursor + .getColumnIndex(KEY_MESSAGE)), cursor.getLong(cursor + .getColumnIndex(KEY_ISPOSTED)), cursor.getLong(cursor + .getColumnIndex(KEY_STREAKDAY))); + + sessionList.add(session); + } while (cursor.moveToNext()); + } + + cursor.close(); + return sessionList; + } + + public ArrayList getAllLocalSessions() { + ArrayList sessionList = new ArrayList(); + + String selectQuery = "SELECT * FROM `" + TABLE_SESSIONS + "` WHERE `" + KEY_ISPOSTED + "` = 0"; + + Cursor cursor = db.rawQuery(selectQuery, null); + + if (cursor.moveToFirst()) { + do { + SessionSQL session = new SessionSQL(cursor.getLong(cursor + .getColumnIndex(KEY_ID)), cursor.getLong(cursor + .getColumnIndex(KEY_STARTED)), cursor.getLong(cursor + .getColumnIndex(KEY_COMPLETED)), cursor.getLong(cursor + .getColumnIndex(KEY_LENGTH)), cursor.getString(cursor + .getColumnIndex(KEY_MESSAGE)), cursor.getLong(cursor + .getColumnIndex(KEY_ISPOSTED)), cursor.getLong(cursor + .getColumnIndex(KEY_STREAKDAY))); + + sessionList.add(session); + } while (cursor.moveToNext()); + } + + cursor.close(); + return sessionList; + } + + public int getNumSessions() { + String countQuery = "SELECT COUNT(*) FROM `" + TABLE_SESSIONS + "`"; + + Cursor cursor = db.rawQuery(countQuery, null); + cursor.moveToFirst(); + int numsessions = cursor.getInt(0); + cursor.close(); + + return numsessions; + } + + public int getTotalTimeSpentMeditating() { + int time_meditating = 0; + Cursor cursor = db.rawQuery("SELECT SUM(`" + KEY_LENGTH + "`) FROM `" + TABLE_SESSIONS + "`", null); + if (cursor.moveToFirst()) { + time_meditating = cursor.getInt(0); + } + cursor.close(); + + return time_meditating; + } + + int numSessionsByDate(String date) { + Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM `" + TABLE_SESSIONS + "` WHERE `" + KEY_DATE + "`=?", new String[]{date}); + cursor.moveToFirst(); + int numsessions = cursor.getInt(0); + cursor.close(); + + return numsessions; + } + + int getLongestSessionLength() { + int longestsessionlength = 0; + Cursor cursor = db.rawQuery("SELECT MAX(`" + KEY_LENGTH + "`) FROM `" + TABLE_SESSIONS + "`", null); + if (cursor.moveToFirst()) { + longestsessionlength = cursor.getInt(0); + } + cursor.close(); + + return longestsessionlength; + } + + SessionSQL getSessionByStarted(long started) { + SessionSQL session = null; + + Cursor cursor = db.query(TABLE_SESSIONS, new String[]{KEY_ID, + KEY_STARTED, KEY_COMPLETED, KEY_LENGTH, KEY_MESSAGE, KEY_ISPOSTED, KEY_STREAKDAY}, + KEY_STARTED + "=?", new String[]{String.valueOf(started)}, + null, null, null, "1" + ); + if (cursor != null) { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); + + session = new SessionSQL(cursor.getLong(cursor + .getColumnIndex(KEY_ID)), cursor.getLong(cursor + .getColumnIndex(KEY_STARTED)), cursor.getLong(cursor + .getColumnIndex(KEY_COMPLETED)), cursor.getLong(cursor + .getColumnIndex(KEY_LENGTH)), cursor.getString(cursor + .getColumnIndex(KEY_MESSAGE)), cursor.getLong(cursor + .getColumnIndex(KEY_ISPOSTED)), cursor.getLong(cursor + .getColumnIndex(KEY_STREAKDAY))); + } + + cursor.close(); + } + + return session; + } + + @Override + public void onCreate(SQLiteDatabase db) { + Log.d("MeditationAssistant", "CREATING DATABASE VERSION " + String.valueOf(DATABASE_VERSION)); + db.execSQL("CREATE TABLE `" + TABLE_SESSIONS + "` (" + + "`" + KEY_ID + "` INTEGER PRIMARY KEY, " + + "`" + KEY_STARTED + "` INTEGER, `" + KEY_COMPLETED + "` INTEGER, " + + "`" + KEY_LENGTH + "` INTEGER, `" + KEY_MESSAGE + "` STRING, " + + "`" + KEY_DATE + "` STRING, `" + KEY_ISPOSTED + "` INTEGER, `" + KEY_STREAKDAY + "` INTEGER" + ")"); + + db.execSQL("CREATE INDEX `" + KEY_STARTED + "_idx` ON `" + TABLE_SESSIONS + "` (`" + KEY_STARTED + "`)"); + db.execSQL("CREATE INDEX `" + KEY_COMPLETED + "_idx` ON `" + TABLE_SESSIONS + "` (`" + KEY_COMPLETED + "`)"); + db.execSQL("CREATE INDEX `" + KEY_DATE + "_idx` ON `" + TABLE_SESSIONS + "` (`" + KEY_DATE + "`)"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + Log.d("MeditationAssistant", "DATABASE UPGRADE INITIATED - Old: " + String.valueOf(oldVersion) + " New: " + String.valueOf(newVersion)); + int curVer = oldVersion; + while (curVer < newVersion) { + curVer++; + switch (curVer) { + case 2: + Log.d("MeditationAssistant", "UPGRADING DATABASE to " + String.valueOf(curVer)); + + db.execSQL("ALTER TABLE `" + TABLE_SESSIONS + "` ADD COLUMN `" + KEY_STREAKDAY + "` INTEGER"); + break; + case 3: + Log.d("MeditationAssistant", "UPGRADING DATABASE to " + String.valueOf(curVer)); + + /* Fix for incorrect upgrade code */ + try { + db.execSQL("ALTER TABLE `" + TABLE_SESSIONS + "` ADD COLUMN `" + KEY_DATE + "` STRING"); + } catch (Exception e) { + // Column already exists + } + db.execSQL("CREATE INDEX `" + KEY_STARTED + "_idx` ON `" + TABLE_SESSIONS + "` (`" + KEY_STARTED + "`)"); + db.execSQL("CREATE INDEX `" + KEY_DATE + "_idx` ON `" + TABLE_SESSIONS + "` (`" + KEY_DATE + "`)"); + break; + case 4: + Log.d("MeditationAssistant", "UPGRADING DATABASE to " + String.valueOf(curVer)); + + /* Fix for incorrect upgrade code */ + try { + db.execSQL("ALTER TABLE `" + TABLE_SESSIONS + "` ADD COLUMN `" + KEY_STREAKDAY + "` INTEGER"); + } catch (Exception e) { + // Column already exists + } + try { + db.execSQL("ALTER TABLE `" + TABLE_SESSIONS + "` ADD COLUMN `" + KEY_DATE + "` STRING"); + db.execSQL("CREATE INDEX `" + KEY_DATE + "_idx` ON `" + TABLE_SESSIONS + "` (`" + KEY_DATE + "`)"); + db.execSQL("CREATE INDEX `" + KEY_STARTED + "_idx` ON `" + TABLE_SESSIONS + "` (`" + KEY_STARTED + "`)"); + } catch (Exception e) { + // Column already exists + } + + db.execSQL("ALTER TABLE `" + TABLE_SESSIONS + "` ADD COLUMN `" + KEY_COMPLETED + "` INTEGER"); + db.execSQL("CREATE INDEX `" + KEY_COMPLETED + "_idx` ON `" + TABLE_SESSIONS + "` (`" + KEY_COMPLETED + "`)"); + + Cursor cursor = db.rawQuery("SELECT * FROM `" + TABLE_SESSIONS + "`", null); + if (cursor.moveToFirst()) { + long session_completed; + + do { + try { + session_completed = cursor.getLong(cursor.getColumnIndex(KEY_COMPLETED)); + } catch (Exception e) { + session_completed = 0; + Log.d("MeditationAssistant", "Error fetching completed:"); + e.printStackTrace(); + } + + if (session_completed == 0) { + Log.d("MeditationAssistant", "UPDATE `" + TABLE_SESSIONS + "` SET `" + KEY_COMPLETED + + "`='" + (cursor.getLong(cursor.getColumnIndex(KEY_STARTED)) + cursor.getLong(cursor.getColumnIndex(KEY_LENGTH))) + "' WHERE `" + KEY_ID + "`='" + + cursor.getLong(cursor.getColumnIndex(KEY_ID)) + "'"); + db.rawQuery("UPDATE `" + TABLE_SESSIONS + "` SET `" + KEY_COMPLETED + + "`='" + (cursor.getLong(cursor.getColumnIndex(KEY_STARTED)) + cursor.getLong(cursor.getColumnIndex(KEY_LENGTH))) + "' WHERE `" + KEY_ID + "`='" + + cursor.getLong(cursor.getColumnIndex(KEY_ID)) + "'", null); + } + } while (cursor.moveToNext()); + } + cursor.close(); + + break; + } + } + } + + public int updateSession(SessionSQL session) { + ContentValues values = new ContentValues(); + values.put(KEY_STARTED, session._started); + values.put(KEY_COMPLETED, session._completed); + values.put(KEY_LENGTH, session._length); + values.put(KEY_MESSAGE, session._message); + values.put(KEY_ISPOSTED, session._isposted); + values.put(KEY_STREAKDAY, session._streakday); + + int result = db.update(TABLE_SESSIONS, values, KEY_ID + " = ?", + new String[]{String.valueOf(session.getID())}); + + getMeditationAssistant().notifySessionsUpdated(); + return result; + } + + public SessionSQL getSessionByDate(String date) { + Log.d("MeditationAssistant", "SQL: get session by date " + date); + SessionSQL session = null; + + Cursor cursor = db.query(TABLE_SESSIONS, new String[]{KEY_ID, + KEY_STARTED, KEY_COMPLETED, KEY_LENGTH, KEY_MESSAGE, KEY_ISPOSTED, KEY_STREAKDAY}, + KEY_DATE + "=?", new String[]{date}, + null, null, null, "1" + ); + if (cursor != null) { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); + + session = new SessionSQL(cursor.getLong(cursor + .getColumnIndex(KEY_ID)), cursor.getLong(cursor + .getColumnIndex(KEY_STARTED)), cursor.getLong(cursor + .getColumnIndex(KEY_COMPLETED)), cursor.getLong(cursor + .getColumnIndex(KEY_LENGTH)), cursor.getString(cursor + .getColumnIndex(KEY_MESSAGE)), cursor.getLong(cursor + .getColumnIndex(KEY_ISPOSTED)), cursor.getLong(cursor + .getColumnIndex(KEY_STREAKDAY))); + } + + cursor.close(); + } + + return session; + } + + public ArrayList getSessionsByDate(String date) { + ArrayList sessionList = new ArrayList(); + + Cursor cursor = db.rawQuery("SELECT * FROM `" + TABLE_SESSIONS + "` WHERE `" + KEY_DATE + "`=? ORDER BY `" + KEY_STARTED + "` ASC", new String[]{date}); + + if (cursor.moveToFirst()) { + do { + SessionSQL session = new SessionSQL(cursor.getLong(cursor + .getColumnIndex(KEY_ID)), cursor.getLong(cursor + .getColumnIndex(KEY_STARTED)), cursor.getLong(cursor + .getColumnIndex(KEY_COMPLETED)), cursor.getLong(cursor + .getColumnIndex(KEY_LENGTH)), cursor.getString(cursor + .getColumnIndex(KEY_MESSAGE)), cursor.getLong(cursor + .getColumnIndex(KEY_ISPOSTED)), cursor.getLong(cursor + .getColumnIndex(KEY_STREAKDAY))); + + sessionList.add(session); + } while (cursor.moveToNext()); + } + + cursor.close(); + + return sessionList; + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/FadeOutAnimationListener.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/FadeOutAnimationListener.java new file mode 100644 index 0000000..994c30e --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/FadeOutAnimationListener.java @@ -0,0 +1,27 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.view.View; +import android.view.animation.Animation; + +public class FadeOutAnimationListener implements Animation.AnimationListener { + View view; + + @Override + public void onAnimationEnd(Animation animation) { + view.setVisibility(View.GONE); + } + + @Override + public void onAnimationRepeat(Animation animation) { + + } + + @Override + public void onAnimationStart(Animation animation) { + + } + + public void setView(View v) { + view = v; + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/FileUtils.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/FileUtils.java new file mode 100644 index 0000000..9931a8f --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/FileUtils.java @@ -0,0 +1,503 @@ +package sh.ftp.rocketninelabs.meditationassistant; +/* + * Copyright (C) 2007-2008 OpenIntents.org + * + * 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. + */ + +import android.annotation.TargetApi; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.database.DatabaseUtils; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; +import android.util.Log; +import android.webkit.MimeTypeMap; + +import java.io.File; +import java.io.FileFilter; +import java.text.DecimalFormat; +import java.util.Comparator; + +/** + * @author Peli + * @author paulburke (ipaulpro) + * @version 2013-12-11 + */ +public class FileUtils { + public static final String MIME_TYPE_AUDIO = "audio/*"; + public static final String MIME_TYPE_TEXT = "text/*"; + public static final String MIME_TYPE_IMAGE = "image/*"; + public static final String MIME_TYPE_VIDEO = "video/*"; + public static final String MIME_TYPE_APP = "application/*"; + public static final String HIDDEN_PREFIX = "."; + /** + * TAG for log messages. + */ + static final String TAG = "FileUtils"; + private static final boolean DEBUG = false; // Set to true to enable logging + /** + * File and folder comparator. + * + * @author paulburke + */ + public static Comparator sComparator = new Comparator() { + @Override + public int compare(File f1, File f2) { + // Sort alphabetically by lower case, which is much cleaner + return f1.getName().toLowerCase().compareTo( + f2.getName().toLowerCase()); + } + }; + /** + * File (not directories) filter. + * + * @author paulburke + */ + public static FileFilter sFileFilter = new FileFilter() { + @Override + public boolean accept(File file) { + final String fileName = file.getName(); + // Return files only (not directories) and skip hidden files + return file.isFile() && !fileName.startsWith(HIDDEN_PREFIX); + } + }; + /** + * Folder (directories) filter. + * + * @author paulburke + */ + public static FileFilter sDirFilter = new FileFilter() { + @Override + public boolean accept(File file) { + final String fileName = file.getName(); + // Return directories only and skip hidden directories + return file.isDirectory() && !fileName.startsWith(HIDDEN_PREFIX); + } + }; + + private FileUtils() { + } //private constructor to enforce Singleton pattern + + /** + * Gets the extension of a file name, like ".png" or ".jpg". + * + * @param uri + * @return Extension including the dot("."); "" if there is no extension; + * null if uri was null. + */ + public static String getExtension(String uri) { + if (uri == null) { + return null; + } + + int dot = uri.lastIndexOf("."); + if (dot >= 0) { + return uri.substring(dot); + } else { + // No extension. + return ""; + } + } + + /** + * @return Whether the URI is a local one. + */ + public static boolean isLocal(String url) { + return (url != null && !url.startsWith("http://") && !url.startsWith("https://")); + } + + /** + * @return True if Uri is a MediaStore Uri. + * @author paulburke + */ + public static boolean isMediaUri(Uri uri) { + return "media".equalsIgnoreCase(uri.getAuthority()); + } + + /** + * Convert File into Uri. + * + * @param file + * @return uri + */ + public static Uri getUri(File file) { + if (file != null) { + return Uri.fromFile(file); + } + return null; + } + + /** + * Returns the path only (without file name). + * + * @param file + * @return + */ + public static File getPathWithoutFilename(File file) { + if (file != null) { + if (file.isDirectory()) { + // no file to be split off. Return everything + return file; + } else { + String filename = file.getName(); + String filepath = file.getAbsolutePath(); + + // Construct path without file name. + String pathwithoutname = filepath.substring(0, + filepath.length() - filename.length()); + if (pathwithoutname.endsWith("/")) { + pathwithoutname = pathwithoutname.substring(0, pathwithoutname.length() - 1); + } + return new File(pathwithoutname); + } + } + return null; + } + + /** + * @return The MIME type for the given file. + */ + public static String getMimeType(File file) { + + String extension = getExtension(file.getName()); + + if (extension.length() > 0) + return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1)); + + return "application/octet-stream"; + } + + /** + * @return The MIME type for the give Uri. + */ + public static String getMimeType(Context context, Uri uri) { + File file = new File(getPath(context, uri)); + return getMimeType(file); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + * @author paulburke + */ + public static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + * @author paulburke + */ + public static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + * @author paulburke + */ + public static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is Google Photos. + */ + public static boolean isGooglePhotosUri(Uri uri) { + return "com.google.android.apps.photos.content".equals(uri.getAuthority()); + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + * @author paulburke + */ + public static String getDataColumn(Context context, Uri uri, String selection, + String[] selectionArgs) { + + Cursor cursor = null; + final String column = "_data"; + final String[] projection = { + column + }; + + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, + null); + if (cursor != null && cursor.moveToFirst()) { + if (DEBUG) + DatabaseUtils.dumpCursor(cursor); + + final int column_index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(column_index); + } + } finally { + if (cursor != null) + cursor.close(); + } + return null; + } + + /** + * Get a file path from a Uri. This will get the the path for Storage Access + * Framework Documents, as well as the _data field for the MediaStore and + * other file-based ContentProviders.
+ *
+ * Callers should check whether the path is local before assuming it + * represents a local file. + * + * @param context The context. + * @param uri The Uri to query. + * @author paulburke + * @see #isLocal(String) + * @see #getFile(Context, Uri) + */ + @TargetApi(Build.VERSION_CODES.KITKAT) + public static String getPath(final Context context, final Uri uri) { + + if (DEBUG) + Log.d(TAG + " File -", + "Authority: " + uri.getAuthority() + + ", Fragment: " + uri.getFragment() + + ", Port: " + uri.getPort() + + ", Query: " + uri.getQuery() + + ", Scheme: " + uri.getScheme() + + ", Host: " + uri.getHost() + + ", Segments: " + uri.getPathSegments().toString() + ); + + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + + // DocumentProvider + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + if ("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } + } + // DownloadsProvider + else if (isDownloadsDocument(uri)) { + + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return getDataColumn(context, contentUri, null, null); + } + // MediaProvider + else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{ + split[1] + }; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + } + // MediaStore (and general) + else if ("content".equalsIgnoreCase(uri.getScheme())) { + + // Return the remote address + if (isGooglePhotosUri(uri)) + return uri.getLastPathSegment(); + + return getDataColumn(context, uri, null, null); + } + // File + else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return null; + } + + /** + * Convert Uri into File, if possible. + * + * @return file A local file that the Uri was pointing to, or null if the + * Uri is unsupported or pointed to a remote resource. + * @author paulburke + * @see #getPath(Context, Uri) + */ + public static File getFile(Context context, Uri uri) { + if (uri != null) { + String path = getPath(context, uri); + if (path != null && isLocal(path)) { + return new File(path); + } + } + return null; + } + + /** + * Get the file size in a human-readable string. + * + * @param size + * @return + * @author paulburke + */ + public static String getReadableFileSize(int size) { + final int BYTES_IN_KILOBYTES = 1024; + final DecimalFormat dec = new DecimalFormat("###.#"); + final String KILOBYTES = " KB"; + final String MEGABYTES = " MB"; + final String GIGABYTES = " GB"; + float fileSize = 0; + String suffix = KILOBYTES; + + if (size > BYTES_IN_KILOBYTES) { + fileSize = size / BYTES_IN_KILOBYTES; + if (fileSize > BYTES_IN_KILOBYTES) { + fileSize = fileSize / BYTES_IN_KILOBYTES; + if (fileSize > BYTES_IN_KILOBYTES) { + fileSize = fileSize / BYTES_IN_KILOBYTES; + suffix = GIGABYTES; + } else { + suffix = MEGABYTES; + } + } + } + return String.valueOf(dec.format(fileSize) + suffix); + } + + /** + * Attempt to retrieve the thumbnail of given File from the MediaStore. This + * should not be called on the UI thread. + * + * @param context + * @param file + * @return + * @author paulburke + */ + public static Bitmap getThumbnail(Context context, File file) { + return getThumbnail(context, getUri(file), getMimeType(file)); + } + + /** + * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This + * should not be called on the UI thread. + * + * @param context + * @param uri + * @return + * @author paulburke + */ + public static Bitmap getThumbnail(Context context, Uri uri) { + return getThumbnail(context, uri, getMimeType(context, uri)); + } + + /** + * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This + * should not be called on the UI thread. + * + * @param context + * @param uri + * @param mimeType + * @return + * @author paulburke + */ + public static Bitmap getThumbnail(Context context, Uri uri, String mimeType) { + if (DEBUG) + Log.d(TAG, "Attempting to get thumbnail"); + + if (!isMediaUri(uri)) { + Log.e(TAG, "You can only retrieve thumbnails for images and videos."); + return null; + } + + Bitmap bm = null; + if (uri != null) { + final ContentResolver resolver = context.getContentResolver(); + Cursor cursor = null; + try { + cursor = resolver.query(uri, null, null, null, null); + if (cursor.moveToFirst()) { + final int id = cursor.getInt(0); + if (DEBUG) + Log.d(TAG, "Got thumb ID: " + id); + + if (mimeType.contains("video")) { + bm = MediaStore.Video.Thumbnails.getThumbnail( + resolver, + id, + MediaStore.Video.Thumbnails.MINI_KIND, + null); + } else if (mimeType.contains(FileUtils.MIME_TYPE_IMAGE)) { + bm = MediaStore.Images.Thumbnails.getThumbnail( + resolver, + id, + MediaStore.Images.Thumbnails.MINI_KIND, + null); + } + } + } catch (Exception e) { + if (DEBUG) + Log.e(TAG, "getThumbnail", e); + } finally { + if (cursor != null) + cursor.close(); + } + } + return bm; + } + + /** + * Get the Intent for selecting content to be used in an Intent Chooser. + * + * @return The intent for opening a file with Intent.createChooser() + * @author paulburke + */ + public static Intent createGetContentIntent() { + // Implicitly allow the user to select a particular kind of data + final Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + // The MIME data type filter + intent.setType("*/*"); + // Only return URIs that can be opened with ContentResolver + intent.addCategory(Intent.CATEGORY_OPENABLE); + return intent; + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/JavaScriptInterface.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/JavaScriptInterface.java new file mode 100644 index 0000000..1fe58ac --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/JavaScriptInterface.java @@ -0,0 +1,47 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.content.Context; +import android.util.Log; +import android.webkit.JavascriptInterface; +import android.widget.Toast; + +public class JavaScriptInterface implements JavascriptCallback { + Context context; + MediNETActivity activity; + + public JavaScriptInterface(MediNETActivity mediNETActivity, + Context applicationContext) { + context = applicationContext; + activity = mediNETActivity; + } + + @JavascriptInterface + public void askToSignIn() { + MeditationAssistant ma = (MeditationAssistant) this.activity + .getApplication(); + this.activity.finish(); + ma.getMediNET().askToSignIn(); + } + + @JavascriptInterface + public void setKey(String key, String provider) { + Log.d("MeditationAssistant", "Setting key" + key); + MeditationAssistant ma = (MeditationAssistant) this.activity + .getApplication(); + ma.setMediNETKey(key, provider); + ma.getMediNET().provider = provider; + ma.getMediNET().connect(); + /* + * Bundle bundle = new Bundle(); bundle.putString("action", + * "changekey"); Intent mIntent = new Intent(); + * mIntent.putExtras(bundle); + * this.activity.setResult(this.activity.RESULT_OK, mIntent); + */ + this.activity.finish(); + } + + @JavascriptInterface + public void showToast(String toast) { + Toast.makeText(context, toast, Toast.LENGTH_SHORT).show(); + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/JavascriptCallback.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/JavascriptCallback.java new file mode 100644 index 0000000..d6f115e --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/JavascriptCallback.java @@ -0,0 +1,5 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +public interface JavascriptCallback { + +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/ListPreferenceSound.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/ListPreferenceSound.java new file mode 100644 index 0000000..a157502 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/ListPreferenceSound.java @@ -0,0 +1,309 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.res.AssetFileDescriptor; +import android.content.res.TypedArray; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.os.Parcel; +import android.os.Parcelable; +import android.preference.ListPreference; +import android.util.AttributeSet; +import android.util.Log; + +import java.io.IOException; + +public class ListPreferenceSound extends ListPreference { + private int mClickedDialogEntryIndex; + private CharSequence[] mEntries; + private CharSequence[] mEntryValues; + private CharSequence mSummary; + private String mValue; + private MediaPlayer mMediaPlayer = null; + private Context ctx = null; + + public ListPreferenceSound(Context context) { + this(context, null); + } + + public ListPreferenceSound(Context context, AttributeSet attrs) { + super(context, attrs); + ctx = context; + + if (mMediaPlayer == null) { + mMediaPlayer = new MediaPlayer(); + } + + TypedArray a = context.obtainStyledAttributes(attrs, + R.styleable.ListPreference, 0, 0); + // mEntries = a.getTextArray(R.styleable.ListPreference_entries); + // mEntryValues = a.getTextArray(R.styleable.ListPreference_entryValues); + setEntries(a.getTextArray(R.styleable.ListPreference_entries)); + setEntryValues(a.getTextArray(R.styleable.ListPreference_entryValues)); + + a.recycle(); + mSummary = super.getSummary(); + } + + public int findIndexOfValue(String value) { + if (value != null && mEntryValues != null) { + for (int i = mEntryValues.length - 1; i >= 0; i--) { + if (mEntryValues[i].equals(value)) { + return i; + } + } + } + return -1; + } + + public CharSequence[] getEntries() { + return mEntries; + } + + public void setEntries(int entriesResId) { + setEntries(getContext().getResources().getTextArray(entriesResId)); + } + + public void setEntries(CharSequence[] entries) { + mEntries = entries; + } + + public CharSequence getEntry() { + int index = getValueIndex(); + return index >= 0 && mEntries != null ? mEntries[index] : null; + } + + public CharSequence[] getEntryValues() { + return mEntryValues; + } + + public void setEntryValues(int entryValuesResId) { + setEntryValues(getContext().getResources().getTextArray( + entryValuesResId)); + } + + public void setEntryValues(CharSequence[] entryValues) { + mEntryValues = entryValues; + } + + @Override + public CharSequence getSummary() { + final CharSequence entry = getEntry(); + if (mSummary == null || entry == null) { + return super.getSummary(); + } else { + //Log.d("MeditationAssistant", "getsummary(): " + String.valueOf(mSummary) + " " + String.valueOf(entry)); + try { + return String.format(mSummary.toString(), entry); + } catch (Exception e) { + e.printStackTrace(); + return mSummary.toString(); + } + } + } + + @Override + public void setSummary(CharSequence summary) { + super.setSummary(summary); + if (summary == null && mSummary != null) { + mSummary = null; + } else if (summary != null && !summary.equals(mSummary)) { + mSummary = summary; + } + } + + public String getValue() { + return mValue; + } + + public void setValue(String value) { + mValue = value; + persistString(value); + } + + private int getValueIndex() { + return findIndexOfValue(mValue); + } + + public void setValueIndex(int index) { + if (mEntryValues != null) { + setValue(mEntryValues[index].toString()); + } + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + super.onDialogClosed(positiveResult); + if (mMediaPlayer != null) { + try { + if (mMediaPlayer.isPlaying()) { + mMediaPlayer.stop(); + mMediaPlayer.reset(); + } + } catch (Exception e) { + Log.d("MeditationAssistant", "Got exception while stopping and resetting sound in ListPreferenceSound"); + e.printStackTrace(); + } + } + if (positiveResult && mClickedDialogEntryIndex >= 0 + && mEntryValues != null) { + String value = mEntryValues[mClickedDialogEntryIndex].toString(); + if (callChangeListener(value)) { + setValue(value); + } + } + } + + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + return a.getString(index); + } + + @Override + protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { + super.onPrepareDialogBuilder(builder); + if (mEntries == null || mEntryValues == null) { + throw new IllegalStateException( + "ListPreference requires an entries array and an entryValues array."); + } + mClickedDialogEntryIndex = getValueIndex(); + builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mClickedDialogEntryIndex = which; + String itemSelected = mEntryValues[mClickedDialogEntryIndex] + .toString(); + + Log.d("MeditationAssistant", + "Selected: " + String.valueOf(which) + " - " + + itemSelected + ); + + if (itemSelected.equals("custom")) { + ListPreferenceSound.this.onClick(dialog, + DialogInterface.BUTTON_POSITIVE); + dialog.dismiss(); + } else if (!itemSelected.equals("none")) { + if (mMediaPlayer != null) { + try { + if (mMediaPlayer.isPlaying()) { + mMediaPlayer.stop(); + mMediaPlayer.reset(); + } + } catch (Exception e) { + Log.d("MeditationAssistant", "Got exception while stopping and resetting sound in ListPreferenceSound"); + e.printStackTrace(); + } + } + + AssetFileDescriptor afd = ctx + .getResources() + .openRawResourceFd( + MeditationSounds + .getMeditationSound(itemSelected) + ); + try { + mMediaPlayer = new MediaPlayer(); + mMediaPlayer.setDataSource( + afd.getFileDescriptor(), + afd.getStartOffset(), + afd.getDeclaredLength()); + mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + mMediaPlayer.prepareAsync(); + // mMediaPlayer.prepare(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalStateException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + if (mMediaPlayer != null) { + mMediaPlayer + .setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + + @Override + public void onCompletion( + MediaPlayer mp) { + mp.release(); + } + }); + mMediaPlayer + .setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared( + MediaPlayer mp) { + mp.start(); + } + }); + } + } + } + } + ); + builder.setPositiveButton( + builder.getContext().getString(R.string.set), + new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + Log.d("MeditationAssistant", "Set clicked"); + ListPreferenceSound.this.onClick(dialog, + DialogInterface.BUTTON_POSITIVE); + dialog.dismiss(); + } + } + ); + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + if (state == null || !state.getClass().equals(SavedState.class)) { + super.onRestoreInstanceState(state); + return; + } + SavedState myState = (SavedState) state; + super.onRestoreInstanceState(myState.getSuperState()); + setValue(myState.value); + } + + @Override + protected Parcelable onSaveInstanceState() { + final Parcelable superState = super.onSaveInstanceState(); + if (isPersistent()) { + return superState; + } + final SavedState myState = new SavedState(superState); + myState.value = getValue(); + return myState; + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + mValue = restoreValue ? getPersistedString(mValue) + : (String) defaultValue; + } + + private static class SavedState extends BaseSavedState { + String value; + + public SavedState(Parcel source) { + super(source); + value = source.readString(); + } + + public SavedState(Parcelable superState) { + super(superState); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeString(value); + } + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MainActivity.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MainActivity.java new file mode 100644 index 0000000..eeb3383 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MainActivity.java @@ -0,0 +1,2546 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.app.Activity; +import android.app.AlarmManager; +import android.app.AlertDialog; +import android.app.PendingIntent; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.text.InputType; +import android.util.Log; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.RadioGroup; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.ViewSwitcher; + +import com.crittercism.app.Crittercism; +import com.github.amlcurran.showcaseview.OnShowcaseEventListener; +import com.github.amlcurran.showcaseview.ShowcaseView; +import com.github.amlcurran.showcaseview.targets.ViewTarget; +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.AdView; +import com.google.android.gms.analytics.GoogleAnalytics; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.HashSet; +import java.util.Locale; +import java.util.Random; +import java.util.Set; + +public class MainActivity extends Activity implements OnShowcaseEventListener { + public static String BROADCAST_ACTION_ALARM = "sh.ftp.rocketninelabs.meditationassistant.ALARM"; + public static int ID_DELAY = 77702; + public static int ID_INTERVAL = 77701; + public static int ID_END = 77703; + + public MeditationAssistant ma = null; + SharedPreferences.OnSharedPreferenceChangeListener sharedPrefslistener = new SharedPreferences.OnSharedPreferenceChangeListener() { + public void onSharedPreferenceChanged(SharedPreferences newprefs, String key) { + Log.d("MeditationAssistant", + key + " changed to " + getMeditationAssistant().getPrefs().getAll().get(key).toString()); + if (getMeditationAssistant().getTimeToStopMeditate() < 1 + && (key.equals("timerHours") || key.equals("timerMinutes"))) { + TextView txtTimer = (TextView) findViewById(R.id.txtTimer); + txtTimer.setText(getMeditationAssistant().getPrefs().getString("timerHours", "0") + + ":" + + String.format("%02d", Integer.valueOf(getMeditationAssistant().getPrefs().getString( + "timerMinutes", "15")))); + } else if (key.equals("pref_meditation_sound_finish") + || key.equals("pref_meditation_sound_finish_custom") + || key.equals("pref_meditation_sound_start") + || key.equals("pref_meditation_sound_start_custom")) { + updateTexts(); + } else if (key.equals("pref_text_size")) { + updateTextSize(); + } else if (key.equals("keyupdate")) { + if (!getMeditationAssistant().getMediNETKey().equals("")) { + getMeditationAssistant().getMediNET().connect(); + } + } + } + }; + private AdView av = null; + private Handler handler; + private Runnable meditateRunnable = null; + private Runnable screenDimRunnable = null; + private Runnable screenOffRunnable = null; + private MediaPlayer mMediaPlayer = null; + private AlarmManager am = null; + private PendingIntent pendingintent = null; + private AlarmManager am_delay = null; + private PendingIntent pendingintent_delay = null; + private AlarmManager am_interval = null; + private PendingIntent pendingintent_interval = null; + private Runnable intervalRunnable = new Runnable() { + @Override + public void run() { + Log.d("MeditationAssistant", "Interval running"); + handler.removeCallbacks(this); + if (getMeditationAssistant().getTimeStartMeditate() > 0) { + if (getMeditationAssistant().getTimeToStopMeditate() != 0 + && getMeditationAssistant().getTimeToStopMeditate() + - (System.currentTimeMillis() / 1000) < 30) { + return; // No interval sounds during the final 30 seconds + } + + if (!getMeditationAssistant().getPrefs().getString("pref_meditation_sound_interval", "") + .equals("none") || getMeditationAssistant().vibrationEnabled()) { + if (!getMeditationAssistant().getPrefs().getString("pref_meditation_sound_interval", "") + .equals("none")) { + stopMediaPlayer(); + mMediaPlayer = null; + if (getMeditationAssistant().getPrefs().getString("pref_meditation_sound_interval", "") + .equals("custom")) { + String soundpath = getMeditationAssistant().getPrefs().getString( + "pref_meditation_sound_interval_custom", ""); + if (!soundpath.equals("")) { + try { + mMediaPlayer = MediaPlayer.create( + getApplicationContext(), + Uri.parse(soundpath)); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else { + mMediaPlayer = MediaPlayer + .create(getApplicationContext(), + MeditationSounds.getMeditationSound(getMeditationAssistant().getPrefs().getString( + "pref_meditation_sound_interval", + "")) + ); + } + + if (mMediaPlayer != null) { + mMediaPlayer + .setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + + @Override + public void onCompletion(MediaPlayer mp) { + mp.release(); + WakeLocker.release(); + } + }); + + WakeLocker.acquire(getApplicationContext(), false); + mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + mMediaPlayer + .setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared( + MediaPlayer mp) { + mp.start(); + } + }); + //mMediaPlayer.prepareAsync(); + } + } + + getMeditationAssistant().vibrateDevice(); + + long interval = Math.max( + getMeditationAssistant().timePreferenceValueToSeconds(getMeditationAssistant().getPrefs().getString("pref_session_interval", "00:00"), "00:00"), 0); + Log.d("MeditationAssistant", "Interval is set to " + String.valueOf(interval) + " seconds"); + + if (interval > 0 && (getMeditationAssistant().getTimeToStopMeditate() == -1 + || getMeditationAssistant().getTimeToStopMeditate() + - (System.currentTimeMillis() / 1000) > (interval + 30) || getMeditationAssistant().getPrefs().getBoolean("pref_softfinish", false))) { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.SECOND, (int) interval); + + Log.d("MeditationAssistant", "Setting INTERVAL WAKEUP alarm for " + + String.valueOf(cal.getTimeInMillis()) + " (Now: " + + System.currentTimeMillis() + ", in: " + String.valueOf((cal.getTimeInMillis() - System.currentTimeMillis()) / 1000) + ")"); + + Intent intent_interval = new Intent( + getApplicationContext(), MainActivity.class); + intent_interval.putExtra("wakeup", true); + intent_interval.putExtra("wakeupinterval", true); + intent_interval.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + intent_interval.setAction(BROADCAST_ACTION_ALARM); + pendingintent_interval = PendingIntent.getActivity( + getApplicationContext(), ID_INTERVAL, + intent_interval, PendingIntent.FLAG_CANCEL_CURRENT); + am_interval = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + if (Build.VERSION.SDK_INT >= 19) { + am_interval.setExact(AlarmManager.RTC_WAKEUP, + cal.getTimeInMillis(), pendingintent_interval); + } else { + am_interval.set(AlarmManager.RTC_WAKEUP, + cal.getTimeInMillis(), pendingintent_interval); + } + handler.postDelayed(this, interval * 1000); + } + } + } + } + }; + private String lastKey = ""; + private Boolean skipDelay = false; + private String previous_timermode = "timed"; + private Boolean usetimepicker = true; + private ShowcaseView sv = null; + private String next_tutorial = ""; + private int intervals = 0; + private Runnable clearWakeLock = new Runnable() { + @Override + public void run() { + WakeLocker.release(); + } + }; + private Boolean finishedTutorial = null; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Crittercism.initialize(getApplicationContext(), "51d51a5ea7928a6b4a000005"); + + setTheme(getMeditationAssistant().getMATheme()); + setContentView(R.layout.activity_main); + + if (getMeditationAssistant().sendUsageReports()) { + getMeditationAssistant().getTracker(MeditationAssistant.TrackerName.APP_TRACKER); + } + + handler = new Handler(); + + lastKey = getMeditationAssistant().getPrefs().getString("key", ""); + + if (getMeditationAssistant().getMediNET() == null) { + getMeditationAssistant().setMediNET(new MediNET(this)); + Log.d("MeditationAssistant", "New instance of MediNET created"); + } else { + getMeditationAssistant().getMediNET().activity = this; + } + + getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); + + findViewById(R.id.btnMeditate).setLongClickable(true); + final View btnMeditate = findViewById(R.id.btnMeditate); + btnMeditate.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + return longPressMeditate(v); + } + }); + + /*CheckBox chkUseTimer = (CheckBox) findViewById(R.id.chkUseTimer); + chkUseTimer.setChecked(getMeditationAssistant().getUseTimer()); + changeUseTimer(null);*/ + + usetimepicker = getMeditationAssistant().getPrefs().getBoolean("pref_usetimepicker", false); + + final EditText editDuration = (EditText) findViewById(R.id.editDuration); + final TimePicker timepickerDuration = (TimePicker) findViewById(R.id.timepickerDuration); + timepickerDuration.setIs24HourView(true); + if (usetimepicker) { + editDuration.setVisibility(View.GONE); + timepickerDuration.setVisibility(View.VISIBLE); + /*EditText newEditDuration = new EditText(this); + newEditDuration.setId(R.id.editDuration); + FrameLayout.LayoutParams editDurationLayoutParams = new FrameLayout.LayoutParams( + android.view.ViewGroup.LayoutParams.FILL_PARENT, + android.view.ViewGroup.LayoutParams.WRAP_CONTENT); + editDurationLayoutParams.gravity = Gravity.CENTER; + editDurationLayoutParams.setMargins(0, 0, 0, 0); + newEditDuration.setLayoutParams(editDurationLayoutParams); + newEditDuration.setIncludeFontPadding(false); + newEditDuration.setInputType(InputType.TYPE_DATETIME_VARIATION_TIME); + newEditDuration.setSingleLine(true); + newEditDuration.imeOp + RelativeLayout layEditDuration = (RelativeLayout) findViewById(R.id.layEditDuration); + layEditDuration.addView(newEditDuration);*/ + } else { + timepickerDuration.setVisibility(View.GONE); + editDuration.setVisibility(View.VISIBLE); + } + + updateTextSize(); + updateMeditate(false, false); + updateTexts(); + updatePresets(); + getMeditationAssistant().setRunnableStopped(true); + startRunnable(); + + editDuration + .setOnEditorActionListener(new EditText.OnEditorActionListener() { + @Override + public boolean onEditorAction(android.widget.TextView v, + int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_DONE) { + ViewSwitcher switchTimer = (ViewSwitcher) findViewById(R.id.switchTimer); + RelativeLayout layEditDuration = (RelativeLayout) findViewById(R.id.layEditDuration); + + if (switchTimer.getCurrentView().equals( + layEditDuration)) { + setDuration(null); + } + return true; + } + + return false; + } + }); + editDuration.setOnKeyListener(new EditText.OnKeyListener() { + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_UP + && keyCode == KeyEvent.KEYCODE_ENTER) { + ViewSwitcher switchTimer = (ViewSwitcher) findViewById(R.id.switchTimer); + RelativeLayout layEditDuration = (RelativeLayout) findViewById(R.id.layEditDuration); + if (switchTimer.getCurrentView().equals(layEditDuration)) { + setDuration(null); + } + + return true; + } + + return false; + } + }); + + Button btnPreset1 = (Button) findViewById(R.id.btnPreset1); + Button btnPreset2 = (Button) findViewById(R.id.btnPreset2); + Button btnPreset3 = (Button) findViewById(R.id.btnPreset3); + + View.OnLongClickListener presetListener = new View.OnLongClickListener() { + @Override + public boolean onLongClick(final View view) { + if (getMeditationAssistant().getTimerMode().equals("endat")) { + ArrayList duration_formatted = new ArrayList(); + if (usetimepicker) { + duration_formatted.add(String.valueOf(timepickerDuration.getCurrentHour())); + duration_formatted.add(String.format("%02d", + timepickerDuration.getCurrentMinute())); + } else { + duration_formatted = getMeditationAssistant().formatDurationEndAt(editDuration.getText().toString().trim()); + } + + if (duration_formatted == null || duration_formatted.size() != 2) { + getMeditationAssistant().shortToast(MainActivity.this, getString(R.string.setPresetHintBlank)); + return true; + } + } else if (!getMeditationAssistant().getTimerMode().equals("untimed")) { + ArrayList duration_formatted = new ArrayList(); + if (usetimepicker) { + duration_formatted.add(String.valueOf(timepickerDuration.getCurrentHour())); + duration_formatted.add(String.format("%02d", + timepickerDuration.getCurrentMinute())); + } else { + duration_formatted = getMeditationAssistant().formatDuration(editDuration.getText().toString().trim()); + } + + if (duration_formatted == null || duration_formatted.size() != 2) { + getMeditationAssistant().shortToast(MainActivity.this, getString(R.string.setPresetHintBlank)); + return true; + } + } + + final String preset_key; + if (view.getId() == R.id.btnPreset1) { + preset_key = "pref_preset_1"; + } else if (view.getId() == R.id.btnPreset2) { + preset_key = "pref_preset_2"; + } else if (view.getId() == R.id.btnPreset3) { + preset_key = "pref_preset_3"; + } else { + return false; + } + + LayoutInflater presetInflater = getLayoutInflater(); + View presetLayout = presetInflater.inflate(R.layout.set_preset, null); + final EditText editPresetTitle = (EditText) presetLayout.findViewById(R.id.editPresetTitle); + editPresetTitle.setText(getPresetDefaultLabel()); + editPresetTitle.setSelection(editPresetTitle.getText().length()); + editPresetTitle.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + + AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); + + builder.setIcon( + getResources() + .getDrawable( + getTheme() + .obtainStyledAttributes( + getMeditationAssistant() + .getMATheme(), + new int[]{R.attr.actionIconForward} + ) + .getResourceId(0, 0) + ) + ) + .setTitle(getString(R.string.setPreset)) + .setView(presetLayout) + .setPositiveButton(getString(R.string.set), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + getMeditationAssistant().getPrefs().edit().putString(preset_key + "_label", editPresetTitle.getText().toString().trim()).apply(); + savePreset(preset_key); + updatePresets(); + } + }) + .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + // Do nothing + } + }).show(); + + return true; + } + }; + + btnPreset1.setOnLongClickListener(presetListener); + btnPreset2.setOnLongClickListener(presetListener); + btnPreset3.setOnLongClickListener(presetListener); + + updateVisibleViews(false); + + if (getMeditationAssistant().getEditingDuration()) { + changeDuration(null); + } + + // String pass = "br[qs$jQ>$_rr1~ bu')5\1]fw| }"; + + /*RelativeLayout.LayoutParams lps = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + lps.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); + lps.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); + int margin = ((Number) (getResources().getDisplayMetrics().density * 24)).intValue(); + lps.setMargins(margin, margin, margin, margin);*/ + + //sv.setButtonPosition(lps); + + if (getMeditationAssistant().getPrefs().getBoolean("pref_autosignin", false)) { + getMeditationAssistant().connectOnce(); + } else { + getMeditationAssistant().getMediNET().updated(); + } + + if (getPackageName() + .equals("sh.ftp.rocketninelabs.meditationassistant")) { + Log.d("MeditationAssistant", "Fetching ad"); + + // AdView av = new AdView(this, AdSize.SMART_BANNER, + // "a15110a172d3cff"); + av = (AdView) findViewById(R.id.adViewMain); + av.setVisibility(View.VISIBLE); + AdRequest adRequest = new AdRequest.Builder() + .addTestDevice(AdRequest.DEVICE_ID_EMULATOR) + .build(); + av.loadAd(adRequest); + } + + onNewIntent(getIntent()); + + Object language = Locale.getDefault().getLanguage(); + if (language != null && !language.equals("en") && getMeditationAssistant().getPrefs().getInt("applaunches", 0) >= 5 && !getMeditationAssistant().getPrefs().getBoolean("askedtotranslate", false)) { + getMeditationAssistant().getPrefs().edit().putBoolean("askedtotranslate", true).apply(); + + DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case DialogInterface.BUTTON_POSITIVE: + startActivity(new Intent( + Intent.ACTION_VIEW, + Uri.parse("http://medinet.ftp.sh/translate")).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + + break; + + case DialogInterface.BUTTON_NEGATIVE: + break; + } + } + }; + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setIcon( + getResources() + .getDrawable( + getTheme() + .obtainStyledAttributes( + getMeditationAssistant() + .getMATheme(), + new int[]{R.attr.actionIconNotImportant} + ) + .getResourceId(0, 0) + ) + ) + .setTitle(getString(R.string.translate)) + .setMessage( + getString(R.string.translateMeditationAssistantText)) + .setPositiveButton(getString(R.string.yes), + dialogClickListener) + .setNegativeButton(getString(R.string.no), + dialogClickListener).show(); + } + + showNextTutorial(); + getMeditationAssistant().recalculateMeditationStreak(); + + long pref_delay = Integer.valueOf(getMeditationAssistant().getPrefs().getString("pref_delay", "-1")); + long pref_interval = Integer.valueOf(getMeditationAssistant().getPrefs().getString("pref_interval", "-1")); + if (pref_delay >= 0 || pref_interval >= 0) { + getMeditationAssistant().getPrefs().edit().putString("pref_delay", "-1").putString("pref_interval", "-1").apply(); + + getMeditationAssistant().getMediNET().announcement = getString(R.string.helpUpgradeDelayInterval); + runOnUiThread(new Runnable() { + @Override + public void run() { + getMeditationAssistant() + .showAnnouncementDialog(getString(R.string.pref_notification)); + } + }); + } + + getMeditationAssistant().setupGoogleClient(MainActivity.this); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + if (sv != null && sv.isShown()) { + try { + sv.hide(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (item.getItemId() == R.id.action_settings) { + Intent intent = new Intent(this, SettingsActivity.class); + startActivity(intent); + return true; + } + return super.onOptionsItemSelected(item); + } + + public void cancelSetDuration(View view) { + ViewSwitcher switchTimer = (ViewSwitcher) findViewById(R.id.switchTimer); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(switchTimer.getWindowToken(), 0); + getMeditationAssistant().setEditingDuration(false); + getMeditationAssistant().setTimerMode(previous_timermode); + changeDuration(null); + updateVisibleViews(false); + } + + public void updateEditDuration() { + if (usetimepicker) { + TimePicker timepickerDuration = (TimePicker) findViewById(R.id.timepickerDuration); + + if (getMeditationAssistant().getTimerMode().equals("timed")) { + timepickerDuration.setEnabled(true); + timepickerDuration.setCurrentHour(Integer.valueOf(getMeditationAssistant().getPrefs().getString("timerHours", "0"))); + timepickerDuration.setCurrentMinute(Integer.valueOf(String.format("%02d", Integer.valueOf(getMeditationAssistant().getPrefs().getString("timerMinutes", "15"))))); + } else if (getMeditationAssistant().getTimerMode().equals("endat")) { + timepickerDuration.setEnabled(true); + timepickerDuration.setCurrentHour(Integer.valueOf(getMeditationAssistant().getPrefs().getString("timerHoursEndAt", "0"))); + timepickerDuration.setCurrentMinute(Integer.valueOf(String.format("%02d", Integer.valueOf(getMeditationAssistant().getPrefs().getString("timerMinutesEndAt", "0"))))); + } else { + timepickerDuration.setEnabled(false); + } + } else { + EditText editDuration = (EditText) findViewById(R.id.editDuration); + //FrameLayout.LayoutParams editDurationLayoutParams = new FrameLayout.LayoutParams( + // android.view.ViewGroup.LayoutParams.FILL_PARENT, + // android.view.ViewGroup.LayoutParams.WRAP_CONTENT); + //editDurationLayoutParams.gravity = Gravity.CENTER; + + if (getMeditationAssistant().getTimerMode().equals("timed")) { + editDuration.setText(getMeditationAssistant().getPrefs().getString("timerHours", "0") + + ":" + + String.format("%02d", Integer.valueOf(getMeditationAssistant().getPrefs().getString( + "timerMinutes", "15")))); + //editDurationLayoutParams.setMargins(0, -23, 0, -11); + } else if (getMeditationAssistant().getTimerMode().equals("endat")) { + editDuration.setText(getMeditationAssistant().getPrefs().getString("timerHoursEndAt", "0") + + ":" + + String.format("%02d", Integer.valueOf(getMeditationAssistant().getPrefs().getString( + "timerMinutesEndAt", "0")))); + + //editDurationLayoutParams.setMargins(0, -23, 0, -11); + } else { + editDuration.setText(getString(R.string.ignore_om)); + //editDurationLayoutParams.setMargins(0, 0, 0, 0); + } + } + + updateMeditate(false, false); + //editDuration.setLayoutParams(editDurationLayoutParams); + } + + public void setDuration(View view) { + ViewSwitcher switchTimer = (ViewSwitcher) findViewById(R.id.switchTimer); + + if (usetimepicker) { + TimePicker timepickerDuration = (TimePicker) findViewById(R.id.timepickerDuration); + + if (getMeditationAssistant().getTimerMode().equals("timed")) { + getMeditationAssistant().getPrefs().edit().putString("timerHours", String.valueOf(timepickerDuration.getCurrentHour())).putString("timerMinutes", String.valueOf(timepickerDuration.getCurrentMinute())).apply(); + } else if (getMeditationAssistant().getTimerMode().equals("endat")) { + getMeditationAssistant().getPrefs().edit().putString("timerHoursEndAt", String.valueOf(timepickerDuration.getCurrentHour())).putString("timerMinutesEndAt", String.valueOf(timepickerDuration.getCurrentMinute())).apply(); + } + } else { + EditText editDuration = (EditText) findViewById(R.id.editDuration); + + if (getMeditationAssistant().getTimerMode().equals("timed")) { + ArrayList duration_formatted = getMeditationAssistant().formatDuration(editDuration.getText().toString().trim()); + if (duration_formatted != null && duration_formatted.size() == 2) { + SharedPreferences.Editor editor = getMeditationAssistant().getPrefs().edit(); + editor.putString("timerHours", duration_formatted.get(0)); + editor.putString("timerMinutes", duration_formatted.get(1)); + editor.apply(); + } else { + getMeditationAssistant().shortToast(this, getString(R.string.setTimerDurationHint)); + return; + } + } else if (getMeditationAssistant().getTimerMode().equals("endat")) { + ArrayList duration_formatted = getMeditationAssistant().formatDurationEndAt(editDuration.getText().toString().trim()); + if (duration_formatted != null && duration_formatted.size() == 2) { + SharedPreferences.Editor editor = getMeditationAssistant().getPrefs().edit(); + editor.putString("timerHoursEndAt", duration_formatted.get(0)); + editor.putString("timerMinutesEndAt", duration_formatted.get(1)); + editor.apply(); + } else { + getMeditationAssistant().shortToast(this, getString(R.string.setTimerEndAtHint)); + return; + } + } + + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(switchTimer.getWindowToken(), 0); + } + + getMeditationAssistant().setEditingDuration(false); + changeDuration(null); + } + + /* Called when the duration is clicked */ + public void changeDuration(View view) { + ViewSwitcher switcher = (ViewSwitcher) findViewById(R.id.switchTimer); + RelativeLayout layEditDuration = (RelativeLayout) findViewById(R.id.layEditDuration); + EditText editDuration = (EditText) findViewById(R.id.editDuration); + + if (getMeditationAssistant().getTimeStartMeditate() > 0) { + if (!switcher.getCurrentView().equals(layEditDuration)) { + return; // Don't switch during a meditation session + } + } + + if (getMeditationAssistant().getEditingDuration()) { + return; // Don't switch back while editing, must use buttons + } + + if (sv != null && sv.isShown()) { + try { + sv.hide(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + // RelativeLayout layRememberDurationOuter = (RelativeLayout) + // findViewById(R.id.layRememberDurationOuter); + + switcher.showNext(); + Boolean wasEditing = false; + if (switcher.getCurrentView().equals(layEditDuration)) { + if (view != null) { + getMeditationAssistant().setEditingDuration(true); + Boolean previous_rememberduration = getMeditationAssistant() + .getRememberDuration(); + previous_timermode = getMeditationAssistant().getTimerMode(); + } + + updateEditDuration(); + + if (getMeditationAssistant().getTimerMode().equals("timed") || getMeditationAssistant().getTimerMode().equals("endat")) { + editDuration.requestFocus(); + InputMethodManager imm = (InputMethodManager) this + .getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(editDuration, + InputMethodManager.SHOW_IMPLICIT); + editDuration.setSelection(0, editDuration.getText().length()); + } + } else { + getMeditationAssistant().setEditingDuration(false); + + wasEditing = true; + } + + updateMeditate(false, false); + updateVisibleViews(false); + + if (wasEditing) { + showNextTutorial(); + } + } + + private void showNextTutorial() { + if (finishedTutorial == null) { + finishedTutorial = getMeditationAssistant().getPrefs().getBoolean("finishedTutorial", false); + + if (!finishedTutorial && getMeditationAssistant().db.getNumSessions() > 0) { // Already recorded a session + getMeditationAssistant().getPrefs().edit().putBoolean("finishedTutorial", true).apply(); + finishedTutorial = true; + } + } + + if (!finishedTutorial) { + if (!getMeditationAssistant().getPrefs().getBoolean("finishedTutorial", false)) { + getMeditationAssistant().getPrefs().edit().putBoolean("finishedTutorial", true).apply(); // Commit early because of crashes + } + + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + if (sv != null) { + return; // Tutorial still visible + } + + if (next_tutorial.equals("")) { + if (!getMeditationAssistant().getEditingDuration()) { + View txtTimer = findViewById(R.id.txtTimer); + if (txtTimer == null) { + return; + } + next_tutorial = "settings"; + + ViewTarget target = new ViewTarget(R.id.txtTimer, this); + try { + sv = new ShowcaseView.Builder(this, true) + .setTarget(target) + .setContentTitle(R.string.timer) + .setContentText(R.string.timerHelp) + .setShowcaseEventListener(this) + .setStyle(R.style.MeditationShowcaseTheme) + .build(); + sv.hideButton(); + sv.setHideOnTouchOutside(false); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else if (next_tutorial.equals("settings")) { + if (!getMeditationAssistant().getEditingDuration()) { + View actionSettings = findViewById(R.id.action_settings); + if (actionSettings == null) { + return; + } + next_tutorial = "medinet"; + + ViewTarget target = new ViewTarget(R.id.action_settings, this); + try { + sv = new ShowcaseView.Builder(this, true) + .setTarget(target) + .setContentTitle(R.string.settings) + .setContentText(R.string.settingsHelp) + .setShowcaseEventListener(this) + .setStyle(R.style.MeditationShowcaseTheme) + .build(); + sv.hideButton(); + sv.setHideOnTouchOutside(false); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else if (next_tutorial.equals("medinet")) { + if (!getMeditationAssistant().getEditingDuration()) { + View btnMeditationStreak = findViewById(R.id.btnMeditationStreak); + if (btnMeditationStreak == null) { + return; + } + next_tutorial = "none"; + finishedTutorial = true; + + ViewTarget target = new ViewTarget(R.id.btnMeditationStreak, this); + try { + sv = new ShowcaseView.Builder(this, true) + .setTarget(target) + .setContentTitle(R.string.mediNET) + .setShowcaseEventListener(this) + .setStyle(R.style.MeditationShowcaseTheme) + .build(); + sv.setContentText(getString(R.string.medinetHelp) + "\n\nनमस्ते"); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } else { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + } + } + + public void showViewMA(View view, boolean fadeView) { + if (view == null) { + return; + } + if (view.getVisibility() != View.VISIBLE && fadeView) { + Animation animation = AnimationUtils.loadAnimation(this, + R.anim.fadeinma); + view.startAnimation(animation); + } + view.setVisibility(View.VISIBLE); + } + + public void hideViewMA(View view, boolean fadeView) { + if (view == null) { + return; + } + if (view.getVisibility() == View.VISIBLE && fadeView) { + Log.d("MeditationAssistant", "Visible, fading out..."); + FadeOutAnimationListener listener = new FadeOutAnimationListener(); + listener.setView(view); + Animation animation = AnimationUtils.loadAnimation(this, + R.anim.fadeoutma); + animation.setAnimationListener(listener); + view.startAnimation(animation); + } else { + view.setVisibility(View.GONE); + } + } + + public void updateVisibleViews(boolean fadeViews) { + // Log.d("MeditationAssistant", "updateVisibleViews"); + RadioGroup radgMainTimerMode = (RadioGroup) findViewById(R.id.radgMainTimerMode); + + RelativeLayout layLowerViews = (RelativeLayout) findViewById(R.id.layLowerViews); + LinearLayout layLowerViewsEditing = (LinearLayout) findViewById(R.id.layLowerViewsEditing); + + if (getMeditationAssistant().getEditingDuration()) { + hideViewMA(layLowerViews, false); + showViewMA(layLowerViewsEditing, false); + } else { + showViewMA(layLowerViews, false); + hideViewMA(layLowerViewsEditing, false); + } + + EditText editDuration = (EditText) findViewById(R.id.editDuration); + + if (getMeditationAssistant().getEditingDuration()) { + if (getMeditationAssistant().getTimerMode().equals("timed") || getMeditationAssistant().getTimerMode().equals("endat")) { + InputMethodManager imm = (InputMethodManager) this + .getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(editDuration, + InputMethodManager.SHOW_IMPLICIT); + + editDuration.setSelection(0, editDuration.getText().length()); + editDuration.setEnabled(true); + } else { + editDuration.setSelection(0, 0); + editDuration.setEnabled(false); + } + } else { + editDuration.setSelection(0, 0); + editDuration.setEnabled(false); + } + + /* Update radio buttons */ + if (getMeditationAssistant().getTimerMode().equals("untimed")) { + radgMainTimerMode.check(R.id.radMainUntimed); + } else if (getMeditationAssistant().getTimerMode().equals("endat")) { + radgMainTimerMode.check(R.id.radMainEndAt); + } else { + radgMainTimerMode.check(R.id.radMainTimed); + } + } + + public void updateTextSize() { + TextView txtTimer = (TextView) findViewById(R.id.txtTimer); + EditText editDuration = (EditText) findViewById(R.id.editDuration); + String text_size = getMeditationAssistant().getPrefs().getString("pref_text_size", "normal"); + if (text_size.equals("tiny")) { + txtTimer.setTextSize(85); + editDuration.setTextSize(85); + } else if (text_size.equals("small")) { + txtTimer.setTextSize(115); + editDuration.setTextSize(115); + } else if (text_size.equals("large")) { + txtTimer.setTextSize(175); + editDuration.setTextSize(175); + } else if (text_size.equals("extralarge")) { + txtTimer.setTextSize(200); + editDuration.setTextSize(200); + } else { // Normal + txtTimer.setTextSize(153); + editDuration.setTextSize(153); + } + } + + public void updatePresets() { + Button btnPreset1 = (Button) findViewById(R.id.btnPreset1); + Button btnPreset2 = (Button) findViewById(R.id.btnPreset2); + Button btnPreset3 = (Button) findViewById(R.id.btnPreset3); + + btnPreset1.setText(getMeditationAssistant().getPrefs().getString("pref_preset_1_label", getString(R.string.setPreset))); + btnPreset2.setText(getMeditationAssistant().getPrefs().getString("pref_preset_2_label", getString(R.string.setPreset))); + btnPreset3.setText(getMeditationAssistant().getPrefs().getString("pref_preset_3_label", getString(R.string.setPreset))); + } + + public String getPresetDefaultLabel() { + EditText editDuration = (EditText) findViewById(R.id.editDuration); + TimePicker timepickerDuration = (TimePicker) findViewById(R.id.timepickerDuration); + + if (getMeditationAssistant().getTimerMode().equals("untimed")) { + return "Untimed"; + } else if (getMeditationAssistant().getTimerMode().equals("endat")) { + ArrayList duration_formatted = new ArrayList(); + if (usetimepicker) { + duration_formatted.add(String.valueOf(timepickerDuration.getCurrentHour())); + duration_formatted.add(String.format("%02d", + timepickerDuration.getCurrentMinute())); + } else { + duration_formatted = getMeditationAssistant().formatDurationEndAt(editDuration.getText().toString().trim()); + } + + if (duration_formatted != null && duration_formatted.size() == 2) { + return String.format(getString(R.string.presetLabelEndAt), duration_formatted.get(0) + ":" + duration_formatted.get(1)); + } + } else { // timed + ArrayList duration_formatted = new ArrayList(); + if (usetimepicker) { + duration_formatted.add(String.valueOf(timepickerDuration.getCurrentHour())); + duration_formatted.add(String.format("%02d", + timepickerDuration.getCurrentMinute())); + } else { + duration_formatted = getMeditationAssistant().formatDuration(editDuration.getText().toString().trim()); + } + + if (duration_formatted != null && duration_formatted.size() == 2) { + return duration_formatted.get(0) + ":" + duration_formatted.get(1); + } + } + + return ""; + } + + public void pressPreset(View view) { + final EditText editDuration = (EditText) findViewById(R.id.editDuration); + + String preset_key; + if (view.getId() == R.id.btnPreset1) { + preset_key = "pref_preset_1"; + } else if (view.getId() == R.id.btnPreset2) { + preset_key = "pref_preset_2"; + } else if (view.getId() == R.id.btnPreset3) { + preset_key = "pref_preset_3"; + } else { + return; + } + + String preset_value = getMeditationAssistant().getPrefs().getString(preset_key, ""); + Boolean successfulRestore = false; + + if (!preset_value.equals("")) { + try { + Set presetSettings = getMeditationAssistant().getPrefs().getStringSet("pref_presetsettings", new HashSet(Arrays.asList(getResources().getStringArray(R.array.presetsettings_default)))); + JSONObject preset = new JSONObject(preset_value); + Log.d("MeditationAssistant", "Restore preset settings: " + presetSettings.toString() + " - Values: " + preset_value); + + // Mode and duration + if (presetSettings.contains("modeandduration")) { + if (preset.getString("modeandduration").equals("untimed")) { + getMeditationAssistant().setTimerMode("untimed"); + + setDuration(null); + } else if (preset.getString("modeandduration").startsWith("e") && preset.getString("modeandduration").length() > 1) { + getMeditationAssistant().setTimerMode("endat"); + + if (usetimepicker) { + String[] preset_split = preset.getString("modeandduration").substring(1).split(":"); + if (preset_split.length == 2) { + TimePicker timepickerDuration = (TimePicker) findViewById(R.id.timepickerDuration); + timepickerDuration.setCurrentHour(Integer.valueOf(preset_split[0])); + timepickerDuration.setCurrentMinute(Integer.valueOf(preset_split[1])); + } + } else { + editDuration.setText(preset.getString("modeandduration").substring(1)); + } + setDuration(null); + } else if (!preset.getString("modeandduration").equals("")) { + getMeditationAssistant().setTimerMode("timed"); + + if (usetimepicker) { + String[] preset_split = preset.getString("modeandduration").split(":"); + if (preset_split.length == 2) { + TimePicker timepickerDuration = (TimePicker) findViewById(R.id.timepickerDuration); + timepickerDuration.setCurrentHour(Integer.valueOf(preset_split[0])); + timepickerDuration.setCurrentMinute(Integer.valueOf(preset_split[1])); + } + } else { + editDuration.setText(preset.getString("modeandduration")); + } + setDuration(null); + } + } + + // Delay + if (presetSettings.contains("delay")) { + getMeditationAssistant().getPrefs().edit().putString("pref_session_delay", preset.getString("delay")).apply(); + } + + // Start sound + if (presetSettings.contains("startsound")) { + getMeditationAssistant().getPrefs().edit().putString("pref_meditation_sound_start", preset.getString("startsound")).apply(); + if (preset.getString("startsound").equals("custom")) { + getMeditationAssistant().getPrefs().edit().putString("pref_meditation_sound_start_custom", preset.getString("startsoundcustom")).apply(); + } + } + + // Interval duration + if (presetSettings.contains("intervalduration")) { + getMeditationAssistant().getPrefs().edit().putString("pref_session_interval", preset.getString("intervalduration")).apply(); + } + + // Interval sound + if (presetSettings.contains("intervalsound")) { + getMeditationAssistant().getPrefs().edit().putString("pref_meditation_sound_interval", preset.getString("intervalsound")).apply(); + if (preset.getString("intervalsound").equals("custom")) { + getMeditationAssistant().getPrefs().edit().putString("pref_meditation_sound_interval_custom", preset.getString("intervalsoundcustom")).apply(); + } + } + + // Interval count + if (presetSettings.contains("intervalcount")) { + getMeditationAssistant().getPrefs().edit().putString("pref_interval_count", preset.getString("intervalcount")).apply(); + } + + // Complete sound + if (presetSettings.contains("completesound")) { + getMeditationAssistant().getPrefs().edit().putString("pref_meditation_sound_finish", preset.getString("completesound")).apply(); + if (preset.getString("completesound").equals("custom")) { + getMeditationAssistant().getPrefs().edit().putString("pref_meditation_sound_finish_custom", preset.getString("completesoundcustom")).apply(); + } + } + + // Ringtone and notifications + if (presetSettings.contains("ringtone")) { + getMeditationAssistant().getPrefs().edit().putString("pref_notificationcontrol", preset.getString("ringtone")).apply(); + } + + // Endless + if (presetSettings.contains("endless")) { + getMeditationAssistant().getPrefs().edit().putBoolean("pref_softfinish", preset.getBoolean("endless")).apply(); + } + + // Vibrate + if (presetSettings.contains("vibrate")) { + getMeditationAssistant().getPrefs().edit().putBoolean("pref_vibrate", preset.getBoolean("vibrate")).apply(); + } + + successfulRestore = true; + } catch (JSONException e) { + e.printStackTrace(); + } + } + + if (successfulRestore) { + Intent presetIntent = new Intent(); + presetIntent.setAction(MeditationAssistant.ACTION_PRESET); + sendBroadcast(presetIntent); + } else { + getMeditationAssistant().shortToast(this, getString(R.string.setPresetHint)); + } + } + + public void openProgress(View view) { + if (sv != null && sv.isShown()) { + try { + sv.hide(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + Intent intent = new Intent(this, ProgressActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + } + + public void savePreset(String preset_key) { + EditText editDuration = (EditText) findViewById(R.id.editDuration); + TimePicker timepickerDuration = (TimePicker) findViewById(R.id.timepickerDuration); + + Preset preset = new Preset(); + if (getMeditationAssistant().getTimerMode().equals("untimed")) { + preset.modeandduration = "untimed"; + } else if (getMeditationAssistant().getTimerMode().equals("endat")) { + ArrayList duration_formatted = new ArrayList(); + if (usetimepicker) { + duration_formatted.add(String.valueOf(timepickerDuration.getCurrentHour())); + duration_formatted.add(String.format("%02d", + timepickerDuration.getCurrentMinute())); + } else { + duration_formatted = getMeditationAssistant().formatDurationEndAt(editDuration.getText().toString().trim()); + } + + if (duration_formatted != null && duration_formatted.size() == 2) { + preset.modeandduration = "e" + duration_formatted.get(0) + ":" + duration_formatted.get(1); + } + } else { // timed + ArrayList duration_formatted = new ArrayList(); + if (usetimepicker) { + duration_formatted.add(String.valueOf(timepickerDuration.getCurrentHour())); + duration_formatted.add(String.format("%02d", + timepickerDuration.getCurrentMinute())); + } else { + duration_formatted = getMeditationAssistant().formatDuration(editDuration.getText().toString().trim()); + } + + if (duration_formatted != null && duration_formatted.size() == 2) { + preset.modeandduration = duration_formatted.get(0) + ":" + duration_formatted.get(1); + } + } + + preset.delay = getMeditationAssistant().getPrefs().getString("pref_session_delay", "00:15"); + preset.startsound = getMeditationAssistant().getPrefs().getString("pref_meditation_sound_start", ""); + preset.startsoundcustom = getMeditationAssistant().getPrefs().getString("pref_meditation_sound_start_custom", ""); + preset.intervalduration = getMeditationAssistant().getPrefs().getString("pref_session_interval", "00:00"); + preset.intervalsound = getMeditationAssistant().getPrefs().getString("pref_meditation_sound_interval", ""); + preset.intervalsoundcustom = getMeditationAssistant().getPrefs().getString("pref_meditation_sound_interval_custom", ""); + preset.intervalcount = getMeditationAssistant().getPrefs().getString("pref_interval_count", ""); + preset.completesound = getMeditationAssistant().getPrefs().getString("pref_meditation_sound_finish", ""); + preset.completesoundcustom = getMeditationAssistant().getPrefs().getString("pref_meditation_sound_finish_custom", ""); + preset.ringtone = getMeditationAssistant().getPrefs().getString("pref_notificationcontrol", ""); + preset.endless = getMeditationAssistant().getPrefs().getBoolean("pref_softfinish", false); + preset.vibrate = getMeditationAssistant().getPrefs().getBoolean("pref_vibrate", false); + + String exported = preset.export().toString(); + Log.d("MeditationAssistant", "Setting preset: " + exported); + getMeditationAssistant().getPrefs().edit().putString(preset_key, exported).apply(); + } + + public void pressMeditate(View view) { + if (sv != null && sv.isShown()) { + try { + sv.hide(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + long timestamp = getMeditationAssistant().getTimestamp(); + + if (getMeditationAssistant().getTimeStartMeditate() > 0) { // session in progress + if (getMeditationAssistant().getTimeStartMeditate() > timestamp) { // currently in delay phase + Log.d("MeditationAssistant", + "PREVIOUS Timestamp: " + + String.valueOf(timestamp) + + " Stop: " + + String.valueOf(getMeditationAssistant() + .getTimeToStopMeditate()) + + " Start: " + + String.valueOf(getMeditationAssistant() + .getTimeStartMeditate()) + ); + getMeditationAssistant().setTimeStartMeditate(timestamp); + + if (getMeditationAssistant().getTimeToStopMeditate() != -1 && getMeditationAssistant().getTimerMode().equals("timed")) { // update end time for timed session + getMeditationAssistant().setTimeToStopMeditate( + timestamp + + getMeditationAssistant() + .getSessionDuration() + ); + } + + Log.d("MeditationAssistant", + "NEW Timestamp: " + + String.valueOf(timestamp) + + " Stop: " + + String.valueOf(getMeditationAssistant() + .getTimeToStopMeditate()) + + " Start: " + + String.valueOf(getMeditationAssistant() + .getTimeStartMeditate()) + ); + handler.removeCallbacks(meditateRunnable); + handler.removeCallbacks(intervalRunnable); + skipDelay = true; + if (am_delay != null && pendingintent_delay != null) { + am_delay.cancel(pendingintent_delay); + } + handler.postDelayed(meditateRunnable, 50); + } else { // Currently in meditation phase + if (!getMeditationAssistant().ispaused) { // In progress, pause the session + am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + am.cancel(pendingintent); + am.cancel(pendingintent_interval); + Log.d("MeditationAssistant", "CANCELLED MAIN WAKEUP AND INTERVAL ALARMS"); + + getMeditationAssistant().pauseSession(); + + handler.removeCallbacks(screenDimRunnable); + handler.removeCallbacks(screenOffRunnable); + WindowManager.LayoutParams params = getWindow().getAttributes(); + params.screenBrightness = -1; + getWindow().setAttributes(params); + + // Always show this notification (add to tutorial?) + //if (getMeditationAssistant().getPrefs().getBoolean("firstpause", true)) { + // getMeditationAssistant().getPrefs().edit().putBoolean("firstpause", false).apply(); + getMeditationAssistant().longToast(getString(R.string.pausedNotification)); + //} + } else { // Paused, un-pause + long pausetime = getMeditationAssistant().unPauseSession(); + + if (getMeditationAssistant().getTimerMode().equals("timed")) { + getMeditationAssistant().setTimeToStopMeditate(getMeditationAssistant().getTimeToStopMeditate() + pausetime); + } else if (getMeditationAssistant().getTimerMode().equals("endat")) { + if (getMeditationAssistant().getTimeToStopMeditate() - pausetime <= 0) { + Intent openAlarmReceiverActivity = new Intent(getApplicationContext(), CompleteActivity.class); + openAlarmReceiverActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + openAlarmReceiverActivity.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + startActivity(openAlarmReceiverActivity); + + return; + } + } + + setIntervalAlarm(); + + if (getMeditationAssistant().getTimeToStopMeditate() != -1 && timestamp < getMeditationAssistant().getTimeToStopMeditate()) { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.SECOND, (int) (getMeditationAssistant() + .getTimeToStopMeditate() - getMeditationAssistant().getTimestamp())); + + Intent intent = new Intent(getApplicationContext(), + MainActivity.class); + intent.putExtra("wakeup", true); + intent.putExtra("fullwakeup", true); + intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + intent.setAction(BROADCAST_ACTION_ALARM); + pendingintent = PendingIntent.getActivity( + getApplicationContext(), ID_END, intent, + PendingIntent.FLAG_CANCEL_CURRENT); + am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + if (Build.VERSION.SDK_INT >= 19) { + am.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), + pendingintent); + } else { + am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), + pendingintent); + } + + Log.d("MeditationAssistant", "Setting MAIN WAKEUP alarm for " + + String.valueOf(cal.getTimeInMillis()) + " (Now: " + + System.currentTimeMillis() + ", in: " + String.valueOf((cal.getTimeInMillis() - System.currentTimeMillis()) / 1000) + ")"); + } + + getMeditationAssistant().ispaused = false; + screenDimOrOff(); + } + } + + return; + } + + getMeditationAssistant().ispaused = false; + getMeditationAssistant().pausetime = 0; + skipDelay = false; + intervals = 0; + + // Context context = getApplicationContext(); + + Log.d("MeditationAssistant", "Timestamp: " + String.valueOf(timestamp)); + Integer secondsTillFinished = 0; + if (getMeditationAssistant().getTimerMode().equals("timed")) { + secondsTillFinished = Integer.parseInt(getMeditationAssistant().getPrefs().getString( + "timerHours", "0")) + * 3600 + + (Integer.parseInt(getMeditationAssistant().getPrefs().getString("timerMinutes", "15")) * 60); + } else if (getMeditationAssistant().getTimerMode().equals("endat")) { + Date now = new Date(); + + Calendar c_now = Calendar.getInstance(); + c_now.setTime(now); + + int end_at_hour = Integer.parseInt(getMeditationAssistant().getPrefs().getString("timerHoursEndAt", "0")); + int end_at_minute = Integer.parseInt(getMeditationAssistant().getPrefs().getString("timerMinutesEndAt", "0")); + + if (end_at_hour > 11) { + end_at_hour -= 12; // convert 24 to 12 hour time + } + + Calendar c_endat = Calendar.getInstance(); + c_endat.setTime(now); + + if (c_now.get(Calendar.HOUR_OF_DAY) >= 12) { // noon or later + Log.d("MeditationAssistant", "End at debug: NOON OR LATER"); + if ((end_at_hour + 12) >= c_now.get(Calendar.HOUR_OF_DAY)) { // later today + Log.d("MeditationAssistant", "End at debug: A LATER TODAY"); + if ((end_at_hour + 12) == c_now.get(Calendar.HOUR_OF_DAY) && end_at_minute <= c_now.get(Calendar.MINUTE)) { // End at is now or earlier + getMeditationAssistant().shortToast(this, getString(R.string.invalidEndAt)); + return; + } + + c_endat.set(Calendar.HOUR_OF_DAY, end_at_hour + 12); + } else { // tomorrow + Log.d("MeditationAssistant", "End at debug: A TOMORROW"); + c_endat.add(Calendar.DATE, 1); + c_endat.set(Calendar.HOUR_OF_DAY, end_at_hour); + } + } else { + Log.d("MeditationAssistant", "End at debug: BEFORE NOON"); + if (end_at_hour >= c_now.get(Calendar.HOUR_OF_DAY)) { // later today (before noon) + Log.d("MeditationAssistant", "End at debug: B LATER TODAY BEFORE NOON"); + if (end_at_hour == c_now.get(Calendar.HOUR_OF_DAY) && end_at_minute <= c_now.get(Calendar.MINUTE)) { // End at is now or earlier + getMeditationAssistant().shortToast(this, getString(R.string.invalidEndAt)); + return; + } + + c_endat.set(Calendar.HOUR_OF_DAY, end_at_hour); + } else { // later today (after noon) + Log.d("MeditationAssistant", "End at debug: B LATER TODAY AFTER NOON"); + c_endat.set(Calendar.HOUR_OF_DAY, end_at_hour + 12); + } + } + c_endat.set(Calendar.MINUTE, end_at_minute); + c_endat.set(Calendar.SECOND, 0); + + Log.d("MeditationAssistant", "NOW HOUROFDAY: " + String.valueOf(c_now.get(Calendar.HOUR_OF_DAY)) + " MINUTE: " + String.valueOf(c_now.get(Calendar.MINUTE))); + Log.d("MeditationAssistant", "END HOUROFDAY: " + String.valueOf(c_endat.get(Calendar.HOUR_OF_DAY)) + " MINUTE: " + String.valueOf(c_endat.get(Calendar.MINUTE))); + Log.d("MeditationAssistant", "-- END AT: " + String.valueOf(c_endat.getTimeInMillis() / 1000) + " NOW: " + String.valueOf(c_now.getTimeInMillis() / 1000)); + + // Add two seconds to account for partial seconds between now and the end at time for pretty durations + secondsTillFinished = (int) ((c_endat.getTimeInMillis() - c_now.getTimeInMillis()) / 1000) + 2; + + if (secondsTillFinished < 60) { + getMeditationAssistant().shortToast(this, getString(R.string.invalidEndAt)); + return; + } + } + + // debug + // secondsTillFinished = 2; + + getMeditationAssistant().setSessionDuration(secondsTillFinished); + + Log.d("MeditationAssistant", "Current delay value: " + getMeditationAssistant().getPrefs().getString("pref_session_delay", "00:15")); + + long delay = Math.max( + getMeditationAssistant().timePreferenceValueToSeconds(getMeditationAssistant().getPrefs().getString("pref_session_delay", "00:15"), "00:15"), 0); + + getMeditationAssistant().setTimeStartMeditate(timestamp + delay); + + if (getMeditationAssistant().getTimerMode().equals("timed")) { + getMeditationAssistant().setTimeToStopMeditate( + timestamp + secondsTillFinished + delay); + } else if (getMeditationAssistant().getTimerMode().equals("endat")) { + if (secondsTillFinished <= delay) { + delay = 0; + } + + getMeditationAssistant().setTimeToStopMeditate( + timestamp + secondsTillFinished); + } else { + getMeditationAssistant().setTimeToStopMeditate(-1); + } + + updateMeditate(true, false); + Log.d("MeditationAssistant", "Starting runnable from startMeditate"); + + Random rand = new Random(); + getMeditationAssistant().shortToast( + getMeditationAssistant().getStartPhrases()[rand.nextInt(getMeditationAssistant().getStartPhrases().length)]); + + meditateRunnable = new Runnable() { + @Override + public void run() { + setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE); + if (getMeditationAssistant().getTimeStartMeditate() == 0) { + return; + } + + if (getMeditationAssistant().getTimeToStopMeditate() != -1) { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.SECOND, (int) (getMeditationAssistant() + .getTimeToStopMeditate() - getMeditationAssistant() + .getTimeStartMeditate())); + + Intent intent = new Intent(getApplicationContext(), + MainActivity.class); + intent.putExtra("wakeup", true); + intent.putExtra("fullwakeup", true); + intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + intent.setAction(BROADCAST_ACTION_ALARM); + pendingintent = PendingIntent.getActivity( + getApplicationContext(), ID_END, intent, + PendingIntent.FLAG_CANCEL_CURRENT); + am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + if (Build.VERSION.SDK_INT >= 19) { + am.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), + pendingintent); + } else { + am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), + pendingintent); + } + + Log.d("MeditationAssistant", "Setting MAIN WAKEUP alarm for " + + String.valueOf(cal.getTimeInMillis()) + " (Now: " + + System.currentTimeMillis() + ", in: " + String.valueOf((cal.getTimeInMillis() - System.currentTimeMillis()) / 1000) + ")"); + } + + if (!skipDelay) { + getMeditationAssistant().vibrateDevice(); + } + + screenDimOrOff(); + + if (!getMeditationAssistant().getPrefs().getString("pref_meditation_sound_start", "").equals( + "none")) { + mMediaPlayer = null; + if (getMeditationAssistant().getPrefs().getString("pref_meditation_sound_start", "") + .equals("custom")) { + String soundpath = getMeditationAssistant().getPrefs().getString( + "pref_meditation_sound_start_custom", ""); + if (!soundpath.equals("")) { + try { + mMediaPlayer = MediaPlayer.create( + getApplicationContext(), + Uri.parse(soundpath)); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else { + mMediaPlayer = MediaPlayer.create( + getApplicationContext(), MeditationSounds + .getMeditationSound(getMeditationAssistant().getPrefs().getString( + "pref_meditation_sound_start", + "")) + ); + } + + if (mMediaPlayer != null) { + mMediaPlayer + .setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + + @Override + public void onCompletion(MediaPlayer mp) { + mp.release(); + WakeLocker.release(); + } + }); + mMediaPlayer + .setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared( + MediaPlayer mp) { + mp.start(); + } + }); + + WakeLocker.acquire(getApplicationContext(), false); + //mMediaPlayer.prepareAsync(); + } + } + + setIntervalAlarm(); + } + }; + + startRunnable(); + + getMeditationAssistant().setNotificationControl(); + + WindowManager.LayoutParams params = getWindow().getAttributes(); + + if (getMeditationAssistant().getPrefs().getString("pref_screencontrol", "dim").equals("on")) { + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + + if (getMeditationAssistant().getPrefs().getBoolean("pref_full_screen", false)) { + getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + + getWindow().setAttributes(params); + + if (delay > 0) { + setVolumeControlStream(AudioManager.STREAM_MUSIC); + + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.SECOND, (int) delay); + + Log.d("MeditationAssistant", "Setting DELAY WAKEUP alarm for " + + String.valueOf(cal.getTimeInMillis()) + " (Now: " + + System.currentTimeMillis() + ", in: " + String.valueOf((cal.getTimeInMillis() - System.currentTimeMillis()) / 1000) + ")"); + + Intent intent_delay = new Intent(getApplicationContext(), + MainActivity.class); + intent_delay.putExtra("wakeup", true); + intent_delay.putExtra("wakeupstart", true); + intent_delay.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + intent_delay.setAction(BROADCAST_ACTION_ALARM); + pendingintent_delay = PendingIntent.getActivity( + getApplicationContext(), ID_DELAY, intent_delay, + PendingIntent.FLAG_CANCEL_CURRENT); + am_delay = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + if (Build.VERSION.SDK_INT >= 19) { + am_delay.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), + pendingintent_delay); + } else { + am_delay.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), + pendingintent_delay); + } + } else { + handler.postDelayed(meditateRunnable, 50); + } + } + + private void setIntervalAlarm() { + long interval = Math.max( + getMeditationAssistant().timePreferenceValueToSeconds(getMeditationAssistant().getPrefs().getString("pref_session_interval", "00:00"), "00:00"), 0); + Log.d("MeditationAssistant", "Interval is set to " + String.valueOf(interval) + " seconds"); + + if (interval > 0) { + Log.d("MeditationAssistant", "Reached postDelayed for interval runnable"); + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.SECOND, (int) interval); + + Log.d("MeditationAssistant", "Setting INITIAL INTERVAL WAKEUP alarm for " + + String.valueOf(cal.getTimeInMillis()) + " (Now: " + + System.currentTimeMillis() + ", in: " + String.valueOf((cal.getTimeInMillis() - System.currentTimeMillis()) / 1000) + ")"); + + Intent intent_interval = new Intent( + getApplicationContext(), MainActivity.class); + intent_interval.putExtra("wakeup", true); + intent_interval.putExtra("wakeupinterval", true); + intent_interval.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + intent_interval.setAction(BROADCAST_ACTION_ALARM); + pendingintent_interval = PendingIntent.getActivity( + getApplicationContext(), ID_INTERVAL, + intent_interval, PendingIntent.FLAG_CANCEL_CURRENT); + am_interval = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + if (Build.VERSION.SDK_INT >= 19) { + Log.d("MeditationAssistant", "Using setExact() for alarm"); + am_interval.setExact(AlarmManager.RTC_WAKEUP, + cal.getTimeInMillis(), pendingintent_interval); + } else { + Log.d("MeditationAssistant", "Using set() for alarm"); + am_interval.set(AlarmManager.RTC_WAKEUP, + cal.getTimeInMillis(), pendingintent_interval); + } + } + } + + private void screenDimOrOff() { + if (getMeditationAssistant().getPrefs().getString("pref_screencontrol", "dim").equals("ondim") || getMeditationAssistant().getPrefs().getString("pref_screencontrol", "dim").equals("dim")) { + screenDimRunnable = new Runnable() { + @Override + public void run() { + if (getMeditationAssistant().getTimeStartMeditate() == 0) { + Log.d("MeditationAssistant", + "Exiting runnable for dimming screen"); + return; + } + + WindowManager.LayoutParams windowParams = getWindow() + .getAttributes(); + windowParams.screenBrightness = 0.01f; + getWindow().setAttributes(windowParams); + + if (getMeditationAssistant().getPrefs().getString("pref_screencontrol", "dim").equals("ondim")) { + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } else { + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + }; + + handler.postDelayed(screenDimRunnable, 250); + } else if (getMeditationAssistant().getPrefs().getString("pref_screencontrol", "dim").equals("off")) { + WindowManager.LayoutParams windowParams = getWindow() + .getAttributes(); + windowParams.screenBrightness = 0.0f; + getWindow().setAttributes(windowParams); + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + screenOffRunnable = new Runnable() { + @Override + public void run() { + if (getMeditationAssistant().getTimeStartMeditate() == 0) { + Log.d("MeditationAssistant", + "Exiting runnable for turning screen off"); + return; + } + + WindowManager.LayoutParams windowParams = getWindow() + .getAttributes(); + windowParams.screenBrightness = -1; + getWindow().setAttributes(windowParams); + } + }; + + handler.postDelayed(screenOffRunnable, 5000); + } + } + + public boolean longPressMeditate(View view) { + long timestamp = System.currentTimeMillis() / 1000; + Log.d("MeditationAssistant", "stopMedidate"); + getMeditationAssistant().unPauseSession(); + + setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE); + + if (am != null && pendingintent != null) { + am.cancel(pendingintent); + Log.d("MeditationAssistant", "Cancelled main wake alarm"); + } + if (am_delay != null && pendingintent_delay != null) { + am_delay.cancel(pendingintent_delay); + Log.d("MeditationAssistant", "Cancelled delay alarm"); + } + if (am_interval != null && pendingintent_interval != null) { + am_interval.cancel(pendingintent_interval); + Log.d("MeditationAssistant", "Cancelled interval alarm"); + } + + if (getMeditationAssistant().getTimeStartMeditate() != 0) { + if (view != null + && timestamp + - getMeditationAssistant().getTimeStartMeditate() > 0) { + Intent openAlarmReceiverActivity = new Intent( + getApplicationContext(), CompleteActivity.class); + openAlarmReceiverActivity.putExtra("manual", true); + openAlarmReceiverActivity + .addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + startActivity(openAlarmReceiverActivity); + } else { + // Reset timestamps for current session + getMeditationAssistant().setTimeStartMeditate(0); + getMeditationAssistant().setTimeToStopMeditate(0); + updateMeditate(false, false); + } + + handler.removeCallbacks(meditateRunnable); + handler.removeCallbacks(intervalRunnable); + handler.removeCallbacks(screenDimRunnable); + handler.removeCallbacks(screenOffRunnable); + getMeditationAssistant().setRunnableStopped(true); + return true; + } + + return false; + } + + public void onTimerModeSelected(View view) { + EditText editDuration = (EditText) findViewById(R.id.editDuration); + TimePicker timepickerDuration = (TimePicker) findViewById(R.id.timepickerDuration); + RelativeLayout.LayoutParams editDurationLayoutParams = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + android.view.ViewGroup.LayoutParams.WRAP_CONTENT); + //editDurationLayoutParams.gravity = Gravity.CENTER; + + String newTimerMode = "timed"; + if (view.getId() == R.id.radMainEndAt || view.getId() == R.id.layMainEndAt) { + newTimerMode = "endat"; + } else if (view.getId() == R.id.radMainUntimed || view.getId() == R.id.layMainUntimed) { + newTimerMode = "untimed"; + } + + getMeditationAssistant().setTimerMode(newTimerMode); + //updateEditDuration(); should the duration be reset when changing modes? + if (newTimerMode.equals("untimed")) { + if (usetimepicker) { + timepickerDuration.setEnabled(false); + } else { + editDurationLayoutParams.setMargins(0, 0, 0, 0); + editDuration.setText(getString(R.string.ignore_om)); + } + } else { + if (usetimepicker) { + timepickerDuration.setEnabled(true); + } else { + editDurationLayoutParams.setMargins(0, -23, 0, -11); + + if (editDuration.getText().toString().equals(getString(R.string.ignore_om))) { + if (newTimerMode.equals("endat")) { // Don't leave om character in edit text + editDuration.setText(getMeditationAssistant().getPrefs().getString("timerHoursEndAt", "0") + + ":" + + String.format("%02d", Integer.valueOf(getMeditationAssistant().getPrefs() + .getString("timerMinutesEndAt", "0")))); + } else { // timed + editDuration.setText(getMeditationAssistant().getPrefs().getString("timerHours", "0") + + ":" + + String.format("%02d", Integer.valueOf(getMeditationAssistant().getPrefs() + .getString("timerMinutes", "15")))); + } + editDuration.requestFocus(); + InputMethodManager imm = (InputMethodManager) this + .getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(editDuration, + InputMethodManager.SHOW_IMPLICIT); + } + } + } + + updateVisibleViews(false); + editDuration.setLayoutParams(editDurationLayoutParams); + } + + @Override + protected void onPause() { + if (getMeditationAssistant().getTimeStartMeditate() > 0 + && getMeditationAssistant().getTimeToStopMeditate() != 0) { + getMeditationAssistant().showNotification(); + } + + if (av != null) { + av.pause(); + } + + getMeditationAssistant().setScreenOff(true); + getMeditationAssistant().getPrefs().unregisterOnSharedPreferenceChangeListener(sharedPrefslistener); + + super.onPause(); + } + + @Override + protected void onResume() { + getMeditationAssistant().hideNotification(); + + if (getIntent().getStringExtra("action") != null) { + Log.d("MeditationAssistant", "Intent for MainActivity: " + + getIntent().getStringExtra("action")); + } + getMeditationAssistant().setScreenOff(false); + WindowManager.LayoutParams params = getWindow().getAttributes(); + params.screenBrightness = -1; + getWindow().setAttributes(params); + + getMeditationAssistant().getPrefs().registerOnSharedPreferenceChangeListener(sharedPrefslistener); + if (lastKey != null && !lastKey.equals("") + && !getMeditationAssistant().getPrefs().getString("key", "").equals(lastKey)) { + Log.d("MeditationAssistant", "onResume detected key change"); + } + + usetimepicker = getMeditationAssistant().getPrefs().getBoolean("pref_usetimepicker", false); + + updateTextSize(); + updateTexts(); + startRunnable(); + + if (getMeditationAssistant().asktorate) { + getMeditationAssistant().asktorate = false; + + if (!getMeditationAssistant().getPrefs().getBoolean("askedtorate", false) && (getMeditationAssistant().getIsBB() || MeditationAssistant.getMarketName().equals("google") || MeditationAssistant.getMarketName().equals("amazon"))) { + getMeditationAssistant().getPrefs().edit().putBoolean("askedtorate", true).apply(); + + DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case DialogInterface.BUTTON_POSITIVE: + getMeditationAssistant().askToRateApp(); + + break; + + case DialogInterface.BUTTON_NEGATIVE: + break; + } + } + }; + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setIcon( + getResources() + .getDrawable( + getTheme() + .obtainStyledAttributes( + getMeditationAssistant() + .getMATheme(), + new int[]{R.attr.actionIconNotImportant} + ) + .getResourceId(0, 0) + ) + ) + .setTitle(getString(R.string.rateMeditationAssistant)) + .setMessage( + getString(R.string.rateMeditationAssistantText)) + .setPositiveButton(getString(R.string.yes), + dialogClickListener) + .setNegativeButton(getString(R.string.no), + dialogClickListener).show(); + } + } + + showNextTutorial(); + + super.onResume(); + + if (av != null) { + av.resume(); + } + } + + @Override + public void onStart() { + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStart(this); + } + if (getMeditationAssistant().googleClient != null) { + getMeditationAssistant().googleClient.connect(); + } + + super.onStart(); + } + + @Override + protected void onStop() { + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStop(this); + } + if (getMeditationAssistant().googleClient != null && getMeditationAssistant().googleClient.isConnected()) { + getMeditationAssistant().googleClient.disconnect(); + } + + super.onStop(); + } + + @Override + public void onDestroy() { + if (!getMeditationAssistant().getPrefs().getBoolean("pref_autosignin", false) && !getMeditationAssistant().getPrefs().getString("key", "").equals("")) { + getMeditationAssistant().getPrefs().edit().putString("key", "").apply(); + } + + if (av != null) { + av.destroy(); + } + + super.onDestroy(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if ((keyCode == KeyEvent.KEYCODE_BACK) && getMeditationAssistant().getEditingDuration()) { + cancelSetDuration(null); + return true; + } + + return super.onKeyDown(keyCode, event); + } + + public void updateTexts() { + /* Log.d("MeditationAssistant", "Updating texts..."); */ + TextView txtMainStatus = (TextView) findViewById(R.id.txtMainStatus); + Button btnMeditationStreak = (Button) findViewById(R.id.btnMeditationStreak); + Resources res = getResources(); + + if (getMeditationAssistant().getTimeToStopMeditate() < 1) { + resetScreenBrightness(); + getMeditationAssistant().unsetNotificationControl(); + + WindowManager.LayoutParams params = getWindow().getAttributes(); + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + getWindow().setAttributes(params); + } + + if (!getMeditationAssistant().getPrefs().getBoolean("pref_showstreak", true) + || getMeditationAssistant().getMeditationStreak() == null + || getMeditationAssistant().getMeditationStreak() < 1) { + + if (getMeditationAssistant().getMediNET().status.equals("success")) { + btnMeditationStreak + .setText(getString(R.string.signOutOfMediNET)); + } else { + + btnMeditationStreak.setText(getString(R.string.signInToMediNET)); + } + } else { + btnMeditationStreak.setText(res.getQuantityString( + R.plurals.daysOfMeditation, getMeditationAssistant() + .getMeditationStreak(), + getMeditationAssistant().getMeditationStreak() + )); + } + + if (getMeditationAssistant().getMediNET().status != null) { + Log.d("MeditationAssistant", "Updating texts with status " + + getMeditationAssistant().getMediNET().status); + if (getMeditationAssistant().getMediNET().status + .equals("connecting")) { + txtMainStatus.setText(getString(R.string.mediNETConnecting)); + } else if (getMeditationAssistant().getMediNET().status + .equals("success")) { + txtMainStatus.setText(getString(R.string.mediNETConnected)); + } else if (getMeditationAssistant().getMediNET().status + .equals("connectingasf")) { + txtMainStatus.setText(getString(R.string.mediNETConnecting)); + } else { + txtMainStatus.setText(""); + } + } + + btnMeditationStreak.postInvalidate(); + txtMainStatus.postInvalidate(); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + + if (getIntent() != null) { + Log.d("MeditationAssistant", "Intent for MainActivity: " + + getIntent().toString()); + if (getIntent().getAction() != null) { + if (getIntent().getAction().equals("widgetclick")) { + if (!getMeditationAssistant().getMediNET().status + .equals("success")) { + getMeditationAssistant().getMediNET().connect(); + } + } else if (getIntent().getAction().equals("notificationPause")) { + if (getMeditationAssistant().getTimeStartMeditate() > 0 && !getMeditationAssistant().ispaused) { + updateMeditate(false, false); + pressMeditate(new View(getApplicationContext())); + } + } else if (getIntent().getAction().equals("notificationEnd")) { + if (getMeditationAssistant().getTimeStartMeditate() > 0) { + longPressMeditate(new View(getApplicationContext())); + } + } + } + + if (intent.getBooleanExtra("wakeup", false)) { + Boolean fullWakeUp = intent.getBooleanExtra("fullwakeup", false); + Boolean wakeUpStart = intent.getBooleanExtra("wakeupstart", false); + Boolean wakeUpInterval = intent.getBooleanExtra("wakeupinterval", false); + Log.d("MeditationAssistant", "ALARM RECEIVER INTEGRATED: Received broadcast - Full: " + (fullWakeUp ? "Full" : "Partial") + " - Start/interval: " + (wakeUpStart ? "Start" : (wakeUpInterval ? "Interval" : "Neither"))); + + WakeLocker.acquire(getApplicationContext(), fullWakeUp); + + handler.removeCallbacks(clearWakeLock); + handler.postDelayed(clearWakeLock, 7000); + + if (intent.getBooleanExtra("wakeupstart", false)) { + handler.postDelayed(meditateRunnable, 50); + } else if (intent.getBooleanExtra("wakeupinterval", false)) { + if (getMeditationAssistant().getTimeStartMeditate() > 0) { + if (getMeditationAssistant().getTimeToStopMeditate() != 0 + && getMeditationAssistant().getTimeToStopMeditate() + - (System.currentTimeMillis() / 1000) < 30 && !getMeditationAssistant().getPrefs().getBoolean("pref_softfinish", false)) { + Log.d("MeditationAssistant", "Interval - final 30 seconds, not firing"); + return; // No interval sounds during the final 30 seconds + } + + String interval_limit = getMeditationAssistant().getPrefs().getString("pref_interval_count", ""); + if (interval_limit.equals("")) { + interval_limit = "0"; + } + if (Integer.valueOf(interval_limit) > 0 && intervals >= Integer.valueOf(interval_limit)) { + Log.d("MeditationAssistant", "Interval - reached interval limit, not firing A"); + return; // No further intervals + } + + if (!getMeditationAssistant().getPrefs().getString("pref_meditation_sound_interval", "") + .equals("none") || getMeditationAssistant().vibrationEnabled()) { + if (getMeditationAssistant().getTimeToStopMeditate() == -1 + || ((System.currentTimeMillis() / 1000) > getMeditationAssistant().getTimeToStopMeditate() && (System.currentTimeMillis() / 1000) - getMeditationAssistant().getTimeToStopMeditate() >= 5) || getMeditationAssistant().getTimeToStopMeditate() + - (System.currentTimeMillis() / 1000) >= 5) { // Not within last 5 seconds + if (!getMeditationAssistant().getPrefs().getString("pref_meditation_sound_interval", "") + .equals("none")) { + stopMediaPlayer(); + mMediaPlayer = null; + if (getMeditationAssistant().getPrefs().getString("pref_meditation_sound_interval", "") + .equals("custom")) { + String soundpath = getMeditationAssistant().getPrefs().getString( + "pref_meditation_sound_interval_custom", ""); + if (!soundpath.equals("")) { + try { + mMediaPlayer = MediaPlayer.create( + getApplicationContext(), + Uri.parse(soundpath)); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else { + mMediaPlayer = MediaPlayer + .create(getApplicationContext(), + MeditationSounds.getMeditationSound(getMeditationAssistant().getPrefs().getString( + "pref_meditation_sound_interval", + "")) + ); + } + + if (mMediaPlayer != null) { + mMediaPlayer + .setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + + @Override + public void onCompletion(MediaPlayer mp) { + mp.release(); + WakeLocker.release(); + } + }); + + WakeLocker.acquire(getApplicationContext(), false); + mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + + mMediaPlayer + .setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared( + MediaPlayer mp) { + mp.start(); + } + }); + //mMediaPlayer.prepareAsync(); + } + } + + getMeditationAssistant().vibrateDevice(); + } + + long interval = Math.max( + getMeditationAssistant().timePreferenceValueToSeconds(getMeditationAssistant().getPrefs().getString("pref_session_interval", "00:00"), "00:00"), 0); + Log.d("MeditationAssistant", "Interval is set to " + String.valueOf(interval) + " seconds"); + + if (interval > 0 && (getMeditationAssistant().getTimeToStopMeditate() == -1 + || ((getMeditationAssistant().getTimeToStopMeditate() + - (System.currentTimeMillis() / 1000)) > (interval + 30)) || getMeditationAssistant().getPrefs().getBoolean("pref_softfinish", false))) { + intervals++; + + if (Integer.valueOf(interval_limit) > 0 && intervals >= Integer.valueOf(interval_limit)) { + Log.d("MeditationAssistant", "Interval - reached interval limit, not firing B"); + return; // No further intervals + } + + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.SECOND, (int) interval); + + Log.d("MeditationAssistant", "Setting INTERVAL WAKEUP alarm for " + + String.valueOf(cal.getTimeInMillis()) + " (Now: " + + System.currentTimeMillis() + ", in: " + String.valueOf((cal.getTimeInMillis() - System.currentTimeMillis()) / 1000) + ") - TOTAL TIME LEFT: " + String.valueOf(getMeditationAssistant().getTimeToStopMeditate() + - (System.currentTimeMillis() / 1000))); + + Intent intent_interval = new Intent( + getApplicationContext(), MainActivity.class); + intent_interval.putExtra("wakeup", true); + intent_interval.putExtra("wakeupinterval", true); + intent_interval.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + intent_interval.setAction(BROADCAST_ACTION_ALARM); + pendingintent_interval = PendingIntent.getActivity( + getApplicationContext(), ID_INTERVAL, + intent_interval, PendingIntent.FLAG_CANCEL_CURRENT); + am_interval = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + if (Build.VERSION.SDK_INT >= 19) { + am_interval.setExact(AlarmManager.RTC_WAKEUP, + cal.getTimeInMillis(), pendingintent_interval); + } else { + am_interval.set(AlarmManager.RTC_WAKEUP, + cal.getTimeInMillis(), pendingintent_interval); + } + } else { + Log.d("MeditationAssistant", "Skipping INTERVAL WAKEUP alarm"); + } + } + } + } + + if (fullWakeUp) { + if (getMeditationAssistant().getPrefs().getBoolean("pref_softfinish", false)) { + if (!getMeditationAssistant().getPrefs().getString("pref_meditation_sound_finish", "") + .equals("none")) { + stopMediaPlayer(); + mMediaPlayer = null; + if (getMeditationAssistant().getPrefs().getString("pref_meditation_sound_finish", "") + .equals("custom")) { + String soundpath = getMeditationAssistant().getPrefs().getString( + "pref_meditation_sound_finish_custom", ""); + if (!soundpath.equals("")) { + try { + mMediaPlayer = MediaPlayer.create( + getApplicationContext(), + Uri.parse(soundpath)); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else { + mMediaPlayer = MediaPlayer + .create(getApplicationContext(), + MeditationSounds.getMeditationSound(getMeditationAssistant().getPrefs().getString( + "pref_meditation_sound_finish", + "")) + ); + } + + if (mMediaPlayer != null) { + mMediaPlayer + .setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + + @Override + public void onCompletion(MediaPlayer mp) { + mp.release(); + WakeLocker.release(); + } + }); + + WakeLocker.acquire(getApplicationContext(), false); + mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + mMediaPlayer + .setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared( + MediaPlayer mp) { + mp.start(); + } + }); + //mMediaPlayer.prepareAsync(); + } + } + + getMeditationAssistant().vibrateDevice(); + } else { + Intent openAlarmReceiverActivity = new Intent(getApplicationContext(), CompleteActivity.class); + openAlarmReceiverActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + openAlarmReceiverActivity.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); + startActivity(openAlarmReceiverActivity); + } + } + } + } + } + + public void updateTextsAsync() { + Log.d("MeditationAssistant", "Update texts async: begin"); + runOnUiThread(new Runnable() { + + @Override + public void run() { + Log.d("MeditationAssistant", "Update texts async: run"); + updateTexts(); + } + }); + } + + public void updateMeditate(boolean setDisabled, boolean complete) { + Button btnMeditate = (Button) findViewById(R.id.btnMeditate); + if (getMeditationAssistant().ispaused) { + btnMeditate.setText(getString(R.string.resumeOrEnd)); + return; + } + + //Log.d("MeditationAssistant", "updateMeditate: " + String.valueOf(getMeditationAssistant() .getTimeToStopMeditate())); + TextView txtTimer = (TextView) findViewById(R.id.txtTimer); + TextView txtDurationSeconds = (TextView) findViewById(R.id.txtDurationSeconds); + ViewSwitcher switchTimer = (ViewSwitcher) findViewById(R.id.switchTimer); + EditText editDuration = (EditText) findViewById(R.id.editDuration); + + FrameLayout.LayoutParams txtTimerLayoutParams = new FrameLayout.LayoutParams( + android.view.ViewGroup.LayoutParams.MATCH_PARENT, + android.view.ViewGroup.LayoutParams.WRAP_CONTENT); + txtTimerLayoutParams.setMargins(0, -23, 0, -11); + txtTimerLayoutParams.gravity = Gravity.CENTER; + + RelativeLayout.LayoutParams editDurationLayoutParams = new RelativeLayout.LayoutParams( + android.view.ViewGroup.LayoutParams.MATCH_PARENT, + android.view.ViewGroup.LayoutParams.WRAP_CONTENT); + editDurationLayoutParams.setMargins(0, -23, 0, -11); + //editDurationLayoutParams.gravity = Gravity.CENTER; not supported with RelativeLayout? + + long duration = 0; + Long timestamp = System.currentTimeMillis() / 1000; + + new Throwable().getStackTrace(); + if (getMeditationAssistant().getTimeToStopMeditate() == -1 + || getMeditationAssistant().getTimeToStopMeditate() > 0) { + if (getMeditationAssistant().getTimeToStopMeditate() != -1) { + if (getMeditationAssistant().getPrefs().getBoolean("pref_softfinish", false) && timestamp > getMeditationAssistant().getTimeToStopMeditate()) { + duration = timestamp - getMeditationAssistant() + .getTimeStartMeditate(); + } else { + duration = Math.min(getMeditationAssistant() + .getTimeToStopMeditate() - timestamp, + getMeditationAssistant().getTimeToStopMeditate() + - getMeditationAssistant() + .getTimeStartMeditate() + ); + } + } else { + duration = timestamp + - getMeditationAssistant().getTimeStartMeditate(); + } + + switchTimer.setClickable(false); + } else { + resetScreenBrightness(); + getMeditationAssistant().unsetNotificationControl(); + + switchTimer.setClickable(true); + } + + if (complete) { + Log.d("MeditationAssistant", "Session complete"); + } else if (getMeditationAssistant().getTimeToStopMeditate() == -1 || (getMeditationAssistant().getTimeToStopMeditate() > 0 && timestamp > getMeditationAssistant().getTimeToStopMeditate() && getMeditationAssistant().getPrefs().getBoolean("pref_softfinish", false))) { + duration -= getMeditationAssistant().pausetime; + + if (timestamp >= getMeditationAssistant().getTimeStartMeditate()) { + int hoursSince = (int) duration / 3600; + int minutesSince = ((int) duration % 3600) / 60; + txtTimer.setText(String.valueOf(hoursSince) + ":" + + String.format("%02d", minutesSince)); + } else { + txtTimer.setText(getString(R.string.ignore_om)); + } + } else if (duration > 0) { + int hoursLeft = (int) duration / 3600; + int minutesLeft = ((int) duration % 3600) / 60; + if (minutesLeft == 60) { + hoursLeft += 1; + minutesLeft = 0; + } + + txtTimer.setText(String.valueOf(hoursLeft) + ":" + + String.format("%02d", minutesLeft)); + } + + if (getMeditationAssistant().getTimeToStopMeditate() == -1 + || duration > 0 || (getMeditationAssistant().getTimeToStopMeditate() > 0 && getMeditationAssistant().getPrefs().getBoolean("pref_softfinish", false))) { + long delayRemaining = getMeditationAssistant() + .getTimeStartMeditate() - timestamp; + + findViewById(R.id.btnMeditate).setEnabled(true); + + if (delayRemaining > 0) { + btnMeditate.setText(getString(R.string.tapToSkip)); + getMeditationAssistant().setAlphaCompat(txtDurationSeconds, 0.75f); + + if (getMeditationAssistant().getTimerMode().equals("untimed")) { + txtTimerLayoutParams.setMargins(0, 0, 0, 0); + editDurationLayoutParams.setMargins(0, 0, 0, 0); + } + } else { + setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE); + + btnMeditate.setText(getString(R.string.pauseOrEnd)); + getMeditationAssistant().setAlphaCompat(txtDurationSeconds, 1f); + } + + if (getMeditationAssistant().getPrefs().getBoolean("pref_display_seconds", true)) { + if (getMeditationAssistant().getTimeStartMeditate() == timestamp + || getMeditationAssistant().getTimeToStopMeditate() == timestamp) { + txtDurationSeconds.setText(getString(R.string.ignore_omkara)); + } else if (getMeditationAssistant().getTimeStartMeditate() < timestamp) { + txtDurationSeconds.setText(String.valueOf(duration % 60)); + } else { + if (delayRemaining >= 60) { + txtDurationSeconds.setText(String.format("%d", + (int) delayRemaining / 60) + + ":" + + String.format("%02d", delayRemaining % 60)); + } else { + txtDurationSeconds.setText(String + .valueOf(delayRemaining % 60)); + } + } + } + } else { + txtDurationSeconds.setText(""); + findViewById(R.id.btnMeditate).setEnabled(true); + btnMeditate.setText(getString(R.string.meditate)); + getMeditationAssistant().setAlphaCompat(txtDurationSeconds, 1.0f); + + if (getMeditationAssistant().getTimerMode().equals("timed")) { + txtTimerLayoutParams.setMargins(0, -23, 0, -11); + editDurationLayoutParams.setMargins(0, -23, 0, -11); + txtTimer.setText(getMeditationAssistant().getPrefs().getString("timerHours", "0") + + ":" + + String.format("%02d", Integer.valueOf(getMeditationAssistant().getPrefs().getString("timerMinutes", "15")))); + } else if (getMeditationAssistant().getTimerMode().equals("endat")) { + txtTimerLayoutParams.setMargins(0, -23, 0, -11); + editDurationLayoutParams.setMargins(0, -23, 0, -11); + txtTimer.setText(getMeditationAssistant().getPrefs().getString("timerHoursEndAt", "0") + + ":" + + String.format("%02d", Integer.valueOf(getMeditationAssistant().getPrefs().getString("timerMinutesEndAt", "0")))); + txtDurationSeconds.setText(getString(R.string.endAt).toLowerCase()); + } else { + txtTimerLayoutParams.setMargins(0, 0, 0, 0); + editDurationLayoutParams.setMargins(0, 0, 0, 0); + txtTimer.setText(getString(R.string.ignore_om)); + } + } + + if (getMeditationAssistant().getTimeStartMeditate() > timestamp) { + if (!txtDurationSeconds.getText().toString().equals("")) { + getMeditationAssistant().setDurationFormatted( + txtDurationSeconds.getText().toString()); + } + } else if (getMeditationAssistant().getTimeStartMeditate() > 0) { + if (txtDurationSeconds.getText().toString().equals("")) { + getMeditationAssistant().setDurationFormatted( + txtTimer.getText().toString()); + } else { + String secondsFormatted = txtDurationSeconds.getText() + .toString(); + if (secondsFormatted.length() == 1 + && String.valueOf(Integer.valueOf(secondsFormatted)) + .equals(secondsFormatted)) { + secondsFormatted = "0" + secondsFormatted; + } + + getMeditationAssistant().setDurationFormatted( + txtTimer.getText().toString() + ":" + secondsFormatted); + } + } + + //Log.d("MeditationAssistant", "DURATION SECONDS: " + String.valueOf(getMeditationAssistant().getEditingDuration())); + + if (getMeditationAssistant().getEditingDuration()) { + getMeditationAssistant().setAlphaCompat(txtDurationSeconds, 0f); + } else { + getMeditationAssistant().setAlphaCompat(txtDurationSeconds, 1f); + } + + txtTimer.setLayoutParams(txtTimerLayoutParams); + editDuration.setLayoutParams(editDurationLayoutParams); + + if (setDisabled) { + btnMeditate.setText(getString(R.string.meditate)); + findViewById(R.id.btnMeditate).setEnabled(false); + } + } + + public void startRunnable() { + if (getMeditationAssistant().getRunnableStopped()) { + Log.d("MeditationAssistant", "Starting runnable"); + Runnable runnable = new Runnable() { + @Override + public void run() { + handler.removeCallbacks(this); + boolean sessionEnding = false; + + if (getMeditationAssistant().getScreenOff()) { + getMeditationAssistant().setRunnableStopped(true); + Log.d("MeditationAssistant", + "Screen off, stopping runnable..."); + } + + if (getMeditationAssistant().pendingNotificationAction + .equals("exit")) { + getMeditationAssistant().pendingNotificationAction = ""; + + if (getMeditationAssistant().getTimeStartMeditate() > 0) { + longPressMeditate(null); + } + finish(); + return; + } else if (getMeditationAssistant().pendingNotificationAction + .equals("end")) { + getMeditationAssistant().pendingNotificationAction = ""; + sessionEnding = true; + + if (getMeditationAssistant().getTimeStartMeditate() > 0) { + longPressMeditate(new View(getApplicationContext())); + } + } + + if (sessionEnding) { + getMeditationAssistant().setRunnableStopped(true); + } else if (getMeditationAssistant().getTimeToStopMeditate() == -1 + || getMeditationAssistant().getTimeToStopMeditate() > (System + .currentTimeMillis() / 1000) || (getMeditationAssistant().getTimeToStopMeditate() != 0 && getMeditationAssistant().getPrefs().getBoolean("pref_softfinish", false))) { + updateMeditate(false, false); + if (!getMeditationAssistant().getScreenOff()) { + handler.postDelayed(this, 250); + } + } else { + Log.d("MeditationAssistant", + "Stopping - start:" + + String.valueOf(getMeditationAssistant() + .getTimeStartMeditate()) + + " stop:" + + String.valueOf(getMeditationAssistant() + .getTimeToStopMeditate()) + ); + + getMeditationAssistant().setRunnableStopped(true); + if (getMeditationAssistant().getTimeToStopMeditate() != 0) { + getMeditationAssistant().setTimeToStopMeditate(0); // Don't trigger the last_reminder change unless necessary + } + updateMeditate(false, (getMeditationAssistant() + .getTimeStartMeditate() > 0)); + } + } + }; + getMeditationAssistant().setRunnableStopped(false); + handler.postDelayed(runnable, 100); + } else { + Log.d("MeditationAssistant", + "Not starting runnable. Stopped flag is not set."); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == MeditationAssistant.REQUEST_FIT) { + getMeditationAssistant().googleAPIAuthInProgress = false; + if (resultCode == RESULT_OK) { + // Make sure the app is not already connected or attempting to connect + if (!getMeditationAssistant().googleClient.isConnecting() && !getMeditationAssistant().googleClient.isConnected()) { + getMeditationAssistant().googleClient.connect(); + + getMeditationAssistant().sendFitData(); + } + } + } + } + + public void pressCommunity(View view) { + if (sv != null && sv.isShown()) { + try { + sv.hide(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + getMeditationAssistant().getMediNET().browseTo(this, "community"); + } + + public void pressMediNET(View view) { + Log.d("MeditationAssistant", "Open medinet: " + getMeditationAssistant().getMediNETKey()); + + if (sv != null && sv.isShown()) { + try { + sv.hide(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (!getMeditationAssistant().getMediNETKey().equals("")) { + if (!getMeditationAssistant().getMediNET().status.equals("success")) { + getMeditationAssistant().getMediNET().connect(); + } else { + DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case DialogInterface.BUTTON_POSITIVE: + getMeditationAssistant().getMediNET().signOut(); + break; + + case DialogInterface.BUTTON_NEGATIVE: + break; + } + } + }; + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setIcon( + getResources().getDrawable( + getTheme().obtainStyledAttributes( + getMeditationAssistant().getMATheme(), + new int[]{R.attr.actionIconSignOut}) + .getResourceId(0, 0) + ) + ) + .setTitle( + getString(R.string.signOutOfMediNETConfirmTitle)) + .setMessage( + String.format( + getString(R.string.signOutOfMediNETConfirm), + getMeditationAssistant() + .getMediNETProvider() + ) + ) + .setPositiveButton(getString(R.string.signOut), + dialogClickListener) + .setNegativeButton(getString(R.string.cancel), + dialogClickListener).show(); + } + } else { + getMeditationAssistant().getMediNET().askToSignIn(); + } + } + + public void stopMediaPlayer() { + if (mMediaPlayer != null) { + mMediaPlayer.release(); + } + } + + public void resetScreenBrightness() { + WindowManager.LayoutParams windowParams = getWindow() + .getAttributes(); + windowParams.screenBrightness = -1; + getWindow().setAttributes(windowParams); + } + + public MeditationAssistant getMeditationAssistant() { + if (ma == null) { + ma = (MeditationAssistant) this.getApplication(); + } + return ma; + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (sv != null && sv.isShown()) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + } + + @Override + public void onShowcaseViewHide(ShowcaseView showcaseView) { + if (!finishedTutorial) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + } + sv = null; + } + + @Override + public void onShowcaseViewDidHide(ShowcaseView showcaseView) { + sv = null; + } + + @Override + public void onShowcaseViewShow(ShowcaseView showcaseView) { + + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MediNET.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MediNET.java new file mode 100644 index 0000000..c5e8382 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MediNET.java @@ -0,0 +1,417 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.Intent; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Handler; +import android.support.v4.app.FragmentActivity; +import android.util.Log; +import android.view.View; +import android.widget.ImageButton; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +/** + * Created by root on 11/2/13. + */ +public class MediNET { + public static Integer version = 5; + public String status = "disconnected"; + public String result = ""; + public MainActivity activity; + public MeditationSession session = new MeditationSession(); + public String provider = ""; + public ArrayList result_sessions = null; + public String announcement = ""; + private Boolean debug = false; + private MeditationAssistant ma = null; + private MediNETTask task = null; + private Handler handler = new Handler(); + private Runnable runnable; + private Runnable runnable2; + private Boolean runnable_finished = true; + private AlertDialog alertDialog = null; + private String browsetopage = ""; + + public MediNET(MainActivity _activity) { + activity = _activity; + runnable = new Runnable() { + @Override + public void run() { + handler.removeCallbacks(this); + getMeditationAssistant().updateWidgets(); + runnable_finished = true; + } + }; + runnable2 = new Runnable() { + @Override + public void run() { + handler.removeCallbacks(this); + Log.d("MeditationAssistant", "Delayed update() running..."); + getMeditationAssistant().getMediNET().updated(); + } + }; + } + + public static String durationToTimerString(long duration, boolean countDown) { + int hours = (int) duration / 3600; + int minutes = ((int) duration % 3600) / 60; + if (countDown) { + minutes += 1; + } + + return String.valueOf(hours) + ":" + String.format("%02d", minutes); + } + + public void askToSignIn() { + /*if (activity == null || activity.stopped) { + Log.d("MeditationAssistant", + "MainActivity null or stopped, restarting... Stopped: " + + activity.stopped.toString());*/ + if (activity == null) { + Intent openActivity = new Intent(getMeditationAssistant() + .getApplicationContext(), MainActivity.class); + openActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + openActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + + handler.postDelayed(new Runnable() { + + @Override + public void run() { + Log.d("MeditationAssistant", + "Open MainActivity runnable is now running..."); + askToSignIn(); + } + }, 400); + + getMeditationAssistant().getApplicationContext().startActivity( + openActivity); + return; + } + + activity.runOnUiThread(new Runnable() { + + @Override + public void run() { + if (activity == null) { + Log.d("MeditationAssistant", + "askToSignIn activity is null, returning..."); + return; + } + getMeditationAssistant().showSignInDialog(activity); + } + }); + } + + public void browseTo(MainActivity act, String page) { + activity = act; + browsetopage = page; + + if (status.equals("success") || page.equals("community")) { + act.runOnUiThread(new Runnable() { + @Override + public void run() { + Intent openActivity = new Intent(activity + .getApplicationContext(), MediNETActivity.class); + openActivity.putExtra("page", browsetopage); + openActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + openActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + getMeditationAssistant().getApplicationContext() + .startActivity(openActivity); + } + }); + } else { + askToSignIn(); + } + } + + public void resetSession() { + session = new MeditationSession(); + } + + public boolean connect() { + ConnectivityManager cm = (ConnectivityManager) getMeditationAssistant() + .getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo netInfo = cm.getActiveNetworkInfo(); + Boolean internetconnected = (netInfo != null && netInfo.isConnectedOrConnecting()); + + if (!internetconnected) { + Log.d("MeditationAssistant", + "Cancelled MediNET connection: Internet isn't connected"); + return false; + } + + if (getMeditationAssistant().getMediNETKey().equals("")) { + askToSignIn(); + return false; + } + + runnable_finished = true; + if (!this.status.equals("success")) { + JSONObject jobj = new JSONObject(); + try { + Log.d("MeditationAssistant", "Begin connect"); + jobj.put("x", getMeditationAssistant().getMediNETKey()); + } catch (JSONException e1) { + e1.printStackTrace(); + } + + // display json object being sent + // Log.d("MeditationAssistant", "JSON object send: " + + // jobj.toString()); + + status = "connecting"; + + updated(); + if (task != null) { + task.cancel(true); + } + task = new MediNETTask(); + task.action = "connect"; + task.context = activity.getApplicationContext(); + + Log.d("MeditationAssistant", "Executing MediNET Task"); + task.doIt(this); + return true; + } + updated(); + return false; + } + + public Boolean deleteSessionByStarted(long started) { + if (task != null) { + task.cancel(true); + } + task = new MediNETTask(); + task.action = "deletesession"; + task.actionextra = String.valueOf(started); + task.context = activity.getApplicationContext(); + if (debug) { + task.nextURL += "&debug77"; + } + task.doIt(this); + return true; + } + + public void signInWithAuthToken(String authtoken) { + if (task != null) { + task.cancel(true); + } + + task = new MediNETTask(); + task.action = "signin"; + task.actionextra = authtoken; + task.context = activity.getApplicationContext(); + + task.doIt(this); + } + + public MainActivity getActivity() { + return activity; + } + + public void setActivity(MainActivity activity) { + this.activity = activity; + } + + public MeditationAssistant getMeditationAssistant() { + if (ma == null) { + ma = (MeditationAssistant) this.activity.getApplication(); + } + return ma; + } + + public MeditationSession getSession() { + return session; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Boolean postSession() { + return postSession(false, null); + } + + public Boolean postSession(Boolean manualposting, FragmentActivity act) { + Log.d("MeditationAssistant", "Session.toString(): " + + this.getSession().export().toString()); + if (task != null) { + task.cancel(true); + } + task = new MediNETTask(); + task.fragment_activity = act; + task.action = "postsession"; + if (manualposting) { + task.actionextra = "manualposting"; + } else { + // Only add streak if there isn't already a session for today + if (getMeditationAssistant().db.numSessionsByDate(getMeditationAssistant().db.timestampToAPIDate(getSession().completed * 1000)) == 0) { + getMeditationAssistant().addMeditationStreak(); + if (getSession().streakday == 0) { + getSession().streakday = getMeditationAssistant().getMeditationStreak(); + } + } + } + task.context = activity.getApplicationContext(); + if (debug) { + task.nextURL += "&debug77"; + } + task.doIt(this); + return true; + } + + public void saveSession(Boolean manualposting, Boolean posted) { + Long postedlong = (long) 0; + if (posted) { + postedlong = (long) 1; + } + + // Only add streak if there isn't already a session for that day + if (getMeditationAssistant().db.numSessionsByDate(getMeditationAssistant().db.timestampToAPIDate(getSession().completed * 1000)) == 0) { + if (!manualposting) { + getMeditationAssistant().addMeditationStreak(); + + if (getSession().streakday == 0) { + getSession().streakday = getMeditationAssistant().getMeditationStreak(); + } + } else { + Calendar c_midnight = new GregorianCalendar(); + c_midnight.setTime(new Date()); + c_midnight.set(Calendar.HOUR_OF_DAY, 0); + c_midnight.set(Calendar.MINUTE, 0); + c_midnight.set(Calendar.SECOND, 0); + c_midnight.set(Calendar.MILLISECOND, 0); + + if ((c_midnight.getTimeInMillis() / 1000) < getSession().started && (getSession().started - (c_midnight.getTimeInMillis() / 1000)) < 86400) { // After midnight today + getMeditationAssistant().addMeditationStreak(); + + if (getSession().streakday == 0) { + getSession().streakday = getMeditationAssistant().getMeditationStreak(); + } + } else { + c_midnight.add(Calendar.DATE, -1); + + if ((c_midnight.getTimeInMillis() / 1000) < getSession().started) { // After midnight yesterday + getMeditationAssistant().addMeditationStreak(false); + + if (getSession().streakday == 0) { + getSession().streakday = getMeditationAssistant().getMeditationStreak(); + } + } + } + } + } + + getMeditationAssistant().db.addSession(new SessionSQL( + getSession().started, getSession().completed, getSession().length, + getSession().message, postedlong, getSession().streakday)); + + resetSession(); + + if (!manualposting) { + getMeditationAssistant().asktorate = true; + } + } + + public void selectProvider(View v) { + ImageButton img = (ImageButton) v; + + Intent intent = new Intent(getMeditationAssistant() + .getApplicationContext(), MediNETActivity.class); + if (img.getId() == R.id.btnGoogle) { + intent.putExtra("provider", "Google"); + } else if (img.getId() == R.id.btnFacebook) { + intent.putExtra("provider", "Facebook"); + } else if (img.getId() == R.id.btnAOL) { + intent.putExtra("provider", "AOL"); + } else if (img.getId() == R.id.btnTwitter) { + intent.putExtra("provider", "Twitter"); + } else if (img.getId() == R.id.btnLive) { + intent.putExtra("provider", "Live"); + } else if (img.getId() == R.id.btnOpenID) { + intent.putExtra("provider", "OpenID"); + } + + getMeditationAssistant().getApplicationContext().startActivity(intent); + } + + public void signOut() { + Log.d("MeditationAssistant", "Signing out"); + if (task != null) { + task.cancel(true); + } + task = new MediNETTask(); + task.action = "signout"; + task.context = activity.getApplicationContext(); + if (debug) { + task.nextURL += "&debug77"; + } + task.doIt(this); + + status = "stopped"; + getMeditationAssistant().setMediNETKey("", ""); + if (!getMeditationAssistant().getPrefs().getBoolean("pref_autosignin", false)) { + getMeditationAssistant().getPrefs().edit().putString("key", "").apply(); + } + //getMeditationAssistant().setMeditationStreak(0, 0); + updated(); + } + + public Boolean syncSessions() { + getMeditationAssistant().shortToast(getMeditationAssistant().getString(R.string.downloadingSessions)); + if (task != null) { + task.cancel(true); + } + task = new MediNETTask(); + task.action = "syncsessions"; + task.context = activity.getApplicationContext(); + if (debug) { + task.nextURL += "&debug77"; + } + task.doIt(this); + return true; + } + + public Boolean uploadSessions() { + getMeditationAssistant().shortToast(getMeditationAssistant().getString(R.string.uploadingSessions)); + if (task != null) { + task.cancel(true); + } + task = new MediNETTask(); + task.action = "uploadsessions"; + task.context = activity.getApplicationContext(); + if (debug) { + task.nextURL += "&debug77"; + } + task.doIt(this); + return true; + } + + public void updateAfterDelay() { + Log.d("MeditationAssistant", "Update after delay: " + status); + handler.postDelayed(runnable2, 1750); + } + + public void updated() { + Log.d("MeditationAssistant", "updated() " + status); + + activity.updateTextsAsync(); + if (runnable_finished) { + runnable_finished = false; + handler.postDelayed(runnable, 750); + } + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MediNETActivity.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MediNETActivity.java new file mode 100644 index 0000000..52cb4d9 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MediNETActivity.java @@ -0,0 +1,566 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.res.Configuration; +import android.graphics.Color; +import android.net.MailTo; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.util.Log; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.webkit.CookieManager; +import android.webkit.CookieSyncManager; +import android.webkit.WebChromeClient; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.FrameLayout; +import android.widget.RelativeLayout; + +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.AdView; +import com.google.android.gms.analytics.GoogleAnalytics; + +import org.apache.http.cookie.Cookie; + +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +public class MediNETActivity extends Activity { + final Activity activity = this; + protected FrameLayout webViewPlaceholder = null; + protected WebView webView = null; + private AdView av = null; + private String provider = ""; + private MeditationAssistant ma = null; + private Handler handler = new Handler(); + private boolean signing_in = false; + private boolean hide_refresh = false; + + public static Intent newEmailIntent(Context context, String address, String subject, String body, String cc) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.putExtra(Intent.EXTRA_EMAIL, new String[]{address}); + intent.putExtra(Intent.EXTRA_TEXT, body); + intent.putExtra(Intent.EXTRA_SUBJECT, subject); + intent.putExtra(Intent.EXTRA_CC, cc); + intent.setType("message/rfc822"); + return intent; + } + + public MeditationAssistant getMeditationAssistant() { + if (ma == null) { + ma = (MeditationAssistant) this.getApplication(); + } + return ma; + } + + public String getPageUrl(String page) { + TimeZone tz = TimeZone.getDefault(); + Date now = new Date(); + + return "http://medinet.ftp.sh/client_android.php?v=" + + MediNET.version.toString() + "&avn=" + + String.valueOf(getMeditationAssistant().getMAAppVersionNumber()) + "&page=" + page + "&th=" + + ma.getMAThemeString() + "&tz=" + + String.valueOf(tz.getOffset(now.getTime())) + "&x=" + + getMeditationAssistant().getMediNETKey(); + } + + public void goTo(String go_to) { + String url; + + if (go_to.equals("Google") || go_to.equals("Facebook") + || go_to.equals("Twitter") || go_to.equals("AOL") + || go_to.equals("OpenID") || go_to.equals("Live") + || go_to.equals("LinkedIn")) { + setTitle(String.format(getString(R.string.signInWithProvider), + go_to)); + url = "http://medinet.ftp.sh/client_android_login.php?v=" + + MediNET.version.toString() + "&avn=" + + String.valueOf(getMeditationAssistant().getMAAppVersionNumber()) + "&provider=" + go_to; + provider = go_to; + signing_in = true; + } else if (go_to.equals("gpl") || go_to.equals("lgpl")) { + setTitle(""); + signing_in = true; + hide_refresh = true; + + if (go_to.equals("gpl")) { + url = "file:///android_asset/gpl.html"; + } else { + url = "file:///android_asset/lgpl.html"; + } + } else { + if (go_to.equals("community")) { + setTitle(getString(R.string.community)); + } else if (go_to.equals("sessions")) { + setTitle(getString(R.string.sessions)); + } else if (go_to.equals("account")) { + setTitle(getString(R.string.account)); + } else if (go_to.equals("forum")) { + setTitle(getString(R.string.forum)); + } else if (go_to.equals("groups")) { + setTitle(getString(R.string.groups)); + } else if (go_to.equals("signout")) { + + } else { + return; + } + + url = getPageUrl(go_to); + signing_in = false; + } + + Log.d("MeditationAssistant", go_to + " - Going to: " + url); + + webView.loadUrl(url); + setWindowBackground(); + } + + @SuppressLint({"AddJavascriptInterface", "SetJavaScriptEnabled"}) + protected void initUI(Boolean activityOnCreate) { + webViewPlaceholder = ((FrameLayout) findViewById(R.id.webViewPlaceholder)); + + if (webView == null) { + webView = new WebView(getApplicationContext()); + + // potential fixes for keeping zoom + // webView.getSettings().setLoadWithOverviewMode(true); + // webView.getSettings().setUseWideViewPort(true); + + webView.setWebChromeClient(new WebChromeClient() { + @Override + public void onProgressChanged(WebView view, int progress) { + if (Build.VERSION.SDK_INT >= 15) { // setProgress added API-15 + activity.setProgress(progress * 100); + } + } + }); + + webView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + WebView.HitTestResult result = webView.getHitTestResult(); + Log.d("MeditationAssistant", "Hit test"); + if (result != null) { + if (result.getType() == WebView.HitTestResult.IMAGE_TYPE + || result.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) { + Log.d("MeditationAssistant", + "Image: " + result.toString()); + Intent browserIntent = new Intent( + Intent.ACTION_VIEW, Uri.parse(result + .getExtra()) + ); + startActivity(browserIntent); + return true; + } else if (result.getType() == WebView.HitTestResult.SRC_ANCHOR_TYPE) { + Log.d("MeditationAssistant", + "Anchor: " + result.toString()); + Intent browserIntent = new Intent( + Intent.ACTION_VIEW, Uri.parse(result + .getExtra()) + ); + startActivity(browserIntent); + return true; + } + } + + return false; + } + }); + + webView.setHapticFeedbackEnabled(true); + webView.setLongClickable(true); + // webView.setInitialScale(getMeditationAssistant().getWebViewScale()); + + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); + + webView.setLayoutParams(params); + webView.getSettings().setSupportZoom(true); + // webView.getSettings().setBuiltInZoomControls(true); + webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); + webView.setScrollbarFadingEnabled(true); + webView.getSettings().setLoadsImagesAutomatically(true); + + if (Build.VERSION.SDK_INT < 11) { + webView.getSettings(); + webView.setBackgroundColor(Color.TRANSPARENT); + } else { + // Fix background flicker + webView.getSettings(); + webView.setBackgroundColor(Color.argb(1, 0, 0, 0)); + } + + // JavaScript + webView.addJavascriptInterface( + new JavaScriptInterface(this, this.getApplicationContext()), + "MA"); + webView.getSettings().setJavaScriptEnabled(true); + + // Cookies + List cookies = getMeditationAssistant().getHttpClient() + .getCookieStore().getCookies(); + + if (!cookies.isEmpty()) { + CookieManager cookieManager = CookieManager.getInstance(); + + for (Cookie cookie : cookies) { + String cookieString = cookie.getName() + "=" + + cookie.getValue() + "; domain=" + + cookie.getDomain(); + cookieManager.setCookie("medinet.ftp.sh", cookieString); + CookieSyncManager.getInstance().sync(); + } + } + + webView.setWebViewClient(new WebViewClient() { + @Override + public void onPageFinished(WebView view, String url) { + if (Uri.parse(url) != null && Uri.parse(url).getHost() != null && Uri.parse(url).getHost().equals("medinet.ftp.sh")) { + if (webView.getTitle() != null + && !webView.getTitle().trim().equals("")) { + setTitle(webView.getTitle()); + } + signing_in = url.contains("/hybridauth/"); + } else { + /* + * setTitle(String.format(getString(R.string. + * signInWithProvider), provider)); + */ + } + + setWindowBackground(); + // view.setInitialScale(getMeditationAssistant().getWebViewScale()); + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + /*getMeditationAssistant().setWebViewScale( + (int) (100 * view.getScale()));*/ + Log.d("MeditationAssistant", + "Signing_in: " + String.valueOf(signing_in) + " - " + + url + ); + if (url != null && url.startsWith("mailto:")) { + MailTo mt = MailTo.parse(url); + Intent i = newEmailIntent(MediNETActivity.this, mt.getTo(), mt.getSubject(), mt.getBody(), mt.getCc()); + startActivity(i); + view.reload(); + return true; + /*} else if (url != null && Uri.parse(url) != null && Uri.parse(url).getHost() != null + && !Uri.parse(url).getHost() + .equals("medinet.ftp.sh") + && webView.getUrl() != null + && Uri.parse(webView.getUrl()).getHost() != null && Uri.parse(webView.getUrl()).getHost() + .equals("medinet.ftp.sh") + && !webView.getUrl().contains("provider=OpenID")) { + + Log.d("MA", "!!!!!!!!!!!!!!!!! OPENING!!!"); + Intent browserIntent = new Intent(Intent.ACTION_VIEW, + Uri.parse(url)); + startActivity(browserIntent);*/ + } else { + view.loadUrl(url); + } + + Log.d("MA", Uri.parse(url).toString()); + Log.d("MA", Uri.parse(url).getHost()); + return true; + } + }); + + webView.getSettings().setSupportMultipleWindows(true); + webView.setWebChromeClient(new WebChromeClient() { + @Override + public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, android.os.Message resultMsg) { + WebView.HitTestResult result = view.getHitTestResult(); + String data = result.getExtra(); + Context context = view.getContext(); + + context.startActivity(new Intent( + Intent.ACTION_VIEW, + Uri.parse(data)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + + return false; + } + }); + } + + // webView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR); + webViewPlaceholder.addView(webView); + // webView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR); + + if (activityOnCreate) { + if (getIntent().hasExtra("provider")) { + provider = getIntent().getStringExtra("provider"); + if (provider.equals("Google") || provider.equals("Facebook") + || provider.equals("Twitter") || provider.equals("AOL") + || provider.equals("OpenID") || provider.equals("Live") + || provider.equals("LinkedIn")) { + signing_in = true; + goTo(provider); + } + } else if (getIntent().hasExtra("page") + && (getIntent().getStringExtra("page").equals("community") + || getIntent().getStringExtra("page").equals( + "sessions") + || getIntent().getStringExtra("page").equals( + "account") + || getIntent().getStringExtra("page").equals( + "groups") + || getIntent().getStringExtra("page").equals( + "forum") + || getIntent().getStringExtra("page").equals("gpl") || getIntent() + .getStringExtra("page").equals("lgpl"))) { + signing_in = false; + goTo(getIntent().getStringExtra("page")); + } + } else { + if (getPackageName().equals( + "sh.ftp.rocketninelabs.meditationassistant")) { + Log.d("MeditationAssistant", "Fetching ad"); + + // AdView av = new AdView(this, AdSize.SMART_BANNER, + // "a15110a172d3cff"); + av = (AdView) findViewById(R.id.adViewMediNET); + av.setVisibility(View.VISIBLE); + AdRequest adRequest = new AdRequest.Builder() + .addTestDevice(AdRequest.DEVICE_ID_EMULATOR) + .build(); + av.loadAd(adRequest); + + /* + * (new Thread() { public void run() { Looper.prepare(); AdView + * av = (AdView) findViewById(R.id.adViewMediNET); + * + * + * + * av.loadAd(adrequest); } }).start(); + */ + + } else { + // av.setVisibility(View.GONE); + } + } + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + if (webView != null) { + webViewPlaceholder.removeView(webView); + } + + super.onConfigurationChanged(newConfig); + + setContentView(R.layout.activity_medinet); + + initUI(false); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + requestWindowFeature(Window.FEATURE_PROGRESS); + super.onCreate(savedInstanceState); + + setTheme(getMeditationAssistant().getMATheme()); + setContentView(R.layout.activity_medinet); + getActionBar().setDisplayHomeAsUpEnabled(true); + + if (getPackageName() + .equals("sh.ftp.rocketninelabs.meditationassistant")) { + Log.d("MeditationAssistant", "Fetching ad"); + + // AdView av = new AdView(this, AdSize.SMART_BANNER, + // "a15110a172d3cff"); + av = (AdView) findViewById(R.id.adViewMediNET); + av.setVisibility(View.VISIBLE); + AdRequest adRequest = new AdRequest.Builder() + .addTestDevice(AdRequest.DEVICE_ID_EMULATOR) + .build(); + av.loadAd(adRequest); + } + + if (getMeditationAssistant().sendUsageReports()) { + getMeditationAssistant().getTracker(MeditationAssistant.TrackerName.APP_TRACKER); + } + + initUI(true); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.medinet, menu); + + return true; + } + + @Override + public void onDestroy() { + if (getMeditationAssistant().getMediNET() != null) { + if (getMeditationAssistant().getMediNET().getStatus() != null + && getMeditationAssistant().getMediNET().getStatus() + .equals("connecting")) { + getMeditationAssistant().getMediNET().setStatus("disconnected"); + } + getMeditationAssistant().getMediNET().updated(); + } + + if (av != null) { + av.destroy(); + } + + super.onDestroy(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) { + webView.goBack(); + return true; + } + + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + Log.d("MeditationAssistant", + "Selected menu item: " + String.valueOf(item.getItemId())); + int itemId = item.getItemId(); + if (itemId == android.R.id.home) { + finish(); + return true; + } else if (itemId == R.id.refreshMediNET) { + webView.loadUrl("javascript:window.location.reload(true)"); + return true; + } else if (itemId == R.id.menuMediNETCommunity) { + goTo("community"); + return true; + } else if (itemId == R.id.menuMediNETSessions) { + goTo("sessions"); + return true; + } else if (itemId == R.id.menuMediNETForum) { + goTo("forum"); + return true; + } else if (itemId == R.id.menuMediNETGroups) { + goTo("groups"); + return true; + } else if (itemId == R.id.menuMediNETAccount) { + goTo("account"); + return true; + } else if (itemId == R.id.menuMediNETBack) { + if (webView.canGoBack()) { + webView.goBack(); + } + return true; + } else if (itemId == R.id.menuMediNETForward) { + if (webView.canGoForward()) { + webView.goForward(); + } + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + protected void onPause() { + if (av != null) { + av.pause(); + } + CookieSyncManager.getInstance().stopSync(); + super.onStop(); + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + if (signing_in) { + menu.findItem(R.id.menuMediNET).setVisible(false); + } else { + menu.findItem(R.id.menuMediNET).setVisible(true); + } + + if (hide_refresh) { + menu.findItem(R.id.refreshMediNET).setVisible(false); + } else { + menu.findItem(R.id.refreshMediNET).setVisible(true); + } + + super.onPrepareOptionsMenu(menu); + + return true; + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + + webView.restoreState(savedInstanceState); + } + + @Override + protected void onResume() { + CookieSyncManager.getInstance().startSync(); + super.onResume(); + if (av != null) { + av.resume(); + } + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + + webView.saveState(outState); + } + + @Override + public void onStart() { + super.onStart(); + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStart(this); + } + } + + @Override + protected void onStop() { + super.onStop(); + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStop(this); + } + } + + public void setWindowBackground() { + if (getMeditationAssistant().getMATheme() != R.style.MeditationDarkTheme && getMeditationAssistant().getMATheme() != R.style.Buddhism) { + getWindow().setBackgroundDrawable( + getResources().getDrawable( + android.R.drawable.screen_background_light) + ); + } else { + /*getWindow() + .setBackgroundDrawable( + getResources().getDrawable( + android.R.drawable.background_holo_dark));*/ + webView.getSettings(); + if (signing_in) { + webView.setBackgroundColor(Color.WHITE); + } else { + if (Build.VERSION.SDK_INT < 11) { + webView.setBackgroundColor(Color.TRANSPARENT); + } else { + // Fix background flicker + webView.setBackgroundColor(Color.argb(1, 0, 0, 0)); + } + } + } + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MediNETTask.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MediNETTask.java new file mode 100644 index 0000000..2380f35 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MediNETTask.java @@ -0,0 +1,479 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.content.Context; +import android.os.AsyncTask; +import android.support.v4.app.FragmentActivity; +import android.util.Log; + +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.message.BasicNameValuePair; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.TimeZone; + +public class MediNETTask extends AsyncTask { + public Context context; + public String nextURL = null; + public String action = ""; + public String actionextra = ""; + public MediNET medinet; + public String x; + public FragmentActivity fragment_activity = null; + private BufferedReader webReader; + private MeditationAssistant ma = null; + private Crypt crypt = new Crypt(); + + @Override + protected MediNET doInBackground(MediNET... medinets) { + this.medinet = medinets[0]; + this.medinet.result = ""; + + if (isCancelled()) { + Log.d("MeditationAssistant", "Task cancelled"); + return this.medinet; + } + + TimeZone tz = TimeZone.getDefault(); + Date now = new Date(); + int offsetFromUTC = tz.getOffset(now.getTime()); + String appVersion = getMeditationAssistant().getMAAppVersion() + (getMeditationAssistant().getMAIsAppFull() ? "full" : "free"); + + if (this.nextURL == null) { + this.nextURL = "http://medinet.ftp.sh/client_android.php?v=" + + MediNET.version.toString() + "&av=" + + appVersion + "&avn=" + + String.valueOf(getMeditationAssistant().getMAAppVersionNumber()) + "&tz=" + + String.valueOf(offsetFromUTC); + } + + if (action.equals("signin")) { + this.nextURL = "http://medinet.ftp.sh/client_android_login_oauth2.php?v=" + + MediNET.version.toString() + "&av=" + + appVersion + "&avn=" + + String.valueOf(getMeditationAssistant().getMAAppVersionNumber()) + "&tz=" + + String.valueOf(offsetFromUTC) + "&token=" + actionextra; + } + + Log.d("MeditationAssistant", "URL => " + this.nextURL); + + HttpPost httpPost = new HttpPost(this.nextURL); + HttpResponse webResponse = null; + ArrayList sessionssql = null; + + try { + List nameValuePairs = new ArrayList(2); + nameValuePairs.add(new BasicNameValuePair("x", medinet + .getMeditationAssistant().getMediNETKey())); + + if (action.equals("connect")) { + nameValuePairs.add(new BasicNameValuePair("action", "connect")); + } else if (action.equals("postsession")) { + nameValuePairs.add(new BasicNameValuePair("postsession", Crypt + .bytesToHex(crypt.encrypt(medinet.getSession().export() + .toString())))); + if (actionextra.equals("manualposting")) { + nameValuePairs.add(new BasicNameValuePair("manualposting", + "true")); + } + } else if (action.equals("deletesession")) { + nameValuePairs.add(new BasicNameValuePair("action", + "deletesession")); // Session start time + nameValuePairs.add(new BasicNameValuePair("session", + actionextra)); + } else if (action.equals("syncsessions")) { + nameValuePairs.add(new BasicNameValuePair("action", + "syncsessions")); + } else if (action.equals("uploadsessions")) { + JSONArray jsonsessions = new JSONArray(); + sessionssql = getMeditationAssistant().db.getAllLocalSessions(); + + if (sessionssql.size() == 0) { + getMeditationAssistant().longToast( + medinet.activity, + getMeditationAssistant().getString(R.string.sessionsNotImported)); + + return medinet; + } + + for (SessionSQL uploadsessionsql : sessionssql) { + MeditationSession uploadsession = new MeditationSession(); + uploadsession.id = uploadsessionsql._id; + uploadsession.length = uploadsessionsql._length; + uploadsession.started = uploadsessionsql._started; + uploadsession.completed = uploadsessionsql._completed; + uploadsession.streakday = uploadsessionsql._streakday; + uploadsession.message = uploadsessionsql._message; + + jsonsessions.put(uploadsession.export()); + } + + Log.d("MeditationAssistant", jsonsessions.toString()); + + nameValuePairs.add(new BasicNameValuePair("uploadsessions", Crypt + .bytesToHex(crypt.encrypt(jsonsessions.toString())))); + } else if (action.equals("signout")) { + nameValuePairs + .add(new BasicNameValuePair("signout", "signout")); + } + + Log.d("MeditationAssistant", "Post to " + this.nextURL + ", " + + nameValuePairs.toString()); + httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); + webResponse = getMeditationAssistant().getHttpClient().execute( + httpPost, getMeditationAssistant().getHttpContext()); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (Exception e) { + getMeditationAssistant().longToast(getMeditationAssistant().getString(R.string.sessionNotPosted)); + e.printStackTrace(); + } + + if (webResponse == null) { + Log.d("MeditationAssistant", "Unable to connect to MediNET"); + medinet.status = "disconnected"; + + if (!getMeditationAssistant().getMediNETKey().equals("") + && medinet.activity != null) { + getMeditationAssistant().longToast(medinet.activity, + getMeditationAssistant().getString(R.string.unableToConnect)); + medinet.activity.updateTextsAsync(); + } + + return medinet; + } + String result = ""; + + try { + this.webReader = new BufferedReader(new InputStreamReader( + webResponse.getEntity().getContent())); + } catch (IllegalStateException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + String line; + try { + while ((line = this.webReader.readLine()) != null) { + result += line + "\n"; + } + } catch (IOException e) { + e.printStackTrace(); + } + + Calendar date = new GregorianCalendar(); + date.setTimeZone(TimeZone.getDefault()); + date.set(Calendar.HOUR_OF_DAY, 0); + date.set(Calendar.MINUTE, 0); + date.set(Calendar.SECOND, 0); + date.set(Calendar.MILLISECOND, 0); + date.add(Calendar.DAY_OF_MONTH, 2); + Log.d("MeditationAssistant", + "two days: " + date.getTimeZone().getDisplayName() + + String.valueOf(date.getTimeInMillis() / 1000) + ); + + Log.d("MeditationAssistant", "Result: " + result); + if (webResponse.getFirstHeader("x-MediNET") != null) { + if (webResponse.getFirstHeader("x-MediNET").getValue() + .equals("signin")) { + this.medinet.askToSignIn(); + } else { + if (action.equals("signin") && webResponse.getFirstHeader("x-MediNET-Key") != null) { + /* Oauth2 sign in */ + Log.d("MeditationAssistant", "Header key: " + + webResponse.getFirstHeader("x-MediNET-Key") + .getValue()); + if (!webResponse.getFirstHeader("x-MediNET-Key") + .getValue().equals("")) { + getMeditationAssistant().setMediNETKey(webResponse.getFirstHeader("x-MediNET-Key") + .getValue(), "Google"); + //getMeditationAssistant().getMediNET().connect(); + + try { + getMeditationAssistant().shortToast( + medinet.activity, + getMeditationAssistant().getString(R.string.mediNETConnected)); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else if (webResponse.getFirstHeader("x-MediNET-Streak") != null) { + Log.d("MeditationAssistant", "Header streak: " + + webResponse.getFirstHeader("x-MediNET-Streak") + .getValue()); + if (!webResponse.getFirstHeader("x-MediNET-Streak") + .getValue().equals("")) { + String streak_header = webResponse.getFirstHeader( + "x-MediNET-Streak").getValue(); + if (streak_header.contains(",")) { + getMeditationAssistant().setMeditationStreak(Integer.valueOf(streak_header.split(",")[0]), Integer.valueOf(streak_header.split(",")[1])); + getMeditationAssistant().recalculateMeditationStreak(); + } + } + } + if (webResponse.getFirstHeader("x-MediNET-Meditating") != null) { + if (!webResponse.getFirstHeader("x-MediNET-Meditating") + .getValue().equals("")) { + // TODO: Was this going to be a meditating-now feature? + } + } + if (webResponse.getFirstHeader("x-MediNET-MaxStreak") != null) { + if (!webResponse.getFirstHeader("x-MediNET-MaxStreak") + .getValue().equals("")) { + Integer maxstreak = Integer.valueOf(webResponse.getFirstHeader("x-MediNET-MaxStreak") + .getValue()); + if (maxstreak > getMeditationAssistant().getLongestMeditationStreak()) { + getMeditationAssistant().setLongestMeditationStreak(maxstreak); + } + } + } + } + Log.d("MeditationAssistant", "Header: " + + webResponse.getFirstHeader("x-MediNET").getValue()); + + if (!result.equals("") + && !result.trim().startsWith("<")) { + JSONObject jsonObj; + try { + jsonObj = new JSONObject(result); + Log.d("MeditationAssistant", + "jsonobj: " + jsonObj.toString()); + if (jsonObj.has("status")) { + medinet.status = jsonObj.getString("status"); + } + if (jsonObj.has("result")) { + medinet.result = jsonObj.getString("result"); + } + if (jsonObj.has("announce")) { + medinet.announcement = jsonObj.getString("announce"); + try { + medinet.activity.runOnUiThread(new Runnable() { + @Override + public void run() { + getMeditationAssistant() + .showAnnouncementDialog(null); + } + }); + } catch (Exception e) { + Log.d("MeditationAssistant", + "Caught error while parsing announcement..."); + e.printStackTrace(); + } + } + + if (action.equals("connect")) { + if (!getMeditationAssistant().getPrefs().getBoolean( + "asked_staledata", false)) { + try { + medinet.activity.runOnUiThread(new Runnable() { + @Override + public void run() { + getMeditationAssistant() + .showStaleDataDialog(); + } + }); + } catch (Exception e) { + Log.d("MeditationAssistant", + "Caught error while showing stale data dialog..."); + e.printStackTrace(); + } + + getMeditationAssistant().getPrefs().edit() + .putBoolean("asked_staledata", true) + .apply(); + } + } else if (action.equals("postsession")) { + if (medinet.result.equals("posted")) { + if (actionextra.equals("manualposting")) { + if (fragment_activity != null) { + fragment_activity + .runOnUiThread(new Runnable() { + @Override + public void run() { + getMeditationAssistant() + .shortToast( + getMeditationAssistant().getString(R.string.sessionPosted)); + } + }); + } + } else { + medinet.saveSession(false, true); + } + } else if (medinet.result.equals("alreadyposted") + && actionextra.equals("manualposting") + && fragment_activity != null) { + fragment_activity.runOnUiThread(new Runnable() { + @Override + public void run() { + getMeditationAssistant().shortToast( + getMeditationAssistant().getString(R.string.sessionAlreadyPosted)); + } + }); + } + } else if (action.equals("deletesession")) { + if (medinet.result.equals("deleted")) { + Log.d("MeditationAssistant", "Deleted session"); + + getMeditationAssistant().shortToast( + medinet.activity, + getMeditationAssistant().getString(R.string.sessionDeletedMediNET)); + + SessionSQL deletedsession = getMeditationAssistant().db.getSessionByStarted(Long.valueOf(actionextra)); + if (deletedsession != null) { + deletedsession._isposted = (long) 0; + try { + getMeditationAssistant().db.updateSession(deletedsession); + } catch (Exception e) { + // Do nothing, it was probably deleted locally as well + } + } + } else if (medinet.result.equals("notdeleted")) { + getMeditationAssistant().shortToast( + medinet.activity, + getMeditationAssistant().getString(R.string.sessionNotFoundMediNET)); + } else if (medinet.result.equals("accessdenied")) { + getMeditationAssistant() + .shortToast(medinet.activity, + getMeditationAssistant().getString(R.string.sessionNotProperAccount)); + } + } else if (action.equals("uploadsessions")) { + if (sessionssql != null && medinet.result.equals("uploaded")) { + for (SessionSQL sessionsql : sessionssql) { + sessionsql._isposted = (long) 1; + getMeditationAssistant().db.updateSession(sessionsql); + } + + Integer sessuploaded = sessionssql.size(); + getMeditationAssistant().longToast( + medinet.activity, + String.format(getMeditationAssistant().getResources().getQuantityString( + R.plurals.sessionsUploaded, sessuploaded, + sessuploaded), String.valueOf(sessuploaded)) + ); + } else { + getMeditationAssistant().longToast( + medinet.activity, + getMeditationAssistant().getString(R.string.sessionsNotImported)); + } + } else if (action.equals("syncsessions")) { + JSONArray jArray = jsonObj.getJSONArray("syncsessions"); + + Integer sessimported = 0; + + SessionSQL sess; + for (int i = 0; i < jArray.length(); i++) { + JSONObject session = jArray.getJSONObject(i); + + if (getMeditationAssistant().db + .getSessionByStarted(session + .getLong("started")) == null) { + sessimported += 1; + + sess = new SessionSQL(); + sess._length = session.getLong("length"); + sess._started = session.getLong("started"); + sess._completed = session.getLong("completed"); // Added in API 5 + sess._message = session.getString("message"); + sess._streakday = session.getLong("streakday"); + sess._isposted = (long) 1; + + Log.d("MeditationAssistant", + "Adding session started at " + + String.valueOf(sess._started) + ); + getMeditationAssistant().db.addSession(sess); + } else { + Log.d("MeditationAssistant", + "Skipping session " + String.valueOf(session)); + } + } + + if (sessimported > 0) { + getMeditationAssistant().longToast( + medinet.activity, + String.format(getMeditationAssistant().getResources().getQuantityString( + R.plurals.sessionsImported, sessimported, + sessimported), String.valueOf(sessimported)) + ); + } else { + getMeditationAssistant().longToast( + medinet.activity, + getMeditationAssistant().getString(R.string.sessionsNotImported)); + } + } + } catch (JSONException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + publishProgress(); + medinet.updateAfterDelay(); + + if (context == null) { + Throwable t = new Throwable(); + t.printStackTrace(); + } + + return medinet; + } + + public void doIt(MediNET m) { + try { + executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, m); + } catch (Exception e) { + execute(m); + e.printStackTrace(); + } + } + + public MeditationAssistant getMeditationAssistant() { + if (ma == null) { + ma = (MeditationAssistant) medinet.activity.getApplication(); + } + return ma; + } + + @Override + protected void onPostExecute(MediNET medinet) { + Log.d("MeditationAssistant", + "onPostExecute: " + String.valueOf(action)); + if (action != null) { + if (action.equals("connect")) { + try { + MainActivity mainActivity = medinet.activity; + mainActivity.updateTexts(); + Log.d("MeditationAssistant", + "Updated texts from finished 'connect'"); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + @Override + protected void onProgressUpdate(Integer... progress) { + Log.d("MeditataionAssistant", "Progress update"); + medinet.updated(); + medinet.activity.updateTextsAsync(); + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationAssistant.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationAssistant.java new file mode 100644 index 0000000..0ff8cc6 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationAssistant.java @@ -0,0 +1,1497 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.accounts.AccountManagerCallback; +import android.accounts.AccountManagerFuture; +import android.accounts.AuthenticatorException; +import android.accounts.OperationCanceledException; +import android.app.Activity; +import android.app.AlarmManager; +import android.app.AlertDialog; +import android.app.Application; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentSender; +import android.content.SharedPreferences; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.media.AudioManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.Vibrator; +import android.preference.PreferenceManager; +import android.support.v4.app.NotificationCompat; +import android.util.Log; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.webkit.CookieSyncManager; +import android.widget.ImageButton; +import android.widget.Toast; + +import com.google.android.gms.analytics.GoogleAnalytics; +import com.google.android.gms.analytics.Tracker; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GooglePlayServicesUtil; +import com.google.android.gms.common.Scopes; +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.common.api.Scope; +import com.google.android.gms.fitness.Fitness; +import com.google.android.gms.fitness.FitnessActivities; +import com.google.android.gms.fitness.data.Field; +import com.google.android.gms.fitness.data.Session; +import com.google.android.gms.fitness.request.DataTypeCreateRequest; +import com.google.android.gms.fitness.request.SessionInsertRequest; + +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.impl.client.BasicCookieStore; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.BasicHttpContext; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; + +public class MeditationAssistant extends Application { + + public static String ACTION_PRESET = "sh.ftp.rocketninelabs.meditationassistant.PRESET"; + public static String ACTION_REMINDER = "sh.ftp.rocketninelabs.meditationassistant.DAILY_NOTIFICATION"; + public static String ACTION_UPDATED = "sh.ftp.rocketninelabs.meditationassistant.DAILY_NOTIFICATION_UPDATED"; + + public static int REQUEST_FIT = 22; + + public String package_name; + public Boolean debug_widgets = false; // Debug + public long lastpostedsessionstart = 0; + public boolean ispaused = false; + public long pausestart = 0; + public long pausetime = 0; + public int previousRingerMode = -1; + public String toastText = ""; + public DefaultHttpClient httpClient = null; + public BasicCookieStore cookieStore = null; + public BasicHttpContext httpContext = null; + public String pendingNotificationAction = ""; + public Boolean asktorate = false; + public DatabaseHandler db = null; + public AlarmManager reminderAlarmManager = null; + public PendingIntent reminderPendingIntent = null; + public String theme = null; + AlertDialog alertDialog = null; + String AUTH_TOKEN_TYPE = "oauth2:https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email"; + HashMap mTrackers = new HashMap(); + private String appVersion = null; + private Boolean appFull = null; + private long timeToStopMeditate = 0; + private long timeStartMeditate = 0; + private MediNET medinet = null; + private boolean screenoff = false; + private boolean runnablestopped = true; + private boolean sessrunnablestopped = true; + private String medinetkey = null; + private String medinetprovider = null; + private boolean connectedonce = false; + private boolean editingduration = false; + private Boolean rememberduration = null; + private Integer meditationstreak = null; + private long meditationstreakexpires = 0; + private long sessrunnablestarttime = 0; + private boolean sesswassignedout = false; + private Boolean sendusage = null; + private Activity toastActivity; + private long sessionduration = 0; + private Integer webview_scale = null; + private String timerMode = null; + private String durationFormatted = ""; + private Activity signin_activity = null; + private Bundle signin_options = new Bundle(); + private SharedPreferences prefs = null; + + private static final String AUTH_PENDING = "auth_state_pending"; + public boolean googleAPIAuthInProgress = false; + public GoogleApiClient googleClient = null; + + public static String getMarketName() { + return "google"; + //return "amazon"; + //return "getjar"; + // return "slideme"; + } + + public static int dpToPixels(float dp, Context context) { + Resources resources = context.getResources(); + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, + resources.getDisplayMetrics()); + } + + public static DefaultHttpClient getThreadSafeHttpClient() { + + DefaultHttpClient client = new DefaultHttpClient(); + ClientConnectionManager mgr = client.getConnectionManager(); + HttpParams params = client.getParams(); + client = new DefaultHttpClient(new ThreadSafeClientConnManager(params, + mgr.getSchemeRegistry()), params); + return client; + } + + public static void setAlphaCompat(View view, float alpha) { + view.setAlpha(alpha); + } + + public Boolean getIsBB() { + String osname = System.getProperty("os.name"); + return osname != null && osname.equals("qnx"); + } + + synchronized Tracker getTracker(TrackerName trackerId) { + if (!mTrackers.containsKey(trackerId)) { + GoogleAnalytics analytics = GoogleAnalytics.getInstance(this); + Tracker t = analytics.newTracker(R.xml.analytics_tracker); + mTrackers.put(trackerId, t); + } + return mTrackers.get(trackerId); + } + + public boolean canVibrate() { + try { + Vibrator vi = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); + return vi.hasVibrator(); + } catch (NoSuchMethodError e) { + } catch (Exception e) { + } + return true; + } + + public void connectOnce() { + if (!connectedonce) { + getMediNET().connect(); + connectedonce = true; + } + } + + public String[] getStartPhrases() { + String[] start_phrases = {"om tat sat", "om mani padme hum"}; + // start_phrases.add("namo akasagarbhaya om arya kamari mauli svaha"); + + return start_phrases; + } + + public void askToRateApp() { + if (getIsBB()) { + try { + startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("appworld://content/" + (getApplicationContext().getPackageName().equals("sh.ftp.rocketninelabs.meditationassistant") ? "59939924" : "59939922")) + ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } catch (ActivityNotFoundException e) { + Log.d("MeditationAssistant", "Couldn't open play store"); + startActivity(new Intent( + Intent.ACTION_VIEW, + Uri.parse("appworld://content/" + (getApplicationContext().getPackageName().equals("sh.ftp.rocketninelabs.meditationassistant") ? "59939924" : "59939922")) + ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } + } else if (MeditationAssistant.getMarketName().equals("google")) { + try { + startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("market://details?id=" + + getApplicationContext().getPackageName()) + ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } catch (ActivityNotFoundException e) { + Log.d("MeditationAssistant", "Couldn't open play store"); + startActivity(new Intent( + Intent.ACTION_VIEW, + Uri.parse("http://play.google.com/store/apps/details?id=" + + getApplicationContext().getPackageName()) + ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } + } else if (MeditationAssistant.getMarketName().equals("amazon")) { + try { + startActivity(new Intent(Intent.ACTION_VIEW, + Uri.parse("amzn://apps/android?p=" + + getApplicationContext().getPackageName()) + ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } catch (ActivityNotFoundException e) { + Log.d("MeditationAssistant", "Couldn't open amazon store"); + startActivity(new Intent( + Intent.ACTION_VIEW, + Uri.parse("http://www.amazon.com/gp/mas/dl/android?p=" + + getApplicationContext().getPackageName()) + ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } + } + } + + public void setNotificationControl() { + AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + previousRingerMode = audioManager.getRingerMode(); + + if (getPrefs().getString("pref_notificationcontrol", "").equals("vibrate")) { + audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); + } else if (getPrefs().getString("pref_notificationcontrol", "").equals("silent")) { + audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT); + } + } + + public void unsetNotificationControl() { + AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + + if (previousRingerMode >= 0 && getPrefs().getString("pref_notificationcontrol", "").equals("vibrate") || getPrefs().getString("pref_notificationcontrol", "").equals("silent")) { + audioManager.setRingerMode(previousRingerMode); + } + + previousRingerMode = -1; + } + + public String getDurationFormatted() { + return durationFormatted; + } + + public void setDurationFormatted(String d) { + if (!d.equals(durationFormatted)) { + durationFormatted = d; + // showNotification(); + } + } + + public boolean getEditingDuration() { + return editingduration; + } + + public void setEditingDuration(boolean bool) { + editingduration = bool; + } + + public DefaultHttpClient getHttpClient() { + if (httpClient == null) { + httpClient = getThreadSafeHttpClient(); + httpClient.setCookieStore(cookieStore); + } + + return httpClient; + } + + public BasicHttpContext getHttpContext() { + if (cookieStore == null) { + cookieStore = new BasicCookieStore(); + + httpContext = new BasicHttpContext(); + // Bind custom cookie store to the local context + httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); + } + return httpContext; + } + + public int getMATextColor(Boolean enabled) { + if (enabled) { + if (!getMAThemeString().equals("dark") && !getMAThemeString().equals("buddhism")) { + return android.R.color.primary_text_light; + } else { + return android.R.color.primary_text_dark; + } + } else { + if (!getMAThemeString().equals("dark") && !getMAThemeString().equals("buddhism")) { + return android.R.color.secondary_text_light; + } else { + return android.R.color.secondary_text_dark; + } + } + } + + public int getMATheme() { + return getMATheme(false); + } + + public int getMATheme(Boolean dialogue) { + if (theme == null) { + theme = getPrefs().getString("pref_theme", "dark"); + } + + if (theme.equals("buddhism")) { + return dialogue ? R.style.BuddhismDialogue : R.style.Buddhism; + } + + if (dialogue) { + if (!theme.equals("dark")) { + return R.style.MeditationLightDialogTheme; + } else { + return R.style.MeditationDarkDialogTheme; + } + } else { + if (theme.equals("light")) { + return R.style.MeditationLightTheme; + } else if (theme.equals("lightdark")) { + return R.style.MeditationLightDarkTheme; + } else { + return R.style.MeditationDarkTheme; + } + } + } + + public String getMAThemeString() { + if (theme == null) { + theme = getPrefs().getString("pref_theme", "dark"); + } + + return theme; + } + + public MediNET getMediNET() { + if (medinet == null) { + // + } + return medinet; + } + + public void setMediNET(MediNET medi) { + medinet = medi; + Log.d("MeditationAssistant", "Session: " + String.valueOf(medinet)); + } + + public String getMediNETKey() { + Log.d("MeditationAssistant", "getMediNETKey() - medinetkey: " + String.valueOf(medinetkey) + " prefs: " + getPrefs().getString("key", "")); + if (medinetkey == null) { + medinetkey = getPrefs().getString("key", ""); + } + return medinetkey; + } + + public String getMediNETProvider() { + if (medinetprovider == null) { + medinetprovider = getPrefs().getString("provider", ""); + } + if (medinetprovider.trim().equals("")) { + return "Unknown"; + } + return medinetprovider; + } + + public void recalculateMeditationStreak() { + Calendar dayCalendar = Calendar.getInstance(); + Integer daysback = 0; + Integer recalculatedstreak = 0; + Boolean sessionexiststoday = false; + + while (true) { + if (db.numSessionsByDate(String.valueOf(dayCalendar.get(Calendar.DAY_OF_MONTH)) + "-" + + String.valueOf(dayCalendar.get(Calendar.MONTH) + 1) + "-" + + String.valueOf(dayCalendar.get(Calendar.YEAR))) > 0) { + recalculatedstreak++; + + if (daysback == 0) { + sessionexiststoday = true; + } + } else if (daysback > 0) { + break; + } + + daysback++; + dayCalendar.add(Calendar.DAY_OF_YEAR, -1); + } + + if (getMeditationStreak() < recalculatedstreak) { + setMeditationStreak(recalculatedstreak, sessionexiststoday ? getMidnightTwoDaysTimestamp() : getMidnightOneDayTimestamp()); + } + } + + public Integer getMeditationStreak() { + long timestamp = System.currentTimeMillis() / 1000; + + if (meditationstreak == null || meditationstreakexpires < 1) { // streak + // or + // expires + // timestamp + // not + // set + meditationstreak = getPrefs().getInt("meditationstreak", 0); + meditationstreakexpires = getPrefs().getLong("meditationstreakexpires", + 0); + } + + if (meditationstreakexpires > 0 && meditationstreakexpires < timestamp) { // expires + // timestamp + // has passed + meditationstreak = 0; + meditationstreakexpires = 0; + + getPrefs().edit().putInt("meditationstreak", meditationstreak).putLong("meditationstreakexpires", meditationstreakexpires).apply(); + } + + return meditationstreak; + } + + public void addMeditationStreak() { + addMeditationStreak(true); + } + + public void addMeditationStreak(Boolean twodays) { + Integer streak = getMeditationStreak(); + Log.d("MeditationAssistant", "addMeditationStreak() - Streak: " + String.valueOf(streak) + " Expires: in " + String.valueOf(meditationstreakexpires - getTimestamp()) + " seconds"); + if (meditationstreak == null || meditationstreak == 0 || meditationstreakexpires - getTimestamp() < 86400) { + streak++; + + if (twodays) { + setMeditationStreak(streak, + getMidnightTwoDaysTimestamp()); + } else { + setMeditationStreak(streak, + getMidnightOneDayTimestamp()); + } + } + } + + public int getLongestMeditationStreak() { + return getPrefs().getInt("longeststreak", 0); + } + + public void setLongestMeditationStreak(int ms) { + getPrefs().edit().putInt("longeststreak", ms).apply(); + } + + public long getMidnightOneDayTimestamp() { + Calendar c_midnight_oneday = new GregorianCalendar(); + c_midnight_oneday.setTime(new Date()); + c_midnight_oneday.set(Calendar.HOUR_OF_DAY, 0); + c_midnight_oneday.set(Calendar.MINUTE, 0); + c_midnight_oneday.set(Calendar.SECOND, 0); + c_midnight_oneday.set(Calendar.MILLISECOND, 0); + c_midnight_oneday.add(Calendar.DATE, 1); // One day + + return c_midnight_oneday.getTimeInMillis() / 1000; + } + + public long getMidnightTwoDaysTimestamp() { + Calendar c_midnight_twodays = new GregorianCalendar(); + c_midnight_twodays.setTime(new Date()); + c_midnight_twodays.set(Calendar.HOUR_OF_DAY, 0); + c_midnight_twodays.set(Calendar.MINUTE, 0); + c_midnight_twodays.set(Calendar.SECOND, 0); + c_midnight_twodays.set(Calendar.MILLISECOND, 0); + c_midnight_twodays.add(Calendar.DATE, 2); // Two days + + return c_midnight_twodays.getTimeInMillis() / 1000; + } + + public void notifySessionsUpdated() { + Log.d("MeditationAssistant", "Sending session update notification"); + getPrefs().edit().putLong("sessionsupdate", getTimestamp()).apply(); + } + + public Integer timePreferenceValueToSeconds(String timePreferenceValue, String defaultValue) { + try { + String[] timeValueSplit = ((timePreferenceValue != null && timePreferenceValue != "") ? timePreferenceValue : defaultValue).split(":"); + return (Integer.valueOf(timeValueSplit[0]) * 60) + Integer.valueOf(timeValueSplit[1]); + } catch (Exception e) { + e.printStackTrace(); + } + + return 0; + } + + public ArrayList formatDuration(String duration) { + if (!duration.equals("")) { + String[] duration_separated = duration.split(":"); + String newHours = "-1"; + String newMinutes = "-1"; + + if (duration_separated.length > 1) { + if (!duration_separated[0].trim().equals("")) { + try { + newHours = String.valueOf(Integer + .valueOf(duration_separated[0])); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + newHours = "0"; + } + if (!duration_separated[1].trim().equals("")) { + try { + newMinutes = String.valueOf(Integer + .valueOf(duration_separated[1])); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + newMinutes = "0"; + } + } else { + try { + newMinutes = String.valueOf(Integer.valueOf(duration)); + newHours = "0"; + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (Integer.valueOf(newMinutes) >= 60) { + newHours = String.format("%d", + (int) (Integer.valueOf(newHours) + Math.floor(Integer + .valueOf(newMinutes) / 60)) + ); + newMinutes = String.format("%02d", + Integer.valueOf(newMinutes) % 60); + } + + if (!newHours.equals("-1") && !newMinutes.equals("-1") + && !(newHours.equals("0") && newMinutes.equals("0"))) { + ArrayList formatted_duration = new ArrayList(); + formatted_duration.add(newHours); + formatted_duration.add(String.format("%02d", + Integer.valueOf(newMinutes))); + + return formatted_duration; + } + } + + return null; + } + + public ArrayList formatDurationEndAt(String duration) { + if (!duration.equals("")) { + String[] duration_separated = duration.split(":"); + String newHours = "-1"; + String newMinutes = "-1"; + Boolean shorthand = false; + + if (duration_separated.length > 1) { + if (!duration_separated[0].trim().equals("")) { + try { + newHours = String.valueOf(Integer + .valueOf(duration_separated[0])); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + newHours = "0"; + } + if (!duration_separated[1].trim().equals("")) { + try { + newMinutes = String.valueOf(Integer + .valueOf(duration_separated[1])); + if (duration_separated[1].trim().length() < 2) { + shorthand = true; + } + } catch (Exception e) { + e.printStackTrace(); + } + } else { + newMinutes = "0"; + } + } else { + try { + newHours = String.valueOf(Integer.valueOf(duration)); + newMinutes = "0"; + } catch (Exception e) { + e.printStackTrace(); + } + } + + Log.d("MeditationAssistant", "Formatted end at duration newMinutes: " + newMinutes); + if (shorthand && Integer.valueOf(newMinutes) > 0 && Integer.valueOf(newMinutes) <= 5) { // shorthand 3 -> 30, 4 -> 40... + newMinutes = String.format("%02d", + Integer.valueOf(newMinutes) * 10); + } else if (Integer.valueOf(newMinutes) >= 60) { + newHours = String.format("%d", + (int) (Integer.valueOf(newHours) + Math.floor(Integer + .valueOf(newMinutes) / 60)) + ); + newMinutes = String.format("%02d", + Integer.valueOf(newMinutes) % 60); + } + + if (Integer.valueOf(newHours) == 0 || Integer.valueOf(newHours) > 24) { + return null; // Invalid hour for time + } else if (Integer.valueOf(newHours) > 12) { + newHours = String.valueOf(Integer.valueOf(newHours) - 12); // Subtract 12 hours if 24 hour time was provided + } + + if (!newHours.equals("-1") && !newMinutes.equals("-1") + && !(newHours.equals("0") && newMinutes.equals("0"))) { + ArrayList formatted_duration = new ArrayList(); + formatted_duration.add(newHours); + formatted_duration.add(String.format("%02d", + Integer.valueOf(newMinutes))); + + return formatted_duration; + } + } + + return null; + } + + public SharedPreferences getPrefs() { + if (prefs == null) { + prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + } + return prefs; + } + + public boolean getRememberDuration() { + if (rememberduration == null) { + rememberduration = getPrefs().getBoolean("pref_rememberlasttimer", true); + } + return rememberduration; + } + + public boolean getRunnableStopped() { + return runnablestopped; + } + + public void setRunnableStopped(boolean bool) { + runnablestopped = bool; + } + + public boolean getScreenOff() { + return screenoff; + } + + public void setScreenOff(boolean bool) { + screenoff = bool; + } + + public long getSessionDuration() { + return sessionduration; + } + + public void setSessionDuration(long duration) { + sessionduration = duration; + } + + public long getSessionsRunnableStartTime() { + return sessrunnablestarttime; + } + + public void setSessionsRunnableStartTime(long l) { + sessrunnablestarttime = l; + } + + public boolean getSessionsRunnableStopped() { + return sessrunnablestopped; + } + + public void setSessionsRunnableStopped(boolean bool) { + sessrunnablestopped = bool; + } + + public boolean getSessionsRunnableWasSignedOut() { + return sesswassignedout; + } + + public void setSessionsRunnableWasSignedOut(boolean bool) { + sesswassignedout = bool; + } + + public Long getTimestamp() { + return System.currentTimeMillis() / 1000; + } + + public long getTimeStartMeditate() { + return timeStartMeditate; + } + + public void setTimeStartMeditate(long l) { + timeStartMeditate = l; + pendingNotificationAction = ""; + // Log.d("MeditationAssistant", String.valueOf(timeToStopMeditate)); + } + + public long getTimeToStopMeditate() { + return timeToStopMeditate; + } + + public void setTimeToStopMeditate(long l) { + timeToStopMeditate = l; + getPrefs().edit().putLong("last_reminder", getTimestamp()).apply(); + //(new Exception()).printStackTrace(); + Log.d("MeditationAssistant", "Setting time to stop meditating: " + + String.valueOf(timeToStopMeditate)); + } + + public String getTimerMode() { + if (timerMode == null) { + timerMode = getPrefs().getString("pref_timer_mode", "timed"); + } + return timerMode; + } + + public void setTimerMode(String tm) { + timerMode = tm; + + getPrefs().edit().putString("pref_timer_mode", timerMode).apply(); + } + + public Integer getWebViewScale() { + if (webview_scale == null) { + webview_scale = getPrefs().getInt("webviewscale", 100); + } + return webview_scale; + } + + public void setWebViewScale(int scale) { + webview_scale = scale; + + getPrefs().edit().putInt("webviewscale", webview_scale).apply(); + } + + public void hideNotification() { + NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + notificationManager.cancelAll(); + } + + public void longToast(Activity activity, String text) { + try { + Looper.prepare(); + } catch (Exception e) { + //e.printStackTrace(); + } + + if (activity == null) { + Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG) + .show(); + } else { + toastActivity = activity; + toastText = text; + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(toastActivity, toastText, Toast.LENGTH_LONG) + .show(); + } + }); + } + } + + public void longToast(String text) { + longToast(null, text); + } + + @Override + public void onCreate() { + super.onCreate(); + + package_name = getApplicationContext().getPackageName(); + + Integer applaunches = getPrefs().getInt("applaunches", 0) + 1; + getPrefs().edit().putInt("applaunches", applaunches).apply(); + + Log.d("MeditationAssistant", + "Meditation Assistant running (" + applaunches + " launches) on API level " + + String.valueOf(Build.VERSION.SDK_INT) + ); + + // Reset timer to default values + if (!getPrefs().getBoolean("pref_rememberlasttimer", true)) { + SharedPreferences.Editor editor = getPrefs().edit(); + editor.putString("timerHours", + getPrefs().getString("timerDefaultHours", "15")); + editor.putString("timerMinutes", + getPrefs().getString("timerDefaultMinutes", "15")); + editor.apply(); + } + + // Upgrade to the new delay and interval preferences + /*long pref_delay = Integer.valueOf(getPrefs().getString("pref_delay", "-1")); + if (pref_delay >= 0) { + Log.d("MeditationAssistant", "Upgrading pref_delay to TimePreference: from " + String.valueOf(pref_delay) + " to " + String.format("%02d", pref_delay / 60) + ":" + String.format("%02d", pref_delay % 60)); + getPrefs().edit().putString("pref_session_delay", String.format("%02d", pref_delay / 60) + ":" + String.format("%02d", pref_delay % 60)).apply(); + getPrefs().edit().putString("pref_delay", "-1").apply(); + Log.d("MeditationAssistant", "New pref_session_delay value: " + getPrefs().getString("pref_session_delay", "00:15")); + + } + long pref_interval = Integer.valueOf(getPrefs().getString("pref_interval", "-1")); + if (pref_interval >= 0) { + Log.d("MeditationAssistant", "Upgrading pref_interval to TimePreference: from " + String.valueOf(pref_interval) + " to " + String.format("%02d", pref_interval / 60) + ":" + String.format("%02d", pref_interval % 60)); + getPrefs().edit().putString("pref_session_delay", String.format("%02d", pref_interval / 60) + ":" + String.format("%02d", pref_interval % 60)).apply(); + getPrefs().edit().putString("pref_interval", "-1").apply(); + }*/ + + db = DatabaseHandler.getInstance(getApplicationContext()); + CookieSyncManager.createInstance(getApplicationContext()); + + reminderAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + + /* Send the daily notification updated intent just in case the receiver hasn't been called yet */ + Log.d("MeditationAssistant", "Sending initial daily notification updated intent"); + Intent intent = new Intent(); + intent.setAction(MeditationAssistant.ACTION_UPDATED); + sendBroadcast(intent); + } + + public void setupGoogleClient(final Activity activity) { + //if (googleClient != null) { + /// return; + //} + Log.d("MeditationAssistant", "Setting up Google Fit"); + + googleClient = new GoogleApiClient.Builder(activity) + .addApi(Fitness.HISTORY_API) + .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE)) + .addConnectionCallbacks( + new GoogleApiClient.ConnectionCallbacks() { + + @Override + public void onConnected(Bundle bundle) { + Log.d("MeditationAssistant", "!!! Connected to Google Fit"); + // Now you can make calls to the Fitness APIs. + // Put application specific code here. + } + + @Override + public void onConnectionSuspended(int i) { + // If your connection to the sensor gets lost at some point, + // you'll be able to determine the reason and react to it here. + if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) { + Log.d("MeditationAssistant", "Connection lost. Cause: Network Lost."); + } else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) { + Log.d("MeditationAssistant", "Connection lost. Reason: Service Disconnected"); + } + } + } + ) + .addOnConnectionFailedListener( + new GoogleApiClient.OnConnectionFailedListener() { + // Called whenever the API client fails to connect. + @Override + public void onConnectionFailed(ConnectionResult result) { + Log.d("MeditationAssistant", "Connection failed. Cause: " + result.toString()); + if (!result.hasResolution()) { + // Show the localized error dialog + GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), + activity, 0).show(); + return; + } + // The failure has a resolution. Resolve it. + // Called typically when the app is not yet authorized, and an + // authorization dialog is displayed to the user. + if (!googleAPIAuthInProgress) { + try { + Log.d("MeditationAssistant", "Attempting to resolve failed connection"); + googleAPIAuthInProgress = true; + result.startResolutionForResult(activity, + REQUEST_FIT); + } catch (IntentSender.SendIntentException e) { + Log.d("MeditationAssistant", + "Exception while starting resolution activity", e); + } + } + } + } + ) + .build(); + } + + public void sendFitData() { + Calendar cal = Calendar.getInstance(); + Date now = new Date(); + cal.setTime(now); + long endTime = cal.getTimeInMillis(); + cal.add(Calendar.HOUR, -1); + long startTime = cal.getTimeInMillis(); + + Session session = new Session.Builder() + .setName("No name") + .setDescription("Duration: blah blah") + .setIdentifier("meditation" + "11231241") + .setActivity(FitnessActivities.MEDITATION) + .setStartTime(startTime, TimeUnit.MILLISECONDS) + .setEndTime(endTime, TimeUnit.MILLISECONDS) + .build(); + + SessionInsertRequest insertRequest = new SessionInsertRequest.Builder() + .setSession(session) + .build(); + + // Then, invoke the Sessions API to insert the session and await the result, +// which is possible here because of the AsyncTask. Always include a timeout when +// calling await() to avoid hanging that can occur from the service being shutdown +// because of low memory or other conditions. + Log.d("MeditationAssistant", "Inserting the session in the History API"); + com.google.android.gms.common.api.Status insertStatus = + Fitness.SessionsApi.insertSession(googleClient, insertRequest) + .await(1, TimeUnit.MINUTES); + +// Before querying the session, check to see if the insertion succeeded. + if (!insertStatus.isSuccess()) { + Log.d("MeditationAssistant", "There was a problem inserting the session: " + + insertStatus.getStatusMessage()); + return; + } + +// At this point, the session has been inserted and can be read. + Log.i("MeditationAssistant", "Session insert was successful!"); + } + + public boolean sendUsageReports() { + if (sendusage == null) { + sendusage = getPrefs().getBoolean("pref_sendusage", true); + } + return sendusage; + } + + public void setMediNETKey(String key, String provider) { + Log.d("MeditationAssistant", "Setting medinet key: " + key + " - " + provider); + medinetkey = key; + medinetprovider = provider; + long timestamp = System.currentTimeMillis() / 1000; + + SharedPreferences.Editor editor = getPrefs().edit(); + if (getPrefs().getBoolean("pref_rememberme", true)) { + Log.d("MeditationAssistant", "Storing medinet key: " + key + " - " + provider); + editor.putString("key", key); + editor.putString("provider", provider); + } + editor.putString("keyupdate", String.valueOf(timestamp)); + editor.apply(); + } + + public void setMeditationStreak(Integer ms, long expires) { + if (meditationstreak == null) { + meditationstreak = getMeditationStreak(); + } + if (ms >= meditationstreak) { + meditationstreak = ms; + meditationstreakexpires = expires; + + Calendar date = new GregorianCalendar(); + date.setTimeZone(TimeZone.getDefault()); + long timestamp = date.getTimeInMillis() / 1000; + Log.d("MeditationAssistant", + "Streak: " + String.valueOf(meditationstreak) + ", expires: " + + String.valueOf(expires) + " (in " + + String.valueOf(expires - timestamp) + " seconds)" + ); + + getPrefs().edit().putInt("meditationstreak", meditationstreak).putLong("meditationstreakexpires", meditationstreakexpires).apply(); + + if (meditationstreak > getLongestMeditationStreak()) { + setLongestMeditationStreak(meditationstreak); + } + + updateWidgets(); + } else { + Log.d("MeditationAssistant", + "Not setting new meditation streak, current streak is higher"); + } + + /* Update all widgets */ + Intent update_widgets = new Intent(getApplicationContext(), MeditationProvider.class); + update_widgets.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + sendBroadcast(update_widgets); + } + + public void pauseSession() { + pausestart = getTimestamp(); + ispaused = true; + } + + public long unPauseSession() { + if (!ispaused) { + return 0; + } + + long thispausetime; + if (getTimerMode().equals("endat")) { + thispausetime = Math.min(getTimeToStopMeditate(), getTimestamp()) - pausestart; + } else { + thispausetime = Math.max(0, getTimestamp() - pausestart); + } + pausetime += thispausetime; + + Log.d("MeditationAssistant", "PAUSE: Un-paused. Paused for " + String.valueOf(thispausetime) + " seconds (" + String.valueOf(pausetime) + " total)"); + + ispaused = false; + return thispausetime; + } + + public void shortToast(Activity activity, String text) { + try { + Looper.prepare(); + } catch (Exception e) { + //e.printStackTrace(); + } + + if (activity == null) { + Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT) + .show(); + } else { + toastActivity = activity; + toastText = text; + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(toastActivity, toastText, Toast.LENGTH_SHORT) + .show(); + } + }); + } + } + + public void shortToast(String text) { + shortToast(null, text); + } + + public AlertDialog showAnnouncementDialog(String title) { + try { + Looper.prepare(); + } catch (Exception e) { + //e.printStackTrace(); + } + + if (getMediNET().activity != null + && !getMediNET().announcement.equals("")) { + AlertDialog announceDialog = new AlertDialog.Builder( + getMediNET().activity) + .setPositiveButton(R.string.dismiss, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int id) { + + } + } + ) + .setTitle(title == null ? getString(R.string.announcement) : title) + .setMessage(medinet.announcement) + .setIcon( + getMediNET().activity + .getResources() + .getDrawable( + getTheme() + .obtainStyledAttributes( + getMATheme(true), + new int[]{R.attr.actionIconGoToToday}) + .getResourceId(0, 0) + ) + ) + .setCancelable(false).create(); + + announceDialog.show(); + + return announceDialog; + } + + return null; + } + + public void showNotification() { + if (!getPrefs().getBoolean("pref_notification", true) + || getTimeStartMeditate() < 1) { + hideNotification(); + return; + } + + Intent intent = new Intent(this, MainActivity.class); + intent.setAction("notification"); + // intent.putExtra("notificationButton", "notification"); + // intent.putExtra("notificationButton", ""); + PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, + PendingIntent.FLAG_UPDATE_CURRENT); + + Intent intent2 = new Intent(this, MainActivity.class); + // intent2.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + intent2.setAction("notificationPause"); + PendingIntent pIntentPause = PendingIntent.getActivity(this, 0, intent2, + PendingIntent.FLAG_UPDATE_CURRENT); + + Intent intent3 = new Intent(this, MainActivity.class); + // intent3.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + // intent3.putExtra("notificationButton", "end"); + intent3.setAction("notificationEnd"); + PendingIntent pIntentEnd = PendingIntent.getActivity(this, 0, intent3, + PendingIntent.FLAG_UPDATE_CURRENT); + + String streaktext = ""; + if (getMeditationStreak() > 1) { + streaktext = String.valueOf(getMeditationStreak()); + } + + String titleText = getString(R.string.sessionInProgress); + String contentText = getString(R.string.appName); + + /* + * if (!getDurationFormatted().equals("") && getTimeToStopMeditate() > + * (System .currentTimeMillis() / 1000)) { titleText = + * getDurationFormatted(); contentText = + * getString(R.string.sessionInProgress); } + */ + + Notification notification = new NotificationCompat.Builder(this) + .setOngoing(true) + .setSmallIcon(R.drawable.ic_notification) + .setContentTitle(titleText) + .setContentText(contentText) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setContentInfo(streaktext) + .setContentIntent(pIntent) + .addAction(R.drawable.ic_action_pause, + getString(R.string.pause), pIntentPause) + .addAction(R.drawable.ic_action_stop, + getString(R.string.end), pIntentEnd).build(); + + // .setContentText(contentText).setOngoing(true) + // .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), + // notification_icon)) + NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + notificationManager.notify(0, notification); + } + + public AlertDialog showSignInDialog(final Activity activity) { + signin_activity = activity; + + AccountManager accountManager = AccountManager + .get(getApplicationContext()); + final Account[] accounts = accountManager + .getAccountsByType("com.google"); + + final int size = accounts.length; + + if (size > 0) { + String[] names = new String[size + 1]; + int i = 0; + for (i = 0; i < size; i++) { + names[i] = accounts[i].name; + } + names[i] = getString(R.string.signInWithOpenID); + + AlertDialog accountsAlertDialog = new AlertDialog.Builder(activity) + .setTitle(getString(R.string.signInWith)) + .setItems(names, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + if (which != size) { + AccountManager am = AccountManager.get(getApplicationContext()); + + if (am != null) { + am.getAuthToken(accounts[which], AUTH_TOKEN_TYPE, null, signin_activity, new OnTokenAcquired(), new Handler(new Handler.Callback() { + + public boolean handleMessage(Message msg) { + Log.d("MeditationAssistant", "on error: " + msg.what); + shortToast(getString(R.string.signInGoogleError)); + return false; + } + })); + } + } else { + showOpenIDSignInDialog(activity); + } + } + }) + .create(); + accountsAlertDialog.show(); + + return accountsAlertDialog; + } else { + return showOpenIDSignInDialog(activity); + } + } + + public AlertDialog showOpenIDSignInDialog(Activity activity) { + if (alertDialog != null && alertDialog.getOwnerActivity() != null + && alertDialog.getOwnerActivity() == activity) { + Log.d("MeditationAssistant", + "Attempting to reuse MediNET sign in dialog"); + + try { + if (!alertDialog.isShowing()) { + alertDialog.show(); + } + + Log.d("MeditationAssistant", "Reusing MediNET sign in dialog"); + return alertDialog; + } catch (WindowManager.BadTokenException e) { + // Activity is not in the foreground + } + } + + int[] buttons = {R.id.btnGoogle, R.id.btnFacebook, R.id.btnAOL, + R.id.btnTwitter, R.id.btnLive, R.id.btnOpenID}; + + View view = LayoutInflater.from(activity).inflate( + R.layout.medinet_signin, + (ViewGroup) activity.findViewById(R.id.medinetsignin_root)); + + for (int buttonid : buttons) { + ImageButton btn = (ImageButton) view.findViewById(buttonid); + + if (btn.getId() == R.id.btnGoogle) { + if (!getMAThemeString().equals("dark")) { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_google_light)); + } else { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_google)); + } + } else if (btn.getId() == R.id.btnFacebook) { + if (!getMAThemeString().equals("dark")) { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_facebook_light)); + } else { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_facebook)); + } + } else if (btn.getId() == R.id.btnAOL) { + if (!getMAThemeString().equals("dark")) { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_aol_light)); + } else { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_aol)); + } + } else if (btn.getId() == R.id.btnTwitter) { + if (!getMAThemeString().equals("dark")) { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_twitter_light)); + } else { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_twitter)); + } + } else if (btn.getId() == R.id.btnLive) { + if (!getMAThemeString().equals("dark")) { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_live_light)); + } else { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_live)); + } + } else if (btn.getId() == R.id.btnOpenID) { + if (!getMAThemeString().equals("dark")) { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_openid_light)); + } else { + btn.setImageDrawable(getResources().getDrawable( + R.drawable.logo_openid)); + } + } + + btn.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + ImageButton img = (ImageButton) v; + Intent intent = new Intent(getApplicationContext(), + MediNETActivity.class); + + if (img.getId() == R.id.btnGoogle) { + intent.putExtra("provider", "Google"); + } else if (img.getId() == R.id.btnFacebook) { + intent.putExtra("provider", "Facebook"); + } else if (img.getId() == R.id.btnAOL) { + intent.putExtra("provider", "AOL"); + } else if (img.getId() == R.id.btnTwitter) { + intent.putExtra("provider", "Twitter"); + } else if (img.getId() == R.id.btnLive) { + intent.putExtra("provider", "Live"); + } else if (img.getId() == R.id.btnOpenID) { + intent.putExtra("provider", "OpenID"); + } + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + if (alertDialog != null) { + try { + alertDialog.dismiss(); + } catch (Exception e) { + // Do nothing + } + } + + startActivity(intent); + } + }); + } + + alertDialog = new AlertDialog.Builder(activity) + .setView(view) + .setTitle(R.string.signInToMediNET) + .setIcon( + activity.getResources().getDrawable( + getTheme().obtainStyledAttributes(getMATheme(true), + new int[]{R.attr.actionIconForward}) + .getResourceId(0, 0) + ) + ).create(); + alertDialog + .setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + if (getMediNETKey() == "") { + getMediNET().status = "disconnected"; + getMediNET().updated(); + } + } + }); + alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + if (getMediNETKey() == "") { + getMediNET().status = "disconnected"; + getMediNET().updated(); + } + } + }); + + alertDialog.show(); + return alertDialog; + } + + public AlertDialog showStaleDataDialog() { + Log.d("MeditationAssistant", "Showing stale data dialog"); + + try { + Looper.prepare(); + } catch (Exception e) { + //e.printStackTrace(); + } + + if (getMediNET().activity != null) { + AlertDialog staleDataDialog = new AlertDialog.Builder( + getMediNET().activity) + .setPositiveButton(R.string.wordimport, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int id) { + getMediNET().syncSessions(); + } + } + ) + .setNegativeButton(R.string.dismiss, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int id) { + // Do nothing + } + } + ) + .setTitle(R.string.importsessionstitle) + .setMessage(R.string.importsessionsmessage) + .setIcon( + getMediNET().activity + .getResources() + .getDrawable( + getTheme() + .obtainStyledAttributes( + getMATheme(true), + new int[]{R.attr.actionIconDownCloud}) + .getResourceId(0, 0) + ) + ) + .create(); + + staleDataDialog.show(); + + return staleDataDialog; + } else { + longToast(getString(R.string.importSessionsHint)); + } + + return null; + } + + public void updateWidgets() { + AppWidgetManager man = AppWidgetManager + .getInstance(getApplicationContext()); + /*int[] ids = man.getAppWidgetIds(new ComponentName( + getApplicationContext(), MeditationProvider.class));*/ + Intent updateIntent = new Intent(); + updateIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + getApplicationContext().sendBroadcast(updateIntent); + } + + public Boolean vibrationEnabled() { + return (getPrefs().getBoolean("pref_vibrate", false) && canVibrate()); + } + + public void vibrateDevice() { + if (vibrationEnabled()) { + try { + Vibrator vi = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); + long[] pattern = {225, 110, 225, 110, 225, 110}; + vi.vibrate(pattern, -1); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public String getMAAppVersion() { + if (appVersion == null) { + appVersion = ""; + try { + PackageInfo pInfo = getPackageManager().getPackageInfo( + getPackageName(), 0); + appVersion = pInfo.versionName; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + } + + return appVersion; + } + + public int getMAAppVersionNumber() { + return BuildConfig.VERSION_CODE; + } + + public Boolean getMAIsAppFull() { + if (appFull == null) { + appFull = !(getPackageName().equals( + "sh.ftp.rocketninelabs.meditationassistant")); + } + + return appFull; + } + + public enum TrackerName { + APP_TRACKER, // Tracker used only in this app. + GLOBAL_TRACKER, // Tracker used by all the apps from a company. eg: roll-up tracking. + ECOMMERCE_TRACKER, // Tracker used by all ecommerce transactions from a company. + } + + private class OnTokenAcquired implements AccountManagerCallback { + @Override + public void run(AccountManagerFuture result) { + + Intent launch = null; + try { + launch = (Intent) result.getResult().get(AccountManager.KEY_INTENT); + + if (launch == null) { + String authtoken = result.getResult().getString(AccountManager.KEY_AUTHTOKEN); + if (!authtoken.equals("")) { + getMediNET().signInWithAuthToken(authtoken); + } + } + } catch (OperationCanceledException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (AuthenticatorException e) { + e.printStackTrace(); + } + if (launch != null) { + signin_activity.startActivityForResult(launch, 0); + } + } + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider.java new file mode 100644 index 0000000..63192fe --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider.java @@ -0,0 +1,87 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +public class MeditationProvider extends AppWidgetProvider { + + private int[] mergeInts(int[] arg1, int[] arg2) { + int[] result = new int[arg1.length + arg2.length]; + System.arraycopy(arg1, 0, result, 0, arg1.length); + System.arraycopy(arg2, 0, result, arg1.length, arg2.length); + return result; + } + + @Override + public void onEnabled(Context context) { + Log.d("MeditationAssistant", "Widget onEnabled"); + super.onEnabled(context); + } + + @Override + public void onReceive(Context context, Intent intent) { + super.onReceive(context, intent); + if (intent != null) { + Log.d("MeditationAssistant", "Provider intent: " + intent.toString()); + } + + if (intent != null + && intent.getAction() != null + && intent.getAction().equals( + AppWidgetManager.ACTION_APPWIDGET_UPDATE)) { + AppWidgetManager gm = AppWidgetManager.getInstance(context); + int[] ids = gm.getAppWidgetIds(new ComponentName(context, + MeditationProvider.class)); + ids = mergeInts(ids, gm.getAppWidgetIds(new ComponentName(context, + MeditationProvider2.class))); + ids = mergeInts(ids, gm.getAppWidgetIds(new ComponentName(context, + MeditationProvider3.class))); + + onUpdate(context, gm, ids); + } + } + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, + int[] appWidgetIds) { + Intent intent = new Intent(context, MeditationService.class); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); + context.startService(intent); + + String ids_formatted = ""; + for (int id : appWidgetIds) { + ids_formatted += ", " + String.valueOf(id); + } + Log.d("MeditationAssistant", "Widget onUpdate, service started for IDs: " + ids_formatted); + + super.onUpdate(context, appWidgetManager, appWidgetIds); + + + /* + * int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); + * for (int widgetId : allWidgetIds) { RemoteViews remoteViews = new + * RemoteViews(context.getPackageName(), R.layout.widget_layout); + * + * SActivity ctx = (SActivity) context; Log.d("MeditationAssistant", + * "!!!" + ctx.getApplication().toString()); // Set the text + * remoteViews.setTextViewText(R.id.txtDays, ctx.getApplication() + * .toString()); + * + * // Register an onClickListener // Intent intent = new Intent(context, + * MeditationProvider.class); + * + * // intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); // + * intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, // + * appWidgetIds); + * + * // PendingIntent pendingIntent = PendingIntent.getBroadcast(context, + * // 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); // + * remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent); + * appWidgetManager.updateAppWidget(widgetId, remoteViews); } + */ + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider1.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider1.java new file mode 100644 index 0000000..45d026d --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider1.java @@ -0,0 +1,5 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +public class MeditationProvider1 extends MeditationProvider { + +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider2.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider2.java new file mode 100644 index 0000000..ee835bc --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider2.java @@ -0,0 +1,5 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +public class MeditationProvider2 extends MeditationProvider { + +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider3.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider3.java new file mode 100644 index 0000000..41bde2d --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationProvider3.java @@ -0,0 +1,5 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +public class MeditationProvider3 extends MeditationProvider { + +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationService.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationService.java new file mode 100644 index 0000000..3f55318 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationService.java @@ -0,0 +1,76 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.app.PendingIntent; +import android.app.Service; +import android.appwidget.AppWidgetManager; +import android.content.Intent; +import android.os.IBinder; +import android.util.Log; +import android.widget.RemoteViews; + +public class MeditationService extends Service { + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this + .getApplicationContext()); + Log.d("MeditationAssistant", "Widget onStartCommand(): " + String.valueOf(intent)); + + if (intent == null) { + Log.d("MeditationAssistant", "Widget intent was null, exiting..."); + return START_STICKY; + } + + int[] allWidgetIds = intent + .getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS); + + /* + * ComponentName thisWidget = new ComponentName(getApplicationContext(), + * MeditationProvider.class); + */ + + for (int widgetId : allWidgetIds) { + RemoteViews updateViews = new RemoteViews(this.getPackageName(), + R.layout.widget_layout); + getApplication(); + + MeditationAssistant ma = (MeditationAssistant) this + .getApplication(); + + if (ma.getMeditationStreak() > 0) { + updateViews.setTextViewText(R.id.txtWidgetDays, + String.valueOf(ma.getMeditationStreak())); + updateViews.setTextViewText( + R.id.txtWidgetText, + getResources().getQuantityString( + R.plurals.daysOfMeditationWithoutCount, + ma.getMeditationStreak()) + ); + } else { + updateViews.setTextViewText(R.id.txtWidgetDays, + getString(R.string.ignore_om)); + updateViews.setTextViewText(R.id.txtWidgetText, + getString(R.string.meditateToday)); + } + + Intent clickintent = new Intent(getApplicationContext(), + MainActivity.class); + // clickintent.putExtra("widgetid", startId); + clickintent.setAction("widgetclick"); + PendingIntent pendingIntent = PendingIntent.getActivity( + getApplicationContext(), 0, clickintent, 0); + updateViews.setOnClickPendingIntent(R.id.layWidget, pendingIntent); + updateViews.setOnClickPendingIntent(R.id.txtWidgetDays, + pendingIntent); + updateViews.setOnClickPendingIntent(R.id.txtWidgetText, + pendingIntent); + + appWidgetManager.updateAppWidget(widgetId, updateViews); + } + + return START_STICKY; + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationSession.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationSession.java new file mode 100644 index 0000000..c0aeff0 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationSession.java @@ -0,0 +1,30 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import org.json.JSONException; +import org.json.JSONObject; + +public class MeditationSession { + public long id = 0; + public long length = 0; + public long started = 0; + public long completed = 0; + public long streakday = 0; + public String date = ""; + public String time = ""; + public String message = ""; + + public JSONObject export() { + JSONObject jobj = new JSONObject(); + try { + jobj.put("id", id); + jobj.put("length", length); + jobj.put("started", started); + jobj.put("completed", completed); + jobj.put("streakday", streakday); + jobj.put("message", message); + } catch (JSONException e1) { + e1.printStackTrace(); + } + return jobj; + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationSounds.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationSounds.java new file mode 100644 index 0000000..1c99e11 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MeditationSounds.java @@ -0,0 +1,45 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +public class MeditationSounds { + public static int getMeditationSound(String sound) { + if (sound.equals("gong")) { + return R.raw.gong; + } else if (sound.equals("gong_burmese")) { + return R.raw.gong_burmese; + } else if (sound.equals("gong_metal")) { + return R.raw.gong_metal; + } else if (sound.equals("gong_heavy")) { + return R.raw.gong_heavy; + } else if (sound.equals("bell_indian")) { + return R.raw.bell_indian; + } else if (sound.equals("bell_temple")) { + return R.raw.bell_temple; + } else if (sound.equals("tinsha")) { + return R.raw.tinsha; + } else if (sound.equals("None")) { + return 0; + } + return R.raw.gong; + } + + public static String getMeditationSoundName(String sound) { // TODO: Localize + if (sound.equals("gong")) { + return "Gong"; + } else if (sound.equals("gong_burmese")) { + return "Burmese gong"; + } else if (sound.equals("gong_metal")) { + return "Metal gong"; + } else if (sound.equals("gong_heavy")) { + return "Heavy gong"; + } else if (sound.equals("bell_indian")) { + return "Indian bell"; + } else if (sound.equals("bell_temple")) { + return "Temple bell"; + } else if (sound.equals("tinsha")) { + return "Three Tinsha"; + } else if (sound.equals("none")) { + return ""; + } + return "Gong"; + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MonthAdapter.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MonthAdapter.java new file mode 100644 index 0000000..611d3ea --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MonthAdapter.java @@ -0,0 +1,17 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.content.Context; +import android.util.DisplayMetrics; +import android.view.View; + +public class MonthAdapter extends MonthAdapterMA { + + public MonthAdapter(Context c, int month, int year, DisplayMetrics metrics, ProgressActivity _pa, + MeditationAssistant _ma) { + super(c, month, year, metrics, _pa, _ma); + } + + @Override + protected void onDate(int[] date, int position, View item) { + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MonthAdapterMA.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MonthAdapterMA.java new file mode 100644 index 0000000..236d53b --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/MonthAdapterMA.java @@ -0,0 +1,303 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.content.Context; +import android.graphics.Paint; +import android.graphics.Typeface; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.List; + +public abstract class MonthAdapterMA extends BaseAdapter { + private final int[] mDaysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, + 31, 30, 31}; + private GregorianCalendar mCalendar; + private Calendar mCalendarToday; + private Context mContext; + private DisplayMetrics mDisplayMetrics; + private List mItems; + private int mMonth; + private int mYear; + private int mDaysShown; + private int mDaysLastMonth; + private int mDaysNextMonth; + private int mDayHeight; + private String[] mDays = null; + private MeditationAssistant ma = null; + private ProgressActivity pa = null; + + public MonthAdapterMA(Context c, int month, int year, + DisplayMetrics metrics, ProgressActivity _pa, MeditationAssistant _ma) { + mContext = c; + mDayHeight = MeditationAssistant.dpToPixels(50, mContext); + + mMonth = month; + mYear = year; + mCalendar = new GregorianCalendar(mYear, mMonth, 1); + mCalendarToday = Calendar.getInstance(); + mDisplayMetrics = metrics; + ma = _ma; + pa = _pa; + + mDays = new String[]{mContext.getString(R.string.dayMondayShort), + mContext.getString(R.string.dayTuesdayShort), + mContext.getString(R.string.dayWednesdayShort), + mContext.getString(R.string.dayThursdayShort), + mContext.getString(R.string.dayFridayShort), + mContext.getString(R.string.daySaturdayShort), + mContext.getString(R.string.daySundayShort)}; + populateMonth(); + } + + private int daysInMonth(int month) { + int daysInMonth = mDaysInMonth[month]; + if (month == 1 && mCalendar.isLeapYear(mYear)) + daysInMonth++; + return daysInMonth; + } + + private int getBarHeight() { + switch (mDisplayMetrics.densityDpi) { + case DisplayMetrics.DENSITY_HIGH: + return 48; + case DisplayMetrics.DENSITY_MEDIUM: + return 32; + case DisplayMetrics.DENSITY_LOW: + return 24; + default: + return 48; + } + } + + @Override + public int getCount() { + return mItems.size(); + } + + private int[] getDate(int position) { + int date[] = new int[3]; + if (position <= 6) { + return null; // day names + } else if (position <= mDaysLastMonth + 6) { + // previous month + date[0] = Integer.parseInt(mItems.get(position)); + if (mMonth == 0) { + date[1] = 11; + date[2] = mYear - 1; + } else { + date[1] = mMonth - 1; + date[2] = mYear; + } + } else if (position <= mDaysShown - mDaysNextMonth) { + // current month + date[0] = position - (mDaysLastMonth + 6); + date[1] = mMonth; + date[2] = mYear; + } else { + // next month + date[0] = Integer.parseInt(mItems.get(position)); + if (mMonth == 11) { + date[1] = 0; + date[2] = mYear + 1; + } else { + date[1] = mMonth + 1; + date[2] = mYear; + } + } + return date; + } + + private int getDay(int day) { + switch (day) { + case Calendar.MONDAY: + return 0; + case Calendar.TUESDAY: + return 1; + case Calendar.WEDNESDAY: + return 2; + case Calendar.THURSDAY: + return 3; + case Calendar.FRIDAY: + return 4; + case Calendar.SATURDAY: + return 5; + case Calendar.SUNDAY: + return 6; + default: + return 0; + } + } + + @Override + public Object getItem(int position) { + return mItems.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + public MeditationAssistant getMeditationAssistant() { + return ma; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + final TextView view = new TextView(mContext); + view.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL); + view.setText(mItems.get(position)); + + int[] date = getDate(position); + if (date != null) { + view.setTextSize(20); + String date_formatted = String.valueOf(date[0]) + "-" + + String.valueOf(date[1] + 1) + "-" + + String.valueOf(date[2]); + + int numSessions = getMeditationAssistant().db.numSessionsByDate(date_formatted); + if (numSessions > 0) { + // At least one meditation session exists for this date + + view.setTag(R.id.calendarDate, date); + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + int[] date = (int[]) view.getTag(R.id.calendarDate); + if (date != null) { + pa.goToSessionAtDate(date); + } + } + }); + + if (getMeditationAssistant().getMAThemeString().equals("dark")) { + /*int bgcolor = (date[1] == mMonth) ? R.color.highlighted_text_light + : R.color.dim_foreground_light;*/ + int bgcolor = (date[1] == mMonth) ? android.R.color.holo_blue_dark + : android.R.color.secondary_text_dark; + + // : android.R.color.dim_foreground_light; + + view.setBackgroundColor(getMeditationAssistant() + .getResources().getColor(bgcolor)); + } else { + int bgcolor = (date[1] == mMonth) ? R.color.highlighted_text_dark + : R.color.dim_foreground_dark; + //: R.color.dim_foreground_holo_dark; + + view.setBackgroundColor(getMeditationAssistant() + .getResources().getColor(bgcolor)); + } + + if (numSessions > 1) { // Make large and bold if there's more than one session + view.setTypeface(null, Typeface.BOLD); + view.setTextSize(23); + } + } + + view.setHeight(mDayHeight); + if (date[1] != mMonth) { // previous or next month + if (getMeditationAssistant().getMAThemeString().equals("dark")) { + view.setTextColor(getMeditationAssistant().getResources() + .getColor(android.R.color.tertiary_text_light)); + } else { + view.setTextColor(getMeditationAssistant().getResources() + .getColor(android.R.color.tertiary_text_dark)); + } + } else { // current month + view.setTextColor(getMeditationAssistant() + .getResources() + .getColor( + getMeditationAssistant() + .getTheme() + .obtainStyledAttributes( + getMeditationAssistant() + .getMATheme(), + new int[]{android.R.attr.textColorPrimary} + ) + .getResourceId(0, 0) + )); + + if (isToday(date[0], date[1], date[2])) { + view.setPaintFlags(view.getPaintFlags() + | Paint.UNDERLINE_TEXT_FLAG); + } + } + } else { + view.setTextSize(16); + view.setPadding(0, 0, 0, + MeditationAssistant.dpToPixels(1, mContext)); + view.setTypeface(null, Typeface.BOLD); + view.setTextColor(getMeditationAssistant().getResources().getColor( + getMeditationAssistant() + .getTheme() + .obtainStyledAttributes( + getMeditationAssistant().getMATheme(), + new int[]{android.R.attr.textColorPrimary}) + .getResourceId(0, 0) + )); + view.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP); + } + + onDate(date, position, view); + return view; + } + + @Override + public boolean isEnabled(int position) { + return false; + } + + private boolean isToday(int day, int month, int year) { + return mCalendarToday.get(Calendar.MONTH) == month + && mCalendarToday.get(Calendar.YEAR) == year + && mCalendarToday.get(Calendar.DAY_OF_MONTH) == day; + } + + /** + * @param date - null if day title (0 - dd / 1 - mm / 2 - yy) + * @param position - position in item list + * @param item - view for date + */ + protected abstract void onDate(int[] date, int position, View item); + + private void populateMonth() { + mItems = new ArrayList(); + for (String day : mDays) { + mItems.add(day); + mDaysShown++; + } + + int firstDay = getDay(mCalendar.get(Calendar.DAY_OF_WEEK)); + int prevDay; + if (mMonth == 0) + prevDay = daysInMonth(11) - firstDay + 1; + else + prevDay = daysInMonth(mMonth - 1) - firstDay + 1; + for (int i = 0; i < firstDay; i++) { + mItems.add(String.valueOf(prevDay + i)); + mDaysLastMonth++; + mDaysShown++; + } + + int daysInMonth = daysInMonth(mMonth); + for (int i = 1; i <= daysInMonth; i++) { + mItems.add(String.valueOf(i)); + mDaysShown++; + } + + mDaysNextMonth = 1; + while (mDaysShown % 7 != 0) { + mItems.add(String.valueOf(mDaysNextMonth)); + mDaysShown++; + mDaysNextMonth++; + } + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/NumToWord.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/NumToWord.java new file mode 100644 index 0000000..b68b5ee --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/NumToWord.java @@ -0,0 +1,94 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import java.util.Scanner; + +public class NumToWord { + // array containing single digits + public static final String[] digits = {"", "one", "two", "three", "four", + "five", "six", "seven", "eight", "nine", + }; + + // array containing teens + public static final String[] teens = {"eleven", "twelve", "thirteen", + "fourteen", " fifteen", "sixteen", "seventeen", "eighteen", + "nineteen"}; + + // array containing tens numbers + public static final String[] tens = {"ten", "twenty", "therty", "fourty", + "fifty", "sixty", "seventy", "eighty", "ninety",}; + + // string for hundreds numbers + public static final String hundred = "hundred"; + + public static int tmpDigit, // temp number to store digits + tmpTeen, // temp to store teens numbers + tmpTen, // temp number to store tens + number, // number to be converted to words + result; // result number + // deciding whether a num is teen or not + public static boolean teen = false; + + public static String getWord(int num) { + if (num > 0 && num < 10) { + result = num % 10; + return digits[result]; + } + if (num > 10 && num < 20) { + result = num % 10; + return teens[result - 1]; + } + if (num > 19 && num < 100) { + result = num / 10; + return tens[result - 1] + digits[num % 10]; + } + return ""; + } + + public static void main(String[] args) { + + Scanner in = new Scanner(System.in); + + // getting user input + System.out.print("Please enter a number: "); + number = in.nextInt(); // number to be converted + // input validation + while (number <= 0) { + System.out.println("Number should be bigger than cero!"); + System.out.print("Please enter a number:"); + number = in.nextInt(); + } + // converting single digits number + if (number > 0 && number < 10) { + result = number % 10; + System.out.println(digits[result]); + } + // converting teen numbers + if (number > 10 && number < 20) { + result = number % 10; + System.out.println(teens[result - 1]); + } + // converting from 20 to 100 numbers + if (number > 19 && number < 100) { + result = number / 10; // finding tens + System.out.print(tens[result - 1]); + + number %= 10; // finding single digits + System.out.println(digits[number]); + } + // converting from 101 to 999 + if (number > 100 && number < 1000) { + result = number / 100; // getting hundreds + // getting tens, and finding tens, and teens numbers + tmpTen = number % 100; + if (tmpTen > 1 && tmpTen < 20)// if teen go get it + { + tmpTeen = tmpTen % 10; + teen = true; + } else + // if not a teen split number + tmpTen /= 10; + // finding digits + tmpDigit = number % 10; + } + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/NumberPicker.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/NumberPicker.java new file mode 100644 index 0000000..9907169 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/NumberPicker.java @@ -0,0 +1,2642 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +/* + * Copyright (C) 2008 The Android Open Source Project + * + * 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. + */ + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Paint.Align; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.text.InputFilter; +import android.text.InputType; +import android.text.Spanned; +import android.text.TextUtils; +import android.text.method.NumberKeyListener; +import android.util.AttributeSet; +import android.util.SparseArray; +import android.util.TypedValue; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.LayoutInflater.Filter; +import android.view.MotionEvent; +import android.view.VelocityTracker; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.AccessibilityNodeInfo; +import android.view.accessibility.AccessibilityNodeProvider; +import android.view.animation.DecelerateInterpolator; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.text.DecimalFormatSymbols; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +//import android.annotation.Widget; + +/** + * A widget that enables the user to select a number form a predefined range. + * There are two flavors of this widget and which one is presented to the user + * depends on the current theme. + *
    + *
  • + * If the current theme is derived from {@link android.R.style#Theme} the widget + * presents the current value as an editable input field with an increment button + * above and a decrement button below. Long pressing the buttons allows for a quick + * change of the current value. Tapping on the input field allows to type in + * a desired value. + *
  • + *
  • + * If the current theme is derived from {@link android.R.style#Theme_Holo} or + * {@link android.R.style#Theme_Holo_Light} the widget presents the current + * value as an editable input field with a lesser value above and a greater + * value below. Tapping on the lesser or greater value selects it by animating + * the number axis up or down to make the chosen value current. Flinging up + * or down allows for multiple increments or decrements of the current value. + * Long pressing on the lesser and greater values also allows for a quick change + * of the current value. Tapping on the current value allows to type in a + * desired value. + *
  • + *
+ *

+ * For an example of using this widget, see {@link android.widget.TimePicker}. + *

+ */ +//@Widget +@SuppressWarnings("*") +public class NumberPicker extends LinearLayout { + + /** + * The number of items show in the selector wheel. + */ + private static final int SELECTOR_WHEEL_ITEM_COUNT = 3; + + /** + * The default update interval during long press. + */ + private static final long DEFAULT_LONG_PRESS_UPDATE_INTERVAL = 300; + + /** + * The index of the middle selector item. + */ + private static final int SELECTOR_MIDDLE_ITEM_INDEX = SELECTOR_WHEEL_ITEM_COUNT / 2; + + /** + * The coefficient by which to adjust (divide) the max fling velocity. + */ + private static final int SELECTOR_MAX_FLING_VELOCITY_ADJUSTMENT = 8; + + /** + * The the duration for adjusting the selector wheel. + */ + private static final int SELECTOR_ADJUSTMENT_DURATION_MILLIS = 800; + + /** + * The duration of scrolling while snapping to a given position. + */ + private static final int SNAP_SCROLL_DURATION = 300; + + /** + * The strength of fading in the top and bottom while drawing the selector. + */ + private static final float TOP_AND_BOTTOM_FADING_EDGE_STRENGTH = 0.9f; + + /** + * The default unscaled height of the selection divider. + */ + private static final int UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT = 2; + + /** + * The default unscaled distance between the selection dividers. + */ + private static final int UNSCALED_DEFAULT_SELECTION_DIVIDERS_DISTANCE = 48; + + /** + * The resource id for the default layout. + */ + private static final int DEFAULT_LAYOUT_RESOURCE_ID = 0; + + /** + * Constant for unspecified size. + */ + private static final int SIZE_UNSPECIFIED = -1; + private static final TwoDigitFormatter sTwoDigitFormatter = new TwoDigitFormatter(); + /** + * The numbers accepted by the input text's {@link Filter} + */ + private static final char[] DIGIT_CHARACTERS = new char[]{ + // Latin digits are the common case + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + // Arabic-Indic + '\u0660', '\u0661', '\u0662', '\u0663', '\u0664', '\u0665', '\u0666', '\u0667', '\u0668' + , '\u0669', + // Extended Arabic-Indic + '\u06f0', '\u06f1', '\u06f2', '\u06f3', '\u06f4', '\u06f5', '\u06f6', '\u06f7', '\u06f8' + , '\u06f9' + }; + /** + * The increment button. + */ + private final ImageButton mIncrementButton; + /** + * The decrement button. + */ + private final ImageButton mDecrementButton; + /** + * The text for showing the current value. + */ + private final EditText mInputText; + /** + * The distance between the two selection dividers. + */ + private final int mSelectionDividersDistance; + /** + * The min height of this widget. + */ + private final int mMinHeight; + /** + * The max height of this widget. + */ + private final int mMaxHeight; + /** + * The max width of this widget. + */ + private final int mMinWidth; + /** + * Flag whether to compute the max width. + */ + private final boolean mComputeMaxWidth; + /** + * The height of the text. + */ + private final int mTextSize; + /** + * Cache for the string representation of selector indices. + */ + private final SparseArray mSelectorIndexToStringCache = new SparseArray(); + /** + * The selector indices whose value are show by the selector. + */ + private final int[] mSelectorIndices = new int[SELECTOR_WHEEL_ITEM_COUNT]; + /** + * The {@link Paint} for drawing the selector. + */ + private final Paint mSelectorWheelPaint; + /** + * The {@link Drawable} for pressed virtual (increment/decrement) buttons. + */ + private final Drawable mVirtualButtonPressedDrawable; + /** + * The {@link Scroller} responsible for flinging the selector. + */ + private final Scroller mFlingScroller; + /** + * The {@link Scroller} responsible for adjusting the selector. + */ + private final Scroller mAdjustScroller; + /** + * The back ground color used to optimize scroller fading. + */ + private final int mSolidColor; + /** + * Flag whether this widget has a selector wheel. + */ + private final boolean mHasSelectorWheel; + /** + * Divider for showing item to be selected while scrolling + */ + private final Drawable mSelectionDivider; + /** + * The height of the selection divider. + */ + private final int mSelectionDividerHeight; + /** + * Helper class for managing pressed state of the virtual buttons. + */ + private final PressedStateHelper mPressedStateHelper; + /** + * The max width of this widget. + */ + private int mMaxWidth; + /** + * The height of the gap between text elements if the selector wheel. + */ + private int mSelectorTextGapHeight; + /** + * The values to be displayed instead the indices. + */ + private String[] mDisplayedValues; + /** + * Lower value of the range of numbers allowed for the NumberPicker + */ + private int mMinValue; + /** + * Upper value of the range of numbers allowed for the NumberPicker + */ + private int mMaxValue; + /** + * Current value of this NumberPicker + */ + private int mValue; + /** + * Listener to be notified upon current value change. + */ + private OnValueChangeListener mOnValueChangeListener; + /** + * Listener to be notified upon scroll state change. + */ + private OnScrollListener mOnScrollListener; + /** + * Formatter for for displaying the current value. + */ + private Formatter mFormatter; + /** + * The speed for updating the value form long press. + */ + private long mLongPressUpdateInterval = DEFAULT_LONG_PRESS_UPDATE_INTERVAL; + /** + * The height of a selector element (text + gap). + */ + private int mSelectorElementHeight; + /** + * The initial offset of the scroll selector. + */ + private int mInitialScrollOffset = Integer.MIN_VALUE; + /** + * The current offset of the scroll selector. + */ + private int mCurrentScrollOffset; + /** + * The previous Y coordinate while scrolling the selector. + */ + private int mPreviousScrollerY; + /** + * Handle to the reusable command for setting the input text selection. + */ + private SetSelectionCommand mSetSelectionCommand; + /** + * Handle to the reusable command for changing the current value from long + * press by one. + */ + private ChangeCurrentByOneFromLongPressCommand mChangeCurrentByOneFromLongPressCommand; + /** + * Command for beginning an edit of the current value via IME on long press. + */ + private BeginSoftInputOnLongPressCommand mBeginSoftInputOnLongPressCommand; + /** + * The Y position of the last down event. + */ + private float mLastDownEventY; + /** + * The time of the last down event. + */ + private long mLastDownEventTime; + /** + * The Y position of the last down or move event. + */ + private float mLastDownOrMoveEventY; + /** + * Determines speed during touch scrolling. + */ + private VelocityTracker mVelocityTracker; + /** + * @see ViewConfiguration#getScaledTouchSlop() + */ + private int mTouchSlop; + /** + * @see ViewConfiguration#getScaledMinimumFlingVelocity() + */ + private int mMinimumFlingVelocity; + /** + * @see ViewConfiguration#getScaledMaximumFlingVelocity() + */ + private int mMaximumFlingVelocity; + /** + * Flag whether the selector should wrap around. + */ + private boolean mWrapSelectorWheel; + /** + * The current scroll state of the number picker. + */ + private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE; + + /** + * Flag whether to ignore move events - we ignore such when we show in IME + * to prevent the content from scrolling. + */ + private boolean mIngonreMoveEvents; + + /** + * Flag whether to show soft input on tap. + */ + private boolean mShowSoftInputOnTap; + + /** + * The top of the top selection divider. + */ + private int mTopSelectionDividerTop; + + /** + * The bottom of the bottom selection divider. + */ + private int mBottomSelectionDividerBottom; + + /** + * The virtual id of the last hovered child. + */ + private int mLastHoveredChildVirtualViewId; + + /** + * Whether the increment virtual button is pressed. + */ + private boolean mIncrementVirtualButtonPressed; + + /** + * Whether the decrement virtual button is pressed. + */ + private boolean mDecrementVirtualButtonPressed; + + /** + * Provider to report to clients the semantic structure of this widget. + */ + private SupportAccessibilityNodeProvider mAccessibilityNodeProvider; + /** + * The keycode of the last handled DPAD down event. + */ + private int mLastHandledDownDpadKeyCode = -1; + + /** + * Create a new number picker. + * + * @param context The application environment. + */ + public NumberPicker(Context context) { + this(context, null); + } + + /** + * Create a new number picker. + * + * @param context The application environment. + * @param attrs A collection of attributes. + */ + public NumberPicker(Context context, AttributeSet attrs) { + this(context, attrs, R.attr.numberPickerStyle); + } + + /** + * Create a new number picker + * + * @param context the application environment. + * @param attrs a collection of attributes. + * @param defStyle The default style to apply to this view. + */ + public NumberPicker(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs); + + // process style attributes + TypedArray attributesArray = context.obtainStyledAttributes( + attrs, R.styleable.NumberPicker, defStyle, 0); + final int layoutResId = attributesArray.getResourceId( + R.styleable.NumberPicker_internalLayout, DEFAULT_LAYOUT_RESOURCE_ID); + + mHasSelectorWheel = (layoutResId != DEFAULT_LAYOUT_RESOURCE_ID); + + mSolidColor = attributesArray.getColor(R.styleable.NumberPicker_solidColor, 0); + + mSelectionDivider = attributesArray.getDrawable(R.styleable.NumberPicker_selectionDivider); + + final int defSelectionDividerHeight = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT, + getResources().getDisplayMetrics()); + mSelectionDividerHeight = attributesArray.getDimensionPixelSize( + R.styleable.NumberPicker_selectionDividerHeight, defSelectionDividerHeight); + + final int defSelectionDividerDistance = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_SELECTION_DIVIDERS_DISTANCE, + getResources().getDisplayMetrics()); + mSelectionDividersDistance = attributesArray.getDimensionPixelSize( + R.styleable.NumberPicker_selectionDividersDistance, defSelectionDividerDistance); + + mMinHeight = attributesArray.getDimensionPixelSize( + R.styleable.NumberPicker_internalMinHeight, SIZE_UNSPECIFIED); + + mMaxHeight = attributesArray.getDimensionPixelSize( + R.styleable.NumberPicker_internalMaxHeight, SIZE_UNSPECIFIED); + if (mMinHeight != SIZE_UNSPECIFIED && mMaxHeight != SIZE_UNSPECIFIED + && mMinHeight > mMaxHeight) { + throw new IllegalArgumentException("minHeight > maxHeight"); + } + + mMinWidth = attributesArray.getDimensionPixelSize( + R.styleable.NumberPicker_internalMinWidth, SIZE_UNSPECIFIED); + + mMaxWidth = attributesArray.getDimensionPixelSize( + R.styleable.NumberPicker_internalMaxWidth, SIZE_UNSPECIFIED); + if (mMinWidth != SIZE_UNSPECIFIED && mMaxWidth != SIZE_UNSPECIFIED + && mMinWidth > mMaxWidth) { + throw new IllegalArgumentException("minWidth > maxWidth"); + } + + mComputeMaxWidth = (mMaxWidth == SIZE_UNSPECIFIED); + + mVirtualButtonPressedDrawable = attributesArray.getDrawable( + R.styleable.NumberPicker_virtualButtonPressedDrawable); + + attributesArray.recycle(); + + mPressedStateHelper = new PressedStateHelper(); + + // By default Linearlayout that we extend is not drawn. This is + // its draw() method is not called but dispatchDraw() is called + // directly (see ViewGroup.drawChild()). However, this class uses + // the fading edge effect implemented by View and we need our + // draw() method to be called. Therefore, we declare we will draw. + setWillNotDraw(!mHasSelectorWheel); + + LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + inflater.inflate(layoutResId, this, true); + + OnClickListener onClickListener = new OnClickListener() { + public void onClick(View v) { + hideSoftInput(); + mInputText.clearFocus(); + if (v.getId() == R.id.np__increment) { + changeValueByOne(true); + } else { + changeValueByOne(false); + } + } + }; + + OnLongClickListener onLongClickListener = new OnLongClickListener() { + public boolean onLongClick(View v) { + hideSoftInput(); + mInputText.clearFocus(); + if (v.getId() == R.id.np__increment) { + postChangeCurrentByOneFromLongPress(true, 0); + } else { + postChangeCurrentByOneFromLongPress(false, 0); + } + return true; + } + }; + + // increment button + if (!mHasSelectorWheel) { + mIncrementButton = (ImageButton) findViewById(R.id.np__increment); + mIncrementButton.setOnClickListener(onClickListener); + mIncrementButton.setOnLongClickListener(onLongClickListener); + } else { + mIncrementButton = null; + } + + // decrement button + if (!mHasSelectorWheel) { + mDecrementButton = (ImageButton) findViewById(R.id.np__decrement); + mDecrementButton.setOnClickListener(onClickListener); + mDecrementButton.setOnLongClickListener(onLongClickListener); + } else { + mDecrementButton = null; + } + + // input text + mInputText = (EditText) findViewById(R.id.np__numberpicker_input); + mInputText.setOnFocusChangeListener(new OnFocusChangeListener() { + public void onFocusChange(View v, boolean hasFocus) { + if (hasFocus) { + mInputText.selectAll(); + } else { + mInputText.setSelection(0, 0); + validateInputTextView(v); + } + } + }); + mInputText.setFilters(new InputFilter[]{ + new InputTextFilter() + }); + + mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER); + mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE); + + // initialize constants + ViewConfiguration configuration = ViewConfiguration.get(context); + mTouchSlop = configuration.getScaledTouchSlop(); + mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity(); + mMaximumFlingVelocity = configuration.getScaledMaximumFlingVelocity() + / SELECTOR_MAX_FLING_VELOCITY_ADJUSTMENT; + mTextSize = (int) mInputText.getTextSize(); + + // create the selector wheel paint + Paint paint = new Paint(); + paint.setAntiAlias(true); + paint.setTextAlign(Align.CENTER); + paint.setTextSize(mTextSize); + paint.setTypeface(mInputText.getTypeface()); + ColorStateList colors = mInputText.getTextColors(); + int color = colors.getColorForState(ENABLED_STATE_SET, Color.WHITE); + paint.setColor(color); + mSelectorWheelPaint = paint; + + // create the fling and adjust scrollers + mFlingScroller = new Scroller(getContext(), null, true); + mAdjustScroller = new Scroller(getContext(), new DecelerateInterpolator(2.5f)); + + updateInputTextView(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + // If not explicitly specified this view is important for accessibility. + if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) { + setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); + } + } + } + + /** + * @hide + */ + @SuppressWarnings("FinalStaticMethod") + public static final Formatter getTwoDigitFormatter() { + return sTwoDigitFormatter; + } + + /** + * Utility to reconcile a desired size and state, with constraints imposed + * by a MeasureSpec. Will take the desired size, unless a different size + * is imposed by the constraints. The returned value is a compound integer, + * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and + * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting + * size is smaller than the size the view wants to be. + * + * @param size How big the view wants to be + * @param measureSpec Constraints imposed by the parent + * @return Size information bit mask as defined by + * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}. + */ + public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) { + int result = size; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + switch (specMode) { + case MeasureSpec.UNSPECIFIED: + result = size; + break; + case MeasureSpec.AT_MOST: + if (specSize < size) { + result = specSize | MEASURED_STATE_TOO_SMALL; + } else { + result = size; + } + break; + case MeasureSpec.EXACTLY: + result = specSize; + break; + } + return result | (childMeasuredState & MEASURED_STATE_MASK); + } + + static private String formatNumberWithLocale(int value) { + return String.format(Locale.getDefault(), "%d", value); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + if (!mHasSelectorWheel) { + super.onLayout(changed, left, top, right, bottom); + return; + } + final int msrdWdth = getMeasuredWidth(); + final int msrdHght = getMeasuredHeight(); + + // Input text centered horizontally. + final int inptTxtMsrdWdth = mInputText.getMeasuredWidth(); + final int inptTxtMsrdHght = mInputText.getMeasuredHeight(); + final int inptTxtLeft = (msrdWdth - inptTxtMsrdWdth) / 2; + final int inptTxtTop = (msrdHght - inptTxtMsrdHght) / 2; + final int inptTxtRight = inptTxtLeft + inptTxtMsrdWdth; + final int inptTxtBottom = inptTxtTop + inptTxtMsrdHght; + mInputText.layout(inptTxtLeft, inptTxtTop, inptTxtRight, inptTxtBottom); + + if (changed) { + // need to do all this when we know our size + initializeSelectorWheel(); + initializeFadingEdges(); + mTopSelectionDividerTop = (getHeight() - mSelectionDividersDistance) / 2 + - mSelectionDividerHeight; + mBottomSelectionDividerBottom = mTopSelectionDividerTop + 2 * mSelectionDividerHeight + + mSelectionDividersDistance; + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (!mHasSelectorWheel) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + return; + } + // Try greedily to fit the max width and height. + final int newWidthMeasureSpec = makeMeasureSpec(widthMeasureSpec, mMaxWidth); + final int newHeightMeasureSpec = makeMeasureSpec(heightMeasureSpec, mMaxHeight); + super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec); + // Flag if we are measured with width or height less than the respective min. + final int widthSize = resolveSizeAndStateRespectingMinSize(mMinWidth, getMeasuredWidth(), + widthMeasureSpec); + final int heightSize = resolveSizeAndStateRespectingMinSize(mMinHeight, getMeasuredHeight(), + heightMeasureSpec); + setMeasuredDimension(widthSize, heightSize); + } + + /** + * Move to the final position of a scroller. Ensures to force finish the scroller + * and if it is not at its final position a scroll of the selector wheel is + * performed to fast forward to the final position. + * + * @param scroller The scroller to whose final position to get. + * @return True of the a move was performed, i.e. the scroller was not in final position. + */ + private boolean moveToFinalScrollerPosition(Scroller scroller) { + scroller.forceFinished(true); + int amountToScroll = scroller.getFinalY() - scroller.getCurrY(); + int futureScrollOffset = (mCurrentScrollOffset + amountToScroll) % mSelectorElementHeight; + int overshootAdjustment = mInitialScrollOffset - futureScrollOffset; + if (overshootAdjustment != 0) { + if (Math.abs(overshootAdjustment) > mSelectorElementHeight / 2) { + if (overshootAdjustment > 0) { + overshootAdjustment -= mSelectorElementHeight; + } else { + overshootAdjustment += mSelectorElementHeight; + } + } + amountToScroll += overshootAdjustment; + scrollBy(0, amountToScroll); + return true; + } + return false; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + if (!mHasSelectorWheel || !isEnabled()) { + return false; + } + final int action = event.getAction() & MotionEvent.ACTION_MASK; + switch (action) { + case MotionEvent.ACTION_DOWN: { + removeAllCallbacks(); + mInputText.setVisibility(View.INVISIBLE); + mLastDownOrMoveEventY = mLastDownEventY = event.getY(); + mLastDownEventTime = event.getEventTime(); + mIngonreMoveEvents = false; + mShowSoftInputOnTap = false; + // Handle pressed state before any state change. + if (mLastDownEventY < mTopSelectionDividerTop) { + if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) { + mPressedStateHelper.buttonPressDelayed( + PressedStateHelper.BUTTON_DECREMENT); + } + } else if (mLastDownEventY > mBottomSelectionDividerBottom) { + if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) { + mPressedStateHelper.buttonPressDelayed( + PressedStateHelper.BUTTON_INCREMENT); + } + } + // Make sure we support flinging inside scrollables. + getParent().requestDisallowInterceptTouchEvent(true); + if (!mFlingScroller.isFinished()) { + mFlingScroller.forceFinished(true); + mAdjustScroller.forceFinished(true); + onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); + } else if (!mAdjustScroller.isFinished()) { + mFlingScroller.forceFinished(true); + mAdjustScroller.forceFinished(true); + } else if (mLastDownEventY < mTopSelectionDividerTop) { + hideSoftInput(); + postChangeCurrentByOneFromLongPress( + false, ViewConfiguration.getLongPressTimeout()); + } else if (mLastDownEventY > mBottomSelectionDividerBottom) { + hideSoftInput(); + postChangeCurrentByOneFromLongPress( + true, ViewConfiguration.getLongPressTimeout()); + } else { + mShowSoftInputOnTap = true; + postBeginSoftInputOnLongPressCommand(); + } + return true; + } + } + return false; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (!isEnabled() || !mHasSelectorWheel) { + return false; + } + if (mVelocityTracker == null) { + mVelocityTracker = VelocityTracker.obtain(); + } + mVelocityTracker.addMovement(event); + int action = event.getAction() & MotionEvent.ACTION_MASK; + switch (action) { + case MotionEvent.ACTION_MOVE: { + if (mIngonreMoveEvents) { + break; + } + float currentMoveY = event.getY(); + if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { + int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY); + if (deltaDownY > mTouchSlop) { + removeAllCallbacks(); + onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); + } + } else { + int deltaMoveY = (int) ((currentMoveY - mLastDownOrMoveEventY)); + scrollBy(0, deltaMoveY); + invalidate(); + } + mLastDownOrMoveEventY = currentMoveY; + } + break; + case MotionEvent.ACTION_UP: { + removeBeginSoftInputCommand(); + removeChangeCurrentByOneFromLongPress(); + mPressedStateHelper.cancel(); + VelocityTracker velocityTracker = mVelocityTracker; + velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity); + int initialVelocity = (int) velocityTracker.getYVelocity(); + if (Math.abs(initialVelocity) > mMinimumFlingVelocity) { + fling(initialVelocity); + onScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); + } else { + int eventY = (int) event.getY(); + int deltaMoveY = (int) Math.abs(eventY - mLastDownEventY); + long deltaTime = event.getEventTime() - mLastDownEventTime; + long tapTimeout = ViewConfiguration.getTapTimeout(); + if (deltaMoveY <= mTouchSlop) { // && deltaTime < ViewConfiguration.getTapTimeout()) { + if (mShowSoftInputOnTap) { + mShowSoftInputOnTap = false; + showSoftInput(); + } else { + int selectorIndexOffset = (eventY / mSelectorElementHeight) + - SELECTOR_MIDDLE_ITEM_INDEX; + if (selectorIndexOffset > 0) { + changeValueByOne(true); + mPressedStateHelper.buttonTapped( + PressedStateHelper.BUTTON_INCREMENT); + } else if (selectorIndexOffset < 0) { + changeValueByOne(false); + mPressedStateHelper.buttonTapped( + PressedStateHelper.BUTTON_DECREMENT); + } + } + } else { + ensureScrollWheelAdjusted(); + } + onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); + } + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + break; + } + return true; + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + final int action = event.getAction() & MotionEvent.ACTION_MASK; + switch (action) { + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + removeAllCallbacks(); + break; + } + return super.dispatchTouchEvent(event); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + final int keyCode = event.getKeyCode(); + switch (keyCode) { + case KeyEvent.KEYCODE_DPAD_CENTER: + case KeyEvent.KEYCODE_ENTER: + removeAllCallbacks(); + break; + case KeyEvent.KEYCODE_DPAD_DOWN: + case KeyEvent.KEYCODE_DPAD_UP: + if (!mHasSelectorWheel) { + break; + } + switch (event.getAction()) { + case KeyEvent.ACTION_DOWN: + if (mWrapSelectorWheel || (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) + ? getValue() < getMaxValue() : getValue() > getMinValue()) { + requestFocus(); + mLastHandledDownDpadKeyCode = keyCode; + removeAllCallbacks(); + if (mFlingScroller.isFinished()) { + changeValueByOne(keyCode == KeyEvent.KEYCODE_DPAD_DOWN); + } + return true; + } + break; + case KeyEvent.ACTION_UP: + if (mLastHandledDownDpadKeyCode == keyCode) { + mLastHandledDownDpadKeyCode = -1; + return true; + } + break; + } + } + return super.dispatchKeyEvent(event); + } + + @Override + public boolean dispatchTrackballEvent(MotionEvent event) { + final int action = event.getAction() & MotionEvent.ACTION_MASK; + switch (action) { + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + removeAllCallbacks(); + break; + } + return super.dispatchTrackballEvent(event); + } + + @Override + protected boolean dispatchHoverEvent(MotionEvent event) { + if (!mHasSelectorWheel) { + return super.dispatchHoverEvent(event); + } + + if (((AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE)).isEnabled()) { + final int eventY = (int) event.getY(); + final int hoveredVirtualViewId; + if (eventY < mTopSelectionDividerTop) { + hoveredVirtualViewId = AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_DECREMENT; + } else if (eventY > mBottomSelectionDividerBottom) { + hoveredVirtualViewId = AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_INCREMENT; + } else { + hoveredVirtualViewId = AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_INPUT; + } + final int action = event.getAction() & MotionEvent.ACTION_MASK; + SupportAccessibilityNodeProvider provider = getSupportAccessibilityNodeProvider(); + + switch (action) { + case MotionEvent.ACTION_HOVER_ENTER: { + provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId, + AccessibilityEvent.TYPE_VIEW_HOVER_ENTER); + mLastHoveredChildVirtualViewId = hoveredVirtualViewId; + provider.performAction(hoveredVirtualViewId, + AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); + } + break; + case MotionEvent.ACTION_HOVER_MOVE: { + if (mLastHoveredChildVirtualViewId != hoveredVirtualViewId + && mLastHoveredChildVirtualViewId != View.NO_ID) { + provider.sendAccessibilityEventForVirtualView( + mLastHoveredChildVirtualViewId, + AccessibilityEvent.TYPE_VIEW_HOVER_EXIT); + provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId, + AccessibilityEvent.TYPE_VIEW_HOVER_ENTER); + mLastHoveredChildVirtualViewId = hoveredVirtualViewId; + provider.performAction(hoveredVirtualViewId, + AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); + } + } + break; + case MotionEvent.ACTION_HOVER_EXIT: { + provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId, + AccessibilityEvent.TYPE_VIEW_HOVER_EXIT); + mLastHoveredChildVirtualViewId = View.NO_ID; + } + break; + } + } + return false; + } + + @Override + public void computeScroll() { + Scroller scroller = mFlingScroller; + if (scroller.isFinished()) { + scroller = mAdjustScroller; + if (scroller.isFinished()) { + return; + } + } + scroller.computeScrollOffset(); + int currentScrollerY = scroller.getCurrY(); + if (mPreviousScrollerY == 0) { + mPreviousScrollerY = scroller.getStartY(); + } + scrollBy(0, currentScrollerY - mPreviousScrollerY); + mPreviousScrollerY = currentScrollerY; + if (scroller.isFinished()) { + onScrollerFinished(scroller); + } else { + invalidate(); + } + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + if (!mHasSelectorWheel) { + mIncrementButton.setEnabled(enabled); + } + if (!mHasSelectorWheel) { + mDecrementButton.setEnabled(enabled); + } + mInputText.setEnabled(enabled); + } + + @Override + public void scrollBy(int x, int y) { + int[] selectorIndices = mSelectorIndices; + if (!mWrapSelectorWheel && y > 0 + && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) { + mCurrentScrollOffset = mInitialScrollOffset; + return; + } + if (!mWrapSelectorWheel && y < 0 + && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] >= mMaxValue) { + mCurrentScrollOffset = mInitialScrollOffset; + return; + } + mCurrentScrollOffset += y; + while (mCurrentScrollOffset - mInitialScrollOffset > mSelectorTextGapHeight) { + mCurrentScrollOffset -= mSelectorElementHeight; + decrementSelectorIndices(selectorIndices); + setValueInternal(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX], true); + if (!mWrapSelectorWheel && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) { + mCurrentScrollOffset = mInitialScrollOffset; + } + } + while (mCurrentScrollOffset - mInitialScrollOffset < -mSelectorTextGapHeight) { + mCurrentScrollOffset += mSelectorElementHeight; + incrementSelectorIndices(selectorIndices); + setValueInternal(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX], true); + if (!mWrapSelectorWheel && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] >= mMaxValue) { + mCurrentScrollOffset = mInitialScrollOffset; + } + } + } + + @Override + public int getSolidColor() { + return mSolidColor; + } + + /** + * Sets the listener to be notified on change of the current value. + * + * @param onValueChangedListener The listener. + */ + public void setOnValueChangedListener(OnValueChangeListener onValueChangedListener) { + mOnValueChangeListener = onValueChangedListener; + } + + /** + * Set listener to be notified for scroll state changes. + * + * @param onScrollListener The listener. + */ + public void setOnScrollListener(OnScrollListener onScrollListener) { + mOnScrollListener = onScrollListener; + } + + /** + * Set the formatter to be used for formatting the current value. + *

+ * Note: If you have provided alternative values for the values this + * formatter is never invoked. + *

+ * + * @param formatter The formatter object. If formatter is null, + * {@link String#valueOf(int)} will be used. + * @see #setDisplayedValues(String[]) + */ + public void setFormatter(Formatter formatter) { + if (formatter == mFormatter) { + return; + } + mFormatter = formatter; + initializeSelectorWheelIndices(); + updateInputTextView(); + } + + /** + * Shows the soft input for its input text. + */ + private void showSoftInput() { + InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + if (inputMethodManager != null) { + if (mHasSelectorWheel) { + mInputText.setVisibility(View.VISIBLE); + } + mInputText.requestFocus(); + inputMethodManager.showSoftInput(mInputText, 0); + } + } + + /** + * Hides the soft input if it is active for the input text. + */ + private void hideSoftInput() { + InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + if (inputMethodManager != null && inputMethodManager.isActive(mInputText)) { + inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); + if (mHasSelectorWheel) { + mInputText.setVisibility(View.INVISIBLE); + } + } + } + + /** + * Computes the max width if no such specified as an attribute. + */ + private void tryComputeMaxWidth() { + if (!mComputeMaxWidth) { + return; + } + int maxTextWidth = 0; + if (mDisplayedValues == null) { + float maxDigitWidth = 0; + for (int i = 0; i <= 9; i++) { + final float digitWidth = mSelectorWheelPaint.measureText(formatNumberWithLocale(i)); + if (digitWidth > maxDigitWidth) { + maxDigitWidth = digitWidth; + } + } + int numberOfDigits = 0; + int current = mMaxValue; + while (current > 0) { + numberOfDigits++; + current = current / 10; + } + maxTextWidth = (int) (numberOfDigits * maxDigitWidth); + } else { + final int valueCount = mDisplayedValues.length; + for (int i = 0; i < valueCount; i++) { + final float textWidth = mSelectorWheelPaint.measureText(mDisplayedValues[i]); + if (textWidth > maxTextWidth) { + maxTextWidth = (int) textWidth; + } + } + } + maxTextWidth += mInputText.getPaddingLeft() + mInputText.getPaddingRight(); + if (mMaxWidth != maxTextWidth) { + if (maxTextWidth > mMinWidth) { + mMaxWidth = maxTextWidth; + } else { + mMaxWidth = mMinWidth; + } + invalidate(); + } + } + + /** + * Gets whether the selector wheel wraps when reaching the min/max value. + * + * @return True if the selector wheel wraps. + * @see #getMinValue() + * @see #getMaxValue() + */ + public boolean getWrapSelectorWheel() { + return mWrapSelectorWheel; + } + + /** + * Sets whether the selector wheel shown during flinging/scrolling should + * wrap around the {@link NumberPicker#getMinValue()} and + * {@link NumberPicker#getMaxValue()} values. + *

+ * By default if the range (max - min) is more than the number of items shown + * on the selector wheel the selector wheel wrapping is enabled. + *

+ *

+ * Note: If the number of items, i.e. the range ( + * {@link #getMaxValue()} - {@link #getMinValue()}) is less than + * the number of items shown on the selector wheel, the selector wheel will + * not wrap. Hence, in such a case calling this method is a NOP. + *

+ * + * @param wrapSelectorWheel Whether to wrap. + */ + public void setWrapSelectorWheel(boolean wrapSelectorWheel) { + final boolean wrappingAllowed = (mMaxValue - mMinValue) >= mSelectorIndices.length; + if ((!wrapSelectorWheel || wrappingAllowed) && wrapSelectorWheel != mWrapSelectorWheel) { + mWrapSelectorWheel = wrapSelectorWheel; + } + } + + /** + * Sets the speed at which the numbers be incremented and decremented when + * the up and down buttons are long pressed respectively. + *

+ * The default value is 300 ms. + *

+ * + * @param intervalMillis The speed (in milliseconds) at which the numbers + * will be incremented and decremented. + */ + public void setOnLongPressUpdateInterval(long intervalMillis) { + mLongPressUpdateInterval = intervalMillis; + } + + /** + * Returns the value of the picker. + * + * @return The value. + */ + public int getValue() { + return mValue; + } + + /** + * Set the current value for the number picker. + *

+ * If the argument is less than the {@link NumberPicker#getMinValue()} and + * {@link NumberPicker#getWrapSelectorWheel()} is false the + * current value is set to the {@link NumberPicker#getMinValue()} value. + *

+ *

+ * If the argument is less than the {@link NumberPicker#getMinValue()} and + * {@link NumberPicker#getWrapSelectorWheel()} is true the + * current value is set to the {@link NumberPicker#getMaxValue()} value. + *

+ *

+ * If the argument is less than the {@link NumberPicker#getMaxValue()} and + * {@link NumberPicker#getWrapSelectorWheel()} is false the + * current value is set to the {@link NumberPicker#getMaxValue()} value. + *

+ *

+ * If the argument is less than the {@link NumberPicker#getMaxValue()} and + * {@link NumberPicker#getWrapSelectorWheel()} is true the + * current value is set to the {@link NumberPicker#getMinValue()} value. + *

+ * + * @param value The current value. + * @see #setWrapSelectorWheel(boolean) + * @see #setMinValue(int) + * @see #setMaxValue(int) + */ + public void setValue(int value) { + setValueInternal(value, false); + } + + /** + * Returns the min value of the picker. + * + * @return The min value + */ + public int getMinValue() { + return mMinValue; + } + + /** + * Sets the min value of the picker. + * + * @param minValue The min value inclusive. + *

+ * Note: The length of the displayed values array + * set via {@link #setDisplayedValues(String[])} must be equal to the + * range of selectable numbers which is equal to + * {@link #getMaxValue()} - {@link #getMinValue()} + 1. + */ + public void setMinValue(int minValue) { + if (mMinValue == minValue) { + return; + } + if (minValue < 0) { + throw new IllegalArgumentException("minValue must be >= 0"); + } + mMinValue = minValue; + if (mMinValue > mValue) { + mValue = mMinValue; + } + boolean wrapSelectorWheel = mMaxValue - mMinValue > mSelectorIndices.length; + setWrapSelectorWheel(wrapSelectorWheel); + initializeSelectorWheelIndices(); + updateInputTextView(); + tryComputeMaxWidth(); + invalidate(); + } + + /** + * Returns the max value of the picker. + * + * @return The max value. + */ + public int getMaxValue() { + return mMaxValue; + } + + /** + * Sets the max value of the picker. + * + * @param maxValue The max value inclusive. + *

+ * Note: The length of the displayed values array + * set via {@link #setDisplayedValues(String[])} must be equal to the + * range of selectable numbers which is equal to + * {@link #getMaxValue()} - {@link #getMinValue()} + 1. + */ + public void setMaxValue(int maxValue) { + if (mMaxValue == maxValue) { + return; + } + if (maxValue < 0) { + throw new IllegalArgumentException("maxValue must be >= 0"); + } + mMaxValue = maxValue; + if (mMaxValue < mValue) { + mValue = mMaxValue; + } + boolean wrapSelectorWheel = mMaxValue - mMinValue > mSelectorIndices.length; + setWrapSelectorWheel(wrapSelectorWheel); + initializeSelectorWheelIndices(); + updateInputTextView(); + tryComputeMaxWidth(); + invalidate(); + } + + /** + * Gets the values to be displayed instead of string values. + * + * @return The displayed values. + */ + public String[] getDisplayedValues() { + return mDisplayedValues; + } + + /** + * Sets the values to be displayed. + * + * @param displayedValues The displayed values. + *

+ * Note: The length of the displayed values array + * must be equal to the range of selectable numbers which is equal to + * {@link #getMaxValue()} - {@link #getMinValue()} + 1. + */ + public void setDisplayedValues(String[] displayedValues) { + if (mDisplayedValues == displayedValues) { + return; + } + mDisplayedValues = displayedValues; + if (mDisplayedValues != null) { + // Allow text entry rather than strictly numeric entry. + mInputText.setRawInputType(InputType.TYPE_CLASS_TEXT + | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + } else { + mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER); + } + updateInputTextView(); + initializeSelectorWheelIndices(); + tryComputeMaxWidth(); + } + + @Override + protected float getTopFadingEdgeStrength() { + return TOP_AND_BOTTOM_FADING_EDGE_STRENGTH; + } + + @Override + protected float getBottomFadingEdgeStrength() { + return TOP_AND_BOTTOM_FADING_EDGE_STRENGTH; + } + + @Override + protected void onDetachedFromWindow() { + removeAllCallbacks(); + super.onDetachedFromWindow(); + } + + @Override + protected void onDraw(Canvas canvas) { + if (!mHasSelectorWheel) { + super.onDraw(canvas); + return; + } + float x = (getRight() - getLeft()) / 2; + float y = mCurrentScrollOffset; + + // draw the virtual buttons pressed state if needed + if (mVirtualButtonPressedDrawable != null + && mScrollState == OnScrollListener.SCROLL_STATE_IDLE) { + if (mDecrementVirtualButtonPressed) { + //mVirtualButtonPressedDrawable.setState(PRESSED_STATE_SET); + mVirtualButtonPressedDrawable.setState(PRESSED_ENABLED_STATE_SET); + mVirtualButtonPressedDrawable.setBounds(0, 0, getRight(), mTopSelectionDividerTop); + mVirtualButtonPressedDrawable.draw(canvas); + } + if (mIncrementVirtualButtonPressed) { + //mVirtualButtonPressedDrawable.setState(PRESSED_STATE_SET); + mVirtualButtonPressedDrawable.setState(PRESSED_ENABLED_STATE_SET); + mVirtualButtonPressedDrawable.setBounds(0, mBottomSelectionDividerBottom, getRight(), + getBottom()); + mVirtualButtonPressedDrawable.draw(canvas); + } + } + + // draw the selector wheel + int[] selectorIndices = mSelectorIndices; + for (int i = 0; i < selectorIndices.length; i++) { + int selectorIndex = selectorIndices[i]; + String scrollSelectorValue = mSelectorIndexToStringCache.get(selectorIndex); + // Do not draw the middle item if input is visible since the input + // is shown only if the wheel is static and it covers the middle + // item. Otherwise, if the user starts editing the text via the + // IME he may see a dimmed version of the old value intermixed + // with the new one. + if (i != SELECTOR_MIDDLE_ITEM_INDEX || mInputText.getVisibility() != VISIBLE) { + canvas.drawText(scrollSelectorValue, x, y, mSelectorWheelPaint); + } + y += mSelectorElementHeight; + } + + // draw the selection dividers + if (mSelectionDivider != null) { + // draw the top divider + int topOfTopDivider = mTopSelectionDividerTop; + int bottomOfTopDivider = topOfTopDivider + mSelectionDividerHeight; + mSelectionDivider.setBounds(0, topOfTopDivider, getRight(), bottomOfTopDivider); + mSelectionDivider.draw(canvas); + + // draw the bottom divider + int bottomOfBottomDivider = mBottomSelectionDividerBottom; + int topOfBottomDivider = bottomOfBottomDivider - mSelectionDividerHeight; + mSelectionDivider.setBounds(0, topOfBottomDivider, getRight(), bottomOfBottomDivider); + mSelectionDivider.draw(canvas); + } + } + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + event.setClassName(NumberPicker.class.getName()); + event.setScrollable(true); + event.setScrollY((mMinValue + mValue) * mSelectorElementHeight); + event.setMaxScrollY((mMaxValue - mMinValue) * mSelectorElementHeight); + } + + @Override + public AccessibilityNodeProvider getAccessibilityNodeProvider() { + if (!mHasSelectorWheel) { + return super.getAccessibilityNodeProvider(); + } + if (mAccessibilityNodeProvider == null) { + mAccessibilityNodeProvider = new SupportAccessibilityNodeProvider(); + } + return mAccessibilityNodeProvider.mProvider; + } + + /** + * Makes a measure spec that tries greedily to use the max value. + * + * @param measureSpec The measure spec. + * @param maxSize The max value for the size. + * @return A measure spec greedily imposing the max size. + */ + private int makeMeasureSpec(int measureSpec, int maxSize) { + if (maxSize == SIZE_UNSPECIFIED) { + return measureSpec; + } + final int size = MeasureSpec.getSize(measureSpec); + final int mode = MeasureSpec.getMode(measureSpec); + switch (mode) { + case MeasureSpec.EXACTLY: + return measureSpec; + case MeasureSpec.AT_MOST: + return MeasureSpec.makeMeasureSpec(Math.min(size, maxSize), MeasureSpec.EXACTLY); + case MeasureSpec.UNSPECIFIED: + return MeasureSpec.makeMeasureSpec(maxSize, MeasureSpec.EXACTLY); + default: + throw new IllegalArgumentException("Unknown measure mode: " + mode); + } + } + + /** + * Utility to reconcile a desired size and state, with constraints imposed + * by a MeasureSpec. Tries to respect the min size, unless a different size + * is imposed by the constraints. + * + * @param minSize The minimal desired size. + * @param measuredSize The currently measured size. + * @param measureSpec The current measure spec. + * @return The resolved size and state. + */ + private int resolveSizeAndStateRespectingMinSize( + int minSize, int measuredSize, int measureSpec) { + if (minSize != SIZE_UNSPECIFIED) { + final int desiredWidth = Math.max(minSize, measuredSize); + return resolveSizeAndState(desiredWidth, measureSpec, 0); + } else { + return measuredSize; + } + } + + /** + * Resets the selector indices and clear the cached string representation of + * these indices. + */ + private void initializeSelectorWheelIndices() { + mSelectorIndexToStringCache.clear(); + int[] selectorIndices = mSelectorIndices; + int current = getValue(); + for (int i = 0; i < mSelectorIndices.length; i++) { + int selectorIndex = current + (i - SELECTOR_MIDDLE_ITEM_INDEX); + if (mWrapSelectorWheel) { + selectorIndex = getWrappedSelectorIndex(selectorIndex); + } + selectorIndices[i] = selectorIndex; + ensureCachedScrollSelectorValue(selectorIndices[i]); + } + } + + /** + * Sets the current value of this NumberPicker. + * + * @param current The new value of the NumberPicker. + * @param notifyChange Whether to notify if the current value changed. + */ + private void setValueInternal(int current, boolean notifyChange) { + if (mValue == current) { + return; + } + // Wrap around the values if we go past the start or end + if (mWrapSelectorWheel) { + current = getWrappedSelectorIndex(current); + } else { + current = Math.max(current, mMinValue); + current = Math.min(current, mMaxValue); + } + int previous = mValue; + mValue = current; + updateInputTextView(); + if (notifyChange) { + notifyChange(previous, current); + } + initializeSelectorWheelIndices(); + invalidate(); + } + + /** + * Changes the current value by one which is increment or + * decrement based on the passes argument. + * decrement the current value. + * + * @param increment True to increment, false to decrement. + */ + private void changeValueByOne(boolean increment) { + if (mHasSelectorWheel) { + mInputText.setVisibility(View.INVISIBLE); + if (!moveToFinalScrollerPosition(mFlingScroller)) { + moveToFinalScrollerPosition(mAdjustScroller); + } + mPreviousScrollerY = 0; + if (increment) { + mFlingScroller.startScroll(0, 0, 0, -mSelectorElementHeight, SNAP_SCROLL_DURATION); + } else { + mFlingScroller.startScroll(0, 0, 0, mSelectorElementHeight, SNAP_SCROLL_DURATION); + } + invalidate(); + } else { + if (increment) { + setValueInternal(mValue + 1, true); + } else { + setValueInternal(mValue - 1, true); + } + } + } + + private void initializeSelectorWheel() { + initializeSelectorWheelIndices(); + int[] selectorIndices = mSelectorIndices; + int totalTextHeight = selectorIndices.length * mTextSize; + float totalTextGapHeight = (getBottom() - getTop()) - totalTextHeight; + float textGapCount = selectorIndices.length; + mSelectorTextGapHeight = (int) (totalTextGapHeight / textGapCount + 0.5f); + mSelectorElementHeight = mTextSize + mSelectorTextGapHeight; + // Ensure that the middle item is positioned the same as the text in + // mInputText + int editTextTextPosition = mInputText.getBaseline() + mInputText.getTop(); + mInitialScrollOffset = editTextTextPosition + - (mSelectorElementHeight * SELECTOR_MIDDLE_ITEM_INDEX); + mCurrentScrollOffset = mInitialScrollOffset; + updateInputTextView(); + } + + private void initializeFadingEdges() { + setVerticalFadingEdgeEnabled(true); + setFadingEdgeLength((getBottom() - getTop() - mTextSize) / 2); + } + + /** + * Callback invoked upon completion of a given scroller. + */ + private void onScrollerFinished(Scroller scroller) { + if (scroller == mFlingScroller) { + if (!ensureScrollWheelAdjusted()) { + updateInputTextView(); + } + onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); + } else { + if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { + updateInputTextView(); + } + } + } + + /** + * Handles transition to a given scrollState + */ + private void onScrollStateChange(int scrollState) { + if (mScrollState == scrollState) { + return; + } + mScrollState = scrollState; + if (mOnScrollListener != null) { + mOnScrollListener.onScrollStateChange(this, scrollState); + } + } + + /** + * Flings the selector with the given velocityY. + */ + private void fling(int velocityY) { + mPreviousScrollerY = 0; + + if (velocityY > 0) { + mFlingScroller.fling(0, 0, 0, velocityY, 0, 0, 0, Integer.MAX_VALUE); + } else { + mFlingScroller.fling(0, Integer.MAX_VALUE, 0, velocityY, 0, 0, 0, Integer.MAX_VALUE); + } + + invalidate(); + } + + /** + * @return The wrapped index selectorIndex value. + */ + private int getWrappedSelectorIndex(int selectorIndex) { + if (selectorIndex > mMaxValue) { + return mMinValue + (selectorIndex - mMaxValue) % (mMaxValue - mMinValue) - 1; + } else if (selectorIndex < mMinValue) { + return mMaxValue - (mMinValue - selectorIndex) % (mMaxValue - mMinValue) + 1; + } + return selectorIndex; + } + + /** + * Increments the selectorIndices whose string representations + * will be displayed in the selector. + */ + private void incrementSelectorIndices(int[] selectorIndices) { + for (int i = 0; i < selectorIndices.length - 1; i++) { + selectorIndices[i] = selectorIndices[i + 1]; + } + int nextScrollSelectorIndex = selectorIndices[selectorIndices.length - 2] + 1; + if (mWrapSelectorWheel && nextScrollSelectorIndex > mMaxValue) { + nextScrollSelectorIndex = mMinValue; + } + selectorIndices[selectorIndices.length - 1] = nextScrollSelectorIndex; + ensureCachedScrollSelectorValue(nextScrollSelectorIndex); + } + + /** + * Decrements the selectorIndices whose string representations + * will be displayed in the selector. + */ + private void decrementSelectorIndices(int[] selectorIndices) { + for (int i = selectorIndices.length - 1; i > 0; i--) { + selectorIndices[i] = selectorIndices[i - 1]; + } + int nextScrollSelectorIndex = selectorIndices[1] - 1; + if (mWrapSelectorWheel && nextScrollSelectorIndex < mMinValue) { + nextScrollSelectorIndex = mMaxValue; + } + selectorIndices[0] = nextScrollSelectorIndex; + ensureCachedScrollSelectorValue(nextScrollSelectorIndex); + } + + /** + * Ensures we have a cached string representation of the given + * selectorIndex to avoid multiple instantiations of the same string. + */ + private void ensureCachedScrollSelectorValue(int selectorIndex) { + SparseArray cache = mSelectorIndexToStringCache; + String scrollSelectorValue = cache.get(selectorIndex); + if (scrollSelectorValue != null) { + return; + } + if (selectorIndex < mMinValue || selectorIndex > mMaxValue) { + scrollSelectorValue = ""; + } else { + if (mDisplayedValues != null) { + int displayedValueIndex = selectorIndex - mMinValue; + scrollSelectorValue = mDisplayedValues[displayedValueIndex]; + } else { + scrollSelectorValue = formatNumber(selectorIndex); + } + } + cache.put(selectorIndex, scrollSelectorValue); + } + + private String formatNumber(int value) { + return (mFormatter != null) ? mFormatter.format(value) : formatNumberWithLocale(value); + } + + private void validateInputTextView(View v) { + String str = String.valueOf(((TextView) v).getText()); + if (TextUtils.isEmpty(str)) { + // Restore to the old value as we don't allow empty values + updateInputTextView(); + } else { + // Check the new value and ensure it's in range + int current = getSelectedPos(str); + setValueInternal(current, true); + } + } + + /** + * Updates the view of this NumberPicker. If displayValues were specified in + * the string corresponding to the index specified by the current value will + * be returned. Otherwise, the formatter specified in {@link #setFormatter} + * will be used to format the number. + * + * @return Whether the text was updated. + */ + private boolean updateInputTextView() { + /* + * If we don't have displayed values then use the current number else + * find the correct value in the displayed values for the current + * number. + */ + String text = (mDisplayedValues == null) ? formatNumber(mValue) + : mDisplayedValues[mValue - mMinValue]; + if (!TextUtils.isEmpty(text) && !text.equals(mInputText.getText().toString())) { + mInputText.setText(text); + return true; + } + + return false; + } + + /** + * Notifies the listener, if registered, of a change of the value of this + * NumberPicker. + */ + private void notifyChange(int previous, int current) { + if (mOnValueChangeListener != null) { + mOnValueChangeListener.onValueChange(this, previous, mValue); + } + } + + /** + * Posts a command for changing the current value by one. + * + * @param increment Whether to increment or decrement the value. + */ + private void postChangeCurrentByOneFromLongPress(boolean increment, long delayMillis) { + if (mChangeCurrentByOneFromLongPressCommand == null) { + mChangeCurrentByOneFromLongPressCommand = new ChangeCurrentByOneFromLongPressCommand(); + } else { + removeCallbacks(mChangeCurrentByOneFromLongPressCommand); + } + mChangeCurrentByOneFromLongPressCommand.setStep(increment); + postDelayed(mChangeCurrentByOneFromLongPressCommand, delayMillis); + } + + /** + * Removes the command for changing the current value by one. + */ + private void removeChangeCurrentByOneFromLongPress() { + if (mChangeCurrentByOneFromLongPressCommand != null) { + removeCallbacks(mChangeCurrentByOneFromLongPressCommand); + } + } + + /** + * Posts a command for beginning an edit of the current value via IME on + * long press. + */ + private void postBeginSoftInputOnLongPressCommand() { + if (mBeginSoftInputOnLongPressCommand == null) { + mBeginSoftInputOnLongPressCommand = new BeginSoftInputOnLongPressCommand(); + } else { + removeCallbacks(mBeginSoftInputOnLongPressCommand); + } + postDelayed(mBeginSoftInputOnLongPressCommand, ViewConfiguration.getLongPressTimeout()); + } + + /** + * Removes the command for beginning an edit of the current value via IME. + */ + private void removeBeginSoftInputCommand() { + if (mBeginSoftInputOnLongPressCommand != null) { + removeCallbacks(mBeginSoftInputOnLongPressCommand); + } + } + + /** + * Removes all pending callback from the message queue. + */ + private void removeAllCallbacks() { + if (mChangeCurrentByOneFromLongPressCommand != null) { + removeCallbacks(mChangeCurrentByOneFromLongPressCommand); + } + if (mSetSelectionCommand != null) { + removeCallbacks(mSetSelectionCommand); + } + if (mBeginSoftInputOnLongPressCommand != null) { + removeCallbacks(mBeginSoftInputOnLongPressCommand); + } + mPressedStateHelper.cancel(); + } + + /** + * @return The selected index given its displayed value. + */ + private int getSelectedPos(String value) { + if (mDisplayedValues == null) { + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + // Ignore as if it's not a number we don't care + } + } else { + for (int i = 0; i < mDisplayedValues.length; i++) { + // Don't force the user to type in jan when ja will do + value = value.toLowerCase(); + if (mDisplayedValues[i].toLowerCase().startsWith(value)) { + return mMinValue + i; + } + } + + /* + * The user might have typed in a number into the month field i.e. + * 10 instead of OCT so support that too. + */ + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + + // Ignore as if it's not a number we don't care + } + } + return mMinValue; + } + + /** + * Posts an {@link SetSelectionCommand} from the given selectionStart + * to selectionEnd. + */ + private void postSetSelectionCommand(int selectionStart, int selectionEnd) { + if (mSetSelectionCommand == null) { + mSetSelectionCommand = new SetSelectionCommand(); + } else { + removeCallbacks(mSetSelectionCommand); + } + mSetSelectionCommand.mSelectionStart = selectionStart; + mSetSelectionCommand.mSelectionEnd = selectionEnd; + post(mSetSelectionCommand); + } + + /** + * Ensures that the scroll wheel is adjusted i.e. there is no offset and the + * middle element is in the middle of the widget. + * + * @return Whether an adjustment has been made. + */ + private boolean ensureScrollWheelAdjusted() { + // adjust to the closest value + int deltaY = mInitialScrollOffset - mCurrentScrollOffset; + if (deltaY != 0) { + mPreviousScrollerY = 0; + if (Math.abs(deltaY) > mSelectorElementHeight / 2) { + deltaY += (deltaY > 0) ? -mSelectorElementHeight : mSelectorElementHeight; + } + mAdjustScroller.startScroll(0, 0, 0, deltaY, SELECTOR_ADJUSTMENT_DURATION_MILLIS); + invalidate(); + return true; + } + return false; + } + + private SupportAccessibilityNodeProvider getSupportAccessibilityNodeProvider() { + return new SupportAccessibilityNodeProvider(); + } + + /** + * Interface to listen for changes of the current value. + */ + public interface OnValueChangeListener { + + /** + * Called upon a change of the current value. + * + * @param picker The NumberPicker associated with this listener. + * @param oldVal The previous value. + * @param newVal The new value. + */ + void onValueChange(NumberPicker picker, int oldVal, int newVal); + } + + /** + * Interface to listen for the picker scroll state. + */ + public interface OnScrollListener { + + /** + * The view is not scrolling. + */ + public static int SCROLL_STATE_IDLE = 0; + + /** + * The user is scrolling using touch, and his finger is still on the screen. + */ + public static int SCROLL_STATE_TOUCH_SCROLL = 1; + + /** + * The user had previously been scrolling using touch and performed a fling. + */ + public static int SCROLL_STATE_FLING = 2; + + /** + * Callback invoked while the number picker scroll state has changed. + * + * @param view The view whose scroll state is being reported. + * @param scrollState The current scroll state. One of + * {@link #SCROLL_STATE_IDLE}, + * {@link #SCROLL_STATE_TOUCH_SCROLL} or + * {@link #SCROLL_STATE_IDLE}. + */ + public void onScrollStateChange(NumberPicker view, int scrollState); + } + + /** + * Interface used to format current value into a string for presentation. + */ + public interface Formatter { + + /** + * Formats a string representation of the current value. + * + * @param value The currently selected value. + * @return A formatted string representation. + */ + public String format(int value); + } + + /** + * Use a custom NumberPicker formatting callback to use two-digit minutes + * strings like "01". Keeping a static formatter etc. is the most efficient + * way to do this; it avoids creating temporary objects on every call to + * format(). + */ + private static class TwoDigitFormatter implements NumberPicker.Formatter { + final StringBuilder mBuilder = new StringBuilder(); + final Object[] mArgs = new Object[1]; + char mZeroDigit; + java.util.Formatter mFmt; + + TwoDigitFormatter() { + final Locale locale = Locale.getDefault(); + init(locale); + } + + private static char getZeroDigit(Locale locale) { + // return LocaleData.get(locale).zeroDigit; + return new DecimalFormatSymbols(locale).getZeroDigit(); + } + + private void init(Locale locale) { + mFmt = createFormatter(locale); + mZeroDigit = getZeroDigit(locale); + } + + public String format(int value) { + final Locale currentLocale = Locale.getDefault(); + if (mZeroDigit != getZeroDigit(currentLocale)) { + init(currentLocale); + } + mArgs[0] = value; + mBuilder.delete(0, mBuilder.length()); + mFmt.format("%02d", mArgs); + return mFmt.toString(); + } + + private java.util.Formatter createFormatter(Locale locale) { + return new java.util.Formatter(mBuilder, locale); + } + } + + /** + * @hide + */ + public static class CustomEditText extends EditText { + + public CustomEditText(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public void onEditorAction(int actionCode) { + super.onEditorAction(actionCode); + if (actionCode == EditorInfo.IME_ACTION_DONE) { + clearFocus(); + } + } + } + + /** + * Filter for accepting only valid indices or prefixes of the string + * representation of valid indices. + */ + class InputTextFilter extends NumberKeyListener { + + // XXX This doesn't allow for range limits when controlled by a + // soft input method! + public int getInputType() { + return InputType.TYPE_CLASS_TEXT; + } + + @Override + protected char[] getAcceptedChars() { + return DIGIT_CHARACTERS; + } + + @Override + public CharSequence filter( + CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { + if (mDisplayedValues == null) { + CharSequence filtered = super.filter(source, start, end, dest, dstart, dend); + if (filtered == null) { + filtered = source.subSequence(start, end); + } + + String result = String.valueOf(dest.subSequence(0, dstart)) + filtered + + dest.subSequence(dend, dest.length()); + + if ("".equals(result)) { + return result; + } + int val = getSelectedPos(result); + + /* + * Ensure the user can't type in a value greater than the max + * allowed. We have to allow less than min as the user might + * want to delete some numbers and then type a new number. + */ + if (val > mMaxValue) { + return ""; + } else { + return filtered; + } + } else { + CharSequence filtered = String.valueOf(source.subSequence(start, end)); + if (TextUtils.isEmpty(filtered)) { + return ""; + } + String result = String.valueOf(dest.subSequence(0, dstart)) + filtered + + dest.subSequence(dend, dest.length()); + String str = String.valueOf(result).toLowerCase(); + for (String val : mDisplayedValues) { + String valLowerCase = val.toLowerCase(); + if (valLowerCase.startsWith(str)) { + postSetSelectionCommand(result.length(), val.length()); + return val.subSequence(dstart, val.length()); + } + } + return ""; + } + } + } + + class PressedStateHelper implements Runnable { + public static final int BUTTON_INCREMENT = 1; + public static final int BUTTON_DECREMENT = 2; + + private final int MODE_PRESS = 1; + private final int MODE_TAPPED = 2; + + private int mManagedButton; + private int mMode; + + public void cancel() { + mMode = 0; + mManagedButton = 0; + NumberPicker.this.removeCallbacks(this); + if (mIncrementVirtualButtonPressed) { + mIncrementVirtualButtonPressed = false; + invalidate(0, mBottomSelectionDividerBottom, getRight(), getBottom()); + } + mDecrementVirtualButtonPressed = false; + if (mDecrementVirtualButtonPressed) { + invalidate(0, 0, getRight(), mTopSelectionDividerTop); + } + } + + public void buttonPressDelayed(int button) { + cancel(); + mMode = MODE_PRESS; + mManagedButton = button; + NumberPicker.this.postDelayed(this, ViewConfiguration.getTapTimeout()); + } + + public void buttonTapped(int button) { + cancel(); + mMode = MODE_TAPPED; + mManagedButton = button; + NumberPicker.this.post(this); + } + + @Override + public void run() { + switch (mMode) { + case MODE_PRESS: { + switch (mManagedButton) { + case BUTTON_INCREMENT: { + mIncrementVirtualButtonPressed = true; + invalidate(0, mBottomSelectionDividerBottom, getRight(), getBottom()); + } + break; + case BUTTON_DECREMENT: { + mDecrementVirtualButtonPressed = true; + invalidate(0, 0, getRight(), mTopSelectionDividerTop); + } + } + } + break; + case MODE_TAPPED: { + switch (mManagedButton) { + case BUTTON_INCREMENT: { + if (!mIncrementVirtualButtonPressed) { + NumberPicker.this.postDelayed(this, + ViewConfiguration.getPressedStateDuration()); + } + mIncrementVirtualButtonPressed ^= true; + invalidate(0, mBottomSelectionDividerBottom, getRight(), getBottom()); + } + break; + case BUTTON_DECREMENT: { + if (!mDecrementVirtualButtonPressed) { + NumberPicker.this.postDelayed(this, + ViewConfiguration.getPressedStateDuration()); + } + mDecrementVirtualButtonPressed ^= true; + invalidate(0, 0, getRight(), mTopSelectionDividerTop); + } + } + } + break; + } + } + } + + /** + * Command for setting the input text selection. + */ + class SetSelectionCommand implements Runnable { + private int mSelectionStart; + + private int mSelectionEnd; + + public void run() { + mInputText.setSelection(mSelectionStart, mSelectionEnd); + } + } + + /** + * Command for changing the current value from a long press by one. + */ + class ChangeCurrentByOneFromLongPressCommand implements Runnable { + private boolean mIncrement; + + private void setStep(boolean increment) { + mIncrement = increment; + } + + @Override + public void run() { + changeValueByOne(mIncrement); + postDelayed(this, mLongPressUpdateInterval); + } + } + + /** + * Command for beginning soft input on long press. + */ + class BeginSoftInputOnLongPressCommand implements Runnable { + + @Override + public void run() { + showSoftInput(); + mIngonreMoveEvents = true; + } + } + + class SupportAccessibilityNodeProvider { + + AccessibilityNodeProviderImpl mProvider; + + private SupportAccessibilityNodeProvider() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + mProvider = new AccessibilityNodeProviderImpl(); + } + } + + public boolean performAction(int virtualViewId, int action, Bundle arguments) { + return mProvider != null && mProvider.performAction(virtualViewId, action, arguments); + } + + public void sendAccessibilityEventForVirtualView(int virtualViewId, int eventType) { + if (mProvider != null) + mProvider.sendAccessibilityEventForVirtualView(virtualViewId, eventType); + } + } + + /** + * Class for managing virtual view tree rooted at this picker. + */ + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + class AccessibilityNodeProviderImpl extends AccessibilityNodeProvider { + private static final int UNDEFINED = Integer.MIN_VALUE; + + private static final int VIRTUAL_VIEW_ID_INCREMENT = 1; + + private static final int VIRTUAL_VIEW_ID_INPUT = 2; + + private static final int VIRTUAL_VIEW_ID_DECREMENT = 3; + + private final Rect mTempRect = new Rect(); + + private final int[] mTempArray = new int[2]; + + private int mAccessibilityFocusedView = UNDEFINED; + + @Override + public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { + switch (virtualViewId) { + case View.NO_ID: + return createAccessibilityNodeInfoForNumberPicker(getScrollX(), getScrollY(), + getScrollX() + (getRight() - getLeft()), getScrollY() + (getBottom() - getTop())); + case VIRTUAL_VIEW_ID_DECREMENT: + return createAccessibilityNodeInfoForVirtualButton(VIRTUAL_VIEW_ID_DECREMENT, + getVirtualDecrementButtonText(), getScrollX(), getScrollY(), + getScrollX() + (getRight() - getLeft()), + mTopSelectionDividerTop + mSelectionDividerHeight); + case VIRTUAL_VIEW_ID_INPUT: + return createAccessibiltyNodeInfoForInputText(); + case VIRTUAL_VIEW_ID_INCREMENT: + return createAccessibilityNodeInfoForVirtualButton(VIRTUAL_VIEW_ID_INCREMENT, + getVirtualIncrementButtonText(), getScrollX(), + mBottomSelectionDividerBottom - mSelectionDividerHeight, + getScrollX() + (getRight() - getLeft()), getScrollY() + (getBottom() - getTop())); + } + return super.createAccessibilityNodeInfo(virtualViewId); + } + + @Override + public List findAccessibilityNodeInfosByText(String searched, + int virtualViewId) { + if (TextUtils.isEmpty(searched)) { + return Collections.emptyList(); + } + String searchedLowerCase = searched.toLowerCase(); + List result = new ArrayList(); + switch (virtualViewId) { + case View.NO_ID: { + findAccessibilityNodeInfosByTextInChild(searchedLowerCase, + VIRTUAL_VIEW_ID_DECREMENT, result); + findAccessibilityNodeInfosByTextInChild(searchedLowerCase, + VIRTUAL_VIEW_ID_INPUT, result); + findAccessibilityNodeInfosByTextInChild(searchedLowerCase, + VIRTUAL_VIEW_ID_INCREMENT, result); + return result; + } + case VIRTUAL_VIEW_ID_DECREMENT: + case VIRTUAL_VIEW_ID_INCREMENT: + case VIRTUAL_VIEW_ID_INPUT: { + findAccessibilityNodeInfosByTextInChild(searchedLowerCase, virtualViewId, + result); + return result; + } + } + return super.findAccessibilityNodeInfosByText(searched, virtualViewId); + } + + @Override + public boolean performAction(int virtualViewId, int action, Bundle arguments) { + switch (virtualViewId) { + case View.NO_ID: { + switch (action) { + case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView != virtualViewId) { + mAccessibilityFocusedView = virtualViewId; + // requestAccessibilityFocus(); + performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); + return true; + } + } + return false; + case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView == virtualViewId) { + mAccessibilityFocusedView = UNDEFINED; + // clearAccessibilityFocus(); + performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null); + return true; + } + return false; + } + case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { + if (NumberPicker.this.isEnabled() + && (getWrapSelectorWheel() || getValue() < getMaxValue())) { + changeValueByOne(true); + return true; + } + } + return false; + case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { + if (NumberPicker.this.isEnabled() + && (getWrapSelectorWheel() || getValue() > getMinValue())) { + changeValueByOne(false); + return true; + } + } + return false; + } + } + break; + case VIRTUAL_VIEW_ID_INPUT: { + switch (action) { + case AccessibilityNodeInfo.ACTION_FOCUS: { + if (NumberPicker.this.isEnabled() && !mInputText.isFocused()) { + return mInputText.requestFocus(); + } + } + break; + case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: { + if (NumberPicker.this.isEnabled() && mInputText.isFocused()) { + mInputText.clearFocus(); + return true; + } + return false; + } + case AccessibilityNodeInfo.ACTION_CLICK: { + if (NumberPicker.this.isEnabled()) { + showSoftInput(); + return true; + } + return false; + } + case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView != virtualViewId) { + mAccessibilityFocusedView = virtualViewId; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); + mInputText.invalidate(); + return true; + } + } + return false; + case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView == virtualViewId) { + mAccessibilityFocusedView = UNDEFINED; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); + mInputText.invalidate(); + return true; + } + } + return false; + default: { + return mInputText.performAccessibilityAction(action, arguments); + } + } + } + return false; + case VIRTUAL_VIEW_ID_INCREMENT: { + switch (action) { + case AccessibilityNodeInfo.ACTION_CLICK: { + if (NumberPicker.this.isEnabled()) { + NumberPicker.this.changeValueByOne(true); + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_CLICKED); + return true; + } + } + return false; + case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView != virtualViewId) { + mAccessibilityFocusedView = virtualViewId; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); + invalidate(0, mBottomSelectionDividerBottom, getRight(), getBottom()); + return true; + } + } + return false; + case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView == virtualViewId) { + mAccessibilityFocusedView = UNDEFINED; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); + invalidate(0, mBottomSelectionDividerBottom, getRight(), getBottom()); + return true; + } + } + return false; + } + } + return false; + case VIRTUAL_VIEW_ID_DECREMENT: { + switch (action) { + case AccessibilityNodeInfo.ACTION_CLICK: { + if (NumberPicker.this.isEnabled()) { + final boolean increment = (virtualViewId == VIRTUAL_VIEW_ID_INCREMENT); + NumberPicker.this.changeValueByOne(increment); + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_CLICKED); + return true; + } + } + return false; + case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView != virtualViewId) { + mAccessibilityFocusedView = virtualViewId; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); + invalidate(0, 0, getRight(), mTopSelectionDividerTop); + return true; + } + } + return false; + case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: { + if (mAccessibilityFocusedView == virtualViewId) { + mAccessibilityFocusedView = UNDEFINED; + sendAccessibilityEventForVirtualView(virtualViewId, + AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED); + invalidate(0, 0, getRight(), mTopSelectionDividerTop); + return true; + } + } + return false; + } + } + return false; + } + return super.performAction(virtualViewId, action, arguments); + } + + public void sendAccessibilityEventForVirtualView(int virtualViewId, int eventType) { + switch (virtualViewId) { + case VIRTUAL_VIEW_ID_DECREMENT: { + if (hasVirtualDecrementButton()) { + sendAccessibilityEventForVirtualButton(virtualViewId, eventType, + getVirtualDecrementButtonText()); + } + } + break; + case VIRTUAL_VIEW_ID_INPUT: { + sendAccessibilityEventForVirtualText(eventType); + } + break; + case VIRTUAL_VIEW_ID_INCREMENT: { + if (hasVirtualIncrementButton()) { + sendAccessibilityEventForVirtualButton(virtualViewId, eventType, + getVirtualIncrementButtonText()); + } + } + break; + } + } + + private void sendAccessibilityEventForVirtualText(int eventType) { + if (((AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE)).isEnabled()) { + AccessibilityEvent event = AccessibilityEvent.obtain(eventType); + mInputText.onInitializeAccessibilityEvent(event); + mInputText.onPopulateAccessibilityEvent(event); + event.setSource(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT); + requestSendAccessibilityEvent(NumberPicker.this, event); + } + } + + private void sendAccessibilityEventForVirtualButton(int virtualViewId, int eventType, + String text) { + if (((AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE)).isEnabled()) { + AccessibilityEvent event = AccessibilityEvent.obtain(eventType); + event.setClassName(Button.class.getName()); + event.setPackageName(getContext().getPackageName()); + event.getText().add(text); + event.setEnabled(NumberPicker.this.isEnabled()); + event.setSource(NumberPicker.this, virtualViewId); + requestSendAccessibilityEvent(NumberPicker.this, event); + } + } + + private void findAccessibilityNodeInfosByTextInChild(String searchedLowerCase, + int virtualViewId, List outResult) { + switch (virtualViewId) { + case VIRTUAL_VIEW_ID_DECREMENT: { + String text = getVirtualDecrementButtonText(); + if (!TextUtils.isEmpty(text) + && text.toLowerCase().contains(searchedLowerCase)) { + outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_DECREMENT)); + } + } + return; + case VIRTUAL_VIEW_ID_INPUT: { + CharSequence text = mInputText.getText(); + if (!TextUtils.isEmpty(text) && + text.toString().toLowerCase().contains(searchedLowerCase)) { + outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INPUT)); + return; + } + CharSequence contentDesc = mInputText.getText(); + if (!TextUtils.isEmpty(contentDesc) && + contentDesc.toString().toLowerCase().contains(searchedLowerCase)) { + outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INPUT)); + return; + } + } + break; + case VIRTUAL_VIEW_ID_INCREMENT: { + String text = getVirtualIncrementButtonText(); + if (!TextUtils.isEmpty(text) + && text.toLowerCase().contains(searchedLowerCase)) { + outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INCREMENT)); + } + } + return; + } + } + + private AccessibilityNodeInfo createAccessibiltyNodeInfoForInputText() { + AccessibilityNodeInfo info = mInputText.createAccessibilityNodeInfo(); + info.setSource(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT); + if (mAccessibilityFocusedView != VIRTUAL_VIEW_ID_INPUT) { + info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); + } + if (mAccessibilityFocusedView == VIRTUAL_VIEW_ID_INPUT) { + info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); + } + return info; + } + + private AccessibilityNodeInfo createAccessibilityNodeInfoForVirtualButton(int virtualViewId, + String text, int left, int top, int right, int bottom) { + AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(); + info.setClassName(Button.class.getName()); + info.setPackageName(getContext().getPackageName()); + info.setSource(NumberPicker.this, virtualViewId); + info.setParent(NumberPicker.this); + info.setText(text); + info.setClickable(true); + info.setLongClickable(true); + info.setEnabled(NumberPicker.this.isEnabled()); + Rect boundsInParent = mTempRect; + boundsInParent.set(left, top, right, bottom); + // TODO info.setVisibleToUser(isVisibleToUser(boundsInParent)); + info.setBoundsInParent(boundsInParent); + Rect boundsInScreen = boundsInParent; + int[] locationOnScreen = mTempArray; + getLocationOnScreen(locationOnScreen); + boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]); + info.setBoundsInScreen(boundsInScreen); + + if (mAccessibilityFocusedView != virtualViewId) { + info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); + } + if (mAccessibilityFocusedView == virtualViewId) { + info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); + } + if (NumberPicker.this.isEnabled()) { + info.addAction(AccessibilityNodeInfo.ACTION_CLICK); + } + + return info; + } + + private AccessibilityNodeInfo createAccessibilityNodeInfoForNumberPicker(int left, int top, + int right, int bottom) { + AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(); + info.setClassName(NumberPicker.class.getName()); + info.setPackageName(getContext().getPackageName()); + info.setSource(NumberPicker.this); + + if (hasVirtualDecrementButton()) { + info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_DECREMENT); + } + info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT); + if (hasVirtualIncrementButton()) { + info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INCREMENT); + } + + info.setParent((View) getParentForAccessibility()); + info.setEnabled(NumberPicker.this.isEnabled()); + info.setScrollable(true); + + /** TODO: Figure out compat implementation for this + final float applicationScale = + getContext().getResources().getCompatibilityInfo().applicationScale; + + Rect boundsInParent = mTempRect; + boundsInParent.set(left, top, right, bottom); + boundsInParent.scale(applicationScale); + info.setBoundsInParent(boundsInParent); + + info.setVisibleToUser(isVisibleToUser()); + + Rect boundsInScreen = boundsInParent; + int[] locationOnScreen = mTempArray; + getLocationOnScreen(locationOnScreen); + boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]); + boundsInScreen.scale(applicationScale); + info.setBoundsInScreen(boundsInScreen); + */ + + if (mAccessibilityFocusedView != View.NO_ID) { + info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); + } + if (mAccessibilityFocusedView == View.NO_ID) { + info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); + } + if (NumberPicker.this.isEnabled()) { + if (getWrapSelectorWheel() || getValue() < getMaxValue()) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + } + if (getWrapSelectorWheel() || getValue() > getMinValue()) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + } + } + + return info; + } + + private boolean hasVirtualDecrementButton() { + return getWrapSelectorWheel() || getValue() > getMinValue(); + } + + private boolean hasVirtualIncrementButton() { + return getWrapSelectorWheel() || getValue() < getMaxValue(); + } + + private String getVirtualDecrementButtonText() { + int value = mValue - 1; + if (mWrapSelectorWheel) { + value = getWrappedSelectorIndex(value); + } + if (value >= mMinValue) { + return (mDisplayedValues == null) ? formatNumber(value) + : mDisplayedValues[value - mMinValue]; + } + return null; + } + + private String getVirtualIncrementButtonText() { + int value = mValue + 1; + if (mWrapSelectorWheel) { + value = getWrappedSelectorIndex(value); + } + if (value <= mMaxValue) { + return (mDisplayedValues == null) ? formatNumber(value) + : mDisplayedValues[value - mMinValue]; + } + return null; + } + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/Preset.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/Preset.java new file mode 100644 index 0000000..1263f21 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/Preset.java @@ -0,0 +1,42 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import org.json.JSONException; +import org.json.JSONObject; + +public class Preset { + public String modeandduration = ""; + public String delay = ""; + public String startsound = ""; + public String startsoundcustom = ""; + public String intervalduration = ""; + public String intervalsound = ""; + public String intervalsoundcustom = ""; + public String intervalcount = ""; + public String completesound = ""; + public String completesoundcustom = ""; + public String ringtone = ""; + public Boolean endless = false; + public Boolean vibrate = false; + + public JSONObject export() { + JSONObject jobj = new JSONObject(); + try { + jobj.put("modeandduration", modeandduration); + jobj.put("delay", delay); + jobj.put("startsound", startsound); + jobj.put("startsoundcustom", startsoundcustom); + jobj.put("intervalduration", intervalduration); + jobj.put("intervalsound", intervalsound); + jobj.put("intervalsoundcustom", intervalsoundcustom); + jobj.put("intervalcount", intervalcount); + jobj.put("completesound", completesound); + jobj.put("completesoundcustom", completesoundcustom); + jobj.put("ringtone", ringtone); + jobj.put("endless", endless); + jobj.put("vibrate", vibrate); + } catch (JSONException e1) { + e1.printStackTrace(); + } + return jobj; + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/ProgressActivity.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/ProgressActivity.java new file mode 100644 index 0000000..81c63c1 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/ProgressActivity.java @@ -0,0 +1,811 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.app.AlertDialog; +import android.app.DatePickerDialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.app.NavUtils; +import android.support.v4.view.PagerTabStrip; +import android.support.v4.view.ViewPager; +import android.util.Log; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.DatePicker; +import android.widget.EditText; +import android.widget.TabHost; +import android.widget.TextView; + +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.AdView; +import com.google.android.gms.analytics.GoogleAnalytics; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.Iterator; +import java.util.Locale; +import java.util.TimeZone; + +public class ProgressActivity extends FragmentActivity { + public SparseArray sessions_map = new SparseArray(); + TabHost mTabHost; + ViewPager mViewPager; + ProgressPagerAdapter mPagerAdapter = null; + int pagePosition = 0; + private AlertDialog addSessionDialog = null; + private AdView av = null; + private int SESSIONS_FRAGMENT = 0; + private int CALENDAR_FRAGMENT = 1; + private int STATS_FRAGMENT = 2; + private SessionsFragment sessionsFragment = null; + private MeditationAssistant ma = null; + private MenuItem menuCalendarBack = null; + private MenuItem menuCalendarForward = null; + private String beingSet = "started"; + private Button btnSetDateStarted = null; + private Button btnSetTimeStarted = null; + private Button btnSetDateCompleted = null; + private Button btnSetTimeCompleted = null; + private EditText editAddSessionMessage = null; + private int startedYear = -1; + private int startedMonth = -1; + private int startedDay = -1; + private int startedHour = -1; + private int startedMinute = -1; + private int completedYear = -1; + private int completedMonth = -1; + private int completedDay = -1; + private int completedHour = -1; + private int completedMinute = -1; + private DatePickerDialog.OnDateSetListener mDateSetListener = + new DatePickerDialog.OnDateSetListener() { + @Override + public void onDateSet(DatePicker view, int year, + int monthOfYear, int dayOfMonth) { + if (beingSet.equals("started")) { + startedYear = year; + startedMonth = monthOfYear; + startedDay = dayOfMonth; + + if (completedYear == -1 || completedMonth == -1 || completedDay == -1) { + completedYear = startedYear; + completedMonth = startedMonth; + completedDay = startedDay; + } else if (completedYear != -1 && completedMonth != -1 && completedDay != -1) { + Calendar c_started = Calendar.getInstance(); + c_started.set(Calendar.YEAR, startedYear); + c_started.set(Calendar.MONTH, startedMonth); + c_started.set(Calendar.DAY_OF_MONTH, startedDay); + c_started.set(Calendar.HOUR_OF_DAY, 0); + c_started.set(Calendar.MINUTE, 0); + c_started.set(Calendar.SECOND, 0); + c_started.set(Calendar.MILLISECOND, 0); + + Calendar c_completed = Calendar.getInstance(); + c_completed.set(Calendar.YEAR, completedYear); + c_completed.set(Calendar.MONTH, completedMonth); + c_completed.set(Calendar.DAY_OF_MONTH, completedDay); + c_completed.set(Calendar.HOUR_OF_DAY, 0); + c_completed.set(Calendar.MINUTE, 0); + c_completed.set(Calendar.SECOND, 0); + c_completed.set(Calendar.MILLISECOND, 0); + + if (c_started.getTimeInMillis() > c_completed.getTimeInMillis()) { + completedYear = startedYear; + completedMonth = startedMonth; + completedDay = startedDay; + } + } + } else { + completedYear = year; + completedMonth = monthOfYear; + completedDay = dayOfMonth; + } + + updateDateAndTimeButtons(); + } + }; + private TimePickerDialog.OnTimeSetListener mTimeSetListener = + new TimePickerDialog.OnTimeSetListener() { + @Override + public void onTimeSet(TimePicker view, int hourOfDay, int minute) { + if (beingSet.equals("started")) { + startedHour = hourOfDay; + startedMinute = minute; + + if (completedHour == -1 && completedMinute == -1) { + completedHour = startedHour; + completedMinute = startedMinute; + } + } else { + completedHour = hourOfDay; + completedMinute = minute; + } + + updateDateAndTimeButtons(); + } + }; + private AlertDialog sessionDetailsDialog = null; + + public MeditationAssistant getMeditationAssistant() { + if (ma == null) { + ma = (MeditationAssistant) this.getApplication(); + } + return ma; + } + + public void updateDateAndTimeButtons() { + SimpleDateFormat sdf_date = new SimpleDateFormat("MMMM d", + Locale.getDefault()); + SimpleDateFormat sdf_time = new SimpleDateFormat("h:mm a", + Locale.getDefault()); + + sdf_date.setTimeZone(TimeZone.getDefault()); + sdf_time.setTimeZone(TimeZone.getDefault()); + + if (startedYear == -1 || startedMonth == -1 || startedDay == -1) { + btnSetDateStarted.setText(getString(R.string.setDate)); + } else { + Calendar c = Calendar.getInstance(); + c.set(Calendar.YEAR, startedYear); + c.set(Calendar.MONTH, startedMonth); + c.set(Calendar.DAY_OF_MONTH, startedDay); + c.set(Calendar.HOUR_OF_DAY, 0); + c.set(Calendar.MINUTE, 0); + c.set(Calendar.SECOND, 0); + c.set(Calendar.MILLISECOND, 0); + + btnSetDateStarted.setText(sdf_date.format(c.getTime())); + } + if (completedYear == -1 || completedMonth == -1 || completedDay == -1) { + btnSetDateCompleted.setText(getString(R.string.setDate)); + } else { + Calendar c = Calendar.getInstance(); + c.set(Calendar.YEAR, completedYear); + c.set(Calendar.MONTH, completedMonth); + c.set(Calendar.DAY_OF_MONTH, completedDay); + c.set(Calendar.HOUR_OF_DAY, 0); + c.set(Calendar.MINUTE, 0); + c.set(Calendar.SECOND, 0); + c.set(Calendar.MILLISECOND, 0); + + btnSetDateCompleted.setText(sdf_date.format(c.getTime())); + } + + if (startedHour == -1 || startedMinute == -1) { + btnSetTimeStarted.setText(getString(R.string.setTime)); + } else { + Calendar c = Calendar.getInstance(); + c.set(Calendar.HOUR_OF_DAY, startedHour); + c.set(Calendar.MINUTE, startedMinute); + c.set(Calendar.SECOND, 0); + c.set(Calendar.MILLISECOND, 0); + + btnSetTimeStarted.setText(sdf_time.format(c.getTime())); + } + if (completedHour == -1 || completedMinute == -1) { + btnSetTimeCompleted.setText(getString(R.string.setTime)); + } else { + Calendar c = Calendar.getInstance(); + c.set(Calendar.HOUR_OF_DAY, completedHour); + c.set(Calendar.MINUTE, completedMinute); + c.set(Calendar.SECOND, 0); + c.set(Calendar.MILLISECOND, 0); + + btnSetTimeCompleted.setText(sdf_time.format(c.getTime())); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setTheme(getMeditationAssistant().getMATheme()); + setContentView(R.layout.activity_progress); + getActionBar().setDisplayHomeAsUpEnabled(true); /// todo: not necessary on settings activity why? + //getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); + + if (getPackageName().equals("sh.ftp.rocketninelabs.meditationassistant")) { + Log.d("MeditationAssistant", "Fetching ad"); + + av = (AdView) findViewById(R.id.adViewProgress); + av.setVisibility(View.VISIBLE); + AdRequest adRequest = new AdRequest.Builder() + .addTestDevice(AdRequest.DEVICE_ID_EMULATOR) + .build(); + av.loadAd(adRequest); + } + + mViewPager = (ViewPager) findViewById(R.id.pager); + + mPagerAdapter = new ProgressPagerAdapter( + getSupportFragmentManager()); + + mViewPager.setAdapter(mPagerAdapter); + + /*ActionBar.TabListener tabListener = new ActionBar.TabListener() { + + public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { + // hide the given tab + } + + public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) { + // probably ignore this event + } + + @Override + public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { + + } + }; + + getActionBar().addTab(getActionBar().newTab() + .setText(getString(R.string.sessions)) + .setTabListener(tabListener)); + getActionBar().addTab(getActionBar().newTab() + .setText(getString(R.string.statistics)) + .setTabListener(tabListener)); + + getActionBar().addTab(getActionBar().newTab() + .setText(getString(R.string.calendar)) + .setTabListener(tabListener));*/ + + PagerTabStrip tabStrip = (PagerTabStrip) findViewById(R.id.titles); + tabStrip.setDrawFullUnderline(true); + + if (getMeditationAssistant().getMAThemeString().equals("buddhism")) { + tabStrip.setBackgroundColor(getResources().getColor(R.color.buddhism_tab_background)); + tabStrip.setTabIndicatorColor(getResources().getColor(R.color.buddhism_tab_color)); + tabStrip.setTextColor(getResources().getColor(android.R.color.primary_text_dark)); + } else { + tabStrip.setTabIndicatorColor(getResources().getColor(android.R.color.holo_blue_dark)); + } + + + /*ViewPagerIndicator titleIndicator = (TitlePageIndicator) findViewById(R.id.titles); + titleIndicator.setViewPager(mViewPager); + + titleIndicator.setFooterIndicatorStyle(IndicatorStyle.Underline); + + titleIndicator + .setOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, + float positionOffset, int positionOffsetPixels) { + } + + @Override + public void onPageScrollStateChanged(int state) { + } + + @Override + public void onPageSelected(int position) { + if (menuCalendarBack != null + && menuCalendarForward != null) { + pagePosition = position; + } + } + });*/ + + String defaulttab = getMeditationAssistant().getPrefs().getString( + "pref_progresstab", "calendar"); + if (defaulttab.equals("sessions")) { + mViewPager.setCurrentItem(SESSIONS_FRAGMENT, false); + } else if (defaulttab.equals("stats")) { + mViewPager.setCurrentItem(STATS_FRAGMENT, false); + } else { + mViewPager.setCurrentItem(CALENDAR_FRAGMENT, false); + } + + if (getMeditationAssistant().sendUsageReports()) { + getMeditationAssistant().getTracker(MeditationAssistant.TrackerName.APP_TRACKER); + } + } + + public void goToSessionAtDate(int[] date) { + if (date != null) { + SessionSQL sessionsql = getMeditationAssistant().db.getSessionByDate(String.valueOf(date[0]) + "-" + String.valueOf(date[1] + 1) + "-" + String.valueOf(date[2])); + if (sessionsql != null) { + final Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(sessionsql._completed * 1000); + Date sess_date = cal.getTime(); + + if (getMeditationAssistant().db.numSessionsByDate(String.valueOf(date[0]) + "-" + String.valueOf(date[1] + 1) + "-" + String.valueOf(date[2])) > 1) { + if (sessionDetailsDialog != null && sessionDetailsDialog.isShowing()) { + sessionDetailsDialog.dismiss(); + } + + SimpleDateFormat sdf = new SimpleDateFormat("d MMM yyyy", + Locale.getDefault()); + SimpleDateFormat sdf2 = new SimpleDateFormat("h:mm a", + Locale.getDefault()); + + ArrayList sessions = getMeditationAssistant().db.getSessionsByDate(String.valueOf(date[0]) + "-" + String.valueOf(date[1] + 1) + "-" + String.valueOf(date[2])); + + final ArrayAdapter sessionsDialogAdapter = new ArrayAdapter( + this, + android.R.layout.select_dialog_item); + + sessions_map.clear(); + int session_index = 0; + for (Iterator i = sessions.iterator(); i.hasNext(); ) { + SessionSQL session = i.next(); + Calendar cal2 = Calendar.getInstance(); + cal2.setTimeInMillis(session._completed * 1000); + sessionsDialogAdapter.add(String.valueOf(session._length / 3600) + ":" + + String.format("%02d", (session._length % 3600) / 60) + + " - " + sdf2.format(cal2.getTime())); + + sessions_map.put(session_index, session); + session_index++; + } + + if (sessionDetailsDialog != null && sessionDetailsDialog.isShowing()) { + sessionDetailsDialog.dismiss(); + } + + sessionDetailsDialog = new AlertDialog.Builder(this) + .setIcon( + getResources().getDrawable( + getMeditationAssistant().getTheme().obtainStyledAttributes(getMeditationAssistant().getMATheme(true), + new int[]{R.attr.actionIconGoToToday}) + .getResourceId(0, 0) + ) + ) + .setTitle(sdf.format(sess_date)) + .setAdapter(sessionsDialogAdapter, + new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + SessionSQL session = sessions_map.get(which); + if (session != null) { + showSessionPopup(session); + } + + try { + dialog.dismiss(); + } catch (Exception e) { + + } + } + }) + .create(); + + sessionDetailsDialog.show(); + } else { + showSessionPopup(sessionsql); + } + + /*mViewPager.setCurrentItem(SESSIONS_FRAGMENT, false); + Integer session_position = ((SessionAdapter) sessionsFragment.getListAdapter()).sessions_map.get(String.valueOf(date[0]) + "-" + String.valueOf(date[1] + 1) + "-" + String.valueOf(date[2])); + if (session_position != null) { + Log.d("MeditationAssistant", "Position: " + String.valueOf(session_position)); + sessionsFragment.getListView().smoothScrollToPosition(session_position); + }*/ + } + } + } + + private void showSessionPopup(SessionSQL sessionsql) { + final Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(sessionsql._completed * 1000); + Date sess_date = cal.getTime(); + + SimpleDateFormat sdf = new SimpleDateFormat("d MMM yyyy h:mm a", + Locale.getDefault()); + sdf.setTimeZone(TimeZone.getDefault()); + + SimpleDateFormat sdf2 = new SimpleDateFormat("h:mm a", + Locale.getDefault()); + sdf2.setTimeZone(TimeZone.getDefault()); + + String session_title = String.valueOf(sessionsql._length / 3600) + ":" + + String.format("%02d", (sessionsql._length % 3600) / 60) + + " - " + sdf.format(sess_date); + + cal.setTimeInMillis(sessionsql._started * 1000); + String session_started = sdf2.format(cal.getTime()); + + View detailsView = LayoutInflater.from(this).inflate( + R.layout.session_details, + (ViewGroup) findViewById(R.id.sessionDetails_root)); + + TextView txtSessionDetailsStarted = (TextView) detailsView.findViewById(R.id.txtSessionDetailsStarted); + TextView txtSessionDetailsMessage = (TextView) detailsView.findViewById(R.id.txtSessionDetailsMessage); + + txtSessionDetailsStarted.setText(String.format(getString(R.string.sessionStartedAt), session_started)); + + if (!sessionsql._message.trim().equals("")) { + txtSessionDetailsMessage.setText(sessionsql._message.trim()); + } else { + View divSessionDetailsMessage = detailsView.findViewById(R.id.divSessionDetailsMessage); + + divSessionDetailsMessage.setVisibility(View.GONE); + txtSessionDetailsMessage.setVisibility(View.GONE); + } + + if (sessionDetailsDialog != null && sessionDetailsDialog.isShowing()) { + sessionDetailsDialog.dismiss(); + } + + sessionDetailsDialog = new AlertDialog.Builder(this) + .setIcon( + getResources().getDrawable( + getMeditationAssistant().getTheme().obtainStyledAttributes(getMeditationAssistant().getMATheme(true), + new int[]{R.attr.actionIconGoToToday}) + .getResourceId(0, 0) + ) + ) + .setTitle(session_title) + .setView(detailsView) + .create(); + + sessionDetailsDialog.show(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.progress, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int i = item.getItemId(); + if (i == android.R.id.home) { + NavUtils.navigateUpFromSameTask(this); + } else if (i == R.id.addSession) { + if (addSessionDialog != null) { + try { + if (addSessionDialog.isShowing()) { + addSessionDialog.dismiss(); + } + } catch (WindowManager.BadTokenException e) { + // Activity is not in the foreground + } + } + + //debug + + if (getMeditationAssistant() + .getTimeStartMeditate() > 0) { + getMeditationAssistant().shortToast(getString(R.string.addSessionMeditating)); + return true; + } + + startedYear = -1; + startedMonth = -1; + startedDay = -1; + startedHour = -1; + startedMinute = -1; + + completedYear = -1; + completedMonth = -1; + completedDay = -1; + completedHour = -1; + completedMinute = -1; + + View addSessionView = LayoutInflater.from(this).inflate( + R.layout.session_add, + (ViewGroup) findViewById(R.id.sessionAdd_root)); + + btnSetDateStarted = (Button) addSessionView.findViewById(R.id.btnSetDateStarted); + btnSetTimeStarted = (Button) addSessionView.findViewById(R.id.btnSetTimeStarted); + btnSetDateCompleted = (Button) addSessionView.findViewById(R.id.btnSetDateCompleted); + btnSetTimeCompleted = (Button) addSessionView.findViewById(R.id.btnSetTimeCompleted); + editAddSessionMessage = (EditText) addSessionView.findViewById(R.id.editAddSessionMessage); + + btnSetDateStarted.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + beingSet = "started"; + DatePickerDialog dateDialog = null; + + if (startedYear == -1 || startedMonth == -1 || startedDay == -1) { + Calendar c = Calendar.getInstance(); + dateDialog = new DatePickerDialog(ProgressActivity.this, + mDateSetListener, + c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)); + } else { + dateDialog = new DatePickerDialog(ProgressActivity.this, + mDateSetListener, + startedYear, startedMonth, startedDay); + } + + dateDialog.show(); + } + }); + btnSetTimeStarted.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + beingSet = "started"; + TimePickerDialog timeDialog = null; + + if (startedHour == -1 || startedMinute == -1) { + Calendar c = Calendar.getInstance(); + timeDialog = new TimePickerDialog(ProgressActivity.this, + mTimeSetListener, + c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), false); + } else { + timeDialog = new TimePickerDialog(ProgressActivity.this, + mTimeSetListener, + startedHour, startedMinute, false); + } + + timeDialog.show(); + } + }); + btnSetDateCompleted.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + beingSet = "completed"; + DatePickerDialog dateDialog = null; + + if (completedYear == -1 || completedMonth == -1 || completedDay == -1) { + Calendar c = Calendar.getInstance(); + dateDialog = new DatePickerDialog(ProgressActivity.this, + mDateSetListener, + c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)); + } else { + dateDialog = new DatePickerDialog(ProgressActivity.this, + mDateSetListener, + completedYear, completedMonth, completedDay); + } + + dateDialog.show(); + } + }); + btnSetTimeCompleted.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + beingSet = "completed"; + TimePickerDialog timeDialog = null; + + if (completedHour == -1 || completedMinute == -1) { + Calendar c = Calendar.getInstance(); + timeDialog = new TimePickerDialog(ProgressActivity.this, + mTimeSetListener, + c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), false); + } else { + timeDialog = new TimePickerDialog(ProgressActivity.this, + mTimeSetListener, + completedHour, completedMinute, false); + } + + timeDialog.show(); + } + }); + + updateDateAndTimeButtons(); + + addSessionDialog = new AlertDialog.Builder(this) + .setIcon( + getResources().getDrawable( + getMeditationAssistant().getTheme().obtainStyledAttributes(getMeditationAssistant().getMATheme(true), + new int[]{R.attr.actionIconNew}) + .getResourceId(0, 0) + ) + ) + .setTitle(getString(R.string.addSession)) + .setView(addSessionView) + .setPositiveButton(getString(R.string.add), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, + int which) { + // Overridden later + } + }) + .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, + int which) { + dialogInterface.dismiss(); + } + }) + .create(); + + addSessionDialog.show(); + + Button saveButton = addSessionDialog.getButton(AlertDialog.BUTTON_POSITIVE); + saveButton.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View view) { + if (startedYear == -1 || startedMonth == -1 || startedDay == -1 || startedHour == -1 || startedMinute == -1 || completedYear == -1 || completedMonth == -1 || completedDay == -1 || completedHour == -1 || completedMinute == -1) { + getMeditationAssistant().shortToast(getString(R.string.invalidDateOrTime)); + } else { + Calendar c_started = Calendar.getInstance(); + c_started.set(Calendar.YEAR, startedYear); + c_started.set(Calendar.MONTH, startedMonth); + c_started.set(Calendar.DAY_OF_MONTH, startedDay); + c_started.set(Calendar.HOUR_OF_DAY, startedHour); + c_started.set(Calendar.MINUTE, startedMinute); + c_started.set(Calendar.SECOND, 0); + c_started.set(Calendar.MILLISECOND, 0); + + Calendar c_completed = Calendar.getInstance(); + c_completed.set(Calendar.YEAR, completedYear); + c_completed.set(Calendar.MONTH, completedMonth); + c_completed.set(Calendar.DAY_OF_MONTH, completedDay); + c_completed.set(Calendar.HOUR_OF_DAY, completedHour); + c_completed.set(Calendar.MINUTE, completedMinute); + c_completed.set(Calendar.SECOND, 0); + c_completed.set(Calendar.MILLISECOND, 0); + + if (c_started.getTimeInMillis() > Calendar.getInstance().getTimeInMillis() || c_completed.getTimeInMillis() > Calendar.getInstance().getTimeInMillis() || c_completed.getTimeInMillis() <= c_started.getTimeInMillis()) { + getMeditationAssistant().shortToast(getString(R.string.invalidDateOrTime)); + } else if (getMeditationAssistant().db + .getSessionByStarted(c_started.getTimeInMillis() / 1000) == null) { + getMeditationAssistant().getMediNET().resetSession(); + getMeditationAssistant().getMediNET().session.started = c_started.getTimeInMillis() / 1000; + getMeditationAssistant().getMediNET().session.length = ((c_completed.getTimeInMillis() / 1000) - (c_started.getTimeInMillis() / 1000)); + getMeditationAssistant().getMediNET().session.completed = c_completed.getTimeInMillis() / 1000; + getMeditationAssistant().getMediNET().session.message = editAddSessionMessage.getText().toString().trim(); + getMeditationAssistant().getMediNET().saveSession(true, false); + + addSessionDialog.dismiss(); + + if (sessionsFragment != null) { + sessionsFragment.refreshSessionList(); + } + + /*if (calendarFragment != null) { + calendarFragment.refreshMonthDisplay(); + }*/ + } else { + getMeditationAssistant().shortToast(getString(R.string.addSessionExists)); + } + } + } + }); + + return true; + } + + return super.onOptionsItemSelected(item); + } + + @Override + public void onStart() { + super.onStart(); + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStart(this); + } + } + + @Override + protected void onStop() { + super.onStop(); + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStop(this); + } + } + + @Override + public void onPause() { + if (av != null) { + av.pause(); + } + super.onPause(); + } + + @Override + public void onResume() { + super.onResume(); + if (av != null) { + av.resume(); + } + } + + @Override + public void onDestroy() { + if (av != null) { + av.destroy(); + } + super.onDestroy(); + } + + class ProgressPagerAdapter extends FragmentPagerAdapter { + private final String[] ProgressPages = new String[]{ + getString(R.string.sessions), getString(R.string.calendar), getString(R.string.statistics)}; + + public ProgressPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public int getCount() { + return ProgressPages.length; + } + + @Override + public Fragment getItem(int position) { + if (position == SESSIONS_FRAGMENT) { + sessionsFragment = new SessionsFragment(); + return sessionsFragment; + } else if (position == CALENDAR_FRAGMENT) { + CalendarFragment calendarFragment = new CalendarFragment(); + return calendarFragment; + } else if (position == STATS_FRAGMENT) { + return new StatsFragment(); + } else { + return null; + } + } + + @Override + public CharSequence getPageTitle(int position) { + return ProgressPages[position % ProgressPages.length].toUpperCase(); + } + } +} + +/* +public class ProgressActivity extends FragmentActivity + implements ItemListFragment.Callbacks { + + /** + * Whether or not the activity is in two-pane mode, i.e. running on a tablet + * device. + private boolean mTwoPane; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_item_list); + + if (findViewById(R.id.item_detail_container) != null) { + // The detail container view will be present only in the + // large-screen layouts (res/values-large and + // res/values-sw600dp). If this view is present, then the + // activity should be in two-pane mode. + mTwoPane = true; + + // In two-pane mode, list items should be given the + // 'activated' state when touched. + ((ItemListFragment) getSupportFragmentManager() + .findFragmentById(R.id.item_list)) + .setActivateOnItemClick(true); + } + } + + /** + * Callback method from {@link ItemListFragment.Callbacks} + * indicating that the item with the given ID was selected. + @Override + public void onItemSelected(String id) { + if (mTwoPane) { + // In two-pane mode, show the detail view in this activity by + // adding or replacing the detail fragment using a + // fragment transaction. + Bundle arguments = new Bundle(); + arguments.putString(ItemDetailFragment.ARG_ITEM_ID, id); + ItemDetailFragment fragment = new ItemDetailFragment(); + fragment.setArguments(arguments); + getSupportFragmentManager().beginTransaction() + .replace(R.id.item_detail_container, fragment) + .apply(); + + } else { + // In single-pane mode, simply start the detail activity + // for the selected item ID. + Intent detailIntent = new Intent(this, ItemDetailActivity.class); + detailIntent.putExtra(ItemDetailFragment.ARG_ITEM_ID, id); + startActivity(detailIntent); + } + } +} +*/ \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/Scroller.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/Scroller.java new file mode 100644 index 0000000..4f602e3 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/Scroller.java @@ -0,0 +1,495 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +/* + * Copyright (C) 2006 The Android Open Source Project + * + * 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. + */ + +import android.content.Context; +import android.hardware.SensorManager; +import android.util.FloatMath; +import android.view.ViewConfiguration; +import android.view.animation.AnimationUtils; +import android.view.animation.Interpolator; + +/** + * This class encapsulates scrolling. The duration of the scroll + * can be passed in the constructor and specifies the maximum time that + * the scrolling animation should take. Past this time, the scrolling is + * automatically moved to its final stage and computeScrollOffset() + * will always return false to indicate that scrolling is over. + */ +public class Scroller { + private static final int DEFAULT_DURATION = 250; + private static final int SCROLL_MODE = 0; + private static final int FLING_MODE = 1; + private static final int NB_SAMPLES = 100; + private static final float[] SPLINE = new float[NB_SAMPLES + 1]; + private static float DECELERATION_RATE = (float) (Math.log(0.75) / Math.log(0.9)); + @SuppressWarnings("FieldCanBeLocal") + private static float ALPHA = 800; // pixels / seconds + private static float START_TENSION = 0.4f; // Tension at start: (0.4 * total T, 1.0 * Distance) + private static float END_TENSION = 1.0f - START_TENSION; + private static float sViscousFluidScale; + private static float sViscousFluidNormalize; + + static { + float x_min = 0.0f; + for (int i = 0; i <= NB_SAMPLES; i++) { + final float t = (float) i / NB_SAMPLES; + float x_max = 1.0f; + float x, tx, coef; + while (true) { + x = x_min + (x_max - x_min) / 2.0f; + coef = 3.0f * x * (1.0f - x); + tx = coef * ((1.0f - x) * START_TENSION + x * END_TENSION) + x * x * x; + if (Math.abs(tx - t) < 1E-5) break; + if (tx > t) x_max = x; + else x_min = x; + } + final float d = coef + x * x * x; + SPLINE[i] = d; + } + SPLINE[NB_SAMPLES] = 1.0f; + + // This controls the viscous fluid effect (how much of it) + sViscousFluidScale = 8.0f; + // must be set to 1.0 (used in viscousFluid()) + sViscousFluidNormalize = 1.0f; + sViscousFluidNormalize = 1.0f / viscousFluid(1.0f); + } + + private final float mPpi; + private int mMode; + private int mStartX; + private int mStartY; + private int mFinalX; + private int mFinalY; + private int mMinX; + private int mMaxX; + private int mMinY; + private int mMaxY; + private int mCurrX; + private int mCurrY; + private long mStartTime; + private int mDuration; + private float mDurationReciprocal; + private float mDeltaX; + private float mDeltaY; + private boolean mFinished; + private Interpolator mInterpolator; + private boolean mFlywheel; + private float mVelocity; + private float mDeceleration; + + /** + * Create a Scroller with the default duration and interpolator. + */ + public Scroller(Context context) { + this(context, null); + } + + /** + * Create a Scroller with the specified interpolator. If the interpolator is + * null, the default (viscous) interpolator will be used. "Flywheel" behavior will + * be in effect for apps targeting Honeycomb or newer. + */ + public Scroller(Context context, Interpolator interpolator) { + this(context, interpolator, true); + } + + /** + * Create a Scroller with the specified interpolator. If the interpolator is + * null, the default (viscous) interpolator will be used. Specify whether or + * not to support progressive "flywheel" behavior in flinging. + */ + public Scroller(Context context, Interpolator interpolator, boolean flywheel) { + mFinished = true; + mInterpolator = interpolator; + mPpi = context.getResources().getDisplayMetrics().density * 160.0f; + mDeceleration = computeDeceleration(ViewConfiguration.getScrollFriction()); + mFlywheel = flywheel; + } + + static float viscousFluid(float x) { + x *= sViscousFluidScale; + if (x < 1.0f) { + x -= (1.0f - (float) Math.exp(-x)); + } else { + float start = 0.36787944117f; // 1/e == exp(-1) + x = 1.0f - (float) Math.exp(1.0f - x); + x = start + x * (1.0f - start); + } + x *= sViscousFluidNormalize; + return x; + } + + /** + * The amount of friction applied to flings. The default value + * is {@link android.view.ViewConfiguration#getScrollFriction}. + * + * @param friction A scalar dimension-less value representing the coefficient of + * friction. + */ + public final void setFriction(float friction) { + mDeceleration = computeDeceleration(friction); + } + + private float computeDeceleration(float friction) { + return SensorManager.GRAVITY_EARTH // g (m/s^2) + * 39.37f // inch/meter + * mPpi // pixels per inch + * friction; + } + + /** + * Returns whether the scroller has finished scrolling. + * + * @return True if the scroller has finished scrolling, false otherwise. + */ + public final boolean isFinished() { + return mFinished; + } + + /** + * Force the finished field to a particular value. + * + * @param finished The new finished value. + */ + public final void forceFinished(boolean finished) { + mFinished = finished; + } + + /** + * Returns how long the scroll event will take, in milliseconds. + * + * @return The duration of the scroll in milliseconds. + */ + public final int getDuration() { + return mDuration; + } + + /** + * Returns the current X offset in the scroll. + * + * @return The new X offset as an absolute distance from the origin. + */ + public final int getCurrX() { + return mCurrX; + } + + /** + * Returns the current Y offset in the scroll. + * + * @return The new Y offset as an absolute distance from the origin. + */ + public final int getCurrY() { + return mCurrY; + } + + /** + * Returns the current velocity. + * + * @return The original velocity less the deceleration. Result may be + * negative. + */ + public float getCurrVelocity() { + return mVelocity - mDeceleration * timePassed() / 2000.0f; + } + + /** + * Returns the start X offset in the scroll. + * + * @return The start X offset as an absolute distance from the origin. + */ + public final int getStartX() { + return mStartX; + } + + /** + * Returns the start Y offset in the scroll. + * + * @return The start Y offset as an absolute distance from the origin. + */ + public final int getStartY() { + return mStartY; + } + + /** + * Returns where the scroll will end. Valid only for "fling" scrolls. + * + * @return The final X offset as an absolute distance from the origin. + */ + public final int getFinalX() { + return mFinalX; + } + + /** + * Sets the final position (X) for this scroller. + * + * @param newX The new X offset as an absolute distance from the origin. + * @see #extendDuration(int) + * @see #setFinalY(int) + */ + public void setFinalX(int newX) { + mFinalX = newX; + mDeltaX = mFinalX - mStartX; + mFinished = false; + } + + /** + * Returns where the scroll will end. Valid only for "fling" scrolls. + * + * @return The final Y offset as an absolute distance from the origin. + */ + public final int getFinalY() { + return mFinalY; + } + + /** + * Sets the final position (Y) for this scroller. + * + * @param newY The new Y offset as an absolute distance from the origin. + * @see #extendDuration(int) + * @see #setFinalX(int) + */ + public void setFinalY(int newY) { + mFinalY = newY; + mDeltaY = mFinalY - mStartY; + mFinished = false; + } + + /** + * Call this when you want to know the new location. If it returns true, + * the animation is not yet finished. loc will be altered to provide the + * new location. + */ + public boolean computeScrollOffset() { + if (mFinished) { + return false; + } + + int timePassed = (int) (AnimationUtils.currentAnimationTimeMillis() - mStartTime); + + if (timePassed < mDuration) { + switch (mMode) { + case SCROLL_MODE: + float x = timePassed * mDurationReciprocal; + + if (mInterpolator == null) + x = viscousFluid(x); + else + x = mInterpolator.getInterpolation(x); + + mCurrX = mStartX + Math.round(x * mDeltaX); + mCurrY = mStartY + Math.round(x * mDeltaY); + break; + case FLING_MODE: + final float t = (float) timePassed / mDuration; + final int index = (int) (NB_SAMPLES * t); + final float t_inf = (float) index / NB_SAMPLES; + final float t_sup = (float) (index + 1) / NB_SAMPLES; + final float d_inf = SPLINE[index]; + final float d_sup = SPLINE[index + 1]; + final float distanceCoef = d_inf + (t - t_inf) / (t_sup - t_inf) * (d_sup - d_inf); + + mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX)); + // Pin to mMinX <= mCurrX <= mMaxX + mCurrX = Math.min(mCurrX, mMaxX); + mCurrX = Math.max(mCurrX, mMinX); + + mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY)); + // Pin to mMinY <= mCurrY <= mMaxY + mCurrY = Math.min(mCurrY, mMaxY); + mCurrY = Math.max(mCurrY, mMinY); + + if (mCurrX == mFinalX && mCurrY == mFinalY) { + mFinished = true; + } + + break; + } + } else { + mCurrX = mFinalX; + mCurrY = mFinalY; + mFinished = true; + } + return true; + } + + /** + * Start scrolling by providing a starting point and the distance to travel. + * The scroll will use the default value of 250 milliseconds for the + * duration. + * + * @param startX Starting horizontal scroll offset in pixels. Positive + * numbers will scroll the content to the left. + * @param startY Starting vertical scroll offset in pixels. Positive numbers + * will scroll the content up. + * @param dx Horizontal distance to travel. Positive numbers will scroll the + * content to the left. + * @param dy Vertical distance to travel. Positive numbers will scroll the + * content up. + */ + public void startScroll(int startX, int startY, int dx, int dy) { + startScroll(startX, startY, dx, dy, DEFAULT_DURATION); + } + + /** + * Start scrolling by providing a starting point and the distance to travel. + * + * @param startX Starting horizontal scroll offset in pixels. Positive + * numbers will scroll the content to the left. + * @param startY Starting vertical scroll offset in pixels. Positive numbers + * will scroll the content up. + * @param dx Horizontal distance to travel. Positive numbers will scroll the + * content to the left. + * @param dy Vertical distance to travel. Positive numbers will scroll the + * content up. + * @param duration Duration of the scroll in milliseconds. + */ + public void startScroll(int startX, int startY, int dx, int dy, int duration) { + mMode = SCROLL_MODE; + mFinished = false; + mDuration = duration; + mStartTime = AnimationUtils.currentAnimationTimeMillis(); + mStartX = startX; + mStartY = startY; + mFinalX = startX + dx; + mFinalY = startY + dy; + mDeltaX = dx; + mDeltaY = dy; + mDurationReciprocal = 1.0f / (float) mDuration; + } + + /** + * Start scrolling based on a fling gesture. The distance travelled will + * depend on the initial velocity of the fling. + * + * @param startX Starting point of the scroll (X) + * @param startY Starting point of the scroll (Y) + * @param velocityX Initial velocity of the fling (X) measured in pixels per + * second. + * @param velocityY Initial velocity of the fling (Y) measured in pixels per + * second + * @param minX Minimum X value. The scroller will not scroll past this + * point. + * @param maxX Maximum X value. The scroller will not scroll past this + * point. + * @param minY Minimum Y value. The scroller will not scroll past this + * point. + * @param maxY Maximum Y value. The scroller will not scroll past this + * point. + */ + public void fling(int startX, int startY, int velocityX, int velocityY, + int minX, int maxX, int minY, int maxY) { + // Continue a scroll or fling in progress + if (mFlywheel && !mFinished) { + float oldVel = getCurrVelocity(); + + float dx = (float) (mFinalX - mStartX); + float dy = (float) (mFinalY - mStartY); + float hyp = FloatMath.sqrt(dx * dx + dy * dy); + + float ndx = dx / hyp; + float ndy = dy / hyp; + + float oldVelocityX = ndx * oldVel; + float oldVelocityY = ndy * oldVel; + if (Math.signum(velocityX) == Math.signum(oldVelocityX) && + Math.signum(velocityY) == Math.signum(oldVelocityY)) { + velocityX += oldVelocityX; + velocityY += oldVelocityY; + } + } + + mMode = FLING_MODE; + mFinished = false; + + float velocity = FloatMath.sqrt(velocityX * velocityX + velocityY * velocityY); + + mVelocity = velocity; + final double l = Math.log(START_TENSION * velocity / ALPHA); + mDuration = (int) (1000.0 * Math.exp(l / (DECELERATION_RATE - 1.0))); + mStartTime = AnimationUtils.currentAnimationTimeMillis(); + mStartX = startX; + mStartY = startY; + + float coeffX = velocity == 0 ? 1.0f : velocityX / velocity; + float coeffY = velocity == 0 ? 1.0f : velocityY / velocity; + + int totalDistance = + (int) (ALPHA * Math.exp(DECELERATION_RATE / (DECELERATION_RATE - 1.0) * l)); + + mMinX = minX; + mMaxX = maxX; + mMinY = minY; + mMaxY = maxY; + + mFinalX = startX + Math.round(totalDistance * coeffX); + // Pin to mMinX <= mFinalX <= mMaxX + mFinalX = Math.min(mFinalX, mMaxX); + mFinalX = Math.max(mFinalX, mMinX); + + mFinalY = startY + Math.round(totalDistance * coeffY); + // Pin to mMinY <= mFinalY <= mMaxY + mFinalY = Math.min(mFinalY, mMaxY); + mFinalY = Math.max(mFinalY, mMinY); + } + + /** + * Stops the animation. Contrary to {@link #forceFinished(boolean)}, + * aborting the animating cause the scroller to move to the final x and y + * position + * + * @see #forceFinished(boolean) + */ + public void abortAnimation() { + mCurrX = mFinalX; + mCurrY = mFinalY; + mFinished = true; + } + + /** + * Extend the scroll animation. This allows a running animation to scroll + * further and longer, when used with {@link #setFinalX(int)} or {@link #setFinalY(int)}. + * + * @param extend Additional time to scroll in milliseconds. + * @see #setFinalX(int) + * @see #setFinalY(int) + */ + public void extendDuration(int extend) { + int passed = timePassed(); + mDuration = passed + extend; + mDurationReciprocal = 1.0f / mDuration; + mFinished = false; + } + + /** + * Returns the time elapsed since the beginning of the scrolling. + * + * @return The elapsed time in milliseconds. + */ + public int timePassed() { + return (int) (AnimationUtils.currentAnimationTimeMillis() - mStartTime); + } + + /** + * @hide + */ + public boolean isScrollingInDirection(float xvel, float yvel) { + return !mFinished && Math.signum(xvel) == Math.signum(mFinalX - mStartX) && + Math.signum(yvel) == Math.signum(mFinalY - mStartY); + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SessionAdapter.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SessionAdapter.java new file mode 100644 index 0000000..a9265a0 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SessionAdapter.java @@ -0,0 +1,84 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +public class SessionAdapter extends ArrayAdapter { + public Map sessions_map = new HashMap(); + // private final ArrayList sessions; + private Context context = null; + private ArrayList sessions = null; + + public SessionAdapter(Context context, ArrayList sess) { + super(context, R.layout.activity_sessions_item, sess); + this.context = context; + this.sessions = sess; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + View rowView = inflater.inflate(R.layout.activity_sessions_item, + parent, false); + TextView txtSessionLength = (TextView) rowView + .findViewById(R.id.session_length); + TextView txtSessionStarted = (TextView) rowView + .findViewById(R.id.session_started); + TextView txtSessionStartedTime = (TextView) rowView + .findViewById(R.id.session_started_time); + + txtSessionLength + .setText(String.valueOf(sessions.get(position)._length / 3600) + + ":" + + String.format("%02d", + (sessions.get(position)._length % 3600) / 60)); + // txtSessionLength.setText(String.format("%d:%02d", + // sessions.get(position).length/3600, + // (sessions.get(position).length%3600)/60)); + + final Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis((sessions.get(position)._started + sessions + .get(position)._length) * 1000); + Date date = cal.getTime(); + + SimpleDateFormat sdf = new SimpleDateFormat("h:mm a", Locale.getDefault()); + SimpleDateFormat sdf2 = new SimpleDateFormat("d MMM yyyy", Locale.getDefault()); + SimpleDateFormat sdf3 = new SimpleDateFormat("d-M-yyyy", Locale.getDefault()); + sdf.setTimeZone(TimeZone.getDefault()); + sdf2.setTimeZone(TimeZone.getDefault()); + sdf3.setTimeZone(TimeZone.getDefault()); + + // sessions.get(position).date = sdf.format(date); + // sessions.get(position).time = sdf2.format(date); + + txtSessionStartedTime.setText(sdf.format(date)); + txtSessionStarted.setText(sdf2.format(date)); + + // Change icon based on name + // String s = values[position]; + + // Log.d("MeditationAssistant", "LV: " + s); + + /*if (!sessions_map.containsKey(sdf3.format(date))) { + Log.d("MeditationAssistant", "Session position: " + sdf3.format(date) + " - " + String.valueOf(position)); + sessions_map.put(sdf3.format(date), position); + }*/ + + return rowView; + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SessionSQL.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SessionSQL.java new file mode 100644 index 0000000..9760863 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SessionSQL.java @@ -0,0 +1,42 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +public class SessionSQL { + public Long _id; + public Long _started; + public Long _completed; + public Long _length; + public String _message; + public Long _isposted; + public Long _streakday; + + public SessionSQL() { + } + + public SessionSQL(Long id, Long started, Long completed, Long length, String message, + Long isposted, Long streakday) { + this._id = id; + this._started = started; + this._completed = completed; + this._length = length; + this._message = message; + this._isposted = isposted; + this._streakday = streakday; + } + + public SessionSQL(Long started, Long completed, Long length, String message, Long isposted, Long streakday) { + this._started = started; + this._completed = completed; + this._length = length; + this._message = message; + this._isposted = isposted; + this._streakday = streakday; + } + + public Long getID() { + return this._id; + } + + public void setID(Long id) { + this._id = id; + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SessionsFragment.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SessionsFragment.java new file mode 100644 index 0000000..6bdbaef --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SessionsFragment.java @@ -0,0 +1,273 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.v4.app.ListFragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.ListView; +import android.widget.TextView; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class SessionsFragment extends ListFragment { + public MeditationAssistant ma = null; + AlertDialog sessionDialog = null; + AlertDialog sessionDetailsDialog = null; + SessionSQL selected_session = null; + String session_title = null; + String session_started = null; + + SharedPreferences.OnSharedPreferenceChangeListener sharedPrefslistener = new SharedPreferences.OnSharedPreferenceChangeListener() { + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + if (key.equals("sessionsupdate")) { + Log.d("MeditationAssistant", "Got sessions update, refreshing SessionsFragment"); + refreshSessionList(); + } + } + }; + + public MeditationAssistant getMeditationAssistant() { + if (ma == null) { + ma = (MeditationAssistant) getActivity().getApplication(); + } + return ma; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getMeditationAssistant().getPrefs().registerOnSharedPreferenceChangeListener(sharedPrefslistener); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + getListView().setOnItemLongClickListener(new android.widget.AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(android.widget.AdapterView adapterView, View view, int position, long id) { + if (sessionDetailsDialog != null) { + try { + if (sessionDetailsDialog.isShowing()) { + sessionDetailsDialog.dismiss(); + } + } catch (WindowManager.BadTokenException e) { + // Activity is not in the foreground + } + } + + if (sessionDialog != null) { + try { + if (sessionDialog.isShowing()) { + sessionDialog.dismiss(); + } + } catch (WindowManager.BadTokenException e) { + // Activity is not in the foreground + } + } + + selected_session = (SessionSQL) getListView().getItemAtPosition(position); + setSessionDialogDetails(); + + sessionDialog = new AlertDialog.Builder(getActivity()) + .setIcon( + getActivity().getResources().getDrawable( + getMeditationAssistant().getTheme().obtainStyledAttributes(getMeditationAssistant().getMATheme(true), + new int[]{R.attr.actionIconGoToToday}) + .getResourceId(0, 0) + ) + ) + .setTitle(session_title) + .setItems(R.array.session_actions, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int which) { + if (which == 0) { + if (getMeditationAssistant() + .getTimeStartMeditate() > 0) { + getActivity().runOnUiThread( + new Runnable() { + @Override + public void run() { + getMeditationAssistant() + .shortToast( + getString(R.string.sessionNotPostedMeditating)); + } + } + ); + } else { + getMeditationAssistant().getMediNET().session.started = selected_session._started; + getMeditationAssistant().getMediNET().session.length = selected_session._length; + getMeditationAssistant().getMediNET().session.message = selected_session._message; + getMeditationAssistant().getMediNET().session.streakday = selected_session._streakday; + getMeditationAssistant().getMediNET() + .postSession(true, + getActivity()); + } + } else { + AlertDialog deleteDialog = new AlertDialog.Builder( + getActivity()) + .setIcon( + getActivity().getResources().getDrawable( + getMeditationAssistant().getTheme().obtainStyledAttributes(getMeditationAssistant().getMATheme(true), + new int[]{R.attr.actionIconGoToToday}) + .getResourceId(0, 0) + ) + ) + .setTitle(session_title) + .setItems( + R.array.session_delete_actions, + new DialogInterface.OnClickListener() { + @Override + public void onClick( + DialogInterface dialog, + int which) { + if (which == 0 + || which == 1) { + // Delete + // locally + getMeditationAssistant().db + .deleteSession(selected_session); + getMeditationAssistant() + .shortToast( + getString(R.string.sessionDeletedLocally)); + } + if (which == 0 + || which == 2) { + // Delete on + // Medinet + getMeditationAssistant() + .getMediNET() + .deleteSessionByStarted( + selected_session._started); + } + + if (which == 0 + || which == 1) { + refreshSessionList(); + } + } + } + ).create(); + deleteDialog.show(); + } + } + } + ).create(); + + sessionDialog.show(); + + return true; + } + }); + + refreshSessionList(); + } + + @Override + public void onListItemClick(ListView l, View v, int position, long id) { + if (sessionDetailsDialog != null) { + try { + if (sessionDetailsDialog.isShowing()) { + sessionDetailsDialog.dismiss(); + } + } catch (WindowManager.BadTokenException e) { + // Activity is not in the foreground + } + } + + if (sessionDialog != null) { + try { + if (sessionDialog.isShowing()) { + sessionDialog.dismiss(); + } + } catch (WindowManager.BadTokenException e) { + // Activity is not in the foreground + } + } + + selected_session = (SessionSQL) l.getItemAtPosition(position); + setSessionDialogDetails(); + + View detailsView = LayoutInflater.from(getActivity()).inflate( + R.layout.session_details, + (ViewGroup) getActivity().findViewById(R.id.sessionDetails_root)); + + TextView txtSessionDetailsStarted = (TextView) detailsView.findViewById(R.id.txtSessionDetailsStarted); + TextView txtSessionDetailsMessage = (TextView) detailsView.findViewById(R.id.txtSessionDetailsMessage); + + txtSessionDetailsStarted.setText(String.format(getString(R.string.sessionStartedAt), session_started)); + + if (!selected_session._message.trim().equals("")) { + txtSessionDetailsMessage.setText(selected_session._message.trim()); + } else { + View divSessionDetailsMessage = detailsView.findViewById(R.id.divSessionDetailsMessage); + + divSessionDetailsMessage.setVisibility(View.GONE); + txtSessionDetailsMessage.setVisibility(View.GONE); + } + + sessionDetailsDialog = new AlertDialog.Builder(getActivity()) + .setIcon( + getActivity().getResources().getDrawable( + getMeditationAssistant().getTheme().obtainStyledAttributes(getMeditationAssistant().getMATheme(true), + new int[]{R.attr.actionIconGoToToday}) + .getResourceId(0, 0) + ) + ) + .setTitle(session_title) + .setView(detailsView) + .create(); + + sessionDetailsDialog.show(); + } + + private void setSessionDialogDetails() { + SimpleDateFormat sdf = new SimpleDateFormat("d MMM yyyy h:mm a", + Locale.getDefault()); + sdf.setTimeZone(TimeZone.getDefault()); + + SimpleDateFormat sdf2 = new SimpleDateFormat("h:mm a", + Locale.getDefault()); + sdf2.setTimeZone(TimeZone.getDefault()); + + final Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(selected_session._completed * 1000); + Date date = cal.getTime(); + + session_title = String.valueOf(selected_session._length / 3600) + ":" + + String.format("%02d", (selected_session._length % 3600) / 60) + + " - " + sdf.format(date); + + cal.setTimeInMillis(selected_session._started * 1000); + session_started = sdf2.format(cal.getTime()); + } + + public void refreshSessionList() { + setListAdapter(new SessionAdapter(getActivity(), + getMeditationAssistant().db.getAllSessions())); + } + + @Override + public void onPause() { + getMeditationAssistant().getPrefs().unregisterOnSharedPreferenceChangeListener(sharedPrefslistener); + super.onPause(); + } + + @Override + public void onResume() { + getMeditationAssistant().getPrefs().registerOnSharedPreferenceChangeListener(sharedPrefslistener); + super.onResume(); + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SettingsActivity.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SettingsActivity.java new file mode 100644 index 0000000..179a287 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/SettingsActivity.java @@ -0,0 +1,745 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.Intent; +import android.content.res.Configuration; +import android.media.Ringtone; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.PreferenceActivity; +import android.preference.PreferenceCategory; +import android.preference.PreferenceFragment; +import android.preference.RingtonePreference; +import android.text.TextUtils; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Toast; + +import com.google.android.gms.analytics.GoogleAnalytics; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; + +/** + * A {@link PreferenceActivity} that presents a set of application settings. On + * handset devices, settings are presented as a single list. On tablets, + * settings are split by category, with category headers shown to the left of + * the list of settings. + *

+ * See + * Android Design: Settings for design guidelines and the Settings + * API Guide for more information on developing a Settings UI. + */ +@SuppressWarnings("deprecation") +public class SettingsActivity extends PreferenceActivity { + /** + * Determines whether to always show the simplified settings UI, where + * settings are presented in a single list. When false, settings are shown + * as a master/detail two-pane view on tablets. When true, a single pane is + * shown on tablets. + */ + private static final boolean ALWAYS_SIMPLE_PREFS = false; + + public Boolean initialThemeChange = true; + public Boolean initialTimePickerChange = true; + public Boolean initialSoundChangeStart = true; + public Boolean initialSoundChangeInterval = true; + public Boolean initialSoundChangeFinish = true; + public SessionPreferenceFragment sessionPreferenceFragment = null; + public ReminderPreferenceFragment reminderPreferenceFragment = null; + public MeditationPreferenceFragment meditationPreferenceFragment = null; + public MediNETPreferenceFragment medinetPreferenceFragment = null; + public MiscellaneousPreferenceFragment miscellaneousPreferenceFragment = null; + int PREF_SOUND_START = 1; + int PREF_SOUND_INTERVAL = 3; + int PREF_SOUND_FINISH = 2; + private MeditationAssistant ma = null; + + /** + * A preference value change listener that updates the preference's summary + * to reflect its new value. + */ + private Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object value) { + if (preference instanceof CheckBoxPreference) { + if (preference.getKey().equals("pref_daily_reminder")) { + Intent intent = new Intent(); + intent.setAction(MeditationAssistant.ACTION_UPDATED); + sendBroadcast(intent); + } else if (preference.getKey().equals("pref_usetimepicker")) { + if (!initialTimePickerChange) { + Toast.makeText(SettingsActivity.this, getString(R.string.restartAppApplyTimePicker), Toast.LENGTH_SHORT).show(); + } + initialTimePickerChange = false; + } + + return true; + } + + String stringValue = ""; + if (!preference.getKey().equals("pref_presetsettings")) { + stringValue = value.toString(); + } + + if (preference.getKey().equals("pref_presetsettings")) { + HashSet presetSettings = (HashSet) value; + if (presetSettings.size() == 0) { + preference.setSummary(getString(R.string.disabled)); + } else { + List presetsettings = Arrays.asList(getResources().getStringArray(R.array.presetsettings)); + List presetsettings_values = Arrays.asList(getResources().getStringArray(R.array.presetsettings_values)); + + String presetsummary = ""; + + for (Iterator preseti = presetsettings_values.iterator(); preseti.hasNext(); ) { + String preset = preseti.next(); + if (presetSettings.contains(preset)) { + if (presetsummary != "") { + presetsummary += ", "; + } + presetsummary += presetsettings.get(presetsettings_values.indexOf(preset)); + } + } + + preference.setSummary(presetsummary); + } + } else if (preference instanceof ListPreference || preference instanceof ListPreferenceSound) { + // For list preferences, look up the correct display value in + // the preference's 'entries' list. + ListPreference listPreference = (ListPreference) preference; + int index = listPreference.findIndexOfValue(stringValue); + + // Set the summary to reflect the new value. + preference.setSummary( + index >= 0 + ? listPreference.getEntries()[index] + : "Gong" + ); // TODO: Don't hardcode sound names + + if (listPreference.getKey().equals("pref_theme")) { + if (!initialThemeChange) { + Toast.makeText(SettingsActivity.this, getString(R.string.restartAppApplyTheme), Toast.LENGTH_SHORT).show(); + } + initialThemeChange = false; + } else if (listPreference.getKey().equals("pref_meditation_sound_start")) { + if (stringValue.equals("custom")) { + if (!initialSoundChangeStart) { + Intent intent = new Intent( + Intent.ACTION_GET_CONTENT); + intent.setType("file/*"); + intent.addCategory(Intent.CATEGORY_OPENABLE); + Intent finalIntent = Intent.createChooser( + intent, getString(R.string.selectSound)); + startActivityForResult(finalIntent, PREF_SOUND_START); + } + + preference.setSummary(customSoundSummary(getMeditationAssistant().getPrefs().getString("pref_meditation_sound_start_custom", ""))); + } + initialSoundChangeStart = false; + } else if (listPreference.getKey().equals("pref_meditation_sound_interval")) { + if (stringValue.equals("custom")) { + if (!initialSoundChangeInterval) { + Intent intent = new Intent( + Intent.ACTION_GET_CONTENT); + intent.setType("file/*"); + intent.addCategory(Intent.CATEGORY_OPENABLE); + Intent finalIntent = Intent.createChooser( + intent, getString(R.string.selectSound)); + startActivityForResult(finalIntent, PREF_SOUND_INTERVAL); + } + + preference.setSummary(customSoundSummary(getMeditationAssistant().getPrefs().getString("pref_meditation_sound_interval_custom", ""))); + } + initialSoundChangeInterval = false; + } else if (listPreference.getKey().equals("pref_meditation_sound_finish")) { + if (stringValue.equals("custom")) { + if (!initialSoundChangeFinish) { + Intent intent = new Intent( + Intent.ACTION_GET_CONTENT); + intent.setType("file/*"); + intent.addCategory(Intent.CATEGORY_OPENABLE); + Intent finalIntent = Intent.createChooser( + intent, getString(R.string.selectSound)); + startActivityForResult(finalIntent, PREF_SOUND_FINISH); + } + + preference.setSummary(customSoundSummary(getMeditationAssistant().getPrefs().getString("pref_meditation_sound_finish_custom", ""))); + } + initialSoundChangeFinish = false; + } + } else if (preference instanceof RingtonePreference) { + // For ringtone preferences, look up the correct display value + // using RingtoneManager. + if (TextUtils.isEmpty(stringValue)) { + // Empty values correspond to 'silent' (no ringtone). + //preference.setSummary(R.string.pref_ringtone_silent); + + } else { + Ringtone ringtone = RingtoneManager.getRingtone( + preference.getContext(), Uri.parse(stringValue)); + + if (ringtone == null) { + // Clear the summary if there was a lookup error. + preference.setSummary(null); + } else { + // Set the summary to reflect the new ringtone display + // name. + String name = ringtone.getTitle(preference.getContext()); + preference.setSummary(name); + } + } + } else if (preference instanceof TimePreference) { + if (preference.getKey().equals("pref_daily_reminder_time")) { + String timeValue = ""; + try { + String[] timeValueSplit = ((stringValue != null && stringValue != "") ? stringValue : "19:00").split(":"); + + String ampm = "AM"; + if (Integer.valueOf(timeValueSplit[0]) >= 12) { + timeValueSplit[0] = String.valueOf(Integer.valueOf(timeValueSplit[0]) - 12); + ampm = "PM"; + } + if (Integer.valueOf(timeValueSplit[0]) == 0) { + timeValueSplit[0] = "12"; + } + + timeValue = String.valueOf(Integer.valueOf(timeValueSplit[0])) + ":" + + String.format("%02d", Integer.valueOf(timeValueSplit[1])) + " " + ampm; + } catch (Exception e) { + e.printStackTrace(); + } + preference.setSummary(timeValue); + + Intent intent = new Intent(); + intent.setAction(MeditationAssistant.ACTION_UPDATED); + sendBroadcast(intent); + } else { // pref_session_delay and pref_session_interval + Log.d("MeditationAssistant", preference.getKey() + " value: " + String.valueOf(stringValue)); + + String timeValue = ""; + Boolean isDisabled = false; + try { + String[] timeValueSplit = ((stringValue != null && stringValue != "") ? stringValue : (preference.getKey().equals("pref_session_delay") ? "00:15" : "00:00")).split(":"); + timeValue = String.valueOf((int) Math.floor(Integer.valueOf(timeValueSplit[0]) / 60)) + ":" + + String.format("%02d", Integer.valueOf(timeValueSplit[0]) % 60) + ":" + + String.format("%02d", Integer.valueOf(timeValueSplit[1])); + isDisabled = (Integer.valueOf(timeValueSplit[0]) == 0 && Integer.valueOf(timeValueSplit[1]) == 0); + } catch (Exception e) { + e.printStackTrace(); + } + + preference.setSummary(isDisabled ? getString(R.string.disabled) : timeValue); + + if (preference.getKey().equals("pref_session_interval")) { + ListPreferenceSound prefIntervalSound = (ListPreferenceSound) (sessionPreferenceFragment == null ? findPreference("pref_meditation_sound_interval") : sessionPreferenceFragment.findPreference("pref_meditation_sound_interval")); + prefIntervalSound.setEnabled(!isDisabled); + + EditTextPreference prefIntervalCount = (EditTextPreference) (sessionPreferenceFragment == null ? findPreference("pref_interval_count") : sessionPreferenceFragment.findPreference("pref_interval_count")); + prefIntervalCount.setEnabled(!isDisabled); + } + } + } else if (preference.getKey().equals("pref_interval_count")) { + if (stringValue == null || String.valueOf(stringValue).trim().equals("")) { + stringValue = "0"; + } + if (Integer.valueOf(stringValue) <= 0) { + preference.setSummary(getString(R.string.unlimited)); + } else { + preference.setSummary(getResources().getQuantityString( + R.plurals.numtimes, Integer.valueOf(stringValue), + String.valueOf(Integer.valueOf(stringValue)) + )); + } + } else if (preference.getKey().equals("pref_daily_reminder_text")) { + String reminderText = getString(R.string.reminderText); + if (stringValue != null && !String.valueOf(stringValue).trim().equals("")) { + reminderText = String.valueOf(stringValue).trim(); + } + preference.setSummary(reminderText); + } else { + // For all other preferences, set the summary to the value's + // simple string representation. + preference.setSummary(stringValue); + } + + return true; + } + }; + private Long uploadsessions_lastlick = (long) 0; + private Long importsessions_lastlick = (long) 0; + + /** + * Helper method to determine if the device has an extra-large screen. For + * example, 10" tablets are extra-large. + */ + private static boolean isXLargeTablet(Context context) { + return (context.getResources().getConfiguration().screenLayout + & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE; + } + + /** + * Determines whether the simplified settings UI should be shown. This is + * true if this is forced via {@link #ALWAYS_SIMPLE_PREFS}, or the device + * doesn't have newer APIs like {@link PreferenceFragment}, or the device + * doesn't have an extra-large screen. In these cases, a single-pane + * "simplified" settings UI should be shown. + */ + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + private static boolean isSimplePreferences(Context context) { + return Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB + || !isXLargeTablet(context); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + setTheme(getMeditationAssistant().getMATheme()); + + if (getMeditationAssistant().sendUsageReports()) { + getMeditationAssistant().getTracker(MeditationAssistant.TrackerName.APP_TRACKER); + } + + super.onCreate(savedInstanceState); + } + + @Override + public void onStart() { + super.onStart(); + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStart(this); + } + } + + @Override + protected void onStop() { + super.onStop(); + if (getMeditationAssistant().sendUsageReports()) { + GoogleAnalytics.getInstance(this).reportActivityStop(this); + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + Uri d = null; + String pref = ""; + String pref_key = ""; + if (requestCode == PREF_SOUND_START) { + pref_key = "pref_meditation_sound_start"; + pref = "pref_meditation_sound_start_custom"; + } else if (requestCode == PREF_SOUND_INTERVAL) { + pref_key = "pref_meditation_sound_interval"; + pref = "pref_meditation_sound_interval_custom"; + } else if (requestCode == PREF_SOUND_FINISH) { + pref_key = "pref_meditation_sound_finish"; + pref = "pref_meditation_sound_finish_custom"; + } else { + return; + } + + if (data != null) { + d = data.getData(); + if (d != null) { + if (!d.toString().equals("")) { + getMeditationAssistant().getPrefs().edit().putString(pref, FileUtils.getPath(this, d)).apply(); + } + } + } + + if (requestCode == PREF_SOUND_START) { + initialSoundChangeStart = true; + } else if (requestCode == PREF_SOUND_INTERVAL) { + initialSoundChangeInterval = true; + } else if (requestCode == PREF_SOUND_FINISH) { + initialSoundChangeFinish = true; + } + + ListPreferenceSound prefMeditationSound = (ListPreferenceSound) (sessionPreferenceFragment == null ? findPreference(pref_key) : sessionPreferenceFragment.findPreference(pref_key)); + prefMeditationSound.getOnPreferenceChangeListener().onPreferenceChange(prefMeditationSound, getMeditationAssistant().getPrefs().getString(pref_key, "gong")); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.settings, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + Intent intent = null; + int i = item.getItemId(); + if (i == R.id.action_about) { + intent = new Intent(this, AboutActivity.class); + startActivity(intent); + return true; + } else if (i == R.id.action_accountsettings) { + Intent openActivity = new Intent(this, + MediNETActivity.class); + openActivity.putExtra("page", "account"); + startActivity(openActivity); + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + + setupSimplePreferencesScreen(); + } + + void setupSoundPreferences(PreferenceFragment preferenceFragment) { + String[] meditation_sounds = getResources().getStringArray(R.array.meditation_sounds); + String[] meditation_sounds_values = getResources().getStringArray(R.array.meditation_sounds_values); + + ListPreferenceSound prefMeditationSoundStart = (ListPreferenceSound) (preferenceFragment == null ? findPreference("pref_meditation_sound_start") : preferenceFragment.findPreference("pref_meditation_sound_start")); + prefMeditationSoundStart.setEntries(meditation_sounds); + prefMeditationSoundStart.setEntryValues(meditation_sounds_values); + + ListPreferenceSound prefMeditationSoundInterval = (ListPreferenceSound) (preferenceFragment == null ? findPreference("pref_meditation_sound_interval") : preferenceFragment.findPreference("pref_meditation_sound_interval")); + prefMeditationSoundInterval.setEntries(meditation_sounds); + prefMeditationSoundInterval.setEntryValues(meditation_sounds_values); + + ListPreferenceSound prefMeditationSoundFinish = (ListPreferenceSound) (preferenceFragment == null ? findPreference("pref_meditation_sound_finish") : preferenceFragment.findPreference("pref_meditation_sound_finish")); + prefMeditationSoundFinish.setEntries(meditation_sounds); + prefMeditationSoundFinish.setEntryValues(meditation_sounds_values); + } + + void setupPreferences(String pref_type, PreferenceFragment preferenceFragment) { + if (pref_type.equals("all") || pref_type.equals("session")) { + if (preferenceFragment != null) { + sessionPreferenceFragment = (SessionPreferenceFragment) preferenceFragment; + } + + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_session_delay") : preferenceFragment.findPreference("pref_session_delay")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_meditation_sound_start") : preferenceFragment.findPreference("pref_meditation_sound_start")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_meditation_sound_interval") : preferenceFragment.findPreference("pref_meditation_sound_interval")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_session_interval") : preferenceFragment.findPreference("pref_session_interval")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_interval_count") : preferenceFragment.findPreference("pref_interval_count")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_meditation_sound_finish") : preferenceFragment.findPreference("pref_meditation_sound_finish")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_notificationcontrol") : preferenceFragment.findPreference("pref_notificationcontrol")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_presetsettings") : preferenceFragment.findPreference("pref_presetsettings")); + } + if (pref_type.equals("all") || pref_type.equals("reminder")) { + if (preferenceFragment != null) { + reminderPreferenceFragment = (ReminderPreferenceFragment) preferenceFragment; + } + + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_daily_reminder_text") : preferenceFragment.findPreference("pref_daily_reminder_text")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_daily_reminder_time") : preferenceFragment.findPreference("pref_daily_reminder_time")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_daily_reminder") : preferenceFragment.findPreference("pref_daily_reminder")); + } + if (pref_type.equals("all") || pref_type.equals("meditation")) { + if (preferenceFragment != null) { + meditationPreferenceFragment = (MeditationPreferenceFragment) preferenceFragment; + } + + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_usetimepicker") : preferenceFragment.findPreference("pref_usetimepicker")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_text_size") : preferenceFragment.findPreference("pref_text_size")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_progresstab") : preferenceFragment.findPreference("pref_progresstab")); + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_screencontrol") : preferenceFragment.findPreference("pref_screencontrol")); + } + if (pref_type.equals("all") || pref_type.equals("medinet")) { + if (preferenceFragment != null) { + medinetPreferenceFragment = (MediNETPreferenceFragment) preferenceFragment; + } + + Preference uploadSessions = (preferenceFragment == null ? findPreference("uploadsessions") : preferenceFragment.findPreference("uploadsessions")); + uploadSessions + .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference arg0) { + + if (getMeditationAssistant().getMediNETKey().equals("")) { + getMeditationAssistant().getMediNET().askToSignIn(); + getMeditationAssistant().shortToast( + getString(R.string.signInToMediNET)); + } else { + ArrayList sessionssql = getMeditationAssistant().db.getAllLocalSessions(); + + if (sessionssql.size() == 0) { + getMeditationAssistant().longToast( + getMeditationAssistant().getString(R.string.sessionsNotImported)); + + return false; + } + + if (getMeditationAssistant().getTimestamp() + - uploadsessions_lastlick > 5) { + uploadsessions_lastlick = getMeditationAssistant() + .getTimestamp(); + getMeditationAssistant().getMediNET() + .uploadSessions(); + } + } + + return false; + } + }); + + Preference importSessions = (preferenceFragment == null ? findPreference("importsessions") : preferenceFragment.findPreference("importsessions")); + importSessions + .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference arg0) { + if (getMeditationAssistant().getMediNETKey().equals("")) { + getMeditationAssistant().getMediNET().askToSignIn(); + getMeditationAssistant().shortToast( + getString(R.string.signInToImport)); + } else { + if (getMeditationAssistant().getTimestamp() + - importsessions_lastlick > 5) { + importsessions_lastlick = getMeditationAssistant() + .getTimestamp(); + getMeditationAssistant().getMediNET() + .syncSessions(); + } + } + + return false; + } + }); + } + if (pref_type.equals("all") || pref_type.equals("miscellaneous")) { + if (preferenceFragment != null) { + miscellaneousPreferenceFragment = (MiscellaneousPreferenceFragment) preferenceFragment; + } + + bindPreferenceSummaryToValue(preferenceFragment == null ? findPreference("pref_theme") : preferenceFragment.findPreference("pref_theme")); + } + } + + /** + * Shows the simplified settings UI if the device configuration if the + * device configuration dictates that a simplified, single-pane UI should be + * shown. + */ + private void setupSimplePreferencesScreen() { + if (!isSimplePreferences(this)) { + return; + } + + // In the simplified UI, fragments are not used at all and we instead + // use the older PreferenceActivity APIs. + + // Add 'Session' preferences. + PreferenceCategory fakeHeader = new PreferenceCategory(this); + addPreferencesFromResource(R.xml.pref_session); + + // Add 'Daily Reminder' preferences + fakeHeader = new PreferenceCategory(this); + fakeHeader.setTitle(R.string.pref_daily_reminder); + getPreferenceScreen().addPreference(fakeHeader); + addPreferencesFromResource(R.xml.pref_reminder); + + // Add 'Meditation' preferences + fakeHeader = new PreferenceCategory(this); + fakeHeader.setTitle(R.string.meditation); + getPreferenceScreen().addPreference(fakeHeader); + addPreferencesFromResource(R.xml.pref_meditation); + + // Add 'MediNET' preferences + fakeHeader = new PreferenceCategory(this); + fakeHeader.setTitle(R.string.mediNET); + getPreferenceScreen().addPreference(fakeHeader); + addPreferencesFromResource(R.xml.pref_medinet); + + // Add 'Miscellaneous' preferences + fakeHeader = new PreferenceCategory(this); + fakeHeader.setTitle(R.string.miscellaneous); + getPreferenceScreen().addPreference(fakeHeader); + addPreferencesFromResource(R.xml.pref_miscellaneous); + + setupSoundPreferences(null); + setupPreferences("all", null); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean onIsMultiPane() { + return isXLargeTablet(this) && !isSimplePreferences(this); + } + + /** + * {@inheritDoc} + */ + @Override + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public void onBuildHeaders(List

target) { + if (!isSimplePreferences(this)) { + loadHeadersFromResource(R.xml.pref_headers, target); + } + } + + private String customSoundSummary(String meditation_sound) { + if (meditation_sound == null || meditation_sound.equals("")) { + return getString(R.string.noSound); + } + + try { + return meditation_sound.substring(meditation_sound.lastIndexOf("/") + 1); + } catch (Exception e) { + return meditation_sound; + } + } + + /** + * Binds a preference's summary to its value. More specifically, when the + * preference's value is changed, its summary (line of text below the + * preference title) is updated to reflect the value. The summary is also + * immediately updated upon calling this method. The exact display format is + * dependent on the type of preference. + * + * @see #sBindPreferenceSummaryToValueListener + */ + private void bindPreferenceSummaryToValue(Preference preference) { + // Set the listener to watch for value changes. + preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener); + + // Trigger the listener immediately with the preference's + // current value. + if (preference.getKey().equals("pref_daily_reminder") || preference.getKey().equals("pref_usetimepicker")) { + sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, + getMeditationAssistant().getPrefs() + .getBoolean(preference.getKey(), false) + ); + } else if (preference.getKey().equals("pref_presetsettings")) { + sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, getMeditationAssistant().getPrefs().getStringSet("pref_presetsettings", new HashSet(Arrays.asList(getResources().getStringArray(R.array.presetsettings_default)))) + ); + } else { + sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, + getMeditationAssistant().getPrefs() + .getString(preference.getKey(), "") + ); + } + } + + public MeditationAssistant getMeditationAssistant() { + if (ma == null) { + ma = (MeditationAssistant) this.getApplication(); + } + return ma; + } + + @Override + protected boolean isValidFragment(String fragmentName) { + return SessionPreferenceFragment.class.getName().equals(fragmentName) || + ReminderPreferenceFragment.class.getName().equals(fragmentName) || + MeditationPreferenceFragment.class.getName().equals(fragmentName) || + MediNETPreferenceFragment.class.getName().equals(fragmentName) || + MiscellaneousPreferenceFragment.class.getName().equals(fragmentName); + } + + /** + * This fragment shows general preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public static class SessionPreferenceFragment extends PreferenceFragment { + public SessionPreferenceFragment() { + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.pref_session); + PreferenceCategory prefCatSession = (PreferenceCategory) findPreference("pref_cat_session"); + getPreferenceScreen().removePreference(prefCatSession); + + SettingsActivity settingsactivity = (SettingsActivity) getActivity(); + settingsactivity.setupSoundPreferences(this); + settingsactivity.setupPreferences("session", this); + } + } + + /** + * This fragment shows notification preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public static class ReminderPreferenceFragment extends PreferenceFragment { + public ReminderPreferenceFragment() { + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.pref_reminder); + + SettingsActivity settingsactivity = (SettingsActivity) getActivity(); + settingsactivity.setupPreferences("reminder", this); + } + } + + /** + * This fragment shows notification preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public static class MeditationPreferenceFragment extends PreferenceFragment { + public MeditationPreferenceFragment() { + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.pref_meditation); + + SettingsActivity settingsactivity = (SettingsActivity) getActivity(); + settingsactivity.setupPreferences("meditation", this); + } + } + + /** + * This fragment shows notification preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public static class MediNETPreferenceFragment extends PreferenceFragment { + public MediNETPreferenceFragment() { + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.pref_medinet); + + SettingsActivity settingsactivity = (SettingsActivity) getActivity(); + settingsactivity.setupPreferences("medinet", this); + } + } + + /** + * This fragment shows data and sync preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public static class MiscellaneousPreferenceFragment extends PreferenceFragment { + public MiscellaneousPreferenceFragment() { + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.pref_miscellaneous); + + SettingsActivity settingsactivity = (SettingsActivity) getActivity(); + settingsactivity.setupPreferences("miscellaneous", this); + } + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/StatsFragment.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/StatsFragment.java new file mode 100644 index 0000000..dc65aad --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/StatsFragment.java @@ -0,0 +1,149 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import java.text.NumberFormat; +import java.util.Locale; + +public class StatsFragment extends Fragment { + private MeditationAssistant ma = null; + private View fragment_progress_stats = null; + SharedPreferences.OnSharedPreferenceChangeListener sharedPrefslistener = new SharedPreferences.OnSharedPreferenceChangeListener() { + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + if (key.equals("sessionsupdate")) { + Log.d("MeditationAssistant", "Got sessions update, refreshing StatsFragment"); + refreshStatsDisplay(); + } + } + }; + + public MeditationAssistant getMeditationAssistant() { + if (ma == null) { + ma = (MeditationAssistant) getActivity().getApplication(); + } + return ma; + } + + public void refreshStatsDisplay() { + if (fragment_progress_stats == null) { + return; + } + + Locale currentLocale = getResources().getConfiguration().locale; + + int time_spent_meditating = getMeditationAssistant().db.getTotalTimeSpentMeditating(); + int time_spent_meditating_days = time_spent_meditating / 86400; + int abovedays = time_spent_meditating % 86400; + int time_spent_meditating_hours = abovedays / 3600; + int abovehours = abovedays % 3600; + int time_spent_meditating_minutes = abovehours / 60; + + TextView txtTimespentMeditatingDays = (TextView) fragment_progress_stats.findViewById(R.id.txtTimeSpentMeditatingDays); + TextView txtTimespentMeditatingHours = (TextView) fragment_progress_stats.findViewById(R.id.txtTimeSpentMeditatingHours); + TextView txtTimespentMeditatingMinutes = (TextView) fragment_progress_stats.findViewById(R.id.txtTimeSpentMeditatingMinutes); + + txtTimespentMeditatingDays.setText(String.valueOf(time_spent_meditating_days)); + txtTimespentMeditatingHours.setText(String.valueOf(time_spent_meditating_hours)); + txtTimespentMeditatingMinutes.setText(String.valueOf(time_spent_meditating_minutes)); + + TextView txtOtherStatisticsSessions = (TextView) fragment_progress_stats.findViewById(R.id.txtOtherStatisticsSessions); + TextView txtOtherStatisticsLongestDuration = (TextView) fragment_progress_stats.findViewById(R.id.txtOtherStatisticsLongestDuration); + TextView txtOtherStatisticsAverageDuration = (TextView) fragment_progress_stats.findViewById(R.id.txtOtherStatisticsAverageDuration); + TextView txtOtherStatisticsLongestStreak = (TextView) fragment_progress_stats.findViewById(R.id.txtOtherStatisticsLongestStreak); + + int numSessions = getMeditationAssistant().db.getNumSessions(); + txtOtherStatisticsSessions.setText(NumberFormat.getNumberInstance(currentLocale).format(numSessions)); + + double secondsPerSession = 0; + if (numSessions > 0) { + secondsPerSession = time_spent_meditating / numSessions; + secondsPerSession = Math.floor(secondsPerSession); + } + int secondsPerSessionHours = (int) secondsPerSession / 3600; + int secondsPerSessionRemainder = (int) secondsPerSession % 3600; + int secondsPerSessionMinutes = secondsPerSessionRemainder / 60; + int secondsPerSessionSeconds = secondsPerSessionRemainder % 60; + + txtOtherStatisticsAverageDuration.setText(String.valueOf(secondsPerSessionHours) + ":" + String.format("%02d", secondsPerSessionMinutes) + ":" + String.format("%02d", secondsPerSessionSeconds)); + + // Re-use variables + secondsPerSession = getMeditationAssistant().db.getLongestSessionLength(); + secondsPerSessionHours = (int) secondsPerSession / 3600; + secondsPerSessionRemainder = (int) secondsPerSession % 3600; + secondsPerSessionMinutes = secondsPerSessionRemainder / 60; + secondsPerSessionSeconds = secondsPerSessionRemainder % 60; + + txtOtherStatisticsLongestDuration.setText(String.valueOf(secondsPerSessionHours) + ":" + String.format("%02d", secondsPerSessionMinutes) + ":" + String.format("%02d", secondsPerSessionSeconds)); + + int longestStreak = getMeditationAssistant().getLongestMeditationStreak(); + txtOtherStatisticsLongestStreak.setText(String.format(getResources().getQuantityString(R.plurals.daysOfMeditationMinimal, longestStreak, longestStreak), NumberFormat.getNumberInstance(currentLocale).format(longestStreak))); + } + + @SuppressWarnings("deprecation") + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getMeditationAssistant().getPrefs().registerOnSharedPreferenceChangeListener(sharedPrefslistener); + + int color_primary = getResources().getColor(getMeditationAssistant().getMATextColor(true)); + int color_primary_disabled = getResources().getColor(getMeditationAssistant().getMATextColor(false)); + + /* Getting resource not found errors here */ + try { + color_primary = getResources().getColor( + getMeditationAssistant() + .getTheme() + .obtainStyledAttributes( + getMeditationAssistant().getMATheme(), + new int[]{android.R.attr.textColorPrimary}) + .getResourceId(0, 0) + ); + color_primary_disabled = getResources() + .getColor( + getMeditationAssistant() + .getTheme() + .obtainStyledAttributes( + getMeditationAssistant() + .getMATheme(), + new int[]{android.R.attr.textColorPrimaryDisableOnly} + ) + .getResourceId(0, 0) + ); + } catch (Exception e) { + Log.d("MeditationAssistant", "Unable to get color resources in StatsFragment:"); + e.printStackTrace(); + } + } + + @SuppressWarnings("deprecation") + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + Context ctx = getActivity().getApplicationContext(); + fragment_progress_stats = inflater.inflate(R.layout.fragment_progress_stats, null); + + refreshStatsDisplay(); + + return fragment_progress_stats; + } + + @Override + public void onPause() { + getMeditationAssistant().getPrefs().unregisterOnSharedPreferenceChangeListener(sharedPrefslistener); + super.onPause(); + } + + @Override + public void onResume() { + getMeditationAssistant().getPrefs().registerOnSharedPreferenceChangeListener(sharedPrefslistener); + super.onResume(); + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/TimePicker.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/TimePicker.java new file mode 100644 index 0000000..0227519 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/TimePicker.java @@ -0,0 +1,551 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +/* + * Copyright (C) 2007 The Android Open Source Project + * + * 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. + */ + +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.format.DateUtils; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.TextView; + +import java.text.DateFormatSymbols; +import java.util.Calendar; +import java.util.Locale; + +/** + * A view for selecting the time of day, in either 24 hour or AM/PM mode. The + * hour, each minute digit, and AM/PM (if applicable) can be conrolled by + * vertical spinners. The hour can be entered by keyboard input. Entering in two + * digit hours can be accomplished by hitting two digits within a timeout of + * about a second (e.g. '1' then '2' to select 12). The minutes can be entered + * by entering single digits. Under AM/PM mode, the user can hit 'a', 'A", 'p' + * or 'P' to pick. For a dialog using this view, see + * {@link android.app.TimePickerDialog}. + *

+ * See the Pickers + * guide. + *

+ */ +//@Widget +public class TimePicker extends FrameLayout { + + private static final boolean DEFAULT_ENABLED_STATE = true; + + private static final int HOURS_IN_HALF_DAY = 12; + + /** + * A no-op callback used in the constructor to avoid null checks later in + * the code. + */ + private static final OnTimeChangedListener NO_OP_CHANGE_LISTENER = new OnTimeChangedListener() { + public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { + } + }; + // ui components + public final NumberPicker mHourSpinner; + private final NumberPicker mMinuteSpinner; + private final NumberPicker mAmPmSpinner; + private final EditText mHourSpinnerInput; + private final EditText mMinuteSpinnerInput; + private final EditText mAmPmSpinnerInput; + private final TextView mDivider; + // Note that the legacy implementation of the TimePicker is + // using a button for toggling between AM/PM while the new + // version uses a NumberPicker spinner. Therefore the code + // accommodates these two cases to be backwards compatible. + private final Button mAmPmButton; + private final String[] mAmPmStrings; + // state + private boolean mIs24HourView; + private boolean mIsAm; + private boolean mIsEnabled = DEFAULT_ENABLED_STATE; + + // callbacks + private OnTimeChangedListener mOnTimeChangedListener; + + private Calendar mTempCalendar; + + private Locale mCurrentLocale; + + public TimePicker(Context context) { + this(context, null); + } + + public TimePicker(Context context, AttributeSet attrs) { + this(context, attrs, R.attr.timePickerStyle); + } + + public TimePicker(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + // initialization based on locale + setCurrentLocale(Locale.getDefault()); + + // process style attributes + //TypedArray attributesArray = context.obtainStyledAttributes( + // attrs, R.styleable.TimePicker, defStyle, 0); + //int layoutResourceId = attributesArray.getResourceId( + // R.styleable.TimePicker_internalLayout, R.layout.time_picker); + //attributesArray.recycle(); + int layoutResourceId = R.layout.time_picker_holo; + + LayoutInflater inflater = (LayoutInflater) context.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + inflater.inflate(layoutResourceId, TimePicker.this, true); + + // hour + mHourSpinner = (NumberPicker) findViewById(R.id.hour); + mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { + public void onValueChange(NumberPicker spinner, int oldVal, int newVal) { + updateInputState(); + if (!is24HourView()) { + if ((oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) + || (oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1)) { + mIsAm = !mIsAm; + updateAmPmControl(); + } + } + onTimeChanged(); + } + }); + mHourSpinnerInput = (EditText) mHourSpinner.findViewById(R.id.np__numberpicker_input); + mHourSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT); + + // divider (only for the new widget style) + mDivider = (TextView) findViewById(R.id.divider); + if (mDivider != null) { + mDivider.setText(R.string.time_picker_separator); + } + + // minute + mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); + mMinuteSpinner.setMinValue(0); + mMinuteSpinner.setMaxValue(59); + mMinuteSpinner.setOnLongPressUpdateInterval(100); + mMinuteSpinner.setFormatter(NumberPicker.getTwoDigitFormatter()); + mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { + public void onValueChange(NumberPicker spinner, int oldVal, int newVal) { + updateInputState(); + int minValue = mMinuteSpinner.getMinValue(); + int maxValue = mMinuteSpinner.getMaxValue(); + if (oldVal == maxValue && newVal == minValue) { + int newHour = mHourSpinner.getValue() + 1; + if (!is24HourView() && newHour == HOURS_IN_HALF_DAY) { + mIsAm = !mIsAm; + updateAmPmControl(); + } + mHourSpinner.setValue(newHour); + } else if (oldVal == minValue && newVal == maxValue) { + int newHour = mHourSpinner.getValue() - 1; + if (!is24HourView() && newHour == HOURS_IN_HALF_DAY - 1) { + mIsAm = !mIsAm; + updateAmPmControl(); + } + mHourSpinner.setValue(newHour); + } + onTimeChanged(); + } + }); + mMinuteSpinnerInput = (EditText) mMinuteSpinner.findViewById(R.id.np__numberpicker_input); + mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT); + + /* Get the localized am/pm strings and use them in the spinner */ + mAmPmStrings = new DateFormatSymbols().getAmPmStrings(); + + // am/pm + View amPmView = findViewById(R.id.amPm); + if (amPmView instanceof Button) { + mAmPmSpinner = null; + mAmPmSpinnerInput = null; + mAmPmButton = (Button) amPmView; + mAmPmButton.setOnClickListener(new OnClickListener() { + public void onClick(View button) { + button.requestFocus(); + mIsAm = !mIsAm; + updateAmPmControl(); + onTimeChanged(); + } + }); + } else { + mAmPmButton = null; + mAmPmSpinner = (NumberPicker) amPmView; + mAmPmSpinner.setMinValue(0); + mAmPmSpinner.setMaxValue(1); + mAmPmSpinner.setDisplayedValues(mAmPmStrings); + mAmPmSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + updateInputState(); + picker.requestFocus(); + mIsAm = !mIsAm; + updateAmPmControl(); + onTimeChanged(); + } + }); + mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.np__numberpicker_input); + mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE); + } + + // update controls to initial state + updateHourControl(); + updateAmPmControl(); + + setOnTimeChangedListener(NO_OP_CHANGE_LISTENER); + + // set to current time + setCurrentHour(mTempCalendar.get(Calendar.HOUR_OF_DAY)); + setCurrentMinute(mTempCalendar.get(Calendar.MINUTE)); + + if (!isEnabled()) { + setEnabled(false); + } + + // If not explicitly specified this view is important for accessibility. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) { + setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); + } + } + + @Override + public boolean isEnabled() { + return mIsEnabled; + } + + @Override + public void setEnabled(boolean enabled) { + if (mIsEnabled == enabled) { + return; + } + super.setEnabled(enabled); + mMinuteSpinner.setEnabled(enabled); + if (mDivider != null) { + mDivider.setEnabled(enabled); + } + mHourSpinner.setEnabled(enabled); + if (mAmPmSpinner != null) { + mAmPmSpinner.setEnabled(enabled); + } else { + mAmPmButton.setEnabled(enabled); + } + mIsEnabled = enabled; + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + setCurrentLocale(newConfig.locale); + } + + /** + * Sets the current locale. + * + * @param locale The current locale. + */ + private void setCurrentLocale(Locale locale) { + if (locale.equals(mCurrentLocale)) { + return; + } + mCurrentLocale = locale; + mTempCalendar = Calendar.getInstance(locale); + } + + @Override + protected Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + return new SavedState(superState, getCurrentHour(), getCurrentMinute()); + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + SavedState ss = (SavedState) state; + super.onRestoreInstanceState(ss.getSuperState()); + setCurrentHour(ss.getHour()); + setCurrentMinute(ss.getMinute()); + } + + /** + * Set the callback that indicates the time has been adjusted by the user. + * + * @param onTimeChangedListener the callback, should not be null. + */ + public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) { + mOnTimeChangedListener = onTimeChangedListener; + } + + /** + * @return The current hour in the range (0-23). + */ + public Integer getCurrentHour() { + int currentHour = mHourSpinner.getValue(); + if (is24HourView()) { + return currentHour; + } else if (mIsAm) { + return currentHour % HOURS_IN_HALF_DAY; + } else { + return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY; + } + } + + /** + * Set the current hour. + */ + public void setCurrentHour(Integer currentHour) { + // why was Integer used in the first place? + if (currentHour == null || currentHour == getCurrentHour()) { + return; + } + if (!is24HourView()) { + // convert [0,23] ordinal to wall clock display + if (currentHour >= HOURS_IN_HALF_DAY) { + mIsAm = false; + if (currentHour > HOURS_IN_HALF_DAY) { + currentHour = currentHour - HOURS_IN_HALF_DAY; + } + } else { + mIsAm = true; + if (currentHour == 0) { + currentHour = HOURS_IN_HALF_DAY; + } + } + updateAmPmControl(); + } + mHourSpinner.setValue(currentHour); + onTimeChanged(); + } + + /** + * Set whether in 24 hour or AM/PM mode. + * + * @param is24HourView True = 24 hour mode. False = AM/PM. + */ + public void setIs24HourView(Boolean is24HourView) { + if (mIs24HourView == is24HourView) { + return; + } + mIs24HourView = is24HourView; + // cache the current hour since spinner range changes + int currentHour = getCurrentHour(); + updateHourControl(); + // set value after spinner range is updated + setCurrentHour(currentHour); + updateAmPmControl(); + } + + /** + * @return true if this is in 24 hour view else false. + */ + public boolean is24HourView() { + return mIs24HourView; + } + + /** + * @return The current minute. + */ + public Integer getCurrentMinute() { + return mMinuteSpinner.getValue(); + } + + /** + * Set the current minute (0-59). + */ + public void setCurrentMinute(Integer currentMinute) { + if (currentMinute == getCurrentMinute()) { + return; + } + mMinuteSpinner.setValue(currentMinute); + onTimeChanged(); + } + + @Override + public int getBaseline() { + return mHourSpinner.getBaseline(); + } + + @Override + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { + onPopulateAccessibilityEvent(event); + return true; + } + + @Override + public void onPopulateAccessibilityEvent(AccessibilityEvent event) { + super.onPopulateAccessibilityEvent(event); + + int flags = DateUtils.FORMAT_SHOW_TIME; + if (mIs24HourView) { + flags |= DateUtils.FORMAT_24HOUR; + } else { + flags |= DateUtils.FORMAT_12HOUR; + } + mTempCalendar.set(Calendar.HOUR_OF_DAY, getCurrentHour()); + mTempCalendar.set(Calendar.MINUTE, getCurrentMinute()); + String selectedDateUtterance = DateUtils.formatDateTime(getContext(), + mTempCalendar.getTimeInMillis(), flags); + event.getText().add(selectedDateUtterance); + } + + @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + event.setClassName(TimePicker.class.getName()); + } + + @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + info.setClassName(TimePicker.class.getName()); + } + + private void updateHourControl() { + if (is24HourView()) { + mHourSpinner.setMinValue(0); + mHourSpinner.setMaxValue(23); + mHourSpinner.setFormatter(NumberPicker.getTwoDigitFormatter()); + } else { + mHourSpinner.setMinValue(1); + mHourSpinner.setMaxValue(12); + mHourSpinner.setFormatter(null); + } + } + + private void updateAmPmControl() { + if (is24HourView()) { + if (mAmPmSpinner != null) { + mAmPmSpinner.setVisibility(View.GONE); + } else { + mAmPmButton.setVisibility(View.GONE); + } + } else { + int index = mIsAm ? Calendar.AM : Calendar.PM; + if (mAmPmSpinner != null) { + mAmPmSpinner.setValue(index); + mAmPmSpinner.setVisibility(View.VISIBLE); + } else { + mAmPmButton.setText(mAmPmStrings[index]); + mAmPmButton.setVisibility(View.VISIBLE); + } + } + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + } + + private void onTimeChanged() { + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + if (mOnTimeChangedListener != null) { + mOnTimeChangedListener.onTimeChanged(this, getCurrentHour(), getCurrentMinute()); + } + } + + private void trySetContentDescription(View root, int viewId, int contDescResId) { + View target = root.findViewById(viewId); + if (target != null) { + target.setContentDescription(getContext().getString(contDescResId)); + } + } + + private void updateInputState() { + // Make sure that if the user changes the value and the IME is active + // for one of the inputs if this widget, the IME is closed. If the user + // changed the value via the IME and there is a next input the IME will + // be shown, otherwise the user chose another means of changing the + // value and having the IME up makes no sense. + //InputMethodManager inputMethodManager = InputMethodManager.peekInstance(); + InputMethodManager inputMethodManager = + (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + if (inputMethodManager != null) { + if (inputMethodManager.isActive(mHourSpinnerInput)) { + mHourSpinnerInput.clearFocus(); + inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); + } else if (inputMethodManager.isActive(mMinuteSpinnerInput)) { + mMinuteSpinnerInput.clearFocus(); + inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); + } else if (inputMethodManager.isActive(mAmPmSpinnerInput)) { + mAmPmSpinnerInput.clearFocus(); + inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); + } + } + } + + /** + * The callback interface used to indicate the time has been adjusted. + */ + public interface OnTimeChangedListener { + + /** + * @param view The view associated with this listener. + * @param hourOfDay The current hour. + * @param minute The current minute. + */ + void onTimeChanged(TimePicker view, int hourOfDay, int minute); + } + + /** + * Used to save / restore state of time picker + */ + private static class SavedState extends BaseSavedState { + + @SuppressWarnings({"unused", "hiding"}) + public static final Parcelable.Creator CREATOR = new Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + private final int mHour; + private final int mMinute; + + private SavedState(Parcelable superState, int hour, int minute) { + super(superState); + mHour = hour; + mMinute = minute; + } + + private SavedState(Parcel in) { + super(in); + mHour = in.readInt(); + mMinute = in.readInt(); + } + + public int getHour() { + return mHour; + } + + public int getMinute() { + return mMinute; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(mHour); + dest.writeInt(mMinute); + } + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/TimePickerDialog.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/TimePickerDialog.java new file mode 100644 index 0000000..ee7bf72 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/TimePickerDialog.java @@ -0,0 +1,157 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +/* + * Copyright (C) 2007 The Android Open Source Project + * + * 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. + */ + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; + +import sh.ftp.rocketninelabs.meditationassistant.TimePicker.OnTimeChangedListener; + +/** + * A dialog that prompts the user for the time of day using a {@link TimePicker}. + *

+ *

See the Pickers + * guide.

+ */ +public class TimePickerDialog extends AlertDialog + implements OnClickListener, OnTimeChangedListener { + + private static final String HOUR = "hour"; + private static final String MINUTE = "minute"; + private static final String IS_24_HOUR = "is24hour"; + private final TimePicker mTimePicker; + private final OnTimeSetListener mCallback; + int mInitialHourOfDay; + int mInitialMinute; + boolean mIs24HourView; + + /** + * @param context Parent. + * @param callBack How parent is notified. + * @param hourOfDay The initial hour. + * @param minute The initial minute. + * @param is24HourView Whether this is a 24 hour view, or AM/PM. + */ + public TimePickerDialog(Context context, + OnTimeSetListener callBack, + int hourOfDay, int minute, boolean is24HourView) { + this(context, Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB ? R.style.Theme_Dialog_Alert : 0, callBack, hourOfDay, minute, is24HourView); + } + + /** + * @param context Parent. + * @param theme the theme to apply to this dialog + * @param callBack How parent is notified. + * @param hourOfDay The initial hour. + * @param minute The initial minute. + * @param is24HourView Whether this is a 24 hour view, or AM/PM. + */ + public TimePickerDialog(Context context, + int theme, + OnTimeSetListener callBack, + int hourOfDay, int minute, boolean is24HourView) { + super(context, theme); + mCallback = callBack; + mInitialHourOfDay = hourOfDay; + mInitialMinute = minute; + mIs24HourView = is24HourView; + + setIcon(0); + setTitle(R.string.setTime); + + Context themeContext = getContext(); + setButton(BUTTON_POSITIVE, themeContext.getText(R.string.set), this); + + LayoutInflater inflater = + (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View view = inflater.inflate(R.layout.time_picker_dialog, null); + setView(view); + mTimePicker = (TimePicker) view.findViewById(R.id.timePicker); + + // initialize state + mTimePicker.setIs24HourView(mIs24HourView); + mTimePicker.setCurrentHour(mInitialHourOfDay); + mTimePicker.setCurrentMinute(mInitialMinute); + mTimePicker.setOnTimeChangedListener(this); + } + + public void onClick(DialogInterface dialog, int which) { + tryNotifyTimeSet(); + } + + public void updateTime(int hourOfDay, int minutOfHour) { + mTimePicker.setCurrentHour(hourOfDay); + mTimePicker.setCurrentMinute(minutOfHour); + } + + public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { + /* do nothing */ + } + + private void tryNotifyTimeSet() { + if (mCallback != null) { + mTimePicker.clearFocus(); + mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(), + mTimePicker.getCurrentMinute()); + } + } + + @Override + protected void onStop() { + tryNotifyTimeSet(); + super.onStop(); + } + + @Override + public Bundle onSaveInstanceState() { + Bundle state = super.onSaveInstanceState(); + state.putInt(HOUR, mTimePicker.getCurrentHour()); + state.putInt(MINUTE, mTimePicker.getCurrentMinute()); + state.putBoolean(IS_24_HOUR, mTimePicker.is24HourView()); + return state; + } + + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + int hour = savedInstanceState.getInt(HOUR); + int minute = savedInstanceState.getInt(MINUTE); + mTimePicker.setIs24HourView(savedInstanceState.getBoolean(IS_24_HOUR)); + mTimePicker.setCurrentHour(hour); + mTimePicker.setCurrentMinute(minute); + } + + /** + * The callback interface used to indicate the user is done filling in + * the time (they clicked on the 'Set' button). + */ + public interface OnTimeSetListener { + + /** + * @param view The view associated with this listener. + * @param hourOfDay The hour that was set. + * @param minute The minute that was set. + */ + void onTimeSet(TimePicker view, int hourOfDay, int minute); + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/TimePreference.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/TimePreference.java new file mode 100644 index 0000000..1b6bc22 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/TimePreference.java @@ -0,0 +1,114 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.content.Context; +import android.content.res.TypedArray; +import android.preference.DialogPreference; +import android.preference.PreferenceManager; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; + +public class TimePreference extends DialogPreference { + private int lastHour = 0; + private int lastMinute = 0; + private TimePicker picker = null; + private Boolean is24hour = true; + private Integer maxhours = 24; + private Context ctx = null; + + public TimePreference(Context context, AttributeSet attrs) { + super(context, attrs); + + ctx = context; + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TimePreference); + is24hour = a.getBoolean(R.styleable.TimePreference_is24hour, false); + maxhours = a.getInteger(R.styleable.TimePreference_maxHours, 24); + a.recycle(); + + setPositiveButtonText("Set"); + setNegativeButtonText("Cancel"); + } + + public static int getHour(String time) { + String[] pieces = time.split(":"); + + return (Integer.parseInt(pieces[0])); + } + + public static int getMinute(String time) { + String[] pieces = time.split(":"); + + return (Integer.parseInt(pieces[1])); + } + + @Override + protected View onCreateDialogView() { + picker = new TimePicker(getContext()); + picker.setIs24HourView(is24hour); + if (maxhours != 24) { + picker.mHourSpinner.setMaxValue(maxhours); + } + + return (picker); + } + + @Override + protected void onBindDialogView(View v) { + super.onBindDialogView(v); + + picker.setCurrentHour(lastHour); + picker.setCurrentMinute(lastMinute); + + Log.d("MeditationAssistant", "TimePreference onBindDialogView: " + String.valueOf(lastHour) + ":" + String.valueOf(lastMinute)); + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + super.onDialogClosed(positiveResult); + + if (positiveResult) { + lastHour = picker.getCurrentHour(); + lastMinute = picker.getCurrentMinute(); + + String time = String.valueOf(lastHour) + ":" + String.valueOf(lastMinute); + + Log.d("MeditationAssistant", "TimePreference positive result: " + time); + + if (callChangeListener(time)) { + persistString(time); + } + } + } + + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + return (a.getString(index)); + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + String time = null; + String defaultv = "00:00"; + + if (restoreValue) { + if (defaultValue == null) { + time = getPersistedString(defaultv); + } else { + time = getPersistedString(defaultValue.toString()); + } + } else { + time = defaultValue.toString(); + } + + /*if (getKey() != null) { + time = PreferenceManager.getDefaultSharedPreferences(ctx).getString(getKey(), getKey().equals("pref_session_delay") ? "00:15" : (getKey().equals("pref_daily_reminder") ? "19:00" : "00:00")); + }*/ + Log.d("MeditationAssistant", String.valueOf(getKey()) + " current value - " + PreferenceManager.getDefaultSharedPreferences(ctx).getString(getKey(), "")); + + Log.d("MeditationAssistant", "TimePreference (" + String.valueOf(getKey()) + ") restoreValue: " + String.valueOf(restoreValue) + " - defaultValue: " + String.valueOf(defaultValue) + " - defaultv: " + String.valueOf(defaultv) + " - time: " + String.valueOf(time)); + + lastHour = getHour(time); + lastMinute = getMinute(time); + } +} diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/WakeLocker.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/WakeLocker.java new file mode 100644 index 0000000..5d38fe7 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/WakeLocker.java @@ -0,0 +1,36 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.content.Context; +import android.os.PowerManager; +import android.util.Log; + +public abstract class WakeLocker { + private static PowerManager.WakeLock wakeLock; + + public static void acquire(Context ctx, Boolean turnScreenOn) { + Log.d("MeditationAssistant", "WAKELOCKER: Acquiring wakelock"); + if (wakeLock != null) { + Log.d("MeditationAssistant", "WAKELOCKER: Releasing old wakelock first..."); + wakeLock.release(); + } + + PowerManager pm = (PowerManager) ctx + .getSystemService(Context.POWER_SERVICE); + + if (turnScreenOn) { + wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | + PowerManager.ON_AFTER_RELEASE, "MeditationAssistant"); + } else { + wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MeditationAssistant"); + } + wakeLock.acquire(); + } + + public static void release() { + if (wakeLock != null) { + Log.d("MeditationAssistant", "WAKELOCKER: Releasing wakelock"); + wakeLock.release(); + } + wakeLock = null; + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/WearListenerService.java b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/WearListenerService.java new file mode 100644 index 0000000..ac99180 --- /dev/null +++ b/MeditationAssistant/src/main/java/sh/ftp/rocketninelabs/meditationassistant/WearListenerService.java @@ -0,0 +1,55 @@ +package sh.ftp.rocketninelabs.meditationassistant; + +import android.util.Log; + +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.common.data.FreezableUtils; +import com.google.android.gms.wearable.DataEventBuffer; +import com.google.android.gms.wearable.Wearable; +import com.google.android.gms.wearable.WearableListenerService; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class WearListenerService extends WearableListenerService { + + private static final String TAG = "MeditationAssistant"; + private static final String START_ACTIVITY_PATH = "/start-activity"; + private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received"; + + @Override + public void onDataChanged(DataEventBuffer dataEvents) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "onDataChanged: " + dataEvents); + } + final List events = FreezableUtils + .freezeIterable(dataEvents); + + GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this) + .addApi(Wearable.API) + .build(); + + ConnectionResult connectionResult = + googleApiClient.blockingConnect(30, TimeUnit.SECONDS); + + if (!connectionResult.isSuccess()) { + Log.e(TAG, "Failed to connect to GoogleApiClient."); + } + + // Loop through the events and send a message + // to the node that created the data item. + /*for (DataEvent event : events) { + Uri uri = event.getDataItem().getUri(); + + // Get the node id from the host value of the URI + String nodeId = uri.getHost(); + // Set the data of the message to be the bytes of the URI + byte[] payload = uri.toString().getBytes(); + + // Send the RPC + Wearable.MessageApi.sendMessage(googleApiClient, nodeId, + DATA_ITEM_RECEIVED_PATH, payload); + }*/ + } +} \ No newline at end of file diff --git a/MeditationAssistant/src/main/res/anim/fadeinma.xml b/MeditationAssistant/src/main/res/anim/fadeinma.xml new file mode 100644 index 0000000..befa346 --- /dev/null +++ b/MeditationAssistant/src/main/res/anim/fadeinma.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/MeditationAssistant/src/main/res/anim/fadeoutma.xml b/MeditationAssistant/src/main/res/anim/fadeoutma.xml new file mode 100644 index 0000000..4c07b2b --- /dev/null +++ b/MeditationAssistant/src/main/res/anim/fadeoutma.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/MeditationAssistant/src/main/res/anim/spin.xml b/MeditationAssistant/src/main/res/anim/spin.xml new file mode 100644 index 0000000..41b66fa --- /dev/null +++ b/MeditationAssistant/src/main/res/anim/spin.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ab_bottom_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/ab_bottom_solid_buddhism.9.png new file mode 100644 index 0000000..337da0f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ab_bottom_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ab_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/ab_solid_buddhism.9.png new file mode 100644 index 0000000..9e77a28 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ab_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ab_stacked_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/ab_stacked_solid_buddhism.9.png new file mode 100644 index 0000000..d75b0f2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ab_stacked_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ab_texture_tile_buddhism.png b/MeditationAssistant/src/main/res/drawable-hdpi/ab_texture_tile_buddhism.png new file mode 100644 index 0000000..39a71de Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ab_texture_tile_buddhism.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ab_transparent_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/ab_transparent_buddhism.9.png new file mode 100644 index 0000000..2be2a47 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ab_transparent_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/btn_cab_done_default_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/btn_cab_done_default_buddhism.9.png new file mode 100644 index 0000000..c8d351e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/btn_cab_done_default_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/btn_cab_done_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/btn_cab_done_focused_buddhism.9.png new file mode 100644 index 0000000..f7f6c77 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/btn_cab_done_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/btn_cab_done_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/btn_cab_done_pressed_buddhism.9.png new file mode 100644 index 0000000..8d332ef Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/btn_cab_done_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_disabled_focused_holo_light.png new file mode 100644 index 0000000..09d155b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_disabled_holo_light.png new file mode 100644 index 0000000..9dbad9b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_focused_holo_light.png new file mode 100644 index 0000000..25e1575 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_holo_light.png new file mode 100644 index 0000000..b1b52b2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_pressed_holo_light.png new file mode 100644 index 0000000..e5f0ddf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_off_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_disabled_focused_holo_light.png new file mode 100644 index 0000000..50c2ee5 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_disabled_holo_light.png new file mode 100644 index 0000000..cd02122 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_focused_holo_light.png new file mode 100644 index 0000000..4c99f2a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_holo_light.png new file mode 100644 index 0000000..98659d0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_pressed_holo_light.png new file mode 100644 index 0000000..313698a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_check_on_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..98c1321 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_disabled_holo_light.9.png new file mode 100644 index 0000000..6a2a92c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_focused_holo_light.9.png new file mode 100644 index 0000000..f982dea Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_normal_holo_light.9.png new file mode 100644 index 0000000..4466325 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_pressed_holo_light.9.png new file mode 100644 index 0000000..3c414bf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_default_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png new file mode 100644 index 0000000..6589f5f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_disabled_holo_light.png new file mode 100644 index 0000000..25e8e1b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_focused_holo_light.png new file mode 100644 index 0000000..e171f1b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_holo_light.png new file mode 100644 index 0000000..5021bb4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_pressed_holo_light.png new file mode 100644 index 0000000..065e49a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_off_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png new file mode 100644 index 0000000..0169d83 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_disabled_holo_light.png new file mode 100644 index 0000000..6e61b52 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_focused_holo_light.png new file mode 100644 index 0000000..fa5a3e0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_holo_light.png new file mode 100644 index 0000000..af2cd4c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_pressed_holo_light.png new file mode 100644 index 0000000..7f66e28 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_radio_on_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..e0a2ac7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png new file mode 100644 index 0000000..a7e6bc3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_focused_holo_light.9.png new file mode 100644 index 0000000..3c1e1d3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_normal_holo_light.9.png new file mode 100644 index 0000000..aba5581 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png new file mode 100644 index 0000000..9f68344 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..c8c5f76 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png new file mode 100644 index 0000000..4144b61 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_focused_holo_light.9.png new file mode 100644 index 0000000..24b422c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_normal_holo_light.9.png new file mode 100644 index 0000000..3ee5a49 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png new file mode 100644 index 0000000..a0d649d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_fastscroll_thumb_default_holo.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_fastscroll_thumb_default_holo.png new file mode 100644 index 0000000..2267af0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_fastscroll_thumb_default_holo.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_fastscroll_thumb_pressed_holo.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_fastscroll_thumb_pressed_holo.png new file mode 100644 index 0000000..aaf6fa2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_fastscroll_thumb_pressed_holo.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_ic_navigation_drawer.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_ic_navigation_drawer.png new file mode 100644 index 0000000..480e9e7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_ic_navigation_drawer.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_activated_holo.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_activated_holo.9.png new file mode 100644 index 0000000..5b4e992 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_activated_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_focused_holo.9.png new file mode 100644 index 0000000..bdd137c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_longpressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_longpressed_holo.9.png new file mode 100644 index 0000000..e9196aa Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_longpressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_pressed_holo_light.9.png new file mode 100644 index 0000000..895e51b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_selector_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_selector_disabled_holo_light.9.png new file mode 100644 index 0000000..ca8e9a2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_list_selector_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progress_bg_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progress_bg_holo_light.9.png new file mode 100644 index 0000000..3f12166 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progress_bg_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progress_primary_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progress_primary_holo_light.9.png new file mode 100644 index 0000000..8be1726 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progress_primary_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progress_secondary_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progress_secondary_holo_light.9.png new file mode 100644 index 0000000..edbf5a8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progress_secondary_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo1.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo1.png new file mode 100644 index 0000000..572128f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo1.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo2.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo2.png new file mode 100644 index 0000000..62970e3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo2.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo3.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo3.png new file mode 100644 index 0000000..14ab127 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo3.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo4.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo4.png new file mode 100644 index 0000000..27a9019 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo4.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo5.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo5.png new file mode 100644 index 0000000..8174420 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo5.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo6.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo6.png new file mode 100644 index 0000000..6a7f5fb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo6.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo7.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo7.png new file mode 100644 index 0000000..b71a75c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo7.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo8.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo8.png new file mode 100644 index 0000000..56ae841 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_progressbar_indeterminate_holo8.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_default_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_default_holo_light.9.png new file mode 100644 index 0000000..5b06f8e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_default_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_disabled_holo_light.9.png new file mode 100644 index 0000000..d0d9419 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_focused_holo_light.9.png new file mode 100644 index 0000000..fa902f0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_pressed_holo_light.9.png new file mode 100644 index 0000000..5fb95ea Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_spinner_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_selected_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_selected_focused_holo.9.png new file mode 100644 index 0000000..4ef83dd Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_selected_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_selected_holo.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_selected_holo.9.png new file mode 100644 index 0000000..89bf62e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_selected_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_selected_pressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_selected_pressed_holo.9.png new file mode 100644 index 0000000..d2d4c5d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_selected_pressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_unselected_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_unselected_focused_holo.9.png new file mode 100644 index 0000000..13d2a9a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_unselected_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_unselected_holo.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_unselected_holo.9.png new file mode 100644 index 0000000..3734b6a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_unselected_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_unselected_pressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_unselected_pressed_holo.9.png new file mode 100644 index 0000000..5f7630d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_tab_unselected_pressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_text_select_handle_left.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_text_select_handle_left.png new file mode 100644 index 0000000..4e02c0f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_text_select_handle_left.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_text_select_handle_middle.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_text_select_handle_middle.png new file mode 100644 index 0000000..08b9259 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_text_select_handle_middle.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_text_select_handle_right.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_text_select_handle_right.png new file mode 100644 index 0000000..c35c438 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_text_select_handle_right.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_activated_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_activated_holo_light.9.png new file mode 100644 index 0000000..43b72ef Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_activated_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_default_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_default_holo_light.9.png new file mode 100644 index 0000000..5fa1d03 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_default_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..b70db4e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_disabled_holo_light.9.png new file mode 100644 index 0000000..a77d66d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_focused_holo_light.9.png new file mode 100644 index 0000000..f3df1f9 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/buddhism_textfield_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/cab_background_bottom_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/cab_background_bottom_buddhism.9.png new file mode 100644 index 0000000..843d8ab Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/cab_background_bottom_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/cab_background_top_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/cab_background_top_buddhism.9.png new file mode 100644 index 0000000..9be957e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/cab_background_top_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_accounts.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_accounts.png new file mode 100644 index 0000000..2282659 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_accounts.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_accounts_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_accounts_light.png new file mode 100644 index 0000000..79a9ba0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_accounts_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_brightness_low.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_brightness_low.png new file mode 100644 index 0000000..6006dce Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_brightness_low.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_brightness_low_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_brightness_low_light.png new file mode 100644 index 0000000..9ce5da1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_brightness_low_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_chat.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_chat.png new file mode 100644 index 0000000..d1c182d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_chat.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_chat_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_chat_light.png new file mode 100644 index 0000000..7118f29 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_chat_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_downcloud.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_downcloud.png new file mode 100644 index 0000000..c8dc0eb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_downcloud.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_downcloud_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_downcloud_light.png new file mode 100644 index 0000000..283f20a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_downcloud_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_flash_on.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_flash_on.png new file mode 100644 index 0000000..dcf6d1b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_flash_on.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_flash_on_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_flash_on_light.png new file mode 100644 index 0000000..7104e3f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_flash_on_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_forward.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_forward.png new file mode 100644 index 0000000..5516b5c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_forward.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_forward_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_forward_light.png new file mode 100644 index 0000000..c97ad27 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_forward_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_full_screen.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_full_screen.png new file mode 100644 index 0000000..5e68541 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_full_screen.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_full_screen_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_full_screen_light.png new file mode 100644 index 0000000..1e484de Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_full_screen_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_go_to_today.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_go_to_today.png new file mode 100644 index 0000000..93d3b87 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_go_to_today.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_go_to_today_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_go_to_today_light.png new file mode 100644 index 0000000..55f9677 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_go_to_today_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_group.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_group.png new file mode 100644 index 0000000..7f0ce90 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_group.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_group_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_group_light.png new file mode 100644 index 0000000..bf91dc7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_group_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_info.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_info.png new file mode 100644 index 0000000..9b902d0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_info.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_info_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_info_light.png new file mode 100644 index 0000000..c19f7f8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_info_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_network_cell.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_network_cell.png new file mode 100644 index 0000000..40716c4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_network_cell.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_network_cell_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_network_cell_light.png new file mode 100644 index 0000000..c11f7cb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_network_cell_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_new.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_new.png new file mode 100644 index 0000000..41cd8a4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_new.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_new_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_new_light.png new file mode 100644 index 0000000..52ffc61 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_new_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_next_item.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_next_item.png new file mode 100644 index 0000000..74c1448 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_next_item.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_next_item_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_next_item_light.png new file mode 100644 index 0000000..ee7aceb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_next_item_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_not_important.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_not_important.png new file mode 100644 index 0000000..df0aa4b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_not_important.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_not_important_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_not_important_light.png new file mode 100644 index 0000000..40967e2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_not_important_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_pause.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_pause.png new file mode 100644 index 0000000..b057588 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_pause.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_person.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_person.png new file mode 100644 index 0000000..fb7ad44 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_person.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_person_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_person_light.png new file mode 100644 index 0000000..e02a988 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_person_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_previous_item.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_previous_item.png new file mode 100644 index 0000000..d06bce8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_previous_item.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_previous_item_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_previous_item_light.png new file mode 100644 index 0000000..6447949 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_previous_item_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_refresh.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_refresh.png new file mode 100644 index 0000000..dda3592 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_refresh.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_refresh_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_refresh_light.png new file mode 100644 index 0000000..3752d38 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_refresh_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_ring_volume.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_ring_volume.png new file mode 100644 index 0000000..47e35fc Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_ring_volume.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_ring_volume_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_ring_volume_light.png new file mode 100644 index 0000000..08bf6ae Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_ring_volume_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_settings.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_settings.png new file mode 100644 index 0000000..54eecde Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_settings.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_settings_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_settings_light.png new file mode 100644 index 0000000..0eb78f7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_settings_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_share.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_share.png new file mode 100644 index 0000000..ce9fd90 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_share.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_share_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_share_light.png new file mode 100644 index 0000000..202a5c8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_share_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sign_out.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sign_out.png new file mode 100644 index 0000000..6cd89e1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sign_out.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sign_out_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sign_out_light.png new file mode 100644 index 0000000..8cf93dc Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sign_out_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sort_by_size.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sort_by_size.png new file mode 100644 index 0000000..b2ccc5b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sort_by_size.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sort_by_size_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sort_by_size_light.png new file mode 100644 index 0000000..bee2adc Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_sort_by_size_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_stop.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_stop.png new file mode 100644 index 0000000..b4bae41 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_stop.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_time.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_time.png new file mode 100644 index 0000000..71541fc Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_time.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_time_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_time_light.png new file mode 100644 index 0000000..075507b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_time_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_upcloud.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_upcloud.png new file mode 100644 index 0000000..c7e8ac8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_upcloud.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_upcloud_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_upcloud_light.png new file mode 100644 index 0000000..9ee0e1f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_upcloud_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_view_as_list.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_view_as_list.png new file mode 100644 index 0000000..00f874f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_view_as_list.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_view_as_list_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_view_as_list_light.png new file mode 100644 index 0000000..6d259be Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_view_as_list_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_volume_on.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_volume_on.png new file mode 100644 index 0000000..96b42d1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_volume_on.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_volume_on_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_volume_on_light.png new file mode 100644 index 0000000..1335d49 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_volume_on_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_website.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_website.png new file mode 100644 index 0000000..ae7581b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_website.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_website_light.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_website_light.png new file mode 100644 index 0000000..01fcdbb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_action_website_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/ic_notification.png b/MeditationAssistant/src/main/res/drawable-hdpi/ic_notification.png new file mode 100644 index 0000000..afb3787 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/ic_notification.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/list_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/list_focused_buddhism.9.png new file mode 100644 index 0000000..a2951bd Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/list_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/list_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/list_focused_holo.9.png new file mode 100644 index 0000000..5552708 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/list_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/list_longpressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/list_longpressed_holo.9.png new file mode 100644 index 0000000..4ea7afa Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/list_longpressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/list_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/list_pressed_buddhism.9.png new file mode 100644 index 0000000..74e4359 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/list_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/list_pressed_holo_dark.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/list_pressed_holo_dark.9.png new file mode 100644 index 0000000..5654cd6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/list_pressed_holo_dark.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/list_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/list_pressed_holo_light.9.png new file mode 100644 index 0000000..5654cd6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/list_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png new file mode 100644 index 0000000..f6fd30d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/list_selector_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/list_selector_disabled_holo_light.9.png new file mode 100644 index 0000000..ca8e9a2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/list_selector_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/menu_dropdown_panel_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/menu_dropdown_panel_buddhism.9.png new file mode 100644 index 0000000..2c7f561 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/menu_dropdown_panel_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/np_numberpicker_selection_divider.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/np_numberpicker_selection_divider.9.png new file mode 100644 index 0000000..c9c72ba Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/np_numberpicker_selection_divider.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/progress_bg_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/progress_bg_buddhism.9.png new file mode 100644 index 0000000..3d5c707 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/progress_bg_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/progress_primary_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/progress_primary_buddhism.9.png new file mode 100644 index 0000000..a1d1b6c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/progress_primary_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/progress_secondary_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/progress_secondary_buddhism.9.png new file mode 100644 index 0000000..0281677 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/progress_secondary_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_default_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_default_buddhism.9.png new file mode 100644 index 0000000..4fd4aeb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_default_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_disabled_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_disabled_buddhism.9.png new file mode 100644 index 0000000..d42c97b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_disabled_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_focused_buddhism.9.png new file mode 100644 index 0000000..5268ac9 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_pressed_buddhism.9.png new file mode 100644 index 0000000..dda5bd5 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/spinner_ab_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/tab_selected_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/tab_selected_buddhism.9.png new file mode 100644 index 0000000..1e8a244 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/tab_selected_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/tab_selected_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/tab_selected_focused_buddhism.9.png new file mode 100644 index 0000000..8a01a9d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/tab_selected_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/tab_selected_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/tab_selected_pressed_buddhism.9.png new file mode 100644 index 0000000..7b2aa9f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/tab_selected_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/tab_unselected_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/tab_unselected_buddhism.9.png new file mode 100644 index 0000000..2d7c013 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/tab_unselected_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/tab_unselected_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/tab_unselected_focused_buddhism.9.png new file mode 100644 index 0000000..85668eb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/tab_unselected_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-hdpi/tab_unselected_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-hdpi/tab_unselected_pressed_buddhism.9.png new file mode 100644 index 0000000..5df03de Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-hdpi/tab_unselected_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_accounts.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_accounts.png new file mode 100644 index 0000000..e83c6ef Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_accounts.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_accounts_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_accounts_light.png new file mode 100644 index 0000000..6d09956 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_accounts_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_brightness_low.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_brightness_low.png new file mode 100644 index 0000000..feef8d6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_brightness_low.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_brightness_low_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_brightness_low_light.png new file mode 100644 index 0000000..0accee1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_brightness_low_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_chat.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_chat.png new file mode 100644 index 0000000..3aae697 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_chat.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_chat_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_chat_light.png new file mode 100644 index 0000000..0f1f6ee Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_chat_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_downcloud.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_downcloud.png new file mode 100644 index 0000000..3ae8033 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_downcloud.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_downcloud_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_downcloud_light.png new file mode 100644 index 0000000..fcb52fc Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_downcloud_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_flash_on.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_flash_on.png new file mode 100644 index 0000000..e177e1e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_flash_on.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_flash_on_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_flash_on_light.png new file mode 100644 index 0000000..ed995c0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_flash_on_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_forward.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_forward.png new file mode 100644 index 0000000..2277f8a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_forward.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_forward_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_forward_light.png new file mode 100644 index 0000000..e8ae406 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_forward_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_full_screen.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_full_screen.png new file mode 100644 index 0000000..4d35dba Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_full_screen.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_full_screen_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_full_screen_light.png new file mode 100644 index 0000000..f493a47 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_full_screen_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_go_to_today.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_go_to_today.png new file mode 100644 index 0000000..cc83761 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_go_to_today.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_go_to_today_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_go_to_today_light.png new file mode 100644 index 0000000..6d28956 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_go_to_today_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_group.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_group.png new file mode 100644 index 0000000..1328891 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_group.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_group_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_group_light.png new file mode 100644 index 0000000..7d5118e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_group_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_info.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_info.png new file mode 100644 index 0000000..ed38db3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_info.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_info_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_info_light.png new file mode 100644 index 0000000..bd9613f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_info_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_network_cell.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_network_cell.png new file mode 100644 index 0000000..dba3246 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_network_cell.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_network_cell_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_network_cell_light.png new file mode 100644 index 0000000..eb4c0eb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_network_cell_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_new.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_new.png new file mode 100644 index 0000000..19a5075 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_new.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_new_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_new_light.png new file mode 100644 index 0000000..ad43b18 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_new_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_next_item.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_next_item.png new file mode 100644 index 0000000..c0d3d24 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_next_item.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_next_item_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_next_item_light.png new file mode 100644 index 0000000..0193564 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_next_item_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_not_important.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_not_important.png new file mode 100644 index 0000000..62bdfc9 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_not_important.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_not_important_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_not_important_light.png new file mode 100644 index 0000000..93ff200 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_not_important_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_pause.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_pause.png new file mode 100644 index 0000000..3a4afb8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_pause.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_person.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_person.png new file mode 100644 index 0000000..f149689 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_person.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_person_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_person_light.png new file mode 100644 index 0000000..18dc2ea Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_person_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_previous_item.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_previous_item.png new file mode 100644 index 0000000..14363f9 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_previous_item.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_previous_item_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_previous_item_light.png new file mode 100644 index 0000000..64e01be Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_previous_item_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_refresh.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_refresh.png new file mode 100644 index 0000000..5e8f5d9 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_refresh.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_refresh_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_refresh_light.png new file mode 100644 index 0000000..e184c9b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_refresh_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_ring_volume.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_ring_volume.png new file mode 100644 index 0000000..8d7b1a7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_ring_volume.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_ring_volume_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_ring_volume_light.png new file mode 100644 index 0000000..96fd15a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_ring_volume_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_settings.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_settings.png new file mode 100644 index 0000000..19080b6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_settings.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_settings_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_settings_light.png new file mode 100644 index 0000000..9de1f5e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_settings_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_share.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_share.png new file mode 100644 index 0000000..9fd14bf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_share.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_share_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_share_light.png new file mode 100644 index 0000000..a5b0c5d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_share_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sign_out.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sign_out.png new file mode 100644 index 0000000..fc371cb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sign_out.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sign_out_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sign_out_light.png new file mode 100644 index 0000000..0454702 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sign_out_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sort_by_size.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sort_by_size.png new file mode 100644 index 0000000..ddcee7c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sort_by_size.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sort_by_size_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sort_by_size_light.png new file mode 100644 index 0000000..ab9b5aa Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_sort_by_size_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_stop.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_stop.png new file mode 100644 index 0000000..210fcf0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_stop.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_time.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_time.png new file mode 100644 index 0000000..5f72ecb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_time.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_time_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_time_light.png new file mode 100644 index 0000000..286df04 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_time_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_upcloud.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_upcloud.png new file mode 100644 index 0000000..fb2d43c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_upcloud.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_upcloud_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_upcloud_light.png new file mode 100644 index 0000000..f6ab906 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_upcloud_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_view_as_list.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_view_as_list.png new file mode 100644 index 0000000..7782615 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_view_as_list.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_view_as_list_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_view_as_list_light.png new file mode 100644 index 0000000..b14d80b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_view_as_list_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_volume_on.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_volume_on.png new file mode 100644 index 0000000..593acae Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_volume_on.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_volume_on_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_volume_on_light.png new file mode 100644 index 0000000..1d8dfbf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_volume_on_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_website.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_website.png new file mode 100644 index 0000000..797c647 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_website.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_website_light.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_website_light.png new file mode 100644 index 0000000..d502614 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_action_website_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-ldpi/ic_notification.png b/MeditationAssistant/src/main/res/drawable-ldpi/ic_notification.png new file mode 100644 index 0000000..0f64a23 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-ldpi/ic_notification.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ab_bottom_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/ab_bottom_solid_buddhism.9.png new file mode 100644 index 0000000..add7c75 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ab_bottom_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ab_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/ab_solid_buddhism.9.png new file mode 100644 index 0000000..503fce6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ab_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ab_stacked_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/ab_stacked_solid_buddhism.9.png new file mode 100644 index 0000000..26b4a10 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ab_stacked_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ab_texture_tile_buddhism.png b/MeditationAssistant/src/main/res/drawable-mdpi/ab_texture_tile_buddhism.png new file mode 100644 index 0000000..7d8ae49 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ab_texture_tile_buddhism.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ab_transparent_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/ab_transparent_buddhism.9.png new file mode 100644 index 0000000..18b456a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ab_transparent_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/btn_cab_done_default_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/btn_cab_done_default_buddhism.9.png new file mode 100644 index 0000000..70f1520 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/btn_cab_done_default_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/btn_cab_done_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/btn_cab_done_focused_buddhism.9.png new file mode 100644 index 0000000..b94cdcf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/btn_cab_done_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/btn_cab_done_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/btn_cab_done_pressed_buddhism.9.png new file mode 100644 index 0000000..4acbbf6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/btn_cab_done_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_disabled_focused_holo_light.png new file mode 100644 index 0000000..b8a462a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_disabled_holo_light.png new file mode 100644 index 0000000..db19043 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_focused_holo_light.png new file mode 100644 index 0000000..f6549cf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_holo_light.png new file mode 100644 index 0000000..f5eaf80 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_pressed_holo_light.png new file mode 100644 index 0000000..c237545 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_off_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_disabled_focused_holo_light.png new file mode 100644 index 0000000..257f48f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_disabled_holo_light.png new file mode 100644 index 0000000..20e2aab Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_focused_holo_light.png new file mode 100644 index 0000000..f4e4db4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_holo_light.png new file mode 100644 index 0000000..ff06ba5 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_pressed_holo_light.png new file mode 100644 index 0000000..09f2df1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_check_on_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..a19ab01 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_disabled_holo_light.9.png new file mode 100644 index 0000000..d424a0e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_focused_holo_light.9.png new file mode 100644 index 0000000..0ec0c19 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_normal_holo_light.9.png new file mode 100644 index 0000000..e134087 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_pressed_holo_light.9.png new file mode 100644 index 0000000..90c8de1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_default_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png new file mode 100644 index 0000000..c087975 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_disabled_holo_light.png new file mode 100644 index 0000000..a67375e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_focused_holo_light.png new file mode 100644 index 0000000..04d510d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_holo_light.png new file mode 100644 index 0000000..0d81a6a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_pressed_holo_light.png new file mode 100644 index 0000000..ad8341b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_off_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png new file mode 100644 index 0000000..58ff13e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_disabled_holo_light.png new file mode 100644 index 0000000..4583c3e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_focused_holo_light.png new file mode 100644 index 0000000..6b0ae6c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_holo_light.png new file mode 100644 index 0000000..4ae19c4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_pressed_holo_light.png new file mode 100644 index 0000000..7d47196 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_radio_on_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..47e9ed6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png new file mode 100644 index 0000000..3a35a4e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_focused_holo_light.9.png new file mode 100644 index 0000000..c994cfc Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_normal_holo_light.9.png new file mode 100644 index 0000000..37f70c5 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png new file mode 100644 index 0000000..98a9f10 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..020f69f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png new file mode 100644 index 0000000..4beb424 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_focused_holo_light.9.png new file mode 100644 index 0000000..f5c72e3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_normal_holo_light.9.png new file mode 100644 index 0000000..101bd9b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png new file mode 100644 index 0000000..54f56e1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_fastscroll_thumb_default_holo.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_fastscroll_thumb_default_holo.png new file mode 100644 index 0000000..a022891 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_fastscroll_thumb_default_holo.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_fastscroll_thumb_pressed_holo.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_fastscroll_thumb_pressed_holo.png new file mode 100644 index 0000000..a8ad792 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_fastscroll_thumb_pressed_holo.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_ic_navigation_drawer.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_ic_navigation_drawer.png new file mode 100644 index 0000000..dbf577f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_ic_navigation_drawer.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_activated_holo.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_activated_holo.9.png new file mode 100644 index 0000000..b66f2b6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_activated_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_focused_holo.9.png new file mode 100644 index 0000000..b819468 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_longpressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_longpressed_holo.9.png new file mode 100644 index 0000000..ba6538f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_longpressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_pressed_holo_light.9.png new file mode 100644 index 0000000..886a6ee Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_selector_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_selector_disabled_holo_light.9.png new file mode 100644 index 0000000..42cb646 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_list_selector_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progress_bg_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progress_bg_holo_light.9.png new file mode 100644 index 0000000..780b4b2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progress_bg_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progress_primary_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progress_primary_holo_light.9.png new file mode 100644 index 0000000..ff7bbdb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progress_primary_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progress_secondary_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progress_secondary_holo_light.9.png new file mode 100644 index 0000000..ca0a772 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progress_secondary_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo1.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo1.png new file mode 100644 index 0000000..6d9275b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo1.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo2.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo2.png new file mode 100644 index 0000000..cdde28b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo2.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo3.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo3.png new file mode 100644 index 0000000..a913092 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo3.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo4.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo4.png new file mode 100644 index 0000000..dc345eb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo4.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo5.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo5.png new file mode 100644 index 0000000..8d950e3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo5.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo6.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo6.png new file mode 100644 index 0000000..d075f39 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo6.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo7.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo7.png new file mode 100644 index 0000000..6e8cd66 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo7.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo8.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo8.png new file mode 100644 index 0000000..679882a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_progressbar_indeterminate_holo8.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_default_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_default_holo_light.9.png new file mode 100644 index 0000000..fc3e7f7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_default_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_disabled_holo_light.9.png new file mode 100644 index 0000000..a78d6c0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_focused_holo_light.9.png new file mode 100644 index 0000000..adfff05 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_pressed_holo_light.9.png new file mode 100644 index 0000000..b68afaf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_spinner_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_selected_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_selected_focused_holo.9.png new file mode 100644 index 0000000..3e55373 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_selected_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_selected_holo.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_selected_holo.9.png new file mode 100644 index 0000000..bd7f999 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_selected_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_selected_pressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_selected_pressed_holo.9.png new file mode 100644 index 0000000..e73ba8b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_selected_pressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_unselected_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_unselected_focused_holo.9.png new file mode 100644 index 0000000..403255d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_unselected_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_unselected_holo.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_unselected_holo.9.png new file mode 100644 index 0000000..b635eb4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_unselected_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_unselected_pressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_unselected_pressed_holo.9.png new file mode 100644 index 0000000..4074bf6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_tab_unselected_pressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_text_select_handle_left.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_text_select_handle_left.png new file mode 100644 index 0000000..a7fafb1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_text_select_handle_left.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_text_select_handle_middle.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_text_select_handle_middle.png new file mode 100644 index 0000000..ae89d5a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_text_select_handle_middle.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_text_select_handle_right.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_text_select_handle_right.png new file mode 100644 index 0000000..5f91253 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_text_select_handle_right.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_activated_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_activated_holo_light.9.png new file mode 100644 index 0000000..5a3d3b4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_activated_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_default_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_default_holo_light.9.png new file mode 100644 index 0000000..15efce9 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_default_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..0d5ea83 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_disabled_holo_light.9.png new file mode 100644 index 0000000..ea6d2f7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_focused_holo_light.9.png new file mode 100644 index 0000000..071343f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/buddhism_textfield_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/cab_background_bottom_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/cab_background_bottom_buddhism.9.png new file mode 100644 index 0000000..0b3d1ce Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/cab_background_bottom_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/cab_background_top_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/cab_background_top_buddhism.9.png new file mode 100644 index 0000000..e3a0ba1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/cab_background_top_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_accounts.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_accounts.png new file mode 100644 index 0000000..3f5ef98 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_accounts.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_accounts_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_accounts_light.png new file mode 100644 index 0000000..5d6228b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_accounts_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_brightness_low.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_brightness_low.png new file mode 100644 index 0000000..9d391a7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_brightness_low.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_brightness_low_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_brightness_low_light.png new file mode 100644 index 0000000..3e704c5 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_brightness_low_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_chat.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_chat.png new file mode 100644 index 0000000..ab0c68c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_chat.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_chat_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_chat_light.png new file mode 100644 index 0000000..3e0e8f6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_chat_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_downcloud.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_downcloud.png new file mode 100644 index 0000000..653d7b8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_downcloud.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_downcloud_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_downcloud_light.png new file mode 100644 index 0000000..524819b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_downcloud_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_flash_on.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_flash_on.png new file mode 100644 index 0000000..5ebe9d1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_flash_on.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_flash_on_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_flash_on_light.png new file mode 100644 index 0000000..07c0126 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_flash_on_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_forward.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_forward.png new file mode 100644 index 0000000..f79b10d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_forward.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_forward_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_forward_light.png new file mode 100644 index 0000000..19e4f30 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_forward_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_full_screen.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_full_screen.png new file mode 100644 index 0000000..0cbf0da Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_full_screen.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_full_screen_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_full_screen_light.png new file mode 100644 index 0000000..d8f097f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_full_screen_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_go_to_today.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_go_to_today.png new file mode 100644 index 0000000..a9e73f1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_go_to_today.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_go_to_today_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_go_to_today_light.png new file mode 100644 index 0000000..a76bb8a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_go_to_today_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_group.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_group.png new file mode 100644 index 0000000..d52a776 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_group.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_group_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_group_light.png new file mode 100644 index 0000000..852c809 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_group_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_info.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_info.png new file mode 100644 index 0000000..7ede67d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_info.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_info_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_info_light.png new file mode 100644 index 0000000..37ab254 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_info_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_network_cell.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_network_cell.png new file mode 100644 index 0000000..7aea978 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_network_cell.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_network_cell_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_network_cell_light.png new file mode 100644 index 0000000..754775e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_network_cell_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_new.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_new.png new file mode 100644 index 0000000..fcbceef Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_new.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_new_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_new_light.png new file mode 100644 index 0000000..d989b4e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_new_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_next_item.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_next_item.png new file mode 100644 index 0000000..e8ba00e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_next_item.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_next_item_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_next_item_light.png new file mode 100644 index 0000000..cfe0c41 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_next_item_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_not_important.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_not_important.png new file mode 100644 index 0000000..c013e05 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_not_important.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_not_important_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_not_important_light.png new file mode 100644 index 0000000..6ffd1b3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_not_important_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_pause.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_pause.png new file mode 100644 index 0000000..3580dab Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_pause.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_person.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_person.png new file mode 100644 index 0000000..26ee460 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_person.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_person_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_person_light.png new file mode 100644 index 0000000..2f6333e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_person_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_previous_item.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_previous_item.png new file mode 100644 index 0000000..1ce787b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_previous_item.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_previous_item_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_previous_item_light.png new file mode 100644 index 0000000..e27b72f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_previous_item_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_refresh.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_refresh.png new file mode 100644 index 0000000..00a4cb4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_refresh.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_refresh_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_refresh_light.png new file mode 100644 index 0000000..fc57b91 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_refresh_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_ring_volume.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_ring_volume.png new file mode 100644 index 0000000..fae6cc9 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_ring_volume.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_ring_volume_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_ring_volume_light.png new file mode 100644 index 0000000..93dd51e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_ring_volume_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_settings.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_settings.png new file mode 100644 index 0000000..25c36db Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_settings.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_settings_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_settings_light.png new file mode 100644 index 0000000..c290e59 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_settings_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_share.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_share.png new file mode 100644 index 0000000..af7970f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_share.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_share_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_share_light.png new file mode 100644 index 0000000..5da4106 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_share_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sign_out.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sign_out.png new file mode 100644 index 0000000..d2d03ba Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sign_out.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sign_out_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sign_out_light.png new file mode 100644 index 0000000..a84f5fd Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sign_out_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sort_by_size.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sort_by_size.png new file mode 100644 index 0000000..868b39c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sort_by_size.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sort_by_size_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sort_by_size_light.png new file mode 100644 index 0000000..cdee6ac Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_sort_by_size_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_stop.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_stop.png new file mode 100644 index 0000000..2f4dd89 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_stop.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_time.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_time.png new file mode 100644 index 0000000..3ab9b19 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_time.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_time_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_time_light.png new file mode 100644 index 0000000..21bab53 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_time_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_upcloud.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_upcloud.png new file mode 100644 index 0000000..d389ed9 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_upcloud.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_upcloud_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_upcloud_light.png new file mode 100644 index 0000000..322cc40 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_upcloud_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_view_as_list.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_view_as_list.png new file mode 100644 index 0000000..2b12543 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_view_as_list.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_view_as_list_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_view_as_list_light.png new file mode 100644 index 0000000..896d60b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_view_as_list_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_volume_on.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_volume_on.png new file mode 100644 index 0000000..0b0cef3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_volume_on.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_volume_on_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_volume_on_light.png new file mode 100644 index 0000000..e1a5715 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_volume_on_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_website.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_website.png new file mode 100644 index 0000000..4a3f396 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_website.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_website_light.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_website_light.png new file mode 100644 index 0000000..f376c9a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_action_website_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/ic_notification.png b/MeditationAssistant/src/main/res/drawable-mdpi/ic_notification.png new file mode 100644 index 0000000..fd9e751 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/ic_notification.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/list_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/list_focused_buddhism.9.png new file mode 100644 index 0000000..6b25f7e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/list_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/list_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/list_focused_holo.9.png new file mode 100644 index 0000000..00f05d8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/list_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/list_longpressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/list_longpressed_holo.9.png new file mode 100644 index 0000000..3bf8e03 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/list_longpressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/list_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/list_pressed_buddhism.9.png new file mode 100644 index 0000000..a58996d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/list_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/list_pressed_holo_dark.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/list_pressed_holo_dark.9.png new file mode 100644 index 0000000..6e77525 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/list_pressed_holo_dark.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/list_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/list_pressed_holo_light.9.png new file mode 100644 index 0000000..6e77525 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/list_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png new file mode 100644 index 0000000..92da2f0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/list_selector_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/list_selector_disabled_holo_light.9.png new file mode 100644 index 0000000..42cb646 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/list_selector_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/menu_dropdown_panel_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/menu_dropdown_panel_buddhism.9.png new file mode 100644 index 0000000..f57b6a2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/menu_dropdown_panel_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/np_numberpicker_selection_divider.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/np_numberpicker_selection_divider.9.png new file mode 100644 index 0000000..076fc16 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/np_numberpicker_selection_divider.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/progress_bg_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/progress_bg_buddhism.9.png new file mode 100644 index 0000000..9372a60 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/progress_bg_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/progress_primary_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/progress_primary_buddhism.9.png new file mode 100644 index 0000000..188c481 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/progress_primary_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/progress_secondary_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/progress_secondary_buddhism.9.png new file mode 100644 index 0000000..e6cb3dc Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/progress_secondary_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_default_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_default_buddhism.9.png new file mode 100644 index 0000000..9aeafee Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_default_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_disabled_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_disabled_buddhism.9.png new file mode 100644 index 0000000..88dd441 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_disabled_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_focused_buddhism.9.png new file mode 100644 index 0000000..f6c4c5c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_pressed_buddhism.9.png new file mode 100644 index 0000000..3580ff2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/spinner_ab_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/tab_selected_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/tab_selected_buddhism.9.png new file mode 100644 index 0000000..33860b8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/tab_selected_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/tab_selected_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/tab_selected_focused_buddhism.9.png new file mode 100644 index 0000000..77f20ce Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/tab_selected_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/tab_selected_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/tab_selected_pressed_buddhism.9.png new file mode 100644 index 0000000..c9c1085 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/tab_selected_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/tab_unselected_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/tab_unselected_buddhism.9.png new file mode 100644 index 0000000..89054c4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/tab_unselected_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/tab_unselected_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/tab_unselected_focused_buddhism.9.png new file mode 100644 index 0000000..7b60c00 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/tab_unselected_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-mdpi/tab_unselected_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-mdpi/tab_unselected_pressed_buddhism.9.png new file mode 100644 index 0000000..450cb8e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-mdpi/tab_unselected_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/.directory b/MeditationAssistant/src/main/res/drawable-xhdpi/.directory new file mode 100644 index 0000000..a355b42 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable-xhdpi/.directory @@ -0,0 +1,8 @@ +[Dolphin] +SortFoldersFirst=false +Timestamp=2015,5,16,1,36,6 +Version=3 +ViewMode=1 + +[Settings] +HiddenFilesShown=true diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ab_bottom_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ab_bottom_solid_buddhism.9.png new file mode 100644 index 0000000..232e2e4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ab_bottom_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ab_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ab_solid_buddhism.9.png new file mode 100644 index 0000000..1354ef5 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ab_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ab_stacked_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ab_stacked_solid_buddhism.9.png new file mode 100644 index 0000000..e9a6e32 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ab_stacked_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ab_texture_tile_buddhism.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ab_texture_tile_buddhism.png new file mode 100644 index 0000000..4544d4e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ab_texture_tile_buddhism.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ab_transparent_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ab_transparent_buddhism.9.png new file mode 100644 index 0000000..b6b2b54 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ab_transparent_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/btn_cab_done_default_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/btn_cab_done_default_buddhism.9.png new file mode 100644 index 0000000..3521ae3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/btn_cab_done_default_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/btn_cab_done_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/btn_cab_done_focused_buddhism.9.png new file mode 100644 index 0000000..75d8af7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/btn_cab_done_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/btn_cab_done_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/btn_cab_done_pressed_buddhism.9.png new file mode 100644 index 0000000..772bde1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/btn_cab_done_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_disabled_focused_holo_light.png new file mode 100644 index 0000000..62a6875 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_disabled_holo_light.png new file mode 100644 index 0000000..6a364bb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_focused_holo_light.png new file mode 100644 index 0000000..9714021 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_holo_light.png new file mode 100644 index 0000000..a1c2005 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_pressed_holo_light.png new file mode 100644 index 0000000..7ae2fad Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_off_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_disabled_focused_holo_light.png new file mode 100644 index 0000000..ae7c5aa Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_disabled_holo_light.png new file mode 100644 index 0000000..d705b42 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_focused_holo_light.png new file mode 100644 index 0000000..3522f60 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_holo_light.png new file mode 100644 index 0000000..bb0d21c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_pressed_holo_light.png new file mode 100644 index 0000000..db233e7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_check_on_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..ba4f89a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_disabled_holo_light.9.png new file mode 100644 index 0000000..b410d23 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_focused_holo_light.9.png new file mode 100644 index 0000000..fabe3af Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_normal_holo_light.9.png new file mode 100644 index 0000000..24b60a5 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_pressed_holo_light.9.png new file mode 100644 index 0000000..01eb12e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_default_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png new file mode 100644 index 0000000..8fb78ad Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_disabled_holo_light.png new file mode 100644 index 0000000..1030a80 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_focused_holo_light.png new file mode 100644 index 0000000..4e5d031 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_holo_light.png new file mode 100644 index 0000000..08b65d2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_pressed_holo_light.png new file mode 100644 index 0000000..0bbf8a3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_off_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png new file mode 100644 index 0000000..bb0cc66 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_disabled_holo_light.png new file mode 100644 index 0000000..5741490 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_focused_holo_light.png new file mode 100644 index 0000000..948b3c4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_holo_light.png new file mode 100644 index 0000000..253a1f1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_pressed_holo_light.png new file mode 100644 index 0000000..c6a6d83 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_radio_on_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..17a156c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png new file mode 100644 index 0000000..61230cb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_focused_holo_light.9.png new file mode 100644 index 0000000..f777596 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_normal_holo_light.9.png new file mode 100644 index 0000000..54e5e8e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png new file mode 100644 index 0000000..a096c03 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..d15a33c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png new file mode 100644 index 0000000..e006747 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_focused_holo_light.9.png new file mode 100644 index 0000000..0015e84 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_normal_holo_light.9.png new file mode 100644 index 0000000..d1d527a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png new file mode 100644 index 0000000..7490663 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_fastscroll_thumb_default_holo.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_fastscroll_thumb_default_holo.png new file mode 100644 index 0000000..19de8e6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_fastscroll_thumb_default_holo.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_fastscroll_thumb_pressed_holo.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_fastscroll_thumb_pressed_holo.png new file mode 100644 index 0000000..7d4482f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_fastscroll_thumb_pressed_holo.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_ic_navigation_drawer.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_ic_navigation_drawer.png new file mode 100644 index 0000000..d819f21 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_ic_navigation_drawer.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_activated_holo.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_activated_holo.9.png new file mode 100644 index 0000000..ce6b13a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_activated_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_focused_holo.9.png new file mode 100644 index 0000000..ccc1d58 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_longpressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_longpressed_holo.9.png new file mode 100644 index 0000000..22ab079 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_longpressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_pressed_holo_light.9.png new file mode 100644 index 0000000..5411638 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_selector_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_selector_disabled_holo_light.9.png new file mode 100644 index 0000000..c6a7d4d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_list_selector_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progress_bg_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progress_bg_holo_light.9.png new file mode 100644 index 0000000..cbd19ac Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progress_bg_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progress_primary_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progress_primary_holo_light.9.png new file mode 100644 index 0000000..106b431 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progress_primary_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progress_secondary_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progress_secondary_holo_light.9.png new file mode 100644 index 0000000..5e147f8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progress_secondary_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo1.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo1.png new file mode 100644 index 0000000..ff4633d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo1.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo2.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo2.png new file mode 100644 index 0000000..9642033 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo2.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo3.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo3.png new file mode 100644 index 0000000..c866d18 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo3.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo4.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo4.png new file mode 100644 index 0000000..345aa0e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo4.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo5.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo5.png new file mode 100644 index 0000000..6137db3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo5.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo6.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo6.png new file mode 100644 index 0000000..106f903 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo6.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo7.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo7.png new file mode 100644 index 0000000..60ffa31 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo7.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo8.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo8.png new file mode 100644 index 0000000..683beef Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_progressbar_indeterminate_holo8.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_default_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_default_holo_light.9.png new file mode 100644 index 0000000..b412c4d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_default_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_disabled_holo_light.9.png new file mode 100644 index 0000000..fe54126 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_focused_holo_light.9.png new file mode 100644 index 0000000..d5863eb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_pressed_holo_light.9.png new file mode 100644 index 0000000..c4407ac Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_spinner_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_selected_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_selected_focused_holo.9.png new file mode 100644 index 0000000..0ca4a87 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_selected_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_selected_holo.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_selected_holo.9.png new file mode 100644 index 0000000..bd12e8c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_selected_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_selected_pressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_selected_pressed_holo.9.png new file mode 100644 index 0000000..4b40f3d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_selected_pressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_unselected_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_unselected_focused_holo.9.png new file mode 100644 index 0000000..357bc90 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_unselected_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_unselected_holo.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_unselected_holo.9.png new file mode 100644 index 0000000..ae15ee2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_unselected_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_unselected_pressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_unselected_pressed_holo.9.png new file mode 100644 index 0000000..17d781a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_tab_unselected_pressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_text_select_handle_left.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_text_select_handle_left.png new file mode 100644 index 0000000..2c6011a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_text_select_handle_left.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_text_select_handle_middle.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_text_select_handle_middle.png new file mode 100644 index 0000000..ba5eee5 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_text_select_handle_middle.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_text_select_handle_right.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_text_select_handle_right.png new file mode 100644 index 0000000..31548cc Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_text_select_handle_right.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_activated_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_activated_holo_light.9.png new file mode 100644 index 0000000..1126acf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_activated_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_default_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_default_holo_light.9.png new file mode 100644 index 0000000..f0ad55a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_default_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..40a28cf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_disabled_holo_light.9.png new file mode 100644 index 0000000..4ffdd86 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_focused_holo_light.9.png new file mode 100644 index 0000000..5c7ec8a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/buddhism_textfield_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/cab_background_bottom_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/cab_background_bottom_buddhism.9.png new file mode 100644 index 0000000..50feb0a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/cab_background_bottom_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/cab_background_top_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/cab_background_top_buddhism.9.png new file mode 100644 index 0000000..c8d2933 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/cab_background_top_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_accounts.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_accounts.png new file mode 100644 index 0000000..efaf7fb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_accounts.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_accounts_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_accounts_light.png new file mode 100644 index 0000000..374df3c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_accounts_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_brightness_low.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_brightness_low.png new file mode 100644 index 0000000..7549d6c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_brightness_low.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_brightness_low_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_brightness_low_light.png new file mode 100644 index 0000000..180501d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_brightness_low_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_chat.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_chat.png new file mode 100644 index 0000000..57f8455 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_chat.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_chat_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_chat_light.png new file mode 100644 index 0000000..d8814bf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_chat_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_downcloud.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_downcloud.png new file mode 100644 index 0000000..1fa495a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_downcloud.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_downcloud_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_downcloud_light.png new file mode 100644 index 0000000..d17ef02 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_downcloud_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_flash_on.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_flash_on.png new file mode 100644 index 0000000..a8482a1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_flash_on.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_flash_on_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_flash_on_light.png new file mode 100644 index 0000000..a394d7f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_flash_on_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_forward.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_forward.png new file mode 100644 index 0000000..1865023 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_forward.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_forward_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_forward_light.png new file mode 100644 index 0000000..e3b2d92 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_forward_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_full_screen.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_full_screen.png new file mode 100644 index 0000000..5e48ef2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_full_screen.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_full_screen_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_full_screen_light.png new file mode 100644 index 0000000..7653097 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_full_screen_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_go_to_today.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_go_to_today.png new file mode 100644 index 0000000..286e592 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_go_to_today.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_go_to_today_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_go_to_today_light.png new file mode 100644 index 0000000..3304935 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_go_to_today_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_group.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_group.png new file mode 100644 index 0000000..b5eade0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_group.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_group_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_group_light.png new file mode 100644 index 0000000..2f1c7b1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_group_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_info.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_info.png new file mode 100644 index 0000000..4536a8d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_info.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_info_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_info_light.png new file mode 100644 index 0000000..9f1c2a0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_info_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_network_cell.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_network_cell.png new file mode 100644 index 0000000..97d603e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_network_cell.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_network_cell_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_network_cell_light.png new file mode 100644 index 0000000..b39a95e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_network_cell_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_new.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_new.png new file mode 100644 index 0000000..a6a3b48 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_new.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_new_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_new_light.png new file mode 100644 index 0000000..e8a2f34 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_new_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_next_item.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_next_item.png new file mode 100644 index 0000000..f07f2dd Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_next_item.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_next_item_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_next_item_light.png new file mode 100644 index 0000000..c535b5f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_next_item_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_not_important.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_not_important.png new file mode 100644 index 0000000..b824c02 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_not_important.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_not_important_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_not_important_light.png new file mode 100644 index 0000000..137f7e9 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_not_important_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_pause.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_pause.png new file mode 100644 index 0000000..aafdd4a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_pause.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_person.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_person.png new file mode 100644 index 0000000..87b8c66 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_person.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_person_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_person_light.png new file mode 100644 index 0000000..3178bff Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_person_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_previous_item.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_previous_item.png new file mode 100644 index 0000000..e53c4ed Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_previous_item.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_previous_item_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_previous_item_light.png new file mode 100644 index 0000000..eb9e46e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_previous_item_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_refresh.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_refresh.png new file mode 100644 index 0000000..21701fb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_refresh.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_refresh_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_refresh_light.png new file mode 100644 index 0000000..d62213b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_refresh_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_ring_volume.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_ring_volume.png new file mode 100644 index 0000000..3e0ba02 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_ring_volume.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_ring_volume_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_ring_volume_light.png new file mode 100644 index 0000000..7cb4b68 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_ring_volume_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_settings.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_settings.png new file mode 100644 index 0000000..425a8bc Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_settings.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_settings_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_settings_light.png new file mode 100644 index 0000000..999d0f0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_settings_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_share.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_share.png new file mode 100644 index 0000000..e90b02d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_share.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_share_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_share_light.png new file mode 100644 index 0000000..e82a4a4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_share_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sign_out.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sign_out.png new file mode 100644 index 0000000..f640921 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sign_out.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sign_out_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sign_out_light.png new file mode 100644 index 0000000..58bc912 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sign_out_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sort_by_size.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sort_by_size.png new file mode 100644 index 0000000..958c042 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sort_by_size.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sort_by_size_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sort_by_size_light.png new file mode 100644 index 0000000..743a6a6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_sort_by_size_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_stop.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_stop.png new file mode 100644 index 0000000..c14cfe2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_stop.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_time.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_time.png new file mode 100644 index 0000000..2198221 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_time.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_time_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_time_light.png new file mode 100644 index 0000000..2e7d163 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_time_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_upcloud.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_upcloud.png new file mode 100644 index 0000000..501870f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_upcloud.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_upcloud_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_upcloud_light.png new file mode 100644 index 0000000..7faef01 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_upcloud_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_view_as_list.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_view_as_list.png new file mode 100644 index 0000000..7daa963 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_view_as_list.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_view_as_list_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_view_as_list_light.png new file mode 100644 index 0000000..0323b78 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_view_as_list_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_volume_on.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_volume_on.png new file mode 100644 index 0000000..8e38fbf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_volume_on.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_volume_on_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_volume_on_light.png new file mode 100644 index 0000000..5c4ec6a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_volume_on_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_website.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_website.png new file mode 100644 index 0000000..56e43eb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_website.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_website_light.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_website_light.png new file mode 100644 index 0000000..da86d86 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_action_website_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/ic_notification.png b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_notification.png new file mode 100644 index 0000000..7b59ad0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/ic_notification.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/list_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/list_focused_buddhism.9.png new file mode 100644 index 0000000..f6a1845 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/list_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/list_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/list_focused_holo.9.png new file mode 100644 index 0000000..b545f8e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/list_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/list_longpressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/list_longpressed_holo.9.png new file mode 100644 index 0000000..eda10e6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/list_longpressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/list_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/list_pressed_buddhism.9.png new file mode 100644 index 0000000..4f6f689 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/list_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/list_pressed_holo_dark.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/list_pressed_holo_dark.9.png new file mode 100644 index 0000000..e4b3393 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/list_pressed_holo_dark.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/list_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/list_pressed_holo_light.9.png new file mode 100644 index 0000000..e4b3393 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/list_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/list_selector_disabled_holo_dark.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/list_selector_disabled_holo_dark.9.png new file mode 100644 index 0000000..88726b6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/list_selector_disabled_holo_dark.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/list_selector_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/list_selector_disabled_holo_light.9.png new file mode 100644 index 0000000..c6a7d4d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/list_selector_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/menu_dropdown_panel_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/menu_dropdown_panel_buddhism.9.png new file mode 100644 index 0000000..c073309 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/menu_dropdown_panel_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/np_numberpicker_selection_divider.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/np_numberpicker_selection_divider.9.png new file mode 100644 index 0000000..97eb5fe Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/np_numberpicker_selection_divider.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/progress_bg_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/progress_bg_buddhism.9.png new file mode 100644 index 0000000..8b4853a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/progress_bg_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/progress_primary_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/progress_primary_buddhism.9.png new file mode 100644 index 0000000..f4a8b24 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/progress_primary_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/progress_secondary_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/progress_secondary_buddhism.9.png new file mode 100644 index 0000000..5b96c77 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/progress_secondary_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_default_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_default_buddhism.9.png new file mode 100644 index 0000000..14b1401 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_default_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_disabled_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_disabled_buddhism.9.png new file mode 100644 index 0000000..c9dfbd6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_disabled_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_focused_buddhism.9.png new file mode 100644 index 0000000..6647026 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_pressed_buddhism.9.png new file mode 100644 index 0000000..cfc8b5e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/spinner_ab_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/tab_selected_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_selected_buddhism.9.png new file mode 100644 index 0000000..da54c88 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_selected_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/tab_selected_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_selected_focused_buddhism.9.png new file mode 100644 index 0000000..3f544a3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_selected_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/tab_selected_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_selected_pressed_buddhism.9.png new file mode 100644 index 0000000..2545458 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_selected_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/tab_unselected_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_unselected_buddhism.9.png new file mode 100644 index 0000000..4f51e6d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_unselected_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/tab_unselected_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_unselected_focused_buddhism.9.png new file mode 100644 index 0000000..d3adcf1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_unselected_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xhdpi/tab_unselected_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_unselected_pressed_buddhism.9.png new file mode 100644 index 0000000..2312ef2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xhdpi/tab_unselected_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_bottom_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_bottom_solid_buddhism.9.png new file mode 100644 index 0000000..84addfd Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_bottom_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_solid_buddhism.9.png new file mode 100644 index 0000000..56d75f8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_stacked_solid_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_stacked_solid_buddhism.9.png new file mode 100644 index 0000000..46d6772 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_stacked_solid_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_texture_tile_buddhism.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_texture_tile_buddhism.png new file mode 100644 index 0000000..d2b4a8d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_texture_tile_buddhism.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_transparent_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_transparent_buddhism.9.png new file mode 100644 index 0000000..f2a2cf9 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ab_transparent_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/btn_cab_done_default_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/btn_cab_done_default_buddhism.9.png new file mode 100644 index 0000000..0c0079c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/btn_cab_done_default_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/btn_cab_done_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/btn_cab_done_focused_buddhism.9.png new file mode 100644 index 0000000..d456829 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/btn_cab_done_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/btn_cab_done_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/btn_cab_done_pressed_buddhism.9.png new file mode 100644 index 0000000..2ef2a7b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/btn_cab_done_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_disabled_focused_holo_light.png new file mode 100644 index 0000000..49d9b45 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_disabled_holo_light.png new file mode 100644 index 0000000..47a6373 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_focused_holo_light.png new file mode 100644 index 0000000..21a1a04 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_holo_light.png new file mode 100644 index 0000000..441cd86 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_pressed_holo_light.png new file mode 100644 index 0000000..773206f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_off_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_disabled_focused_holo_light.png new file mode 100644 index 0000000..ae5a8fe Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_disabled_holo_light.png new file mode 100644 index 0000000..013c1f6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_focused_holo_light.png new file mode 100644 index 0000000..5db998b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_holo_light.png new file mode 100644 index 0000000..d75b02d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_pressed_holo_light.png new file mode 100644 index 0000000..4b0e395 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_check_on_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..563f69e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_disabled_holo_light.9.png new file mode 100644 index 0000000..b4c90d4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_focused_holo_light.9.png new file mode 100644 index 0000000..82db86e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_normal_holo_light.9.png new file mode 100644 index 0000000..4580857 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_pressed_holo_light.9.png new file mode 100644 index 0000000..53c5df3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_default_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png new file mode 100644 index 0000000..4941372 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_disabled_holo_light.png new file mode 100644 index 0000000..06f0cc7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_focused_holo_light.png new file mode 100644 index 0000000..3ce240a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_holo_light.png new file mode 100644 index 0000000..6112308 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_pressed_holo_light.png new file mode 100644 index 0000000..9fe2ebf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_off_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png new file mode 100644 index 0000000..b8ebf85 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_disabled_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_disabled_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_disabled_holo_light.png new file mode 100644 index 0000000..adb7304 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_disabled_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_focused_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_focused_holo_light.png new file mode 100644 index 0000000..5897fe8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_focused_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_holo_light.png new file mode 100644 index 0000000..afb93f5 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_pressed_holo_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_pressed_holo_light.png new file mode 100644 index 0000000..58108fc Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_radio_on_pressed_holo_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..3d0a4fe Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png new file mode 100644 index 0000000..9b3900a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_focused_holo_light.9.png new file mode 100644 index 0000000..885d3eb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_normal_holo_light.9.png new file mode 100644 index 0000000..d3ef0e1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png new file mode 100644 index 0000000..c9edf5c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_off_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..b5ca4bb Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png new file mode 100644 index 0000000..1920f35 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_focused_holo_light.9.png new file mode 100644 index 0000000..4336960 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_normal_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_normal_holo_light.9.png new file mode 100644 index 0000000..97d81aa Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_normal_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png new file mode 100644 index 0000000..f907579 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_btn_toggle_on_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_fastscroll_thumb_default_holo.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_fastscroll_thumb_default_holo.png new file mode 100644 index 0000000..cf2d470 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_fastscroll_thumb_default_holo.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_fastscroll_thumb_pressed_holo.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_fastscroll_thumb_pressed_holo.png new file mode 100644 index 0000000..44b2cc8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_fastscroll_thumb_pressed_holo.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_ic_navigation_drawer.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_ic_navigation_drawer.png new file mode 100644 index 0000000..5e94a4e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_ic_navigation_drawer.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_activated_holo.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_activated_holo.9.png new file mode 100644 index 0000000..7a02760 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_activated_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_focused_holo.9.png new file mode 100644 index 0000000..52ed8a3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_longpressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_longpressed_holo.9.png new file mode 100644 index 0000000..82036b6 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_longpressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_pressed_holo_light.9.png new file mode 100644 index 0000000..c7b06aa Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_selector_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_selector_disabled_holo_light.9.png new file mode 100644 index 0000000..70bc9f2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_list_selector_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progress_bg_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progress_bg_holo_light.9.png new file mode 100644 index 0000000..fb146c3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progress_bg_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progress_primary_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progress_primary_holo_light.9.png new file mode 100644 index 0000000..a5b5585 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progress_primary_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progress_secondary_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progress_secondary_holo_light.9.png new file mode 100644 index 0000000..d759767 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progress_secondary_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo1.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo1.png new file mode 100644 index 0000000..08ac79d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo1.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo2.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo2.png new file mode 100644 index 0000000..1aba36c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo2.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo3.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo3.png new file mode 100644 index 0000000..cebcc34 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo3.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo4.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo4.png new file mode 100644 index 0000000..40b51a1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo4.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo5.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo5.png new file mode 100644 index 0000000..2c754ab Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo5.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo6.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo6.png new file mode 100644 index 0000000..c8d0f40 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo6.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo7.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo7.png new file mode 100644 index 0000000..5217cf7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo7.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo8.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo8.png new file mode 100644 index 0000000..7073b8c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_progressbar_indeterminate_holo8.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_default_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_default_holo_light.9.png new file mode 100644 index 0000000..a5fc9b5 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_default_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_disabled_holo_light.9.png new file mode 100644 index 0000000..4cef095 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_focused_holo_light.9.png new file mode 100644 index 0000000..9751d28 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_pressed_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_pressed_holo_light.9.png new file mode 100644 index 0000000..fd462d7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_spinner_pressed_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_selected_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_selected_focused_holo.9.png new file mode 100644 index 0000000..d782020 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_selected_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_selected_holo.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_selected_holo.9.png new file mode 100644 index 0000000..ecd7cc8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_selected_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_selected_pressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_selected_pressed_holo.9.png new file mode 100644 index 0000000..5094b45 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_selected_pressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_unselected_focused_holo.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_unselected_focused_holo.9.png new file mode 100644 index 0000000..f0772a7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_unselected_focused_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_unselected_holo.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_unselected_holo.9.png new file mode 100644 index 0000000..90abc2a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_unselected_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_unselected_pressed_holo.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_unselected_pressed_holo.9.png new file mode 100644 index 0000000..bb9d262 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_tab_unselected_pressed_holo.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_text_select_handle_left.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_text_select_handle_left.png new file mode 100644 index 0000000..390449c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_text_select_handle_left.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_text_select_handle_middle.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_text_select_handle_middle.png new file mode 100644 index 0000000..82369bc Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_text_select_handle_middle.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_text_select_handle_right.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_text_select_handle_right.png new file mode 100644 index 0000000..9678c1e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_text_select_handle_right.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_activated_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_activated_holo_light.9.png new file mode 100644 index 0000000..947417c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_activated_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_default_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_default_holo_light.9.png new file mode 100644 index 0000000..6db1dd0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_default_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_disabled_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_disabled_focused_holo_light.9.png new file mode 100644 index 0000000..d157d7d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_disabled_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_disabled_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_disabled_holo_light.9.png new file mode 100644 index 0000000..c91f7da Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_disabled_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_focused_holo_light.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_focused_holo_light.9.png new file mode 100644 index 0000000..d02b3d7 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/buddhism_textfield_focused_holo_light.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/cab_background_bottom_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/cab_background_bottom_buddhism.9.png new file mode 100644 index 0000000..4dbdc82 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/cab_background_bottom_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/cab_background_top_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/cab_background_top_buddhism.9.png new file mode 100644 index 0000000..e32b3e5 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/cab_background_top_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_brightness_low.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_brightness_low.png new file mode 100644 index 0000000..8f7a916 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_brightness_low.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_brightness_low_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_brightness_low_light.png new file mode 100644 index 0000000..e138b25 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_brightness_low_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_flash_on.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_flash_on.png new file mode 100644 index 0000000..3d75e9e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_flash_on.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_flash_on_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_flash_on_light.png new file mode 100644 index 0000000..cec1145 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_flash_on_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_full_screen.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_full_screen.png new file mode 100644 index 0000000..e8dff1e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_full_screen.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_full_screen_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_full_screen_light.png new file mode 100644 index 0000000..6337e24 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_full_screen_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_info.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_info.png new file mode 100644 index 0000000..a7bdf34 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_info.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_info_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_info_light.png new file mode 100644 index 0000000..0fe809b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_info_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_new.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_new.png new file mode 100644 index 0000000..c42c2bf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_new.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_new_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_new_light.png new file mode 100644 index 0000000..c0cd3d9 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_new_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_not_important.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_not_important.png new file mode 100644 index 0000000..436b0ca Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_not_important.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_not_important_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_not_important_light.png new file mode 100644 index 0000000..4e62bde Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_not_important_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_person.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_person.png new file mode 100644 index 0000000..0b9ea00 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_person.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_person_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_person_light.png new file mode 100644 index 0000000..fd1bcdd Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_person_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_refresh.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_refresh.png new file mode 100644 index 0000000..44ee117 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_refresh.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_refresh_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_refresh_light.png new file mode 100644 index 0000000..cb847f3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_refresh_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_ring_volume.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_ring_volume.png new file mode 100644 index 0000000..9960695 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_ring_volume.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_ring_volume_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_ring_volume_light.png new file mode 100644 index 0000000..b1a88b3 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_ring_volume_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_settings.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_settings.png new file mode 100644 index 0000000..fe5fec4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_settings.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_settings_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_settings_light.png new file mode 100644 index 0000000..530227e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_settings_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_share.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_share.png new file mode 100644 index 0000000..22ed428 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_share.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_share_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_share_light.png new file mode 100644 index 0000000..3e44100 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_share_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_sort_by_size.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_sort_by_size.png new file mode 100644 index 0000000..25fe91d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_sort_by_size.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_sort_by_size_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_sort_by_size_light.png new file mode 100644 index 0000000..d4bb95e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_sort_by_size_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_stop.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_stop.png new file mode 100644 index 0000000..c86dbb1 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_stop.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_time.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_time.png new file mode 100644 index 0000000..a06752c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_time.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_time_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_time_light.png new file mode 100644 index 0000000..66a149e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_time_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_volume_on.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_volume_on.png new file mode 100644 index 0000000..87f2bc8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_volume_on.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_volume_on_light.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_volume_on_light.png new file mode 100644 index 0000000..cd66857 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_action_volume_on_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_notification.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_notification.png new file mode 100644 index 0000000..54b9582 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/ic_notification.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/list_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/list_focused_buddhism.9.png new file mode 100644 index 0000000..48ec873 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/list_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/list_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/list_pressed_buddhism.9.png new file mode 100644 index 0000000..3af5169 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/list_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/menu_dropdown_panel_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/menu_dropdown_panel_buddhism.9.png new file mode 100644 index 0000000..12227be Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/menu_dropdown_panel_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/progress_bg_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/progress_bg_buddhism.9.png new file mode 100644 index 0000000..7c221af Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/progress_bg_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/progress_primary_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/progress_primary_buddhism.9.png new file mode 100644 index 0000000..bbb90e0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/progress_primary_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/progress_secondary_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/progress_secondary_buddhism.9.png new file mode 100644 index 0000000..bba175c Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/progress_secondary_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_default_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_default_buddhism.9.png new file mode 100644 index 0000000..f178f19 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_default_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_disabled_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_disabled_buddhism.9.png new file mode 100644 index 0000000..9ec5a1e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_disabled_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_focused_buddhism.9.png new file mode 100644 index 0000000..dd2f60d Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_pressed_buddhism.9.png new file mode 100644 index 0000000..5770c06 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/spinner_ab_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_selected_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_selected_buddhism.9.png new file mode 100644 index 0000000..f4e0d31 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_selected_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_selected_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_selected_focused_buddhism.9.png new file mode 100644 index 0000000..f12803f Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_selected_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_selected_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_selected_pressed_buddhism.9.png new file mode 100644 index 0000000..d006ba0 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_selected_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_unselected_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_unselected_buddhism.9.png new file mode 100644 index 0000000..5abeb53 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_unselected_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_unselected_focused_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_unselected_focused_buddhism.9.png new file mode 100644 index 0000000..b5ba438 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_unselected_focused_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_unselected_pressed_buddhism.9.png b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_unselected_pressed_buddhism.9.png new file mode 100644 index 0000000..6bf3408 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxhdpi/tab_unselected_pressed_buddhism.9.png differ diff --git a/MeditationAssistant/src/main/res/drawable-xxxhdpi/ic_notification.png b/MeditationAssistant/src/main/res/drawable-xxxhdpi/ic_notification.png new file mode 100644 index 0000000..5a29ac8 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable-xxxhdpi/ic_notification.png differ diff --git a/MeditationAssistant/src/main/res/drawable/ab_background_textured_buddhism.xml b/MeditationAssistant/src/main/res/drawable/ab_background_textured_buddhism.xml new file mode 100644 index 0000000..c0d90c7 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/ab_background_textured_buddhism.xml @@ -0,0 +1,21 @@ + + + + \ No newline at end of file diff --git a/MeditationAssistant/src/main/res/drawable/btn_cab_done_buddhism.xml b/MeditationAssistant/src/main/res/drawable/btn_cab_done_buddhism.xml new file mode 100644 index 0000000..51fd813 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/btn_cab_done_buddhism.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_activated_background_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_activated_background_holo_light.xml new file mode 100644 index 0000000..2cc51d6 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_activated_background_holo_light.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_btn_check_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_btn_check_holo_light.xml new file mode 100644 index 0000000..8261f56 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_btn_check_holo_light.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_btn_default_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_btn_default_holo_light.xml new file mode 100644 index 0000000..1a55cfc --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_btn_default_holo_light.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_btn_radio_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_btn_radio_holo_light.xml new file mode 100644 index 0000000..185f17b --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_btn_radio_holo_light.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_btn_toggle_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_btn_toggle_holo_light.xml new file mode 100644 index 0000000..88a1e2d --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_btn_toggle_holo_light.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_edit_text_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_edit_text_holo_light.xml new file mode 100644 index 0000000..d5dd889 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_edit_text_holo_light.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_fastscroll_thumb_holo.xml b/MeditationAssistant/src/main/res/drawable/buddhism_fastscroll_thumb_holo.xml new file mode 100644 index 0000000..6baef9f --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_fastscroll_thumb_holo.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_item_background_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_item_background_holo_light.xml new file mode 100644 index 0000000..4082de8 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_item_background_holo_light.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_list_selector_background_transition_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_list_selector_background_transition_holo_light.xml new file mode 100644 index 0000000..55dbcae --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_list_selector_background_transition_holo_light.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_list_selector_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_list_selector_holo_light.xml new file mode 100644 index 0000000..09b3895 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_list_selector_holo_light.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_progress_horizontal_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_progress_horizontal_holo_light.xml new file mode 100644 index 0000000..a465f07 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_progress_horizontal_holo_light.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_progress_indeterminate_horizontal_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_progress_indeterminate_horizontal_holo_light.xml new file mode 100644 index 0000000..89532c3 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_progress_indeterminate_horizontal_holo_light.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_spinner_background_holo_light.xml b/MeditationAssistant/src/main/res/drawable/buddhism_spinner_background_holo_light.xml new file mode 100644 index 0000000..27e849b --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_spinner_background_holo_light.xml @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/buddhism_tab_indicator_holo.xml b/MeditationAssistant/src/main/res/drawable/buddhism_tab_indicator_holo.xml new file mode 100644 index 0000000..d566536 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/buddhism_tab_indicator_holo.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/charis.png b/MeditationAssistant/src/main/res/drawable/charis.png new file mode 100644 index 0000000..589d5d4 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/charis.png differ diff --git a/MeditationAssistant/src/main/res/drawable/item_background_holo_dark.xml b/MeditationAssistant/src/main/res/drawable/item_background_holo_dark.xml new file mode 100644 index 0000000..7c8590c --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/item_background_holo_dark.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/item_background_holo_light.xml b/MeditationAssistant/src/main/res/drawable/item_background_holo_light.xml new file mode 100644 index 0000000..99b5ac2 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/item_background_holo_light.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/list_selector_background_transition_holo_dark.xml b/MeditationAssistant/src/main/res/drawable/list_selector_background_transition_holo_dark.xml new file mode 100644 index 0000000..a225729 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/list_selector_background_transition_holo_dark.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/list_selector_background_transition_holo_light.xml b/MeditationAssistant/src/main/res/drawable/list_selector_background_transition_holo_light.xml new file mode 100644 index 0000000..0ac8398 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/list_selector_background_transition_holo_light.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/logo_aol.png b/MeditationAssistant/src/main/res/drawable/logo_aol.png new file mode 100644 index 0000000..e85720b Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_aol.png differ diff --git a/MeditationAssistant/src/main/res/drawable/logo_aol_light.png b/MeditationAssistant/src/main/res/drawable/logo_aol_light.png new file mode 100644 index 0000000..5e386c2 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_aol_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable/logo_facebook.png b/MeditationAssistant/src/main/res/drawable/logo_facebook.png new file mode 100644 index 0000000..4829121 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_facebook.png differ diff --git a/MeditationAssistant/src/main/res/drawable/logo_facebook_light.png b/MeditationAssistant/src/main/res/drawable/logo_facebook_light.png new file mode 100644 index 0000000..51dbb75 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_facebook_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable/logo_google.png b/MeditationAssistant/src/main/res/drawable/logo_google.png new file mode 100644 index 0000000..3083b58 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_google.png differ diff --git a/MeditationAssistant/src/main/res/drawable/logo_google_light.png b/MeditationAssistant/src/main/res/drawable/logo_google_light.png new file mode 100644 index 0000000..1ddbd5a Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_google_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable/logo_live.png b/MeditationAssistant/src/main/res/drawable/logo_live.png new file mode 100644 index 0000000..19510ea Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_live.png differ diff --git a/MeditationAssistant/src/main/res/drawable/logo_live_light.png b/MeditationAssistant/src/main/res/drawable/logo_live_light.png new file mode 100644 index 0000000..438edbe Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_live_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable/logo_openid.png b/MeditationAssistant/src/main/res/drawable/logo_openid.png new file mode 100644 index 0000000..d4e970e Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_openid.png differ diff --git a/MeditationAssistant/src/main/res/drawable/logo_openid_light.png b/MeditationAssistant/src/main/res/drawable/logo_openid_light.png new file mode 100644 index 0000000..0136379 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_openid_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable/logo_twitter.png b/MeditationAssistant/src/main/res/drawable/logo_twitter.png new file mode 100644 index 0000000..a8bfb81 Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_twitter.png differ diff --git a/MeditationAssistant/src/main/res/drawable/logo_twitter_light.png b/MeditationAssistant/src/main/res/drawable/logo_twitter_light.png new file mode 100644 index 0000000..0f9dfaf Binary files /dev/null and b/MeditationAssistant/src/main/res/drawable/logo_twitter_light.png differ diff --git a/MeditationAssistant/src/main/res/drawable/progress_horizontal_buddhism.xml b/MeditationAssistant/src/main/res/drawable/progress_horizontal_buddhism.xml new file mode 100644 index 0000000..a9b3a1b --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/progress_horizontal_buddhism.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/selectable_background_buddhism.xml b/MeditationAssistant/src/main/res/drawable/selectable_background_buddhism.xml new file mode 100644 index 0000000..4d60d6d --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/selectable_background_buddhism.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/MeditationAssistant/src/main/res/drawable/spinner_background_ab_buddhism.xml b/MeditationAssistant/src/main/res/drawable/spinner_background_ab_buddhism.xml new file mode 100644 index 0000000..5b8cd1a --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/spinner_background_ab_buddhism.xml @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/drawable/tab_indicator_ab_buddhism.xml b/MeditationAssistant/src/main/res/drawable/tab_indicator_ab_buddhism.xml new file mode 100644 index 0000000..afbbb71 --- /dev/null +++ b/MeditationAssistant/src/main/res/drawable/tab_indicator_ab_buddhism.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/MeditationAssistant/src/main/res/layout/activity_about.xml b/MeditationAssistant/src/main/res/layout/activity_about.xml new file mode 100644 index 0000000..58c1e45 --- /dev/null +++ b/MeditationAssistant/src/main/res/layout/activity_about.xml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +