第二阶段团队SCRUM

第二阶段冲刺已经完成,学期也进入尾声,下面进行总结。

首先给出任务板。

任务

未完成

已完成

负责人

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

王兵兵

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

张宏伟

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

朴远东

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

朴远东+王兵兵

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

王兵兵

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

王兵兵

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

张宏伟

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

半√

王兵兵+张宏伟

其他敲定界面补充。

团队任务:UI设计

选做:增加功能。

本学期完成了大部分任务,但有些功能存在缺陷,还有部分功能未完成,需要在假期进行补充再去申请软件著作权。第二阶段工作上,王兵兵做得比较多,张宏伟补上了一些功能,朴远东则是在功能的基础上进行了完善和填充。藉此进行了第二阶段的团队绩效。

产品的革新功能如下:

增设了打开动画:

 

注册界面优化,含有验证码,验证码图片可以点击,点击即可更换验证码图片。

 

增设了底部导航栏:

 

个人笔记界面完成,并实现了长按删除功能,个人笔记预览和收藏笔记预览可以实现点击图片查看大图的dialog

 

 

分享大厅界面完善,含下拉刷新功能,实时更新公开笔记的信息:

 

我的界面可以更改用户头像,但只能在APP内生效。退出再进后重置

 

收藏笔记界面,与个人笔记界面类似:

 

意见反馈界面:

 

由于完成所用的代码过多。这里只贴出四个fragment代码,对应下面四个板块的功能:

Mine.java:我的界面

  1 package com.itheima.network.fragment;
  2 
  3 import android.app.AlertDialog;
  4 import android.content.Context;
  5 import android.content.DialogInterface;
  6 import android.content.Intent;
  7 import android.graphics.Bitmap;
  8 import android.graphics.BitmapFactory;
  9 import android.net.Uri;
 10 import android.os.Bundle;
 11 import android.util.Log;
 12 import android.view.LayoutInflater;
 13 import android.view.View;
 14 import android.view.ViewGroup;
 15 import android.widget.ImageView;
 16 import android.widget.LinearLayout;
 17 import android.widget.TextView;
 18 import android.widget.Toast;
 19 
 20 import androidx.annotation.NonNull;
 21 import androidx.annotation.Nullable;
 22 import androidx.fragment.app.Fragment;
 23 
 24 import com.itheima.network.R;
 25 import com.itheima.network.activity.About;
 26 import com.itheima.network.activity.Mycollection;
 27 import com.itheima.network.activity.SpinnerActivity;
 28 import com.itheima.network.func_reference.BitmapUtils;
 29 import com.itheima.network.store.FindUserId;
 30 import com.jph.takephoto.app.TakePhoto;
 31 import com.jph.takephoto.app.TakePhotoImpl;
 32 import com.jph.takephoto.compress.CompressConfig;
 33 import com.jph.takephoto.model.CropOptions;
 34 import com.jph.takephoto.model.InvokeParam;
 35 import com.jph.takephoto.model.TContextWrap;
 36 import com.jph.takephoto.model.TResult;
 37 import com.jph.takephoto.permission.InvokeListener;
 38 import com.jph.takephoto.permission.PermissionManager;
 39 import com.jph.takephoto.permission.TakePhotoInvocationHandler;
 40 import com.zhy.http.okhttp.OkHttpUtils;
 41 import com.zhy.http.okhttp.callback.BitmapCallback;
 42 
 43 import java.io.File;
 44 import java.io.FileInputStream;
 45 
 46 import butterknife.BindView;
 47 import butterknife.ButterKnife;
 48 import butterknife.OnClick;
 49 import okhttp3.Call;
 50 
 51 
 52 public class Mine extends Fragment implements TakePhoto.TakeResultListener, InvokeListener {
 53 
 54     @BindView(R.id.my_collect)
 55     LinearLayout myCollect;
 56     @BindView(R.id.my_suggestion)
 57     LinearLayout mySuggestion;
 58     @BindView(R.id.my_contact)
 59     LinearLayout myContact;
 60     @BindView(R.id.my_modify)
 61     LinearLayout myModify;
 62     @BindView(R.id.iv_me_icon)
 63     ImageView ivMeIcon;
 64     @BindView(R.id.tv_me_name)
 65     TextView tvMeName;
 66 
 67     private Context mContext;
 68     private FindUserId findUserId;
 69 
 70     TakePhoto takePhoto;
 71     InvokeParam invokeParam;
 72     String imagePath;
 73     File file;
 74     Uri uri;
 75     int size;
 76     CropOptions cropOptions;
 77     Bitmap bitmap;
 78     File test;
 79 
 80 
 81 
 82 
 83     @Nullable
 84     @Override
 85     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 86         View view = View.inflate(getActivity( ), R.layout.fragment_mine, null);
 87         getTakePhoto().onCreate(savedInstanceState);
 88         mContext = view.getContext( );
 89         ButterKnife.bind(this, view);
 90         init( );
 91         initEvents();
 92         return view;
 93     }
 94 
 95     public void initEvents(){
 96         //各控件初始化
 97         file = new File(mContext.getExternalCacheDir(), System.currentTimeMillis() + ".png");
 98         uri = Uri.fromFile(file);
 99         size = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
100         cropOptions = new CropOptions.Builder().setOutputX(size).setOutputX(size).setWithOwnCrop(false).create();
101 
102     }
103 
104     private void init() {
105         findUserId = new FindUserId(getActivity( ));
106         tvMeName.setText(findUserId.ReadUserName( ));
107         setIcon( );
108     }
109 
110     @OnClick({R.id.my_collect, R.id.my_suggestion, R.id.my_contact, R.id.my_modify})
111     public void onViewClicked(View view) {
112         switch (view.getId( )) {
113             case R.id.my_collect:
114                 Intent intent = new Intent(this.getActivity( ), Mycollection.class);
115                 startActivity(intent);
116                 Toast.makeText(mContext, "我的收藏", Toast.LENGTH_SHORT).show( );
117                 break;
118             case R.id.my_suggestion:
119                 Intent intent1 = new Intent(this.getActivity( ), SpinnerActivity.class);
120                 startActivity(intent1);
121                 Toast.makeText(mContext, "意见反馈", Toast.LENGTH_SHORT).show( );
122                 break;
123             case R.id.my_contact:
124                 Intent intent2 = new Intent(this.getActivity( ), About.class);
125                 startActivity(intent2);
126                 break;
127             case R.id.my_modify:
128                 Toast.makeText(mContext, "修改密码", Toast.LENGTH_SHORT).show( );
129                 break;
130             default:
131                 break;
132         }
133     }
134 
135     public void setIcon() {
136         boolean flag = findUserId.ReadIcon( );
137         Log.e("flag的值", "" + flag);
138         if (!flag) {
139             String path = "http://39.101.190.190:8080/filesource/default_user_icon.png";
140             OkHttpUtils
141                     .get( )
142                     .url(path)
143                     .build( )
144                     .execute(new BitmapCallback( ) {
145                         @Override
146                         public void onError(Call call, Exception e, int id) {
147                             Toast.makeText(mContext, "网络异常" + id, Toast.LENGTH_SHORT).show( );
148                         }
149 
150                         @Override
151                         public void onResponse(Bitmap response, int id) {
152                             Bitmap bitmap = response;
153                             BitmapUtils.saveBitmap(bitmap, mContext);
154                             findUserId.WriterIcon( );
155                             bitmap = BitmapUtils.zoom(response, 62, 62);
156                             bitmap = BitmapUtils.circleBitmap(bitmap);
157                             ivMeIcon.setImageBitmap(bitmap);
158                         }
159                     });
160         } else {
161             String TargetPath = mContext.getFilesDir( ) + "/image/icon.png";
162             try {
163                 FileInputStream fis = new FileInputStream(TargetPath);
164                 Bitmap bitmap = BitmapFactory.decodeStream(fis);
165                 bitmap = BitmapUtils.zoom(bitmap, 62, 62);
166                 bitmap = BitmapUtils.circleBitmap(bitmap);
167                 ivMeIcon.setImageBitmap(bitmap);
168                 fis.close( );
169             } catch (Exception e) {
170                 e.printStackTrace( );
171             }
172 
173         }
174     }
175 
176     @OnClick(R.id.iv_me_icon)
177     public void onViewClicked()
178     {
179         String[] items = new String[]{"图库","相机"};
180         //提供一个AlertDialog
181         new AlertDialog.Builder(mContext)
182                 .setTitle("选择来源")
183                 .setItems(items, new DialogInterface.OnClickListener()
184                 {
185                     @Override
186                     public void onClick(DialogInterface dialog, int which)
187                     {
188                         switch (which)
189                         {
190                             case 0 ://图库
191                                 takePhoto.onPickFromGalleryWithCrop(uri, cropOptions);
192                                 break;
193 
194                             case 1://相机
195                                 takePhoto.onPickFromCaptureWithCrop(uri, cropOptions);
196                                 break;
197                             default:
198                                 break;
199 
200                         }
201                     }
202                 })
203                 .setCancelable(false)
204                 .show();
205 
206     }
207 
208 
209     @Override
210     public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
211         getTakePhoto().onActivityResult(requestCode, resultCode, data);
212         super.onActivityResult(requestCode, resultCode, data);
213     }
214 
215     @Override
216     public void onSaveInstanceState(@NonNull Bundle outState) {
217         getTakePhoto().onSaveInstanceState(outState);
218         super.onSaveInstanceState(outState);
219     }
220 
221     @Override
222     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
223         super.onRequestPermissionsResult(requestCode, permissions, grantResults);
224         //以下代码为处理Android6.0、7.0动态权限所需
225         PermissionManager.TPermissionType type = PermissionManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
226         PermissionManager.handlePermissionsResult(getActivity(), type, invokeParam, this);
227     }
228 
229     @Override
230     public PermissionManager.TPermissionType invoke(InvokeParam invokeParam) {
231         PermissionManager.TPermissionType type = PermissionManager.checkPermission(TContextWrap.of(this), invokeParam.getMethod());
232         if (PermissionManager.TPermissionType.WAIT.equals(type)) {
233             this.invokeParam = invokeParam;
234         }
235         return type;
236     }
237 
238     public TakePhoto getTakePhoto() {
239         //获得TakePhoto实例
240         if (takePhoto == null) {
241             takePhoto = (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this, this));
242         }
243         //设置压缩规则,最大500kb
244         takePhoto.onEnableCompress(new CompressConfig.Builder().setMaxSize(500 * 1024).create(), true);
245         return takePhoto;
246     }
247 
248     @Override
249     public void takeSuccess(final TResult result) {
250         //成功取得照片
251         test = new File(result.getImage().getOriginalPath());
252         if(test.exists()){
253             bitmap = BitmapFactory.decodeFile(result.getImage().getOriginalPath());
254             bitmap=BitmapUtils.zoom(bitmap,62,62);
255             bitmap=BitmapUtils.circleBitmap(bitmap);
256             ivMeIcon.setImageBitmap(bitmap);
257         }
258     }
259 
260 
261     @Override
262     public void takeFail(TResult result, String msg) {
263         //取得失败
264         Toast.makeText(mContext,"设置失败",Toast.LENGTH_SHORT).show();
265     }
266 
267     @Override
268     public void takeCancel() {
269         //取消
270     }
271 }

Note_local.java:个人笔记

  1 package com.itheima.network.fragment;
  2 
  3 import android.app.AlertDialog;
  4 import android.content.Context;
  5 import android.content.DialogInterface;
  6 import android.content.Intent;
  7 import android.os.Bundle;
  8 import android.view.LayoutInflater;
  9 import android.view.View;
 10 import android.view.ViewGroup;
 11 import android.widget.AdapterView;
 12 import android.widget.ListView;
 13 import android.widget.Toast;
 14 
 15 import androidx.annotation.NonNull;
 16 import androidx.annotation.Nullable;
 17 import androidx.fragment.app.Fragment;
 18 
 19 import com.alibaba.fastjson.JSONArray;
 20 import com.alibaba.fastjson.JSONObject;
 21 import com.itheima.network.R;
 22 import com.itheima.network.activity.DetailNoteActivity;
 23 import com.itheima.network.adpter.Note_localAdapter;
 24 import com.itheima.network.enity.Note_pojo;
 25 import com.itheima.network.store.FindUserId;
 26 import com.zhy.http.okhttp.OkHttpUtils;
 27 import com.zhy.http.okhttp.callback.StringCallback;
 28 
 29 import java.util.ArrayList;
 30 import java.util.List;
 31 
 32 import butterknife.BindView;
 33 import butterknife.ButterKnife;
 34 import okhttp3.Call;
 35 
 36 
 37 public class Note_local extends Fragment {
 38 
 39     @BindView(R.id.mynote_list_view)
 40     ListView mynoteListView;
 41 
 42     private Context mContext;
 43     private AlertDialog.Builder mDialogBuilder;
 44     private List<Note_pojo> notePojoList = new ArrayList<>( );
 45     private  static  final String url = "http://39.101.190.190:8080/CloudNoteServlet/NoteServlet";
 46     private int userid;
 47     private Note_localAdapter note_localAdapter;
 48 
 49 
 50     @Nullable
 51     @Override
 52     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
 53     {
 54         View view = View.inflate(getActivity( ), R.layout.fragment_note_local, null);
 55         mContext = view.getContext( );
 56         ButterKnife.bind(this, view);
 57         mDialogBuilder = new AlertDialog.Builder(mContext);
 58         FindUserId findUserId=new FindUserId(mContext);
 59         userid=findUserId.ReadUserId();
 60         initData(0);
 61         return view;
 62     }
 63 
 64 
 65     public void initData(int a)
 66     {
 67         if(a!=0)
 68         {
 69             notePojoList.subList(0,notePojoList.size()).clear();
 70         }
 71 
 72         OkHttpUtils
 73                 .get()
 74                 .url(url)
 75                 .addParams("method", "getMyNote")
 76                 .addParams("user_id", "" + userid)
 77                 .build( )
 78                 .execute(new StringCallback( ) {
 79                     @Override
 80                     public void onError(Call call, Exception e, int id)
 81                     {
 82                         Toast.makeText(mContext, "获取数据失败,请检查网络", Toast.LENGTH_SHORT).show( );
 83                     }
 84 
 85                     @Override
 86                     public void onResponse(String response, int id)
 87                     {
 88                         JSONArray array = JSONArray.parseArray(response);
 89                         for (int i = 0; i < array.size( ); i++)
 90                         {
 91                             JSONObject json = array.getJSONObject(i);
 92                             Note_pojo notePojo = new Note_pojo();
 93                             notePojo.setNote_id(json.getInteger("note_id"));
 94                             notePojo.setTitle(json.getString("title"));
 95                             notePojo.setCourse(json.getString("course"));
 96                             notePojo.setDate(json.getString("date"));
 97                             notePojoList.add(notePojo);
 98                         }
 99                         if(a==0)
100                         {
101                             initListView();
102                         }
103                         else
104                             {
105                             note_localAdapter.refresh();
106                             Toast.makeText(mContext,"删除数据成功",Toast.LENGTH_SHORT).show();
107                         }
108 
109                     }
110 
111                 });
112     }
113 
114     private void initListView() {
115         note_localAdapter = new Note_localAdapter(mContext,R.layout.mynote_list_item, notePojoList);
116         mynoteListView.setAdapter( note_localAdapter);
117         mynoteListView.setOnItemClickListener(new AdapterView.OnItemClickListener( )
118         {
119             @Override
120             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
121                 Note_pojo notePojo = notePojoList.get(position);
122                 Toast.makeText(mContext, "你好" + notePojo.getNote_id(), Toast.LENGTH_SHORT).show( );
123                 Intent intent=new Intent(view.getContext(), DetailNoteActivity.class);
124                 intent.putExtra("note_id",notePojo.getNote_id());
125                 intent.putExtra("view","none");
126                 startActivity(intent);
127             }
128         });
129 
130 
131         mynoteListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener( )
132         {
133             @Override
134             public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
135             {
136                 mDialogBuilder.setTitle("提示");
137                 mDialogBuilder.setMessage("您是否要删除该条记录?");
138                 mDialogBuilder.setPositiveButton("是", new DialogInterface.OnClickListener( )
139                 {
140                     @Override
141                     public void onClick(DialogInterface dialog, int which)
142                     {
143                         Note_pojo notePojo = notePojoList.get(position);
144                         delete(notePojo.getNote_id());
145                         Toast.makeText(mContext, "删除成功" + notePojo.getNote_id(), Toast.LENGTH_SHORT).show( );
146                     }
147                 });
148 
149                 mDialogBuilder.setNegativeButton("否", new DialogInterface.OnClickListener( )
150                 {
151                     @Override
152                     public void onClick(DialogInterface dialog, int which)
153                     {
154                         dialog.dismiss( );
155                     }
156                 });
157                 mDialogBuilder.show( );
158                 return true;
159             }
160         });
161     }
162 
163     private void delete(int note_id)
164     {
165         OkHttpUtils
166                 .post()
167                 .url(url)
168                 .addParams("method", "deleteMyNote")
169                 .addParams("user_id", ""+userid)
170                 .addParams("note_id", ""+note_id)
171                 .build()
172                 .execute(new StringCallback( ) {
173                     @Override
174                     public void onError(Call call, Exception e, int id)
175                     {
176                         Toast.makeText(mContext,"删除数据失败,请检查网络",Toast.LENGTH_SHORT).show();
177                     }
178 
179                     @Override
180                     public void onResponse(String response, int id)
181                     {
182                         if(response.equals("success"))
183                         {
184                             initData(1);
185                         }
186 
187                     }
188                 });
189 
190     }
191 
192     public interface  noterefresh
193     {
194         public void refresh();
195     }
196 
197 
198 }

Notespace.java:分享笔记界面

  1 package com.itheima.network.fragment;
  2 
  3 import android.annotation.SuppressLint;
  4 import android.content.Context;
  5 import android.os.Bundle;
  6 import android.view.LayoutInflater;
  7 import android.view.View;
  8 import android.view.ViewGroup;
  9 import android.widget.Toast;
 10 
 11 import androidx.annotation.NonNull;
 12 import androidx.annotation.Nullable;
 13 import androidx.fragment.app.Fragment;
 14 import androidx.recyclerview.widget.LinearLayoutManager;
 15 import androidx.recyclerview.widget.RecyclerView;
 16 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 17 
 18 import com.alibaba.fastjson.JSONArray;
 19 import com.alibaba.fastjson.JSONObject;
 20 import com.itheima.network.R;
 21 import com.itheima.network.adpter.PublicNoteAdapter;
 22 import com.itheima.network.enity.Note_pojo;
 23 import com.zhy.http.okhttp.OkHttpUtils;
 24 import com.zhy.http.okhttp.callback.StringCallback;
 25 
 26 import java.util.ArrayList;
 27 import java.util.List;
 28 
 29 import butterknife.BindView;
 30 import butterknife.ButterKnife;
 31 import okhttp3.Call;
 32 
 33 public class Notespace extends Fragment
 34 {
 35 
 36     @BindView(R.id.recyclerView)
 37     RecyclerView recyclerView;
 38     @BindView(R.id.swipe_refresh_layout)
 39     SwipeRefreshLayout swipeRefreshLayout;
 40 
 41     private Context mContext;
 42     private List<Note_pojo> notePojoList=new ArrayList<>();
 43     private PublicNoteAdapter publicNoteAdapter;
 44 
 45     @Nullable
 46     @Override
 47     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
 48     {
 49         View view = View.inflate(getActivity( ), R.layout.fragment_notespace, null);
 50         mContext=view.getContext();
 51         ButterKnife.bind(this,view);
 52         init(false);
 53         downFresh();
 54         return view;
 55     }
 56 
 57     private void init(boolean flag)
 58     {
 59         if(flag)
 60         {
 61             notePojoList.subList(0,notePojoList.size()).clear();
 62         }
 63         LinearLayoutManager linearLayoutManager=new LinearLayoutManager(mContext);
 64         recyclerView.setLayoutManager(linearLayoutManager);
 65         String url = "http://39.101.190.190:8080/CloudNoteServlet/NoteServlet";
 66         OkHttpUtils
 67                 .get( )
 68                 .url(url)
 69                 .addParams("method", "getpublicNotes")
 70                 .build( )
 71                 .execute(new StringCallback( )
 72                 {
 73                     @Override
 74                     public void onError(Call call, Exception e, int id)
 75                     {
 76                         Toast.makeText(mContext,"网络异常", Toast.LENGTH_SHORT).show( );
 77                     }
 78 
 79                     @Override
 80                     public void onResponse(String response, int id)
 81                     {
 82                         JSONArray array = JSONArray.parseArray(response);
 83                         for (int i = 0; i < array.size( ); i++)
 84                         {
 85                             JSONObject json = array.getJSONObject(i);
 86                             Note_pojo notePojo = new Note_pojo();
 87                             notePojo.setNote_id(json.getInteger("note_id"));
 88                             notePojo.setUser_icon(json.getString("user_icon"));
 89                             notePojo.setUser_name(json.getString("username"));
 90                             notePojo.setTitle(json.getString("title"));
 91                             notePojo.setCourse(json.getString("course"));
 92                             notePojo.setDate(json.getString("date"));
 93                             notePojoList.add(notePojo);
 94                         }
 95                         if(flag)
 96                         {
 97                             publicNoteAdapter.refreshList();
 98                             swipeRefreshLayout.setRefreshing(false);//当刷新结束时隐藏刷新条
 99                         }
100                         else
101                         {
102                             initView();
103                         }
104 
105                     }
106 
107                 });
108     }
109 
110     private void initView()
111     {
112         publicNoteAdapter=new PublicNoteAdapter(this.getActivity(),notePojoList);
113         recyclerView.setAdapter(publicNoteAdapter);
114     }
115 
116 
117     @SuppressLint("ResourceAsColor")
118     public void downFresh()
119     {
120         swipeRefreshLayout.setColorSchemeColors(R.color.define2);//设置刷新进度颜色
121         swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener( )
122         {
123             @Override
124             public void onRefresh()
125             {
126                 init(true);
127             }
128         });
129     }
130 
131     public interface  inform
132     {
133         public void refreshList();
134     }
135 }

Record.java:记录上传界面:

  1 package com.itheima.network.fragment;
  2 
  3 import android.annotation.SuppressLint;
  4 import android.app.AlertDialog;
  5 import android.app.AlertDialog.Builder;
  6 import android.content.Context;
  7 import android.content.DialogInterface;
  8 import android.content.Intent;
  9 import android.graphics.Bitmap;
 10 import android.graphics.BitmapFactory;
 11 import android.net.Uri;
 12 import android.os.Bundle;
 13 import android.text.TextUtils;
 14 import android.view.LayoutInflater;
 15 import android.view.View;
 16 import android.view.ViewGroup;
 17 import android.widget.AdapterView;
 18 import android.widget.Button;
 19 import android.widget.EditText;
 20 import android.widget.GridView;
 21 import android.widget.ImageView;
 22 import android.widget.RadioGroup;
 23 import android.widget.SimpleAdapter;
 24 import android.widget.SimpleAdapter.ViewBinder;
 25 import android.widget.Toast;
 26 
 27 import androidx.annotation.NonNull;
 28 import androidx.annotation.Nullable;
 29 import androidx.fragment.app.Fragment;
 30 
 31 import com.itheima.network.R;
 32 import com.itheima.network.func_reference.MyDialog;
 33 import com.itheima.network.store.FindUserId;
 34 import com.jph.takephoto.app.TakePhoto;
 35 import com.jph.takephoto.app.TakePhotoImpl;
 36 import com.jph.takephoto.compress.CompressConfig;
 37 import com.jph.takephoto.model.CropOptions;
 38 import com.jph.takephoto.model.InvokeParam;
 39 import com.jph.takephoto.model.TContextWrap;
 40 import com.jph.takephoto.model.TResult;
 41 import com.jph.takephoto.permission.InvokeListener;
 42 import com.jph.takephoto.permission.PermissionManager;
 43 import com.jph.takephoto.permission.TakePhotoInvocationHandler;
 44 import com.zhy.http.okhttp.OkHttpUtils;
 45 import com.zhy.http.okhttp.callback.StringCallback;
 46 
 47 import java.io.ByteArrayOutputStream;
 48 import java.io.File;
 49 import java.io.FileOutputStream;
 50 import java.io.IOException;
 51 import java.text.SimpleDateFormat;
 52 import java.util.ArrayList;
 53 import java.util.Date;
 54 import java.util.HashMap;
 55 import java.util.Map;
 56 import java.util.Set;
 57 
 58 import okhttp3.Call;
 59 
 60 public class Record extends Fragment implements MyDialog.OnButtonClickListener, AdapterView.OnItemClickListener,
 61         TakePhoto.TakeResultListener, InvokeListener
 62 {
 63     private MyDialog dialog;// 图片选择对话框
 64     public static final int NONE = 0;
 65     public static final int PHOTOHRAPH = 1;// 拍照
 66     public static final int PHOTOZOOM = 2; // 缩放
 67     public static final int PHOTORESOULT = 3;// 结果
 68     public static final String IMAGE_UNSPECIFIED = "image/*";
 69 
 70     private GridView gridView; // 网格显示缩略图
 71     private final int IMAGE_OPEN = 4; // 打开图片标记
 72     private String pathImage; // 选择图片路径
 73     private Bitmap bmp; // 导入临时图片
 74     private ArrayList<HashMap<String, Bitmap>> imageItem;
 75     private SimpleAdapter simpleAdapter; // 适配器
 76     private EditText note; // 笔记文本
 77     private EditText title; // 标题文本
 78     private EditText kemu; //学科
 79     private Button handin; // 上传按钮
 80     private RadioGroup rg; // 单选按钮组
 81     private boolean judge; // 判定公开/私有
 82     private String del1,del2,del3,del4;//删除文件用
 83     private View mview;
 84     private Context mContext;
 85 
 86     TakePhoto takePhoto;
 87     InvokeParam invokeParam;
 88     String imagePath;
 89     File file;
 90     Uri uri;
 91     int size;
 92     CropOptions cropOptions;
 93     Bitmap bitmap;
 94     File test;
 95 
 96 
 97     @SuppressLint("SourceLockedOrientationActivity")
 98     @Nullable
 99     @Override
100     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
101     {
102         View view=View.inflate(getActivity(), R.layout.fragment_record,null);
103         getTakePhoto().onCreate(savedInstanceState);
104         mview=view;
105         mContext=view.getContext();
106         //上传文件到服务器中
107         init();
108         //加载图片与回显
109         initData();
110         initEvents();
111         return view;
112     }
113 
114     public void initEvents()
115     {
116         //各控件初始化
117         file = new File(mContext.getExternalCacheDir(), System.currentTimeMillis() + ".png");
118         uri = Uri.fromFile(file);
119         size = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
120         cropOptions = new CropOptions.Builder().setOutputX(size).setOutputX(size).setWithOwnCrop(false).create();
121     }
122 
123     private void init()
124     {
125         //声明
126         note = mview.findViewById(R.id.Wnote);
127         gridView= mview.findViewById(R.id.gridView);
128         handin = mview.findViewById(R.id.handin);
129         title = mview.findViewById(R.id.title);
130         kemu = mview.findViewById(R.id.kemu);
131         rg = mview.findViewById(R.id.rg);
132         note.setHorizontallyScrolling(true);
133         gridView.setOnItemClickListener(this);
134         dialog = new MyDialog(this.getActivity());
135         dialog.setOnButtonClickListener(this);
136         // activity中调用其他activity中组件的方法
137         LayoutInflater layout = this.getLayoutInflater();
138         View view = layout.inflate(R.layout.layout_select_photo, null);
139 
140         //单选按钮(公开/私有)
141         rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
142         {
143             @Override
144             public void onCheckedChanged(RadioGroup group, int checkedId)
145             {
146                 if(checkedId == R.id.ok){
147                     judge = true;
148                 }else{
149                     judge = false;
150                 }
151             }
152         });
153 
154         handin.setOnClickListener(new View.OnClickListener()
155         {
156             //是否公开
157             private String see_str = "";
158             //正文
159             private String note_str = "";
160             //标题
161             private String title_str = "";
162             //学科
163             private  String kemu_str = "";
164             //年级(传参获取)
165             private String year_str = "3";
166             FindUserId findUserId=new FindUserId(getActivity());
167             String user_str=findUserId.ReadUserName();
168             int userID=findUserId.ReadUserId();
169             @Override
170             public void onClick(View v) {
171                 Map<String,File> fileMap=new HashMap<>();
172                 if(judge){
173                     see_str = "public";
174                 }else{
175                     see_str = "private";
176                 }
177                 note_str = note.getText().toString();
178                 title_str = title.getText().toString();
179                 kemu_str = kemu.getText().toString();
180 
181 
182                 //图片文件,设定最多上传3张,不包括+号图片。
183                 int pic_i=0;
184                 for(HashMap<String, Bitmap> pic:imageItem){
185                     Set<String> set=pic.keySet();
186                     for(String key:set){
187                         if(pic_i==0){
188                             //跳过默认的+号图片
189                             pic_i++;
190                             continue;
191                         }
192                         //取出bitmap,转换成file,上传
193                         else if(pic_i==1){
194                             Bitmap fbm1 = pic.get(key);
195                             //设置文件命名前缀部分
196                             String image1user = user_str+"_image1";
197                             //调用方法生成图片文件
198                             File mFile1 = doImage(fbm1,image1user);
199                             del2 = mContext.getExternalFilesDir(null).toString()+"/CloudNoteImage/"+mFile1.getName();
200                             fileMap.put("image1.png",mFile1);
201                             pic_i++;
202                         }
203                         else if(pic_i==2){
204                             Bitmap fbm2 = pic.get(key);
205                             //设置文件命名前缀部分
206                             String image2user = user_str+"_image2";
207                             //调用方法生成图片文件
208                             File mFile2 = doImage(fbm2,image2user);
209                             del3 = mContext.getExternalFilesDir(null).toString()+"/CloudNoteImage/"+mFile2.getName();
210                             fileMap.put("image2.png",mFile2);
211                             pic_i++;
212                         }
213                         else if(pic_i==3){
214                             Bitmap fbm3 = pic.get(key);
215                             //设置文件命名前缀部分
216                             String image3user = user_str+"_image3";
217                             //调用方法生成图片文件
218                             File mFile3= doImage(fbm3,image3user);
219                             del4 = mContext.getExternalFilesDir(null).toString()+"/CloudNoteImage/"+mFile3.getName();
220                             fileMap.put("image3.png",mFile3);
221                             pic_i++;
222                         }
223                     }
224                 }
225 
226                 String URL="http://39.101.190.190:8080/CloudNoteServlet/UserServlet"+"?method=uploading&title="+title_str+
227                         "&see="+see_str+"&kemu="+kemu_str+"&userID="+userID;
228                 String noteuser = user_str+"_note";
229                 File Notefile = doString(note_str,noteuser);
230                 del1 = mContext.getExternalFilesDir(null).toString()+"/CloudNoteTXT/"+Notefile.getName();
231                 fileMap.put("note.txt",Notefile);
232                 Map<String, String> params = new HashMap<>();
233                 params.put("username",user_str);
234                 OkHttpUtils.post()
235                         .files("files",fileMap)
236                         .url(URL)
237                         .params(params)
238                         .build()
239                         .connTimeOut(20000)
240                         .writeTimeOut(20000)
241                         .readTimeOut(20000)
242                         .execute(new StringCallback( ) {
243                             @Override
244                             public void onError(Call call, Exception e, int id)
245                             {
246                                 Toast.makeText(getActivity(),"上传文件出现异常,请重试"+id,Toast.LENGTH_SHORT).show();
247                             }
248 
249                             @Override
250                             public void onResponse(String response, int id)
251                             {
252                                 if(response.equals("fail"))
253                                 {
254                                     Toast.makeText(getActivity(),"上传文件失败"+id,Toast.LENGTH_SHORT).show();
255                                 }else{
256                                     Toast.makeText(getActivity(),"上传文件成功"+id,Toast.LENGTH_SHORT).show();
257                                     if(del1!=null){
258                                         deletefile(del1);
259                                     }
260                                     if(del2!=null){
261                                         deletefile(del2);
262                                     }
263                                     if(del3!=null){
264                                         deletefile(del3);
265                                     }
266                                     if(del4!=null){
267                                         deletefile(del4);
268                                     }
269                                 }
270                             }
271                         });
272             }
273         });
274     }
275     private void initData()
276     {
277         /*
278          * 载入默认图片添加图片加号
279          */
280         bmp = BitmapFactory.decodeResource(getResources(),
281                 R.drawable.ic_addpic); // 加号
282         imageItem = new ArrayList<HashMap<String, Bitmap>>();
283         HashMap<String, Bitmap> map = new HashMap<String, Bitmap>();
284         map.put("itemImage", bmp);
285         imageItem.add(map);
286         simpleAdapter = new SimpleAdapter(this.getActivity(), imageItem,
287                 R.layout.griditem_addpic, new String[] { "itemImage" },
288                 new int[] { R.id.imageView1 });
289         simpleAdapter.setViewBinder(new ViewBinder() {
290             @Override
291             public boolean setViewValue(View view, Object data,
292                                         String textRepresentation) {
293                 // TODO Auto-generated method stub
294                 if (view instanceof ImageView && data instanceof Bitmap) {
295                     ImageView i = (ImageView) view;
296                     i.setImageBitmap((Bitmap) data);
297                     return true;
298                 }
299                 return false;
300             }
301         });
302         gridView.setAdapter(simpleAdapter);
303     }
304 
305     //Bitmap转file
306     public  File doImage(Bitmap fbitmap, String user) {
307         ByteArrayOutputStream fbaos = new ByteArrayOutputStream();
308         fbitmap.compress(Bitmap.CompressFormat.JPEG,100,fbaos);
309         int options = 100;
310         //判断是否大于20kb,是则继续压缩
311         while(fbaos.toByteArray().length/1024>20 &&options>10){
312             fbaos.reset();
313             options-=10;
314             fbitmap.compress(Bitmap.CompressFormat.JPEG,options,fbaos);
315             long length = fbaos.toByteArray().length;
316         }
317         SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
318         Date date = new Date(System.currentTimeMillis());
319         String filename = user+"_"+format.format(date);
320         String filepath = mContext.getExternalFilesDir(null).toString()+"/CloudNoteImage";
321         File pathfile = new File(filepath);
322         if(!pathfile.exists()){
323             pathfile.mkdir();
324         }
325         File file = new File(filepath,filename+".png");
326         //注意创建文件,否则会发生文件读取错误
327         if(!file.exists()){
328             try{
329                 file.createNewFile();
330             }catch (IOException e){
331                 e.printStackTrace();
332             }
333         }
334         try{
335             FileOutputStream fos = new FileOutputStream(file);
336             try{
337                 fos.write(fbaos.toByteArray());
338                 fos.flush();
339                 fos.close();
340             } catch (IOException e) {
341                 e.printStackTrace();
342             }
343         }catch (IOException e){
344             e.printStackTrace();
345         }
346         return file;
347     }
348 
349     //将正文信息写入txt文件
350     public  File doString(String strwrite, String user){
351         //取时间
352         SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
353         Date date = new Date(System.currentTimeMillis());
354         //生成文件名
355         String filename = user+"_"+format.format(date);
356 
357         String filepath =mContext.getExternalFilesDir(null).toString()+"/CloudNoteTXT";
358         //创建文件
359         File pathfile = new File(filepath);
360         if(!pathfile.exists()){
361             pathfile.mkdir();
362         }
363         File file = new File(filepath,filename+".txt");
364         if(!file.exists()){
365             try{
366                 file.createNewFile();
367             }catch (IOException e){
368                 e.printStackTrace();
369             }
370         }
371         try{
372             FileOutputStream outputStream = new FileOutputStream(file);
373             outputStream.write(strwrite.getBytes());
374             outputStream.close();
375         } catch (IOException e) {
376             e.printStackTrace();
377         }
378         return file;
379     }
380     //删除文件
381     public void deletefile(String df){
382         File file = new File(df);
383         if(file.isFile()){
384             file.delete();
385         }
386     }
387     //调用相机
388     @Override
389     public void camera() {
390         takePhoto.onPickFromCaptureWithCrop(uri, cropOptions);
391     }
392 
393     //调用相册
394     @Override
395     public void gallery() {
396         takePhoto.onPickFromGalleryWithCrop(uri, cropOptions);
397     }
398 
399     @Override
400     public void cancel() {
401         // TODO Auto-generated method stub
402         dialog.cancel();
403     }
404 
405 
406 
407     @Override
408     public void onResume()
409     {
410         // TODO Auto-generated method stub
411         super.onResume();
412         //判定有图片添加
413         if (!TextUtils.isEmpty(pathImage))
414         {
415             //bitmap回显
416             Bitmap addbmp = BitmapFactory.decodeFile(pathImage);
417             //将信息存入Map中
418             HashMap<String, Bitmap> map = new HashMap<String, Bitmap>();
419             map.put("itemImage", addbmp);
420             imageItem.add(map);
421             //在griditem_addpic.xml中向imageView1添加图片
422             simpleAdapter = new SimpleAdapter(this.getActivity(), imageItem,
423                     R.layout.griditem_addpic, new String[] { "itemImage" },
424                     new int[] { R.id.imageView1 });
425             simpleAdapter.setViewBinder(new ViewBinder() {
426                 @Override
427                 public boolean setViewValue(View view, Object data,
428                                             String textRepresentation)
429                 {
430                     // TODO Auto-generated method stub
431                     if (view instanceof ImageView && data instanceof Bitmap)
432                     {
433                         ImageView i = (ImageView) view;
434                         i.setImageBitmap((Bitmap) data);
435                         return true;
436                     }
437                     return false;
438                 }
439             });
440             gridView.setAdapter(simpleAdapter);
441             simpleAdapter.notifyDataSetChanged();
442             // 刷新后释放防止手机休眠后自动添加
443             pathImage = null;
444             dialog.dismiss();
445         }
446 
447     }
448 
449     @Override
450     public void onItemClick(AdapterView<?> parent, View v, int position, long id)
451     {
452         // TODO Auto-generated method stub
453         if (imageItem.size() == 4&&position==0) { // 第一张为默认图片,点击+号时才判定是否已满
454             Toast.makeText(this.getActivity(), "图片数3张已满",
455                     Toast.LENGTH_SHORT).show();
456         } else if (position == 0) { // 点击图片位置为+ 0对应0张图片
457             // 选择图片
458             dialog.show();
459 
460             // 通过onResume()刷新数据
461         } else {
462             dialog(position);
463         }
464 
465     }
466 
467     /*
468      * Dialog对话框提示用户删除操作 position为删除图片位置
469      */
470     protected void dialog(final int position)
471     {
472         AlertDialog.Builder builder = new Builder(this.getActivity());
473         builder.setMessage("确认移除已添加图片吗?");
474         builder.setTitle("提示");
475         builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
476             @Override
477             public void onClick(DialogInterface dialog, int which) {
478                 dialog.dismiss();
479                 imageItem.remove(position);
480                 simpleAdapter.notifyDataSetChanged();
481             }
482         });
483         builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
484             @Override
485             public void onClick(DialogInterface dialog, int which) {
486                 dialog.dismiss();
487             }
488         });
489         builder.create().show();
490     }
491 
492 
493 
494 
495     @Override
496     public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
497         getTakePhoto().onActivityResult(requestCode, resultCode, data);
498         super.onActivityResult(requestCode, resultCode, data);
499     }
500 
501     @Override
502     public void onSaveInstanceState(@NonNull Bundle outState) {
503         getTakePhoto().onSaveInstanceState(outState);
504         super.onSaveInstanceState(outState);
505     }
506 
507     @Override
508     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
509         super.onRequestPermissionsResult(requestCode, permissions, grantResults);
510         //以下代码为处理Android6.0、7.0动态权限所需
511         PermissionManager.TPermissionType type = PermissionManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
512         PermissionManager.handlePermissionsResult(getActivity(), type, invokeParam, this);
513     }
514 
515     @Override
516     public PermissionManager.TPermissionType invoke(InvokeParam invokeParam) {
517         PermissionManager.TPermissionType type = PermissionManager.checkPermission(TContextWrap.of(this), invokeParam.getMethod());
518         if (PermissionManager.TPermissionType.WAIT.equals(type)) {
519             this.invokeParam = invokeParam;
520         }
521         return type;
522     }
523 
524     public TakePhoto getTakePhoto() {
525         //获得TakePhoto实例
526         if (takePhoto == null) {
527             takePhoto = (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this, this));
528         }
529         //设置压缩规则,最大500kb
530         takePhoto.onEnableCompress(new CompressConfig.Builder().setMaxSize(500 * 1024).create(), true);
531         return takePhoto;
532     }
533 
534     @Override
535     public void takeSuccess(final TResult result) {
536         //成功取得照片
537         test = new File(result.getImage().getOriginalPath());
538         if(test.exists()){
539             bitmap = BitmapFactory.decodeFile(result.getImage().getOriginalPath());
540             // 将图片放入gridview中
541             HashMap<String, Bitmap> map = new HashMap<String, Bitmap>();
542             map.put("itemImage", bitmap);
543             imageItem.add(map);
544             simpleAdapter = new SimpleAdapter(this.getActivity(), imageItem,
545                     R.layout.griditem_addpic, new String[] { "itemImage" },
546                     new int[] { R.id.imageView1 });
547             simpleAdapter.setViewBinder(new ViewBinder() {
548                 @Override
549                 public boolean setViewValue(View view, Object data,
550                                             String textRepresentation) {
551                     // TODO Auto-generated method stub
552                     if (view instanceof ImageView && data instanceof Bitmap) {
553                         ImageView i = (ImageView) view;
554                         i.setImageBitmap((Bitmap) data);
555                         return true;
556                     }
557                     return false;
558                 }
559             });
560             gridView.setAdapter(simpleAdapter);
561             simpleAdapter.notifyDataSetChanged();
562             dialog.dismiss();
563         }
564     }
565 
566 
567     @Override
568     public void takeFail(TResult result, String msg) {
569         //取得失败
570         Toast.makeText(mContext,"设置失败",Toast.LENGTH_SHORT).show();
571     }
572 
573     @Override
574     public void takeCancel() {
575         //取消
576     }
577 }

最后再附上团队会议截图,我们就着已完成任务表进行分析。

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