How to send a website to a second activity in kotlin? - android

I am trying to create an application that allows sending any website as data, but when I write the address it does not load in the second activity.
Note: in the manifest I already put this code <uses-permission android: name = "android.permission.INTERNET" />
This is my code
MainActivity
bt_ir.setOnClickListener {
val sitio = pt_sitio.text.toString()
val inten = Intent (this, MainActivity2_Webview::class.java)
inten.putExtra("Clave", sitio)
startActivity(inten)
}
Second Activity
val intent = intent
val name = intent.getStringExtra("Clave")
wv_sitio.loadUrl("http//:${name}")
bt_atras.setOnClickListener {
finish()
}

You have a typo in your URL string after http, it should be :// instead of //:
As well as that, if you're using http instead of https, you might need to set usesCleartextTraffic in the manifest to true - this was the default before API 28, if you target 28+ it defaults to false and you have to explicitly enable it.
There's also a more complex system with a Network security configuration if you want more fine control over which sites are allowed through.
Depending on what's going on in your WebView, you might need use setMixedContentMode to ALWAYS_ALLOW or something - this is a security problem, so using https would be better, but that's up to you!

Related

Android: Can explicit intents work without adding QUERY_ALL_PACKAGES (or package under queries tag) to my manifest?

I have small code which makes sure a url is always opened in browser. It is working so far.
Recently, I got message from Google Play Console stating:
If your app requires the QUERY_ALL_PACKAGES permission, you need to
submit the declaration form in Play Console by July 12
I have checked and verified, we don't use QUERY_ALL_PACKAGES in my app. However, we use Explicit Intents and resolveActivity in few places. One of the code (I took it from this place) is:
override fun openInBrowser(url: String) {
val dummyIntent = Intent(Intent.ACTION_VIEW, Uri.parse("http://"))
val resolveInfo = context.packageManager.resolveActivity(dummyIntent, PackageManager.MATCH_DEFAULT_ONLY)
val browserPackageName = resolveInfo?.activityInfo?.packageName
val realIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
if (browserPackageName != null && browserPackageName.isNotBlank() && browserPackageName != "android") {
realIntent.setPackage(browserPackageName)
}
startActivity(context, realIntent, null)
}
I am not sure if it falls under the category of querying a package. I have gone through this link and as per my understanding I don't need to add either package under queries tag or QUERY_ALL_PACKAGES. I just want to validate my understanding.
The limited app visibility affects the return results of methods that give information about other apps, such as queryIntentActivities(), getPackageInfo(), and getInstalledApplications(). The limited visibility also affects explicit interactions with other apps, such as starting another app's service.
Some packages are still visible automatically. Your app can always see these packages in its queries for other installed apps. To view other packages, declare your app's need for increased package visibility using the element. The use cases page provides examples for common app interaction scenarios.

How do I set up assistant shortcut suggestions with actions.intent.OPEN_APP_FEATURE?

So I'm just wondering why my code isn't working. How do I give AppShorcutIntent a specific intent with an action and data and stuff like that?
This is my code so far:
val appShortcutIntent = AppShortcutIntent.builder()
.setIntentName("actions.intent.OPEN_APP_FEATURE")
.setPackageName("com.app.name")
.setIntentParamName("feature")
.setIntentParamValue("")
.build()
shortcutsClient.lookupShortcut(appShortcutIntent)
.addOnSuccessListener { shortcutLookupResult ->
if (shortcutLookupResult.isShortcutPresent) {
shortcutsClient.createShortcutSettingsIntent().addOnSuccessListener { intent ->
requireActivity().startActivity(intent)
}
return#addOnSuccessListener
}
val signalShortcut = AppShortcutSuggestion.builder()
.setAppShortcutIntent(appShortcutIntent)
.setCommand("feature on")
.build()
shortcutsClient.createShortcutSuggestionIntent(signalShortcut).addOnSuccessListener { intent ->
requireActivity().startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
}
}
I have tried so many different things and none of it seems to want to work the way I want. I know the question doesn't have anything specific as the parameter value but no matter what I set the param value too it still just doesn't get recognized as a unique intent when I use the shortcut.
The in-app promo library API doesn't deal with Android intents. It deals with Assistant's built-in intents, which are an entirely different things (even though they are both called "intents"). In the example you copied, it refers to the BII called OPEN_APP_FEATURE.
By using this API, you are telling Assistant how to create a shortcut that launches the app using a BII that it is already configured to handle. This BII is important because it carries the ability to recognize natural language queries associated with it. Android intents don't have that context.

NFC-tag password protection with ST25 android SDK

I'm working with ST25 tags, more specifically type5 tags ST25DV64K. The ST25 SDK for android has some interesting examples and tutorials in it. I'm still struggling to use the code example provided at the end of the doc here concerning password-protected data, which consist in those lines:
byte[] password;
int passwordNumber = type5Tag.getPasswordNumber(area);
tag.presentPassword(passwordNumber, password);
NDEFMsg ndefMsg = myTag.readNdefMessage(area);
first problem, when I instanciate a type5 tag i don't see those methods for Type5Tag class:
import com.st.st25sdk.type5.*;
Type5Tag tag5;
tag5.??
Then, it is not clear how we are supposed to set up a password in the first place. I can't find any examples of setting up a password for a specific area, and removing it, and what is the format of the password that we can use? Is it possible to do this from android or do we have to use the ST25 app? Examples welcome! Thanks.
In the ST25 SDK Zip file, you will find an example of a basic Android App using the ST25 SDK Library (it is in \integration\android\examples\ST25AndroidDemoApp).
This example uses a class called “TagDiscovery” which is able to identify any ST25 Tag and to instantiate the right object. In your case, if you are only using ST25DV64K Tags, you will probably want to do something simple.
Here is what I suggest you:
In your android activity, I expect that you have subscribed to receive a notification every time an NFC tag is taped (in “ST25AndroidDemoApp” example, look at enableForegroundDispatch() in onResume() function).
To identify if the Intent corresponds to an “NFC Intent”, we check if the Intent’s Action is ACTION_NDEF_DISCOVERED, or ACTION_TECH_DISCOVERED or ACTION_TAG_DISCOVERED.
When this is the case, we know that it is an NFC Intent. We can then call this to get the instance of androidTag:
Tag androidTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
This object represents the current NFC tag in Android.
We’re now going to instantiate a ST25DVTag object.
import com.st.st25sdk.type5.st25dv.ST25DVTag;
…
AndroidReaderInterface readerInterface = AndroidReaderInterface.newInstance(androidTag);
byte[] uid = androidTag.getId();
uid = Helper.reverseByteArray(uid);
ST25DVTag myST25DVTag = new ST25DVTag(readerInterface, uid);
You now have an object called myST25DVTag that can be used to communicate with the tag!
For example, if you want to use the passwords:
byte[] password = new byte[]; // TODO: Fill the password
int passwordNumber = myST25DVTag.getPasswordNumber(area);
myST25DVTag.presentPassword(passwordNumber, password);
NDEFMsg ndefMsg = myST25DVTag.readNdefMessage(area);
Before doing that, you need to check which password is associated to this area. The tag has 3 passwords that can be freely assigned to any area. By default no password is set so you should set one. Here is an example where I use the password 2 for Area1:
int AREA1 = 1;
int passwordChosen = 2;
myST25DVTag.setPasswordNumber(AREA1, passwordChosen);
I suggest that you install the ”ST25 NFC Tap” Android App from Google Play: https://play.google.com/store/apps/details?id=com.st.st25nfc&hl=fr&gl=US
If you tap you ST25DV and go to the “Areas Security Status” menu, you will be able to see: the number of areas, which ones are protected by password for read and/or write, which password is used…etc
If you are interested, the source code of this application is available here: https://www.st.com/en/embedded-software/stsw-st25001.html
Tell me if something is unclear.
Disclaimer: I am on of the development team for the ST25 SDK.

How can I return an app to the foreground, considering the new security changes in API 29?

I have an app that makes an http request via the localhost to a separate, third-party app which I do not control, and waits for a response from that call before continuing. The workflow goes like this:
User is inside my app
User presses a button, which launches and calls out to the third-party application
User interacts with the third-party application
When the third-party application finishes its work, my app picks up the completed http response, and pulls itself back to the forefront via MoveTaskToFront for the user to continue working.
This functions properly in Android 9 and below, but the last step does not work in Android 10, I believe due to the new restrictions on launching activities from the background.
I have no control over the third-party app, so I cannot modify it to close itself when finished working, or request that the calling app be returned to the foreground when appropriate. Does anyone know of a workaround for this?
Edit: as requested, I've added the code snippet with the call out. This is a Xamarin project, so it's written in C#, but this particular code section is Android-platform-specific, so I am able to make Android system calls.
First I have to bring up the third-party app:
Intent intent = CrossCurrentActivity.Current.AppContext.PackageManager.GetLaunchIntentForPackage("com.bbpos.android.tsys");
if (intent != null)
{
// We found the activity now start the activity
intent.AddFlags(ActivityFlags.ClearTask);
CrossCurrentActivity.Current.AppContext.StartActivity(intent);
}
Then I call into it via the localhost, process the response, and want to switch back to my app.
using (var client = new HttpClient())
{
// by calling .Result we're forcing synchronicity
var response = client.GetAsync("http://127.0.0.1:8080/v2/pos?TransportKey=" + pTransportKey + "&Format=JSON").Result;
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
// as above, forcing synchronicity
string responseString = responseContent.ReadAsStringAsync().Result;
var result = JsonConvert.DeserializeObject<GeniusTransactionResponse>(responseString);
var manager = (ActivityManager)Application.Context.GetSystemService(Context.ActivityService);
var test = manager.AppTasks.First().TaskInfo.Id;
manager.AppTasks.First().MoveToFront();
//manager.MoveTaskToFront(CrossCurrentActivity.Current.Activity.TaskId, 0);
return result;
}
else
{
return null;
}
}
Quick update in case anyone else has this same issue: I was able to work around this by adding an Accessibility Service to the project. Simply having an Accessibility Service registered and enabled by the user allows MoveTaskToFront to function as it did in APIs <29; the actual service doesn't need to do anything.

How to open Android Outlook application from an external one

I'm currently developing an Android application in order to display home screen widgets. Those ones are related to Microsoft Outlook (Events + Messages) in order to show incoming events and unread new messages in a kind of dynamic tiles.
The Msal graph library helps me a lot to authenticate and retrieve in formations which contains an identifier for each event / message results
But now I want to know if the outlook application is installed on the user device and if there is a way to open Outlook when the user click on the widget. Moreover if the user can open the corresponding clicked event or message with the identifier.
For example the Event widget currently displaying a birthday event. The user click on it. Then it opens Outlook and display directly that birthday event.
Regards
I don't think this is officially documented somewhere. But here's what you can do to find out about it.
You can list all Microsoft applications installed on your device...
val packages = context.packageManager
.getInstalledApplications(PackageManager.GET_META_DATA)
for (info in packages) {
if(info.packageName.startsWith("com.microsoft", true)){
Log.d("package name:" + info.packageName)
Log.d("Launch Activity: " + context.packageManager.getLaunchIntentForPackage(info.packageName))
}
}
Take a note of the "launch intent" displayed in the LogCat. You can use that to launch Outlook. Just make sure you don't hard-code those values because Microsoft can change those values at any point, for example the activity class can change. So, instead of doing this...
context.startActivity(
Intent().apply {
action = Intent.ACTION_MAIN
addCategory(Intent.CATEGORY_LAUNCHER)
setPackage("com.microsoft.office.outlook")
component = ComponentName("com.microsoft.office.outlook", "com.microsoft.office.outlook.MainActivity")
}
)
Do this...
context.startActivity(
Intent().apply {
action = Intent.ACTION_MAIN
addCategory(Intent.CATEGORY_LAUNCHER)
component = ComponentName(
outlookLaunchIntent?.component?.packageName,
outlookLaunchIntent?.component?.className
)
setPackage(outlookLaunchIntent.package)
}
)
Also, remember that getLaunchIntentForPackage and component can return null, so make sure you check for null values properly
I am relaying a suggestion from a couple of internal folks:
Please try to open the event using one of the following URLs:
ms-outlook://events/open?restid=%s&account=test#om.com (if you have a regular REST id)
ms-outlook://events/open?immutableid=%s&account=test#om.com (if you are using an immutable id)
Since immutable IDs are still in preview stage in Microsoft Graph, and customers should not use preview APIs in their production apps, I think option #1 applies to your case.
Please reply here if the URL works, or not, and if you have other related questions. I requested the couple of folks to keep an eye on this thread as well.
Well, i managed to open the outlook android application with the help of your code #Leo. As im not developping with Kotlin, ill post the JAVA code below :
Intent outlookLaunchIntent = context.getPackageManager().getLaunchIntentForPackage("com.microsoft.office.outlook");
if (outlookLaunchIntent != null) {
context.startActivity(outlookLaunchIntent );
}
Below code to open event/message in a web browser provided by webLink property of the graph API. (I only test for event and the url provided not working. Ill post a new issue on StackOverFlow for that but you already see the issue over there : https://github.com/microsoftgraph/microsoft-graph-docs/issues/4203
try {
Intent webIntent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse(calendarWebLink));
webIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(webIntent);
} catch (RuntimeException e) {
// The url is invalid, maybe missing http://
e.printStackTrace();
}
However im still stuck on the decicive goal of my widget item click which is to open the relative event/email in the Microsoft Outlook Android application.
Microsoft Outlook Android app contains widgets which can achieve what im looking for. So i wonder if it is possible to list its broadcast receivers.
The best thing i found is an old manifest for that app but it doesnt help me.
https://gist.github.com/RyPope/df0e61f477af4b73865cd72bdaa7d8c2
Hi may you try to open the event using one of the url:
ms-outlook://events/open?restid=%s&account=test#om.com (If the
user is having rest id)
ms-outlook://events/open?immutableid=%s&account=test#om.com (If
the user is having immutable id)

Categories

Resources