在做app開發的時候圖片上傳是最基本的功能了,一般都是調用手機相機拍照,然后上傳到服務器上。下面就說一下,如何調用相機拍照並上傳到服務器上的。
首先要在AndroidManifest.xml添加網絡權限:
調用相機權限:
<uses-permission android:name="android.permission.CAMERA" />
往服務器上上傳圖片,需要網絡權限:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>`
上傳圖片我們一般不用Android studio自帶的上傳方法,會用插件來實現圖片上傳,這里推薦使用okhttp.
將okhttp插件導入工程后,下面就直接上代碼了。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".GaoWen.CamerIcon"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:orientation="vertical" android:layout_margin="10dp" android:layout_weight="4"> <TextView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:text="請填寫備注:" android:textSize="20dp" android:gravity="center_vertical"/> <EditText android:id="@+id/text_info" android:layout_weight="3" android:layout_width="match_parent" android:layout_height="0dp" android:inputType="textMultiLine" android:layout_gravity="center" android:gravity="left|top" android:background="@drawable/log" android:minLines="6" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:orientation="vertical" android:layout_margin="10dp" android:layout_weight="1"> <TextView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:text="照片列表:" android:textSize="20dp" android:gravity="center_vertical"/> </LinearLayout> <HorizontalScrollView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3" android:layout_margin="10dp" android:background="@drawable/log" > <LinearLayout android:id="@+id/iconlayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > </LinearLayout> </HorizontalScrollView> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="2"> <ImageView android:id="@+id/addimg" android:layout_width="match_parent" android:layout_height="80dp" android:layout_marginLeft="150dp" android:layout_marginRight="150dp" android:src="@drawable/xiangji" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <Button android:id="@+id/submit" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginLeft="50dp" android:layout_marginRight="50dp" android:text="提交" android:textColor="@color/white" android:background="@drawable/point_logbtn" /> </LinearLayout> </LinearLayout>
動態開啟攝像機權限:
public void openCamera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); intent.addCategory(Intent.CATEGORY_DEFAULT); //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); uri = getImageUri(); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(intent, 1); } public Uri getImageUri() { File refile=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),"path"); if (!refile.exists()){refile.mkdirs();} imaname=System.currentTimeMillis()+".png"; file = new File(refile, imaname); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } String path = file.getPath(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { listpath.add(path); uri = Uri.fromFile(file); } else { //兼容android7.0 使用共享文件的形式 // uri= FileProvider.getUriForFile(MainPage.this, "com.example.appmanager.fileProvider", file); ContentValues contentValues = new ContentValues(1); contentValues.put(MediaStore.Images.Media.DATA, path); uri = this.getApplication().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); } return uri; } /** * 回調 * @param requestCode * @param resultCode * @param data */ @SuppressLint("ResourceType") @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode==1){ LinearLayout.LayoutParams lytp = new LinearLayout.LayoutParams(300,400); ImageView imageView=new ImageView(this); lytp.setMargins(10,10,0,0); imageView.setLayoutParams(lytp); LinearLayout layout= ((LinearLayout) this.findViewById(R.id.iconlayout)); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { LayoutInflater inflater = LayoutInflater.from(CamerIcon.this); View imgEntryView = inflater.inflate(R.layout.largeicon, null); // 加載自定義的布局文件 final AlertDialog dialog = new AlertDialog.Builder(CamerIcon.this).create(); ImageView img = imgEntryView.findViewById(R.id.large_image); Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); img.setImageBitmap(bitmap); dialog.setView(imgEntryView); // 自定義dialog dialog.show(); // 點擊布局文件(也可以理解為點擊大圖)后關閉dialog,這里的dialog不需要按鈕 imgEntryView.setOnClickListener(new View.OnClickListener() { public void onClick(View paramView) { dialog.cancel(); } }); } }); imageView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { new AlertDialog.Builder(CamerIcon.this) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle("提示") .setMessage("你確定要刪除嗎") .setPositiveButton("確定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { layout.removeView(imageView); if (list.size()>0){ int j=0; //需求是刪除B和D Iterator<Icon> iterator = list.iterator(); while (iterator.hasNext()) { Icon value = iterator.next(); if (value.getImageID()==v.getId()) { iterator.remove(); Log.e("======", value + "已經移除"); } } } // finish();//Exit Activity } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }).create().show(); return true; } }); layout.addView(imageView); imageView.setImageURI(uri); imageView.setBackgroundResource(R.drawable.log); } if (requestCode==2 && data != null){ //獲取圖片路徑 Uri selectedImage = data.getData(); String[] filePathColumns = {MediaStore.Images.Media.DATA}; Cursor c = getContentResolver().query(selectedImage, filePathColumns, null, null, null); c.moveToFirst(); int columnIndex = c.getColumnIndex(filePathColumns[0]); String imagePath = c.getString(columnIndex); Bitmap bm = BitmapFactory.decodeFile(imagePath); // img.setImageBitmap(bm); c.close(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(permissions[0].equals(Manifest.permission.CAMERA)){ if(grantResults[0]== PackageManager.PERMISSION_GRANTED){ Toast.makeText(CamerIcon.this,"已授權",Toast.LENGTH_SHORT).show(); }else { Toast.makeText(this, "授權失敗", Toast.LENGTH_SHORT).show(); } } } /** * 判斷是否授權開啟攝像機功能 */ private void isOpenPhoto(){ if (Build.VERSION.SDK_INT >= 23) { int REQUEST_CODE_CONTACT = 101; String[] permissions = { Manifest.permission.WRITE_EXTERNAL_STORAGE}; //驗證是否許可權限 for (String str : permissions) { if (CamerIcon.this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) { //申請權限 CamerIcon.this.requestPermissions(permissions, REQUEST_CODE_CONTACT); return; } } } if(Build.VERSION.SDK_INT>=23){ ActivityCompat.requestPermissions(CamerIcon.this,new String[]{Manifest.permission.CAMERA},0); int permission = ContextCompat.checkSelfPermission(CamerIcon.this.getApplicationContext(), Manifest.permission.CAMERA); if(permission== PackageManager.PERMISSION_GRANTED){ //如果有了相機的權限就調用相機 }else { AlertDialog.Builder builder=new AlertDialog.Builder(CamerIcon.this); builder.setTitle("提示"); builder.setMessage("是否開啟相機權限"); builder.setPositiveButton("是", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //去請求相機權限 ActivityCompat.requestPermissions(CamerIcon.this,new String[]{Manifest.permission.CAMERA},0); } }); builder.setNegativeButton("否", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(CamerIcon.this, "您拒絕了開啟相機權限", Toast.LENGTH_SHORT).show(); } }); builder.show(); } } }
將圖片上傳到服務器的方法:
public void uploading(View view,String url,File file) { //創建RequestBody封裝參數 RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), file);// MediaType.parse("image/jpeg")//application/octet-stream //創建MultipartBody,給RequestBody進行設置 MultipartBody multipartBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file",file.getName(), fileBody) .build(); //創建Request Request request = new Request.Builder() .url(url)//"ip:1111/Api/App/ImgUpload?UId=7" .post(multipartBody) .build(); //創建okhttp對象 OkHttpClient okHttpClient = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .build(); //上傳完圖片,得到服務器反饋數據 okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e("ff", "uploadMultiFile() e=" + e); } @Override public void onResponse(Call call, Response response) throws IOException { Log.i("ff", "uploadMultiFile() response=" + response.body().string()); } }); }
效果: