البرنامج التعليمي: إرسال إعلامات الدفع إلى أجهزة معينة باستخدام Azure Notification Hubs، وGoogle Firebase Cloud Messaging
نظرة عامة
هام
اعتبارا من يونيو 2024، لن يتم دعم واجهات برمجة التطبيقات القديمة FCM وسيتم إيقافها. لتجنب أي تعطيل في خدمة الإعلامات المؤقتة، يجب الترحيل إلى بروتوكول FCM v1 في أقرب وقت ممكن.
يوضح لك هذا البرنامج التعليمي كيفية استخدام Azure Notification Hubs لبث إشعارات الأخبار العاجلة إلى تطبيق Android. عند الانتهاء، سوف تتمكن من التسجيل في فئات الأخبار العاجلة التي تهمك، وتلقي الإشعارات المنبثقة بشأن هذه الفئات فقط. هذا السيناريو هو نمط شائع للعديد من التطبيقات حيث يجب أن يتم إرسال الإشعارات إلى مجموعات من المستخدمين الذين أعلنوا في السابق عن اهتمامهم بها، على سبيل المثال، قارئ RSS، تطبيقات لمحبي الموسيقى، إلخ.
يتم تمكين هذا السيناريو عن طريق تضمين علامة واحدة أو أكثر عند إنشاء تسجيل في Notification Hub. عند إرسال الإشعارات إلى علامة ما، ستتلقى جميع الأجهزة التي سجلت العلامة الإشعار. لأن العلامات هي مجرد سلاسل، فإنها لا يجب أن يتم توفيرها مقدمًا. لمزيد من المعلومات حول العلامات، راجع Notification Hubs Routing and Tag Expressions.
في هذا البرنامج التعليمي، تتخذ الإجراءات التالية:
- قم بإضافة تحديد الفئة إلى تطبيق الأجهزة المحمولة.
- التسجيل للحصول على إشعارات بعلامات.
- إرسال إشعارات مزودة بعلامات.
- اختبار التطبيق
المتطلبات الأساسية
يقوم هذا البرنامج التعليمي على أساس التطبيق الذي قمت بإنشائه في البرنامج التعليمي: دفع الإشعارات إلى الأجهزة التي تعمل بنظام تشغيل Android باستخدامAzure Notification Hubs وFirebase Cloud Messaging. قم بإكمال البرنامج التعليمي: دفع الإشعارات إلى الأجهزة التي تعمل بنظام تشغيل Android عن طريق استخدام إشعارات Azure Notification Hubs وFirebase Cloud Messaging.
إضافة تحديد الفئة إلى التطبيق
الخطوة الأولى هي إضافة عناصر واجهة المستخدم إلى النشاط الرئيسي الحالي الذي يمكّن المُستخدم من تحديد فئات التسجيل. الفئات التي يختارها المُستخدم مُخزنة على الجهاز. عند بدء تشغيل التطبيق، يتم إنشاء تسجيل جهاز في مركز الإشعارات الخاص بك مع الفئات المحددة كعلامات.
افتح
res/layout/activity_main.xml file
، واستبدل المحتوي بالتالي:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.breakingnews.MainActivity" android:orientation="vertical"> <CheckBox android:id="@+id/worldBox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/label_world" /> <CheckBox android:id="@+id/politicsBox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/label_politics" /> <CheckBox android:id="@+id/businessBox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/label_business" /> <CheckBox android:id="@+id/technologyBox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/label_technology" /> <CheckBox android:id="@+id/scienceBox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/label_science" /> <CheckBox android:id="@+id/sportsBox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/label_sports" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="subscribe" android:text="@string/button_subscribe" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" android:id="@+id/text_hello" /> </LinearLayout>
افتح الملف ثم أضف الخطوط
res/values/strings.xml
التالية:<string name="button_subscribe">Subscribe</string> <string name="label_world">World</string> <string name="label_politics">Politics</string> <string name="label_business">Business</string> <string name="label_technology">Technology</string> <string name="label_science">Science</string> <string name="label_sports">Sports</string>
ينبغي أن يبدو التخطيط الرسومي لـ
main_activity.xml
الخاص بك كالصورة التالية:قم بإنشاء فئة
Notifications
في نفس الحزمة باعتبارها فئةMainActivity
خاصة بك.import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeUnit; import android.content.Context; import android.content.SharedPreferences; import android.os.AsyncTask; import android.util.Log; import android.widget.Toast; import com.google.android.gms.tasks.OnSuccessListener; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.InstanceIdResult; import com.microsoft.windowsazure.messaging.NotificationHub; public class Notifications { private static final String PREFS_NAME = "BreakingNewsCategories"; private FirebaseInstanceId fcm; private NotificationHub hub; private Context context; private String senderId; public static String FCM_token = ""; private static final String TAG = "Notifications"; public Notifications(Context context, String hubName, String listenConnectionString) { this.context = context; this.senderId = senderId; fcm = FirebaseInstanceId.getInstance(); hub = new NotificationHub(hubName, listenConnectionString, context); } public void storeCategoriesAndSubscribe(Set<String> categories) { SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0); settings.edit().putStringSet("categories", categories).commit(); subscribeToCategories(categories); } public Set<String> retrieveCategories() { SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0); return settings.getStringSet("categories", new HashSet<String>()); } public void subscribeToCategories(final Set<String> categories) { new AsyncTask<Object, Object, Object>() { @Override protected Object doInBackground(Object... params) { try { FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() { @Override public void onSuccess(InstanceIdResult instanceIdResult) { FCM_token = instanceIdResult.getToken(); Log.d(TAG, "FCM Registration Token: " + FCM_token); } }); TimeUnit.SECONDS.sleep(1); String templateBodyFCM = "{\"data\":{\"message\":\"$(messageParam)\"}}"; hub.registerTemplate(FCM_token,"simpleFCMTemplate", templateBodyFCM, categories.toArray(new String[categories.size()])); } catch (Exception e) { Log.e("MainActivity", "Failed to register - " + e.getMessage()); return e; } return null; } protected void onPostExecute(Object result) { String message = "Subscribed for categories: " + categories.toString(); Toast.makeText(context, message, Toast.LENGTH_LONG).show(); } }.execute(null, null, null); } }
تستخدم هذه الفئة التخزين المحلي لتخزين فئات الأخبار التي يجب أن يتلقاها هذا الجهاز. كما أنه يحتوي على أساليب تسجيل هذه الفئات.
في
MainActivity
الصف الخاص بك، قم بإضافة حقلNotifications
لـ:private Notifications notifications;
وبعدها قم بتحديث الأسلوب
onCreate
، كما هو موضح في التعليمات البرمجية التالية. يمكنك التسجيل في لوحات Notification Hubs في أسلوب subscribeToCategories في فئة الإعلامات.@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mainActivity = this; FirebaseService.createChannelAndHandleNotifications(getApplicationContext()); notifications = new Notifications(this, NotificationSettings.HubName, NotificationSettings.HubListenConnectionString); notifications.subscribeToCategories(notifications.retrieveCategories()); }
تأكد أنه تم تعيين اسم المركز وسلسلة الاتصال بشكل صحيح في الفئة NotificationSettings.
إشعار
نظرًا لأن بيانات الاعتماد الموزعة مع تطبيق العميل ليست آمنة بشكل عام، يجب عليك فقط توزيع مفتاح الوصول إلى الاستماع مع تطبيق العميل الخاص بك. يتيح الوصول إلى الاستماع لتطبيقك التسجيل للحصول على الإشعارات، ولكن لا يمكن تعديل التسجيلات الموجودة ولا يمكن إرسال الإشعارات. يتم استخدام مفتاح الوصول الكامل في خدمة خلفية آمنة لإرسال الإعلامات وتغيير التسجيلات الموجودة.
بعد ذلك، أضف الاستيراد التالي:
import android.widget.CheckBox; import java.util.HashSet; import java.util.Set; import android.view.View;
إضافة الأسلوب التالي
subscribe
لمعالجة إجراء النقر فوق زر الاشتراك:public void subscribe(View sender) { final Set<String> categories = new HashSet<String>(); CheckBox world = (CheckBox) findViewById(R.id.worldBox); if (world.isChecked()) categories.add("world"); CheckBox politics = (CheckBox) findViewById(R.id.politicsBox); if (politics.isChecked()) categories.add("politics"); CheckBox business = (CheckBox) findViewById(R.id.businessBox); if (business.isChecked()) categories.add("business"); CheckBox technology = (CheckBox) findViewById(R.id.technologyBox); if (technology.isChecked()) categories.add("technology"); CheckBox science = (CheckBox) findViewById(R.id.scienceBox); if (science.isChecked()) categories.add("science"); CheckBox sports = (CheckBox) findViewById(R.id.sportsBox); if (sports.isChecked()) categories.add("sports"); notifications.storeCategoriesAndSubscribe(categories); }
يُنشئ هذا الأسلوب قائمة الفئات ويستخدم
Notifications
الفئة لتخزين القائمة في التخزين المحلي وتسجيل العلامات المطابقة لمركز الإعلام. عند تغيير الفئات، يتم إعادة إنشاء التسجيل بالفئات الجديدة.
أصبح تطبيقك الآن قادرًا على تخزين مجموعة من الفئات في مساحة تخزين محلية على الجهاز والتسجيل في مركز الإعلامات كلما غيّر المُستخدم تحديد الفئات.
التسجيل للحصول على الإعلامات
تُسجّل هذه الخطوات مع مركز العلامات عند بدء التشغيل باستخدام الفئات التي تم تخزينها في التخزين المحلي.
قم بتأكيد أن التعليمة البرمجية التالية موجودة في نهاية
onCreate
الأسلوب فيMainActivity
الفئة:notifications.subscribeToCategories(notifications.retrieveCategories());
يؤكد هذا الرمز أنه في كل مرة يتم تشغيل التطبيق، يتم استرداد الفئات من التخزين المحلي، ويطلب تسجيل لهذه الفئات.
ثم قم بتحديث
onStart()
الأسلوب منMainActivity
الفئة كما يلي:@Override protected void onStart() { super.onStart(); isVisible = true; Set<String> categories = notifications.retrieveCategories(); CheckBox world = (CheckBox) findViewById(R.id.worldBox); world.setChecked(categories.contains("world")); CheckBox politics = (CheckBox) findViewById(R.id.politicsBox); politics.setChecked(categories.contains("politics")); CheckBox business = (CheckBox) findViewById(R.id.businessBox); business.setChecked(categories.contains("business")); CheckBox technology = (CheckBox) findViewById(R.id.technologyBox); technology.setChecked(categories.contains("technology")); CheckBox science = (CheckBox) findViewById(R.id.scienceBox); science.setChecked(categories.contains("science")); CheckBox sports = (CheckBox) findViewById(R.id.sportsBox); sports.setChecked(categories.contains("sports")); }
يحدّث هذا الرمز النشاط الرئيسي طبقاً لحالة الفئات المحفوظة مُسبقاً.
التطبيق الآن مكتمل ويمكن تخزين مجموعة من الفئات في التخزين المحلي للجهاز المُستخدم للتسجيل في مركز الإعلام كلما غيّر المستخدم اختيار الفئات. بعد ذلك، حدد الخلفية التي يمكن إرسال إعلامات الفئة إلى هذا التطبيق.
إرسال الإعلامات ذات العلامة
في هذا القسم، ترسل الأخبار العاجلة كإعلامات نموذجية موسومة من تطبيق .NET console.
في Visual Studio، قم بإنشاء تطبيق جديد لـ Visual C# console:
- في القائمة، حدد "File">"New">"Project".
- في "Create a new project"، حدد "Console App (.NET Framework)" لـ C# في قائمة النماذج، وحدد "Next".
- أدخل اسمًا للتطبيق.
- بالنسبة إلى "Solution"، اختر "Add to solution"، وحدد "Create" لإنشاء المشروع.
حدد "Tools">"NuGet Package Manager">"Package Manager Console" ثم قم بتشغيل الأمر التالي في نافذة وحدة التحكم:
Install-Package Microsoft.Azure.NotificationHubs
يضيف هذا الإجراء مرجعاً إلى Azure Notification Hubs SDK باستخدام حزمة Microsoft.Azure.NotificationHubs.
افتح Program.cs، ثم قم بإضافة العبارة
using
التالية:using Microsoft.Azure.NotificationHubs;
في الفئة
Program
، قم بإضافة الأسلوب التالي أو استبداله إذا كان موجودا بالفعل:private static async void SendTemplateNotificationAsync() { // Define the notification hub. NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString("<connection string with full access>", "<hub name>"); // Apple requires the apns-push-type header for all requests var headers = new Dictionary<string, string> {{"apns-push-type", "alert"}}; // Create an array of breaking news categories. var categories = new string[] { "World", "Politics", "Business", "Technology", "Science", "Sports"}; // Send the notification as a template notification. All template registrations that contain // "messageParam" and the proper tags will receive the notifications. // This includes APNS, GCM/FCM, WNS, and MPNS template registrations. Dictionary<string, string> templateParams = new Dictionary<string, string>(); foreach (var category in categories) { templateParams["messageParam"] = "Breaking " + category + " News!"; await hub.SendTemplateNotificationAsync(templateParams, category); } }
يرسل هذا الرمز إعلامات نموذجية لكل من العلامات الست في صفيف السلسلة. يضمن استخدام العلامات ألا تتلقى الأجهزة إعلامات إلا من الفئات المسجلة.
في التعليمات البرمجية السابقة، استبدل العنصرين النائبين
<hub name>
و<connection string with full access>
باستخدام مركز الإعلامات وسلسلة الاتصال لديك الخاصة بـ DefaultFullSharedAccessSignature من لوحة المعلومات الخاصة بمركز الإعلامات لديك.في الأسلوب
Main()
، قم بإضافة الأسطر التالية:SendTemplateNotificationAsync(); Console.ReadLine();
قم بإنشاء تطبيق وحدة التحكم.
اختبار التطبيق
في Android Studio، قم بتشغيل التطبيق على جهاز يعمل بنظام تشغيل Android أو المحاكي. توفر واجهة المستخدم الخاصة بالتطبيق مجموعة من التبديلات التي تمكّنك من اختيار الفئات التي تشترك فيها.
قم بتمكين تبديل فئة واحدة أو أكثر، ثم انقر فوق اشتراك. يحول التطبيق الفئات المحددة إلى علامات ويطلب تسجيل جهاز جديد للعلامات المحددة من مركز الإعلامات. يتم إرجاع الفئات المُسجلة وعرضها في الإعلامات المنبثقة.
تشغيل تطبيق وحدة التحكم .NET، الذي يرسل إعلامات لكل فئة. تظهر الإعلامات للفئات المحددة كإعلامات منبثقة.
الخطوات التالية
في هذا البرنامج التعليمي، قمت بإرسال إعلامات البث إلى أجهزة معينة تعمل بنظام تشغيل Android والتي تم تسجيلها للفئات. لمعرفة كيفية إرسال إعلامات مباشرة إلى مستخدمين معينين، اكتشف البرنامج التعليمي التالي: