基于Android开发疫情时报APP

Posted 木头科技㉿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Android开发疫情时报APP相关的知识,希望对你有一定的参考价值。

基于android开发疫情时报APP

要求:

对其软件要求较高,要考虑兼容性。首先,在APP开发工具方面,有更多开发者选择的是Eclipese
进行开发,但是最近google好像停止对Eclipese的sdk更新了,所以我推荐大家使用android studio
,它是Google官方指定的Android开发工具, 目前我用的是4.1.2稳定版,及JDK1-8.0,Gradle 6.3。
Gradle也极为重要,它的作用就是管理项目中的依赖、打包、编译……它就是一个构建工具,也就是一些复杂的操作不需要开发者自己去弄,而是通过构建工具去完成的。还有所调用的权限,本论文引用网址的及访问本地数据库权限至关重要,APP必须访问受限数据或执行受限操作才能实现某个用例,要先声明相应的权限,才能实现相对于的功能。

理论意义:

新冠肺炎疫情之下,为提倡关注疫情情况,各大网络平台推出了实时疫情时报网站,在当前大数据技术飞速发展的时代背景下,但独立的软件少之又少,本项目是基于Android开发的疫情时报APP,可以更加方便的了解疫情进展,更能够密切的查看疫情新闻,及了解为疫情做出贡献的英雄学者。

实际意义:

以我为例子,刚开始我花大量时间在微博上,看微博热搜和主页。但微博的信息量极大,我不得不每天花费一定量的时间来获取信息。接着我开始通过微信“看一看”和“朋友圈”来获取相关信息,这个渠道的好处在于通过我的朋友筛选出了质量不错的信息,我可以看到大家都在关注的热点。
以上两个途径是我最开始获取疫情信息的主要途径。但这两个途径并没有满足我另外的需求,比如获取个别城市相关的最新疫情消息和相关新闻。准确来说,我需要设计出一款实时监控疫情动态的APP,打开APP就能够直观的查看疫情相关的疫情,繁琐操作减少,更能切合我对疫情的了解状况。

一、绪论

本文是基于Android Studio的一款疫情时报APP,阐述了Android程序设计语言在软件开发中的应用方式,并以ios手机软件为例对Android程序设计语言在软件开发中的实践运用进行了详细分析,Android程序的应用最主要的便是在编程效率的提升方面,以往在编程方面存在着来自诸多方面的限制。

通常情况下来说,Java语言会应用在对于Android手机软件的开发上,而iOS则大多会采用c++或者是Objective-C语言进行开发。所以当在对一款移动端应用进行制作的时候需要同两个平台相适应,便要对两个不同的开发语言进行应用,在各自平台上分别将相同的逻辑开发一次。但此举往往涉及到对于大量人力和财力的浪费,特别是在时间方面的花费,对于移动互联网市场来说,时间是至关重要的影响因素,所以亟待采用适当的方法来解决这一问题。其本身存在着较高的专业程度,但从目前来看,编程不再像从前一样面临较高的难度,其在准入门槛方面也有所降低,强化对于Android程序设计语言的应用能够在极大程度上实现编程效率的提升,这样一来便能够有效发挥出其对于软件开发技术提高的推动作用。

二、项目完整展现




![在这里插入图片描述](https://img-blog.csdnimg.cn/ee7eb2779e1f4061afd9a44943f5fd4b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyo5aS044m_,size_16,color_FFFFFF,t_70,g_se,x_16

三、关于前端布局的框架

1 新闻界面

新闻界面由顶部搜索栏(带图片装饰)与新闻展示栏两部分组成。其中新闻展示栏集RecyclerViewSmartRefreshLayout两个类为一体,添加了装饰线和加载动画,加载流畅。新闻的点击进入详情页利用CardView类的click事件实现,加载内容为新闻的正文内容。

从Android 5.0开始,谷歌公司推出了一个用于大量数据展示的新控件RecylerView,可以用来代替传统的ListView,更加强大和灵活。RecyclerView并不会完全替代ListView(这点从ListView没有被标记为@Deprecated可以看出),两者的使用场景不一样。但是RecyclerView的出现会让很多开源项目被废弃,例如横向滚动的ListView, 横向滚动的GridView, 瀑布流控件,因为RecyclerView能够实现所有这些功能。

SmartRefreshLayout的目标是打造一个强大,稳定,成熟的下拉刷新框架,正如名字所说,SmartRefreshLayout是一个“聪明”或者“智能”的下拉刷新布局,由于它的“智能”,它不只是支持所有的View,还支持多层嵌套的视图结构[1]。 它继承自ViewGroup 而不是FrameLayout或LinearLayout,提高了性能。 也吸取了现在流行的各种刷新布局的优点,包括谷歌官方的 SwipeRefreshLayout, 其他第三方的 Ultra-Pull-To-Refresh、

TwinklingRefreshLayout 。还集成了各种炫酷的 Header 和 Footer。注:在SmartRefreshLayout若没有使用特殊Header,可以不添加SmartRefreshHeader依赖包

2 标签增减

标签增减功能位于主页右下角的设置栏中,我们利用ChipsView组件及其相关动作函数实现了这一功能,方便且带有动态效果。我们利用Intent在主界面Activity与工具栏Activity之间传递信息,从而实现了近乎同步的标签增删操作。

3 疫情界面

疫情界面主要为基础的主界面框架,WebView主要是嵌入了一个夸克网址(https://broccoli.uc.cn/apps/pneumonia/routes/index),Android WebView在Android平台上是一个特殊的View,基于webkit引擎、展现web页面的控件,这个类可以被用来在你的app中仅仅显示一张在线的网页,WebView内部实现是采用渲染引擎来展示view的内容,提供网页前进后退,网页放大,缩小,搜索。
现在很多APP都内置了Web网页,本项目采用的是夸克网站平台比如说很多电商平台,淘宝、京东、聚划算等等。WebView比较灵活,不需要升级客户端,只需要修改网页代码即可。一些经常变化的页面可以用WebView这种方式去加载网页。例如中秋节跟国庆节打开的页面不一样,如果是用WebView显示的话,只修改修改html页面就行,而不需要升级客户端。

4 学者界面

疫情学者界面分为高关注学者与追忆学者两个标签,每个标签栏下有对应学者的信息(与新闻列表类似),最外层用竖向排列的 LinearLayout 包裹,它有两个子节点,上面是用于滑动和装载 Fragment 的 ViewPager,下面是两个 Tab 的布局。且能够点击进入学者名片,查看学者头像、生平简介、主要贡献等信息。这里也调用了一个Material Design Chip View库实现返回桌面。

5 历史界面

在主界面右下角的工具栏中能够查看浏览历史,此处我们追踪了每一个新闻对象的”被浏览“事件,并在程序后台自动进行历史记录,同时能够在离线状态下进行查看。.当点击到某一个新闻的时候,访问数据库是否有该新闻的信息,有的话更新新闻浏览的时间,更新数据库。没有的话添加到数据库中。

6 分享功能

利用系统自带的分享功能进行分享,目前能够通过任何能够发送文本的应用(包括蓝牙)分享包含新闻摘要与具体内容的纯文本。创建一个选择器,让用户自己选择分享到哪里。这里有一点得注意,Intent传递的数据的Type(就是setType()方法)一定要控制好,不然会出错。

四、代码

以下只是5%代码,加以参考即可。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
>

    <FrameLayout
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@id/nav_view"
    />

    <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/nav_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
        android:background="@color/bisque"
            android:layout_alignParentBottom="true"
            app:menu="@menu/bottom_nav_menu"/>

</RelativeLayout>

MainActivity.java

package com.java.zhushuqi;

import android.os.Bundle;
import android.view.MenuItem;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import com.java.zhushuqi.backend.ConnectInterface;
import com.java.zhushuqi.backend.News;
import com.java.zhushuqi.backend.Server;
import com.java.zhushuqi.ui.Scholar.ScholarFragment;
import com.java.zhushuqi.ui.data.PlaceholderFragment;
import com.java.zhushuqi.ui.news.NewsFragment;
import com.java.zhushuqi.ui.knowledge.KnowledgeFragment;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import androidx.appcompat.app.AppCompatActivity;
import io.reactivex.functions.Consumer;

import java.util.List;

public class MainActivity extends AppCompatActivity 
    private Fragment[] fragments;
    private int lastFragment = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Server.server = new Server();
        ConnectInterface.InitServer().subscribe(new Consumer<List<News>>() 
            @Override
            public void accept(List<News> currentNews) 
                initView();
            
        );
    

    private void initView() 
        NewsFragment newsFragment = new NewsFragment();
        PlaceholderFragment dashboardFragment = new PlaceholderFragment();
        KnowledgeFragment notificationsFragment = new KnowledgeFragment();
        ScholarFragment scholarFragment = new ScholarFragment();
        fragments = new Fragment[] newsFragment,dashboardFragment,scholarFragment,notificationsFragment;

        getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment, newsFragment).show(newsFragment).commit();
        BottomNavigationView bottomNavigation = findViewById(R.id.nav_view);
        bottomNavigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() 
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) 
            switch (item.getItemId()) 
                case R.id.navigation_news:
                    if (lastFragment != 0) 
                        switchFragment(lastFragment, 0);
                        lastFragment = 0;
                    
                    return true;
                case R.id.navigation_data:
                    if (lastFragment != 1) 
                        switchFragment(lastFragment, 1);
                        lastFragment = 1;
                    
                    return true;
                case R.id.navigation_knowledge:
                    if (lastFragment != 2) 
                        switchFragment(lastFragment, 2);
                        lastFragment = 2;
                    
                    return true;

                default:
                    break;
            
            return false;
        
    ;

    private void switchFragment(int lastFragment, int index) 
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.hide(fragments[lastFragment]);
        if (!fragments[index].isAdded())
            transaction.add(R.id.nav_host_fragment, fragments[index]);
        transaction.show(fragments[index]).commitAllowingStateLoss();
    


package com.java.zhushuqi.backend;

import android.util.Log;

import org.json.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;

public class NewsLoader 
    static String link = "https://covid-dashboard.aminer.cn/api/events/list?type=%s&page=%d&size=%d";

    static String GetContentFromURL(String url) throws IOException 
        URL cs = new URL(url);
        URLConnection urlcnt = cs.openConnection();
        urlcnt.setConnectTimeout(10 * 1000);
        urlcnt.connect();
        BufferedReader in = new BufferedReader(new InputStreamReader(urlcnt.getInputStream()));
        String line, body = "";
        while ((line = in.readLine()) != null)
            body = body + line;
        in.close();
        return body;
    

    public static void GetNews(final int page, final String type, final int size, ArrayList<News> newsl) throws IOException, JSONException 
        String URL_String = new String(String.format(link, type, page, size));
        String body = GetContentFromURL(URL_String);
        if (body.equals("")) 
            Log.d("warning", "No message received.");
        
        JSONObject news_json = new JSONObject(body);
        GetNewsFromJSON(news_json, newsl);
    

    public static void GetNewsFromJSON(JSONObject src, ArrayList<News> newsl) throws JSONException 
        JSONArray list, authorlist;
        JSONObject obj, author;
        list = src.optJSONArray("data");
        for (int i = list.length() - 1; i >= 0; i--) 
            News news = new News();
            obj = list.getJSONObject(i);//这一页里的第i条新闻
            news.id = obj.optString("_id");
            news.content = obj.optString("content");
            news.date = obj.optString("date");
            news.seg_text = obj.optString("seg_text").split(" ");
            news.source = obj.optString("source");
            news.title = obj.optString("title");
            news.type = obj.optString("type");
            newsl.add(0, news);
        
    

    public static int RenewNews(final int page, final String type, final int size, ArrayList<News> newsl) throws IOException, JSONException 
        String URL_String = new String(String.format(link, type, page, size));
        String body = GetContentFromURL(URL_String);
        if (body.equals("")) 
            Log.d("warning", "No message received.");
        
        JSONObject news_json = new JSONObject(body);
        return (RenewNewsFromJSON(news_json, newsl));
    

    public static void RetrieveNews(final int page, final String type, final int size, ArrayList<News> newsl) throws IOException, JSONException 
        String URL_String = new String(String.format(link, type, page, size));
        String body = GetContentFromURL(URL_String);
        if (body.equals("")) 
            Log.d("warning", "No message received.");
        
        JSONObject news_json = new JSONObject(body);
        RetrieveNewsFromJSON(news_json, newsl);
    

    public static void RetrieveNewsFromJSON(JSONObject src, ArrayList<News> newsl) throws JSONException
        JSONArray list;
        JSONObject obj;
        list = src.optJSONArray("data");
        for (int i = 0; i < list.length(); i++) 
            News news = new News();
            obj = list.getJSONObject(i);//这一页里的第i条新闻
            news.id = obj.optString("_id");
            news.content = obj.optString("content");
            news.date = obj.optString("date");
            news.seg_text = obj.optString("seg_text").split(" ");
            news.source = obj.optString("source");
            news.title = obj.optString("title");
            news.type = obj.optString("type");
            newsl.add(news);//把旧新闻一条一条加到新闻列表的末端
        
    


    public static int RenewNewsFromJSON(JSONObject src, ArrayList<News> newsl) throws JSONException以上是关于基于Android开发疫情时报APP的主要内容,如果未能解决你的问题,请参考以下文章

疫情防范APP开发

javah生成jni头文件时报错 Error: cannot access android.support...

学习时报:建议加大数字货币的试点工作

Appium运行时报does not have permission android.permission.CLEAR_APP_USER_DATA to clear data

android Studio 项目里报这个错误,是啥原因啊。编译时报错。

用eclipse开发Android,用Genymotion测试时报错adb发生错误