當前位置:
首頁 >
Android7.0以上如何获取头像(拍照或者从相册中选择)
發布時間:2024/1/8
40
豆豆
生活随笔
收集整理的這篇文章主要介紹了
Android7.0以上如何获取头像(拍照或者从相册中选择)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
大概的流程
2.1創建存放圖片的文件夾
2.2將文件夾路徑轉換為uri
2.3隱式啟動相機的Activity,uri作為intent的一個參數.
2.4拍照結束后,執行onActivityResult(…)獲得圖片
3.1啟動相冊Activity
3.2選擇結束后,執行onActivityResult(…)獲得圖片
1、動態獲取權限
(1)AndroidManifest.xml添加如下權限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CAMERA" /> <activityandroid:name=".UserBaseInfoActivity"android:windowSoftInputMode="stateHidden"><intent-filter><action android:name="androd.media.action.IMAGE_CAPTURE"/><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity>(2)通過代碼動態獲取權限:
//判斷android版本號,彈出申請權限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {showConfirmAppPermissions();//添加以下代碼,否則Android7.0以后調用相機時會出現閃退的問題StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();StrictMode.setVmPolicy(builder.build());} // 7.0動態申請權限 public void showConfirmAppPermissions() {if (ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) !=PackageManager.PERMISSION_GRANTED) {if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)) {} else {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 1);}} }2、布局文件xml的代碼如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:background="@color/colorLightGray"xmlns:android="http://schemas.android.com/apk/res/android"><RelativeLayoutandroid:id="@+id/UserBaseInfo_RLayoutTitle"android:layout_width="match_parent"android:layout_height="50dp"android:layout_alignParentTop="true"android:background="@color/colorLightBlue"><ImageViewandroid:id="@+id/UserBaseInfo_ivGoBack"android:layout_width="30dp"android:layout_height="30dp"android:layout_alignParentLeft="true"android:layout_centerVertical="true"android:paddingLeft="5dp"android:src="@mipmap/getbackwhite"/><TextViewandroid:id="@+id/UserBaseInfo_tvTitle"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="50dp"android:layout_marginRight="50dp"android:singleLine="true"android:text="基本信息"android:layout_centerHorizontal="true"android:layout_centerVertical="true"android:textColor="@color/colorWhite"android:textSize="@dimen/textTitleSize"android:focusable="true"android:focusableInTouchMode="true"/></RelativeLayout><ScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:paddingLeft="10dp"android:text="用戶頭像"android:textSize="16dp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="100dp"android:background="@color/colorWhite"android:orientation="horizontal"android:paddingLeft="10dp"><ImageViewandroid:id="@+id/UserBaseInfo_ivAvatar"android:layout_width="80dp"android:layout_height="80dp"android:layout_gravity="center_vertical"android:scaleType="fitXY"android:src="@mipmap/no_avatar" /><ImageViewandroid:id="@+id/UserBaseInfo_ivAvatarAdd"android:layout_width="80dp"android:layout_height="80dp"android:layout_gravity="center_vertical"android:layout_marginLeft="10dp"android:scaleType="fitXY"android:src="@mipmap/add_icon" /></LinearLayout><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:paddingLeft="10dp"android:text="個人信息"android:textSize="16dp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/colorWhite"android:orientation="vertical"android:paddingLeft="10dp"android:paddingRight="10dp"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:paddingBottom="15dp"android:paddingTop="15dp"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="姓名"android:textSize="14dp" /><EditTextandroid:id="@+id/UserBaseInfo_etUserName"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="3"android:background="@drawable/edittext_bgwhite_noborder"android:hint="請輸入您的姓名"android:textSize="14dp" /></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="@color/colorLightGray"></View><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:paddingBottom="15dp"android:paddingTop="15dp"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="微信號"android:textSize="14dp" /><EditTextandroid:id="@+id/UserBaseInfo_etWebChatNumber"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="3"android:background="@drawable/edittext_bgwhite_noborder"android:hint="請輸入您的微信號"android:textSize="14dp" /></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="@color/colorLightGray"></View><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:paddingBottom="15dp"android:paddingTop="15dp"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="生日"android:textSize="14dp" /><TextViewandroid:id="@+id/UserBaseInfo_tvBirthday"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="3"android:hint="2018年7月15日"android:background="@drawable/edittext_bgwhite_noborder"android:textSize="14dp" /></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="@color/colorLightGray"></View><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:paddingBottom="15dp"android:paddingTop="15dp"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="手機號"android:textSize="14dp" /><EditTextandroid:id="@+id/UserBaseInfo_etPhone"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="3"android:background="@drawable/edittext_bgwhite_noborder"android:hint="請輸入您的手機號"android:textSize="14dp" /></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="@color/colorLightGray"></View><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:paddingBottom="15dp"android:paddingTop="15dp"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="身份證號"android:textSize="14dp" /><EditTextandroid:id="@+id/UserBaseInfo_etCardNO"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="3"android:background="@drawable/edittext_bgwhite_noborder"android:hint="請輸入您的身份證號"android:textSize="14dp" /></LinearLayout><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="@color/colorLightGray"></View><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:paddingBottom="15dp"android:paddingTop="15dp"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="郵箱"android:textSize="14dp" /><EditTextandroid:id="@+id/UserBaseInfo_etEmail"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="3"android:background="@drawable/edittext_bgwhite_noborder"android:hint="請輸入您的郵箱"android:textSize="14dp" /></LinearLayout></LinearLayout><Buttonandroid:id="@+id/UserBaseInfo_btnSubmit"android:layout_width="match_parent"android:layout_height="35dp"android:layout_marginBottom="20dp"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:layout_marginTop="20dp"android:background="@drawable/btn_circlecorner_gradient"android:text=" 提交"android:textColor="@color/colorWhite" /></LinearLayout></ScrollView></LinearLayout>3、UserBaseInfoActivity.java的代碼如下:
package com.deepreality.membership_app;import android.Manifest; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.support.annotation.Nullable; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.widget.Button; import android.widget.DatePicker; import android.widget.ImageView; import android.widget.PopupWindow; import android.widget.TextView; import android.widget.Toast;import com.deepreality.membership_app.CustomView.MyAlertDialog; import com.deepreality.membership_app.Model.DeviceBaseInfo;import java.io.File;public class UserBaseInfoActivity extends AppCompatActivity implements View.OnClickListener {private Context mContext;private ImageView ivGoBack, ivAvatar, ivAvatarAdd;private TextView tvBirthday;private static final int CROP_PHOTO = 2;private static final int REQUEST_CODE_PICK_IMAGE=3;private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE_TAKE_PHOTO = 6;private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE_CHOOSE_IMAGE = 7;private File fileImage;private Uri imageUri;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);//隱藏標題欄supportRequestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_userbaseinfo);baseDataInit();bindViews();bindViewAddListener();}private void baseDataInit() {mContext = this;}private void bindViews() {ivGoBack = findViewById(R.id.UserBaseInfo_ivGoBack);ivAvatar = findViewById(R.id.UserBaseInfo_ivAvatar);ivAvatarAdd = findViewById(R.id.UserBaseInfo_ivAvatarAdd);tvBirthday = findViewById(R.id.UserBaseInfo_tvBirthday);}private void bindViewAddListener() {ivGoBack.setOnClickListener(this);ivAvatarAdd.setOnClickListener(this);tvBirthday.setOnClickListener(this);}/*** 拍照并檢查權限*/public void takePhoneAndCheckPermissions(){if (ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA},MY_PERMISSIONS_REQUEST_CALL_PHONE_TAKE_PHOTO);}else {takePhoto();}}/*** 從相冊中選擇圖片并檢查權限*/public void choosePhoneAndCheckPermissions(){if (ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},MY_PERMISSIONS_REQUEST_CALL_PHONE_CHOOSE_IMAGE);}else {choosePhoto();}}/*** 拍照*/private void takePhoto(){//最后一個參數是文件夾的名稱,可以隨便起File file = new File(Environment.getExternalStorageDirectory(), "MemberShipAvatars");if(!file.exists()){file.mkdir();}//這里將時間作為不同照片的名稱fileImage = new File(file, System.currentTimeMillis()+".jpg");//如果該文件夾已經存在,則刪除它,否則創建一個try {if (fileImage.exists()) {fileImage.delete();}fileImage.createNewFile();} catch (Exception e) {e.printStackTrace();}//隱式打開拍照的Activity,并且傳入CROP_PHOTO常量作為拍照結束后回調的標志imageUri = Uri.fromFile(fileImage);Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);startActivityForResult(intent, CROP_PHOTO);}/*** 從相冊選取圖片*/private void choosePhoto(){Intent intent = new Intent(Intent.ACTION_PICK);intent.setType("image/*");//相片類型startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);}/*** 權限返回的判斷* @param requestCode* @param permissions* @param grantResults*/@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {switch (requestCode) {case MY_PERMISSIONS_REQUEST_CALL_PHONE_TAKE_PHOTO: {takePhoto();break;}case MY_PERMISSIONS_REQUEST_CALL_PHONE_CHOOSE_IMAGE: {choosePhoto();break;}default:break;}}super.onRequestPermissionsResult(requestCode, permissions, grantResults);}@Overrideprotected void onDestroy() {super.onDestroy();}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.UserBaseInfo_ivGoBack: {finish();break;}case R.id.UserBaseInfo_tvBirthday: {final MyAlertDialog dialog = new MyAlertDialog(mContext, R.style.myDialog);final View view1 = View.inflate(mContext, R.layout.layout_datepicker, null);Button dialogConfirm = (Button) view1.findViewById(R.id.Layout_DatePicker_btnConfirm);final DatePicker datePicker = view1.findViewById(R.id.Layout_DatePicker_dPicker);dialog.setView(view1);dialog.setProperty(0, 0, 800, 600);//設置坐標和寬高dialog.setCanceledOnTouchOutside(true);dialog.show();dialogConfirm.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//doSomethingint year = datePicker.getYear();//月份獲取的值會比實際月份少1int month = datePicker.getMonth() + 1;int day = datePicker.getDayOfMonth();String dateStr = year + "年" + month + "月" + day + "日";tvBirthday.setText(dateStr);dialog.dismiss();}});break;}case R.id.UserBaseInfo_ivAvatarAdd: {final MyAlertDialog dialog = new MyAlertDialog(mContext, R.style.myDialog);final View view1 = View.inflate(mContext, R.layout.layout_userbaseinfo_avatar, null);Button btnTakePhoto = (Button) view1.findViewById(R.id.Layout_UserBaseInfo_Avatar_btnTakePhoto);Button btnChooseImage = (Button) view1.findViewById(R.id.Layout_UserBaseInfo_Avatar_btnChooseImage);dialog.setView(view1);dialog.setProperty(0, 0, DeviceBaseInfo.DEVICE_WIDTH - 20, 400);//設置坐標和寬高dialog.setCanceledOnTouchOutside(true);dialog.show();btnTakePhoto.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(mContext, "拍照", Toast.LENGTH_SHORT).show();takePhoneAndCheckPermissions();dialog.dismiss();}});btnChooseImage.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(mContext, "從相冊中選擇", Toast.LENGTH_SHORT).show();choosePhoneAndCheckPermissions();dialog.dismiss();}});break;}default:break;}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {switch (requestCode) {case CROP_PHOTO:if (resultCode == RESULT_OK) {try {//該uri就是照片文件夾對應的uriBitmap bit = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));ivAvatar.setImageBitmap(bit);} catch (Exception e) {e.printStackTrace();Log.d("tag",e.getMessage());}}break;case REQUEST_CODE_PICK_IMAGE:if (resultCode == RESULT_OK) {try {//該uri是上一個Activity返回的Uri uri = data.getData();Bitmap bit = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));ivAvatar.setImageBitmap(bit);} catch (Exception e) {e.printStackTrace();Log.d("tag",e.getMessage());}}break;default:break;}super.onActivityResult(requestCode, resultCode, data);} }特別注意:個別品牌(例如,小米,小米,小米)的手機會出現拍照或者選擇圖片之后,頭像的顯示方向不對,一般是旋轉了90度!!!因為他們本身在保存圖片的時候,已經旋轉了90度了。如果我們能拿到那個旋轉值,就可以進行圖片旋轉來達到我們的目的了。
解決方案:
(將輸入流InputStream轉換為Bitmap后,那個旋轉值就獲取不到了)
1、先將輸入流轉換為byte[]數組,然后保存為File對象到本地。
2、通過文件路徑來獲取旋轉值。
3、通過旋轉值來進行圖片旋轉。
代碼如下:
/*** 根據Uri來獲取圖片旋轉后的Bitmap對象* @param imgUri* @return*/ private Bitmap rotaingImageViewBaseOfImageUri(Uri imgUri) {//該uri就是照片文件夾對應的uritry {byte[] bytes = PublicMethodUtil.toByteArray(getContentResolver().openInputStream(imgUri));//保存文件PublicMethodUtil.createFileWithByte(bytes);//獲取旋轉角度int degree = PublicMethodUtil.readPictureDegree(avatarImagePath);bitmap = PublicMethodUtil.Bytes2Bimap(bytes);bitmap = PublicMethodUtil.rotaingImageView(degree, bitmap);return bitmap;} catch (IOException e) {e.printStackTrace();}return null; }其中,調用的其他方法為:
/*** 讀取照片旋轉角度** @param path 照片路徑* @return 角度*/ public static int readPictureDegree(String path) {int degree = 0;try {ExifInterface exifInterface = new ExifInterface(path);int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);switch (orientation) {case ExifInterface.ORIENTATION_ROTATE_90:degree = 90;break;case ExifInterface.ORIENTATION_ROTATE_180:degree = 180;break;case ExifInterface.ORIENTATION_ROTATE_270:degree = 270;break;}} catch (IOException e) {e.printStackTrace();}return degree; }/*** 旋轉圖片* @param angle 旋轉角度* @param bitmap 被旋轉的對象* @return*/ public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {Bitmap returnBm = null;// 根據旋轉角度,生成旋轉矩陣Matrix matrix = new Matrix();matrix.postRotate(angle);try {// 將原始圖片按照旋轉矩陣進行旋轉,并得到新的圖片returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);} catch (OutOfMemoryError e) {}if (returnBm == null) {returnBm = bitmap;}if (bitmap != returnBm) {bitmap.recycle();}return returnBm; }/*** InputStream轉換為byte[]數組* @param input* @return* @throws IOException*/ public static byte[] toByteArray(InputStream input) throws IOException {ByteArrayOutputStream output = new ByteArrayOutputStream();byte[] buffer = new byte[4096];int n = 0;while (-1 != (n = input.read(buffer))) {output.write(buffer, 0, n);}return output.toByteArray(); }/*** byte[]數組轉換為Bitmap對象* @param b* @return*/ public static Bitmap Bytes2Bimap(byte[] b) {if (b.length != 0) {return BitmapFactory.decodeByteArray(b, 0, b.length);} else {return null;} }/*** 根據byte數組生成文件** @param bytes* 生成文件用到的byte數組*/ public static void createFileWithByte(byte[] bytes) {// TODO Auto-generated method stub/*** 創建File對象,其中包含文件所在的目錄以及文件的命名*/File file = new File(UserBaseInfo.userImageDirectory + "/" + UserBaseInfo.userAvatarImageName);// 創建FileOutputStream對象FileOutputStream outputStream = null;// 創建BufferedOutputStream對象BufferedOutputStream bufferedOutputStream = null;try {// 如果文件存在則刪除if (file.exists()) {file.delete();}// 在文件系統中根據路徑創建一個新的空文件file.createNewFile();// 獲取FileOutputStream對象outputStream = new FileOutputStream(file);// 獲取BufferedOutputStream對象bufferedOutputStream = new BufferedOutputStream(outputStream);// 往文件所在的緩沖輸出流中寫byte數據bufferedOutputStream.write(bytes);// 刷出緩沖輸出流,該步很關鍵,要是不執行flush()方法,那么文件的內容是空的。bufferedOutputStream.flush();} catch (Exception e) {// 打印異常信息e.printStackTrace();} finally {// 關閉創建的流對象if (outputStream != null) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}if (bufferedOutputStream != null) {try {bufferedOutputStream.close();} catch (Exception e2) {e2.printStackTrace();}}} }?Demo地址:https://download.csdn.net/download/lpcrazyboy/11038396
問題匯總:
(1)異常信息:exposed beyond app through ClipData.Item.getUri()
首先在AndroidManifest.xml中添加provider
<providerandroid:name="android.support.v4.content.FileProvider"android:authorities="${applicationId}.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/provider_paths" /> </provider>res/xml/provider_paths.xml
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"><external-path name="external_files" path="."/> </paths>然后修改代碼
void takePhoto(String cameraPhotoPath) {File cameraPhoto = new File(cameraPhotoPath);Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);Uri photoUri = FileProvider.getUriForFile(this,getPackageName() + ".provider",cameraPhoto);takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);startActivityForResult(takePhotoIntent, REQUEST_TAKE_PHOTO); }?
總結
以上是生活随笔為你收集整理的Android7.0以上如何获取头像(拍照或者从相册中选择)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小程序踩坑之旅
- 下一篇: 腾讯微博Android客户端开发 - O