最近写了一个简单的新闻客户端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);
}
});
//<---------------------------------------------------------------------------------------
编写NewsDetailActivity
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();
}
}
handler中进行处理
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,还请各位多多包涵。