一、項目團隊
團隊成員
姓名:湯文濤 學號:1600802129 班級:計算機164班 博客地址:https://www.cnblogs.com/taotao01/
姓名:楊聖豪 學號:1600802101 班級:計算機163班 博客地址:http://www.cnblogs.com/ysh1998/
姓名:黃東強 學號:1600802083 班級:計算機163班 博客地址:http://www.cnblogs.com/hdq163/
二、APK鏈接
https://dev.tencent.com/u/xiaogui01/p/Android-TYH/git/blob/master/app/app-release.apk
APP運行錄屏
https://www.bilibili.com/video/av40161307/
三、代碼鏈接
https://git.dev.tencent.com/xiaogui01/Android-TYH.git
四、團隊項目介紹
4.1項目總體效果截圖
4.2實現的功能及其效果描述:
我們實現的功能有登錄、注冊、密碼修改、查看修改個人信息、上傳商品、查看我的發布、查看所有商品、查看某個商品的詳細信息、給商家留言這幾個主要的功能。
進入APP首先是登錄界面,沒有用戶名會提示先注冊,注冊時會驗證用戶名是否已存在;登錄時會驗證用戶名是否存在以及對應的密碼是否正確。
登陸后進入首頁,下邊的導航欄都可以跳轉實現,上面的四個商品分類導航欄用於查詢該分類的商品。
個人中心頁面里面的查詢個人信息、修改密碼、我的發布、關於我們都已實現;修改密碼會判斷原始密碼的正確性以及把新密碼修改到數據庫中。
發布頁面可以點擊上方的ImageButton來讀取手機上的圖片,填寫好商品的信息點擊發布按鈕就會把信息插入到商品表中,然后在主頁和我的發布頁面(會判斷當前登錄的用戶)顯示。
在首頁點擊商品會直接跳轉到該商品的詳細信息頁面,下方有留言區,可以留言。
目前已經實現了預期的大部分功能,有些小問題還在完善中。
五、關鍵代碼
5.1 修改用戶信息
usersave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {//賬號userId,密碼passWord,姓名name,專業subject,電話phone,QQ號qq,地址address
post_name=username.getText().toString();
post_subject=usersubject.getText().toString();
post_phone=userphone.getText().toString();
post_qq=userqq.getText().toString();
post_address=useraddress.getText().toString();
ContentValues values=new ContentValues();
values.put("name",post_name);
values.put("subject",post_subject);
values.put("phone",post_phone);
values.put("qq",post_qq);
values.put("address",post_address);
saveValues(values);
Toast.makeText(getApplicationContext(), "修改成功", Toast.LENGTH_SHORT).show();
startActivity(intent);
}
});
5.2 驗證是否登錄
myshow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(a.equals("")||a==null){
Toast.makeText(getApplicationContext(), "請先登錄!", Toast.LENGTH_SHORT).show();
intent = new Intent(MyselfActivity.this,LoginMainActivity.class);
startActivity(intent);
}
intent = new Intent(MyselfActivity.this,MyselfActivity.class);
startActivity(intent);
}
});
5.3 登錄獲取用戶ID,設置為全局變量
protected static String post_userid;
5.4 上傳商品信息插入到數據庫
Button fabu=(Button)findViewById(R.id.fabu);
fabu.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onClick(View v) {
EditText title=(EditText)findViewById(R.id.m1_title);
Spinner style=(Spinner)findViewById(R.id.m1_style);
EditText price=(EditText)findViewById(R.id.m1_price);
EditText phone=(EditText)findViewById(R.id.m1_phone);
EditText nr=(EditText)findViewById(R.id.m1_nr);
Date curDate = new Date(System.currentTimeMillis());
String str = formatter.format(curDate);
SQLiteDatabase db=dbHelper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("Id",25);
values.put("title",title.getText().toString());
// values.put("style", style.getTooltipText().toString());
values.put("style", str);
values.put("time",str.toString());
values.put("price",price.getText().toString());
values.put("phone",phone.getText().toString());
values.put("nr",nr.getText().toString());
db.insert("Sc_message",null,values);
Intent intent=new Intent(MainActivity_m1.this,MainActivity.class);
startActivity(intent);
}
});
5.5 把上傳數據庫中的信息顯示在我的發布列表中
MyDatabaseHelper mydb = new MyDatabaseHelper(this,"1600802129.db",null,1);
final SQLiteDatabase ddb = mydb.getWritableDatabase();
ListView listView = (ListView)findViewById(R.id.show_fabu);
Map<String, Object> item;
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
Cursor cursor = db.query("Sc_message",null,null,null,null,null,null,null);
if (cursor.moveToFirst()){
while (!cursor.isAfterLast()){
item = new HashMap<String, Object>();
item.put("id",cursor.getInt(0));
item.put("title",cursor.getString(1));
item.put("nr",cursor.getBlob(6));
item.put("style",cursor.getBlob(2));
item.put("time",cursor.getString(3));
item.put("price",cursor.getString(4));
item.put("phone",cursor.getString(5));
cursor.moveToNext();
data.add(item);
}
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, R.layout.my_fabu, new String[] { "image", "title", "price", "pl", "ly" },
new int[] { R.id.show_image, R.id.show_title, R.id.show_price, R.id.show_pl, R.id.show_view });
listView.setAdapter(simpleAdapter);
5.6顯示商品列表
Dbtest dbtest = new Dbtest(this);
final SQLiteDatabase db = dbtest.getWritableDatabase();
ListView listView = (ListView)findViewById(R.id.listView);
Map<String, Object> item; // 列表項內容用Map存儲
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>(); // 列表
Cursor cursor = db.query(TABLENAME,null,null,null,null,null,null,null); // 數據庫查詢
if (cursor.moveToFirst()){
while (!cursor.isAfterLast()){
item = new HashMap<String, Object>(); // 為列表項賦值
item.put("id",cursor.getInt(0));
item.put("userid",cursor.getString(1));
item.put("image",cursor.getBlob(6));
item.put("title",cursor.getBlob(2));
item.put("kind",cursor.getString(3));
item.put("info",cursor.getString(4));
item.put("price",cursor.getString(6));
cursor.moveToNext();
data.add(item); // 加入到列表中
}
}
// 使用SimpleAdapter布局listview
SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, R.layout.listitem, new String[] { "image", "title", "kind", "info", "price" },
new int[] { R.id.item_image, R.id.title, R.id.kind, R.id.info, R.id.price });
listView.setAdapter(simpleAdapter);
5.7實現點擊相應列表項,跳到指定內容的頁面
// 為列表項設置監聽器
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
intent = new Intent(main_page.this, item_info.class);
intent.putExtra("id", data.get(position).get("id").toString()); // 獲取該列表項的key為id的鍵值,即商品的id,將其儲存在Bundle傳遞給打開的頁面
startActivity(intent);
}
});
Cursor cursor = db.query(TABLENAME,null,"id=?",new String[]{intent.getStringExtra("id")},null,null,null,null); // 根據接收到的id進行數據庫查詢
Log.i("商品的id是",intent.getStringExtra("id"));
if (cursor.moveToFirst()){
while (!cursor.isAfterLast()){
//imageView.setImageResource(R.drawable.buy_item1);
title.setText(cursor.getString(2));
price.setText(cursor.getString(5));
info.setText(cursor.getString(4));
cursor.moveToNext();
}
}
5.8實現圖片的上傳和即時顯示
imageButton=(ImageButton)findViewById(R.id.m1_image);
imageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(AddItem.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(AddItem.this, new
String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
} else {
//打開系統相冊
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 1);
}
}
});
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//獲取圖片路徑
if (requestCode == 1 && resultCode == Activity.RESULT_OK && data != null) {
Uri selectedImage = data.getData();
String[] filePathColumns = {MediaStore.Images.Media.DATA};
Cursor c = getContentResolver().query(selectedImage, filePathColumns, null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePathColumns[0]);
String imagePath = c.getString(columnIndex);
showImage(imagePath);
c.close();
}
}
//加載圖片
private void showImage(String imaePath) {
Bitmap bm = BitmapFactory.decodeFile(imaePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
image = baos.toByteArray();
imageButton.setImageBitmap(bm);
}
5.9實現讀取數據庫中的圖片並將其插入到列表中
byte[] imagedata;
Bitmap imagebm;
imagedata = cursor.getBlob(6);
imagebm = BitmapFactory.decodeByteArray(imagedata, 0, imagedata.length);
item.put("image",imagebm);
SimpleAdapter simpleAdapter = new SimpleAdapter(this, data, R.layout.listitem, new String[] { "image", "title", "kind", "info", "price" },
new int[] { R.id.item_image, R.id.title, R.id.kind, R.id.info, R.id.price });
simpleAdapter.setViewBinder(new SimpleAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Object data, String textRepresentation) {
if(view instanceof ImageView && data instanceof Bitmap){
ImageView iv = (ImageView)view;
iv.setImageBitmap( (Bitmap)data );
return true;
}else{
return false;
}
}
});
listView.setAdapter(simpleAdapter);
六、評選其他團隊APK
第一名:李凱、季軒石組
實現了一個添加計划並打卡的app,界面簡潔美觀,交互感很好。
優點:app實現了基本的添加計划修改計划並打卡等功能,並在日期輸入時調起了系統日歷,提高了交互性。
缺點:app並沒有用戶登錄功能,可能是考慮只在單機上使用;而且提醒功能沒有,點擊“打卡”選項會閃退。
如果是我來做:如果我來參與這個項目的話,我應該會考慮加入后台提醒的功能,比如添加了某個時刻后,在到時間時手機系統給出提醒
第二名:洪居興,鄧旺,李洪岩組
制作了一個旅游方面的APP,實現了登錄注冊、手機發驗證碼、查看地圖、查看部分自帶的景點信息描述,總體上效果不錯。
優點:實現了手機驗證碼這個功能,能調用第三方發送驗證保證了安全性;其次,實現了查詢地圖的功能,通過調用百度地圖來實時確定自己的位置,完成了旅游APP較大的功能,很不錯。
缺點:界面比較簡單,而且地圖定位時定位的不太准確,有一定誤差。查詢功能也沒有實現,只能查看APP上已有的風景區,技術尚且不能滿足客戶需求,但后期可以繼續來完善。
如果是我來做:如果是我來做的話,我會主要來做風景區查詢這一塊,通過跳轉其它瀏覽器來查詢地方返回一些數據,手機驗證碼的話我可能不會先去做。其實在這幾天時間他們能做出這些已經很不錯啦。
第三名:劉宇瑩、孟鑫菲組
制作了一個電子拍賣的APP,實現了服務器端和客戶端。
優點:項目實現了用戶的登錄、注冊、查看所有物品種類、查看用戶競拍的物品、查看用戶的拍賣物品,添加用戶拍賣物品等功能;實現的功能比較完善。在項目中設計了服務器端和安卓端。這個很好
缺點:部分功能沒有實現,而且登錄的時候時不時會閃退,用戶體驗感較差。
如果是我來做:如果我參與這個項目我會優先解決閃退問題。
第四名:段嗣躍,陳素偉組
制作了一個二手交易平台APP,實現了注冊登錄查詢功能
優點:一些功能實現的比較好,如注冊之后可以直接點擊登錄,保留了注冊時賬號密碼。發布界面實現了圖片上傳功能,並能顯示出來。界面總體上比較美觀。
缺點:APP功能不太完善,有的界面沒有實際功能,只是靜態頁面,APP有待完善,例如消息頁面能查看交易與互動信息。
如果是我來做:如果我來做我會主要實現上傳和查詢界面,增加用戶對商品評論功能。
第五名:沈順文組
制作了一個代碼方面的簡單APP--代碼殺,實現了基本的功能,內容比較多。
優點:界面還可以,功能板塊考慮的比較全面,比較符合實際情況,而且還是自己一個人獨自完成的,這點很棒。
缺點:部分功能沒有實現,查詢問題還是只能查詢APP自帶的一些內容,具有局限性。同樣,APP上也存在閃退問題沒解決。
如果是我來做:如果我參與這個項目的話,我會把中的放在查詢功能上。
七、團隊成員遇到的問題及解決的方法
成員1:湯文濤
問題一:如何把上傳數據庫中的信息依次顯示在查看發布列表里面
解決方法:通過網上查詢解決辦法,我先寫了一個商品信息模板,在發布列表對應的Java文件中來讀取數據庫中的信息,用一個新的列表存儲,在調用模板傳參到顯示頁面中。
問題二:在把發布商品信息傳到數據庫時,Spinner中的選項無法直接獲取插入到數據庫
解決方法:在對應的Java文件中開頭定義一個新的String對象,添加Spinner響應事件,在響應中用定義的String對象來接收選項值,再在插入數據時直接插入這個String對象。
問題三:如何上傳相片
解決方法:通過添加ImageButton響應按鈕,點擊獲取SD卡權限從手機自帶的圖庫中添加照片(但是只能添加一張),然后在點擊發布按鈕的響應中用BLOB類型插入到數據庫中。
成員2:楊聖豪
問題一:如何實現圖文列表顯示
解決方法:使用SimpleAdapter類,為listview設置一個模板布局xml文件,代表listview中每個列表項的布局樣式,使用Map儲存列表項中各個屬性,將多個Map儲存在List中,最后調用SimpleAdapter類構造函數構造其對象布局各個列表項
問題二:如何實現底部導航欄置底
解決方法:因為linerlayout布局是垂直依次排列的,導航欄作為最后一個組件默認是不會置底的,所以需要設置底部導航欄和導航欄上方的組件高度為0,通過設置兩個組件的權重來控制導航欄置底。
問題三:如何實現點擊相應列表項,跳到指定內容的頁面
解決方法:因為每個列表項都是Map類型的對象,獲取其鍵為"id"的值,通過Bundle傳值給跳轉到的頁面,在頁面中根據id進行數據庫查詢,查到該id對應的商品信息,顯示在頁面中
問題四:如何實現圖片的上傳和即時顯示
解決方法:調用系統相冊,獲取圖片的路徑,編碼成bitmap格式,在相應的imageview / imagebutton處調用setImageBitmap函數顯示圖片
問題五:如何讀取數據庫中的圖片並將其插入到列表中
解決方法:調用getBlob后,使用BitmapFactory.decodeByteArray進行解碼,因為使用了listview,不能直接setImageBitmap,方法是調用過SimpleAdapter構造函數布局好listview之后,再為SimpleAdapter對象設置setViewBinder,對於listview中需要設置圖片的view調用setImageBitmap函數。
成員3:黃東強
問題一:程序頁面Intent進行跳轉時會程序無法運行
解決方法:意外終止,多次調試,發現結果為,未在Mainfest.xml中配置Activity
問題二:用戶未登錄卻能訪問用戶信息頁面和修改密碼頁面
解決方法:先驗證全局變量用戶Id是否為空,若為空則彈出用戶未登錄,跳轉至登錄頁面
問題三:如何登錄后獲取用戶ID
解決方法:設置為全局變量,使各個Activity都能訪問到它。百度上的設置全局變量有2中方式,一種是新建Application類來存放userId,一種是新建java類來存放userId,按其方法,會導致userId為空時,程序意外終止無法進行。最后設置一個靜態全局變量static userid來存放數據,其他Activity可以正常訪問並修改。
八、項目成員分工及打分
姓名 | 分工 | 比例 | 分數 |
---|---|---|---|
湯文濤 | 上傳、我的發布、留言的頁面設計及功能實現 | 33% | 10 |
楊聖豪 | 商品信息、主頁、商品分類的頁面設計及功能實現,整合項目 | 34% | 10 |
黃東強 | 登錄、注冊、個人中心的頁面設計及功能實現 | 33% | 10 |