package com.gh.common.util; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.net.wifi.WifiManager; import android.os.Build; import android.os.Environment; import android.provider.Settings; import android.telephony.TelephonyManager; import android.text.TextUtils; import com.gh.common.constant.Config; import com.gh.gamecenter.retrofit.JSONObjectResponse; import com.gh.gamecenter.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; import com.gh.gamecenter.retrofit.StringResponse; import com.tencent.stat.StatConfig; import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; import okhttp3.MediaType; import okhttp3.RequestBody; import okhttp3.ResponseBody; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Func1; import rx.schedulers.Schedulers; public class TokenUtils { // 注册设备 public static synchronized void register(final Context context) { Map params = new HashMap<>(); params.put("MANUFACTURER", Build.MANUFACTURER); params.put("MODEL", Build.MODEL); params.put("ANDROID_SDK", String.valueOf(Build.VERSION.SDK_INT)); params.put("ANDROID_VERSION", Build.VERSION.RELEASE); String android_id = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); if (!TextUtils.isEmpty(android_id)) { params.put("ANDROID_ID", android_id); } String imei = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId(); if (!TextUtils.isEmpty(imei)) { params.put("IMEI", imei); } WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); String mac = wm.getConnectionInfo().getMacAddress(); if (!TextUtils.isEmpty(mac) || !":::::".equals(mac)) { params.put("MAC", mac); } else { SharedPreferences sp = context.getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); sp.edit().putBoolean("isUploadMac", false).apply(); } String mid = StatConfig.getMid(context); if (!TextUtils.isEmpty(mid) || !"0".equals(mid)) { params.put("MTA_ID", mid); } else { SharedPreferences sp = context.getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); sp.edit().putBoolean("isUploadMid", false).apply(); } RequestBody body = RequestBody.create(MediaType.parse("application/json"), new JSONObject(params).toString()); RetrofitManager.getUser().postRegister(body) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .subscribe(new JSONObjectResponse() { @Override public void onResponse(JSONObject response) { if (response.length() != 0) { try { // 保存device_id saveDeviceId(context, response.getString("device_id")); Utils.log("device_id = " + response.getString("device_id")); } catch (JSONException e) { e.printStackTrace(); } } } }); } // 获取用户token public static synchronized Observable getToken(final Context context, boolean isCheck) { String token = null; if (isCheck) { SharedPreferences sp = context.getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); token = sp.getString("token", null); if (token != null) { long expire = sp.getLong("token_expire", 0) * 1000 - 10 * 1000; long time = Utils.getTime(context); // 判断token是否过期 if (time >= expire) { // token已过期 token = null; } } } if (token == null) { Map params = new HashMap<>(); params.put("device_id", getDeviceId(context)); return RetrofitManager.getUser() .postLogin(RequestBody.create(MediaType.parse("application/json"), new JSONObject(params).toString())) .flatMap(new Func1>() { @Override public Observable call(ResponseBody responseBody) { String value = null; try { SharedPreferences sp = context.getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); Editor editor = sp.edit(); JSONObject response = new JSONObject(responseBody.string()); editor.putString("user_name", response.getString("name")); editor.putString("user_icon", response.getString("icon")); response = response.getJSONObject("token"); editor.putString("token", response.getString("value")); editor.putLong("token_expire", response.getLong("expire")); editor.apply(); // 服务器返回的token和本地已存的token相同,更新本地时间 getTime(context); value = response.getString("value"); } catch (IOException | JSONException e) { e.printStackTrace(); } return Observable.just(value); } }).onErrorResumeNext(new Func1>() { @Override public Observable call(Throwable throwable) { return Observable.error(throwable); } }); } return Observable.just(token); } // 检查设备信息是否已经上传完整 public static synchronized void checkDeviceInfo(Context context, String token) { final SharedPreferences sp = context.getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); final HashMap params = new HashMap<>(); if (!sp.getBoolean("isUploadExtra", false)) { params.put("MANUFACTURER", Build.MANUFACTURER); params.put("MODEL", Build.MODEL); params.put("ANDROID_SDK", String.valueOf(Build.VERSION.SDK_INT)); params.put("ANDROID_VERSION", Build.VERSION.RELEASE); } if (!sp.getBoolean("isUploadMac", true)) { WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); String mac = wm.getConnectionInfo().getMacAddress(); if (!TextUtils.isEmpty(mac) || !":::::".equals(mac)) { params.put("MAC", mac); } } if (!sp.getBoolean("isUploadMid", true)) { String mid = StatConfig.getMid(context); if (!TextUtils.isEmpty(mid) || !"0".equals(mid)) { params.put("MTA_ID", mid); } } if (params.size() != 0) { RequestBody body = RequestBody.create(MediaType.parse("application/json"), new JSONObject(params).toString()); RetrofitManager.getUser().postDevice(token, body, TokenUtils.getDeviceId(context)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Response() { @Override public void onResponse(ResponseBody response) { SharedPreferences.Editor editor = sp.edit(); editor.putBoolean("isUploadExtra", true); editor.putBoolean("isUploadMac", true); editor.putBoolean("isUploadMid", true); editor.apply(); } }); } } // 获取服务器时间 public static synchronized void getTime(Context context) { final SharedPreferences sp = context.getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); RetrofitManager.getApi().getTime() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new StringResponse() { @Override public void onResponse(String response) { if (response.matches("^[0-9]{10}$")) { try { Editor editor = sp.edit(); editor.putLong("server_time", Long.parseLong(response)); editor.putLong("client_time", System.currentTimeMillis() / 1000); editor.apply(); } catch (NumberFormatException e) { e.printStackTrace(); } } } }); } public static synchronized void saveDeviceId(Context context, String device_id){ saveSharedPreferences(context, device_id); saveDataFile(context, device_id); svaeSDCard(device_id, "/gh-uuid");// SDCard根目录 svaeSDCard(device_id, "/system"); // SDCard system目录 svaeSDCard(device_id, "/data"); // SDCard data目录 } //将uuid存到sp private static void saveSharedPreferences(Context context, String device_id) { SharedPreferences sp = context.getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); SharedPreferences.Editor edit = sp.edit(); edit.putString("uuid", device_id); edit.apply(); Utils.log("saveDeviceId", "保存成功SP"); } //将uuid存到data/data/PackageName/files文件夹下 private static void saveDataFile(Context context, String device_id) { FileOutputStream fops; try { fops = context.openFileOutput("uuid", Context.MODE_PRIVATE); fops.write(device_id.getBytes()); fops.close(); Utils.log("saveDeviceId", "保存成功DataFile"); } catch (Exception e) { Utils.log("保存uuid到data/data/PackageName/files文件异常" + e.toString()); e.printStackTrace(); } } //将uuid存到SD卡 private static void svaeSDCard(String device_id, String saveDir) { File sdCardDir = Environment.getExternalStorageDirectory(); String path = sdCardDir.getPath() + saveDir; File file = new File(path); if (!file.exists()){ file.mkdirs(); } // 判断文件是否存在,存在则删除 File uuidFile = new File(path +"/uuid"); if (uuidFile.isFile() && uuidFile.exists()){ Utils.log(saveDir + "文件夹里的文件存在,执行删除操作"); uuidFile.delete(); } File writeFile = new File(file, "uuid"); FileOutputStream fos; try { fos = new FileOutputStream(writeFile); fos.write(device_id.getBytes()); fos.close(); Utils.log("saveDeviceId", "保存成功SDCard"+"目录为:"+saveDir); } catch (Exception e) { Utils.log("保存uuid到SDCard异常" + saveDir + e.toString()); e.printStackTrace(); } } public static synchronized String getDeviceId(Context context) { return loadSharedPreferences(context, false); } //读取SharedPreferences的uuid private static String loadSharedPreferences(Context context, boolean isCheck) { SharedPreferences sp = context.getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE); String uuid = sp.getString("uuid", null); if (isCheck){ return uuid; } if (uuid == null){ return loadDataFile(context, false); } Utils.log("getDeviceId", "获取成功SP" + uuid); return uuid; } //读取data/data/PackageName/files的uuid private static String loadDataFile(Context context, boolean isCheck) { File file = new File(context.getFilesDir(), "uuid"); if (file.exists()){ try { FileInputStream fis = new FileInputStream(file); byte[] b = new byte[1024]; int count = -1; String uuid = null; while ((count = fis.read(b)) != -1) { uuid = new String(b, 0, count, "UTF-8"); } Utils.log("getDeviceId", "获取成功DataFile"+ uuid); return uuid; } catch (Exception e) { e.printStackTrace(); } }else if (!isCheck){ String[] dirName = {"/gh-uuid", "/system", "/data"}; for (int i = 0; i< 3; i++) { String s = loadSDCard(dirName[i]); if (s != null) { return s; } } } return null; } //读取SD卡的uuid private static String loadSDCard(String saveDir){ File sdCardDir = Environment.getExternalStorageDirectory(); String path = sdCardDir.getPath() + saveDir; File file = new File(path, "uuid"); if (file.exists()){ FileInputStream fis = null; ByteArrayOutputStream bos = null; try { fis = new FileInputStream(file); bos = new ByteArrayOutputStream(); byte[] array = new byte[1024]; int len = -1; while( (len = fis.read(array)) != -1){ bos.write(array,0,len); } bos.close(); fis.close(); Utils.log("getDeviceId", "获取成功SDCard"+"目录为:"+saveDir+"::"+bos.toString()); return bos.toString(); } catch (IOException e) { e.printStackTrace(); } } return null; } }