النوايا الشائعة

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

عند استدعاء startActivity() أو startActivityForResult() وتمرير نية ضمنية، يحلّ النظام النية إلى تطبيق يمكنه التعامل مع النية ويبدأ Activity المقابل له. إذا كان هناك أكثر من تطبيق واحد يمكنه معالجة الطلب، يعرض النظام للمستخدم مربّع حوار لاختيار التطبيق الذي يريد استخدامه.

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

تنبيه: في حال عدم توفّر تطبيقات على الجهاز يمكنها تلقّي نية ضمنية، يتعطّل التطبيق عند استدعاء startActivity(). للتحقّق أولاً من توفّر تطبيق لتلقّي الطلب، يمكنك استدعاء resolveActivity() على عنصر Intent. إذا كانت النتيجة غير فارغة، يعني ذلك أنّ هناك تطبيقًا واحدًا على الأقل يمكنه معالجة الطلب، ومن الآمن استدعاء startActivity(). إذا كانت النتيجة فارغة، لا تستخدِم الغرض، وأوقِف الميزة التي تستدعي الغرض إن أمكن.

إذا لم تكن على دراية بكيفية إنشاء intent أو intent filter، يُرجى أولاً قراءة intent وintent filter.

لمعرفة كيفية تفعيل الأهداف المدرَجة في هذه الصفحة من مضيف التطوير، يُرجى الاطّلاع على قسم التحقّق من الأهداف باستخدام Android Debug Bridge.

الإجراءات الصوتية من Google

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

منبّه

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

إنشاء منبّه

الإجراءات الصوتية من Google

  • "ضبط منبّه الساعة 7 صباحًا"

لإنشاء منبّه جديد، استخدِم الإجراء ACTION_SET_ALARM وحدِّد تفاصيل المنبّه، مثل الوقت والرسالة، باستخدام الإضافات التالية.

ملاحظة: لا تتوفّر سوى الساعة والدقائق والرسائل الإضافية في الإصدار 2.3 من Android (مستوى واجهة برمجة التطبيقات 9) والإصدارات الأقدم. تتوفر الإضافات الأخرى في الإصدارات الأعلى من المنصة.

الإجراء
ACTION_SET_ALARM
معرّف الموارد المنتظم (URI) للبيانات
None
نوع MIME
بدون إشعارات
ميزات إضافية
EXTRA_HOUR
‫
ساعة المنبّه
EXTRA_MINUTES
دقائق المنبّه
EXTRA_MESSAGE
رسالة مخصّصة لتحديد المنبّه
EXTRA_DAYS
‫ArrayList يتضمّن كل يوم من أيام الأسبوع التي يتكرّر فيها هذا المنبّه. يجب تحديد كل يوم باستخدام عدد صحيح من الفئة Calendar، مثل MONDAY.

لضبط منبّه لمرة واحدة، لا تحدّد هذه الإضافة.

EXTRA_RINGTONE
معرّف موارد منتظم (URI) من النوع content: يحدّد نغمة رنين لاستخدامها مع المنبّه، أو VALUE_RINGTONE_SILENT لعدم استخدام نغمة رنين.

لاستخدام نغمة الرنين التلقائية، لا تحدِّد هذه الإضافة.

EXTRA_VIBRATE
قيمة منطقية تحدّد ما إذا كان يجب تفعيل الاهتزاز لهذا المنبّه.
EXTRA_SKIP_UI
قيمة منطقية تحدّد ما إذا كان على التطبيق المستجيب تخطّي واجهة المستخدم عند ضبط المنبّه. إذا كانت القيمة "صحيح"، يجب أن يتجاوز التطبيق أي واجهة مستخدم للتأكيد ويضبط المنبّه المحدّد.

مثال على نية الشراء:

Kotlin

fun createAlarm(message: String, hour: Int, minutes: Int) {
    val intent = Intent(AlarmClock.ACTION_SET_ALARM).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_HOUR, hour)
        putExtra(AlarmClock.EXTRA_MINUTES, minutes)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void createAlarm(String message, int hour, int minutes) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_HOUR, hour)
            .putExtra(AlarmClock.EXTRA_MINUTES, minutes);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
ملاحظة:

لاستدعاء الغرض ACTION_SET_ALARM، يجب أن يتضمّن تطبيقك الإذن SET_ALARM:

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_ALARM" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

إنشاء موقّت

الإجراءات الصوتية من Google

  • "ضبط موقّت لمدة 5 دقائق"

لإنشاء موقّت عد تنازلي، استخدِم الإجراء ACTION_SET_TIMER وحدِّد تفاصيل الموقّت، مثل المدة، باستخدام الإضافات التالية.

ملاحظة: يتوفّر هذا الغرض في الإصدار Android 4.4 (المستوى 19 من واجهة برمجة التطبيقات) والإصدارات الأحدث.

الإجراء
ACTION_SET_TIMER
معرّف الموارد المنتظم (URI) للبيانات
None
نوع MIME
بدون إشعارات
ميزات إضافية
EXTRA_LENGTH
تمثّل هذه السمة مدة الموقّت بالثواني.
EXTRA_MESSAGE
رسالة مخصّصة لتحديد الموقّت
EXTRA_SKIP_UI
قيمة منطقية تحدّد ما إذا كان على التطبيق المستجيب تخطّي واجهة المستخدم عند ضبط الموقّت. إذا كانت القيمة "صحيح"، يجب أن يتجاوز التطبيق أي واجهة مستخدم للتأكيد ويبدأ الموقّت المحدّد.

مثال على نية الشراء:

Kotlin

fun startTimer(message: String, seconds: Int) {
    val intent = Intent(AlarmClock.ACTION_SET_TIMER).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_LENGTH, seconds)
        putExtra(AlarmClock.EXTRA_SKIP_UI, true)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void startTimer(String message, int seconds) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
            .putExtra(AlarmClock.EXTRA_SKIP_UI, true);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
ملاحظة:

لاستدعاء الغرض ACTION_SET_TIMER، يجب أن يتضمّن تطبيقك الإذن SET_ALARM:

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_TIMER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

إظهار جميع المنبهات

لعرض قائمة المنبّهات، استخدِم الإجراء ACTION_SHOW_ALARMS.

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

ملاحظة: يتوفّر هذا الغرض في الإصدار Android 4.4 (المستوى 19 من واجهة برمجة التطبيقات) والإصدارات الأحدث.

الإجراء
ACTION_SHOW_ALARMS
معرّف الموارد المنتظم (URI) للبيانات
None
نوع MIME
بدون إشعارات

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SHOW_ALARMS" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

التقويم

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

إضافة حدث في التقويم

لإضافة حدث جديد إلى تقويم المستخدم، استخدِم الإجراء ACTION_INSERT وحدِّد معرّف الموارد المنتظم (URI) للبيانات باستخدام Events.CONTENT_URI. يمكنك بعد ذلك تحديد تفاصيل الحدث المختلفة باستخدام الإضافات التالية.

الإجراء
ACTION_INSERT
معرّف الموارد المنتظم (URI) للبيانات
Events.CONTENT_URI
نوع MIME
"vnd.android.cursor.dir/event"
ميزات إضافية
EXTRA_EVENT_ALL_DAY
قيمة منطقية تحدّد ما إذا كان هذا الحدث يستمر طوال اليوم.
EXTRA_EVENT_BEGIN_TIME
وقت بدء الحدث (بالملي ثانية منذ بدء الحقبة)
EXTRA_EVENT_END_TIME
وقت انتهاء الحدث (بالملي ثانية منذ بدء حقبة يونكس)
TITLE
عنوان الحدث
DESCRIPTION
وصف الحدث
EVENT_LOCATION
الموقع الجغرافي للحدث
EXTRA_EMAIL
قائمة قيم مفصولة بفاصلة بعناوين البريد الإلكتروني التي تحدّد المدعوين.

يمكن تحديد المزيد من تفاصيل الأحداث باستخدام الثوابت المحدّدة في الفئة CalendarContract.EventsColumns.

مثال على نية الشراء:

Kotlin

fun addEvent(title: String, location: String, begin: Long, end: Long) {
    val intent = Intent(Intent.ACTION_INSERT).apply {
        data = Events.CONTENT_URI
        putExtra(Events.TITLE, title)
        putExtra(Events.EVENT_LOCATION, location)
        putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
        putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void addEvent(String title, String location, long begin, long end) {
    Intent intent = new Intent(Intent.ACTION_INSERT)
            .setData(Events.CONTENT_URI)
            .putExtra(Events.TITLE, title)
            .putExtra(Events.EVENT_LOCATION, location)
            .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
            .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.INSERT" />
        <data android:mimeType="vnd.android.cursor.dir/event" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

الكاميرا

في ما يلي الإجراءات الشائعة لتطبيقات الكاميرا، بما في ذلك المعلومات التي تحتاجها لإنشاء intent filter للإعلان عن قدرة تطبيقك على تنفيذ كل إجراء.

التقاط صورة أو فيديو وإرجاعهما

لفتح تطبيق كاميرا والحصول على الصورة أو الفيديو الناتجَين، استخدِم الإجراء ACTION_IMAGE_CAPTURE أو ACTION_VIDEO_CAPTURE. يجب أيضًا تحديد موقع معرّف الموارد المنتظم (URI) الذي تريد أن تحفظ الكاميرا الصورة أو الفيديو فيه، وذلك في الإضافة EXTRA_OUTPUT.

الإجراء
ACTION_IMAGE_CAPTURE أو
ACTION_VIDEO_CAPTURE
مخطّط URI للبيانات
None
نوع MIME
None
ميزات إضافية
EXTRA_OUTPUT
موقع معرّف الموارد المنتظم (URI) الذي يحفظ فيه تطبيق الكاميرا ملف الصورة أو الفيديو (كعنصر Uri).

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

ملاحظة: عند استخدام ACTION_IMAGE_CAPTURE لالتقاط صورة، قد تعرض الكاميرا أيضًا نسخة مصغّرة من الصورة في النتيجة Intent، ويتم حفظها كـ Bitmap في حقل إضافي باسم "data".

مثال على نية الشراء:

Kotlin

const val REQUEST_IMAGE_CAPTURE = 1
val locationForPhotos: Uri = ...

fun capturePhoto(targetFilename: String) {
    val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
        putExtra(MediaStore.EXTRA_OUTPUT, Uri.withAppendedPath(locationForPhotos, targetFilename))
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
        val thumbnail: Bitmap = data.getParcelableExtra("data")
        // Do other work with full size photo saved in locationForPhotos.
        ...
    }
}

Java

static final int REQUEST_IMAGE_CAPTURE = 1;
static final Uri locationForPhotos;

public void capturePhoto(String targetFilename) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.withAppendedPath(locationForPhotos, targetFilename));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelableExtra("data");
        // Do other work with full size photo saved in locationForPhotos.
        ...
    }
}

لإجراء ذلك عند العمل على الإصدار 12 من نظام التشغيل Android (المستوى 31 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، يُرجى الرجوع إلى مثال intent التالي.

مثال على نية الشراء:

Kotlin

val REQUEST_IMAGE_CAPTURE = 1

private fun dispatchTakePictureIntent() {
    val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
    } catch (e: ActivityNotFoundException) {
        // Display error state to the user.
    }
}

Java

static final int REQUEST_IMAGE_CAPTURE = 1;

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    } catch (ActivityNotFoundException e) {
        // Display error state to the user.
    }
}
</section></div>

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

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.IMAGE_CAPTURE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

عند التعامل مع هذا الغرض، اجعل نشاطك يتحقق من الإضافة EXTRA_OUTPUT في Intent الوارد، ثم احفظ الصورة أو الفيديو الملتقط في الموقع المحدد بواسطة تلك الإضافة واستدعِ setResult() باستخدام Intent يتضمن صورة مصغرة مضغوطة في إضافة باسم "data".

بدء تشغيل تطبيق الكاميرا في وضع الصورة الثابتة

الإجراءات الصوتية من Google

  • "التقاط صورة"

لفتح تطبيق كاميرا في وضع الصورة الثابتة، استخدِم الإجراء INTENT_ACTION_STILL_IMAGE_CAMERA.

الإجراء
INTENT_ACTION_STILL_IMAGE_CAMERA
مخطّط URI للبيانات
None
نوع MIME
None
ميزات إضافية
بدون إشعارات

مثال على نية الشراء:

Kotlin

private fun dispatchTakePictureIntent() {
    val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
    } catch (e: ActivityNotFoundException) {
        // Display error state to the user.
    }
}

Java

public void capturePhoto(String targetFilename) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.withAppendedPath(locationForPhotos, targetFilename));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.STILL_IMAGE_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

افتح تطبيق الكاميرا في وضع الفيديو

الإجراءات الصوتية من Google

  • "تسجيل فيديو"

لفتح تطبيق كاميرا في وضع الفيديو، استخدِم الإجراء INTENT_ACTION_VIDEO_CAMERA.

الإجراء
INTENT_ACTION_VIDEO_CAMERA
مخطّط URI للبيانات
None
نوع MIME
None
ميزات إضافية
بدون إشعارات

مثال على نية الشراء:

Kotlin

fun capturePhoto() {
    val intent = Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA)
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
    }
}

Java

public void capturePhoto() {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.VIDEO_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

تطبيق جهات الاتصال/الأشخاص

في ما يلي الإجراءات الشائعة لتطبيقات إدارة جهات الاتصال، بما في ذلك المعلومات التي تحتاجها لإنشاء intent filter للإعلان عن قدرة تطبيقك على تنفيذ كل إجراء.

اختيار جهة اتصال

للسماح للمستخدم باختيار جهة اتصال ومنح تطبيقك إذن الوصول إلى جميع معلومات جهة الاتصال، استخدِم الإجراء ACTION_PICK وحدِّد نوع MIME على أنّه Contacts.CONTENT_TYPE.

تحتوي النتيجة Intent التي تم إرسالها إلى دالة الاستدعاء onActivityResult() على معرّف الموارد المنتظم (URI) content: الذي يشير إلى جهة الاتصال المحدّدة. يمنح الردّ تطبيقك أذونات مؤقتة لقراءة جهة الاتصال هذه باستخدام واجهة برمجة التطبيقات مقدِّم جهات الاتصال، حتى إذا لم يتضمّن تطبيقك الإذن READ_CONTACTS.

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

الإجراء
ACTION_PICK
مخطّط URI للبيانات
None
نوع MIME
Contacts.CONTENT_TYPE

مثال على نية الشراء:

Kotlin

const val REQUEST_SELECT_CONTACT = 1

fun selectContact() {
    val intent = Intent(Intent.ACTION_PICK).apply {
        type = ContactsContract.Contacts.CONTENT_TYPE
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_SELECT_CONTACT)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
        val contactUri: Uri = data.data
        // Do something with the selected contact at contactUri.
        //...
    }
}

Java

static final int REQUEST_SELECT_CONTACT = 1;

public void selectContact() {
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_CONTACT);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
        Uri contactUri = data.getData();
        // Do something with the selected contact at contactUri.
        ...
    }
}

للحصول على معلومات حول كيفية استرداد تفاصيل الاتصال بعد الحصول على معرّف الموارد المنتظم (URI) لجهة الاتصال، يُرجى الاطّلاع على استرداد تفاصيل جهة اتصال.

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

اختيار بيانات جهات اتصال معيّنة

للسماح للمستخدم باختيار معلومة معيّنة من جهة اتصال، مثل رقم هاتف أو عنوان بريد إلكتروني أو نوع بيانات آخر، استخدِم الإجراء ACTION_PICK وحدِّد نوع MIME لأحد أنواع المحتوى التالية، مثل CommonDataKinds.Phone.CONTENT_TYPE للحصول على رقم هاتف جهة الاتصال.

ملاحظة: في كثير من الحالات، يحتاج تطبيقك إلى الحصول على إذن READ_CONTACTS لعرض معلومات محدّدة عن جهة اتصال معيّنة.

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

تحتوي النتيجة Intent التي تم تسليمها إلى دالة الاستدعاء onActivityResult() على معرّف الموارد المنتظم (URI) content: الذي يشير إلى بيانات جهة الاتصال المحدّدة. يمنح الردّ تطبيقك أذونات مؤقتة لقراءة بيانات جهة الاتصال هذه حتى إذا لم يتضمّن تطبيقك إذن READ_CONTACTS.

الإجراء
ACTION_PICK
مخطّط URI للبيانات
None
نوع MIME
CommonDataKinds.Phone.CONTENT_TYPE
اختَر من جهات الاتصال التي لديها رقم هاتف.
CommonDataKinds.Email.CONTENT_TYPE
اختَر من جهات الاتصال التي لديها عنوان بريد إلكتروني.
CommonDataKinds.StructuredPostal.CONTENT_TYPE
اختَر من جهات الاتصال التي لها عنوان بريدي.

أو إحدى قيم CONTENT_TYPE الأخرى العديدة ضمن ContactsContract.

مثال على نية الشراء:

Kotlin

const val REQUEST_SELECT_PHONE_NUMBER = 1

fun selectContact() {
    // Start an activity for the user to pick a phone number from contacts.
    val intent = Intent(Intent.ACTION_PICK).apply {
        type = CommonDataKinds.Phone.CONTENT_TYPE
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == Activity.RESULT_OK) {
        // Get the URI and query the content provider for the phone number.
        val contactUri: Uri = data.data
        val projection: Array<String> = arrayOf(CommonDataKinds.Phone.NUMBER)
        contentResolver.query(contactUri, projection, null, null, null).use { cursor ->
            // If the cursor returned is valid, get the phone number.
            if (cursor.moveToFirst()) {
                val numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER)
                val number = cursor.getString(numberIndex)
                // Do something with the phone number.
                ...
            }
        }
    }
}

Java

static final int REQUEST_SELECT_PHONE_NUMBER = 1;

public void selectContact() {
    // Start an activity for the user to pick a phone number from contacts.
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(CommonDataKinds.Phone.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == RESULT_OK) {
        // Get the URI and query the content provider for the phone number.
        Uri contactUri = data.getData();
        String[] projection = new String[]{CommonDataKinds.Phone.NUMBER};
        Cursor cursor = getContentResolver().query(contactUri, projection,
                null, null, null);
        // If the cursor returned is valid, get the phone number.
        if (cursor != null && cursor.moveToFirst()) {
            int numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER);
            String number = cursor.getString(numberIndex);
            // Do something with the phone number.
            //...
        }
    }
}

عرض جهة اتصال

لعرض تفاصيل جهة اتصال معروفة، استخدِم الإجراء ACTION_VIEW وحدِّد جهة الاتصال باستخدام معرّف موارد منتظم (URI) من النوع content: كبيانات الغرض.

هناك طريقتان أساسيتان لاسترداد معرّف الموارد المنتظم (URI) لجهة الاتصال في البداية:

  • استخدِم معرّف الموارد المنتظم (URI) لجهة الاتصال الذي يعرضه الإجراء ACTION_PICK الموضّح في القسم السابق. لا تتطلّب هذه الطريقة أي أذونات للتطبيق.
  • الوصول إلى قائمة جميع جهات الاتصال مباشرةً، كما هو موضّح في استرداد قائمة جهات الاتصال يتطلّب هذا النهج الحصول على إذن READ_CONTACTS.
الإجراء
ACTION_VIEW
مخطّط URI للبيانات
content:<URI>
نوع MIME
ما مِن صورة فائزة: يتم استنتاج النوع من معرّف الموارد المنتظم (URI) لجهة الاتصال.

مثال على نية الشراء:

Kotlin

fun viewContact(contactUri: Uri) {
    val intent = Intent(Intent.ACTION_VIEW, contactUri)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void viewContact(Uri contactUri) {
    Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

تعديل جهة اتصال حالية

لتعديل جهة اتصال معروفة، استخدِم الإجراء ACTION_EDIT، وحدِّد جهة الاتصال باستخدام معرّف الموارد المنتظم (URI) content: كبيانات الغرض، وأدرِج أي معلومات اتصال معروفة في الإضافات المحدّدة بواسطة الثوابت في ContactsContract.Intents.Insert.

هناك طريقتان أساسيتان لاسترداد معرّف الموارد المنتظم (URI) لجهة الاتصال في البداية:

  • استخدِم معرّف الموارد المنتظم (URI) لجهة الاتصال الذي يعرضه الإجراء ACTION_PICK الموضّح في القسم السابق. لا تتطلّب هذه الطريقة أي أذونات للتطبيق.
  • الوصول إلى قائمة جميع جهات الاتصال مباشرةً، كما هو موضّح في استرداد قائمة جهات الاتصال يتطلّب هذا النهج الحصول على إذن READ_CONTACTS.
الإجراء
ACTION_EDIT
مخطّط URI للبيانات
content:<URI>
نوع MIME
يتم استنتاج النوع من معرّف الموارد المنتظم (URI) لجهة الاتصال.
ميزات إضافية
عنصر إضافي واحد أو أكثر من العناصر المحدّدة في ContactsContract.Intents.Insert لتتمكّن من ملء حقول تفاصيل الاتصال.

مثال على نية الشراء:

Kotlin

fun editContact(contactUri: Uri, email: String) {
    val intent = Intent(Intent.ACTION_EDIT).apply {
        data = contactUri
        putExtra(ContactsContract.Intents.Insert.EMAIL, email)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void editContact(Uri contactUri, String email) {
    Intent intent = new Intent(Intent.ACTION_EDIT);
    intent.setData(contactUri);
    intent.putExtra(Intents.Insert.EMAIL, email);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

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

إدراج جهة اتصال

لإدراج جهة اتصال جديدة، استخدِم الإجراء ACTION_INSERT، وحدِّد Contacts.CONTENT_TYPE كنوع MIME، وأدرِج أي معلومات اتصال معروفة في الإضافات المحدّدة بواسطة الثوابت في ContactsContract.Intents.Insert.

الإجراء
ACTION_INSERT
مخطّط URI للبيانات
None
نوع MIME
Contacts.CONTENT_TYPE
ميزات إضافية
سمة إضافية واحدة أو أكثر من السمات المحدّدة في ContactsContract.Intents.Insert.

مثال على نية الشراء:

Kotlin

fun insertContact(name: String, email: String) {
    val intent = Intent(Intent.ACTION_INSERT).apply {
        type = ContactsContract.Contacts.CONTENT_TYPE
        putExtra(ContactsContract.Intents.Insert.NAME, name)
        putExtra(ContactsContract.Intents.Insert.EMAIL, email)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void insertContact(String name, String email) {
    Intent intent = new Intent(Intent.ACTION_INSERT);
    intent.setType(Contacts.CONTENT_TYPE);
    intent.putExtra(Intents.Insert.NAME, name);
    intent.putExtra(Intents.Insert.EMAIL, email);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

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

البريد الإلكتروني

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

إنشاء رسالة إلكترونية تتضمّن مرفقات اختيارية

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

الإجراء
ACTION_SENDTO (في حال عدم وجود مرفقات) أو
ACTION_SEND (في حال وجود مرفق واحد) أو
ACTION_SEND_MULTIPLE (في حال وجود مرفقات متعددة)
مخطّط URI للبيانات
None
نوع MIME
"text/plain"
"*/*"
ميزات إضافية
Intent.EXTRA_EMAIL
مصفوفة سلاسل نصية لجميع عناوين البريد الإلكتروني للمستلِمين في حقل "إلى".
Intent.EXTRA_CC
‫
مصفوفة سلاسل نصية لجميع عناوين البريد الإلكتروني للمستلِمين في حقل "نسخة إلى".
Intent.EXTRA_BCC
‫
مصفوفة سلاسل نصية لجميع عناوين البريد الإلكتروني للمستلِمين في حقل "نسخة مخفية الوجهة".
Intent.EXTRA_SUBJECT
سلسلة تحتوي على موضوع الرسالة الإلكترونية
Intent.EXTRA_TEXT
سلسلة تحتوي على نص الرسالة الإلكترونية
Intent.EXTRA_STREAM
‫Uri يشير إلى المرفق. في حال استخدام الإجراء ACTION_SEND_MULTIPLE، يكون هذا العنصر بدلاً من ذلك عبارة عن ArrayList يحتوي على عناصر Uri متعددة.

مثال على نية الشراء:

Kotlin

fun composeEmail(addresses: Array<String>, subject: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SEND).apply {
        type = "*/*"
        putExtra(Intent.EXTRA_EMAIL, addresses)
        putExtra(Intent.EXTRA_SUBJECT, subject)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void composeEmail(String[] addresses, String subject, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("*/*");
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

إذا أردت التأكّد من أنّ تطبيق البريد الإلكتروني فقط هو الذي سيتعامل مع نيتك، وليس تطبيقًا اجتماعيًا أو تطبيقًا للرسائل النصية، استخدِم الإجراء ACTION_SENDTO وأدرِج مخطط البيانات "mailto:" كما هو موضّح في المثال التالي:

Kotlin

fun composeEmail(addresses: Array<String>, subject: String) {
    val intent = Intent(Intent.ACTION_SENDTO).apply {
        data = Uri.parse("mailto:") // Only email apps handle this.
        putExtra(Intent.EXTRA_EMAIL, addresses)
        putExtra(Intent.EXTRA_SUBJECT, subject)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // Only email apps handle this.
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="*/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SENDTO" />
        <data android:scheme="mailto" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

وحدة تخزين الملفات

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

استرداد نوع معيّن من الملفات

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

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

يتضمّن هدف النتيجة الذي تم تسليمه إلى طريقة onActivityResult() بيانات مع معرّف موارد منتظم (URI) يشير إلى الملف. يمكن أن يكون معرّف الموارد المنتظم (URI) أي شيء، مثل معرّف موارد منتظم (URI) لـ http: أو معرّف موارد منتظم (URI) لـ file: أو معرّف موارد منتظم (URI) لـ content:. ومع ذلك، إذا أردت حصر الملفات القابلة للاختيار على تلك التي يمكن الوصول إليها من أداة توفير المحتوى (معرّف موارد منتظم content:) والمتاحة كملف بث باستخدام openFileDescriptor()، أضِف الفئة CATEGORY_OPENABLE إلى نيتك.

على نظام التشغيل Android 4.3 (مستوى واجهة برمجة التطبيقات 18) والإصدارات الأحدث، يمكنك أيضًا السماح للمستخدم باختيار ملفات متعددة عن طريق إضافة EXTRA_ALLOW_MULTIPLE إلى الغرض، وضبطه على true. يمكنك بعد ذلك الوصول إلى كل ملف من الملفات المحدّدة في كائن ClipData الذي تعرضه الدالة getClipData().

الإجراء
ACTION_GET_CONTENT
مخطّط URI للبيانات
None
نوع MIME
نوع MIME الذي يتوافق مع نوع الملف الذي يحتاج المستخدم إلى اختياره.
ميزات إضافية
EXTRA_ALLOW_MULTIPLE
قيمة منطقية تحدّد ما إذا كان بإمكان المستخدم اختيار أكثر من ملف واحد في كل مرة.
EXTRA_LOCAL_ONLY
قيمة منطقية تحدّد ما إذا كان يجب أن يكون الملف الذي تم عرضه متاحًا مباشرةً من الجهاز، بدلاً من طلب تنزيله من خدمة عن بُعد.
Category (اختيارية)
CATEGORY_OPENABLE
لعرض الملفات "القابلة للفتح" فقط والتي يمكن تمثيلها كملف بيانات باستخدام openFileDescriptor().

مثال على طلب الحصول على صورة:

Kotlin

const val REQUEST_IMAGE_GET = 1

fun selectImage() {
    val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
        type = "image/*"
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == Activity.RESULT_OK) {
        val thumbnail: Bitmap = data.getParcelableExtra("data")
        val fullPhotoUri: Uri = data.data
        // Do work with photo saved at fullPhotoUri.
        ...
    }
}

Java

static final int REQUEST_IMAGE_GET = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelable("data");
        Uri fullPhotoUri = data.getData();
        // Do work with photo saved at fullPhotoUri.
        ...
    }
}

مثال على فلتر intent لإرجاع صورة:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The OPENABLE category declares that the returned file is accessible
             from a content provider that supports OpenableColumns
             and ContentResolver.openFileDescriptor(). -->
        <category android:name="android.intent.category.OPENABLE" />
    </intent-filter>
</activity>

فتح نوع معيّن من الملفات

بدلاً من استرداد نسخة من ملف يجب استيراده إلى تطبيقك، باستخدام الإجراء ACTION_GET_CONTENT، عند التشغيل على Android 4.4 أو إصدار أحدث، يمكنك بدلاً من ذلك طلب فتح ملف يديره تطبيق آخر من خلال استخدام الإجراء ACTION_OPEN_DOCUMENT وتحديد نوع MIME. للسماح للمستخدم أيضًا بإنشاء مستند جديد يمكن لتطبيقك الكتابة فيه، استخدِم الإجراء ACTION_CREATE_DOCUMENT بدلاً من ذلك.

على سبيل المثال، بدلاً من اختيار مستندات PDF حالية، يتيح الغرض ACTION_CREATE_DOCUMENT للمستخدمين اختيار مكان إنشاء مستند جديد، مثل داخل تطبيق آخر يدير مساحة تخزين المستند. يتلقّى تطبيقك بعد ذلك موقع معرّف الموارد المنتظم (URI) حيث يمكنه كتابة المستند الجديد.

في حين أنّ الغرض الذي يتم تسليمه إلى طريقة onActivityResult() من الإجراء ACTION_GET_CONTENT قد يعرض معرّف موارد منتظم (URI) من أي نوع، فإنّ الغرض من النتيجة من ACTION_OPEN_DOCUMENT وACTION_CREATE_DOCUMENT يحدّد دائمًا الملف المختار على أنّه معرّف موارد منتظم (URI) content: مدعوم من DocumentsProvider. يمكنك فتح الملف باستخدام openFileDescriptor() والاستعلام عن تفاصيله باستخدام أعمدة من DocumentsContract.Document.

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

يمكنك أيضًا السماح للمستخدم باختيار ملفات متعددة من خلال إضافة EXTRA_ALLOW_MULTIPLE إلى الغرض، وضبطه على true. إذا اختار المستخدم عنصرًا واحدًا فقط، يمكنك استرداد العنصر من getData(). إذا اختار المستخدم أكثر من عنصر واحد، ستعرض الدالة getData() القيمة null، وعليك بدلاً من ذلك استرداد كل عنصر من كائن ClipData الذي تعرضه الدالة getClipData().

ملاحظة: يجب أن يحدّد intent نوع MIME ويجب أن يوضّح الفئة CATEGORY_OPENABLE. يمكنك تحديد أكثر من نوع MIME واحد إذا كان ذلك مناسبًا، وذلك من خلال إضافة مصفوفة من أنواع MIME باستخدام الإضافة EXTRA_MIME_TYPES. وفي هذه الحالة، يجب ضبط نوع MIME الأساسي في setType() على "*/*".

الإجراء
ACTION_OPEN_DOCUMENT أو
ACTION_CREATE_DOCUMENT
مخطّط URI للبيانات
None
نوع MIME
نوع MIME الذي يتوافق مع نوع الملف الذي يحتاج المستخدم إلى اختياره.
ميزات إضافية
EXTRA_MIME_TYPES
مصفوفة من أنواع MIME التي تتوافق مع أنواع الملفات التي يطلبها تطبيقك. عند استخدام هذه الإضافة، يجب ضبط نوع MIME الأساسي في setType() على "*/*".
EXTRA_ALLOW_MULTIPLE
قيمة منطقية تحدّد ما إذا كان بإمكان المستخدم اختيار أكثر من ملف واحد في كل مرة.
EXTRA_TITLE
يُستخدَم مع ACTION_CREATE_DOCUMENT لتحديد اسم ملف أوّلي.
EXTRA_LOCAL_ONLY
قيمة منطقية تحدّد ما إذا كان يجب أن يكون الملف الذي تم عرضه متاحًا مباشرةً من الجهاز، بدلاً من طلب تنزيله من خدمة عن بُعد.
Category (الفئة)
CATEGORY_OPENABLE
لعرض الملفات "القابلة للفتح" فقط والتي يمكن تمثيلها كملف بيانات باستخدام openFileDescriptor().

مثال على طلب الحصول على صورة:

Kotlin

const val REQUEST_IMAGE_OPEN = 1

fun selectImage2() {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
        type = "image/*"
        addCategory(Intent.CATEGORY_OPENABLE)
    }
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == Activity.RESULT_OK) {
        val fullPhotoUri: Uri = data.data
        // Do work with full size photo saved at fullPhotoUri.
        ...
    }
}

Java

static final int REQUEST_IMAGE_OPEN = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.setType("image/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
        Uri fullPhotoUri = data.getData();
        // Do work with full size photo saved at fullPhotoUri.
        ...
    }
}

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

لتوفير ملفات تطبيقك في واجهة المستخدم هذه والسماح للتطبيقات الأخرى بفتحها، عليك تنفيذ DocumentsProvider وتضمين intent filter لـ PROVIDER_INTERFACE ("android.content.action.DOCUMENTS_PROVIDER")، كما هو موضّح في المثال التالي:

<provider ...
    android:grantUriPermissions="true"
    android:exported="true"
    android:permission="android.permission.MANAGE_DOCUMENTS">
    <intent-filter>
        <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
    </intent-filter>
</provider>

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

الإجراءات المحلية

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

الاتصال بسيارة

الإجراءات الصوتية من Google

  • "أريد طلب سيارة أجرة"
  • "أريد طلب سيارة"

(على Wear OS فقط)

لطلب سيارة أجرة، استخدِم الإجراء ACTION_RESERVE_TAXI_RESERVATION.

ملاحظة: يجب أن تطلب التطبيقات تأكيدًا من المستخدم قبل إكمال هذا الإجراء.

الإجراء
ACTION_RESERVE_TAXI_RESERVATION
معرّف الموارد المنتظم (URI) للبيانات
None
نوع MIME
None
ميزات إضافية
بدون إشعارات

مثال على نية الشراء:

Kotlin

fun callCar() {
    val intent = Intent(ReserveIntents.ACTION_RESERVE_TAXI_RESERVATION)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void callCar() {
    Intent intent = new Intent(ReserveIntents.ACTION_RESERVE_TAXI_RESERVATION);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="com.google.android.gms.actions.RESERVE_TAXI_RESERVATION" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

خرائط

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

عرض موقع جغرافي على الخريطة

لفتح خريطة، استخدِم الإجراء ACTION_VIEW وحدِّد معلومات عن الموقع الجغرافي للجهاز في بيانات intent باستخدام أحد المخططات التالية.

الإجراء
ACTION_VIEW
مخطّط URI للبيانات
geo:latitude,longitude
عرض الخريطة عند خط الطول وخط العرض المحدّدَين

مثال: "geo:47.6,-122.3"

geo:latitude,longitude?z=zoom
عرض الخريطة عند خط الطول وخط العرض المحدّدَين بمستوى تكبير معيّن يعرض مستوى التكبير 1 الكرة الأرضية بأكملها، مع التركيز على خط العرض وخط الطول المحدَّدين. وأعلى مستوى تكبير (الأقرب) هو 23.

مثال: "geo:47.6,-122.3?z=11"

geo:0,0?q=lat,lng(label)
عرض الخريطة عند خط الطول وخط العرض المحدّدَين مع تصنيف نصي

مثال: "geo:0,0?q=34.99,-106.61(Treasure)"

geo:0,0?q=my+street+address
عرض الموقع الجغرافي لـ "عنوان الشارع"، والذي يمكن أن يكون عنوانًا محدّدًا أو طلب بحث عن موقع جغرافي

مثال: "geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA"

ملاحظة: يجب ترميز جميع السلاسل التي يتم تمريرها في معرّف الموارد المنتظم (URI) لـ geo. على سبيل المثال، تصبح السلسلة 1st & Pike, Seattle 1st%20%26%20Pike%2C%20Seattle. يتم ترميز المسافات في السلسلة باستخدام %20 أو استبدالها بعلامة الجمع (+).

نوع MIME
بدون إشعارات

مثال على نية الشراء:

Kotlin

fun showMap(geoLocation: Uri) {
    val intent = Intent(Intent.ACTION_VIEW).apply {
        data = geoLocation
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void showMap(Uri geoLocation) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(geoLocation);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="geo" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

موسيقى أو فيديو

في ما يلي الإجراءات الشائعة لتطبيقات الموسيقى والفيديو، بما في ذلك المعلومات التي تحتاجها لإنشاء intent filter للإعلان عن قدرة تطبيقك على تنفيذ كل إجراء.

تشغيل ملف وسائط

لتشغيل ملف موسيقى، استخدِم الإجراء ACTION_VIEW وحدِّد موقع معرّف الموارد المنتظم (URI) للملف في بيانات intent.

الإجراء
ACTION_VIEW
مخطّط URI للبيانات
file:<URI>
content:<URI>
http:<URL>
نوع MIME
"audio/*"
"application/ogg"
"application/x-ogg"
"application/itunes"
أو أي معلومات أخرى يتطلبها تطبيقك

مثال على نية الشراء:

Kotlin

fun playMedia(file: Uri) {
    val intent = Intent(Intent.ACTION_VIEW).apply {
        data = file
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void playMedia(Uri file) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(file);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:type="audio/*" />
        <data android:type="application/ogg" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

تشغيل موسيقى استنادًا إلى طلب بحث

الإجراءات الصوتية من Google

  • "تشغيل أغنية بيلي جين لمايكل جاكسون"

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

في هذا الغرض، يجب تضمين السلسلة الإضافية EXTRA_MEDIA_FOCUS التي تحدّد وضع البحث المطلوب. على سبيل المثال، يمكن أن يحدّد وضع البحث ما إذا كان البحث عن اسم فنّان أو اسم أغنية.

الإجراء
INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
مخطّط URI للبيانات
None
نوع MIME
None
ميزات إضافية
MediaStore.EXTRA_MEDIA_FOCUS (مطلوب)

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

أي - "vnd.android.cursor.item/*"

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

ميزات إضافية:

  • ‫QUERY (مطلوبة): سلسلة فارغة. يتم توفير هذه الإضافة دائمًا لضمان التوافق مع الأنظمة القديمة. يمكن للتطبيقات الحالية التي لا تتوافق مع أوضاع البحث معالجة هذا الطلب كبحث غير منظَّم.

غير منظَّمة - "vnd.android.cursor.item/*"

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

ميزات إضافية:

  • ‫QUERY (مطلوبة): سلسلة تحتوي على أي تركيبة من الفنان أو الألبوم أو اسم الأغنية أو النوع

النوع - Audio.Genres.ENTRY_CONTENT_TYPE

تشغيل موسيقى من نوع معيّن

ميزات إضافية:

  • ‫"android.intent.extra.genre" (مطلوبة): النوع
  • ‫QUERY (مطلوب): النوع يتم توفير هذه الإضافة دائمًا لضمان التوافق مع الأنظمة القديمة. يمكن للتطبيقات الحالية التي لا تعرف أوضاع البحث معالجة هذا الغرض كبحث غير منظَّم.

الفنان: Audio.Artists.ENTRY_CONTENT_TYPE

تشغيل موسيقى لفنان معيّن

ميزات إضافية:

  • ‫EXTRA_MEDIA_ARTIST (مطلوبة): الفنان
  • ‫"android.intent.extra.genre": النوع
  • ‫QUERY (مطلوبة): سلسلة تحتوي على أي تركيبة من الفنان أو النوع الموسيقي يتم توفير هذه الإضافة دائمًا للتوافق مع الأنظمة القديمة. ويمكن للتطبيقات الحالية التي لا تتعرّف على أوضاع البحث معالجة هذا الغرض كبحث غير منظَّم.

الألبوم: Audio.Albums.ENTRY_CONTENT_TYPE

تشغيل موسيقى من ألبوم معيّن

ميزات إضافية:

  • ‫EXTRA_MEDIA_ALBUM (مطلوبة): الألبوم
  • ‫EXTRA_MEDIA_ARTIST: الفنان
  • ‫"android.intent.extra.genre": النوع
  • ‫QUERY (مطلوبة): سلسلة تحتوي على أي تركيبة من الألبوم أو الفنان يتم توفير هذه الإضافة دائمًا للتوافق مع الأنظمة القديمة. ويمكن للتطبيقات الحالية التي لا تتيح أوضاع البحث معالجة هذا الغرض كبحث غير منظَّم.

أغنية - "vnd.android.cursor.item/audio"

تشغيل أغنية معيّنة

ميزات إضافية:

  • ‫EXTRA_MEDIA_ALBUM: الألبوم
  • ‫EXTRA_MEDIA_ARTIST: الفنان
  • ‫"android.intent.extra.genre": النوع
  • ‫EXTRA_MEDIA_TITLE (مطلوبة): اسم الأغنية
  • ‫QUERY (مطلوبة): سلسلة تحتوي على أي تركيبة من الألبوم أو الفنان أو النوع أو العنوان يتم توفير هذه الإضافة دائمًا لضمان التوافق مع الأنظمة القديمة. ويمكن للتطبيقات الحالية التي لا تتضمّن أوضاع البحث معالجة هذا الطلب كبحث غير منظَّم.

قائمة التشغيل - Audio.Playlists.ENTRY_CONTENT_TYPE

تشغيل قائمة تشغيل معيّنة أو قائمة تشغيل تطابق بعض المعايير المحدّدة من خلال إضافات أخرى

ميزات إضافية:

  • ‫EXTRA_MEDIA_ALBUM: الألبوم
  • ‫EXTRA_MEDIA_ARTIST: الفنان
  • ‫"android.intent.extra.genre": النوع
  • ‫"android.intent.extra.playlist": قائمة التشغيل
  • ‫EXTRA_MEDIA_TITLE: اسم الأغنية التي تستند إليها قائمة التشغيل
  • ‫QUERY (مطلوبة): سلسلة تحتوي على أي تركيبة من الألبوم أو الفنان أو النوع أو قائمة التشغيل أو العنوان يتم توفير هذه الإضافة دائمًا لضمان التوافق مع الأنظمة القديمة. يمكن للتطبيقات الحالية التي لا تتوافق مع أوضاع البحث معالجة هذا الطلب كبحث غير منظَّم.

مثال على نية الشراء:

إذا أراد المستخدم الاستماع إلى موسيقى من فنان معيّن، قد ينشئ تطبيق البحث الطلب التالي:

Kotlin

fun playSearchArtist(artist: String) {
    val intent = Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH).apply {
        putExtra(MediaStore.EXTRA_MEDIA_FOCUS, MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE)
        putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist)
        putExtra(SearchManager.QUERY, artist)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void playSearchArtist(String artist) {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH);
    intent.putExtra(MediaStore.EXTRA_MEDIA_FOCUS,
                    MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE);
    intent.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist);
    intent.putExtra(SearchManager.QUERY, artist);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

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

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    if (intent.action.compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) {

        val mediaFocus: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS)
        val query: String? = intent.getStringExtra(SearchManager.QUERY)

        // Some of these extras might not be available depending on the search mode.
        val album: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM)
        val artist: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST)
        val genre: String? = intent.getStringExtra("android.intent.extra.genre")
        val playlist: String? = intent.getStringExtra("android.intent.extra.playlist")
        val title: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE)

        // Determine the search mode and use the corresponding extras.
        when {
            mediaFocus == null -> {
                // 'Unstructured' search mode (backward compatible)
                playUnstructuredSearch(query)
            }
            mediaFocus.compareTo("vnd.android.cursor.item/*") == 0 -> {
                if (query?.isNotEmpty() == true) {
                    // 'Unstructured' search mode.
                    playUnstructuredSearch(query)
                } else {
                    // 'Any' search mode.
                    playResumeLastPlaylist()
                }
            }
            mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Genre' search mode.
                playGenre(genre)
            }
            mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Artist' search mode.
                playArtist(artist, genre)
            }
            mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Album' search mode.
                playAlbum(album, artist)
            }
            mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0 -> {
                // 'Song' search mode.
                playSong(album, artist, genre, title)
            }
            mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Playlist' search mode.
                playPlaylist(album, artist, genre, playlist, title)
            }
        }
    }
}

Java

protected void onCreate(Bundle savedInstanceState) {
    //...
    Intent intent = this.getIntent();
    if (intent.getAction().compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) {

        String mediaFocus = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS);
        String query = intent.getStringExtra(SearchManager.QUERY);

        // Some of these extras might not be available depending on the search mode.
        String album = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM);
        String artist = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST);
        String genre = intent.getStringExtra("android.intent.extra.genre");
        String playlist = intent.getStringExtra("android.intent.extra.playlist");
        String title = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE);

        // Determine the search mode and use the corresponding extras.
        if (mediaFocus == null) {
            // 'Unstructured' search mode (backward compatible).
            playUnstructuredSearch(query);

        } else if (mediaFocus.compareTo("vnd.android.cursor.item/*") == 0) {
            if (query.isEmpty()) {
                // 'Any' search mode.
                playResumeLastPlaylist();
            } else {
                // 'Unstructured' search mode.
                playUnstructuredSearch(query);
            }

        } else if (mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0) {
            // 'Genre' search mode.
            playGenre(genre);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0) {
            // 'Artist' search mode.
            playArtist(artist, genre);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0) {
            // 'Album' search mode.
            playAlbum(album, artist);

        } else if (mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0) {
            // 'Song' search mode.
            playSong(album, artist, genre, title);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0) {
            // 'Playlist' search mode.
            playPlaylist(album, artist, genre, playlist, title);
        }
    }
}

ملاحظة جديدة

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

إنشاء ملاحظة

لإنشاء ملاحظة جديدة، استخدِم الإجراء ACTION_CREATE_NOTE وحدِّد تفاصيل الملاحظة، مثل الموضوع والنص، باستخدام الإضافات التالية.

ملاحظة: يجب أن تطلب التطبيقات تأكيدًا من المستخدم قبل إكمال هذا الإجراء.

الإجراء
ACTION_CREATE_NOTE
مخطّط URI للبيانات
None
نوع MIME
PLAIN_TEXT_TYPE
"*/*"
ميزات إضافية
EXTRA_NAME
سلسلة تشير إلى عنوان الملاحظة أو موضوعها.
EXTRA_TEXT
سلسلة تشير إلى نص الملاحظة.

مثال على نية الشراء:

Kotlin

fun createNote(subject: String, text: String) {
    val intent = Intent(NoteIntents.ACTION_CREATE_NOTE).apply {
        putExtra(NoteIntents.EXTRA_NAME, subject)
        putExtra(NoteIntents.EXTRA_TEXT, text)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void createNote(String subject, String text) {
    Intent intent = new Intent(NoteIntents.ACTION_CREATE_NOTE)
            .putExtra(NoteIntents.EXTRA_NAME, subject)
            .putExtra(NoteIntents.EXTRA_TEXT, text);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="com.google.android.gms.actions.CREATE_NOTE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="*/*" />
    </intent-filter>
</activity>

الهاتف

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

بدء مكالمة هاتفية

لفتح تطبيق الهاتف والاتصال برقم هاتف، استخدِم الإجراء ACTION_DIAL وحدِّد رقم هاتف باستخدام مخطّط URI التالي. عند فتح تطبيق الهاتف، يعرض رقم الهاتف، وعلى المستخدم النقر على زر اتصال لبدء المكالمة الهاتفية.

الإجراءات الصوتية من Google

  • "الاتصال بالرقم 555-5555"
  • "الاتصال بـ بوب"
  • "الاتصال بالبريد الصوتي"

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

يتطلّب الإجراء ACTION_CALL إضافة الإذن CALL_PHONE إلى ملف البيان:

<uses-permission android:name="android.permission.CALL_PHONE" />
الإجراء
  • ‫ACTION_DIAL: لفتح برنامج الاتصال أو تطبيق الهاتف
  • ‫ACTION_CALL: لإجراء مكالمة هاتفية (يتطلّب إذن CALL_PHONE)
مخطّط URI للبيانات
  • tel:<phone-number>
  • voicemail:<phone-number>
نوع MIME
بدون إشعارات

أرقام الهواتف الصالحة هي تلك المحدّدة في IETF RFC 3966. تشمل الأمثلة الصالحة ما يلي:

  • tel:2125551212
  • tel:(212) 555 1212

يُعدّ برنامج الاتصال في تطبيق "الهاتف" جيدًا في تسوية المخططات، مثل أرقام الهواتف. لذلك، لا يُشترط استخدام المخطط الموضّح في طريقة Uri.parse(). ومع ذلك، إذا لم تكن قد جرّبت مخططًا أو لم تكن متأكدًا مما إذا كان يمكن التعامل معه، استخدِم طريقة Uri.fromParts() بدلاً من ذلك.

مثال على نية الشراء:

Kotlin

fun dialPhoneNumber(phoneNumber: String) {
    val intent = Intent(Intent.ACTION_DIAL).apply {
        data = Uri.parse("tel:$phoneNumber")
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void dialPhoneNumber(String phoneNumber) {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:" + phoneNumber));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

في ما يلي الإجراءات الشائعة لتطبيقات البحث، بما في ذلك المعلومات التي تحتاجها لإنشاء intent filter للإعلان عن قدرة تطبيقك على تنفيذ كل إجراء.

البحث باستخدام تطبيق معيّن

الإجراءات الصوتية من Google

  • "أريد البحث عن فيديوهات عن القطط على تطبيق myvideoapp"

لإتاحة البحث في سياق تطبيقك، عليك الإعلان عن intent filter في تطبيقك باستخدام الإجراء SEARCH_ACTION، كما هو موضّح في مثال intent filter التالي.

ملاحظة: لا ننصح باستخدام SEARCH_ACTION للبحث عن التطبيقات. بدلاً من ذلك، يمكنك تنفيذ الإجراء GET_THING للاستفادة من ميزة البحث داخل التطبيق المضمّنة في &quot;مساعد Google&quot;. لمزيد من المعلومات، يُرجى الاطّلاع على مستندات إجراءات التطبيقات في &quot;مساعد Google&quot;.

الإجراء
"com.google.android.gms.actions.SEARCH_ACTION"
يتيح التطبيق طلبات البحث من "الإجراءات الصوتية" في Google.
ميزات إضافية
QUERY
سلسلة تحتوي على طلب البحث

مثال على intent filter:

<activity android:name=".SearchActivity">
    <intent-filter>
        <action android:name="com.google.android.gms.actions.SEARCH_ACTION"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

إجراء بحث الويب

لبدء بحث الويب، استخدِم الإجراء ACTION_WEB_SEARCH وحدِّد سلسلة البحث في البيانات الإضافية SearchManager.QUERY.

الإجراء
ACTION_WEB_SEARCH
مخطّط URI للبيانات
None
نوع MIME
None
ميزات إضافية
SearchManager.QUERY
سلسلة البحث

مثال على نية الشراء:

Kotlin

fun searchWeb(query: String) {
    val intent = Intent(Intent.ACTION_WEB_SEARCH).apply {
        putExtra(SearchManager.QUERY, query)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void searchWeb(String query) {
    Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
    intent.putExtra(SearchManager.QUERY, query);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

الإعدادات

لفتح شاشة في تطبيق "الإعدادات" (Settings) الخاص بالنظام عندما يتطلّب تطبيقك من المستخدم تغيير إعداد معيّن، استخدِم أحد إجراءات الأهداف التالية:

الإجراء
ACTION_SETTINGS
ACTION_WIRELESS_SETTINGS
ACTION_AIRPLANE_MODE_SETTINGS
ACTION_WIFI_SETTINGS
ACTION_APN_SETTINGS
ACTION_BLUETOOTH_SETTINGS
ACTION_DATE_SETTINGS
ACTION_LOCALE_SETTINGS
ACTION_INPUT_METHOD_SETTINGS
ACTION_DISPLAY_SETTINGS
ACTION_SECURITY_SETTINGS
ACTION_LOCATION_SOURCE_SETTINGS
ACTION_INTERNAL_STORAGE_SETTINGS
ACTION_MEMORY_CARD_SETTINGS

للاطّلاع على شاشات الإعدادات الإضافية المتاحة، يُرجى مراجعة مستندات Settings .

مخطّط URI للبيانات
None
نوع MIME
بدون إشعارات

مثال على نية الشراء:

Kotlin

fun openWifiSettings() {
    val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void openWifiSettings() {
    Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

المراسلة النصية

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

إنشاء رسالة SMS أو رسالة وسائط متعددة مع مرفق

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

الإجراء
ACTION_SENDTO أو
ACTION_SEND أو
ACTION_SEND_MULTIPLE
مخطّط URI للبيانات
sms:<phone_number>
smsto:<phone_number>
mms:<phone_number>
mmsto:<phone_number>

ويتم التعامل مع هذه المخطَّطات بالطريقة نفسها.

نوع MIME
"text/plain"
"image/*"
"video/*"
ميزات إضافية
"subject"
سلسلة لموضوع الرسالة (عادةً لرسائل الوسائط المتعددة فقط)
"sms_body"
سلسلة للرسالة النصية.
EXTRA_STREAM
‫Uri يشير إلى الصورة أو الفيديو المطلوب إرفاقه. في حال استخدام الإجراء ACTION_SEND_MULTIPLE، تكون هذه الإضافة عبارة عن ArrayList من عناصر Uri تشير إلى الصور أو الفيديوهات المطلوب إرفاقها.

مثال على نية الشراء:

Kotlin

fun composeMmsMessage(message: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SENDTO).apply {
        type = HTTP.PLAIN_TEXT_TYPE
        putExtra("sms_body", message)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setType(HTTP.PLAIN_TEXT_TYPE);
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

إذا أردت التأكّد من أنّ تطبيق المراسلة النصية فقط هو الذي سيتعامل مع طلبك، وليس تطبيقات البريد الإلكتروني أو التطبيقات الاجتماعية الأخرى، استخدِم الإجراء ACTION_SENDTO وأدرِج مخطّط البيانات "smsto:" كما هو موضّح في المثال التالي:

Kotlin

fun composeMmsMessage(message: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SEND).apply {
        data = Uri.parse("smsto:")  // Only SMS apps respond to this.
        putExtra("sms_body", message)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setData(Uri.parse("smsto:"));  // Only SMS apps respond to this.
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="text/plain" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

ملاحظة: إذا كنت تطوّر تطبيقًا للمراسلة عبر SMS/MMS، عليك تنفيذ intent filters لعدة إجراءات إضافية لكي يكون التطبيق متاحًا كـ تطبيق SMS التلقائي على Android 4.4 والإصدارات الأحدث. لمزيد من المعلومات، يُرجى الاطّلاع على المستندات على الرابط Telephony.

متصفح ويب

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

تحميل عنوان URL للويب

الإجراءات الصوتية من Google

  • "فتح example.com"

لفتح صفحة ويب، استخدِم الإجراء ACTION_VIEW وحدِّد عنوان URL للويب في بيانات intent.

الإجراء
ACTION_VIEW
مخطّط URI للبيانات
http:<URL>
https:<URL>
نوع MIME
"text/plain"
"text/html"
"application/xhtml+xml"
"application/vnd.wap.xhtml+xml"

مثال على نية الشراء:

Kotlin

fun openWebPage(url: String) {
    val webpage: Uri = Uri.parse(url)
    val intent = Intent(Intent.ACTION_VIEW, webpage)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void openWebPage(String url) {
    Uri webpage = Uri.parse(url);
    Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

مثال على intent filter:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <!-- Include the host attribute if you want your app to respond
             only to URLs with your app's domain. -->
        <data android:scheme="http" android:host="www.example.com" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The BROWSABLE category is required to get links from web pages. -->
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>

ملاحظة: إذا كان تطبيق Android يوفّر وظائف مشابهة لموقعك الإلكتروني، يمكنك تضمين intent filter لعناوين URL التي تشير إلى موقعك الإلكتروني. بعد ذلك، إذا كان تطبيقك مثبّتًا لدى المستخدمين، ستفتح الروابط من الرسائل الإلكترونية أو صفحات الويب الأخرى التي تشير إلى موقعك الإلكتروني تطبيق Android بدلاً من صفحة الويب. مزيد من المعلومات في مقالة التعامل مع روابط Android App Links

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

التحقّق من الأهداف باستخدام Android Debug Bridge

للتحقّق من أنّ تطبيقك يستجيب للطلبات التي تريد إتاحتها، يمكنك استخدام أداة adb لتشغيل طلبات معيّنة من خلال اتّباع الخطوات التالية:

  1. إعداد جهاز Android من أجل التطوير أو استخدام جهاز افتراضي
  2. ثبِّت إصدارًا من تطبيقك يتعامل مع الأهداف التي تريد إتاحتها.
  3. يمكنك تفعيل intent باستخدام adb:
    adb shell am start -a <ACTION> -t <MIME_TYPE> -d <DATA> \
      -e <EXTRA_NAME> <EXTRA_VALUE> -n <ACTIVITY>
    

    على سبيل المثال:

    adb shell am start -a android.intent.action.DIAL \
      -d tel:555-5555 -n org.example.MyApp/.MyActivity
    
  4. إذا حدّدت فلاتر intent المطلوبة، يمكنك معالجة intent.

لمزيد من المعلومات، يُرجى الاطّلاع على إصدار أوامر واجهة الأوامر.