团队SCRUM

1.整个项目预期的工作量:2020-04-10至本学期项目提交日期  需要完成的主要任务        目前已花费的时间:2020-04-10-2020-04-27  目前已花费的时间为17天       还剩余时间:10天以上

2.团队任务看板照片  

任务

未完成

已完成

负责人

服务器搭建,准备好开发相关的环境,如数据库等。

 √

 王兵兵

登录注册功能,实现用户注册信息入库,登录时遍历核实信息。

 √

 张宏伟

记录笔记功能,实现用户记录的笔记入库,包括是否公开,插入的图片信息。

 √

 朴远东

查看笔记功能,实现用户浏览自己的笔记,界面上要求实现笔记的删除,对笔记的修改。

 朴远东

分享大厅界面,实现条件搜索,显示笔记,查看笔记,收藏笔记功能,记得刷新按钮。

 王兵兵

收藏笔记功能,显示在分享大厅页面中收藏的笔记,实现对笔记的删除和查看操作。

 √

 王兵兵

“关于我们”写入简易介绍,留下团队邮箱;“意见反馈”添加留言板和提交按钮,信息提交可考虑数据库,或提交到团队邮箱中,核心目的是让开发人员可见。

“我的”界面排版,至少完成修改信息界面,实现对用户信息的修改;帮助界面写入APP的使用方法。

其他敲定界面补充。

团队任务:UI设计

选做:增加功能。

3.SCRUM会议照片

4.产品的状态

产品功能:最新做好的功能(登录注册验证,记录笔记,上传笔记和相关照片到云服务器,分享大厅,收藏和查看相关的笔记)

产品界面:

代码:

package com.example.toa;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.RadioGroup;
import android.widget.SimpleAdapter;
import android.widget.SimpleAdapter.ViewBinder;
import android.widget.Toast;

import org.jetbrains.annotations.NotNull;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;


public class MainActivity extends Activity implements
        MyDialog.OnButtonClickListener, OnItemClickListener{
    private MyDialog dialog;// 图片选择对话框
    public static final int NONE = 0;
    public static final int PHOTOHRAPH = 1;// 拍照
    public static final int PHOTOZOOM = 2; // 缩放
    public static final int PHOTORESOULT = 3;// 结果
    public static final String IMAGE_UNSPECIFIED = "image/*";
    public static final MediaType PNG = MediaType.parse("image/png");

    private GridView gridView; // 网格显示缩略图
    private final int IMAGE_OPEN = 4; // 打开图片标记
    private String pathImage; // 选择图片路径
    private Bitmap bmp; // 导入临时图片
    private ArrayList<HashMap<String, Bitmap>> imageItem;
    private SimpleAdapter simpleAdapter; // 适配器
    private EditText note; // 笔记文本
    private EditText title; // 标题文本
    private EditText kemu; //学科
    private Button handin; // 上传按钮
    private RadioGroup rg; // 单选按钮组
    private boolean judge; // 判定公开/私有

    @SuppressLint("SourceLockedOrientationActivity")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        /*
         * 防止键盘挡住输入框 不希望遮挡设置activity属性 android:windowSoftInputMode="adjustPan"
         * 希望动态调整高度 android:windowSoftInputMode="adjustResize"
         */
        getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        // 锁定屏幕
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(R.layout.activity_main);
        //点击事件
        init();
        //加载图片与回显
        initData();
    }

    private void init() {
        //声明
        note = (EditText)findViewById(R.id.note);
        gridView = (GridView) findViewById(R.id.gridView);
        handin = (Button)findViewById(R.id.handin);
        title = (EditText)findViewById(R.id.title);
        kemu = (EditText)findViewById(R.id.kemu);
        rg = (RadioGroup)findViewById(R.id.rg);
        note.setHorizontallyScrolling(true);
        gridView.setOnItemClickListener(this);
        dialog = new MyDialog(this);
        dialog.setOnButtonClickListener(this);
        // activity中调用其他activity中组件的方法
        LayoutInflater layout = this.getLayoutInflater();
        View view = layout.inflate(R.layout.layout_select_photo, null);

        //单选按钮(公开/私有)
        rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if(checkedId == R.id.ok){
                    judge = true;
                }else{
                    judge = false;
                }
            }
        });

        handin.setOnClickListener(new View.OnClickListener() {
            //是否公开
            private String see_str = "";
            //正文
            private String note_str = "";
            //标题
            private String title_str = "";
            //用户名(登录界面传参获取)
            private String user_str = "try";
            //学科
            private  String kemu_str = "";
            //年级(传参获取)
            private String year_str = "3";
            @Override
            public void onClick(View v) {
                if(judge){
                    see_str = "公开";
                }else{
                    see_str = "私有";
                }
                note_str = note.getText().toString();
                title_str = title.getText().toString();
                kemu_str = kemu.getText().toString();

                //本地Tomcat,注意不能写localhost,写本机的ip地址【连接服务器时记得改地址】
                String URL="http://192.168.101.18:8080/CloudNote/CloudServlet";
                //URL携带部分参数
                URL+="?title="+title_str+"&see="+see_str+"&user="+user_str+"&kemu="+kemu_str+"&year="+year_str;
                //OKHttp
                OkHttpClient client = new OkHttpClient();
                MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.ALTERNATIVE);
                //文本文件
                MediaType NoteType = MediaType.parse("text/html;charset=utf-8");
                //设置文件命名前缀部分
                String noteuser = user_str+"_note";
                File Notefile = doString(note_str,noteuser);
                builder.addFormDataPart("note",Notefile.getName(),RequestBody.create(NoteType,Notefile));

                //图片文件,设定最多上传3张,不包括+号图片。
                int pic_i=0;
                for(HashMap<String,Bitmap>pic:imageItem){
                    Set<String> set=pic.keySet();
                    for(String key:set){
                        if(pic_i==0){
                            //跳过默认的+号图片
                            pic_i++;
                            continue;
                        }
                        //取出bitmap,转换成file,上传
                        else if(pic_i==1){
                            Bitmap fbm1 = pic.get(key);
                            //设置文件命名前缀部分
                            String image1user = user_str+"_image1";
                            //调用方法生成图片文件
                            File dofile = doImage(fbm1,image1user);
                            builder.addFormDataPart("image1",dofile.getName(),RequestBody.create(PNG,dofile));
                            pic_i++;
                        }
                        else if(pic_i==2){
                            Bitmap fbm2 = pic.get(key);
                            //设置文件命名前缀部分
                            String image2user = user_str+"_image2";
                            //调用方法生成图片文件
                            File dofile = doImage(fbm2,image2user);
                            builder.addFormDataPart("image2",dofile.getName(),RequestBody.create(PNG,dofile));
                            pic_i++;
                        }
                        else if(pic_i==3){
                            Bitmap fbm3 = pic.get(key);
                            //设置文件命名前缀部分
                            String image3user = user_str+"_image3";
                            //调用方法生成图片文件
                            File dofile = doImage(fbm3,image3user);
                            builder.addFormDataPart("image3",dofile.getName(),RequestBody.create(PNG,dofile));
                            pic_i++;
                        }
                    }
                }
                RequestBody requestBody = builder.build();
                Request request = new Request.Builder().url(URL)
                        .post(requestBody)
                        .build();
                client.newCall(request).enqueue(new Callback() {
                    @Override
                    public void onFailure(@NotNull Call call, @NotNull IOException e) {
                        Log.i("TRYxxx","连接失败");
                        e.printStackTrace();
                    }

                    @Override
                    public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                        Log.i("TRYxxx","连接的消息"+response.message());
                        if(response.isSuccessful()){
                            Log.i("TRYxxx","连接成功");
                        }
                    }
                });
            }
        });
    }
    private void initData() {
        /*
         * 载入默认图片添加图片加号
         */
        bmp = BitmapFactory.decodeResource(getResources(),
                R.drawable.ic_addpic); // 加号
        imageItem = new ArrayList<HashMap<String, Bitmap>>();
        HashMap<String, Bitmap> map = new HashMap<String, Bitmap>();
        map.put("itemImage", bmp);
        imageItem.add(map);
        simpleAdapter = new SimpleAdapter(this, imageItem,
                R.layout.griditem_addpic, new String[] { "itemImage" },
                new int[] { R.id.imageView1 });
        simpleAdapter.setViewBinder(new ViewBinder() {
            @Override
            public boolean setViewValue(View view, Object data,
                                        String textRepresentation) {
                // TODO Auto-generated method stub
                if (view instanceof ImageView && data instanceof Bitmap) {
                    ImageView i = (ImageView) view;
                    i.setImageBitmap((Bitmap) data);
                    return true;
                }
                return false;
            }
        });
        gridView.setAdapter(simpleAdapter);
    }

    //Bitmap转file
    public static File doImage(Bitmap fbitmap, String user) {
        ByteArrayOutputStream fbaos = new ByteArrayOutputStream();
        fbitmap.compress(Bitmap.CompressFormat.JPEG,100,fbaos);
        int options = 100;
        //判断是否大于20kb,是则继续压缩
        while(fbaos.toByteArray().length/1024>20){
            fbaos.reset();
            options-=10;
            fbitmap.compress(Bitmap.CompressFormat.JPEG,options,fbaos);
            long length = fbaos.toByteArray().length;
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date(System.currentTimeMillis());
        String filename = user+"_"+format.format(date);
        String filepath = Environment.getExternalStorageDirectory().toString()+"/CloudNoteImage";
        File pathfile = new File(filepath);
        if(!pathfile.exists()){
            pathfile.mkdir();
        }
        File file = new File(filepath,filename+".png");
        //注意创建文件,否则会发生文件读取错误
        if(!file.exists()){
            try{
                file.createNewFile();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        try{
            FileOutputStream fos = new FileOutputStream(file);
            try{
                fos.write(fbaos.toByteArray());
                fos.flush();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return file;
    }

    //将正文信息写入txt文件
    public static File doString(String strwrite, String user){
        //取时间
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date(System.currentTimeMillis());
        //生成文件名
        String filename = user+"_"+format.format(date);
        String filepath = Environment.getExternalStorageDirectory().toString()+"/CloudNoteTXT";
        //创建文件
        File pathfile = new File(filepath);
        if(!pathfile.exists()){
            pathfile.mkdir();
        }
        File file = new File(filepath,filename+".txt");
        if(!file.exists()){
            try{
                file.createNewFile();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        try{
            FileOutputStream outputStream = new FileOutputStream(file);
            outputStream.write(strwrite.getBytes());
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }
    //调用相机
    @Override
    public void camera() {
        // TODO Auto-generated method stub
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(
                Environment.getExternalStorageDirectory(), "temp.jpg")));
        startActivityForResult(intent, PHOTOHRAPH);
    }

    //调用相册
    @Override
    public void gallery() {
        // TODO Auto-generated method stub
        Intent intent = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, IMAGE_OPEN);

    }

    @Override
    public void cancel() {
        // TODO Auto-generated method stub
        dialog.cancel();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == NONE)
            return;
        // 拍照
        if (requestCode == PHOTOHRAPH) {
            // 设置文件保存路径这里放在跟目录下
            File picture = new File(Environment.getExternalStorageDirectory()
                    + "/temp.jpg");
            startPhotoZoom(Uri.fromFile(picture));
        }

        if (data == null)
            return;

        // 处理结果
        if (requestCode == PHOTORESOULT) {
            Bundle extras = data.getExtras();
            if (extras != null) {
                Bitmap photo = extras.getParcelable("data");
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                photo.compress(Bitmap.CompressFormat.JPEG, 75, stream);// (0-100)压缩文件
                // 将图片放入gridview中
                HashMap<String, Bitmap> map = new HashMap<String, Bitmap>();
                map.put("itemImage", photo);
                imageItem.add(map);
                simpleAdapter = new SimpleAdapter(this, imageItem,
                        R.layout.griditem_addpic, new String[] { "itemImage" },
                        new int[] { R.id.imageView1 });
                simpleAdapter.setViewBinder(new ViewBinder() {
                    @Override
                    public boolean setViewValue(View view, Object data,
                                                String textRepresentation) {
                        // TODO Auto-generated method stub
                        if (view instanceof ImageView && data instanceof Bitmap) {
                            ImageView i = (ImageView) view;
                            i.setImageBitmap((Bitmap) data);
                            return true;
                        }
                        return false;
                    }
                });
                gridView.setAdapter(simpleAdapter);
                simpleAdapter.notifyDataSetChanged();
                dialog.dismiss();
            }

        }
        // 打开图片
        if (resultCode == RESULT_OK && requestCode == IMAGE_OPEN) {
            startPhotoZoom(data.getData());
        }
        super.onActivityResult(requestCode, resultCode, data);

    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        //判定有图片添加
        if (!TextUtils.isEmpty(pathImage)) {
            //bitmap回显
            Bitmap addbmp = BitmapFactory.decodeFile(pathImage);
            //将信息存入Map中
            HashMap<String, Bitmap> map = new HashMap<String, Bitmap>();
            map.put("itemImage", addbmp);
            imageItem.add(map);
            //在griditem_addpic.xml中向imageView1添加图片
            simpleAdapter = new SimpleAdapter(this, imageItem,
                    R.layout.griditem_addpic, new String[] { "itemImage" },
                    new int[] { R.id.imageView1 });
            simpleAdapter.setViewBinder(new ViewBinder() {
                @Override
                public boolean setViewValue(View view, Object data,
                                            String textRepresentation) {
                    // TODO Auto-generated method stub
                    if (view instanceof ImageView && data instanceof Bitmap) {
                        ImageView i = (ImageView) view;
                        i.setImageBitmap((Bitmap) data);
                        return true;
                    }
                    return false;
                }
            });
            gridView.setAdapter(simpleAdapter);
            simpleAdapter.notifyDataSetChanged();
            // 刷新后释放防止手机休眠后自动添加
            pathImage = null;
            dialog.dismiss();
        }

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
        // TODO Auto-generated method stub
        if (imageItem.size() == 4&&position==0) { // 第一张为默认图片,点击+号时才判定是否已满
            Toast.makeText(MainActivity.this, "图片数3张已满",
                    Toast.LENGTH_SHORT).show();
        } else if (position == 0) { // 点击图片位置为+ 0对应0张图片
            // 选择图片
            dialog.show();

            // 通过onResume()刷新数据
        } else {
            dialog(position);
        }

    }

    /*
     * Dialog对话框提示用户删除操作 position为删除图片位置
     */
    protected void dialog(final int position) {
        AlertDialog.Builder builder = new Builder(MainActivity.this);
        builder.setMessage("确认移除已添加图片吗?");
        builder.setTitle("提示");
        builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                imageItem.remove(position);
                simpleAdapter.notifyDataSetChanged();
            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.create().show();
    }

    public void startPhotoZoom(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, IMAGE_UNSPECIFIED);
        intent.putExtra("crop", "true");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // outputX outputY 是裁剪图片宽高
        intent.putExtra("outputX", 64);
        intent.putExtra("outputY", 64);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, PHOTORESOULT);
    }

}
View Code

测设用例:

不同设备测试和数据库存储路径和照片查看

原文地址:https://www.cnblogs.com/pyd2020/p/12791957.html