Sending data from one app to another thrid party app - android

public void executeApp(ExecuteABCDEvent event) {
PackageManager pm = this.getContext().getPackageManager();
try {
String packageName = "package name here";
Intent launchIntent = pm.getLaunchIntentForPackage(packageName);
this.getContext().startActivity(launchIntent);
} catch (Exception e1) {
Log.d("Exception", e1.getMessage());
}
}
I am opening a 3rd pary application using the above code.
Along with opening of this 3rd party application I also want to populate some text fields.
Solution 1: put and get data from intent.
I cannot user solution 1 as i cannot use the get methods in 3rd party app.
Solution 2: Content provider.I am not sure how content provider of application works and how it helps.
Is there another approach for this.

You have no good way of doing what you want. For obvious security reasons, apps cannot hack into other apps.
You are welcome to create an AccessibilityService and attempt to use that to achieve your ends. I am skeptical that it will work, and even if it does, I am skeptical that many people will install your app, given the large security warnings that are presented when the user goes in to activate your AccessibilityService.

Related

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)

Google Keep list note from inside your app

In my app, I am writing a functionality to share a shopping list to Google Keep. For this, I use the Intent.ACTION_SEND action and set the package to the one of Google Keep.
Everything works great, but I am wondering if it is possible to add an EXTRA parameter to the Intent telling Google Keep it must be displayed as a list with checkboxes, like it is possible to add extra event-specific extra's when creating a Calendar Event. Now, it is displayed as plain text.
Here is my code:
try {
Intent keepIntent = new Intent(Intent.ACTION_SEND);
keepIntent.setType("text/plain");
keepIntent.setPackage("com.google.android.keep");
keepIntent.putExtra(Intent.EXTRA_SUBJECT, "Shopping List " + recipe.getName());
keepIntent.putExtra(Intent.EXTRA_TEXT, "Flower\nyeast\nbutter\nalmonds");
startActivity(keepIntent);
} catch (Exception e) {
Dialogs.toastShort(this, "Google Keep is not installed on your device");
}
Now, I get this as result:
What, I want to get is this as result - without that the user has to select "show checkboxes" in the actionbar:
Thanks for your help.
Unfortunately, it's not possible. Google has not published an API for public nor 3rd party use. If you check out the http traffic you can see the underlying API but there's no real way to replicate it. Sorry

Is there a means to forcefully autodial special numbers on Android?

I've been working on an android app concept in which the app has to auto-dial some special USSD codes in order to initiate certain telco services of interest to the user when the user initiates the service via a shortcut in the app.
The trouble I'm finding is that when the app tries to auto-dial such short codes or USSD numbers, the phone's OS (or is it the Call Intent), doesn't auto-dial, but instead presents the user with the code/number in the dial-pad and so the user has to manually initiate the call - which sort of defeats my intention of allowing users to initiate the services with just one click - the shortcut.
Currently, this is how I'm initiating these calls:
intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + number.trim()));
try {
activity.startActivity(intent);
} catch (Exception e) {
Log.d(Tag, e.getMessage());
}
Interestingly, a number such as +256772777000 will auto-dial, launching the user into the call automatically, but a number/code such as 911, *112#, *1*23#, etc won't.
So, what do I need to do differently, or is this not possible at all?
UPDATE
Actually, looking at another app in which I was autodialling user-specified numbers, the problem with the above code trying to auto-dial ussd codes was that instead of using intent.ACTION_CALL, I was using intent.ACTION_DIAL - which definitely just prompts the user with the number to call, without directly calling it. When I fixed that, the app now works as expected. See answer below...
Code samples are most welcome.
Actually, despite what some people were claiming about Android preventing such a feature. When I looked at the code in one of my older apps which auto-dials user-specified numbers, I found the solution to be:
intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + number.trim()));
try {
activity.startActivity(intent);
} catch (Exception e) {
Log.d(Tag, e.getMessage());
}
This works as expected - USSD codes get auto-dialled when above code runs. The only important thing to note when using this approach, being that you have to add the following permissions to your manifest:
<uses-permission android:name="android.permission.CALL_PHONE" />
So, as indicated in the update to my question, the problem with my original approach was using intent.ACTION_DIAL instead of intent.ACTION_CALL.

How can I do an Amazon App Store search using an Intent and filter it by developer name?

Is there a way to start an Intent on the Kindle Fire that will cause the AppStore app to open and display all the apps for a certain developer? For instance, on a phone/tablet with the Android Market installed, I can do this:
Intent otherApps = new Intent(Intent.ACTION_VIEW,Uri.parse("market://search?q=pub:\"" + developerName + "\""));
activity.startActivity(otherApps);
And show all my apps in the Android Market. Can I do that with the Amazon App Store? If so, how? I've tried that Intent with other seemingly valid names (such as "ZeptoLab") and I don't get any filtering. It just drops me in the full unfiltered App Store. Looking up a specific app with "market://details?id=package.name" does seem to work.
From https://developer.amazon.com/help/faq.html#Marketing:
To point to your app for marketing purposes use the URL http://www.amazon.com/gp/mas/dl/android?p=packagename (where packagename is your app package name).
If you want to link to the list of all your applications on the Amazon Appstore use the URL http://www.amazon.com/gp/mas/dl/android?p=packagename&showAll=1.
e.g. http://www.amazon.com/gp/mas/dl/android?p=com.rovio.angrybirds&showAll=1
All this can be seen here: https://developer.amazon.com/sdk/in-app-purchasing/sample-code/deeplink.html
Update(deep linking):
amzn://apps/android?p=
Best way is to look at their website (or here), which currently states this :
search: amzn://apps/android?s=amazon%20mp3 or http://www.amazon.com/gp/mas/dl/android?s=amazon%20mp3
detail page using package name: amzn://apps/android?p=com.amazon.mp3 or http://www.amazon.com/gp/mas/dl/android?p=com.amazon.mp3
detail page using unique ID ("asin") : amzn://apps/android?asin=B004FRX0MY or http://www.amazon.com/gp/mas/dl/android?asin=B004FRX0MY
show all apps of the developer who made the app: amzn://apps/android?p=com.amazon.mp3&showAll=1 or http://www.amazon.com/gp/mas/dl/android?p=com.amazon.mp3&showAll=1
Amazon supports their own deep links now: https://developer.amazon.com/appsandservices/apis/earn/in-app-purchasing/docs/deeplink
E.g. you can start an intent with uri amzn://apps/android?p=my.package.name.
From - https://developer.amazon.com/help/tuabg.html
For in-app advertising or mobile browser based linking, please:
Use this link structure: http:// www.amazon.com/gp/mas/dl/android?p=com.example.package/ref=mas_pm_app_name
For a link that directs to a list of all of your apps within our U.S. store, please:
Use this link structure: http://www.amazon.com/gp/mas/dl/android?p=com.example.package&showAll=1
Now, you think amazon would have this correct on their own website, but the first part that I put in bold is wrong. This is what it should actually be:
http://www.amazon.com/gp/mas/dl/android?p=com.example.package&ref=mas_pm_app_name
Notice the & instead of the / between the package name and ref. Hopefully this helps some other people since this little detail wasted some of my time...
Here's the solution I came up with using the advice below from chiuki:
I added a boolean to one of my resource files that indicates whether or not the app is published in the Amazon AppStore or Android Market. Yeah, you have to change it whenever you publish your app, but think of it sort of like remembering to set debuggable to "false" when you publish. Put it on a check list. It goes like this:
In resource file:
<bool name="app_is_in_amazon_app_store">true< /bool>
In code:
public class SomeUtil
{
private static Boolean isInAmazonAppStore;
public static boolean isInAmazonAppStore(Activity activity)
{
if (isInAmazonAppStore == null)
{
isInAmazonAppStore = activity.getResources().getBoolean(R.bool.app_is_in_amazon_app_store) ;
}
return isInAmazonAppStore;
}
public static void startOtherMarketAppsActivity(Activity activity)
{
try
{
Intent otherApps = null;
if (isInAmazonAppStore(activity))
{
otherApps = new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.amazon.com/gp/mas/dl/android?p=" + getPackageNameInAmazonAppStore(activity) + "&showAll=1"));
}
else
{
otherApps = new Intent(Intent.ACTION_VIEW,Uri.parse("market://search?q=pub:\"" + getAndroidDeveloperName(activity) + "\""));
}
activity.startActivity(otherApps);
}
catch(Exception ex){ /* error handling */}
}

How to programatically hide Caller ID on Android

on Android phones, under Call -> Additional settings -> Caller ID
it is possible to hide your caller ID. I want to do that programatically from my code, but was not able to find a way to do that.
I searched through
android.provider
android.telephony
for 2.1 release and was not able to find it.
Has anybody successfully solved this issue?
Thanks in advance. Best regards.
Here I will describe two approaches I tried.
1.) It is possible to display Additional Call Settings screen from your application. Although it looks like it is part of the Settings application, that is not true. This Activity is part of the Native Phone Application, and it may be approached with the following intent:
Intent additionalCallSettingsIntent = new Intent("android.intent.action.MAIN");
ComponentName distantActivity = new ComponentName("com.android.phone", "com.android.phone.GsmUmtsAdditionalCallOptions");
additionalCallSettingsIntent.setComponent(distantActivity);
startActivity(additionalCallSettingsIntent);
Then user has to manually press on the CallerID preference and gets radio button with 3 options.
This was not actually what I wanted to achieve when I asked this question. I wanted to avoid step where user has to select any further options.
2.) When approach described under 1.) is executed in the Native Phone Application, function setOutgoingCallerIdDisplay() from com.android.internal.telephony.Phone has been used.
This was the basis for the next approach: use Java Reflection on this class and try to invoke the function with appropriate parameters:
try
{
Class <?> phoneFactoryClass = Class.forName("com.android.internal.telephony.PhoneFactory");
try
{
Method getDefaultPhoneMethod = phoneFactoryClass.getDeclaredMethod("getDefaultPhone");
Method makeDefaultPhoneMethod = phoneFactoryClass.getMethod("makeDefaultPhone" , Context.class);
try
{
makeDefaultPhoneMethod.invoke(null, this);
Object defaultPhone = getDefaultPhoneMethod.invoke(null);
Class <?> phoneInterface = Class.forName("com.android.internal.telephony.Phone");
Method getPhoneServiceMethod = phoneInterface.getMethod("setOutgoingCallerIdDisplay", int.class, Message.class);
getPhoneServiceMethod.invoke(defaultPhone, 1, null);
}
catch (InvocationTargetException ex)
{
ex.printStackTrace();
}
catch (IllegalAccessException ex)
{
ex.printStackTrace();
}
}
catch (NoSuchMethodException ex)
{
ex.printStackTrace();
}
}
catch (ClassNotFoundException ex)
{
ex.printStackTrace();
}
Firstly I tried just to use getDefaultPhone(), but I get RuntimeException
"PhoneFactory.getDefaultPhone must be called from Looper thread"
Obviously, issue lies in the fact that I tried to call this method from the Message Loop that was not the Native Phone App one.
Tried to avoid this by making own default phone, but this was a security violation:
ERROR/AndroidRuntime(2338): java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.provider.Telephony.SPN_STRINGS_UPDATED from pid=2338, uid=10048
The only way to overcome (both of) this would be to sign your app with the same key as the core systems app, as described under
Run secure API calls as root, android
I'm not sure if this is a global feature, but Australian phones can hide their number by prefixing the caller's number with #31# or 1831. This may not be the perfect solution, but a prefix like this could possibly work for your requirements during coding.

Categories

Resources