这是一篇开博客以来最认真的文章(被困扰了三天才解决的)。
AndroidStudio部分:
第一步:拍照上传按钮点击事件
uploadBtn = findViewById(R.id.BtnUploadMor);//定位在xml文件中定义的上传按钮
Uri imgFileUrl;
String uploadImgName;
uploadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);//调用手机拍照功能其实就是启动一个activity
String filename= "test.jpg";//自定义的照片名称
File file = new File(Environment.getExternalStorageDirectory(), filename);//拍照后照片存储路径
if(file.exists())//如果同名图片已存在就删除图片
{
file.delete();
}
//获取图片存储路径(大概吧。。。)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
imgFileUrl = FileProvider.getUriForFile(getContext(), "com.example.test.fileProvider", file);
}
else {
imgFileUrl = Uri.fromFile(file);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, imgFileUrl); //指定图片存放位置,指定后,在onActivityResult里得到的Data将为null
uploadImgName=filename;
startActivityForResult(intent, CAMERA_PIC_REQUEST);//开启相机
}
});
上述代码中Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE)需要自己在AndroidManifest中定义,如下
<application
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.test.fileProvider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"
tools:replace="android:resource"/>
</provider>
</application>
其中, android:resource="@xml/file_paths"也是需要自己在res文件夹下创建一个xml文件夹,再新建file_paths.xml文件:
file_paths.xml中的内容:
<?xml version="1.0" encoding="utf-8"?>
<paths >
<external-path
name="external_path"
path="." />
</paths>
第二步:照片接收及处理
ImageView pic;
pic = (ImageView) findViewById(R.id.pic);
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (resultCode == RESULT_OK)
{
pic.setImageURI(imgFileUrl);//imageview控件显示刚拍的图片
uploading(uploadBtn,uploadImgName);//上传照片至服务器的方法
}
else
{
Toast.makeText(MyApplication.getContext(), "照片保存不成功!", Toast.LENGTH_SHORT).show();
return;
}
}
public void uploading(View view,String uploadImgName) {
//图片上传WebAPI接口的URL地址:imageUri
//创建上传文件对象
File file = new File(Environment.getExternalStorageDirectory(), uploadImgName);
if (!file.exists()) { // 检查图片存放的文件夹是否存在
file.mkdir(); // 不存在的话 创建文件夹
}
//创建RequestBody封装参数
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);// MediaType.parse("image/jpeg")//application/octet-stream
//创建MultipartBody,给RequestBody进行设置
MultipartBody multipartBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", uploadImgName, fileBody)
.build();
//创建Request
Request request = new Request.Builder()
.url(imageUri)
.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());
}
});
}
第三步:照片写入权限
由于现在许多手机对于相册的使用需要用户手动开启,故在onCreate方法中需要加入请求照片写入权限的代码:
if(Build.VERSION.SDK_INT >= 23){//判断当前系统的版本
int checkWriteStoragePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);//获取系统是否被授予该种权限
if(checkWriteStoragePermission != PackageManager.PERMISSION_GRANTED){
//如果没有被授予
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_CODE_ASK_WRITE_EXTERNAL_STORAGE);
return;//请求获取该种权限
}}
AndroidManifest中需加入的权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
至此,AndroidStudio部份的代码完成了。
WebAPI部分:
首先新建一个controller:UploadImgController
public class UploadImgController : Controller
{
public ApiResult uploadPic()
{
ApiResult apiResult = new ApiResult();
try
{
HttpPostedFileBase file = Request.Files["file"];//获取上传的图片
if (file != null)
{
// 文件上传后的保存路径
string filePath = "D:/TR/image" + "/";
//如果不存在该文件夹就创建一个新的
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
string fileName = Path.GetFileName(file.FileName);// 原始文件名称
string fileExtension = Path.GetExtension(fileName); // 文件扩展名
string savePath = filePath + fileName; // 保存文件名称
file.SaveAs(savePath);
FileInfo fileInfo = new FileInfo(savePath);
FileStream fs = fileInfo.OpenRead();/文件读取
byte[] bytes = new byte[fs.Length];/实例化二进制类型
fs.Read(bytes, 0, Convert.ToInt32(fs.Length));/读取赋值与二进制数组中
fs.Close();关闭
apiResult.Data = "上传成功!";
}
else
{
apiResult.ErrMsg = "请选择上传的文件!";
}
return apiResult;
}
catch (Exception ex)//捕获异常
{
apiResult.ErrMsg = "请求发生错误,请稍后重试!";
return apiResult;
}
}
}
其中,返回类ApiResult是自定义Model:
public class ApiResult
{
public string Data { get; set; }
public string ErrMsg { get; set; }
}
参考文章:Android上传图片后台服务器代码