Prevent a process from starting and block its launching - android

My problem is the next :
When an user hold search's button on an android phone, and this, while a progress bar is in action, the following error message is displayed:
ERROR / AndroidRuntime ( 16794 ): java.lang. SecurityException: Requesting codes from com.google.android.voicesearch (with uid 10028) to be run in process com.xxxx.myApplication (with uid 10088)
Thus, further to this message I tried several things: kill the process ' com.google.android.voicesearch ' :
JAVA code :
if (event.getKeyCode() == KeyEvent.KEYCODE_SEARCH)
{
if (!event.isLongPress() && !Utils.getMyProgress().isShowing())
{
searchProducts();
}
else
{
android.os.Process.killProcess(android.os.Process.getUidForName("com.google.android.voicesearch"));
}
return true;
}
Unsuccessfully! Thus the idea is to prevent the process 'com.google.android.voicesearch' from being started
every time the user of the telephone maintainings for a long time the key(touch) "to look for" of its telephone (example on htc, this key(touch) exists. Rather, a physical and not tactile key(touch)!)
Maybe is it possible to block the launch of this process ('com.google.android.voicesearch') in the in the manifest.xml, while my application is launched :
manifest.xml :
<application
android:debuggable="false"
android:enabled="false"
android:killAfterRestore="false"
android:process="com.google.android.voicesearch">
</application>
Any idea ?
Thanks for answers !

In order to implement search with assistance from the Android system (to deliver search queries to an activity and provide search suggestions), your application must provide a search configuration in the form of an XML file called the searchable configuration. It configures certain UI aspects of the search dialog or widget and defines how features such as suggestions and voice search behave. This file is traditionally named searchable.xml and must be saved in the res/xml/ project directory.
According to this page, you only have to remove the voice entries from that file.

Related

Android Studio - showing new activity over other apps results in a blackscreen

I'm trying to develop an android app for the SDK version 30 that (when a button is clicked) starts listening to what apps are opened on the phone. If it detects the user opening Whatsapp, it is supposed to show a LockScreen activity over Whatsapp that makes you answer a math question before being able to use Whatsapp.
I know this can be done as their are apps like QualityTime or Forest that have similar features to restrict you from using certain apps, but I am a newbie when it comes to programming (probably obvious from my code) and feel totally stuck.
I have already figured out how to detect what app the user opened in the last second with code from stack overflow:
public String getCurrentApp() {
String topPackageName = "None";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager mUsageStatsManager = (UsageStatsManager) getSystemService("usagestats");
long time = System.currentTimeMillis();
List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1, time);
// Sort the stats by the last time used
if (stats != null) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : stats) {
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (!mySortedMap.isEmpty())
{
topPackageName = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
}
return topPackageName;
}
I have another function that is started when the user clicks the button in my app to "activate" the listening process. This function keeps checking if the user opens Whatsapp and is then supposed to display the Lockscreen activity on top:
public void startListening(View view)
{
System.out.println("Lock activated.");
while (activated) {
String currentlyRunningApp;
currentlyRunningApp = getCurrentApp();
if (currentlyRunningApp.equals("com.whatsapp"))
{
System.out.println("Whatsapp detected. Showing Lockscreen...");
Intent i = new Intent(this,LockScreen.class);
startActivity(i);
}
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
(All of the code I have shown is in my MainActivity btw.)
I have the following permissions granted to my app:
android.permission.PACKAGE_USAGE_STATS (for the getCurrentApp() function)
android.permission.SYSTEM_ALERT_WINDOW (as suggested here)
android.permission.ACTION_MANAGE_OVERLAY_PERMISSION (although I am not sure I even need this one)
My problem is, that instead of showing the Lockscreen activity I created, it only shows a blackscreen for the user. The Lockscreen activity itself works fine if I let the user open it through a button on the mainActivity, so the issue seems to really be that I can not properly show an activity if my app is running in the background and I want to display it on top of Whatsapp.
I have tried to look through similar questions, but all of the posts on here with similar use cases seem to be very old and outdated (i.e. this or this), as the newer versions seem to have way tighter security restrictions.
I also tried to do it with a screen overlay instead of an activity (using this source), but this doesn't even give me a blackscreen - just does nothing...
I am also aware that there are probably better ways to program the whole "listening and checking for whatsapp" part - i.e. with a service instead of a while-loop or something, but I only found out about services while researching this problem and I'd like to fix the blackscreen issue first.
After lots of trial and error I figured out that the issues was indeed caused by a missing permission, but one that I could not find on any stack overflow answer related to black screen problems. On top of that, I believe it's an issue that only occurred because I used a Xiaomi device for testing.
There are currently two separate permissions for displaying screens over other apps that you will need to grant:
Display over other apps, also called Display pop-up window. This is the android.permission.ACTION_MANAGE_OVERLAY_PERMISSION that I wasn't sure was even needed. So to emphasize, I definetly do need this permission.
Display pop-up windows while running in the background. This is the permission I was missing.
After I allowed them both (which you can do under Settings > Apps > Manage Apps > Your App > Other Permissions) everything worked fine.
To direct the user directly to the settings menu where they can allow these permissions, I used the code from this stack overflow answer. This is also where I got the info that it's a xiaomi-specific "issue".

Pepper Robot - How to launch tablet applications through DialogFlow?

I'm trying to incorporate Pepper's built in Android tablet more in DialogFlow interactions. Particularly, my goal is to open applications installed on the tablet itself for people to use while they're talking with Pepper. I'm aware there is a 'j-tablet-browser' app installed on Pepper's end that can let a person browse the tablet like an ordinary Android device, but I would like to take it one step further and directly launch an Android app, like Amazon's Alexa.
The best solution I can up with is:
User says specific utterance (e.g. "Pepper, open Alexa please")
DialogFlow launches the j-tablet-browser behavior
{
"speak": "Sure, just a second",
"action": "startApp",
"action_parameters": {
"appId": "j-tablet-browser/."
}
}
User navigates the Android menu manually to tap the Alexa icon
My ideal goal is to make the process seamless:
User says specific utterance (e.g. "Pepper, open Alexa please")
DialogFlow launches the Alexa app installed on the Android tablet
Does anyone have an idea how this could be done?
This is quite a broad question so I'll try and focus on the specifics for launching an app with a Dialogflow chatbot. If you don't already have a QiSDK Dialogflow chatbot running on Pepper, there is a good tutorial here which details the full process. If you already have a chatbot implemented I hope the below steps are general enough for you to apply to your project.
This chatbot only returns text results for Pepper to say, so you'll need to make some modifications to allow particular actions to be launched.
Modifying DialogflowDataSource
Step 2 on this page of the tutorial details how to send a text query to Dialogflow and get a text response. You'll want to modify it to return the full reponse object (including actions), not just the text. Define a new function called detectIntentFullResponse for example.
// Change this
return response.queryResult.fulfillmentText
// to this
return response.queryResult
Modifying DialogflowChatbot
Step 2 on this page shows how to implement a QiSDK Chatbot. Add some logic to check for actions in the replyTo function.
var response: DetectIntentResponse? = null
// ...
response = dataSource.detectIntentFullResponse(input, dialogflowSessionId, language)
// ...
return if (reponse.action != null) {
StandardReplyReaction(
ActionReaction(qiContext, response), ReplyPriority.NORMAL
)
} else if (reponse.answer != null) {
StandardReplyReaction(
SimpleSayReaction(qiContext, reponse.answer), ReplyPriority.NORMAL
)
} else {
StandardReplyReaction(
EmptyChatbotReaction(qiContext), ReplyPriority.FALLBACK
)
}
Now make a new Class, ActionReaction. Note that the below is incomplete, but should serve as an example of how you can determine which action to run (if you want others). Look at SimpleSayReaction for more implementation details.
class ActionReaction internal constructor(context: QiContext, private val response: DetectIntentResponse) :
BaseChatbotReaction(context) {
override fun runWith(speechEngine: SpeechEngine) {
if (response.action == "launch-app") {
var appID = response.parameters.app.toString()
// launch app at appID
}
}
}
As for launching the app, various approaches are detailed in other questions, such as here. It is possible to extend this approach to do other actions, such as running or retrieving online data.

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)

ActivityNotFoundException for intent android.settings.NFC_PAYMENT_SETTINGS

I'm trying to open settings on NFC Tap & Pay page with this piece of code:
startActivity(new Intent(Settings.ACTION_NFC_PAYMENT_SETTINGS));
While testing on LG Nexus 5X with Android 7.1.2 I have received this crash:
android.content.ActivityNotFoundException:
No Activity found to handle Intent { act=android.settings.NFC_PAYMENT_SETTINGS }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1809)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1523)
at android.app.Activity.startActivityForResult(Activity.java:4228)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(SourceFile:50)
at android.support.v4.app.FragmentActivity.startActivityForResult(SourceFile:79)
at android.app.Activity.startActivityForResult(Activity.java:4186)
at android.support.v4.app.FragmentActivity.startActivityForResult(SourceFile:859)
at android.app.Activity.startActivity(Activity.java:4525)
at android.app.Activity.startActivity(Activity.java:4493)
at ...
Well, this crash can be handled easilly with try-catch but what is wierd, when I open this NFC settings manually, code works like a charm - no crash. Why? Does anyone have an explanation for this behavior?
In documentation[1] is written this:
In some cases, a matching Activity may not exist, so ensure you
safeguard against this.
Is it possible that they meant this sentence like "you have to open settings manually, then it works fine"?
[1] https://developer.android.com/reference/android/provider/Settings.html#ACTION_NFC_PAYMENT_SETTINGS
From: https://developer.android.com/reference/android/provider/Settings.html#ACTION_NFC_PAYMENT_SETTINGS
ACTION_NFC_PAYMENT_SETTINGS
added in API level 19
String ACTION_NFC_PAYMENT_SETTINGS
Activity Action:
Show NFC Tap & Pay settings
This shows UI that allows the user to configure Tap&Pay settings.
In some cases, a matching Activity may not exist, so ensure you safeguard against this.
Input: Nothing
Output: Nothing
Constant Value: "android.settings.NFC_PAYMENT_SETTINGS"
ACTION_NFC_PAYMENT_SETTINGS is not supported by your device or can at least not be handled.
Update 1
Since your minAPILevel is 19, the action should be supported by the android RT. However, it is possible, that the link between the action and the NFC settings-menu, ALTHOUGH the menu exists, is not or can not be established.
Try to use Settings.ACTION_NFC_SETTINGS as the action and see if it starts.
If so, I'd expect an implementation issue.
To guard against the exceptions, I'd recommend using:
PackageManager packageManager = getActivity().getPackageManager();
if (intent.resolveActivity(packageManager) != null) {
startActivity(<your intent>);
} else {
Log.d(TAG, "No application available to handle requested action.");
}
See: How to check if an intent can be handled from some activity? for credit and reference.

How to enable Android Open Application voice interaction

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"

Categories

Resources