头像的上传
现在无论大小app,用户信息中的头像信息显然是必不可少的,所以这篇博文讲解了app头像的选取。说明一下,我们进行头像的更改基本上都是在主页面的fragment里面,所以这里也是在这样的环境下进行模拟;
第一步:选取头像图片的来源
点击头像框,弹出选择头像的对话框
fragment的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<ImageView
android:id="@+id/iv_header"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@android:drawable/ic_menu_compass"
/>
</LinerLayout>
点击头像后调用的方法
private void showDialog() {
new AlertDialog.Builder(getActivity())
.setTitle(R.string.select_image_source)
.setNegativeButton(R.string.camera, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
//照相
// checkPermission();
takephoto();
}
})
.setPositiveButton(R.string.albums, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
selectPicture();
}
;
}).show();
}
第二步,获取图片;
从上面代码可以看出,我们在对话框的点击事件中调用的两个方法:takephoto()和selectPicture(),分别代表照相获取图片和从相册中选择图片;
takephoto():照相获取图片
private void takephoto() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
tempUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "image.jpg"));
intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
startActivityForResult(intent, TAKE_PICTURE);
}
上面代码就是调用系统相机,打开相机界面,并将相机的照相图片存在指定的image.jpg里面
selectPicture:从相片中获取图片
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
((MainActivity) getActivity()).startActivityForResult(intent, CHOOSE_PICTURE);
这样,我们便可以获取到图片资源了,
第三步 对获取到的图片资源进行剪裁
上面的代码中可以看出,我们在调用系统界面获取图片是使用的是startActivityForResult()方法,这样我们便可以在onActivityResult()方法里获取到图片资源。在文章开头时我有提到,我们是在activity的fragment里面进行的选择头像操作,因为我们是在fragment里面调用的startActivityForResult(),我们很多人就会下意思的在fragment里面调用onActivityResult()方法,但到最后会发现一直获取不到返回值,我第一次发现这个有问题时在我们别人调bug时发现的,他的头像调取是在fragment的fragment里面进行的,结果发现一直获取不到返回信息,并且他那个基本架构不常见,所以这里不说细节了,有需要的可以研究一下;
这里我们需要在主界面Activity里面调用,才能获取到返回值;
主界面的布局:
<?xml version="1.0" encoding="utf-8"?>
<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.hpl.demoapplication.MainActivity">
<FrameLayout
android:id="@+id/content_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"></FrameLayout>
</
elativeLayout>
主界面的代码
package com.hpl.demoapplication;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final int TAKE_PICTURE = 0x0001;
private static final int CHOOSE_PICTURE = 0x0002;
private static final int CROP_SMALL_PICTURE = 0x0003;
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction().replace(R.id.content_view, new MyFragment()).commit();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode){
case TAKE_PICTURE:
startPhotoZoom(MyFragment.tempUri);
break;
case CHOOSE_PICTURE:
startPhotoZoom(data.getData());
break;
case CROP_SMALL_PICTURE:
if (data != null) {
setImageToView(data); // 让刚才选择裁剪得到的图片显示在界面上
}
break;
}
}
private void setImageToView(Intent data) {
FragmentManager supportFragmentManager = getSupportFragmentManager();
List<Fragment> fragments = supportFragmentManager.getFragments();
if(fragments == null){
return;
}
MyFragment fragment = (MyFragment) fragments.get(fragments.size() - 1);
Bundle bundle = data.getExtras();
if(bundle != null){
Bitmap bitmap = bundle.getParcelable("data");
fragment.iv_header.setImageBitmap(bitmap);
}
}
private void startPhotoZoom(Uri uri) {
if(uri == null){
Log.i(TAG, "startPhotoZoom: The uri is no exist!!");
return;
}
//调用系统的裁图功能
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri,"image/*");
// crop为true是设置在开启的intent中设置显示的view可以剪裁
intent.putExtra("crop", true);
//设置图片的裁剪比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
//设置剪裁图片的宽高
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
intent.putExtra("return-data", true);
startActivityForResult(intent, CROP_SMALL_PICTURE);
}
}
在onActivityResult方法里面我们可以看到,在获取到图片资源后,我们调用了startPhotoZoom方法对图片进行了剪裁,这里也是调用的系统剪裁,然后将剪裁后的图片经过startActivityForResult方法进行返回;
第四步 将剪裁后的图片显示在ImageView上面并上传;
将图片剪裁后,我们同样在onActivityResult里面获取到了剪裁后的图片数据,然后我们调用了setImageToView()方法,由于ImageView在fragment里面,我们无法直接获取控件进行布局,所以我们先获取到ImageView所在的Fragment,
FragmentManager supportFragmentManager = getSupportFragmentManager();
List<Fragment> fragments = supportFragmentManager.getFragments();
if(fragments == null){
return;
}
MyFragment fragment = (MyFragment) fragments.get(fragments.size()- 1;
然后将数据显示在ImageView空间上;具体头像上传的时自己把握;
第五步 android6.0权限解决
这里直接将Fragment的代码给大家,不是很周密的解决方法,自行研究,哈哈
package com.hpl.demoapplication;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
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.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.Toast;
import java.io.File;
/**
* Created by 79115 on 2016/12/2.
*/
public class MyFragment extends Fragment implements View.OnClickListener {
private static final int TAKE_PICTURE = 0x0001;
private static final int REQUEST_CODE_ASK_CAMERA = 100;
private static final int CHOOSE_PICTURE = 0x0002;
private View view;
public static Uri tempUri;
public ImageView iv_header;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_my, null);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
iv_header = (ImageView) view.findViewById(R.id.iv_header);
iv_header.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.iv_header:
showDialog();
break;
}
}
private void checkPermission() {
int sdkInt = Build.VERSION.SDK_INT;
if (Build.VERSION.SDK_INT >= 23) {
int checkCallPhonePermission = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA);
if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{
Manifest.permission.CAMERA}, REQUEST_CODE_ASK_CAMERA);
} else {
takephoto();
}
} else {
takephoto();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_CAMERA:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
takephoto();
} else {
// Permission Denied
Toast.makeText(getActivity(), "为获取到照相机权限", Toast.LENGTH_SHORT).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void showDialog() {
new AlertDialog.Builder(getActivity())
.setTitle(R.string.select_image_source)
.setNegativeButton(R.string.camera, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
//照相
checkPermission();
//takephoto();
}
})
.setPositiveButton(R.string.albums, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
selectPicture();
}
}).show();
}
private void selectPicture() {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
((MainActivity) getActivity()).startActivityForResult(intent, CHOOSE_PICTURE);
}
private void takephoto() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
tempUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "image.jpg"));
intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
((MainActivity) getActivity()).startActivityForResult(intent, TAKE_PICTURE);
}
}