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

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

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

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

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

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

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

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

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

منبّه

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

إنشاء منبّه

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

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

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

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

الإجراء
ACTION_SET_ALARM
معرّف الموارد المنتظم للبيانات
لا شيء
نوع 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" />

مثال على فلتر الأهداف:

<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 وحدِّد تفاصيل المؤقت، مثل المدة، باستخدام الإضافات التالية.

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

الإجراء
ACTION_SET_TIMER
معرّف الموارد المنتظم للبيانات
لا شيء
نوع 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" />

مثال على فلتر الأهداف:

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

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

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

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

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

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

مثال على فلتر الأهداف:

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

التقويم

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

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

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

الإجراء
ACTION_INSERT
معرّف الموارد المنتظم للبيانات
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);
    }
}

مثال على فلتر الأهداف:

<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>

الكاميرا

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

التقاط صورة أو فيديو وعرضه

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

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

عندما يعيد تطبيق الكاميرا التركيز إلى نشاطك بنجاح، أي عندما يتلقّى تطبيقك عملية رد الاتصال onActivityResult()، يمكنك الوصول إلى الصورة أو الفيديو في معرّف الموارد الموحّد الذي حدّدته باستخدام القيمة 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 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، يُرجى الرجوع إلى مثال الغرض التالي.

مثال على النية:

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 مناسب للموقع الجغرافي الناتج، يُرجى قراءة التقاط صور أو تسجيل فيديوهات.

مثال على فلتر الأهداف:

<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) للبيانات
لا شيء
نوع MIME
لا شيء
الميزات الإضافية
لا شيء

مثال على النية:

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);
    }
}

مثال على فلتر الأهداف:

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

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

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

  • تسجيل فيديو ("record a video")

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

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

مثال على النية:

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);
    }
}

مثال على فلتر الأهداف:

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

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

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

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

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

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

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

الإجراء
ACTION_PICK
مخطط معرّف الموارد المنتظم (URI) للبيانات
لا شيء
نوع 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) الخاص بجهة الاتصال باستخدام هذا الغرض، لن تحتاج عادةً إلى إذن 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) للبيانات
لا شيء
نوع 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) للبيانات
لا شيء
نوع 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);
    }
}

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

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

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

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

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

الإجراء
ACTION_SENDTO (لعدم إرفاق أي ملف) أو
ACTION_SEND (لإرفاق ملف واحد) أو
ACTION_SEND_MULTIPLE (لإرفاق عدة ملفات)
مخطط معرّف الموارد المنتظم (URI) للبيانات
لا شيء
نوع 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);
    }
}

مثال على فلتر الأهداف:

<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 المطلوب. إنّ مرجع الملف الذي يتم إرجاعه إلى تطبيقك يكون مؤقتًا لدورة الحياة الحالية لنشاطك، لذا إذا أردت الوصول إليه لاحقًا، عليك استيراد نسخة يمكنك قراءتها لاحقًا.

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

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

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

الإجراء
ACTION_GET_CONTENT
مخطط معرّف الموارد المنتظم (URI) للبيانات
لا شيء
نوع MIME
نوع MIME الذي يتوافق مع نوع الملف الذي يحتاج المستخدم إلى اختياره.
الميزات الإضافية
EXTRA_ALLOW_MULTIPLE
قيمة منطقية تحدّد ما إذا كان بإمكان المستخدم اختيار أكثر من ملف واحد في المرة الواحدة.
EXTRA_LOCAL_ONLY
قيمة منطقية تحدّد ما إذا كان يجب أن يكون الملف الذي تم عرضه متاحًا مباشرةً من الجهاز، بدلاً من الحاجة إلى تنزيله من خدمة بعيدة.
الفئة (اختيارية)
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.
        ...
    }
}

مثال على فلتر الأهداف لعرض صورة:

<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 يحدّد دائمًا الملف المختار كمعرّف موارد منتظم content: يستند إلى DocumentsProvider. يمكنك فتح الملف باستخدام openFileDescriptor() والاستعلام عن تفاصيله باستخدام الأعمدة من DocumentsContract.Document.

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

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

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

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

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

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

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

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

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

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

(Wear OS فقط)

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

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

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

مثال على النية:

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);
    }
}

مثال على فلتر الأهداف:

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

Maps

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

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

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

الإجراء
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"

ملاحظة: يجب ترميز جميع السلاسل التي يتم تمريرها في معرّف الموارد الموحّد 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);
    }
}

مثال على فلتر الأهداف:

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

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

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

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

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

الإجراء
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);
    }
}

مثال على فلتر الأهداف:

<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

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

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

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

الإجراء
INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
مخطط معرّف الموارد المنتظم (URI) للبيانات
لا شيء
نوع MIME
لا شيء
الميزات الإضافية
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);
    }
}

مثال على فلتر الأهداف:

<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);
        }
    }
}

ملاحظة جديدة

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

إنشاء ملاحظة

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

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

الإجراء
ACTION_CREATE_NOTE
مخطط معرّف الموارد المنتظم (URI) للبيانات
لا شيء
نوع 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);
    }
}

مثال على فلتر الأهداف:

<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>

الهاتف

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

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

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

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

  • "الاتصال بالرقم 555-5555"
  • "الاتصال بـ "بوب" ("call bob")
  • الاتصال بالبريد الصوتي ("call voicemail")

لإجراء مكالمة هاتفية مباشرةً، استخدِم الإجراء 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);
    }
}

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

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

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

  • البحث عن فيديوهات عن القطط على myvideoapp ("search for cat videos on myvideoapp")

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

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

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

مثال على فلتر الأهداف:

<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) للبيانات
لا شيء
نوع MIME
لا شيء
الميزات الإضافية
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);
    }
}

الإعدادات

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

الإجراء
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) للبيانات
لا شيء
نوع 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);
    }
}

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

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

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

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

الإجراء
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);
    }
}

مثال على فلتر الأهداف:

<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>

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

متصفح الويب

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

تحميل عنوان URL لصفحة ويب

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

  • "open example.com"

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

الإجراء
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);
    }
}

مثال على فلتر الأهداف:

<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 يوفّر وظائف مشابهة لتلك التي يوفّرها موقعك الإلكتروني، أدرِج فلتر أهداف لعناوين URL التي تشير إلى موقعك الإلكتروني. بعد ذلك، إذا كان المستخدمون قد ثبّتوا تطبيقك، ستفتح الروابط الواردة من الرسائل الإلكترونية أو صفحات الويب الأخرى التي تشير إلى موقعك الإلكتروني تطبيق Android بدلاً من صفحة الويب. يمكنك الاطّلاع على مزيد من المعلومات في مقالة التعامل مع روابط التطبيقات المتوافقة مع Android.

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

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

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

  1. يمكنك إعداد جهاز Android للتطوير أو استخدام جهاز افتراضي.
  2. ثبِّت إصدارًا من تطبيقك يتعامل مع الأهداف التي تريد توفيرها.
  3. إطلاق هدف باستخدام 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.

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