Can I receive a share intent without opening my Flutter app? - flutter

I'm creating an app in Flutter to store any type of media, imagem, video, pdfs, etc. And I want to be able to receive share intents from other apps in the easiest way possible for the user.
So, my idea is to be able to simply receive the media without needing to open the app for the user to input something, they should simply select my app to receive the media and continue using the "source" app. Is that possible in flutter?

this should work very well based on your requirement, receive_sharing_intent, just following the setup for android & ios and try the example:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
StreamSubscription _intentDataStreamSubscription;
List<SharedMediaFile> _sharedFiles;
String _sharedText;
#override
void initState() {
super.initState();
// For sharing images coming from outside the app while the app is in the memory
_intentDataStreamSubscription =
ReceiveSharingIntent.getMediaStream().listen((List<SharedMediaFile> value) {
setState(() {
print("Shared:" + (_sharedFiles?.map((f)=> f.path)?.join(",") ?? ""));
_sharedFiles = value;
});
}, onError: (err) {
print("getIntentDataStream error: $err");
});
// For sharing images coming from outside the app while the app is closed
ReceiveSharingIntent.getInitialMedia().then((List<SharedMediaFile> value) {
setState(() {
_sharedFiles = value;
});
});
// For sharing or opening urls/text coming from outside the app while the app is in the memory
_intentDataStreamSubscription =
ReceiveSharingIntent.getTextStream().listen((String value) {
setState(() {
_sharedText = value;
});
}, onError: (err) {
print("getLinkStream error: $err");
});
// For sharing or opening urls/text coming from outside the app while the app is closed
ReceiveSharingIntent.getInitialText().then((String value) {
setState(() {
_sharedText = value;
});
});
}
#override
void dispose() {
_intentDataStreamSubscription.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) {
const textStyleBold = const TextStyle(fontWeight: FontWeight.bold);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
children: <Widget>[
Text("Shared files:", style: textStyleBold),
Text(_sharedFiles?.map((f)=> f.path)?.join(",") ?? ""),
SizedBox(height: 100),
Text("Shared urls/text:", style: textStyleBold),
Text(_sharedText ?? "")
],
),
),
),
);
}
}

Using Receive Sharing intent package, you can receive text & media files in closed as well as opened application.
Below code snippet to receive intent in closed application,
// For sharing images coming from outside the app while the app is closed
ReceiveSharingIntent.getInitialMedia().then((List<SharedMediaFile> value) {
setState(() {
_sharedFiles = value;
});
});
You can go through this link for further understanding on how to receive intent in already opened & closed application.

Related

How can I integrate Google FIT in Flutter app?

I want steps count and calories burned data in my flutter app. I am using health: ^3.1.1+1 package but I'm getting "Authorization not granted" even after giving all permission. I even used permission handler for permission and I was successfully getting permission with permission handler, still I am not getting data from health package. Please help me with the process to authorize my app to fetch data from Google Fit API.
I have successfully generate my OAuth client id from google console and added the json file in my project. Please let me know if there is any other place where I need to add my client id.
I am using given below sample code provided in with the package.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:health/health.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
enum AppState {
DATA_NOT_FETCHED,
FETCHING_DATA,
DATA_READY,
NO_DATA,
AUTH_NOT_GRANTED
}
class _MyAppState extends State<MyApp> {
List<HealthDataPoint> _healthDataList = [];
AppState _state = AppState.DATA_NOT_FETCHED;
#override
void initState() {
super.initState();
}
/// Fetch data from the healt plugin and print it
Future fetchData() async {
// get everything from midnight until now
DateTime startDate = DateTime(2020, 11, 07, 0, 0, 0);
DateTime endDate = DateTime(2025, 11, 07, 23, 59, 59);
HealthFactory health = HealthFactory();
// define the types to get
List<HealthDataType> types = [
HealthDataType.STEPS,
HealthDataType.WEIGHT,
HealthDataType.HEIGHT,
HealthDataType.BLOOD_GLUCOSE,
HealthDataType.DISTANCE_WALKING_RUNNING,
];
setState(() => _state = AppState.FETCHING_DATA);
// you MUST request access to the data types before reading them
bool accessWasGranted = await health.requestAuthorization(types);
int steps = 0;
if (accessWasGranted) {
try {
// fetch new data
List<HealthDataPoint> healthData =
await health.getHealthDataFromTypes(startDate, endDate, types);
// save all the new data points
_healthDataList.addAll(healthData);
} catch (e) {
print("Caught exception in getHealthDataFromTypes: $e");
}
// filter out duplicates
_healthDataList = HealthFactory.removeDuplicates(_healthDataList);
// print the results
_healthDataList.forEach((x) {
print("Data point: $x");
steps += x.value.round();
});
print("Steps: $steps");
// update the UI to display the results
setState(() {
_state =
_healthDataList.isEmpty ? AppState.NO_DATA : AppState.DATA_READY;
});
} else {
print("Authorization not granted");
setState(() => _state = AppState.DATA_NOT_FETCHED);
}
}
Widget _contentFetchingData() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
padding: EdgeInsets.all(20),
child: CircularProgressIndicator(
strokeWidth: 10,
)),
Text('Fetching data...')
],
);
}
Widget _contentDataReady() {
return ListView.builder(
itemCount: _healthDataList.length,
itemBuilder: (_, index) {
HealthDataPoint p = _healthDataList[index];
return ListTile(
title: Text("${p.typeString}: ${p.value}"),
trailing: Text('${p.unitString}'),
subtitle: Text('${p.dateFrom} - ${p.dateTo}'),
);
});
}
Widget _contentNoData() {
return Text('No Data to show');
}
Widget _contentNotFetched() {
return Text('Press the download button to fetch data');
}
Widget _authorizationNotGranted() {
return Text('''Authorization not given.
For Android please check your OAUTH2 client ID is correct in Google Developer Console.
For iOS check your permissions in Apple Health.''');
}
Widget _content() {
if (_state == AppState.DATA_READY)
return _contentDataReady();
else if (_state == AppState.NO_DATA)
return _contentNoData();
else if (_state == AppState.FETCHING_DATA)
return _contentFetchingData();
else if (_state == AppState.AUTH_NOT_GRANTED)
return _authorizationNotGranted();
return _contentNotFetched();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.file_download),
onPressed: () {
fetchData();
},
)
],
),
body: Center(
child: _content(),
)),
);
}
}
Go to Google Cloud Platform > Apis & Services > OAuth consent screen and check if your app is in Testing mode and add gmails to allow user to use the Oauth
Remember to upload the android debug key sha1!
New version of the health package solved my problem.

how to get mobile number in flutter

I am using "mobile_number(version - 1.0.3)" plugin to get mobile number in flutter app, am running in original device but i couldn't get mobile number.instead of errors i can get mobile number as null along with other sim details as shown in screen shot.
help me to resolve this problem, i had just copy pasted the example given by plugin that is the code
plugin link
It says:
Note: If the mobile number is not pre-exist on sim card it will not return te phone number.
I think mobile number does not pre-exist on the SIM if the SIM is not original (i.e. replaced)
If the phone number isn't stored on the sim (aka null), then you can't get it from anywhere else, in that case you probably want to forward the user to a different page where they can type the phone number using TextField and then store it somewhere
Use Mobile_number package to get mobile number and other details. For example
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mobile_number/mobile_number.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _mobileNumber = '';
List<SimCard> _simCard = <SimCard>[];
#override
void initState() {
super.initState();
MobileNumber.listenPhonePermission((isPermissionGranted) {
if (isPermissionGranted) {
initMobileNumberState();
} else {}
});
initMobileNumberState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initMobileNumberState() async {
if (!await MobileNumber.hasPhonePermission) {
await MobileNumber.requestPhonePermission;
return;
}
String mobileNumber = '';
// Platform messages may fail, so we use a try/catch PlatformException.
try {
mobileNumber = (await MobileNumber.mobileNumber)!;
_simCard = (await MobileNumber.getSimCards)!;
} on PlatformException catch (e) {
debugPrint("Failed to get mobile number because of '${e.message}'");
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_mobileNumber = mobileNumber;
});
}
Widget fillCards() {
List<Widget> widgets = _simCard
.map((SimCard sim) => Text(
'Sim Card Number: (${sim.countryPhonePrefix}) - ${sim.number}\nCarrier Name: ${sim.carrierName}\nCountry Iso: ${sim.countryIso}\nDisplay Name: ${sim.displayName}\nSim Slot Index: ${sim.slotIndex}\n\n'))
.toList();
return Column(children: widgets);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
children: <Widget>[
Text('Running on: $_mobileNumber\n'),
fillCards()
],
),
),
),
);
}
}

How to generate Pre Launch report for Flutter App?

I have a login screen which uses phone authentication for creating account.
I have used Firebase Phone auth for login and also have stored one number for testing purpose.
But don't know how to pass the number and OTP to generate Pre Launch Report.
They are asking for Username, Username Resource ID, Password , Password Resource ID.
Where to find Resource ID for username and password fields in flutter code.
In the Google play console at the bottom of the left
Click on App content
Click on App access
Click on manage
Click on add new instructions
Add your all details here it should be test accounts
Try this :
dependencies:
flutter_runtime_env: ^0.0.4
Example:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_runtime_env/flutter_runtime_env.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _isInFirebaseTestLab = false;
#override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
var result = await inFirebaseTestLab();
setState(() {
_isInFirebaseTestLab = result;
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('is in FirebaseTest Lab'),
),
body: Center(
child: Text('is in FirebaseTest Lab: $_isInFirebaseTestLab\n'),
),
),
);
}
}

Where to put a function to trigger on exit/stop/close event of flutter/dart application?

I have a simple greeter gRPC example server code written in go and exported as C library that I'm trying to run with a flutter app using go-flutter desktop engine via ffi and dart Isolates.
I have made a StopGrpc() function, which works if I call it to stop gRPC server.
But if I don't manually first trigger the StopGrpc() function before exiting the application I keep getting the following waiting for isolates _startGrpc to check in which never ends, and I have to force quit the application.
An Observatory debugger and profiler on Flutter test device is available at: http://127.0.0.1:50300/
go-flutter: closing application
Attempt:11 waiting for isolate _startGrpc to check in
Attempt:12 waiting for isolate _startGrpc to check in
Here's the full copy of lib/main.dart file for reference:
/// Example code from: https://codingwithjoe.com/dart-fundamentals-isolates/
/// Flutter example code from: https://gist.github.com/jebright/a7086adc305615aa3a655c6d8bd90264
import 'dart:async';
import 'package:flutter/material.dart';
import 'dart:isolate';
import 'dart:ffi';
// import 'package:ffi/ffi.dart';
// -- Normal gRPC server type definitions --
typedef startgrpc_func = void Function();
typedef StartGrpc = void Function();
typedef stopgrpc_func = void Function();
typedef StopGrpc = void Function();
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Isolate Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Isolates'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Isolate _isolate;
bool _running = false;
static int _counter = 0;
String notification = "";
ReceivePort _receivePort;
void _start() async {
_running = true;
_receivePort = ReceivePort();
_isolate = await Isolate.spawn(_startGrpc, _receivePort.sendPort);
_receivePort.listen(_handleMessage, onDone: () {
print("done!");
});
}
static void _checkTimer(SendPort sendPort) async {
Timer.periodic(new Duration(seconds: 1), (Timer t) {
_counter++;
String msg = 'notification ' + _counter.toString();
print('SEND: ' + msg);
sendPort.send(msg);
});
}
static void _startGrpc(SendPort sendPort) async {
// -- Normal gRPC server start code --
final greeter = DynamicLibrary.open('assets/greeter.so');
final void Function() startGrpc = greeter
.lookup<NativeFunction<Void Function()>>('StartGrpc')
.asFunction();
String msg = "Started gRPC server...";
sendPort.send(msg);
startGrpc();
}
static void _stopGrpc() async {
// -- Normal gRPC server stop code --
final greeter = DynamicLibrary.open('assets/greeter.so');
final void Function() stopGrpc = greeter
.lookup<NativeFunction<Void Function()>>('StopGrpc')
.asFunction();
// String msg = "Stoped gRPC server...";
// sendPort.send(msg);
stopGrpc();
}
void _handleMessage(dynamic data) {
print('RECEIVED: ' + data);
setState(() {
notification = data;
});
}
void _stop() {
if (_isolate != null) {
setState(() {
_running = false;
notification = '';
});
_stopGrpc();
_receivePort.close();
_isolate.kill(priority: Isolate.immediate);
_isolate = null;
}
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(
notification,
),
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _running ? _stop : _start,
tooltip: _running ? 'Timer stop' : 'Timer start',
child: _running ? new Icon(Icons.stop) : new Icon(Icons.play_arrow),
),
);
}
}
If I first trigger StopGrpc() to stop gRPC server, and then close the application, the application exits without any issue.
Normal exit looks like this in debug console:
An Observatory debugger and profiler on Flutter test device is available at: http://127.0.0.1:50300/
Greet function was invoked with greeting:<first_name:"Satinder" last_name:"Grewal" >
flutter: done!
go-flutter: closing application
Lost connection to device.
hover: App 'flutter_isolates' exited.
hover: Closing the flutter attach sub process..
So, I need to know where to put StopGrpc() function to trigger on application close/exit action.
Can someone please tell me how can I trigger a function to stop the server when exiting the application?
This is the go-grpc code that I'm compiling for this go-flutter application as a C library:
https://github.com/satindergrewal/flutter-practice/blob/master/go_dart_ffi_c_shared/greet/greet_server/server.go
And this is the flutter code that I'm using to test flutter Isolates: https://github.com/satindergrewal/flutter-practice/tree/master/flutter_isolates
I have already asked for help from go-flutter and they pointed me to ask in flutter/flutter help channels.
Would really appreciate help on it.
Thanks,
Satinder
#override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
void didChangeAppLifecycleState(AppLifecycleState state) {
setState(() {
if (AppLifecycleState.paused == state) {
//Your function
}
});
}
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
enter link description here
enter link description here
Add an exit button to your application, if the user leaves the application with that button, trigger the function with that button.The above codes will be triggered if the user directly closes the application or keeps it in the background. Read more on the links

Is there any way to open link that comes from onesignal on webview?

I'm using webview widget in my flutter app I want to open a link when user tap on notification, the link comes from additional data on one signal
I tried to make this but it doesn't work
my code :
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:onesignal/onesignal.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _debugLabelString = "";
String url = "https://www.google.com";
#override
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
if (!mounted) return;
OneSignal.shared.setLogLevel(OSLogLevel.verbose, OSLogLevel.none);
OneSignal.shared.setRequiresUserPrivacyConsent(_requireConsent);
var settings = {
OSiOSSettings.autoPrompt: false,
OSiOSSettings.promptBeforeOpeningPushUrl: true
};
OneSignal.shared.setNotificationReceivedHandler((notification) {
this.setState(() {
url = notification.payload.additionalData['url'].toString() ;
});
});
OneSignal.shared
.setNotificationOpenedHandler((OSNotificationOpenedResult result) {
this.setState(() {
// the value of result.notification.payload.additionalData['url'] =
// https://www.facebook.com/
url = result.notification.payload.additionalData['url'].toString() ;
});
});
// NOTE: Replace with your own app ID from https://www.onesignal.com
await OneSignal.shared
.init("086d22bd-5539-4849-9db2-01589fd3429d", iOSSettings: settings);
OneSignal.shared
.setInFocusDisplayType(OSNotificationDisplayType.notification);
}
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: const Text('OneSignal Flutter Demo'),
backgroundColor: Color.fromARGB(255, 212, 86, 83),
),
body: WebviewScaffold(
url: url,
withJavascript: true,
)
),
);
}
}
I put facebook.com on in additional data it show google page not facebook how to make it show the save value the I put on additional data
The setNotificationReceivedHandler creates the callback for when a notification is received on the device in the foreground.
For the "on notification open" callback (which works for if it is in the background), use the setNotificationOpened handler.
Flutter event handler reference.
If you're looking to handle this in the background regardless of whether the notification is opened or not, see Background Notifications (note: be prepared to write native code, here)