Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握!

马肤

温馨提示:这篇文章已超过472天没有更新,请注意相关的内容是否还可用!

摘要:本文介绍了如何在Android手机上将图片上传到服务器的方法。文章详细阐述了上传过程,包括获取图片、建立网络连接、发送请求等步骤。文章语言简洁明了,逻辑清晰,适合对Android开发有一定了解的人群阅读。即使是初学者,通过仔细阅读,也能理解并掌握图片上传的基本原理和操作方法。全网范围内,本文的内容易于理解,是Android图片上传的优质教程。

Android上传手机图片到服务器

  • 1、整体流程
  • 2、页面布局
  • 3、选择图片
    • 流程
    • 实现
    • 演示结果
    • 完整代码
    • 4、路径转换
      • 路径转换
      • Utils工具类
      • 权限申请
      • 完整代码
      • 5、创建文件
      • 6、服务器端
      • 7、传输
      • 8、演示
      • 9、完整代码
        • 目录结构
        • AndroidManifest.xml
        • 布局文件activity_main.xml
        • 传输文件工具类HttpUtil
        • 路径转换工具类Utils
        • MainActivity类

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第1张

          1、整体流程

          通过安卓app选取本地图片然后上传到服务器的整体流程步骤如下:

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第2张

          2、页面布局

          样式

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第3张

          布局代码

          
              
              
              
              
          
          

          id:iv_image用于呈现选择的图片

          id:xz用于选择图片的按钮

          id:sc用于上传的按钮

          3、选择图片

          流程

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第4张

          流程:点击“选择图片”在本机选取图片然后呈现到ImageView中(这个操作过程是不需要申请任何权限的)

          实现

          (1)获取“选择图片”按钮,并设置监听事件。

          xz = (Button) findViewById(R.id.xz);//选择照片按钮
          xz.setOnClickListener(this);//设置监听
          

          (2)获取ImageView,便于之后呈现图片

          iv_image = (ImageView) findViewById(R.id.iv_image);//展示图片按钮
          

          (3)点击“选择图片”后操作,选取图片

          点击事件

          @Override
              public void onClick(View view) {
                  switch (view.getId()) {
                      case R.id.xz:
                          xzImage();//选择图片
                          break;
                  }
              }
          

          xzImage()函数进行图片选择

          private void xzImage() {
                  
                  Intent intent = new Intent("android.intent.action.GET_CONTENT");
                  intent.setType("image/*");
                  startActivityForResult(intent,CHOOSE_PHOTO); // 打开本地存储
                  //CHOOSE_PHOTO:全局常量,标识
          }
          

          CHOOSE_PHOTO:是一个全局常量,用于标识这是选择图片的这个操作,便于在回调函数中使用。

          public static final int CHOOSE_PHOTO = 1;
          

          (4)重写选择图片后的回调函数

          当在手机上选择完图片后会回调onActivityResult函数,将一下“选择的信息”返回供用户操作。

          requestCode:标识码

          data:选择的图片的信息

          data.getData()可以获取到图片的路径,但是是虚拟路径不是真实的存储路径,虚拟路径在ImageView组件中可以使用,但是如果通过虚拟路径进行创建文件(new File(“路径”))是不可能的。

          @Override
              protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                  super.onActivityResult(requestCode, resultCode, data);
                //requestCode:标识码
                //data:选择的图片的信息
                  switch (requestCode) {
                      case CHOOSE_PHOTO:
                          //显示图片
                          iv_image.setImageURI(data.getData());//放在ImageView中呈现
                          break;
                      default:
                          break;
                  }
              }
          

          以上操作全部是无需权限申请的

          演示结果

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第5张

          完整代码

          上述操作的完整代码

          public class MainActivity extends AppCompatActivity implements View.OnClickListener {
              private Button xz;
              private ImageView iv_image;
              public static final int CHOOSE_PHOTO = 1;//标识选择图片
              @Override
              protected void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_main);
                  //按钮
                  xz = (Button) findViewById(R.id.xz);//选择照片按钮
                  //图片
                  iv_image = (ImageView) findViewById(R.id.iv_image);//展示图片
                  //设置点击事件监听
                  xz.setOnClickListener(this);
              }
              @Override
              public void onClick(View view) {
                  switch (view.getId()) {
                      case R.id.xz:
                          xzImage();
                          break;
                  }
              }
              private void xzImage() {
                  Intent intent = new Intent("android.intent.action.GET_CONTENT");
                  intent.setType("image/*");
                  startActivityForResult(intent,CHOOSE_PHOTO); // 打开本地存储
              }
              @Override
              protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                  super.onActivityResult(requestCode, resultCode, data);
                  switch (requestCode) {
                      case CHOOSE_PHOTO://判断是不是选择照片后的操作
                          //显示图片
                          iv_image.setImageURI(data.getData());
                          break;
                      default:
                          break;
                  }
              }
          }
          

          4、路径转换

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第6张

          由于data.getData()获取到的是图片的虚拟路径,所以我们需要对路径进行路径转换,从虚拟路径到真实路径的转换。(通过Utils.getRealPath(this, data)方法进行转换)

          Utils.getRealPath(this, data)方法是封装的工具类

          路径转换

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第7张

          Utils工具类

          public class Utils {
              public static String getRealPath(Context context,Intent data){
                  // 判断手机系统版本号
                  if (Build.VERSION.SDK_INT >= 19) {
                      // 4.4及以上系统使用这个方法处理图片
                      return handleImageOnKitKat(context,data);
                  } else {
                      // 4.4以下系统使用这个方法处理图片
                      return handleImageBeforeKitKat(context,data);
                  }
              }
              @TargetApi(19)
              private static String handleImageOnKitKat(Context context,Intent data) {
                  String imagePath = null;
                  Uri uri = data.getData();
                  if (DocumentsContract.isDocumentUri(context, uri)) {
                      // 如果是document类型的Uri,则通过document id处理
                      String docId = DocumentsContract.getDocumentId(uri);
                      if("com.android.providers.media.documents".equals(uri.getAuthority())) {
                          String id = docId.split(":")[1]; // 解析出数字格式的id
                          String selection = MediaStore.Images.Media._ID + "=" + id;
                          imagePath = getImagePath(context,MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
                      } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
                          Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public downloads"), Long.valueOf(docId));
                          imagePath = getImagePath(context,contentUri, null);
                      }
                  } else if ("content".equalsIgnoreCase(uri.getScheme())) {
                      // 如果是content类型的Uri,则使用普通方式处理
                      imagePath = getImagePath(context,uri, null);
                  } else if ("file".equalsIgnoreCase(uri.getScheme())) {
                      // 如果是file类型的Uri,直接获取图片路径即可
                      imagePath = uri.getPath();
                  }
                  //displayImage(imagePath); // 根据图片路径显示图片
                  return imagePath;
              }
              private static String handleImageBeforeKitKat(Context context,Intent data) {
                  Uri uri = data.getData();
                  String imagePath = getImagePath(context,uri, null);
                  return imagePath;
              }
              @SuppressLint("Range")
              private static String getImagePath(Context context,Uri uri, String selection) {
                  String path = null;
                  // 通过Uri和selection来获取真实的图片路径
                  Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null);
                  if (cursor != null) {
                      if (cursor.moveToFirst()) {
                          path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
                      }
                      cursor.close();
                  }
                  return path;
              }
          }
          

          权限申请

          由于在工具类中进行路径转换时候需要用到存储权限,所以我们在之前代码的基础上加上动态权限申请

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第8张

          注意:是在点击“选择图片”后进行权限申请,申请完后再去选择图片

          顺序是这样子的:点击“选择图片按钮” == > 权限申请 ==》选择图片·

          (1)在Manifest.xml中加入权限声明

          
          
          
          

          (2)在onclick处加上权限检测、申请步骤

          @Override
              public void onClick(View view) {
                  switch (view.getId()) {
                      case R.id.xz:
                          if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                              ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION);
                          } else {
                              xzImage();
                          }
                          break;
                  }
              }
          

          Manifest.permission.WRITE_EXTERNAL_STORAGE既包括读权限又包括写权限,所以在Manifest.xml中才声明了两个

          STORAGE_PERMISSION:是一个全局常量,用于标识申请的是什么权限,方便在权限的回调函数中使用。

          public static final int STORAGE_PERMISSION = 1;
          

          (3)添加权限的回调函数

          //选择权限后的回调函数
              @Override
              public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
                  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                  switch (requestCode) {
                      case STORAGE_PERMISSION:
                      //检查是否有读取存储卡的权限,如果有则选择图片,如果没有则提示
                          if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                              xzImage();
                          } else {
                              Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
                          }
                          break;
                      default:
                  }
              }
          

          STORAGE_PERMISSION:标识申请的是存储权限,是全局常量。

          (4)测试

          我们在onActivityResult中输出虚拟路径和真实路径看一下(如果不做上述的权限申请,则在调用Utils.getRealPath(this, data)方法进行路径转换时会报错)

          //选择图片后的回调函数
              @Override
              protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                  super.onActivityResult(requestCode, resultCode, data);
                  switch (requestCode) {
                      case CHOOSE_PHOTO:
                          //显示图片
                          iv_image.setImageURI(data.getData());
                          System.out.println("图片在手机上的虚拟路径为:"+data.getData());
                          String realPath = Utils.getRealPath(this, data);
                          System.out.println("图片在手机上的真实路径为:"+realPath);
                          break;
                      default:
                          break;
                  }
              }
          

          申请权限

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第9张

          输出

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第10张

          完整代码

          public class MainActivity extends AppCompatActivity implements View.OnClickListener {
              private Button xz;
              private ImageView iv_image;
              public static final int CHOOSE_PHOTO = 1;//标识选择图片
              public static final int STORAGE_PERMISSION = 1;//标识权限申请
              @Override
              protected void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_main);
                  //按钮
                  xz = (Button) findViewById(R.id.xz);//选择照片按钮
                  //图片
                  iv_image = (ImageView) findViewById(R.id.iv_image);//展示图片
                  //设置点击事件监听
                  xz.setOnClickListener(this);
              }
              @Override
              public void onClick(View view) {
                  switch (view.getId()) {
                      case R.id.xz:
                          if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                              ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION);
                          } else {
                              xzImage();
                          }
                          break;
                  }
              }
              private void xzImage() {
                  Intent intent = new Intent("android.intent.action.GET_CONTENT");
                  intent.setType("image/*");
                  startActivityForResult(intent,CHOOSE_PHOTO); // 打开本地存储
              }
              //选择图片后的回调函数
              @Override
              protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                  super.onActivityResult(requestCode, resultCode, data);
                  switch (requestCode) {
                      case CHOOSE_PHOTO:
                          //显示图片
                          iv_image.setImageURI(data.getData());
                          System.out.println("图片在手机上的虚拟路径为:"+data.getData());
                          String realPath = Utils.getRealPath(this, data);
                          System.out.println("图片在手机上的真实路径为:"+realPath);
                          break;
                      default:
                          break;
                  }
              }
              //选择权限后的回调函数
              @Override
              public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
                  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                  switch (requestCode) {
                      case STORAGE_PERMISSION:
                         //检查是否有读取存储卡的权限,如果有则选择图片,如果没有则提示
                          if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                              xzImage();
                          } else {
                              Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
                          }
                          break;
                      default:
                  }
              }
          }
          

          5、创建文件

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第11张

          当我们通过Utils.getRealPath(this, data)方法获取到真实的图片路径后就可以通过new File(路径的方式将图片封装成File对象了)

          String realPath = Utils.getRealPath(this, data);
          file = new File(realPath);
          

          这里的file是全局变量,便于后续上传的时候使用

          private File file=null;
          

          所以此时选择图片后的回调函数变为如下:

          //选择图片后的回调函数
              @Override
              protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                  super.onActivityResult(requestCode, resultCode, data);
                  switch (requestCode) {
                      case CHOOSE_PHOTO:
                          //显示图片
                          iv_image.setImageURI(data.getData());
                          //System.out.println("图片在手机上的虚拟路径为:"+data.getData());
                          String realPath = Utils.getRealPath(this, data);
                          file = new File(realPath);
                          //System.out.println("图片在手机上的真实路径为:"+realPath);
                          break;
                      default:
                          break;
                  }
              }
          

          至此从相册选择图片到将图片创建成file对象已经全部完成。

          这半部分全部完成

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第12张

          6、服务器端

          为便于测试,该项目的服务器代码比较简单,通过一个接口接收文件(uploadfile),以及传过来的其余参数(name)。输出其余参数,并将图片存储到项目的当前目录下命名为a.jpg

          @RestController
          @RequestMapping("/test")
          @CrossOrigin
          public class TestController {
              /**
               * 
               * @param uploadfile 接收文件
               * @param name 接收其余参数
               * @return
               * @throws IOException
               */
              @PostMapping("/upload")
              public String upload(MultipartFile uploadfile,String name) throws IOException {
                  //1、输出测试
                  System.out.println("==============");
                  System.out.println(uploadfile);
                  System.out.println(name);
                  System.out.println(uploadfile.getName());
                  System.out.println(uploadfile.getSize());
                  //2、将上传的图片存储到硬盘
                  InputStream inputStream = uploadfile.getInputStream();
                  FileChannel inChannel = (FileChannel) Channels.newChannel(inputStream);
                  FileChannel outChannel = new FileOutputStream("./a.jpg").getChannel();//当前目录下,命名为a.jpg
                  inChannel.transferTo(0,inChannel.size(),outChannel);
                  //3、关闭流
                  inChannel.close();
                  outChannel.close();
                  inputStream.close();
                  
                  //4、返回成功信息
                  return "success";
              }
          }
          

          (springboot项目)

          目前为止服务器端的代码也以及全部搞定

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第13张

          7、传输

          Android端的东西全部搞定,服务器端的东西也全部搞定,接下来就是通信了,也就是将文件从Android端传输到服务器端。

          传输文件采用okhttp进行数据的传输

          (1)权限申请

          由于传输的时候使用到网络,所以在Manifest.xml中声明网络权限

              
          

          并在Manifest.xml中加入这个,我们不采用https进行传输

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第14张

          (2)引入okhttp的依赖

          //okhttp
              implementation 'com.squareup.okhttp3:okhttp:3.14.9'
          

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第15张

          刷新后便可以将okhttp的依赖加载到本地

          (3)传输文件的工具类

          通过okhttp封装成上传文件的工具类

          public class HttpUtil {
              /**
               *
               * @param address  服务器地址
               * @param requestBody  请求体数据
               * @param callback  回调接口
               */
              public static void uploadFile(String address,RequestBody requestBody ,okhttp3.Callback callback){
                  //发送请求
                  OkHttpClient client = new OkHttpClient.Builder()
                          .connectTimeout(60, TimeUnit.SECONDS)//设置连接超时时间
                          .readTimeout(60, TimeUnit.SECONDS)//设置读取超时时间
                          .build();
                  Request request = new Request.Builder()
                          .url(address)
                          .post(requestBody)
                          .build();
                  client.newCall(request).enqueue(callback);
              }
          }
          

          (4)上传函数

          获取“上传按钮”并设置监听事件

          sc = (Button) findViewById(R.id.sc);//上传按钮
          sc.setOnClickListener(this);//上传
          

          在点击事件中添加scImage()函数,在点击"上传图片"按钮后触发

          onclick中

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第16张

          @Override
              public void onClick(View view) {
                  switch (view.getId()) {
                      case R.id.xz:
                          if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                              ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION);
                          } else {
                              xzImage();
                          }
                          break;
                      case R.id.sc:
                          scImage();
                          break;
                  }
              }
          

          scImage()函数

          private void scImage() {
                  //1、创建请求体
                  RequestBody requestBody = new MultipartBody.Builder()
                          .setType(MultipartBody.FORM)//请求类型
                          .addFormDataPart("name", "lisi")//参数1
                          .addFormDataPart("uploadfile", "uploadfile", RequestBody.create(MediaType.parse("*/*"), file)) // 第一个参数传到服务器的字段名,第二个你自己的文件名,第三个MediaType.parse("*/*")数据类型,这个是所有类型的意思,file就是我们之前创建的全局file,里面是创建的图片
                          .build();
                   //2、调用工具类上传图片以及参数
                  HttpUtil.uploadFile("http://你的服务器IP:8080/test/upload", requestBody, new Callback() {
                  
                      //请求失败回调函数
                      @Override
                      public void onFailure(Call call, IOException e) {
                          System.out.println("=============");
                          System.out.println("异常::");
                          e.printStackTrace();
                      }
                      
                      //请求成功响应函数
                      @Override
                      public void onResponse(Call call, Response response) throws IOException {
                          showResponse(response.body().string());//在主线程中显示提示框
                      }
                  });
              }
          

          注意:安卓端的字段名要与服务器端接收的字段名字一样

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第17张

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第18张

          由于在子线程不能操作ui,所以这里调用showResponse在主线程中提示,响应结果。

          showResponse()

          //ui操作,提示框
              private void showResponse(final String response) {
                  runOnUiThread(new Runnable() {
                      @Override
                      public void run() {
                          // 在这里进行UI操作,将结果显示到界面上
                          Toast.makeText(MainActivity.this, response, Toast.LENGTH_SHORT).show();
                      }
                  });
              }
          

          8、演示

          至此已经完成了所有步骤“Android端”、“服务器端”、“传输数据”的代码编写。

          我们将服务器端代码在服务器部署好,然后在Android端输入对应的ip,进行测试。

          服务的“当前文件夹目录”

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第19张

          传输

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第20张

          传输完后

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第21张

          可以拉到本地打开看一下

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第22张

          9、完整代码

          目录结构

          Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!),Android图片上传至服务器教程,一篇文章带你轻松掌握! 第23张

          AndroidManifest.xml

          
              
              
              
              
              
              
                  
                      
                          
                          
                      
                      
                  
              
          
          

          布局文件activity_main.xml

          
              
              
              
          
          

          传输文件工具类HttpUtil

          public class HttpUtil {
              /**
               *
               * @param address  服务器地址
               * @param requestBody  请求体数据
               * @param callback  回调接口
               */
              public static void uploadFile(String address,RequestBody requestBody ,okhttp3.Callback callback){
                  //发送请求
                  OkHttpClient client = new OkHttpClient.Builder()
                          .connectTimeout(60, TimeUnit.SECONDS)//设置连接超时时间
                          .readTimeout(60, TimeUnit.SECONDS)//设置读取超时时间
                          .build();
                  Request request = new Request.Builder()
                          .url(address)
                          .post(requestBody)
                          .build();
                  client.newCall(request).enqueue(callback);
              }
          }
          

          路径转换工具类Utils

          public class Utils {
              public static String getRealPath(Context context,Intent data){
                  // 判断手机系统版本号
                  if (Build.VERSION.SDK_INT >= 19) {
                      // 4.4及以上系统使用这个方法处理图片
                      return handleImageOnKitKat(context,data);
                  } else {
                      // 4.4以下系统使用这个方法处理图片
                      return handleImageBeforeKitKat(context,data);
                  }
              }
              @TargetApi(19)
              private static String handleImageOnKitKat(Context context,Intent data) {
                  String imagePath = null;
                  Uri uri = data.getData();
                  if (DocumentsContract.isDocumentUri(context, uri)) {
                      // 如果是document类型的Uri,则通过document id处理
                      String docId = DocumentsContract.getDocumentId(uri);
                      if("com.android.providers.media.documents".equals(uri.getAuthority())) {
                          String id = docId.split(":")[1]; // 解析出数字格式的id
                          String selection = MediaStore.Images.Media._ID + "=" + id;
                          imagePath = getImagePath(context,MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
                      } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
                          Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public downloads"), Long.valueOf(docId));
                          imagePath = getImagePath(context,contentUri, null);
                      }
                  } else if ("content".equalsIgnoreCase(uri.getScheme())) {
                      // 如果是content类型的Uri,则使用普通方式处理
                      imagePath = getImagePath(context,uri, null);
                  } else if ("file".equalsIgnoreCase(uri.getScheme())) {
                      // 如果是file类型的Uri,直接获取图片路径即可
                      imagePath = uri.getPath();
                  }
                  //displayImage(imagePath); // 根据图片路径显示图片
                  return imagePath;
              }
              private static String handleImageBeforeKitKat(Context context,Intent data) {
                  Uri uri = data.getData();
                  String imagePath = getImagePath(context,uri, null);
                  return imagePath;
              }
              @SuppressLint("Range")
              private static String getImagePath(Context context,Uri uri, String selection) {
                  String path = null;
                  // 通过Uri和selection来获取真实的图片路径
                  Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null);
                  if (cursor != null) {
                      if (cursor.moveToFirst()) {
                          path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
                      }
                      cursor.close();
                  }
                  return path;
              }
          }
          

          MainActivity类

          public class MainActivity extends AppCompatActivity implements View.OnClickListener {
              private Button xz;
              private Button sc;
              private ImageView iv_image;
              public static final int CHOOSE_PHOTO = 1;
              public static final int STORAGE_PERMISSION = 1;
              private File file=null;
              @Override
              protected void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_main);
                  //按钮
                  xz = (Button) findViewById(R.id.xz);//选择照片按钮
                  sc = (Button) findViewById(R.id.sc);//上传按钮
                  //图片
                  iv_image = (ImageView) findViewById(R.id.iv_image);//展示图片
                  //设置点击事件监听
                  xz.setOnClickListener(this);//选择
                  sc.setOnClickListener(this);//上传
              }
              @Override
              public void onClick(View view) {
                  switch (view.getId()) {
                      case R.id.xz:
                          if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                              ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION);
                          } else {
                              xzImage();
                          }
                          break;
                      case R.id.sc:
                          scImage();
                          break;
                  }
              }
          
              private void xzImage() {
                  Intent intent = new Intent("android.intent.action.GET_CONTENT");
                  intent.setType("image/*");
                  startActivityForResult(intent,CHOOSE_PHOTO); // 打开本地存储
              }
              private void scImage() {
                  RequestBody requestBody = new MultipartBody.Builder()
                          .setType(MultipartBody.FORM)
                          .addFormDataPart("name", "lisi")
                          .addFormDataPart("uploadfile", "uploadfile", RequestBody.create(MediaType.parse("*/*"), file)) // 第一个参数传到服务器的字段名,第二个你自己的文件名,第三个MediaType.parse("*/*")数据类型,这个是所有类型的意思,file就是我们之前创建的全局file,里面是创建的图片
                          .build();
                          
                  HttpUtil.uploadFile("http://你自己的ip:8080/test/upload", requestBody, new Callback() {
                      @Override
                      public void onFailure(Call call, IOException e) {
                          System.out.println("=============");
                          System.out.println("异常::");
                          e.printStackTrace();
                          //Toast.makeText(MainActivity.this, "上传异常", Toast.LENGTH_SHORT).show();
                      }
                      @Override
                      public void onResponse(Call call, Response response) throws IOException {
                          showResponse(response.body().string());
                          //Toast.makeText(MainActivity.this, "上传成功", Toast.LENGTH_SHORT).show();
                      }
                  });
              }
              //选择图片后的回调函数
              @Override
              protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                  super.onActivityResult(requestCode, resultCode, data);
                  switch (requestCode) {
                      case CHOOSE_PHOTO:
                          //显示图片
                          iv_image.setImageURI(data.getData());
                          //System.out.println("图片在手机上的虚拟路径为:"+data.getData());
                          String realPath = Utils.getRealPath(this, data);
                          file = new File(realPath);
                          //System.out.println("图片在手机上的真实路径为:"+realPath);
                          break;
                      default:
                          break;
                  }
              }
              //选择权限后的回调函数
              @Override
              public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
                  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                  switch (requestCode) {
                      case STORAGE_PERMISSION:
                          if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                              xzImage();
                          } else {
                              Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
                          }
                          break;
                      default:
                  }
              }
              //ui操作,提示框
              private void showResponse(final String response) {
                  runOnUiThread(new Runnable() {
                      @Override
                      public void run() {
                          // 在这里进行UI操作,将结果显示到界面上
                          Toast.makeText(MainActivity.this, response, Toast.LENGTH_SHORT).show();
                      }
                  });
              }
          }
          

0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码