作为应用的重要关注指标-激活, 须要在每次启动时, 都上传手机的物理标识到server. 我来简述一下须要上传的信息.
1. 获取
激活信息主要包括:
1. AppId: 公司拥有多款应用, 标示本应用的类型. 2. Platform: 平台Android或者iOS. 3. SystemVersion: 在Android中, 代表Android版本号号. 4. Version: 本应用的版本号. 5. AppVersion: 本应用的server接口版本号. 6. IMEI(International Mobile Equipment Identity): 国际移动设备标识, 手机身份. 7. DeviceId: 设备标示, 通常是IMEI, 也能够是Mac地址. 8. Mac: WIFI的Mac地址. 9. SecureId: 设备随机生成的第一个引导, 间接获取设备寿命. 10. InstallId: 应用安装时间. 11. MODEL: 设备型号 12. MANUFACTURER: 设备生产工厂.当中获取DeviceId须要权限: READ_PHONE_STATE
; 获取Mac地址须要权限ACCESS_WIFI_STATE
.
/** * 获取手机标示, 用于激活信息, 须要权限 * READ_PHONE_STATE和ACCESS_WIFI_STATE * * Created by wangchenlong on 15/12/11. */public class ActiveInfo { @SuppressWarnings("unused") private static final String TAG = "DEBUG-WCL: " + ActiveInfo.class.getSimpleName(); @SuppressWarnings("all") private static final String STAT_INFO_STR = "app=%s&platform=android&systemVer=%s&version=%s&app_ver=%s&imei=%s" + "&device_id=%s&mac=%s&secureId=%s&installId=%s&phoneType=%s_by_%s&vendor="; private static final String APP_ID = "512"; private static final String VENDOR = "PedometerLibrary"; private static final int HTTP_OK = 200; // 请求成功 private static final int TIME_OUT = 5 * 1000; // 连接超时时间 private static ActiveInfo sInstance; private final Context mContext; private final SharedPreferences mPrefs; private final TelephonyManager mTelephonyManager; private final WifiManager mWifiManager; private ActiveInfo() { mContext = PedometerManager.getInstance().getContext(); mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext); mTelephonyManager = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); mWifiManager = (WifiManager) (mContext.getSystemService(Context.WIFI_SERVICE)); } public static ActiveInfo getInstance() { if (sInstance == null) { sInstance = new ActiveInfo(); } return sInstance; } // 获取签名信息 private String getPhoneSignature() { String signature; // 手机标示 signature = String.format(STAT_INFO_STR, getUrlString(APP_ID), // 应用ID getUrlString(android.os.Build.VERSION.RELEASE), // 系统版本号 getUrlString(BuildConfig.VERSION_NAME), // SDK版本号 getUrlString(BuildConfig.VERSION_NAME), // server版本号 getUrlString(getDeviceId()), // IMEI getUrlString(getDeviceId()), // 设备ID getUrlString(getMac()), // Mac地址 getUrlString(getSecureId()), // 安全ID getUrlString(getInstallId()), // 安装时间 getUrlString(android.os.Build.MODEL), // 设备型号 getUrlString(android.os.Build.MANUFACTURER)); // 设备工厂 signature += VENDOR; return signature; } private String getUrlString(String s) { //noinspection deprecation return URLEncoder.encode(s); } // 获取设备ID, 须要权限READ_PHONE_STATE private String getDeviceId() { if (mPrefs.contains(PrefsConsts.PHONE_INFO_DEVICE_ID_PREFS)) { return mPrefs.getString(PrefsConsts.PHONE_INFO_DEVICE_ID_PREFS, ""); } else { mPrefs.edit().putString( PrefsConsts.PHONE_INFO_DEVICE_ID_PREFS, mTelephonyManager.getDeviceId()) .apply(); return mPrefs.getString(PrefsConsts.PHONE_INFO_DEVICE_ID_PREFS, ""); } } // 获取Mac地址, 须要权限ACCESS_WIFI_STATE private String getMac() { if (mPrefs.contains(PrefsConsts.PHONE_INFO_MAC_ADDRESS_PREFS)) { return mPrefs.getString(PrefsConsts.PHONE_INFO_MAC_ADDRESS_PREFS, ""); } else { mPrefs.edit().putString( PrefsConsts.PHONE_INFO_MAC_ADDRESS_PREFS, mWifiManager.getConnectionInfo().getMacAddress()) .apply(); return mPrefs.getString(PrefsConsts.PHONE_INFO_MAC_ADDRESS_PREFS, ""); } } // 获取安全ID private String getSecureId() { if (mPrefs.contains(PrefsConsts.PHONE_INFO_SECURE_ID_PREFS)) { return mPrefs.getString(PrefsConsts.PHONE_INFO_SECURE_ID_PREFS, ""); } else { mPrefs.edit().putString( PrefsConsts.PHONE_INFO_SECURE_ID_PREFS, Settings.Secure.getString( mContext.getContentResolver(), Settings.Secure.ANDROID_ID)) .apply(); return mPrefs.getString(PrefsConsts.PHONE_INFO_SECURE_ID_PREFS, ""); } } // 获取安装时的系统时间 private String getInstallId() { if (mPrefs.contains(PrefsConsts.PHONE_INFO_INSTALL_ID_PREFS)) { return mPrefs.getString(PrefsConsts.PHONE_INFO_INSTALL_ID_PREFS, ""); } else { mPrefs.edit().putString( PrefsConsts.PHONE_INFO_INSTALL_ID_PREFS, String.format("%d", System.currentTimeMillis())) .apply(); return mPrefs.getString(PrefsConsts.PHONE_INFO_INSTALL_ID_PREFS, ""); } } // 发送激活信息 public void postActiveInfo() { String path = "http://api.chunyu.me/api/launch_request/?"; path += getPhoneSignature(); Log.d(TAG, "url: " + path); try { URL url = new URL(path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(TIME_OUT); // 连接超时 connection.connect(); if (connection.getResponseCode() == HTTP_OK) { Log.d(TAG, " 发送激活信息成功"); } else { Log.e(TAG, " 发送激活信息失败: " + connection.getResponseCode()); } connection.disconnect(); } catch (IOException e) { e.printStackTrace(); } }}
为了降低获代替价, 能够存储一些关键值到首选项.
2. 上传
网络请求必须使用异步线程, 我们仅仅是上传激活, 并不关心返回值, 比較简单.
new PostActiveTask().execute(); // 发送激活信息
// 发送激活任务的线程 private class PostActiveTask extends AsyncTask{ @Override protected Void doInBackground(Void... params) { ActiveInfo.getInstance().postActiveInfo(); return null; } @Override protected void onPostExecute(Void result) { } }
返回均为空值, 在
doInBackground
中, 须要注明return null
.
OK, Enjoy It.