• 安卓APP源码和设计报告——基于Android的垃圾分类系统


    《移动应用开发》大作业报告

    题 目基于Android的垃圾分类系统
    系 部
    班 级
    学 生 姓 名
    学 号
    指 导 教 师
    时 间

    1、项目名称

    垃圾分类系统

    2、项目概述

    近些年,由于人民生活水平是的提高,生活方式与生活节奏的加快,使我国的垃圾生产数量已远超我国环境所能承受的能力,这也得到了国家领导人的注意,所以我国提出了垃圾分类的举措。垃圾分类措施陆续在各地展开,我国将垃圾分为四类:可回收垃圾、有害垃圾、湿垃圾和干垃圾。

    随着越来越多的城市实施垃圾分类的政策,为了提供更加方便快捷的学习垃圾分类知识,软件的方式无疑是现代社会最有效可行的方式,所以开发了基于Android的垃圾分类系统。

    本系统主要将垃圾分类与Android平台的App相结合,开发出一个对用户有所帮助的了解垃圾分类的系统,运用手机App 的易于流行的特点,来让人们了解垃圾分类的知识。因为垃圾无处不在并且每个人每天都在产生垃圾,所以该App能够满足日常生活中绝大部分用户的需求。

    本系统最终开发了一个功能基本完善的垃圾分类系统,集用户的登录和注册管理、垃圾分类答题管理、搜索垃圾信息管理、垃圾分类百科学习管理为一体的垃圾分类系统。

    该系统主要实现的功能模块包括:

    用户中心模块:实现用户登录和注册的功能。

    答题模块:用户通过答题的形式来辨别和加深对垃圾类别的认识。

    查询垃圾信息模块:通过文字搜索的方式查询对应类别垃圾的信息。

    垃圾百科模块:通过页面学习四类垃圾的分类情况。

    设置模块:显示登录用户名,用户协议和强制下线等功能。

    3、目的与要求

    通过一个综合的实例,进一步掌握移动应用程序开发的基本原理和方法,提高基于Android Studio对图形用户界面的设计和开发能力,以及对控件事件处理、数据存储以及网络访问的能力。具体包括如下几个方面:

    1)熟练掌握Android开发工具Android Studio的使用。

    2)熟练掌握Android线性布局的使用方法,并熟练使用Activity、Fragment、ListView、TextView、Button、EditText、ImageView等视图组件构建具有良好用户体验的App界面。

    3)熟练掌握对控件常用事件进行处理的方法。

    4)掌握数据存储或网络访问的基本方法。

    4、系统实现环境

    集成开发环境:Android Studio 3.0及以上

    JDK :1.8及以上

    Android版本:9.0及以上

    Android API:28及以上

    5、系统设计与实现

    1)用户的账号和密码保持在安卓本地数据库:使用 Android自带的关系型数据库SQLite。创建MydatabaseHelper继承SQLiteOpenHelper。

    static String name="user.db";

    static int dbVersion=1;

    public MydatabaseHelper(Context context){

    super(context, name,null, dbVersion);

    }

    public void onCreate(SQLiteDatabase db) {

    String sql="create table user(id integer primary key autoincrement,username varchar(20),password varchar(20))";

    db.execSQL(sql);

    }

    2)登录功能:在LoginActivity通过.getText().toString()得到用户输入信息,在UserService里通过帮助类dbHelper获得数据库对象,通过UserService 类里面String sql="select * from user where username=? and password=?"根据用户信息查询数据库信息,若用户输入信息匹配数据库信息则登录成功,反之则登录失败。

    login = findViewById(R.id.login);

    login.setOnClickListener(new View.OnClickListener() {

    public void onClick(View v) {

    String account = et_account.getText().toString(); //得到用户输入信息

    String password = et_password.getText().toString();

    System.out.println(account);

    System.out.println(password);

    Log.i("TAG",account+"_"+password);

    UserService uService=new UserService(LoginActivity.this);

    boolean flag=uService.login(account, password);

    if (flag) {

    editor= pref.edit();

    if(rememberPass.isChecked()){

    editor.putBoolean("remember_password", true);

    editor.putString("account",account);

    editor.putString("password",password);

    }else{

    editor.clear();

    }

    editor.apply();

    Log.i("TAG","登录成功");

    Toast.makeText(LoginActivity.this, "登陆成功", Toast.LENGTH_SHORT).show();

    Intent intent = new Intent(LoginActivity.this, MainActivity.class);

    intent.putExtra("str",account);

    startActivity(intent);

    finish();

    }

    else {

    Log.i("TAG","登录失败");

    Toast.makeText(LoginActivity.this, "密码或者用户名输入错误!", Toast.LENGTH_SHORT).show();

    }

    }

    });

    3)注册功能:通过UserService 类里面String sql="insert into user(username,password) values(?,?)"实现判断注册是否成功。

    register.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
    String name=username.getText().toString().trim();
    String pass=password.getText().toString().trim();
    Log.i("TAG",name+"_"+pass);
    UserService uService=new UserService(RegisterActivity.this);
    User user=new User();
    user.setUsername(name);
    user.setPassword(pass);
    uService.register(user);
    Toast.makeText(RegisterActivity.this, "注册成功", Toast.LENGTH_LONG).show();
    Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
    startActivity(intent);
    finish();
    }
    });

    UserService类:

    public boolean login(String username,String password){

    SQLiteDatabase sdb=dbHelper.getReadableDatabase();

    String sql="select * from user where username=? and password=?";

    Cursor cursor=sdb.rawQuery(sql, new String[]{username,password});

    if(cursor.moveToFirst()==true){

    cursor.close();

    return true;

    }

    return false;

    }

    public boolean register(User user){

    SQLiteDatabase sdb=dbHelper.getReadableDatabase();

    String sql="insert into user(username,password) values(?,?)";

    Object obj[]={user.getUsername(),user.getPassword()};

    sdb.execSQL(sql, obj);

    return true;

    }

    4)搜索功能:使用OkHttp和Gson进行简单网络请求与解析。在HttpUtil类里面创建sendOkHttpRequest()网络请求方法,在进行OKHttp封装:在SearchActivity里通过String garbageUrl写搜索接口地址,调用HttpUtil类中的sendOkHttpRequest()方法进行搜索功能,在使用GSON将网络返回的json字符串转为对象。

    HttpUtil类 :

    public class HttpUtil {

    public static void sendOkHttpRequest(String address,okhttp3.Callback callback){

    OkHttpClient client=new OkHttpClient();

    Request request=new Request.Builder().url(address).build();

    client.newCall(request).enqueue(callback);

    }

    }

    SearchActivity :OKHttp封装

    public void requestGarbage(final String garbageID){

    String garbageUrl=

    "https://api.tianapi.com/lajifenlei/index?key=882f80503756018b20d77c21d92057bc&word="+garbageID;

    HttpUtil.sendOkHttpRequest(garbageUrl, new Callback() {

    public void onResponse(Call call, Response response) throws IOException {

    final String responseText = response.body().string();

    final GarbageSearch garbageSearch= Utility.handleGarbageSearchResponse(responseText);

    Log.d(getClass().getSimpleName(), "========="+garbageSearch.msg);

    runOnUiThread(new Runnable() {

    public void run() {

    Log.d(getClass().getSimpleName(), "========="+garbageSearch.msg);

    if(garbageSearch!=null&&"success".equals(garbageSearch.msg) ) {

    SharedPreferences.Editor editor=

    PreferenceManager.getDefaultSharedPreferences(SearchActivity.this).edit();

    editor.putString("garbageSearch",responseText);

    editor.apply();

    showGarbageInfo(garbageSearch);

    }else {

    Toast.makeText(SearchActivity.this,"获取垃圾信息失败",Toast.LENGTH_SHORT).show();

    }

    }

    });

    }

    Utility :Gson解析json数据

    public class Utility {

    public static GarbageSearch handleGarbageSearchResponse(String response){

    try{

    return new Gson().fromJson(response, GarbageSearch.class);

    }catch(Exception e){

    e.printStackTrace();

    return null;

    }

    }

    }

    5)百科学习功能:通过TabLayout与ViewPager的联合使用实现顶部导航和页面对应一起切换。这样通过FragmentPagerAdapter适配器把百科的四个垃圾Fragment与ViewPager连在一起。

    public class PagerAdapter extends FragmentPagerAdapter {//定义适配器

    List fragments;

    public PagerAdapter(FragmentManager fm, List fragments) {

    super(fm);

    this.fragments=fragments;

    }

    public int getCount() {

    return fragments.size();//有几个页面

    }

    public Fragment getItem(int position) {

    return fragments.get(position);//显示第几个页面

    }

    6)答题功能:使用bean类序列化存储题目实现答题功能。

    private TextView btn_sub1;

    private List mList;

    private TextView select1;

    private ImageView back;

    private RadioGroup select1_1; // 题目

    private int num = 0; // 分数

    private boolean isXaun = false;

    select1 = findViewById(R.id.tv_timu);

    select1_1 = findViewById(R.id.select1_1);

    mList = new ArrayList<>();

    // A 可回收物 B 干垃圾 C 有害垃圾 D 湿垃圾

    RefuseBean refuseBean1 = new RefuseBean();

    refuseBean1.setName("剩菜属于什么垃圾?");

    refuseBean1.setType("D 湿垃圾");

    mList.add(refuseBean1);

    num = (int) Math.floor(Math.random() * 10 + 1);

    select1.setText(mList.get(num - 1).getName());

    btn_sub1 = findViewById(R.id.btn_sub1);

    select1_1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

    public void onCheckedChanged(RadioGroup group, int checkedId) { //单选框 RadioGroup

    isXaun = true; }

    });

    public void onClick(View v) {

    TextView answer = (TextView) findViewById(R.id.answer);

    if (!isXaun) {

    Toast.makeText(ExamActivity.this, "请选择答案", Toast.LENGTH_SHORT).show();

    return;

    }

    String select11 = select1.getText().toString();

    if (select11.equals(mList.get(num - 1).getName())) {

    for (int i = 0; i < select1_1.getChildCount(); i++) {

    RadioButton select1_1_1 = (RadioButton) select1_1.getChildAt(i);

    String select1_1_11 = select1_1_1.getText().toString();

    if (select1_1_1.isChecked()) {

    if (select1_1_11.equals(mList.get(num - 1).getType())) {

    switch (i) {

    case 0:

    answer.setText("您当前答案是 A ,答对了,真棒!");

    break;

    case 1:

    answer.setText("您当前答案是 B ,答对了,真棒!");

    break;

    case 2:

    answer.setText("您当前答案是 C ,答对了,真棒!");

    break;

    case 3:

    answer.setText("您当前答案是 D ,答对了,真棒!");

    break;

    }

    } else {

    answer.setText("答错了,正确答案是 " + mList.get(num - 1).getType());

    }

    break;

    }

    }

    }

    7)强制下线功能:在应用重新开始时注册广播接收器。因为创建了BaseActivity类作为所有活动的父类,所以只需要在BaseActivity中动态注册一个广播接收器。在BaseActivity类的onResume()中new ForceOfflineReceiver()实现在应用重新开始时注册广播接收器,在SettingsActivity里面的onClick()里添加sendBroadcast(intent)实现创建点击提示强制下线。

    主要代码:

    class ForceOfflineReceiver extends BroadcastReceiver{ // 创建一个广播接收器

    public void onReceive(final Context context, Intent intent) { // 写一个强制下线的警告框

    AlertDialog.Builder builder = new AlertDialog.Builder(context);

    builder.setTitle("警告");

    builder.setMessage("你正在强制下线");

    builder.setCancelable(false);

    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

    public void onClick(DialogInterface dialogInterface, int i) {

    ActivityCollector.finishAll();// 销毁所有活动

    Intent intent = new Intent(context, LoginActivity.class); // 重新启动LoginActivity

    context.startActivity(intent);

    }

    });

    builder.show();

    }

    }

    6、系统运行结果

    1)登录注册页面:

    图1 登录 图2 注册

    2)首页:答题页面和搜索页面

    图3 首页 图2 答题页面

    图4 搜索页面

    3)百科页面:

    图5 百科页面

    4)设置页面:

    图6 设置页面 图7 用户协议

    图8 当前版本 图9 强制下线

    7、实验总结

    通过本学期Android studio的学习,知道了Android是一个平台,它包括:基础系统、开发工具和完整的文档;,它采用Linux为其支撑操作系统,以Java作为其开发环境,实现了完整的电话、视频、网络、界面设计等基础功能。了解了一个界面就是一个Activity,View是组件,Intent:是Android应用程序界面之间及功能部件之间实现信息交互的桥梁,Service运行于后台的程序,Android应用程序的配置文件AndroidManifest.xml。

    通过一个垃圾分类的实例,进一步掌握移动应用程序开发的基本原理和方法,提高基于Android Studio对图形用户界面的设计和开发能力,以及对控件事件处理、数据存储以及网络访问的能力。但是在完成垃圾分类APP的设计过程中也出现了很多错误。

    比如配置错误:使用OkHttp进行网络请求和使用Gson进行数据解析时报错,解决方法是在build.gradle中增加compile 'com.squareup.okhttp3:okhttp:3.2.0'和compile 'com.google.code.gson:gson:2.7'。在xml文件中写页面时也有很多错误,比如图片铺不满ImageView,加上属性android:scaleType="fitXY"得到解决;页面各个控件排布混乱,通过RelativeLayout和LinearLayout布局,orientation和layout_weight等属性写出基本满意页面布局。Java类中把ViewPager和Fragment结合起来时,刚开始适配器是PagerAdapter,后来换用FragmentPagerAdapter,当你实现一个FragmentPagerAdapter,你必须至少覆盖getCount()和getItem()方法。使用网络请求时报权限错误,在AndroidManifest.xml里面加入允许网络android.permission.INTERNET得到解决。

    本系统也还有很多有待改进的地方,比如页面UI不够美观,页面功能不够完善等。

  • 相关阅读:
    Three.js 进阶之旅:全景漫游-高阶版在线看房 🏡
    go的orm框架-Gorm
    信息系统项目管理师必背核心考点(七十四)软件生存周期模型
    【Docker 那些事儿】容器网络的 “梦华录”(上篇)
    数据情报分析EXCEL篇
    react 函数组件 +类组件注意事项(基础)
    人工智能在医疗健康领域的应用与发展
    【GIT】:一文快速了解什么是GIT
    基于springboot+vue专业手语翻译预约系统
    神经网络结构搜索
  • 原文地址:https://blog.csdn.net/qq_39154376/article/details/128211825