第二阶段冲刺已经完成,学期也进入尾声,下面进行总结。
首先给出任务板。
任务 |
未完成 |
已完成 |
负责人 |
服务器搭建,准备好开发相关的环境,如数据库等。 |
√ |
王兵兵 |
|
登录注册功能,实现用户注册信息入库,登录时遍历核实信息。 |
√ |
张宏伟 |
|
记录笔记功能,实现用户记录的笔记入库,包括是否公开,插入的图片信息。 |
√ |
朴远东 |
|
查看笔记功能,实现用户浏览自己的笔记,界面上要求实现笔记的删除,对笔记的修改。 |
√ |
朴远东+王兵兵 |
|
分享大厅界面,实现条件搜索,显示笔记,查看笔记,收藏笔记功能,记得刷新按钮。 |
√ |
王兵兵 |
|
收藏笔记功能,显示在分享大厅页面中收藏的笔记,实现对笔记的删除和查看操作。 |
√ |
王兵兵 |
|
“关于我们”写入简易介绍,留下团队邮箱;“意见反馈”添加留言板和提交按钮,信息提交可考虑数据库,或提交到团队邮箱中,核心目的是让开发人员可见。 |
√ |
张宏伟 |
|
“我的”界面排版,至少完成修改信息界面,实现对用户信息的修改;帮助界面写入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 }
最后再附上团队会议截图,我们就着已完成任务表进行分析。