این سند چندین مورد استفاده رایج را ارائه میدهد که در آنها یک برنامه با سایر برنامهها تعامل دارد. هر بخش راهنماییهایی در مورد چگونگی دستیابی به عملکرد برنامه با قابلیت مشاهده بسته محدود ارائه میدهد، که اگر برنامه شما اندروید ۱۱ (سطح API 30) یا بالاتر را هدف قرار میدهد، باید در نظر بگیرید.
وقتی برنامهای که اندروید ۱۱ یا بالاتر را هدف قرار میدهد از یک اینتنت برای شروع یک اکتیویتی در برنامهی دیگر استفاده میکند، سادهترین رویکرد، فراخوانی اینتنت و مدیریت خطای ActivityNotFoundException در صورت عدم دسترسی به برنامه است.
اگر بخشی از برنامه شما به دانستن اینکه آیا فراخوانی startActivity() میتواند موفق شود یا خیر، مانند نمایش یک رابط کاربری، بستگی دارد، یک عنصر به عنصر <queries> در مانیفست برنامه خود اضافه کنید. معمولاً این یک عنصر <intent> است.
URL های باز
این بخش روشهای مختلف باز کردن URLها در برنامهای که اندروید ۱۱ یا بالاتر را هدف قرار میدهد، شرح میدهد.
باز کردن URLها در مرورگر یا برنامه دیگر
برای باز کردن یک URL، از intent ای استفاده کنید که حاوی اکشن ACTION_VIEW intent باشد، همانطور که در راهنمای بارگذاری URL وب توضیح داده شده است. پس از فراخوانی startActivity() با استفاده از این intent، یکی از موارد زیر اتفاق میافتد:
- URL در یک برنامه مرورگر وب باز میشود.
- URL در برنامهای باز میشود که از URL به عنوان یک لینک عمیق پشتیبانی میکند.
- یک کادر محاورهای ابهامزدایی ظاهر میشود که به کاربر اجازه میدهد انتخاب کند کدام برنامه URL را باز کند.
خطای
ActivityNotFoundExceptionبه این دلیل رخ میدهد که برنامهای روی دستگاه نصب نشده است که بتواند URL را باز کند. (این مورد غیرمعمول است.)توصیه میشود که برنامه شما در صورت وقوع
ActivityNotFoundExceptionآن را دریافت و مدیریت کند.
از آنجا که متد startActivity() برای شروع فعالیت یک برنامه دیگر نیازی به قابلیت مشاهده بسته ندارد، نیازی به اضافه کردن عنصر <queries> به مانیفست برنامه خود یا ایجاد تغییر در عنصر <queries> موجود ندارید. این موضوع هم برای intent های ضمنی و هم صریح که یک URL را باز میکنند، صادق است.
بررسی کنید که آیا مرورگر در دسترس است یا خیر
در برخی موارد، برنامه شما ممکن است بخواهد قبل از تلاش برای باز کردن یک URL، تأیید کند که حداقل یک مرورگر در دستگاه موجود است یا اینکه یک مرورگر خاص، مرورگر پیشفرض است. در این موارد، عنصر <intent> زیر را به عنوان بخشی از عنصر <queries> در مانیفست خود قرار دهید:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" /> </intent>
وقتی تابع queryIntentActivities() را فراخوانی میکنید و یک web intent را به عنوان آرگومان به آن ارسال میکنید، در برخی موارد لیست برگردانده شده شامل برنامههای مرورگر موجود است. اگر کاربر URL را طوری پیکربندی کرده باشد که به طور پیشفرض در یک برنامه غیر مرورگر باز شود، لیست شامل برنامههای مرورگر نمیشود.
باز کردن URLها در تبهای سفارشی
تبهای سفارشی به یک برنامه اجازه میدهند ظاهر و حس مرورگر را سفارشی کند. شما میتوانید یک URL را در یک تب سفارشی باز کنید بدون اینکه نیازی به اضافه کردن یا تغییر عنصر <queries> در مانیفست برنامه خود داشته باشید.
با این حال، ممکن است بخواهید بررسی کنید که آیا دستگاه دارای مرورگری است که از تبهای سفارشی پشتیبانی میکند یا خیر ، یا با استفاده از CustomTabsClient.getPackageName() یک مرورگر خاص را برای راهاندازی با تبهای سفارشی انتخاب کنید. در این موارد، عنصر <intent> زیر را به عنوان بخشی از عنصر <queries> در مانیفست خود قرار دهید:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.support.customtabs.action.CustomTabsService" /> </intent>
اجازه دهید برنامههای غیر مرورگر، URLها را مدیریت کنند
حتی اگر برنامه شما میتواند URLها را با استفاده از تبهای سفارشی باز کند، توصیه میشود در صورت امکان به یک برنامه غیر مرورگر اجازه دهید URL را باز کند. برای ارائه این قابلیت در برنامه خود، سعی کنید با استفاده از یک intent که پرچم intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER را تنظیم میکند، تابع startActivity() را فراخوانی کنید. اگر سیستم خطای ActivityNotFoundException صادر کند، برنامه شما میتواند URL را در یک تب سفارشی باز کند.
اگر یک intent شامل این پرچم باشد، فراخوانی startActivity() باعث میشود که در صورت وقوع هر یک از شرایط زیر، یک ActivityNotFoundException صادر شود:
- این تماس مستقیماً یک برنامه مرورگر را اجرا میکرد.
- این فراخوانی یک کادر محاورهای ابهامزدایی به کاربر نشان میداد که در آن تنها گزینهها، برنامههای مرورگر بودند.
قطعه کد زیر نحوه بهروزرسانی منطق شما برای استفاده از پرچم اینتنت FLAG_ACTIVITY_REQUIRE_NON_BROWSER را نشان میدهد:
کاتلین
try { val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply { // The URL should either launch directly in a non-browser app (if it's // the default) or in the disambiguation dialog. addCategory(CATEGORY_BROWSABLE) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER } startActivity(intent) } catch (e: ActivityNotFoundException) { // Only browser apps are available, or a browser is the default. // So you can open the URL directly in your app, for example in a // Custom Tab. openInCustomTabs(url) }
جاوا
try { Intent intent = new Intent(ACTION_VIEW, Uri.parse(url)); // The URL should either launch directly in a non-browser app (if it's the // default) or in the disambiguation dialog. intent.addCategory(CATEGORY_BROWSABLE); intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER); startActivity(intent); } catch (ActivityNotFoundException e) { // Only browser apps are available, or a browser is the default. // So you can open the URL directly in your app, for example in a // Custom Tab. openInCustomTabs(url); }
از گفتگوی ابهامزدایی خودداری کنید
اگر میخواهید از نمایش کادر محاورهای ابهامزدایی که کاربران ممکن است هنگام باز کردن یک URL ببینند، جلوگیری کنید و در عوض ترجیح میدهید خودتان URL را در این شرایط مدیریت کنید، میتوانید از یک intent استفاده کنید که پرچم intent FLAG_ACTIVITY_REQUIRE_DEFAULT را تنظیم میکند.
اگر یک intent شامل این پرچم باشد، فراخوانی startActivity() باعث میشود که یک ActivityNotFoundException صادر شود، در حالی که فراخوانی میتوانست یک کادر محاورهای ابهامزدایی را به کاربر نشان دهد.
اگر یک اینتنت شامل هر دو پرچم این و پرچم اینتنت FLAG_ACTIVITY_REQUIRE_NON_BROWSER باشد، فراخوانی startActivity() باعث میشود که در صورت وقوع هر یک از شرایط زیر، خطای ActivityNotFoundException رخ دهد:
- این تماس مستقیماً برنامه مرورگر را اجرا میکرد.
- این فراخوانی یک کادر محاورهای ابهامزدایی به کاربر نشان میداد.
قطعه کد زیر نحوه استفاده از پرچمهای FLAG_ACTIVITY_REQUIRE_NON_BROWSER و FLAG_ACTIVITY_REQUIRE_DEFAULT را با هم نشان میدهد:
کاتلین
val url = URL_TO_LOAD try { // For this intent to be invoked, the system must directly launch a // non-browser app. val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply { addCategory(CATEGORY_BROWSABLE) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER or FLAG_ACTIVITY_REQUIRE_DEFAULT } startActivity(intent) } catch (e: ActivityNotFoundException) { // This code executes in one of the following cases: // 1. Only browser apps can handle the intent. // 2. The user has set a browser app as the default app. // 3. The user hasn't set any app as the default for handling this URL. openInCustomTabs(url) }
جاوا
String url = URL_TO_LOAD; try { // For this intent to be invoked, the system must directly launch a // non-browser app. Intent intent = new Intent(ACTION_VIEW, Uri.parse(url)); intent.addCategory(CATEGORY_BROWSABLE); intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER | FLAG_ACTIVITY_REQUIRE_DEFAULT); startActivity(intent); } catch (ActivityNotFoundException e) { // This code executes in one of the following cases: // 1. Only browser apps can handle the intent. // 2. The user has set a browser app as the default app. // 3. The user hasn't set any app as the default for handling this URL. openInCustomTabs(url); }
باز کردن یک فایل
اگر برنامه شما فایلها یا پیوستها را مدیریت میکند، مثلاً بررسی میکند که آیا دستگاهی میتواند یک فایل مشخص را باز کند یا خیر، معمولاً سادهترین کار این است که یک activity را شروع کنید که بتواند فایل را مدیریت کند. برای انجام این کار، از یک intent استفاده کنید که شامل اکشن ACTION_VIEW intent و URI مربوط به فایل خاص باشد. اگر هیچ برنامهای روی دستگاه موجود نباشد، برنامه شما میتواند ActivityNotFoundException را دریافت کند. در منطق مدیریت exception خود، میتوانید یا خطایی را نشان دهید یا خودتان سعی کنید فایل را مدیریت کنید.
اگر برنامه شما باید از قبل بداند که آیا برنامه دیگری میتواند یک فایل مشخص را باز کند یا خیر، عنصر <intent> را در قطعه کد زیر به عنوان بخشی از عنصر <queries> در مانیفست خود قرار دهید. اگر از قبل نوع فایل را در زمان کامپایل میدانید، آن را نیز اضافه کنید.
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.VIEW" /> <!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". --> <data android:mimeType="application/pdf" /> </intent>
سپس میتوانید با فراخوانی resolveActivity() به همراه intent خود، بررسی کنید که آیا یک برنامه در دسترس است یا خیر.
اعطای دسترسی به URI
توجه: اعلام مجوزهای دسترسی URI همانطور که در این بخش توضیح داده شده است، برای برنامههایی که اندروید ۱۱ (سطح API 30) یا بالاتر را هدف قرار میدهند، الزامی است و برای همه برنامهها، صرف نظر از نسخه SDK هدف آنها و اینکه آیا ارائه دهندگان محتوای خود را صادر میکنند یا خیر، توصیه میشود.
برای برنامههایی که اندروید ۱۱ یا بالاتر را برای دسترسی به URI محتوا هدف قرار میدهند، intent برنامه شما باید مجوزهای دسترسی به URI را با تنظیم یک یا هر دو پرچم intent زیر اعلام کند: FLAG_GRANT_READ_URI_PERMISSION و FLAG_GRANT_WRITE_URI_PERMISSION .
در اندروید ۱۱ و بالاتر، مجوزهای دسترسی URI قابلیتهای زیر را به برنامهای که intent را دریافت میکند، میدهند:
- بسته به مجوزهای URI داده شده، دادههایی را که URI محتوا نشان میدهد، از آنها بخوانید یا در آنها بنویسید.
- دسترسی به برنامهای که حاوی ارائهدهنده محتوا (content provider) است و با اعتبار URI مطابقت دارد. برنامهای که حاوی ارائهدهنده محتوا است ممکن است با برنامهای که intent را ارسال میکند متفاوت باشد.
قطعه کد زیر نحوه اضافه کردن یک پرچم مجوز URI را نشان میدهد تا برنامه دیگری که اندروید ۱۱ یا بالاتر را هدف قرار میدهد بتواند دادهها را در URI محتوا مشاهده کند:
کاتلین
val shareIntent = Intent(Intent.ACTION_VIEW).apply { flags = Intent.FLAG_GRANT_READ_URI_PERMISSION data = CONTENT_URI_TO_SHARE_WITH_OTHER_APP }
جاوا
Intent shareIntent = new Intent(Intent.ACTION_VIEW); shareIntent.setFlags(FLAG_GRANT_READ_URI_PERMISSION); shareIntent.setData(CONTENT_URI_TO_SHARE_WITH_OTHER_APP);
اتصال به سرویسها
اگر برنامه شما نیاز به تعامل با سرویسی دارد که به طور خودکار قابل مشاهده نیست، میتوانید اقدام مربوط به intent را درون یک عنصر <queries> تعریف کنید. بخشهای زیر مثالهایی از استفاده از سرویسهای پرکاربرد را ارائه میدهند.
اتصال به موتور تبدیل متن به گفتار
اگر برنامه شما با موتور تبدیل متن به گفتار (TTS) تعامل دارد، عنصر <intent> زیر را به عنوان بخشی از عنصر <queries> در مانیفست خود قرار دهید:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.TTS_SERVICE" /> </intent>
اتصال به یک سرویس تشخیص گفتار
اگر برنامه شما با یک سرویس تشخیص گفتار تعامل دارد، عنصر <intent> زیر را به عنوان بخشی از عنصر <queries> در مانیفست خود قرار دهید:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.speech.RecognitionService" /> </intent>
اتصال به سرویسهای مرورگر رسانه
اگر برنامه شما یک برنامه مرورگر رسانه کلاینت است، عنصر <intent> زیر را به عنوان بخشی از عنصر <queries> در مانیفست خود وارد کنید:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.media.browse.MediaBrowserService" /> </intent>
ارائه قابلیتهای سفارشی
اگر برنامه شما نیاز به انجام اقدامات قابل تنظیم یا نمایش اطلاعات قابل تنظیم بر اساس تعاملاتش با سایر برنامهها دارد، میتوانید آن رفتار سفارشی را با استفاده از امضاهای فیلتر intent به عنوان بخشی از عنصر <queries> در مانیفست خود نمایش دهید. بخشهای زیر راهنماییهای دقیقی برای چندین سناریوی رایج ارائه میدهند.
جستجو برای برنامه های پیامکی
اگر برنامه شما به اطلاعاتی در مورد مجموعه برنامههای پیامکی نصب شده روی دستگاه نیاز دارد، برای مثال برای بررسی اینکه کدام برنامه، مدیریتکننده پیامک پیشفرض دستگاه است، عنصر <intent> زیر را به عنوان بخشی از عنصر <queries> در مانیفست خود قرار دهید:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.SENDTO"/> <data android:scheme="smsto" android:host="*" /> </intent>
ایجاد یک برگه اشتراکگذاری سفارشی
هر زمان که امکان دارد، از یک برگه اشتراکی ارائه شده توسط سیستم استفاده کنید. به عنوان یک روش جایگزین، عنصر <intent> زیر را به عنوان بخشی از عنصر <queries> در مانیفست خود قرار دهید:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.SEND" /> <!-- Replace with the MIME type that your app works with, if needed. --> <data android:mimeType="image/jpeg" /> </intent>
فرآیند ساخت صفحه اشتراکگذاری در منطق برنامه شما، مانند فراخوانی queryIntentActivities() ، در مقایسه با نسخههای اندروید قبل از اندروید ۱۱ بدون تغییر باقی میماند.
نمایش اقدامات انتخاب متن سفارشی
وقتی کاربران متنی را در برنامه شما انتخاب میکنند، نوار ابزار انتخاب متن، مجموعهای از عملیات ممکن برای انجام روی متن انتخاب شده را نشان میدهد. اگر این نوار ابزار، اقدامات سفارشی از برنامههای دیگر را نشان میدهد، عنصر <intent> زیر را به عنوان بخشی از عنصر <queries> در مانیفست خود وارد کنید:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.PROCESS_TEXT" /> <data android:mimeType="text/plain" /> </intent>
نمایش ردیفهای داده سفارشی برای یک مخاطب
برنامهها میتوانند ردیفهای داده سفارشی را به ارائهدهنده مخاطبین اضافه کنند . برای اینکه یک برنامه مخاطبین بتواند این دادههای سفارشی را نمایش دهد، باید بتواند موارد زیر را انجام دهد:
- فایل
contacts.xmlرا از برنامههای دیگر بخوانید. - یک آیکون مربوط به نوع MIME سفارشی را بارگذاری کنید.
اگر برنامه شما یک برنامه مخاطبین است، عناصر <intent> زیر را به عنوان بخشی از عنصر <queries> در مانیفست خود قرار دهید:
<!-- Place inside the <queries> element. --> <!-- Lets the app read the contacts.xml file from other apps. --> <intent> <action android:name="android.accounts.AccountAuthenticator" /> </intent> <!-- Lets the app load an icon corresponding to the custom MIME type. --> <intent> <action android:name="android.intent.action.VIEW" /> <data android:scheme="content" android:host="com.android.contacts" android:mimeType="vnd.android.cursor.item/*" /> </intent>