Lost connection to device in Flutter? - flutter

I'm facing a problem while using the plugins image_picker: "0.6.1+11" and
barcode_scan: "^1.0.0". Firstly I scan a barcode and then take a picture from the camera.
The problem is most of the times the android app restarts itself after taking image from the camera without any log. The log just prints "Lost connection to the device."
Here is the code:
Future scanCarton() async {
try {
String barcode = await BarcodeScanner.scan();
await getImage().then((imageFile){
if (imageFile != null){
Map<String,String>requestData = new Map<String,String>();
requestData["content"] = barcode;
requestData["type"] = "carton";
requestData["mode"] = "job";
if (widget.orderData.product_type.toLowerCase() == "batched"){
requestData["carton_id"] = "0";
}else{
requestData["carton_id"] = "${scannedCartonCount + 1}";
}
if(this.mounted){
setState(() {
_isLoading = true;
});
}else{
print("Gotcha 2");
}
upload(imageFile, UrlFile.UPLOAD_SCAN_IMAGE, "carton", requestData).then((value){
if(this.mounted){
setState(() {
_isLoading = false;
});
}else{
print("Gotcha 4");
}
incrementCartonCount();
if(widget.orderData.product_type.toLowerCase() == "batched"){
openNextCartonPopup();
}
});
}
});
} on PlatformException catch (e) {
if (e.code == BarcodeScanner.CameraAccessDenied) {
print('The user did not grant the camera permission!');
} else {
print('Unknown error $e') ;
}
} on FormatException{
print( 'null (User returned using the "back"-button before scanning anything. Result)');
} catch (e) {
print('Unknown error: $e');
}
}

You just need to configure to ask for permission beforehand.
For iOS, add the following keys to your Info.plist file, located at <project root>/ios/Runner/Info.plist:
NSPhotoLibraryUsageDescription - describes why your app needs permission for the photo library. This is called Privacy - Photo Library Usage Description in the visual editor.
NSCameraUsageDescription - describes why your app needs access to the camera. This is called Privacy - Camera Usage Description in the visual editor.
NSMicrophoneUsageDescription - describes why your app needs access to the microphone, if you intend to record videos. This is called Privacy - Microphone Usage Description in the visual editor.
In the same way, you need to add permissions in Android.

Try your method with dispose()
#override
void dispose() {
[your method name].dispose();
super.dispose();
}

I got the same issue and found the solution. If you have TextField and imager picker in the same page, please make sure the textfield is unfocused (the cursor should be gone from you TextField) when you pick image.
Do something like FocusScope.of(context).requestFocus(new FocusNode()); in your pickImage method.

Related

Flutter - Firebase Dynamic Link not Working while app is in kill mode

I have integrated Firebase Dynamic link in my Flutter application to open and navigate application users to specific screen in app.
For that first of all I have added below plugin in pubspec.yaml file:
firebase_dynamic_links: ^5.0.5
Then, I have created a separate class to handle related stuffs as below:
class DynamicLinkService {
late BuildContext context;
FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance;
Future<void> initDynamicLinks(BuildContext context) async {
this.context = context;
dynamicLinks.onLink.listen((dynamicLinkData) {
var dynamicLink=dynamicLinkData.link.toString();
if (dynamicLink.isNotEmpty &&
dynamicLink.startsWith(ApiConstants.baseUrl) &&
dynamicLink.contains("?")) {
//Getting data here and navigating...
...
...
...
}
}).onError((error) {
print("This is error >>> "+error.message);
});
}
}
Now, I am initialising Deep-link as below in my home_screen:
final DynamicLinkService _dynamicLinkService = DynamicLinkService();
and then calling below method in initState()
#override
void initState() {
SchedulerBinding.instance.addPostFrameCallback((_) async {
await _dynamicLinkService.initDynamicLinks(context);
});
}
This is working like a charm! when my application is in recent mode or in background mode.
But the issue is when the application is closed/Killed, clicking on dynamic link just open the app but could not navigate.
What might be the issue? Thanks in advance.
Let me answer my own question, It might be useful for someone!
So, In above code I forgot to add code to handle dynamic link while the app is in closed/kill mode.
We need to add this code separately:
//this is when the app is in closed/kill mode
final PendingDynamicLinkData? initialLink = await FirebaseDynamicLinks.instance.getInitialLink();
if (initialLink != null) {
handleDynamicLink(initialLink);
}
So, final code looks like as below:
//this is when the app is in closed/kill mode
final PendingDynamicLinkData? initialLink = await FirebaseDynamicLinks.instance.getInitialLink();
if (initialLink != null) {
handleDynamicLink(initialLink);
}
//this is when the app is in recent/background mode
dynamicLinks.onLink.listen((dynamicLinkData) {
handleDynamicLink(dynamicLinkData);
}).onError((error) {
print("This is error >>> "+error.message);
});
Its working like a charm now! That's All.

How to resolve Lost Connection to Device (Flutter Image Picker)

I'm building an app that requires me to use the camera of the device. I have followed all the procedures to set it up via the Image Picker Documentation and I am still having issues.
Funny enough, it was working fine when I tested it last time but as I added new widgets to screen and tried testing again, the app crashed with very minimal error message which says:
Lost connection to device.
This is how I capture the image:
Future<void> _pickImage() async {
try {
bool isPermisionGranted = await _requestFilePermission();
if (!isPermisionGranted) {
showToast('Please give us access to your camera.');
return;
}
final image = await ImagePicker().pickImage(source: ImageSource.camera, imageQuality: 90);
if (image == null) return;
final tempImageFile = File(image.path);
setState(() {
_imageFile = tempImageFile;
});
if (!mounted) return;
Navigator.of(context).pushNamed(Routes.chi, arguments: {'image_file': _imageFile});
} on PlatformException catch (e) {
debugPrint('Failed to pick image: $e');
showToast('Failed to pick image');
}
}
Could this be a memory issue? And how can I resolve it?

Flutter uni_links duplicate the app every time a link is clicked

I am implementing a password recovery function based on the url sent to the email. Opening the app based on that url was successful. But instead of directly opening the required page in the app that is in the background, it duplicates the app. Although it still leads me to the password recovery page, now there will be 2 same apps running side by side
Procedure
Enter your email to send the password reset link
Click submit
Open the email containing the recovery link
Duplicate the app and open a recovery password page
Things what happen
Splash screen, first page open in the app, I am trying to do as instructed from uni_links package but still no success. Currently the function getInitialLink has the effect of opening the app based on the recovery link
class SplashController extends GetxController {
final SharedPreferencesHelper _helper = Get.find<SharedPreferencesHelper>();
late StreamSubscription sub;
#override
void onReady() async {
super.onReady();
await checkToken();
}
Future<void> checkToken() async {
await Future.delayed(Duration(seconds: 3));
var token = _helper.getToken();
if (token == null) {
Get.offNamed(Routes.LOGIN);
} else {
Get.offNamed(Routes.MAIN);
}
}
#override
void onInit() {
super.onInit();
initUniLinks();
}
Future<Null> initUniLinks() async {
// Platform messages may fail, so we use a try/catch PlatformException.
try {
String? initialLink = await getInitialLink();
if (initialLink != null) {
print("okay man");
Get.toNamed(Routes.RECOVERY);
}
sub = getLinksStream().listen((link) {
}, onError: (err) {
});
} on PlatformException {
// Handle exception by warning the user their action did not succeed
// return?
}
}
}
I found the solution, actually this answer is already on Stackoverflow, and it's really simple.
In the AndroidManifest.xml file of the app. Find "android:launchMode" and change its old value to singleTask. And here is the result
android:launchMode="singleTask"

Does face ID support for android in Flutter?

i am trying to implement faceID for android in flutter. My android phone has face unlock feature but unable to detect while running my flutter app in phone. i am using below code :
Future<void> _getListOfBiometricTypes() async {
List<BiometricType> listofBiometrics;
try {
listofBiometrics = await _localAuthentication.getAvailableBiometrics();
} on PlatformException catch (e) {
print(e);
}
if (!mounted) return;
setState(() {
_availableBiometricTypes = listofBiometrics;
print(_availableBiometricTypes.length);
print(_availableBiometricTypes.toString());
});
}
only finger print detected. Why not showing face ID detection?

How to get call back of Google location service dialog button click's in flutter?

I need to fetch current location of device in my Flutter App. I have added plugins are location: ^2.3.5 and geolocator: ^5.0.1 to get current location.
All is working fine but when the GPS of my device is off(disabled) then it shows a dialog that i have shown in Image please check it.I need call back on press ok button so that i can get current location and execute next code lines. I will be thankful to you if you help me.
Here have some code.
getCurrentLocation() async{
try {
await location.getLocation().then((locationData){
if(locationData!=null){
moveHomeWithLatLon(context,false,locationData.latitude.toString(),locationData.longitude.toString());
}else{
dialogInternetCheck(context, alert, "Please check location services on device");
}
});
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
error = 'Permission denied';
dialogInternetCheck(context, alert, "Location services "+error);
}
}
}
You should check for the service status result after requesting location service. If it is true that means the user has provided the access. I have provided the example below
bool serviceStatusResult = await location.requestService();
print("Service status activated after request: $serviceStatusResult");
if (serviceStatusResult) {
await _getCurrentLocation();
}
Future<bool> _getCurrentLocation() async {
try {
Location location = Location();
LocationData userLocation = await location.getLocation();
} on PlatformException catch (e) {
Log.info("Location fetch failed : ${e.toString()}");
}
return Future.value(true);
}