android 修改头像后并上传到阿里云
16lz
2021-01-23
说句题外话,之前打算修改头像后把头像的base64字符串或字节数组直接传给后台,但是考虑到传输中出现的各种问题以及我后台接收时的不方便,所以改为了android端直接上传到阿里云,然后android直接传一个远程url给后台存储,这样就方便多了。
话不多说,代码走起。
首先你要在你的清单文件中加入各项权限以及一个provider
filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
build.grade
//上传头像 implementation 'com.facebook.fresco:fresco:1.1.0' annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0' implementation 'com.jakewharton:butterknife:8.4.0' implementation 'com.aliyun.dpa:oss-android-sdk:+'
activity_main.xml中就一个圆形的头像空间,其中这个圆形头像是我自定义的
CircleImageView.java
import android.widget.ImageView;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.ColorFilter;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.Shader;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.net.Uri;import android.support.annotation.ColorInt;import android.support.annotation.ColorRes;import android.support.annotation.DrawableRes;import android.util.AttributeSet;import android.widget.ImageView;import com.example.sdyx.recover.R;public class CircleImageView extends ImageView { private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP; private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; private static final int COLORDRAWABLE_DIMENSION = 2; private static final int DEFAULT_BORDER_WIDTH = 0; private static final int DEFAULT_BORDER_COLOR = Color.BLACK; private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT; private static final boolean DEFAULT_BORDER_OVERLAY = false; private final RectF mDrawableRect = new RectF(); private final RectF mBorderRect = new RectF(); private final Matrix mShaderMatrix = new Matrix(); private final Paint mBitmapPaint = new Paint(); private final Paint mBorderPaint = new Paint(); private final Paint mFillPaint = new Paint(); private int mBorderColor = DEFAULT_BORDER_COLOR; private int mBorderWidth = DEFAULT_BORDER_WIDTH; private int mFillColor = DEFAULT_FILL_COLOR; private Bitmap mBitmap; private BitmapShader mBitmapShader; private int mBitmapWidth; private int mBitmapHeight; private float mDrawableRadius; private float mBorderRadius; private ColorFilter mColorFilter; private boolean mReady; private boolean mSetupPending; private boolean mBorderOverlay; private boolean mDisableCircularTransformation; public CircleImageView(Context context) { super(context); init(); } public CircleImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH); mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR); mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY); mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR); a.recycle(); init(); } private void init() { super.setScaleType(SCALE_TYPE); mReady = true; if (mSetupPending) { setup(); mSetupPending = false; } } @Override public ScaleType getScaleType() { return SCALE_TYPE; } @Override public void setScaleType(ScaleType scaleType) { if (scaleType != SCALE_TYPE) { throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType)); } } @Override public void setAdjustViewBounds(boolean adjustViewBounds) { if (adjustViewBounds) { throw new IllegalArgumentException("adjustViewBounds not supported."); } } @Override protected void onDraw(Canvas canvas) { if (mDisableCircularTransformation) { super.onDraw(canvas); return; } if (mBitmap == null) { return; } if (mFillColor != Color.TRANSPARENT) { canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mFillPaint); } canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint); if (mBorderWidth > 0) { canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); setup(); } @Override public void setPadding(int left, int top, int right, int bottom) { super.setPadding(left, top, right, bottom); setup(); } @Override public void setPaddingRelative(int start, int top, int end, int bottom) { super.setPaddingRelative(start, top, end, bottom); setup(); } public int getBorderColor() { return mBorderColor; } public void setBorderColor(@ColorInt int borderColor) { if (borderColor == mBorderColor) { return; } mBorderColor = borderColor; mBorderPaint.setColor(mBorderColor); invalidate(); } /** * @deprecated Use {@link #setBorderColor(int)} instead */ @Deprecated public void setBorderColorResource(@ColorRes int borderColorRes) { setBorderColor(getContext().getResources().getColor(borderColorRes)); } /** * Return the color drawn behind the circle-shaped drawable. * * @return The color drawn behind the drawable * * @deprecated Fill color support is going to be removed in the future */ @Deprecated public int getFillColor() { return mFillColor; } /** * Set a color to be drawn behind the circle-shaped drawable. Note that * this has no effect if the drawable is opaque or no drawable is set. * * @param fillColor The color to be drawn behind the drawable * * @deprecated Fill color support is going to be removed in the future */ @Deprecated public void setFillColor(@ColorInt int fillColor) { if (fillColor == mFillColor) { return; } mFillColor = fillColor; mFillPaint.setColor(fillColor); invalidate(); } /** * Set a color to be drawn behind the circle-shaped drawable. Note that * this has no effect if the drawable is opaque or no drawable is set. * * @param fillColorRes The color resource to be resolved to a color and * drawn behind the drawable * * @deprecated Fill color support is going to be removed in the future */ @Deprecated public void setFillColorResource(@ColorRes int fillColorRes) { setFillColor(getContext().getResources().getColor(fillColorRes)); } public int getBorderWidth() { return mBorderWidth; } public void setBorderWidth(int borderWidth) { if (borderWidth == mBorderWidth) { return; } mBorderWidth = borderWidth; setup(); } public boolean isBorderOverlay() { return mBorderOverlay; } public void setBorderOverlay(boolean borderOverlay) { if (borderOverlay == mBorderOverlay) { return; } mBorderOverlay = borderOverlay; setup(); } public boolean isDisableCircularTransformation() { return mDisableCircularTransformation; } public void setDisableCircularTransformation(boolean disableCircularTransformation) { if (mDisableCircularTransformation == disableCircularTransformation) { return; } mDisableCircularTransformation = disableCircularTransformation; initializeBitmap(); } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); initializeBitmap(); } @Override public void setImageDrawable(Drawable drawable) { super.setImageDrawable(drawable); initializeBitmap(); } @Override public void setImageResource(@DrawableRes int resId) { super.setImageResource(resId); initializeBitmap(); } @Override public void setImageURI(Uri uri) { super.setImageURI(uri); initializeBitmap(); } @Override public void setColorFilter(ColorFilter cf) { if (cf == mColorFilter) { return; } mColorFilter = cf; applyColorFilter(); invalidate(); } @Override public ColorFilter getColorFilter() { return mColorFilter; } private void applyColorFilter() { if (mBitmapPaint != null) { mBitmapPaint.setColorFilter(mColorFilter); } } private Bitmap getBitmapFromDrawable(Drawable drawable) { if (drawable == null) { return null; } if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } try { Bitmap bitmap; if (drawable instanceof ColorDrawable) { bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); } Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } catch (Exception e) { e.printStackTrace(); return null; } } private void initializeBitmap() { if (mDisableCircularTransformation) { mBitmap = null; } else { mBitmap = getBitmapFromDrawable(getDrawable()); } setup(); } private void setup() { if (!mReady) { mSetupPending = true; return; } if (getWidth() == 0 && getHeight() == 0) { return; } if (mBitmap == null) { invalidate(); return; } mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mBitmapPaint.setAntiAlias(true); mBitmapPaint.setShader(mBitmapShader); mBorderPaint.setStyle(Paint.Style.STROKE); mBorderPaint.setAntiAlias(true); mBorderPaint.setColor(mBorderColor); mBorderPaint.setStrokeWidth(mBorderWidth); mFillPaint.setStyle(Paint.Style.FILL); mFillPaint.setAntiAlias(true); mFillPaint.setColor(mFillColor); mBitmapHeight = mBitmap.getHeight(); mBitmapWidth = mBitmap.getWidth(); mBorderRect.set(calculateBounds()); mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f); mDrawableRect.set(mBorderRect); if (!mBorderOverlay && mBorderWidth > 0) { mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f); } mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f); applyColorFilter(); updateShaderMatrix(); invalidate(); } private RectF calculateBounds() { int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight(); int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom(); int sideLength = Math.min(availableWidth, availableHeight); float left = getPaddingLeft() + (availableWidth - sideLength) / 2f; float top = getPaddingTop() + (availableHeight - sideLength) / 2f; return new RectF(left, top, left + sideLength, top + sideLength); } private void updateShaderMatrix() { float scale; float dx = 0; float dy = 0; mShaderMatrix.set(null); if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) { scale = mDrawableRect.height() / (float) mBitmapHeight; dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f; } else { scale = mDrawableRect.width() / (float) mBitmapWidth; dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f; } mShaderMatrix.setScale(scale, scale); mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top); mBitmapShader.setLocalMatrix(mShaderMatrix); }}
MyApplication.java
import android.app.Application;import android.content.Context;import com.facebook.drawee.backends.pipeline.Fresco;/** * Created by ${yf} on 2017/2/16. */public class MyApplication extends Application { private static MyApplication myApplication; @Override public void onCreate() { super.onCreate(); myApplication = this; //初始化Fresco Fresco.initialize(this); } public static Context getApp() { return myApplication; }}
MainActivity.java 声明CircleImageView及初始化就写了,做android的都知道。
private OSS oss;private static final int REQUEST_CODE_TAKE_PHOTO = 1;private static final int REQUEST_CODE_ALBUM = 2;private static final int REQUEST_CODE_CROUP_PHOTO = 3;private File file;private Uri uri; mCircleImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View view) { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle("提示"); builder.setMessage("请选择修改头像方式"); //调用相机拍照 builder.setPositiveButton("拍照", new DialogInterface.OnClickListener() { @Override public void onClick( DialogInterface dialogInterface, int i) { if (PermissionUtil.hasCameraPermission(MainActivity.this)) { uploadAvatarFromPhotoRequest(); } } }); //从相册里面取照片 builder.setNegativeButton("相册", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { uploadAvatarFromAlbumRequest(); } }); builder.create().show(); } }); private void init() { file = new File(FileUtil.getCachePath(this), "user-avatar.jpg"); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { uri = Uri.fromFile(file); } else { //通过FileProvider创建一个content类型的Uri(android 7.0需要这样的方法跨应用访问) uri = FileProvider.getUriForFile(MyApplication.getApp(), "com.sdyx.provider", file); } } /**初始化阿里云*/ private void initOSS() { OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(ConstantUtils.accessKeyId, ConstantUtils.accessKeySecret); ClientConfiguration conf = new ClientConfiguration(); conf.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒 conf.setSocketTimeout(15 * 1000); // socket超时,默认15秒 conf.setMaxConcurrentRequest(5); // 最大并发请求书,默认5个 conf.setMaxErrorRetry(2); // 失败后最大重试次数,默认2次 OSSLog.enableLog(); oss = new OSSClient(getApplicationContext(), ConstantUtils.endpoint, credentialProvider, conf); } /** * photo */ private void uploadAvatarFromPhotoRequest() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO); } /** * album */ private void uploadAvatarFromAlbumRequest() { Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); photoPickerIntent.setType("image/*"); startActivityForResult(photoPickerIntent, REQUEST_CODE_ALBUM); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != -1) { return; } if (requestCode == REQUEST_CODE_ALBUM && data != null) { Uri newUri; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { newUri = Uri.parse("file:///" + CropUtils.getPath(this, data.getData())); } else { newUri = data.getData(); } if (newUri != null) { startPhotoZoom(newUri); } else { Toast.makeText(this, "没有得到相册图片", Toast.LENGTH_LONG).show(); } } else if (requestCode == REQUEST_CODE_TAKE_PHOTO) { startPhotoZoom(uri); } else if (requestCode == REQUEST_CODE_CROUP_PHOTO) { uploadAvatarFromPhoto(); } } private void uploadAvatarFromPhoto() { compressAndUploadAvatar(file.getPath()); } private void compressAndUploadAvatar(String fileSrc) { final File cover = FileUtil.getSmallBitmap(this, fileSrc);// String mimeType = "image/*";// requestBody = RequestBody.create(MediaType.parse(mimeType), file);// String fileName = cover.getName();// photo = MultipartBody.Part.createFormData("portrait", fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length()), requestBody); //加载本地图片// Uri uri = Uri.fromFile(cover);// Bitmap bmp= BitmapFactory.decodeFile(cover.getPath());// mCircleImageView.setImageBitmap(bmp); new Thread(new Runnable() { @Override public void run() { asyncPutObjectFromLocalFile(getPhotoFileName(),cover.getPath()); } }).start(); } /** * 从本地文件上传,使用非阻塞的异步接口 * @param uploadObject 这个是你要上传到OSS的文件路径,加入想上传到文件夹则前面加上xxx/xxx形式的路径即可 * @param locationPath 这个路径是你要上传的文件的路径(本地) */ public void asyncPutObjectFromLocalFile(final String uploadObject, String locationPath) { /** * 构造上传请求 * oss 配置 * testBucket 申请的Bucket名称 * uploadObject 这个是你要上传到OSS的文件路径(一般是 "img" + "/" + "当前时间" + ".png";) * path 这个路径是你要上传的文件的路径(本地) */ PutObjectRequest put = new PutObjectRequest(ConstantUtils.accessBucket, uploadObject, locationPath); // 异步上传时可以设置进度回调 put.setProgressCallback(new OSSProgressCallback() { @Override public void onProgress(PutObjectRequest request, long currentSize, long totalSize) { // 在这里可以实现进度条展现功能 Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize); } }); oss.asyncPutObject(put, new OSSCompletedCallback() { @Override public void onSuccess(PutObjectRequest request, PutObjectResult result) { Log.d("PutObject", "UploadSuccess"); Log.e("PutObject", "上传图片成功"); Log.d("ETag", result.getETag()); Log.d("RequestId", result.getRequestId()); String path = "https://"+ConstantUtils.accessBucket+"."+ConstantUtils.endpoint+"/"+uploadObject; } @Override public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) { Toast.makeText(MainActivity.this, "上传失败", Toast.LENGTH_SHORT).show(); // 请求异常 if (clientExcepion != null) { // 本地异常如网络异常等 clientExcepion.printStackTrace(); } if (serviceException != null) { // 服务异常 Log.e("ErrorCode", serviceException.getErrorCode()); Log.e("RequestId", serviceException.getRequestId()); Log.e("HostId", serviceException.getHostId()); Log.e("RawMessage", serviceException.getRawMessage()); } } }); } /** * * @return 图片上传到阿里云的路径 */ public static String getPhotoFileName() { Date date = new Date(System.currentTimeMillis()); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS", Locale.getDefault()); return ConstantUtils.accessFolder + dateFormat.format(date) + ".png"; }
CropUtils.java
import android.annotation.SuppressLint;import android.content.ContentUris;import android.content.Context;import android.database.Cursor;import android.net.Uri;import android.os.Build;import android.os.Environment;import android.provider.DocumentsContract;import android.provider.MediaStore;import android.util.Log;import static android.content.ContentValues.TAG;/** * Created by yf on 2016/2/23. */public class CropUtils { @SuppressLint("NewApi") public static String getPath(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;// DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[]{split[1]}; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } else { String uriStr = uri.toString(); String path = uriStr.substring(10, uriStr.length()); if (path.startsWith("com.sec.android.gallery3d")) { Log.e(TAG, "It's auto backup pic path:" + uri.toString()); return null; } String[] filePathColumn = {MediaStore.Images.Media.DATA}; Cursor cursor = context.getContentResolver().query(uri, filePathColumn, null, null, null); if (cursor != null) { cursor.moveToFirst(); } int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String picturePath = cursor.getString(columnIndex); cursor.close(); return picturePath; } return null; } /** * Get the value of the data column for this Uri. This is useful for * MediaStore Uris, and other file-based ContentProviders. * * @param context The context. * @param uri The Uri to query. * @param selection (Optional) Filter used in the query. * @param selectionArgs (Optional) Selection arguments used in the query. * @return The value of the _data column, which is typically a file path. */ private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = {column}; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int column_index = cursor.getColumnIndexOrThrow(column); return cursor.getString(column_index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ private static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ private static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is MediaProvider. */ private static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); }}
DialogPermission.java
import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.provider.Settings;import android.util.Log;/** * 权限提示对话框 * Created by yf on 2016/7/25. */public class DialogPermission { Context mContext; String mNotice; public DialogPermission(Context context, String notice){ mContext=context; mNotice=notice; showDialog(); } private void showDialog() { new AlertDialog.Builder(mContext).setTitle("系统提示")//设置对话框标题 .setMessage(mNotice)//设置显示的内容 .setPositiveButton("设置",new DialogInterface.OnClickListener() {//添加确定按钮 @Override public void onClick(DialogInterface dialog, int which) {//确定按钮的响应事件 Intent intent = new Intent(Settings.ACTION_APN_SETTINGS); mContext.startActivity(intent); } }).setNegativeButton("放弃",new DialogInterface.OnClickListener() {//添加返回按钮 @Override public void onClick(DialogInterface dialog, int which) {//响应事件 Log.i("DialogPermission","Dialog关闭"); } }).show();//在按键响应事件中显示此对话框 }}
FileUtils.java
import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Environment;import android.util.Log;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.OutputStream;/** * Created by yf on 2016/7/22 0022. * 文件的缓存与读取 */public class FileUtil { private static final String TAG = "FileUtil"; /** * 获取缓存路径 * * @param context * @return */ public static String getCachePath(Context context) { String cachePath = null; if (Environment.MEDIA_MOUNTED.equals(Environment .getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { cachePath = context.getExternalCacheDir().getPath(); } else { cachePath = context.getCacheDir().getPath(); } return cachePath; } /** * 删除指定文件 * * @param file * @return */ public static boolean deleteFile(File file) { if (file.exists() && file.isFile()) { return file.delete(); } return false; } /** * 递归删除文件和文件夹 * * @param file 要删除的根目录 */ public static void recursionDeleteFile(File file) { if (file.isFile()) { file.delete(); return; } if (file.isDirectory()) { File[] childFile = file.listFiles(); if (childFile == null || childFile.length == 0) { file.delete(); return; } for (File f : childFile) { recursionDeleteFile(f); } file.delete(); } } /** * 压缩图片方法,为了上传到服务器,保证图片大小在100k一下 * * @param context * @param fileSrc * @return */ public static File getSmallBitmap(Context context, String fileSrc) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(fileSrc, options); options.inSampleSize = calculateInSampleSize(options, 480, 800); Log.i(TAG, "options.inSampleSize-->" + options.inSampleSize); options.inJustDecodeBounds = false; Bitmap img = BitmapFactory.decodeFile(fileSrc, options); Log.i(TAG, "file size after compress-->" + img.getByteCount() / 256); String filename = context.getFilesDir() + File.separator + "video-" + img.hashCode() + ".jpg"; saveBitmap2File(img, filename); return new File(filename); } /** * 设置压缩的图片的大小设置的参数 * * @param options * @param reqWidth * @param reqHeight * @return */ public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { int height = options.outHeight; int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { int heightRatio = Math.round(height) / reqHeight; int widthRatio = Math.round(width) / reqWidth; inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } /** * 保存bitmap到文件 * * @param bmp * @param filename * @return */ public static boolean saveBitmap2File(Bitmap bmp, String filename) { Bitmap.CompressFormat format = Bitmap.CompressFormat.JPEG; int quality = 50;//压缩50% 100表示不压缩 OutputStream stream = null; try { stream = new FileOutputStream(filename); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return bmp.compress(format, quality, stream); }}
PermissionUtil.java
import android.Manifest;import android.app.Activity;import android.content.pm.PackageManager;import android.os.Build;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v4.util.SimpleArrayMap;import android.util.Log;/** * Created by yf on 2016/7/22 0022. */public class PermissionUtil { public static final int REQUEST_SHOWCAMERA = 0; public static final int REQUEST_READ_EXTERNAL_STORAGE = 1; public static final int REQUEST_RECORD_AUDIO = 2; public static final int REQUEST_CONTACTS = 3; public static final int REQUEST_LOCATION = 4; private static final SimpleArrayMap MIN_SDK_PERMISSIONS; static { MIN_SDK_PERMISSIONS = new SimpleArrayMap<>(8); MIN_SDK_PERMISSIONS.put("com.android.voicemail.permission.ADD_VOICEMAIL", 14); MIN_SDK_PERMISSIONS.put("android.permission.BODY_SENSORS", 20); MIN_SDK_PERMISSIONS.put("android.permission.READ_CALL_LOG", 16); MIN_SDK_PERMISSIONS.put("android.permission.READ_EXTERNAL_STORAGE", 16); MIN_SDK_PERMISSIONS.put("android.permission.USE_SIP", 9); MIN_SDK_PERMISSIONS.put("android.permission.WRITE_CALL_LOG", 16); MIN_SDK_PERMISSIONS.put("android.permission.SYSTEM_ALERT_WINDOW", 23); MIN_SDK_PERMISSIONS.put("android.permission.WRITE_SETTINGS", 23); } private static boolean permissionExists(String permission) { Integer minVersion = MIN_SDK_PERMISSIONS.get(permission); return minVersion == null || Build.VERSION.SDK_INT >= minVersion; } public static boolean hasCameraPermission(Activity activity){ int hasPermission = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA); if(!permissionExists(Manifest.permission.CAMERA)){ Log.e("permission","your system does not suppport"+ Manifest.permission.CAMERA+" permission"); return false; } if (hasPermission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA}, PermissionUtil.REQUEST_SHOWCAMERA); return false; } return true; } public static boolean hasReadExternalStoragePermission(Activity activity){ int hasPermission = ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE); if(!permissionExists(Manifest.permission.READ_EXTERNAL_STORAGE)){ Log.e("permission","your system does not suppport "+ Manifest.permission.READ_EXTERNAL_STORAGE+" permission"); return false; } if (hasPermission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PermissionUtil.REQUEST_READ_EXTERNAL_STORAGE); return false; } return true; } public static boolean hasRecordAudioPermission(Activity activity){ int hasPermission = ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO); if(!permissionExists(Manifest.permission.RECORD_AUDIO)){ Log.e("permission","your system does not suppport"+ Manifest.permission.RECORD_AUDIO+" permission"); return false; } if (hasPermission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.RECORD_AUDIO}, PermissionUtil.REQUEST_RECORD_AUDIO); return false; } return true; } public static boolean hasContactsPermission(Activity activity){ int hasWPermission = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_CONTACTS); int hasRPermission = ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_CONTACTS); if(hasRPermission== PackageManager.PERMISSION_GRANTED && hasWPermission== PackageManager.PERMISSION_GRANTED){ return true; } ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_CONTACTS}, PermissionUtil.REQUEST_CONTACTS); return false; } public static boolean hasLocationPermission(Activity activity){ int hasFPermission = ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION); int hasCPermission = ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_COARSE_LOCATION); if(hasFPermission== PackageManager.PERMISSION_GRANTED&&hasCPermission== PackageManager.PERMISSION_GRANTED){ return true; } ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, PermissionUtil.REQUEST_LOCATION); return false; }}
SharePreferenceMark.java
/** * SharedPreference存储 记录只出现一次的组件是否已经出现过 * Created by yf on 2016/7/25. */public final class SharedPreferenceMark { public static Boolean hasShowCamera=false;//是否已经提示过摄像头权限 public static Boolean hasShowLocation=false;//是否已经提示过摄像头权限 public static Boolean hasShowRecordAudio=false;//是否已经提示过摄像头权限 public static Boolean hasShowExtralStoreage=false;//是否已经提示过摄像头权限 public static Boolean hasShowContact=false;//是否已经提示过摄像头权限 public static Boolean getHasShowCamera() { return hasShowCamera; } public static void setHasShowCamera(Boolean hasShowCamera) { SharedPreferenceMark.hasShowCamera = hasShowCamera; } public static Boolean getHasShowLocation() { return hasShowLocation; } public static void setHasShowLocation(Boolean hasShowLocation) { SharedPreferenceMark.hasShowLocation = hasShowLocation; } public static Boolean getHasShowRecordAudio() { return hasShowRecordAudio; } public static void setHasShowRecordAudio(Boolean hasShowRecordAudio) { SharedPreferenceMark.hasShowRecordAudio = hasShowRecordAudio; } public static Boolean getHasShowExtralStoreage() { return hasShowExtralStoreage; } public static void setHasShowExtralStoreage(Boolean hasShowExtralStoreage) { SharedPreferenceMark.hasShowExtralStoreage = hasShowExtralStoreage; } public static Boolean getHasShowContact() { return hasShowContact; } public static void setHasShowContact(Boolean hasShowContact) { SharedPreferenceMark.hasShowContact = hasShowContact; }}
ConstantUtils.java
public static String endpoint = "";public static String accessKeyId = ""; // accessKeyIdpublic static String accessKeySecret = ""; // accessKeySecretpublic static String accessBucket = ""; // 这个就是你申请的bucket名称public static String accessFolder = "headImage/"; //存放图片的文件夹
可以下载这个demo,我是仿照这个弄得。
https://github.com/yangfang521314/UserAvatar
更多相关文章
- Android res/raw文件以及raw与res/assets异同
- Windows环境下编译Assimp库生成Android可用的.so文件
- [eclipse]android开发如何查看源代码文件(android source)
- android DDMS 连接真机(己ROOT),用file explore看不到data/data文
- Cocos2d-x在win32,android和IOS下的文件读写问题
- 在Qt for Android中添加.a或so库文件
- Android 开发之旅:深入分析布局文件&又是“Hello World!”
- Android res/raw文件;raw与res/assets异同
- 全面的Android文件目录解析和获取方法(包含对6.0系统的说明)