2015-12-10 10 views
5

ギャラリーから画像を取得して画像ビューに設定しようとしていますが、Android 6では権限の問題があります。以下は、許可を求める方法です。外部ストレージを読み込むか外部ストレージに書き込むかを尋ねてください。Android 6の権限の方法を理解する

private static final int READ_CONTACTS_PERMISSIONS_REQUEST = 1; 


    public void getPermissionToReadExternalStorage() { 

    if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) 
      != PackageManager.PERMISSION_GRANTED) { 

     if (shouldShowRequestPermissionRationale(
       Manifest.permission.READ_EXTERNAL_STORAGE)) { 

      requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
        READ_CONTACTS_PERMISSIONS_REQUEST); 
     }}} 
    @Override 
      public void onRequestPermissionsResult(int requestCode, 
                @NonNull String permissions[], 
                @NonNull int[] grantResults){ 
       // Make sure it's our original READ_CONTACTS request 
       if (requestCode == READ_CONTACTS_PERMISSIONS_REQUEST) { 
        if (grantResults.length == 1 && 
          grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
         Toast.makeText(getActivity(), "Read Contacts permission granted", Toast.LENGTH_SHORT).show(); 

        } else { 
         Toast.makeText(getActivity(), "Read Contacts permission denied", Toast.LENGTH_SHORT).show(); 
        } 
       } else { 
        super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
       } 
      } 

を今私のクリックのリスナーにギャラリーからデータを選択する:

 pro.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
      intent.setType("image/*"); 
      if (android.os.Build.VERSION.SDK_INT >= 23) { 
       getPermissionToReadExternalStorage(); 
       if (getPermissionToReadExternalStorage() this???? <==) 
       startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0); 
      } else { 
       startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0); 
     }} 

    }); 
    return v; 
} 

は今、私はこの方法getPermissionToReadExternalStorage()ので、結果を取得したい。ここ

は、私がこれまでにやっていることですAndroid 6のギャラリーを選ぶためのアクティビティを開始できます。voidクラスの結果を取得するにはどうすればよいですか? もう1つのことは、私のアプリケーションが要求するすべてのアクセス許可のためにメソッドを記述しなければならないのですか?

答えて

6

私は完全にコードを書き換えて権限を要求しました。 これは、複数のアクセス権を要求し、適切な結果でコードを実行することをサポートします。 preMarshmallowデバイスでも動作しますので、その場合はコードをチェックしてコピーする必要はありません。

まず、このコードでActivityクラスを作成します(あなたが必要とする活動のいずれかの王、例えばAppCompatActivity拡張することができます):

を:あなたは、このクラスを追加し、断片からの許可を要求する場合

public abstract class PermissionActivity extends AppCompatActivity { 

    private final ArrayList<PermissionListener> permissionListeners = new ArrayList<>(); 

    @SuppressWarnings("unused") 
    public void requestPermissions(int requestCode, String[] requestPermissions, PermissionListener permissionListener) { 
     requestPermissions(requestCode, requestPermissions, null, permissionListener); 
    } 

    @SuppressWarnings("unused") 
    public void requestPermissions(final int requestCode, String[] requestPermissions, String message, final PermissionListener permissionListener) { 
     final int[] grantResults = new int[requestPermissions.length]; 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
      ArrayList<String> list_notGranted = new ArrayList<>(); 

      for (String requestPermission : requestPermissions) 
       if (ContextCompat.checkSelfPermission(this, requestPermission) != PackageManager.PERMISSION_GRANTED) 
        list_notGranted.add(requestPermission); 

      if (list_notGranted.size() > 0) { 
       permissionListeners.add(permissionListener); 

       requestPermissions = list_notGranted.toArray(new String[list_notGranted.size()]); 

       if (message != null) { 
        boolean shouldShowRequestPermissionRationale = false; 

        for (String permission : requestPermissions) 
         if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { 
          shouldShowRequestPermissionRationale = true; 
          break; 
         } 

        if (shouldShowRequestPermissionRationale) { 
         final String[] f_requestPermissions = requestPermissions; 

         AlertDialog.Builder builder = new AlertDialog.Builder(this); 

         builder.setMessage(message); 

         DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() { 

          @TargetApi(Build.VERSION_CODES.M) 
          @Override 
          public void onClick(DialogInterface dialog, int which) { 
           switch (which) { 
            case DialogInterface.BUTTON_POSITIVE: 
             PermissionActivity.super.requestPermissions(f_requestPermissions, requestCode); 
             break; 
            default: 
             for (int i = 0; i < grantResults.length; i++) 
              grantResults[i] = PackageManager.PERMISSION_DENIED; 

             if (permissionListener != null) 
              permissionListener.onResult(requestCode, f_requestPermissions, grantResults); 
             break; 
           } 
          } 
         }; 

         builder.setPositiveButton("OK", onClickListener); 
         builder.setNegativeButton("Cancel", onClickListener); 

         builder.show(); 
        } else { 
         super.requestPermissions(requestPermissions, requestCode); 
        } 
       } else { 
        super.requestPermissions(requestPermissions, requestCode); 
       } 
      } else { 
       for (int i = 0; i < grantResults.length; i++) 
        grantResults[i] = PackageManager.PERMISSION_GRANTED; 

       if (permissionListener != null) 
        permissionListener.onResult(requestCode, requestPermissions, grantResults); 
      } 
     } else { 
      if (permissionListener != null) { 
       for (int i = 0; i < grantResults.length; i++) 
        grantResults[i] = PackageManager.PERMISSION_GRANTED; 

       permissionListener.onResult(requestCode, requestPermissions, grantResults); 
      } 
     } 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { 
     for (Iterator<PermissionListener> it = permissionListeners.iterator(); it.hasNext();) { 
      PermissionListener permissionListener = it.next(); 
      if (permissionListener.onResult(requestCode, permissions, grantResults)) { 
       it.remove(); 
      } 
     } 
    } 

    public interface PermissionListener { 

     boolean onResult(int requestCode, String[] requestPermissions, int[] grantResults); 

    } 
} 

public class PermissionFragment extends Fragment { 

    @SuppressWarnings("unused") 
    public void requestPermissions(int requestCode, String[] requestPermissions, PermissionActivity.PermissionListener permissionListener) { 
     requestPermissions(requestCode, requestPermissions, null, permissionListener); 
    } 

    @SuppressWarnings("unused") 
    public void requestPermissions(final int requestCode, String[] requestPermissions, String message, PermissionActivity.PermissionListener permissionListener) { 
     ((PermissionActivity) getActivity()).requestPermissions(requestCode, requestPermissions, message, permissionListener); 
    } 
} 

アクティビティとフラグメントは、スタンダードオブジェクトではなく、これらのクラスを拡張する必要があります。

今、あなたがメソッドを呼び出すことにより、権限を要求する準備ができている:

requestPermissions(int requestCode, String[] requestPermissions, PermissionListener permissionListener) 

許可が仕事へのアプリのために必要とされている場合は、このメソッドを呼び出すと、権限が必要な理由というメッセージを指定する必要があります。

requestPermissions(int requestCode, String[] requestPermissions, String message, PermissionListener permissionListener) 

DONT MISSCALLここ

// DON'T USE THIS ONE! 
requestPermissions(String[] requestPermissions, int requestCode) 
// DON'T USE THIS ONE! 

されているデフォルトの方法は、連絡先を要求する例を示します。

private void requestAndLoadContacts() { 
    String[] permissions = new String[]{Manifest.permission.READ_CONTACTS}; 

    requestPermissions(REQUEST_PERMISSIONS_CONTACTS, permissions, "Read contacts permission is required for the app to work!", new PermissionListener() { 

     @Override 
     public boolean onResult(int requestCode, String[] requestPermissions, int[] grantResults) { 
      // Check if the requestCode is ours 
      if (requestCode == REQUEST_PERMISSIONS_CONTACTS) { 
       // Check if the permission is correct and is granted 
       if (requestPermissions[0].equals(Manifest.permission.READ_CONTACTS) && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
        // Permission granted 
        // Calling a method to actually load the contacts 
        loadContacts(); 
       } else { 
        // Permission not granted 
        Toast.makeText(MainActivity.this, "Access denied!", Toast.LENGTH_SHORT).show(); 
       } 

       return true; 
      } 

      return false; 
     } 
    }); 
} 

注: あなたがPermissionListenerを実装する場合、忘れてはいけませんを返すrequestCodeが正しい場合、その他PermissionListenerとはArrayListからを削除されず、ほとんどメモリリークが発生しません。

+0

おかげで、dude.iがあなたを手に入れました。 –

+0

良いアイデア!古いアンドロイドバージョンを扱うContextCompatを使用して改善することは可能ですか?ありがとうございました! – Gilian

+1

しかし、 "permissionListeners.remove(permissionListener);" ConcurrentModificationExceptionをスローしないでください。 – Gilian

0

EDIT

私は、コードをrewrittedし、別の答えに掲載しています。

旧答え:

はい、あなたはすべての時間を確認し、許可を求める必要があります。

は通常、私はこのようなコードを書く:

private int requestPermissionCode; 
private Runnable requestPermissionRunnable; 

private void runPermissionCode(String requestPermission, int requestCode, Runnable codeToRun) { 
    if (android.os.Build.VERSION.SDK_INT >= 23) { 
     if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) 
       != PackageManager.PERMISSION_GRANTED) { 

      requestPermissionCode = requestCode; 
      requestPermissionRunnable = codeToRun; 

      requestPermissions(new String[]{requestPermission}, 
        requestCode); 
     } 
    } else { 
     codeToRun.run(); 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, 
             @NonNull String permissions[], 
             @NonNull int[] grantResults) { 
    if (requestCode == requestPermissionCode) { 
     if (grantResults.length == 1 && 
       grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

      if (requestPermissionRunnable != null) 
       requestPermissionRunnable.run(); 
     } else { 
      Toast.makeText(getActivity(), "Permission denied", Toast.LENGTH_SHORT).show(); 
     } 
    } else { 
     super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    } 
} 

をし、このようにそれを実行します。

runPermissionCode(Manifest.permission.READ_EXTERNAL_STORAGE, READ_CONTACTS_PERMISSIONS_REQUEST, new Runnable() { 

     @Override 
     public void run() { 
      // your code here 
     } 
    }); 

を、私はそれが最善の方法ではありません確信しているが、少なくともそれはへの可能性を提供します権限を要求し、操作を簡単にする。

+0

onRequestPermissionsResult権限のための方法を確認してくださいしかし、どのようにあなたがそれを使うのですか?ユーザーが何かをクリックしようとしているときにそれを使うか?????あなたの仕事を行うことができる許可が与えられます。私の場合、どうやって使用しますか?他のケースではリスナーのようなコードを私に表示するだけです。 –

0

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
     if (!canAccessAccounts()|| !canAccessLocation() ||!canAccessInternet()) { 
      requestPermissions(INITIAL_PERMS, INITIAL_REQUEST); 
     } 
    } 

チェック許可が付与された権限のための装置および要求のためにあなたの許可

private static final int INITIAL_REQUEST = 1337; 
private static final int GET_ACCOUNTS = INITIAL_REQUEST+2; 
private static final int LOCATION_REQUEST =INITIAL_REQUEST+3; 

private static final String[] INITIAL_PERMS = { 
     Manifest.permission.GET_ACCOUNTS, 
     Manifest.permission.INTERNET, 
     Manifest.permission.ACCESS_FINE_LOCATION 
}; 

チェックを初期化したりしませ

private boolean canAccessAccounts() { 

    return (hasPermission(Manifest.permission.GET_ACCOUNTS)); 
} 
private boolean canAccessLocation() { 

    return (hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)); 
} 
private boolean canAccessInternet() { 
    return (hasPermission(Manifest.permission.INTERNET)); 
} 
private boolean hasPermission(String perm) { 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
     return (PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm)); 
    } 
    return (true); 
} 

更新権限と

void UpdatePermissions(){ 

    canAccessInternet(); 
    canAccessLocation(); 
    canAccessInternet(); 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
    UpdatePermissions(); 
    switch(requestCode) { 
     case GET_ACCOUNTS: 
      if (canAccessAccounts()) { 

      } 
      else { 

      } 
      break; 

     case LOCATION_REQUEST: 
      if (canAccessLocation()) { 

      } 
      else { 

      } 
      break; 

     case INITIAL_REQUEST: 
      if(canAccessInternet()){ 

      }else { 

      } 
      break; 

    } 
} 
関連する問題