Refactor MainActivity and Preferences

pull/145/head
Alinson S. Xavier 9 years ago
parent 83ef8564e1
commit 6445bf62bc

@ -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,122 +100,100 @@ public class MainActivity extends BaseActivity
switch (item.getItemId())
{
case R.id.action_night_mode:
{
if(InterfaceUtils.isNightMode())
InterfaceUtils.setCurrentTheme(InterfaceUtils.THEME_LIGHT);
else
InterfaceUtils.setCurrentTheme(InterfaceUtils.THEME_DARK);
refreshTheme();
toggleNightMode();
return true;
}
case R.id.action_settings:
{
Intent intent = new Intent(this, SettingsActivity.class);
startActivityForResult(intent, 0);
showSettingsScreen();
return true;
}
case R.id.action_about:
{
Intent intent = new Intent(this, AboutActivity.class);
startActivity(intent);
showAboutScreen();
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);
showFAQScreen();
return true;
}
default:
return super.onOptionsItemSelected(item);
}
}
private void refreshTheme()
{
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
Intent intent = new Intent(MainActivity.this, MainActivity.class);
MainActivity.this.finish();
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
startActivity(intent);
}
}, 500); // Let the menu disappear first
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch (resultCode)
{
case RESULT_IMPORT_DATA:
listHabitsFragment.showImportDialog();
case HabitsApplication.RESULT_IMPORT_DATA:
showImportScreen();
break;
case RESULT_EXPORT_CSV:
listHabitsFragment.exportAllHabits();
case HabitsApplication.RESULT_EXPORT_CSV:
controller.exportCSV();
break;
case RESULT_EXPORT_DB:
listHabitsFragment.exportDB();
case HabitsApplication.RESULT_EXPORT_DB:
controller.exportDB();
break;
case RESULT_BUG_REPORT:
generateBugReport();
case HabitsApplication.RESULT_BUG_REPORT:
controller.sendBugReport();
break;
}
}
private void generateBugReport()
private void showFAQScreen()
{
try
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(getString(R.string.helpURL)));
startActivity(intent);
}
private void showAboutScreen()
{
HabitsApplication.dumpBugReportToFile();
Intent intent = new Intent(this, AboutActivity.class);
startActivity(intent);
}
catch (IOException e)
private void showSettingsScreen()
{
// ignored
Intent intent = new Intent(this, SettingsActivity.class);
startActivityForResult(intent, 0);
}
try
private void toggleNightMode()
{
String log = "---------- BUG REPORT BEGINS ----------\n";
log += HabitsApplication.generateBugReport();
log += "---------- BUG REPORT ENDS ------------\n";
if(InterfaceUtils.isNightMode())
InterfaceUtils.setCurrentTheme(InterfaceUtils.THEME_LIGHT);
else
InterfaceUtils.setCurrentTheme(InterfaceUtils.THEME_DARK);
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);
refreshTheme();
}
catch (IOException e)
private void refreshTheme()
{
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
e.printStackTrace();
showToast(R.string.bug_report_failed);
Intent intent = new Intent(MainActivity.this, MainActivity.class);
MainActivity.this.finish();
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
startActivity(intent);
}
}, 500); // Let the menu disappear first
}
@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);
}
@Override
protected void onDestroy()
public void showImportScreen()
{
File dir = FileUtils.getFilesDir(null);
if(dir == null)
{
localBroadcastManager.unregisterReceiver(receiver);
super.onDestroy();
showMessage(R.string.could_not_import);
return;
}
class Receiver extends BroadcastReceiver
FilePickerDialog picker = new FilePickerDialog(this, dir);
picker.setListener(new FilePickerDialog.OnFileSelectedListener()
{
@Override
public void onReceive(Context context, Intent intent)
public void onFileSelected(File file)
{
listHabitsFragment.onPostExecuteCommand(null);
controller.importData(file);
}
});
picker.show();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults)
public void refresh(Long refreshKey)
{
if (grantResults.length <= 0) return;
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) return;
listHabitsFragment.loader.updateAllHabits(true);
}
listHabitsFragment.showImportDialog();
@Override
public ProgressBar getProgressBar()
{
return new AndroidProgressBar(listHabitsFragment.progressBar);
}
}

@ -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);
}
}
}

@ -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);
}

@ -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,80 +40,96 @@ 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.models.Habit;
import org.isoron.uhabits.ui.BaseActivity;
import org.isoron.uhabits.ui.HintManager;
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.ui.HintManager;
import org.isoron.uhabits.utils.ReminderUtils;
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));
createListView(view);
if(savedInstanceState != null)
{
EditHabitDialogFragment frag = (EditHabitDialogFragment) getFragmentManager()
.findFragmentByTag("editHabit");
if(frag != null) frag.setOnSavedListener(this);
}
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);
@ -130,26 +138,15 @@ public class ListHabitsFragment extends Fragment
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(this);
listView.setDropListener(new HabitsDropListener());
listView.setDragListener(dragListener);
listView.setFloatViewManager(dragSortController);
listView.setDragEnabled(true);
listView.setLongClickable(true);
if(savedInstanceState != null)
{
EditHabitDialogFragment frag = (EditHabitDialogFragment) getFragmentManager()
.findFragmentByTag("editHabit");
if(frag != null) frag.setOnSavedListener(this);
}
loader.updateAllHabits(true);
setHasOptionsMenu(true);
return view;
}
@Override
@ -158,9 +155,7 @@ public class ListHabitsFragment extends Fragment
{
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,109 +386,31 @@ public class ListHabitsFragment extends Fragment
}
}
private class HabitsDragListener implements DragSortListView.DragListener
private class HabitsDropListener implements DragSortListView.DropListener
{
@Override
public void drag(int from, int to)
{
}
@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)
public void drop(int from, int to)
{
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;
if(from == to) return;
if(actionMode != null) actionMode.finish();
default:
activity.showToast(R.string.could_not_import);
break;
loader.reorder(from, to);
adapter.notifyDataSetChanged();
loader.updateAllHabits(false);
}
}
public void exportAllHabits()
private class HabitsDragListener implements DragSortListView.DragListener
{
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()
public void drag(int from, int to)
{
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
public void startDrag(int position)
{
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);
}
}
Loading…
Cancel
Save