Android版本更新代码

ゝ一纸荒年。 2022-04-22 00:18 333阅读 0赞

ApkUtils

  1. /**
  2. *
  3. * App相关辅助类
  4. * Created by kenway on 17/3/9 18:15
  5. * Email : xiaokai090704@126.com
  6. */
  7. public class ApkUtils {
  8. private ApkUtils(){
  9. /* cannot be instantiated */
  10. throw new UnsupportedOperationException("cannot be instantiated");
  11. }
  12. /**
  13. * 获取应用程序名称
  14. */
  15. public static String getAppName(Context context){
  16. try {
  17. PackageManager manager= context.getPackageManager();
  18. PackageInfo info = manager.getPackageInfo(context.getPackageName(),0);
  19. int labeRes= info.applicationInfo.labelRes;
  20. return context.getResources().getString(labeRes);
  21. } catch (PackageManager.NameNotFoundException e) {
  22. e.printStackTrace();
  23. }
  24. return null;
  25. }
  26. /**
  27. * get App versionName
  28. *
  29. * @param context
  30. * @return 当前应用的版本名称
  31. */
  32. public static String getVersionName(Context context)
  33. {
  34. try
  35. {
  36. PackageManager packageManager = context.getPackageManager();
  37. PackageInfo packageInfo = packageManager.getPackageInfo(
  38. context.getPackageName(), 0);
  39. return packageInfo.versionName;
  40. } catch (PackageManager.NameNotFoundException e)
  41. {
  42. e.printStackTrace();
  43. }
  44. return null;
  45. }
  46. /**
  47. * get App versionCode
  48. * @param context
  49. * @return 当前应用的版本Code
  50. */
  51. public static int getVersionCode(Context context){
  52. PackageManager packageManager=context.getPackageManager();
  53. PackageInfo packageInfo;
  54. int versionCode = 0;
  55. try {
  56. packageInfo=packageManager.getPackageInfo(context.getPackageName(),0);
  57. versionCode=packageInfo.versionCode;
  58. } catch (PackageManager.NameNotFoundException e) {
  59. e.printStackTrace();
  60. }
  61. return versionCode;
  62. }
  63. /**
  64. * 得到安装的intent
  65. * @param apkFile
  66. * @return
  67. */
  68. public static Intent getInstallIntent(Context context,File apkFile) {
  69. Intent intent = new Intent();
  70. intent.setAction(Intent.ACTION_VIEW);
  71. //7.0以上需要使用FileProvider安装apk
  72. if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
  73. intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
  74. Uri contentUri = FileProvider.getUriForFile(context,"com.alpha.fileprovider", apkFile);
  75. intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
  76. }else {
  77. intent.setDataAndType(Uri.fromFile(new File(apkFile.getAbsolutePath())),
  78. "application/vnd.android.package-archive");
  79. intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  80. }
  81. return intent;
  82. }
  83. }

PreferenceUtils

  1. package com.alpha.alphaapp.version;
  2. import com.lidroid.xutils.DbUtils;
  3. import com.lidroid.xutils.exception.DbException;
  4. import android.content.Context;
  5. import android.content.SharedPreferences;
  6. import android.content.SharedPreferences.Editor;
  7. /**
  8. *
  9. * @项目名: WinfoSeaMap
  10. * @包名: com.winfo.seamap.utils
  11. * @类名: PreferenceUtils
  12. * @创建者: yanfeijun
  13. * @创建时间: 2015-9-15 上午10:55:24
  14. * @描述: SharedPreferences工具类
  15. *
  16. * @svn版本: $Rev: 93 $
  17. * @更新人: $Author: wenjie $
  18. * @更新时间: $Date: 2015-09-24 15:48:12 +0800 (Thu, 24 Sep 2015) $
  19. * @更新描述: TODO
  20. */
  21. public class PreferenceUtils
  22. {
  23. private static SharedPreferences mSp;
  24. private final static String SP_NAME = "config";
  25. /**
  26. * 获得sharePreference内存对象
  27. *
  28. * @param context
  29. * @return
  30. */
  31. private static SharedPreferences getSp(Context context)
  32. {
  33. if (mSp == null)
  34. {
  35. mSp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
  36. }
  37. return mSp;
  38. }
  39. /**
  40. * 获取boolean类型的值
  41. *
  42. * @param context
  43. * 上下文
  44. * @param key
  45. * 对应的键
  46. * @param defValue
  47. * 如果没有对应的值,
  48. * @return
  49. */
  50. public static boolean getBoolean(Context context, String key, boolean defValue)
  51. {
  52. SharedPreferences sp = getSp(context);
  53. return sp.getBoolean(key, defValue);
  54. }
  55. /**
  56. * 获取boolean类型的值,如果没有对应的值,默认值返回false
  57. *
  58. * @param context
  59. * 上下文
  60. * @param key
  61. * 对应的键
  62. * @return
  63. */
  64. public static boolean getBoolean(Context context, String key)
  65. {
  66. return getBoolean(context, key, false);
  67. }
  68. /**
  69. * 设置int类型的值
  70. *
  71. * @param context
  72. * @param key
  73. * @param value
  74. */
  75. public static void setInt(Context context, String key, int value)
  76. {
  77. SharedPreferences sp = getSp(context);
  78. Editor editor = sp.edit();
  79. editor.putInt(key, value);
  80. editor.commit();
  81. }
  82. /**
  83. * 设置boolean类型的值
  84. *
  85. * @param context
  86. * @param key
  87. * @param value
  88. */
  89. public static void setBoolean(Context context, String key, boolean value)
  90. {
  91. SharedPreferences sp = getSp(context);
  92. Editor editor = sp.edit();
  93. editor.putBoolean(key, value);
  94. editor.commit();
  95. }
  96. /**
  97. * 获取String类型的值
  98. *
  99. * @param context
  100. * 上下文
  101. * @param key
  102. * 对应的键
  103. * @param defValue
  104. * 如果没有对应的值,
  105. * @return
  106. */
  107. public static String getString(Context context, String key, String defValue)
  108. {
  109. SharedPreferences sp = getSp(context);
  110. return sp.getString(key, defValue);
  111. }
  112. /**
  113. * 获取int类型的值
  114. *
  115. * @param context
  116. * 上下文
  117. * @param key
  118. * 对应的键
  119. * @param defValue
  120. * 如果没有对应的值,
  121. * @return
  122. */
  123. public static int getInt(Context context, String key, int defValue)
  124. {
  125. SharedPreferences sp = getSp(context);
  126. return sp.getInt(key, defValue);
  127. }
  128. /**
  129. * 获取String类型的值,如果没有对应的值,默认值返回null
  130. *
  131. * @param context
  132. * 上下文
  133. * @param key
  134. * 对应的键
  135. * @return
  136. */
  137. public static String getString(Context context, String key)
  138. {
  139. return getString(context, key, null);
  140. }
  141. /**
  142. * 设置String类型的值
  143. *
  144. * @param context
  145. * @param key
  146. * @param value
  147. */
  148. public static void setString(Context context, String key, String value)
  149. {
  150. SharedPreferences sp = getSp(context);
  151. Editor editor = sp.edit();
  152. editor.putString(key, value);
  153. editor.commit();
  154. }
  155. /**
  156. * 获取long类型的值
  157. *
  158. * @param context
  159. * 上下文
  160. * @param key
  161. * 对应的键
  162. * @param defValue
  163. * 如果没有对应的值,
  164. * @return
  165. */
  166. public static long getLong(Context context, String key, long defValue)
  167. {
  168. SharedPreferences sp = getSp(context);
  169. return sp.getLong(key, defValue);
  170. }
  171. /**
  172. * 获取long类型的值,如果没有对应的值,默认值返回0
  173. *
  174. * @param context
  175. * 上下文
  176. * @param key
  177. * 对应的键
  178. * @return
  179. */
  180. public static Long getLong(Context context, String key)
  181. {
  182. return getLong(context, key, 0);
  183. }
  184. /**
  185. * 设置Long类型的值
  186. *
  187. * @param context
  188. * @param key
  189. * @param value
  190. */
  191. public static void setLong(Context context, String key, long value)
  192. {
  193. SharedPreferences sp = getSp(context);
  194. Editor editor = sp.edit();
  195. editor.putLong(key, value);
  196. editor.commit();
  197. }
  198. /**
  199. * 根据key值删除指定的数据
  200. * @param context
  201. * @param key
  202. */
  203. public static void remove(Context context , String key){
  204. SharedPreferences sp = getSp(context);
  205. Editor editor = sp.edit();
  206. editor.remove(key);
  207. editor.commit();
  208. }
  209. }

UpdateStatus

  1. package com.alpha.alphaapp.version;
  2. /**
  3. * Created by kenway on 17/7/12 18:07
  4. * Email : xiaokai090704@126.com
  5. */
  6. public interface UpdateStatus {
  7. /**
  8. * 没有新版本
  9. */
  10. int NO = 1;
  11. /**
  12. * 有新版本
  13. */
  14. int YES = 2;
  15. /**
  16. * 连接超时
  17. */
  18. int TIMEOUT = 3;
  19. /**
  20. * 没有wifi
  21. */
  22. int NOWIFI = 4;
  23. /**
  24. * 数据解析出错
  25. */
  26. int ERROR = -1;
  27. }

UpdateVersionService

  1. **
  2. * @author wenjie
  3. * 下载新版本的服务类
  4. */
  5. public class UpdateVersionService extends Service {
  6. private static final String TAG = "UpdateVersionService";
  7. private NotificationManager nm;
  8. private Notification notification;
  9. //标题标识
  10. private int titleId = 0;
  11. //安装文件
  12. private File updateFile;
  13. private static HttpHandler<File> httpHandler;
  14. private HttpUtils httpUtils;
  15. private long initTotal = 0;//文件的总长度
  16. @Override
  17. public void onCreate() {
  18. super.onCreate();
  19. httpUtils = new HttpUtils();
  20. updateFile = new File(SDCardUtils.getRootDirectory() + "/updateVersion/"+ MyApplication.APP_NAME_E);
  21. if(!updateFile.exists()){
  22. //先得到文件的上级目录,并创建上级目录,在创建文件
  23. updateFile.getParentFile().mkdir();
  24. try {
  25. //创建文件
  26. updateFile.createNewFile();
  27. } catch (IOException e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
  32. notification = new Notification();
  33. notification.icon = R.drawable.icon512;
  34. notification.tickerText = "开始下载";
  35. notification.when = System.currentTimeMillis();
  36. notification.contentView = new RemoteViews(getPackageName(), R.layout.notification_version);
  37. }
  38. @Override
  39. public int onStartCommand(Intent intent, int flags, int startId) {
  40. Bundle bundle = intent.getExtras();
  41. String url = bundle.getString("downloadUrl");
  42. nm.notify(titleId, notification);
  43. downLoadFile(url);
  44. return super.onStartCommand(intent, flags, startId);
  45. }
  46. public void downLoadFile(String url) {
  47. httpHandler = httpUtils.download(url, updateFile.getAbsolutePath(), true, false, new RequestCallBack<File>() {
  48. @Override
  49. public void onSuccess(ResponseInfo<File> response) {
  50. ToastUtils.showToast(getApplicationContext(), "下载完成!");
  51. // 更改文字
  52. notification.contentView.setTextViewText(R.id.msg, "下载完成!点击安装");
  53. // notification.contentView.setViewVisibility(R.id.btnStartStop, View.GONE);
  54. // notification.contentView.setViewVisibility(R.id.btnCancel,View.GONE);
  55. // 发送消息
  56. nm.notify(0, notification);
  57. stopSelf();
  58. //收起通知栏
  59. // UpdateVersionUtil.collapseStatusBar(UpdateVersionService.this);
  60. //自动安装新版本
  61. Intent installIntent = ApkUtils.getInstallIntent(UpdateVersionService.this,updateFile);
  62. startActivity(installIntent);
  63. }
  64. @Override
  65. public void onFailure(HttpException error, String msg) {
  66. LogUtils.e("下载失败 error=="+error.getMessage());
  67. LogUtils.e("下载失败 msg=="+msg);
  68. //网络连接错误
  69. if (error.getExceptionCode() == 0) {
  70. // 更改文字
  71. notification.contentView.setTextViewText(R.id.msg, "网络异常!请检查网络设置!");
  72. } else if (error.getExceptionCode() == 416) {//文件已经下载完毕
  73. // 更改文字
  74. notification.contentView.setTextViewText(R.id.msg, MyApplication.APP_NAME_C);
  75. // 更改文字
  76. notification.contentView.setTextViewText(R.id.bartext, "检测到新版本已经下载完成,点击即安装!");
  77. // 隐藏进度条
  78. notification.contentView.setViewVisibility(R.id.progressBar1, View.GONE);
  79. Intent intent = ApkUtils.getInstallIntent(UpdateVersionService.this,updateFile);
  80. PendingIntent pendingIntent = PendingIntent.getActivity(UpdateVersionService.this, 0, intent, 0);
  81. notification.flags = Notification.FLAG_AUTO_CANCEL;//点击通知栏之后 消失
  82. notification.contentIntent = pendingIntent;//启动指定意图
  83. }
  84. // 发送消息
  85. ToastUtils.showToast(getApplicationContext(), "下载失败,请检查网络!");
  86. nm.notify(0, notification);
  87. }
  88. @Override
  89. public void onLoading(long total, long current, boolean isUploading) {
  90. if (initTotal == 0) {//说明第一次开始下载
  91. initTotal = total;
  92. }
  93. if (initTotal != total) {//说明下载过程中暂停过,文件的总长度出现问题 就把初始的文件的长度赋值给他重新计算已经下载的比例
  94. total = initTotal;
  95. }
  96. long l = current * 100 / total;
  97. notification.contentView.setTextViewText(R.id.msg, "正在下载:"+MyApplication.APP_NAME_C);
  98. LogUtils.e("正在下载:"+ l + "%");
  99. // 更改文字
  100. notification.contentView.setTextViewText(R.id.bartext, l + "%");
  101. // 更改进度条
  102. notification.contentView.setProgressBar(R.id.progressBar1, 100, (int) l, false);
  103. // 发送消息
  104. nm.notify(0, notification);
  105. }
  106. @Override
  107. public void onStart() {
  108. notification.contentView.setTextViewText(R.id.msg, "开始下载:"+MyApplication.APP_NAME_C);
  109. ToastUtils.showToast(getApplicationContext(),"开始下载:"+MyApplication.APP_NAME_C);
  110. nm.notify(titleId, notification);
  111. }
  112. });
  113. }
  114. public static HttpHandler<File> getHandler() {
  115. return httpHandler;
  116. }
  117. @Override
  118. public void onDestroy() {
  119. //下载完成时,清除该通知,自动安装
  120. nm.cancel(titleId);
  121. LogUtils.e(TAG, "UpdateVersionService----onDestroy");
  122. super.onDestroy();
  123. }
  124. @Override
  125. public IBinder onBind(Intent intent) {
  126. return null;
  127. }
  128. }

UpdateVersionUtil

  1. package com.alpha.alphaapp.version;
  2. import android.app.AlertDialog;
  3. import android.app.Dialog;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.os.Build;
  7. import android.view.LayoutInflater;
  8. import android.view.View;
  9. import android.widget.Button;
  10. import android.widget.TextView;
  11. import com.alpha.alphaapp.R;
  12. import com.alpha.alphaapp.app.MyApplication;
  13. import com.alpha.lib_sdk.app.log.LogUtils;
  14. import com.alpha.lib_sdk.app.net.ReqCallBack;
  15. import com.alpha.lib_sdk.app.net.RequestManager;
  16. import com.alpha.lib_sdk.app.tool.JsonUtil;
  17. import com.alpha.lib_sdk.app.unitily.SDCardUtils;
  18. import com.alpha.lib_sdk.app.unitily.SPUtils;
  19. import com.alpha.lib_sdk.app.unitily.ToastUtils;
  20. import org.json.JSONObject;
  21. import java.io.File;
  22. import java.lang.reflect.Method;
  23. /**
  24. * Created by kenway on 17/7/12 17:28
  25. * Email : xiaokai090704@126.com
  26. */
  27. public class UpdateVersionUtil {
  28. private static final String TAG = "UpdateVersionUtil";
  29. /**
  30. * 接口回调
  31. */
  32. public interface UpdateListener {
  33. void onUpdateReturned(int updateStatus, VersionInfo info);
  34. }
  35. public UpdateListener updateListener;
  36. public void setUpdateListener(UpdateListener updateListener) {
  37. this.updateListener = updateListener;
  38. }
  39. /**
  40. * 检测是否有新版本
  41. *
  42. * @param context
  43. * @param url 获取版本信息
  44. * @param isDebug 是否为正式版
  45. */
  46. public static void doCheckVersionUpdate(final Context context, String url, boolean isDebug) {
  47. //本地测试是否有新版本发布
  48. UpdateVersionUtil.UpdateListener listener = new UpdateVersionUtil.UpdateListener() {
  49. @Override
  50. public void onUpdateReturned(int updateStatus, final VersionInfo info) {
  51. //判断回调过来的版本检测状态
  52. switch (updateStatus) {
  53. case UpdateStatus.YES:
  54. //弹出更新提示
  55. UpdateVersionUtil.showDialog(context, info);
  56. break;
  57. case UpdateStatus.NO:
  58. //没有新版本
  59. // ToastUtils.showToast(context, "已经是最新版本了!");
  60. break;
  61. case UpdateStatus.NOWIFI:
  62. //当前是非Wifi网络
  63. // ToastUtils.showToast(context, "只有在wifi下更新");
  64. UpdateVersionUtil.showDialog(context, info);
  65. // DialogUtils.showDialog(MainActivity.this, "温馨提示","当前非wifi网络,下载会消耗手机流量!", "确定", "取消",new DialogOnClickListenner() {
  66. // @Override
  67. // public void btnConfirmClick(Dialog dialog) {
  68. // dialog.dismiss();
  69. // //点击确定之后弹出更新对话框
  70. // UpdateVersionUtil.showDialog(SplashActivity.this,info);
  71. // }
  72. //
  73. // @Override
  74. // public void btnCancelClick(Dialog dialog) {
  75. // dialog.dismiss();
  76. // }
  77. // });
  78. break;
  79. case UpdateStatus.ERROR:
  80. //检测失败
  81. ToastUtils.showToast(context, "检测失败,请稍后重试!");
  82. break;
  83. case UpdateStatus.TIMEOUT:
  84. //链接超时
  85. ToastUtils.showToast(context, "链接超时");
  86. break;
  87. }
  88. }
  89. };
  90. if (isDebug) {
  91. //debug
  92. localCheckVersion(context, listener);
  93. } else {
  94. //正式版
  95. checkVersion(context, url, listener);
  96. }
  97. }
  98. /**
  99. * 网络测试 检查版本
  100. */
  101. private static void checkVersion(final Context context, String url, final UpdateListener listener) {
  102. ReqCallBack<String> call = new ReqCallBack<String>() {
  103. @Override
  104. public void onReqSuccess(String result) {
  105. try {
  106. JSONObject jsonObject = JsonUtil.stringToJson(result);
  107. VersionInfo mVersionInfo = JsonUtil.jsonToBean(jsonObject.toString(), VersionInfo.class);
  108. String clientVersion = ApkUtils.getVersionName(context);
  109. String serverVersion = mVersionInfo.getVersion();
  110. LogUtils.e("clientVersionInfo=="+clientVersion+",serverVersion=="+mVersionInfo.getVersion());
  111. //有新版本
  112. if (!clientVersion.equals(serverVersion)) {
  113. // if (!NetUtils.isWifi(context)) {
  114. // listener.onUpdateReturned(UpdateStatus.NOWIFI, mVersionInfo);
  115. // } else {
  116. // listener.onUpdateReturned(UpdateStatus.YES, mVersionInfo);
  117. // }
  118. listener.onUpdateReturned(UpdateStatus.YES, mVersionInfo);
  119. } else {
  120. listener.onUpdateReturned(UpdateStatus.NO, null);
  121. }
  122. } catch (Exception e) {
  123. e.printStackTrace();
  124. listener.onUpdateReturned(UpdateStatus.ERROR, null);
  125. }
  126. }
  127. @Override
  128. public void onReqFailed(String errorMsg) {
  129. listener.onUpdateReturned(UpdateStatus.TIMEOUT, null);
  130. }
  131. };
  132. RequestManager.getInstance(context).requestGet(url, call);
  133. }
  134. private static void localCheckVersion(Context context, UpdateListener listener) {
  135. try {
  136. VersionInfo mVersionInfo = new VersionInfo();
  137. mVersionInfo.setUrl("http://gdown.baidu.com/data/wisegame/57a788487345e938/QQ_358.apk");
  138. mVersionInfo.setContent("更新内容:\n1、增加更新功能\n2、增加apk下载!\n3、用户界面优化!\n4、修改了不知道什么功能!");
  139. mVersionInfo.setVersion(2 + "");
  140. mVersionInfo.setVersion("v 1.0.4");
  141. mVersionInfo.setSize("9.3M");
  142. String clientVersionName = ApkUtils.getVersionName(context);
  143. String serverVersionCode = mVersionInfo.getVersion();
  144. LogUtils.e(TAG, "clientVersionCode==" + clientVersionName + ",serverVersionCode==" + serverVersionCode);
  145. //有新版本
  146. if (!clientVersionName.equals(serverVersionCode)) {
  147. listener.onUpdateReturned(UpdateStatus.YES, mVersionInfo);
  148. // if (!NetUtils.isWifi(context)) {
  149. // listener.onUpdateReturned(UpdateStatus.NOWIFI, mVersionInfo);
  150. // } else {
  151. // listener.onUpdateReturned(UpdateStatus.YES, mVersionInfo);
  152. // }
  153. } else {
  154. //无新本
  155. listener.onUpdateReturned(UpdateStatus.NO, null);
  156. }
  157. } catch (Exception e) {
  158. e.printStackTrace();
  159. listener.onUpdateReturned(UpdateStatus.ERROR, null);
  160. }
  161. }
  162. private static void showDialog(final Context context, final VersionInfo versionInfo) {
  163. final Dialog dialog = new AlertDialog.Builder(context).create();
  164. //这里的名字可以修改
  165. final File file = new File(SDCardUtils.getRootDirectory() + "/updateVersion/" + MyApplication.APP_NAME_E);
  166. dialog.setCancelable(true);
  167. dialog.setCanceledOnTouchOutside(false);
  168. dialog.show();
  169. View view = LayoutInflater.from(context).inflate(R.layout.dialog_version, null);
  170. dialog.setContentView(view);
  171. final Button btnOk = (Button) view.findViewById(R.id.btn_update_id_ok);
  172. Button btnCancel = (Button) view.findViewById(R.id.btn_update_id_cancel);
  173. TextView tvContent = (TextView) view.findViewById(R.id.tv_update_content);
  174. TextView tvUpdateTitle = (TextView) view.findViewById(R.id.tv_update_title);
  175. TextView tvUpdateMsgSize = (TextView) view.findViewById(R.id.tv_update_msg_size);
  176. tvContent.setText(versionInfo.getContent());
  177. tvUpdateTitle.setText("版本: " + versionInfo.getVersion());
  178. final String existVersion = (String) SPUtils.get(context, SPUtils.KEY_VERSION, "string");
  179. if (file.exists() && file.getName().equals(MyApplication.APP_NAME_E) && existVersion.equals(versionInfo.getVersion())) {
  180. tvUpdateMsgSize.setText("新版本已经下载,是否安装");
  181. } else {
  182. tvUpdateMsgSize.setText("大小: " + versionInfo.getSize());
  183. }
  184. btnOk.setOnClickListener(new View.OnClickListener() {
  185. @Override
  186. public void onClick(View v) {
  187. dialog.dismiss();
  188. if (v.getId() == R.id.btn_update_id_ok) {
  189. //新版本已经下载
  190. if (file.exists() && file.getName().equals(MyApplication.APP_NAME_E)&&existVersion.equals(versionInfo.getVersion())) {
  191. Intent intent = ApkUtils.getInstallIntent(context, file);
  192. context.startActivity(intent);
  193. } else {
  194. //没有下载,则开启服务下载最新版本
  195. LogUtils.e(TAG, "新版本即将开始下载。。。。");
  196. Intent intent = new Intent(context, UpdateVersionService.class);
  197. intent.putExtra("downloadUrl", versionInfo.getUrl());
  198. context.startService(intent);
  199. SPUtils.put(context, SPUtils.KEY_VERSION, versionInfo.getVersion());
  200. }
  201. }
  202. }
  203. });
  204. btnCancel.setOnClickListener(new View.OnClickListener() {
  205. @Override
  206. public void onClick(View v) {
  207. dialog.dismiss();
  208. }
  209. });
  210. }
  211. // /**
  212. // * 收起通知栏
  213. // */
  214. //
  215. // public static void collapsingNotification(Context context){
  216. // //这里更改为新的
  217. Object service = context.getSystemService("statusbar");
  218. // Object service=null;
  219. // if (null == service)
  220. // return;
  221. // try {
  222. // Class<?> clazz = Class.forName("android.app.StatusBarManager");
  223. // int sdkVersion = android.os.Build.VERSION.SDK_INT;
  224. // Method collapse;
  225. // if (sdkVersion <= 16) {
  226. // collapse = clazz.getMethod("collapse");
  227. // } else {
  228. // collapse = clazz.getMethod("collapsePanels");
  229. // }
  230. // collapse.setAccessible(true);
  231. // collapse.invoke(service);
  232. // } catch (Exception e) {
  233. // e.printStackTrace();
  234. // }
  235. // }
  236. /**
  237. * 收起通知栏
  238. *
  239. * @param context
  240. */
  241. public static void collapseStatusBar(Context context) {
  242. try {
  243. Object statusBarManager = context.getSystemService("statusbar");
  244. Method collapse;
  245. if (Build.VERSION.SDK_INT <= 16) {
  246. collapse = statusBarManager.getClass().getMethod("collapse");
  247. } else {
  248. collapse = statusBarManager.getClass().getMethod("collapsePanels");
  249. }
  250. collapse.invoke(statusBarManager);
  251. } catch (Exception localException) {
  252. localException.printStackTrace();
  253. }
  254. }
  255. }

VersionInfo

  1. package com.alpha.alphaapp.version;
  2. import com.google.gson.Gson;
  3. import com.google.gson.reflect.TypeToken;
  4. import org.json.JSONException;
  5. import org.json.JSONObject;
  6. import java.io.Serializable;
  7. import java.lang.reflect.Type;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. /**
  11. * Created by kenway on 17/7/12 17:37
  12. * Email : xiaokai090704@126.com
  13. * 版本信息类
  14. */
  15. public class VersionInfo implements Serializable {
  16. private static final long serialVersionUID = 1L;
  17. private String version;
  18. private String md5;
  19. private String url;
  20. private String content;
  21. private String size;
  22. public static VersionInfo objectFromData(String str, String key) {
  23. try {
  24. JSONObject jsonObject = new JSONObject(str);
  25. return new Gson().fromJson(jsonObject.getJSONObject(key).toString(), VersionInfo.class);
  26. } catch (JSONException e) {
  27. e.printStackTrace();
  28. }
  29. return null;
  30. }
  31. public static List<VersionInfo> arrayVersionInfoFromData(String str, String key) {
  32. try {
  33. JSONObject jsonObject = new JSONObject(str);
  34. Type listType = new TypeToken<ArrayList<VersionInfo>>() {
  35. }.getType();
  36. return new Gson().fromJson(jsonObject.getJSONArray(key).toString(), listType);
  37. } catch (JSONException e) {
  38. e.printStackTrace();
  39. }
  40. return new ArrayList();
  41. }
  42. public String getVersion() {
  43. return version;
  44. }
  45. public void setVersion(String version) {
  46. this.version = version;
  47. }
  48. public String getMd5() {
  49. return md5;
  50. }
  51. public void setMd5(String md5) {
  52. this.md5 = md5;
  53. }
  54. public String getUrl() {
  55. return url;
  56. }
  57. public void setUrl(String url) {
  58. this.url = url;
  59. }
  60. public String getContent() {
  61. return content;
  62. }
  63. public void setContent(String content) {
  64. this.content = content;
  65. }
  66. public String getSize() {
  67. return size;
  68. }
  69. public void setSize(String size) {
  70. this.size = size;
  71. }
  72. @Override
  73. public String toString() {
  74. return "VersionInfo{" +
  75. "version='" + version + '\'' +
  76. ", md5='" + md5 + '\'' +
  77. ", url='" + url + '\'' +
  78. ", content='" + content + '\'' +
  79. ", size='" + size + '\'' +
  80. '}';
  81. }
  82. }

ToastUtils

  1. import android.app.Activity;
  2. import android.content.Context;
  3. import android.view.Gravity;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7. import android.widget.ImageView;
  8. import android.widget.LinearLayout;
  9. import android.widget.TextView;
  10. import android.widget.Toast;
  11. import com.alpha.lib_sdk.R;
  12. /**
  13. * Toast统一管理类
  14. * Created by kenway on 17/3/9 18:02
  15. * Email : xiaokai090704@126.com
  16. */
  17. public class ToastUtils {
  18. private ToastUtils() {
  19. /* cannot be instantiated */
  20. throw new UnsupportedOperationException("cannot be instantiated");
  21. }
  22. public static boolean isShow = true;
  23. /**
  24. * 短时间显示Toast
  25. *
  26. * @param context
  27. * @param message
  28. */
  29. public static void showShort(Context context, CharSequence message) {
  30. if (isShow)
  31. Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
  32. }
  33. /**
  34. * 短时间显示Toast
  35. *
  36. * @param context
  37. * @param message
  38. */
  39. public static void showShort(Context context, int message) {
  40. if (isShow)
  41. Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
  42. }
  43. /**
  44. * 长时间显示Toast
  45. *
  46. * @param context
  47. * @param message
  48. */
  49. public static void showLong(Context context, CharSequence message) {
  50. if (isShow)
  51. Toast.makeText(context, message, Toast.LENGTH_LONG).show();
  52. }
  53. /**
  54. * 长时间显示Toast
  55. *
  56. * @param context
  57. * @param message
  58. */
  59. public static void showLong(Context context, int message) {
  60. if (isShow)
  61. Toast.makeText(context, message, Toast.LENGTH_LONG).show();
  62. }
  63. /**
  64. * 自定义显示Toast时间
  65. *
  66. * @param context
  67. * @param message
  68. * @param duration
  69. */
  70. public static void show(Context context, CharSequence message, int duration) {
  71. if (isShow)
  72. Toast.makeText(context, message, duration).show();
  73. }
  74. /**
  75. * 自定义显示Toast时间
  76. * @param context
  77. * @param message
  78. * @param duration
  79. */
  80. public static void show(Context context, int message, int duration) {
  81. if (isShow)
  82. Toast.makeText(context, message, duration).show();
  83. }
  84. private static String oldMsg;
  85. protected static Toast toast = null;
  86. private static long oneTime = 0;
  87. private static long twoTime = 0;
  88. /**
  89. * 吐出一个显示时间较短的提示
  90. *
  91. * @param context 上下文
  92. * @param s 文本内容
  93. */
  94. public static void showToast(Context context, String s) {
  95. if (toast == null) {
  96. toast = Toast.makeText(context, s, Toast.LENGTH_SHORT);
  97. toast.show();
  98. oneTime = System.currentTimeMillis();
  99. } else {
  100. twoTime = System.currentTimeMillis();
  101. if (s.equals(oldMsg)) {
  102. if (twoTime - oneTime > Toast.LENGTH_SHORT) {
  103. toast.show();
  104. }
  105. } else {
  106. oldMsg = s;
  107. toast.setText(s);
  108. toast.show();
  109. }
  110. }
  111. oneTime = twoTime;
  112. }
  113. /**
  114. * 吐出一个显示时间较短的提示
  115. *
  116. * @param context 上下文
  117. * @param resId 文本内容
  118. */
  119. public static void showToast(Context context, int resId) {
  120. String s = ResourceUtil.resToStr(context, resId);
  121. if (toast == null) {
  122. toast = Toast.makeText(context, s, Toast.LENGTH_SHORT);
  123. toast.show();
  124. oneTime = System.currentTimeMillis();
  125. } else {
  126. twoTime = System.currentTimeMillis();
  127. if (s.equals(oldMsg)) {
  128. if (twoTime - oneTime > Toast.LENGTH_SHORT) {
  129. toast.show();
  130. }
  131. } else {
  132. oldMsg = s;
  133. toast.setText(s);
  134. toast.show();
  135. }
  136. }
  137. oneTime = twoTime;
  138. }
  139. public static void showForumToast(Context context, String msg, int resDrawable) {
  140. //Inflater意思是充气
  141. //LayoutInflater这个类用来实例化XML文件到其相应的视图对象的布局
  142. LayoutInflater inflater =LayoutInflater.from(context);
  143. //通过制定XML文件及布局ID来填充一个视图对象
  144. View layout = inflater.inflate(R.layout.widget_toast,null);
  145. ImageView image = (ImageView) layout.findViewById(R.id.widget_toast_iv);
  146. //设置布局中图片视图中图片
  147. image.setImageResource(resDrawable);
  148. TextView title = (TextView) layout.findViewById(R.id.widget_toast_tv);
  149. //设置标题
  150. title.setText(msg);
  151. Toast toast= new Toast(context);
  152. toast.setGravity(Gravity.CENTER , 0, 0);
  153. toast.setDuration(Toast.LENGTH_SHORT);
  154. toast.setView(layout);
  155. toast.show();
  156. }
  157. }
  158. /**
  159. * Created by kenway on 17/3/9 18:05
  160. * Email : xiaokai090704@126.com
  161. */
  162. public class SPUtils {
  163. public static final String KEY_VERSION="version";
  164. /**
  165. * 保存在手机里面的文件名
  166. */
  167. public static final String FILE_NAME = "share_data";
  168. /**
  169. * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
  170. *
  171. * @param context
  172. * @param key
  173. * @param object
  174. */
  175. public static void put(Context context, String key, Object object)
  176. {
  177. SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
  178. Context.MODE_PRIVATE);
  179. SharedPreferences.Editor editor = sp.edit();
  180. if (object instanceof String)
  181. {
  182. editor.putString(key, (String) object);
  183. } else if (object instanceof Integer)
  184. {
  185. editor.putInt(key, (Integer) object);
  186. } else if (object instanceof Boolean)
  187. {
  188. editor.putBoolean(key, (Boolean) object);
  189. } else if (object instanceof Float)
  190. {
  191. editor.putFloat(key, (Float) object);
  192. } else if (object instanceof Long)
  193. {
  194. editor.putLong(key, (Long) object);
  195. } else
  196. {
  197. editor.putString(key, object.toString());
  198. }
  199. SharedPreferencesCompat.apply(editor);
  200. }
  201. /**
  202. * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
  203. *
  204. * @param context
  205. * @param key
  206. * @param defaultObject
  207. * @return
  208. */
  209. public static Object get(Context context, String key, Object defaultObject)
  210. {
  211. SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
  212. Context.MODE_PRIVATE);
  213. if (defaultObject instanceof String)
  214. {
  215. return sp.getString(key, (String) defaultObject);
  216. } else if (defaultObject instanceof Integer)
  217. {
  218. return sp.getInt(key, (Integer) defaultObject);
  219. } else if (defaultObject instanceof Boolean)
  220. {
  221. return sp.getBoolean(key, (Boolean) defaultObject);
  222. } else if (defaultObject instanceof Float)
  223. {
  224. return sp.getFloat(key, (Float) defaultObject);
  225. } else if (defaultObject instanceof Long)
  226. {
  227. return sp.getLong(key, (Long) defaultObject);
  228. }
  229. return null;
  230. }
  231. /**
  232. * 移除某个key值已经对应的值
  233. * @param context
  234. * @param key
  235. */
  236. public static void remove(Context context, String key)
  237. {
  238. SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
  239. Context.MODE_PRIVATE);
  240. SharedPreferences.Editor editor = sp.edit();
  241. editor.remove(key);
  242. SharedPreferencesCompat.apply(editor);
  243. }
  244. /**
  245. * 清除所有数据
  246. * @param context
  247. */
  248. public static void clear(Context context)
  249. {
  250. SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
  251. Context.MODE_PRIVATE);
  252. SharedPreferences.Editor editor = sp.edit();
  253. editor.clear();
  254. SharedPreferencesCompat.apply(editor);
  255. }
  256. /**
  257. * 查询某个key是否已经存在
  258. * @param context
  259. * @param key
  260. * @return
  261. */
  262. public static boolean contains(Context context, String key)
  263. {
  264. SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
  265. Context.MODE_PRIVATE);
  266. return sp.contains(key);
  267. }
  268. /**
  269. * 返回所有的键值对
  270. *
  271. * @param context
  272. * @return
  273. */
  274. public static Map<String, ?> getAll(Context context)
  275. {
  276. SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
  277. Context.MODE_PRIVATE);
  278. return sp.getAll();
  279. }
  280. /**
  281. * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
  282. *
  283. * @author zhy
  284. *
  285. */
  286. private static class SharedPreferencesCompat
  287. {
  288. private static final Method sApplyMethod = findApplyMethod();
  289. /**
  290. * 反射查找apply的方法
  291. *
  292. * @return
  293. */
  294. @SuppressWarnings({ "unchecked", "rawtypes" })
  295. private static Method findApplyMethod()
  296. {
  297. try
  298. {
  299. Class clz = SharedPreferences.Editor.class;
  300. return clz.getMethod("apply");
  301. } catch (NoSuchMethodException e)
  302. {
  303. }
  304. return null;
  305. }
  306. /**
  307. * 如果找到则使用apply执行,否则使用commit
  308. *
  309. * @param editor
  310. */
  311. public static void apply(SharedPreferences.Editor editor)
  312. {
  313. try
  314. {
  315. if (sApplyMethod != null)
  316. {
  317. sApplyMethod.invoke(editor);
  318. return;
  319. }
  320. } catch (IllegalArgumentException e)
  321. {
  322. } catch (IllegalAccessException e)
  323. {
  324. } catch (InvocationTargetException e)
  325. {
  326. }
  327. editor.commit();
  328. }
  329. }
  330. }

SDcardUtils

  1. package com.alpha.lib_sdk.app.unitily;
  2. import android.annotation.TargetApi;
  3. import android.os.Build;
  4. import android.os.Environment;
  5. import android.os.StatFs;
  6. import java.io.File;
  7. /**
  8. * Created by kenway on 17/3/9 18:11
  9. * Email : xiaokai090704@126.com
  10. */
  11. public class SDCardUtils {
  12. public static String getPath(){
  13. return Environment.getExternalStorageDirectory().getAbsolutePath();
  14. }
  15. /**
  16. * 获取SD卡的状态
  17. * @return
  18. */
  19. public static String getState(){
  20. return Environment.getExternalStorageState();
  21. }
  22. /**
  23. * SD卡是否可用
  24. * @return 只有当SD卡已经安装并且准备好了才返回true
  25. */
  26. public static boolean isAvailable(){
  27. return getState().equals(Environment.MEDIA_MOUNTED);
  28. }
  29. /**
  30. * 获取SD卡的根目录
  31. * @return null:不存在SD卡
  32. */
  33. public static File getRootDirectory(){
  34. return isAvailable()?Environment.getExternalStorageDirectory():null;
  35. }
  36. /**
  37. * 获取SD卡的根路径
  38. * @return null:不存在SD卡
  39. */
  40. public static String getRootPath(){
  41. File rootDirectory = getRootDirectory();
  42. return rootDirectory != null ?rootDirectory.getPath():null;
  43. }
  44. /**
  45. * 获取SD卡总的容量
  46. * @return 总容量;-1:SD卡不可用
  47. */
  48. @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
  49. public static long getTotalSize(){
  50. if(isAvailable()){
  51. StatFs statFs = new StatFs(getRootDirectory().getPath());
  52. if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1){
  53. return statFs.getBlockCount() * statFs.getBlockSize();
  54. }else{
  55. return statFs.getBlockCount() * statFs.getBlockSize();
  56. }
  57. }else{
  58. return -1;
  59. }
  60. }
  61. /**
  62. * 获取SD卡中可用的容量
  63. * @return 可用的容量;-1:SD卡不可用
  64. */
  65. @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
  66. public static long getAvailableSize(){
  67. if(isAvailable()){
  68. StatFs statFs = new StatFs(getRootDirectory().getPath());
  69. if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1){
  70. return statFs.getAvailableBlocks() * statFs.getBlockSize();
  71. }else{
  72. return statFs.getAvailableBlocks() * statFs.getBlockSize();
  73. }
  74. }else{
  75. return -1;
  76. }
  77. }
  78. }

JsonUtils

  1. package com.alpha.lib_sdk.app.tool;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. import org.json.JSONArray;
  8. import org.json.JSONException;
  9. import org.json.JSONObject;
  10. import android.content.Context;
  11. import com.google.gson.Gson;
  12. /**
  13. * json 和 实体类之间的相互转换
  14. *
  15. * @author 00
  16. */
  17. public class JsonUtil {
  18. /**
  19. * 将一个实体对象 转换成一个json字符串 提示对象中可包含集合
  20. *
  21. * @param t 实体类
  22. * @return
  23. */
  24. public static <T> String beanToJson(T t) {
  25. Gson gson = new Gson();
  26. String json = gson.toJson(t);
  27. return json;
  28. }
  29. /**
  30. * 将一个json字符串 转换成一个实体类对象 可包含list
  31. *
  32. * @param json
  33. * @param class1
  34. * @return
  35. */
  36. public static <T> T jsonToBean(String json, Class<T> class1) {
  37. T t = null;
  38. try {
  39. Gson gson = new Gson();
  40. t = class1.newInstance();
  41. t = gson.fromJson(json, class1);
  42. } catch (java.lang.InstantiationException e) {
  43. e.printStackTrace();
  44. } catch (IllegalAccessException e) {
  45. e.printStackTrace();
  46. }
  47. return t;
  48. }
  49. /**
  50. * 将一个json字符串 转换成一个实体类集合 可包含list
  51. * [{},{},{}]
  52. * @param jsonArray
  53. * @param class1
  54. * @return
  55. */
  56. public static <T> List<T> jsonToBeanArray(String jsonArray, Class<T> class1) {
  57. List<T> list = new ArrayList<>();
  58. T t = null;
  59. try {
  60. JSONArray array = new JSONArray(jsonArray);
  61. for (int i = 0; i < array.length(); i++) {
  62. JSONObject object = array.getJSONObject(i);
  63. Gson gson = new Gson();
  64. t = class1.newInstance();
  65. t = gson.fromJson(object.toString(), class1);
  66. list.add(t);
  67. }
  68. } catch (java.lang.InstantiationException e) {
  69. e.printStackTrace();
  70. } catch (IllegalAccessException e) {
  71. e.printStackTrace();
  72. } catch (JSONException e) {
  73. e.printStackTrace();
  74. }
  75. return list;
  76. }
  77. /**
  78. * 将json字符串转换成一个json对象
  79. *
  80. * @param str
  81. * @return
  82. */
  83. public static JSONObject stringToJson(String str) {
  84. try {
  85. return new JSONObject(str);
  86. } catch (JSONException e) {
  87. e.printStackTrace();
  88. return null;
  89. }
  90. }
  91. public static String getString(InputStream is) {
  92. try {
  93. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  94. byte[] buffer = new byte[1024];
  95. int len = -1;
  96. while ((len = is.read(buffer)) != -1) {
  97. baos.write(buffer, 0, len);
  98. }
  99. byte[] byteArray = baos.toByteArray();
  100. //String str = new String(byteArray);
  101. return new String(byteArray, "utf-8");
  102. } catch (IOException e) {
  103. e.printStackTrace();
  104. }
  105. return "";
  106. }
  107. /**
  108. * 从assert文件夹中读取json文件,然后转化为json对象
  109. *
  110. * @throws Exception
  111. */
  112. public static JSONObject getJsonDataFromAssets(Context context, String jsonFileName) throws Exception {
  113. JSONObject mJsonObj = null;
  114. StringBuffer sb = new StringBuffer();
  115. InputStream is = context.getAssets().open(jsonFileName);
  116. int len = -1;
  117. byte[] buf = new byte[1024];
  118. while ((len = is.read(buf)) != -1) {
  119. sb.append(new String(buf, 0, len, "UTF-8"));
  120. }
  121. is.close();
  122. mJsonObj = new JSONObject(sb.toString());
  123. return mJsonObj;
  124. }
  125. public static String getJSONStrFromList(List list){
  126. Gson gson = new Gson();
  127. String str = gson.toJson(list);
  128. return str;
  129. }
  130. }

RequestManager

  1. package com.alpha.lib_sdk.app.net;
  2. import android.content.Context;
  3. import android.os.Handler;
  4. import android.util.Log;
  5. import com.alpha.lib_sdk.app.log.LogUtils;
  6. import com.alpha.lib_sdk.app.tool.SortTools;
  7. import com.alpha.lib_sdk.app.tool.SystemUtils;
  8. import java.io.File;
  9. import java.io.FileOutputStream;
  10. import java.io.IOException;
  11. import java.io.InputStream;
  12. import java.security.cert.CertificateException;
  13. import java.util.HashMap;
  14. import java.util.concurrent.TimeUnit;
  15. import javax.net.ssl.HostnameVerifier;
  16. import javax.net.ssl.SSLContext;
  17. import javax.net.ssl.SSLSession;
  18. import javax.net.ssl.SSLSocketFactory;
  19. import javax.net.ssl.TrustManager;
  20. import javax.net.ssl.X509TrustManager;
  21. import okhttp3.Call;
  22. import okhttp3.Callback;
  23. import okhttp3.FormBody;
  24. import okhttp3.MediaType;
  25. import okhttp3.MultipartBody;
  26. import okhttp3.OkHttpClient;
  27. import okhttp3.Request;
  28. import okhttp3.RequestBody;
  29. import okhttp3.Response;
  30. import okio.Buffer;
  31. import okio.BufferedSink;
  32. import okio.Okio;
  33. import okio.Source;
  34. /**
  35. * Created by kenway on 17/5/22 14:09
  36. * Email : xiaokai090704@126.com
  37. * 请求管理类 okHttpClient
  38. */
  39. public class RequestManager {
  40. private static final String TAG = "RequestManager";
  41. private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
  42. private static final MediaType MEDIA_OBJECT_STREAM = MediaType.parse("application/octet-stream");//mdiatype 这个需要和服务端保持一致 你需要看下你们服务器设置的ContentType 是不是这个,他们设置的是哪个 我们要和他们保持一致
  43. private static RequestManager mInstance;//单例引用
  44. private OkHttpClient mOkHttpClient;//okHttpClient;
  45. private Handler okHttpHandler;//全局处理子线程和M线程通信
  46. private RequestManager(Context context) {
  47. //初始化OkHttpClient
  48. mOkHttpClient = gettUnsafeOkHttpClient().newBuilder()
  49. .connectTimeout(10, TimeUnit.SECONDS)
  50. .readTimeout(10, TimeUnit.SECONDS)
  51. .writeTimeout(10, TimeUnit.SECONDS)
  52. .build();
  53. okHttpHandler = new Handler(context.getMainLooper());//属于主线程的Handler
  54. }
  55. private static OkHttpClient gettUnsafeOkHttpClient() {
  56. try {
  57. // Create a trust manager that does not validate certificate chains
  58. final TrustManager[] trustAllCerts = new TrustManager[]{
  59. new X509TrustManager() {
  60. @Override
  61. public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
  62. }
  63. @Override
  64. public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
  65. }
  66. @Override
  67. public java.security.cert.X509Certificate[] getAcceptedIssuers() {
  68. return new java.security.cert.X509Certificate[]{};
  69. }
  70. }
  71. };
  72. // Install the all-trusting trust manager
  73. final SSLContext sslContext = SSLContext.getInstance("SSL");
  74. sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
  75. // Create an ssl socket factory with our all-trusting manager
  76. final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
  77. OkHttpClient.Builder builder = new OkHttpClient.Builder();
  78. builder.sslSocketFactory(sslSocketFactory);
  79. builder.hostnameVerifier(new HostnameVerifier() {
  80. @Override
  81. public boolean verify(String hostname, SSLSession session) {
  82. return true;
  83. }
  84. });
  85. OkHttpClient okHttpClient = builder.build();
  86. return okHttpClient;
  87. } catch (Exception e) {
  88. throw new RuntimeException(e);
  89. }
  90. }
  91. /**
  92. * 获取网络请求管理类实例
  93. *
  94. * @param context
  95. * @return
  96. */
  97. public static RequestManager getInstance(Context context) {
  98. RequestManager inst = mInstance;
  99. if (inst == null) {
  100. synchronized (RequestManager.class) {
  101. inst = mInstance;
  102. if (inst == null) {
  103. inst = new RequestManager(context.getApplicationContext());
  104. mInstance = inst;
  105. }
  106. }
  107. }
  108. return inst;
  109. }
  110. public <T> Call requestGetWXData(String actionUrl, final ReqCallBack<T> callBack) {
  111. try {
  112. String requestUrl = actionUrl;
  113. Request request = new Request.Builder().url(actionUrl).get().build();
  114. final Call call = mOkHttpClient.newCall(request);
  115. call.enqueue(new Callback() {
  116. @Override
  117. public void onFailure(Call call, IOException e) {
  118. failedCallBack("访问失败", callBack);
  119. LogUtils.e(TAG, e.toString());
  120. }
  121. @Override
  122. public void onResponse(Call call, Response response) throws IOException {
  123. if (response.isSuccessful()) {
  124. String string = response.body().string();
  125. LogUtils.e(TAG, "response ----->" + string);
  126. successCallBack((T) string, callBack);
  127. } else {
  128. failedCallBack("服务器错误", callBack);
  129. }
  130. }
  131. });
  132. return call;
  133. } catch (Exception e) {
  134. LogUtils.e(TAG, e.toString());
  135. }
  136. return null;
  137. }
  138. /**
  139. * 获取省市县的get请求
  140. *
  141. * @param actionUrl
  142. * @param callBack
  143. * @param <T>
  144. * @return
  145. */
  146. public <T> Call requestGet(String actionUrl, final ReqCallBack<T> callBack) {
  147. try {
  148. final Request request = new Request.Builder().url(actionUrl).get().build();
  149. final Call call = mOkHttpClient.newCall(request);
  150. call.enqueue(new Callback() {
  151. @Override
  152. public void onFailure(Call call, IOException e) {
  153. failedCallBack("访问失败", callBack);
  154. LogUtils.e(TAG, "这里发生了错误==" + e.toString());
  155. }
  156. @Override
  157. public void onResponse(Call call, Response response) throws IOException {
  158. if (response.isSuccessful()) {
  159. String string = response.body().string();
  160. successCallBack((T) string, callBack);
  161. } else {
  162. failedCallBack("服务器错误", callBack);
  163. }
  164. }
  165. });
  166. return call;
  167. } catch (Exception e) {
  168. LogUtils.e(TAG, e.toString());
  169. }
  170. return null;
  171. }
  172. /**
  173. * okHttp post异步请求 发送json数据
  174. *
  175. * @param actionUrl 接口地址
  176. * @param json 请求参数json 数据 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  177. * @param callBack 请求返回数据回调
  178. * @param <T> 数据泛型
  179. * @return
  180. */
  181. public <T> Call requestPostByJsonAsyn(String actionUrl, String json, final ReqCallBack<T> callBack) {
  182. try {
  183. RequestBody body = RequestBody.create(JSON, json);
  184. Request request = new Request.Builder().url(actionUrl).post(body).build();
  185. final Call call = mOkHttpClient.newCall(request);
  186. call.enqueue(new Callback() {
  187. @Override
  188. public void onFailure(Call call, IOException e) {
  189. failedCallBack("访问失败", callBack);
  190. LogUtils.e(TAG, e.toString());
  191. }
  192. @Override
  193. public void onResponse(Call call, Response response) throws IOException {
  194. if (response.isSuccessful()) {
  195. String string = response.body().string();
  196. LogUtils.e(TAG, "response ----->" + string);
  197. successCallBack((T) string, callBack);
  198. } else {
  199. failedCallBack("服务器错误", callBack);
  200. }
  201. }
  202. });
  203. return call;
  204. } catch (Exception e) {
  205. LogUtils.e(e.toString());
  206. }
  207. return null;
  208. }
  209. /**
  210. * okHttp post异步请求表单提交
  211. * 论坛模块使用
  212. *
  213. * @param actionUrl 接口地址
  214. * @param paramsMap 请求参数
  215. * @param callBack 请求返回数据回调
  216. * @param <T> 数据泛型
  217. * @return
  218. */
  219. public <T> Call requestPostByAsynWithForm(String actionUrl, HashMap<String, String> paramsMap, final ReqCallBack<T> callBack) {
  220. paramsMap.put(ForumNetPostUtil.KEY_TICK, SystemUtils.getCurrentTimeMillis() + "");
  221. paramsMap.put(ForumNetPostUtil.KEY_RANDOM, ForumNetPostUtil.createRandom(false, 12));//12位数字和字母随机数据
  222. String sign = SortTools.getSign(paramsMap);
  223. paramsMap.put(ForumNetPostUtil.KEY_SIGN, sign);
  224. paramsMap.put(ForumNetPostUtil.KEY_APPID, JsonEncryptUtil.getAPPID());
  225. LogUtils.e("论坛发送数据"+paramsMap.toString());
  226. try {
  227. FormBody.Builder builder = new FormBody.Builder();
  228. for (String key : paramsMap.keySet()) {
  229. builder.add(key, paramsMap.get(key));
  230. }
  231. RequestBody formBody = builder.build();
  232. String requestUrl = actionUrl;
  233. Request request = new Request.Builder().url(actionUrl).post(formBody).build();
  234. final Call call = mOkHttpClient.newCall(request);
  235. call.enqueue(new Callback() {
  236. @Override
  237. public void onFailure(Call call, IOException e) {
  238. failedCallBack("访问失败", callBack);
  239. LogUtils.e(TAG, e.toString());
  240. }
  241. @Override
  242. public void onResponse(Call call, Response response) throws IOException {
  243. if (response.isSuccessful()) {
  244. String string = response.body().string();
  245. successCallBack((T) string, callBack);
  246. } else {
  247. LogUtils.e("错误原因," + response.toString());
  248. failedCallBack("服务器错误", callBack);
  249. }
  250. }
  251. });
  252. return call;
  253. } catch (Exception e) {
  254. LogUtils.e(TAG, e.toString());
  255. }
  256. return null;
  257. }
  258. /**
  259. * okHttp post异步请求表单提交
  260. *
  261. * @param actionUrl 接口地址
  262. * @param paramsMap 请求参数
  263. * @param callBack 请求返回数据回调
  264. * @param <T> 数据泛型
  265. * @return
  266. */
  267. public <T> Call requestPostByCommonAsynWithForm(String actionUrl, HashMap<String, String> paramsMap, final ReqCallBack<T> callBack) {
  268. try {
  269. FormBody.Builder builder = new FormBody.Builder();
  270. for (String key : paramsMap.keySet()) {
  271. builder.add(key, paramsMap.get(key));
  272. }
  273. RequestBody formBody = builder.build();
  274. String requestUrl = actionUrl;
  275. Request request = new Request.Builder().url(actionUrl).post(formBody).build();
  276. final Call call = mOkHttpClient.newCall(request);
  277. call.enqueue(new Callback() {
  278. @Override
  279. public void onFailure(Call call, IOException e) {
  280. failedCallBack("访问失败", callBack);
  281. LogUtils.e(TAG, e.toString());
  282. }
  283. @Override
  284. public void onResponse(Call call, Response response) throws IOException {
  285. if (response.isSuccessful()) {
  286. String string = response.body().string();
  287. successCallBack((T) string, callBack);
  288. } else {
  289. LogUtils.e("错误原因," + response.toString());
  290. failedCallBack("服务器错误", callBack);
  291. }
  292. }
  293. });
  294. return call;
  295. } catch (Exception e) {
  296. LogUtils.e(TAG, e.toString());
  297. }
  298. return null;
  299. }
  300. /**
  301. * 统一同意处理成功信息
  302. *
  303. * @param result
  304. * @param callBack
  305. * @param <T>
  306. */
  307. private <T> void successCallBack(final T result, final ReqCallBack<T> callBack) {
  308. okHttpHandler.post(new Runnable() {
  309. @Override
  310. public void run() {
  311. if (callBack != null) {
  312. callBack.onReqSuccess(result);
  313. }
  314. }
  315. });
  316. }
  317. /**
  318. * okHttp post异步上传文件。带参数
  319. *
  320. * @param actionUrl 接口地址
  321. * @param paramsMap 请求参数
  322. * @param callBack 请求返回数据回调
  323. * @param <T> 数据泛型
  324. * @return
  325. */
  326. public <T> Call uploadFile(String actionUrl, HashMap<String, Object> paramsMap, final ReqCallBack<T> callBack) {
  327. try {
  328. //带参数上传文件
  329. MultipartBody.Builder builder_pic = new MultipartBody.Builder();
  330. builder_pic.setType(MultipartBody.FORM);
  331. LogUtils.e(paramsMap.toString());
  332. //追加参数
  333. for (String key : paramsMap.keySet()) {
  334. Object object = paramsMap.get(key);
  335. if (!(object instanceof File)) {
  336. builder_pic.addFormDataPart(key, object.toString());
  337. } else {
  338. File file = (File) object;
  339. builder_pic.addFormDataPart(key, file.getName(), RequestBody.create(null, file));
  340. }
  341. }
  342. //创建RequestBody
  343. RequestBody body = builder_pic.build();
  344. //创建Request
  345. final Request request = new Request.Builder().url(actionUrl).post(body).build();
  346. final Call call = mOkHttpClient.newCall(request);
  347. call.enqueue(new Callback() {
  348. @Override
  349. public void onFailure(Call call, IOException e) {
  350. failedCallBack("访问失败", callBack);
  351. LogUtils.e(TAG, e.toString());
  352. }
  353. @Override
  354. public void onResponse(Call call, Response response) throws IOException {
  355. if (response.isSuccessful()) {
  356. String string = response.body().string();
  357. LogUtils.e("onResponse--->" + string);
  358. successCallBack((T) string, callBack);
  359. } else {
  360. failedCallBack("服务器错误", callBack);
  361. }
  362. }
  363. });
  364. return call;
  365. } catch (Exception e) {
  366. LogUtils.e(e.toString());
  367. }
  368. return null;
  369. }
  370. /**
  371. * 带参数带进度上传文件
  372. *
  373. * @param actionUrl
  374. * @param paramsMap
  375. * @param callBack
  376. * @param <T>
  377. */
  378. public <T> void upLoadFileHasProgress(String actionUrl, HashMap<String, Object> paramsMap, final ReqProgressCallBack<T> callBack) {
  379. try {
  380. //补全请求地址
  381. MultipartBody.Builder builder = new MultipartBody.Builder();
  382. //设置类型
  383. builder.setType(MultipartBody.FORM);
  384. //追加参数
  385. for (String key : paramsMap.keySet()) {
  386. Object object = paramsMap.get(key);
  387. if (!(object instanceof File)) {
  388. builder.addFormDataPart(key, object.toString());
  389. } else {
  390. File file = (File) object;
  391. builder.addFormDataPart(key, file.getName(), createProgressRequestBody(MEDIA_OBJECT_STREAM, file, callBack));
  392. }
  393. }
  394. //创建RequestBody
  395. RequestBody body = builder.build();
  396. //创建Request
  397. final Request request = new Request.Builder().url(actionUrl).post(body).build();
  398. final Call call = mOkHttpClient.newBuilder().writeTimeout(50, TimeUnit.SECONDS).build().newCall(request);
  399. call.enqueue(new Callback() {
  400. @Override
  401. public void onFailure(Call call, IOException e) {
  402. LogUtils.e(e.toString());
  403. failedCallBack("上传失败", callBack);
  404. }
  405. @Override
  406. public void onResponse(Call call, Response response) throws IOException {
  407. LogUtils.e("上传成功===response.isSuccessful()==" + response.isSuccessful());
  408. if (response.isSuccessful()) {
  409. String string = response.body().string();
  410. LogUtils.e("response ----->" + string);
  411. successCallBack((T) string, callBack);
  412. } else {
  413. LogUtils.e("response.toString==" + response.toString());
  414. failedCallBack("上传失败", callBack);
  415. }
  416. }
  417. });
  418. } catch (Exception e) {
  419. LogUtils.e(e.toString());
  420. }
  421. }
  422. /**
  423. * 不带进度文件下载
  424. *
  425. * @param callBack
  426. * @param <T>
  427. */
  428. public <T> void downLoadFile(String fileUrl, final String destFileDir, final ReqCallBack<T> callBack) {
  429. final String fileName = fileUrl;
  430. final File file = new File(destFileDir, fileName);
  431. // LogUtils.e("filePath==" + file.getAbsolutePath());
  432. if (file.exists()) {
  433. LogUtils.e("该文件已存在");
  434. successCallBack((T) file, callBack);
  435. return;
  436. }
  437. final Request request = new Request.Builder().url(fileUrl).build();
  438. final Call call = mOkHttpClient.newCall(request);
  439. call.enqueue(new Callback() {
  440. @Override
  441. public void onFailure(Call call, IOException e) {
  442. Log.e(TAG, e.toString());
  443. failedCallBack("下载失败", callBack);
  444. }
  445. @Override
  446. public void onResponse(Call call, Response response) throws IOException {
  447. InputStream is = null;
  448. byte[] buf = new byte[2048];
  449. int len = 0;
  450. FileOutputStream fos = null;
  451. try {
  452. long total = response.body().contentLength();
  453. long current = 0;
  454. is = response.body().byteStream();
  455. fos = new FileOutputStream(file);
  456. while ((len = is.read(buf)) != -1) {
  457. current += len;
  458. fos.write(buf, 0, len);
  459. Log.e(TAG, "current------>" + current);
  460. }
  461. fos.flush();
  462. successCallBack((T) file, callBack);
  463. } catch (IOException e) {
  464. Log.e(TAG, e.toString());
  465. failedCallBack("下载失败", callBack);
  466. } finally {
  467. try {
  468. if (is != null) {
  469. is.close();
  470. }
  471. if (fos != null) {
  472. fos.close();
  473. }
  474. } catch (IOException e) {
  475. Log.e(TAG, e.toString());
  476. }
  477. }
  478. }
  479. });
  480. }
  481. /**
  482. * 统一处理失败信息
  483. *
  484. * @param errorMsg
  485. * @param callBack
  486. * @param <T>
  487. */
  488. private <T> void failedCallBack(final String errorMsg, final ReqCallBack<T> callBack) {
  489. okHttpHandler.post(new Runnable() {
  490. @Override
  491. public void run() {
  492. if (callBack != null) {
  493. callBack.onReqFailed(errorMsg);
  494. }
  495. }
  496. });
  497. }
  498. public <T> RequestBody createProgressRequestBody(final MediaType contentType, final File file, final ReqProgressCallBack<T> callBack) {
  499. return new RequestBody() {
  500. @Override
  501. public MediaType contentType() {
  502. return contentType;
  503. }
  504. @Override
  505. public long contentLength() throws IOException {
  506. return file.length();
  507. }
  508. @Override
  509. public void writeTo(BufferedSink sink) throws IOException {
  510. Source source;
  511. try {
  512. source = Okio.source(file);
  513. Buffer buf = new Buffer();
  514. long remaining = contentLength();
  515. long current = 0;
  516. for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) {
  517. sink.write(buf, readCount);
  518. current += readCount;
  519. progressCallBack(remaining, current, callBack);
  520. }
  521. } catch (Exception e) {
  522. e.printStackTrace();
  523. }
  524. }
  525. };
  526. }
  527. /**
  528. * 统一处理进度信息
  529. *
  530. * @param total 总计大小
  531. * @param current 当前进度
  532. * @param callBack
  533. * @param <T>
  534. */
  535. private <T> void progressCallBack(final long total, final long current, final ReqProgressCallBack<T> callBack) {
  536. okHttpHandler.post(new Runnable() {
  537. @Override
  538. public void run() {
  539. if (callBack != null) {
  540. callBack.onProgress(total, current);
  541. }
  542. }
  543. });
  544. }
  545. }
  546. package com.alpha.lib_sdk.app.net;
  547. public interface ReqCallBack<T> {
  548. /**
  549. * 响应成功
  550. */
  551. void onReqSuccess(T result);
  552. /**
  553. * 响应失败
  554. */
  555. void onReqFailed(String errorMsg);
  556. }

manifest.xml

  1. <!--版本更新的服务-->
  2. <service android:name=".version.UpdateVersionService" />
  3. <receiver android:name="com.alpha.lib_sdk.app.net.broadcast.NetWorkChangeBroadcasetReceiver">
  4. <intent-filter android:priority="1000">      
  5. <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
  6. </intent-filter>
  7. </receiver>

UpdateVersionServices

  1. package com.alpha.alphaapp.version;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import com.alpha.alphaapp.R;
  5. import com.alpha.alphaapp.app.MyApplication;
  6. import com.alpha.lib_sdk.app.log.LogUtils;
  7. import com.alpha.lib_sdk.app.unitily.SDCardUtils;
  8. import com.alpha.lib_sdk.app.unitily.ToastUtils;
  9. import com.lidroid.xutils.HttpUtils;
  10. import com.lidroid.xutils.exception.HttpException;
  11. import com.lidroid.xutils.http.HttpHandler;
  12. import com.lidroid.xutils.http.ResponseInfo;
  13. import com.lidroid.xutils.http.callback.RequestCallBack;
  14. import android.app.Notification;
  15. import android.app.NotificationManager;
  16. import android.app.PendingIntent;
  17. import android.app.Service;
  18. import android.content.Intent;
  19. import android.os.Bundle;
  20. import android.os.IBinder;
  21. import android.view.View;
  22. import android.widget.RemoteViews;
  23. /**
  24. * @author wenjie
  25. * 下载新版本的服务类
  26. */
  27. public class UpdateVersionService extends Service {
  28. private static final String TAG = "UpdateVersionService";
  29. private NotificationManager nm;
  30. private Notification notification;
  31. //标题标识
  32. private int titleId = 0;
  33. //安装文件
  34. private File updateFile;
  35. private static HttpHandler<File> httpHandler;
  36. private HttpUtils httpUtils;
  37. private long initTotal = 0;//文件的总长度
  38. @Override
  39. public void onCreate() {
  40. super.onCreate();
  41. httpUtils = new HttpUtils();
  42. updateFile = new File(SDCardUtils.getRootDirectory() + "/updateVersion/"+ MyApplication.APP_NAME_E);
  43. if(!updateFile.exists()){
  44. //先得到文件的上级目录,并创建上级目录,在创建文件
  45. updateFile.getParentFile().mkdir();
  46. try {
  47. //创建文件
  48. updateFile.createNewFile();
  49. } catch (IOException e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
  54. notification = new Notification();
  55. notification.icon = R.drawable.icon512;
  56. notification.tickerText = "开始下载";
  57. notification.when = System.currentTimeMillis();
  58. notification.contentView = new RemoteViews(getPackageName(), R.layout.notification_version);
  59. }
  60. @Override
  61. public int onStartCommand(Intent intent, int flags, int startId) {
  62. Bundle bundle = intent.getExtras();
  63. String url = bundle.getString("downloadUrl");
  64. nm.notify(titleId, notification);
  65. downLoadFile(url);
  66. return super.onStartCommand(intent, flags, startId);
  67. }
  68. public void downLoadFile(String url) {
  69. httpHandler = httpUtils.download(url, updateFile.getAbsolutePath(), true, false, new RequestCallBack<File>() {
  70. @Override
  71. public void onSuccess(ResponseInfo<File> response) {
  72. ToastUtils.showToast(getApplicationContext(), "下载完成!");
  73. // 更改文字
  74. notification.contentView.setTextViewText(R.id.msg, "下载完成!点击安装");
  75. // notification.contentView.setViewVisibility(R.id.btnStartStop, View.GONE);
  76. // notification.contentView.setViewVisibility(R.id.btnCancel,View.GONE);
  77. // 发送消息
  78. nm.notify(0, notification);
  79. stopSelf();
  80. //收起通知栏
  81. // UpdateVersionUtil.collapseStatusBar(UpdateVersionService.this);
  82. //自动安装新版本
  83. Intent installIntent = ApkUtils.getInstallIntent(UpdateVersionService.this,updateFile);
  84. startActivity(installIntent);
  85. }
  86. @Override
  87. public void onFailure(HttpException error, String msg) {
  88. LogUtils.e("下载失败 error=="+error.getMessage());
  89. LogUtils.e("下载失败 msg=="+msg);
  90. //网络连接错误
  91. if (error.getExceptionCode() == 0) {
  92. // 更改文字
  93. notification.contentView.setTextViewText(R.id.msg, "网络异常!请检查网络设置!");
  94. } else if (error.getExceptionCode() == 416) {//文件已经下载完毕
  95. // 更改文字
  96. notification.contentView.setTextViewText(R.id.msg, MyApplication.APP_NAME_C);
  97. // 更改文字
  98. notification.contentView.setTextViewText(R.id.bartext, "检测到新版本已经下载完成,点击即安装!");
  99. // 隐藏进度条
  100. notification.contentView.setViewVisibility(R.id.progressBar1, View.GONE);
  101. Intent intent = ApkUtils.getInstallIntent(UpdateVersionService.this,updateFile);
  102. PendingIntent pendingIntent = PendingIntent.getActivity(UpdateVersionService.this, 0, intent, 0);
  103. notification.flags = Notification.FLAG_AUTO_CANCEL;//点击通知栏之后 消失
  104. notification.contentIntent = pendingIntent;//启动指定意图
  105. }
  106. // 发送消息
  107. ToastUtils.showToast(getApplicationContext(), "下载失败,请检查网络!");
  108. nm.notify(0, notification);
  109. }
  110. @Override
  111. public void onLoading(long total, long current, boolean isUploading) {
  112. if (initTotal == 0) {//说明第一次开始下载
  113. initTotal = total;
  114. }
  115. if (initTotal != total) {//说明下载过程中暂停过,文件的总长度出现问题 就把初始的文件的长度赋值给他重新计算已经下载的比例
  116. total = initTotal;
  117. }
  118. long l = current * 100 / total;
  119. notification.contentView.setTextViewText(R.id.msg, "正在下载:"+MyApplication.APP_NAME_C);
  120. LogUtils.e("正在下载:"+ l + "%");
  121. // 更改文字
  122. notification.contentView.setTextViewText(R.id.bartext, l + "%");
  123. // 更改进度条
  124. notification.contentView.setProgressBar(R.id.progressBar1, 100, (int) l, false);
  125. // 发送消息
  126. nm.notify(0, notification);
  127. }
  128. @Override
  129. public void onStart() {
  130. notification.contentView.setTextViewText(R.id.msg, "开始下载:"+MyApplication.APP_NAME_C);
  131. ToastUtils.showToast(getApplicationContext(),"开始下载:"+MyApplication.APP_NAME_C);
  132. nm.notify(titleId, notification);
  133. }
  134. });
  135. }
  136. public static HttpHandler<File> getHandler() {
  137. return httpHandler;
  138. }
  139. @Override
  140. public void onDestroy() {
  141. //下载完成时,清除该通知,自动安装
  142. nm.cancel(titleId);
  143. LogUtils.e(TAG, "UpdateVersionService----onDestroy");
  144. super.onDestroy();
  145. }
  146. @Override
  147. public IBinder onBind(Intent intent) {
  148. return null;
  149. }
  150. }

发表评论

表情:
评论列表 (有 0 条评论,333人围观)

还没有评论,来说两句吧...

相关阅读