Android: Problem with the camera opening in webview - android

After a few days struggling with opening camera within webview I decided to ask the question here.
So,
I have a webview in my app which open a web page where is a camera. To forestall the questions, I do not have access to the website code.
I work on the android sdk 30 and Pixel 3 api 30. I tried it to open also on old android SDKs (23 - 24) or on the newest android 12. Tried to add android:requestLegacyExternalStorage with target sdk version 29.
When i try to open the given website in the chrome on my emulator it works correctly.
I think it can be problem with camera permissions but i have no idea how to check it. Calling requestPermissions for the camera also didn't help me.
And I just keep getting this error all the time:
E/cr_VideoCapture: getCameraCharacteristics:
java.lang.IllegalArgumentException: supportsCameraApi:2340: Unknown camera ID 0
at android.hardware.camera2.CameraManager.throwAsPublicException(CameraManager.java:1001)
at android.hardware.camera2.CameraManager.getCameraCharacteristics(CameraManager.java:449)
at ft0.i(chromium-TrichromeWebViewGoogle6432.aab-stable-489612734:1047)
at org.chromium.media.VideoCaptureFactory.isLegacyOrDeprecatedDevice(chromium-TrichromeWebViewGoogle6432.aab-stable-489612734:1339)
at org.chromium.media.VideoCaptureFactory.getFacingMode(chromium-TrichromeWebViewGoogle6432.aab-stable-489612734:93)
Caused by: android.os.ServiceSpecificException: supportsCameraApi:2340: Unknown camera ID 0 (code 3)
at android.os.Parcel.createExceptionOrNull(Parcel.java:2387)
at android.os.Parcel.createException(Parcel.java:2357)
at android.os.Parcel.readException(Parcel.java:2340)
at android.os.Parcel.readException(Parcel.java:2282)
at android.hardware.ICameraService$Stub$Proxy.supportsCameraApi(ICameraService.java:906)
at android.hardware.camera2.CameraManager.supportsCameraApiLocked(CameraManager.java:1054)
at android.hardware.camera2.CameraManager.supportsCamera2ApiLocked(CameraManager.java:1030)
at android.hardware.camera2.CameraManager.getCameraCharacteristics(CameraManager.java:422)
at ft0.i(chromium-TrichromeWebViewGoogle6432.aab-stable-489612734:1047) 
at org.chromium.media.VideoCaptureFactory.isLegacyOrDeprecatedDevice(chromium-TrichromeWebViewGoogle6432.aab-stable-489612734:1339) 
at org.chromium.media.VideoCaptureFactory.getFacingMode(chromium-TrichromeWebViewGoogle6432.aab-stable-489612734:93) 
Thanks :)

Make sure to add permission in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA"/>
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
Then in your activity, You can check camera permission like below
if(ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)== PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.CAMERA)==PackageManager.PERMISSION_GRANTED) {
}
Inside this condition you can use android.provider.MediaStore.ACTION_IMAGE_CAPTURE to get the list of camera intent from packagemanager

Related

How to read Samsung Android MessagingContentProvider (SecurityException)

I need to directly read
content://com.samsung.android.messaging.service.provider.MessageContentProvider/messages
(Why? Trying to find some way to get to RCS messages, which do not trigger SMS_RECEIVED)
As expected there is a SecurityException
Caused by: java.lang.SecurityException:
Permission Denial: opening provider com.samsung.android.messaging.service.provider.MessageContentProvider
from ProcessRecord{c72fe1ad0 14345:com.gearandroid.phoneleashfree/u0a474} (pid=14345, uid=10474)
requires com.samsung.android.messaging.permission.READ_MESSAGE or
com.samsung.android.messaging.permission.WRITE_MESSAGE
at android.os.Parcel.createException(Parcel.java:1966)
I added com.samsung.android.messaging.permission.READ_MESSAGE and om.samsung.android.messaging.permission.WRITE_MESSAGE to AndroidManifest.xml:
<uses-permission android:name="com.samsung.android.messaging.permission.READ_MESSAGE"/>
<uses-permission android:name="com.samsung.android.messaging.permission.WRITE_MESSAGE"/>
But no luck. Thanks for help, suggestions

Android - Camera permissions denied without prompting

I was running into issues with the manual process behind requesting permissions (just kept falling into the 'denied' code), so I switched over to using Dexter to simplify. I implemented the following code in onCreate(), and I did a fresh install of the app:
Dexter.withActivity(this)
.withPermission(Manifest.permission.CAMERA)
.withListener(new PermissionListener() {
#Override public void onPermissionGranted(PermissionGrantedResponse response) {
Log.d(TAG, "GRANTED!");
initCamera();
}
#Override public void onPermissionDenied(PermissionDeniedResponse response) {
Log.d(TAG, "DENIED!");
}
#Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
Log.d(TAG, "PERMISSION RATIONAL SHOULD BE SHOWN!");
}
}).check();
It immediately falls into the "DENIED!" log, and it never even prompts me. I tried this particular code to attempt multiple permissions (which is ultimately what I need to do):
Dexter.withActivity(activity)
.withPermissions(Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(new MultiplePermissionsListener() {
#Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
Log.d(TAG, "Accepted: " + report.getGrantedPermissionResponses().size() + " | Denied: " + report.getDeniedPermissionResponses().get(0).getPermissionName());
}
#Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
Log.d(TAG, "continuing permissions request..");
token.continuePermissionRequest();
}
})
.check();
It prompts for permissions to Record Audio, then it asks about Access to photos/media/files on the device (it never asks about Camera). Then once that's done, it prints the log: "Accepted 3 | Denied: android.permission.CAMERA". It denies it without even prompting me again.
My Manifest is set properly to have CAMERA in the proper place (outside of the 'application' tag). See below for reference:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.my.app">
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
etc..
Odd thing is that when I go into Settings > Applications > MyApp, the Camera option is not even displayed in there.
I don't think it's an issue with Dexter, since it's doing basically the same thing when I set it up manually (and I confirmed that it's definitely setup properly in that case after looking at a few top S.O. posts).
Any thoughts on what the issue could be here? FYI - I'm using a Galaxy S6, OS 6.0.2. The other users experiencing this seem to be other devices with 6.0+ OS. Thanks in advance!
EDIT:
Testing various devices, it works on some and does not work on some:
Moto X (OS 5.0) - Broken
Nexus 5 (OS 7.0) - Works
Samsung S6 (OS 6.0.1) - Broken
Broken Moto X (OS 6.0) - Works
Doesn't seem to be a solid pattern.. Definitely strange. I also started a brand new project and ran the same code - worked fine and allowed access to my camera. So it doesn't appear to be fully device-specific..
The issue with this turned out to be a third-party library, which had this line in their Manifest, overriding our own permission:
<uses-permission android:name="android.permission.CAMERA" tools:node="remove" />
The solution was either to manually import their project as a module (rather than use gradle), and then comment out that line, OR more simple - you can add "tools:node="replace"" to the end of the main project's CAMERA permission line, and it works fine after that; no need to import the project with the latter approach.
What you need is native runtime permissions not dexter, Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app. It also gives the user more control over the app's functionality; for example, a user could choose to give a camera app access to the camera but not to the device location. The user can revoke the permissions at any time, by going to the app's Settings screen.
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.YOUR_PERMISSION);
then what you need is to request a certain permission if that check is false,
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.YOUR_PERMISSION},
MY_PERMISSION_CODE);
Bare in ind that you need to as well declare them also in the manifest, based on what you have shown still that was already done. For more information.

Application that can get Location and runs on android 4.0.3+

For android versions less than 6 just adding these permission requests to the manifest works:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
But for android version 6 I need explicitly request permission too to get the location:
requestPermissions(new String[]{ Manifest.permission.ACCESS_FINE_LOCATION}, 1340);
The problem is that If I add the above code the App works only on android 6 and fails to run on lower versions as requestPermissions does not exist on lower versions. and If I remove it I won't be able to get the location on android 6.
What can I do that my app be able to get the location on android 4.0.3+
You can check the API level of the phone that is running your app like this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//later than 4.x - so here you can run the code
//ideally you want to make this call in a helper method which you then annotate with the #TargetApi
requestPermissions(new String[]{ Manifest.permission.ACCESS_FINE_LOCATION}, 1340);
}
else{
//nothing to do in your case ?
}
You can also use #TargetApi(Build.VERSION_CODES.LOLLIPOP) in the methods where you want to make "Lollipop+" calls.

Unit test for uses-permission permissions

I'm trying to figure a way to test if <uses-permission android:name="android.permission.INTERNET" /> is set in AndroidManifest.xml, but I can't. Is it possible to do that? Right now I'm using ActivityInstrumentationTestCase2.
I'm trying to learn testing in Android Studio, and I think that testing that certain uses-permission permissions are set is a good idea at the start of testing the application.
This is how I ended up doing it:
Context testContext = getActivity().getContext();
PackageManager pm = testContext.getPackageManager();
expected = PackageManager.PERMISSION_GRANTED;
actual = pm.checkPermission(Manifest.permission.<PERMISSION_YOU_ARE_LOOKING_FOR>, testContext.getPackageName());
assertEquals(expected, actual);

Activity Access Restriction Implementation in a Monodroid Application

I have a requirement where I need to restrict access to an activity of a Monodroid Application. Hence i tried a spike where the application IntentSayHello would have an access restricted Activity called SayHelloActivity. As the first step i defined the permission tag in the AndroidManifest.xml of the application as below:
...
...
</application>
<permission
android:name="intentsayhello.permission.SAYHELLO"
android:protectionLevel="signature" android:label="#string/permlbl_restricted"
android:description="#string/permdesc_restricted">
</permission>
</manifest>
Please note that i'm using protectionLevel = signature which means that any other application signed with the same certificate as IntentSayHello can only access the restricted activity.
Now i coded the SayHelloActivity as below:
[Activity(Label = "SayHelloActivity", MainLauncher = true, Icon = "#drawable/icon", Permission = "intentsayhello.permission.SAYHELLO")]
[IntentFilter(new string[] { "companyXYZ.intent.sayhello.MAIN" },Categories = new string[]{Intent.CategoryDefault},
DataMimeType = "vnd.companyXYZ.say.hello/vnd.companyXYZ.activity")]
public class SayHelloActivity : Activity
{
.....
.....
}
After this i tested with a client application by invoking SayHelloActivity of IntentSayHello through an implicit intent and i got SecurityException as expected.
Permission Denial: starting Intent { act=companyXYZ.intent.sayhello.MAIN typ=vnd.companyXYZ.say.hello/vnd.companyXYZ.activity cmp=IntentSayHello.IntentSayHello/intentsayhello.SayHelloActivity }
from ProcessRecord{4094f850 9126:DiffKeyHello.DiffKeyHello/10097} (pid=9126, uid=10097) requires intentsayhello.permission.SAYHELLO
Now if i want my client Application to be given access to the SayHelloActivity of the restricted application, i'm supposed sign my client application with the same keystore (certificate) and also mention in the AndroidManifest.xml of the client application as below:
...
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="intentsayhello.permission.SAYHELLO" />
</manifest>
But when i did both of this, the client application still could not invoke the SayHelloActivity and same SecurityException is thrown.
I would like to know the directions/solution to this issue.
Thanks
After Googling around, hit upon this page: http://lists.ximian.com/pipermail/mono-bugs/2011-January/108218.html
I took the cue from this page that the need to be put into the Client's AssemblyInfo.cs. The syntax would be:
// Add some common permissions, these can be removed if not needed
[assembly: UsesPermission("intentsayhello.permission.SAYHELLO")]
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
It worked from then on.
Further search in mono android forum, i found that another way of doing this is to explicitly add the androidmanifest.xml in the .csproj file as below:
<PropertyGroup>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
</PropertyGroup>
Either of the above solutions works, only i do not know which/both are correct practice.

Categories

Resources