发送手机物理标识请求
- - CSDN博客推荐文章作为应用的重要关注指标-激活, 需要在每次启动时, 都上传手机的物理标识到服务器. 激活信息主要包含:. AppId: 公司拥有多款应用, 标示本应用的类型. Platform: 平台Android或者iOS. SystemVersion: 在Android中, 代表Android版本号. Version: 本应用的版本.
作为应用的重要关注指标-激活, 需要在每次启动时, 都上传手机的物理标识到服务器. 我来简述一下需要上传的信息.
激活信息主要包含:
1. AppId: 公司拥有多款应用, 标示本应用的类型.
2. Platform: 平台Android或者iOS.
3. SystemVersion: 在Android中, 代表Android版本号.
4. Version: 本应用的版本.
5. AppVersion: 本应用的服务器接口版本.
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
* <p/>
* 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), // 服务器版本
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();
}
}
}
为了减少获取代价, 可以存储一些关键值到首选项.
网络请求必须使用异步线程, 我们只是上传激活, 并不关心返回值, 比较简单.
new PostActiveTask().execute(); // 发送激活信息
// 发送激活任务的线程
private class PostActiveTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
ActiveInfo.getInstance().postActiveInfo();
return null;
}
@Override
protected void onPostExecute(Void result) {
}
}
返回均为空值, 在
doInBackground
中, 需要注明return null
.
OK, Enjoy It.