إنشاء تطبيق لتدوين الملاحظات

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

يمكن للمستخدمين الوصول إلى تطبيقات تدوين الملاحظات من شاشة القفل أو أثناء تشغيل تطبيقات أخرى.

يوفر دعم قلم الشاشة لتدوين الملاحظات تجربة مستخدم استثنائية.

دور الملاحظات

يحدِّد الدور RoleManager.ROLE_NOTES تطبيقات تدوين الملاحظات ويمنحها إذن LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE.

لاكتساب دور الملاحظات في تطبيقك، عليك اتّباع الخطوات التالية:

  1. يمكنك الاتصال بالرقم isRoleAvailable() للتحقُّق من حالة الدور.
  2. إذا كان دور الملاحظات متاحًا، يمكنك استدعاء createRequestRoleIntent() للحصول على غرض متعلق بالملاحظات.
  3. يمكنك الاتصال بـ startActivityForResult() مع نية حث المستخدم على منح دور الملاحظات إلى تطبيقك.

يجب أن يحصل تطبيق واحد فقط على دور الملاحظات.

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

بيان التطبيق

ليصبح تطبيقك مؤهّلاً لدور الملاحظات، يجب أن يتضمّن البيان البيان التالي في بيان التطبيق:

<activity
    android:name="YourActivityName"
    android:exported="true"
    android:showWhenLocked="true"
    android:turnScreenOn="true">
    <intent-filter>
        <action android:name="android.intent.action.CREATE_NOTE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

يتيح البيان للمستخدمين تعيين دور الملاحظات لتطبيقك، ما يجعله تطبيق تدوين الملاحظات التلقائي:

  • تُحدِّد ACTION_CREATE_NOTE إجراء النية الذي يستجيب له تطبيقك.

  • يتيح showWhenLocked إمكانية الوصول إلى تطبيقك من شاشة قفل الجهاز.

  • يتيح turnScreenOn لتطبيقك تشغيل شاشة الجهاز عند تشغيله.

ميزات التطبيق

يوفّر تطبيق تدوين الملاحظات المميّز على الشاشة الكبيرة إمكانية كاملة للاستفادة من إمكانات تدوين الملاحظات.

متوافق مع قلم الشاشة

عند استدعاء تطبيقك مع ضبط المزيد من أهداف EXTRA_USE_STYLUS_MODE على true، من المفترض أن يفتح التطبيق ملاحظة تقبل الإدخال باستخدام قلم الشاشة (أو باللمس).

في حال ضبط الغرض الإضافي على false، من المفترَض أن يفتح تطبيقك ملاحظة تقبل إدخال لوحة المفاتيح.

الوصول إلى شاشة القفل

يجب أن يوفّر تطبيقك نشاطًا بملء الشاشة يتم تشغيله عند فتح التطبيق من شاشة قفل الجهاز.

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

يمكنك التحقّق مما إذا تم تشغيل تطبيقك من شاشة القفل باستخدام KeyguardManager#isKeyguardLocked(). لطلب المصادقة على الجهاز وفتح قفله، يُرجى الاتصال بـ KeyguardManager#requestDismissKeyguard():

Kotlin

val keyguardManager = getSystemService(KEYGUARD_SERVICE) as KeyguardManager

keyguardManager.requestDismissKeyguard(
    this,
    object : KeyguardDismissCallback() {

    override fun onDismissError() {
        // Unlock failed. Dismissing keyguard is not feasible.
    }

    override fun onDismissSucceeded() {
        // Unlock succeeded. Device is now unlocked.
    }

    override fun onDismissCancelled() {
        // Unlock failed. User cancelled operation or request otherwise cancelled.
    }
})

Java

KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);

boolean isLocked = keyguardManager.isKeyguardLocked();

keyguardManager.requestDismissKeyguard(
    this,
    new KeyguardManager.KeyguardDismissCallback() {

  @Override
  public void onDismissError() {
      // Unlock failed. Dismissing keyguard is not feasible.
  }

  @Override
  public void onDismissSucceeded() {
      // Unlock succeeded. Device is now unlocked.
  }

  @Override
  public void onDismissCancelled() {
      // Unlock failed. User cancelled operation or request otherwise cancelled.
  }
});

نوافذ عائمة

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

يجب أن يتوافق تطبيقك مع الوضع multi-instance ليتمكّن المستخدمون من إنشاء ملاحظات متعدّدة في نوافذ عائمة متعدّدة حتى عندما يكون تطبيق تدوين الملاحظات مفعلاً في وضع ملء الشاشة أو في وضع تقسيم الشاشة.

تسجيل المحتوى

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

يجب أن يوفر تطبيق تدوين الملاحظات واجهة مستخدم يؤدي إلى تشغيل ActivityResultLauncher من إنشاء registerForActivityResult(). يتم تقديم إجراء الغرض من ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE إلى مشغِّل التطبيقات إما بشكلٍ مباشر أو من خلال ActivityResultContract.

يلتقط نشاط النظام المحتوى ويحفظه على الجهاز ويعرض معرّف الموارد المنتظم (URI) للمحتوى إلى تطبيقك في وسيطة رد الاتصال في registerForActivityResult().

يستخدم المثال التالي عقد StartActivityForResult عام:

Kotlin

private val startForResult = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()) {
        result: ActivityResult ->
            if (result.resultCode == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
                val uri = result.data?.data
                // Use the URI to paste the captured content into the note.
            }
    }

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        NotesTheme {
            Surface(color = MaterialTheme.colorScheme.background) {
                CaptureButton(
                    onClick = {
                        Log.i("ContentCapture", "Launching intent...")
                        startForResult.launch(Intent(ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE))
                    })
            }
        }
    }
}

@Composable
fun CaptureButton(onClick: () -> Unit) {
    Button(onClick = onClick)
    {Text("Capture Content")}
}

Java

private final ActivityResultLauncher<Intent> startForResult = registerForActivityResult(
    new ActivityResultContracts.StartActivityForResult(),
    result -> {
        if (result.getResultCode() == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
            Uri uri = result.getData() != null ? result.getData().getData() : null;
            // Use the URI to paste the captured content into the note.
        }
    });

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button captureButton = findViewById(R.id.capture_button);

    captureButton.setOnClickListener(
        view -> {
            Log.i("ContentCapture", "Launching intent...");
            startForResult.launch(new Intent(ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE));
        });
}

يجب أن يتعامل تطبيقك مع جميع رموز النتائج:

عندما يتم التقاط المحتوى بنجاح، الصق الصورة التي تم التقاطها في الملاحظة، على سبيل المثال:

Kotlin

registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
    result: ActivityResult ->
        if (result.resultCode == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
            val uri = result.data?data
            // Use the URI to paste the captured content into the note.
        }
}

Java

registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
    result -> {
        if (result.getResultCode() == Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
            Uri uri = result.getData() != null ? result.getData().getData() : null;
            // Use the URI to paste the captured content into the note.
        }
    });

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

لتحديد ما إذا كان تطبيقك في نافذة عائمة (أو فقاعة تفسيرية)، عليك استدعاء الطرق التالية:

  • isLaunchedFromBubble() للتأكّد من أنّ تطبيق تدوين الملاحظات لم يتم تشغيله في وضع ملء الشاشة من شاشة قفل الجهاز
  • isRoleHeld(RoleManager.ROLE_NOTES) للتحقّق من أنّ تطبيقك هو تطبيق تدوين الملاحظات التلقائي (يمكن تشغيل تطبيقك في محادثة أو في أي نوع آخر من فقاعات المحادثات إذا لم يكن التطبيق لديه دور الملاحظات)

مراجع إضافية