Skip to content

Commit

Permalink
Add feature to upload images when new topic and comment
Browse files Browse the repository at this point in the history
close #19
  • Loading branch information
mzlogin committed May 12, 2019
1 parent eaedbc7 commit dda216d
Show file tree
Hide file tree
Showing 14 changed files with 482 additions and 13 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'org.jsoup:jsoup:1.10.3'
implementation 'org.jsoup:jsoup:1.11.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package org.mazhuang.guanggoo.base;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

/**
* @author mazhuang
* @date 2019-05-12
*/
public abstract class BaseUploadImageFragment<T> extends BaseFragment<T> {
protected void chooseImage() {
CharSequence[] items = {"从相册选择", "拍照", "取消"};
new AlertDialog.Builder(getActivity())
.setTitle("选择图片来源")
.setItems(items, (dialog, which) -> {
if ( which == 0 ){
try {
//选择照片的时候也一样,我们用Action为Intent.ACTION_GET_CONTENT,
//有些人使用其他的Action但我发现在有些机子中会出问题,所以优先选择这个
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, which);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
toast(e.getMessage());
}
} else if (which == 1) {
try {
//拍照我们用Action为MediaStore.ACTION_IMAGE_CAPTURE,
//有些人使用其他的Action但我发现在有些机子中会出问题,所以优先选择这个
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, which);
} catch (Exception e) {
e.printStackTrace();
toast(e.getMessage());
}
}
})
.create()
.show();
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (resultCode == Activity.RESULT_OK) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();

if (requestCode == 0) {
// 从相册选择
ContentResolver resolver = getActivity().getContentResolver();
// 照片的原始资源地址
Uri originalUri = data.getData();
try {
Bitmap image = MediaStore.Images.Media.getBitmap(resolver,
originalUri);
if (image != null) {
image.compress(Bitmap.CompressFormat.JPEG, 30, baos);
InputStream is = new ByteArrayInputStream(baos.toByteArray());
doUploadImage(is);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} else if (requestCode == 1) {
// 拍照后
Bundle extras = data.getExtras();
if (extras != null) {
// 这里是有些拍照后的图片是直接存放到Bundle中的所以我们可以从这里面获取Bitmap图片
Bitmap image = extras.getParcelable("data");
if (image != null) {
image.compress(Bitmap.CompressFormat.JPEG, 30, baos);
InputStream is = new ByteArrayInputStream(baos.toByteArray());
doUploadImage(is);
}
}
}
}
}

/**
* 实际执行图片上传的动作
* @param inputStream 选中图片的流
*/
public abstract void doUploadImage(InputStream inputStream);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.mazhuang.guanggoo.data.entity;

import lombok.Data;

/**
* @author mazhuang
* @date 2019-05-12
*/
@Data
public class UploadImageResponse {
public static final String CODE_SUCCESS = "success";

private String code;
private String msg;
private Content data;

@Data
public static class Content {
private int width;
private int height;
private long size;
private String url;
private String delete;
}
}
116 changes: 116 additions & 0 deletions app/src/main/java/org/mazhuang/guanggoo/data/task/UploadImageTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package org.mazhuang.guanggoo.data.task;

import android.text.TextUtils;

import com.google.gson.Gson;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.mazhuang.guanggoo.data.OnResponseListener;
import org.mazhuang.guanggoo.data.entity.UploadImageResponse;
import org.mazhuang.guanggoo.util.ConstantUtil;

import java.io.IOException;
import java.io.InputStream;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;

/**
* @author mazhuang
* @date 2019-05-12
*/
public class UploadImageTask extends BaseTask<String> {

public static final String URL = "https://sm.ms/api/upload";
public static final String KEY = "smfile";

private InputStream mStream;

public UploadImageTask(InputStream stream, OnResponseListener<String> listener) {
super(listener);
mStream = stream;
}

@Override
public void run() {
String errorMsg;
try {
Connection.Response response = doPostFileRequest(URL, KEY, mStream);
if (response != null && response.statusCode() == ConstantUtil.HTTP_STATUS_200) {
Gson gson = new Gson();
UploadImageResponse entity = gson.fromJson(response.body(), UploadImageResponse.class);
if (UploadImageResponse.CODE_SUCCESS.equals(entity.getCode())) {
if (entity.getData() != null && !TextUtils.isEmpty(entity.getData().getUrl())) {
successOnUI(entity.getData().getUrl());
return;
}
errorMsg = "图片上传返回数据有误";
} else {
errorMsg = entity.getMsg();
}
} else {
errorMsg = "图片上传失败";
}
} catch (Exception e) {
e.printStackTrace();
errorMsg = e.getMessage();
}
failedOnUI(errorMsg);
}

public static Connection.Response doPostFileRequest(String url, String key, InputStream inputStream) throws IOException {
// Https请求
if (url.startsWith("https")) {
trustEveryone();
}
return Jsoup.connect(url)
.method(Connection.Method.POST)
.ignoreContentType(true)
.timeout(12000)
.data(key, "filename", inputStream)
.execute();
}


/**
* 解决Https请求,返回404错误
*/
public static void trustEveryone() {
try {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {

@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new X509TrustManager[]{new X509TrustManager() {

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}}, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.mazhuang.guanggoo.base.BasePresenter;
import org.mazhuang.guanggoo.base.BaseView;

import java.io.InputStream;

/**
*
* @author mazhuang
Expand All @@ -17,6 +19,13 @@ interface Presenter extends BasePresenter {
* @param content 内容
*/
void newTopic(String title, String content);


/**
* 上传图片
* @param inputStream 图片输入流
*/
void uploadImage(InputStream inputStream);
}

interface View extends BaseView<Presenter> {
Expand All @@ -30,5 +39,17 @@ interface View extends BaseView<Presenter> {
* @param msg 失败提示信息
*/
void onNewTopicFailed(String msg);

/**
* 上传图片成功
* @param url 图片地址
*/
void onUploadImageSucceed(String url);

/**
* 上传图片失败
* @param msg 失败提示信息
*/
void onUploadImageFailed(String msg);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,21 @@

import org.mazhuang.guanggoo.R;
import org.mazhuang.guanggoo.base.BaseFragment;
import org.mazhuang.guanggoo.base.BaseUploadImageFragment;

import java.io.InputStream;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
*
* @author mazhuang
* @date 2017/10/10
*/

public class NewTopicFragment extends BaseFragment<NewTopicContract.Presenter> implements NewTopicContract.View {
public class NewTopicFragment extends BaseUploadImageFragment<NewTopicContract.Presenter> implements NewTopicContract.View {

@BindView(R.id.title) EditText mTitleEditText;
@BindView(R.id.content) EditText mContentEditText;
Expand Down Expand Up @@ -131,4 +135,30 @@ public String getTitle() {
return getString(R.string.new_topic);
}
}

@OnClick(R.id.add_image)
public void onAddImage() {
chooseImage();
}

@Override
public void doUploadImage(InputStream inputStream) {
mPresenter.uploadImage(inputStream);
}

@Override
public void onUploadImageSucceed(String url) {
if (!TextUtils.isEmpty(url)) {
String text = TextUtils.isEmpty(mContentEditText.getText()) ?
String.format("![](%s)", url) :
String.format("%s\n![](%s)", mContentEditText.getText(), url);
mContentEditText.setText(text);
mContentEditText.setSelection(mContentEditText.getText().length());
}
}

@Override
public void onUploadImageFailed(String msg) {
toast(msg);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import org.mazhuang.guanggoo.data.NetworkTaskScheduler;
import org.mazhuang.guanggoo.data.OnResponseListener;
import org.mazhuang.guanggoo.data.task.NewTopicTask;
import org.mazhuang.guanggoo.data.task.UploadImageTask;

import java.io.InputStream;

/**
*
Expand Down Expand Up @@ -46,4 +49,23 @@ public void onFailed(String msg) {
}
}));
}

@Override
public void uploadImage(InputStream inputStream) {
mView.startLoading();

NetworkTaskScheduler.getInstance().execute(new UploadImageTask(inputStream, new OnResponseListener<String>() {
@Override
public void onSucceed(String url) {
mView.stopLoading();
mView.onUploadImageSucceed(url);
}

@Override
public void onFailed(String msg) {
mView.stopLoading();
mView.onUploadImageFailed(msg);
}
}));
}
}
Loading

0 comments on commit dda216d

Please sign in to comment.