I get a `cannot open camera "0" without camera permission` Error when I try to open a camera to scan a QR code - flutter

I get a cannot open camera "0" without camera permission Error when I try to open a camera to scan a QR code.
I have a QR code scanner function that does not open the camera. The scanner screen appears but I do not see the box with the line inside for scanning.
I have also added camera permissions in the Android manifest
Android Manifest Permissions
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera"
android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
The Scanner Function is below
Future <void> scanqr() async {
final qrCode = await scanner.scan();
setState(() {
this.qrCode = qrCode;
});
}

//use permission_handler package and use the below code.. it will work fine
Future <void> scanqr() async {
await Permission.camera.request();
final qrCode = await scanner.scan();
setState(() {
this.qrCode = qrCode;
});
}

Related

Using permission Handler - Nearby device Permission Not working

I am building a Flutter Application that needs to connect to bluetooth devices nearby.
I followed the documentation for permission_handler here
and it works (kinda) but strangely enough it does not fully set the nearby device permission properly because when I go scan for nearby devices it is unable to find any.
I know this is the problem because when I manually toggle the permission in the app settings it works as intended.
For reference my androidmanifest.xml:
<!-- Permissions options for the `contacts` group -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<!-- Permissions options for the `storage` group -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
Code to check if permission is granted:
bool permGranted = true;
var status = await Permission.location.status;
if (status.isDenied) {
permGranted = false;
if (await Permission.location.request().isGranted) {
permGranted = true;
}
}
if (permGranted) {
_logMessage('Start ble discovery');
...
thanks in advance for any help!
Integrating the example app into my existing app is what helped me solve my error in the end.
The problem was that I was not allowing all the permissions I needed before attempting to scan for devices nearby.
it turns out when you manuelly toggle location on and off you also accept many other permissions as well.
here is the code needed:
bool permGranted = true;
var status = await Permission.location.status;
if (status.isDenied) {
permGranted = false;
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.bluetoothScan,
Permission.bluetoothAdvertise,
Permission.bluetoothConnect
].request();
if (statuses[Permission.location]!.isGranted &&
statuses[Permission.bluetoothScan]!.isGranted &&
statuses[Permission.bluetoothAdvertise]!.isGranted &&
statuses[Permission.bluetoothConnect]!.isGranted) {
permGranted = true;
} //check each permission status after.
}

Flutter/Dart - File.writeAsBytes executes with no error but can't find the file

I have a base64 encoded string of a PDF file. I'm trying to save it as a file in the android device. My code runs with no error, but i can't find the file.
Uint8List bytes = base64.decode(encodedStr);
String dir = (await getExternalStorageDirectories(
type: StorageDirectory.downloads))!
.first
.path;
File file = File("$dir/" +
DateTime.now().millisecondsSinceEpoch.toString() +
".pdf");
await file.writeAsBytes(bytes);
Also, I tried to include code to ask for permission before trying to save the file, but it didn't change anything.
var status = await Permission.storage.status;
if (!status.isGranted) {
await Permission.storage.request();
}
if (await Permission.storage.request().isGranted) {
try {
await file.writeAsBytes(bytes);
} catch (e) {
print(e);
}
}
And, as another attempt, I included these permission on my AndroidManifest file. Also, no changes.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
//dir = /storage/emulated/0/Android/data/com.xxxxxxxxxxxxxxxx.xxxxx/files/Download
//dir + file = /storage/emulated/0/Android/data/com.xxxxxxxxxxxxxxxx.xxxxx/files/Download/1655924904315.pdf
//file path after written = /storage/emulated/0/Android/data/com.xxxxxxxxxxxxxxxx.xxxxx/files/Download/1655924904315.pdf
Is there anything wrong with my code or something that I can change in order for it to work ?
The above code is using path_provider and permission_handler packages and was tested in an emulator and in a physical device.
Thanks.
Try importing io and use file of io and use this package https://pub.dev/packages/pdf
import 'dart:io' as io;
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
final pdf = pw.Document();
final dir = await getTemporaryDirectory();
final path = "${dir.path}/pdfname.pdf";
final file = await io.File(path).writeAsBytes(pdf.save());
It happens that the files are being correctly generated, but they are being saved in the application's directory. A download folder has being created and the files are being saved there. I didn't find the files searching via android, but when I connected my physical device to a PC I was able the find them.
It seems that this has something to do with this https://github.com/flutter/flutter/issues/35783 . Path_provider started to return application document directory after 1.1.0 instead of the general downloads folder.
I'll check how to access the path I want correctly.

Permission Denied even after granting the Storage Permission

I have added every thing required to download files to local storage still I'm getting this error
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception:
FileSystemException: Creation failed, path =
'/storage/emulated/0/uth_content' (OS Error: Operation not permitted,
errno = 1)
In Manifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
android:requestLegacyExternalStorage="true"
android:hardwareAccelerated="true"
<application
android:requestLegacyExternalStorage="true" >
In pubspec.yaml
permission_handler: ^6.1.1
My Dart File
#override
Future<int> downloadZipFile() async{
Directory extStorage = await _externalDataSource.GetExtStoragePath();
if(extStorage !=null) {
var response = await _apiDataSource.downloadZipContent(extStorage.path);
File zipfile = await response.zipFile;
debugPrint("Downloaded file :" + zipfile.path + "Exist: " + zipfile.existsSync().toString());
return response.statusCode;
}
else{
debugPrint("Path is empty");
createFolder("uth_content");
}
}
Future<String> createFolder(String cow) async {
final folderName = cow;
final path = Directory("/storage/emulated/0/$folderName");
var status = await Permission.storage.status;
if (!status.isGranted) {
await Permission.storage.request();
}
if ((await path.exists())) {
return path.path;
} else {
path.create();
return path.path;
}
}
How can I ensure that the folder is created, my android api is 30
You are missing this permission in your AndroidManifest.xml
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
To get the permission use
if (await Permission.manageExternalStorage.request().isGranted) {...}
NOTE: This permission is considered pretty risky so play store will reject your app unless it's your app's core functionality.
This is what google says
Core functionality is defined as the main purpose of the app. Without
this core functionality, the app is "broken" or rendered unusable. The
core functionality, as well as any core features that comprise this
core functionality, must all be prominently documented and promoted in
the app's description.
And if you are planning to create a file in an external directory and you are not able to find it, it's because you'd have to tell the device to refresh for the files. So I'd recommend using this package and passing your newly created file path to it or if you wanna do it manually with kotlin here's the code
private fun broadcastFileUpdate(path: String) {
context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(File(path))))
println("updated!")
}

Flutter: Location permission: when in use or always

I'm trying to know if the user has selected "only when in use" or "always" for the location.
https://pub.dev/packages/location_permissions
I tried this code from the package:
ServiceStatus serviceStatus =
await LocationPermissions().checkServiceStatus();
print(serviceStatus);
But it prints:
ServiceStatus.enabled
Is there a possibility (perhaps with another package) to know this?
Thanks in advance!
permission_handler can do this.
enum PermissionGroup {
...
/// Android: Fine and Coarse Location
/// iOS: CoreLocation - Always
locationAlways,
/// Android: Fine and Coarse Location
/// iOS: CoreLocation - WhenInUse
locationWhenInUse
}
Requesting permissions:
final ph = PermissionHandler();
final requested = await ph.requestPermissions([
PermissionGroup.locationAlways,
PermissionGroup.locationWhenInUse
]);
final alwaysGranted = requested[PermissionGroup.locationAlways] == PermissionStatus.granted;
final whenInUseGranted = requested[PermissionGroup.locationWhenInUse] == PermissionStatus.granted;
Add these permissions to AndroidManifest.xml inside <manifest> tag:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test_project">
<!-- add these -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
...
And these to <dict> tag of Info.plist:
<!-- Permission options for the `location` group -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>Need location when in use</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Always and when in use!</string>
<key>NSLocationUsageDescription</key>
<string>Older devices need location.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Can I haz location always?</string>
This library is support Stream so you can check like that.
LocationPermissions().serviceStatus.listen((event) {
if(event == ServiceStatus.disabled){
print('Location Disabled');
}else{
print('Location Enabled');
});
Good luck.
Geolocator package may be used for that. From its readMe page:
This method returns a value of the GeolocationStatus enum indicating
the availability of the location services on the device. Optionally
you can specify if you want to test for
GeolocationPermission.locationAlways or
GeolocationPermission.locationWhenInUse
. Have a look here - https://pub.dev/packages/geolocator

Moodle "upload" button of my site doesn't function inside android webview

I am developing an android application. I have used webview to load my moodle site; everything is fine but the "upload" button doe not function! When for example I click on the "upload" button to upload my photo in profile of moodle, nothing happens.
I have included the following in the manifest file:
<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"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!--
Allows Glide to monitor connectivity status and restart failed requests if users go from a disconnected to a connected network state.
-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
And the following lines have been added to the MainActivity:
<if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int hasCameraPermission =
checkSelfPermission(Manifest.permission.CAMERA);
Log.d(TAG, "has camera permission: " + hasCameraPermission);
int hasRecordPermission =
checkSelfPermission(Manifest.permission.RECORD_AUDIO);
Log.d(TAG, "has record permission: " + hasRecordPermission);
int hasAudioPermission =
checkSelfPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS);
Log.d(TAG, "has audio permission: " + hasAudioPermission);
List<String> permissions = new ArrayList<>();
if (hasCameraPermission != PackageManager.PERMISSION_GRANTED) {
permissions.add(Manifest.permission.CAMERA);
}
if (hasRecordPermission != PackageManager.PERMISSION_GRANTED) {
permissions.add(Manifest.permission.RECORD_AUDIO);
}
if (hasAudioPermission != PackageManager.PERMISSION_GRANTED) {
permissions.add(Manifest.permission.MODIFY_AUDIO_SETTINGS);
}
if (!permissions.isEmpty()) {
requestPermissions(permissions.toArray(new
String[permissions.size()]),111);
}
}
The following were also added to the webView activity:
wvs.setWebChromeClient(new WebChromeClient() {
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
#Override
public void onPermissionRequest(final PermissionRequest request) {
SiteActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
request.grant(request.getResources());
}
});
}
#Override
public void onPermissionRequestCanceled(PermissionRequest
request) {
// The following line was underlined red so I commented it out!
//Log.d(TAG, "onPermissionRequestCanceled");
}
});
After adding the above lines, when I run the app, I am asked to give permission but then a white page opens in webview and nothing happens!
Also, recording audio and video does not function inside the moodle site running in a webview! This may also help to find out the issue!
Would you please help me to eliminate the problem.
I highly appreciate your help.
Faramarz