{ "id": "163490", "key": "TIMOB-23955", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": { "id": "3", "description": "The problem is a duplicate of an existing issue.", "name": "Duplicate" }, "resolutiondate": "2016-10-06T15:16:34.000+0000", "created": "2016-09-27T19:17:40.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [ "Android", "Hyperloop" ], "versions": [ { "id": "18264", "name": "hyperloop 1.2.7", "archived": false, "released": true, "releaseDate": "2017-02-06" } ], "issuelinks": [ { "id": "52850", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "155237", "key": "TIMOB-20490", "fields": { "summary": "Android: Apps should be able to open/resume and respond to intents", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } }, { "id": "52849", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "155282", "key": "TIMOB-20502", "fields": { "summary": "Using Android shortcut to start new activity fails to detect Alloy.", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } }, { "id": "52820", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "163484", "key": "TIMOB-23953", "fields": { "summary": "Hyperloop: Android - Fails to cast Ti.Android.Intent to native Android Intent", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } } ], "assignee": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "updated": "2017-03-20T22:26:30.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "13715", "name": "Hyperloop", "description": "Hyperloop project" } ], "description": "Starting an activity and getting its result is fundamental to Android development. Hyperloop does not provide a way to do this...at least to my knowledge. I worked with several folks on TiSlack and no one seems to have a working solution. Here was the best attempt using what is available in HyperLoop:\r\n\r\n{code}\r\nvar Activity = require('android.app.Activity');\r\nvar Intent = Alloy.require('android.content.Intent');\r\nvar CardIOActivity = Alloy.require('io.card.payment.CardIOActivity');\r\n\r\nvar MyActivity = Activity.extend({\r\n onActivityResult: function(requestCode, resultCode, data) {\r\n console.log('!!!!!!onActivityResult');\r\n }\r\n });\r\n\r\n//Cast the current activity to your overridden native one\r\nvar windowActivity = new MyActivity(window.getActivity());\r\n\r\nvar scanIntent = new Intent(windowActivity, CardIOActivity.class);\r\n\r\nwindowActivity.startActivityForResult(scanIntent, 100); //Fails\r\n{code}\r\n\r\nHere is the error that is thrown:\r\n{code}\r\n[ERROR] : HyperloopProxy: (main) [6645,21912] Exception thrown during invocation of method: public void Activity_Proxy.startActivityForResult(android.content.Intent,int), args: [Intent { cmp=/io.card.payment.CardIOActivity (has extras) }, 100]\r\n[ERROR] : HyperloopProxy: java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.ActivityThread$ApplicationThread android.app.ActivityThread.getApplicationThread()' on a null object reference\r\n[ERROR] : HyperloopProxy: \tat android.app.Activity.startActivityForResult(Activity.java:4026)\r\n[ERROR] : HyperloopProxy: \tat Activity_Proxy.super$startActivityForResult$void(Activity_Proxy.generated)\r\n[ERROR] : HyperloopProxy: \tat java.lang.reflect.Method.invoke(Native Method)\r\n[ERROR] : HyperloopProxy: \tat java.lang.reflect.Method.invoke(Method.java:372)\r\n[ERROR] : HyperloopProxy: \tat com.android.dx.stock.ProxyBuilder.callSuper(ProxyBuilder.java:546)\r\n[ERROR] : HyperloopProxy: \tat hyperloop.DynamicSubclassInvocationHandler.invoke(DynamicSubclassInvocationHandler.java:33)\r\n[ERROR] : HyperloopProxy: \tat Activity_Proxy.startActivityForResult(Activity_Proxy.generated)\r\n[ERROR] : HyperloopProxy: \tat android.app.Activity.startActivityForResult(Activity.java:3973)\r\n[ERROR] : HyperloopProxy: \tat Activity_Proxy.super$startActivityForResult$void(Activity_Proxy.generated)\r\n[ERROR] : HyperloopProxy: \tat java.lang.reflect.Method.invoke(Native Method)\r\n[ERROR] : HyperloopProxy: \tat java.lang.reflect.Method.invoke(Method.java:372)\r\n[ERROR] : HyperloopProxy: \tat com.android.dx.stock.ProxyBuilder.callSuper(ProxyBuilder.java:546)\r\n[ERROR] : HyperloopProxy: \tat hyperloop.DynamicSubclassInvocationHandler.invoke(DynamicSubclassInvocationHandler.java:33)\r\n[ERROR] : HyperloopProxy: \tat Activity_Proxy.startActivityForResult(Activity_Proxy.generated)\r\n[ERROR] : HyperloopProxy: \tat java.lang.reflect.Method.invoke(Native Method)\r\n[ERROR] : HyperloopProxy: \tat java.lang.reflect.Method.invoke(Method.java:372)\r\n[ERROR] : HyperloopProxy: \tat hyperloop.BaseProxy.invokeMethod(BaseProxy.java:145)\r\n[ERROR] : HyperloopProxy: \tat hyperloop.InstanceProxy.invokeMethod(InstanceProxy.java:183)\r\n[ERROR] : HyperloopProxy: \tat hyperloop.BaseProxy.callNativeFunction(BaseProxy.java:127)\r\n[ERROR] : HyperloopProxy: \tat org.appcelerator.kroll.runtime.v8.V8Object.nativeFireEvent(Native Method)\r\n[ERROR] : HyperloopProxy: \tat org.appcelerator.kroll.runtime.v8.V8Object.fireEvent(V8Object.java:62)\r\n[ERROR] : HyperloopProxy: \tat org.appcelerator.kroll.KrollProxy.doFireEvent(KrollProxy.java:918)\r\n[ERROR] : HyperloopProxy: \tat org.appcelerator.kroll.KrollProxy.handleMessage(KrollProxy.java:1141)\r\n[ERROR] : HyperloopProxy: \tat org.appcelerator.titanium.proxy.TiViewProxy.handleMessage(TiViewProxy.java:357)\r\n[ERROR] : HyperloopProxy: \tat android.os.Handler.dispatchMessage(Handler.java:98)\r\n[ERROR] : HyperloopProxy: \tat android.os.Looper.loop(Looper.java:145)\r\n[ERROR] : HyperloopProxy: \tat android.app.ActivityThread.main(ActivityThread.java:6843)\r\n[ERROR] : HyperloopProxy: \tat java.lang.reflect.Method.invoke(Native Method)\r\n[ERROR] : HyperloopProxy: \tat java.lang.reflect.Method.invoke(Method.java:372)\r\n[ERROR] : HyperloopProxy: \tat com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)\r\n[ERROR] : HyperloopProxy: \tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)\r\n{code}\r\n", "attachment": [], "flagged": false, "summary": "Hyperloop - not possible to start a native activity and get its result", "creator": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "subtasks": [], "reporter": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "environment": "Hyperloop on Android", "closedSprints": [ { "id": 722, "state": "closed", "name": "2016 Sprint 20 SDK", "startDate": "2016-09-28T16:50:17.299Z", "endDate": "2016-10-12T16:50:00.000Z", "completeDate": "2016-10-10T06:17:01.016Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "397421", "author": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "body": "Also if you replace the line:\r\n{code}\r\nvar windowActivity = new MyActivity(window.getActivity());\r\n{code}\r\nwith:\r\n{code}\r\nvar windowActivity = new Activity(window.getActivity());\r\n{code}\r\nthe Activity will start just fine, but there is no way to get the result.", "updateAuthor": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "created": "2016-09-27T19:21:23.000+0000", "updated": "2016-09-27T19:21:23.000+0000" }, { "id": "397423", "author": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "body": "I cannot find a way to update the ticket's description...but I made a copy/paste mistake. The lines:\r\n{code}\r\nvar Intent = Alloy.require('android.content.Intent');\r\nvar CardIOActivity = Alloy.require('io.card.payment.CardIOActivity');\r\n{code}\r\nshould be this instead\r\n{code}\r\nvar Intent = require('android.content.Intent');\r\nvar CardIOActivity = require('io.card.payment.CardIOActivity');\r\n{code}", "updateAuthor": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "created": "2016-09-27T19:31:30.000+0000", "updated": "2016-09-27T19:31:30.000+0000" }, { "id": "397536", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "Well, first off that \"cast\" will never work - the active/current activity is going to be whatever it already is, you can't just pass it into the dynamically generated subclass to turn it into that subclass.\r\n\r\nThis isn't a use case I've tried yet, so it's likely they'll need to be some mix of standard Titanium API usage and some custom hyperloop code meshing nicely together - and I probably didn't add the silent conversions for Intents (between Titanium.Android.Intent and android.content.Intent) into the hyperloop code yet.\r\n\r\nMy best guess right now would be an approach like so:\r\n{code}\r\nvar Intent = require('android.content.Intent'),\r\n CardIOActivity = require('io.card.payment.CardIOActivity');\r\n\r\nvar scanIntent = new Intent(Ti.Android.currentActivity, CardIOActivity.class);\r\n\r\nTi.Android.currentActivity.startActivityForResult(scanIntent, function (result) {\r\n Ti.API.info(result.requestCode);\r\n Ti.API.info(result.resultCode);\r\n});\r\n{code}\r\n\r\nHere, the startActivityForResult call is actually the one from our Titanium API at http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Android.Activity-method-startActivityForResult\r\n\r\nAgain, I still need to test if this works, but this seems like a workable approach.", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2016-09-28T17:08:59.000+0000", "updated": "2016-09-28T18:26:37.000+0000" }, { "id": "397540", "author": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "updateAuthor": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "created": "2016-09-28T17:21:00.000+0000", "updated": "2016-09-28T17:29:51.000+0000" }, { "id": "397548", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "OK, I just tested my code above and yeah it doesn't work. I'm working on special casing conversions between native Activity and the Titanium ActivityProxy, as well as Intent and Titanium's IntentProxy.\r\n\r\nFor now, you can \"cast\" a Titanium Activity to a native one, but can't with Intents. But additionally, if you try and pass a Titanium Activity or Intent to a method expecting the native Activity or Intent (or vice-versa, passing in native ones where we expect Ti proxies) that currently fails. I'm going to try and address all these cases now and see if we can't get this to work.", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2016-09-28T18:06:59.000+0000", "updated": "2016-09-28T18:06:59.000+0000" }, { "id": "397552", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "Yuck, so I can fix TIMOB-23953 pretty easily. However, to allow Titanium API methods to accept hyperloop proxies as you would need in my snippet above, I'll likely need to make SDK changes. I'll investigate more, but I'm guessing I'd need to add some code in the SDK and hyperloop to handle that.", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2016-09-28T18:42:20.000+0000", "updated": "2016-09-28T18:42:20.000+0000" }, { "id": "397557", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "So I _think_ might be able to hack this eventually with changes only to hyperloop, but it'd end up in some clunky syntax that I'm not sure we'd want to support. Basically you'd need to create a new native/hyperloop Intent, then cast it to a Titanium IntentProxy, then call a special method to unwrap the hyperloop wrapper down to the actual native IntentProxy and pass that into the Titanium API call. Something like:\r\n\r\n{code:javascript}\r\nvar Intent = require('android.content.Intent'),\r\n IntentProxy = require('org.appcelerator.titanium.proxy.IntentProxy'),\r\n CardIOActivity = require('io.card.payment.CardIOActivity');\r\n\r\nvar scanIntent = new Intent(Ti.Android.currentActivity, CardIOActivity.class);\r\nvar proxy = new IntentProxy(scanIntent);\r\n\r\nTi.Android.currentActivity.startActivityForResult(proxy.getNativeObject(), function (result) {\r\n Ti.API.info(result.requestCode);\r\n Ti.API.info(result.resultCode);\r\n});\r\n{code}\r\n\r\nThat's less than ideal, and exposes the Titanium proxy classes and a new accessor method to unwrap hyperloop's wrapper (which is really intended to be transparent). I'd prefer to introduce some interface/mechanism into the SDK itself to be able to support hyperloop's wrappers better when they match up properly in terms of the wrapped type. But right now, given the architecture of hyper loop's wrapper classes (specifically InstanceProxy), I don't think I could do so in a type-safe manner at all, we'd basically just have to have some marking interface that we can query to see if the implemented object can convert/adapt to the expect class we want to manipulate.", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2016-09-28T20:18:59.000+0000", "updated": "2016-09-28T20:18:59.000+0000" }, { "id": "397566", "author": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "body": "How about something like the following....would this work?\r\n\r\n{code}\r\nvar Activity = require('android.app.Activity'),\r\n Intent = require('android.content.Intent'),\r\n IntentProxy = require('org.appcelerator.titanium.proxy.IntentProxy'),\r\n CardIOActivity = require('io.card.payment.CardIOActivity');\r\n\r\nvar scanIntent = new Intent(new Activity(Ti.Android.currentActivity), CardIOActivity.class);\r\nvar proxy = new IntentProxy(scanIntent);\r\n\r\nTi.Android.currentActivity.startActivityForResult(proxy, function (result) {\r\n Ti.API.info(result.requestCode);\r\n Ti.API.info(result.resultCode);\r\n \r\n var resultIntent = new Intent(result.intent);\r\n});\r\n{code}", "updateAuthor": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "created": "2016-09-28T21:18:16.000+0000", "updated": "2016-09-28T21:18:16.000+0000" }, { "id": "397585", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "Unfortunately not, no. I tried this as well. You ultimately get a crash because the Ti.Android.currentActivity.startActivityForResult() call expects an IntenTproxy as the first argument and while we try to pretend that the proxy is an IntentProxy, under the hood it's not really.\r\n\r\nWhen you do {{new IntentProxy}} it's *actually* creating a hyperloop wrapper whose wrapped Java type is InstanceProxy (basically a generic proxy that holds an instance of some object and uses reflection to access methods and fields on the object it wraps). You can unwrap the hyperloop proxy (proxy variable above in JS world) to the \"native\"/Java InstanceProxy instance it holds in Java-land, but can't \"unwrap\" that to the actual IntentProxy it's holding - unless I add some new method/property to do that (the getNativeObject() call in my example above).\r\n", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2016-09-28T23:30:41.000+0000", "updated": "2016-09-28T23:30:41.000+0000" }, { "id": "397636", "author": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "body": "What if there was a general way to cast a native object to a Ti one...just like you do when going from Ti to native? Probably would require some work but would handle all cases.\r\n\r\n{code}\r\nvar Activity = require('android.app.Activity');\r\nvar Intent = require('android.content.Intent');\r\nvar CardIOActivity = require('io.card.payment.CardIOActivity');\r\n\r\n//create native intent\r\nvar nativeIntent = new Intent(new Activity(Ti.Android.currentActivity), CardIOActivity.class);\r\n\r\n//a few different ideas for casting to Ti\r\nvar tiIntent1 = new Ti.Android.Intent(nativeIntent); \r\nvar tiIntent2 = Ti.Android.createIntent(nativeIntent); \r\nvar tiIntent3 = Ti.Android.Intent.cast(nativeIntent); \r\n{code}", "updateAuthor": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "created": "2016-09-29T14:37:07.000+0000", "updated": "2016-09-29T14:37:07.000+0000" }, { "id": "397691", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "Ok, managed to get this working locally with no changes beyond the fix for TIMOB-23953. Here's what I did:\r\n\r\n- Grabbed the aar for the library: http://search.maven.org/remotecontent?filepath=io/card/android-sdk/5.4.2/android-sdk-5.4.2.aar\r\n- Dropped it into app/platform/android\r\n- Modified my tiapp.xml to add the activities to the manifest for android:\r\n{code:xml}\r\n \r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n{code}\r\n\r\n- Then used this code:\r\n{code:javascript}\r\n\tvar Intent = require('android.content.Intent'),\r\n\t\tCardIOActivity = require('io.card.payment.CardIOActivity'),\r\n\t\tCreditCard = require('io.card.payment.CreditCard');\r\n\r\n\t$.button.addEventListener('click', function () {\r\n\t\tvar scanIntent = Titanium.Android.createIntent({\r\n\t\t\tclassName: 'io.card.payment.CardIOActivity'\r\n\t\t});\r\n\r\n\t\t// customize these values to suit your needs.\r\n\t\tscanIntent.putExtra(CardIOActivity.EXTRA_REQUIRE_EXPIRY, true); // default: false\r\n\t\tscanIntent.putExtra(CardIOActivity.EXTRA_REQUIRE_CVV, false); // default: false\r\n\t\tscanIntent.putExtra(CardIOActivity.EXTRA_REQUIRE_POSTAL_CODE, false); // default: false\r\n\t\tscanIntent.putExtra(CardIOActivity.EXTRA_RESTRICT_POSTAL_CODE_TO_NUMERIC_ONLY, false); // default: false\r\n\t\tscanIntent.putExtra(CardIOActivity.EXTRA_REQUIRE_CARDHOLDER_NAME, false); // default: false\r\n\r\n\t\t// hides the manual entry button\r\n\t\t// if set, developers should provide their own manual entry mechanism in the app\r\n\t\tscanIntent.putExtra(CardIOActivity.EXTRA_SUPPRESS_MANUAL_ENTRY, false); // default: false\r\n\r\n\t\t// matches the theme of your application\r\n\t\tscanIntent.putExtra(CardIOActivity.EXTRA_KEEP_APPLICATION_THEME, false); // default: false\r\n\r\n\t\tTi.Android.currentActivity.startActivityForResult(scanIntent, function (result) {\r\n\t\t\tTi.API.info(result.requestCode);\r\n\t\t\tTi.API.info(result.resultCode);\r\n\t\t\tvar nativeIntent = new Intent(result.intent);\r\n\t\t\tTi.API.info(nativeIntent);\r\n\t\t\tvar card = nativeIntent.getParcelableExtra(CardIOActivity.EXTRA_SCAN_RESULT);\r\n\t\t\tTi.API.info(card);\r\n\t\t\tvar scanResult = CreditCard.cast(card);\r\n\t\t\tTi.API.info(\"Card Number: \" + scanResult.getRedactedCardNumber() + \"\\n\");\r\n\r\n\t\t\t// Do something with the raw number, e.g.:\r\n\t\t\t// myService.setCardNumber( scanResult.cardNumber );\r\n\r\n\t\t\tif (scanResult.isExpiryValid()) {\r\n\t\t\t\tTi.API.info(\"Expiration Date: \" + scanResult.expiryMonth + \"/\" + scanResult.expiryYear + \"\\n\");\r\n\t\t\t}\r\n\r\n\t\t\tif (scanResult.cvv != null) {\r\n\t\t\t\t// Never log or display a CVV\r\n\t\t\t\tTi.API.info(\"CVV has \" + scanResult.cvv.length() + \" digits.\\n\");\r\n\t\t\t}\r\n\r\n\t\t\tif (scanResult.postalCode != null) {\r\n\t\t\t\tTi.API.info(\"Postal Code: \" + scanResult.postalCode + \"\\n\");\r\n\t\t\t}\r\n\r\n\t\t\tif (scanResult.cardholderName != null) {\r\n\t\t\t\tTi.API.info(\"Cardholder Name : \" + scanResult.cardholderName + \"\\n\");\r\n\t\t\t}\r\n\t\t});\r\n\t});\r\n{code}\r\n\r\nThis works for me, but there's on weird behavior here. Specifically after the user enters their CC info and clicks Done, the UI disappears, but it doesn't seem like the activity \"finishes\". I have to hit the back button on the Android emulator before the Ti.Android.currentActivity.startActivityForResult callback fires.", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2016-09-29T23:51:58.000+0000", "updated": "2016-09-29T23:51:58.000+0000" }, { "id": "397698", "author": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "body": "Ya with the ability to cast a Ti Intent to a native one, this is a great workaround. I would like to try it out, but I don't have access to hyperloop 1.2.8, only 1.2.7.", "updateAuthor": { "name": "btknorr", "key": "btknorr", "displayName": "Brian Knorr", "active": true, "timeZone": "America/Chicago" }, "created": "2016-09-30T00:53:55.000+0000", "updated": "2016-09-30T00:53:55.000+0000" }, { "id": "398245", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "Ok, So I'm going to mark this as \"duplicate\" for now since the other fix seems to enable this to work. [~btknorr] Please feel free to re-open if the workaround doesn't work for you once you've tried on Hyperloop 1.2.8+. I don't have insight as to when exactly that gets released or if support is able to release a build in advance to you.", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2016-10-06T15:16:34.000+0000", "updated": "2016-10-06T15:16:34.000+0000" }, { "id": "414113", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as duplicate.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-20T22:26:30.000+0000", "updated": "2017-03-20T22:26:30.000+0000" } ], "maxResults": 15, "total": 15, "startAt": 0 } } }