mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Refactor MainActivity and Preferences
This commit is contained in:
@@ -23,6 +23,7 @@ import android.os.Build;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import org.isoron.uhabits.BaseTest;
|
||||
import org.isoron.uhabits.HabitsApplication;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -34,7 +35,7 @@ import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class HabitsApplicationTest
|
||||
public class HabitsApplicationTest extends BaseTest
|
||||
{
|
||||
@Test
|
||||
public void test_getLogcat() throws IOException
|
||||
@@ -45,7 +46,10 @@ public class HabitsApplicationTest
|
||||
String msg = "LOGCAT TEST";
|
||||
new RuntimeException(msg).printStackTrace();
|
||||
|
||||
String log = HabitsApplication.getLogcat();
|
||||
HabitsApplication app = HabitsApplication.getInstance();
|
||||
assert(app != null);
|
||||
|
||||
String log = app.getLogcat();
|
||||
assertThat(log, containsString(msg));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ package org.isoron.uhabits.unit.tasks;
|
||||
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import org.isoron.uhabits.BaseTest;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
@@ -55,9 +54,8 @@ public class ExportCSVTaskTest extends BaseTest
|
||||
{
|
||||
HabitFixtures.createShortHabit();
|
||||
List<Habit> habits = Habit.getAll(true);
|
||||
ProgressBar bar = new ProgressBar(targetContext);
|
||||
|
||||
ExportCSVTask task = new ExportCSVTask(habits, bar);
|
||||
ExportCSVTask task = new ExportCSVTask(habits, null);
|
||||
task.setListener(new ExportCSVTask.Listener()
|
||||
{
|
||||
@Override
|
||||
|
||||
@@ -19,11 +19,8 @@
|
||||
|
||||
package org.isoron.uhabits.unit.tasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import org.isoron.uhabits.BaseTest;
|
||||
import org.isoron.uhabits.tasks.ExportDBTask;
|
||||
@@ -52,10 +49,7 @@ public class ExportDBTaskTest extends BaseTest
|
||||
@Test
|
||||
public void testExportCSV() throws Throwable
|
||||
{
|
||||
Context context = InstrumentationRegistry.getContext();
|
||||
|
||||
ProgressBar bar = new ProgressBar(context);
|
||||
ExportDBTask task = new ExportDBTask(bar);
|
||||
ExportDBTask task = new ExportDBTask(null);
|
||||
task.setListener(new ExportDBTask.Listener()
|
||||
{
|
||||
@Override
|
||||
|
||||
@@ -22,11 +22,10 @@ package org.isoron.uhabits.unit.tasks;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import org.isoron.uhabits.BaseTest;
|
||||
import org.isoron.uhabits.utils.FileUtils;
|
||||
import org.isoron.uhabits.tasks.ImportDataTask;
|
||||
import org.isoron.uhabits.utils.FileUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -67,7 +66,7 @@ public class ImportDataTaskTest extends BaseTest
|
||||
task.setListener(new ImportDataTask.Listener()
|
||||
{
|
||||
@Override
|
||||
public void onImportFinished(int result)
|
||||
public void onImportDataFinished(int result)
|
||||
{
|
||||
assertThat(result, equalTo(expectedResult));
|
||||
}
|
||||
@@ -80,11 +79,9 @@ public class ImportDataTaskTest extends BaseTest
|
||||
@NonNull
|
||||
private ImportDataTask createTask(String assetFilename) throws IOException
|
||||
{
|
||||
ProgressBar bar = new ProgressBar(targetContext);
|
||||
File file = new File(String.format("%s/%s", baseDir.getPath(), assetFilename));
|
||||
copyAssetToFile(assetFilename, file);
|
||||
|
||||
return new ImportDataTask(file, bar);
|
||||
return new ImportDataTask(file, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.isoron.uhabits.models.Checkmark;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
import org.isoron.uhabits.tasks.BaseTask;
|
||||
import org.isoron.uhabits.ui.show.ShowHabitActivity;
|
||||
import org.isoron.uhabits.widgets.WidgetManager;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -123,10 +124,10 @@ public class HabitBroadcastReceiver extends BroadcastReceiver
|
||||
public static void sendRefreshBroadcast(Context context)
|
||||
{
|
||||
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(context);
|
||||
Intent refreshIntent = new Intent(MainActivity.ACTION_REFRESH);
|
||||
Intent refreshIntent = new Intent(HabitsApplication.ACTION_REFRESH);
|
||||
manager.sendBroadcast(refreshIntent);
|
||||
|
||||
MainActivity.updateWidgets(context);
|
||||
WidgetManager.updateWidgets(context);
|
||||
}
|
||||
|
||||
private void dismissAllHabits()
|
||||
|
||||
@@ -21,6 +21,8 @@ package org.isoron.uhabits;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
@@ -28,9 +30,12 @@ import android.view.WindowManager;
|
||||
|
||||
import com.activeandroid.ActiveAndroid;
|
||||
|
||||
import org.isoron.uhabits.utils.DateUtils;
|
||||
import org.isoron.uhabits.tasks.BaseTask;
|
||||
import org.isoron.uhabits.utils.DatabaseUtils;
|
||||
import org.isoron.uhabits.utils.DateUtils;
|
||||
import org.isoron.uhabits.utils.FileUtils;
|
||||
import org.isoron.uhabits.utils.ReminderUtils;
|
||||
import org.isoron.uhabits.widgets.WidgetManager;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
@@ -39,8 +44,17 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class HabitsApplication extends Application
|
||||
public class HabitsApplication extends Application implements MainController.System
|
||||
{
|
||||
public static final String ACTION_REFRESH = "org.isoron.uhabits.ACTION_REFRESH";
|
||||
public static final int RESULT_IMPORT_DATA = 1;
|
||||
public static final int RESULT_EXPORT_CSV = 2;
|
||||
public static final int RESULT_EXPORT_DB = 3;
|
||||
public static final int RESULT_BUG_REPORT = 4;
|
||||
|
||||
@Nullable
|
||||
private static HabitsApplication application;
|
||||
|
||||
@Nullable
|
||||
private static Context context;
|
||||
|
||||
@@ -64,11 +78,18 @@ public class HabitsApplication extends Application
|
||||
return context;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HabitsApplication getInstance()
|
||||
{
|
||||
return application;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
super.onCreate();
|
||||
HabitsApplication.context = this;
|
||||
HabitsApplication.application = this;
|
||||
|
||||
if (isTestMode())
|
||||
{
|
||||
@@ -87,7 +108,7 @@ public class HabitsApplication extends Application
|
||||
super.onTerminate();
|
||||
}
|
||||
|
||||
public static String getLogcat() throws IOException
|
||||
public String getLogcat() throws IOException
|
||||
{
|
||||
int maxNLines = 250;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
@@ -116,7 +137,7 @@ public class HabitsApplication extends Application
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String getDeviceInfo()
|
||||
public String getDeviceInfo()
|
||||
{
|
||||
if(context == null) return "";
|
||||
|
||||
@@ -125,7 +146,7 @@ public class HabitsApplication extends Application
|
||||
|
||||
b.append(String.format("App Version Name: %s\n", BuildConfig.VERSION_NAME));
|
||||
b.append(String.format("App Version Code: %s\n", BuildConfig.VERSION_CODE));
|
||||
b.append(String.format("OS Version: %s (%s)\n", System.getProperty("os.version"),
|
||||
b.append(String.format("OS Version: %s (%s)\n", java.lang.System.getProperty("os.version"),
|
||||
android.os.Build.VERSION.INCREMENTAL));
|
||||
b.append(String.format("OS API Level: %s\n", android.os.Build.VERSION.SDK));
|
||||
b.append(String.format("Device: %s\n", android.os.Build.DEVICE));
|
||||
@@ -141,7 +162,7 @@ public class HabitsApplication extends Application
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static File dumpBugReportToFile() throws IOException
|
||||
public File dumpBugReportToFile() throws IOException
|
||||
{
|
||||
String date = DateUtils.getBackupDateFormat().format(DateUtils.getLocalTime());
|
||||
|
||||
@@ -151,17 +172,63 @@ public class HabitsApplication extends Application
|
||||
|
||||
File logFile = new File(String.format("%s/Log %s.txt", dir.getPath(), date));
|
||||
FileWriter output = new FileWriter(logFile);
|
||||
output.write(generateBugReport());
|
||||
output.write(getBugReport());
|
||||
output.close();
|
||||
|
||||
return logFile;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String generateBugReport() throws IOException
|
||||
public String getBugReport() throws IOException
|
||||
{
|
||||
String logcat = getLogcat();
|
||||
String deviceInfo = getDeviceInfo();
|
||||
return deviceInfo + "\n" + logcat;
|
||||
}
|
||||
|
||||
public void sendFile(@NonNull String archiveFilename)
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_SEND);
|
||||
intent.setType("application/zip");
|
||||
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(archiveFilename)));
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
public void sendEmail(String to, String subject, String content)
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_SEND);
|
||||
intent.setType("message/rfc822");
|
||||
intent.putExtra(Intent.EXTRA_EMAIL, new String[] {to});
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
|
||||
intent.putExtra(Intent.EXTRA_TEXT, content);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
public void scheduleReminders()
|
||||
{
|
||||
new BaseTask()
|
||||
{
|
||||
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
{
|
||||
ReminderUtils.createReminderAlarms(getContext());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
public void updateWidgets()
|
||||
{
|
||||
new BaseTask()
|
||||
{
|
||||
|
||||
@Override
|
||||
protected void doInBackground()
|
||||
{
|
||||
WidgetManager.updateWidgets(getContext());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,86 +19,62 @@
|
||||
|
||||
package org.isoron.uhabits;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import org.isoron.uhabits.ui.list.ListHabitsFragment;
|
||||
import org.isoron.uhabits.utils.DateUtils;
|
||||
import org.isoron.uhabits.utils.ReminderUtils;
|
||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||
import org.isoron.uhabits.models.Checkmark;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
import org.isoron.uhabits.tasks.BaseTask;
|
||||
import org.isoron.uhabits.tasks.ProgressBar;
|
||||
import org.isoron.uhabits.ui.AboutActivity;
|
||||
import org.isoron.uhabits.ui.AndroidProgressBar;
|
||||
import org.isoron.uhabits.ui.BaseActivity;
|
||||
import org.isoron.uhabits.ui.IntroActivity;
|
||||
import org.isoron.uhabits.ui.list.ListHabitsFragment;
|
||||
import org.isoron.uhabits.ui.settings.FilePickerDialog;
|
||||
import org.isoron.uhabits.ui.settings.SettingsActivity;
|
||||
import org.isoron.uhabits.ui.show.ShowHabitActivity;
|
||||
import org.isoron.uhabits.widgets.CheckmarkWidgetProvider;
|
||||
import org.isoron.uhabits.widgets.FrequencyWidgetProvider;
|
||||
import org.isoron.uhabits.widgets.HistoryWidgetProvider;
|
||||
import org.isoron.uhabits.widgets.ScoreWidgetProvider;
|
||||
import org.isoron.uhabits.widgets.StreakWidgetProvider;
|
||||
import org.isoron.uhabits.utils.FileUtils;
|
||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||
import org.isoron.uhabits.widgets.WidgetManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
|
||||
public class MainActivity extends BaseActivity
|
||||
implements ListHabitsFragment.OnHabitClickListener
|
||||
implements ListHabitsFragment.OnHabitClickListener, MainController.Screen
|
||||
{
|
||||
private MainController controller;
|
||||
private ListHabitsFragment listHabitsFragment;
|
||||
private SharedPreferences prefs;
|
||||
private BroadcastReceiver receiver;
|
||||
private LocalBroadcastManager localBroadcastManager;
|
||||
|
||||
public static final String ACTION_REFRESH = "org.isoron.uhabits.ACTION_REFRESH";
|
||||
|
||||
public static final int RESULT_IMPORT_DATA = 1;
|
||||
public static final int RESULT_EXPORT_CSV = 2;
|
||||
public static final int RESULT_EXPORT_DB = 3;
|
||||
public static final int RESULT_BUG_REPORT = 4;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.list_habits_activity);
|
||||
|
||||
setupSupportActionBar(false);
|
||||
|
||||
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
listHabitsFragment =
|
||||
(ListHabitsFragment) getSupportFragmentManager().findFragmentById(R.id.fragment1);
|
||||
|
||||
receiver = new Receiver();
|
||||
localBroadcastManager = LocalBroadcastManager.getInstance(this);
|
||||
localBroadcastManager.registerReceiver(receiver, new IntentFilter(ACTION_REFRESH));
|
||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
listHabitsFragment = (ListHabitsFragment) fragmentManager.findFragmentById(R.id.fragment1);
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
|
||||
onPreLollipopStartup();
|
||||
onPreLollipopCreate();
|
||||
|
||||
onStartup();
|
||||
controller = new MainController();
|
||||
controller.setScreen(this);
|
||||
controller.setSystem((HabitsApplication) getApplication());
|
||||
controller.onStartup();
|
||||
}
|
||||
|
||||
private void onPreLollipopStartup()
|
||||
private void onPreLollipopCreate()
|
||||
{
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar == null) return;
|
||||
@@ -108,50 +84,13 @@ public class MainActivity extends BaseActivity
|
||||
actionBar.setBackgroundDrawable(new ColorDrawable(color));
|
||||
}
|
||||
|
||||
private void onStartup()
|
||||
{
|
||||
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
|
||||
InterfaceUtils.incrementLaunchCount(this);
|
||||
InterfaceUtils.updateLastAppVersion(this);
|
||||
showTutorial();
|
||||
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params)
|
||||
{
|
||||
ReminderUtils.createReminderAlarms(MainActivity.this);
|
||||
updateWidgets(MainActivity.this);
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
|
||||
}
|
||||
|
||||
private void showTutorial()
|
||||
{
|
||||
Boolean firstRun = prefs.getBoolean("pref_first_run", true);
|
||||
|
||||
if (firstRun)
|
||||
{
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putBoolean("pref_first_run", false);
|
||||
editor.putLong("last_hint_timestamp", DateUtils.getStartOfToday()).apply();
|
||||
editor.apply();
|
||||
|
||||
Intent intent = new Intent(this, IntroActivity.class);
|
||||
this.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
menu.clear();
|
||||
getMenuInflater().inflate(R.menu.list_habits_menu, menu);
|
||||
|
||||
MenuItem nightModeItem = menu.findItem(R.id.action_night_mode);
|
||||
nightModeItem.setChecked(InterfaceUtils.isNightMode());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -161,6 +100,70 @@ public class MainActivity extends BaseActivity
|
||||
switch (item.getItemId())
|
||||
{
|
||||
case R.id.action_night_mode:
|
||||
toggleNightMode();
|
||||
return true;
|
||||
|
||||
case R.id.action_settings:
|
||||
showSettingsScreen();
|
||||
return true;
|
||||
|
||||
case R.id.action_about:
|
||||
showAboutScreen();
|
||||
return true;
|
||||
|
||||
case R.id.action_faq:
|
||||
showFAQScreen();
|
||||
return true;
|
||||
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
switch (resultCode)
|
||||
{
|
||||
case HabitsApplication.RESULT_IMPORT_DATA:
|
||||
showImportScreen();
|
||||
break;
|
||||
|
||||
case HabitsApplication.RESULT_EXPORT_CSV:
|
||||
controller.exportCSV();
|
||||
break;
|
||||
|
||||
case HabitsApplication.RESULT_EXPORT_DB:
|
||||
controller.exportDB();
|
||||
break;
|
||||
|
||||
case HabitsApplication.RESULT_BUG_REPORT:
|
||||
controller.sendBugReport();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void showFAQScreen()
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse(getString(R.string.helpURL)));
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void showAboutScreen()
|
||||
{
|
||||
Intent intent = new Intent(this, AboutActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void showSettingsScreen()
|
||||
{
|
||||
Intent intent = new Intent(this, SettingsActivity.class);
|
||||
startActivityForResult(intent, 0);
|
||||
}
|
||||
|
||||
private void toggleNightMode()
|
||||
{
|
||||
if(InterfaceUtils.isNightMode())
|
||||
InterfaceUtils.setCurrentTheme(InterfaceUtils.THEME_LIGHT);
|
||||
@@ -168,35 +171,6 @@ public class MainActivity extends BaseActivity
|
||||
InterfaceUtils.setCurrentTheme(InterfaceUtils.THEME_DARK);
|
||||
|
||||
refreshTheme();
|
||||
return true;
|
||||
}
|
||||
|
||||
case R.id.action_settings:
|
||||
{
|
||||
Intent intent = new Intent(this, SettingsActivity.class);
|
||||
startActivityForResult(intent, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
case R.id.action_about:
|
||||
{
|
||||
Intent intent = new Intent(this, AboutActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
case R.id.action_faq:
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse(getString(R.string.helpURL)));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshTheme()
|
||||
@@ -216,67 +190,10 @@ public class MainActivity extends BaseActivity
|
||||
}, 500); // Let the menu disappear first
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
switch (resultCode)
|
||||
{
|
||||
case RESULT_IMPORT_DATA:
|
||||
listHabitsFragment.showImportDialog();
|
||||
break;
|
||||
|
||||
case RESULT_EXPORT_CSV:
|
||||
listHabitsFragment.exportAllHabits();
|
||||
break;
|
||||
|
||||
case RESULT_EXPORT_DB:
|
||||
listHabitsFragment.exportDB();
|
||||
break;
|
||||
|
||||
case RESULT_BUG_REPORT:
|
||||
generateBugReport();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void generateBugReport()
|
||||
{
|
||||
try
|
||||
{
|
||||
HabitsApplication.dumpBugReportToFile();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
String log = "---------- BUG REPORT BEGINS ----------\n";
|
||||
log += HabitsApplication.generateBugReport();
|
||||
log += "---------- BUG REPORT ENDS ------------\n";
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_SEND);
|
||||
intent.setType("message/rfc822");
|
||||
intent.putExtra(Intent.EXTRA_EMAIL, new String[] { "dev@loophabits.org" });
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, "Bug Report - Loop Habit Tracker");
|
||||
intent.putExtra(Intent.EXTRA_TEXT, log);
|
||||
startActivity(intent);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
showToast(R.string.bug_report_failed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHabitClicked(Habit habit)
|
||||
{
|
||||
Intent intent = new Intent(this, ShowHabitActivity.class);
|
||||
intent.setData(Uri.parse("content://org.isoron.uhabits/habit/" + habit.getId()));
|
||||
startActivity(intent);
|
||||
showHabitScreen(habit);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -290,7 +207,7 @@ public class MainActivity extends BaseActivity
|
||||
protected void doInBackground()
|
||||
{
|
||||
dismissNotifications(MainActivity.this);
|
||||
updateWidgets(MainActivity.this);
|
||||
WidgetManager.updateWidgets(MainActivity.this);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
@@ -304,48 +221,49 @@ public class MainActivity extends BaseActivity
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateWidgets(Context context)
|
||||
private void showHabitScreen(Habit habit)
|
||||
{
|
||||
updateWidgets(context, CheckmarkWidgetProvider.class);
|
||||
updateWidgets(context, HistoryWidgetProvider.class);
|
||||
updateWidgets(context, ScoreWidgetProvider.class);
|
||||
updateWidgets(context, StreakWidgetProvider.class);
|
||||
updateWidgets(context, FrequencyWidgetProvider.class);
|
||||
Intent intent = new Intent(this, ShowHabitActivity.class);
|
||||
intent.setData(Uri.parse("content://org.isoron.uhabits/habit/" + habit.getId()));
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private static void updateWidgets(Context context, Class providerClass)
|
||||
public void showIntroScreen()
|
||||
{
|
||||
ComponentName provider = new ComponentName(context, providerClass);
|
||||
Intent intent = new Intent(context, providerClass);
|
||||
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
||||
int ids[] = AppWidgetManager.getInstance(context).getAppWidgetIds(provider);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
|
||||
context.sendBroadcast(intent);
|
||||
Intent intent = new Intent(this, IntroActivity.class);
|
||||
this.startActivity(intent);
|
||||
}
|
||||
|
||||
public void showImportScreen()
|
||||
{
|
||||
File dir = FileUtils.getFilesDir(null);
|
||||
if(dir == null)
|
||||
{
|
||||
showMessage(R.string.could_not_import);
|
||||
return;
|
||||
}
|
||||
|
||||
FilePickerDialog picker = new FilePickerDialog(this, dir);
|
||||
picker.setListener(new FilePickerDialog.OnFileSelectedListener()
|
||||
{
|
||||
@Override
|
||||
public void onFileSelected(File file)
|
||||
{
|
||||
controller.importData(file);
|
||||
}
|
||||
});
|
||||
picker.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy()
|
||||
public void refresh(Long refreshKey)
|
||||
{
|
||||
localBroadcastManager.unregisterReceiver(receiver);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
class Receiver extends BroadcastReceiver
|
||||
{
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
listHabitsFragment.onPostExecuteCommand(null);
|
||||
}
|
||||
listHabitsFragment.loader.updateAllHabits(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||
@NonNull int[] grantResults)
|
||||
public ProgressBar getProgressBar()
|
||||
{
|
||||
if (grantResults.length <= 0) return;
|
||||
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) return;
|
||||
|
||||
listHabitsFragment.showImportDialog();
|
||||
return new AndroidProgressBar(listHabitsFragment.progressBar);
|
||||
}
|
||||
}
|
||||
|
||||
179
app/src/main/java/org/isoron/uhabits/MainController.java
Normal file
179
app/src/main/java/org/isoron/uhabits/MainController.java
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.uhabits;
|
||||
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
import org.isoron.uhabits.tasks.ExportCSVTask;
|
||||
import org.isoron.uhabits.tasks.ExportDBTask;
|
||||
import org.isoron.uhabits.tasks.ImportDataTask;
|
||||
import org.isoron.uhabits.tasks.ProgressBar;
|
||||
import org.isoron.uhabits.utils.DateUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MainController implements ImportDataTask.Listener, ExportCSVTask.Listener,
|
||||
ExportDBTask.Listener
|
||||
{
|
||||
public interface Screen
|
||||
{
|
||||
void showIntroScreen();
|
||||
|
||||
void showMessage(Integer stringId);
|
||||
|
||||
void refresh(Long refreshKey);
|
||||
|
||||
ProgressBar getProgressBar();
|
||||
}
|
||||
|
||||
public interface System
|
||||
{
|
||||
void sendFile(String filename);
|
||||
|
||||
void sendEmail(String to, String subject, String content);
|
||||
|
||||
void scheduleReminders();
|
||||
|
||||
void updateWidgets();
|
||||
|
||||
File dumpBugReportToFile() throws IOException;
|
||||
|
||||
String getBugReport() throws IOException;
|
||||
}
|
||||
|
||||
System sys;
|
||||
Screen screen;
|
||||
Preferences prefs;
|
||||
|
||||
public MainController()
|
||||
{
|
||||
prefs = Preferences.getInstance();
|
||||
}
|
||||
|
||||
public void setScreen(Screen screen)
|
||||
{
|
||||
this.screen = screen;
|
||||
}
|
||||
|
||||
public void setSystem(System sys)
|
||||
{
|
||||
this.sys = sys;
|
||||
}
|
||||
|
||||
public void onStartup()
|
||||
{
|
||||
prefs.initialize();
|
||||
prefs.incrementLaunchCount();
|
||||
prefs.updateLastAppVersion();
|
||||
if(prefs.isFirstRun()) onFirstRun();
|
||||
|
||||
sys.updateWidgets();
|
||||
sys.scheduleReminders();
|
||||
}
|
||||
|
||||
private void onFirstRun()
|
||||
{
|
||||
prefs.setFirstRun(false);
|
||||
prefs.setLastHintTimestamp(DateUtils.getStartOfToday());
|
||||
screen.showIntroScreen();
|
||||
}
|
||||
|
||||
public void importData(File file)
|
||||
{
|
||||
ImportDataTask task = new ImportDataTask(file, screen.getProgressBar());
|
||||
task.setListener(this);
|
||||
task.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImportDataFinished(int result)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case ImportDataTask.SUCCESS:
|
||||
screen.refresh(null);
|
||||
screen.showMessage(R.string.habits_imported);
|
||||
break;
|
||||
|
||||
case ImportDataTask.NOT_RECOGNIZED:
|
||||
screen.showMessage(R.string.file_not_recognized);
|
||||
break;
|
||||
|
||||
default:
|
||||
screen.showMessage(R.string.could_not_import);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void exportCSV()
|
||||
{
|
||||
ExportCSVTask task = new ExportCSVTask(Habit.getAll(true), screen.getProgressBar());
|
||||
task.setListener(this);
|
||||
task.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExportCSVFinished(String filename)
|
||||
{
|
||||
if(filename != null) sys.sendFile(filename);
|
||||
else screen.showMessage(R.string.could_not_export);
|
||||
}
|
||||
|
||||
public void exportDB()
|
||||
{
|
||||
ExportDBTask task = new ExportDBTask(screen.getProgressBar());
|
||||
task.setListener(this);
|
||||
task.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExportDBFinished(String filename)
|
||||
{
|
||||
if(filename != null) sys.sendFile(filename);
|
||||
else screen.showMessage(R.string.could_not_export);
|
||||
}
|
||||
|
||||
public void sendBugReport()
|
||||
{
|
||||
try
|
||||
{
|
||||
sys.dumpBugReportToFile();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
String log = "---------- BUG REPORT BEGINS ----------\n";
|
||||
log += sys.getBugReport();
|
||||
log += "---------- BUG REPORT ENDS ------------\n";
|
||||
String to = "dev@loophabits.org";
|
||||
String subject = "Bug Report - Loop Habit Tracker";
|
||||
sys.sendEmail(log, to, subject);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
screen.showMessage(R.string.bug_report_failed);
|
||||
}
|
||||
}
|
||||
}
|
||||
81
app/src/main/java/org/isoron/uhabits/Preferences.java
Normal file
81
app/src/main/java/org/isoron/uhabits/Preferences.java
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.uhabits;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
public class Preferences
|
||||
{
|
||||
private static Preferences singleton;
|
||||
|
||||
private Context context;
|
||||
private SharedPreferences prefs;
|
||||
|
||||
private Preferences()
|
||||
{
|
||||
this.context = HabitsApplication.getContext();
|
||||
prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
}
|
||||
|
||||
public static Preferences getInstance()
|
||||
{
|
||||
if(singleton == null) singleton = new Preferences();
|
||||
return singleton;
|
||||
}
|
||||
|
||||
public void initialize()
|
||||
{
|
||||
PreferenceManager.setDefaultValues(context, R.xml.preferences, false);
|
||||
}
|
||||
|
||||
|
||||
public void incrementLaunchCount()
|
||||
{
|
||||
int count = prefs.getInt("launch_count", 0);
|
||||
prefs.edit().putInt("launch_count", count + 1).apply();
|
||||
}
|
||||
|
||||
public void updateLastAppVersion()
|
||||
{
|
||||
prefs.edit().putInt("last_version", BuildConfig.VERSION_CODE).apply();
|
||||
}
|
||||
|
||||
public boolean isFirstRun()
|
||||
{
|
||||
return prefs.getBoolean("pref_first_run", true);
|
||||
}
|
||||
|
||||
public void setFirstRun(boolean isFirstRun)
|
||||
{
|
||||
prefs.edit().putBoolean("pref_first_run", isFirstRun).apply();
|
||||
}
|
||||
|
||||
public void setLastHintTimestamp(long timestamp)
|
||||
{
|
||||
prefs.edit().putLong("last_hint_timestamp", timestamp).apply();
|
||||
}
|
||||
|
||||
public boolean isShortToggleEnabled()
|
||||
{
|
||||
return prefs.getBoolean("pref_short_toggle", false);
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,10 @@
|
||||
package org.isoron.uhabits.tasks;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import org.isoron.uhabits.utils.FileUtils;
|
||||
import org.isoron.uhabits.io.HabitsCSVExporter;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
import org.isoron.uhabits.utils.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -58,12 +56,7 @@ public class ExportCSVTask extends BaseTask
|
||||
protected void onPreExecute()
|
||||
{
|
||||
super.onPreExecute();
|
||||
|
||||
if(progressBar != null)
|
||||
{
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if(progressBar != null) progressBar.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,9 +65,7 @@ public class ExportCSVTask extends BaseTask
|
||||
if(listener != null)
|
||||
listener.onExportCSVFinished(archiveFilename);
|
||||
|
||||
if(progressBar != null)
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
if(progressBar != null) progressBar.hide();
|
||||
super.onPostExecute(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
package org.isoron.uhabits.tasks;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import org.isoron.uhabits.utils.DatabaseUtils;
|
||||
import org.isoron.uhabits.utils.FileUtils;
|
||||
@@ -54,23 +52,14 @@ public class ExportDBTask extends BaseTask
|
||||
protected void onPreExecute()
|
||||
{
|
||||
super.onPreExecute();
|
||||
|
||||
if(progressBar != null)
|
||||
{
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if(progressBar != null) progressBar.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
{
|
||||
if(listener != null)
|
||||
listener.onExportDBFinished(filename);
|
||||
|
||||
if(progressBar != null)
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
if(listener != null) listener.onExportDBFinished(filename);
|
||||
if(progressBar != null) progressBar.hide();
|
||||
super.onPostExecute(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ package org.isoron.uhabits.tasks;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import org.isoron.uhabits.io.GenericImporter;
|
||||
|
||||
@@ -36,7 +34,7 @@ public class ImportDataTask extends BaseTask
|
||||
|
||||
public interface Listener
|
||||
{
|
||||
void onImportFinished(int result);
|
||||
void onImportDataFinished(int result);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -66,21 +64,14 @@ public class ImportDataTask extends BaseTask
|
||||
{
|
||||
super.onPreExecute();
|
||||
|
||||
if(progressBar != null)
|
||||
{
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if(progressBar != null) progressBar.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid)
|
||||
{
|
||||
if(progressBar != null)
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
if(listener != null) listener.onImportFinished(result);
|
||||
|
||||
if(progressBar != null) progressBar.hide();
|
||||
if(listener != null) listener.onImportDataFinished(result);
|
||||
super.onPostExecute(null);
|
||||
}
|
||||
|
||||
|
||||
26
app/src/main/java/org/isoron/uhabits/tasks/ProgressBar.java
Normal file
26
app/src/main/java/org/isoron/uhabits/tasks/ProgressBar.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.uhabits.tasks;
|
||||
|
||||
public interface ProgressBar
|
||||
{
|
||||
void show();
|
||||
void hide();
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.uhabits.ui;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import org.isoron.uhabits.tasks.ProgressBar;
|
||||
|
||||
public class AndroidProgressBar implements ProgressBar
|
||||
{
|
||||
private final android.widget.ProgressBar progressBar;
|
||||
|
||||
public AndroidProgressBar(android.widget.ProgressBar progressBar)
|
||||
{
|
||||
this.progressBar = progressBar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show()
|
||||
{
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide()
|
||||
{
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
@@ -72,28 +72,28 @@ abstract public class BaseActivity extends AppCompatActivity implements Thread.U
|
||||
{
|
||||
if (undoList.isEmpty())
|
||||
{
|
||||
showToast(R.string.toast_nothing_to_undo);
|
||||
showMessage(R.string.toast_nothing_to_undo);
|
||||
return;
|
||||
}
|
||||
|
||||
Command last = undoList.pop();
|
||||
redoList.push(last);
|
||||
last.undo();
|
||||
showToast(last.getUndoStringId());
|
||||
showMessage(last.getUndoStringId());
|
||||
}
|
||||
|
||||
protected void redo()
|
||||
{
|
||||
if (redoList.isEmpty())
|
||||
{
|
||||
showToast(R.string.toast_nothing_to_redo);
|
||||
showMessage(R.string.toast_nothing_to_redo);
|
||||
return;
|
||||
}
|
||||
Command last = redoList.pop();
|
||||
executeCommand(last, false, null);
|
||||
}
|
||||
|
||||
public void showToast(Integer stringId)
|
||||
public void showMessage(Integer stringId)
|
||||
{
|
||||
if (stringId == null) return;
|
||||
if (toast == null) toast = Toast.makeText(this, stringId, Toast.LENGTH_SHORT);
|
||||
@@ -126,7 +126,7 @@ abstract public class BaseActivity extends AppCompatActivity implements Thread.U
|
||||
}.execute();
|
||||
|
||||
|
||||
showToast(command.getExecuteStringId());
|
||||
showMessage(command.getExecuteStringId());
|
||||
}
|
||||
|
||||
protected void setupSupportActionBar(boolean homeButtonEnabled)
|
||||
@@ -156,7 +156,7 @@ abstract public class BaseActivity extends AppCompatActivity implements Thread.U
|
||||
try
|
||||
{
|
||||
ex.printStackTrace();
|
||||
HabitsApplication.dumpBugReportToFile();
|
||||
((HabitsApplication) getApplication()).dumpBugReportToFile();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.uhabits.ui.list;
|
||||
|
||||
public class ListHabitsController
|
||||
{
|
||||
public interface Screen
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private Screen screen;
|
||||
|
||||
|
||||
public void setScreen(Screen screen)
|
||||
{
|
||||
this.screen = screen;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,16 +20,9 @@
|
||||
package org.isoron.uhabits.ui.list;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.view.ActionMode;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
@@ -40,7 +33,6 @@ import android.view.View.OnClickListener;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
@@ -48,96 +40,76 @@ import android.widget.TextView;
|
||||
|
||||
import com.mobeta.android.dslv.DragSortController;
|
||||
import com.mobeta.android.dslv.DragSortListView;
|
||||
import com.mobeta.android.dslv.DragSortListView.DropListener;
|
||||
|
||||
import org.isoron.uhabits.ui.BaseActivity;
|
||||
import org.isoron.uhabits.Preferences;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.commands.Command;
|
||||
import org.isoron.uhabits.commands.ToggleRepetitionCommand;
|
||||
import org.isoron.uhabits.ui.edit.EditHabitDialogFragment;
|
||||
import org.isoron.uhabits.ui.settings.FilePickerDialog;
|
||||
import org.isoron.uhabits.utils.FileUtils;
|
||||
import org.isoron.uhabits.utils.DateUtils;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
import org.isoron.uhabits.ui.BaseActivity;
|
||||
import org.isoron.uhabits.ui.HintManager;
|
||||
import org.isoron.uhabits.utils.ReminderUtils;
|
||||
import org.isoron.uhabits.ui.edit.EditHabitDialogFragment;
|
||||
import org.isoron.uhabits.utils.DateUtils;
|
||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||
import org.isoron.uhabits.utils.InterfaceUtils.OnSavedListener;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
import org.isoron.uhabits.tasks.ExportCSVTask;
|
||||
import org.isoron.uhabits.tasks.ExportDBTask;
|
||||
import org.isoron.uhabits.tasks.ImportDataTask;
|
||||
import org.isoron.uhabits.utils.ReminderUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ListHabitsFragment extends Fragment
|
||||
implements OnSavedListener, OnItemClickListener, OnLongClickListener, DropListener,
|
||||
implements OnSavedListener, OnItemClickListener, OnLongClickListener,
|
||||
OnClickListener, ListHabitsLoader.Listener, AdapterView.OnItemLongClickListener,
|
||||
HabitSelectionCallback.Listener, ImportDataTask.Listener, ExportCSVTask.Listener,
|
||||
ExportDBTask.Listener
|
||||
HabitSelectionCallback.Listener, ListHabitsController.Screen
|
||||
{
|
||||
long lastLongClick = 0;
|
||||
private boolean isShortToggleEnabled;
|
||||
private boolean showArchived;
|
||||
|
||||
private ActionMode actionMode;
|
||||
private ListHabitsAdapter adapter;
|
||||
private ListHabitsLoader loader;
|
||||
public ListHabitsLoader loader;
|
||||
private HintManager hintManager;
|
||||
private ListHabitsHelper helper;
|
||||
private List<Integer> selectedPositions;
|
||||
private OnHabitClickListener habitClickListener;
|
||||
private BaseActivity activity;
|
||||
private SharedPreferences prefs;
|
||||
|
||||
private DragSortListView listView;
|
||||
private LinearLayout llButtonsHeader;
|
||||
private ProgressBar progressBar;
|
||||
public ProgressBar progressBar;
|
||||
private View llEmpty;
|
||||
|
||||
private ListHabitsController controller;
|
||||
private Preferences prefs;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState)
|
||||
{
|
||||
View view = inflater.inflate(R.layout.list_habits_fragment, container, false);
|
||||
|
||||
View llHint = view.findViewById(R.id.llHint);
|
||||
TextView tvStarEmpty = (TextView) view.findViewById(R.id.tvStarEmpty);
|
||||
listView = (DragSortListView) view.findViewById(R.id.listView);
|
||||
llButtonsHeader = (LinearLayout) view.findViewById(R.id.llButtonsHeader);
|
||||
llEmpty = view.findViewById(R.id.llEmpty);
|
||||
|
||||
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
selectedPositions = new LinkedList<>();
|
||||
loader = new ListHabitsLoader();
|
||||
helper = new ListHabitsHelper(activity, loader);
|
||||
|
||||
hintManager = new HintManager(activity, llHint);
|
||||
|
||||
loader.setListener(this);
|
||||
loader.setCheckmarkCount(helper.getButtonCount());
|
||||
|
||||
llHint.setOnClickListener(this);
|
||||
|
||||
TextView tvStarEmpty = (TextView) view.findViewById(R.id.tvStarEmpty);
|
||||
tvStarEmpty.setTypeface(InterfaceUtils.getFontAwesome(activity));
|
||||
|
||||
adapter = new ListHabitsAdapter(getActivity(), loader);
|
||||
adapter.setSelectedPositions(selectedPositions);
|
||||
adapter.setOnCheckmarkClickListener(this);
|
||||
adapter.setOnCheckmarkLongClickListener(this);
|
||||
|
||||
DragSortListView.DragListener dragListener = new HabitsDragListener();
|
||||
DragSortController dragSortController = new HabitsDragSortController();
|
||||
|
||||
listView.setAdapter(adapter);
|
||||
listView.setOnItemClickListener(this);
|
||||
listView.setOnItemLongClickListener(this);
|
||||
listView.setDropListener(this);
|
||||
listView.setDragListener(dragListener);
|
||||
listView.setFloatViewManager(dragSortController);
|
||||
listView.setDragEnabled(true);
|
||||
listView.setLongClickable(true);
|
||||
createListView(view);
|
||||
|
||||
if(savedInstanceState != null)
|
||||
{
|
||||
@@ -148,19 +120,42 @@ public class ListHabitsFragment extends Fragment
|
||||
|
||||
loader.updateAllHabits(true);
|
||||
|
||||
controller = new ListHabitsController();
|
||||
controller.setScreen(this);
|
||||
prefs = Preferences.getInstance();
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
return view;
|
||||
}
|
||||
|
||||
private void createListView(View view)
|
||||
{
|
||||
adapter = new ListHabitsAdapter(getActivity(), loader);
|
||||
adapter.setSelectedPositions(selectedPositions);
|
||||
adapter.setOnCheckmarkClickListener(this);
|
||||
adapter.setOnCheckmarkLongClickListener(this);
|
||||
|
||||
DragSortListView.DragListener dragListener = new HabitsDragListener();
|
||||
DragSortController dragSortController = new HabitsDragSortController();
|
||||
|
||||
listView = (DragSortListView) view.findViewById(R.id.listView);
|
||||
listView.setAdapter(adapter);
|
||||
listView.setOnItemClickListener(this);
|
||||
listView.setOnItemLongClickListener(this);
|
||||
listView.setDropListener(new HabitsDropListener());
|
||||
listView.setDragListener(dragListener);
|
||||
listView.setFloatViewManager(dragSortController);
|
||||
listView.setDragEnabled(true);
|
||||
listView.setLongClickable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onAttach(Activity activity)
|
||||
{
|
||||
super.onAttach(activity);
|
||||
this.activity = (BaseActivity) activity;
|
||||
|
||||
habitClickListener = (OnHabitClickListener) activity;
|
||||
prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -175,9 +170,7 @@ public class ListHabitsFragment extends Fragment
|
||||
helper.updateEmptyMessage(llEmpty);
|
||||
helper.updateHeader(llButtonsHeader);
|
||||
hintManager.showHintIfAppropriate();
|
||||
|
||||
adapter.notifyDataSetChanged();
|
||||
isShortToggleEnabled = prefs.getBoolean("pref_short_toggle", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -192,49 +185,41 @@ public class ListHabitsFragment extends Fragment
|
||||
{
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
inflater.inflate(R.menu.list_habits_options, menu);
|
||||
|
||||
MenuItem showArchivedItem = menu.findItem(R.id.action_show_archived);
|
||||
showArchivedItem.setChecked(showArchived);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo)
|
||||
{
|
||||
super.onCreateContextMenu(menu, view, menuInfo);
|
||||
getActivity().getMenuInflater().inflate(R.menu.list_habits_context, menu);
|
||||
|
||||
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
|
||||
final Habit habit = loader.habits.get(info.id);
|
||||
|
||||
if (habit.isArchived()) menu.findItem(R.id.action_archive_habit).setVisible(false);
|
||||
else menu.findItem(R.id.action_unarchive_habit).setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
switch (item.getItemId())
|
||||
{
|
||||
case R.id.action_add:
|
||||
{
|
||||
EditHabitDialogFragment frag = EditHabitDialogFragment.createHabitFragment();
|
||||
frag.setOnSavedListener(this);
|
||||
frag.show(getFragmentManager(), "editHabit");
|
||||
showCreateHabitScreen();
|
||||
return true;
|
||||
}
|
||||
|
||||
case R.id.action_show_archived:
|
||||
toggleShowArchived();
|
||||
return true;
|
||||
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleShowArchived()
|
||||
{
|
||||
showArchived = !showArchived;
|
||||
loader.setIncludeArchived(showArchived);
|
||||
loader.updateAllHabits(true);
|
||||
activity.invalidateOptionsMenu();
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
private void showCreateHabitScreen()
|
||||
{
|
||||
EditHabitDialogFragment frag = EditHabitDialogFragment.createHabitFragment();
|
||||
frag.setOnSavedListener(this);
|
||||
frag.show(getFragmentManager(), "editHabit");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -248,47 +233,46 @@ public class ListHabitsFragment extends Fragment
|
||||
habitClickListener.onHabitClicked(habit);
|
||||
}
|
||||
else
|
||||
{
|
||||
toggleItemSelected(position);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleItemSelected(int position)
|
||||
{
|
||||
int k = selectedPositions.indexOf(position);
|
||||
if(k < 0)
|
||||
selectedPositions.add(position);
|
||||
else
|
||||
selectedPositions.remove(k);
|
||||
if(k < 0) selectedPositions.add(position);
|
||||
else selectedPositions.remove(k);
|
||||
|
||||
if(selectedPositions.isEmpty()) actionMode.finish();
|
||||
else actionMode.invalidate();
|
||||
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
selectItem(position);
|
||||
selectHabit(position);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void selectItem(int position)
|
||||
private void selectHabit(int position)
|
||||
{
|
||||
if(!selectedPositions.contains(position))
|
||||
selectedPositions.add(position);
|
||||
|
||||
if(!selectedPositions.contains(position)) selectedPositions.add(position);
|
||||
adapter.notifyDataSetChanged();
|
||||
if(actionMode == null) startSupportActionMode();
|
||||
actionMode.invalidate();
|
||||
}
|
||||
|
||||
if(actionMode == null)
|
||||
private void startSupportActionMode()
|
||||
{
|
||||
HabitSelectionCallback callback = new HabitSelectionCallback(activity, loader);
|
||||
callback.setSelectedPositions(selectedPositions);
|
||||
callback.setOnSavedListener(this);
|
||||
callback.setListener(this);
|
||||
|
||||
actionMode = activity.startSupportActionMode(callback);
|
||||
}
|
||||
|
||||
if(actionMode != null) actionMode.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaved(Command command, Object savedObject)
|
||||
{
|
||||
@@ -320,12 +304,11 @@ public class ListHabitsFragment extends Fragment
|
||||
|
||||
private void onCheckmarkLongClick(View v)
|
||||
{
|
||||
if (isShortToggleEnabled) return;
|
||||
|
||||
toggleCheck(v);
|
||||
if (prefs.isShortToggleEnabled()) return;
|
||||
toggleCheckmark(v);
|
||||
}
|
||||
|
||||
private void toggleCheck(View v)
|
||||
private void toggleCheckmark(View v)
|
||||
{
|
||||
Long id = helper.getHabitIdFromCheckmarkView(v);
|
||||
Habit habit = loader.habits.get(id);
|
||||
@@ -347,25 +330,14 @@ public class ListHabitsFragment extends Fragment
|
||||
activity.executeCommand(c, refreshKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drop(int from, int to)
|
||||
{
|
||||
if(from == to) return;
|
||||
if(actionMode != null) actionMode.finish();
|
||||
|
||||
loader.reorder(from, to);
|
||||
adapter.notifyDataSetChanged();
|
||||
loader.updateAllHabits(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
switch (v.getId())
|
||||
{
|
||||
case R.id.tvCheck:
|
||||
if (isShortToggleEnabled) toggleCheck(v);
|
||||
else activity.showToast(R.string.long_press_to_toggle);
|
||||
if (prefs.isShortToggleEnabled()) toggleCheckmark(v);
|
||||
else activity.showMessage(R.string.long_press_to_toggle);
|
||||
break;
|
||||
|
||||
case R.id.llHint:
|
||||
@@ -414,6 +386,20 @@ public class ListHabitsFragment extends Fragment
|
||||
}
|
||||
}
|
||||
|
||||
private class HabitsDropListener implements DragSortListView.DropListener
|
||||
{
|
||||
@Override
|
||||
public void drop(int from, int to)
|
||||
{
|
||||
if(from == to) return;
|
||||
if(actionMode != null) actionMode.finish();
|
||||
|
||||
loader.reorder(from, to);
|
||||
adapter.notifyDataSetChanged();
|
||||
loader.updateAllHabits(false);
|
||||
}
|
||||
}
|
||||
|
||||
private class HabitsDragListener implements DragSortListView.DragListener
|
||||
{
|
||||
@Override
|
||||
@@ -424,99 +410,7 @@ public class ListHabitsFragment extends Fragment
|
||||
@Override
|
||||
public void startDrag(int position)
|
||||
{
|
||||
selectItem(position);
|
||||
}
|
||||
}
|
||||
|
||||
public void showImportDialog()
|
||||
{
|
||||
File dir = FileUtils.getFilesDir(null);
|
||||
if(dir == null)
|
||||
{
|
||||
activity.showToast(R.string.could_not_import);
|
||||
return;
|
||||
}
|
||||
|
||||
FilePickerDialog picker = new FilePickerDialog(activity, dir);
|
||||
picker.setListener(new FilePickerDialog.OnFileSelectedListener()
|
||||
{
|
||||
@Override
|
||||
public void onFileSelected(File file)
|
||||
{
|
||||
ImportDataTask task = new ImportDataTask(file, progressBar);
|
||||
task.setListener(ListHabitsFragment.this);
|
||||
task.execute();
|
||||
}
|
||||
});
|
||||
|
||||
picker.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImportFinished(int result)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case ImportDataTask.SUCCESS:
|
||||
loader.updateAllHabits(true);
|
||||
activity.showToast(R.string.habits_imported);
|
||||
break;
|
||||
|
||||
case ImportDataTask.NOT_RECOGNIZED:
|
||||
activity.showToast(R.string.file_not_recognized);
|
||||
break;
|
||||
|
||||
default:
|
||||
activity.showToast(R.string.could_not_import);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void exportAllHabits()
|
||||
{
|
||||
ExportCSVTask task = new ExportCSVTask(Habit.getAll(true), progressBar);
|
||||
task.setListener(this);
|
||||
task.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExportCSVFinished(@Nullable String archiveFilename)
|
||||
{
|
||||
if(archiveFilename != null)
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_SEND);
|
||||
intent.setType("application/zip");
|
||||
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(archiveFilename)));
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
else
|
||||
{
|
||||
activity.showToast(R.string.could_not_export);
|
||||
}
|
||||
}
|
||||
|
||||
public void exportDB()
|
||||
{
|
||||
ExportDBTask task = new ExportDBTask(progressBar);
|
||||
task.setListener(this);
|
||||
task.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExportDBFinished(@Nullable String filename)
|
||||
{
|
||||
if(filename != null)
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_SEND);
|
||||
intent.setType("application/octet-stream");
|
||||
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(filename)));
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
else
|
||||
{
|
||||
activity.showToast(R.string.could_not_export);
|
||||
selectHabit(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||
|
||||
import org.isoron.uhabits.MainActivity;
|
||||
import org.isoron.uhabits.HabitsApplication;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.utils.ReminderUtils;
|
||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
||||
@@ -43,10 +43,10 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
|
||||
setResultOnPreferenceClick("importData", MainActivity.RESULT_IMPORT_DATA);
|
||||
setResultOnPreferenceClick("exportCSV", MainActivity.RESULT_EXPORT_CSV);
|
||||
setResultOnPreferenceClick("exportDB", MainActivity.RESULT_EXPORT_DB);
|
||||
setResultOnPreferenceClick("bugReport", MainActivity.RESULT_BUG_REPORT);
|
||||
setResultOnPreferenceClick("importData", HabitsApplication.RESULT_IMPORT_DATA);
|
||||
setResultOnPreferenceClick("exportCSV", HabitsApplication.RESULT_EXPORT_CSV);
|
||||
setResultOnPreferenceClick("exportDB", HabitsApplication.RESULT_EXPORT_DB);
|
||||
setResultOnPreferenceClick("bugReport", HabitsApplication.RESULT_BUG_REPORT);
|
||||
|
||||
updateRingtoneDescription();
|
||||
|
||||
|
||||
@@ -33,10 +33,7 @@ import android.preference.PreferenceManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import org.isoron.uhabits.BuildConfig;
|
||||
import org.isoron.uhabits.HabitsApplication;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.commands.Command;
|
||||
@@ -71,32 +68,6 @@ public abstract class InterfaceUtils
|
||||
return fontAwesome;
|
||||
}
|
||||
|
||||
public static void showSoftKeyboard(View view)
|
||||
{
|
||||
InputMethodManager imm = (InputMethodManager) view.getContext()
|
||||
.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
|
||||
public static void incrementLaunchCount(Context context)
|
||||
{
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
int count = prefs.getInt("launch_count", 0);
|
||||
prefs.edit().putInt("launch_count", count + 1).apply();
|
||||
}
|
||||
|
||||
public static void updateLastAppVersion(Context context)
|
||||
{
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
prefs.edit().putInt("last_version", BuildConfig.VERSION_CODE).apply();
|
||||
}
|
||||
|
||||
public static int getLaunchCount(Context context)
|
||||
{
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
return prefs.getInt("launch_count", 0);
|
||||
}
|
||||
|
||||
public static String getAttribute(Context context, AttributeSet attrs, String name,
|
||||
String defaultValue)
|
||||
{
|
||||
|
||||
@@ -30,7 +30,6 @@ import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
import org.isoron.uhabits.MainActivity;
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
|
||||
@@ -81,7 +80,7 @@ public class HabitPickerDialog extends Activity implements AdapterView.OnItemCli
|
||||
getApplicationContext());
|
||||
prefs.edit().putLong(BaseWidgetProvider.getHabitIdKey(widgetId), habitId).commit();
|
||||
|
||||
MainActivity.updateWidgets(this);
|
||||
WidgetManager.updateWidgets(this);
|
||||
|
||||
Intent resultValue = new Intent();
|
||||
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.uhabits.widgets;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class WidgetManager
|
||||
{
|
||||
public static void updateWidgets(Context context)
|
||||
{
|
||||
updateWidgets(context, CheckmarkWidgetProvider.class);
|
||||
updateWidgets(context, HistoryWidgetProvider.class);
|
||||
updateWidgets(context, ScoreWidgetProvider.class);
|
||||
updateWidgets(context, StreakWidgetProvider.class);
|
||||
updateWidgets(context, FrequencyWidgetProvider.class);
|
||||
}
|
||||
|
||||
private static void updateWidgets(Context context, Class providerClass)
|
||||
{
|
||||
ComponentName provider = new ComponentName(context, providerClass);
|
||||
Intent intent = new Intent(context, providerClass);
|
||||
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
||||
int ids[] = AppWidgetManager.getInstance(context).getAppWidgetIds(provider);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user