I have an ionic App that has an external webpage it links to. I can listen for browser closing, but I also wish to listen for the user using the Android back button to return return to the App. here is the code I use.
import { Browser } from '#capacitor/browser';
viewWebPage = async ( url: string ) => {
url = this.LINK
await Browser.open( { url: url } );
Browser.addListener('browserFinished', () => {
console.log("browser finished");
});
// add listener for back button
};
Turns out if you use the Android back button to completely exit the open browser window the Capacitor Browser plugin will capture the event with
import { Browser } from '#capacitor/browser';
viewWebPage = async ( url: string ) => {
url = this.LINK
await Browser.open( { url: url } );
Browser.addListener('browserFinished', () => {
console.log("browser exited");
});
};
I'm running vue.js app using vite and everything works fine in chrome/firefox browsers. also the basic functionality works fine on safari and IOS. I'm trying to access the cache storage and sync token between pwa app and safari browser.
Two weird things happens:
When user login to the website I set the cache and I simulate user behavior. for example a basic user login and then change the url to something else and back to the website. When this thing happens the caches variable is undefined...
When I set cache and user installs pwa there's no data stored in cache storage.
Note: I persist cache in local-storage of the browser and I know that I can't use local-storage to get token thus I use cache to share it between browser and pwa
Codes
How I cache token:
const CACHE_NAME = "auth";
const TOKEN_KEY = "token";
const FAKE_ENDPOINT = "/get-token";
export const saveToken = async (token: string) => {
try {
const cache = await caches.open(CACHE_NAME);
const responseBody = JSON.stringify({
[TOKEN_KEY]: token
});
const response = new Response(responseBody);
await cache.put(FAKE_ENDPOINT, response);
console.log("Token saved! 🎉");
console.log("Saved token: ", await getToken())
} catch (error) {
// It's up to you how you resolve the error
console.log("saveToken error:", {error});
}
};
export const getToken = async () => {
try {
const cache = await caches.open(CACHE_NAME);
const response = await cache.match(FAKE_ENDPOINT);
if (!response) {
return null;
}
const responseBody = await response.json();
return responseBody[TOKEN_KEY];
} catch (error) {
// Gotta catch 'em all
console.log("getToken error:", {error});
}
};
Plug-in functions return version in imagepath.
same behaviour in all these functions getImagesPath() ,getVideoPath(),getAudioPath(),getFilePath().
Plug in: https://pub.dev/packages/storage_path , storage_path: ^0.2.0
Future<void> getImagesPath() async {
String imagespath = "";
try {
**imagespath = await StoragePath.imagesPath;** // return IOS Version (Example: Ios 15.2)
var response = jsonDecode(imagespath);
print(response);
var imageList = response as List;
List<FileModel> list = imageList.map<FileModel>((json) => FileModel.fromJson(json)).toList();
setState(() {
imagePath = list[11].files[0];
});
} on PlatformException {
imagespath = 'Failed to get path';
}
return imagespath;
}
I got it. Actually, I missed reading the Readme file. This plug-in is only available with android.
ONLY FOR ANDROID
I have used the following method as specified in the documentation.
Future<void> launchUniversalLink(String url) async {
if (await canLaunch(url)) {
final bool nativeAppLaunchSuccess = await launch(url, forceSafariVC: false, universalLinksOnly: true);
print(nativeAppLaunchSuccess);
}else {
print('launch not successfull');
}
}
if I give URL = 'https://www.WhatsApp.com'
print(nativeAppLaunchSuccess); output ==> true
but still the app launches in the browser.
can anyone help me with this problem
Oh I'm sorry. This is my mistake.
Please use 'device_apps' flutter package and usage is below.
And here is a how to know app package name.
https://www.techmesto.com/find-android-app-package-name/
In ios, you know other app's custom Url schema that officially opened.
But usually we can not know that url.
So below ios code is executed, it will open appstore page and need to push 'open' button.
if (Platform.isAndroid) {
if (await DeviceApps.isAppInstalled('com.nbt.moves') ==
true) {
DeviceApps.openApp('com.nbt.moves');
}
} else {
const url =
'https://apps.apple.com/kr/app/%EC%BA%90%EC%8B%9C%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%93%9C-%EC%8A%A4%ED%85%9D%EC%97%85/id1400703652?uo=4';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
Hello I search a simple example (Android and iOS) to send SMS with this package
https://pub.dartlang.org/packages/url_launcher
In the plugin page I only see how to open sms native app with phone number, but no extra message
sms:<phone number>, e.g. sms:5550101234 Send an SMS message to <phone
number> using the default messaging app
On Android the full sms: URI is supported and you can send a message with a body like that (RFC5724):
_textMe() async {
// Android
const uri = 'sms:+39 348 060 888?body=hello%20there';
if (await canLaunch(uri)) {
await launch(uri);
} else {
// iOS
const uri = 'sms:0039-222-060-888?body=hello%20there';
if (await canLaunch(uri)) {
await launch(uri);
} else {
throw 'Could not launch $uri';
}
}
}
On iOS the official doc says you can only use the number field of The URI.
Instead as Konstantine pointed out, if you use a non standard URI and instead and instead of starting the query string with ? you use & it still works as well. It seems like an undocumented feature.
The sms scheme is used to launch the Messages app. The format for URLs
of this type is “sms:”, where is an optional parameter
that specifies the target phone number of the SMS message. This
parameter can contain the digits 0 through 9 and the plus (+), hyphen
(-), and period (.) characters. The URL string must not include any
message text or other information.
PS. to check the plaform you could use the dart.io library Platform class:
_textMe() async {
if (Platform.isAndroid) {
const uri = 'sms:+39 348 060 888?body=hello%20there';
await launch(uri);
} else if (Platform.isIOS) {
// iOS
const uri = 'sms:0039-222-060-888&body=hello%20there';
await launch(uri);
}
}
you can trying this for android and IOS:
sendMessage() async {
if(Platform.isAndroid){
//FOR Android
url ='sms:+6000000000?body=message';
await launch(url);
}
else if(Platform.isIOS){
//FOR IOS
url ='sms:+6000000000&body=message';
}
}
This answer is for the new people coming in here for answers.
The previous answers are right however they won't work on iOS.
The App might crash on iOS but work on Android.
so to solve that we need to implement sending SMS in the way given below
String? encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((e) => '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
Uri smsUri = Uri(
scheme: 'sms',
path: '$phoneNumber',
query: encodeQueryParameters(<String, String>{
'body':
'Hey this is message body'
}),
);
try {
if (await canLaunch(smsUri.toString())) {
await launch(smsUri.toString());
}
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Some error occured'),
),
);
}
Final updated answer post flutter 3 and latest url launcher package
smsUri = Uri(scheme: 'sms', path: phoneNumber);
try {
print(smsUri.toString());
if (await canLaunchUrl(
smsUri,
)) {
await launchUrl(smsUri);
}
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: const Text('Some error occured'),
),
);
}
Here is the updated answer for sending SMS based on the OS of the device. I have tried the previous answers but I was facing body text issues on IOS devices.
_launchSms() async {
try {
if (Platform.isAndroid) {
String uri = 'sms:$phoneNumber?body=${Uri.encodeComponent("Hello there")}';
await launchUrl(Uri.parse(uri));
} else if (Platform.isIOS) {
String uri = 'sms:$phoneNumber&body=${Uri.encodeComponent("Hello there")}';
await launchUrl(Uri.parse(uri));
}
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Some error occurred. Please try again!'),
),
);
}
}