شاشة الأحدث

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

تستخدم شاشة "التطبيقات الحديثة" نموذجًا يركّز على المستندات تم تقديمه في نظام التشغيل Android 5.0 (المستوى 21 من واجهة برمجة التطبيقات)، حيث يمكن أن تظهر مثيلات متعددة من النشاط نفسه الذي يحتوي على مستندات مختلفة كمهام في شاشة "التطبيقات الحديثة". على سبيل المثال، قد يتضمّن Google Drive مهمة لكل مستند من عدة مستندات Google. يظهر كل مستند كمهمة في شاشة "المستندات الحديثة" على النحو التالي:

تعرض شاشة "المستندات الحديثة" مستندَين من Google Drive، يتم تمثيل كل منهما كمهمة منفصلة.

مثال شائع آخر هو عندما يستخدم المستخدم المتصفح وينقر على مشاركة > Gmail. تظهر شاشة إنشاء في تطبيق Gmail. يؤدي النقر على زر "التطبيقات الحديثة" في ذلك الوقت إلى عرض Chrome وGmail كعمليتَين منفصلتَين:

شاشة "التطبيقات الحديثة" تعرض Chrome وGmail يعملان كمهام منفصلة.

عادةً، تسمح للنظام بتحديد كيفية تمثيل مهامك وأنشطتك في شاشة "التطبيقات الحديثة". ليس عليك تعديل هذا السلوك. ومع ذلك، يمكن لتطبيقك تحديد كيفية ظهور الأنشطة في شاشة "التطبيقات الحديثة" ووقت ظهورها.

يتيح لك الصف ActivityManager.AppTask إدارة المهام، وتتيح لك علامات نشاط الصف Intent تحديد وقت إضافة نشاط أو إزالته من شاشة "التطبيقات الحديثة". تتيح لك سمات <activity> أيضًا ضبط السلوك في ملف البيان.

إضافة مهام إلى شاشة "التطبيقات الحديثة"

يمنحك استخدام علامات الفئة Intent لإضافة مهمة تحكّمًا أكبر في وقت وكيفية فتح مستند أو إعادة فتحه في شاشة "الملفات الحديثة". عند استخدام سمات <activity>، يمكنك الاختيار بين فتح المستند دائمًا في مهمة جديدة أو إعادة استخدام مهمة حالية للمستند.

استخدام علامة Intent لإضافة مهمة

عند إنشاء مستند جديد لنشاطك، عليك استدعاء الطريقة startActivity() مع تمرير الغرض الذي يبدأ النشاط. لإدراج فاصل منطقي كي يتعامل النظام مع نشاطك على أنّه مهمة جديدة في شاشة &quot;التطبيقات الحديثة&quot;، مرِّر العلامة FLAG_ACTIVITY_NEW_DOCUMENT في طريقة addFlags() الخاصة بـ Intent التي تشغّل النشاط.

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

private fun newDocumentIntent(context: Context): Intent =
    Intent(context, NewDocumentActivity::class.java).apply {
        addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT or Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS)
        putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, documentCounter++)
    }

@Composable
fun CreateDocumentButton() {
    val context = LocalContext.current
    Button(
        onClick = {
            val intent = newDocumentIntent(context)
            // Add FLAG_ACTIVITY_MULTIPLE_TASK if needed based on state
            context.startActivity(intent)
        }
    ) {
        Text("Create New Document")
    }
}

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

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

class DocumentCentricActivity : ComponentActivity() {
    private var documentState by mutableStateOf(
        DocumentState(
            count = 0,
            textResId = R.string.hello_new_document_counter
        )
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val initialCount = intent.getIntExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0)

        documentState = documentState.copy(count = initialCount)

        setContent {
            MaterialTheme {
                DocumentScreen(
                    count = documentState.count,
                    textResId = documentState.textResId
                )
            }
        }
    }

    override fun onNewIntent(newIntent: Intent) {
        super.onNewIntent(newIntent)
        // If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this Activity is reused.
        documentState = documentState.copy(
            textResId = R.string.reusing_document_counter
        )
    }

    data class DocumentState(val count: Int, @StringRes val textResId: Int)

    companion object {
        const val KEY_EXTRA_NEW_DOCUMENT_COUNTER = "KEY_EXTRA_NEW_DOCUMENT_COUNTER"
    }
}

@Composable
fun DocumentScreen(count: Int, @StringRes textResId: Int) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.Center
    ) {
        // UI reacts to whichever string resource ID was passed down
        Text(text = stringResource(id = textResId))
        Spacer(modifier = Modifier.height(8.dp))
        Text(text = "Counter: $count")
    }
}

في الرمز البرمجي السابق، يتعامل النشاط مع التوجيه على مستوى نظام التشغيل (onCreate وonNewIntent)، بينما تكون الدالة @Composable مسؤولة فقط عن عرض واجهة المستخدم استنادًا إلى الحالة المقدَّمة.

استخدام سمة النشاط لإضافة مهمة

يمكن أن يحدّد النشاط أيضًا في ملف البيان أنّه يتم تشغيله دائمًا في مهمة جديدة باستخدام السمة <activity> android:documentLaunchMode. تتضمّن هذه السمة أربع قيم تؤدي إلى التأثيرات التالية عندما يفتح المستخدم مستندًا باستخدام التطبيق:

intoExisting
يعيد النشاط استخدام مهمة حالية للمستند. وهذا الإجراء مماثل لضبط العلامة FLAG_ACTIVITY_NEW_DOCUMENT بدون ضبط العلامة FLAG_ACTIVITY_MULTIPLE_TASK، كما هو موضّح في القسم استخدام علامة Intent لإضافة مهمة.
always
ينشئ النشاط مهمة جديدة للمستند، حتى إذا كان المستند مفتوحًا. ويكون استخدام هذه القيمة مماثلاً لضبط العلامتَين FLAG_ACTIVITY_NEW_DOCUMENT وFLAG_ACTIVITY_MULTIPLE_TASK.
none
لا يؤدي النشاط إلى إنشاء مهمة جديدة للمستند. تعامِل شاشة "التطبيقات الحديثة" النشاط كما تفعل تلقائيًا. تعرض هذه السمة مهمة واحدة للتطبيق، والتي تستأنف من أي نشاط استدعاه المستخدم آخر مرة.
never
لا يؤدي النشاط إلى إنشاء مهمة جديدة للمستند. يؤدي ضبط هذه القيمة إلى تجاهل سلوك العلامتَين FLAG_ACTIVITY_NEW_DOCUMENT وFLAG_ACTIVITY_MULTIPLE_TASK. إذا تم ضبط أيّ من هذين الخيارين في الغرض، وكانت شاشة &quot;التطبيقات الحديثة&quot; تعرض مهمة واحدة للتطبيق، سيتم استئناف التطبيق من آخر نشاط استدعاه المستخدم.

إزالة المهام

يتم تلقائيًا إغلاق مهمة المستند من شاشة "المستندات الحديثة" عند انتهاء نشاطها. يمكنك إلغاء هذا السلوك باستخدام الفئة ActivityManager.AppTask أو العلامة Intent أو السمة <activity>.

يمكنك في أي وقت استبعاد مهمة من شاشة "المستندات الحديثة" تمامًا عن طريق ضبط قيمة السمة <activity> على android:excludeFromRecentstrue.

يمكنك ضبط الحد الأقصى لعدد المهام التي يمكن أن يتضمّنها تطبيقك في شاشة &quot;التطبيقات الحديثة&quot; من خلال ضبط السمة <activity>android:maxRecents على قيمة عدد صحيح. عند بلوغ الحد الأقصى لعدد المهام، تختفي المهمة الأقل استخدامًا من شاشة "التطبيقات الحديثة". القيمة التلقائية هي 16، والحد الأقصى للقيمة هو 50 (25 على الأجهزة التي تتوفر فيها ذاكرة منخفضة). لا تصلح القيم الأقل من 1.

استخدام فئة AppTask لإزالة المهام

في النشاط الذي ينشئ مهمة جديدة في شاشة &quot;النشاطات الأخيرة&quot;، يمكنك تحديد وقت إزالة المهمة وإنهاء جميع الأنشطة المرتبطة بها من خلال استدعاء الطريقة finishAndRemoveTask():

@Composable
fun RemoveTaskButton() {
    val context = LocalContext.current
    Button(
        onClick = {
            // It is good practice to remove a document from the overview stack if not needed anymore.
            (context as? Activity)?.finishAndRemoveTask()
        }
    ) {
        Text("Remove from Recents")
    }
}

الاحتفاظ بالمهام المكتملة

إذا أردت الاحتفاظ بمهمة في شاشة "المستخدَمة مؤخرًا"، حتى إذا انتهى نشاطها، مرِّر العلامة FLAG_ACTIVITY_RETAIN_IN_RECENTS في طريقة addFlags() للغرض الذي يبدأ النشاط.

private fun newDocumentIntent() =
        Intent(this, NewDocumentActivity::class.java).apply {
            addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT or
                    android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS)
            putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, getAndIncrement())
        }

لتحقيق التأثير نفسه، اضبط السمة <activity> android:autoRemoveFromRecents على false. القيمة التلقائية هي true لأنشطة المستندات وfalse للأنشطة العادية. يؤدي استخدام هذه السمة إلى تجاهل العلامة FLAG_ACTIVITY_RETAIN_IN_RECENTS.

تفعيل ميزة مشاركة عناوين URL الحديثة (هواتف Pixel فقط)

على أجهزة Pixel التي تعمل بنظام التشغيل Android 12 أو إصدار أحدث، يمكن للمستخدمين مشاركة روابط إلى محتوى الويب الذي تم عرضه مؤخرًا مباشرةً من شاشة "التطبيقات الحديثة". بعد الانتقال إلى المحتوى في أحد التطبيقات، يمكن للمستخدم التمرير سريعًا إلى شاشة &quot;التطبيقات الحديثة&quot; والعثور على التطبيق الذي شاهد فيه المحتوى، ثم النقر على زر الرابط لنسخ عنوان URL أو مشاركته.

شاشة "الملفات الحديثة" مع رابط لمشاركة محتوى الويب الذي تم عرضه مؤخرًا

يمكن لأي تطبيق تفعيل ميزة الربط بالتطبيقات الحديثة الاستخدام للمستخدمين من خلال توفير واجهة مستخدم على الويب وتجاوز onProvideAssistContent()، كما هو موضّح في المثال التالي:

class MainActivity : ComponentActivity() {

    // Track the current URL as state so the UI can update it during navigation
    private var currentWebUri by mutableStateOf("https://example.com/home")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            AppTheme {
                // Pass a lambda to your Compose UI so it can update the URL state
                // as the user navigates through your app.
                MainScreen(
                    onPageChanged = { newUrl -> currentWebUri = newUrl }
                )
            }
        }
    }

    override fun onProvideAssistContent(outContent: AssistContent) {
        super.onProvideAssistContent(outContent)

        // The system calls this when the user enters the Recents screen.
        // Provide the active URI tracked by the Compose state.
        outContent.webUri = Uri.parse(currentWebUri)
    }
}