题记:原因是老师希望有一款上课用于点名的app,经过这几天的奋笔疾码,总算是完成了任务。其中 感谢小伙伴@NOtExpectError的帮助,解决了不少问题。
思考:如何解决签到的问题?
我的想法是分别写出教师端以及学生端的问题。教师端可以生成二维码并上传至服务器,学生端进行扫描,扫描结果与最新生成的二维码内一样则签到次数+1并将签到情况改成true,这样就导致了学生端没有主动换成false的方法,所以我将教师端生成二维码时同时将服务器所有学生的注册情况都改更新成false。教师端我就不进行展示 ,今天主要说学生端。
工具:
- bmob后端云(真滴好用啊!)
- zxing(生成扫描二维码要用)
- as3.2(emmm反正我喜欢用这个)
现在我们东西弄好了那就让我们愉快的打代码吧!
因为这是一个直接面对学生的客户端,界面肯定首当其冲了!
本来我是想加splash,不过仔细考虑了一下,其实并无卵。。。吼吼吼真香所以我还是毅然决然的加了!!!设了两秒跳转并将原界面finsh();然后就是登陆界面啦。
这个界面布局还挺简单的,如下图:
底下的微信登陆,对不起打扰了。原本以为微信的接口还算好接吧。还需要应用官网的,表示再见!
整个界面布局文件如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/title1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/login_main"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/title1"
android:layout_marginTop="10dp"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/StudentUser"
android:textSize="14dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_below="@+id/title"
android:orientation="vertical"
android:padding="5dp"
android:gravity="center">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/et_usename"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="13dp"
android:layout_marginRight="13dp"
android:layout_marginBottom="1dp"
android:layout_weight="3"
android:singleLine="true"
android:background="@android:drawable/edit_text"
android:gravity="center"
android:hint="@string/usename"
android:textCursorDrawable="@drawable/shape_et_border" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="13dp"
android:layout_marginTop="1dp"
android:singleLine="true"
android:layout_marginRight="13dp"
android:background="@android:drawable/edit_text"
android:gravity="center"
android:hint="@string/userpassword"
android:inputType="textPassword" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/buttom0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/edittext"
android:orientation="horizontal">
<CheckBox
android:id="@+id/cb_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="记住我" />
</LinearLayout>
<LinearLayout
android:id="@+id/buttom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/buttom0"
android:layout_marginTop="35dp"
android:orientation="horizontal">
<Button
android:id="@+id/btn_login"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:background="@drawable/btn_round"
android:enabled="true"
android:gravity="center"
android:text="@string/login"
android:textColor="@color/white"
android:textSize="18sp" />
<Button
android:id="@+id/btn_register"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:background="@drawable/btn_round"
android:enabled="true"
android:gravity="center"
android:text="@string/register"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/bottom1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/buttom"
android:layout_marginTop="10dp"
android:padding="5dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="1dp"
android:gravity="center"
android:text="@string/otherlogin" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/bottom1"
android:layout_marginTop="10dp"
android:gravity="center"
android:orientation="horizontal"
android:padding="5dp">
<ImageView
android:id="@+id/iv_wechat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/wx_button"
android:gravity="center" />
</LinearLayout>
</RelativeLayout>
啊哈哈可以说很长了,然后就是注册界面,因为一个人刚用肯定是没有号的,所以我们提供他注册的方式:
这个界面就比较水了。反正就是写完就会往服务器端传信息,姓名,班级,学号,密码。还有用户所看不到的,比如签到次数默认为0,权限默认为无,默认无签到。至于为什么加入内码呢,因为考虑app可能会有其他用户使用但我们只面向学生,所以加了这个算是一次认证。
为什么说刚刚是一次认证呢?因为用户注册完后会提示需要管理员授予权限,这就需要我们后台进行权限授予,否则就算你注册了也不可以使用本软件。这是防止学生自己恶意注册。
输入账号密码后则进入了主界面,原先的想法是主界面就签到功能就好了,不过随即一想这样就很废柴了这个app,所以在主界面加了一个listview做点击事件,如下:
这里面就可以从后台远程添加,然后客户端就可以刷新获得,这样有什么知识点老师要讲的或者同学愿意听的都可以直接实时更新。比较灵活,实现原理就是点击跳转webview,服务器端数据库保存标题和网址,这样点击即可加载,很方便也很实用。
有细心的小伙伴可能已经发现了,你的左上角有个点击按钮,是的一直没出现的签到功能就在那里
班级群号功能是教师端进行修改服务器同步更新,学生端也同步更新接收,签到功能则是打开二维码扫描功能。ios帮签暂时未开发。反馈则直径跳转qq界面与我进行反馈。
可能有人要说!!woc!!干货呢!!!不要听你瞎巴拉巴拉的!!!
吼吼吼!这就来干货。
之所以称之为干货。我觉得在写代码中遇到的问题比写代码本身更重要!
ps:晚上来更新,有课。先溜了,顺便让我整理一下。
ps:前来更新
bmob后端云使用入坑:
后端云查询主要用了匿名内部类,这就导致了里面的东西用完就会被回收,所以我们必须要用到持久化 技术来传递一些必要的东西,比如获取的用户,密码等。这里我采用的是shareperfernces的方法。
还有bmob采用的是异步的方式!!!划重点所以并不会像正常执行顺序一样从上往下执行。所以要不然就用匿名内部类层层嵌套,要不就用rxjava链式查询。
ps:我用bmob查询的时候遇到返回为空的情况但是用bql查询就完美解决。所以能用bql还是bql查询吧。
附上二维码查询的代码
private CaptureManager capture;
private DecoratedBarcodeView barcodeScannerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aty_on_time);// 自定义布局
barcodeScannerView = (DecoratedBarcodeView) findViewById(R.id.dbv_erweima);
capture = new CaptureManager(this, barcodeScannerView);
capture.initializeFromIntent(getIntent(), savedInstanceState);
capture.decode();
}
@Override
protected void onResume() {
super.onResume();
capture.onResume();
}
@Override
protected void onPause() {
super.onPause();
capture.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
capture.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
capture.onSaveInstanceState(outState);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.OnTime">
<com.journeyapps.barcodescanner.DecoratedBarcodeView
android:id="@+id/dbv_erweima"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_framing_rect_height="200dp"
app:zxing_framing_rect_width="200dp"
app:zxing_preview_scaling_strategy="fitXY"
app:zxing_use_texture_view="true">
</com.journeyapps.barcodescanner.DecoratedBarcodeView>
</RelativeLayout>
/**
* 回调二维码结果
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if (intentResult != null) {
if (intentResult.getContents() == null) {
dialogshow();//提示失败
} else {
成功的代码。。。。。
}
} else {
super.onActivityResult(requestCode, resultCode, data);//循环调用
}
}
/**
* 二维码设置
*/
private void onshow() {
new IntentIntegrator(this)
.setPrompt("请对准二维码")// 设置提示语
.setBeepEnabled(true)
.setOrientationLocked(false)
.setCaptureActivity(OnTime.class) // 设置自定义的activity是OnTime
.initiateScan(); // 初始化扫描
}