راهنمای فنی دسترسی های اندروید
این مطلب راهنمای فنی دسترسی های اندروید برای توسعه دهندگان است و شامل راهنمای ایجاد دسترسی دوربین، بازیابی مخاطبین، افزودن تماس، ارسال پیام کوتاه و موارد مهم دیگر میشود که در ادامه به آنها خواهیم پرداخت.
استفاده از دوربین دستگاه در Java
در ابتدا در مورد استفاده از دوربین دستگاه بدون استفاده از دسترسی برای زبان برنامهنویسی جاوا صحبت خواهیم کرد. باید در نظر داشته باشید که با توجه به قوانین انتشار در بازار، اگر برنامه شما نیازمند استفاده از دسترسی دوربین در برنامه است، لازم است تا حد امکان این دسترسی رو به صورت "intent" پیادهسازی کنید.
دسترسی دوربین:
<uses-permission android:name="android.permission.CAMERA"/>
جهت پیادهسازی این دسترسی به صورت "intent" لازم است طبق مراحل زیر عمل کنید. ابتدا با استفاده از کد زیر درخواست بازگشایی دوربین دستگاه را ارسال میکنیم:
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
پساز بازگشایی دوربین و ثبت تصویر، محتوا به برنامه برگشت داده میشود. جهت دریافت تصویر مانند مثال زیر عمل خواهیم کرد:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
Uri imageUri = data.getData();
if(imageUri != null) {
// do something with image
}
}
}
استفاده از دوربین دستگاه در "Kotlin"
مانند زبان برنامهنویسی جاوا، در زبان برنامه نویسی Kotlin هم اگر برنامه شما نیازمند استفاده از دسترسی دوربین در برنامه است، لازم است این دسترسی رو به صورت "intent" پیادهسازی کنید.
<uses-permission android:name="android.permission.CAMERA"/>
جهت پیادهسازی این دسترسی به صورت "intent" لازم است طبق مراحل زیر را به صورت گام به گام عمل کنید. ابتدا با استفاده از کد زیر درخواست بازگشایی دوربین دستگاه را ارسال میکنیم:
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
پساز بازگشایی دوربین و ثبت تصویر، محتوا به برنامه برگشت داده خواهد شد. جهت دریافت تصویر مانند مثال زیر عمل خواهیم کرد:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
var imageUri = data?.data
// do something with image
}
}
برقراری تماس در برنامه به صورت "Intent"
اگر برنامه شما قرار است از قابلیت تماس گوشی کاربر استفاده کند، برای انجام این کار، بدون استفاده از دسترسی "android.permission.CALL_PHONE" به صورت زیر عمل میکنیم.
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:09xxxxxxxxx"))
startActivity(intent)
در صورتی که اکشن Intent.ACTION_DIAL را با Intent.ACTION_CALL جایگزین کنیم، خطای java.lang.SecurityException دریافت خواهیم کرد. این موضوع به این معنا است که استفاده از اکشن Intent.ACTION_CALL نیازمند اضافه کردن دسترسی "android.permission.CALL_PHONE" در فایل مانیفست برنامه است.
بازیابی مخاطبین ذخیره شده
در ادامه مطلب راهنمای دسترسی های اندروید جهت دریافت اطلاعات تنها یک مخاطب و انتخاب آن توسط کاربر، ابتدا از "Intent" برای نمایش لیست مخاطبین ذخیره شده استفاده خواهیم کرد.
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, {reqCode});
"reqCode" هر مقدار دلخواه با تایپ "int" است که جهت ایجاد وجه تمایز بین نتیجههای برگشتی استفاده میشود.
پساز انتخاب مخاطب توسط کاربر، نتیجه به روش "onActivityResult" برمیگردد.
@Override
public void onActivityResult(int reqCode, int resultCode, Intent data){
super.onActivityResult(reqCode, resultCode, data);
}
به منظور خواندن شماره همراه و نام مخاطب انتخاب شده توسط کاربر به صورت زیر عمل کنید.
Uri contactUri = data.getData();
String[] projection = {
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone._ID
}
Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null);
cursor.moveToNext();
Long id = cursor.getLong(cursor.getColumnIndex(projection[2]));
String name = cursor.getString(cursor.getColumnIndex(projection[1]));
String phoneNumber = cursor.getString(cursor.getColumnIndex(projection[0]));
cursor.close();
افزودن مخاطب
جهت افزودن مخاطب از طریق "Intent" از کد زیر استفاده کنید.'
Intent intent = new Intent(Intent.ACTION_INSERT);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
intent.putExtra(ContactsContract.Intents.Insert.NAME, "09xxxxxxxxx");
intent.putExtra(ContactsContract.Intents.Insert.PHONE, "John");
intent.putExtra(ContactsContract.Intents.Insert.EMAIL, "John@mail.com");
startActivity(intent);
در صورت تمایل به بسته شدن خودکار صفحهی مخاطبین مقدار زیر را همراه با "Intent" ارسال کنید.
intent.putExtra("finishActivityOnSaveCompleted", true)
ویرایش و حذف مخاطب
برای انجام عملیات حذف و ویرایش یک مخاطب، با استفاده از کد زیر، صفحهی جزئیات مخاطب ذخیره شده در دفترچه تلفن دستگاه را نمایش میدهیم، کاربر به انتخاب خود میتواند مخاطب نمایش دادهشده را حذف یا ویرایش کند.
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(contactID));
intent.setData(uri);
startActivity(intent);
"contactID" شناسهی مخاطب مورد نظر میباشد که میتوان به این صورت آنرا دریافت کرد.
افزودن رویداد به تقویم
جهت افزودن رویداد در تقویم از طریق "Intent" میتوان به روش زیر عمل کرد.
Intent intent = new Intent(Intent.ACTION_INSERT)
.setData(Events.CONTENT_URI)
.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
.putExtra(Events.TITLE, "title")
.putExtra(Events.DESCRIPTION, "description")
.putExtra(Events.EVENT_LOCATION, "location")
.putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
.putExtra(Intent.EXTRA_EMAIL, "example@gmail.com");
startActivity(intent);
پساز درج اطلاعات مورد نظر خود میتوانید از طریق "Intent" و تقویم پیشفرض دستگاه جهت افزودن رویداد استفاده کنید.
این نحوهی پیادهسازی نیازی به استفاده از دسترسی خاصی ندارد.
ارسال پیام کوتاه
به عنوان یکی از مهمترین بخشهای راهنمای دسترسی های اندروید جهت ارسال پیام کوتاه از طریق "Intent" میتوان به روش زیر عمل کرد.
Uri uri = Uri.parse("smsto:09xxxxxxxxx");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
intent.putExtra("sms_body", "The SMS text");
startActivity(intent);
پساز اجرای کد بالا، "Message App" دستگاه با اطلاعات ارسالی از طریق "Intent" نمایش داده میشود و کاربر با اختیار خود میتواند پیام را ارسال و یا آن را حذف کند. استفاده از "Intent" در ارسال پیام کوتاه نیازی به اضافه کردن دسترسی "Send SMS" ندارد.
نمایش بستههای نصب شده
با توجه به محدودیت اندروید ۱۱ در نمایش بستههای نصبشده روی دستگاه، جهت استفاده از روشهای زیر نیاز به افزودن دسترسی QUERY_ALL_PACKAGES در فایل مانیفست برنامه خواهد بود.
getInstalledApplications() و queryIntentActivities() ،getPackageInfo()
در برخی موارد و با درنظر گرفتن سیاستهای اپاستورهای متفاوت، جهت انتشار برنامههایی با این دسترسی، میتوان از راهحلهای جایگزین استفاده کرد.
نیاز به افزودن دسترسی QUERY_ALL_PACKAGES در فایل مانیفست برنامه خواهد بود.
در برخی موارد و با درنظر گرفتن سیاستهای اپاستورهای متفاوت، جهت انتشار برنامههایی با این دسترسی، میتوان از راهحلهای جایگزین استفاده کرد.
نمایش یک برنامهی نصبشده با نام بستهی مشخص
فرض کنید برنامهای به مشاهدهی وضعیت نصب برنامهی کروم روی دستگاه کاربر نیاز دارد.
<queries>
<package android:name="com.android.chrome"/>
</queries>
دسترسی "QUERY_ALL_PACKAGES" تمام بستههای نصب شده روی دستگاه را نمایش میدهد. این مورد ممکن است باعث نقض حریم خصوصی کاربران شود. با افزودن کد بالا در فایل مانیفست میتوانید دسترسی ذکر شده را حذف کنید، به طوری که مشکلی در عملکرد برنامه ایجاد نشود.
نمایش بستههای نصب شده با "mimeType" و "action" مشخص
<queries>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="image/jpeg" />
</intent>
</queries>
برای لیست کردن برنامههایی با "action" و "mimeType" مشخص میتوان از دستور بالا استفاده کرد.
دریافت وضعیت پرداخت در مرورگر و خارج از برنامه
همانطور که پیش از این در راهنمای دسترسی های اندروید گفتیم، با توجه به اینکه درگاه پرداخت باید در مرورگری خارج از برنامه بازگشایی و نمایش داده شود لازم است از طریقی برنامه، وضعیت پرداخت را جهت ارائه خدمات مناسب بررسی کند. فرض کنید پس از پرداخت بدون در نظر گرفتن وضعیت آن (موفق، ناموفق) مرورگر به آدرسی مانند آدرس زیر توسط سرور "Redirect" خواهد شد.
header('Location: https://myapplication.ir?q=valuee&s=success');
جهت بازگشایی برنامه توسط مرورگر پساز "Redirect" شدن به آدرس فوق باید در ابتدا با استفاده از "IntentFilter" برنامهی خود را به عنوان میزبان معرفی کنیم. فرض کنید وضعیت پرداخت باید به اکتیویتی با نام "PaymentActivity" برگردانده شود. برای اینکار تگ "activity" مربوط به اکتیویتی پرداخت در فایل "Manifest" به صورت زیر خواهد بود.
<activity android:name=".PaymentActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data
android:host="myapplication.ir"
android:scheme="https">
</data>
</intent-filter>
</activity>
با استفاده از تگ زیر "PaymentActivity" قادر خواهد بود تا توسط مرورگر فراخوانی شود.
<category android:name="android.intent.category.BROWSABLE"/>
با استفاده از تگ زیر، "Intent" ارسالی از مرورگر را فیلتر خواهیم کرد.
<data
android:host="myapplication.ir"
android:scheme="https">
</data>
با توجه به نحوهی پیادهسازی، برنامه هماکنون قادر خواهد بود آدرسهای باز شده در مرورگر با فرمت زیر را میزبانی کند.
https://myapplication.ir?q=valuee&s=success
پساز اجرای "PaymentActivity" توسط مرورگر، روش زیر صدا زده خواهد شد.
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if(intent.getAction() != null && intent.getAction().equals(Intent.ACTION_VIEW)) {
Uri uri = intent.getData();
try {
String q = uri.getQueryParameter("q");
String s = uri.getQueryParameter("s");
//do something with data
}catch (NullPointerException exception) { }
}
}
پیشنهاد میکنیم وضعیت پرداخت را از طریق "query-string" دریافت نکنید. بهتر است پساز بازگشت از مرورگر، برنامه وضعیت پرداخت را از منبعی معتبر مانند سرور سوال کند.
درج خودکار پیامک فعالسازی
برای تایید خودکار شماره تلفنها، باید هر دو بخش کلاینت و سرور تایید شماره همراه را پیاده سازی کنید. این سند نحوه پیادهسازی بخش مشتری در برنامه "Android" را توصیف می کند.
ابتدا "Play Services auth component" را در فایل "Gradle" خود اضافه کنید.
implementation 'com.google.android.gms:play-services-auth:19.0.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:17.5.0'
با راهنمای دسترسی برنامه های اندروید شما میتوانید شماره همراه کاربر را به هر صورت که برای برنامه شما مناسب است بدست آورید. غالباً پیادهسازی باکسی با امکان انتخاب شماره همراه ذخیرهشده در دستگاه تجربه کاربری زیباتری را به کاربر ارائه میدهد.
روش زیر به پیادهسازی این فرایند به شما کمک خواهد کرد. البته لازم به ذکر است حذف این مرحله مشکلی در عملکرد برنامه شما جهت خواندن خودکار پیامکها ایجاد نخواهد کرد.
private fun requestHint() {
val hintRequest = HintRequest.Builder().apply {
setPhoneNumberIdentifierSupported(true)
}
val credentialIntent =
Credentials.getClient(this).getHintPickerIntent(hintRequest.build())
startIntentSenderForResult(credentialIntent.intentSender, RESOLVE_HINT, null, 0, 0, 0)
}
شماره همراه انتخاب شده توسط کاربر به روش "onActivityResult" بر خواهد گشت.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RESOLVE_HINT)
if (resultCode == Activity.RESULT_OK) {
val credential = data?.getParcelableExtra<Credential>(Credential.EXTRA_KEY)
// Selected phone number
val phone = credential?.id;
}
}
جهت شروع فرایند تایید خودکار شماره همراه کاربر از روش زیر استفاده می کنیم.
fun smsRetriever() {
val smsRetriever = SmsRetriever.getClient(context)
val task = smsRetriever.startSmsRetriever()
task.addOnSuccessListener {
// Successfully started retriever, expect broadcast intent
// ...
}
task.addOnFailureListener {
// Failed to start retriever, inspect Exception for more details
// ...
}
}
فرایند فوق تنها برای ۵ دقیقه جهت دریافت پیامک حاوی کد فعالسازی و شناسهی منحصر به فرد برنامهی شما فعال خواهد بود.
زمانی که پیامک فعالسازی در دستگاه کاربر دریافت شد، سرویسهای گوگل یک "Intent" با اکشن "SmsRetriever.SMS_RETRIEVED_ACTION" ارسال خواهد کرد که حاوی متن پیام است.
جهت دریافت آن لازم است از یک "BroadcastReceiver" استفاده کنید.
class MBroadcastRetriever : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if(intent != null) {
if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) {
val extras = intent.extras
val status: Status? = extras!![SmsRetriever.EXTRA_STATUS] as Status
when (status?.statusCode) {
CommonStatusCodes.SUCCESS -> {
// Get SMS message contents
val smsMessage = extras[SmsRetriever.EXTRA_SMS_MESSAGE] as String?
}
CommonStatusCodes.TIMEOUT -> {
// Waiting for SMS timed out (5 minutes)
// Handle the error ...
}
}
}
}
}
}
همانطور که مشخص است، متن پیامک در متغیر "smsMessage" ذخیره شده است. شما میتوانید از این متغیر جهت درج خودکار کد فعالسازی در کادر مربوط استفاده کنید.
نکات مهم مربوط به قالب صحیح پیامک ارسالی:
- طول پیامک ارسالی نباید بیشتر از ۱۴۰ بایت باشد.
- متن پیامک حاوی یک کد فعالسازی یکبار مصرف است.
- متن پیامک شامل یک رشتهی منحصر به فرد ۱۱ کاراکتری است که برنامهی شما را مشخص میکند.
Your ExampleApp code is: 5489A2
FA+9qCX9VSu
محاسبه رشته یکتا برنامه
جهت محاسبهی رشته یکتا مربوط به برنامه از اسکریپت توسعهداده شده توسط گوگل استفاده کنید. ما بخشهایی از این اسکریپت را برای استفاده آسانتر تغییر دادیم. برای انجام این کار ابتدا پساز دریافت فایل اسکریپت، کد زیر را در محیط "command prompt" اجرا کنید.
./sms_retriever_hash_v9.sh --package "com.your.packagename" --keystore /path/to/your.keystore
فراموش نکنید نام بستهی برنامه و مسیر فایل "keystore" را متناسب با برنامهی خود تغییر دهید. خروجی اسکریپت یک فایل "sms_retriever_hash.txt" با محتویات زیر است.
SMS Retriever hash code: [value: (example IOhh7MhVDB5)]
First 8 bytes encoded by base64: [value]
SHA-256 output in hex: [value]
certificate in hex: [value]
مقدار "SMS Retriever hash code" چکیده برنامهی شماست که در متن پیامک ارسال خواهد شد.
در نهایت میتوانید سوالات خود در رابطه با دسترسی های اندروید را از طریق ثبت تیکت یا تماس با شماره ۰۲۱۹۱۰۰۹۷۹۸ با پشتیبانی توسعه دهندگان بازار در میان بگذارید.
به مطالب ارائه شده چه امتیازی میدهید؟
اگر در مورد محتوا نظر یا پیشنهادی دارید لطفا برای ما بنویسید.
زمان انتشار: ۱۴۰۱-۰۲-۲۰ ۰۷:۵۱
آخرین بهروزرسانی: ۱۴۰۱-۰۲-۲۰ ۱۰:۵۴