For instrumented tests of location services I need mocked locations. But the current concept from Android seems to be not very practical.
In order to be allowed to use mocked locations the test-package also needs the permission android.permission.ACCESS_MOCK_LOCATION. When added to a debug-manifest I get the hint, that this permission will only be granted to System-Apps. I have to add tools:ignore="ProtectedPermissions" to the permission to suppress this warning. IMHO it makes no sense to issue such a warning for a property that is necessary for such tests.
Then I need to select this test-package as mock-location provider for the test-device. Acceptable for a manual test. But do I really have to manually select this setting for every device I want to test my code on? (What about this firebase-test on a farm of test devices? There I can not make this setting.)
And what if I have more than one app that tests mocked location? Currently I can not test both packages on the same device.
Or am I missing something?
I am developing an Android app using Kotlin. I am writing instrumented tests for my application. I am granting the permissions in my test using GrantPermissionRule as below.
#get:Rule
var permissionRule: GrantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION)
However, that does not fit well with my requirements. I am wiping out all the granted permissions after each does. Also, I like to test the scenarios where the permissions are not granted. I am launching the activity explicitly in my test like this.
#Test
fun exampleTest() {
this.eventDetailsActivityRule.launchActivity(intent)
}
I like to explicitly grant the permissions using GrantPermissionRule after or before launching the activity. How can I do that?
Implementing a MediaProjection sample for Screen Recording purposes while having my project setup in InstantApps mode gave me Security Permission error when running this line of code:
val REQUEST_MEDIA_PROJECTION = 101
startActivityForResult(mMediaProjectionManager?.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION)
But prompts you and allows you to continue when not an InstantApp.
Any ideas on a workaround, besides switching back to the regular non InstantApp
I found that kivy is very nice framework to build cross platform application and I am very interested in kivy just to do android application as I think is easy and comfortable in kivy.
After trying few examples, I am interested to know how should handle android run time permission for the kivy app.
Actually I had searched on google, but no single working example out there. Should I go back to android / java or it possible with kivy and some other python libs.
pyjnius is the way to go. You have to port these instructions using pyjnius. This involves the following steps:
Unfortunately the api call to ContextCompat.checkSelfPermission is implemented in the android sdk support library which has to be downloaded seperately,
so get the .aar with the version best matching your android API level for example here.
copy it into your project dir and reference it from your buildozer.spec:
android.add_aars = support-v4-26.0.0-alpha1.aar
make sure jinius is in the requirements in buildozer.spec
use the following code snippet
Note: this is a blocking function which waits until the permissions dialog is answered. If the app already has the permission the function returns immediately. So for example if you want to get the permissions for writing to the SD card and for the camera, which are both "dangerous permissions", call:
perms = ["android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.CAMERA"]
haveperms = acquire_permissions(perms)
And here the function for acquiring the permissions:
import time
import functools
import jnius
def acquire_permissions(permissions, timeout=30):
"""
blocking function for acquiring storage permission
:param permissions: list of permission strings , e.g. ["android.permission.READ_EXTERNAL_STORAGE",]
:param timeout: timeout in seconds
:return: True if all permissions are granted
"""
PythonActivity = jnius.autoclass('org.kivy.android.PythonActivity')
Compat = jnius.autoclass('android.support.v4.content.ContextCompat')
currentActivity = jnius.cast('android.app.Activity', PythonActivity.mActivity)
checkperm = functools.partial(Compat.checkSelfPermission, currentActivity)
def allgranted(permissions):
"""
helper function checks permissions
:param permissions: list of permission strings
:return: True if all permissions are granted otherwise False
"""
return reduce(lambda a, b: a and b,
[True if p == 0 else False for p in map(checkperm, permissions)]
)
haveperms = allgranted(permissions)
if haveperms:
# we have the permission and are ready
return True
# invoke the permissions dialog
currentActivity.requestPermissions(permissions, 0)
# now poll for the permission (UGLY but we cant use android Activity's onRequestPermissionsResult)
t0 = time.time()
while time.time() - t0 < timeout and not haveperms:
# in the poll loop we could add a short sleep for performance issues?
haveperms = allgranted(permissions)
return haveperms
Probably the cleanest way would be to pimp p4a's PythonActivity.java to do that but this one does it for me for now.
Hi this question is old but you can use
request_permissions([Permission.WRITE_EXTERNAL_STORAGE])
#For requesting permission you can pass a list with all the permissions you need
check_permission('android.permission.WRITE_EXTERNAL_STORAGE')
#returns True if you have the permission
you can check: python-for-android example
you can check the code and the list of permission you can use with this method:
python-for-android code
python-for-android doesn't have any code for handling runtime permissions. I expect to look at it sooner rather than later, but there's no ETA for it.
You can probably add the code for it yourself if you're interested and know how. If you'd like to try it, such contributions would be very welcome.
i know this answer is a little late, but to get permissions you have to specify them before the build. E.g buildozer uses a buildozer.spec. In this file you can specify the permissions you need.
specific question for you. I'm trying to write a feature in a test framework that adds call logs to the device/emulator. This requires android.permission.WRITE_CALL_LOGS.
I am using selendroid, and have added this permission to the AndroidManifest. However, this permission is not in my application under test.
In the Instrumentation class, I inevitably try to run
getContext().getContentResolver().insert(CallLog.Calls.CONTENT_URI, values);
and it returns an error citing permission issues. getContext() is supposed to return the context of the instrumentation, which I assume is the selendroid app installed on the device, which should have the proper WRITE_CALL_LOGS permission.
Where am I going wrong?