diff --git a/build.properties b/build.properties index b80dec3..7ad57c8 100755 --- a/build.properties +++ b/build.properties @@ -1,4 +1,9 @@ -titanium.platform=/Users/benjamin/Library/Application Support/Titanium/mobilesdk/osx/3.2.0.GA/android -android.platform=/Users/benjamin/Android/sdk/platforms/android-15 -google.apis=/Users/benjamin/Android/sdk/add-ons/addon-google_apis-google-15 -android.ndk=/Users/benjamin/Android/ndk/ \ No newline at end of file +titanium.sdk=C:\\ProgramData\\Titanium +titanium.os=win32 +titanium.version=3.2.2.GA +android.sdk=C:\\android-sdk-win +android.ndk=C:\\android-ndk-r9d + +titanium.platform=${titanium.sdk}/mobilesdk/${titanium.os}/${titanium.version}/android +android.platform=${android.sdk}/platforms/android-10 +google.apis=${android.sdk}/add-ons/addon-google_apis-google-10 \ No newline at end of file diff --git a/dist/bencoding.android.tools-android-0.35.zip b/dist/bencoding.android.tools-android-0.35.zip new file mode 100644 index 0000000..be9fdc9 Binary files /dev/null and b/dist/bencoding.android.tools-android-0.35.zip differ diff --git a/dist/bencoding.android.tools-android-0.36.zip b/dist/bencoding.android.tools-android-0.36.zip new file mode 100644 index 0000000..001df94 Binary files /dev/null and b/dist/bencoding.android.tools-android-0.36.zip differ diff --git a/dist/bencoding.android.tools-android-0.37.zip b/dist/bencoding.android.tools-android-0.37.zip new file mode 100644 index 0000000..e6d207c Binary files /dev/null and b/dist/bencoding.android.tools-android-0.37.zip differ diff --git a/documentation/bootreceiver.md b/documentation/bootreceiver.md index 63f7adf..184ce0c 100755 --- a/documentation/bootreceiver.md +++ b/documentation/bootreceiver.md @@ -60,7 +60,9 @@ Using the information from step #1’s AndroidManifest.xml add an android config + + diff --git a/documentation/platform.md b/documentation/platform.md index 6a1cb81..c370382 100755 --- a/documentation/platform.md +++ b/documentation/platform.md @@ -108,3 +108,24 @@ Boolean (true/false) ---- + +getSystemDateTime +This method returns an object representing the current time on the device, useful when you need to know if the timezone has changed, since the JavaScript engine will often initialize this value up front and never check the OS. + +Parameters +None + +Returns +HashMap containing the following keys: +
    +
  • TZOffset: The timezone offset of the device, in minutes.
  • +
  • Year
  • +
  • Month
  • +
  • Day
  • +
  • Hour
  • +
  • Minutes
  • +
  • Seconds
  • +
  • Date: In the format yyyy/MM/ss HH:mm:ss
  • +
+ +---- diff --git a/manifest b/manifest index ea9ec6b..30bcde3 100755 --- a/manifest +++ b/manifest @@ -2,7 +2,7 @@ # this is your module manifest and used by Titanium # during compilation, packaging, distribution, etc. # -version: 0.34 +version: 0.37 apiversion: 2 description: A collection of utilities designed to make working with Titanium on Android alittle easier. author: Benjamin Bahrenburg diff --git a/src/bencoding/android/receivers/BootReceiver.java b/src/bencoding/android/receivers/BootReceiver.java index 9cf7ec8..ec18b46 100755 --- a/src/bencoding/android/receivers/BootReceiver.java +++ b/src/bencoding/android/receivers/BootReceiver.java @@ -5,9 +5,10 @@ import org.appcelerator.kroll.KrollDict; import org.appcelerator.titanium.TiApplication; - import bencoding.android.Common; - +import bencoding.android.services.MainMenuService; +import bencoding.android.services.WakefulIntentService; +import bencoding.android.tools.AndroidtoolsModule; import android.R; import android.app.Notification; import android.app.NotificationManager; @@ -65,6 +66,7 @@ public void onReceive(Context context, Intent intent) { Common.msgLogger("Processing bootType of " + bootType); if(TiApplication.getInstance()!=null){ + Common.msgLogger("App instance is not null. fireAppEvent"); KrollDict event = new KrollDict(); event.put("type", bootType); TiApplication.getInstance().fireAppEvent(BOOT_TYPE, event); @@ -72,12 +74,14 @@ public void onReceive(Context context, Intent intent) { //If bootType of start provided, startup the app if(bootType.equalsIgnoreCase(BOOT_TYPE_PROPERTY)){ + Common.msgLogger("bootType is PROPERTYBASED. Startup and return."); bootProperty(context,bundle); return; } //If bootType of start provided, startup the app if(bootType.equalsIgnoreCase(BOOT_TYPE_START)){ + Common.msgLogger("bootType is RESTART. Call openBootUp. Send to back? " + bundle.getBoolean(START_SEND_TO_BACK, false)); openBootUp(context, bundle.getBoolean(START_SEND_TO_BACK, false)); return; } @@ -133,10 +137,12 @@ private void bootProperty(Context context, Bundle bundle){ writeStartDate(bundle); } private void openBootUp(Context context, boolean sendToBack){ + + Common.msgLogger("Called openBootUp"); bootStartup(context); //Check if the app should immediately be sent to the background if(sendToBack){ - sendToBackground(); + sendToBackground(TiApplication.getInstance()); } } private void propertyNotify(Context context, Bundle bundle){ @@ -150,19 +156,24 @@ private void propertyNotify(Context context, Bundle bundle){ private void bootStartup(Context context){ if(TiApplication.getInstance() == null){ Intent standardIntent = context.getPackageManager().getLaunchIntentForPackage(context.getApplicationContext().getPackageName()); + standardIntent.putExtra(AndroidtoolsModule.LAUNCHED_FROM_BOOTRECEIVER, true); context.startActivity(standardIntent); }else{ Intent tiIntent = TiApplication.getInstance().getPackageManager().getLaunchIntentForPackage(TiApplication.getInstance().getApplicationContext().getPackageName()); + tiIntent.putExtra(AndroidtoolsModule.LAUNCHED_FROM_BOOTRECEIVER, true); tiIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); TiApplication.getInstance().startActivity(tiIntent); } } - private void sendToBackground(){ - Intent startMain = new Intent(Intent.ACTION_MAIN); - startMain.addCategory(Intent.CATEGORY_HOME); - startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - TiApplication.getInstance().startActivity(startMain); + private void sendToBackground(Context context){ + Common.msgLogger(".sendToBackground()"); + WakefulIntentService.acquireStaticLock(context); + Common.msgLogger(".sendToBackground(): Static wake lock acquired"); + Intent svcIntent = new Intent(context, MainMenuService.class); + + context.startService(svcIntent); + Common.msgLogger(".sendToBackground(): Service Started"); } private void notifyOnStart(Context context,String msgTitle,String msgText, int msgIcon){ diff --git a/src/bencoding/android/services/MainMenuService.java b/src/bencoding/android/services/MainMenuService.java new file mode 100644 index 0000000..5d81771 --- /dev/null +++ b/src/bencoding/android/services/MainMenuService.java @@ -0,0 +1,39 @@ +package bencoding.android.services; + +import android.content.Context; +import android.content.Intent; +import bencoding.android.Common; + +import org.appcelerator.titanium.TiApplication; + +public class MainMenuService extends WakefulIntentService{ + private Context _context = null; + public static final String ACTIVITY_CONTEXT_PARAM = "ACTIVITYCONTEXT"; + + public MainMenuService() { + super("MainMenuService"); + } + + @Override + protected void onHandleIntent(Intent intent) + { + // Make the context whatever the current TiApplication is. + if (TiApplication.getInstance() != null) + _context = TiApplication.getInstance(); + + if (_context == null) + { + Common.msgLogger("No context. Returning"); + return; + } + + Common.msgLogger(".onHandleIntent()"); + Common.msgLogger(".onHandleIntent(). About to start activity."); + Intent startMain = new Intent(Intent.ACTION_MAIN); + startMain.addCategory(Intent.CATEGORY_HOME); + startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + _context.startActivity(startMain); + Common.msgLogger(".onHandleIntent(). Call super.onHandleIntent()."); + super.onHandleIntent(intent); + } +} diff --git a/src/bencoding/android/services/WakefulIntentService.java b/src/bencoding/android/services/WakefulIntentService.java new file mode 100644 index 0000000..7a29de4 --- /dev/null +++ b/src/bencoding/android/services/WakefulIntentService.java @@ -0,0 +1,63 @@ +package bencoding.android.services; + +import android.app.IntentService; +import android.content.Context; +import android.content.Intent; +import android.os.PowerManager; + +/* + * Thanks to this article for this implementation for creating a "wakeful" IntentService. + * http://dhimitraq.wordpress.com/tag/android-wakelock/ + */ +public class WakefulIntentService extends IntentService { + private static PowerManager.WakeLock lockStatic=null; + private PowerManager.WakeLock lockLocal=null; + public static final String LOCK_NAME_STATIC="bencoding.android.tools.Static"; + public static final String LOCK_NAME_LOCAL="bencoding.android.tools.Local"; + + public WakefulIntentService(String name) + { + super(name); + } + + /** + * Acquire a partial static WakeLock, you need too call this within the class + * that calls startService() + * @param context + */ + public static void acquireStaticLock(Context context) { + getLock(context).acquire(); + } + + synchronized private static PowerManager.WakeLock getLock(Context context) { + if (lockStatic==null) { + PowerManager + mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE); + lockStatic=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + LOCK_NAME_STATIC); + lockStatic.setReferenceCounted(true); + } + return(lockStatic); + } + + @Override + public void onCreate() { + super.onCreate(); + PowerManager mgr=(PowerManager)getSystemService(Context.POWER_SERVICE); + lockLocal=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + LOCK_NAME_LOCAL); + lockLocal.setReferenceCounted(true); + } + + @Override + public void onStart(Intent intent, final int startId) { + lockLocal.acquire(); + super.onStart(intent, startId); + getLock(this).release(); + } + + @Override + protected void onHandleIntent(Intent intent) { + lockLocal.release(); + } +} diff --git a/src/bencoding/android/tools/AndroidtoolsModule.java b/src/bencoding/android/tools/AndroidtoolsModule.java index dbc18f4..cfa2a7b 100755 --- a/src/bencoding/android/tools/AndroidtoolsModule.java +++ b/src/bencoding/android/tools/AndroidtoolsModule.java @@ -10,7 +10,6 @@ import org.appcelerator.kroll.KrollModule; import org.appcelerator.kroll.annotations.Kroll; - import org.appcelerator.titanium.TiApplication; import bencoding.android.Common; @@ -25,6 +24,12 @@ public AndroidtoolsModule() { super(); } + + /* + * A boolean extra that is set to "true" on the intent if it is launched by the bencoding BootReceiver. + */ + @Kroll.constant + public static final String LAUNCHED_FROM_BOOTRECEIVER = "LaunchedFromBootReceiver"; @Kroll.onAppCreate public static void onAppCreate(TiApplication app) diff --git a/src/bencoding/android/tools/PlatformProxy.java b/src/bencoding/android/tools/PlatformProxy.java index 749186d..4026bb8 100755 --- a/src/bencoding/android/tools/PlatformProxy.java +++ b/src/bencoding/android/tools/PlatformProxy.java @@ -1,7 +1,10 @@ package bencoding.android.tools; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Calendar; import java.util.HashMap; +import java.util.TimeZone; import org.appcelerator.kroll.KrollProxy; import org.appcelerator.kroll.annotations.Kroll; @@ -11,6 +14,7 @@ import java.util.List; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; @@ -190,4 +194,26 @@ public void launchIntentForPackage(String packageName){ Intent launchIntent = TiApplication.getInstance().getApplicationContext().getPackageManager().getLaunchIntentForPackage(packageName); TiApplication.getInstance().startActivity(launchIntent); } + + @SuppressWarnings("rawtypes") + @Kroll.method + public HashMap getSystemDateTime() { + Calendar cal = Calendar.getInstance(); + TimeZone tz = TimeZone.getDefault(); + SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + HashMap dateMap = new HashMap(); + + // dateMap.put("TZOffset", Integer.toString(Math.round(tz.getOffset(cal.getTimeInMillis() / 1000 / 60)))); + dateMap.put("TZOffset", TimeUnit.MILLISECONDS.toMinutes(tz.getOffset(cal.getTimeInMillis()))); + dateMap.put("Date", df.format(cal.getTime())); + dateMap.put("Month", cal.get(cal.MONTH)); + dateMap.put("Year", cal.get(cal.YEAR)); + dateMap.put("Day", cal.get(cal.DAY_OF_MONTH)); + dateMap.put("Hour", cal.get(cal.HOUR_OF_DAY)); + dateMap.put("Minutes", cal.get(cal.MINUTE)); + dateMap.put("Seconds", cal.get(cal.SECOND)); + dateMap.put("DayOfWeek", cal.get(cal.DAY_OF_WEEK)); + + return dateMap; + } } \ No newline at end of file