package com.geek_alarm.android; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.Point; import android.media.RingtoneManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Build; import android.preference.PreferenceManager; import android.view.Display; import android.view.WindowManager; import com.geek_alarm.android.activities.TaskActivity; import java.util.Calendar; import java.util.Date; public class Utils { private static final String LAST_TASKS_UPDATE_TIME = "lastTasksUpdateTime"; private static final long MIN_TASKS_UPDATE_FREQUENCY = 1000 * 60 * 60 * 24; // Once a day private static final int MILLISECONDS_IN_HOUR = 1000 * 60 * 60; private static final int MILLISECONDS_IN_MINUTE = 1000 * 60; private static final int HTC_SENSATION_SCREEN_WIDTH = 540; private static final int HTC_SENSATION_SCREEN_HEIGHT = 960; public static final String NUMBER_OF_ATTEMPTS = "numberOfAttempts"; public static final String POSITIVE_BALANCE = "positiveBalance"; public static int DEFAULT_NUMBER_OF_ATTEMPTS = 10; public static int DEFAULT_POSITIVE_BALANCE = 3; public static int DAYS_OF_WEEK_NAMES[] = { R.string.monday, R.string.tuesday, R.string.wednesday, R.string.thursday, R.string.friday, R.string.saturday, R.string.sunday }; private final static int[] DAYS_OF_WEEK = new int[8]; static { int[] days = {Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY, Calendar.FRIDAY, Calendar.SATURDAY, Calendar.SUNDAY}; for (int i = 0; i < 7; i++) { DAYS_OF_WEEK[days[i]] = i; } } private static final String ALARM_SOUND = "alarm_sound"; /** * Checks if device is connected to internet. * @return true or false. */ public static boolean isOnline() { Context context = Application.getContext(); ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); if (netInfo != null && netInfo.isConnectedOrConnecting()) { return true; } return false; } /** * Transforms calendar day of week to number (from 0 to 7). * E.g. Calendar.MONDAY -> 0 * Calendar.TUESDAY -> 1 * @param calendarDayOfWeek * @return */ public static int getDayOfWeek(int calendarDayOfWeek) { return DAYS_OF_WEEK[calendarDayOfWeek]; } /** * Returns earliest date in future, which has given hour and minute. * E.g now is May 1, 2000. 14:00 * getNextTime(14, 15) -> May 1, 2000, 14:15 * getNextTime(13, 15) -> May 2, 2000, 13:15 * @param hour * @param minute * @return date in millis. */ public static long getNextTime(int hour, int minute) { Calendar cur = Calendar.getInstance(); Calendar next = Calendar.getInstance(); next.set(Calendar.MINUTE, minute); next.set(Calendar.HOUR_OF_DAY, hour); next.set(Calendar.SECOND, 0); cur.set(Calendar.SECOND, 59); if (next.before(cur)) { next.add(Calendar.DAY_OF_MONTH, 1); } return next.getTimeInMillis(); } /** * Returns string representation for time gap between 2 dates given in milliseconds. * E.g. "5 hours 2 minutes". * @param from * @param to * @return string representation of the time gap */ public static String timeBetween(long from, long to) { long diff = to - from; long hours = diff / MILLISECONDS_IN_HOUR; diff %= MILLISECONDS_IN_HOUR; long minutes = diff / MILLISECONDS_IN_MINUTE; return String.format("%d hour%s %d minute%s left", hours, hours == 1 ? "" : "s", minutes, minutes == 1 ? "" : "s"); } private static PendingIntent buildAlarmIntent(int alarmId) { Intent intent = new Intent(Application.getContext(), TaskActivity.class); intent.setData(Uri.parse("id:" + alarmId)); PendingIntent pending = PendingIntent.getActivity( Application.getContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); return pending; } /** * Sets alarm in AlarmManager, so TaskActivity will be launched at alarm's time every day. * It's TaskActivity's responsibility to check if current day is enabled in this alarm. * @param alarm to be set. */ public static void setAlarm(AlarmPreference alarm) { AlarmManager manager = (AlarmManager) Application.getContext().getSystemService(Context.ALARM_SERVICE); PendingIntent intent = buildAlarmIntent(alarm.getId()); long nextTime = getNextTime(alarm.getHour(), alarm.getMinute()); manager.setRepeating(AlarmManager.RTC_WAKEUP, nextTime, AlarmManager.INTERVAL_DAY, intent); } public static void cancelAlarm(AlarmPreference alarm) { AlarmManager manager = (AlarmManager) Application.getContext().getSystemService(Context.ALARM_SERVICE); PendingIntent intent = buildAlarmIntent(alarm.getId()); manager.cancel(intent); } public static SharedPreferences getPreferences() { return PreferenceManager.getDefaultSharedPreferences(Application.getContext()); } /** * Returns alarm sound. * 1. Returns selected sound, if exists * 2. Returns default alarm sound, if exists. * 3. Returns built in mario sound, exists! * @return uri to sound. */ public static Uri getCurrentAlarmSound() { Uri sound = null; // Look up sound in preferences. SharedPreferences pref = getPreferences(); String uriString = pref.getString(ALARM_SOUND, null); if (uriString != null) { sound = Uri.parse(uriString); } // Look up default alarm sound. if (sound == null) { sound = RingtoneManager.getActualDefaultRingtoneUri( Application.getContext(), RingtoneManager.TYPE_ALARM); } return sound; } /** * Saves given uri as alarm sound. * @param uri */ public static void setCurrentAlarmSound(Uri uri) { SharedPreferences pref = getPreferences(); SharedPreferences.Editor editor = pref.edit(); editor.putString(ALARM_SOUND, uri.toString()); editor.commit(); } /** * Run update task types async task. It will get latest tasks from server and update local copy. * By default update happens when user opens application. * If user opens application too frequently we don't want to check server every time. So we check it * at only if last check was more then 1 day ago. * But sometimes we need to force update (to get latest updates if we now they are on server :)), so forceUpdate * can be used to achieve it. * @param forceUpdate - if true, then ignore last task time update and check anyway. */ public static void updateTaskTypesAsync(boolean forceUpdate) { long lastTime = getPreferences().getLong(LAST_TASKS_UPDATE_TIME, 0); long currentTime = new Date().getTime(); if (forceUpdate || currentTime - lastTime > MIN_TASKS_UPDATE_FREQUENCY) { new UpdateTaskTypesAsyncTask().execute(); } SharedPreferences.Editor editor = getPreferences().edit(); editor.putLong(LAST_TASKS_UPDATE_TIME, currentTime); editor.commit(); } /** * Max number of tasks user can try to solve during 1 alarm session. * @return number of tasks user can try to solve */ public static int getNumberOfAttempts() { return getPreferences().getInt(NUMBER_OF_ATTEMPTS, DEFAULT_NUMBER_OF_ATTEMPTS); } /** * User must solve NUMBER_OF_SOLVED - NUMBER_OF_FAILED tasks to dismiss alarm. * @return NUMBER_OF_SOLVED - NUMBER_OF_FAILED */ public static int getPositiveBalance() { return getPreferences().getInt(POSITIVE_BALANCE, DEFAULT_POSITIVE_BALANCE); } public static Bitmap resizeImage(final Bitmap image) { Point screenSize = getScreenSize(); double screenWidth = (double) screenSize.x; double screenHeight = (double) screenSize.y; double scale = Math.min(screenWidth / HTC_SENSATION_SCREEN_WIDTH, screenHeight / HTC_SENSATION_SCREEN_HEIGHT); return Bitmap.createScaledBitmap( image, (int) (image.getWidth() * scale), (int) (image.getHeight() * scale), true); } private static Point getScreenSize() { Point result = new Point(); WindowManager wm = (WindowManager) Application.getContext().getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); if(Build.VERSION.SDK_INT> Build.VERSION_CODES.HONEYCOMB){ display.getSize(result); } else { result.set(display.getWidth(), display.getHeight()); } return result; } }