On iPhone, an application can associate a new protocol name to itself so that if a user types in 'myapp://xxx' in a web browser it calls the application.
Is this possible with BlackBerry or Android?
For Android have a look at this question's answers:
Android Respond To URL in Intent
and also the following page especially in the section "Data Types" about android:scheme on this page:
http://developer.android.com/guide/topics/intents/intents-filters.html
For your app you would put something like the following in your AndroidManifest.xml:
<intent-filter><action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:scheme="myapp"></data>
</intent-filter>
For BlackBerry - yes, to an extent, look at the net.rim.device.api.browser.plugin package (JDE 4.0.0 and later). It allows you to specify a callback interface for a given MIME type & other parameters.
Basically you subclass BrowserContentProvider to indicate the MIME type(s) you want to receive, and register with BrowserContentProviderRegistery.
I don't have a lot of experience with this - but it looks like you may be limited to providing custom rendering functionality - that may be ok for you. I'm not sure how limited your ability to do anything else would be - you'd have to try things out.
For blackberry devices running 4.0 or later (all "trackball" devices and up run at least 4.2) the following code is all you need:
// Get the default sessionBrowserSession
net.rim.blackberry.api.browser.browserSession = Browser.getDefaultSession();
// now launch the URL
browserSession.displayPage("http://www.BlackBerry.com");
Since this is a pretty reusable code segment I recommend placing it the following function:
public static void loadURL(String url)
{
try{
net.rim.blackberry.api.browser.BrowserSession bSession = net.rim.blackberry.api.browser.Browser.getDefaultSession();
bSession.displayPage(url);
bSession.showBrowser();
}
catch (Exception ex){
System.out.println("Error loading url [" + url + "]: " + ex.getMessage());
}
}
Related
I need to get action name of intent filter located in service tags from specified installed package name.
Actually, this issue may related to parsing AndroidManifest.xml file, but I want to use relevant functions/classes provided by Android to get action name instead of parsing xml directly.
Well, to put it more clearly;
I am writing a code that gets installed apps and then filters media apps.
When I compare manifest files of some media applications, I figured out that the common thing they use "android.media.browse.MediaBrowserService" action name. So, I thought I could create a filter by looking for this service action name.
Here is a sample snippet from AndroidManifest.xml:
...
<service
android:name="com.example.mediabrowser.XXXMediaBrowserService"
android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
...
I hope everything has been well understood so far.
After realizing all this stuff, I pulled the services name from the installed package name by filtering Intent.ACTION_MAIN.
final List<PackageInfo> packages = pm.getInstalledPackages(0);
for(PackageInfo pi : packages)
{
pi = getPackageManager().getPackageInfo(pi.packageName, PackageManager.GET_SERVICES);
Log.e("SERVICES: ", pi.packageName + Arrays.toString(pi.services));
}
This code just presents me the service list. So I was able to capture the service name "com.example.mediabrowser.XXXMediaBrowserService" in the AndroidManifest.xml that I mentioned above.
My purpose is to pull the action name (android.media.browse.MediaBrowserService) that belongs to in this service. I tried a few methods on how to do this, but I couldn't get any results.
Have a nice day.
Good news!
The solution is here,
final Intent providerIntent = new Intent(MediaBrowserService.SERVICE_INTERFACE);
List<ResolveInfo> mediaApps = pm.queryIntentServices(providerIntent, 0);
for (ResolveInfo info : mediaApps) {
Log.e("MEDIA APPS: ", String.valueOf((info.serviceInfo.packageName)));
}
Best regards...
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)
I used SpeechRecognizer on android to recognize the User's voice.
It worked well until uninstall the Google App.
(https://play.google.com/store/apps/details?id=com.google.android.googlequicksearchbox&hl=en)
I updated the Google App, but I got errors such as "bind to recognition service failed".
How can I make the app run successfully?
What should I do to use SpeechRecognizer normally?
Thanks.
Update manifest
I'm using Algolia's voice input library and it was failing to take voice input on Pixel 2 and android 11 devices. The reason being unable to bind to voice recognition service.
To solve it, In the manifest file, insert this query element just under your opening tag:
<queries>
<package android:name="com.google.android.googlequicksearchbox"/>
</queries>
I know I am answering this a bit late but I have struggled with this error for a while now. It turns out you need to activate Google's Quick Search Box. So the solution I used is: I check if the SpeechRecognizer is available (using isRecognitionAvailable(context)). If the SpeechRecognizer is not available, you can activate it like this :
if(!SpeechRecognizer.isRecognitionAvailable(mainActivity)){
String appPackageName = "com.google.android.googlequicksearchbox";
try {
mainActivity.startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=" + appPackageName)));
} catch (android.content.ActivityNotFoundException anfe) {
mainActivity.startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
}
Every time the Google app is updated some way or the other there is always an issue with the speech recognizer callbacks. Either Google periodically changes their timeout clause or some weird issues like yours pops out of nowhere.
You need to make your code dynamic in such a way that even if there is an error in the speech callback methods, you need to catch that error and try listening again automatically. This has been discussed widely in this post and there are plenty of answers provided for you to check and implement them based on your requirement.
If you don't want this you can always try out DroidSpeech library which takes care of these speech error issues whenever something pops up and provides you with continuous voice recognition.
Just implement the library using Gradle and add the following lines of code.
DroidSpeech droidSpeech = new DroidSpeech(this, null);
droidSpeech.setOnDroidSpeechListener(this);
To start listening to the user call the below code,
droidSpeech.startDroidSpeechRecognition();
And you will get the voice result in the listener method,
#Override
public void onDroidSpeechFinalResult(String
finalSpeechResult, boolean droidSpeechWillListen)
{
}
You need to add this in the manifest like so:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
**<queries>
<intent>
<action android:name="android.speech.RecognitionService" />
</intent>
</queries>**
According to the system voice command docs, you can open an application with a voice command. e.g. OK Google - open foobar. Also according to the docs, this Works by default; no specific intent.
In my sample development app, this isn't working. I've tried adding a few combinations of action and category permutations to the intent-filter, but no luck so far.
I'm targeting a minimum SDK of 23, testing on a device with 6.0.1.
Should this work, and if so, what are the changes to a new empty activity project I need to enable it?
As far as I am aware, Google simply iterates over a list of installed applications and opens the corresponding application if it finds an exact match.
To test this, use the following Intent
final String PACKAGE_NAME_GOOGLE_NOW = "com.google.android.googlequicksearchbox";
final String GOOGLE_NOW_SEARCH_ACTIVITY = ".SearchActivity";
final String APP_NAME = "Open " +getString(R.string.app_name);
final Intent startMyAppIntent = new Intent(Intent.ACTION_WEB_SEARCH);
startMyAppIntent.setComponent(new ComponentName(PACKAGE_NAME_GOOGLE_NOW,
PACKAGE_NAME_GOOGLE_NOW + GOOGLE_NOW_SEARCH_ACTIVITY));
startMyAppIntent.putExtra(SearchManager.QUERY, APP_NAME);
startMyAppIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(startMyAppIntent);
} catch (final ActivityNotFoundException e) {
e.printStackTrace();
}
If this opens your application, then it is simply a case of the phonetics of your application name, or how Google interprets your pronunciation of it.
I do think that there should be an option to add a 'phonetic app label' to the application's manifest (or some other globally available configuration file), so Google could open your application if the unique name is not common enough to generate a voice search result.
If this doesn't open your application, check that you are correctly defining your application name in the manifest as follows:
<application
android:label="#string/app_name"
I've written an Android client for a mobile backend starter app according to this tutorial. Everything works up to the section implementing Continuous Queries.
I've written a query and I'm calling it from the correct place in the code (onPostCreate()), however the query never returns any data.
I don't believe this is an authentication problem because I'm able to make other calls successfully.
Here is the code which never returns a result:
CloudCallbackHandler<List<CloudEntity>> handler = new CloudCallbackHandler<List<CloudEntity>>() {
#Override
public void onComplete(List<CloudEntity> results) {
for (CloudEntity entity : results) {
UserLocation loc = new UserLocation(entity);
mUserLocations.remove(loc);
mUserLocations.add(loc);
drawMarkers();
}
}
#Override
public void onError(IOException e) {
Toast.makeText(getApplicationContext(), e.getMessage(),
Toast.LENGTH_LONG).show();
}
};
CloudQuery query = new CloudQuery("UserLocation");
query.setLimit(50);
query.setSort(CloudEntity.PROP_UPDATED_AT, Order.DESC);
query.setScope(Scope.FUTURE_AND_PAST);
getCloudBackend().list(query, handler);
With the debugger I've verified that the getCloudBackend().list() line executes, but the onComplete() method is never hit, and neither is onError().
Here is an example of a call that works perfectly:
UserLocation self = new UserLocation(super.getAccountName(),
gh.encode(mCurrentLocation));
getCloudBackend().update(self.asEntity(), updateHandler);
Essentially, getCloudBackend().update() works, while getCloudBackend().list() does not.
I should also add that I've downloaded the full source from the github repo linked in the tutorial, and the same problem exists with that code.
I've also tried re-deploying the backend server multiple times.
Ok so I have finally fixed the problem! The issue is both in the manifest and in the class GCMIntentService.java
In the manifest the GCM is registered as a service and belongs to a package. By default this service is a part of the default package com.google.cloud.backend.android. When you create a new package and have all your client code in there, you need to move the GCMIntentService.java class into that new package and in the manifest modify the service and broadcast receiver
<service android:name="yourpackagename.GCMIntentService" />
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="yourpackagename" />
</intent-filter>
</receiver>
Any other permission that comes with the default package name should also be updated to the main package name. This doesn't need to be modified if you're only going to use that one default package that comes with the mobile backend starter.
Regarding the GoogleAuthIOException I received that as well initially. So I redid all the steps to enable GCM and authentication. Things to keep in mind though are that I still followed the tutorial and went with Web Application -> Generic when registering the GCM server key and Web Client ID. Also another key thing to keep in mind when registering for the Android Client ID is that with your SHA1 fingerprint it also needs a package name. Again the package name has to be your main client package if you're using more than one package for your project. You can get the project number that goes in the Consts.java (and it's required to register GCM) from the old Google API console and the project ID from the new cloud console. The Web client ID also goes in the Consts.java file and also in that same file you have to enable auth by changing
public static final boolean IS_AUTH_ENABLED = false;
to
public static final boolean IS_AUTH_ENABLED = true;
Hope this helps.
So I am also getting the SAME EXACT problem you are. getCloudBackend().update() works for me, and not only with the geohasher class, I also tried to send updates to the cloud with myLocation.toString() where myLocation is a LatLng and it gets updated fine.
Sorry for not giving you the actual solution to your problem. It's a really odd situation that the same exact code worked in the Google I/O demo but not when we (and I followed the tutorial very thoroughly) actually try it out. I feel that this is a server problem if anything.
Thanks for reporting this -- sorry you are having a problem. THe most likely problem is in configuring GCM. Can you verify you have GCM enabled on the project and all the setup steps where done correctly? Maybe try to send a message and see if that works?