So I'm trying to get the IDs of the Physical cameras on the phone (Xiaomi Red Mi Note 9). First I'm getting the IDs of the Logical cameras and use those IDs to get some information about the Physical ones, but every time I get "0" Physical cameras.
Here is the code :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if( checkSelfPermission(Manifest.permission.CAMERA)==PackageManager.PERMISSION_GRANTED)
{
cameraManager=(CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
logicalCameraIdS=cameraManager.getCameraIdList();
for(String logicalCameraId :logicalCameraIdS)
{
cameraCharacteristics=cameraManager.getCameraCharacteristics(logicalCameraId);
Set<String> physicalCameraIdS=cameraCharacteristics.getPhysicalCameraIds();
if(physicalCameraIdS.size()>=2)
{
Log.i(" Message : ", "We have more then One camera");
}
else{
Log.i(" Message : ", "We Do not have multip[le cameras");
}
}
}
catch (CameraAccessException e)
{
Log.i("Camera Error", e.toString());
}
}
else
{
requestPermissions(new String[]{Manifest.permission.CAMERA},1);
}
}
Manifest permissions
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.front" />
<uses-feature android:name="android.hardware.camera.back" />```
Can someone explain what I'm doing wrong, and how to do it properly?
I'm answering this questions in order to prevent other people from making my mistake. As I stated in my question, I'm trying to run that code on an Xiaomi Redmi Note 9 and digging internet a little more I found out that Redmi Note 9S and 9Pro support the Android 11(API 30) while regular Redmi Note 9 doesn't yet. It runs on Android 10 (API 29) while the code that I wrote is for API 30 so only thing that I have to is just wait till an update to Android 11 for Redmi Note 9.
Thanks for people that looked at this question and I consider the question answered.
Related
I would like to enable bluetooth with my app without user interaction, the prompt does not appear on my devices - Android 7, 8 & 9, and my friend's Android 10. But it appears in my work colleague's devices (Android 10).
I used the following permissions
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
And used the following Bluetooth Adaptor methods.
bluetoothAdapter.enable();
bluetoothAdapter.disable();
I have no intent ACTION_REQUEST_ENABLE or ACTION_REQUEST_DISABLE in my source code.
Am I missing some permissions or methods?
Or is this an environment problem?
Any advise on how should I handle this would be much appreciated.
Thank you.
bluetoothAdapter.enable() will directly run com.android.settings/.bluetooth.RequestPermissionHelperActivity, and you should listen for ACTION_STATE_CHANGED yourself.
I think use the BluetoothAdapter.ACTION_REQUEST_ENABLE is a better way, which will first run com.android.settings.bluetooth.RequestPermissionActivity and then RequestPermissionHelperActivity. RequestPermissionActivity will listen for ACTION_STATE_CHANGED, while your app only need the result code of Activity.RESULT_OK.
private boolean ensureBluetoothEnabled() {
if(((BluetoothManager) Objects.requireNonNull(getSystemService(Context.BLUETOOTH_SERVICE)))
.getAdapter().isEnabled()) {
return true;
} else {
Intent btIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
btIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, Constants.PACKAGE);
startActivityForResult(btIntent, REQUEST_CODE_BL_OPEN);
return false;
}
}
I'm trying to create C++ Android native camera wrapper using the NDK camera2 API (from abi level 24). I created some snippet code using an example I found and compile it for target API level 24 and run it on Android 7.1 phone:
ACameraManager *cameraManager = ACameraManager_create();
VB(cameraManager!=nullptr, "Could not create CameraManager.");
camera_status = ACameraManager_getCameraIdList(cameraManager, &m_camera_id_list);
if (camera_status != ACAMERA_OK) {
LOGE("Failed to get camera id list (reason: %d)\n", camera_status);
return ERR_CAMERAAPI_UNKNOWN_ERROR;
}
if (m_camera_id_list->numCameras < 1) {
LOGE("No camera device detected.\n");
return ERR_CAMERAAPI_UNKNOWN_ERROR;
}
When I run this naive code on Xiaomi mi4c Android 7.1 phone I get an empty camera list.
I also tried to run on the same phone a snippet created with Java camera2 API that does the same thing:
import android.hardware.camera2.CameraDevice;
Activity activity = getActivity();
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
String[] cameraIds = manager.getCameraIdList()
manager.openCamera(cameraIds[0], mStateCallback, mBackgroundHandler);
This time I see in the logical that it actually finds two cameras and print their resolutions.
My manifest of course contains these lines:
<uses-sdk android:minSdkVersion="24" />
<uses-feature android:name="android.hardware.camera2" android:required="true" />
<uses-feature android:name="android.hardware.sensor.gyroscope" android:required="false" />
<uses-permission android:name="android.permission.CAMERA"/>
And I approve the permissions requests.
Does anyone knows why it finds the phone cameras when using the Java camera2 API but does not find them when using the NDK camera2 API?
The NDK camera2 support does not work if
CameraCharacteristics.get(INFO_SUPPORTED_HARDWARE_LEVEL) == INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
This is probably the case of Xiaomi mi4c.
I'm trying to access the front facing camera through the Camera2 API using an actual device
the problem occurs when trying to
cameraManager.openCamera(..,..,..)
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraID);
if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Time out waiting to lock camera opening.");
}
manager.openCamera(mCameraID, mStateCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
Log.e("mr", "OpenCamera - Camera Access Exception");
} catch (IllegalArgumentException e) {
Log.e("mr", "OpenCamera - Illegal Argument Exception");
} catch (SecurityException e) {
e.printStackTrace();
Log.e("mr", "OpenCamera - Security Exception:");
} catch (InterruptedException e) {
Log.e("mr", "OpenCamera - Interrupted Exception");
}
the Cameramanager says
I/CameraManagerGlobal: Connecting to camera service
which is coming from this CameraManager.java function
private void connectCameraServiceLocked() {
// Only reconnect if necessary
if (mCameraService != null) return;
Log.i(TAG, "Connecting to camera service");
Then my GLSurfaceView remains blank
AndroidMainfest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
P.S:
It works with the back camera
It works with the nexus 6 API 23 emulator
Permissions are requested at runtime for Android M
I'm using GLSurfaceView as a viewfinder
The front camera was working perfectly on the same device using the normal CameraAPI with a TextureView
Tried to Uninstall/Reboot/Clear Cache
the device I'm using is a Sony Z5 premium
I'm using this example Render camera preview using OpenGL ES 2.0 on Android API 21 or higher
If you're just copying that example, I noticed it has the following line:
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
The front camera probably doesn't support that, since it likely has no flash. You need to check what AE modes are actually supported - the same goes for the various other settings the sample sets, where it isn't checking what the device actually supports.
That said, you should be getting an error if the value is bad, but it might be coming in on the CameraCaptureSession.CaptureListener.onCaptureFailed, and the sample is not listening to those. There's probably also some logcat from the camera service, if you look at all logging, not just your own app's logs.
But try removing that line, and see if it works.
I've ended with changing the Sony Xperia Z5 premium to another device and it worked perfectly.
it looks like that Sony is facing some problems with the new API as i saw in the following link:
Sony Camera2 API limitations
there might be a work around but anyway i'm making an application for specific purpose i don't want it to be working on all devices
First get Camera service like this
CameraManager cameraManager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
I have a Xamarin Forms 2.0 application that uses ZXing.Net.Mobile and ZXing.Net.Mobile.Forms version 2.0.3.1. I'm trying to build a simple QR code scanner, but whenever I launch the ZXingScannerPage on Android I can see the default overlay (with the text and the red line) but I don't see the output of the camera so I can't actually scan anything. I have already listed the Camera permission in my AndroidManifest:
<uses-permission android:name="android.permission.CAMERA" />
I tried the sample code from the readme: https://github.com/Redth/ZXing.Net.Mobile as well as from their Samples/Forms project. I now have this code:
private async void OnScanQrClicked(object sender, EventArgs e)
{
_scannerPage = new ZXingScannerPage();
_scannerPage.OnScanResult += HandleScanResult;
await Navigation.PushAsync(_scannerPage);
}
private void HandleScanResult(Result result)
{
_scannerPage.IsScanning = false;
Device.BeginInvokeOnMainThread(() =>
{
Navigation.PopAsync();
DisplayAlert("Scanned code", result.Text, "OK");
});
}
Some more specs: I'm running Android 5.1 on a Moto G (v1).
Why am I not seeing the output of the camera?
I fixed it by getting rid of ZXing.Net.Mobile.Forms and downgrading ZXing.Net.Mobile from 2.0 to 1.5. I had to change my implementation, but that was relatively easy.
Another thing people may look at in the future (I didn't try it) is adding the flashlight permission: https://github.com/Redth/ZXing.Net.Mobile/issues/227.
After flashing my Nexus 5 to the Android 5.0 preview release hammerhead-lpx13d, the OS reports that it no longer supports Bluetooth LE advertising. If you call:
((BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE))
.getAdapter().getBluetoothLeAdvertiser()
always returns null. In addition, the new method:
((BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE))
.getAdapter().isMultipleAdvertisementSupported()
always returns false
The first method used to return a valid object on the first Android L preview release for the Nexus 5 back in June. It no longer does, after flashing the latest update.
Does anybody see otherwise?
EDIT: This has been reproduced by at least one person, who opened an issue with Google here: https://code.google.com/p/android-developer-preview/issues/detail?id=1570
Unfortunately, the official answer from Google is no, the Nexus 5 no longer supports advertising.
We introduced BLE peripheral mode in Android 5.0 Lollipop. Nexus 6 and
Nexus 9 are the first two production Nexus devices that support BLE
peripheral mode. Due to hardware chipset dependency, older Nexus
devices (4/5/7) will not have access to the feature on Lollipop.
See Comment #52 on issue 1570 by danielho...#google.com: BLE advertise mode not working
https://code.google.com/p/android-developer-preview/issues/detail?id=1570
That said, I have confirmed that advertising is supported by the Nexus 9 tablet. See here for details: http://developer.radiusnetworks.com/2014/11/18/beacon-transmission-with-android-5.html
This is not full a solution, but a proposed work-around posted by mattprec on Google Code. It allows you to get a BluetoothLeAdvertiser instance by calling the private constructor rather than using the public API. Unfortunately, reports of testing on a Nexus 5 and a Nexus 7 2013 edition say that even after you get an instance you can't use the object to make advertisements come out. Also, be warned that even if you can get it to work, it might break on any minor code release of Android because it is using a non-public API.
For the record, here's the code snippet copied from that page:
private static BluetoothLeAdvertiser getAdvertiserHack(BluetoothAdapter adapter) {
try {
Class<? extends BluetoothAdapter> adapterClass = adapter.getClass();
Field advertiserField = adapterClass.getDeclaredField("sBluetoothLeAdvertiser");
advertiserField.setAccessible(true);
Object advertiser = advertiserField.get(adapter);
if (advertiser == null) {
Field bluetoothManagerServiceField = adapterClass.getDeclaredField("mManagerService");
bluetoothManagerServiceField.setAccessible(true);
Object bluetoothManagerService = bluetoothManagerServiceField.get(adapter);
Constructor<?> constructor = BluetoothLeAdvertiser.class.getDeclaredConstructor(
bluetoothManagerServiceField.getType());
constructor.setAccessible(true);
advertiser = constructor.newInstance(bluetoothManagerService);
advertiserField.set(adapter, advertiser);
}
return (BluetoothLeAdvertiser) advertiser;
} catch (Exception e) {
return null;
}
}
That said, I have confirmed that advertising is supported by the Nexus
9 tablet. See here for details:
http://developer.radiusnetworks.com/2014/11/18/beacon-transmission-with-android-5.html
QuickBeacon app is working fine on Nexus 9. In app there is a Beacon Format option.#davidgyoung Could you give exact String for BeaconParser to make this library transmit in iBeacon format?
UPDATE:
Related question up to android-beacon-library/BLE Android SDK. Is there possibility - without calling startAdvertising method - to check if there is advertising service running in background?
UPDATE:
Recording to this : https://code.google.com/p/android-developer-preview/issues/detail?id=1570#c52
Now only Nexus 6 and Nexus 9 supports BLE Peripheal Mode in Android 5.0
UPDATE:
I work on Nexus 5 Android 5.0 build number LPX13D
according to this https://stackoverflow.com/a/26611779/1906420
After implementig your workaround bluetoothAdvertiser is not null. Calling startAdvertising from bluetoothAdvertiser
bluetoothAdvertiser.startAdvertising(settingsBuilder.build(), dataBuilder.build(), advertiseCallback);
where
private AdvertiseCallback advertiseCallback = new AdvertiseCallback() {
#Override
public void onStartSuccess(AdvertiseSettings settingsInEffec) {
}
#Override
public void onStartFailure(int result) {
if (result == ADVERTISE_FAILED_DATA_TOO_LARGE) {
Log.d(TAG, "Failed to start advertising as the advertise data to be broadcasted is larger than 31 bytes.");
}
else if(result == ADVERTISE_FAILED_TOO_MANY_ADVERTISERS){
Log.d(TAG, "Failed to start advertising because no advertising instance is available.");
}
else if(result == ADVERTISE_FAILED_ALREADY_STARTED){
Log.d(TAG, "Failed to start advertising as the advertising is already started.");
}
else if(result == ADVERTISE_FAILED_INTERNAL_ERROR){
Log.d(TAG, "Operation failed due to an internal error.");
}
else if(result == ADVERTISE_FAILED_FEATURE_UNSUPPORTED){
Log.d(TAG, "This feature is not supported on this platform.");
}
else {
Log.d(TAG, "There was unknown error.");
}
}
};
always give callback onStartFailure with error code 5 ( ADVERTISE_FAILED_FEATURE_UNSUPPORTED )