簡體   English   中英

想要在 flutter 應用程序中添加新文檔時使用一個信號發送推送通知。我應該使用 launchUrl() 方法嗎?

[英]Wants to send push notification using one signal when new document is added in the flutter app.Should I use launchUrl() method for it?

下面是 AddNewDocument.dart 文件。 每當我添加任何文檔時,它都應該向用戶顯示新的推送通知,並且應該導航到文檔詳細信息頁面。 有什么方法可以實現嗎?

import 'package:AtDocHUB/Controller/DocumentController.dart';
import 'package:AtDocHUB/Model/Document.dart';
import 'package:AtDocHUB/View/Document/DocumentPage.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:dropdown_button2/dropdown_button2.dart';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:form_field_validator/form_field_validator.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:jiffy/jiffy.dart';

DateTime now = DateTime.now();
String formattedDate = DateFormat("yyyy-MM-dd").format(now);

//import 'package:flutter_text_form_field/flutter_text_form_field.dart';
class AddNewDocument extends StatefulWidget {
  @override
  State createState() {
    return _AddNewDocumentState();
  }
}

class _AddNewDocumentState extends State<AddNewDocument> {
  late final String date1;

  late String datainput;

  final List<String> items1 = ["Open", "Closed", "Cancel", "Submitted"];
  String? selectedItem;

  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  

  TextEditingController docTitleController = TextEditingController();
  TextEditingController tokenNoController = TextEditingController();
  
  TextEditingController partyNameController = TextEditingController();
  TextEditingController startDateController = TextEditingController();
  TextEditingController endDateController = TextEditingController();
  late String docType = docTypeController.text;

  final List<String> items = [
    "Residential",
    "Commercial",
  ];
  String? selectedValue;

  List<DropdownMenuItem<String>> _addDividersAfterItems(List<String> items) {
    List<DropdownMenuItem<String>> _menuItems = [];
    for (var item in items) {
      _menuItems.addAll(
        [
          DropdownMenuItem<String>(
            value: item,
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 8.0),
              child: Text(
                item,
                style: const TextStyle(
                  fontSize: 14,
                ),
              ),
            ),
          ),
          //If it's last item, we will not add Divider after it.
          if (item != items.last)
            const DropdownMenuItem<String>(
              enabled: false,
              child: Divider(),
            ),
        ],
      );
    }
    return _menuItems;
  }

  List<int> _getDividersIndexes() {
    List<int> _dividersIndexes = [];
    for (var i = 0; i < (items.length * 2) - 1; i++) {
      //Dividers indexes will be the odd indexes
      if (i.isOdd) {
        _dividersIndexes.add(i);
      }
    }
    return _dividersIndexes;
  }

  @override
  void dispose() {
    docStatusController.dispose();
    docTypeController.dispose();
    super.dispose();
  }

  @override
  Future<Document>? _futureDocument;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Color.fromARGB(255, 3, 87, 156),
        title: Text('Add New Document'),
        leading: IconButton(
            icon: BackButtonIcon(),
            onPressed: () => Navigator.of(context).push(MaterialPageRoute(
                builder: (BuildContext context) => DocumentPage()))),
      ),
      body:
          //Container(

          SafeArea(
        child: SingleChildScrollView(
          child: Container(
            alignment: Alignment.center,
            padding: const EdgeInsets.all(10),
            child: (_futureDocument == null)
                ? buildColumn()
                : buildFutureBuilder(),
          ),
        ),
      ),
    );
  }

  Form buildColumn() {
    return Form(
      key: formKey,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          SizedBox(
            height: 10,
          ),
          TextFormField(
            minLines: 1,
            maxLines: 3,

            textCapitalization: TextCapitalization.words,

            inputFormatters: [
              FilteringTextInputFormatter.allow(
                  RegExp("[ ',-/ a-z A-Z á-ú Á-Ú 0-9]")),
            ],

            controller: docTitleController,
            style: TextStyle(fontSize: 12),
            keyboardType: TextInputType.multiline,
            decoration: const InputDecoration(
                errorStyle: const TextStyle(fontSize: 0.05),
                border: OutlineInputBorder(),
                hintStyle: TextStyle(fontSize: 12),
                labelStyle: TextStyle(
                  fontSize: 12,
                ),
                labelText: 'Document Title',
                hintText: 'Document title required'),

            // validator: ,
            validator:
                MultiValidator([RequiredValidator(errorText: 'Required*')]),
          ),
          SizedBox(
            height: 20,
          ),
          Wrap(
            children: [
              SizedBox(
                width: MediaQuery.of(context).size.width * 0.4,
                child: TextFormField(
                  style: TextStyle(fontSize: 12),
                  minLines: 1,
                  maxLines: 2,
                  inputFormatters: [
                    FilteringTextInputFormatter.digitsOnly,
                    LengthLimitingTextInputFormatter(14)
                  ],
                  controller: tokenNoController,
                  keyboardType: TextInputType.number,
                  decoration: const InputDecoration(
                      errorStyle: const TextStyle(fontSize: 0.05),
                      counterText: "",
                      border: OutlineInputBorder(),
                      hintStyle: TextStyle(fontSize: 12),
                      labelStyle: TextStyle(
                        fontSize: 12,
                      ),
                      labelText: 'Token No',
                      hintText: 'Token no required'),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Please enter token No';
                    } else if (value.length < 14) {
                      return 'Please enter 14 digits number';
                    }
                    return null;
                  },
                ),
              ),
              SizedBox(
                width: 15,
              ),
            
          SizedBox(
            height: 20,
          ),
          SizedBox(
            width: MediaQuery.of(context).size.width,
            child: TextFormField(
              minLines: 1,
              maxLines: 4,
              inputFormatters: [
                LengthLimitingTextInputFormatter(50),
                FilteringTextInputFormatter.allow(RegExp("[a-z A-Z]")),
              ],
              controller: partyNameController,
              keyboardType: TextInputType.name,
              decoration: const InputDecoration(
                  errorStyle: const TextStyle(fontSize: 0.05),
                  border: OutlineInputBorder(),
                  hintStyle: TextStyle(fontSize: 12),
                  labelStyle: TextStyle(
                    fontSize: 12,
                  ),
                  labelText: 'Party Name',
                  hintText: 'Party name required'),
              validator:
                  MultiValidator([RequiredValidator(errorText: 'Required*')]),
            ),
          ),
          SizedBox(
            height: 20,
          ),
          SizedBox(
            height: 20,
          ),
          Row(
            children: [
              SizedBox(
                width: MediaQuery.of(context).size.width * 0.4,
                child: TextFormField(
                  //  autovalidateMode: AutovalidateMode.onUserInteraction,
                  //FilteringTextInputFormatter.allow(RegExp("[- 0-9]")),
                  inputFormatters: [
                    FilteringTextInputFormatter.allow(RegExp("[- 0-9]")),
                    LengthLimitingTextInputFormatter(10)
                  ],
                  controller: startDateController,
                  keyboardType: TextInputType.datetime,
                  decoration: const InputDecoration(
                    errorStyle: const TextStyle(fontSize: 0.05),
                    prefixIcon: Icon(Icons.calendar_month),
                    border: OutlineInputBorder(),
                    hintStyle: TextStyle(fontSize: 12),
                    labelStyle: TextStyle(
                      fontSize: 12,
                    ),
                    labelText: 'Start Date',
                    hintText: 'yyyy-MM-dd',
                  ),
                  onTap: () async {
                    DateTime? pickedDate = await showDatePicker(
                      context: context,
                      initialDate: DateTime.now(),
                      firstDate: DateTime(
                          1991), //DateTime.now() - not to allow to choose before today.
                      lastDate: DateTime(2101),
                      // onConfirm:widget.onChanged,
                    ).then((pickedDate) {
                      if (pickedDate != null) {
                        // print(
                        // pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
                        String formattedDate =
                            DateFormat('yyyy-MM-dd').format(pickedDate);

                        print(formattedDate);

                        setState(() {
                          startDateController.text = formattedDate;
                          //set output date to TextField value.
                        });
                        print(startDateController.text);
                      } else {
                        print("Date is not selected");
                      }
                    });
                    final int dur = int.parse(durationController.text);
                    var stDate = DateTime.parse(startDateController.text);

                    var jiffy = Jiffy(stDate).add(
                      months: dur,
                      days: -1,
                      // days: 1095,
                    );
                    DateTime d = jiffy.dateTime;
                    String s = jiffy.format('yyyy-MM-dd');
                    setState(() {
                      endDateController.text = s.toString();
                    });
                  },

                  validator: MultiValidator(
                      [RequiredValidator(errorText: 'Required*')]),
                ),
              ),
              SizedBox(
                width: 13,
              ),
              SizedBox(
                // height: MediaQuery.of(context).size.height * 0.06,
                width: MediaQuery.of(context).size.width * 0.5,
                child: TextFormField(
                  // maxLength: 8,
                  // autovalidateMode: AutovalidateMode.onUserInteraction,
                  autofocus: false,
                  controller: endDateController,
                  inputFormatters: [
                    FilteringTextInputFormatter.allow(RegExp("[- 0-9]")),
                    LengthLimitingTextInputFormatter(10)
                  ],
                  keyboardType: TextInputType.datetime,
                  decoration: const InputDecoration(
                      errorStyle: const TextStyle(fontSize: 0.05),
                      // prefixIcon: Icon(Icons.calendar_month),
                      counterText: "",
                      border: OutlineInputBorder(),
                      hintStyle: TextStyle(fontSize: 12),
                      labelStyle: TextStyle(
                        fontSize: 12,
                      ),
                      labelText: 'End Date',
                      hintText: ' yyyy-MM-dd'),
                  onTap: () async {},

                  validator: MultiValidator(
                      [RequiredValidator(errorText: 'Required*')]),
                ),
              ),
            ],
          ),
          SizedBox(
            height: 20,
          ),
          SizedBox(
            //  height: MediaQuery.of(context).size.height * 0.06,
            width: MediaQuery.of(context).size.width,
            child: TextFormField(
              minLines: 1,
              maxLines: 4,

              // autovalidateMode: AutovalidateMode.onUserInteraction,
              inputFormatters: [
                FilteringTextInputFormatter.allow(RegExp("[a-z A-Z 0-9]")),
                // FilteringTextInputFormatter.digitsOnly,
                LengthLimitingTextInputFormatter(50)
              ],
              controller: rentDescController,
              keyboardType: TextInputType.multiline,
              decoration: const InputDecoration(
                  errorStyle: const TextStyle(fontSize: 0.05),
                  border: OutlineInputBorder(),
                  hintStyle: TextStyle(fontSize: 12),
                  labelStyle: TextStyle(
                    fontSize: 12,
                  ),
                  labelText: 'Rent Description',
                  hintText: 'Rent Description required'),
              // validator:
              //     MultiValidator([RequiredValidator(errorText: 'Required*')]),
            ),
          ),
          SizedBox(
            height: 20,
          ),
          Container(

              //alignment: Alignment.center,
              height: 35,
              width: 200,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(6),
                color: Color.fromARGB(255, 3, 89, 168),
              ),
              child: ElevatedButton(
                onPressed: () {
                  formKey.currentState?.validate();
                  final isValidForm = formKey.currentState!.validate();
                  if (isValidForm) {
                    //formKey.currentState?.validate();
                    // final int docId = int.parse(docIdController.text).toInt();
                    final String docTitle = docTitleController.text;
                    final int tokenNo =
                        int.parse(tokenNoController.text).toInt();
                    //final String tokenNo = tokenNoController.text;
                    final String partyName = partyNameController.text;
                    final String startDate = startDateController.text;
                    final String endDate = endDateController.text;

                    Navigator.of(context).push(MaterialPageRoute(
                        builder: (BuildContext context) => DocumentPage()));

                    setState(() {
                      _futureDocument = createDocument(
                        // docId,
                        docTitle,
                        tokenNo,
                       startDate,
                        endDate,
                        //  createdAt,
                      );
                    });
                    // }
                  }
                },
                child: const Text("Save"),
                style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all(
                        Color.fromARGB(255, 3, 89, 168))),
              ))
        ],
      ),
    );
    //])
    //);
  }

  FutureBuilder<Document> buildFutureBuilder() {
    return FutureBuilder<Document>(
      future: _futureDocument,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return Text(snapshot.data!.docTitle);
        } else if (snapshot.hasError) {
          return Text('${snapshot.error}');
        }

        return const CircularProgressIndicator();
      },
    );
  }
}

下面是 main.dart 文件,我在其中初始化了 App Id 和其他必需的東西。推送通知正確地進入應用程序,當我點擊通知時它會打開應用程序。 但我想在新文檔添加到應用程序時顯示推送通知,當用戶點擊該特定通知時,它應該將用戶導航到文檔詳細信息頁面。我還附上了 AddNewDocumentFile.dart。

import 'package:flutter/material.dart';

import 'package:onesignal_flutter/onesignal_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'View/LoginPage.dart';
import 'View/homePageAdmin.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SharedPrefService.init();
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class SharedPrefService {
  static late SharedPreferences pref;

  static Future<void> init() async {
    pref = await SharedPreferences.getInstance();
    var usrEmail = pref.getString('email');
  }
}

class _MyAppState extends State<MyApp> {
  // This widget is the root of your application.
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    initPlatformState();
  }

  Future<void> initPlatformState() async {
    OneSignal.shared.setAppId('e89acaa4-5388-4e3a-bd69-44d197bdcbd7');
    OneSignal.shared
        .promptUserForPushNotificationPermission()
        .then((accepted) {});
    
  }

  @override
  Widget build(BuildContext context) {
    var usrEmail = SharedPrefService.pref.getString('email');

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
       
        primarySwatch: Colors.indigo,
      ),
      home: usrEmail == null ? LoginPage() : homePageAdmin(),
    );
  }
}

您只需要調用OneSignal.shared.postNotification(notification); 在您的createDocument function 完成后。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM