آموزش RunTime Permission در برنامه نویسی اندروید
سلام دوستان در این سری از آموزش های برنامه نویسی اندروید به آموزش RunTime Permission در برنامه نویسی اندروید می پردازیم. شاید سوال شما این باشد که این دسترسی در زمان اجرا یا Runtime Permission به چه دردی می خورند و اصلا کاربردی دارند؟ زمانی که کاربر دارد اپلیکیشن شما را نصب می کند در بخش permission هیچ دسترسی نشان داده نمی شود ! و گفتنی است که RunTime Permission از Api 23 یا Marshmallow وارد اندروید شده است و زمانی که شما در خال ساخت پروژه خود هستید باید MinSdk را برابر با 23 قرار دهید همانطور که گفتیم این دسترسی ها به کاربر نمایش داده نمی شود اما به جای آن از در هنگام استفاده از برنامه پرسیده می شود که آیا اجازه میدهید این اپ به طور مثال از اینترنت استفاده کند و دقت کنید شما باید همانند قبل دسترسی ها را در AndroidManifest.xml قرار دهید. در ادامه به مثالی از نحوه استفاده از آن می پردازم.
ما به یکسری از دسترسی های می پردازیم بقیه ی آنها نیز به همین شکل هستند.
ابتدا فایل AndroidManifest.xml را باز کرده دسترسی ها را اضافه کنید.
1 2 3 4 5 6 7 | <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.CALL_PHONE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.GET_ACCOUNTS"/> |
فایل Activity_main.xml را باز کرده کدهای زیر را در آن قرار دهید در ادامه آنها را توضیح می دهیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.theodhor.runtimepermissions.MainActivity"> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Location" android:id="@+id/location" android:layout_marginBottom="10dp" android:onClick="ask" /> <Button style="?android:attr/buttonStyleSmall" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Write ExStorage" android:id="@+id/write" android:onClick="ask" android:layout_marginBottom="10dp" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Read ExStorage" android:id="@+id/read" android:layout_marginBottom="10dp" android:onClick="ask" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Call" android:id="@+id/call" android:layout_marginBottom="10dp" android:onClick="ask" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Camera" android:id="@+id/camera" android:layout_marginBottom="10dp" android:onClick="ask" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Get Accounts" android:id="@+id/accounts" android:layout_marginBottom="10dp" android:onClick="ask" /> </LinearLayout> </RelativeLayout> |
در بالا تعدادی دکمه است با کلیک کردن بروی آنها اجزای دسترسی از کاربر گرفته می شود.
layout شما همانند زیر می شود.
بعد از نصب برنامه یک صفحه برای شما می آید (فقط در گوشی هایی با API 23 به بالا) که از شما می پرسد آیا می خواهید این برنامه این دسترسی ها را داشته باشد شما همه را فعال کرده تا تست برنامه را ببینید (همانند عکس زیر)
کد های زیر بعد از Oncreate قرار دهید(قبل از آخرین علامت آکولاد بسته زیرا این یک void است )
1 2 3 4 5 6 7 8 9 10 11 | private void askForPermission(String permission, Integer requestCode) { if (ContextCompat.checkSelfPermission(MainActivity.this, permission) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode); } else { ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode); } } else { Toast.makeText(this, "" + permission + " is already granted.", Toast.LENGTH_SHORT).show(); } } |
در صورتی که شما در مرحله قبل دسترسی ها را باز نکرده باشید ما یک Void داریم که تشخیص می دهد که آیا شما آن دسترسی ها را داده اید یا خیر البته این void دو مقدار ورودی دارد به خاطر اینکه ما می خواهیم چندین دسترسی را بررسی کنیم به این شکل آن را ایجاد کرده ایم و در صورتی که قبلا این دسترسی را داده باشید با پیام permission is already granted روبه رو خواهید شد.
این void ما دو مقدار ورودی دارد اولی نام آن که به صورت رشته است و دومی کد دسترسی آن که از نوع عددی (integer) است.
کد زیر را هم بعد از Oncreate اضافه کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public void ask(View v){ switch (v.getId()){ case R.id.location: askForPermission(Manifest.permission.ACCESS_FINE_LOCATION,LOCATION); break; case R.id.call: askForPermission(Manifest.permission.CALL_PHONE,CALL); break; case R.id.write: askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,WRITE_EXST); break; case R.id.read: askForPermission(Manifest.permission.READ_EXTERNAL_STORAGE,READ_EXST); break; case R.id.camera: askForPermission(Manifest.permission.CAMERA,CAMERA); break; case R.id.accounts: askForPermission(Manifest.permission.GET_ACCOUNTS,ACCOUNTS); break; default: break; } } |
این کد برای این است که برنامه تشخصی دهد شما روی چه دکمه ای کلیک کرده اید و بعد از کلیک یک پیام به شما نمایش میدهد که آیا شما اجزای دسترسی می دهید یا خیر .
همانطور که گفتیم آن Void ما مقدار ورودی دوم ان به صورت عددی است و نیاز دارد تا مقداری برای آن فرستاده شود برای همین باید کد زیر را قبل از Oncreate اضافه کنید.
1 2 3 4 5 6 7 | static final Integer LOCATION = 0x1; static final Integer CALL = 0x2; static final Integer WRITE_EXST = 0x3; static final Integer READ_EXST = 0x4; static final Integer CAMERA = 0x5; static final Integer ACCOUNTS = 0x6; static final Integer GPS_SETTINGS = 0x7; |
عدد های بالا مقدار های عددی هر یک از دسترسی ها است.
برای اینکه بعد تایید یا رد کردن دسترسی توسط کاربر ما کاری انجام دهیم (زمانی که به ما دسترسی میدهد یا نمی دهد)
باید کد زیر را اضافه کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED){ switch (requestCode) { //Call case 2: Intent callIntent = new Intent(Intent.ACTION_CALL); callIntent.setData(Uri.parse("tel:" + "{This is a telephone number}")); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { startActivity(callIntent); } break; //Write external Storage case 3: break; //Read External Storage case 4: Intent imageIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(imageIntent, 11); break; //Camera case 5: Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(takePictureIntent, 12); } break; //Accounts case 6: AccountManager manager = (AccountManager) getSystemService(ACCOUNT_SERVICE); Account[] list = manager.getAccounts(); Toast.makeText(this,""+list[0].name,Toast.LENGTH_SHORT).show(); for(int i=0; i<list.length;i++){ Log.e("Account "+i,""+list[i].name); } } Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show(); } } |
کد های بالا یک request برای انجام یک کار به طور مثال نوشتن در حافظه یا خواندن از جافظه می فرستد و قبل از آن از کاربر می خواهد که دسترسی آن کار را بدهد در صورتی که دسترسی دهد پیام Permission Granted و در صورتی که نپذیر پیام Permission denied نمایش داده می شود.
این آموزش هم به پایان رسید .
موفق باشید.
سلام، واقعا دمتون گرم، خیلی نیاز به این آموزش داشتم وبسایت. ها و انجمن های خارجی زیادی رو سرچ کردم ولی جواب درستی نگرفتم واقعا عالی بود مرسی
سلام خواهش می کنم
سلام . واقعا فوق العاده بود . حیفم اومد تشکر نکنم
سلام و درود خواهش می کنم نظر لطف شماست.
خیلی ممنون بابت زحماتتون دمتون گرم
سلام. .ممنونم. با این روش اگر گوشی Api 23 نبود و کمتر بود، گوشی چه عملکردی خواهد داشت؟
سلام عملکرد خاصی نباید داشته باشد.
سلام سپاس گذارم از زمان و صبری که گذاشتید. بسیار شیوا وصحیح بود <3
سلام خسته نباشید من میخوام این دسترسی هارو از داخل کلاس g بگیرم چون توی اون باید برنامم حافظه رو بخونه میشه بگید توی context ها چی بزارم چون گیر میده هرچی میزارم
instance اکتیویتی رو قرار دهید.
سلام
با تشکز فراوان از شما .
یک سوال داشتم خدمتتان .
من یک برنامه نوشتم که بارکد خوان هست و اطلاعات بارکد رو می خونه و به سرور ارسال می کنه و یک سری اطلاعات که مرتبط با اون بارکد هست رو از دیتابیس میگیره به روش جی سون و به کاربر نمایش میده .( یک سیستم کنترل تردد )
این برنامه به خوبی با اندروید نسخه های 4 و 5 کار می کنه و هیچ مشکلی نداره .
اما وقتی بر روی اندروید 6 به بالا نصب می کنم . برنامه اجرا میشه و وقتی هم که می خواد بارکد رو بخونه . از کاربر اجازه دسترسی هم سوال می کنه . اما بعد از خواندن بارکد ، برنامه متوقف میشه یا خارج میشه (کرش) و یا دوباره برنامه از اول اجرا میشه . و نمی تونه کار مورد نظر رو انحام بده .
minisdk برنامه 16 هست .
به نظر شما اشکال از چی می تونه باشه که در نسخه های شش به بالا کار نمی کنه و نمی تونه اتصال برقرار کنه ؟
سلام و درود
لاگ قرار دهید بررسی کنیم.
خدا خیرت بده
ممنون
با سلام و خسته نباشید ممنون از مطالبتون فقط یه سوال خوب من می خوام که این دسترسی ها رو قبل از نصب برنامه بهش اضافه کنم و دیگه هیچ نیازی نباشه که بخوایم بریم داخل برنامه و بهش دسترسی بدیم چون بعضی از برنامه ها قبلش این دسترسی ها رو دارند ولی بعضی برنامه ها باید نصب بشه و بعد دسترسی بدیم لطفا راهنمایی کنید که من این دسترسی ها رو بهش بدم قبل نصب خیلی ممنون از سایت خوبتون با تشکر
خسته نباشید… ببخشید .. همه متد ها قبل یا بعد از onCreate قرار گرفتن؟ یعنی تو خودت onCreate چیزی نباید باشه؟
تشکر دوست عزیز. خیلی خوب این بحث رو توضیح دادین.
سلام من یه سورس دارم میخوام از کاربر دسترسی لوکیشن بگیره زیاد هم فعلا حرفه ای نیستم میخواستم اگه بشه شما واسم انجام بدید شماره واتس اپ 09227043976 من راه ارتباطی پیدا نکردم با شما پیام بدید در مورد هزینش هم صحبت کنیم
سلام ، خسته نباشید.
میشه بگین وقتی این کدها رو وارد کردم ،
Import بالای صفحه باید چی باشند؟
من برام هشتتا تا ارور اومد!! (در اصل 2تان که تکرار شدند)
ارور اول :
Unknown variable or field “requestcode
دومی :
Unknown method ShouldShowRequestPermission of com.company.access.ActivityCompat