项目简介
完整的二维码扫描功能
漂亮的界面
查询数据库功能
写入到本地文件在本地文件中手动创建txt文件
打卡功能实现
下面看代码
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.zxing://点击扫描二维码的button
scanner();
break;
default:
break;
}
}
/**
* 扫描
*/
private void scanner() {
Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
startActivityForResult(intent, SCAN_CODE);
}
/**
* 二维码获取到数据在此方法中返回
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case SCAN_CODE:
if (resultCode == RESULT_OK) {
zXingData = data.getStringExtra("scan_result");
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "没有扫描出结果",
Toast.LENGTH_SHORT).show();
}
meetContent();
break;
default:
break;
}
}
其中scanner()方法中CaptureActivity.class是集成到项目中的类,不用做处理,
对返回的数据进行解析, 我这里因为是定制化的二维码.所以有固定的解析格式,朋友们如果拿到返回的数据想怎么做都行.
/**
* 扫描数据返回
*/
private void meetContent() {
if (TextUtils.isEmpty(zXingData))
return;
System.out.println(zXingData);
String[] result = zXingData.split("::");
System.out.println(result.length + "");
if (9 != result.length) {
scanner();
return;
}
int i = result.length;
tvExternalTeach.setText(result[i - 1]);// 外单位老师
tvThisTeach.setText(result[i - 2]);// 本单位老师
tvUnit.setText(result[i - 3]);// 组织单位
tvTime.setText(result[i - 4]);// 培训课时
tvLocation.setText(result[i - 5]);// 培训地点
tvEndTime.setText(result[i - 6]);// 培训地点
tvStartTime.setText(result[i - 7]);// 开始时间
// public String substring(int beginIndex)
tvTitle.setText(result[i - 8].substring(10));// 培训标题
}
直接贴代码,朋友们可以把这个搞成一个工具类使用
我的数据库是放在项目中asset文件夹下的,第一步先把数据库拷贝到项目中,只有在安装app时拷贝一次,以后就不用拷贝了
/**
* 拷贝数据库
*
* @param string
*/
private void copyDb(String string) {
File file = new File(getFilesDir(), string);
if (file.exists()) {
return;
}
FileOutputStream out = null;
InputStream in = null;
try {
out = new FileOutputStream(file);
in = getAssets().open(string);
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
数据库查询的类, 直接传入参数就可以查,
package com.gs.meeting.dao;
import java.io.File;
import java.util.ArrayList;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.widget.Toast;
/**
*
* @author 刘朝
*
* 2016-11-18
*
*
*/
public class AppInfoDao {
private static ArrayList list;
private static SQLiteDatabase database;
private static StringBuilder sb;
public static ArrayList findAll(Context context) {
File filesDir = context.getFilesDir();
database = SQLiteDatabase.openDatabase(filesDir.getAbsolutePath()
+ "/meeting.db", null, SQLiteDatabase.OPEN_READONLY);
String sql = "select * from personInfo ";
sb = new StringBuilder();
sb.append(sql);
Cursor cursor = database.rawQuery(sb.toString(), null);
list = new ArrayList();
if (cursor == null) {
Toast.makeText(context, "没有查询到数据......", Toast.LENGTH_SHORT).show();
}
if (cursor != null) {
while (cursor.moveToNext()) {
SignInfo packageName = new SignInfo();
String no = cursor.getString(cursor.getColumnIndex("NO"));
String dp = cursor.getString(cursor.getColumnIndex("dp"));
String naMe = cursor.getString(cursor.getColumnIndex("name"));
String cardId = cursor.getString(cursor
.getColumnIndex("cardID"));
packageName.no = no;
packageName.dp = dp;
packageName.name = naMe;
packageName.cardId = cardId;
if (!list.contains(cursor)) {
list.add(packageName);
}
}
cursor.close();
}
database.close();
return list;
}
/**
* 条件查询
*/
public static ArrayList conditionQuery(Context context,
String condition) {
try {
File filesDir = context.getFilesDir();
database = SQLiteDatabase.openDatabase(filesDir.getAbsolutePath()
+ "/meeting.db", null, SQLiteDatabase.OPEN_READONLY);
// SELECT f_name, l_name from employee_data where f_name = 'John';
String sql = "select * from personInfo where cardID = '"
+ condition + "'";
sb = new StringBuilder();
sb.append(sql);
Cursor cursor = database.rawQuery(sb.toString(), null);
list = new ArrayList();
if (cursor == null) {
Toast.makeText(context, "没有查询到数据......", Toast.LENGTH_SHORT)
.show();
}
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
SignInfo packageName = new SignInfo();
String no = cursor.getString(cursor.getColumnIndex("NO"));
String dp = cursor.getString(cursor.getColumnIndex("dp"));
String naMe = cursor.getString(cursor
.getColumnIndex("name"));
String cardId = cursor.getString(cursor
.getColumnIndex("cardID"));
packageName.no = no;
packageName.dp = dp;
packageName.name = naMe;
packageName.cardId = cardId;
if (!list.contains(cursor)) {
list.add(packageName);
}
cursor.close();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
database.close();
System.out.println(list);
return list;
}
}
监听edittext键盘回车的监听
etCardId.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEND
|| (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
etCardid = etCardId.getText().toString().trim();
if (etCardid == null) {
return true;
}
boolean add = set.add(etCardid);
if (add == false) {
etCardId.setText("");
return true;
}
if (etCardId != null && add == true) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
String[] strings = etCardid.split("\r\n");
String str = strings[0];
mList = AppInfoDao.conditionQuery(
getApplicationContext(), str);
for (int i = 0; i < mList.size(); i++) {
allList.add(mList.get(i));
}
listView();
}
}, 100);
}
}
return true;
}
});
这里有两个集合,第一个集合mList 是根据条件查询数据库, 第二个集合allList是为了把每次签到的id都存起来,可以同时显示.为了不让签到多次,我在这里搞了个hashset集合,保证元素唯一,当然这样做可能不合理,但是因为功能比较小,浪费不了多少内存,为了实现功能暂时这样搞了.我这里用了个split截取字符串方法,是因为我手上这个打卡器没打一次卡它给我的数据就会自带一个回车键,在这里可以要,也可以不要,都行.
setOnEditorActionListener这个方法是监听键盘回车的,我也是第一次见到,挺好用的.可以收藏了.
这里还搞了个子线程,其实没必要的.要不要都行,测试过了,对性能完全没有影响
代码贴上,三种方式随便搞. 这里别忘了权限啊.
/**
* 追加文件:使用FileOutputStream,在构造FileOutputStream时,把第二个参数设为true
*
* @param fileName
* @param content
*/
public void print(String str) {
String fileName = getSDPath() + "/Download/" + "sign.txt";
method1(fileName, str);
}
public static void method1(String file, String conent) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file, true)));
out.write(conent);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 追加文件:使用FileWriter
*
* @param fileName
* @param content
*/
public static void method2(String fileName, String content) {
try {
// 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
FileWriter writer = new FileWriter(fileName, true);
writer.write(content);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 追加文件:使用RandomAccessFile
*
* @param fileName
* 文件名
* @param content
* 追加的内容
*/
public static void method3(String fileName, String content) {
try {
// 打开一个随机访问文件流,按读写方式
RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");
// 文件长度,字节数
long fileLength = randomFile.length();
// 将写文件指针移到文件尾。
randomFile.seek(fileLength);
randomFile.writeBytes(content);
randomFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public String getSDPath() {
File sdDir = null;
boolean sdCardExist = Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
if (sdCardExist) {
sdDir = Environment.getExternalStorageDirectory();// 获取跟目录
}
return sdDir.toString();
}