Skip to content

Latest commit

 

History

History
180 lines (147 loc) · 7.27 KB

File metadata and controls

180 lines (147 loc) · 7.27 KB

إصلاح نظام النغمات المخصصة للإشعارات

المشاكل التي تم حلها

1. مشكلة رسالة الخطأ المربكة

المشكلة:

  • عند اختيار نغمة مخصصة، كانت تظهر رسالة خطأ: "Could not persist sound access, it might not work later"
  • هذه الرسالة كانت تظهر حتى عند نجاح العملية، مما يسبب إرباكاً للمستخدم

السبب:

  • بعض مزودي المحتوى (Content Providers) لا يدعمون takePersistableUriPermission
  • الكود القديم كان يعتبر هذا خطأً ويعرض رسالة تحذير

الحل:

  • تم تحسين معالجة الاستثناءات لتجاهل فشل takePersistableUriPermission بشكل صامت
  • النغمة تعمل بشكل صحيح حتى بدون الصلاحية الدائمة في معظم الحالات
  • تظهر رسالة خطأ فقط عند فشل حفظ النغمة فعلياً

2. عدم وجود تأكيد واضح للنجاح

المشكلة:

  • لم تكن هناك رسالة تأكيد واضحة عند نجاح اختيار النغمة
  • المستخدم لا يعرف إذا تم حفظ اختياره أم لا

الحل:

  • تم إضافة SnackbarHost لعرض رسائل النجاح والفشل
  • يتم عرض رسالة "تم تحديث صوت الإشعار" عند النجاح
  • يتم عرض رسالة "تم إعادة تعيين صوت الإشعار إلى الافتراضي" عند إعادة التعيين

3. تحسين تجربة المستخدم

التحسينات:

  • رسائل خطأ أكثر وضوحاً ودقة
  • استخدام SnackbarDuration.Short للنجاح و Long للأخطاء
  • معالجة أفضل للاستثناءات مع رسائل مفصلة

الملفات المعدلة

1. NotificationSoundSettingsScreen.kt

التغييرات:

// إضافة SnackbarHostState
val snackbarHostState = remember { SnackbarHostState() }

// مراقبة رسائل النجاح والفشل من ViewModel
LaunchedEffect(Unit) {
    viewModel.successMessage.collectLatest { message ->
        message?.let {
            snackbarHostState.showSnackbar(
                message = it,
                duration = SnackbarDuration.Short
            )
        }
    }
}

LaunchedEffect(Unit) {
    viewModel.errorMessage.collectLatest { message ->
        message?.let {
            snackbarHostState.showSnackbar(
                message = it,
                duration = SnackbarDuration.Long
            )
        }
    }
}

// تحسين معالجة اختيار النغمة
val pickSoundLauncher = rememberLauncherForActivityResult(
    contract = ActivityResultContracts.GetContent(),
    onResult = { uri: Uri? ->
        uri?.let {
            currentRingtone?.stop()
            isPlayingSound = false
            try {
                val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION
                try {
                    context.contentResolver.takePersistableUriPermission(it, takeFlags)
                } catch (e: SecurityException) {
                    // بعض مزودي المحتوى لا يدعمون الصلاحيات الدائمة
                    // هذا طبيعي - سنحفظ URI وستعمل في هذه الجلسة
                }
                viewModel.updateCustomNotificationSound(it.toString())
            } catch (e: Exception) {
                Toast.makeText(
                    context, 
                    context.getString(R.string.sound_selection_failed, e.localizedMessage ?: "Unknown error"), 
                    Toast.LENGTH_LONG
                ).show()
            }
        }
    }
)

// إضافة SnackbarHost إلى Scaffold
Scaffold(
    topBar = { /* ... */ },
    snackbarHost = { SnackbarHost(hostState = snackbarHostState) }
) { /* ... */ }

2. strings.xml (English)

إضافة:

<string name="sound_selection_failed">Failed to select sound: %1$s</string>

3. strings.xml (Arabic)

إضافة:

<string name="sound_selection_failed">فشل في اختيار الصوت: %1$s</string>

كيفية عمل النظام الآن

1. عند اختيار نغمة مخصصة:

  1. يفتح منتقي الملفات (GetContent())
  2. يختار المستخدم ملف صوتي
  3. يحاول التطبيق الحصول على صلاحية دائمة (إن أمكن)
  4. يحفظ URI في قاعدة البيانات
  5. يعرض رسالة نجاح في Snackbar: "تم تحديث صوت الإشعار"

2. عند إعادة التعيين للافتراضي:

  1. يحذف URI المخصص من قاعدة البيانات
  2. يعرض رسالة نجاح: "تم إعادة تعيين صوت الإشعار إلى الافتراضي"

3. عند حدوث خطأ:

  1. يعرض رسالة خطأ مفصلة في Snackbar
  2. الرسالة تحتوي على سبب الخطأ

الصلاحيات المطلوبة

لا توجد صلاحيات إضافية مطلوبة!

  • GetContent() يستخدم منتقي النظام الذي يتعامل مع الصلاحيات تلقائياً
  • takePersistableUriPermission اختياري ويعمل النظام بدونه

الاختبار

سيناريوهات الاختبار:

  1. ✅ اختيار نغمة من مدير الملفات
  2. ✅ اختيار نغمة من تطبيق موسيقى
  3. ✅ تشغيل النغمة المختارة
  4. ✅ إعادة التعيين للافتراضي
  5. ✅ إعادة تشغيل التطبيق والتحقق من بقاء النغمة
  6. ✅ اختبار مع مزودي محتوى مختلفين

ملاحظات مهمة

حول takePersistableUriPermission:

  • هذه الصلاحية ليست ضرورية دائماً
  • بعض مزودي المحتوى لا يدعمونها
  • النغمة ستعمل في معظم الحالات حتى بدون هذه الصلاحية
  • في حالات نادرة، قد تحتاج لإعادة اختيار النغمة بعد إعادة تشغيل الجهاز

أفضل الممارسات:

  • استخدام نغمات من مجلد التنزيلات أو الموسيقى يعمل بشكل أفضل
  • تجنب استخدام نغمات من تطبيقات خارجية قد تحذف الملفات

التحسينات المستقبلية المقترحة

  1. نسخ النغمة محلياً:

    • نسخ ملف النغمة إلى مجلد التطبيق الخاص
    • يضمن عمل النغمة دائماً حتى بعد حذف الملف الأصلي
  2. معاينة النغمة قبل الحفظ:

    • تشغيل النغمة تلقائياً بعد الاختيار
    • زر "حفظ" و "إلغاء" للتأكيد
  3. مكتبة نغمات مدمجة:

    • توفير مجموعة من النغمات المدمجة
    • لا تحتاج لصلاحيات خارجية

الخلاصة

تم حل جميع المشاكل المتعلقة بنظام النغمات المخصصة:

  • ✅ إزالة رسائل الخطأ المربكة
  • ✅ إضافة تأكيدات واضحة للنجاح
  • ✅ تحسين معالجة الأخطاء
  • ✅ تحسين تجربة المستخدم
  • ✅ عدم طلب صلاحيات غير ضرورية

النظام الآن يعمل بشكل سلس وواضح للمستخدم!