文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android上传手机图片到服务器(这篇你要是看不懂,全网没你可以看懂的了!!!)

2023-09-02 06:32

关注

Android上传手机图片到服务器

在这里插入图片描述

1、整体流程

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

2、页面布局

样式

在这里插入图片描述
布局代码

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center"    android:orientation="vertical"    >    <ImageView        android:layout_width="200dp"        android:layout_height="200dp"        android:background="#555555"        android:id="@+id/iv_image"/>    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/xz"        android:text="选择图片"/>    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/sc"        android:text="上传图片"/>    LinearLayout>

id:iv_image用于呈现选择的图片
id:xz用于选择图片的按钮
id:sc用于上传的按钮

3、选择图片

流程

在这里插入图片描述
流程:点击“选择图片”在本机选取图片然后呈现到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    @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项目)
目前为止服务器端的代码也以及全部搞定
在这里插入图片描述

7、传输

Android端的东西全部搞定,服务器端的东西也全部搞定,接下来就是通信了,也就是将文件从Android端传输到服务器端。
传输文件采用okhttp进行数据的传输
(1)权限申请
由于传输的时候使用到网络,所以在Manifest.xml中声明网络权限

    <uses-permission android:name="android.permission.INTERNET" />

并在Manifest.xml中加入这个,我们不采用https进行传输
在这里插入图片描述

(2)引入okhttp的依赖

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

在这里插入图片描述
刷新后便可以将okhttp的依赖加载到本地
(3)传输文件的工具类
通过okhttp封装成上传文件的工具类

public class HttpUtil {        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中
在这里插入图片描述

@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就是我们之前创建的全局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());//在主线程中显示提示框            }        });    }

注意:安卓端的字段名要与服务器端接收的字段名字一样
在这里插入图片描述
在这里插入图片描述

由于在子线程不能操作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,进行测试。

服务的“当前文件夹目录”
在这里插入图片描述
传输
在这里插入图片描述

传输完后
在这里插入图片描述
可以拉到本地打开看一下
在这里插入图片描述

9、完整代码

目录结构

在这里插入图片描述

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">        <uses-permission android:name="android.permission.INTERNET" />        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/Theme.MyApplication"        android:usesCleartextTraffic="true"        >        <activity            android:name=".MainActivity"            android:exported="true">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            intent-filter>            <meta-data                android:name="android.app.lib_name"                android:value="" />        activity>    application>manifest>

布局文件activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center"    android:orientation="vertical"    >    <ImageView        android:layout_width="200dp"        android:layout_height="200dp"        android:background="#555555"        android:id="@+id/iv_image"/>    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/xz"        android:text="选择图片"/>    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/sc"        android:text="上传图片"/>LinearLayout>

传输文件工具类HttpUtil

public class HttpUtil {        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*"), 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();            }        });    }}

来源地址:https://blog.csdn.net/baiqi123456/article/details/129327111

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-服务器
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯