واجهات برمجة تطبيقات Android 4.1

مستوى واجهة برمجة التطبيقات: 16

يُعد Android 4.1 (JELLY_BEAN) تطورًا على مستوى النظام الأساسي ويوفر أداءً محسنًا وتجربة مستخدم محسّنة. وتضيف ميزات جديدة للمستخدمين ومطوري التطبيقات. يقدم هذا المستند مقدمة لأهم واجهات برمجة التطبيقات الجديدة والأكثر فائدة لمطوّري التطبيقات.

بصفتك مطور تطبيقات، يتوفر Android 4.1 لك من مدير SDK كصورة نظام يمكنك تشغيلها في محاكي Android ومنصة SDK يمكنك من خلالها إنشاء تطبيقك. ينبغي لك تنزيل صورة النظام والنظام الأساسي في أقرب وقت ممكن لإنشاء تطبيقك واختباره على Android 4.1.

لتحسين أداء تطبيقك على الأجهزة التي تعمل بالإصدار 4.1 من نظام التشغيل Android، يجب ضبط السمة targetSdkVersion على "16"، وتثبيتها على إحدى صور النظام التي تعمل بالإصدار 4.1 من نظام التشغيل Android، واختبارها، ثم نشر تحديث يتضمّن هذا التغيير.

يمكنك استخدام واجهات برمجة التطبيقات في Android 4.1 مع إتاحة الإصدارات القديمة أيضًا من خلال إضافة شروط إلى الرمز البرمجي للتحقّق من مستوى واجهة برمجة تطبيقات النظام قبل تنفيذ واجهات برمجة التطبيقات غير المتوافقة مع minSdkVersion. لمعرفة المزيد حول الحفاظ على التوافق مع الأنظمة القديمة، يُرجى قراءة إنشاء واجهات مستخدم متوافقة مع الأنظمة القديمة.

تتوفّر مزيد من المعلومات حول طريقة عمل مستويات واجهة برمجة التطبيقات في القسم ما هو مستوى واجهة برمجة التطبيقات؟

مكوّنات التطبيق

الخدمات المعزولة

من خلال تحديد android:isolatedProcess="true" في العلامة <service>، سيتم تشغيل Service من خلال عملية رقم تعريف المستخدم المعزولة الخاصة بها والتي ليس لها أذونات خاصة بها.

إدارة الذاكرة

توفّر ثوابت ComponentCallbacks2 الجديدة، مثل TRIM_MEMORY_RUNNING_LOW وTRIM_MEMORY_RUNNING_CRITICAL، مزيدًا من المعلومات للعمليات التي تعمل في المقدّمة حول حالة الذاكرة قبل أن يستدعي النظام onLowMemory().

تتيح لك طريقة getMyMemoryState(ActivityManager.RunningAppProcessInfo) الجديدة استرداد الحالة العامة للذاكرة.

موفّرو المحتوى

تتيح لك طريقة جديدة، وهي acquireUnstableContentProviderClient()، الوصول إلى ContentProviderClient قد تكون "غير ثابتة" بحيث لن يتعطل تطبيقك في حال تعطّل موفِّر المحتوى. وهو مفيد عندما تتفاعل مع مزودي المحتوى في تطبيق منفصل.

خلفيات متحركة

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

لتشغيل أداة اختيار الخلفية المتحركة، يمكنك استدعاء startActivity() مع Intent باستخدام ACTION_CHANGE_LIVE_WALLPAPER وعنصر إضافي يحدّد ComponentName كسلسلة في EXTRA_LIVE_WALLPAPER_COMPONENT.

التنقّل في حزمة التطبيقات

يسهّل Android 4.1 تنفيذ أنماط التصميم المناسبة للتنقل لأعلى. ما عليك سوى إضافة android:parentActivityName إلى كل عنصر <activity> في ملف البيان. يستخدم النظام هذه المعلومات لفتح النشاط المناسب عندما يضغط المستخدم على الزر لأعلى في شريط الإجراءات (مع الانتهاء أيضًا من النشاط الحالي). لذا، إذا أعلنت عن android:parentActivityName لكل نشاط، لن تحتاج إلى طريقة onOptionsItemSelected() لمعالجة أحداث النقر على رمز التطبيق في شريط الإجراءات، لأن النظام الآن يتعامل مع هذا الحدث ويستأنف أو ينشئ النشاط المناسب.

يُعدّ هذا مفيدًا بشكل خاص في الحالات التي يدخل فيها المستخدم من أحد أنشطة تطبيقك من خلال هدف "المراجعة التفصيلية"، مثل إشعار أو غرض من تطبيق مختلف (كما هو موضّح في دليل التصميم للتنقّل بين التطبيقات). عندما يدخل المستخدم نشاطك بهذه الطريقة، قد لا يحتوي تطبيقك بطبيعة الحال على مجموعة من الأنشطة التي يمكن استئنافها أثناء انتقال المستخدم لأعلى. ومع ذلك، عند توفير السمة android:parentActivityName لأنشطتك، يتعرّف النظام على ما إذا كان تطبيقك يحتوي حاليًا على حزمة من الأنشطة الرئيسية، وفي حال عدم توفيره، ينشئ حزمة خلفية اصطناعية تحتوي على جميع الأنشطة الرئيسية.

ملاحظة: عندما يُدخِل المستخدم نشاطًا عميقًا في تطبيقك وينشئ مهمة جديدة لتطبيقك، يدرج النظام مجموعة الأنشطة الرئيسية في المهمة. وبالتالي، يؤدي الضغط على الزر "رجوع" أيضًا إلى الانتقال مرة أخرى إلى مجموعة الأنشطة الرئيسية.

عندما ينشئ النظام حزمة خلفية اصطناعية لتطبيقك، ينشئ Intent أساسي لإنشاء مثيل جديد لكل نشاط رئيسي. وبالتالي، ليست هناك حالة محفوظة للأنشطة الرئيسية بالطريقة التي كنت تتوقع أن يتنقل بها المستخدم بشكل طبيعي خلال كل نشاط. إذا كان أي من الأنشطة الرئيسية يعرض عادةً واجهة مستخدم تعتمد على سياق المستخدم، لن تتوفّر معلومات السياق هذه وعليك عرضها عندما يعود المستخدم إلى الحزمة. على سبيل المثال، إذا كان المستخدم يشاهد ألبومًا في أحد تطبيقات الموسيقى، فإن الانتقال للأعلى قد ينقله إلى نشاط يسرد جميع الألبومات في نوع موسيقى محدد. في هذه الحالة، إذا كان يجب إنشاء الحزمة، من الضروري إبلاغ النشاط الرئيسي بالنوع الذي ينتمي إليه الألبوم الحالي حتى يتمكّن الأصل من عرض القائمة المناسبة كما لو كان المستخدم قد جاء من هذا النشاط فعليًا. لإرسال هذه المعلومات إلى نشاط رئيسي اصطناعي، عليك إلغاء طريقة onPrepareNavigateUpTaskStack(). يزوّدك هذا بكائن TaskStackBuilder أنشأه النظام لتجميع الأنشطة الرئيسية. يحتوي TaskStackBuilder على Intent عناصر يستخدمها النظام لإنشاء كل نشاط رئيسي. أثناء تنفيذ onPrepareNavigateUpTaskStack()، يمكنك تعديل Intent المناسبة لإضافة بيانات إضافية يمكن أن يستخدمها النشاط الرئيسي لتحديد السياق المناسب وعرض واجهة المستخدم المناسبة.

عندما ينشئ النظام TaskStackBuilder، يضيف كائنات Intent المستخدمة لإنشاء الأنشطة الرئيسية بترتيبها المنطقي بدءًا من أعلى شجرة النشاط. إذن، آخر Intent تمت إضافته إلى الصفيفة الداخلية هو الأصل المباشر للنشاط الحالي. إذا كنت تريد تعديل Intent للعنصر الرئيسي للنشاط، عليك أولاً تحديد طول الصفيف باستخدام getIntentCount() وتمرير هذه القيمة إلى editIntentAt().

إذا كانت بنية تطبيقك أكثر تعقيدًا، تتوفّر عدة واجهات برمجة تطبيقات أخرى تتيح لك التعامل مع سلوك التنقّل للأعلى وتخصيص الحزمة الخلفية الاصطناعية بالكامل. وتشمل بعض واجهات برمجة التطبيقات التي تمنحك تحكّمًا إضافيًا ما يلي:

onNavigateUp()
يمكنك تجاوز هذا الإجراء لتنفيذ إجراء مخصَّص عندما يضغط المستخدم على الزر للأعلى.
navigateUpTo(Intent)
يمكنك طلب هذا الإجراء لإنهاء النشاط الحالي والانتقال إلى النشاط المُشار إليه في السمة Intent المقدّمة. إذا كان النشاط موجودًا في الحزمة الخلفية، ولكنه ليس أقرب عنصر رئيسي، يعني ذلك أيضًا أنّ جميع الأنشطة الأخرى بين النشاط الحالي والنشاط المحدّد بالنية قد اكتملت أيضًا.
getParentActivityIntent()
يمكنك استدعاء هذا الحدث للحصول على عنصر Intent الذي سيبدأ العنصر الرئيسي المنطقي للنشاط الحالي.
shouldUpRecreateTask(Intent)
يمكنك استدعاء هذا الحدث لمعرفة ما إذا كان يجب إنشاء حزمة خلفية اصطناعية من أجل الانتقال للأعلى. تعرض القيمة true إذا كان يجب إنشاء حزمة اصطناعية، أو تعرض القيمة "false" في حال توفُّر الحزمة المناسبة.
finishAffinity()
يجب استدعاؤها لإنهاء النشاط الحالي وجميع أنشطة أولياء الأمور التي لها نفس اهتمامات ذات اهتمامات مشتركة في النشاط الحالي. في حال إلغاء السلوكيات التلقائية، مثل onNavigateUp()، عليك استدعاء هذه الطريقة عند إنشاء حزمة اصطناعية للخلفية أثناء التنقل للأعلى.
onCreateNavigateUpTaskStack
يمكنك إلغاء هذا الإجراء إذا كنت بحاجة إلى التحكّم بشكل كامل في طريقة إنشاء حزمة المهام الاصطناعية. وإذا أردت ببساطة إضافة بعض البيانات الإضافية إلى أغراض حزمة البيانات السابقة، عليك بدلاً من ذلك إلغاء السمة onPrepareNavigateUpTaskStack().

ومع ذلك، لا تحتاج معظم التطبيقات إلى استخدام واجهات برمجة التطبيقات هذه أو تنفيذ onPrepareNavigateUpTaskStack()، ولكن يمكنها تحقيق السلوك الصحيح ببساطة من خلال إضافة android:parentActivityName إلى كل عنصر <activity>.

وسائط متعددة

برامج ترميز الوسائط

تتيح الفئة MediaCodec الوصول إلى برامج ترميز الوسائط منخفضة المستوى لترميز الوسائط وفك ترميزها. يمكنك إنشاء مثيل لـ MediaCodec من خلال طلب createEncoderByType() لترميز الوسائط أو طلب createDecoderByType() لفك ترميز الوسائط. تستخدم كل طريقة من هذه الطرق نوع MIME لنوع الوسائط التي تريد ترميزها أو فك ترميزها، مثل "video/3gpp" أو "audio/vorbis".

من خلال إنشاء مثيل لـ MediaCodec، يمكنك استدعاء configure() لتحديد خصائص مثل تنسيق الوسائط أو ما إذا كان المحتوى مشفَّرًا أم لا.

سواء كنت تعمل على ترميز الوسائط أو فك ترميزها، ستتم بقية العملية نفسها بعد إنشاء MediaCodec. استدعِ getInputBuffers() أولاً للحصول على مصفوفة من كائنات ByteBuffer الإدخال وgetOutputBuffers() للحصول على مصفوفة من عناصر الإخراج ByteBuffer.

عندما تكون مستعدًا لترميز أو فك ترميز، استدعِ dequeueInputBuffer() للحصول على موضع الفهرس ByteBuffer (من مصفوفة المخازن المؤقتة للإدخال) الذي عليك استخدامه لإدخال البيانات في وسائط المصدر. بعد ملء ByteBuffer بوسائط المصدر، عليك التنازل عن ملكية المورد الاحتياطي من خلال طلب queueInputBuffer().

وبالمثل بالنسبة إلى المخزن المؤقت للمخرجات، يمكنك استدعاء dequeueOutputBuffer() للحصول على موضع الفهرس في ByteBuffer حيث ستتلقى النتائج. بعد قراءة المخرجات من ByteBuffer، عليك سحب الملكية من خلال الاتصال بـ releaseOutputBuffer().

يمكنك التعامل مع بيانات الوسائط المشفّرة في برامج الترميز من خلال طلب queueSecureInputBuffer() بالاقتران مع واجهات برمجة تطبيقات MediaCrypto، بدلاً من queueInputBuffer() العادية.

لمزيد من المعلومات حول كيفية استخدام برامج الترميز، يمكنك الاطّلاع على مستندات MediaCodec.

تسجيل الصوت عند الانتهاء

تتيح لك الطريقة الجديدة startRecording() بدء التسجيل الصوتي استنادًا إلى إشارة يتم تحديدها من خلال MediaSyncEvent. تحدّد MediaSyncEvent جلسة صوتية (مثل الجلسة المحدّدة من خلال MediaPlayer)، وعند اكتمالها، يؤدّي ذلك إلى تشغيل مسجّل الصوت لبدء التسجيل. على سبيل المثال، يمكنك استخدام هذه الوظيفة لتشغيل نغمة صوتية تشير إلى بداية جلسة التسجيل ويبدأ التسجيل تلقائيًا حتى لا تحتاج إلى مزامنة النغمة وبداية التسجيل يدويًا.

مسارات النص المحدد زمنيًا

يعالج "MediaPlayer" الآن المقاطع الصوتية المضمّنة في النطاق وخارجه. تأتي المسارات النصية ضمن النطاق كمسار نصي ضمن مصدر وسائط MP4 أو 3GPP. يمكن إضافة المقاطع النصية خارج الإطار كمصدر نص خارجي عبر طريقة addTimedTextSource(). بعد إضافة جميع مصادر المسارات النصية الخارجية، يجب استدعاء getTrackInfo() للحصول على القائمة المحدّثة لجميع المسارات المتاحة في مصدر بيانات.

لضبط المسار لاستخدامه مع MediaPlayer، يجب استدعاء selectTrack()، باستخدام موضع الفهرس للمسار الذي تريد استخدامه.

لتلقّي إشعار عندما يكون المقطع الصوتي جاهزًا للتشغيل، نفِّذ واجهة MediaPlayer.OnTimedTextListener وأرسله إلى setOnTimedTextListener().

تأثيرات الصوت

تتيح الفئة AudioEffect الآن أنواعًا إضافية من عمليات المعالجة المسبقة للصوت عند التقاط الصوت:

  • تعمل أداة إلغاء صدى الصوت الصوتي (AEC) مع AcousticEchoCanceler على إزالة مساهمة الإشارة المُستلَمة من الطرف البعيد من الإشارة الصوتية التي تم تسجيلها.
  • إنّ ميزة التحكّم التلقائي في الاكتساب (AGC) من خلال AutomaticGainControl تعمل تلقائيًا على تسوية ناتج الإشارة المسجّلة.
  • تعمل ميزة كتم الضوضاء (NS) في NoiseSuppressor على إزالة الضوضاء في الخلفية من الإشارة التي تم التقاطها.

يمكنك تطبيق هذه التأثيرات مسبقة المعالجة على الصوت الذي تم التقاطه باستخدام AudioRecord باستخدام إحدى الفئات الفرعية AudioEffect.

ملاحظة: لا يمكن ضمان أنّ جميع الأجهزة تدعم هذه التأثيرات، لذا عليك دائمًا التحقّق أولاً من مدى التوفّر من خلال استدعاء isAvailable() في فئة التأثير الصوتي المقابلة.

تشغيل بلا فجوات

يمكنك الآن تشغيل المحتوى بدون فواصل بين كائنَين منفصلَين في ميزة "MediaPlayer". في أي وقت قبل انتهاء أول MediaPlayer، يمكنك الاتصال بـ setNextMediaPlayer() ويحاول Android تشغيل اللاعب الثاني عند توقف أول لعبة.

موجِّه الوسائط. توفّر واجهات برمجة التطبيقات MediaRouter وMediaRouteActionProvider وMediaRouteButton الجديدة، آليات عادية وواجهة مستخدم لاختيار مكان تشغيل الوسائط.

الكاميرا

حركة التركيز التلقائي

تسمح لك الواجهة الجديدة Camera.AutoFocusMoveCallback بالاستماع إلى التغييرات التي تطرأ على حركة التركيز التلقائي. يمكنك تسجيل واجهتك من خلال setAutoFocusMoveCallback(). وعندما تكون الكاميرا في وضع التركيز التلقائي المستمر (FOCUS_MODE_CONTINUOUS_VIDEO أو FOCUS_MODE_CONTINUOUS_PICTURE)، ستتلقى مكالمة إلى الرقم onAutoFocusMoving() لإعلامك بما إذا كان التركيز التلقائي قد بدأ في التحرك أو توقف عن الحركة.

أصوات الكاميرا

توفّر الفئة MediaActionSound مجموعة بسيطة من واجهات برمجة التطبيقات لإنتاج أصوات عادية تصدرها الكاميرا أو غير ذلك من إجراءات الوسائط. يجب استخدام واجهات برمجة التطبيقات هذه لتشغيل الصوت المناسب عند إنشاء كاميرا ثابتة أو كاميرا فيديو مخصصة.

لتشغيل صوت، ما عليك سوى إنشاء مثيل لكائن MediaActionSound، وطلب load() من تحميل الصوت المطلوب مسبقًا، ثم طلب "play()" في الوقت المناسب.

إمكانية الاتصال

شعاع Android

يدعم TMAndroid Beam الآن عمليات نقل حمولات كبيرة الحجم عبر البلوتوث. عند تحديد البيانات المراد نقلها إما باستخدام طريقة setBeamPushUris() الجديدة أو واجهة معاودة الاتصال الجديدة NfcAdapter.CreateBeamUrisCallback، ينفِّذ Android عملية نقل البيانات إلى البلوتوث أو وسيلة نقل بديلة أخرى لتحقيق سرعات نقل أسرع. ويُعدّ هذا الأمر مفيدًا على وجه الخصوص للحمولات الكبيرة مثل ملفات الصور والصوت ولا يتطلّب إقرانًا مرئيًا بين الأجهزة. لا يحتاج تطبيقك إلى عمل إضافي للاستفادة من عمليات النقل عبر البلوتوث.

تستخدم الطريقة setBeamPushUris() مصفوفة من عناصر Uri التي تحدّد البيانات التي تريد نقلها من تطبيقك. بدلاً من ذلك، يمكنك تنفيذ الواجهة NfcAdapter.CreateBeamUrisCallback التي يمكنك تحديدها لنشاطك من خلال استدعاء setBeamPushUrisCallback().

عند استخدام واجهة معاودة الاتصال، يطلب النظام طريقة createBeamUris() للواجهة عندما ينفِّذ المستخدم مشاركة باستخدام شعاع Android بحيث يمكنك تحديد معرّفات الموارد المنتظمة (URI) لمشاركتها في وقت المشاركة. يكون هذا مفيدًا إذا كانت معرّفات الموارد المنتظمة (URI) التي تريد مشاركتها قد تختلف بناءً على سياق المستخدم ضمن النشاط، في حين أنّ استدعاء setBeamPushUris() يفيد عندما لا تتغير معرّفات الموارد المنتظمة (URI) التي ستتم مشاركتها ويمكنك تحديدها مسبقًا بأمان.

اكتشاف خدمة الشبكة

يضيف Android 4.1 دعمًا لاكتشاف الخدمة المستندة إلى نظام أسماء النطاقات (DNS) للبث المتعدد، والذي يسمح لك بالعثور على الخدمات التي تقدّمها الأجهزة النظيرة والاتصال بها عبر Wi-Fi، مثل الأجهزة الجوّالة والطابعات والكاميرات ومشغّلات الوسائط وغيرها من الخدمات المسجّلة في الشبكة المحلية.

تحتوي الحزمة الجديدة android.net.nsd على واجهات برمجة التطبيقات الجديدة التي تتيح لك بث خدماتك على الشبكة المحلية واكتشاف الأجهزة المحلية على الشبكة والاتصال بالأجهزة.

لتسجيل خدمتك، عليك أولاً إنشاء عنصر NsdServiceInfo وتحديد السمات المختلفة لخدمتك باستخدام طُرق مثل setServiceName() وsetServiceType() و setPort().

بعد ذلك، يجب تنفيذ العلامة NsdManager.RegistrationListener وتمريرها إلى registerService() من خلال NsdServiceInfo.

لاكتشاف الخدمات على الشبكة، يمكنك تنفيذ NsdManager.DiscoveryListener وتمريرها إلى discoverServices().

عندما تتلقّى "NsdManager.DiscoveryListener" استدعاءات عن الخدمات التي تم العثور عليها، عليك حلّ المشكلة المتعلقة بالخدمة من خلال طلب resolveService()، من خلال تمرير عملية تنفيذ NsdManager.ResolveListener التي تستقبل عنصر NsdServiceInfo يحتوي على معلومات حول الخدمة التي تم اكتشافها، ما يسمح لك ببدء الاتصال.

رصد خدمة Wi-Fi P2P

تم تحسين واجهات برمجة تطبيقات Wi-Fi P2P في Android 4.1 لإتاحة رصد خدمة الربط المسبق في WifiP2pManager. ويتيح لك ذلك اكتشاف الأجهزة القريبة وفلترتها حسب الخدمات باستخدام تقنية Wi-Fi P2P قبل الاتصال بشبكة، في حين تسمح لك ميزة "اكتشاف خدمة الشبكة" باكتشاف خدمة على شبكة متصلة حاليًا (مثل شبكة Wi-Fi محلية).

لبث تطبيقك كخدمة عبر Wi-Fi حتى تتمكن الأجهزة الأخرى من اكتشاف تطبيقك والاتصال به، يمكنك استدعاء addLocalService() باستخدام عنصر WifiP2pServiceInfo يصف خدمات تطبيقك.

لبدء رصد الأجهزة المجاورة عبر Wi-Fi، عليك أولاً تحديد ما إذا كنت تريد التواصل باستخدام Bonjour أو Upnp. لاستخدام Bonjour، عليك أولاً إعداد بعض أدوات استقبال الاتصال من خلال setDnsSdResponseListeners()، والتي تتطلب كلاً من WifiP2pManager.DnsSdServiceResponseListener وWifiP2pManager.DnsSdTxtRecordListener. لاستخدام Upnp، يمكنك الاتصال بـ setUpnpServiceResponseListener()، الذي يستغرق WifiP2pManager.UpnpServiceResponseListener.

قبل البدء في اكتشاف الخدمات على الأجهزة المحلية، يجب أيضًا الاتصال بالرقم addServiceRequest(). عندما تتلقى WifiP2pManager.ActionListener التي تم تمريرها إلى هذه الطريقة معاودة الاتصال بنجاح، يمكنك البدء باكتشاف الخدمات على الأجهزة المحلية من خلال الاتصال بالرقم discoverServices().

عندما يتم اكتشاف الخدمات المحلية، ستتلقى معاودة الاتصال إما إلى WifiP2pManager.DnsSdServiceResponseListener أو WifiP2pManager.UpnpServiceResponseListener، بناءً على ما إذا تم التسجيل لاستخدام Bonjour أو Upnp. يحتوي ردّ الاتصال الذي تم تلقّيه في كلتا الحالتين على عنصر WifiP2pDevice يمثّل الجهاز النظير.

بيانات استخدام الشبكة

تتيح لك الطريقة الجديدة "isActiveNetworkMetered()" التحقّق مما إذا كان الجهاز متصلاً حاليًا بشبكة تفرض تكلفة استخدام. ومن خلال التحقق من هذه الحالة قبل إجراء معاملات كثيفة في الشبكة، يمكنك المساعدة في إدارة استخدام البيانات التي قد تكلف المستخدمين أموالاً واتخاذ قرارات مدروسة بشأن إجراء المعاملات الآن أو لاحقًا (مثلاً، عندما يتصل الجهاز بشبكة Wi-Fi).

تسهيل الاستخدام

واجهات برمجة التطبيقات لخدمات تسهيل الاستخدام

تمت زيادة مدى وصول واجهات برمجة التطبيقات لخدمات تسهيل الاستخدام بشكل كبير في الإصدار Android 4.1. تتيح لك هذه الميزة الآن إنشاء خدمات تراقب المزيد من أحداث الإدخال وتستجيب لها، مثل الإيماءات المعقّدة باستخدام onGesture() وأحداث إدخال أخرى من خلال الإضافات إلى الفئات AccessibilityEvent وAccessibilityNodeInfo وAccessibilityRecord.

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

إمكانية تخصيص التنقل في التطبيق

عند إنشاء تطبيق Android، يمكنك الآن تخصيص مخططات التنقل من خلال العثور على العناصر التي يمكن التركيز عليها وأدوات الإدخال باستخدام findFocus() وfocusSearch()، وضبط التركيز باستخدام setAccessibilityFocused().

تطبيقات مصغّرة يسهل الوصول إليها

تتيح لك الفئة android.view.accessibility.AccessibilityNodeProvider الجديدة عرض طرق عرض مخصّصة ومعقّدة لخدمات تسهيل الاستخدام كي تتمكّن من تقديم المعلومات بطريقة أسهل. تسمح android.view.accessibility.AccessibilityNodeProvider لأداة المستخدم ذات المحتوى المتقدم، مثل شبكة التقويم، بتقديم بنية دلالية منطقية لخدمات تسهيل الاستخدام منفصلة تمامًا عن بنية تنسيق الأداة. يسمح هذا الهيكل الدلالي لخدمات إمكانية الوصول بتقديم نموذج تفاعل أكثر فائدة للمستخدمين من ضعاف البصر.

النسخ واللصق

النسخ واللصق حسب النية

يمكنك الآن ربط كائن ClipData بالعنصر Intent باستخدام الإجراء setClipData(). ويُعدّ ذلك مفيدًا على وجه الخصوص عند استخدام غرض لنقل معرّفات content: متعددة إلى تطبيق آخر، كما هو الحال عند مشاركة مستندات متعددة. ستراعي معرّفات الموارد المنتظمة (URI) content: التي يتم تقديمها بهذه الطريقة أيضًا علامات الغرض لتوفير إمكانية الوصول للقراءة أو الكتابة، ما يسمح لك بمنح الوصول إلى معرّفات URI متعددة في الغرض. عند بدء غرض ACTION_SEND أو ACTION_SEND_MULTIPLE، يتم الآن تلقائيًا نشر معرّفات الموارد المنتظمة (URI) المُدخلة في الغرض إلى ClipData حتى يحصل المُستلِم على إذن الوصول.

دعم أنماط HTML وأنماط السلسلة

تتيح الفئة ClipData الآن استخدام النصوص ذات الأنماط المحدّدة (إما على شكل HTML أو سلاسل بنمط Android). يمكنك إضافة نص بنمط HTML إلى ClipData باستخدام newHtmlText().

نص Renderscript

تم تحسين وظيفة احتساب Renderscript بالميزات التالية:

  • دعم نواة متعددة ضمن نص برمجي واحد.
  • إتاحة القراءة من عملية التخصيص باستخدام نماذج العيّنات المفلتَرة من عملية الحوسبة في واجهة برمجة تطبيقات جديدة خاصة بالنصوص البرمجية rsSample.
  • دعم مستويات مختلفة من دقة الملف الشخصي في #pragma.
  • إتاحة طلب البحث عن معلومات إضافية من كائنات RS من نص برمجي للحوسبة
  • تحسينات عديدة على الأداء

تتوفر أيضًا نماذج جديدة لتحديد دقة النقطة العائمة المطلوبة من خلال نصوص Renderscript الحوسبية. يتيح لك هذا تمكين عمليات NEON مثل العمليات الحسابية للمتجهات السريعة على مسار وحدة المعالجة المركزية والتي لن يكون ممكنًا بخلاف ذلك مع معيار IEEE 754-2008 الكامل.

ملاحظة: تم إيقاف المحرك التجريبي لرسومات Renderscript الآن.

Animation

الصور المتحركة لبدء النشاط

يمكنك الآن تشغيل Activity باستخدام الصور المتحركة للتكبير/التصغير أو الصور المتحركة المخصّصة لك. لتحديد الصورة المتحركة التي تريدها، استخدِم واجهات برمجة تطبيقات ActivityOptions لإنشاء Bundle يمكنك تمريره بعد ذلك إلى أي من الطرق التي تبدأ نشاطًا، مثل startActivity().

تتضمن فئة ActivityOptions طريقة مختلفة لكل نوع من الصور المتحركة التي قد ترغب في عرضها عند فتح نشاطك:

makeScaleUpAnimation()
لإنشاء صورة متحركة لتوسيع نافذة النشاط من موضع بداية محدّد على الشاشة وحجم بداية محدّد. على سبيل المثال، تستخدم الشاشة الرئيسية في Android 4.1 هذا الخيار عند فتح أحد التطبيقات.
makeThumbnailScaleUpAnimation()
ينشئ رسمًا متحركًا يزيد حجم نافذة النشاط بدءًا من موضع محدد وصورة مصغّرة مقدَّمة. على سبيل المثال، تستخدم نافذة "التطبيقات المستخدَمة مؤخرًا" في Android 4.1 هذا الخيار عند الرجوع إلى أحد التطبيقات.
makeCustomAnimation()
ينشئ صورة متحركة تحدّدها مواردك الخاصة: صورة تحدّد الصورة المتحركة أثناء بدء النشاط وأخرى للنشاط الذي يتم إيقافه.

مؤثرات الوقت

توفّر السمة TimeAnimator الجديدة آلية بسيطة لرد الاتصال من خلال العلامة TimeAnimator.TimeListener التي ترسل إشعارًا إليك عند كل لقطة من الصورة المتحركة. ما مِن مدة أو إضافة أو ضبط لقيمة العنصر في أداة الصور المتحرّكة هذه. يتلقّى المستمع معلومات حول كل لقطة، بما في ذلك إجمالي الوقت المنقضي والوقت المنقضي منذ الإطار السابق للرسم المتحرك.

واجهة المستخدم

الإشعارات

في Android 4.1، يمكنك إنشاء إشعارات تتضمن مناطق محتوى أكبر ومعاينات للصور الكبيرة وأزرار إجراءات متعددة وأولوية قابلة للتهيئة.

أنماط الإشعارات

تتيح لك الطريقة الجديدة setStyle() تحديد نمط من بين ثلاثة أنماط جديدة للإشعار بأن كل نمط يوفّر منطقة محتوى أكبر. لتحديد نمط منطقة المحتوى الكبيرة، مرر setStyle() بأحد الكائنات التالية:

Notification.BigPictureStyle
بالنسبة إلى الإشعارات التي تتضمّن مرفق صورة كبيرًا
Notification.BigTextStyle
بالنسبة إلى الإشعارات التي تتضمن قدرًا كبيرًا من النصوص، مثل رسالة إلكترونية واحدة
Notification.InboxStyle
بالنسبة إلى الإشعارات التي تتضمّن قائمة من السلاسل، مثل المقتطفات من رسائل إلكترونية متعددة
إجراءات الإشعارات

يتوفّر الآن زرَّي إجراء كحد أقصى في أسفل رسالة الإشعار، سواء كان الإشعار يستخدم النمط العادي أو النمط الأكبر.

لإضافة زر إجراء، اتصل بالرقم addAction(). تتطلّب هذه الطريقة ثلاث وسيطات: مورد قابل للرسم لرمز، ونص للزر، وPendingIntent يحدّد الإجراء المطلوب تنفيذه.

الأولويات

يمكنك الآن أن تشير إلى النظام في مدى أهمية تأثير الإشعار في ترتيب الإشعارات في القائمة من خلال ضبط الأولوية باستخدام setPriority(). يمكنك اجتياز هذا المستوى من المستويات الخمسة المختلفة للأولوية التي حدّدتها ثوابت PRIORITY_* في الفئة Notification. القيمة التلقائية هي PRIORITY_DEFAULT، وهناك مستويان أعلى ومستويان أدنى.

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

عناصر التحكُّم في واجهة مستخدم النظام

أضاف نظام التشغيل Android 4.0 (Ice Cream السندويش) علامات جديدة للتحكم في رؤية عناصر واجهة المستخدم الخاصة بالنظام، مثل تعتيم شريط النظام أو جعله يختفي تمامًا على الهواتف المحمولة. يضيف Android 4.1 بعض العلامات الإضافية التي تتيح لك التحكّم بشكل أكبر في مظهر عناصر واجهة مستخدم النظام وتنسيق نشاطك في ما يتعلّق بها من خلال طلب الرمز setSystemUiVisibility() وتمرير العلامات التالية:

SYSTEM_UI_FLAG_FULLSCREEN
إخفاء واجهة المستخدم غير المهمة للنظام (مثل شريط الحالة) إذا كان نشاطك يستخدم شريط الإجراءات في وضع التراكب (من خلال تفعيل android:windowActionBarOverlay)، ستعمل هذه العلامة أيضًا على إخفاء شريط الإجراءات مع عرض صورة متحركة منسَّقة معًا عند إخفاء الاثنين وإظهارهما.
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
يضبط هذا الإعداد تنسيق نشاطك لاستخدام مساحة الشاشة نفسها التي تكون متاحة عند تفعيل SYSTEM_UI_FLAG_FULLSCREEN حتى إذا كانت عناصر واجهة مستخدم النظام لا تزال مرئية. سيتم تراكب أجزاء من التصميم من خلال واجهة مستخدم النظام، إلا أنّ ذلك مفيد إذا كان تطبيقك يخفي واجهة مستخدم النظام ويعرضها غالبًا باستخدام SYSTEM_UI_FLAG_FULLSCREEN، لأنّ ذلك يتجنّب تعديل التنسيق مع حدود التصميم الجديدة في كل مرة تخفي فيها واجهة مستخدم النظام أو تظهر فيها.
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
يضبط هذا الإعداد تنسيق نشاطك لاستخدام مساحة الشاشة نفسها المتاحة عند تفعيل SYSTEM_UI_FLAG_HIDE_NAVIGATION (مُضاف في Android 4.0) حتى إذا كانت عناصر واجهة مستخدم النظام لا تزال مرئية. ومع أنّ شريط التنقّل سيغطّي أجزاءً من التنسيق، يكون ذلك مفيدًا إذا كان تطبيقك يخفي شريط التنقل ويعرضه غالبًا مع SYSTEM_UI_FLAG_HIDE_NAVIGATION، لأنّ ذلك يتجنّب تعديل التنسيق مع حدود التصميم الجديدة في كل مرة يخفي فيها شريط التنقّل أو يظهر فيه.
SYSTEM_UI_FLAG_LAYOUT_STABLE
يمكنك إضافة هذه العلامة إذا كنت تستخدم SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN و/أو SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION لضمان بقاء الحدود المحدّدة متسقة عند استدعاء fitSystemWindows() في عرض مع مساحة الشاشة المتاحة. أي أنّه عند استخدام مجموعة العلامات هذه، سيعمل fitSystemWindows() كما لو لم يتغير مستوى رؤية عناصر واجهة مستخدم النظام حتى بعد إخفاء جميع واجهات المستخدم الخاصة بالنظام.

لمزيد من النقاش حول علامات واجهة المستخدم الخاصة بالنظام الأخرى، يمكنك الاطّلاع على تلك التي تمت إضافتها في Android 4.0.

المشاهدات عن بُعد

أصبحت الآن ميزتا GridLayout وViewStub طريقة عرض عن بُعد، لذا يمكنك استخدامهما في تنسيقات لتطبيقاتك المصغّرة وتنسيقات مخصّصة للإشعارات.

مجموعات الخطوط

يضيف نظام التشغيل Android 4.1 عدة أنواع أخرى من نمط خط Roboto إلى 10 خيارات مختلفة، ويمكن أن تستخدمها التطبيقات كلها. يمكن لتطبيقاتك الآن الوصول إلى المجموعة الكاملة من الصيغ الفاتحة والمكثفة.

فيما يلي المجموعة الكاملة من خطوط Roboto المتاحة:

  • عادي
  • مائل
  • غامق
  • غامق ومائل
  • فاتح
  • مائل فاتح
  • مكثفة عادية
  • مائل مكثف
  • غامق غامق
  • مكثف غامق ومائل

يمكنك تطبيق أي من هذه الطرق باستخدام السمة fontFamily الجديدة مع السمة textStyle.

القيم المسموح بها للسمة fontFamily هي:

  • "sans-serif" مقابل اشتراك Roboto العادي
  • "sans-serif-light" لجهاز Roboto Light
  • "sans-serif-condensed" لـ Roboto Condensed

يمكنك بعد ذلك تطبيق التنسيق الغامق و/أو المائل باستخدام قيمتَي textStyle "bold" و"italic". يمكنك تطبيق القيمتين كما يلي: android:textStyle="bold|italic".

يمكنك أيضًا استخدام Typeface.create(). مثلاً: Typeface.create("sans-serif-light", Typeface.NORMAL)

إطار عمل الإدخال

أجهزة إدخال متعددة

تسمح لك الفئة InputManager الجديدة بإجراء طلبات بحث عن مجموعة أجهزة الإدخال المتصلة حاليًا والتسجيل لتلقّي إشعار عند إضافة جهاز جديد أو تغييره أو إزالته. يُعدّ ذلك مفيدًا على وجه الخصوص إذا كنت تصمّم لعبة تتيح استخدام العديد من اللاعبين وتريد معرفة عدد وحدات التحكّم المتصلة بالإنترنت ووقت حدوث تغييرات في عدد وحدات التحكّم.

يمكنك الاستعلام عن جميع أجهزة الإدخال المتصلة عن طريق طلب الرقم getInputDeviceIds(). يؤدي ذلك إلى عرض مصفوفة من الأعداد الصحيحة، يكون كل منها مُعرّفًا لجهاز إدخال مختلف. يمكنك بعد ذلك استدعاء getInputDevice() للحصول على InputDevice لرقم تعريف جهاز إدخال محدّد.

إذا كنت تريد تلقّي إشعار عند توصيل أجهزة إدخال جديدة أو تغييرها أو فصلها، يمكنك تنفيذ واجهة InputManager.InputDeviceListener وتسجيلها من خلال registerInputDeviceListener().

الاهتزاز مع وحدات التحكم بالإدخال

إذا كانت أجهزة الإدخال المتصلة بها إمكانات خاصة بها للاهتزاز، يمكنك الآن التحكّم في اهتزاز هذه الأجهزة باستخدام واجهات برمجة تطبيقات Vibrator الحالية ببساطة من خلال استدعاء getVibrator() على InputDevice.

الأذونات

في ما يلي الأذونات الجديدة:

READ_EXTERNAL_STORAGE
يوفّر وصولًا آمنًا للقراءة في وحدة التخزين الخارجية. في Android 4.1، تظل جميع التطبيقات يمكنها الوصول للقراءة بشكل افتراضي. وسيتم تغيير هذا في إصدار مستقبلي لاشتراط أن تطلب التطبيقات صراحةً إذن الوصول للقراءة باستخدام هذا الإذن. إذا كان التطبيق يطلب إذنًا بالتعديل مسبقًا، فسيحصل تلقائيًا على إذن بالقراءة أيضًا. يتوفّر خيار جديد للمطوّرين يتيح تفعيل وضع قيود على الوصول للقراءة، وذلك ليتمكّن المطوّرون من اختبار تطبيقاتهم لمعرفة سلوك Android في المستقبل.
android.Manifest.permission.READ_USER_DICTIONARY
تتيح للتطبيق قراءة قاموس المستخدم. ويجب أن يكون هذا الإجراء مطلوبًا فقط باستخدام أداة IME أو أداة تعديل القواميس، مثل تطبيق "الإعدادات".
READ_CALL_LOG
يسمح هذا الإذن للتطبيق بقراءة سجلّ المكالمات في النظام الذي يحتوي على معلومات حول المكالمات الواردة والصادرة.
WRITE_CALL_LOG
تسمح لتطبيق بتعديل سجلّ مكالمات النظام المُخزَّن على هاتفك
android.Manifest.permission.WRITE_USER_DICTIONARY
تسمح لتطبيق بالكتابة إلى قاموس الكلمات لدى المستخدم.

ميزات الجهاز

يتضمّن Android 4.1 بيانًا جديدًا بالميزات للأجهزة المخصّصة لعرض واجهة المستخدم على شاشة التلفزيون: FEATURE_TELEVISION. لتوضيح أنّ تطبيقك يتطلّب واجهة تلفزيون، عليك الإفصاح عن هذه الميزة في ملف البيان باستخدام العنصر <uses-feature>:

<manifest ... >
    <uses-feature android:name="android.hardware.type.television"
                  android:required="true" />
    ...
</manifest>

تعرف هذه الميزة "التلفزيون" على أنّه تجربة تلفزيون نموذجية في غرفة المعيشة، يتم عرضه على شاشة كبيرة حيث يجلس المستخدم بعيدًا، والشكل السائد للإدخال يشبه لوحة التحكم، ولا يكون عادةً من خلال اللمس أو الماوس/جهاز المؤشر.