最近写了一个简单的新闻客户端app+后台服务,主要是为了熟悉巩固一下知识点,增加编码熟练度
首先来画主界面
实现上图中的页面布局,主要是分成了三部分
最外层使用LinearLayout
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- </LinearLayout>
第一部分RelativeLayout
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="50dip"
- android:background="#3C3C3C">
- <TextView
- android:id="@+id/main_hand_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="10dp"
- android:layout_marginTop="12dp"
- android:text="新闻客户端"
- android:textColor="#e7e7e7"
- android:textSize="18sp" />
- <ImageView
- android:id="@+id/main_hand_refresh"
- android:layout_width="30dip"
- android:layout_height="30dip"
- android:layout_alignParentRight="true"
- android:layout_marginRight="10dip"
- android:layout_marginTop="10dip"
- android:onClick="titleBar_image_click"
- android:src="@drawable/main_hand_refresh" />
- </RelativeLayout>
第二部分RelativeLayout
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:layout_marginTop="1dp"
- android:background="#3C3C3C">
- <HorizontalScrollView
- android:id="@+id/main_category_scroll"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_toLeftOf="@id/main_category_button"
- android:scrollbars="none">
- <LinearLayout
- android:id="@+id/main_category_linear"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal" />
- </HorizontalScrollView>
- <Button
- android:id="@+id/main_category_button"
- android:layout_width="35dip"
- android:layout_height="35dip"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:background="@drawable/main_category_button" />
- </RelativeLayout>
第三部分是ListView,那为了有下拉刷新的效果,在外层嵌套了SwipeRefreshLayout
- <android.support.v4.widget.SwipeRefreshLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <ListView
- android:id="@+id/main_body_list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:divider="@drawable/line"
- android:fadeScrollbars="false"
- android:listSelector="@drawable/main_body_list_selector"
- android:scrollbarFadeDuration="0"></ListView>
- </android.support.v4.widget.SwipeRefreshLayout>
接着实现MainActivity代码
- package com.mynews.activity;
- import android.app.ActionBar;
- import android.graphics.Color;
- import android.graphics.drawable.ColorDrawable;
- import android.os.AsyncTask;
- import android.os.Handler;
- import android.os.Message;
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- import android.view.Gravity;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.AbsListView;
- import android.widget.AdapterView;
- import android.widget.BaseAdapter;
- import android.widget.Button;
- import android.widget.GridView;
- import android.widget.HorizontalScrollView;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.ListView;
- import android.widget.ProgressBar;
- import android.widget.SimpleAdapter;
- import android.widget.TextView;
- import com.mynews.R;
- import com.mynews.model.News;
- import com.mynews.utils.DensityUtil;
- import com.mynews.utils.GetPinyin;
- import com.mynews.utils.PicassoUtil;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.util.EntityUtils;
- import org.json.JSONArray;
- import org.json.JSONObject;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- public class MainActivity extends AppCompatActivity {
- private String CURRENTCATEGORY = "toutiao"; //点击的类别的拼音
- private int COUNT = 1; //分页的记录值
- private List<News> newsList = new ArrayList<>(); //新闻的集合
- private ListView mainBodyList; //列表listView
- private View mainBodyListBottom; //listView底部
- private TextView mainBodyListBottomTV; //listView底部的TextView
- private ProgressBar mainBodyListBottomPB; //listView底部的进度条
- private NewsAdapter newsAdapter; //新闻适配器
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mainBodyList = findViewById(R.id.main_body_list);
- //<-----------------------------------设置点击按钮滚动标题栏---------------------------------------
- final HorizontalScrollView category_scrollview = findViewById(R.id.main_category_scroll);
- Button main_category_button = findViewById(R.id.main_category_button);
- main_category_button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- category_scrollview.fling(DensityUtil.px2dip(MainActivity.this, 1500)); //滚动方法
- }
- });
- //--------------------------------------------------------------------------------------->
- //-----------------------------------设置点击按钮滚动标题栏--------------------------------------->
- int columnWidth = 400; //分类间隔距离 px
- String[] categoryArray = getResources().getStringArray(R.array.main_category_item); //分类信息
- List<Map<String, String>> categorys = new ArrayList<>();
- for (int i = 0; i < categoryArray.length; i++) {
- Map<String, String> map = new HashMap<>();
- map.put("main_category_item", categoryArray[i]);
- categorys.add(map);
- }
- SimpleAdapter categoryAdapter = new SimpleAdapter(this, categorys, R.layout.main_category_item, new String[]{"main_category_item"}, new int[]{R.id.main_category_item});
- //创建网格视图
- GridView gridView = new GridView(this);
- gridView.setNumColumns(GridView.AUTO_FIT); //列数设置为自动
- gridView.setSelector(new ColorDrawable(Color.TRANSPARENT)); //设置选中颜色为透明色
- gridView.setColumnWidth(DensityUtil.px2dip(this, columnWidth)); //设置列宽,DensityUtil.px2dip()转换px为dip的工具类方法
- gridView.setGravity(Gravity.CENTER); //设置对齐方式
- int dipColumnWidth = DensityUtil.px2dip(this, columnWidth) * categorys.size();
- ActionBar.LayoutParams params = new ActionBar.LayoutParams(dipColumnWidth, ActionBar.LayoutParams.WRAP_CONTENT);
- gridView.setLayoutParams(params);
- gridView.setAdapter(categoryAdapter);
- LinearLayout categoryLinearlayout = findViewById(R.id.main_category_linear);
- categoryLinearlayout.addView(gridView);
- //<---------------------------------------------------------------------------------------
- //-----------------------------------item的点击事件监听--------------------------------------->
- gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
- TextView categoryTitle;
- //这个循环主要作用清空所有item的背景,并设置初始颜色
- for (int j = 0; j < adapterView.getCount(); j++) {
- ((TextView) adapterView.getChildAt(j)).setTextColor(getResources().getColor(R.color.color_ADB2AD));
- adapterView.getChildAt(j).setBackgroundDrawable(null);
- }
- CURRENTCATEGORY = GetPinyin.getPingYin(((TextView) view).getText().toString()); //设置点击后的类别拼音,此处的工具类需要导包 pinyin4j-2.5.0.jar
- COUNT = 1; //分页的记录值
- categoryTitle = (TextView) view;
- categoryTitle.setTextColor(getResources().getColor(R.color.color_FFFFFF));
- categoryTitle.setBackgroundResource(R.drawable.main_category_item_selector);
- newsList = new ArrayList<>(); //清空新闻list
- mainBodyList.removeFooterView(mainBodyListBottom); //清除底部view
- new NewsTask().execute(getResources().getString(R.string.issue) + "news?type=" + CURRENTCATEGORY); //异步请求数据 R.string.issue=http://10.0.2.2:8080/news/api/
- }
- });
- //<---------------------------------------------------------------------------------------
- //-----------------------------------listVIew的拖动监听事件监听--------------------------------------->
- mainBodyList.setOnScrollListener(new AbsListView.OnScrollListener() {
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) { //停止滑动状态
- if (view.getLastVisiblePosition() == (view.getCount() - 1)) { //滑动到listView的最后
- mainBodyListBottomTV.setVisibility(View.GONE); //隐藏
- mainBodyListBottomPB.setVisibility(View.VISIBLE); //显示
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- addData(getResources().getString(R.string.issue) + "news?type=" + CURRENTCATEGORY, COUNT);
- handler.sendEmptyMessage(2);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- }
- }
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
- }
- });
- //<---------------------------------------------------------------------------------------
- new NewsTask().execute(getResources().getString(R.string.issue) + "news?type=" + CURRENTCATEGORY); //初始化加载
- }
- class NewsTask extends AsyncTask<String, Void, List<News>> {
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- }
- @Override
- protected List<News> doInBackground(String... strings) {
- //使用httpclient需要在app目录下的build.gradle文件中的Android里面加上useLibrary 'org.apache.http.legacy' /*加载 HttpClient*/
- HttpClient httpClient = new DefaultHttpClient();
- HttpGet httpGet = new HttpGet(strings[0]);
- try {
- HttpResponse httpResponse = httpClient.execute(httpGet);
- if (httpResponse.getStatusLine().getStatusCode() == 200) {
- HttpEntity entity = httpResponse.getEntity();
- String json = EntityUtils.toString(entity, "utf-8");
- JSONArray jsonArray = new JSONObject(json).getJSONArray("pdList");
- for (int i = 0; i < jsonArray.length(); i++) {
- JSONObject element = jsonArray.getJSONObject(i);
- News news = new News();
- news.setNEWSDETAIL_ID(element.getString("NEWSDETAIL_ID"));
- news.setUNIQUEKEY(element.getString("UNIQUEKEY"));
- news.setTITLE(element.getString("TITLE"));
- news.setURL(element.getString("URL"));
- news.setDATE(element.getString("DATE"));
- news.setPIC1(element.getString("PIC1"));
- news.setCATEGORY(element.getString("CATEGORY"));
- news.setCOMMENT(element.getString("COMMENT"));
- newsList.add(news);
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return newsList;
- }
- @Override
- protected void onPostExecute(List<News> newsList) {
- super.onPostExecute(newsList);
- mainBodyListBottom = getLayoutInflater().inflate(R.layout.main_body_list_bottom, null);
- mainBodyListBottomTV = mainBodyListBottom.findViewById(R.id.main_body_list_bottom_tv);
- mainBodyListBottomPB = mainBodyListBottom.findViewById(R.id.main_body_list_bottom_pb);
- if (newsList.size() == 0) {
- mainBodyListBottomTV.setText("暂无新闻");
- }
- mainBodyList.addFooterView(mainBodyListBottom);
- mainBodyList.setAdapter(newsAdapter = new NewsAdapter(newsList));
- handler.sendEmptyMessage(1);
- }
- }
- class NewsAdapter extends BaseAdapter {
- public List<News> data;
- public NewsAdapter(List<News> data) {
- this.data = data;
- }
- @Override
- public int getCount() {
- return data.size();
- }
- @Override
- public Object getItem(int i) {
- return i;
- }
- @Override
- public long getItemId(int i) {
- return 0;
- }
- @Override
- public View getView(int i, View view, ViewGroup viewGroup) {
- NewsList newsList;
- if (view == null) {
- newsList = new NewsList();
- view = getLayoutInflater().inflate(R.layout.main_body_list_item, viewGroup, false);
- newsList.imageView = view.findViewById(R.id.imageView);
- newsList.textView1 = view.findViewById(R.id.tv_title);
- newsList.textView2 = view.findViewById(R.id.tv_below);
- view.setTag(newsList);
- } else {
- newsList = (NewsList) view.getTag();
- }
- newsList.textView1.setText(data.get(i).getTITLE());
- newsList.textView2.setText(data.get(i).getDATE());
- PicassoUtil.loadImageWithHodler(MainActivity.this, data.get(i).getPIC1(), R.drawable.loading, newsList.imageView); //使用picasso加载图片资源
- return view;
- }
- }
- class NewsList {
- ImageView imageView;
- TextView textView1;
- TextView textView2;
- }
- /**
- * * 加载分页数据
- *
- * @param count 第几页
- * @param path 地址
- */
- private void addData(String path, int count) {
- HttpClient httpClient = new DefaultHttpClient();
- HttpGet httpGet = new HttpGet(path + "&count=" + count);
- try {
- HttpResponse httpResponse = httpClient.execute(httpGet);
- if (httpResponse.getStatusLine().getStatusCode() == 200) {
- HttpEntity entity = httpResponse.getEntity();
- String json = EntityUtils.toString(entity, "utf-8");
- JSONArray jsonArray = new JSONObject(json).getJSONArray("pdList");
- for (int i = 0; i < jsonArray.length(); i++) {
- JSONObject element = jsonArray.getJSONObject(i);
- News news = new News();
- news.setNEWSDETAIL_ID(element.getString("NEWSDETAIL_ID"));
- news.setUNIQUEKEY(element.getString("UNIQUEKEY"));
- news.setTITLE(element.getString("TITLE"));
- news.setURL(element.getString("URL"));
- news.setDATE(element.getString("DATE"));
- news.setPIC1(element.getString("PIC1"));
- news.setCATEGORY(element.getString("CATEGORY"));
- news.setCOMMENT(element.getString("COMMENT"));
- newsList.add(news);
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- private Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == 1) {
- }else if(msg.what == 2){ //数据加载完毕
- mainBodyListBottomPB.setVisibility(View.GONE); //隐藏进度条
- mainBodyListBottomTV.setVisibility(View.VISIBLE); //显示底部textView
- newsAdapter.notifyDataSetChanged();//刷新listview
- COUNT++;
- }
- }
- };
- }
补充:后台服务端代码和接口,点击这里
看看效果,基本实现了主要功能。但是细节做的不太好,找图片资源太耗时了。
接着实现新闻详情界面,顶部的左右箭头绑定了ViewFlipper 的nextView方法 和previousView方法,跟帖数随着发帖数量增加
新闻详情布局主要分为三个部分
最外层使用相对布局
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/new_detail_rl"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- </RelativeLayout>
第一部分
- <RelativeLayout
- android:id="@+id/news_detail_hand_relative"
- android:layout_width="match_parent"
- android:layout_height="50dip"
- android:background="@color/color_D32204">
- <Button
- android:id="@+id/news_detail_hand_relative_btn_left"
- android:layout_width="35dip"
- android:layout_height="35dip"
- android:layout_alignParentLeft="true"
- android:layout_marginTop="6dip"
- android:background="@drawable/zuo" />
- <TextView
- android:id="@+id/news_detail_hand_relative_tv_category"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="10dip"
- android:layout_marginVertical="13dip"
- android:layout_toEndOf="@+id/news_detail_hand_relative_btn_left"
- android:textSize="18sp" />
- <Button
- android:id="@+id/news_detail_hand_relative_btn_comment"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_marginRight="20dip"
- android:background="#00000000" />
- <Button
- android:id="@+id/news_detail_hand_relative_btn_right"
- android:layout_width="35dip"
- android:layout_height="35dip"
- android:layout_alignParentRight="true"
- android:layout_marginTop="6dip"
- android:background="@drawable/you" />
- </RelativeLayout>
第二部分,使用ViewFlipper能够加载多个body主体,并能通过方法切换
- <ViewFlipper
- android:id="@+id/news_detail_body_flipper"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_below="@+id/news_detail_hand_relative"
- android:layout_marginBottom="40dip"></ViewFlipper>
第三部分
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="40dip"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true"
- android:background="@drawable/background"
- android:gravity="center"
- android:orientation="horizontal"
- android:visibility="visible">
- <LinearLayout
- android:id="@+id/news_detail_bottom_ll_01"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginTop="3dip"
- android:gravity="center"
- android:orientation="horizontal"
- android:visibility="gone">
- <EditText
- android:id="@+id/news_detail_bottom_ll_01_et_comment"
- android:layout_width="290dip"
- android:layout_height="40dip"
- android:layout_marginLeft="2dip" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="|" />
- <!--发表-->
- <Button
- android:id="@+id/btn_send"
- android:layout_width="70dip"
- android:layout_height="40dip"
- android:layout_marginLeft="2dip"
- android:layout_marginRight="2dip"
- android:text="发表" />
- </LinearLayout>
- <LinearLayout
- android:id="@+id/news_detail_bottom_ll_02"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginTop="3dip"
- android:gravity="center"
- android:orientation="horizontal">
- <ImageButton
- android:id="@+id/news_detail_bottom_ll_02_ib_write"
- android:layout_width="290dip"
- android:layout_height="40dip"
- android:layout_marginLeft="2dip"
- android:background="#00000000"
- android:src="@drawable/button" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="7dip"
- android:text="|" />
- <!--收藏-->
- <Button
- android:id="@+id/news_detail_bottom_ll_02_btn_collect"
- android:layout_width="60dip"
- android:layout_height="40dip"
- android:layout_marginLeft="2dip"
- android:layout_marginRight="2dip"
- android:text="收藏" />
- </LinearLayout>
- </LinearLayout>
编写NewsDetailActivity 先把MainActivity中ListView的item点击事件补上
- //-----------------------------------listView的item点击事件--------------------------------------->
- mainBodyList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
- Intent intent = new Intent(MainActivity.this, NewsDetailActivity.class);
- Bundle bundle = new Bundle();
- bundle.putSerializable("list", (Serializable) newsList);//序列化,要注意转化(Serializable)
- intent.putExtra("list", bundle);
- intent.putExtra("i", i);
- startActivity(intent);
- }
- });
- //<---------------------------------------------------------------------------------------
- package com.mynews.activity;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.support.annotation.Nullable;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.ViewGroup;
- import android.webkit.WebView;
- import android.widget.BaseAdapter;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ImageButton;
- import android.widget.LinearLayout;
- import android.widget.ProgressBar;
- import android.widget.TextView;
- import android.widget.Toast;
- import android.widget.ViewFlipper;
- import com.mynews.R;
- import com.mynews.dao.CollectDao;
- import com.mynews.model.Collect;
- import com.mynews.model.News;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.util.EntityUtils;
- import org.json.JSONObject;
- import java.net.URLEncoder;
- import java.util.List;
- /**
- * Created by Administrator on 2017/12/28.
- */
- public class NewsDetailActivity extends Activity implements View.OnClickListener{
- private String TAG = NewsDetailActivity.class.getSimpleName();
- private Intent intent; //意图对象
- private int COUNT = 0; //记录页数
- private List<News> newsList; //传递过来的list集合
- private TextView tvCategory; //头部显示新闻类别的文本控件
- private Button btnComment; //头部的跟帖按钮
- private ViewFlipper viewFlipper; //view容器
- private LayoutInflater layoutInflater;
- private ProgressBar newsDetailBodyPB; //主体部分的进度条
- private int mStartX = 0;
- private Button newsDetailHandRelativeBtnLeft; //上一篇按钮
- private Button newsDetailHandRelativeBtnRight; //下一篇按钮
- private ImageButton newsDetailBottomLl02IbWrite; //图片按钮
- private Button newsDetailBottomLl01BtnSend; //发送跟帖按钮
- private Button newsDetailBottomLl02BtnCollect; //收藏按钮
- private long downTime; //收藏按钮按下的时间
- private long upTime; //收藏按钮按下的记录时间
- private volatile boolean onBtnTouch = false; //是否按下按钮
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.news_detail);
- //-----------------------------------获取MainActivity传递的参数------------------------------------->
- intent = getIntent(); //获取意图对象
- Bundle bundle = intent.getBundleExtra("list"); //获取新闻集合
- newsList = (List<News>) bundle.getSerializable("list"); //新闻集合
- COUNT = intent.getIntExtra("i", 0); //获取MainActivity点击的item的位置
- //设置头部的新闻类别
- tvCategory = findViewById(R.id.news_detail_hand_relative_tv_category);
- tvCategory.setText(newsList.get(COUNT).getCATEGORY());
- //设置头部的跟帖数
- btnComment = findViewById(R.id.news_detail_hand_relative_btn_comment);
- btnComment.setText(newsList.get(COUNT).getCOMMENT() + "跟帖");
- //设置显示新闻主体
- viewFlipper = findViewById(R.id.news_detail_body_flipper);
- layoutInflater = getLayoutInflater();
- //使用打气筒构造内容主体body
- View view = layoutInflater.inflate(R.layout.news_detail_body, null);
- //设置进度条按钮显示
- newsDetailBodyPB = view.findViewById(R.id.news_detail_body_pb);
- newsDetailBodyPB.setVisibility(View.VISIBLE);
- //viewFlipper.removeAllViews();
- for (int i = 0; i < newsList.size(); i++) {
- View inflate = layoutInflater.inflate(R.layout.news_detail_body, null);
- WebView newsDetailBodyWV = inflate.findViewById(R.id.news_detail_body_wv);
- newsDetailBodyWV.loadUrl(newsList.get(i).getURL()); //设置webView加载URL内容
- viewFlipper.addView(inflate, i); //把构造的主体内容加入到viewFlipper容器中
- //绑定主体的触摸监听事件
- newsDetailBodyWV.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- switch (motionEvent.getAction()) {
- case MotionEvent.ACTION_DOWN: //手指按下触发
- //按下时的横坐标
- mStartX = (int) motionEvent.getX();
- break;
- case MotionEvent.ACTION_UP: //手指抬起触发
- //像左滑动
- if (motionEvent.getX() < mStartX) {
- nextView();
- } else if (motionEvent.getX() > mStartX) { //向右滑动
- previousView();
- }
- break;
- }
- return true;
- }
- });
- }
- viewFlipper.setDisplayedChild(COUNT); //设置第几个view显示
- newsDetailBodyPB.setVisibility(View.GONE); //进度条隐藏
- //<--------------------------------------------------------------------------------------------------
- //---------------------------------------------设置点击事件---------------------------------------------------->
- newsDetailHandRelativeBtnLeft = findViewById(R.id.news_detail_hand_relative_btn_left);//上一页
- newsDetailHandRelativeBtnRight = findViewById(R.id.news_detail_hand_relative_btn_right);//下一页
- newsDetailBottomLl02IbWrite = findViewById(R.id.news_detail_bottom_ll_02_ib_write);//写跟帖
- newsDetailBottomLl01BtnSend = findViewById(R.id.news_detail_bottom_ll_01_btn_send);//发表
- newsDetailHandRelativeBtnLeft.setOnClickListener(this);
- newsDetailHandRelativeBtnRight.setOnClickListener(this);
- newsDetailBottomLl02IbWrite.setOnClickListener(this);
- newsDetailBottomLl01BtnSend.setOnClickListener(this);
- //------------------------------------------------------------------------------------------------->
- //---------------------------------------------设置收藏点击事件---------------------------------------------------->
- newsDetailBottomLl02BtnCollect = findViewById(R.id.news_detail_bottom_ll_02_btn_collect); //收藏 按钮是否被按下
- newsDetailBottomLl02BtnCollect.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
- downTime = System.currentTimeMillis();
- onBtnTouch = true;
- Thread t = new Thread() {
- @Override
- public void run() {
- while (onBtnTouch) {
- upTime = System.currentTimeMillis();
- try {
- Thread.sleep(100);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- };
- t.start();
- } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
- onBtnTouch = false;
- if (upTime - downTime > 500) {
- handler.sendEmptyMessage(3); //按下按钮超过0.5秒
- } else {
- handler.sendEmptyMessage(2);
- }
- } else if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL) { //手指按下移开时触发事件
- onBtnTouch = false;
- }
- return true;
- }
- });
- //------------------------------------------------------------------------------------------------->
- }
- @Override
- public void onClick(View view) {
- //点击的是上一页
- if (view.getId() == newsDetailHandRelativeBtnLeft.getId()) {
- previousView();
- } else if (view.getId() == newsDetailHandRelativeBtnRight.getId()) { //点击的是下一页
- nextView();
- } else if (view.getId() == newsDetailBottomLl02IbWrite.getId()) { //点击的是写跟贴
- LinearLayout ll01 = findViewById(R.id.news_detail_bottom_ll_01);
- ll01.setVisibility(View.VISIBLE);
- LinearLayout ll02 = findViewById(R.id.news_detail_bottom_ll_02);
- ll02.setVisibility(View.GONE);
- } else if (view.getId() == newsDetailBottomLl01BtnSend.getId()) { //点击的是发表
- final EditText etComment = findViewById(R.id.news_detail_bottom_ll_01_et_comment);
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- StringBuffer sb = new StringBuffer();
- sb.append("content=");
- sb.append(URLEncoder.encode(etComment.getText().toString().trim(), "UTF-8"));
- sb.append("&newsdetailId=");
- sb.append(newsList.get(COUNT).getNEWSDETAIL_ID());
- String path = getResources().getString(R.string.issue) + "addComment?" + sb.toString();
- addComment(path);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- Toast.makeText(this, "保存成功!", Toast.LENGTH_SHORT).show();
- LinearLayout ll01 = findViewById(R.id.news_detail_bottom_ll_01);
- ll01.setVisibility(View.GONE);
- LinearLayout ll02 = findViewById(R.id.news_detail_bottom_ll_02);
- ll02.setVisibility(View.VISIBLE);
- }
- }
- /**
- * 添加跟帖
- *
- * @param path 路径
- */
- private void addComment(String path) throws Exception {
- HttpClient httpClient = new DefaultHttpClient();
- HttpGet httpGet = new HttpGet(path);
- HttpResponse httpResponse;
- try {
- httpGet.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
- httpResponse = httpClient.execute(httpGet);
- if (httpResponse.getStatusLine().getStatusCode() == 200) {
- HttpEntity entity = httpResponse.getEntity();
- String result = EntityUtils.toString(entity, "utf-8");
- // String status = new JSONObject(result).getString("message");
- // String message = new JSONObject(result).getString("status");
- String count = new JSONObject(result).getString("count");
- Message message1 = Message.obtain();
- message1.obj = count;
- message1.what = 1;
- handler.sendMessage(message1);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- //点击的是下一页
- private void nextView() {
- COUNT++;
- Log.i(TAG, "nextView: count-->" + COUNT);
- if (COUNT <= newsList.size() - 1) {
- showNext();
- } else {
- COUNT = newsList.size() - 1;
- Toast.makeText(this, "已经是最后一条啦!", Toast.LENGTH_SHORT).show();
- }
- }
- //上一页
- private void previousView() {
- COUNT--;
- Log.i(TAG, "previousView: count-->" + COUNT);
- if (COUNT >= 0) {
- showPrevious();
- } else {
- COUNT = 0;
- Toast.makeText(this, "已经是第一条啦!", Toast.LENGTH_SHORT).show();
- }
- }
- //上一条
- private void showPrevious() {
- btnComment.setText(newsList.get(COUNT).getCOMMENT() + "跟帖"); //设置每条新闻对应的跟帖数量
- //设置动画效果
- viewFlipper.setInAnimation(NewsDetailActivity.this, R.anim.push_right_in);
- viewFlipper.setOutAnimation(NewsDetailActivity.this, R.anim.push_right_out);
- viewFlipper.showPrevious(); //调用viewFlipper的上一条方法
- }
- //下一条
- private void showNext() {
- btnComment.setText(newsList.get(COUNT).getCOMMENT() + "跟帖"); //设置每条新闻对应的跟帖数量
- //设置动画效果
- viewFlipper.setInAnimation(NewsDetailActivity.this, R.anim.push_left_in);
- viewFlipper.setOutAnimation(NewsDetailActivity.this, R.anim.push_left_out);
- viewFlipper.showNext();//调用viewFlipper的下一条方法
- }
- /**
- * 创建一个列表弹窗
- */
- private void createListDialog(final List<Collect> collects) {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("收藏列表:");
- builder.setAdapter(new CollectAdapter(collects), new DialogInterface.OnClickListener() {
- /**
- *
- * @param dialogInterface 当前的对话框
- * @param i 当前点击的是列表的第几个 item
- */
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- Intent intent = new Intent(NewsDetailActivity.this, CollectNewsDetailActivity.class);
- intent.putExtra("newsdetailId", collects.get(i).getNewsdetailId());
- startActivity(intent);
- }
- });
- builder.setCancelable(true);//允许被某些方式取消,比如按对话框之外的区域或者是返回键
- builder.show();
- }
- class CollectAdapter extends BaseAdapter {
- private List<Collect> collects;
- public CollectAdapter(List<Collect> collects) {
- this.collects = collects;
- }
- @Override
- public int getCount() {
- return collects.size();
- }
- @Override
- public Object getItem(int i) {
- return i;
- }
- @Override
- public long getItemId(int i) {
- return 0;
- }
- @Override
- public View getView(int i, View view, ViewGroup viewGroup) {
- CollectDialog collectDialog;
- if (view == null) {
- collectDialog = new CollectDialog();
- view = getLayoutInflater().inflate(R.layout.news_detail_collect_dialog, viewGroup, false);
- collectDialog.tv1 = view.findViewById(R.id.btn_collect_dialog_title);
- collectDialog.tv2 = view.findViewById(R.id.btn_collect_dialog_date);
- view.setTag(collectDialog);
- } else {
- collectDialog = (CollectDialog) view.getTag();
- }
- collectDialog.tv1.setText(collects.get(i).getTitle());
- collectDialog.tv2.setText(collects.get(i).getDate());
- return view;
- }
- }
- class CollectDialog {
- TextView tv1;
- TextView tv2;
- }
- private Handler handler = new Handler(){
- CollectDao collectDao = new CollectDao(NewsDetailActivity.this);
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == 1) {
- String count = (String) msg.obj;
- btnComment.setText(count + "跟帖");
- } else if (msg.what == 2) {
- List<Collect> collects = collectDao.queryBuilder1(newsList.get(COUNT).getNEWSDETAIL_ID());
- if (collects.size() <= 0) {
- Collect collect = new Collect();
- collect.setNewsdetailId(newsList.get(COUNT).getNEWSDETAIL_ID());
- collect.setTitle(newsList.get(COUNT).getTITLE());
- collect.setDate(newsList.get(COUNT).getDATE());
- collectDao.addCollect(collect);
- Toast.makeText(NewsDetailActivity.this, "收藏成功,长按可查看收藏哦!", Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(NewsDetailActivity.this, "已收藏该文章,长按可查看收藏哦!", Toast.LENGTH_SHORT).show();
- }
- } else if (msg.what == 3) {
- createListDialog(collectDao.listAll());
- }
- }
- };
- }
NewsDetailActivity 部分在保存收藏文章时使用了ORMLite,需要导入两个jar文件,并且需要编写一个Helper类和一个Dao类。具体看文章最后补上的源码。
接着画下一个布局,界面很简单,直接看代码
布局文件
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/color_E7E7E7"
- android:orientation="vertical">
- <RelativeLayout
- android:id="@+id/comment_list_hand"
- android:layout_width="match_parent"
- android:layout_height="50dip"
- android:background="@color/color_D32204">
- <TextView
- android:id="@+id/comment_list_hand_TV"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="18dip"
- android:layout_marginTop="12dip"
- android:text="跟帖"
- android:textColor="@color/color_E7E7E7"
- android:textSize="18sp" />
- <Button
- android:id="@+id/comment_list_hand_BTN"
- android:layout_width="60dip"
- android:layout_height="45dip"
- android:layout_alignParentRight="true"
- android:layout_marginRight="10dip"
- android:layout_marginTop="4dip"
- android:text="原文"/>
- </RelativeLayout>
- <ListView
- android:id="@+id/comment_list_body"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_below="@+id/comment_list_hand"
- android:cacheColorHint="#00000000"
- android:divider="@drawable/line"
- android:layout_marginBottom="40dip">
- </ListView>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="40dip"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true"
- android:background="@drawable/background"
- android:gravity="center"
- android:orientation="horizontal"
- android:visibility="visible">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginTop="3dip"
- android:gravity="center"
- android:orientation="horizontal">
- <EditText
- android:id="@+id/comment_list_bottom_ET"
- android:layout_width="290dip"
- android:layout_height="40dip"
- android:layout_marginLeft="2dip" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="|" />
- <!--发表-->
- <Button
- android:id="@+id/comment_list_bottom_BTN"
- android:layout_width="70dip"
- android:layout_height="40dip"
- android:layout_marginLeft="2dip"
- android:layout_marginRight="2dip"
- android:text="发表" />
- </LinearLayout>
- </LinearLayout>
- </RelativeLayout>
编写CommentActivity
- package com.mynews.activity;
- import android.app.Activity;
- import android.content.Context;
- import android.os.AsyncTask;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.support.annotation.Nullable;
- import android.view.View;
- import android.view.ViewGroup;
- import android.view.inputmethod.InputMethodManager;
- import android.widget.BaseAdapter;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ListView;
- import android.widget.TextView;
- import android.widget.Toast;
- import com.mynews.R;
- import com.mynews.model.Comment;
- import com.mynews.utils.DateUtil;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.util.EntityUtils;
- import org.json.JSONArray;
- import org.json.JSONObject;
- import java.net.URLEncoder;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * Created by Administrator on 2017/12/28.
- */
- public class CommentActivity extends Activity {
- private EditText commentListBottomET; //底部的输入框控件
- private Button commentListBottomBTN; //底部的发表按钮
- private List<Comment> commentList; //跟帖集合
- private CommentAdapter commentAdapter; //跟帖的适配器
- private ListView commentListView; //跟帖的listView
- private TextView commentListHandTV;
- private Button commentListHandBTN;
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.comment_list);
- commentListHandTV = findViewById(R.id.comment_list_hand_TV);
- commentListView = findViewById(R.id.comment_list_body);
- //-----------------------------------原文按钮点击事件----------------------------------------->
- commentListHandBTN = findViewById(R.id.comment_list_hand_BTN);
- commentListHandBTN.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- finish();
- }
- });
- //<-------------------------------------------------------------------------------------
- //-----------------------------------发表按钮点击事件----------------------------------------->
- commentListBottomBTN = findViewById(R.id.comment_list_bottom_BTN); //获取发表按钮
- commentListBottomET = findViewById(R.id.comment_list_bottom_ET); //获取editText按钮
- commentListBottomBTN.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- String commentContent = commentListBottomET.getText().toString().trim();
- StringBuffer sb = new StringBuffer();
- sb.append("content=");
- sb.append(URLEncoder.encode(commentContent, "UTF-8"));
- sb.append("&newsdetailId=");
- sb.append(getIntent().getStringExtra("newsdetailId"));
- String path = getResources().getString(R.string.issue) + "addComment?" + sb.toString();
- addComment(path);
- Comment comment = new Comment();
- comment.setDATE(DateUtil.getTime());
- comment.setCONTENT(commentContent);
- commentList.add(comment);
- handler.sendEmptyMessage(2);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- });
- new CommentTask().execute(getResources().getString(R.string.issue) + "commentList?newsdetailId=" + getIntent().getStringExtra("newsdetailId"));
- }
- class CommentAdapter extends BaseAdapter {
- private List<Comment> commentList;
- public CommentAdapter(List<Comment> commentList) {
- this.commentList = commentList;
- }
- @Override
- public int getCount() {
- return commentList.size();
- }
- @Override
- public Object getItem(int i) {
- return i;
- }
- @Override
- public long getItemId(int i) {
- return 0;
- }
- @Override
- public View getView(int i, View view, ViewGroup viewGroup) {
- Comment1 comment1;
- if (view == null) {
- comment1 = new Comment1();
- view = getLayoutInflater().inflate(R.layout.comment_list_item, viewGroup, false);
- comment1.tv1 = view.findViewById(R.id.comment_list_item_tv1);
- comment1.tv2 = view.findViewById(R.id.comment_list_item_tv2);
- comment1.tv3 = view.findViewById(R.id.comment_list_item_tv3);
- view.setTag(comment1);
- } else {
- comment1 = (Comment1) view.getTag();
- }
- comment1.tv1.setText(commentList.get(i).getDATE());
- comment1.tv2.setText(commentList.get(i).getCOMMENTID());
- comment1.tv3.setText(commentList.get(i).getCONTENT());
- return view;
- }
- }
- class Comment1 {
- TextView tv1;
- TextView tv2;
- TextView tv3;
- }
- class CommentTask extends AsyncTask<String, Void, List<Comment>> {
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- }
- @Override
- protected List<Comment> doInBackground(String... strings) {
- commentList = new ArrayList<>();
- HttpClient httpClient = new DefaultHttpClient();
- HttpGet httpGet = new HttpGet(strings[0]);
- try {
- HttpResponse httpResponse = httpClient.execute(httpGet);
- if (httpResponse.getStatusLine().getStatusCode() == 200) {
- HttpEntity entity = httpResponse.getEntity();
- String json = EntityUtils.toString(entity, "utf-8");
- JSONArray jsonArray = new JSONObject(json).getJSONArray("pdList");
- for (int i = 0; i < jsonArray.length(); i++) {
- JSONObject element = jsonArray.getJSONObject(i);
- Comment comment = new Comment();
- comment.setCOMMENTID(element.getString("COMMENT_ID"));
- comment.setDATE(element.getString("DATE"));
- comment.setCONTENT(element.getString("CONTENT"));
- commentList.add(comment);
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return commentList;
- }
- @Override
- protected void onPostExecute(List<Comment> commentList) {
- super.onPostExecute(commentList);
- commentListView.setAdapter(commentAdapter = new CommentAdapter(commentList));
- }
- }
- /**
- * 添加跟帖
- *
- * @param path 路径
- */
- private void addComment(String path) throws Exception {
- //Log.i(TAG, "addComment: path------>>" + path);
- HttpClient httpClient = new DefaultHttpClient();
- HttpGet httpGet = new HttpGet(path);
- HttpResponse httpResponse;
- try {
- httpGet.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
- //httpGet.addHeader("charset", HTTP.UTF_8);
- httpResponse = httpClient.execute(httpGet);
- if (httpResponse.getStatusLine().getStatusCode() == 200) {
- HttpEntity entity = httpResponse.getEntity();
- String result = EntityUtils.toString(entity, "utf-8");
- String status = new JSONObject(result).getString("message");
- String message = new JSONObject(result).getString("status");
- String count = new JSONObject(result).getString("count");
- Message message1 = Message.obtain();
- message1.obj = count;
- message1.what = 1;
- handler.sendMessage(message1);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- private Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == 1) {
- String count = (String) msg.obj;
- commentListHandTV.setText("跟帖 " + count + "条");
- Toast.makeText(CommentActivity.this, "发帖成功!", Toast.LENGTH_LONG).show();
- } else if (msg.what == 2) {
- commentAdapter.notifyDataSetChanged();//刷新listview
- commentListBottomET.setText(""); //清空文本
- commentListBottomET.clearFocus(); //清除焦点
- //软键盘隐藏
- InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
- }
- }
- };
- }
到此主要的功能以及基本实现,现在再来给主界面添加上版本更新的代码,让程序每次启动检查是否有新版本,并提示用户是否更新
- package com.mynews.dao;
- import android.app.AlertDialog;
- import android.app.Dialog;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.net.Uri;
- import android.os.Build;
- import android.support.v4.content.FileProvider;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.widget.ProgressBar;
- import android.widget.TextView;
- import com.mynews.BuildConfig;
- import com.mynews.R;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import java.util.Map;
- public class VersionDao {
- private Context context;
- private Map<String, String> map; //服务器端最新app信息
- private volatile boolean cancelUpdate; //下载状态
- private ProgressBar pbNewsDeatil;
- private Dialog downloadDialog;
- private String TAG = VersionDao.class.getSimpleName();
- public VersionDao(Context context, Map<String, String> map) {
- this.context = context;
- this.map = map;
- }
- public void checkUpdate() {
- Log.i(TAG, "checkUpdate: 版本更新");
- if (isUpdate()) {
- showNoticeDialog();
- }
- }
- private boolean isUpdate() {
- //获取当前软件版本号
- String versionName = getVersionName();
- //Log.i(TAG, "isUpdate: versionName=" + versionName);
- //Log.i(TAG, "isUpdate: NUMBER=" + map.get("NUMBER").toString());
- if (!versionName.equals(map.get("NUMBER").toString())) { //版本号字符串不相等时更新
- return true;
- }
- return false;
- }
- /**
- * 当前应用版本号
- *
- * @return 版本号
- */
- private String getVersionName() {
- String versionName = null;
- try {
- //通过上下文对象获取版本号
- versionName = context.getPackageManager().getPackageInfo("com.gm.news", 0).versionName;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return versionName;
- }
- private void showNoticeDialog() {
- //构造对话框
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle("版本更新提示");
- builder.setMessage("检测到新版本," + map.get("CONTENT").toString());
- //更新
- builder.setPositiveButton("更新", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- dialogInterface.dismiss(); //隐藏更新对话框
- showDownloadDialog(); //显示下载进度对话框
- }
- });
- //稍后更新
- builder.setNegativeButton("稍后更新", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- dialogInterface.dismiss();
- }
- });
- Dialog noticeDialog = builder.create();
- noticeDialog.show();
- }
- private void showDownloadDialog() {
- Log.i(TAG, "showDownloadDialog: 弹出更新对话框");
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle("更新进度:");
- LayoutInflater layoutInflater = LayoutInflater.from(context);
- View view = layoutInflater.inflate(R.layout.main_softupload_progress, null);
- pbNewsDeatil = view.findViewById(R.id.pb_newsDetail);
- TextView tv_version_content = view.findViewById(R.id.tv_version_content);
- tv_version_content.setText(map.get("CONTENT").toString()); //版本更新的内容
- builder.setView(view);
- //取消
- builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- dialogInterface.dismiss();
- //设置取消状态
- cancelUpdate = false;
- }
- });
- downloadDialog = builder.create();
- downloadDialog.show();
- cancelUpdate = true; //开始下载
- //下载文件
- download();
- }
- //下载文件
- private void download() {
- Log.i(TAG, "download: 下载文件中");
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- URL url = new URL(map.get("PATH").toString());
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(5000);
- int code = conn.getResponseCode();
- if (code == HttpURLConnection.HTTP_OK) {
- File file = new File(context.getFilesDir().getPath() + "/mynews.apk");
- FileOutputStream fos = new FileOutputStream(file);
- float length = conn.getContentLength();
- InputStream in = conn.getInputStream();
- float total = 0;
- int len = -1;
- byte[] buffer = new byte[100];
- int progress;
- while ((len = in.read(buffer)) != -1) {
- if (cancelUpdate) {
- fos.write(buffer, 0, len);
- total += len;
- progress = (int) ((total / length) * 100);
- pbNewsDeatil.setProgress(progress);
- }
- }
- in.close();
- fos.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- // 进度达到最大值后,窗口消失
- downloadDialog.cancel();
- install();
- }
- }).start();
- }
- private void install() {
- File file = new File(context.getFilesDir().getPath() + "/mynews.apk");
- Intent intent = new Intent(Intent.ACTION_VIEW);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- Uri contentUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", file);
- intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
- } else {
- intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- }
- context.startActivity(intent);
- }
- }
在MainActivity的onCreate方法中调用
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- String path = getResources().getString(R.string.issue) + "findVersion";
- findVersion(path);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- /**
- * 查询版本信息
- *
- * @param path
- */
- private void findVersion(String path) {
- HttpClient httpClient = new DefaultHttpClient();
- HttpGet httpGet = new HttpGet(path);
- HttpResponse httpResponse;
- try {
- httpResponse = httpClient.execute(httpGet);
- if (httpResponse.getStatusLine().getStatusCode() == 200) {
- HttpEntity entity = httpResponse.getEntity();
- String result = EntityUtils.toString(entity, "utf-8");
- JSONObject jsonObject = new JSONObject(result).getJSONObject("pd");
- map = new HashMap<>();
- map.put("VERSION_ID", jsonObject.getString("VERSION_ID"));
- map.put("NUMBER", jsonObject.getString("NUMBER"));
- map.put("CONTENT", jsonObject.getString("CONTENT"));
- map.put("DATE", jsonObject.getString("DATE"));
- map.put("STATUS", jsonObject.getString("STATUS"));
- map.put("PATH", jsonObject.getString("PATH"));
- handler.sendEmptyMessage(4); //数据请求加载完毕发送消息让handler处理
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- if (msg.what == 4) { //版本更新的逻辑
- VersionDao versionDao = new VersionDao(MainActivity.this, map);
- versionDao.checkUpdate(); //更新操作
- }
清单文件中配置
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- <provider
- android:name="android.support.v4.content.FileProvider"
- android:authorities="com.mynews.fileProvider"
- android:exported="false"
- android:grantUriPermissions="true">
- <meta-data
- android:name="android.support.FILE_PROVIDER_PATHS"
- android:resource="@xml/file_paths" />
- </provider>
res文件夹下新建xml文件夹,新建文件file_paths
- <?xml version="1.0" encoding="utf-8"?>
- <paths xmlns:android="http://schemas.android.com/apk/res/android">
- <files-path
- name="external_files"
- path="" />
- </paths>
可能有一部分功能代码逻辑处理的并不是很好或是有BUG,还请各位多多包涵。小弟继续努力!