1. 程式人生 > >Android實現拍照相簿圖片上傳功能

Android實現拍照相簿圖片上傳功能

更改頭像功能不像修改資訊一樣直接提交引數就可以,需要上傳圖片檔案
我就直接貼程式碼了首先給出佈局檔案

  <ImageView
        android:id="@+id/iv"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@mipmap/ic_launcher" />

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="拍照" /> <Button android:id="@+id/btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="攝像" /> <TextView android:id="@+id/tv" android:layout_width="wrap_content"
android:layout_height="wrap_content" />

然後就是上傳的程式碼了

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btn1, btn2;
    private ImageView headIv;
    private TextView textView;
    private static final String TAG = "MainActivity";
    private
final int IMAGE_RESULT_CODE = 2; private final int PICK = 1; private String url = "";//此處為上傳圖片地址,我就不寫了 private String imgString = ""; private Intent intent; private Handler mHandler = new Handler(Looper.getMainLooper()); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn1 = findViewById(R.id.btn1); btn2 = findViewById(R.id.btn2); textView = findViewById(R.id.tv); headIv = findViewById(R.id.iv); btn1.setOnClickListener(this); btn2.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn1: intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, PICK); break; case R.id.btn2: intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, IMAGE_RESULT_CODE); break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { // 表示 呼叫照相機拍照 case PICK: if (resultCode == RESULT_OK) { Bundle bundle = data.getExtras(); Bitmap bitmap = (Bitmap) bundle.get("data"); imgString = bitmapToBase64(bitmap); uploadImg(); } break; // 選擇圖片庫的圖片 case IMAGE_RESULT_CODE: if (resultCode == RESULT_OK) { Uri uri = data.getData(); Bitmap bitmap2 = PhotoUtils.getBitmapFromUri(uri, this); imgString = bitmapToBase64(bitmap2); uploadImg(); } break; } } //上傳圖片檔案的操作 public void uploadImg() { OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); //上傳圖片引數需要與服務端溝通,我就不多做解釋了,我新增的都是我們服務端需要的 //你們根據情況自行更改 //另外網路請求我就不多做解釋了 FormBody body = new FormBody.Builder().add("dir", "c/image") .add("data", imgString) .add("file", "headicon") .add("ext", "jpg").build(); Request request = new Request.Builder().url(url).post(body).build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { final String data = response.body().string(); Gson gson = new Gson(); final Beans bean = gson.fromJson(data, Beans.class); Log.d(TAG, "onResponse: " + data); mHandler.post(new Runnable() { @Override public void run() { //載入圖片用的Gilde框架,也可以自己自由選擇, //""裡面取決於服務端的返回值是否需要自行新增地址 Glide.with(MainActivity.this).load(""+bean.getData().getUrl()).into(headIv); } }); } }); } //如上參需要64位編碼可呼叫此方法,不需要可以忽略 public static String bitmapToBase64(Bitmap bitmap) { String result = null; ByteArrayOutputStream baos = null; try { if (bitmap != null) { baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); baos.flush(); baos.close(); byte[] bitmapBytes = baos.toByteArray(); result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (baos != null) { baos.flush(); baos.close(); } } catch (IOException e) { e.printStackTrace(); } } return result; } }

我儘量把說明都寫在了註釋裡,就不在這裡多說了
最後把照片工具類貼出來,因為MainActivity有呼叫
我不寫出來可能有的小夥伴因為這一個報錯就不知如何處理
實體類我就不寫了,因為真的太簡單了

public class PhotoUtils {
    private static final String TAG = "PhotoUtils";

    /**
     * @param activity    當前activity
     * @param imageUri    拍照後照片儲存路徑
     * @param requestCode 呼叫系統相機請求碼
     */
    public static void takePicture(Activity activity, Uri imageUri, int requestCode) {
        //呼叫系統相機
        Intent intentCamera = new Intent();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intentCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //新增這一句表示對目標應用臨時授權該Uri所代表的檔案
        }
        intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
        //將拍照結果儲存至photo_file的Uri中,不保留在相簿中
        intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        activity.startActivityForResult(intentCamera, requestCode);
    }

    /**
     * @param activity    當前activity
     * @param requestCode 開啟相簿的請求碼
     */
    public static void openPic(Activity activity, int requestCode) {
        Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
        photoPickerIntent.setType("image/*");
        activity.startActivityForResult(photoPickerIntent, requestCode);
    }

    /**
     * @param activity    當前activity
     * @param orgUri      剪裁原圖的Uri
     * @param desUri      剪裁後的圖片的Uri
     * @param aspectX     X方向的比例
     * @param aspectY     Y方向的比例
     * @param width       剪裁圖片的寬度
     * @param height      剪裁圖片高度
     * @param requestCode 剪裁圖片的請求碼
     */
    public static void cropImageUri(Activity activity, Uri orgUri, Uri desUri, int aspectX, int aspectY, int width, int height, int requestCode) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        intent.setDataAndType(orgUri, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", aspectX);
        intent.putExtra("aspectY", aspectY);
        intent.putExtra("outputX", width);
        intent.putExtra("outputY", height);
        intent.putExtra("scale", true);
        //將剪下的圖片儲存到目標Uri中
        intent.putExtra(MediaStore.EXTRA_OUTPUT, desUri);
        intent.putExtra("return-data", false);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        activity.startActivityForResult(intent, requestCode);
    }

    /**
     * 讀取uri所在的圖片
     *
     * @param uri      圖片對應的Uri
     * @param mContext 上下文物件
     * @return 獲取影象的Bitmap
     */
    public static Bitmap getBitmapFromUri(Uri uri, Context mContext) {
        try {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), uri);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @param context 上下文物件
     * @param uri     當前相簿照片的Uri
     * @return 解析後的Uri對應的String
     */
    @SuppressLint("NewApi")
    public static String getPath(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        String pathHead = "file:///";
        // 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 pathHead + 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 pathHead + 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 pathHead + getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return pathHead + getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return pathHead + uri.getPath();
        }
        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());
    }
}