Photo Sharing App Part II: Understanding OSS Functions & Creating UI

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: We will build a photo sharing Android app with real-time image uploading and downloading functionality using Alibaba Cloud OSS.

Practices_of_De_duplication_and_Image_Search_Services

By Sai Sarath Chandra, Alibaba Cloud Tech Share Author and Alibaba Cloud MVP

In Last section, we have created the workspace setup and required STS credentials using "Resource Access Management" to access the Object Storage Service of Alibaba Cloud. In this section will be creating the Android application and will also be bootstrapping the user interface of the application, we will also be discussing the various synchronous and asynchronous functionalities of the object storage service Android SDK provided by Alibaba Cloud and we will also see the working of the image processing capabilities of the Alibaba Cloud using Android.

Creating Android project:

Create an Android project with the name you prefer. I provided the name "Photo Sharing". If you use the same settings as I used you don't need to change much of the code and in this way you can prevent the address cause by the code changes.

1

Select the min SDK and device compatibility, I am targeting the devices with minimum API level 19 or later only phone and tablet.

2

Select empty activity and proceed further.

3

Keep all the default values as given and click finish.

4

let the Android Studio to build code and open the project.

Creating the User Interface:

Setting up Gradle:

Open your application level gradle file and update the dependency section with the given below code.

implementation fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:27.0.2'
testImplementation 'junit:junit:4.12'
compile 'com.aliyun.dpa:oss-android-sdk:2.4.5'
compile 'com.github.jkwiecien:EasyImage:1.3.1'
implementation 'com.github.bumptech.glide:glide:4.4.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.4.0'
implementation 'com.android.support:recyclerview-v7:27.0.2'
compile group: 'commons-io', name: 'commons-io', version: '2.6'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okio:okio:1.9.0'
compile 'com.android.support:cardview-v7:27.0.2'

once the gradle file is being updated please synchronise the changes and make sure everything compile successfully with no errors / warnings

This gradle file contains the dependencies for both Object Storage Service (OSS) SDK from Alibaba cloud, their interdependencies and also some of the support libraries which we will use in creating the user interface of the application.

Creating activity XML:

we will create for XML files for the complete UI of the application.

activity_welcome.xml

This screen will be shown as the first screen of the application the responsibility of the screen is to navigate the user between the upload file section and view images option. Please create the file name as mentioned under layout folder and copy the following code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/uploadFiles"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_margin="8dp"
        android:textSize="24sp"
        android:textColor="#FFFFFF"
        android:text="UPLOAD FILES"
        android:background="#303F9F"/>

    <Button
        android:id="@+id/viewImages"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_margin="8dp"
        android:textColor="#FFFFFF"
        android:textSize="24sp"
        android:background="#388E3C"
        android:text="VIEW IMAGES" />

</LinearLayout>

Just to give a view how approximately it looks once this is done. Please find the image below:

5

activity_main.xml

Once the user selects the "Upload Files" option then the user will be navigated here.

This screen will be responsible for providing the user the ability to upload a picture from camera gallery and documents. the screen will also provide the capability for various image processing functionalities like resize, crop, rotate, watermarking etc...

please create the file as the name mentioned and replace the file content with the following code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">

        <ImageButton
            android:id="@+id/cameraBtn"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="8dp"
            android:layout_weight="1"
            android:background="#E91E63"
            android:src="@drawable/ic_camera_enhance_white_24dp" />

        <ImageButton
            android:id="@+id/galleryBtn"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="8dp"
            android:layout_weight="1"
            android:background="#9C27B0"
            android:src="@drawable/ic_view_24dp" />

        <ImageButton
            android:id="@+id/documentsBtn"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_margin="8dp"
            android:layout_weight="1"
            android:background="#F44336"
            android:src="@drawable/ic_folder_24dp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_margin="8dp"
        android:layout_weight="4"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">

            <Button
                android:id="@+id/resizeImg"
                style="@style/Widget.AppCompat.Button.Borderless"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="#00ACC1"
                android:text="Resize" />

            <Button
                android:id="@+id/cropImg"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="#7CB342"
                android:text="Crop" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">

            <Button
                android:id="@+id/rotateImg"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="#FDD835"
                android:text="Rotate" />

            <Button
                android:id="@+id/sharpenImg"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="#F4511E"
                android:text="Sharpen"
                android:textColor="#FFFFFF" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">

            <Button
                android:id="@+id/watermarkImg"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="#757575"
                android:text="Add Watermark"
                android:textColor="#FFFFFF" />

        </LinearLayout>

    </LinearLayout>


</LinearLayout>

To show how it looks after you have done this step. Please find the Image below.

You might not get the exact similar look as we didn't add the fonts programmatically as we targeting the user's Android KitKat 4.4. After we add the fonts programmatically we can see the changes in the Android Application directly.

6

activity_img_recycler.xml

When the user selects view images option in the welcome screen then the user will be navigated to this particular screen in the screen will be using recycler view of Android support library to show the list of images which are fetched from the server in real time and show the images which are applied with the image processing functionalities.

A brief background of recycler view as this is the advance form of list view which uses less memory and creates high-performance list which are very fluid and very memory efficient. we will discuss more when we create the Core Java code for the same.

Please create the file and copy the code as displayed:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical" />

</LinearLayout>

recyclerview_row.xml

This particular XML is used for displaying the images in the recycler view this XML depicts the UI for the single row in the recycler view.

please create the file as mentioned and copy the corresponding code to the file from below:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="wrap_content"
    >
    <!-- A CardView that contains a TextView -->
    <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        card_view:cardCornerRadius="4dp">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/imageView"
                android:src="@drawable/placeholder"
                android:adjustViewBounds="false"/>

            <TextView
                android:layout_marginTop="8dp"
                android:layout_marginBottom="8dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/imageView"
                android:id="@+id/imageName"
                android:textAlignment="center"
                android:textSize="18sp"
                android:textStyle="bold"
                android:textColor="#000000"
                android:text="Image Name"/>

        </RelativeLayout>

    </android.support.v7.widget.CardView>
</LinearLayout>

Understanding OSS (Object Storage Service) Android SDK

Unlike other Android projects we have created till now where we use Java SDK and use the downloaded jar files into the application. the OSS Android SDK provides both synchronous and asynchronous functionality, this means there is no need for you to create separate asynchronous task to run the UI related code in your application.

if you have little experience with RX Java it will be little easy to understand how the asynchronous code execute in a synchronous block to give a brief background of how asynchronous code execute

Everything in reactive languages uses event based mechanism to notify the methods or the observers

•The code with his executive and producing the result is called observable
•The code which listen for the updates of the observable is called observer
•When the observable complete the execution it notifies the observer that the code execution is completed and provides the result to the observer on to their on success method.

The main advantage of asynchronous or event based coding is that we can prevent so many NullPointer exception and we can write high performance code and again that is a discussion by itself.

Fortunately, we not need to understand or implement all the low-level functionalities of an event based asynchronous coding in our application as this is already handled by Alibaba cloud team and provides high level functions which are very easy to understand and use. for example, now we see the uploading task in an asynchronous fashion where we need to implement couple of methods to achieve this functionality and this is very easy. You will feel very comfortable once you understand the asynchronous coding as this reduces the complexities posed by AsyncTask. Please find the below code:

PutObjectRequest put = new PutObjectRequest(getString(R.string.Bucket_Name), "Demo_Picture_1.png", filePath);
put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
    @Override
    public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
        Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
    }
});
OSSAsyncTask task = 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());
    }
    @Override
    public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
        // Request exception
        if (clientExcepion != null) {
            // Local exception, such as a network exception
            clientExcepion.printStackTrace();
        }
        if (serviceException != null) {
            // Service exception
            Log.e("ErrorCode", serviceException.getErrorCode());
            Log.e("RequestId", serviceException.getRequestId());
            Log.e("HostId", serviceException.getHostId());
            Log.e("RawMessage", serviceException.getRawMessage());
        }
    }
});

Initially the PutRequest object is created with all the required parameters like Bucket name, Image key in the file path and then we set the progress call back on this request. This is as similar as "onProgress" method in the AsyncTask. This will be triggered whenever there is an update on the Task.

then we create the task by sending the request along with the 2 ovverrided implementations called "onSuccess" and "onFailure"

onSuccess :

This method is triggered after the successful operation and it carries the result we can use the result to know the status based on the implementation provided

onFailure :

If the execution failed due to any reason this particular method will be triggered and it carries the request along with the client exception or the service exception you can use it to find about the detailed information, stackTrace and reason of occurrence.

Then maybe some scenario where you need to use the AsyncTask in conjunction with the asynchronous code due to the synchronous code in between the multiple asynchronous blocks.

Summary

In this part, we understood the synchronous way of using OSS service of Alibaba cloud and we even created the UI of the application in next section we will be discussing and creating the Java code for the same and provide multiple functionalities to the UI which we have created and we even discuss about the image processing capabilities and how to use them in our Android application.

相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
目录
相关文章
|
9月前
|
编解码 搜索推荐 iOS开发
你知道APP UI设计基础知识和测试点吗?
你知道APP UI设计基础知识和测试点吗?
120 0
|
对象存储
阿里云OSS 服务端签名后直传之分片上传(结合element-ui的upload组件)
阿里云OSS 服务端签名后直传之分片上传(结合element-ui的upload组件)
587 0
在uni-app中使用element-ui
在uni-app中使用element-ui
886 0
|
3月前
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
188 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
|
4月前
|
存储 前端开发 UED
uni-app:icon&修改tabber&unu-ui (四)
本文介绍了如何从阿里巴巴下载矢量图标并使用 `iconfont`,包括创建项目、下载文件、引入 `font.css` 到项目中以及在 `app.vue` 中引用的方法。同时,还详细说明了如何修改 `tabbar` 的样式和配置,以及如何在项目中导入和使用 `uni-ui` 组件库,包括简单的弹出框 `popup` 和带有头部或尾部图标的输入框 `input`。
151 0
|
5月前
|
移动开发 定位技术 Android开发
「揭秘高效App的秘密武器」:Kotlin Flow携手ViewModel,打造极致响应式UI体验,你不可不知的技术革新!
【9月更文挑战第12天】随着移动开发领域对响应式编程的需求增加,管理应用程序状态变得至关重要。Jetpack Compose 和 Kotlin Flow 的组合提供了一种优雅的方式处理 UI 状态变化,简化了状态管理。本文探讨如何利用 Kotlin Flow 增强 ViewModel 功能,构建简洁强大的响应式 UI。
90 3
|
6月前
|
Python
【Azure 应用服务】Python Function App重新部署后,出现 Azure Functions runtime is unreachable 错误
【Azure 应用服务】Python Function App重新部署后,出现 Azure Functions runtime is unreachable 错误
|
6月前
【Azure 应用服务】Function App中的函数(Functions)删除问题
【Azure 应用服务】Function App中的函数(Functions)删除问题
|
8月前
|
存储 安全 前端开发
APP管理后台OSS技术改造
旨在记录之前使用的上传文件是放在服务器的现在改成了oss更加高效管理
|
9月前
Google Earth Engine APP(GEE)—— 一个简单的加载影像的UI(RGB,NDWI和NDVI)这里使用时间滑块进行时间选择
Google Earth Engine APP(GEE)—— 一个简单的加载影像的UI(RGB,NDWI和NDVI)这里使用时间滑块进行时间选择
132 0

热门文章

最新文章

  • 1
    MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
  • 2
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    微信小程序 app.json 配置文件解析与应用
  • 4
    【Azure App Service】基于Linux创建的App Service是否可以主动升级内置的Nginx版本呢?
  • 5
    【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 6
    【Azure Function】Function App出现System.IO.FileNotFoundException异常
  • 7
    原生鸿蒙版小艺APP接入DeepSeek-R1,为HarmonyOS应用开发注入新活力
  • 8
    【Azure Logic App】使用MySQL 新增行触发器遇见错误 :“Unknown column 'created_at' in 'order clause'”
  • 9
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 10
    阿里云APP备案流程图以及备案所需材料整理,跟着教程一步步操作