Problem with InstantApps.showInstallPrompt and postInstallIntent. Intent extras lose - android-instant-apps

postInstallIntent lose bundle extras after installation. I create postInstallIntent this way:
val intent: Intent?
intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.test.ru/activity/main/"))
intent.setPackage(context.packageName)
intent.addCategory(Intent.CATEGORY_BROWSABLE)
intent?.putExtra(EXTRA_FIRST, data1)
intent?.putExtra(EXTRA_SECOND, data2)
Than call it:
InstantApps.showInstallPrompt(
activity,
intent,
REQUEST_CODE,
INSTALL_REFERRER
)
It opens requested activity, but when I try to get data from intent intent.extras in installed app the bundle is empty.
What am I doing wrong or it's a problem of showInstallPrompt?

I understood that you want to pass data from your Instant app to the installed app and this could happen in the following ways as the support from Android documentation:
For Android 8.0 (API level 26) and higher, you can use the Cookie API sample app
For Android 7.1 (API level 25) and lower, you can use Storage API
sample app
For more details see these references:
https://developer.android.com/topic/google-play-instant/getting-started/instant-enabled-app-bundle
How can I restore data from instant app to installed app?
How to transfer the shared prefs from Instant app to full app
How to store data in android instant app and restore it in installed app
Now, in my case, I am using the normal function to open the installed version of the app by using the following function
private fun showInstallPrompt() {
val postInstall = Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_DEFAULT)
.setPackage(packageName)
InstantApps.showInstallPrompt(this#MainActivity, postInstall, 0, null)
}

Related

Kotlin for Volley, how can I check the JSON request for newer data in the API?

I'm working on an app that gets a list of documents/source URL from an api. I'd like to periodically check for new or updated contents within that API so users can update saved items in the database. I'm at a loss on the correct wording to search, thus Google and Stack Overflow have both failed me. My fetching function is below:
The URL for the API is https://api.afiexplorer.com
private fun fetchPubs() {
_binding.contentMain.loading.visibility = View.VISIBLE
request = JsonArrayRequest(
Request.Method.GET,
Config.BASE_URL,
JSONArray(),{ response ->
val items: List<Pubs> =
Gson().fromJson(response.toString(), object : TypeToken<List<Pubs>>() {}.type)
val sortedItems = items.sortedWith(compareBy { it.Number })
pubsList?.clear()
pubsList?.addAll(sortedItems)
// Hardcoded pubs moved to Publications Gitlab Repo
// https://gitlab.com/afi-explorer/pubs
_binding.contentMain.recyclerView.recycledViewPool.clear()
adapter?.notifyDataSetChanged()
_binding.contentMain.loading.visibility = View.GONE
setupData()
Log.i("LENGTH OF DATA", "${items.size}")
},
{error ->
println(error.printStackTrace())
Toasty.error(applicationContext, getString(string.no_internet), Toast.LENGTH_SHORT, true).show()
}
)
MyApplication.instance.addToRequestQueue(request!!)
}
private fun setupData(){
adapter = MainAdapter(applicationContext, pubsList!!, this)
_binding.contentMain.recyclerView.adapter = adapter
}
I tried using ChatGPT to see if that would get me started and that failed miserably. Also searched Google, Reddit and Stack Overflow for similar projects, but mine is a unique scenario I guess. I'm just a hobbyist and intermediate dev I guess. First time working with Volley, everything works, but I would like to find a way to send a notification (preferably not Firebase) if there is updated info within the API listed above. I'm not sure if this is actually doable.
Are you asking if you can somehow find if the remote API has changed its content? If so, how would that service advise you? If the service provider provides a web hook or similar callback you could write a server-based program to send a push notification to your Android app.
Perhaps you intent to poll the API periodically, and then you want to know if there is a change?
If you use a tool such as Postman or curl to easily see the headers of the API https://api.afiexplorer.com you will see, unfortunately, there is no Last-Modified header or ETag header which would allow you to easily determine if there was a change.
Next looking at the content of the API, the author does not provide an obvious version/change date, so no luck there.
What you could do is receive the content as a String, and perform a checksum operation on it, and if it differs you know there has been a change
or if you are deserialising the received JSON in Kotlin data classes, then out of the box, Kotlin will enable you to perform an equality operation on a previous copy of the data to know if there was a change.
This looks like an android app; if so, why don't you create a background service that makes requests to the API and updates the data as needed? You can use an AlarmManager class to set the interval threshold for polling by using the setInexactRepeating() method.
Most apps are updated in this fashion; sometimes, a separate table is created to catalog changesets.
Let me know if this helps.

How to access SAP OData messages in Kapsel offline app?

We are developing an SAP Fiori App to be used on the Launchpad and as an offline-enabled hybrid app as well using the SAP SDK and its Kapsel Plug Ins. One issue we are facing at the moment is the ODATA message handling.
On the Gateway, we are using the Message Manager to add additional information to the response
" ABAP snippet, random Gateway entity method
[...]
DATA(lo_message_container) = me->mo_context->get_message_container( ).
lo_message_container->add_message(
iv_msg_type = /iwbep/cl_cos_logger=>warning
iv_msg_number = '123'
iv_msg_id = 'ZFOO'
).
" optional, only used for 'true' errors
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
message_container = lo_message_container.
In the Fiori app, we can directly access those data from the message manager. The data can be applied to a MessageView control.
// Fiori part (Desktop, online)
var aMessageData = sap.ui.getCore().getMessageManager().getMessageModel().getData();
However, our offline app always has an empty message model. After a sync or flush, the message model is always empty - even after triggering message generating methods in the backend.
The only way to get some kind of messages is to raise a /iwbep/cx_mgw_busi_exception and pass the message container. The messages can be found, in an unparsed state, in the /ErrorArchive entity and be read for further use.
// Hybrid App part, offline, after sync and flush
this.getModel().read("/ErrorArchive", { success: .... })
This approach limits us to negative, "exception worthy", messages only. We also have to code some parts of our app twice (Desktop vs. Offlne App).
So: Is there a "proper" to access those messages after an offline sync and flush?
For analyzing the issue, you might use the tool ILOData as seen in this blog:
Step by Step with the SAP Cloud Platform SDK for Android — Part 6c — Using ILOData
Note, ILOData is part of the Kapsel SDK, so while the blog above was part of a series on the SAP Cloud Platform SDK for Android, it also applies to Kapsel apps.
ILOData is a command line based tool that lets you execute OData requests and queries against an offline store.
It functions as an offline OData client, without the need for an application.
Therefore, it’s a good tool to use to test data from the backend system, as well as verify app behavior.
If a client has a problem with some entries on their device, the offline store from the device can be retrieved using the sendStore method and then ILOData can be used to query the database.
This blog about Kapsel Offline OData plugin might also be helpful.

How to time a function in React Native?

This question suggests using console.time, but that isn't available in React Native. Is there a built in way to measure how long a function call takes, without using any third-party packages?
Using react-native v0.63 (not sure about lower versions), you can use the performance api, which is described in the question you linked in the OP.
var t0 = performance.now()
doSomething() // <---- measured code goes between t0 and t1
var t1 = performance.now()
console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.")
I ran into the same error but managed to fix it easily, just enable debugging on your app to use chrome or react native debugger. From the console of these debuggers, the console.time() and console.timeEnd() is supported and works perfectly
you can use console.time but throw third party packages react-native-console-time-polyfill
otherwise with performance monitor from developer menu Show Perf Monitor

`StreamSocketListener`-based server in Universal App

It is known that Windows 8.1 and Windows Phone 8.1 put lots of constraints on background activities of third-party app. For instance, it is impossible to develop server-like capability (e.g. BitTorrent) in Store App without having to keep the screen always-on using DisplayRequest.
From the latest documentation, I have a feeling that one can utilize the method EnableTransferOwnership of StreamSocketListener to delegate the usual request processing code to a background task. The problem is that I don't know how IBackgroundTask should work in this case. Normally, they are activated by some conditions/triggers such as "Internet becomes available". The only sensible trigger in this case seems to be ControlChannelTrigger but apparently, the documentation implies that it cannot be used with StreamSocketListener since the app needs to be the one who creates and register a StreamSocket, not waiting for the socket to be created by some connecting client.
Is it possible now to implement a StreamSocketListener-based server in Windows 10 Universal app platform? If it is, how can I do that?
Use it to activate a background task on socket activity such as receiving data when the app is not active, e.g.:
var socketTaskBuilder = new BackgroundTaskBuilder();
socketTaskBuilder.Name = "SocketActivityBackgroundTask";
socketTaskBuilder.TaskEntryPoint = "SocketActivityBackgroundTask.SocketActivityTask";
var trigger = new SocketActivityTrigger();
socketTaskBuilder.SetTrigger(trigger);
var task = socketTaskBuilder.Register();
socket = new StreamSocket();
socket.EnableTransferOwnership(task.TaskId, SocketActivityConnectedStandbyAction.Wake);
For a complete example, look at the Socket Activity sample or the documentation.

How can I monitor an application's API calls on a jailbroken iOS device?

I am performing a review on an iOS application for which I do not have the source code. In order to gain more control over the environment, I am running the application on a jailbroken iPad.
I'd like to be able to monitor the API calls that the application is making...ideally I'd like to find something like Rohitab's MS Windows based API Monitor, but instead for iOS.
I have done some research and found a project by KennyTM called "Subjective-C" that seems that it may do what I need. I actually have been using a cycript script, along with the libsubjc.dylib available on the Google code site.
However, I have been unable to figure out how to correctly get it to start logging calls for an app. Here's the link to the cycript script, written by the author of Subjective-C (libsubjc). I pasted the script below as well.
/*
libsubjc.cy ... Use libsubjc in cycript.
Copyright (C) 2009 KennyTM~ <kennytm#gmail.com>
[...GPL3...]
*/
dlopen("libsubjc.dylib", 10);
if (!dlfun) {
function dlfun(fn, encoding, altname) { var f = new Functor(dlsym(RTLD_DEFAULT, fn), encoding); if (f) this[altname || fn] = f; return f; }
}
dlfun("SubjC_start", "v");
dlfun("SubjC_end", "v");
dlfun("SubjC_set_file", "v^{sFILE=}");
dlfun("SubjC_set_maximum_depth", "vI");
dlfun("SubjC_set_print_arguments", "vB");
dlfun("SubjC_set_print_return_value", "vB");
dlfun("SubjC_set_print_timestamp", "vB");
SubjC_Deny = 0, SubjC_Allow = 1;
dlfun("SubjC_clear_filters", "v");
dlfun("SubjC_filter_method", "vi#:");
dlfun("SubjC_filter_class", "vi#");
dlfun("SubjC_filter_selector", "vi:");
dlfun("SubjC_default_filter_type", "vi");
dlfun("SubjC_filter_class_prefixes", "viI^*");
dlfun("SubjC_filter_class_prefix", "vi*");
dlfun("fopen", "^{sFILE=}**");
dlfun("fclose", "i^{sFILE=}");
I have been able to load the libsubjc cycript script, and call the SubjC_start function. However, how do I specify an input filehandle for the line starting with dlfun("SubjC_set_file", "v^{sFILE=}");
Has anyone successfully used the "libsubjc.cy" cycript script with the Subjective-C library (libsubjc.dylib) to monitor an app's API calls?
UPDATE
This is at least generating the output file, but I don't see any information populated within the output file (/tmp/test.txt).
cycript -p SpringBoard libsubjc.cy; cycript -p SpringBoard
f = fopen("/tmp/test.txt", "w");
SubjC_set_file(f);
SubjC_set_maximum_depth(15);
SubjC_set_print_arguments(YES);
SubjC_set_print_return_value(YES);
SubjC_set_print_timestamp(YES);
SubjC_default_filter_type(SubjC_Deny);
SubjC_start();
//do stuff
SubjC_end();
Or, if anyone knows of another way to monitor API calls (w/o source code) on a jailbroken device, please let me know!
I'm not aware of a direct equivalent to API Monitor. However, Frida is a popular tool for mobile app instrumentation, with a tutorial on iOS usage. Once installed, you can trace API calls with a command like frida-trace -U -i "CCCryptorCreate*" Twitter to trace calls from the Twitter app to functions starting with CCCryptorCreate.
Set up a proxy server on your computer to redirect and track all the API calls. This is a common way to peak into iOS web traffic and you don't need a jailbroken device.