I am trying to use CapacitorSQLite with capacitor 3. When I call SQLite.requestPermission() its not showing any dialog box asking for permission and the code seems to be never returning from that call as I can see logs before that call but not after.
code look like
async init(): Promise<void> {
if (this.platform.is('android')) {
try {
const sqlite:any = CapacitorSQLite;
console.log('setting permission handler');
this.handlerPermissions = sqlite.addListener(
'androidPermissionsRequest', async (data:any) => {
if (data.permissionGranted === 1) {
console.log('Perm granted');
this.setupDatabase();
} else {
console.log("Permission not granted");
}
});
console.log('REQUESTING PERMS');
await sqlite.requestPermissions();
} catch (e) {
console.log('error on perm req',e);
const alert = await this.alertCtrl.create({
header: 'No DB access',
message: e.message,
buttons: ['OK']
});
await alert.present();
}
} else {
console.log('not running on android platform');
const alert = await this.alertCtrl.create({
header: 'Not android',
message: this.platform.platforms()[0],
buttons: ['OK']
});
await alert.present();
this.setupDatabase();
}
}
can see the following logs
'setting permission handler'
'REQUESTING PERMS'
but am also expecting one of the following as well
'Perm granted'
"Permission not granted"
'error on perm req'
here's AndroidManifest.xml
<?xml version='1.0' encoding='utf-8'?>
<manifest package="io.ionic.starter" xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="#mipmap/ic_launcher" android:label="#string/app_name" android:roundIcon="#mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="#style/AppTheme" android:usesCleartextTraffic="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:label="#string/title_activity_main" android:launchMode="singleTask" android:name="io.ionic.starter.MainActivity" android:theme="#style/AppTheme.NoActionBarLaunch">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true" android:name="androidx.core.content.FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/file_paths" />
</provider>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Am I missing anything? Capacitor doc says plug will have user-permission that need to be added but couldn't see any for sqlite.
Thanks a lot
You do not need specific permissions for this plugin. Check the documentation for examples of how to use this plugin in Angular, React or Vue depends on what you need.
Related
As a normal behaviour, Android shows up a "New Tag collected" message when it reads an NFC tag.
However, I do not want this message to appear when I use my app.
I searched for many solutions on the internet, but with no success.
Any ideas about what I can do?
I will share the function I use to get the tag's ID and my AndroidManifest.xml.
const readNFC = async (): Promise<string | undefined> => {
return new Promise(async (resolve, reject) => {
try {
await NfcManager.requestTechnology(NfcTech.NdefFormatable);
const tag = await NfcManager.getTag();
if (Platform.OS === 'ios') {
await NfcManager.setAlertMessageIOS('TAG detect');
}
NfcManager.cancelTechnologyRequest();
if (tag) {
resolve(tag.id);
}
} catch (er) {
reject('An error has occurred.');
}
});
};
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.newronda">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:name=".MainApplication"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:roundIcon="#mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/vnd.hello.sample.nfcmanager" />
</intent-filter>
</activity>
</application>
</manifest>
I managed to add to services in my app (Create Excel file - Create PDF file)
In both services I had a problem with open file packages..
Packages I used:
open_document 1.0.5
open_filex: ^4.1.1
open_file: ^3.2.1
I used many packages for that purpose, but I think there is a problem I didn't catch it by adding scripts in (AndroidManifest.xml) file, build.gradle (project level).
I will show you my code.
By the way, I'm using GetX package, so there is the Controller class:
import 'dart:io';
import 'dart:typed_data';
import 'package:get/get.dart';
import 'package:open_document/open_document.dart';
import 'package:path_provider/path_provider.dart';
import 'package:uuid/uuid.dart';
import '../model/bill_model.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
class BillController extends GetxController {
static BillController instance = BillController();
List<String> options = ['Cleaning Tax', 'Running Costs', 'Delay Tax'];
List<BillModel> taxOptions = [
BillModel(id: const Uuid().v1(), name: 'Cleaning Tax'),
BillModel(id: const Uuid().v1(), name: 'Running Costs'),
BillModel(id: const Uuid().v1(), name: 'Delay Tax'),
];
List<BillModel> selectedOptions = [];
Future<Uint8List> createPDF() async {
final pdf = pw.Document();
pdf.addPage(
pw.Page(
build: (context) {
return pw.Center(
child: pw.Text('Hello World'),
);
},
),
);
update();
return pdf.save();
}
Future savePdfFile(String fileName, Uint8List byteList) async {
final output = await getTemporaryDirectory();
var filePath = '${output.path}/$fileName.pdf';
final file = File(filePath);
await file.writeAsBytes(byteList);
await OpenDocument.openDocument(filePath: filePath);
update();
}
}
And here is where I call it in the UI class:
GetBuilder<BillController>(
builder: (controller) => Padding(
padding: EdgeInsets.only(top: Dimensions.height80),
child: AddSaveButton(
title: 'Create bill',
fontSize: Dimensions.font24,
onPress: () async {
final data = await controller.createPDF();
controller.savePdfFile('invoice_5', data);
},
),
),
),
I faced this problem:
Unhandled Exception: PlatformException(channel-error, Unable to establish connection on channel., null, null)
and got a solution form this link in StackOverFlow Unhandled Exception: PlatformException(channel-error, Unable to establish connection on channel., null, null)
After that got new problem : app:processDebugResources and got the acceptable answer in StackOverFlow too in this link: Execution failed for task ':app:processDebugResources' in Flutter project
my AndroidManifest.xml file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.water_collection">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.open_document_example.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
<application
android:label="Water collection"
android:name="${applicationName}"
android:icon="#mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="#style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
Finally nothing had improved, but still didn't know why?!!
Any help will be appreciated.
Finally after a week of searching, I have got a solution..
All what I did was correct, but the problem was in the "Open file" packages..
All packages I used have problems.
At the end I use a package called open_file_plus and every thing worked fine.
I got some information from this URL: Open file by default application flutter
I'm trying to run a basic API call in Flutter using PHP and a MySQL database, but I'm receiving an error which reads:
E/flutter ( 7461): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: Bad state: Insecure HTTP is not allowed by platform
What I've Tried
I have tried the solution proposed here: Bad state: Insecure HTTP is not allowed by platform:
and here: https://www.programmersought.com/article/49295775092/
Sample Code
home.dart
import 'package:flutter/material.dart';
import 'package:flutter_crud/env.sample.dart';
import 'dart:convert';
import 'package:http/http.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
void getData() async{
Response response = await get(Uri.parse("${Env.URL_PREFIX}/list"));
Map data = jsonDecode(response.body);
print(data);
}
#override
void initState() {
super.initState();
getData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter CRUD API'),
centerTitle: true,
),
body:Center(
child: Text('Hello'),
)
);
}
}
The URI prefix comes from env.sample.dart:
class Env{
static String URL_PREFIX = "http://[my.IP.address.here]/flutter_crud";
}
In the debug/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jacobcollinsdev.flutter_crud">
<uses-permission android:name="android.permission.INTERNET"/>
<application android:usesCleartextTraffic="true"/>
</manifest>
In the main/AndroidManifest.xml file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jacobcollinsdev.flutter_crud">
<uses-permission android:name="android.permission.INTERNET" /> <------- I added this line
<application
android:label="flutter_crud"
android:icon="#mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="#xml/network_security_config"> <------ I added this line
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="#style/NormalTheme"
/>
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="#drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<uses-library
android:name="org.apache.http.legacy"
android:required="false" /> <-------I added this code block
</application>
</manifest>
Finally, I have also created this file in android/app/main/res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config clearTextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
So far nothing has resolved the error and I'm all out of ideas. Any feedback would be grand!
simply these lines in
android/app/src/main/AndroidManifest.xml
1). Add <uses-permission android:name="android.permission.INTERNET" />
before application tag
2). Add android:usesCleartextTraffic="true" inside application tag
You should try loading your images from a SSL certificate domain. That is using HTTPS rather than HTTP.
So for your case, replace "http://[my.IP.address.here]/flutter_crud" to use https://.
remove This
class Env{
static String URL_PREFIX = "http://[my.IP.address.here]/flutter_crud";
}
add this
class Env{
static String URL_PREFIX = "https://[my.IP.address.here]/flutter_crud";
}
use https://
instead of http://
I am trying the push notification for the first time. I followed a tutorial. After running the code, I send a test push notification from Firebase. The notification is appearing in the console log but its not coming in the notification pane.
My code is as follows:
RemotePushNotification.js
import React, { useEffect } from 'react'
import PushNotification from 'react-native-push-notification'
const RemotePushController = () => {
useEffect(() => {
PushNotification.configure({
// (optional) Called when Token is generated (iOS and Android)
onRegister: function (token) {
console.log('TOKEN:', token)
},
// (required) Called when a remote or local notification is opened or received
onNotification: function (notification) {
console.log('REMOTE NOTIFICATION ==>', notification)
})
// process the notification here
},
// Android only: GCM or FCM Sender ID
senderID: '############',
popInitialNotification: true,
requestPermissions: true
})
}, [])
return null
}
export default RemotePushController
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app3">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:name=".MainApplication"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:roundIcon="#mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name"
android:value="YOUR NOTIFICATION CHANNEL NAME"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description"
android:value="YOUR NOTIFICATION CHANNEL DESCRIPTION"/>
<!-- Change the resource name to your App's accent color - or any other color you want -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
android:resource="#android:color/white"/>
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
This is the console log
REMOTE NOTIFICATION ==> {"channelId": "fcm_fallback_notification_channel", "color": null, "data": {}, "finish": [Function finish], "foreground": true, "id": "1987265985", "message": "fwafwaawf", "priority": "high", "sound": null, "tag": "campaign_collapse_key_4557183047135736330", "title": "fawfaf", "userInteraction": false, "visibility": "private"}
I believe you have to create a channel management for android.
https://github.com/zo0r/react-native-push-notification#channel-management-android.
Go through above link you will get to know since few months back they have updated it
Add below line in I am trying the push notification for the first time. I followed a tutorial. After running the code, I send a test push notification from Firebase. The notification is appearing in the console log but its not coming in the notification pane.
My code is as follows: AndroidManifest.xml
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/default_notification_channel_id" />
Hopefully you will receive notification
I'm writing an app which needs to get your location at a certain point.
I used the ionic native geolocation for this which is send to the google API for reverse geocoding.
It works completely like I want it to when I just use ionic serve.
But when I try to run it on android it doesn't seem to work at all.
if I run ionic cordova run android --device -c -l I get these console logs:
[20:23:58] console.log: Device Ready
[20:23:58] console.log: [object Object]
[20:23:58] console.log: No location Error
this is the snippet of code at that page.
constructor(public navCtrl: NavController, public navParams: NavParams, private geo: Geolocation, private platform: Platform, public geocodeProvider: GeocodeProvider) {
this.platform.ready().then(()=>{
console.log("Device Ready");
this.geo.getCurrentPosition(this.options).then(resp =>{
console.log(resp.coords.latitude);
console.log(resp.coords.longitude);
this.getCountry(resp.coords.latitude,resp.coords.longitude);
}).catch((err)=>{
console.log(err)
});
});
}
getCountry(lat,long){
this.geocodeProvider.getCountry(lat,long).subscribe(result =>this.country = this.getName(result));
}
getName(JSON:IRootObject){
var location = JSON.results[0].address_components[0].long_name;
return JSON.results[0].address_components[0].long_name;
}
I can't seem to find out why it isn't working.
EDIT:
My android manifest:
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" package="io.ionic.starter" xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="26" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<uses-feature android:name="android.hardware.location" />
<uses-feature android:name="android.hardware.location.gps" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<application android:hardwareAccelerated="true" android:icon="#mipmap/icon" android:label="#string/app_name" android:supportsRtl="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="#string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="#android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="#string/launcher_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="com.google.android.geo.API_KEY" android:value="***" />
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
</application>
</manifest>
I think you are on Android 6 or above. There you have to request permissions at runtime.
Install:
$ ionic cordova plugin add cordova-plugin-android-permissions
$ npm install --save #ionic-native/android-permissions
Use:
import { AndroidPermissions } from '#ionic-native/android-permissions';
constructor(private androidPermissions: AndroidPermissions) {
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.LOCATION_COURSE)
.then(
result => console.log('Has permission?', result.hasPermission),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.LOCATION_COURSE)
);
}
You have to do this request for each permission you need.
See https://ionicframework.com/docs/native/android-permissions/ for details.
In the Guidelines by Google you find additional infos how to request permissions and handle the user response (explain why you need the permissions, don't ask to much, ...)
https://developer.android.com/training/permissions/requesting.html
#fastr.de I added this:
constructor(public navCtrl: NavController, public navParams: NavParams, private geo: Geolocation, private platform: Platform, public geocodeProvider: GeocodeProvider,private androidPermissions: AndroidPermissions) {
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.ACCESS_FINE_LOCATION).then(
result => console.log('Has permission? ACCESS_FINE_LOCATION',result.hasPermission),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.ACCESS_FINE_LOCATION)
);
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.ACCESS_LOCATION_EXTRA_COMMANDS).then(
result => console.log('Has permission? ACCESS_LOCATION_EXTRA_COMMANDS',result.hasPermission),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.ACCESS_LOCATION_EXTRA_COMMANDS)
);
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.ACCESS_COARSE_LOCATION).then(
result => console.log('Has permission? ACCESS_COARSE_LOCATION',result.hasPermission),
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.ACCESS_COARSE_LOCATION)
);
this.platform.ready().then(()=>{
console.log("Device Ready");
this.androidPermissions.requestPermissions([this.androidPermissions.PERMISSION.ACCESS_COARSE_LOCATION, this.androidPermissions.PERMISSION.ACCESS_FINE_LOCATION,this.androidPermissions.PERMISSION.ACCESS_LOCATION_EXTRA_COMMANDS]);
this.geo.getCurrentPosition(this.options).then(resp =>{
console.log(resp.coords.latitude);
console.log(resp.coords.longitude);
this.getCountry(resp.coords.latitude,resp.coords.longitude);
}).catch((err)=>{
console.log(err)
});
});
}
and the console output is:
[16:17:15] console.log: Device Ready
[16:17:15] console.log: Has permission? ACCESS_LOCATION_EXTRA_COMMANDS true
[16:17:15] console.log: Has permission? ACCESS_FINE_LOCATION true
[16:17:15] console.log: Has permission? ACCESS_COARSE_LOCATION true
[16:17:15] console.log: [object Object]
[16:17:15] console.log: No location Error