ارسال داده به برنامه‌های دیگر

‫Android از هدف‌ها و موارد اضافی مرتبط با آن‌ها استفاده می‌کند تا به کاربران امکان دهد بااستفاده از برنامه‌های موردعلاقه‌شان اطلاعات را به‌سرعت هم‌رسانی کنند.

‫Android دو روش برای هم‌رسانی داده بین برنامه‌ها دراختیار کاربران قرار می‌دهد:

  • «برگ هم‌رسانی Android» در درجه اول برای ارسال محتوا به خارج از برنامه و/یا مستقیماً به کاربر دیگر طراحی شده است. برای مثال، هم‌رسانی نشانی وب با یک دوست.
  • «حل‌کننده هدف Android» برای انتقال داده به مرحله بعدی یک تکلیف خوش‌تعریف بهترین گزینه است. برای مثال، باز کردن فایل PDF از برنامه‌تان و اجازه دادن به کاربران برای انتخاب کردن ابزار مشاهده‌گر دلخواهشان.

وقتی قصدی می‌سازید، کنشی را که می‌خواهید قصد انجام دهد مشخص می‌کنید. ‫Android از کنش ACTION_SEND برای ارسال داده از یک فعالیت به فعالیت دیگر، حتی در مرزهای فرایند، استفاده می‌کند. باید داده‌ها و نوع آن‌ها را مشخص کنید. سیستم به‌طور خودکار فعالیت‌های سازگار را که می‌توانند داده‌ها را دریافت کنند شناسایی می‌کند و آن‌ها را به کاربر نمایش می‌دهد. در مورد حل‌کننده هدف، اگر فقط یک فعالیت بتواند هدف را مدیریت کند، آن فعالیت بلافاصله شروع می‌شود.

چرا از «برگه هم‌رسانی Android» استفاده کنیم

شکل ۱. «برگ هم‌رسانی Android».

به‌شدت توصیه می‌کنیم از «برگ هم‌رسانی Android» استفاده کنید تا برای کاربران در سراسر برنامه‌ها یکپارچگی ایجاد کنید. فهرست هدف‌های هم‌رسانی برنامه خودتان را نمایش ندهید یا انواع مختلف برگه هم‌رسانی خودتان را ایجاد نکنید.

«برگ هم‌رسانی Android» به کاربران امکان می‌دهد اطلاعات را با فرد مناسب، با پیشنهادهای برنامه مرتبط، و تنها با یک ضربه هم‌رسانی کنند. «برگ هم‌رسانی» می‌تواند هدف‌هایی را پیشنهاد دهد که برای راه‌حل‌های سفارشی دردسترس نیستند و از رتبه‌بندی یکسانی استفاده می‌کند. دلیل این امر این است که «برگ هم‌رسانی» می‌تواند اطلاعات مربوط به فعالیت برنامه و کاربر را درنظر بگیرد که فقط برای سیستم دردسترس است.

«برگ هم‌رسانی Android» نیز ویژگی‌های کاربردی زیادی برای توسعه‌دهندگان دارد. برای مثال، می‌توانید کارهای زیر را انجام دهید:

استفاده از «برگ هم‌رسانی Android»

برای همه انواع هم‌رسانی، هدفی ایجاد کنید و کنش آن را روی Intent.ACTION_SEND تنظیم کنید. برای نمایش «برگ هم‌رسانی Android»، Intent.createChooser() را فراخوانی کنید و شیء Intent را به آن ارسال کنید. نسخه‌ای از هدف شما را برمی‌گرداند که همیشه «برگ هم‌رسانی Android» را نمایش می‌دهد.

ارسال محتوای نوشتاری

ساده‌ترین و رایج‌ترین استفاده از «برگ هم‌رسانی Android» ارسال محتوای نوشتاری از یک فعالیت به فعالیت دیگر است. برای مثال، اکثر مرورگرها می‌توانند نشانی وب صفحه نمایش‌داده‌شده فعلی را به‌عنوان نوشتار با برنامه دیگری هم‌رسانی کنند. این کار برای هم‌رسانی مقاله یا وب‌سایت با دوستان ازطریق ایمیل یا شبکه‌های اجتماعی مفید است. در اینجا مثالی از نحوه انجام این کار آورده شده است:

fun shareText(context: Context) {
    val sendIntent: Intent = Intent().apply {
        action = ACTION_SEND
        putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
        type = "text/plain"
    }

    val shareIntent = Intent.createChooser(sendIntent, null)
    context.startActivity(shareIntent)
}

به‌صورت اختیاری، می‌توانید موارد اضافی اضافه کنید تا اطلاعات بیشتری را شامل شود، مثل گیرندگان ایمیل (EXTRA_EMAIL، EXTRA_CC، EXTRA_BCC)، موضوع ایمیل (EXTRA_SUBJECT)، و غیره.

توجه: برخی‌از برنامه‌های ایمیل، مثل Gmail، برای موارد اضافی مثل EXTRA_EMAIL و EXTRA_CC، String[] را انتظار دارند. از putExtra(String, String[]) برای افزودن این‌ها به هدف استفاده کنید.

ارسال محتوای دودویی

داده‌های باینری را بااستفاده از کنش ACTION_SEND هم‌رسانی کنید. نوع MIME مناسب را تنظیم کنید و نشانی وب داده‌ها را در extra EXTRA_STREAM، همان‌طور که در مثال زیر نشان داده شده است، قرار دهید. این روش معمولاً برای هم‌رسانی تصویر استفاده می‌شود اما می‌توان از آن برای هم‌رسانی هر نوع محتوای باینری استفاده کرد.

fun shareBinaryContent(context: Context) {
    val shareIntent: Intent = Intent().apply {
        action = ACTION_SEND
        // Example: content://com.google.android.apps.photos.contentprovider/...
        val imageUri: Uri =
            Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/1")
        putExtra(Intent.EXTRA_STREAM, imageUri)
        type = "image/jpeg"
    }
    context.startActivity(Intent.createChooser(shareIntent, null))
}

برنامه دریافت‌کننده برای دسترسی به داده‌هایی که Uri به آن‌ها اشاره می‌کند به اجازه نیاز دارد. دو روش توصیه‌شده برای انجام این کار وجود دارد:

  • داده‌ها را در ContentProvider خودتان ذخیره کنید و مطمئن شوید که برنامه‌های دیگر اجازه دسترسی به ارائه‌دهنده شما را دارند. سازوکار ترجیحی برای ارائه دسترسی استفاده از اجازه‌های هر نشانی وب است که موقتی هستند و فقط به برنامه دریافت‌کننده اجازه دسترسی می‌دهند. برای ایجاد ContentProvider مانند این، از کلاس کمکی FileProvider استفاده کنید.
  • از MediaStore سیستم استفاده کنید. MediaStore بیشتر برای انواع رسانه ویدیویی، صوتی، و تصویری MIME است. بااین‌حال، از Android 3.0 (سطح میانای برنامه‌سازی کاربردی ۱۱) به بعد، می‌تواند انواع غیررسانه‌ای را نیز ذخیره کند. برای اطلاعات بیشتر، به MediaStore.Files مراجعه کنید. فایل‌ها را می‌توان بااستفاده از scanFile() در MediaStore درج کرد، پس‌از آن content://-سبک Uri مناسب برای هم‌رسانی به onScanCompleted() بازخوان ارائه‌شده ارسال می‌شود. توجه داشته باشید که پس‌از اضافه شدن به سیستم MediaStore، محتوا برای همه برنامه‌های دستگاه دردسترس است.

از نوع MIME صحیح استفاده کنید

خاص‌ترین نوع MIME دردسترس برای داده‌هایی را که ارسال می‌کنید ارائه دهید. برای مثال، هنگام هم‌رسانی نوشتار ساده از text/plain استفاده کنید. در اینجا چند نوع رایج MIME هنگام ارسال داده در Android آورده شده است:

گیرندگان برای این ثبت‌نام می‌کنند فرستندگان ارسال می‌کنند
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
`image/*`
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
پسوندهای فایل پشتیبانی‌شده application/pdf

برای اطلاعات بیشتر درباره انواع MIME، به ثبت رسمی IANA انواع رسانه MIME مراجعه کنید.

«برگ هم‌رسانی Android» ممکن است پیش‌نمایش محتوا را براساس نوع MIME ارائه‌شده نشان دهد. برخی‌از ویژگی‌های پیش‌نمایشی فقط برای انواع خاصی دردسترس است.

هم‌رسانی چند محتوا

برای هم‌رسانی چند محتوا، از ACTION_SEND_MULTIPLE عمل همراه با فهرست نشانی‌های وب اشاره‌کننده به محتوا استفاده کنید. نوع MIME براساس ترکیب محتوایی که هم‌رسانی می‌کنید متفاوت است. برای مثال، اگر سه تصویر JPEG هم‌رسانی کنید، از نوع "image/jpg" استفاده می‌کنید. برای ترکیبی از انواع تصویر، از "image/*" برای مطابقت با فعالیتی که از هر نوع تصویری پشتیبانی می‌کند استفاده کنید. اگرچه امکان هم‌رسانی ترکیبی از انواع مختلف وجود دارد، اما ما به‌شدت این کار را منع می‌کنیم، زیرا برای گیرنده مشخص نیست که چه چیزی قرار است ارسال شود. اگر لازم است چند نوع ارسال کنید، از "*/*" استفاده کنید. برنامه دریافت‌کننده باید داده‌هایتان را تجزیه و تحلیل و پردازش کند. مثالی در اینجا ارائه شده است:

fun shareMultiple(context: Context) {
    val imageUris: ArrayList<Uri> = arrayListOf(
        Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/1"),
        Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/2")
    )

    val shareIntent = Intent().apply {
        action = Intent.ACTION_SEND_MULTIPLE
        putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris)
        type = "image/*"
    }
    context.startActivity(Intent.createChooser(shareIntent, null))
}

مطمئن شوید که اشیاء Uri ارائه‌شده به داده‌هایی اشاره می‌کنند که برنامه دریافت‌کننده می‌تواند به آن‌ها دسترسی داشته باشد.

افزودن محتوای غنی به پیش‌نمایش‌های نوشتاری

از Android 10 (سطح API 29) به بعد، «برگ هم‌رسانی Android» پیش‌نمایشی از نوشتار هم‌رسانی‌شده نشان می‌دهد. در برخی موارد، درک متن هم‌رسانی‌شده دشوار است. نشانی وب پیچیده‌ای مثل https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4 را هم‌رسانی کنید. پیش‌نمایش غنی‌تر می‌تواند به کاربران اطمینان دهد که چه چیزی هم‌رسانی می‌شود.

اگر درحال پیش‌نمایش نوشتار هستید، می‌توانید عنوان، تصویر ریزعکس، یا هر دو را تنظیم کنید. قبل‌از تماس با Intent.createChooser()، شرحی به Intent.EXTRA_TITLE اضافه کنید و بااستفاده از ClipData، ریزعکس مرتبطی اضافه کنید.

توجه: نشانی وب محتوای تصویر از FileProvider، معمولاً از <cache-path> پیکربندی‌شده، ارائه می‌شود. برای اطلاعات بیشتر، به هم‌رسانی فایل‌ها مراجعه کنید. حتماً به «برگ هم‌رسانی» اجازه دهید هر تصویری را که می‌خواهید به‌عنوان تصویر کوچک استفاده کنید بخواند. برای اطلاعات بیشتر، به Intent.FLAG_GRANT_READ_URI_PERMISSION مراجعه کنید.

مثالی در اینجا ارائه شده است:

fun richContentToTextPreviewShares(context: Context) {
    val share = Intent.createChooser(
        Intent().apply {
            action = ACTION_SEND
            putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/")

            // (Optional) Here you're setting the title of the content
            putExtra(Intent.EXTRA_TITLE, "Introducing content previews")

            // (Optional) Here you're passing a content URI to an image to be displayed
            data =
                Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/A123456789")
            flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        },
        null
    )
    context.startActivity(share)
}

پیش‌نمایش چیزی شبیه به این است:

شکل ۲. پیش‌نمایش محتوای نوشتاری در «برگه هم‌رسانی Android».

افزودن کنش‌های سفارشی به برگ هم‌رسانی

شکل ۳. کنش‌های سفارشی در «کاربرگ هم‌رسانی Android».

در Android 14 (سطح میانای برنامه‌سازی کاربردی ۳۴) و نسخه‌های جدیدتر، برنامه‌ها می‌توانند کنش‌های سفارشی به «کاربرگ هم‌رسانی Android» اضافه کنند. کنش‌های سفارشی به‌عنوان نمادهای کنش کوچک در بالای «کاربرگ هم‌رسانی Android» نشان داده می‌شوند و برنامه‌ها می‌توانند هر Intent را به‌عنوان کنشی که هنگام کلیک کردن روی نماد فراخوانده می‌شود مشخص کنند.

برای افزودن کنش‌های سفارشی در «برگ هم‌رسانی Android»، ابتدا ChooserAction را با ChooserAction.Builder ایجاد کنید. می‌توانید PendingIntent را به‌عنوان کنشی که هنگام کلیک کردن روی نماد فراخوانده می‌شود مشخص کنید. آرایه‌ای حاوی همه کنش‌های سفارشی‌تان بسازید و آن را به‌عنوان EXTRA_CHOOSER_CUSTOM_ACTIONS از هم‌رسانی Intent مشخص کنید.

fun sharesheetCustomActions(context: Context, previewText: String) {
    val sendIntent = Intent(ACTION_SEND)
        .setType("text/plain")
        .putExtra(Intent.EXTRA_TEXT, previewText)
    val shareIntent = Intent.createChooser(sendIntent, null)
    val customActions = arrayOf(
        ChooserAction.Builder(
            Icon.createWithResource(context, R.drawable.ic_logo),
            "Custom",
            PendingIntent.getBroadcast(
                context,
                1,
                Intent(Intent.ACTION_VIEW),
                PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
            )
        ).build()
    )
    shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions)
    context.startActivity(shareIntent)
}

افزودن هدف‌های سفارشی

«برگ هم‌رسانی Android» به شما امکان می‌دهد حداکثر دو ChooserTarget شیء را مشخص کنید که قبل‌از میان‌برهای هم‌رسانی و هدف‌های انتخابگر بارگیری‌شده از ChooserTargetServices نشان داده می‌شوند. همچنین می‌توانید حداکثر دو هدف را مشخص کنید که به فعالیت‌هایی اشاره می‌کنند که قبل‌از پیشنهادهای برنامه فهرست شده‌اند:

شکل ۴. هدف‌های سفارشی در «برگ هم‌رسانی Android».

Intent.EXTRA_CHOOSER_TARGETS و Intent.EXTRA_INITIAL_INTENTS را پس‌از فراخوانی Intent.createChooser() به «هدف هم‌رسانی» اضافه کنید:

val sendIntent = Intent(ACTION_SEND).apply {
    type = "text/plain"
    putExtra(Intent.EXTRA_TEXT, previewText)
}

val customIntent = Intent().apply {
    component = ComponentName(context.packageName, "${context.packageName}.CustomActivity")
}

val shareIntent = Intent.createChooser(sendIntent, null).apply {
    putExtra(
        Intent.EXTRA_INITIAL_INTENTS,
        arrayOf(customIntent)
    )
}
context.startActivity(shareIntent)

از این ویژگی با دقت استفاده کنید. هر Intent و ChooserTarget سفارشی که اضافه می‌کنید تعداد پیشنهادات سیستم را کاهش می‌دهد. ما معمولاً افزودن هدف‌های سفارشی را توصیه نمی‌کنیم. نمونه مناسب رایج برای افزودن Intent.EXTRA_INITIAL_INTENTS ارائه کنش‌های اضافی است که کاربران می‌توانند روی محتوای هم‌رسانی‌شده انجام دهند. برای مثال، کاربر تصاویری را هم‌رسانی می‌کند و از Intent.EXTRA_INITIAL_INTENTS برای ارسال پیوند به‌جای آن استفاده می‌شود. نمونه مناسب رایج برای افزودن Intent.EXTRA_CHOOSER_TARGETS نمایش افراد یا دستگاه‌های مرتبطی است که برنامه شما ارائه می‌دهد.

کنار گذاشتن هدف‌های ویژه براساس عنصر

با ارائه Intent.EXTRA_EXCLUDE_COMPONENTS می‌توانید هدف‌های خاصی را کنار بگذارید. فقط برای برداشتن هدف‌هایی که روی آن‌ها کنترل دارید این کار را انجام دهید. یک مورد استفاده رایج این است که وقتی کاربران از داخل برنامه شما هم‌رسانی می‌کنند، هدف‌های هم‌رسانی برنامه خودتان را پنهان کنید، زیرا احتمالاً قصد آن‌ها هم‌رسانی در خارج از برنامه شما است.

پس‌از تماس با Intent.createChooser()،‏ Intent.EXTRA_EXCLUDE_COMPONENTS را به قصدتان اضافه کنید:

fun excludeSpecificTargets(context: Context) {
    val share = Intent.createChooser(Intent(ACTION_SEND), null).apply {
        // Only use for components you have control over
        val excludedComponentNames =
            arrayOf(ComponentName("com.example.android", "ExampleClass"))
        putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames)
    }
    context.startActivity(share)
}

دریافت اطلاعات درباره هم‌رسانی

دانستن اینکه کاربران شما چه زمانی هم‌رسانی می‌کنند و چه هدفی را انتخاب می‌کنند می‌تواند مفید باشد. «برگ هم‌رسانی Android» با ارائه ComponentName از هدف‌هایی که کاربران بااستفاده از IntentSender انتخاب می‌کنند، به شما امکان می‌دهد این اطلاعات را دریافت کنید.

ابتدا PendingIntent را برای BroadcastReceiver ایجاد کنید و IntentSender آن را در Intent.createChooser() ارائه دهید:

fun infoAboutSharing(context: Context, requestCode: Int) {
    var share = Intent(ACTION_SEND)
    // ...
    val pi = PendingIntent.getBroadcast(
        context, requestCode,
        Intent(context, ShareBroadcastReceiver::class.java),
        PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
    )
    share = Intent.createChooser(share, null, pi.intentSender)
    context.startActivity(share)
}

پاسخ تماس را در MyBroadcastReceiver دریافت کنید و در Intent.EXTRA_CHOOSER_RESULT ببینید:

override fun onReceive(context: Context?, intent: Intent) {
    val TAG = ShareBroadcastReceiver::class.simpleName
    val chooserResult: ChooserResult? = IntentCompat.getParcelableExtra(
        intent,
        Intent.EXTRA_CHOOSER_RESULT,
        ChooserResult::class.java,
    )
    chooserResult?.let {
        Log.i(TAG,
            "Share callback: isShortcut: ${it.isShortcut}, type: ${typeToString(it.type)}, componentName: ${it.selectedComponent}",
        )
    } ?: Log.i(TAG, "chooserResult is null")
}

برای اطلاعات بیشتر، نمونه سهم پلاتفرم را ببینید.

استفاده از حل‌کننده هدف Android

شکل ۵. حل‌کننده هدف ACTION_SEND.

از حل‌کننده هدف Android بهتر است زمانی استفاده شود که داده‌ها به‌عنوان بخشی از جریان وظیفه به‌خوبی تعریف‌شده به برنامه دیگری ارسال می‌شود.

برای استفاده از حل‌کننده هدف Android، هدفی ایجاد کنید و همان‌طور که برای فراخوانی «برگه هم‌رسانی Android» انجام می‌دهید، موارد اضافی اضافه کنید. بااین‌حال، تماس نگیر Intent.createChooser().

اگر چند برنامه نصب‌شده با فیلترهایی وجود داشته باشد که با ACTION_SEND و نوع MIME مطابقت داشته باشد، سیستم یک چارگوش ابهام‌زدایی به‌نام حل‌کننده هدف نمایش می‌دهد که به کاربر امکان می‌دهد هدف موردنظر را برای هم‌رسانی انتخاب کند. اگر یک برنامه واحد مطابقت داشته باشد، اجرا می‌شود.

در اینجا نمونه‌ای از نحوه استفاده از حل‌کننده هدف Android برای ارسال نوشتار آورده شده است:

fun intentResolver(context: Context) {
    val sendIntent: Intent = Intent().apply {
        action = ACTION_SEND
        putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
        type = "text/plain"
    }
    context.startActivity(sendIntent)
}

بیشتر بدانید

برای اطلاعات بیشتر درباره ارسال داده‌ها، هدف‌ها و فیلترهای هدف را ببینید.