Can any one tell me how to open another app using flutter? - dart

I want to open a bunch of music app links using links data I have in firebase. I want to open, amazonPrimeMusic, Ganna, Spotify, Wynk, JioSavaan to name some.
Widget buildResultCard(data) {
List items = [Text(data['Ganna']),
IconButton(icon:Icon(Icons.all_inclusive),
onPressed: ()=> {Text("Ganna")}
),
Text(data['Wynk']),
IconButton(icon:Icon(Icons.all_inclusive),
onPressed: ()=> {Text("Ganna")}
),
Text(data['JioSavaan']),
IconButton(icon:Icon(Icons.all_inclusive),
onPressed: ()=> {Text("Ganna")}
),
Text(data['PrimeMusic']),
IconButton(icon:Icon(Icons.all_inclusive),
onPressed: ()=> {Text("Ganna")}
)
];
return ListView.builder(
padding: EdgeInsets.only(top: 20),
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return items[index];
},
);
}
when I tap the button in the list it should open up the particular app for which the link is, for example for AmazonPrimeMusic link, it should open the Amazon music app.

add this to the pubspec.yaml file under dependencies-
device_apps:
android_intent:
url_launcher:
and add these to the top -
import 'package:device_apps/device_apps.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:android_intent/android_intent.dart';
and here is the sample code -
_openJioSavaan (data) async
{String dt = data['JioSavaan'] as String;
bool isInstalled = await DeviceApps.isAppInstalled('com.jio.media.jiobeats');
if (isInstalled != false)
{
AndroidIntent intent = AndroidIntent(
action: 'action_view',
data: dt
);
await intent.launch();
}
else
{
String url = dt;
if (await canLaunch(url))
await launch(url);
else
throw 'Could not launch $url';
}
}

You can use flutter_appavailability package. This plugin allows you to check if an app is installed in mobile and using this plugin you can launch an app.
If already installed then launch otherwise open link in WebView using url_launcher.

Hello you actually need two packages. Check the versions before you use them. First of all you need the id of the app. For example for facebook lite the id is com.facebook.lite. You acn find the id if you go to playstore click share and cope the link. The link for facebook lite is https://play.google.com/store/apps/details?id=com.facebook.lite from this one you can easily understand that the id is after "id=". Its the same on the other apps too.
device_apps: ^2.1.1
url_launcher: ^6.0.3
try {
///checks if the app is installed on your mobile device
bool isInstalled = await DeviceApps.isAppInstalled('si.modula.android.instantheartrate');
if (isInstalled) {
DeviceApps.openApp("si.modula.android.instantheartrate");
} else {
///if the app is not installed it lunches google play store so you can install it from there
launch("market://details?id=" +"si.modula.android.instantheartrate");
}
} catch (e) {
print(e);
}
so the code above check if you have already installed the application. If you have done it it will lunch the application if not it is going to open google playstore so you can see it there. It works only for android devices.

Updated :
url_launcher: ^6.1.4
void launchAnotherApp() async {
if (!await launchUrl(Uri.parse("https://www.instagram.com/username/"),
mode: LaunchMode.externalApplication)) {
throw 'Could not launch ';
}
}
It opens another app on your phone. If targeted app not installed on your device it will open in webview.

I think you can use external_app_launcher: ^3.0.0
https://pub.dev/packages/external_app_launcher

You can easily do it with the help of external_app_launcher.
A Flutter plugin that helps you to open another app from your app. The package asks you for four parameters out of which two are mandatory.
Example code:
RaisedButton(
color: Colors.blue,
onPressed: () {
LaunchApp.openApp(
androidPackageName: 'net.pulsesecure.pulsesecure',
iosUrlScheme: 'pulsesecure://',
appStoreLink: 'itms-apps://itunes.apple.com/us/app/pulse-secure/id945832041',
);
// Enter the package name of the App you want to open and for iOS add the URLscheme to the Info.plist file.
// The `openStore` argument decides whether the app redirects to PlayStore or AppStore.
// For testing purpose you can enter com.instagram.android
},
child: Container(
child: Center(
child: Text("Open",
textAlign: TextAlign.center,
),
),
),
)

Related

Flutter, Deep link is not working on iOS when app is closed

In Flutter, I am using Navigator 2.0 using go_router.
I want deeplink in my app to work properly and my app has some properties which needs to be initialized before going to any screen so I have put my MaterialApp.router(...) in a conditional boolean and Splash screen is shown while app is being initialized.
But deeplink doesn't redirect to given path when app is closed on iOS, it just opens the app.
Everything is working fine in android.
It starts working fine in iOS too when I remove async app initialization function from MaterialApp.
What am I doing wrong? Is there better way to initialze app instead of a conditional check in MaterialApp.
I have created a basic reproducible code repo https://github.com/sgshivamgarg8/testapp. Please try it out. To test deeplinks I have put required scripts in scripts/ folder.
Future<void> _appInit() async {
setState(() {
isLoading = true;
});
await Future.delayed(
const Duration(seconds: 1)); // commenting this line solves the issue
setState(() {
isLoading = false;
});
}
#override
Widget build(BuildContext context) {
return isLoading
? const CircularProgressIndicator()
: MaterialApp.router(
routerConfig: _router,
title: 'Test',
theme: ThemeData.light(),
debugShowCheckedModeBanner: false,
);

flutter - HTML file in WebViewController not loading as expected in iOS Simulator

Below the code loads several tweets in WebViews. This code works flawlessly in Android but produces a different result in iOS Simulator. No errors are produced in logs and nothing in flutter analyze pertain to this page and its classes.
Included <key>io.flutter.embedded_views_preview</key><true/> in info.plist
Widget build(BuildContext context) {
var child;
//print(_tweetHTML);
if (_tweetHTML != '' && _tweetHTML.length > 0) {
final downloadUrl = Uri.file(_filename).toString();
print(downloadUrl); //This prints the expected HTML file
// Create the WebView to contian the tweet HTML
final webView = WebView(
initialUrl: downloadUrl,
javascriptMode: JavascriptMode.unrestricted,
gestureNavigationEnabled: true,
navigationDelegate: (NavigationRequest request) {
if (request.url.startsWith(downloadUrl)) {
//print('allowing navigation to $request');
return NavigationDecision.navigate;
} else if (request.isForMainFrame) {
//print('allowing navigation to $request');
_launchURL(request.url);
return NavigationDecision.prevent;
} else {
//print('blocking navigation to $request}');
return NavigationDecision.prevent;
}
},);
final box = LimitedBox(
maxHeight: 500.0,
child: webView,
);
child = box;
} else {
child = Text('Loading...');
}
return Container(child: child);
}
Expected results:
As you can see this works in Android:
Actual results:
However on iOS:
Option 1: add this to html body
<script id="twitter-wjs" type="text/javascript" async defer src="//platform.twitter.com/widgets.js"></script>
Option 2: Check out this widget on github TweetWebView for Flutter
Option 3: use Flutter WebView Plugin by fluttercommunity.dev, BUT This webview is not integrated in the widget tree, it is a native view on top of the flutter view. You won't be able see snackbars, dialogs, or other flutter widgets that would overlap with the region of the screen taken up by the webview.

Unable to play mp3 files from asset in background(when locked) in iOS flutter

There is a weird bug that occurs when I try to play an audio file(.mp3) from assets, in iOS. I'm using audioplayers plugin for this. My task is to play an audio file (either from local storage or assets), after some delay, while the app is not in foreground, that is while the screen is locked or app in in recent tray. The problem is, when I try to play the audio file after any timer function when iPhone is locked (ex. after timer.delay, Future.delay, etc) the app doesn't plays it. The app plays it after unlocking the iPhone. Also a point is to be noted that EVERYTHING WORKS as intended in DEBUG version of the app, and NOT IN RELEASE version. One more thing, I have added background audio permission in info.plist, which is necessary for playing audio in background. In Android, everything is working fine. Also , I have tried the Audio_service plugin, but it didn't worked as well.
My dummy code for app is as follows:
class AudioTesting extends StatefulWidget {
#override
_AudioTestingState createState() => _AudioTestingState();
}
class _AudioTestingState extends State<AudioTesting> {
#override
void initState() {
AudioPlayer _audioPlayer = AudioPlayer();
AudioCache _audioCache = AudioCache();
super.initState();
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
return AudioServiceWidget(
child: Scaffold(
appBar: AppBar(
title: Text('Testing Screen'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(onPressed: (){
Future.delayed(Duration(seconds: 5),(){
_audioCache.load('$test.mp3');
_audioPlayer = await _audioCache.play('$test.mp3');
//This doesnt works in release mode, but works in debug mode, when played in Locked state
});
},
child: Text('Future.delay func'),
),
RaisedButton(onPressed: (){
sleep(Duration(seconds: 5));
_audioCache.load('$test.mp3');
_audioPlayer = await _audioCache.play('$test.mp3');
// This works completely fine in both version
},
child: Text('sleep func'),
),
],
),
),
),
);
}
}
You can reproduce this bug as follows:
Copy paste the above code snippet.
build a release version and deploy it on any physical iOS device.
Click on the buttons and lock your iPhone.
In my case, I used iPhone 8 with iOS 14.4
Are there any possible alternative solutions that would let me play music in background, when triggered by some functions in iOS?

Pop Back to Native iOS App from FlutterViewController

I added flutter module into my existing iOS app. Currently for testing I am showing a FlutterViewController with ahead of time created FlutterEngine in AppDelegate. Though the flutter screen comes up correctly I am not able to come back to the native iOS app.
Little googling showed that SystemNavigator.pop() will do the work but it is not working for me as it is mentioned here and here. How can I go back to my native iOS app ?
My swift side code to show the flutter screen looks like this
#objc func showFlutter() {
let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine
let flutterViewController =
FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
flutterViewController.modalPresentationStyle = .fullScreen
present(flutterViewController, animated: true, completion: nil)
}
My Flutter side code to pop back to the native iOS app looks like this which is not working.
appBar: AppBar(
leading: new IconButton(
icon: new Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => SystemNavigator.pop(),
),
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
If I replace SystemNavigator.pop() with Navigator.of(context).pop() it does not work either and shows a black screen which makes sense as it does not have any fallback route. This is not popping out Screen as much as I understand, it is closing the whole flutter app. Is not it? How can I solve this?
try exit(0) when platform is iOS , somehow SystemNavigator.pop() does not work.
whole code as below:
onPressed: () {
if(Platform.isIOS) {
Navigator.pop(context);
exit(0);
} else {
SystemNavigator.pop(animated: true);
}
},

Google sign in - Flutter

After using the GoogleSignIn plugin, how do I go about setting a standard avatar, and when signed into Google it changes to the Google PhotoURL? I can use the _handlesignin function fine, but cant get the state to change upon signing in? (I have similar problem with trying to create a sign in/sign out button based on the state of the sign in)
I presume it would be some type of if function then else, but couldn't get it to work.
Yes you are right that it requires some if else statement.
I think you are looking for auth.currentUser() function to check the state of the signin and singout of the user.
The following code checks the user signin status and if the user is signned in then places the user profile photo.
FirebaseAuth auth; //firebase auth
FirebaseUser user; // firebase user
var imageUrl = "assets/image.png"; //you can use a image
//as a default image that would be replaced later with the profile photo
Widget userProfilePhoto()
{
return Center(
child: Container(
height: 100.0,
width: 100.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit : BoxFit.fill,
image: NetworkImage(userurl)
)
),
)
),
}
void checkUser()
{
//Check if the user is signned in or not with the currentUser() function
if(auth.currentUser() != null)
{
setState((){
userImageUrl = user.photoUrl;
//if the user is signned in then set the url to be the image url
});
}
else
{
//call signin method to make the user signin
signIn();
}
}

Resources