徐利峰:
实现图书课后题章节答案上传以及图书浏览
上传书籍课后题章节答案
通过图书名,作者名和出版社来区分图书,其中上传的图书分类:图书图片,第一章,第二章,第三章。。。。
package com.lh.std_everything.ui.home.hometype.studyshare.share; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.Spinner; import android.widget.Toast; import com.giftedcat.easylib.selector.MultiImageSelector; import com.lh.std_everything.HttpUtil.HttpUtil; import com.lh.std_everything.MainActivity; import com.lh.std_everything.R; import com.lh.std_everything.ui.home.hometype.dongtai.DongTaiActivity; import com.lh.std_everything.ui.home.hometype.dongtai.NineGridAdapter; import com.lh.std_everything.ui.home.hometype.dongtai.OnAddPicturesListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.Unbinder; public class bookuploadActivity extends AppCompatActivity implements View.OnClickListener{ public EditText ed_title,ed_author,ed_publish; public Spinner spinner; public List<String> list=new ArrayList<>(); public ArrayAdapter<String> sadapter; String selectString; public ImageView submit; public String title; public String author; public String publish; /*图片选取相关参数*/ private static final int REQUEST_IMAGE = 2; private int maxNum = 9; Unbinder unbinder; ProgressBar progressBar; public RecyclerView rvImages; private Handler handle; NineGridAdapter adapter; private int uploadnum=0; private int size; private String urlimg; private List<String> select; List<String> mSelect; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bookupload); init(); /*下拉框选择*/ list.add("图书照片"); list.add("第一章"); list.add("第二章"); list.add("第三章"); list.add("第四章"); list.add("第五章"); list.add("第六章"); list.add("第七章"); list.add("第八章"); list.add("第九章"); list.add("第十章"); list.add("其他"); sadapter=new ArrayAdapter<>(this,android.R.layout.simple_spinner_item,list); sadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(sadapter); spinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){ @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { selectString=sadapter.getItem(position); view.setVisibility(View.VISIBLE); //Toast.makeText(bookuploadActivity.this,selectString,Toast.LENGTH_LONG).show(); } @Override public void onNothingSelected(AdapterView<?> parent) { selectString="NONE"; parent.setVisibility(View.VISIBLE); } }); /*上传*/ submit.setOnClickListener(this); } public void init() { ed_title=findViewById(R.id.ed_booktitle); ed_author=findViewById(R.id.ed_bookauthor); ed_publish=findViewById(R.id.ed_bookpublish); spinner=findViewById(R.id.spinner1); rvImages=findViewById(R.id.rv_imgs); unbinder = ButterKnife.bind(this); submit=findViewById(R.id.submit); progressBar=findViewById(R.id.progressBar); mSelect = new ArrayList<>(); rvImages.setLayoutManager(new GridLayoutManager(this, 3)); adapter = new NineGridAdapter(bookuploadActivity.this, mSelect, rvImages); adapter.setMaxSize(maxNum); rvImages.setAdapter(adapter); adapter.setOnAddPicturesListener(new OnAddPicturesListener() { @Override public void onAdd() { pickImage(); } }); } /*上传图书信息*/ @Override public void onClick(View v) { switch (v.getId()) { case R.id.submit: title=ed_title.getText().toString(); author=ed_author.getText().toString(); publish=ed_publish.getText().toString(); if(title.equals("") || author.equals("") || publish.equals("")|| selectString.equals("")) { Toast.makeText(bookuploadActivity.this,"请填写完整图书信息!",Toast.LENGTH_LONG).show(); return; } String username= MainActivity.getUsername(); handle = new Handler(new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message msg) { switch (msg.what) { case 100: if (uploadnum < size) { writeBookImg(select.get(uploadnum)); } else { Toast.makeText(bookuploadActivity.this, "上传成功", Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.GONE); } break; case 404: Toast.makeText(bookuploadActivity.this, "上传失败,您可以点击上传按钮重新上传", Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.GONE); break; default: break; } return true; } }); /*将动态写到服务器*/ new Thread(new Runnable() { @Override public void run() { String req=""; Log.i("输入的文本:", ""+title+" "+author+" "+" "+publish+" "+selectString); String url2 ="http://116.62.178.231:8080/BaiXiaoSheng/findbook?username="+ MainActivity.getUsername()+"&title="+title+"&author="+author+"&publish="+publish; String ms=String.valueOf(HttpUtil.sendPost(url2,req)); if(ms.equals("no")) { String url ="http://116.62.178.231:8080/BaiXiaoSheng/addbook?username="+ MainActivity.getUsername()+"&title="+title+"&author="+author+"&publish="+publish; Log.i("url:", ""+url); String msg=String.valueOf(HttpUtil.sendPost(url,req)); Log.d("文字上传:",msg); } } }).start(); new Thread(new Runnable() { @Override public void run() { bookuploadActivity.this.runOnUiThread(new Runnable() { @Override public void run() { progressBar.setVisibility(View.VISIBLE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { progressBar.setTooltipText("正在上传..."); } } }); /*将图片一张一张上传到服务器*/ urlimg = "http://116.62.178.231:8080/BaiXiaoSheng/downloadbook?title="+title+"&select="+selectString+"&bookauthor="+author+"&username="+MainActivity.getUsername(); handle.sendEmptyMessage(100); } }).start(); } } /*上传图片*/ private void writeBookImg(final String img) { new Thread(new Runnable() { @Override public void run() { Log.i("图片地址:", img); Map<String, File> fileMap = new HashMap<String, File>(); fileMap.put("file", new File(img)); String msg = null; try { msg = HttpUtil.sendPostImg(urlimg, fileMap); } catch (IOException e) { e.printStackTrace(); } uploadnum++; Log.i("当前已上传照片数:", ""+uploadnum); final String finalMsg = msg; bookuploadActivity.this.runOnUiThread(new Runnable() { @Override public void run() { Log.e("服务器返回信息:", ""+finalMsg); if (finalMsg.equals("yes")) { Log.d("tag", finalMsg); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { progressBar.setTooltipText("图片进度:" + uploadnum + "/" + size); } handle.sendEmptyMessage(100); } else { uploadnum = 0; handle.sendEmptyMessage(404); } } }); } }).start(); } /** * 选择添加图片 */ private void pickImage() { MultiImageSelector selector = MultiImageSelector.create(this); selector.showCamera(true); selector.count(maxNum); selector.multi(); selector.origin(mSelect); selector.start(this, REQUEST_IMAGE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_IMAGE) { if (resultCode == RESULT_OK) { select = data.getStringArrayListExtra(MultiImageSelector.EXTRA_RESULT); size=select.size()-1; Log.i("照片总数:", ""+size); mSelect.clear(); mSelect.addAll(select); adapter.notifyDataSetChanged(); } } } @Override protected void onDestroy() { super.onDestroy(); unbinder.unbind(); } }
服务器端图书章节的存储形式:
点开后是存储的信息:图书照片,第一章,第二章。。。。
查看所有图书
BookListActivity
package com.lh.std_everything.ui.home.hometype.studyshare.share; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.Toast; import com.lh.std_everything.HttpUtil.HttpUtil; import com.lh.std_everything.R; import com.lh.std_everything.ui.home.hometype.news.adapter.NewsAdapter; import org.json.JSONArray; import org.json.JSONException; public class BookListActivity extends AppCompatActivity { public ImageView upload,search; public RecyclerView rc_book; public BooksAdapter adapter; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_book_list); init(); upload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(BookListActivity.this,bookuploadActivity.class); startActivity(intent); } }); rc_book.setLayoutManager(new LinearLayoutManager(BookListActivity.this)); adapter = new BooksAdapter(); getThreadData(); handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message msg) { //线程回调更新数据 if (msg.what == 200) { adapter.setJsonArray((JSONArray) msg.obj); rc_book.setAdapter(adapter); } return true; } }); } public void init() { upload=findViewById(R.id.uploadimg); search=findViewById(R.id.searchimg); rc_book=findViewById(R.id.bookrv); } private void getThreadData() { //线程封装网络请求 new Thread(new Runnable() { @Override public void run() { String reqdata = ""; String address="http://116.62.178.231:8080/BaiXiaoSheng/getallbooks"; try { final JSONArray json = new JSONArray(String.valueOf(HttpUtil.sendPost(address, reqdata))); Log.d("tag", json.toString()); Message msg = new Message(); msg.what = 200; msg.obj = json; handler.sendMessage(msg); } catch (JSONException e) { e.printStackTrace(); } } }).start(); } }
BooksAdapter
package com.lh.std_everything.ui.home.hometype.studyshare.share; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; import com.lh.std_everything.R; import com.lh.std_everything.ui.home.hometype.news.adapter.NewsAdapter; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class BooksAdapter extends RecyclerView.Adapter<BooksAdapter.MyViewHolder>{ JSONArray jsonArray=new JSONArray(); private View itemview; public String arr[]={"begin","one","two","three","four","five","six","seven","eight","nine","ten","others"}; public void setJsonArray(JSONArray jsonArray) { this.jsonArray = jsonArray; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext()); itemview=layoutInflater.inflate(R.layout.cell_book,parent,false); return new BooksAdapter.MyViewHolder(itemview); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { JSONObject bean=null; try { bean= jsonArray.getJSONObject(position); holder.textViewName.setText(bean.getString("bookname")); holder.textViewAuthor.setText(bean.getString("bookauthor")); holder.textViewPublish.setText(bean.getString("bookpublish")); String []urls=bean.getString("head").split("\$"); RequestOptions options = new RequestOptions() .error(R.drawable.error) .placeholder(R.drawable.loading); if(urls.length!=0) { for(int i=0;i<urls.length;i++) { if(!urls[i].equals("null")) { Log.i("url",urls[i]); Glide.with(itemview) .load(urls[i]) .apply(options) .into(holder.bookphoto); break; } } } } catch (JSONException e) { e.printStackTrace(); } holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Bundle bundle=new Bundle(); Intent intent=new Intent(itemview.getContext(), ShowBookActivity.class); try { bundle.putString("bookname", jsonArray.getJSONObject(position).getString("bookname")); bundle.putString("bookauthor", jsonArray.getJSONObject(position).getString("bookauthor")); bundle.putString("bookpublish", jsonArray.getJSONObject(position).getString("bookpublish")); bundle.putString("username", jsonArray.getJSONObject(position).getString("username")); bundle.putString("head", jsonArray.getJSONObject(position).getString("head")); Log.i("bundle中的username:", ""+jsonArray.getJSONObject(position).getString("username")); for(int i=1;i<=11;i++) { if(jsonArray.getJSONObject(position).has(arr[i])) { bundle.putString(arr[i], jsonArray.getJSONObject(position).getString(arr[i])); } } } catch (JSONException e) { e.printStackTrace(); } intent.putExtras(bundle); itemview.getContext().startActivity(intent); } }); } @Override public int getItemCount() { return jsonArray.length(); } static class MyViewHolder extends RecyclerView.ViewHolder{ ImageView bookphoto; TextView textViewName,textViewAuthor,textViewPublish; public MyViewHolder(@NonNull View itemView) { super(itemView); bookphoto=itemView.findViewById(R.id.bookimg); textViewName=itemView.findViewById(R.id.booktitle); textViewAuthor=itemView.findViewById(R.id.bookauthor); textViewPublish= itemView.findViewById(R.id.bookpublish); } } }
明天任务:
做点击图书后到:图书详细信息展示,包含章节展示。
点击对应的章节可查看相应的章节答案
李浩:
消息列表的实现:
效果图:
明日任务:将app打包验证手机端的适配情况。