2016-05-30 16 views
11

Tôi xây dựng một ứng dụng lấy mẫu GPS khi khởi động. Như bạn có thể đã biết, các quyền được yêu cầu trong thời gian chạy từ Android M trở lên.Đợi cho phép người dùng

Vì vậy, trong trường hợp của tôi tôi bắt đầu với việc kiểm tra nếu quyền là cần thiết, như thế này:

private void permissionForAndroidM() 
{ 
    if (Build.VERSION.SDK_INT > 22) { 
     String[] allPermissionNeeded = { 
       Manifest.permission.WRITE_EXTERNAL_STORAGE, 
       Manifest.permission.ACCESS_FINE_LOCATION, 
       Manifest.permission.ACCESS_COARSE_LOCATION, 
       Manifest.permission.CAMERA, 
       Manifest.permission.RECORD_AUDIO}; 

     List<String> permissionNeeded = new ArrayList<>(); 
     for (String permission : allPermissionNeeded) 
      if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) 
       permissionNeeded.add(permission); 
     if (permissionNeeded.size() > 0) { 
      requestPermissions(permissionNeeded.toArray(new String[0]), 0); 
     } 
    } 
} 

nhưng Android tiếp tục chạy mã và yêu cầu dữ liệu GPS (= sụp đổ, vì người sử dụng không chấp nhận yêu cầu cấp phép).

Tôi tìm thấy nhiều giải pháp về việc chờ đầu vào của người dùng (như sử dụng DialogInterface.OnClickListener, link, nhưng không thể triển khai trong trường hợp này, vì tôi không tạo hộp thoại).

Điểm mấu chốt, câu hỏi: Làm cách nào để chờ câu trả lời của người dùng từ hộp thoại cho phép Android?

+2

Chỉ cần ghi đè onRequestPermissionsResult() –

+0

Cảm ơn bạn rất nhiều, tôi did't biết về phương pháp này – AsfK

Trả lời

8

Bạn có thể xử lý phản ứng sử dụng phương pháp trọng

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) 

từ hoạt động của bạn.

11

Android tiếp tục chạy mã và yêu cầu dữ liệu GPS (= lỗi, vì người dùng không chấp nhận yêu cầu cấp phép).

Giống như nhiều thứ trong Android, requestPermissions() không đồng bộ. Người dùng thậm chí không được nhắc về các quyền cho đến khi phương thức này trả về.

Làm cách nào để chờ câu trả lời của người dùng từ hộp thoại cho phép Android?

Bạn không.

Nếu bạn thấy rằng bạn đã có sự cho phép, bạn thực hiện công việc của mình. Nếu bạn thấy rằng bạn phải yêu cầu sự cho phép, bạn trì hoãn thực hiện công việc đó cho đến khi bạn nhận được sự cho phép, trong onRequestPermissionsResult().

4

tôi làm việc đó một cách dưới đây:

1- Tạo một helper Boolean để kiểm tra quyền được cấp:

public class UtilPermissions { 
    public static boolean hasPermissions(Context context, String... allPermissionNeeded) 
    { 
     if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M 
       && context != null && allPermissionNeeded != null) 
      for (String permission : allPermissionNeeded) 
       if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) 
        return false; 
     return true; 
    } 
} 

2- Tạo một Splash màn hình như:

public class Splash extends Activity { 
    private static final int PERMISSION_ALL = 0; 
    private Handler h; 
    private Runnable r; 
    /* 
    SharedPreferences mPrefs; 
    final String settingScreenShownPref = "settingScreenShown"; 
    final String versionCheckedPref = "versionChecked"; 
    */ 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     h = new Handler(); 
     r = new Runnable() { 
      @Override 
      public void run() { 
       Toast.makeText(Splash.this, "Runnable started", Toast.LENGTH_SHORT).show(); 

    /*   // (OPTIONAL) these lines to check if the `First run` ativity is required 
       int versionCode = BuildConfig.VERSION_CODE; 
       String versionName = BuildConfig.VERSION_NAME; 

       mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 
       SharedPreferences.Editor editor = mPrefs.edit(); 

       Boolean settingScreenShown = mPrefs.getBoolean(settingScreenShownPref, false); 
       int savedVersionCode = mPrefs.getInt(versionCheckedPref, 1); 

       if (!settingScreenShown || savedVersionCode != versionCode) { 
        startActivity(new Intent(Splash.this, FirstRun.class)); 
        editor.putBoolean(settingScreenShownPref, true); 
        editor.putInt(versionCheckedPref, versionCode); 
        editor.commit(); 
       } 
       else 
    */ 
       startActivity(new Intent(Splash.this, MainActivity.class)); 
       finish();  
      } 
     }; 

     String[] PERMISSIONS = { 
       READ_PHONE_STATE, 
       MODIFY_AUDIO_SETTINGS, 
       ACCESS_FINE_LOCATION, 
       READ_SMS 
     }; 

     if(!UtilPermissions.hasPermissions(this, PERMISSIONS)){ 
      ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL); 
     } 
     else 
      h.postDelayed(r, 1500); 
    } 

    // Put the below OnRequestPermissionsResult code here 
} 

3- Đã tạo OnRequestPermissionsResult như sau:

@Override 
public void onRequestPermissionsResult(int requestCode, 
             String permissions[], int[] grantResults) { 

    int index = 0; 
    Map<String, Integer> PermissionsMap = new HashMap<String, Integer>(); 
    for (String permission : permissions){ 
     PermissionsMap.put(permission, grantResults[index]); 
     index++; 
    } 

    if((PermissionsMap.get(ACCESS_FINE_LOCATION) != 0) 
      || PermissionsMap.get(READ_SMS) != 0){ 
     Toast.makeText(this, "Location and SMS permissions are a must", Toast.LENGTH_SHORT).show(); 
     finish(); 
    } 
    else 
    { 
     h.postDelayed(r, 1500); 
    } 
} 

4- định nghĩa màn hình Splash như Launcher trong AndroidManifest.xml như:

<activity 
    android:name=".MainActivity" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme.NoActionBar"> 
</activity> 

<activity 
    android:name=".Splash" 
    android:configChanges="orientation|keyboardHidden|screenSize" 
    android:theme="@style/SplashTheme"> 

    <intent-filter> 
     <action android:name="android.intent.action.MAIN" /> 
     <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 
</activity> 

5- Trong styles.xml xác định SplashTheme như:

<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar"> 
    <item name="android:windowBackground">@drawable/Splash</item> 
</style> 

6- Các @drawable/Splash.xmls là:

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item 
     android:drawable="@color/lightgray"/> 

    <item> 
     <bitmap 
      android:gravity="center" 
      android:src="@mipmap/ic_launcher"/> 
    </item> 

</layer-list> 

7- Trong values/colors.xmls các lightgray màu đã được xác định như sau:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <color name="lightgray">#D3D3D3</color> 
</resources> 
Các vấn đề liên quan