赞
踩
对其软件要求较高,要考虑兼容性。首先,在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
新闻界面由顶部搜索栏(带图片装饰)与新闻展示栏两部分组成。其中新闻展示栏集RecyclerView
、SmartRefreshLayout
两个类为一体,添加了装饰线和加载动画,加载流畅。新闻的点击进入详情页利用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依赖包
标签增减功能位于主页右下角的设置栏中,我们利用ChipsView
组件及其相关动作函数实现了这一功能,方便且带有动态效果。我们利用Intent
在主界面Activity
与工具栏Activity
之间传递信息,从而实现了近乎同步的标签增删操作。
疫情界面主要为基础的主界面框架,WebView主要是嵌入了一个夸克网址(https://broccoli.uc.cn/apps/pneumonia/routes/index),Android WebView在Android平台上是一个特殊的View,基于webkit引擎、展现web页面的控件,这个类可以被用来在你的app中仅仅显示一张在线的网页,WebView内部实现是采用渲染引擎来展示view的内容,提供网页前进后退,网页放大,缩小,搜索。
现在很多APP都内置了Web网页,本项目采用的是夸克网站平台比如说很多电商平台,淘宝、京东、聚划算等等。WebView比较灵活,不需要升级客户端,只需要修改网页代码即可。一些经常变化的页面可以用WebView这种方式去加载网页。例如中秋节跟国庆节打开的页面不一样,如果是用WebView显示的话,只修改修改html页面就行,而不需要升级客户端。
疫情学者界面分为高关注学者与追忆学者两个标签,每个标签栏下有对应学者的信息(与新闻列表类似),最外层用竖向排列的 LinearLayout 包裹,它有两个子节点,上面是用于滑动和装载 Fragment 的 ViewPager,下面是两个 Tab 的布局。且能够点击进入学者名片,查看学者头像、生平简介、主要贡献等信息。这里也调用了一个Material Design Chip View库实现返回桌面。
在主界面右下角的工具栏中能够查看浏览历史,此处我们追踪了每一个新闻对象的”被浏览“事件,并在程序后台自动进行历史记录,同时能够在离线状态下进行查看。.当点击到某一个新闻的时候,访问数据库是否有该新闻的信息,有的话更新新闻浏览的时间,更新数据库。没有的话添加到数据库中。
利用系统自带的分享功能进行分享,目前能够通过任何能够发送文本的应用(包括蓝牙)分享包含新闻摘要与具体内容的纯文本。创建一个选择器,让用户自己选择分享到哪里。这里有一点得注意,Intent传递的数据的Type(就是setType()方法)一定要控制好,不然会出错。
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 { String latest_id = newsl.get(0).id; int num = 10; String id = ""; JSONArray list; JSONObject obj; list = src.optJSONArray("data"); for (int i = 0; i < list.length(); i++){ obj = list.getJSONObject(i); id = obj.optString("_id"); if(id.equals(latest_id)){ num = i; break; } } for (int i = num - 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); } return num; } }
package com.java.zhushuqi.ui.data; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import androidx.annotation.Nullable; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProviders; import com.java.zhushuqi.R; /** * A placeholder fragment containing a simple view. */ public class PlaceholderFragment extends Fragment { private static final String ARG_SECTION_NUMBER = "section_number"; private PageViewModel pageViewModel; public static PlaceholderFragment newInstance(int index) { PlaceholderFragment fragment = new PlaceholderFragment(); Bundle bundle = new Bundle(); bundle.putInt(ARG_SECTION_NUMBER, index); fragment.setArguments(bundle); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); pageViewModel = ViewModelProviders.of(this).get(PageViewModel.class); int index = 1; if (getArguments() != null) { index = getArguments().getInt(ARG_SECTION_NUMBER); } pageViewModel.setIndex(index); } @Override public View onCreateView( @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_main, container, false); // final TextView textView = root.findViewById(R.id.section_label); final WebView webView = root.findViewById(R.id.web); pageViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() { @Override public void onChanged(@Nullable String s) { WebSettings settings = webView.getSettings(); settings .setRenderPriority(WebSettings.RenderPriority.HIGH); //开启本地DOM存储 settings.setDomStorageEnabled(true); settings.setUseWideViewPort(true); settings.setLoadWithOverviewMode(true); // 是否可访问Content Provider的资源,默认值 true settings.setAllowContentAccess(true); // 是否可访问本地文件,默认值 true settings.setAllowFileAccess(true); settings.setJavaScriptEnabled(true); settings.setSupportZoom(true); webView.loadUrl(s); webView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //使用WebView加载显示url view.loadUrl(url); //返回true return true; } }); } }); return root; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。