突然接到实验室的活,自己也好久没有写Android了加上最近真的是太忙了,本想去网上随便找代码把这个活完成去做自己的事情来着,毕竟网上代码的年代都有些古老,Android的版本不一样,给的东西也不全,所以也是一拖再拖,最后还是自己静下心来慢慢看代码,慢慢解决问题解决的。
这是我的Android studio版本信息
下面是代码
一、 xml布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加图片:"
android:textSize="20dp"/>
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="300dp"
/>
<LinearLayout
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/take_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/paizhao" />
<Button
android:id="@+id/choose_image"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@mipmap/xiangce" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="生长性描述:"
android:textSize="20dp" />
<EditText
android:id="@+id/Picture_GrowExpre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入生长性描述"
android:inputType="textMultiLine"
android:minLines="5" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="病虫害描述:"
android:textSize="20dp" />
<EditText
android:id="@+id/Picture_DiseaseExpre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入病虫害描述"
android:inputType="textMultiLine"
android:minLines="5" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="异常性描述:"
android:textSize="20dp" />
<EditText
android:id="@+id/Picture_AbnormalExpre"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入异常性描述"
android:inputType="textMultiLine"
android:minLines="5" />
</LinearLayout>
<Button
android:id="@+id/submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="提交" />
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
二、 实现代码
package com.example.zhaopian;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import java.io.ByteArrayOutputStream;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import cz.msebera.android.httpclient.Header;
@SuppressLint("NewApi")
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private ProgressDialog prgDialog;
private int RESULT_LOAD_IMG = 1;
private RequestParams params = new RequestParams();
private String encodedString;
private Bitmap bitmap;
private String imgPath;
private Button submit;
private EditText Picture_GrowExpre;
private EditText Picture_DiseaseExpre;
private EditText Picture_AbnormalExpre;
//下面是拍照
private int SELECT_PIC_BY_TACK_PHOTO = 99;
private Uri photoUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prgDialog= new ProgressDialog(this);
prgDialog.setCancelable(false);
Picture_GrowExpre = findViewById(R.id.Picture_GrowExpre);
Picture_DiseaseExpre = findViewById(R.id.Picture_DiseaseExpre);
Picture_AbnormalExpre = findViewById(R.id.Picture_AbnormalExpre);
findViewById(R.id.submit).setOnClickListener(this);
findViewById(R.id.choose_image).setOnClickListener(this);
findViewById(R.id.take_photo).setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.choose_image://从相册选照片
loadImage();break;
case R.id.take_photo://拍照
takephoto();break;
case R.id.submit:
uploadImage();break;
}
}
public void takephoto() {
//执行拍照前,应该先判断SD卡是否存在
//TODO 设置读写权限
if (Build.VERSION.SDK_INT >= 23) {
int REQUEST_CODE_CONTACT = 101;
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
//验证是否许可权限
for (String str : permissions) {
if (this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) {
//申请权限
this.requestPermissions(permissions, REQUEST_CODE_CONTACT);
}
}
}
String SDState = Environment.getExternalStorageState();
if(SDState.equals(Environment.MEDIA_MOUNTED))
{
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((Activity) MainActivity.this, new String[]{Manifest.permission.CAMERA}, 1);
} else {
//权限已经被授予,在这里直接写要执行的相应方法即可
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//"android.media.action.IMAGE_CAPTURE"
/**
* 需要说明一下,以下操作使用照相机拍照,拍照后的图片会存放在相册中的
* 这里使用的这种方式有一个好处就是获取的图片是拍照后的原图
* 如果不实用ContentValues存放照片路径的话,拍照后获取的图片为缩略图不清晰
*/
ContentValues values = new ContentValues();
photoUri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, photoUri);
/**-----------------*/
startActivityForResult(intent,SELECT_PIC_BY_TACK_PHOTO);
}
}else{
Toast.makeText(this,"内存卡不存在", Toast.LENGTH_LONG).show();
}
}
public void loadImage() {
//TODO 设置读写权限
if (Build.VERSION.SDK_INT >= 23) {
int REQUEST_CODE_CONTACT = 101;
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
//验证是否许可权限
for (String str : permissions) {
if (this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) {
//申请权限
this.requestPermissions(permissions, REQUEST_CODE_CONTACT);
}
}
}
//这里就写了从相册中选择图片,相机拍照的就略过了
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
}
//当图片被选中的返回结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
//这是从相机选择
if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK && null != data ) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
// 获取游标
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
imgPath = cursor.getString(columnIndex);
//4.0以上的版本会自动关闭 (4.0--14;; 4.0.3--15)
if(Integer.parseInt(Build.VERSION.SDK) < 14)
{
//只有4.0以下才需要手动关闭
cursor.close();
}
ImageView imgView = (ImageView) findViewById(R.id.imageView);
imgView.setImageBitmap(BitmapFactory.decodeFile(imgPath));
}
//这是用相机拍照
if (requestCode == SELECT_PIC_BY_TACK_PHOTO && resultCode == RESULT_OK) {
String[] pojo = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(photoUri, pojo, null, null,null);
cursor.moveToFirst();
if(cursor != null )
{
int columnIndex = cursor.getColumnIndexOrThrow(pojo[0]);
String picPath="";
imgPath = cursor.getString(columnIndex);
//4.0以上的版本会自动关闭 (4.0--14;; 4.0.3--15)
if(Integer.parseInt(Build.VERSION.SDK) < 14)
{
//只有4.0以下才需要手动关闭
cursor.close();
}
ImageView imgView = (ImageView) findViewById(R.id.imageView);
imgView.setImageBitmap(BitmapFactory.decodeFile(imgPath));
} else{
Toast.makeText(this, "选择图片文件不正确", Toast.LENGTH_LONG).show();
}
}
} catch (Exception e) {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG).show();
}
}
//开始上传图片
private void uploadImage() {
if (imgPath != null && !imgPath.isEmpty()) {
prgDialog.setMessage("Converting Image to Binary Data");
prgDialog.show();
encodeImagetoString();
} else {
Toast.makeText(getApplicationContext(), "You must select image from gallery before you try to upload",
Toast.LENGTH_LONG).show();
}
}
public void encodeImagetoString() {
new AsyncTask<Void, Void, String>() {
protected void onPreExecute() {
};
@Override
protected String doInBackground(Void... params) {
BitmapFactory.Options options = null;
options = new BitmapFactory.Options();
options.inSampleSize = 3;
bitmap = BitmapFactory.decodeFile(imgPath,
options);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
// 压缩图片
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
while (stream.toByteArray().length / 1024 > 1024*2) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
stream.reset();// 重置stream即清空stream
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream);// 这里压缩options%,把压缩后的数据存放到baos中
}
byte[] byte_arr = stream.toByteArray();
// Base64图片转码为String
encodedString = Base64.encodeToString(byte_arr, 0);
return "";
}
@Override
protected void onPostExecute(String msg) {
prgDialog.setMessage("Calling Upload");
// 将转换后的图片添加到上传的参数中
params.put("image", encodedString);
params.put("imagePath", imgPath);
params.put("Picture_GrowExpre", Picture_GrowExpre.getText().toString());
params.put("Picture_DiseaseExpre", Picture_DiseaseExpre.getText().toString());
params.put("Picture_AbnormalExpre", Picture_AbnormalExpre.getText().toString());
// 上传图片
imageUpload();
}
}.execute(null, null, null);
}
public void imageUpload() {
prgDialog.setMessage("Invoking JSP");
String url = "http://39.99.159.184:8080/upload_war/cucumber_picture_uploadimg.jsp";
AsyncHttpClient client = new AsyncHttpClient();
client.post(url, params, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] bytes) {
prgDialog.hide();
Toast.makeText(getApplicationContext(), "upload success", Toast.LENGTH_LONG).show();
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] bytes, Throwable throwable) {
prgDialog.hide();
if (statusCode == 404) {
Toast.makeText(getApplicationContext(),
"Requested resource not found", Toast.LENGTH_LONG).show();
}
// 当 Http 响应码'500'
else if (statusCode == 500) {
Toast.makeText(getApplicationContext(),
"Something went wrong at server end", Toast.LENGTH_LONG).show();
}
// 当 Http 响应码 404, 500
else {
Toast.makeText(
getApplicationContext(), "Error Occured n Most Common Error: n1. Device " +
"not connected to Internetn2. Web App is not deployed in App servern3." +
" App server is not runningn HTTP Status code : "
+ statusCode, Toast.LENGTH_LONG).show();
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (prgDialog != null) {
prgDialog .dismiss();
}
}
}
三、用到依赖
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'cz.msebera.android:httpclient:4.3.6'
implementation 'com.loopj.android:android-async-http:1.4.9'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
四、Android端需要获取的权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:uses-permissionandroid="http://schemas.android.com/tools"
package="com.example.zhaopian">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<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/AppTheme"
android:requestLegacyExternalStorage="true">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
五、服务器代码
1.jsp代码
<%@page import="com.eric.UploadImage"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>图片上传</title>
</head>
<body>
<%
String imgEncodedStr = request.getParameter("image");
String imgPath = request.getParameter("imagePath");
String picture_GrowExpre = request.getParameter("Picture_GrowExpre");
String Picture_DiseaseExpre = request.getParameter("Picture_DiseaseExpre");
String picture_AbnormalExpre = request.getParameter("Picture_AbnormalExpre");
System.out.println("Filename: "+ imgPath);
if(imgEncodedStr != null){
UploadImage.convertStringtoImage(imgEncodedStr, imgPath,request,picture_GrowExpre,Picture_DiseaseExpre,picture_AbnormalExpre);
out.print("Image upload complete, Please check your directory");
} else{
out.print("Image is empty");
}
%>
</body>
</html>
2.java代码
package com.eric;
import com.utils.JdbcUtil;
import org.apache.commons.codec.binary.Base64;
import javax.servlet.http.HttpServletRequest;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.*;
public class UploadImage {
public static void convertStringtoImage(String encodedImageStr, String fileName,HttpServletRequest request,String picture_GrowExpre,String Picture_DiseaseExpre,String picture_AbnormalExpre){
try {
// Base64解码图片
byte[] imageByteArray = Base64.decodeBase64(encodedImageStr);
/**
* 获取当前相对路径,将图片存到服务器img文件夹下面
* */
String contextPath = request.getContextPath()+"/img";
System.out.println(contextPath+"----------");
//
String[] idArry = fileName.trim().split("\\ ");
String imagePath = "D:/uploads/" + idArry[idArry.length-1];
// FileOutputStream imageOutFile = new FileOutputStream(contextPath);
FileOutputStream imageOutFile = new FileOutputStream(imagePath);
imageOutFile.write(imageByteArray);
imageOutFile.close();
//将图片信息写入数据库
Connection connection = JdbcUtil.getConnection();
PreparedStatement preparedStatement = null;
String sql = "insert into cucumber_picture values(null,?,?,?,?)";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,"1");
preparedStatement.setString(2,picture_GrowExpre);
preparedStatement.setString(3,Picture_DiseaseExpre);
preparedStatement.setString(4,picture_AbnormalExpre);
int i = preparedStatement.executeUpdate();
JdbcUtil.close(connection);
connection.close();
if(i>0){
System.out.println("Image Successfully Stored");
}
} catch (FileNotFoundException fnfe) {
System.out.println("Image Path not found" + fnfe);
} catch (IOException ioe) {
System.out.println("Exception while converting the Image " + ioe);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
其中照片已经存到对应的路径里了,我是因为工作需要也放到了服务器里面。
自己遇到的一些问题
自己遇到了很多问题其中印象比较深的发了博客比如:
动态申请读写权限
动态申请打开摄像头等