diff --git a/.gitignore b/.gitignore
index f0c20a1..aac3b37 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,3 +75,6 @@ lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/
+/.idea/
+/gradlew.bat
+/gradlew
diff --git a/app/.gitignore b/app/.gitignore
index 42afabf..b1b19de 100644
--- a/app/.gitignore
+++ b/app/.gitignore
@@ -1 +1,3 @@
-/build
\ No newline at end of file
+/build
+/src/androidTest/java/com/tt/ttutils/
+/src/test/java/com/tt/ttutils/
diff --git a/app/build.gradle b/app/build.gradle
index 935c06b..fd9af64 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,28 +2,133 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
+def appName() {
+ return "TT"
+}
+
+def releaseTime() {
+ return new Date().format("yyyyMMdd", TimeZone.getDefault())
+}
+
android {
- compileSdkVersion 30
+ compileSdkVersion 29
buildToolsVersion "30.0.1"
defaultConfig {
applicationId "com.tt.ttutils"
minSdkVersion 14
- targetSdkVersion 30
- versionCode 1
- versionName "1.0"
+ targetSdkVersion 29
+// versionCode 1
+// versionName "1.0"
+ multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+ ndk {
+ //选择要添加的对应 cpu 类型的 .so 库。
+ abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a','x86'
+ // 还可以添加 'x86', 'x86_64', 'mips', 'mips64'
+ }
+ manifestPlaceholders = [
+ JPUSH_PKGNAME: applicationId,
+ JPUSH_APPKEY : "731637f412deca8540a1f873", //JPush 上注册的包名对应的 Appkey.
+ JPUSH_CHANNEL: "developer-default", //暂时填写默认值即可.
+ ]
+ }
+
+ lintOptions {
+ checkReleaseBuilds false
+ }
+ dexOptions {
+ jumboMode true
+ }
+ //多版本
+ productFlavors {
+ official {
+ flavorDimensions "default"
+ versionCode 1
+ versionName "1.0"
+ signingConfig signingConfigs.debug
+ }
+
+ beta {
+ flavorDimensions "default"
+ versionCode 1
+ versionName "1.0"
+ signingConfig signingConfigs.debug
+ buildConfigField "String", "test", '"测试文本"'
+ }
+ }
+ sourceSets {
+ beta.res.srcDirs = ['src/beta/res']
+ }
+
+//签名
+ signingConfigs {
+ debug {
+ storeFile file("src/jks/tt.jks")
+ storePassword "fht19961207"
+ keyAlias "key0"
+ keyPassword "981964879aa"
+ v1SigningEnabled true
+ v2SigningEnabled false
+ }
+
+ release {
+ storeFile file("src/jks/tt.jks")
+ storePassword "fht19961207"
+ keyAlias "key0"
+ keyPassword "981964879aa"
+ v1SigningEnabled true
+ v2SigningEnabled false
+ }
}
buildTypes {
- release {
+ debug {
+ // 显示Log
+ buildConfigField "boolean", "LOG_DEBUG", "true"
+ versionNameSuffix "-debug"
minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ //Zipalign优化
+ zipAlignEnabled true
+ signingConfig signingConfigs.debug
+ applicationVariants.all { variant ->
+ variant.outputs.each { output ->
+ def outputFile = output.outputFile
+ if (outputFile != null) {
+ def fileName = "${appName()}-${variant.versionCode}-V${variant.versionName}-${releaseTime()}-${buildType.name}.apk"
+ output.outputFileName = fileName
+ }
+ }
+ }
+ }
+ release {
+ // 不显示Log
+ buildConfigField "boolean", "LOG_DEBUG", "false"
+ //混淆
+ minifyEnabled false
+ //Zipalign优化
+ zipAlignEnabled true
+ //前一部分代表系统默认的android程序的混淆文件,该文件已经包含了基本的混淆声明,后一个文件是自己的定义混淆文件
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ //签名
+ signingConfig signingConfigs.release
+// 将release版本的包名重命名,加上版本及日期
+ applicationVariants.all { variant ->
+ variant.outputs.each { output ->
+ def outputFile = ""
+ if (outputFile != null) {
+ def fileName = "${appName()}-${variant.versionCode}-V${variant.versionName}-${releaseTime()}-${productFlavors[0].name}-${buildType.name}.apk"
+ output.outputFileName = new File(outputFile, fileName)
+ }
+ }
+ }
}
}
}
+
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
@@ -33,5 +138,40 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+ ////三方
+ //极光推送
+ implementation 'cn.jiguang.sdk:jpush:3.7.0' // 此处以JPush 3.7.0 版本为例。
+ implementation 'cn.jiguang.sdk:jcore:2.4.2' // 此处以JCore 2.4.2 版本为例。
+ //okhttp
+ implementation 'com.squareup.okhttp3:okhttp:4.6.0'
+ //RxJava和Retrofit
+ implementation 'io.reactivex.rxjava2:rxjava:2.2.5'
+ implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
+ implementation 'com.squareup.retrofit2:retrofit:2.3.0'
+ implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
+ implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
+ ////json解析
+ //Gson
+ implementation 'com.google.code.gson:gson:2.8.6'
+ //Jackson
+ implementation 'org.codehaus.jackson:jackson-mapper-asl:1.9.13'
+ implementation 'org.codehaus.jackson:jackson-core-asl:1.9.13'
+ //二维码
+ implementation 'com.google.zxing:core:3.3.0'
+
+ //个人
+ //更换字体框架
+ implementation 'uk.co.chrisjenx:calligraphy:2.3.0'
+ ////图片加载框架
+ //Glide
+ implementation 'com.github.bumptech.glide:glide:4.11.0'
+ annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
+ //Fresco
+ implementation 'com.facebook.fresco:fresco:2.2.0'
+ //Picasso
+ implementation 'com.squareup.picasso:picasso:2.71828'
+ //屏幕适配方案
+ //https://github.com/JessYanCoding/AndroidAutoSize
+ implementation 'me.jessyan:autosize:1.2.1'
}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/jks/tt.jks b/app/src/jks/tt.jks
new file mode 100644
index 0000000..34e26b4
Binary files /dev/null and b/app/src/jks/tt.jks differ
diff --git a/app/src/jks/xueshibaoos.jks b/app/src/jks/xueshibaoos.jks
new file mode 100644
index 0000000..b94a626
Binary files /dev/null and b/app/src/jks/xueshibaoos.jks differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 87955bf..97f5b0f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,9 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/tt/MyApplication.kt b/app/src/main/java/com/tt/MyApplication.kt
deleted file mode 100644
index 9d129d9..0000000
--- a/app/src/main/java/com/tt/MyApplication.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.tt
-
-import android.app.Application
-import com.tt.ttutils.java.ToastUtil
-
-class MyApplication : Application() {
- override fun onCreate() {
- super.onCreate()
- ToastUtil.init(this)
- }
-
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/tt/activity/JMainActivity.java b/app/src/main/java/com/tt/activity/JMainActivity.java
new file mode 100644
index 0000000..cf01cd7
--- /dev/null
+++ b/app/src/main/java/com/tt/activity/JMainActivity.java
@@ -0,0 +1,22 @@
+package com.tt.activity;
+
+import com.tt.base.BaseActivity;
+import com.tt.ttutils.R;
+
+public class JMainActivity extends BaseActivity {
+
+ @Override
+ protected int setLayoutResourceID() {
+ return R.layout.activity_main;
+ }
+
+ @Override
+ protected void initView() {
+
+ }
+
+ @Override
+ protected void initData() {
+
+ }
+}
diff --git a/app/src/main/java/com/tt/activity/MainActivity.kt b/app/src/main/java/com/tt/activity/MainActivity.kt
index 66ac0f8..3ea535d 100644
--- a/app/src/main/java/com/tt/activity/MainActivity.kt
+++ b/app/src/main/java/com/tt/activity/MainActivity.kt
@@ -1,16 +1,22 @@
package com.tt.activity
-import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
+import android.util.Log
+import androidx.appcompat.app.AppCompatActivity
import com.tt.ttutils.R
import com.tt.ttutils.java.CmdUtil
+import com.tt.ttutils.java.DevicesUtils
+import kotlinx.android.synthetic.main.activity_main.*
+import me.jessyan.autosize.internal.CancelAdapt
-class MainActivity : AppCompatActivity() {
+class MainActivity : AppCompatActivity(), CancelAdapt {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//截图
- CmdUtil.execute(" screencap -p /sdcard/" + "screen" + System.currentTimeMillis() + ".png");
-
+ CmdUtil.execute(" screencap -p /sdcard/" + "screen" + System.currentTimeMillis() + ".png")
+ textView.setText(DevicesUtils.getSerial())
}
+
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/tt/base/BaseActivity.java b/app/src/main/java/com/tt/base/BaseActivity.java
new file mode 100644
index 0000000..db869c5
--- /dev/null
+++ b/app/src/main/java/com/tt/base/BaseActivity.java
@@ -0,0 +1,131 @@
+package com.tt.base;
+
+import android.os.Build;
+import android.os.Bundle;
+
+
+import android.os.Handler;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+
+public abstract class BaseActivity extends AppCompatActivity {
+ private static Handler sHandler;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(setLayoutResourceID());
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ sHandler = new Handler();
+ sHandler.post(mHideRunnable); // hide the navigation bar
+ final View decorView = getWindow().getDecorView();
+ decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
+ @Override
+ public void onSystemUiVisibilityChange(int visibility) {
+ if (visibility == View.SYSTEM_UI_FLAG_VISIBLE) {
+ sHandler.postDelayed(mHideRunnable, 3000); // hide the navigation bar
+ }
+ }
+ });
+
+ initView();
+ initData();
+ setListener();
+
+ }
+
+
+ protected abstract int setLayoutResourceID();
+
+ protected abstract void initView();
+
+
+ protected void setListener() {
+ }
+
+
+ protected abstract void initData();
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ if (hasFocus) {
+// initViewFull(this);
+ }
+ }
+
+// public static void initViewFull(final Activity activity) {
+// activity.getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
+// @Override
+// public void onSystemUiVisibilityChange(int visibility) {
+// new Thread() {
+// @Override
+// public void run() {
+// super.run();
+// try {
+// Thread.sleep(3000);
+// } catch (InterruptedException e) {
+// e.printStackTrace();
+// }
+// activity.runOnUiThread(new Runnable() {
+// @Override
+// public void run() {
+// initViewFull(activity);
+//
+// }
+// });
+// }
+// }.start();
+// }
+// });
+// // //设置无标题
+// activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+// WindowManager.LayoutParams.FLAG_FULLSCREEN);
+// activity.getWindow().getDecorView().setSystemUiVisibility(
+// View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+// | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+// | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+// | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
+// | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
+// | View.SYSTEM_UI_FLAG_IMMERSIVE);
+// }
+
+ Runnable mHideRunnable = new Runnable() {
+ @Override
+ public void run() {
+ int flags;
+ int curApiVersion = Build.VERSION.SDK_INT;
+ // This work only for android 4.4+
+ if (curApiVersion >= Build.VERSION_CODES.KITKAT) {
+ // This work only for android 4.4+
+ // hide navigation bar permanently in android activity
+ // touch the screen, the navigation bar will not show
+ flags =
+// View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+// | View.SYSTEM_UI_FLAG_IMMERSIVE
+// | View.SYSTEM_UI_FLAG_FULLSCREEN;
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
+ | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
+ | View.SYSTEM_UI_FLAG_IMMERSIVE;
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
+ } else {
+ // touch the screen, the navigation bar will show
+ flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ }
+ // must be executed in main thread
+
+ getWindow().getDecorView().setSystemUiVisibility(flags);
+ }
+ };
+
+}
diff --git a/app/src/main/java/com/tt/base/JMyApplication.java b/app/src/main/java/com/tt/base/JMyApplication.java
new file mode 100644
index 0000000..ba30f39
--- /dev/null
+++ b/app/src/main/java/com/tt/base/JMyApplication.java
@@ -0,0 +1,45 @@
+package com.tt.base;
+
+import android.app.Application;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import com.tt.ttutils.BuildConfig;
+
+public class JMyApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ if (!BuildConfig.DEBUG) {
+ catchException();
+ }
+ }
+ private void catchException() {
+ Thread.setDefaultUncaughtExceptionHandler(
+ new Thread.UncaughtExceptionHandler() {
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ Log.d("捕获异常子线程:", Thread.currentThread().getName() +
+ "在:" + e.getStackTrace()[0].getClassName());
+ }
+ }
+ );
+ //下面是新增方法!
+ new Handler(Looper.getMainLooper()).post(new Runnable() {
+ @Override
+ public void run() {
+ while (true) {
+ try {
+ Looper.loop(); //会先执行这个方法,然后在执行下面的异常捕获方法!
+ } catch (Exception e) {
+ Log.d("捕获异常主线程:", Thread.currentThread().getName() + "在:" + e.getStackTrace()[0].getClassName());
+ e.printStackTrace();
+ }
+ }
+ }
+ });
+ }
+
+
+}
diff --git a/app/src/main/java/com/tt/base/MyApplication.kt b/app/src/main/java/com/tt/base/MyApplication.kt
new file mode 100644
index 0000000..5dad1b7
--- /dev/null
+++ b/app/src/main/java/com/tt/base/MyApplication.kt
@@ -0,0 +1,47 @@
+package com.tt.base
+
+import android.app.Application
+import android.os.Handler
+import android.os.Looper
+import android.util.Log
+import cn.jpush.android.api.JPushInterface
+import com.tt.ttutils.BuildConfig
+import com.tt.ttutils.java.ToastUtil
+
+
+class MyApplication : Application() {
+ private val debug = BuildConfig.DEBUG;
+ override fun onCreate() {
+ super.onCreate()
+ ToastUtil.init(this)
+ JPushInterface.setDebugMode(debug) // 设置开启日志,发布时请关闭日志
+ JPushInterface.init(this) // 初始化 JPush
+ if (!BuildConfig.DEBUG) {
+ catchException();
+ }
+
+ }
+ private fun catchException() {
+ Thread.setDefaultUncaughtExceptionHandler { t, e ->
+ Log.d(
+ "捕获异常子线程:", Thread.currentThread().name +
+ "在:" + e.stackTrace[0].className
+ )
+ }
+ //下面是新增方法!
+ Handler(Looper.getMainLooper()).post(Runnable {
+ while (true) {
+ try {
+ Looper.loop() //会先执行这个方法,然后在执行下面的异常捕获方法!
+ } catch (e: Exception) {
+ Log.d(
+ "捕获异常主线程:",
+ Thread.currentThread().name + "在:" + e.stackTrace[0].className
+ )
+ e.printStackTrace()
+ }
+ }
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tt/sdk/jpush/jpushdemo/ExampleUtil.java b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/ExampleUtil.java
new file mode 100644
index 0000000..75fb5e7
--- /dev/null
+++ b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/ExampleUtil.java
@@ -0,0 +1,133 @@
+package com.tt.sdk.jpush.jpushdemo;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+import android.os.Looper;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.widget.Toast;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import cn.jpush.android.api.JPushInterface;
+
+public class ExampleUtil {
+ public static final String PREFS_NAME = "JPUSH_EXAMPLE";
+ public static final String PREFS_DAYS = "JPUSH_EXAMPLE_DAYS";
+ public static final String PREFS_START_TIME = "PREFS_START_TIME";
+ public static final String PREFS_END_TIME = "PREFS_END_TIME";
+ public static final String KEY_APP_KEY = "JPUSH_APPKEY";
+
+ public static boolean isEmpty(String s) {
+ if (null == s)
+ return true;
+ if (s.length() == 0)
+ return true;
+ if (s.trim().length() == 0)
+ return true;
+ return false;
+ }
+ /**
+ * 只能以 “+” 或者 数字开头;后面的内容只能包含 “-” 和 数字。
+ * */
+ private final static String MOBILE_NUMBER_CHARS = "^[+0-9][-0-9]{1,}$";
+ public static boolean isValidMobileNumber(String s) {
+ if(TextUtils.isEmpty(s)) return true;
+ Pattern p = Pattern.compile(MOBILE_NUMBER_CHARS);
+ Matcher m = p.matcher(s);
+ return m.matches();
+ }
+ // 校验Tag Alias 只能是数字,英文字母和中文
+ public static boolean isValidTagAndAlias(String s) {
+ Pattern p = Pattern.compile("^[\u4E00-\u9FA50-9a-zA-Z_!@#$&*+=.|]+$");
+ Matcher m = p.matcher(s);
+ return m.matches();
+ }
+
+ // 取得AppKey
+ public static String getAppKey(Context context) {
+ Bundle metaData = null;
+ String appKey = null;
+ try {
+ ApplicationInfo ai = context.getPackageManager().getApplicationInfo(
+ context.getPackageName(), PackageManager.GET_META_DATA);
+ if (null != ai)
+ metaData = ai.metaData;
+ if (null != metaData) {
+ appKey = metaData.getString(KEY_APP_KEY);
+ if ((null == appKey) || appKey.length() != 24) {
+ appKey = null;
+ }
+ }
+ } catch (NameNotFoundException e) {
+
+ }
+ return appKey;
+ }
+
+ // 取得版本号
+ public static String GetVersion(Context context) {
+ try {
+ PackageInfo manager = context.getPackageManager().getPackageInfo(
+ context.getPackageName(), 0);
+ return manager.versionName;
+ } catch (NameNotFoundException e) {
+ return "Unknown";
+ }
+ }
+
+ public static void showToast(final String toast, final Context context)
+ {
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ Looper.prepare();
+ Toast.makeText(context, toast, Toast.LENGTH_SHORT).show();
+ Looper.loop();
+ }
+ }).start();
+ }
+
+ public static boolean isConnected(Context context) {
+ ConnectivityManager conn = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo info = conn.getActiveNetworkInfo();
+ return (info != null && info.isConnected());
+ }
+
+ public static String getImei(Context context, String imei) {
+ String ret = null;
+ try {
+ TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ ret = telephonyManager.getDeviceId();
+ } catch (Exception e) {
+ Logger.e(ExampleUtil.class.getSimpleName(), e.getMessage());
+ }
+ if (isReadableASCII(ret)){
+ return ret;
+ } else {
+ return imei;
+ }
+ }
+
+ private static boolean isReadableASCII(CharSequence string){
+ if (TextUtils.isEmpty(string)) return false;
+ try {
+ Pattern p = Pattern.compile("[\\x20-\\x7E]+");
+ return p.matcher(string).matches();
+ } catch (Throwable e){
+ return true;
+ }
+ }
+
+ public static String getDeviceId(Context context) {
+ return JPushInterface.getUdid(context);
+ }
+}
diff --git a/app/src/main/java/com/tt/sdk/jpush/jpushdemo/LocalBroadcastManager.java b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/LocalBroadcastManager.java
new file mode 100644
index 0000000..c42beb3
--- /dev/null
+++ b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/LocalBroadcastManager.java
@@ -0,0 +1,263 @@
+package com.tt.sdk.jpush.jpushdemo;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Set;
+
+/**
+ * Created by efan on 2017/4/14.
+ */
+
+public final class LocalBroadcastManager {
+ private static final String TAG = "JIGUANG-Example";
+ private static final boolean DEBUG = false;
+ private final Context mAppContext;
+ private final HashMap> mReceivers = new HashMap>();
+ private final HashMap> mActions = new HashMap> ();
+ private final ArrayList mPendingBroadcasts = new ArrayList();
+ static final int MSG_EXEC_PENDING_BROADCASTS = 1;
+ private final Handler mHandler;
+ private static final Object mLock = new Object();
+ private static LocalBroadcastManager mInstance;
+
+ public static LocalBroadcastManager getInstance(Context context) {
+ Object var1 = mLock;
+ synchronized (mLock) {
+ if (mInstance == null) {
+ mInstance = new LocalBroadcastManager(context.getApplicationContext());
+ }
+
+ return mInstance;
+ }
+ }
+
+ private LocalBroadcastManager(Context context) {
+ this.mAppContext = context;
+ this.mHandler = new Handler(context.getMainLooper()) {
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case 1:
+ LocalBroadcastManager.this.executePendingBroadcasts();
+ break;
+ default:
+ super.handleMessage(msg);
+ }
+
+ }
+ };
+ }
+
+ public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ HashMap var3 = this.mReceivers;
+ synchronized (this.mReceivers) {
+ ReceiverRecord entry = new ReceiverRecord(filter, receiver);
+ ArrayList filters = (ArrayList) this.mReceivers.get(receiver);
+ if (filters == null) {
+ filters = new ArrayList(1);
+ this.mReceivers.put(receiver, filters);
+ }
+
+ filters.add(filter);
+
+ for (int i = 0; i < filter.countActions(); ++i) {
+ String action = filter.getAction(i);
+ ArrayList entries = (ArrayList) this.mActions.get(action);
+ if (entries == null) {
+ entries = new ArrayList(1);
+ this.mActions.put(action, entries);
+ }
+
+ entries.add(entry);
+ }
+
+ }
+ }
+
+ public void unregisterReceiver(BroadcastReceiver receiver) {
+ HashMap var2 = this.mReceivers;
+ synchronized (this.mReceivers) {
+ ArrayList filters = (ArrayList) this.mReceivers.remove(receiver);
+ if (filters != null) {
+ for (int i = 0; i < filters.size(); ++i) {
+ IntentFilter filter = (IntentFilter) filters.get(i);
+
+ for (int j = 0; j < filter.countActions(); ++j) {
+ String action = filter.getAction(j);
+ ArrayList receivers = (ArrayList) this.mActions.get(action);
+ if (receivers != null) {
+ for (int k = 0; k < receivers.size(); ++k) {
+ if (((ReceiverRecord) receivers.get(k)).receiver == receiver) {
+ receivers.remove(k);
+ --k;
+ }
+ }
+
+ if (receivers.size() <= 0) {
+ this.mActions.remove(action);
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+
+ public boolean sendBroadcast(Intent intent) {
+ HashMap var2 = this.mReceivers;
+ synchronized (this.mReceivers) {
+ String action = intent.getAction();
+ String type = intent.resolveTypeIfNeeded(this.mAppContext.getContentResolver());
+ Uri data = intent.getData();
+ String scheme = intent.getScheme();
+ Set categories = intent.getCategories();
+ boolean debug = (intent.getFlags() & 8) != 0;
+ if (debug) {
+ Logger.v("LocalBroadcastManager", "Resolving type " + type + " scheme " + scheme + " of intent " + intent);
+ }
+
+ ArrayList entries = (ArrayList) this.mActions.get(intent.getAction());
+ if (entries != null) {
+ if (debug) {
+ Logger.v("LocalBroadcastManager", "Action list: " + entries);
+ }
+
+ ArrayList receivers = null;
+
+ int i;
+ for (i = 0; i < entries.size(); ++i) {
+ ReceiverRecord receiver = (ReceiverRecord) entries.get(i);
+ if (debug) {
+ Logger.v("LocalBroadcastManager", "Matching against filter " + receiver.filter);
+ }
+
+ if (receiver.broadcasting) {
+ if (debug) {
+ Logger.v("LocalBroadcastManager", " Filter\'s target already added");
+ }
+ } else {
+ int match = receiver.filter.match(action, type, scheme, data, categories, "LocalBroadcastManager");
+ if (match >= 0) {
+ if (debug) {
+ Logger.v("LocalBroadcastManager", " Filter matched! match=0x" + Integer.toHexString(match));
+ }
+
+ if (receivers == null) {
+ receivers = new ArrayList();
+ }
+
+ receivers.add(receiver);
+ receiver.broadcasting = true;
+ } else if (debug) {
+ String reason;
+ switch (match) {
+ case -4:
+ reason = "category";
+ break;
+ case -3:
+ reason = "action";
+ break;
+ case -2:
+ reason = "data";
+ break;
+ case -1:
+ reason = "type";
+ break;
+ default:
+ reason = "unknown reason";
+ }
+
+ Logger.v("LocalBroadcastManager", " Filter did not match: " + reason);
+ }
+ }
+ }
+
+ if (receivers != null) {
+ for (i = 0; i < receivers.size(); ++i) {
+ ((ReceiverRecord) receivers.get(i)).broadcasting = false;
+ }
+
+ this.mPendingBroadcasts.add(new BroadcastRecord(intent, receivers));
+ if (!this.mHandler.hasMessages(1)) {
+ this.mHandler.sendEmptyMessage(1);
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ public void sendBroadcastSync(Intent intent) {
+ if (this.sendBroadcast(intent)) {
+ this.executePendingBroadcasts();
+ }
+
+ }
+
+ private void executePendingBroadcasts() {
+ while (true) {
+ BroadcastRecord[] brs = null;
+ HashMap i = this.mReceivers;
+ synchronized (this.mReceivers) {
+ int br = this.mPendingBroadcasts.size();
+ if (br <= 0) {
+ return;
+ }
+
+ brs = new BroadcastRecord[br];
+ this.mPendingBroadcasts.toArray(brs);
+ this.mPendingBroadcasts.clear();
+ }
+
+ for (int var6 = 0; var6 < brs.length; ++var6) {
+ BroadcastRecord var7 = brs[var6];
+
+ for (int j = 0; j < var7.receivers.size(); ++j) {
+ ((ReceiverRecord) var7.receivers.get(j)).receiver.onReceive(this.mAppContext, var7.intent);
+ }
+ }
+ }
+ }
+
+ private static class BroadcastRecord {
+ final Intent intent;
+ final ArrayList receivers;
+
+ BroadcastRecord(Intent _intent, ArrayList _receivers) {
+ this.intent = _intent;
+ this.receivers = _receivers;
+ }
+ }
+
+ private static class ReceiverRecord {
+ final IntentFilter filter;
+ final BroadcastReceiver receiver;
+ boolean broadcasting;
+
+ ReceiverRecord(IntentFilter _filter, BroadcastReceiver _receiver) {
+ this.filter = _filter;
+ this.receiver = _receiver;
+ }
+
+ public String toString() {
+ StringBuilder builder = new StringBuilder(128);
+ builder.append("Receiver{");
+ builder.append(this.receiver);
+ builder.append(" filter=");
+ builder.append(this.filter);
+ builder.append("}");
+ return builder.toString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tt/sdk/jpush/jpushdemo/Logger.java b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/Logger.java
new file mode 100644
index 0000000..d188b5a
--- /dev/null
+++ b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/Logger.java
@@ -0,0 +1,42 @@
+package com.tt.sdk.jpush.jpushdemo;
+
+import android.util.Log;
+
+import com.tt.ttutils.BuildConfig;
+
+/**
+ * Created by efan on 2017/4/13.
+ */
+
+public class Logger {
+
+ //设为false关闭日志
+ private static final boolean LOG_ENABLE = BuildConfig.DEBUG;
+
+ public static void i(String tag, String msg){
+ if (LOG_ENABLE){
+ Log.i(tag, msg);
+ }
+ }
+ public static void v(String tag, String msg){
+ if (LOG_ENABLE){
+ Log.v(tag, msg);
+ }
+ }
+ public static void d(String tag, String msg){
+ if (LOG_ENABLE){
+ Log.d(tag, msg);
+ }
+ }
+ public static void w(String tag, String msg){
+ if (LOG_ENABLE){
+ Log.w(tag, msg);
+ }
+ }
+ public static void e(String tag, String msg){
+ if (LOG_ENABLE){
+ Log.e(tag, msg);
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/tt/sdk/jpush/jpushdemo/MyReceiver.java b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/MyReceiver.java
new file mode 100644
index 0000000..3b86573
--- /dev/null
+++ b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/MyReceiver.java
@@ -0,0 +1,123 @@
+package com.tt.sdk.jpush.jpushdemo;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.TextUtils;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Iterator;
+
+import cn.jpush.android.api.JPushInterface;
+
+/**
+ * 自定义接收器
+ *
+ * 如果不定义这个 Receiver,则:
+ * 1) 默认用户会打开主界面
+ * 2) 接收不到自定义消息
+ */
+public class MyReceiver extends BroadcastReceiver {
+ private static final String TAG = "JIGUANG-Example";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ Bundle bundle = intent.getExtras();
+ Logger.d(TAG, "[MyReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(bundle));
+
+ if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
+ String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);
+ Logger.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);
+ //send the Registration Id to your server...
+
+ } else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
+ Logger.d(TAG, "[MyReceiver] 接收到推送下来的自定义消息: " + bundle.getString(JPushInterface.EXTRA_MESSAGE));
+// processCustomMessage(context, bundle);
+
+ } else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
+ Logger.d(TAG, "[MyReceiver] 接收到推送下来的通知");
+ int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);
+ Logger.d(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notifactionId);
+
+ } else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
+ Logger.d(TAG, "[MyReceiver] 用户点击打开了通知");
+
+ //打开自定义的Activity
+ Intent i = new Intent(context, TestActivity.class);
+ i.putExtras(bundle);
+ //i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP );
+ context.startActivity(i);
+
+ } else if(JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) {
+ boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false);
+ Logger.w(TAG, "[MyReceiver]" + intent.getAction() +" connected state change to "+connected);
+ } else {
+ Logger.d(TAG, "[MyReceiver] Unhandled intent - " + intent.getAction());
+ }
+ } catch (Exception e){
+
+ }
+
+ }
+
+ // 打印所有的 intent extra 数据
+ private static String printBundle(Bundle bundle) {
+ StringBuilder sb = new StringBuilder();
+ for (String key : bundle.keySet()) {
+ if (key.equals(JPushInterface.EXTRA_NOTIFICATION_ID)) {
+ sb.append("\nkey:" + key + ", value:" + bundle.getInt(key));
+ }else if(key.equals(JPushInterface.EXTRA_CONNECTION_CHANGE)){
+ sb.append("\nkey:" + key + ", value:" + bundle.getBoolean(key));
+ } else if (key.equals(JPushInterface.EXTRA_EXTRA)) {
+ if (TextUtils.isEmpty(bundle.getString(JPushInterface.EXTRA_EXTRA))) {
+ Logger.i(TAG, "This message has no Extra data");
+ continue;
+ }
+
+ try {
+ JSONObject json = new JSONObject(bundle.getString(JPushInterface.EXTRA_EXTRA));
+ Iterator it = json.keys();
+
+ while (it.hasNext()) {
+ String myKey = it.next();
+ sb.append("\nkey:" + key + ", value: [" +
+ myKey + " - " +json.optString(myKey) + "]");
+ }
+ } catch (JSONException e) {
+ Logger.e(TAG, "Get message extra JSON error!");
+ }
+
+ } else {
+ sb.append("\nkey:" + key + ", value:" + bundle.get(key));
+ }
+ }
+ return sb.toString();
+ }
+
+ //send msg to MainActivity
+// private void processCustomMessage(Context context, Bundle bundle) {
+// if (MainActivity.isForeground) {
+// String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
+// String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
+// Intent msgIntent = new Intent(MainActivity.MESSAGE_RECEIVED_ACTION);
+// msgIntent.putExtra(MainActivity.KEY_MESSAGE, message);
+// if (!ExampleUtil.isEmpty(extras)) {
+// try {
+// JSONObject extraJson = new JSONObject(extras);
+// if (extraJson.length() > 0) {
+// msgIntent.putExtra(MainActivity.KEY_EXTRAS, extras);
+// }
+// } catch (JSONException e) {
+//
+// }
+//
+// }
+// LocalBroadcastManager.getInstance(context).sendBroadcast(msgIntent);
+// }
+// }
+}
diff --git a/app/src/main/java/com/tt/sdk/jpush/jpushdemo/PushMessageReceiver.java b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/PushMessageReceiver.java
new file mode 100644
index 0000000..1faaefe
--- /dev/null
+++ b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/PushMessageReceiver.java
@@ -0,0 +1,140 @@
+package com.tt.sdk.jpush.jpushdemo;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import cn.jpush.android.api.CmdMessage;
+import cn.jpush.android.api.CustomMessage;
+import cn.jpush.android.api.JPushInterface;
+import cn.jpush.android.api.JPushMessage;
+import cn.jpush.android.api.NotificationMessage;
+import cn.jpush.android.service.JPushMessageReceiver;
+
+public class PushMessageReceiver extends JPushMessageReceiver{
+ private static final String TAG = "PushMessageReceiver";
+ @Override
+ public void onMessage(Context context, CustomMessage customMessage) {
+ Log.e(TAG,"[onMessage] "+customMessage);
+// processCustomMessage(context,customMessage);
+ }
+
+ @Override
+ public void onNotifyMessageOpened(Context context, NotificationMessage message) {
+ Log.e(TAG,"[onNotifyMessageOpened] "+message);
+ try{
+ //打开自定义的Activity
+ Intent i = new Intent(context, TestActivity.class);
+ Bundle bundle = new Bundle();
+ bundle.putString(JPushInterface.EXTRA_NOTIFICATION_TITLE,message.notificationTitle);
+ bundle.putString(JPushInterface.EXTRA_ALERT,message.notificationContent);
+ i.putExtras(bundle);
+ //i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP );
+ context.startActivity(i);
+ }catch (Throwable throwable){
+
+ }
+ }
+
+ @Override
+ public void onMultiActionClicked(Context context, Intent intent) {
+ Log.e(TAG, "[onMultiActionClicked] 用户点击了通知栏按钮");
+ String nActionExtra = intent.getExtras().getString(JPushInterface.EXTRA_NOTIFICATION_ACTION_EXTRA);
+
+ //开发者根据不同 Action 携带的 extra 字段来分配不同的动作。
+ if(nActionExtra==null){
+ Log.d(TAG,"ACTION_NOTIFICATION_CLICK_ACTION nActionExtra is null");
+ return;
+ }
+ if (nActionExtra.equals("my_extra1")) {
+ Log.e(TAG, "[onMultiActionClicked] 用户点击通知栏按钮一");
+ } else if (nActionExtra.equals("my_extra2")) {
+ Log.e(TAG, "[onMultiActionClicked] 用户点击通知栏按钮二");
+ } else if (nActionExtra.equals("my_extra3")) {
+ Log.e(TAG, "[onMultiActionClicked] 用户点击通知栏按钮三");
+ } else {
+ Log.e(TAG, "[onMultiActionClicked] 用户点击通知栏按钮未定义");
+ }
+ }
+
+ @Override
+ public void onNotifyMessageArrived(Context context, NotificationMessage message) {
+ Log.e(TAG,"[onNotifyMessageArrived] "+message);
+ }
+
+ @Override
+ public void onNotifyMessageDismiss(Context context, NotificationMessage message) {
+ Log.e(TAG,"[onNotifyMessageDismiss] "+message);
+ }
+
+ @Override
+ public void onRegister(Context context, String registrationId) {
+ Log.e(TAG,"[onRegister] "+registrationId);
+ }
+
+ @Override
+ public void onConnected(Context context, boolean isConnected) {
+ Log.e(TAG,"[onConnected] "+isConnected);
+ }
+
+ @Override
+ public void onCommandResult(Context context, CmdMessage cmdMessage) {
+ Log.e(TAG,"[onCommandResult] "+cmdMessage);
+ }
+
+ @Override
+ public void onTagOperatorResult(Context context,JPushMessage jPushMessage) {
+ TagAliasOperatorHelper.getInstance().onTagOperatorResult(context,jPushMessage);
+ super.onTagOperatorResult(context, jPushMessage);
+ }
+ @Override
+ public void onCheckTagOperatorResult(Context context,JPushMessage jPushMessage){
+ TagAliasOperatorHelper.getInstance().onCheckTagOperatorResult(context,jPushMessage);
+ super.onCheckTagOperatorResult(context, jPushMessage);
+ }
+ @Override
+ public void onAliasOperatorResult(Context context, JPushMessage jPushMessage) {
+ TagAliasOperatorHelper.getInstance().onAliasOperatorResult(context,jPushMessage);
+ super.onAliasOperatorResult(context, jPushMessage);
+ }
+
+ @Override
+ public void onMobileNumberOperatorResult(Context context, JPushMessage jPushMessage) {
+ TagAliasOperatorHelper.getInstance().onMobileNumberOperatorResult(context,jPushMessage);
+ super.onMobileNumberOperatorResult(context, jPushMessage);
+ }
+
+ //send msg to MainActivity
+// private void processCustomMessage(Context context, CustomMessage customMessage) {
+// if (MainActivity.isForeground) {
+// String message = customMessage.message;
+// String extras = customMessage.extra;
+// Intent msgIntent = new Intent(MainActivity.MESSAGE_RECEIVED_ACTION);
+// msgIntent.putExtra(MainActivity.KEY_MESSAGE, message);
+// if (!ExampleUtil.isEmpty(extras)) {
+// try {
+// JSONObject extraJson = new JSONObject(extras);
+// if (extraJson.length() > 0) {
+// msgIntent.putExtra(MainActivity.KEY_EXTRAS, extras);
+// }
+// } catch (JSONException e) {
+//
+// }
+//
+// }
+// LocalBroadcastManager.getInstance(context).sendBroadcast(msgIntent);
+// }
+// }
+
+ @Override
+ public void onNotificationSettingsCheck(Context context, boolean isOn, int source) {
+ super.onNotificationSettingsCheck(context, isOn, source);
+ Log.e(TAG,"[onNotificationSettingsCheck] isOn:"+isOn+",source:"+source);
+ }
+
+}
diff --git a/app/src/main/java/com/tt/sdk/jpush/jpushdemo/PushService.java b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/PushService.java
new file mode 100644
index 0000000..f6116b2
--- /dev/null
+++ b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/PushService.java
@@ -0,0 +1,8 @@
+package com.tt.sdk.jpush.jpushdemo;
+
+
+import cn.jpush.android.service.JCommonService;
+
+public class PushService extends JCommonService {
+
+}
diff --git a/app/src/main/java/com/tt/sdk/jpush/jpushdemo/TagAliasOperatorHelper.java b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/TagAliasOperatorHelper.java
new file mode 100644
index 0000000..8485a56
--- /dev/null
+++ b/app/src/main/java/com/tt/sdk/jpush/jpushdemo/TagAliasOperatorHelper.java
@@ -0,0 +1,338 @@
+package com.tt.sdk.jpush.jpushdemo;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.util.SparseArray;
+
+import java.util.Locale;
+import java.util.Set;
+
+import cn.jpush.android.api.JPushInterface;
+import cn.jpush.android.api.JPushMessage;
+
+/**
+ * 处理tagalias相关的逻辑
+ * */
+public class TagAliasOperatorHelper {
+ private static final String TAG = "JIGUANG-TagAliasHelper";
+ public static int sequence = 1;
+ /**增加*/
+ public static final int ACTION_ADD = 1;
+ /**覆盖*/
+ public static final int ACTION_SET = 2;
+ /**删除部分*/
+ public static final int ACTION_DELETE = 3;
+ /**删除所有*/
+ public static final int ACTION_CLEAN = 4;
+ /**查询*/
+ public static final int ACTION_GET = 5;
+
+ public static final int ACTION_CHECK = 6;
+
+ public static final int DELAY_SEND_ACTION = 1;
+
+ public static final int DELAY_SET_MOBILE_NUMBER_ACTION = 2;
+
+ private Context context;
+
+ private static TagAliasOperatorHelper mInstance;
+ private TagAliasOperatorHelper(){
+ }
+ public static TagAliasOperatorHelper getInstance(){
+ if(mInstance == null){
+ synchronized (TagAliasOperatorHelper.class){
+ if(mInstance == null){
+ mInstance = new TagAliasOperatorHelper();
+ }
+ }
+ }
+ return mInstance;
+ }
+ public void init(Context context){
+ if(context != null) {
+ this.context = context.getApplicationContext();
+ }
+ }
+ private SparseArray