How to open my app by a link in a new tab? - android

I'm adding deep linking to my app, i'm using uni_links https://pub.dev/packages/uni_links.
everything works fine but the app opens in the same tab as the link, and not in a new one.
how can I make the app open in another tab?
example in the image: the app opens on the hangouts tab, instead of go back to it's own tab.

You should use flutter dynamic links
You should read this documentation enter link description here
current veriosn: firebase_dynamic_links: ^2.0.4
Example:
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(MaterialApp(
title: 'Dynamic Links Example',
routes: <String, WidgetBuilder>{
'/': (BuildContext context) => _MainScreen(),
'/helloworld': (BuildContext context) => _DynamicLinkScreen(),
},
));
}
class _MainScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() => _MainScreenState();
}
class _MainScreenState extends State<_MainScreen> {
String? _linkMessage;
bool _isCreatingLink = false;
String _testString =
'To test: long press link and then copy and click from a non-browser '
"app. Make sure this isn't being tested on iOS simulator and iOS xcode "
'is properly setup. Look at firebase_dynamic_links/README.md for more '
'details.';
#override
void initState() {
super.initState();
initDynamicLinks();
}
Future<void> initDynamicLinks() async {
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData? dynamicLink) async {
final Uri? deepLink = dynamicLink?.link;
if (deepLink != null) {
// ignore: unawaited_futures
Navigator.pushNamed(context, deepLink.path);
}
}, onError: (OnLinkErrorException e) async {
print('onLinkError');
print(e.message);
});
final PendingDynamicLinkData? data =
await FirebaseDynamicLinks.instance.getInitialLink();
final Uri? deepLink = data?.link;
if (deepLink != null) {
// ignore: unawaited_futures
Navigator.pushNamed(context, deepLink.path);
}
}
Future<void> _createDynamicLink(bool short) async {
setState(() {
_isCreatingLink = true;
});
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: 'https://cx4k7.app.goo.gl',
link: Uri.parse('https://dynamic.link.example/helloworld'),
androidParameters: AndroidParameters(
packageName: 'io.flutter.plugins.firebasedynamiclinksexample',
minimumVersion: 0,
),
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short,
),
iosParameters: IosParameters(
bundleId: 'com.google.FirebaseCppDynamicLinksTestApp.dev',
minimumVersion: '0',
),
);
Uri url;
if (short) {
final ShortDynamicLink shortLink = await parameters.buildShortLink();
url = shortLink.shortUrl;
} else {
url = await parameters.buildUrl();
}
setState(() {
_linkMessage = url.toString();
_isCreatingLink = false;
});
}
#override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
appBar: AppBar(
title: const Text('Dynamic Links Example'),
),
body: Builder(builder: (BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ButtonBar(
alignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: !_isCreatingLink
? () => _createDynamicLink(false)
: null,
child: const Text('Get Long Link'),
),
ElevatedButton(
onPressed: !_isCreatingLink
? () => _createDynamicLink(true)
: null,
child: const Text('Get Short Link'),
),
],
),
InkWell(
onTap: () async {
if (_linkMessage != null) {
await launch(_linkMessage!);
}
},
onLongPress: () {
Clipboard.setData(ClipboardData(text: _linkMessage));
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Copied Link!')),
);
},
child: Text(
_linkMessage ?? '',
style: const TextStyle(color: Colors.blue),
),
),
Text(_linkMessage == null ? '' : _testString)
],
),
);
}),
),
);
}
}
class _DynamicLinkScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
appBar: AppBar(
title: const Text('Hello World DeepLink'),
),
body: const Center(
child: Text('Hello, World!'),
),
),
);
}
}

Related

Json Empty after parse even though status 200

I am trying to parse a JSON after doing a HTTP GET request for my flutter app, however when it is parsed, the body shows as empty, this is the parsing code
urlHausParseBox() {
Future<_GoneSmishinState> fetchUrlResponse() async {
String url = myController.text;
final response = await http.post(
Uri.parse("https://urlhaus-api.abuse.ch/v1/url/"),
headers: <String, String>{
'Accept': 'application/json',
},
body: (<String, String>{
'url': url,
'query_status': query_status,
'url_status' : url_status,
//'status' : status,
//'urlStatus' : urlStatus,
}));
After this I have a check for the 200 status, and when recieved will return this to use after the fact, I printed the fields 'query_status' and 'url_status' but they came up empty so I printed what I was returning here
if (response.statusCode == 200) {
print (_GoneSmishinState.fromJson(jsonDecode(response.body)));
return _GoneSmishinState.fromJson(jsonDecode(response.body));
but all that is printed out is _GoneSmishinState#23f48(lifecycle state: created, no widget, not mounted)
which is not what is supposed to be returned by the HTTP GET request
The rest of my code is below
import 'dart:convert';
import 'package:validators/validators.dart';
import 'package:flutter/material.dart';
import 'package:sms/sms.dart';
import 'dart:io';
import 'dart:developer' as developer;
import 'package:http/http.dart' as http;
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
String url = "https://urlhaus-api.abuse.ch/v1/urls/recent/"; //address for URL file
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key:key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: "Gone Smishin'",
home: GoneSmishin(),
);
}
}
class GoneSmishin extends StatefulWidget {
const GoneSmishin({Key? key}) : super(key: key);
State<GoneSmishin> createState() {
return _GoneSmishinState(url_status: '', query_status: '');
}
}
class _GoneSmishinState extends State<GoneSmishin> {
String message = "";
String word = "";
bool isOn = false;
final myController = TextEditingController();
#override
void dispose() {
myController.dispose();
super.dispose();
}
_GoneSmishinState({
required this.query_status,
required this.url_status,
});
final String query_status;
final String url_status;
factory _GoneSmishinState.fromJson(Map<String, dynamic> json) {
return _GoneSmishinState(
query_status: json["query_status"],
url_status: json["url_status"],
);
}
urlHausParseBox() {
Future<_GoneSmishinState> fetchUrlResponse() async {
String url = myController.text;
final response = await http.post(
Uri.parse("https://urlhaus-api.abuse.ch/v1/url/"),
headers: <String, String>{
'Accept': 'application/json',
},
body: (<String, String>{
'url': url,
'query_status': query_status,
'url_status' : url_status,
}));
if (response.statusCode == 200) {
print (_GoneSmishinState.fromJson(jsonDecode(response.body)));
return _GoneSmishinState.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load website');
}
}
fetchUrlResponse();
if (query_status == "ok" && url_status == "online") {
const Text ('Found in URLHause Database - Probably Smishing');
print("found");
} else if (query_status == "ok" && url_status == "offline") {
const Text ('Found in URLHaus, not online');
print("found offline");
} else {
const Text ('Found Nothing');
print("not found");
print (query_status);
print (url_status);
}
_pushInput() {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (context) {
return Scaffold(
appBar: AppBar(
title: const Text ('Submit a Link')
),
body: (
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField (
controller: myController,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter your Link Text',
contentPadding: EdgeInsets.symmetric(
vertical: 40, horizontal: 20),
),
),
ElevatedButton(
onPressed: () {
urlHausParseBox();
},
child: const Text('Submit')
)
]
)
));
}
)
);
}
#override
var buttonText = 'OFF';
String textHolder = "App is Off";
changeTextON() {
setState(() {
textHolder = "App is ON";
});
isOn == true;
}
changeTextOFF() {
setState(() {
textHolder = "App is OFF";
});
isOn == false;
}
Widget build(BuildContext context) {
final ButtonStyle outlineButtonStyle = OutlinedButton.styleFrom(
primary: Colors.black87,
minimumSize: Size(200, 130),
padding: EdgeInsets.symmetric(horizontal: 200),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(300)),
),
).copyWith(
side: MaterialStateProperty.resolveWith<BorderSide>(
(Set<MaterialState> states) {
return BorderSide(
color: Theme.of(context).colorScheme.primary,
width: 1,
);
},
),
);
return Scaffold(
appBar: AppBar(
title: const Text("Gone Smishin'"),
actions: [
IconButton(
icon: const Icon(Icons.add_link),
onPressed: _pushInput,
tooltip: 'Submit a Link'
)
],
backgroundColor: Colors.red,
),
body: Column (
children: [
Container(
padding: EdgeInsets.fromLTRB(50, 50, 50, 50),
child: Text('$textHolder',
style: TextStyle(fontSize: 50)
),
),
Container(
//child: Text(result)
),
TextButton(
style: outlineButtonStyle,
onPressed: () {
changeTextON();
},
child: Text('ON')
),
TextButton(
style: outlineButtonStyle,
onPressed: () {
changeTextOFF();
},
child: Text("OFF"),
)
]
),
);
}
}
Change this:
_GoneSmishinState({
required this.query_status,
required this.url_status,
});
final String query_status;
final String url_status;
factory _GoneSmishinState.fromJson(Map<String, dynamic> json) {
return _GoneSmishinState(
query_status: json["query_status"],
url_status: json["url_status"],
);
}
to this:
_GoneSmishinState();
var queryStatus = '';
var urlStatus = '';
and this:
if (response.statusCode == 200) {
print (_GoneSmishinState.fromJson(jsonDecode(response.body)));
return _GoneSmishinState.fromJson(jsonDecode(response.body));
}
to:
if (response.statusCode == 200) {
setState(() {
final decoded = json.decode(response.body);
queryStatus = decoded['query_status'];
urlStatus = decoded['url_status'];
}
);
}
And, finally, patch up any unused/misnamed variables. As an aside, it's difficult to read functions declared inside other functions. Is fetchUrlResponse inside urlHausParseBox? Move it outside.

Getting null values in View Flutter

I want to get data of inventory but not getting. I am doing API integration without model because there are some issues in Model just to get data and want to display in to my view.
this is my service class of get data through API.
Future<dynamic> getInventory() async {
var data;
String? userId = await preferenceService.getuserId();
String? accessToken = await preferenceService.getAccessToken();
var response = await http.get(Uri.parse('${AppUrl.getInventory}/$userId'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Barear $accessToken'
});
print("The data of the specific inventory ===========>>>>>>>> " +
response.body.toString());
if (response.statusCode == 200) {
data = jsonDecode(response.body);
print('This is futr dsta --->>> $data');
} else {
data=[];
}
return data;
}
This is my controller class where i am using above service function
Future getMyInvenoryFromService() async {
try {
isLoadingInventory(true);
await inventoryService.getInventory().then((val) {
if (val != []) {
inventoryData = val;
} else {
inventoryData = [];
}
});
} finally {
isLoadingInventory(false);
}
}
But when i am accessing the data with inventoryData (in controller) i am getting null, but in controller i am getting values when debugging. but i am not understanding why i am receiving null values in view.
This is my view,
class _UserInventoryScreenState extends State<UserInventoryScreen> {
InventoryController inventoryController = Get.put(InventoryController());
InventoryService inventoryService = InventoryService();
GiftController giftController = Get.put(GiftController());
GiftStorageService giftStorageService = GiftStorageService();
#override
void initState() {
super.initState();
/*Future delay() async {
await new Future.delayed(new Duration(milliseconds: 3000), () {
inventoryController.getMyInvenoryFromService();
});
}*/
Timer.run(() {
inventoryController.getMyInvenoryFromService();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.pinkAppBar,
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
leading: InkWell(
onTap: () {
Get.back();
},
child: Icon(Icons.arrow_back)),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Inventory'),
InkWell(
onTap: () {
Get.to(AddInventoryScreen());
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration:
BoxDecoration(border: Border.all(color: Colors.white)),
child: Text(
"Add Inventory",
style: TextStyle(fontSize: 16),
),
),
)
],
),
),
body: Obx(() {
return inventoryController.isLoadingInventory.value == true
? Center(child: CircularProgressIndicator())
: ElevatedButton(
onPressed: () async {
await inventoryController.getMyInvenoryFromService();
},
child: Text("${inventoryController.inventoryData.length}"),
);
If your response.statusCode isn't 200 it might be because you are setting wrong your headers:
'Authorization': 'Barear $accessToken'
Change it to:
'Authorization': 'Bearer $accessToken'

This happens because you used a `BuildContext` that does not include the provider of your choice

I am Working on Flutter App Both for web and mobile and stuck at the Following Error:
======== Exception caught by widgets library =======================================================
The following ProviderNotFoundException was thrown building Products(dirty):
Error: Could not find the correct Provider<List<ProductsModel>> above this Products Widget
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- You added a new provider in your `main.dart` and performed a hot-reload.
To fix, perform a hot-restart.
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that Products is under your MultiProvider/Provider<List<ProductsModel>>.
This usually happens when you are creating a provider and trying to read it immediately.
For example, instead of:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>()),
),
}
```
consider using `builder` like so:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context) {
// No longer throws
return Text(context.watch<Example>()),
}
),
}
```
The relevant error-causing widget was:
Products file:///E:/Flutter%20Projects/flutter_web_firebase_host/lib/screens/home/home.dart:37:63
When the exception was thrown, this was the stack:
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49 throw_
packages/provider/src/provider.dart 332:7 _inheritedElementOf
packages/provider/src/provider.dart 284:30 of
packages/flutter_web_firebase_host/screens/databaseScreens/products.dart 10:31 build
packages/flutter/src/widgets/framework.dart 4569:28 build
...
====================================================================================================
Main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_web_firebase_host/model/users.dart';
import 'package:flutter_web_firebase_host/provider/product_provider.dart';
import 'package:flutter_web_firebase_host/screens/wrapper.dart';
import 'package:flutter_web_firebase_host/services/auth.dart';
import 'package:flutter_web_firebase_host/services/firestore_service.dart';
import 'package:provider/provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
final firestoreServise = FirestoreService();
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => ProductProvider(),
),
StreamProvider(
create: (context) => firestoreServise.getProducts(),
initialData: [],
),
StreamProvider<Users>.value(
value: AuthService().user,
initialData: null,
),
],
/* child: StreamProvider<Users>.value(
value: AuthService().user,
initialData: null*/
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: Wrapper(),
),
);
// );
}
Product.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_web_firebase_host/model/ProductModel.dart';
import 'package:flutter_web_firebase_host/screens/databaseScreens/edit_product.dart';
import 'package:provider/provider.dart';
class Products extends StatelessWidget {
#override
Widget build(BuildContext context) {
final products = Provider.of<List<ProductsModel>>(context, listen: false);
return Scaffold(
appBar: AppBar(
title: Text('Products'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => EditProduct()));
}),
],
),
body: (products != null)
? ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(products[index].name),
trailing: Text(products[index].price.toString()),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => EditProduct(products[index])));
},
);
},
)
: Center(child: CircularProgressIndicator()));
}
}
Home.dart
import 'package:flutter/material.dart';
import 'package:flutter_web_firebase_host/screens/databaseScreens/products.dart';
import 'package:flutter_web_firebase_host/services/auth.dart';
import 'package:flutter_web_firebase_host/shared/drawer.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
backgroundColor: Colors.brown[100],
appBar: AppBar(
title: Text('Brew Crew'),
backgroundColor: Colors.brown[100],
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
icon: Icon(Icons.person),
label: Text('logout'),
onPressed: () async {
await _auth.signOut();
},
),
IconButton(
icon: Icon(Icons.add, color: Colors.black),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => Products()));
}),
],
),
body: SingleChildScrollView(
child: Center(
child: Column(
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(0.0, 50, 0, 0),
child: Container(
child: Text(
'Stock Market',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
)),
),
),
Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 0, 0),
child: Image.asset(
"assets/graph.jpg",
width: 500,
height: 600,
),
),
),
],
),
),
),
drawer: MyDrawer(),
),
);
}
}
product_provider.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter_web_firebase_host/model/ProductModel.dart';
import 'package:flutter_web_firebase_host/services/firestore_service.dart';
import 'package:uuid/uuid.dart';
class ProductProvider with ChangeNotifier {
final firestoreService = FirestoreService();
String _name;
double _price;
String _productId;
var uuid = Uuid();
//Geters
String get name => _name;
double get price => _price;
//Seters
changeName(String value) {
_name = value;
notifyListeners();
}
changePrice(String value) {
_price = double.parse(value);
notifyListeners();
}
loadValues(ProductsModel product) {
_name=product.name;
_price=product.price;
_productId=product.productId;
}
saveProduct() {
print(_productId);
if (_productId == null) {
var newProduct = ProductsModel(name: name, price: price, productId: uuid.v4());
firestoreService.saveProduct(newProduct);
} else {
//Update
var updatedProduct =
ProductsModel(name: name, price: _price, productId: _productId);
firestoreService.saveProduct(updatedProduct);
}
}
}
Authservise.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_web_firebase_host/model/users.dart';
import 'package:google_sign_in/google_sign_in.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// create user obj based on firebase user
Users _userFromFirebaseUser(User user) {
return user != null ? Users(uid: user.uid) : null;
}
// auth change user stream
Stream<Users> get user {
return _auth.authStateChanges().map(_userFromFirebaseUser);
}
// sign in anon
Future signInAnon() async {
try {
UserCredential result = await _auth.signInAnonymously();
User user = result.user;
return _userFromFirebaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
// sign in with email and password
Future signInWithEmailAndPassword(String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(email: email, password: password);
User user = result.user;
return user;
} catch (error) {
print(error.toString());
return null;
}
}
// register with email and password
Future registerWithEmailAndPassword(String email, String password) async {
try {
UserCredential result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
User user = result.user;
return _userFromFirebaseUser(user);
} catch (error) {
print(error.toString());
return null;
}
}
// sign out
Future signOut() async {
try {
return await _auth.signOut();
} catch (error) {
print(error.toString());
return null;
}
}
//sign in with google
Future<bool> loginWithGoogle() async {
try {
GoogleSignIn googleSignIn = GoogleSignIn();
GoogleSignInAccount account = await googleSignIn.signIn();
if(account == null )
return false;
UserCredential res = await _auth.signInWithCredential(GoogleAuthProvider.credential(
idToken: (await account.authentication).idToken,
accessToken: (await account.authentication).accessToken,
));
if(res.user == null)
return false;
return true;
} catch (e) {
print(e.message);
print("Error logging with google");
return false;
}
}
}
Basically my app is connect to firebase both for web app and android app. Also i send data to firestore from my app but when i click the add button to go to textfield to send data it give the error as i mention it in start. I am using multiprovider as you can see my main.dart code
Is There anything I missing. I need Help.
the way to fix this is to put MultiProvider as parent of myApp in your main like this
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => ProductProvider(),
),
StreamProvider(
create: (context) => firestoreServise.getProducts(),
initialData: [],
),
StreamProvider<Users>.value(
value: AuthService().user,
initialData: null,
),
],
child:MyApp(
));

Open Flutter Application Using Dynamic Links [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I'm building a flutter application, and am having some trouble actually opening the app using the firebase_dynamic_links package. I basically took the example code found at https://pub.dev/packages/firebase_dynamic_links#-example-tab- in order to get started, but changed the information in their example to match my own firebase project (which has been setup in both android and iOS, but this testing has all been done with iOS).
I will include code and more useful information below, but I was really just hoping to get a simplified example of how this process should work. I have searched online quite a bit, following different tutorials, but none of them have done the trick for me. It could just be that I'm quite new to flutter, and am missing basic things. In my final application, I will be using dynamic links to allow users to invite other users to join the app (as well as groups within the app) via text, just to give context as to why it is needed.
Here is the code for what I have so far, but as I mentioned it is largely based off of the example from the link above.
main.dart
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:io' show Platform;
import 'package:flutter/material.dart';
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:shopsync/helloworld.dart';
void main() async {
//Setup firebase connection
WidgetsFlutterBinding.ensureInitialized();
final FirebaseApp app = await FirebaseApp.configure(
name: 'shop-sync-d97d8',
options: Platform.isIOS
? const FirebaseOptions(
googleAppID: 'my_googleAppID',
gcmSenderID: 'my_senderID',
databaseURL: 'https://shop-sync-d97d8.firebaseio.com',
apiKey: 'AIzaSyC1TdwTs_KRXMGG2oIAGMX8v48HWqS62dc',
)
: const FirebaseOptions(
googleAppID: 'my_googleAppID',
apiKey: 'myApiKey',
databaseURL: 'my_url',
),
);
runApp(MaterialApp(
title: 'Dynamic Links Example',
routes: <String, WidgetBuilder>{
'/': (BuildContext context) => _MainScreen(),
'/helloworld': (BuildContext context) => HelloWorldScreen(),
},
));
}
class _MainScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() => _MainScreenState();
}
class _MainScreenState extends State<_MainScreen> {
String _linkMessage;
bool _isCreatingLink = false;
String _testString =
"To test: long press link and then copy and click from a non-browser "
"app. Make sure this isn't being tested on iOS simulator and iOS xcode "
"is properly setup. Look at firebase_dynamic_links/README.md for more "
"details.";
#override
void initState() {
super.initState();
initDynamicLinks();
}
void initDynamicLinks() async {
final PendingDynamicLinkData data =
await FirebaseDynamicLinks.instance.getInitialLink();
final Uri deepLink = data?.link;
if (deepLink != null) {
Navigator.pushNamed(context, deepLink.path);
}
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData dynamicLink) async {
final Uri deepLink = dynamicLink?.link;
if (deepLink != null) {
Navigator.pushNamed(context, deepLink.path);
}
}, onError: (OnLinkErrorException e) async {
print('onLinkError');
print(e.message);
});
}
Future<void> _createDynamicLink(bool short) async {
setState(() {
_isCreatingLink = true;
});
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: "https://shopsync.page.link",
link: Uri.parse("https://shopsync.page.link/helloworld"),
androidParameters: AndroidParameters(
packageName: 'com.chrismcdonnell.shopsync',
minimumVersion: 0,
),
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short,
),
iosParameters: IosParameters(
bundleId: 'com.chrismcdonnell.shopsync',
minimumVersion: '0',
),
);
Uri url;
if (short) {
final ShortDynamicLink shortLink = await parameters.buildShortLink();
url = shortLink.shortUrl;
} else {
url = await parameters.buildUrl();
}
setState(() {
_linkMessage = url.toString();
_isCreatingLink = false;
});
}
#override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
appBar: AppBar(
title: const Text('Dynamic Links Example'),
),
body: Builder(builder: (BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ButtonBar(
alignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: !_isCreatingLink
? () => _createDynamicLink(false)
: null,
child: const Text('Get Long Link'),
),
RaisedButton(
onPressed: !_isCreatingLink
? () => _createDynamicLink(true)
: null,
child: const Text('Get Short Link'),
),
],
),
InkWell(
child: Text(
_linkMessage ?? '',
style: const TextStyle(color: Colors.blue),
),
onTap: () async {
if (_linkMessage != null) {
await launch(_linkMessage);
}
},
onLongPress: () {
Clipboard.setData(ClipboardData(text: _linkMessage));
Scaffold.of(context).showSnackBar(
const SnackBar(content: Text('Copied Link!')),
);
},
),
Text(_linkMessage == null ? '' : _testString)
],
),
);
}),
),
);
}
}
class _DynamicLinkScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
appBar: AppBar(
title: const Text('Hello World DeepLink'),
),
body: const Center(
child: Text('Hello, World!'),
),
),
);
}
}
helloworld.dart
//IMPORT NEEDED PACKAGES
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
//CREATE STATEFUL WIDGET
class HelloWorldScreen extends StatefulWidget {
#override
_HelloWorldScreen createState() => _HelloWorldScreen();
}
//CREATE STATE WIDGET
class _HelloWorldScreen extends State<HelloWorldScreen> {
#override
Widget build(BuildContext context) {
//Since this class represents an entire screen, return a scaffold with elements inside it
return Scaffold(
backgroundColor: Colors.white,
//Create AppBar w/ title "My Account"
appBar: AppBar(
title: Text('Hello World'),
automaticallyImplyLeading: false,
),
//Most of the content of the screen will go here
body: SafeArea(
child: Text('Testing'),
),
);
}
}
And lastly, here is the dynamic link I created within the console for testing. Although the final version of the application will create them programatically.
If anything else is needed please let me know. Any help would be greatly appreciated.

Image_picker throws removeInvalidNode all the node in jank list is out of time instead of returning image

I am trying to choose image with gallery or camera and display with image_picker.
When I run the app in android, I am able to choose image but not displaying. In contrast I am getting following in the console for the first time.
I/HwViewRootImpl(11213): removeInvalidNode all the node in jank list is out of time
If I repeat the same, it gives following in each time while press the button instead of opening gallery or camera.
I/flutter (11213): PlatformException(already_active, Image picker is already active, null)
I found following solutions from my search but not solved my case.
flutter clean , flutter clean
changing the version of the plugin
updating all dependencies
using retrieveLostData method as stated in the plugin documentation
Following is the code I have used for retrieve image:
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class CameraApp extends StatefulWidget {
#override
_CameraAppState createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
File imageFile;
#override
void initState() {
super.initState();
}
Future _getImage(int type) async {
print("Called Image Picker");
var image = await ImagePicker.pickImage(
source: type == 1 ? ImageSource.camera : ImageSource.gallery,
);
setState(() {
print("$image.path");
imageFile = image;
});
}
Future<void> retrieveLostData() async {
final LostDataResponse response = await ImagePicker.retrieveLostData();
if (response == null) {
return;
}
if (response.file != null) {
setState(() {
if (response.type == RetrieveType.image) {
imageFile = response.file;
}
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Image Editor"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
imageFile != null
? Image.file(
imageFile,
height: MediaQuery.of(context).size.height / 2,
)
: Text("Image editor"),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text("Add Slip"),
content: Row(
children: <Widget>[
Expanded(
child: new FlatButton(
child: new Text("Camera"),
onPressed: () {
_getImage(1);
Navigator.pop(context);
},
),
),
Expanded(
child: new FlatButton(
child: new Text("Gallery"),
onPressed: () {
_getImage(2);
Navigator.pop(context);
},
),
)
],
),
);
},
);
},
tooltip: 'Pick Image',
child: Icon(Icons.camera),
),
);
}
}
I've tried the sample code that you've shared and for some reason got compiler issues but not the same issue as yours. Therefore, I've tried to debug your code. Here is the fixed code:
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
File imageFile;
#override
void initState() {
super.initState();
}
Future _getImage(int type) async {
print("Called Image Picker");
var image = await await ImagePicker.platform.pickImage(
source: type == 1 ? ImageSource.camera : ImageSource.gallery,
);
setState(() {
print("$image.path");
imageFile = File(image.path);
});
}
Future<void> retrieveLostData() async {
final LostData response = await ImagePicker.platform.retrieveLostData();
if (response == null) {
return;
}
if (response.file != null) {
setState(() {
if (response.type == RetrieveType.image) {
imageFile = response.file as File;
}
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Image Editor"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
imageFile != null
? Image.file(
imageFile,
height: MediaQuery.of(context).size.height / 2,
)
: Text("Image editor"),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text("Add Slip"),
content: Row(
children: <Widget>[
Expanded(
child: new FlatButton(
child: new Text("Camera"),
onPressed: () {
_getImage(1);
Navigator.pop(context);
},
),
),
Expanded(
child: new FlatButton(
child: new Text("Gallery"),
onPressed: () {
_getImage(2);
Navigator.pop(context);
},
),
)
],
),
);
},
);
},
tooltip: 'Pick Image',
child: Icon(Icons.camera),
),
);
}
}
Few of the fixes are these lines:
var image = await await ImagePicker.pickImage(
source: type == 1 ? ImageSource.camera : ImageSource.gallery,
);
It's having an error in the compiler so I've changed it to this:
var image = await await ImagePicker.platform.pickImage(
source: type == 1 ? ImageSource.camera : ImageSource.gallery,
);
Same to these lines:
Future<void> retrieveLostData() async {
final LostData response = await ImagePicker.retrieveLostData();
if (response == null) {
return;
}
if (response.file != null) {
setState(() {
if (response.type == RetrieveType.image) {
imageFile = response;
}
});
}
}
Fixed version:
Future<void> retrieveLostData() async {
final LostData response = await ImagePicker.platform.retrieveLostData();
if (response == null) {
return;
}
if (response.file != null) {
setState(() {
if (response.type == RetrieveType.image) {
imageFile = response.file as File;
}
});
}
}
and this
setState(() {
print("$image.path");
imageFile = image;
}
to this:
setState(() {
print("$image.path");
imageFile = File(image.path);
}
The reason could be the version of image_picker that I'm using. Currently I'm using the image_picker: ^0.7.4.
Here is actual output:
I've also encounter an issue if your running this in an Android API version 30, you get this error:
Unhandled Exception: PlatformException(no_available_camera, No cameras available for taking pictures., null, null)
The workaround is to add <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/> in manifest as mentioned in this GitHub post.

Categories

Resources