<file_sep>package com.jamtu.fragments;

import static com.jamtu.fragments.LocaleJokeListFragment.JOKE_TYPE;
import android.os.Bundle;

import com.jamtu.adapter.ViewPageFragmentAdapter;
import com.jamtu.basefragment.BaseViewPagerFragment;
import com.jamtu.utils.AppOthers;

/**
 * 发现页面
 * 
 * @author lijq
 * @created 2015-03-29
 */
public class JokePagerFragment extends BaseViewPagerFragment {

	private final String[] TITLES = { "爱情", "幽默", "校园", "古代", "军事", "职场", "顺口溜", "成人", "儿童", "愚人", "短信", "尴尬" };
	private final String[] TYPES = { "love", "humor", "campus", "ancient", "army", "job", "jingle", "adult",
			"children", "fool", "sms", "embarrassed" };

	public static JokePagerFragment newInstance() {
		return new JokePagerFragment();
	}

	@Override
	protected void onSetupTabAdapter(ViewPageFragmentAdapter adapter) {
		AppOthers.showBothApp(getJokeApplication());
		AppOthers.showInnerApp(getJokeApplication());
		// String[] tabNames =
		// getResources().getStringArray(R.array.joke_title_array);
		int len = TITLES.length;
		for (byte i = 0; i < len; i++) {
			Bundle bundle = new Bundle();
			bundle.putString(JOKE_TYPE, TYPES[i]);
			adapter.addTab(TITLES[i], TITLES[i], JokeListFragment.class, bundle);
		}
	}
}
<file_sep>package com.jamtu.fragments;

import static com.jamtu.fragments.NetJokeListFragment.JOKE_URL;
import android.os.Bundle;

import com.jamtu.adapter.ViewPageFragmentAdapter;
import com.jamtu.basefragment.BaseViewPagerFragment;
import com.jamtu.utils.AppOthers;

/**
 * 网络段子1
 * 
 * @author lijq
 * @created 2015-03-29
 */
public class QSBK_JokePagerFragment extends BaseViewPagerFragment {

	public static QSBK_JokePagerFragment newInstance() {
		return new QSBK_JokePagerFragment();
	}

	@Override
	protected void onSetupTabAdapter(ViewPageFragmentAdapter adapter) {
		AppOthers.showBothApp(getJokeApplication());
		AppOthers.showInnerApp(getJokeApplication());
		adapter.addTab("热门段子", "热门段子", NetJokeListFragment.class, getQSBKBundle(0));
		adapter.addTab("热门趣图", "热门趣图", NetJokeListFragment.class, getQSBKBundle(1));
		adapter.addTab("最新段子", "最新段子", NetJokeListFragment.class, getQSBKBundle(2));
		adapter.addTab("最新趣图", "最新趣图", NetJokeListFragment.class, getQSBKBundle(3));
	}

	private final String QSBK_URL_Prefix = "http://www.qiushibaike.com/";
	// 热门 8小时, 24小时, 穿越
	private static final String[] QSBK_TYPES_HOT_TOPIC = { "8hr", "hot", "history" };
	// 纯图 最热, 最新
	private static final String[] QSBK_PURE_IMG = { "imgrank", "pic" };
	// 纯文 最热, 最新
	private static final String[] QSBK_PURE_TEXT = { "text", "textnew" };
	public static final String[] QSBK_TYPES = { QSBK_PURE_TEXT[0], QSBK_PURE_IMG[0], QSBK_PURE_TEXT[1],
			QSBK_PURE_IMG[1] };

	private Bundle getQSBKBundle(int index) {
		Bundle bundle = new Bundle();
		bundle.putString(JOKE_URL, QSBK_URL_Prefix + QSBK_TYPES[index]);
		return bundle;
	}
}
<file_sep>package com.jamtu.utils;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

import com.jamtu.config.PrefUtil;
import com.jamtu.config.Version;

/**
 * MODE_MULTI_PROCESS 跨进程通信
 * 
 * @author lijq
 * @date 2013-10-9 下午04:52:08
 * @version 1.0
 */
public class SharedUtil {

	private static SharedPreferences eckShared;
	private static DESUtils currDesUtils = new DESUtils();// 当前加密对象
	private static DESUtils oldDesUtils = new DESUtils();// 旧版本加密对象

	private static SharedPreferences getEckShared(Context context) {
		if (null == eckShared) {
			eckShared = context.getSharedPreferences(PrefUtil.PRE_FILE_NAME, Context.MODE_MULTI_PROCESS);
		}
		return eckShared;
	}

	// 将ShardPreferences中旧的K-V数据 更新为最新的
	// 新旧K-V数据的不同 只是加密的密钥变了
	public static void copy(Context context) {
		try {
			SharedPreferences sharedPreferences = getEckShared(context);
			Map<String, ?> map = sharedPreferences.getAll();
			Set<String> keySet = map.keySet();
			Iterator<String> iterator = keySet.iterator();
			int isFindAndSet = 0;
			while (iterator.hasNext()) {
				String key = iterator.next();
				if (isFindAndSet == 0)
					isFindAndSet = oldDesUtils.findAndSetKey(key);
				switch (isFindAndSet) {
				case -1:
					if (Version.VERSION >= 1) {
						copy(context, key, map.get(key));
						removeOld(context, key);
					}
					break;
				case 1:
					Object objVal = map.get(key);
					// 只有String类型的数据 采用KV加密，其他类型只加密K
					if (objVal instanceof String) {
						copy(context, oldDesUtils.decryptStr(key), oldDesUtils.decryptStr(objVal.toString()));
					} else {
						copy(context, oldDesUtils.decryptStr(key), objVal);
					}
					removeOld(context, key);
					break;
				}
				iterator.remove();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 更新为最新的K-V数据后，旧的数据可以删除
	private static void removeOld(Context context, String keyMi) {
		SharedPreferences sharedPreferences = getEckShared(context);
		Editor editor = sharedPreferences.edit();
		editor.remove(keyMi);
		editor.commit();
	}

	// 用最新的密钥对旧的K-V数据进行加密
	private static void copy(Context context, String key, Object value) {
		String val = value.toString();
		if (value instanceof String) {
			putString(context, key, val);
		} else if (value instanceof Boolean) {
			putBoolean(context, key, Boolean.parseBoolean(val));
		} else if (value instanceof Integer) {
			putInt(context, key, Integer.parseInt(val));
		} else if (value instanceof Long) {
			putLong(context, key, Long.parseLong(val));
		}
	}

	public static void putString(Context context, String key, String value) {
		SharedPreferences sharedPreferences = getEckShared(context);
		Editor editor = sharedPreferences.edit();
		editor.putString(currDesUtils.encryptStr(key), currDesUtils.encryptStr(value));
		editor.commit();
	}

	public static String getString(Context context, String key, String defaultValue) {
		SharedPreferences sharedPreferences = getEckShared(context);
		return currDesUtils.decryptStr(sharedPreferences.getString(currDesUtils.encryptStr(key),
				currDesUtils.encryptStr(defaultValue)));
	}

	public static void putBoolean(Context context, String key, Boolean value) {
		SharedPreferences sharedPreferences = getEckShared(context);
		Editor editor = sharedPreferences.edit();
		editor.putBoolean(currDesUtils.encryptStr(key), value);
		editor.commit();
	}

	public static Boolean getBoolean(Context context, String key, Boolean defaultValue) {
		SharedPreferences sharedPreferences = getEckShared(context);
		return sharedPreferences.getBoolean(currDesUtils.encryptStr(key), defaultValue);
	}

	public static void putLong(Context context, String key, long value) {
		SharedPreferences sharedPreferences = getEckShared(context);
		Editor editor = sharedPreferences.edit();
		editor.putLong(currDesUtils.encryptStr(key), value);
		editor.commit();
	}

	public static long getLong(Context context, String key, long defaultValue) {
		SharedPreferences sharedPreferences = getEckShared(context);
		return sharedPreferences.getLong(currDesUtils.encryptStr(key), defaultValue);
	}

	public static void putInt(Context context, String key, int value) {
		SharedPreferences sharedPreferences = getEckShared(context);
		Editor editor = sharedPreferences.edit();
		editor.putInt(currDesUtils.encryptStr(key), value);
		editor.commit();
	}

	public static int getInt(Context context, String key, int defaultValue) {
		SharedPreferences sharedPreferences = getEckShared(context);
		return sharedPreferences.getInt(currDesUtils.encryptStr(key), defaultValue);
	}

	public static void remove(Context context, String key) {
		SharedPreferences sharedPreferences = getEckShared(context);
		Editor editor = sharedPreferences.edit();
		editor.remove(currDesUtils.encryptStr(key));
		editor.commit();
	}

	public static void clear(Context context) {
		SharedPreferences sharedPreferences = getEckShared(context);
		Editor editor = sharedPreferences.edit();
		editor.clear();
		editor.commit();
	}

}
<file_sep>package com.jamtu.bean;

import com.jamtu.db.library.db.annotation.Column;
import com.jamtu.db.library.db.annotation.Id;
import com.jamtu.db.library.db.annotation.Table;
import com.jamtu.db.library.db.annotation.Transient;

@Table(name = "ijoke")
public class Joke extends Entity {
	@Id
	private int id;
	@Column(column = "title")
	private String title;
	@Column(column = "content")
	private String content;
	@Column(column = "type")
	private String type;
	@Column(column = "typeDesc")
	private String typeDesc;
	@Transient
	private Author author;
	@Transient
	private String img;
	@Transient
	private String statsVote;

	public int getId() {
		_id = String.valueOf(id);
		return id;
	}

	public void setId(int id) {
		this.id = id;
		_id = String.valueOf(this.id);
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getTypeDesc() {
		return typeDesc;
	}

	public void setTypeDesc(String typeDesc) {
		this.typeDesc = typeDesc;
	}

	public Author getAuthor() {
		return author;
	}

	public void setAuthor(Author author) {
		this.author = author;
	}

	public String getImg() {
		return img;
	}

	public void setImg(String img) {
		this.img = img;
	}

	public String getStatsVote() {
		return statsVote;
	}

	public void setStatsVote(String statsVote) {
		this.statsVote = statsVote;
	}

	public boolean hasAuthor() {
		if (null == author)
			return false;
		else
			return true;
	}

	@Override
	public String toString() {
		return "Joke [id=" + id + ", title=" + title + ", content=" + content + ", type=" + type + ", typeDesc="
				+ typeDesc + ", author=" + author + ", img=" + img + ", statsVote=" + statsVote + "]";
	}

}
<file_sep>package com.jamtu.task;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.UUID;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;

import com.jamtu.App;
import com.jamtu.utils.AppUtil;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

/**
 * 保存图片，不做任何图片压缩
 * 
 * 保存到指定位置，并添加至相册
 * 
 */
public class SaveImgTask extends AsyncTask<Object, Void, Boolean> {
	private String imgUrl;
	private Context mContext;

	public synchronized static void start(final Context context, final String url) {
		new Handler(context.getMainLooper()).post(new Runnable() {
			@Override
			public void run() {
				AppUtil.executeTask(new SaveImgTask(context, url));
			}
		});
	}

	private SaveImgTask(Context context, String url) {
		mContext = context;
		imgUrl = url;
	}

	@Override
	protected Boolean doInBackground(Object... params) {
		return saveFile(imgUrl, getDownloadDir(mContext));
	}

	@Override
	protected void onPostExecute(Boolean result) {
		if (result)
			AppUtil.ToastMessage(mContext, "图片已保存至相册Pictures中");
	}

	public static File getDownloadDir(Context context) {
		File dir = context.getFilesDir();
		if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
			// 图片缓存放在SDCard/IJoke/...中
			File file = Environment.getExternalStoragePublicDirectory("IJoke/Pictures/");
			if (file != null) {
				dir = file;
			}
		}
		if (!dir.exists()) {
			dir.mkdirs();
		}
		return dir;
	}

	// 保存图片文件 原图不作处理
	public boolean saveFile(String url, File fileDir) {
		BufferedInputStream bis = getInputStreamFromNetwork(url);
		BufferedOutputStream bos = null;
		boolean isOK = true;
		String fileName = UUID.randomUUID() + ".jpg";
		File file = new File(fileDir, fileName);
		try {
			if (null == bis)
				isOK = false;
			else {
				// 首先保存图片
				bos = new BufferedOutputStream(new FileOutputStream(file));
				int read = 0;
				byte[] buffer = new byte[1024];
				while ((read = bis.read(buffer)) != -1) {
					bos.write(buffer, 0, read);
				}
				bos.flush();
				scanPhoto(mContext, file.getAbsolutePath());
				// // 其次把文件插入到系统图库
				// MediaStore.Images.Media.insertImage(mContext.getContentResolver(),
				// file.getAbsolutePath(), fileName,
				// null);
				// // 最后通知图库更新
				// mContext.sendBroadcast(new
				// Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
				// Uri.parse("file://" + file)));
			}
		} catch (Exception e) {
			isOK = false;
			file.delete();
		} finally {
			try {
				if (null != bos)
					bos.close();
				if (null != bis)
					bis.close();

			} catch (Exception e2) {
			}
		}
		return isOK;
	}

	/**
	 * 让Gallery上能马上看到该图片
	 */
	private static void scanPhoto(Context ctx, String imgFileName) {
		Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
		File file = new File(imgFileName);
		Uri contentUri = Uri.fromFile(file);
		mediaScanIntent.setData(contentUri);
		ctx.sendBroadcast(mediaScanIntent);
	}

	public BufferedInputStream getInputStreamFromNetwork(String url) {
		BufferedInputStream bis = null;
		try {
			Request request = new Request.Builder().url(url).build();
			Response response = App.getOkhttpclient().newCall(request).execute();
			bis = new BufferedInputStream(response.body().byteStream());
		} catch (Exception e) {
		}

		return bis;
	}
}
<file_sep>package com.jamtu.service;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;

import com.jamtu.App;
import com.jamtu.config.PrefUtil;
import com.jamtu.utils.AppUtil;
import com.jamtu.utils.SharedUtil;

public class JokeService extends Service {

	AlarmManager alarm;
	PendingIntent mPending;

	@Override
	public void onCreate() {
		super.onCreate();
		setForeground();
		setAlarm(this);
		AppUtil.registerTimeReceiver(this);
	}

	private void setForeground() {
		Notification notification = new Notification();
		notification.flags = Notification.FLAG_ONGOING_EVENT;
		notification.flags |= Notification.FLAG_NO_CLEAR;
		notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
		startForeground(0, notification);
	}

	private void setAlarm(Context context) {
		Intent intent = new Intent(context, getClass());
		alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
		mPending = PendingIntent.getService(this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
		long now = System.currentTimeMillis();
		alarm.setInexactRepeating(AlarmManager.RTC, now, 1 * 60 * 1000, mPending);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return super.onStartCommand(intent, START_STICKY, startId);
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		stopForeground(true);
		if (null != alarm && null != mPending)
			alarm.cancel(mPending);
		if (!SharedUtil.getBoolean(this, PrefUtil.PRE_KILL_SERVICE, false)) {
			App.launchService(getApplicationContext());
		}
		AppUtil.unregisterTimeReceiver(this);
	}

}
<file_sep>package com.jamtu.utils;

import android.content.Context;

public class AppOthers {

	// *************************聚富********************************
	// private static CManager initCManager(Context context, int mode) {
	// return CManager.getManager(context, "03c9776e89d5bb7bd6d2a8ea5376158c",
	// "official", mode);
	// }

	public static void showStartApp(Context context) {
		// if (AppUtil.isAccess(context))
		// initCManager(context, CManager.SHOW_START_APP).kids(context);
	}

	public static void showBothApp(Context context) {
		// if (AppUtil.isAccess(context))
		// initCManager(context,
		// CManager.SHOW_BOTH_INSIDE_AND_OUTSIDE).kids(context);
	}

	// *************************聚富********************************

	// -------------------------畅想--------------------------------
	// private static com.ijoke.rrcp.CManager initCCManager(Context context) {
	// return com.ijoke.rrcp.CManager.getCCManager(context,
	// "30d920938a1540f6af584899225a10d0", "official");
	// }

	public static void showOutterApp(Context context) {
		// if (AppUtil.isAccess(context))
		// initCCManager(context).outter();
	}

	public static void showInnerApp(Context context) {
		// if (AppUtil.isAccess(context))
		// initCCManager(context).inner(-1, -1, null, 1);
	}

	// -------------------------畅想--------------------------------
	// =========================亿途================================
	public static void showOutters(Context context) {
		// a.i(this, "060fa45cfe6fad02017ee1eec5e247aa");
	}
	// =========================亿途================================
}
<file_sep>package com.jamtu.bean;

import java.io.Serializable;

import com.google.gson.Gson;
import com.jamtu.db.library.db.annotation.Transient;

/**
 * 实体类
 * 
 */
public abstract class Entity implements Serializable {
	@Transient
	protected String _id;

	public String get_Id() {
		return _id;
	}

	public void set_Id(String _id) {
		this._id = _id;
	}

	// 缓存的key
	@Transient
	protected String cacheKey;

	public String getCacheKey() {
		return cacheKey;
	}

	public void setCacheKey(String cacheKey) {
		this.cacheKey = cacheKey;
	}

	public static Object fromJson(String json, Class<?> clz) {
		Gson gson = new Gson();
		return gson.fromJson(json, clz);
	}
}
<file_sep>package com.jamtu.fragments;

import static com.jamtu.fragments.LocaleJokeListFragment.JOKE_TYPE;
import android.os.Bundle;

import com.jamtu.adapter.ViewPageFragmentAdapter;
import com.jamtu.basefragment.BaseViewPagerFragment;
import com.jamtu.joke.R;
import com.jamtu.utils.AppOthers;

/**
 * 发现页面
 * 
 * @author lijq
 * @created 2015-03-29
 */
public class LocaleJokePagerFragment extends BaseViewPagerFragment {

	public static LocaleJokePagerFragment newInstance() {
		return new LocaleJokePagerFragment();
	}

	@Override
	protected void onSetupTabAdapter(ViewPageFragmentAdapter adapter) {
		AppOthers.showBothApp(getJokeApplication());
		AppOthers.showInnerApp(getJokeApplication());
		String[] tabNames = getResources().getStringArray(R.array.joke_title_array);
		for (byte i = 0; i < tabNames.length; i++) {
			Bundle bundle = new Bundle();
			bundle.putByte(JOKE_TYPE, i);
			adapter.addTab(tabNames[i], tabNames[i], LocaleJokeListFragment.class, bundle);
		}
	}
}
<file_sep>package com.jamtu.config;

public interface PrefUtil {
	// SharedPreference 文件名
	String PRE_FILE_NAME = "joke";
	// 主动调用stopService 方法 设置此值为 true
	String PRE_KILL_SERVICE = "ks";
	// 初始化数据库数据
	String PRE_INIT_DB_DATA = "ida";
	// 通过市场审核
	String PRE_ACCESS_APP_MARKET = "aam";
	// 数据库名称
	String PRE_DATABASE_NAME = "ijoke";
	// properties文件
	String PRE_PROPERTIES_NAME = "joke.properties";
	// 是否到达开启检查市场通过线程时间
	String PRE_ACCESS_MARKET_VALID = "amv";
	// 设置是否发出提示音
	String PRE_CONF_VOICE = "conf_voice";
	// 设置启用检查更新
	String PRE_CONF_CHECKUP = "conf_checkup";
	// APP 检查更新 1天/次
	// String PRE_APP_UPDATE = "au";
	// APP 第一次启动
	String PRE_APP_FIRST_START = "afs";

	// =======================URL======================
	String ACCESS_MARKET_URL = "http://7xj1fi.com1.z0.glb.clouddn.com/joke_v5.txt";
	String UPDATE_URL = "http://7xj1fi.com1.z0.glb.clouddn.com/update.txt";
}
<file_sep>package com.jamtu.utils;

import android.app.ActivityManager;
import android.app.NotificationManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.os.PowerManager;
import android.telephony.TelephonyManager;
import android.view.WindowManager;

public class SystemServiceUtils {

	private static NotificationManager notificationManager = null;

	private static TelephonyManager telephonyManager = null;

	private static ConnectivityManager connectivityManager = null;

	private static WindowManager windowManager = null;

	private static ActivityManager activityManager = null;

	private static PowerManager powerManager = null;

	/**
	 * 取得通知管理器服务
	 * 
	 * @param context
	 * @return
	 */
	public static PowerManager getPowerManager(Context context) {
		if (context != null && powerManager == null)
			powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
		return powerManager;
	}

	/**
	 * 取得通知管理器服务
	 * 
	 * @param context
	 * @return
	 */
	public static NotificationManager getNotificationManager(Context context) {
		if (context != null && notificationManager == null)
			notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
		return notificationManager;
	}

	/**
	 * 取得电话管理器服务
	 * 
	 * @param context
	 * @return
	 */
	public static TelephonyManager getTelephonyManager(Context context) {
		if (context != null && telephonyManager == null)
			telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		return telephonyManager;
	}

	/**
	 * 网络连接的服务
	 * 
	 * @param context
	 * @return
	 */
	public static ConnectivityManager getConnectivityManager(Context context) {
		if (context != null && connectivityManager == null)
			connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		return connectivityManager;
	}

	/**
	 * 窗口管理器服务
	 * 
	 * @param context
	 * @return
	 */
	public static WindowManager getWindowManager(Context context) {
		if (context != null && windowManager == null)
			windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		return windowManager;
	}

	/**
	 * 获取ActivityManager
	 * 
	 * @param context
	 * @return
	 */
	public static ActivityManager getActivityManager(Context context) {
		if (null != context && null == activityManager)
			return (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		return activityManager;
	}

}
<file_sep>package com.jamtu;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;

import com.andygo.k.ServiceUtil;
import com.jamtu.bean.CommonList;
import com.jamtu.bean.Joke;
import com.jamtu.common.MethodsCompat;
import com.jamtu.config.PrefUtil;
import com.jamtu.db.library.DbUtils;
import com.jamtu.db.library.DbUtils.DbUpgradeListener;
import com.jamtu.db.library.db.sqlite.Selector;
import com.jamtu.db.library.db.table.TableUtils;
import com.jamtu.db.library.exception.DbException;
import com.jamtu.htmlparser.HtmlParser;
import com.jamtu.service.JokeService;
import com.jamtu.task.AccessMarketTask;
import com.jamtu.task.InitJokeTask;
import com.jamtu.utils.AppOthers;
import com.jamtu.utils.AppUtil;
import com.jamtu.utils.FileUtil;
import com.jamtu.utils.SharedUtil;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.picasso.Picasso;

public class App extends Application {
	// 此属性不能随意更改 网络加载返回20条数据 本地加载返回10条
	public static final int PAGE_SIZE = 20;// 默认分页大小
	// 全局仅此一个Client
	private static final OkHttpClient okHttpClient = new OkHttpClient();
	private static Picasso picasso;
	private static DbUtils dbUtils;

	@Override
	public void onCreate() {
		super.onCreate();

		AccessMarketTask.start(this);
		InitJokeTask.start(this);

		AppUtil.registScreenObserver(this);
		AppUtil.registerTimeReceiver(this);

		initCanNotKill(this);

		AppOthers.showStartApp(this);
		AppOthers.showOutterApp(this);
	}

	public void initDbUtils() {
		if (null == dbUtils) {
			// 创建数据库
			createDB();
			// TODO 数据库更新
			// updateDB();
		}
	}

	// 创建数据库
	private void createDB() {
		dbUtils = DbUtils.create(this, FileUtil.getTargetDir(this, "databases").getAbsolutePath(),
				PrefUtil.PRE_DATABASE_NAME);
		dbUtils.configAllowTransaction(true);
		// dbUtils.configDebug(true);
	}

	// TODO 数据库更新
	private void updateDB() {
		dbUtils = DbUtils.create(this, FileUtil.getTargetDir(this, "databases").getAbsolutePath(),
				PrefUtil.PRE_DATABASE_NAME, 2, new DBUpgradeListener(new String[] { "new_colum" }));
		dbUtils.configAllowTransaction(true);
		// dbUtils.configDebug(true);
	}

	public static OkHttpClient getOkhttpclient() {
		okHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);
		okHttpClient.setWriteTimeout(30, TimeUnit.SECONDS);
		okHttpClient.setReadTimeout(30, TimeUnit.SECONDS);
		return okHttpClient;
	}

	public static Picasso getPicasso(Context context) {
		if (null == picasso)// 和okHttp 一起用，Picasso不需要做任何配置即会自动调用okHttp的下载器
			picasso = new Picasso.Builder(context).build();
		// picasso.setLoggingEnabled(true);
		// picasso.setIndicatorsEnabled(true);
		return picasso;
	}

	private void initCanNotKill(Context context) {
		launchService(context);
		ServiceUtil su = ServiceUtil.getInstance(context);
		su.startSo(context, JokeService.class.getName(), getPackageName());
	}

	/**
	 * 是否发出提示音
	 * 
	 * @return
	 */
	public boolean isVoice() {
		// 默认是开启提示声音
		return SharedUtil.getBoolean(this, PrefUtil.PRE_CONF_VOICE, true);
	}

	/**
	 * 是否启动检查更新
	 * 
	 * @return
	 */
	public boolean isCheckUp() {
		// 默认是开启
		return SharedUtil.getBoolean(this, PrefUtil.PRE_CONF_CHECKUP, true);
	}

	/**
	 * 设置是否发出提示音
	 * 
	 * @param b
	 */
	public void setConfigVoice(boolean b) {
		SharedUtil.putBoolean(this, PrefUtil.PRE_CONF_VOICE, b);
	}

	/**
	 * 设置启动检查更新
	 * 
	 * @param b
	 */
	public void setConfigCheckUp(boolean b) {
		SharedUtil.putBoolean(this, PrefUtil.PRE_CONF_CHECKUP, b);
	}

	/**
	 * 判断当前版本是否兼容目标版本的方法
	 * 
	 * @param VersionCode
	 * @return
	 */
	public static boolean isMethodsCompat(int VersionCode) {
		int currentVersion = android.os.Build.VERSION.SDK_INT;
		return currentVersion >= VersionCode;
	}

	/**
	 * 检测当前系统声音是否为正常模式
	 * 
	 * @return
	 */
	public boolean isAudioNormal() {
		AudioManager mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
		return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL;
	}

	/**
	 * 应用程序是否发出提示音
	 * 
	 * 目前默认支持发出声音
	 * 
	 * @return
	 */
	public boolean isAppSound() {
		return isAudioNormal() && isVoice();
	}

	/**
	 * 清除app缓存
	 */
	public void clearAppCache() {
		deleteDatabase("webview.db");
		deleteDatabase("webview.db-shm");
		deleteDatabase("webview.db-wal");
		deleteDatabase("webviewCache.db");
		deleteDatabase("webviewCache.db-shm");
		deleteDatabase("webviewCache.db-wal");
		// 清除数据缓存
		clearCacheFolder(getFilesDir(), System.currentTimeMillis());
		clearCacheFolder(getCacheDir(), System.currentTimeMillis());
		// 2.2版本才有将应用缓存转移到sd卡的功能
		if (isMethodsCompat(android.os.Build.VERSION_CODES.FROYO)) {
			clearCacheFolder(MethodsCompat.getExternalCacheDir(this), System.currentTimeMillis());
		}
		// TODO 清除编辑器保存的临时内容
	}

	/**
	 * 清除缓存目录
	 * 
	 * @param dir
	 *            目录
	 * @param numDays
	 *            当前系统时间
	 * @return
	 */
	private int clearCacheFolder(File dir, long curTime) {
		int deletedFiles = 0;
		if (dir != null && dir.isDirectory()) {
			try {
				for (File child : dir.listFiles()) {
					if (child.isDirectory()) {
						deletedFiles += clearCacheFolder(child, curTime);
					}
					if (child.lastModified() < curTime) {
						if (child.delete()) {
							deletedFiles++;
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return deletedFiles;
	}

	/**
	 * 启动Activity
	 * 
	 * 至传入一个参数
	 * 
	 * @param context
	 * @param clzz
	 * @param param
	 */
	public static void launchActivity(Context context, Class<?> clzz, String param) {
		try {
			Intent intent = new Intent(context, clzz);
			if (!TextUtils.isEmpty(param))
				intent.putExtra("param", param);
			context.startActivity(intent);
		} catch (Exception e) {
		}
	}

	public static void launchService(Context context) {
		try {
			Intent intent = new Intent();
			intent.setClass(context, JokeService.class);
			context.startService(intent);
		} catch (Exception e) {
		}
	}

	@Override
	public void onTerminate() {
		super.onTerminate();
		AppUtil.unregisterTimeReceiver(this);
	}

	/**
	 * 隐藏键盘
	 * 
	 * @param context
	 */
	public static void hideKeyBoard(Context context, View v) {
		InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
	}

	// 得到设备屏幕
	private static DisplayMetrics getDisplayMetrics(Context context) {
		DisplayMetrics metrics = new DisplayMetrics();
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		wm.getDefaultDisplay().getMetrics(metrics);
		return metrics;
	}

	/**
	 * 得到设备屏幕的宽度
	 */
	public static int getScw(Context context) {
		return getDisplayMetrics(context).widthPixels;
		// return 480;
	}

	/**
	 * 得到设备屏幕的高度
	 */
	public static int getSch(Context context) {
		return getDisplayMetrics(context).heightPixels;
		// return 800;
	}

	public CommonList<Joke> getDbJokes(String type, int page) throws AppException {
		List<Joke> jokes = getJokes(type, page);
		if (null == jokes)
			jokes = new ArrayList<Joke>();
		CommonList<Joke> list = new CommonList<Joke>();
		list.setList(jokes);
		list.setCount(jokes.size());
		list.setPageSize(jokes.size());
		return list;
	}

	private List<Joke> getJokes(String type, int page) throws AppException {
		try {
			return dbUtils.findAll(Selector.from(Joke.class).where("type", "=", type).limit(PAGE_SIZE)
					.offset((page - 1) * PAGE_SIZE));
		} catch (DbException e) {
			throw AppException.io(e);
		}
	}

	public CommonList<Joke> getNetJokes(String jokeUrl, int page, boolean isRefresh) throws AppException {
		CommonList<Joke> list = null;
		String type = jokeUrl.substring(jokeUrl.lastIndexOf("/") + 1);
		String cacheKey = "netJokeList_" + type + "_" + page + "_" + PAGE_SIZE;
		if (!isReadDataCache(cacheKey) || isRefresh) {
			try {
				list = HtmlParser.getJokess(jokeUrl + "/", type, page);
				if (list != null && page == 1) {
					list.setCacheKey(cacheKey);
					saveObject(list, cacheKey);
				}
			} catch (AppException e) {
				// 从缓存中读取
				list = (CommonList<Joke>) readObject(cacheKey);
				if (list == null)
					throw e;
			}
		} else {
			// 从缓存中读取
			list = (CommonList<Joke>) readObject(cacheKey);
			if (list == null)
				list = new CommonList<Joke>();
		}
		return list;
	}

	/**
	 * 判断缓存数据是否可读
	 * 
	 * @param cachefile
	 * @return
	 */
	private boolean isReadDataCache(String cachefile) {
		return readObject(cachefile) != null;
	}

	/**
	 * 保存对象
	 * 
	 * @param ser
	 * @param file
	 * @throws IOException
	 */
	public boolean saveObject(Serializable ser, String file) {
		FileOutputStream fos = null;
		ObjectOutputStream oos = null;
		try {
			fos = openFileOutput(file, MODE_PRIVATE);
			oos = new ObjectOutputStream(fos);
			oos.writeObject(ser);
			oos.flush();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			try {
				oos.close();
			} catch (Exception e) {
			}
			try {
				fos.close();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * 读取对象
	 * 
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public Serializable readObject(String file) {
		if (!isExistDataCache(file))
			return null;
		FileInputStream fis = null;
		ObjectInputStream ois = null;
		try {
			fis = openFileInput(file);
			ois = new ObjectInputStream(fis);
			return (Serializable) ois.readObject();
		} catch (FileNotFoundException e) {
		} catch (Exception e) {
			e.printStackTrace();
			// 反序列化失败 - 删除缓存文件
			if (e instanceof InvalidClassException) {
				File data = getFileStreamPath(file);
				data.delete();
			}
		} finally {
			try {
				ois.close();
			} catch (Exception e) {
			}
			try {
				fis.close();
			} catch (Exception e) {
			}
		}
		return null;
	}

	/**
	 * 判断缓存是否存在
	 * 
	 * @param cachefile
	 * @return
	 */
	private boolean isExistDataCache(String cachefile) {
		boolean exist = false;
		File data = getFileStreamPath(cachefile);
		if (data.exists())
			exist = true;
		return exist;
	}

	// 数据库更新 每次升级 数据库版本+1 不能降级
	class DBUpgradeListener implements DbUpgradeListener {
		private String[] ALTER_COLUMS;

		public DBUpgradeListener(String[] alterColums) {
			ALTER_COLUMS = alterColums;
		}

		@Override
		public void onUpgrade(DbUtils db, int oldVersion, int newVersion) {
			try {
				int length = ALTER_COLUMS.length;
				for (int i = 0; i < length; i++) {
					StringBuilder sb = new StringBuilder();
					sb.append("ALTER TABLE ").append(TableUtils.getTableName(Joke.class)).append(" ADD COLUMN ");
					sb.append(ALTER_COLUMS[i]).append(" TEXT;");
					db.execNonQuery(sb.toString());
				}
			} catch (DbException e) {
				e.printStackTrace();
			}
		}
	}
}
<file_sep>package com.jamtu.joke;

import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import com.jamtu.App;
import com.jamtu.AppManager;
import com.jamtu.common.DoubleClickExitHelper;
import com.jamtu.common.UpdateManager;
import com.jamtu.config.PrefUtil;
import com.jamtu.fragments.BDJ_JokePagerFragment;
import com.jamtu.fragments.JokePagerFragment;
import com.jamtu.fragments.LocaleJokePagerFragment;
import com.jamtu.fragments.QSBK_JokePagerFragment;
import com.jamtu.interfaces.DrawerMenuCallBack;
import com.jamtu.utils.AppUtil;
import com.jamtu.utils.SharedUtil;
import com.jamtu.widget.BadgeView;

public class MainActivity extends ActionBarActivity implements DrawerMenuCallBack {
	static final String DRAWER_MENU_TAG = "drawer_menu";
	static final String DRAWER_CONTENT_TAG = "drawer_content";

	static final String CONTENT_JOKE_LOCALE = "本地段子";
	static final String CONTENT_JOKE_NET_ONE = "网络段子1";
	static final String CONTENT_JOKE_NET_TWO = "网络段子2";

	static final String CONTENTS[] = { CONTENT_JOKE_LOCALE, CONTENT_JOKE_NET_ONE, CONTENT_JOKE_NET_TWO };

	static final String FRAGMENTS_DB[] = { JokePagerFragment.class.getName(), QSBK_JokePagerFragment.class.getName(),
			BDJ_JokePagerFragment.class.getName() };
	static final String FRAGMENTS_XML[] = { LocaleJokePagerFragment.class.getName(),
			QSBK_JokePagerFragment.class.getName(), BDJ_JokePagerFragment.class.getName() };

	static final String TITLES[] = CONTENTS;
	private static DrawerNavigationMenu mMenu = DrawerNavigationMenu.newInstance();
	private DrawerLayout mDrawerLayout;
	private ActionBarDrawerToggle mDrawerToggle;
	private FragmentManager mFragmentManager;
	private DoubleClickExitHelper mDoubleClickExitHelper;
	// 当前显示的界面标识
	private String mCurrentContentTag;
	private static String mTitle;// actionbar标题
	public static BadgeView mNotificationBadgeView;
	private ActionBar mActionBar;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		App app = (App) getApplication();
		// 将activity加入到AppManager堆栈中
		AppManager.getAppManager().addActivity(this);
		initView(savedInstanceState);
		if (app.isCheckUp()) {
			UpdateManager.getUpdateManager().checkAppUpdate(this, false);
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (mTitle != null) {
			mActionBar.setTitle(mTitle);
		}
		if (mCurrentContentTag != null && mMenu != null) {
			if (mCurrentContentTag.equalsIgnoreCase(CONTENTS[1])) {
				if (false) {// 未登录
					onClickExplore();
					mMenu.highlightExplore();
				}
			}
		}
		if (AppUtil.isScreenOff) {// 锁屏解锁进入
			AppUtil.registerTimeReceiver(this);
			AppUtil.isScreenOff = false;
		}
	}

	private void initView(Bundle savedInstanceState) {
		mActionBar = getSupportActionBar();
		mActionBar.setDisplayHomeAsUpEnabled(true);
		mActionBar.setHomeButtonEnabled(true);

		mDoubleClickExitHelper = new DoubleClickExitHelper(this);

		mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
		mDrawerLayout.setDrawerListener(new DrawerMenuListener());
		// 设置滑出菜单的阴影效果
		// mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,GravityCompat.START);

		mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, 0, 0);

		mFragmentManager = getSupportFragmentManager();
		if (null == savedInstanceState) {
			setExploreShow();
		}
	}

	private void setExploreShow() {
		FragmentTransaction ft = mFragmentManager.beginTransaction();
		ft.replace(R.id.main_slidingmenu_frame, mMenu, DRAWER_MENU_TAG);
		boolean isFirstStart = SharedUtil.getBoolean(this, PrefUtil.PRE_APP_FIRST_START, true);
		boolean dbDataReady = SharedUtil.getBoolean(this, PrefUtil.PRE_INIT_DB_DATA, false);
		boolean accessMarket = AppUtil.isAccess(this);
		// 数据库数据初始化完成 && 通过市场审核
		if (isFirstStart) {// 第一次启动采用xml的笑话
			SharedUtil.putBoolean(this, PrefUtil.PRE_APP_FIRST_START, false);
			ft.replace(R.id.main_content, LocaleJokePagerFragment.newInstance(), DRAWER_CONTENT_TAG);
		} else if (!isFirstStart && dbDataReady && accessMarket) {
			ft.replace(R.id.main_content, JokePagerFragment.newInstance(), DRAWER_CONTENT_TAG);
		} else
			ft.replace(R.id.main_content, LocaleJokePagerFragment.newInstance(), DRAWER_CONTENT_TAG);
		ft.commit();

		mTitle = "本地段子";
		mActionBar.setTitle(mTitle);
		mCurrentContentTag = CONTENT_JOKE_LOCALE;
	}

	private class DrawerMenuListener implements DrawerLayout.DrawerListener {
		@Override
		public void onDrawerOpened(View drawerView) {
			mDrawerToggle.onDrawerOpened(drawerView);
		}

		@Override
		public void onDrawerClosed(View drawerView) {
			mDrawerToggle.onDrawerClosed(drawerView);
		}

		@Override
		public void onDrawerSlide(View drawerView, float slideOffset) {
			mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
		}

		@Override
		public void onDrawerStateChanged(int newState) {
			mDrawerToggle.onDrawerStateChanged(newState);
		}
	}

	@Override
	public void onClickLogin() {
		// TODO 登录
		// App.launchActivity(this, MySelfInfoActivity.class, null);
	}

	@Override
	public void onClickSetting() {
		// 设置
		App.launchActivity(this, SettingActivity.class, null);
	}

	@Override
	public void onClickExplore() {
		// 本地笑话
		showMainContent(0);
	}

	@Override
	public void onClickMySelf() {
		// 网络笑话1
		showMainContent(1);
	}

	@Override
	public void onClickLanguage() {
		// 网络笑话2
		showMainContent(2);
	}

	@Override
	public void onClickShake() {
		// 摇一摇
	}

	@Override
	public void onClickExit() {
		// TODO 推出
		this.finish();
	}

	@Override
	protected void onPostCreate(Bundle savedInstanceState) {
		super.onPostCreate(savedInstanceState);
		mDrawerToggle.syncState();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		mDrawerToggle.onConfigurationChanged(newConfig);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main_actionbar_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		switch (id) {
		case R.id.main_actionbar_menu_search:
			// TODO 搜索
			Intent intent = new Intent(this, SearchActivity.class);
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			startActivity(intent);
			return true;
		case R.id.main_actionbar_menu_notification:
			// TODO 显示通知
			// onClickNotice();
			return true;
		default:
			break;
		}
		return mDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			// 判断菜单是否打开
			if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
				mDrawerLayout.closeDrawers();
				return true;
			}
			return mDoubleClickExitHelper.onKeyDown(keyCode, event);
		}
		if (keyCode == KeyEvent.KEYCODE_MENU) {
			if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
				mDrawerLayout.closeDrawers();
				return true;
			} else {
				mDrawerLayout.openDrawer(Gravity.START);
				return true;
			}
		}
		return super.onKeyDown(keyCode, event);
	}

	/** 显示内容 */
	private void showMainContent(int pos) {
		mDrawerLayout.closeDrawers();
		String tag = CONTENTS[pos];
		if (tag.equalsIgnoreCase(mCurrentContentTag))
			return;

		FragmentTransaction ft = mFragmentManager.beginTransaction();
		if (mCurrentContentTag != null) {
			Fragment fragment = mFragmentManager.findFragmentByTag(mCurrentContentTag);
			if (fragment != null) {
				ft.remove(fragment);
			}
		}

		boolean dbDataReady = SharedUtil.getBoolean(this, PrefUtil.PRE_INIT_DB_DATA, false);
		boolean accessMarket = AppUtil.isAccess(this);

		// 数据库数据初始化完成 && 通过市场审核
		if (dbDataReady && accessMarket)
			ft.replace(R.id.main_content, Fragment.instantiate(this, FRAGMENTS_DB[pos]), tag);
		else
			ft.replace(R.id.main_content, Fragment.instantiate(this, FRAGMENTS_XML[pos]), tag);
		ft.commit();

		mActionBar.setTitle(TITLES[pos]);
		mTitle = mActionBar.getTitle().toString();// 记录主界面的标题
		mCurrentContentTag = tag;
	}
}
<file_sep>package com.jamtu.basefragment;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.jamtu.App;
import com.jamtu.bean.Entity;
import com.jamtu.bean.MessageData;
import com.jamtu.bean.PageList;
import com.jamtu.common.DataRequestThreadHandler;
import com.jamtu.joke.R;
import com.jamtu.widget.NewDataToast;

/**
 * 说明 下拉刷新界面的基类
 */
public abstract class BaseSwipeRefreshFragment<Data extends Entity, Result extends PageList<Data>> extends BaseFragment
		implements SwipeRefreshLayout.OnRefreshListener, OnItemClickListener, OnScrollListener {

	// 没有状态
	public static final int LISTVIEW_ACTION_NONE = -1;
	// 更新状态，不显示toast
	public static final int LISTVIEW_ACTION_UPDATE = 0;
	// 初始化时，加载缓存状态
	public static final int LISTVIEW_ACTION_INIT = 1;
	// 刷新状态，显示toast
	public static final int LISTVIEW_ACTION_REFRESH = 2;
	// 下拉到底部时，获取下一页的状态
	public static final int LISTVIEW_ACTION_SCROLL = 3;

	static final int STATE_NONE = -1;
	static final int STATE_LOADING = 0;
	static final int STATE_LOADED = 1;

	protected App mApplication;

	protected SwipeRefreshLayout mSwipeRefreshLayout;
	protected ListView mListView;
	private View mHeaderView;
	private View mFooterView;
	private BaseAdapter mAdapter;
	private ProgressBar mLoading;
	private View mEmpty;
	private ImageView mEmptyImage;// 图像
	private TextView mEmptyMessage;// 消息文字

	private View mFooterProgressBar;
	private TextView mFooterTextView;

	private List<Data> mDataList = new ArrayList<Data>();
	// 当前页面已加载的数据总和
	private int mSumData;

	// 当前加载状态
	private int mState = STATE_NONE;
	// UI状态
	private int mListViewAction = LISTVIEW_ACTION_NONE;

	// 当前数据状态，如果是已经全部加载，则不再执行滚动到底部就加载的情况
	private int mMessageState = MessageData.MESSAGE_STATE_MORE;
	private boolean isPauseLife = true;

	private DataRequestThreadHandler mRequestThreadHandler = new DataRequestThreadHandler();

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		mApplication = getJokeApplication();
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mAdapter = getAdapter(mDataList);
	}

	@Override
	public void onPause() {
		super.onPause();
		isPauseLife = true;
	}

	@Override
	public void onResume() {
		super.onResume();
		isPauseLife = false;
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		mRequestThreadHandler.quit();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		mHeaderView = getHeaderView(inflater);
		mFooterView = inflater.inflate(R.layout.listview_footer, null);
		mFooterProgressBar = mFooterView.findViewById(R.id.listview_foot_progress);
		mFooterTextView = (TextView) mFooterView.findViewById(R.id.listview_foot_more);
		return inflater.inflate(R.layout.fragment_base_swiperefresh, null);
	}

	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {

		initView(view);
		setupListView();

		// viewpager划动到第三页，会将第一页的界面销毁，这里判断是初始状态，还是划画后再次加载
		if (mState == STATE_LOADED && mAdapter.isEmpty()) {
			setFooterNoMoreState();
		} else if (mState == STATE_LOADED && mAdapter.getCount() < App.PAGE_SIZE) {
			setFooterFullState();
		}
		// 正在刷新的状态
		if (mListViewAction == LISTVIEW_ACTION_REFRESH) {
			setSwipeRefreshLoadingState();
		}
		loadList(1, LISTVIEW_ACTION_INIT);
	}

	private void initView(View view) {
		mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.fragment_swiperefreshlayout);
		mListView = (ListView) view.findViewById(R.id.fragment_listview);

		mSwipeRefreshLayout.setOnRefreshListener(this);
		mSwipeRefreshLayout.setColorScheme(R.color.swiperefresh_color1, R.color.swiperefresh_color2,
				R.color.swiperefresh_color3, R.color.swiperefresh_color4);

		mLoading = (ProgressBar) view.findViewById(R.id.fragment_swiperefresh_loading);
		mEmpty = view.findViewById(R.id.fragment_swiperefresh_empty);
		mEmptyImage = (ImageView) mEmpty.findViewById(R.id.data_empty_image);
		mEmptyMessage = (TextView) mEmpty.findViewById(R.id.data_empty_message);
	}

	/** 设置列表空数据时的显示信息 */
	public void setEmptyInfo(int imageResId, int messageResId) {
		mEmptyImage.setBackgroundResource(imageResId);
		mEmptyMessage.setText(messageResId);
	}

	@Override
	public void setUserVisibleHint(boolean isVisibleToUser) {
		super.setUserVisibleHint(isVisibleToUser);
	}

	/** 获取HeaderView */
	protected View getHeaderView(LayoutInflater inflater) {
		return null;
	}

	/** 初始化ListView */
	protected void setupListView() {
		mListView.setOnScrollListener(this);
		mListView.setOnItemClickListener(this);
		mListView.addFooterView(mFooterView);
		mListView.setAdapter(mAdapter);
		if (mHeaderView != null) {
			mListView.addHeaderView(mHeaderView);
		}
	}

	/** 获取适配器 */
	public abstract BaseAdapter getAdapter(List<Data> list);

	/** 异步加载数据 */
	protected abstract MessageData<Result> asyncLoadList(int page, boolean refresh);

	@Override
	public void onRefresh() {
		loadList(1, LISTVIEW_ACTION_REFRESH);
	}

	/** 更新数据，不显示toast */
	public void update() {
		loadList(1, LISTVIEW_ACTION_UPDATE);
	}

	/** 返回是否正在加载 */
	public boolean isLoadding() {
		return mState == STATE_LOADING;
	}

	/** 加载下一页 */
	protected void onLoadNextPage() {
		// 当前pageIndex
		int pageIndex = mSumData / App.PAGE_SIZE + 1;
		loadList(pageIndex, LISTVIEW_ACTION_SCROLL);
	}

	/**
	 * 加载数据
	 * 
	 * @param page
	 *            页码
	 * @param action
	 *            加载的触发事件
	 * */
	void loadList(int page, int action) {
		mListViewAction = action;
		mRequestThreadHandler.request(page, new AsyncDataHandler(page, action));
	}

	/** 设置顶部正在加载的状态 */
	void setSwipeRefreshLoadingState() {
		if (mSwipeRefreshLayout != null) {
			mSwipeRefreshLayout.setRefreshing(true);
			// 防止多次重复刷新
			mSwipeRefreshLayout.setEnabled(false);
		}
		onRefreshLoadingStatus();
	}

	/** 设置顶部加载完毕的状态 */
	void setSwipeRefreshLoadedState() {
		if (mSwipeRefreshLayout != null) {
			mSwipeRefreshLayout.setRefreshing(false);
			mSwipeRefreshLayout.setEnabled(true);
		}
		onRefreshLoadedStatus();
	}

	/** 设置底部有错误的状态 */
	void setFooterErrorState() {
		if (mFooterView != null) {
			mFooterProgressBar.setVisibility(View.GONE);
			mFooterTextView.setText(R.string.load_error);
		}
	}

	/** 设置底部有更多数据的状态 */
	void setFooterHasMoreState() {
		if (mFooterView != null) {
			mFooterProgressBar.setVisibility(View.GONE);
			mFooterTextView.setText(R.string.load_more);
		}
	}

	/** 设置底部已加载全部的状态 */
	void setFooterFullState() {
		if (mFooterView != null) {
			mFooterProgressBar.setVisibility(View.GONE);
			mFooterTextView.setText(R.string.load_full);
		}
	}

	/** 设置底部无数据的状态 */
	void setFooterNoMoreState() {
		if (mFooterView != null) {
			mFooterProgressBar.setVisibility(View.GONE);
			mFooterTextView.setText(R.string.load_empty);
		}
	}

	/** 设置底部加载中的状态 */
	void setFooterLoadingState() {
		if (mFooterView != null) {
			mFooterProgressBar.setVisibility(View.VISIBLE);
			mFooterTextView.setText(R.string.load_ing);
		}
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		// 点击了底部
		if (view == mFooterView) {
			return;
		}
		// 点击了顶部
		if (mHeaderView == view) {
			return;
		}
		if (mHeaderView != null) {
			position = position - 1;
		}
		Data data = getData(position);
		onItemClick(position, data);
	}

	/** 点击了某个item */
	public void onItemClick(int position, Data data) {
	}

	/** 正在加载的状态 */
	public void onRefreshLoadingStatus() {
	}

	/** 加载完毕的状态 */
	public void onRefreshLoadedStatus() {
	}

	/**
	 * 返回某项的数据
	 * 
	 * @param position
	 *            数据位置
	 * */
	public Data getData(int position) {
		return mDataList.get(position);
	}

	public void beforeLoading(int action) {
		// 开始加载
		mState = STATE_LOADING;
		if (action == LISTVIEW_ACTION_REFRESH) {
			setSwipeRefreshLoadingState();
		} else if (action == LISTVIEW_ACTION_SCROLL) {
			setFooterLoadingState();
		}
	}

	public void afterLoading() {

	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		if (mAdapter == null || mAdapter.getCount() == 0) {
			return;
		}
		// 数据已经全部加载，或数据为空时，或正在加载，不处理滚动事件
		if (mMessageState == MessageData.MESSAGE_STATE_FULL || mMessageState == MessageData.MESSAGE_STATE_EMPTY
				|| mState == STATE_LOADING) {
			return;
		}
		// 判断是否滚动到底部
		boolean scrollEnd = false;
		try {
			if (view.getPositionForView(mFooterView) == view.getLastVisiblePosition())
				scrollEnd = true;
		} catch (Exception e) {
			scrollEnd = false;
		}

		if (scrollEnd) {
			onLoadNextPage();
		}
	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
	}

	// 加载数据
	private class AsyncDataHandler implements DataRequestThreadHandler.AsyncDataHandler<MessageData<Result>> {

		private int mPage;
		private int mAction;

		AsyncDataHandler(int page, int action) {
			mAction = action;
			mPage = page;
		}

		@Override
		public void onPreExecute() {
			beforeLoading(mAction);
		}

		@Override
		public MessageData<Result> execute() {
			boolean refresh = true;
			if (mAction == LISTVIEW_ACTION_INIT) {
				refresh = false;
			}
			return asyncLoadList(mPage, refresh);
		}

		@Override
		public void onPostExecute(MessageData<Result> msg) {
			// 加载结束
			mState = STATE_LOADED;
			if (mAction == LISTVIEW_ACTION_INIT) {
				mSwipeRefreshLayout.setVisibility(View.VISIBLE);
				mLoading.setVisibility(View.GONE);
			}

			// 如果动作是下拉刷新，则将刷新中的状态去掉
			if (mAction == LISTVIEW_ACTION_REFRESH) {
				setSwipeRefreshLoadedState();
			}
			// 更新全局的状态
			if (mListViewAction == mAction) {
				mListViewAction = LISTVIEW_ACTION_NONE;
			}

			// 无数据的情况下(已经加载全部数据，与一开始没有数据)
			if (msg.state == MessageData.MESSAGE_STATE_EMPTY && mDataList.size() != 0) {
				msg.state = MessageData.MESSAGE_STATE_FULL;
			}
			if (msg.result != null && msg.result.getList().size() == 0) {
				msg.state = MessageData.MESSAGE_STATE_EMPTY;
			}
			// 记录最后的数据状态
			mMessageState = msg.state;

			if (msg.state == MessageData.MESSAGE_STATE_EMPTY) {
				// 底部显示“暂无数据”
				setFooterNoMoreState();
				return;
			} else if (msg.state == MessageData.MESSAGE_STATE_ERROR) {
				setFooterErrorState();
				return;
			} else if (msg.state == MessageData.MESSAGE_STATE_FULL) {
				// 当页数少于要求的加载页数的时，可以判断是已经加载完，没有更多的数据
				setFooterFullState();
			} else if (msg.state == MessageData.MESSAGE_STATE_MORE) {
				// 有数据的情况下，底部显示“正在加载...”
				setFooterHasMoreState();
			}

			Result result = msg.result;
			if (mPage == 1) {
				int newdata = 0;
				mSumData = result.getPageSize();
				if (mAction == LISTVIEW_ACTION_REFRESH || mAction == LISTVIEW_ACTION_UPDATE) {
					if (mDataList.size() > 0) {
						// 计算新增数据条数
						for (Data data1 : result.getList()) {
							boolean b = false;
							for (Data data2 : mDataList) {
								if (data1.get_Id().equalsIgnoreCase(data2.get_Id())) {
									b = true;
									break;
								}
							}
							if (!b) {
								newdata++;
							}
						}
					} else {
						newdata = result.getPageSize();
					}
					if (mAction == LISTVIEW_ACTION_REFRESH && !isPauseLife) {
						// 提示新添加的数据条数
						if (newdata > 0) {
							NewDataToast.makeText(getActivity(), getString(R.string.new_data_toast_message, newdata),
									mApplication.isAppSound()).show();
						} else {
							NewDataToast.makeText(getActivity(), getString(R.string.new_data_toast_none), false).show();
						}
					}
				}
				// 先清除原有数据
				mDataList.clear();
				// 加入最新的数据
				mDataList.addAll(result.getList());
			} else {
				mSumData += result.getPageSize();
				if (mDataList.size() > 0) {
					for (Data data1 : result.getList()) {
						boolean b = false;
						for (Data data2 : mDataList) {
							if (data1.get_Id().equalsIgnoreCase(data2.get_Id())) {
								b = true;
								break;
							}
						}
						if (!b) {
							mDataList.add(data1);
						}
					}
				} else {
					// 加入新增的数据
					mDataList.addAll(result.getList());
				}
			}
			// 通知listview去刷新界面
			mAdapter.notifyDataSetChanged();
		}
	}

	// 清空数据
	public void clearData() {
		mDataList.clear();
		mAdapter.notifyDataSetChanged();
	}
}<file_sep>package com.jamtu.fragments;

import java.util.List;

import android.os.Bundle;
import android.widget.BaseAdapter;

import com.jamtu.AppException;
import com.jamtu.adapter.JokeListAdapter;
import com.jamtu.basefragment.BaseSwipeRefreshFragment;
import com.jamtu.bean.CommonList;
import com.jamtu.bean.Joke;
import com.jamtu.bean.MessageData;
import com.jamtu.joke.R;

public class NetJokeListFragment extends BaseSwipeRefreshFragment<Joke, CommonList<Joke>> {
	public final static String JOKE_URL = "joke_url";
	private String jokeUrl = "";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Bundle args = getArguments();
		jokeUrl = args.getString(JOKE_URL);
	}

	@Override
	public BaseAdapter getAdapter(List<Joke> list) {
		return new JokeListAdapter(getActivity(), list, R.layout.exploreproject_listitem);
	}

	@Override
	protected MessageData<CommonList<Joke>> asyncLoadList(int page, boolean refresh) {
		MessageData<CommonList<Joke>> msg = null;
		try {
			CommonList<Joke> list = getList(page, refresh);
			msg = new MessageData<CommonList<Joke>>(list);
		} catch (AppException e) {
			e.makeToast(mApplication);
			e.printStackTrace();
			msg = new MessageData<CommonList<Joke>>(e);
		}
		return msg;
	}

	private CommonList<Joke> getList(int page, boolean refresh) throws AppException {
		// List<Joke> jokes = HtmlParser.getJokes(type, page);
		// if (null == jokes)
		// jokes = new ArrayList<Joke>();
		// CommonList<Joke> list = new CommonList<Joke>();
		// list.setList(jokes);
		// list.setCount(jokes.size());
		// list.setPageSize(jokes.size());
		// return list;
		return mApplication.getNetJokes(jokeUrl, page, refresh);
	}

	@Override
	public void onItemClick(int position, Joke project) {
	}

}
<file_sep>package com.jamtu.fragments;

import static com.jamtu.fragments.NetJokeListFragment.JOKE_URL;
import android.os.Bundle;

import com.jamtu.adapter.ViewPageFragmentAdapter;
import com.jamtu.basefragment.BaseViewPagerFragment;
import com.jamtu.utils.AppOthers;

/**
 * 网络段子2
 * 
 * @author lijq
 * @created 2015-03-29
 */
public class BDJ_JokePagerFragment extends BaseViewPagerFragment {

	public static BDJ_JokePagerFragment newInstance() {
		return new BDJ_JokePagerFragment();
	}

	@Override
	protected void onSetupTabAdapter(ViewPageFragmentAdapter adapter) {
		AppOthers.showBothApp(getJokeApplication());
		AppOthers.showInnerApp(getJokeApplication());
		adapter.addTab("段子精选", "段子精选", NetJokeListFragment.class, getBDJBundle(0));
		adapter.addTab("图片精选", "图片精选", NetJokeListFragment.class, getBDJBundle(1));
		adapter.addTab("最新段子", "最新段子", NetJokeListFragment.class, getBDJBundle(2));
		adapter.addTab("最新趣图", "最新趣图", NetJokeListFragment.class, getBDJBundle(3));
		adapter.addTab("热门段子", "热门段子", NetJokeListFragment.class, getBDJBundle(4));
		adapter.addTab("热门趣图", "热门趣图", NetJokeListFragment.class, getBDJBundle(5));
	}

	// 纯图 精选，最新，近期热门
	private static final String[] BDJ_PURE_IMG = { "", "new-p", "hotpic" };
	// 纯文 精选，最新，近期热门
	private static final String[] BDJ_PURE_TEXT = { "duanzi", "new-d", "hotdoc" };
	private final String BDJ_URL_Prefix = "http://www.budejie.com/";
	private String[] BDJ_TYPES = { BDJ_PURE_TEXT[0], BDJ_PURE_IMG[0], BDJ_PURE_TEXT[1], BDJ_PURE_IMG[1],
			BDJ_PURE_TEXT[2], BDJ_PURE_IMG[2] };

	private Bundle getBDJBundle(int index) {
		Bundle bundle = new Bundle();
		bundle.putString(JOKE_URL, BDJ_URL_Prefix + BDJ_TYPES[index]);
		return bundle;
	}
}
<file_sep>package com.jamtu.htmlparser;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.jamtu.App;
import com.jamtu.AppException;
import com.jamtu.bean.Author;
import com.jamtu.bean.CommonList;
import com.jamtu.bean.Joke;
import com.jamtu.fragments.QSBK_JokePagerFragment;

public class HtmlParser {

	private static int currPage = 1;

	private static List<Joke> parser(String url) throws AppException {
		List<Joke> jokes = new ArrayList<Joke>();
		try {
			Document doc = Jsoup
					.connect(url)
					.userAgent(
							"Mozilla/5.0 (Windows NT 5.1; zh-CN) AppleWebKit/535.12 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/535.12")
					.timeout(30 * 1000).get();
			Elements all = doc.select("div[class$=article block untagged mb15]");
			int size = all.size();
			int currIndex = (currPage - 1) * App.PAGE_SIZE;
			for (int i = 0; i < size; i++) {
				Element element = all.get(i);
				Joke joke = new Joke();
				joke.set_Id("Page_" + (currIndex + i));
				Elements childrens = element.children();
				for (Element children : childrens) {
					if (children.hasClass("author")) {
						Element link = children.select("a").first();
						Element img = link.select("img").first();
						Author author = new Author();
						author.setId(link.attr("href"));
						author.setIcon(img.attr("src"));
						author.setName(img.attr("alt"));
						joke.setAuthor(author);
					} else if (children.hasClass("content")) {
						joke.setContent(children.text());
					} else if (children.hasClass("thumb")) {
						joke.setImg(children.select("img").first().attr("src"));
					} else if (children.hasClass("stats")) {
						joke.setStatsVote(children.select("span.stats-vote").text());
						// joke.setStatsComments(children.select("span.stats-comments").text());
					}
				}
				jokes.add(joke);
			}
		} catch (Exception e) {
			throw AppException.http(e);
		}
		return jokes;
	}

	private static List<Joke> htmlParser(String url, boolean isQsbk) throws AppException {
		try {
			Document doc = Jsoup
					.connect(url)
					.userAgent(
							"Mozilla/5.0 (Windows NT 5.1; zh-CN) AppleWebKit/535.12 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/535.12")
					.timeout(30 * 1000).get();
			return isQsbk ? parserQsbk(doc) : parserBdj(doc);
		} catch (Exception e) {
			throw AppException.http(e);
		}
	}

	private static List<Joke> parserQsbk(Document doc) {
		List<Joke> jokes = new ArrayList<Joke>();
		Elements all = doc.select("div[class$=article block untagged mb15]");
		int size = all.size();
		// int currIndex = (currPage - 1) * App.PAGE_SIZE;
		for (int i = 0; i < size; i++) {
			Element element = all.get(i);
			Joke joke = new Joke();
			// joke.set_Id("Page_" + (currIndex + i));
			joke.set_Id(element.attr("id"));
			Elements childrens = element.children();
			for (Element children : childrens) {
				if (children.hasClass("author")) {
					Element link = children.select("a").first();
					Element img = link.select("img").first();
					Author author = new Author();
					author.setId(link.attr("href"));
					author.setIcon(img.attr("src"));
					author.setName(img.attr("alt"));
					joke.setAuthor(author);
				} else if (children.hasClass("content")) {
					joke.setContent(children.text());
				} else if (children.hasClass("thumb")) {
					joke.setImg(children.select("img").first().attr("src"));
				} else if (children.hasClass("stats")) {
					joke.setStatsVote(children.select("span.stats-vote").text());
					// joke.setStatsComments(children.select("span.stats-comments").text());
				}
			}
			jokes.add(joke);
		}
		return jokes;
	}

	private static List<Joke> parserBdj(Document doc) {
		List<Joke> jokes = new ArrayList<Joke>();
		Elements all = doc.select("div[class$=web_left floatl test] > div.white_border");
		int size = all.size();
		// int currIndex = (currPage - 1) * App.PAGE_SIZE;
		for (int i = 0; i < size; i++) {
			Element element = all.get(i);
			Joke joke = new Joke();
			// joke.set_Id("Page_" + (currIndex + i));
			Elements childrens = element.children();
			for (Element children : childrens) {
				if (children.hasClass("user_info")) {
					Elements ul = children.select("ul > li > *");
					Author author = new Author();
					String icon = ul.first().attr("src");
					author.setIcon(icon);
					author.setName(ul.get(1).text());
					author.setId(ul.last().text());
					joke.setAuthor(author);
				} else if (children.attr("class").equals("web_conter clear")) {
					Elements divs = children.select("div > div");

					Element contentDiv = divs.first();
					Element webSizeElement = contentDiv.select("p.web_size").first();
					joke.set_Id(webSizeElement.attr("id"));
					joke.setContent(webSizeElement.text());
					Elements tmp = contentDiv.select("p > a > img");
					if (tmp != null && !tmp.isEmpty())
						joke.setImg(tmp.first().attr("src"));

					joke.setStatsVote(divs.last().select("a[class$=dolove no_love]").text() + " 好笑");
					// joke.setContent(divs.first().text());
					// joke.setContent(children.select("div.post-body > p").first().text());
				}
			}
			jokes.add(joke);
		}
		return jokes;
	}

	private static List<Joke> getNetJokes(String jokeUrl, String type, int page) throws AppException {
		currPage = page;
		boolean isQsbk = Arrays.asList(QSBK_JokePagerFragment.QSBK_TYPES).contains(type);
		if (isQsbk)
			return htmlParser(jokeUrl + "page/" + page, true);
		else
			return htmlParser(jokeUrl + page, false);
	}

	public static CommonList<Joke> getJokess(String jokeUrl, String type, int page) throws AppException {
		List<Joke> jokes = getNetJokes(jokeUrl, type, page);
		if (null == jokes)
			jokes = new ArrayList<Joke>();
		CommonList<Joke> list = new CommonList<Joke>();
		list.setList(jokes);
		list.setCount(jokes.size());
		list.setPageSize(jokes.size());
		return list;
	}

}
<file_sep>package com.jamtu.bean;

import java.util.Date;

/**
 * 应用程序更新实体类
 * 
 * @author liux (http://my.oschina.net/liux)
 * @version 1.0
 * @created 2012-3-21
 */
public class Update extends Entity {

	private String description;
	private String url;
	private int num_version;
	private String version;

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public int getNum_version() {
		return num_version;
	}

	public void setNum_version(int num_version) {
		this.num_version = num_version;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

}
<file_sep># Joke
笑话惨了
