I am using a Raspberry PI3 board to run Android Things dev-preview 0.5.0. A camera is attached to the board. To grant permission manually to the camera I am running following command in terminal:
adb shell pm grant org.tensorflow.demo android.permission.CAMERA
However I am getting following error in return:
Operation not allowed: java.lang.SecurityException: Cannot grant system fixed permission android.permission.CAMERA for package org.tensorflow.demo
The application is running successfully but it does not capture any image.
Rebooting RPi did not work for me. I found that granting the permission manually resolved the access issue:
adb shell pm grant <your.package.name> android.permission.CAMERA
See this post on Github
It is a old issue, but right now works very fine, a few months ago you were need a single reboot for take a permissions, but now I don't to do. Otherwise, you can try the next code example:
Complete code: https://github.com/hpsaturn/bgcamera
Manifiest
<uses-permission android:name="android.permission.CAMERA" />
Check permission:
// We need permission to access the camera
if (checkSelfPermission(Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// A problem occurred auto-granting the permission
Log.d(TAG, "No permission");
return;
}
Init camera
/**
* Starts a builtin camera with api camera 2
*/
private void startCamera() {
CameraManager manager = (CameraManager) ctx.getSystemService(Context.CAMERA_SERVICE);
try {
String pickedCamera = getCamera(manager);
manager.openCamera(pickedCamera, cameraStateCallback, null);
mImageReader = ImageReader.newInstance(mWidth, mHeight, ImageFormat.YUV_420_888, 4 /* images buffered */);
mImageReader.setOnImageAvailableListener(onImageAvailableListener, null);
Log.d(TAG, "imageReader created");
} catch (CameraAccessException e) {
Log.e(TAG, e.getMessage());
}
}
I based from original code of Doorbell example for Android Things:
https://github.com/androidthings/doorbell
I was facing a similar issue and after installing the apk I restarted raspberry pi again. After that its working fine for me.
This happens because:-
Camera permission comes under dangerous permission list. And to get this kind of permission the device need to be booted once. Hope this clarifies the issue.
Related
I am using the permission_handler package in flutter to access permissions of the underlying device that my app would run on.
My problem, however, is that the Permission.locationAlways.isGranted always returns false, even when I have changed the permission to "always allow" in the app settings.
Here's the function that checks the phone's permission using the permission_handler package:
void _checkLocationPermission() async {
bool isGranted = await Permission.locationAlways.isGranted;
print("isGranted -- $isGranted");
if (_locationPermissionGranted != isGranted) {
setState(() {
_locationPermissionGranted = isGranted;
});
}
}
This function is called in the initState() method of the screen. I would appreciate any guidance to solve this; it seems pretty simple and I don't know what I am doing wrong.
Make sure you installed the package properly on ios. Modify the podfile appropriately as explained here: here. Also, this video may help, in case you're struggling with the instructions in the previous link: video
I am developing a Xamarin.Android App to read the incoming call phone number, and I was able to get the same in Android Oreo. But once we upgraded to Android Pie
string telephone = intent.GetStringExtra(TelephonyManager.ExtraIncomingNumber);
always returns 'null'.
While Searching, I find out that by adding 'READ_CALL_LOG' permission it will work in Android Pie.
I already tried by adding 'READ_CALL_LOG' to AndroidManifest.xml,
Also given the run time permission for 'READ_CALL_LOG' and 'READ_PHONE_STATE'
in my MainActivity.cs
But Nothing worked for me.
Please tell me if I am missing anything?
```in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_CALL_LOG" />
```in MainActivity.cs
if (ContextCompat.CheckSelfPermission(this,
Manifest.Permission.ReadPhoneState) !=
Android.Content.PM.Permission.Granted ||
Manifest.Permission.ReadCallLog) != Android.Content.PM.Permission.Granted)
{
ActivityCompat.RequestPermissions(this,
new string[] { Manifest.Permission.ReadCallLog,
Manifest.Permission.ReadPhoneState },2);
}
in Android 9, you have to explicitly ask for both the READ_PHONE_STATE and the READ_CALL_LOG permissions at run time. In previous Android versions you only had to ask for the READ_PHONE_STATE permission. Both of them have to be asked at run time.
If the receiving app has Manifest.permission.READ_CALL_LOG and
Manifest.permission.READ_PHONE_STATE permission, it will receive the
broadcast twice; one with the EXTRA_INCOMING_NUMBER populated with the
phone number, and another with it blank
Here is the TelephonyManager docoument.
I have an app that needs to request permanent access to geolocation permission ( also in the background ) to gather data.
At the apps start I do a permission check like so ( simplified )
private static function check():void{
if (Geolocation.permissionStatus == PermissionStatus.GRANTED){
onPermGranted();
}else{
_geo = new Geolocation();
_geo.addEventListener(PermissionEvent.PERMISSION_STATUS, onPermission );
try {
_geo.locationAlwaysUsePermission = true;
_geo.requestPermission();
} catch(e:Error){
onError(e);
}
}
};
private static function onPermission(e:PermissionEvent):void{
trace("GeolocationUtil::onPermission: "+e.status);
};
The first time the app starts and this gets called and works.
Now if I quit the app, then change the permission to "never", and restart the app, I can see that
_geo.requestPermission();
gets called, but there is no response whatsoever and I do not get the iOS permissions dialog as well.
Any ideas? Thanks a lot!
The system will only ask once for the permission even if you uninstall your app and reinstall it again, looks like it has a system level cache,
Try go to Setting -> General -> Reset -> Reset Location & Privacy
I am doing some automation with Appium on a iOS mobile app.
I need to:
open the app
do some tasks
open safari
I looked around how to do it but I've been reading that it's impossible due to a limitation in apple's framework, it doesn't allow you to sent commands to more than one app per session.
Does anyone know a way around this? Or if what I read is just not 100% true.
it doesn't allow you to sent commands to more than one app per session
Thats true, but you can run 2 sessions in a single test:
create instance of appium driver with app-based capabilities
do what you need in the app
quit driver
create instance of appium driver with browser-based capabilities
do what you need in the safari
quit driver
In a quick way it may look like:
#Test
public void testBothAppAndSafari() throws MalformedURLException {
URL appiumServerUrl = new URL("<your appium server host>");
DesiredCapabilities appCaps = new DesiredCapabilities();
// put required native app capabilities in appCaps
DesiredCapabilities safariCaps = new DesiredCapabilities();
// put required safari capabilities in safariCaps
IOSDriver driver = new IOSDriver(appiumServerUrl, appCaps);
driver.findElement(<locator for element in native app>).click();
// do whatever you want with mobile app
driver.quit();
driver = new IOSDriver(appiumServerUrl, safariCaps);
driver.findElement(<locator for element in web>).click();
// do whatever you want in safari
driver.quit();
}
You can use following approach,
Created two setup one for app and other for safari.
First launch application and perform task
clear first session
Created again new Appium object for safari ( call second setup )
Perform browser activity
Close safari appium session
You also can follow my approach without quit driver.
Go terminate application. (I've used javascript to run terminateApp cause native method not work for me.)
Find Safari on Home screen and then click on it
Use drive.get to open website as you expected.
In there you can change to WEBVIEW_*** to inspect web element.
Back to native context by NATIVE_APP keyword
Sample code:
System.out.println("Run application");
Map<String, Object> params = new HashMap<>();
params.put("bundleId", "com.example");
boolean terminalApp = (boolean) driver.executeScript("mobile: terminateApp", params);
System.out.println("terminateApp: " + terminateApp);
driver.findElementById("Safari").click();
Set<String> contextNames = appDriver.getContextHandles();
// Change context to WEBVIEW_***
appDriver.context(String.valueOf(contextNames.toArray()[1]));
driver.get("https://www.google.com.vn");
Thread.sleep(20000);
// Do something.
// ...
// If you want to communicate with NATIVE context just change to NATIVE_APP.
appDriver.context("NATIVE_APP");
you can activate system apps via driver.activateApp(BUNDLE_ID);
there is no need to kill the app driver and start browser driver to access browser, just switch between apps.
safari
driver.activateApp("com.apple.mobilesafari");
Here is how I resolved the issue:
driver2.activateApp("com.apple.mobilesafari");
Thread.sleep(5000);
boolean openSafariTab =
driver2.findElements(By.xpath("//XCUIElementTypeButton[#name=\"AddTabButton\"]")).size() > 0;
if (openSafariTab) {
driver2.findElement(By.xpath("//XCUIElementTypeButton[#name=\"AddTabButton\"]")).click();
} else { }
Thread.sleep(3000);
driver2.findElement(By.xpath("//XCUIElementTypeTextField[#name=\"TabBarItemTitle\"]")).click();
Thread.sleep(3000);
driver2.findElement(By.xpath("//XCUIElementTypeOther[#name=\"CapsuleViewController" +
"\"]/XCUIElementTypeOther[3]/XCUIElementTypeOther[1]/XCUIElementTypeOther[1]")).sendKeys("https://www.golfbpm.com");
Thread.sleep(3000);
driver2.findElement(By.xpath("//XCUIElementTypeButton[#name=\"Go\"]")).click();
In my initial proof of concept for testing a React Native mobile app using Appium, I noticed that when I load the APK to start my test, I am presented with an Android prompt to "Permit drawing over other apps" as I am creating my AndroidDriver driver. If I move the slider manually, then click the back button, all is good -- the app loads fully, and my test proceeds. However, I don't see how to do this with automation using my Appium script because it looks like the driver instantiation will not complete until the slider is moved.
Most people don't see this in Appium testing as it appears to be specific to React Native in dev mode, as seen here...
Here's my code where I've put in conditional code to click the slider, but I never get there because it waits at the "driver = ..." line:
AndroidDriver driver = null;
#Before
public void setUp() throws Exception {
// < defining capabilities (emulator6p) up here...>
// initialize driver object
try {
driver = new AndroidDriver<WebElement>(new URL("http://127.0.0.1:4723/wd/hub"), emulator6p);
} catch (MalformedURLException e) {
System.out.println(e.getMessage());
}
}
#Test
public void test1() throws Exception {
By BY_slider_permitDrawing = By.id("android:id/switchWidget");
boolean present = (driver.findElements(BY_slider_permitDrawing).size() == 1);
if (present) {
driver.findElement(BY_slider_permitDrawing).click();
driver.navigate().back();
}
WebElement button_begin = driver.findElementByAccessibilityId("button-lets-begin");
button_begin.click();
}
I definitely hear plenty of people say that Appium is a viable solution for React Native testing, and really need to get over this hump.
Thanks in advance for any suggestions!
jph
p.s. In case it wasn't really clear, the test does NOT hang at the "driver = " line if I am not loading the APK from scratch, but I will need to do that for CI testing in the future.
Setting right capabilities helped me to run Appium tests in Debug mode on Android:
{
...
"appWaitPackage": "com.android.settings, com.yourPackage",
"appWaitActivity": "com.android.settings.Settings$AppDrawOverlaySettingsActivity, com.yourPackage.MainActivity",
}
Replace yourPackage with your real package name used in Android app. Some docs here: https://appium.io/docs/en/writing-running-appium/caps/#android-only