Android——華為手機(G9)調用Camera需要手動申請權限


1. 背景

Environment.getExternalStorageDirectory()是Android 2.x時代的產物,那時Android主流設備只有很小的內置存儲器,然后都會外置一張sd卡,那時這個方法返回的就是外置sd卡的根路徑。

但隨着Android進入4.x時代,大部分Android設備都已經內置一個較大存儲卡,甚至不提供外置存儲卡插槽了,此時Environment.getExternalStorageDirectory()返回的路徑其實是由內置存儲卡虛擬出來的一個目錄,用戶在這一目錄下有全部權限。

按理說Android應該繼續提供其他的方法來返回其他的外置存儲卡的路徑,但這一次Android卻沒有,因為Android系統開發者們發現之前直接允許程序任意訪問sd卡的做法導致sd卡上垃圾文件的不可管理性,尤其在程序被卸載后,由於不知道那些文件是由這一程序創建的,所以無法關聯刪除,因此Android 4.0並不給程序開發者提供外置存儲卡的路徑,而是提供了諸如getExternalFilesDirs()和getExternalCacheDirs()這樣的方法,直接給開發者提供一個限制內的存儲文件的空間,這個空間是與程序關聯的,因此在卸載程序時這兩個目錄下的文件也會被關聯刪除。

 

2.問題一

在AndroidManifest里寫入了相機權限,讀寫權限,但華為手機調用Camera失敗,無法寫入手機內存等。

原因:Android系統從6.0版本開始增加了一種運行時權限,Camera正好屬於運行時權限,這種權限的授權不像6.0以前的Android系統可以安裝APP的時候就一次性授權。所以需要在代碼里手動申請權限。某些程序在華為G9上一測試就崩掉的原因:程序在運行中請求camera.open()時實際上程序並未獲得操作Camera的權限,所以camera.open()會一直打開失敗。對於運行時權限不清楚的可以百度搜索Android6.0運行時權限。

 

問題二

華為G9手機Environment.getExternalStorageDirectory()得到的是什么?

答:從手機上自帶的文件管理器來看,上面有兩個存儲位置,一個是內部存儲,是華為G9內置的SD卡;一個是SanDisk SD 卡,這個是自己買的然后安裝上去的。那么,用Environment.getExternalStorageDirectory()得到的是哪個內存里的路徑呢?該方法得到的是/storage/emulated/0是內部存儲,也就是華為G9內置的SD卡,當然這是我經過測試后得到的,如下圖所示。

 

問題三

使用ContextCompat和ActivityCompat報錯

原因:因為這兩個是sdk19以上版本v4包新加的,所以要導入V4包,最好是導入最新的版本,步驟file->project structure->dependencies->右邊“+”號然后添加v4包即可。

 

 

代碼部分就只寫最主要的吧,最底下有源碼地址

MainActivity.java

public class MainActivity extends Activity {
    public static final int TAKE_PHOTO = 1;
    public static final int CROP_PHOTO = 2;
    private static final String IMAGE_FILE_NAME = "head_image.jpg";// 頭像文件
    private static final int CODE_CAMERA_REQUEST = 0xa1;//拍照請求碼
    private static String[] PERMISSIONS_STORAGE = {
//            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,//寫權限
            Manifest.permission.CAMERA//照相權限
    };
    private Button btn;
    private ImageView img;
    private Uri imageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.take_photo);
        img = (ImageView) findViewById(R.id.picture);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //用intent調用相機
                Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                //判斷sd卡是否可用
                if (SDCardUtils.isSDCardEnable()){
                    //ContentValues與HashMap類似,但ContentValues只能保存數據類型,不能保存對象類型
                    ContentValues values = new ContentValues();
                    //key-value形式
                    values.put(MediaStore.Images.Media.TITLE,IMAGE_FILE_NAME);
                    //EXTRA_OUTPUT用於存儲所請求的圖像或視頻的解析Uri
                    imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),IMAGE_FILE_NAME));
                    intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
                }
                //
                startActivityForResult(intentFromCapture,CODE_CAMERA_REQUEST);
            }
        });


        //用於判斷SDK版本是否大於23
        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            //檢查權限
            int i = ContextCompat.checkSelfPermission(this,PERMISSIONS_STORAGE[0]);
            //如果權限申請失敗,則重新申請權限
            if(i!= PackageManager.PERMISSION_GRANTED){
                //重新申請權限函數
                startRequestPermission();
                Log.e("這里","權限請求成功");
            }
        }
    }

    /**
     * 重新申請權限函數
     */
    private void startRequestPermission(){
        //321為請求碼
        ActivityCompat.requestPermissions(this,PERMISSIONS_STORAGE,321);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode==CODE_CAMERA_REQUEST&&resultCode==RESULT_OK){
            try {
                Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                img.setImageBitmap(bitmap);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
}

 源碼地址:http://download.csdn.net/detail/u013293125/9737050


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM