I'm currently trying to implement STILL_IMAGE_CAPTURE_SECURE intent for my camera app. (A intent that gets triggered when the power button is double tapped in secure mode)
I have added WAKE_LOCK and DISABLE_KEYGUARD permissions in the manifest file and set showOnLockScreen and showOnLockScreen to true for that activity.
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<!-- [...] -->
<activity
android:name=".ui.activities.SecureMainActivity"
android:taskAffinity=".ui.activities.SecureMainActivity"
android:label="#string/app_name"
android:configChanges="orientation|keyboardHidden|screenSize"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
android:screenOrientation="nosensor"
android:showWhenLocked="true"
android:showOnLockScreen="true"
android:excludeFromRecents="true"
android:exported="true">
<intent-filter>
<action android:name="android.media.action.STILL_IMAGE_CAMERA_SECURE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
We have tested our app on Android 11 (AOSP) and double tapping to open camera in lock screen works fine/as expected there (our app is visible along with other apps that implement this intent such as Google Camera in an Intent Chooser) but however in Android 12 (AOSP) Google Camera directly gets triggered (which implicitly means that our app isn't being considered for the intent).
If Google Camera isn't installed, nothing really gets triggered.
What could possibly could possibly cause this unexpected behavior?
As per the 'How double-click power launches the camera' guide:
Note that starting in Android 12, as required by some OEMs, if the special string resource config_cameraGesturePackage is nonempty, this will be treated as a package name to be added to the insecure camera intent, constraining the invocation to that single app and typically preventing implicit intent resolution. This package must be on the device or the camera gesture will no longer work properly.
As explained in the commit that added this code:
Using an implicit intent at the moment of picture-taking
usually goes unnoticed. But immediately after installing a
new camera, this behavior becomes incredibly frustrating to
users as they are presented with a puzzling resolver dialog
(or in the case of the secure camera, the authenticator).
And if, at this moment, the user chooses to make one of the
options a default, it's almost impossible to figure out how
to change this setting.
As a result, many OEMs simply hardcode the camera gesture to
launch a specific preinstalled camera, but this is poorly
supported by AOSP, leading to duplicate implementations and
bugs. This patch routes all camera intents in System UI
through a single utility class, creating a convenient spot
to insert a resource that contains the OEM's default
preinstalled camera app.
It goes on to explain how to determine what intents are fired when this action is performed:
Bugreport/dumpsys output to look for:
$ adb shell dumpsys activity service com.android.systemui | grep -C3 'Camera gesture' | tail -3
Camera gesture intents:
Insecure camera: Intent { act=android.media.action.STILL_IMAGE_CAMERA }
Secure camera: Intent { act=android.media.action.STILL_IMAGE_CAMERA_SECURE flg=0x800000 }
Override package: null
By looking at the "Override package", you can see if a particular camera package, such as the one associated with the Google Camera app, is defined as the only camera that can handle this intent. If that is the case, then it is expected that your app will never be able to handle that intent on that particular device.
Of course, if you are an OEM and controlling the resource overlay on your own device, you would want to update the config_cameraGesturePackage string resource to point to your custom camera app or leave it blank if you want to allow any camera app to handle this action.
Related
I am looking to read the ID of any tag detected by the user in background, without actually opening an activity in my app.
What I currently have is an intent-filter for TECH_DISCOVERED in my MainActivity:
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc_tech_filter" />
where nfc_tech_filter.xml defines all the technologies I want. It works as expected, the activity is either opened directly or the user is required to choose between different apps. Is it possible to get limited data about the tag, such as the ID, without any user interaction?
Really NFC's security model is NFC is only handled in the foreground, this matches the logic that if the user has brought the NFC Tag in to range then they are expecting some interaction with it and to do that the App has to be in the foreground.
There a various different ways to start what might be termed "background Service", they all have limitation and they still might be stopped by the system and Google have changed what is supported over time and there was a large set of changes in Android 8.
The android code that handles NFC has various checks to make sure NFC is only handled by a foreground App.
Before API 29, we can remove the launcher icon in the device by removing
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
in the manifest file.
As stated here
As of Android Q, at least one of the app's activities or synthesized activities appears in the returned list unless the app satisfies at least one of the following conditions:
The app is a system app.
The app doesn't request any permissions.
The app doesn't have a launcher activity that is enabled by default. A
launcher activity has an intent containing the ACTION_MAIN action and
the CATEGORY_LAUNCHER category.
Additionally, the system hides
synthesized activities for some or all apps in the following
enterprise-related cases:
If the device is a fully managed device, no synthesized activities for
any app appear in the returned list. If the current user has a work
profile, no synthesized activities for the user's work apps appear in
the returned list.
The third condition states as the same as not to have a launcher activity that is enabled.
How to achieve this in android 10?
I believe the third condition is wrong or outdated.
The behavior on Google's current emulator image of Android 10 (Google APIs Intel x86 Atom System Image 29_r09) differs from the documentation:
getActivityList() always returns at least one activity, except if the app satisfies at least one:
system app
<application> tag is completely empty i.e. no activities, services, ... declared
no permissions declared
This behavior corresponds to the release notes from Android Q Beta:
Launcher icon visibility
In Android Q Beta 2, packages that don't declare any permissions in their respective
manifest files are hidden from the All apps tray, as are the following types of apps:
System apps
Apps that don't contain any components inside their respective manifest's <application> tag
In my Android app there is a security vulnerability that my app can be opened by a malicious application. I am using the following intent filter in the Launcher Activity.
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
This intent filter makes the Main Activity exposed to other apps. Is there any way to expose the Main Activity only to the Android OS and not to other applications. As far as I understand We can't use "exported=false".
Is there any way to expose the Main Activity only to the Android OS and not to other applications.
Not as you are defining the terms.
Every activity, exported or not, is "exposed" to "the Android OS". Otherwise, they would be unusable, even by the app itself. The difference between an exported activity and one that is not is whether a third-party app can start the activity.
The home screen itself is just an app. A device ships with at least one home screen pre-installed, and users can install others from the Play Store or elsewhere. Hence, from the standpoint of your app, the home screen is a third-party activity.
In my Android app there is a security vulnerability that my app can be opened by a malicious application
Having an exported activity is not a "security vulnerability" in its own right. Your argument is akin to saying "there is a security vulnerability in my Web site — how do I allow my home page to only be opened from a Google search result, but not by a bookmark or any other Web site?".
Having unnecessarily exported activities is bad from a security standpoint, but the launcher activity is exported by necessity.
I was going through the sample program of Android things and i have found 2 there.
One was having <category android:name="android.intent.category.LAUNCHER" /> and another was having <category android:name="android.intent.category.IOT_LAUNCHER"/> , So what is the basic diffence between both of them?
reference link
The documentation states:
An application intending to run on an embedded device must declare an activity in its manifest as the main entry point after the device boots
The Activity declared as IOT_LAUNCHER will automatically start, when the device boots.
The definition in AndroidManifest.xml must contain the intent filter with 3 elements:
Action: ACTION_MAIN
Category: CATEGORY_DEFAULT
Category: IOT_LAUNCHER
Look here for more info.
There is nothing that prevents you from declaring the same activity as a default start Activity to be run from Android Studio. The same Activity would be run a boot and by a programmer.
Please find below difference between IOT_LAUNCHER and LAUNCHER:
IOT_LAUNCHER:
This intent is for Android Things which is an extended Android Framework for Internet Of Things(IOT) which is used for embedded programming using Android.
Please check this link for more information.
LAUNCHER:
This intent is for normal Android application which is for mobile and Tablet Device.
There is also one more intent action which is, LEANBACK_LAUNCHER used for Android TV applications.
Google Play store filters applications using this intent actions only.
Thanks.
Let me describe you what I want: I want to build a "master app" and set it so that when the phone is powered up, it immediately goes into the master app. The user can never exit this app (this will be used for something like parental control), and he can only launch other apps from within it.
Basically it will be like a "custom desktop".
I must stress out, it is important that this app never exits. As long as the phone is started, this is the only environment that the user has access to.
Now after I explained what I need, I will need your help to tell me what am I looking for. Is this some kind of "default launcher" that I keep hearing about? Or how is this called?
How can I do it?
Thanks
Add this into Manifest.
<receiver
android:name=".Bootupclass"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
</receiver>
Bootupclass
public class Bootupclass extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
//write intent here
}
}
I need someone to give me the exact code needed to make the app:
Here Goes,
If you make an app as a launcher app, and if it is the ONLY launcher app within your system, it will of course be started when you switch on your device. And also when you click on the home button, since your app is the only launcher app within the system, the same would be started.
so ,
1) start on bootup 2) be the default action when pressing the home button (the "desktop")
could both be merged into 1.
You mentioned that your phone is rooted, So easiest way to achieve what you require would be to
1.Install your app with just these lines within the manifest. i.e within your first activity. Nothing else is required. (this would make your app as a launcher app)
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
2.Un-install the default launcher application within your device.
What is being asked in the question body is different from the question title.
Listening to BOOT_COMPLETED will do literally what is requested by title - give control to the application once when device is powered on or restarted.
It is not enough to achieve the real goal - to prevent user from exiting the application and reaching "normal" home screen - once user presses "exit" or "home", he will essentially leave your app. While you can intercept "Exit" button and prevent it from quitting your app, "home" button is not possible to block programmatically.
In order to make and app like parental control and prevent user from reaching unwanted apps you need to implement "custom home screen" or "custom launcher" (which is the same thing).
It is rather large topic, but this seems to be a good starting point: Android - creating custom launcher.
And because author insists on "exact code", to make your app to start instead of a home screen (after boot or pressing "home" button), you need the following in the manifest:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
After install, press "home" button - you will be given a choice of standard launcher or your app. Check "use as default" and select your app - from now on it will start instead of the normal home screen.
Beware, though, that there are few known issues with custom launchers. One is - you have to block access to settings, otherwise user can switch back to default launcher. Also, after your app is updated (i.e. you post new version) user will be asked what home screen to use and can choose default launcher.
I must stress out, it is important that this app never exits This I believe is not possible.
From your requirement it seems that you require a MDM solution. Upwards of Android 2.2 device administration APIs have been available. Check out http://developer.android.com/guide/topics/admin/device-admin.html
The user will have to install your app and allow it to be a Device Administrator. (You can see currently available administrators from Setting -> Location and Security -> Device Administrator). Now as an administrator you can control features on device eg. disallow apps to be uninstalled, prevent installation of specific apps, disallow launch of specific apps. wipe device if security is breached etc. You can also prevent your app from being uninstalled.
There are apps available with such features. I can name Maas360 off the top of my head.
Disclaimer: I haven't tried the device administration apis myself.