当前位置: 首页>移动开发>正文

android 上传图片实例 android 上传图片到服务器


安卓上传图片到服务器阿里云OSS(可实现多图片上传)

  • 开发过程中遇到的问题
  • 1、W/System.err: java.net.UnknownServiceException:
  • 一、效果演示
  • 二、购买阿里云OSS对象存储
  • 三、设置阿里云OSS对象存储配置
  • 1. 新建Bucket
  • 2. 配置Bucket
  • 3. 绑定域名(如果有)
  • 4. 创建RAM用户获取密匙
  • 四、Android上传到服务器代码实现
  • 1. 引入阿里云OSS依赖
  • 2. AliyunUploadFile工具类
  • 3. AliyunUploadFile工具类调用小例子,可一次上次多张图片



开发过程中遇到的问题


1、W/System.err: java.net.UnknownServiceException:

报错

W/System.err: java.net.UnknownServiceException: 
CLEARTEXT communication to xxx.xxx.xxx not permitted by network security policy


问题分析:

  为保证用户数据和设备的安全,Google针对下一代 Android 系统(Android P) 的应用程序,将要求默认使用加密连接,这意味着 Android P 将禁止 App 使用所有未加密的连接,因此运行 Android P 系统的安卓设备无论是接收或者发送流量,未来都不能明码传输,需要使用下一代(Transport Layer Security)传输层安全协议,而 Android Nougat 和 Oreo 则不受影响。
  在Android P系统的设备上,如果应用使用的是非加密的明文流量的http网络请求,则会导致该应用无法进行网络请求,https则不会受影响,同样地,如果应用嵌套了webview,webview也只能使用https请求。


解决方法:往AndroidManifestapplication中设置下列属性即可。

android:usesCleartextTraffic="true"

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_android 上传图片实例,第1张


一、效果演示


这次主要是实现本地图片上传到服务器的功能,如下gif所示:上传图片之后,就可以通过图片链接来访问到图片,并在页面展示出来。

上传成功之后可以在服务器查看到该图片了,如下图所示:

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_android 上传图片实例_02,第2张



二、购买阿里云OSS对象存储


直接在阿里云首页搜索对象存储OSS

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_java_03,第3张


点击图中所示的地方

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_android 上传图片实例_04,第4张


我们选择标准存储包即可,然后选择中国大陆地区,存储包规格选个40G够用了,因为只是存储博客图片,或者是笔记图片都是够了的。然后时长按自己所需来选即可,反正也不贵。流量的话因为我就上次一点图片,所以按量计费不是很贵。
(咳咳,存储空间虽然不贵,但是外网访问图片资源时下载图片资源不免费,这是真滴坑,值得一提的是上传图片免费,具体可以查看相关资料)

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_android_05,第5张



三、设置阿里云OSS对象存储配置


1. 新建Bucket

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_android_06,第6张


2. 配置Bucket

按图中选择即可,因为我也是服务器小白,所以某些设置可能有问题,但是毕竟这只是一个学习的demo,设置好Bucket之后能使用就行,是吧,嘿嘿嘿…

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_android_07,第7张


然后点击进入该Bucket,创建几个存放图片的文件夹,这里我创建了一个存放头像的文件夹usericons,以及创建一个存放用户发布的图片的文件夹images

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_阿里云_08,第8张


3. 绑定域名(如果有)

如果有域名且域名认证了的话,可以绑定域名。没有就跳过这一步即可。

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_java_09,第9张


这里可能会有一个问题:添加 CNAME 记录提示和 A 记录冲突如何解决
解决方法:添加 CNAME 记录提示和 A 记录冲突解决方法

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_服务器_10,第10张


4. 创建RAM用户获取密匙


点击AccessKey管理

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_服务器_11,第11张


点这个

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_android_12,第12张

创建一个Ram用户

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_java_13,第13张

创建好之后点击确认,名称随便填

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_服务器_14,第14张

经过验证之后就创建成功了记得要保存AccessKey IDAccessKey Secret, 不保存下次就没了,没了能怎么办?重新删掉,再创建一个呗!!!

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_android 上传图片实例_15,第15张


给创建的Ram用户赋值, 在用户界面, 点击添加权限

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_阿里云_16,第16张

最后赋予图中的权限, 点击确认即可, 这样就完成了配置, 完成了之后我们就需要到代码中去配置了。

(其实这样也是完成了图床的配置, 可以使用我们获取到的AcessKeyIDAcessKey SecretPicGo软件上配置,这样随时都能上传图片到该服务器, 还可以配合Typora将写笔记(博客)的图片上传到该服务器,这里就不写了).

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_阿里云_17,第17张



四、Android上传到服务器代码实现

参考文献:
阿里云官网:上传本地文件到阿里云OSS


1. 引入阿里云OSS依赖

//自动获取最新版本
implementation 'com.aliyun.dpa:oss-android-sdk:+'


2. AliyunUploadFile工具类

这个就是我们上传图片封装的工具类了。我已经写好注释了,你只需要将你的AccessKey IDAcessKey Secert等填好,在图片发布Activity中调用该类,将获取到的图片地址传到该类就行了。

public class AliyunUploadFile {

    private OSSCredentialProvider credentialProvider;

    private ClientConfiguration conf;

    private OSS oss;

    // 填写生成的访问密钥AccessKey ID和AccessKey Secret。
    private String AccessKeyId = "LTAI66GDnSkpScpuJMgt26RJ";
    private String SecretKeyId = "U8eEfIlz4f7DTP8hjW4b8FfFUBBxtA";
    // STS接入地址,例如sts.cn-hangzhou.aliyuncs.com。
    private String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
    //bucketName
    private String bucketName = "xiaohaituchuang";


    /**
     *
     * @param context 上下文
     * @param uploadFilePath 上传的文件路径
     */
    public void UploadFile(Context context, String uploadFilePath) {

        // 第一个参数:在【RAM访问控制】创建用户时分配的accessKeyId
        // 第二个参数:在【RAM访问控制】创建用户时分配的accessKeySecret
        OSSCredentialProvider ossCredentialProvider = new OSSPlainTextAKSKCredentialProvider(AccessKeyId, SecretKeyId);

        // 第一个参数:上下文
        // 第二个参数:在OSS控制台创建好Bucket后,会有一个EndPoint(地域节点),比如我这里的节点是:http://oss-cn-hangzhou.aliyuncs.com
        // 第三个参数:OSSCredentialProvider
        OSS oss = new OSSClient(context.getApplicationContext(), endpoint, ossCredentialProvider);


        String img_name = "images/img_";
  


        //获取图片格式后缀名,比如.png, .jpg等等
        String str1 = uploadFilePath.substring(0, uploadFilePath.indexOf("."));
        String str2 = "." + uploadFilePath.substring(str1.length()+1,uploadFilePath.length());


        //上传后图片的地址, 可以将该图片地址存入数据库,我这里就不写存进数据库了。
        String img_url = "http://域名/" + img_name + str2;
        img_name = img_name + str2;


        // 第二个参数:可以是一个文件路径:比如你在xiaohaituchuang创建了一个文件夹为images,那第二个参数传images/img.jpg
        // 第三个参数:是文件的本地路径,比如我这里在本地路径中是姨丈图片,路径是sdcard/img/img.jpg
        PutObjectRequest put = new PutObjectRequest(bucketName, img_name, uploadFilePath);
        // 异步上传时可以设置进度回调。
        put.setProgressCallback((request, currentSize, totalSize) -> {
            Log.d("currentSize = " + currentSize, "totalSize = " + totalSize);
        });
        // 此处调用异步上传方法
        OSSAsyncTask ossAsyncTask= oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                Log.d("PutObject", "UploadSuccess");
                Log.d("ETag", result.getETag());
                Log.d("RequestId", result.getRequestId());
                uploadFlag = 1; //这个是上次多张图片时判断上传成功的标准,我在例子里写有,不需要的话可以删除

            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientException, ServiceException serviceException) {
                // 请求异常。
                if (clientException != null) {
                    // 本地异常,如网络异常等。
                    Log.e("网络异常",clientException.getMessage());
                    uploadFlag = 2;
                }
                if (serviceException != null) {
                    // 服务异常。
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                    uploadFlag = 3;
                }
            }
        });
    }
}


3. AliyunUploadFile工具类调用小例子,可一次上次多张图片

我这里就简单的对发布按钮进行监听, 当点击的时候调用上传文件工具类对图片进行上传。在NineGridViewActivity里面编写:


(1)定义图片集合

private List<File> files; //图片集合
private int[] filesIndex; //图片集合下标

(2)定义图片上传状态:

public static int uploadFlag = 0;   //0:表示图片未开始上传,  1:表示图片上传成功

(3)初始化图片集合
OnCreate方法里面初始化即可。

files = new ArrayList<>();
filesIndex = new int[9];//因为我弄的是最多9张图

(4)获取图片地址。

for (int i = 0; i < list.size(); i++) {
    File file = new File(list.get(i).getImagePath());
    files.add(file);
    filesIndex[i] = 1;
}

在这里获取图片地址:

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_android_18,第18张

(5)调用工具类,点击发布按钮后,就上传。

这里演示的是在NineGridViewActivity中的OnCreate调方法用该工具类:

//绑定上传图片按钮
Button button = findViewById(R.id.send_button);
//监听按钮点击事件,点击后上传图片.
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        AliyunUploadFile picUpload = new AliyunUploadFile();

        Toast.makeText(NineGridViewActivity.this, "上传中,请稍后!!!", Toast.LENGTH_SHORT).show();


        //上传图片
        try {
            for (int i = 0; i < files.size(); i++) {
                if(filesIndex[i] != 1) continue;
                picUpload.UploadFile(NineGridViewActivity.this,files.get(i).getPath());
                //等待该图片上传完成
                while (uploadFlag == 0);
                if(i < files.size()-1) uploadFlag = 0;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //等待最后一张图上传完成
        while (uploadFlag == 0);

        //使用弹窗反馈给用户上传结果
        switch (uploadFlag) {
            case 1:
                Toast.makeText(NineGridViewActivity.this, "上传成功!!!", Toast.LENGTH_SHORT).show();
                break;
            case 2:
                Toast.makeText(NineGridViewActivity.this, "上传失败,网络异常!!!", Toast.LENGTH_SHORT).show();
                break;
            case 3:
                Toast.makeText(NineGridViewActivity.this, "上传失败,服务器异常!!!", Toast.LENGTH_SHORT).show();
                break;
            case 4:
                Toast.makeText(NineGridViewActivity.this, "上传失败,数据库异常!!!", Toast.LENGTH_SHORT).show();
                break;
            default:
                Toast.makeText(NineGridViewActivity.this, "上传失败,未知错误!!!", Toast.LENGTH_SHORT).show();
                break;
        }
    }
});


上传后的图片可以在服务器查看:

android 上传图片实例 android 上传图片到服务器,android 上传图片实例 android 上传图片到服务器_android 上传图片实例_19,第19张



最后大功告成,在阿里云官网里控制台的对象存储OSS中可以看到上传的图片,谢谢大家的观看。



https://www.xamrdz.com/mobile/4qs1961276.html

相关文章: