بحث باسم الموضوع المطلوب

كيفية اكتشاف ما إذا كان تطبيق Flutter موجودًا في الخلفية

في Flutter، توجد طرق متعددة للكشف عما إذا كان التطبيق في الخلفية أم في المقدمة. يتيح لك اكتشاف هذه الحالات تنفيذ إجراءات محددة بناءً على ما إذا كان التطبيق قيد الاستخدام النشط (في المقدمة) أو غير مرئي ولا يتلقى إدخال المستخدم (في الخلفية). في هذا المنشور، سنغطي طريقتين لتحديد ما إذا كان التطبيق في الخلفية أم في المقدمة.

استخدم WidgetsBindingObserver

النهج الأول هو استخدام WidgetsBindingObserverالفئة للكشف عما إذا كان تطبيق Flutter في الخلفية أم في المقدمة. يمكن لهذه الفئة ملاحظة التغييرات في دورة حياة التطبيق من خلال didChangeAppLifecycleStateالطريقة، التي توفر الوصول إلى AppLifecycleState.

يمكن استخدام الفئة WidgetsBindingObserverكمزيج باستخدام withالكلمة الأساسية. لذلك، سنقوم بإنشاء عنصر واجهة مستخدم جديد يسمى BackgroundDetectorيستخدم هذا المزيج.

كاشف الخلفية. دارت

(C)

import 'dart:ui';

import 'package:flutter/material.dart';

class BackgroundDetector extends StatefulWidget {
  const BackgroundDetector({
    required this.child,
    super.key,
  });

  final Widget child;

  @override
  State<BackgroundDetector> createState() => _BackgroundDetectorState();
}

class _BackgroundDetectorState extends State<BackgroundDetector>
    with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) =>
      print('\x1B[34m $state \x1B[0m');

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

(C)

في مقتطف التعليمات البرمجية هذا، قمنا بإنشاء BackgroundDetectorعنصر واجهة مستخدم بحالة. _BackgroundDetectorStateتستخدم الفئة WidgetsBindingObserverالفئة كمزيج مع withالكلمة الأساسية.

في _BackgroundDetectorState، نتجاوز ثلاث وظائف: initStateو dispose، و didChangeAppLifecycleState.

تتوفر الدالتان and دائمًا للأدوات ذات الحالة. نستخدم الدالة initStateلإضافة المراقب والدالة لإزالته بمجرد التخلص من الأداة.disposeinitStatedispose

تم تجاوز الوظيفة didChangeAppLifecycleStateحتى نتمكن من الوصول إلى AppLifecycleState. يتم استدعاء هذه الطريقة كلما تغيرت حالة دورة حياة التطبيق. في الوقت الحالي، نقوم فقط بطباعة حالة دورة الحياة الحالية.

أخيرًا، BackgroundDetectorتتطلب الأداة childعنصر واجهة مستخدم سيتم إرجاعه.

في هذه didChangeAppLifecycleStateالوظيفة، تستخدم عبارة الطباعة أكواد الهروب ANSI لإضافة الألوان في واجهة سطر الأوامر. هذا التلوين مخصص لأغراض العرض التوضيحي فقط.


الرئيسية.دارت

 (C)

import 'package:application_in_background_demo/background_detector.dart';

import 'package:flutter/material.dart';


void main() => runApp(const BackgroundDetector(child: MyApp()));


class MyApp extends StatelessWidget {

  const MyApp({super.key});


  @override

  Widget build(BuildContext context) {

    return const MaterialApp(

      home: Scaffold(),

    );

  }

}


(C)

في main.dartالملف، قمنا بتغليف MyAppالأداة باستخدام BackgroundDetectorالأداة الخاصة بنا. من خلال تغليف تطبيقنا بالكامل بالفئة BackgroundDetector، فسوف يتم دائمًا اكتشاف ما إذا كان التطبيق في الخلفية أم في المقدمة.

راجع ملف GIF أدناه لترى ذلك أثناء العمل. في واجهة سطر الأوامر، نقوم بطباعة حالة دورة حياة التطبيق الحالية في كل مرة تتغير فيها.


تغيير دالة DidChangeAppLifecycleState

بدلاً من طباعة كل شيء، AppLifecycleStateمن الأفضل تنفيذ الإجراءات على حالات معينة فقط. في هذه الحالة، سنغير الوظيفة didChangeAppLifecycleStateلتنفيذ الإجراء على الحالة resumedو فقط paused.

(C)

@override

void didChangeAppLifecycleState(AppLifecycleState state) {

  if (state == AppLifecycleState.resumed) {

    print('\x1B[34m App in foreground\x1B[0m');

  }


  if (state == AppLifecycleState.paused) {

    print('\x1B[33m App in background\x1B[0m');

  }

}

(C)


في مثال الكود هذا، نستخدم AppLifecycleStateالتعداد للكشف عما إذا كانت الحالة الحالية تساوي الحالة التي نريد التصرف بها. resumedتعني الحالة أن التطبيق موجود في المقدمة pausedوتعني الحالة أن التطبيق موجود في الخلفية.


إذا قمنا بتشغيل تطبيقنا مرة أخرى، ستلاحظ أننا الآن ننفذ الإجراءات على الحالة resumedو فقط paused.

الحالات المختلفة لـ AppLifecycleState Enum

حتى الآن، استخدمنا اثنين من الإدخالات الخمسة من AppLifecycleStateالتعداد، الذي يمثل الحالات المختلفة التي يمكن أن يوجد بها التطبيق. فيما يلي قائمة تشرح كل حالة:


  1. detached:يتم تشغيل التطبيق بدون شاشة مرئية في تلك اللحظة المحددة. إما أنه في عملية عرض شيء ما لأول مرة أو بعد إخفاء الشاشة مؤقتًا وقبل أن تصبح مرئية مرة أخرى.
  2. hidden:يتم إخفاء كافة وجهات نظر التطبيق.
  3. inactive:يتم إخفاء التطبيق جزئيًا بواسطة تطبيق آخر أو ورود مكالمة هاتفية. في هذه الحالة، قد يظل التطبيق مرئيًا ولكنه لا يتلقى إدخال المستخدم.
  4. paused:التطبيق موجود في الخلفية ولا يمكن للمستخدم رؤيته. قد يحدث ذلك عندما يقوم المستخدم بالتبديل إلى تطبيق آخر أو عندما ينتقل الجهاز إلى وضع السكون.
  5. resumed:التطبيق موجود في المقدمة ويمكن للمستخدم رؤيته. إنه الحالة النشطة حيث يمكن للمستخدم التفاعل مع التطبيق


باستخدام WidgetsBindingObserverclass و AppLifecycleStateenum، يمكنك بسهولة تتبع حالة دورة حياة التطبيق. ومع ذلك، هناك نهج بديل يمكنك اتباعه لمراقبة حالة دورة حياة التطبيق باستخدام حزمة Flutter FGBG.

إشعار بحدث المقدمة/الخلفية في Flutter

النهج الثاني يستخدم حزمة Flutter FGBG لتحقيق وظائف مماثلة. وبينما WidgetsBindingObserverتتيح لك معرفة متى يصبح تطبيقك نشطًا أو غير نشط، فإنها تأخذ أيضًا في الاعتبار التغييرات في أجزاء أخرى من التطبيق، والتي قد تؤدي إلى ملاحظات غير صحيحة.

تركز حزمة Flutter FGBG فقط على تطبيقك وتلاحظ بدقة متى ينتقل إلى الخلفية أو المقدمة. وهي تفعل ذلك بشكل مختلف بالنسبة لنظامي التشغيل iOS وAndroid للتأكد من صحة الملاحظات.


تثبيت حزمة Flutter FGBG

للبدء في التنفيذ، نحتاج أولاً إلى تثبيت  حزمة  Flutter FGBG  في مشروعنا . يمكننا تثبيت الحزمة من خلال تنفيذ الأمر التالي داخل مشروعنا:

(C)

flutter pub add flutter_fgbg

(C)

بمجرد تنفيذ الأمر، تأكد من التحقق من ملفك pubspec.yamlبحثًا عن التبعيات المضافة. يجب أن ترى حزمة Flutter FGBG مضمنة في قسم التبعيات، مثل هذا:


(C)

dependencies:

  flutter_fgbg: ^0.3.0

(C)

تنفيذ فئة FGBGNotifier

توفر حزمة Flutter FGBG FGBGNotifierعنصر واجهة مستخدم يستخدم للاستماع إلى الأحداث في المقدمة والخلفية. عندما تتغير حالة دورة حياة التطبيق، onEventيتم تشغيل معاودة الاتصال. يتيح لنا هذا تنفيذ إجراءات محددة بناءً على الحالة الحالية للتطبيق.

(C)

import 'package:flutter/material.dart';

import 'package:flutter_fgbg/flutter_fgbg.dart';


void main() => runApp(

  FGBGNotifier(

    onEvent: (FGBGType type) => switch (type) {

      FGBGType.foreground => print('\x1B[34mApp in the foreground (FGBGNotifier)\x1B[0m'),

      FGBGType.background => print('\x1B[33mApp in the background (FGBGNotifier)\x1B[0m'),

    },

    child: const MyApp(),

  ),

);


class MyApp extends StatelessWidget {

  const MyApp({super.key});


  @override

  Widget build(BuildContext context) {

    return const MaterialApp(

      home: Scaffold(),

    );

  }

}

(C)

في main.dartالملف المحدث، قمنا بتنفيذ FGBGNotifierعنصر واجهة المستخدم. يحتاج هذا العنصر إلى onEventخاصية، والتي تأخذ دالة استدعاء تتلقى قيمة من FGBGTypeالتعداد. يحتوي التعداد على قيمتين: foregroundو background.


داخل معاودة الاتصال، نستخدم ifعبارة بسيطة لطباعة رسائل مختلفة بناءً على النوع المستلم. بالإضافة إلى ذلك، FGBGNotifierتأخذ الأداة رمزًا child، وفي هذه الحالة، نضبط MyAppالأداة باعتبارها الطفل.


عندما نقوم بتشغيل التطبيق، سنحصل على نفس السلوك كما في النهج السابق. ومع ذلك، تعمل هذه الحزمة على تبسيط التنفيذ ولا تبلغ إلا عن الأحداث على https://pub.dev/packages/flutter_fgbg#why مستوى التطبيق .


تجاهل بعض الأفعال
تحتوي حزمة Flutter FGBG أيضًا على وظيفة إضافية يمكن استخدامها لتجاهل إجراءات معينة. إذا كنت تريد تجاهل وظيفة تضع التطبيق في الخلفية، فيمكنك تغليف الوظيفة بالوظيفة ignoreWhile.

(C)
FGBGEvents.ignoreWhile(() {
  // your function
});
(C)

خاتمة
يكتشف كلا النهجين بنجاح ما إذا كان التطبيق في الخلفية أم في المقدمة. يستخدم النهج الأول WidgetsBindingObserverو AppLifecycleStateلمراقبة سلوك التطبيق. النهج الثاني أبسط ويستخدم حزمة Flutter FGBG، التي توفر FGBGNotifierأداة لتتبع الأحداث في الخلفية والمقدمة.