diff --git a/demo/.classpath b/demo/.classpath
new file mode 100644
index 0000000..5176974
--- /dev/null
+++ b/demo/.classpath
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/demo/.project b/demo/.project
new file mode 100644
index 0000000..abf7313
--- /dev/null
+++ b/demo/.project
@@ -0,0 +1,33 @@
+
+
+ demo
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/demo/.settings/org.eclipse.jdt.core.prefs b/demo/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..b080d2d
--- /dev/null
+++ b/demo/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/demo/AndroidManifest.xml b/demo/AndroidManifest.xml
new file mode 100644
index 0000000..f76359d
--- /dev/null
+++ b/demo/AndroidManifest.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/proguard-project.txt b/demo/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/demo/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# 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 *;
+#}
diff --git a/demo/project.properties b/demo/project.properties
new file mode 100644
index 0000000..bab180d
--- /dev/null
+++ b/demo/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-19
+android.library.reference.1=../zsdk
diff --git a/demo/res/drawable-hdpi/ic_launcher.png b/demo/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..288b665
Binary files /dev/null and b/demo/res/drawable-hdpi/ic_launcher.png differ
diff --git a/demo/res/layout/activity_main.xml b/demo/res/layout/activity_main.xml
new file mode 100644
index 0000000..e00c9d6
--- /dev/null
+++ b/demo/res/layout/activity_main.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/res/menu/main.xml b/demo/res/menu/main.xml
new file mode 100644
index 0000000..c002028
--- /dev/null
+++ b/demo/res/menu/main.xml
@@ -0,0 +1,9 @@
+
diff --git a/demo/res/values/dimens.xml b/demo/res/values/dimens.xml
new file mode 100644
index 0000000..55c1e59
--- /dev/null
+++ b/demo/res/values/dimens.xml
@@ -0,0 +1,7 @@
+
+
+
+ 16dp
+ 16dp
+
+
diff --git a/demo/res/values/strings.xml b/demo/res/values/strings.xml
new file mode 100644
index 0000000..ca78212
--- /dev/null
+++ b/demo/res/values/strings.xml
@@ -0,0 +1,8 @@
+
+
+
+ demo
+ Settings
+ Hello world!
+
+
diff --git a/demo/res/values/styles.xml b/demo/res/values/styles.xml
new file mode 100644
index 0000000..6ce89c7
--- /dev/null
+++ b/demo/res/values/styles.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/demo/src/com/example/demo/MainActivity.java b/demo/src/com/example/demo/MainActivity.java
new file mode 100644
index 0000000..0b2512d
--- /dev/null
+++ b/demo/src/com/example/demo/MainActivity.java
@@ -0,0 +1,53 @@
+package com.example.demo;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import com.zsdk.client.ZSDK;
+import com.zsdk.client.callback.LoginCallback;
+
+public class MainActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ ZSDK.getInstance().init(this, "1");
+
+ findViewById(R.id.but1).setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View arg0) {
+ ZSDK.getInstance().login(MainActivity.this,
+ new LoginCallback() {
+
+ @Override
+ public void onCall(boolean success, String uid,
+ String uname, String token) {
+ Log.i("xxx ", "success:" + success);
+
+ if (success) {
+ Log.i("xxx ", "uid:" + uid + ":" + uname
+ + ":" + token);
+ }
+
+ }
+ });
+
+ }
+ });
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+}
diff --git a/zsdk/.classpath b/zsdk/.classpath
new file mode 100755
index 0000000..b76ec6c
--- /dev/null
+++ b/zsdk/.classpath
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/zsdk/.project b/zsdk/.project
new file mode 100755
index 0000000..3d1124a
--- /dev/null
+++ b/zsdk/.project
@@ -0,0 +1,33 @@
+
+
+ zsdk
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/zsdk/.settings/org.eclipse.core.resources.prefs b/zsdk/.settings/org.eclipse.core.resources.prefs
new file mode 100755
index 0000000..0359d94
--- /dev/null
+++ b/zsdk/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Tue Jul 23 21:39:08 CST 2013
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/zsdk/.settings/org.eclipse.jdt.core.prefs b/zsdk/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..b080d2d
--- /dev/null
+++ b/zsdk/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/zsdk/AndroidManifest.xml b/zsdk/AndroidManifest.xml
new file mode 100755
index 0000000..e068ec0
--- /dev/null
+++ b/zsdk/AndroidManifest.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/libs/okhttp-3.6.0.jar b/zsdk/libs/okhttp-3.6.0.jar
new file mode 100644
index 0000000..e6e4518
Binary files /dev/null and b/zsdk/libs/okhttp-3.6.0.jar differ
diff --git a/zsdk/libs/okio-1.13.0.jar b/zsdk/libs/okio-1.13.0.jar
new file mode 100644
index 0000000..02c302f
Binary files /dev/null and b/zsdk/libs/okio-1.13.0.jar differ
diff --git a/zsdk/lint.xml b/zsdk/lint.xml
new file mode 100644
index 0000000..ee0eead
--- /dev/null
+++ b/zsdk/lint.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/zsdk/proguard-project.txt b/zsdk/proguard-project.txt
new file mode 100755
index 0000000..f2fe155
--- /dev/null
+++ b/zsdk/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# 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 *;
+#}
diff --git a/zsdk/project.properties b/zsdk/project.properties
new file mode 100755
index 0000000..91d2b02
--- /dev/null
+++ b/zsdk/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-19
+android.library=true
diff --git a/zsdk/res/drawable/btn_shape_blue.xml b/zsdk/res/drawable/btn_shape_blue.xml
new file mode 100644
index 0000000..d86950d
--- /dev/null
+++ b/zsdk/res/drawable/btn_shape_blue.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/res/drawable/btn_shape_orange.xml b/zsdk/res/drawable/btn_shape_orange.xml
new file mode 100644
index 0000000..da441c1
--- /dev/null
+++ b/zsdk/res/drawable/btn_shape_orange.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/res/drawable/sdk_bg.xml b/zsdk/res/drawable/sdk_bg.xml
new file mode 100644
index 0000000..783bdeb
--- /dev/null
+++ b/zsdk/res/drawable/sdk_bg.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/res/drawable/sdk_btn_close.xml b/zsdk/res/drawable/sdk_btn_close.xml
new file mode 100644
index 0000000..1e0fdd2
--- /dev/null
+++ b/zsdk/res/drawable/sdk_btn_close.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/res/drawable/sdk_dialog_loading.xml b/zsdk/res/drawable/sdk_dialog_loading.xml
new file mode 100644
index 0000000..44f2292
--- /dev/null
+++ b/zsdk/res/drawable/sdk_dialog_loading.xml
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/zsdk/res/drawable/sdk_icon_close.png b/zsdk/res/drawable/sdk_icon_close.png
new file mode 100755
index 0000000..8895af3
Binary files /dev/null and b/zsdk/res/drawable/sdk_icon_close.png differ
diff --git a/zsdk/res/drawable/sdk_icon_delete.png b/zsdk/res/drawable/sdk_icon_delete.png
new file mode 100644
index 0000000..881e2f7
Binary files /dev/null and b/zsdk/res/drawable/sdk_icon_delete.png differ
diff --git a/zsdk/res/drawable/sdk_icon_drop.png b/zsdk/res/drawable/sdk_icon_drop.png
new file mode 100755
index 0000000..0c338c4
Binary files /dev/null and b/zsdk/res/drawable/sdk_icon_drop.png differ
diff --git a/zsdk/res/drawable/sdk_loading_img.png b/zsdk/res/drawable/sdk_loading_img.png
new file mode 100644
index 0000000..ffb19f5
Binary files /dev/null and b/zsdk/res/drawable/sdk_loading_img.png differ
diff --git a/zsdk/res/drawable/shape_wihte_frame.xml b/zsdk/res/drawable/shape_wihte_frame.xml
new file mode 100644
index 0000000..14dcf07
--- /dev/null
+++ b/zsdk/res/drawable/shape_wihte_frame.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/res/layout/sdk_account_list_item.xml b/zsdk/res/layout/sdk_account_list_item.xml
new file mode 100644
index 0000000..db0495f
--- /dev/null
+++ b/zsdk/res/layout/sdk_account_list_item.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/res/layout/sdk_account_list_view.xml b/zsdk/res/layout/sdk_account_list_view.xml
new file mode 100644
index 0000000..4344428
--- /dev/null
+++ b/zsdk/res/layout/sdk_account_list_view.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/res/layout/sdk_view_login.xml b/zsdk/res/layout/sdk_view_login.xml
new file mode 100644
index 0000000..c412fec
--- /dev/null
+++ b/zsdk/res/layout/sdk_view_login.xml
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/res/layout/sdk_view_register.xml b/zsdk/res/layout/sdk_view_register.xml
new file mode 100644
index 0000000..4cdd464
--- /dev/null
+++ b/zsdk/res/layout/sdk_view_register.xml
@@ -0,0 +1,155 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/res/layout/sdk_view_wait.xml b/zsdk/res/layout/sdk_view_wait.xml
new file mode 100644
index 0000000..592e5d0
--- /dev/null
+++ b/zsdk/res/layout/sdk_view_wait.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/res/values/sdk_colors.xml b/zsdk/res/values/sdk_colors.xml
new file mode 100644
index 0000000..b84e38d
--- /dev/null
+++ b/zsdk/res/values/sdk_colors.xml
@@ -0,0 +1,9 @@
+
+
+
+ #2f72a7
+ #4f92c7
+ #de9301
+ #feb301
+
+
\ No newline at end of file
diff --git a/zsdk/res/values/sdk_strings.xml b/zsdk/res/values/sdk_strings.xml
new file mode 100644
index 0000000..2649c8b
--- /dev/null
+++ b/zsdk/res/values/sdk_strings.xml
@@ -0,0 +1,14 @@
+
+
+
+ 账号:
+ 密码:
+ 确认:
+
+ 密码
+ 确认密码
+ 账号
+ 注册
+ 登录
+
+
\ No newline at end of file
diff --git a/zsdk/res/values/sdk_style.xml b/zsdk/res/values/sdk_style.xml
new file mode 100644
index 0000000..da93e21
--- /dev/null
+++ b/zsdk/res/values/sdk_style.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zsdk/src/com/zsdk/client/Constant.java b/zsdk/src/com/zsdk/client/Constant.java
new file mode 100644
index 0000000..6c03fd3
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/Constant.java
@@ -0,0 +1,10 @@
+package com.zsdk.client;
+
+public class Constant {
+ public final static int INPUT_MIN_LEN = 1;
+ public final static int INPUT_MAX_LEN = 11;
+
+ // 客户端签名的key
+ public final static String CLIENT_SIGN_KEY = "944z4925*&^$4311e792671";
+
+}
diff --git a/zsdk/src/com/zsdk/client/HttpCode.java b/zsdk/src/com/zsdk/client/HttpCode.java
new file mode 100644
index 0000000..82589c6
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/HttpCode.java
@@ -0,0 +1,8 @@
+package com.zsdk.client;
+
+public enum HttpCode {
+ HttpCodeSuccess,
+ HttpCodeNetError,
+ HttpCodeDataError,
+ HttpCodeLogicError
+}
diff --git a/zsdk/src/com/zsdk/client/ZSDK.java b/zsdk/src/com/zsdk/client/ZSDK.java
new file mode 100644
index 0000000..825fbfd
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/ZSDK.java
@@ -0,0 +1,50 @@
+package com.zsdk.client;
+
+import android.app.Activity;
+
+import com.zsdk.client.callback.LoginCallback;
+import com.zsdk.client.logic.AccountLogic;
+import com.zsdk.client.ui.LoginView;
+import com.zsdk.client.util.DeviceUtil;
+import com.zsdk.client.util.LogUtil;
+import com.zsdk.client.util.ToastUtil;
+
+public class ZSDK {
+ private final static ZSDK _instance = new ZSDK();
+
+ private static Activity _activity;
+ private static String _appId;
+
+ public static ZSDK getInstance() {
+ return _instance;
+ }
+
+ public Activity getActivity() {
+ return _activity;
+ }
+
+ public String getAppId() {
+ return _appId;
+ }
+
+ private ZSDK() {
+ }
+
+ public void init(Activity activity, String appId) {
+ _activity = activity;
+ _appId = appId;
+
+ LogUtil.i("path", DeviceUtil.getWritablePath());
+ AccountLogic.loadLocalAccount();
+ }
+
+ public void login(Activity activity, LoginCallback loginCallback) {
+ if (loginCallback == null) {
+ ToastUtil.show(activity, "参数错误");
+ return;
+ }
+ new LoginView(activity, loginCallback).show();
+
+ }
+
+}
diff --git a/zsdk/src/com/zsdk/client/adapt/AccountSelectAdapter.java b/zsdk/src/com/zsdk/client/adapt/AccountSelectAdapter.java
new file mode 100644
index 0000000..2355a9c
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/adapt/AccountSelectAdapter.java
@@ -0,0 +1,90 @@
+package com.zsdk.client.adapt;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.zsdk.client.logic.AccountLogic;
+import com.zsdk.client.model.AccountInfo;
+import com.zsdk.client.ui.LoginView;
+import com.zsdk.client.util.ResourceUtil;
+
+public class AccountSelectAdapter extends BaseAdapter implements
+ OnClickListener, OnItemClickListener {
+
+ private Context context;
+ private LoginView loginView;
+
+ public AccountSelectAdapter(Context context, LoginView loginView) {
+ this.context = context;
+ this.loginView = loginView;
+ }
+
+ @Override
+ public int getCount() {
+ return AccountLogic.getAccountSize();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return AccountLogic.getAccounts().get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder vh;
+ if (convertView == null) {
+ vh = new ViewHolder();
+
+ convertView = LayoutInflater.from(context).inflate(
+ ResourceUtil.getIdentifier(context,
+ "R.layout.sdk_account_list_item"), null);
+ vh.account = (TextView) convertView.findViewById(ResourceUtil
+ .getIdentifier(context, "R.id.tx_account"));
+ vh.delete = (ImageView) convertView.findViewById(ResourceUtil
+ .getIdentifier(context, "R.id.iv_del"));
+ vh.delete.setTag(position);
+ vh.delete.setOnClickListener(this);
+ convertView.setTag(vh);
+ } else {
+ vh = (ViewHolder) convertView.getTag();
+ }
+ vh.account.setText(AccountLogic.getAccounts().get(position).username);
+ return convertView;
+ }
+
+ @Override
+ public void onClick(View view) {
+ int position = (Integer) view.getTag();
+ AccountInfo accountInfo = AccountLogic.getAccounts().remove(position);
+ this.notifyDataSetChanged();
+ loginView.deleteAccount(accountInfo);
+ AccountLogic.saveLocalAccount();
+
+ }
+
+ static class ViewHolder {
+ TextView account;
+ ImageView delete;
+ }
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position,
+ long id) {
+
+ loginView.update((AccountLogic.getAccounts().get(position)));
+ loginView.hideDrop();
+ }
+}
\ No newline at end of file
diff --git a/zsdk/src/com/zsdk/client/callback/LoginCallback.java b/zsdk/src/com/zsdk/client/callback/LoginCallback.java
new file mode 100644
index 0000000..f2502f9
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/callback/LoginCallback.java
@@ -0,0 +1,5 @@
+package com.zsdk.client.callback;
+
+public interface LoginCallback {
+ void onCall(boolean success, String uid, String uname, String token);
+}
diff --git a/zsdk/src/com/zsdk/client/callback/PostCallback.java b/zsdk/src/com/zsdk/client/callback/PostCallback.java
new file mode 100644
index 0000000..06b39a2
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/callback/PostCallback.java
@@ -0,0 +1,10 @@
+package com.zsdk.client.callback;
+
+import org.json.JSONObject;
+
+import com.zsdk.client.HttpCode;
+
+public interface PostCallback {
+ void onCall(HttpCode err, JSONObject json, String msg);
+
+}
diff --git a/zsdk/src/com/zsdk/client/logic/AccountLogic.java b/zsdk/src/com/zsdk/client/logic/AccountLogic.java
new file mode 100644
index 0000000..b19a925
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/logic/AccountLogic.java
@@ -0,0 +1,215 @@
+package com.zsdk.client.logic;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.zsdk.client.Constant;
+import com.zsdk.client.HttpCode;
+import com.zsdk.client.ZSDK;
+import com.zsdk.client.callback.LoginCallback;
+import com.zsdk.client.callback.PostCallback;
+import com.zsdk.client.model.AccountInfo;
+import com.zsdk.client.util.DeviceUtil;
+import com.zsdk.client.util.EncryptUtil;
+import com.zsdk.client.util.HttpUtil;
+import com.zsdk.client.util.LogUtil;
+import com.zsdk.client.util.StringUtil;
+import com.zsdk.client.util.ToastUtil;
+
+public class AccountLogic {
+
+ private static List accounts = new ArrayList();
+
+ public static AccountInfo getLast() {
+ int size = accounts.size();
+ if (size > 0) {
+ return accounts.get(size - 1);
+ }
+ return null;
+ }
+
+ public static int getAccountSize() {
+ return accounts.size();
+ }
+ public static List getAccounts() {
+ return accounts;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void loadLocalAccount() {
+ accounts.clear();
+
+ String path = DeviceUtil.getWritablePath();
+ File f = new File(path + File.separator + "accouont");
+ if (f.exists()) {
+
+ try {
+ InputStream in = new FileInputStream(f);
+ ObjectInputStream os = new ObjectInputStream(in);
+
+ accounts = (List) os.readObject();
+
+ os.close();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ LogUtil.i("accounts", accounts);
+ }
+
+ public static Map getCommon() {
+ Map map = new HashMap();
+
+ map.put("systemName", android.os.Build.DISPLAY);
+ map.put("systemVersion", android.os.Build.VERSION.RELEASE);
+ map.put("deviceModel", android.os.Build.MODEL);
+ map.put("deviceName", android.os.Build.USER);
+ map.put("appId", ZSDK.getInstance().getAppId());
+ map.put("platform", "android");
+ map.put("root", "0");
+
+ return map;
+ }
+
+ public static void login(String username, String password,
+ LoginCallback callback) {
+ loginOrRegister("login.do", username, password, callback);
+ }
+
+ public static void registerAccount(String username, String password,
+ LoginCallback callback) {
+ loginOrRegister("register.do", username, password, callback);
+ }
+
+ private static AccountInfo findAccountByUid(int uid) {
+ for (AccountInfo accountInfo : accounts) {
+ if (accountInfo.uid == uid) {
+ return accountInfo;
+ }
+ }
+
+ return null;
+ }
+
+ public static void saveLocalAccount() {
+ try {
+ String path = DeviceUtil.getWritablePath();
+ File f = new File(path + File.separator + "accouont");
+ if (!f.exists()) {
+ f.createNewFile();
+ }
+
+ Collections.sort(accounts, new Comparator() {
+ @Override
+ public int compare(AccountInfo o1, AccountInfo o2) {
+ return (int) (o2.lastLoginTime - o1.lastLoginTime);
+ }
+ });
+
+ OutputStream os = new FileOutputStream(f);
+ ObjectOutputStream oos = new ObjectOutputStream(os);
+ oos.writeObject(accounts);
+ oos.close();
+ os.close();
+ } catch (Exception e) {
+ //
+ e.printStackTrace();
+ }
+ }
+
+ private static void loginOrRegister(String path, final String username,
+ final String password, final LoginCallback callback) {
+
+ Map map = getCommon();
+ map.put("username", username);
+ map.put("password", EncryptUtil.md5(password));
+ map.put("sign", genSign(map));
+ HttpUtil.post(path, map, new PostCallback() {
+
+ @Override
+ public void onCall(HttpCode err, JSONObject json, final String msg) {
+
+ if (err == HttpCode.HttpCodeSuccess) {
+ int uid = -1;
+ String token = "";
+ try {
+ uid = json.getInt("uid");
+ token = json.getString("token");
+ } catch (JSONException e) {
+
+ e.printStackTrace();
+ }
+ AccountInfo accountInfo = findAccountByUid(uid);
+ if (accountInfo == null) {
+ accountInfo = new AccountInfo();
+ accounts.add(accountInfo);
+
+ }
+ accountInfo.uid = uid;
+ accountInfo.password = password;
+ accountInfo.username = username;
+ accountInfo.lastLoginTime = System.currentTimeMillis() / 1000L;
+ saveLocalAccount();
+
+ final String ttkoen = token;
+ final String uuid = "" + uid;
+
+ ZSDK.getInstance().getActivity()
+ .runOnUiThread(new Runnable() {
+
+ @Override
+ public void run() {
+ ToastUtil.show(ZSDK.getInstance()
+ .getActivity(), msg);
+ callback.onCall(true, uuid, username,
+ ttkoen);
+
+ }
+ });
+
+ } else {
+ ZSDK.getInstance().getActivity()
+ .runOnUiThread(new Runnable() {
+
+ @Override
+ public void run() {
+ ToastUtil.show(ZSDK.getInstance()
+ .getActivity(), msg);
+ callback.onCall(false, null, null, null);
+
+ }
+ });
+ }
+
+ }
+
+ });
+ }
+
+ private static String genSign(Map map) {
+
+ List keys = new ArrayList(map.keySet());
+
+ String content = StringUtil.getSignData(map, keys, "&", "=") + "&"
+ + Constant.CLIENT_SIGN_KEY;
+ return EncryptUtil.md5(content);
+ }
+
+}
diff --git a/zsdk/src/com/zsdk/client/model/AccountInfo.java b/zsdk/src/com/zsdk/client/model/AccountInfo.java
new file mode 100644
index 0000000..c997e19
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/model/AccountInfo.java
@@ -0,0 +1,21 @@
+package com.zsdk.client.model;
+
+import java.io.Serializable;
+
+public class AccountInfo implements Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6357019483578581915L;
+ public int uid;
+ public String username;
+ public String password;
+ public long lastLoginTime;
+
+ @Override
+ public String toString() {
+ return "uid:" + uid + " username:" + username + " password:" + password
+ + " lastLoginTime:" + lastLoginTime;
+ }
+
+}
diff --git a/zsdk/src/com/zsdk/client/ui/BaseView.java b/zsdk/src/com/zsdk/client/ui/BaseView.java
new file mode 100644
index 0000000..c075932
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/ui/BaseView.java
@@ -0,0 +1,83 @@
+package com.zsdk.client.ui;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+import com.zsdk.client.Constant;
+import com.zsdk.client.util.ResourceUtil;
+import com.zsdk.client.util.StringUtil;
+import com.zsdk.client.util.ToastUtil;
+
+public abstract class BaseView extends AlertDialog {
+ protected Context _context;
+ private LoadingDialog waitDialog;
+
+ protected BaseView(Context context) {
+
+ super(context);
+
+ _context = context;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+
+ super.onCreate(savedInstanceState);
+
+ setContentView(getLayoutId());
+
+ setCancelable(false);
+ setCanceledOnTouchOutside(false);
+ getWindow().setDimAmount(0.1f);
+ getWindow()
+ .clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+ init();
+ }
+
+ public abstract int getLayoutId();
+
+ public abstract void init();
+
+ protected void showToast(String msg) {
+ ToastUtil.show(_context, msg);
+ }
+
+ public boolean checkInputInfo(String account, String password) {
+
+ if (!StringUtil.checkInput(account)
+ || account.length() < Constant.INPUT_MIN_LEN
+ || account.length() > Constant.INPUT_MAX_LEN) {
+ showToast(String.format("用户名长度为%d~%d字母和数字", Constant.INPUT_MIN_LEN,
+ Constant.INPUT_MAX_LEN));
+ return false;
+ }
+ if (!StringUtil.checkInput(password) || password == null
+ || password.length() < Constant.INPUT_MIN_LEN
+ || password.length() > Constant.INPUT_MAX_LEN) {
+ showToast(String.format("密码长度为%d~%d字母和数字", Constant.INPUT_MIN_LEN,
+ Constant.INPUT_MAX_LEN));
+ return false;
+ }
+ return true;
+ }
+
+ protected void showWait() {
+ if (waitDialog == null) {
+
+ waitDialog = new LoadingDialog(_context,
+ ResourceUtil.getIdentifier(_context,
+ "R.style.sdk_wait_dialog"));
+ }
+ waitDialog.show();
+
+ }
+
+ protected void hideWait() {
+ if (waitDialog != null) {
+ waitDialog.dismiss();
+ }
+ }
+
+}
diff --git a/zsdk/src/com/zsdk/client/ui/LoadingDialog.java b/zsdk/src/com/zsdk/client/ui/LoadingDialog.java
new file mode 100644
index 0000000..cbda3a1
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/ui/LoadingDialog.java
@@ -0,0 +1,30 @@
+package com.zsdk.client.ui;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+
+import com.zsdk.client.util.ResourceUtil;
+
+public class LoadingDialog extends Dialog {
+ protected Context _context;
+
+
+
+ public LoadingDialog(Context context, int theme) {
+ super(context, theme);
+ this._context = context;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(ResourceUtil.getIdentifier(_context,
+ "R.layout.sdk_view_wait"));
+ setCancelable(false);
+ setCanceledOnTouchOutside(false);
+
+ }
+
+}
diff --git a/zsdk/src/com/zsdk/client/ui/LoginView.java b/zsdk/src/com/zsdk/client/ui/LoginView.java
new file mode 100644
index 0000000..8f5ab27
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/ui/LoginView.java
@@ -0,0 +1,155 @@
+package com.zsdk.client.ui;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.PopupWindow;
+import android.widget.RelativeLayout.LayoutParams;
+
+import com.zsdk.client.adapt.AccountSelectAdapter;
+import com.zsdk.client.callback.LoginCallback;
+import com.zsdk.client.logic.AccountLogic;
+import com.zsdk.client.model.AccountInfo;
+import com.zsdk.client.util.ResourceUtil;
+
+public class LoginView extends BaseView implements
+ android.view.View.OnClickListener {
+ private EditText etAccount;
+ private EditText etPassword;
+ private Button btnLogin;
+ private Button btnRegister;
+ private ImageView ivClose;
+ private ImageView ivDrop;
+ private LoginCallback loginCallback;
+ private PopupWindow popupWindow;
+ private AccountInfo accountInfo;
+
+ public LoginView(Context context, LoginCallback loginCallback) {
+ super(context);
+ this.loginCallback = loginCallback;
+ }
+
+ @Override
+ public void init() {
+ ivClose = (ImageView) findViewById(ResourceUtil.getIdentifier(_context,
+ "R.id.iv_close"));
+ ivClose.setOnClickListener(this);
+
+ ivDrop = (ImageView) findViewById(ResourceUtil.getIdentifier(_context,
+ "R.id.iv_drop"));
+ ivDrop.setOnClickListener(this);
+
+ btnLogin = (Button) findViewById(ResourceUtil.getIdentifier(_context,
+ "R.id.btn_login"));
+ btnLogin.setOnClickListener(this);
+
+ btnRegister = (Button) findViewById(ResourceUtil.getIdentifier(
+ _context, "R.id.btn_register"));
+ btnRegister.setOnClickListener(this);
+
+ etAccount = (EditText) findViewById(ResourceUtil.getIdentifier(
+ _context, "R.id.et_account"));
+
+ etPassword = (EditText) findViewById(ResourceUtil.getIdentifier(
+ _context, "R.id.et_password"));
+
+ update(AccountLogic.getLast());
+ }
+
+ public void update(AccountInfo accountInfo) {
+ this.accountInfo = accountInfo;
+ if (accountInfo != null) {
+ etAccount.setText(accountInfo.username);
+ etPassword.setText(accountInfo.password);
+ } else {
+ etAccount.setText("");
+ etPassword.setText("");
+ }
+ }
+
+ public void deleteAccount(AccountInfo accountInfo) {
+ if (this.accountInfo != null && this.accountInfo == accountInfo) {
+ update(AccountLogic.getLast());
+ }
+
+ }
+
+ public void hideDrop() {
+ if (popupWindow != null) {
+ popupWindow.dismiss();
+ }
+ }
+
+ private void showDrop() {
+ if (popupWindow == null) {
+
+ View view = LayoutInflater.from(_context).inflate(
+ ResourceUtil.getIdentifier(_context,
+ "R.layout.sdk_account_list_view"), null);
+
+ ListView listView = (ListView) view.findViewById(ResourceUtil
+ .getIdentifier(_context, "R.id.listView"));
+ AccountSelectAdapter accountSelectAdapter = new AccountSelectAdapter(
+ _context, this);
+ listView.setAdapter(accountSelectAdapter);
+
+ listView.setOnItemClickListener(accountSelectAdapter);
+
+ popupWindow = new PopupWindow(view, LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT);
+ popupWindow.setOutsideTouchable(false);
+ popupWindow.setFocusable(true);
+ }
+
+ popupWindow.showAsDropDown(etAccount);
+
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view == ivClose) {
+ dismiss();
+ this.loginCallback.onCall(false, null, null, null);
+ } else if (view == ivDrop) {
+ showDrop();
+
+ } else if (view == btnLogin) {
+ String account = etAccount.getText().toString();
+ String password = etPassword.getText().toString();
+
+ if (checkInputInfo(account, password)) {
+ showWait();
+ AccountLogic.login(account, password, new LoginCallback() {
+
+ @Override
+ public void onCall(boolean success, String uid,
+ String uname, String token) {
+ hideWait();
+ LoginView.this.loginCallback.onCall(success, uid,
+ uname, token);
+ if (success) {
+ dismiss();
+ }
+
+ }
+ });
+
+ }
+
+ } else if (view == btnRegister) {
+ dismiss();
+ new RegisterView(_context, loginCallback).show();
+ }
+
+ }
+
+ @Override
+ public int getLayoutId() {
+ return ResourceUtil.getIdentifier(_context, "R.layout.sdk_view_login");
+ }
+
+}
diff --git a/zsdk/src/com/zsdk/client/ui/RegisterView.java b/zsdk/src/com/zsdk/client/ui/RegisterView.java
new file mode 100644
index 0000000..5572624
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/ui/RegisterView.java
@@ -0,0 +1,92 @@
+package com.zsdk.client.ui;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+
+import com.zsdk.client.callback.LoginCallback;
+import com.zsdk.client.logic.AccountLogic;
+import com.zsdk.client.util.ResourceUtil;
+
+public class RegisterView extends BaseView implements
+ android.view.View.OnClickListener {
+ private EditText etAccount;
+ private EditText etPassword;
+ private EditText etPasswordConfirm;
+
+ private Button btnRegister;
+ private ImageView ivClose;
+ private LoginCallback loginCallback;
+
+ public RegisterView(Context context, LoginCallback loginCallback) {
+ super(context);
+ this.loginCallback = loginCallback;
+ }
+
+ @Override
+ public void init() {
+ ivClose = (ImageView) findViewById(ResourceUtil.getIdentifier(_context,
+ "R.id.iv_close"));
+ ivClose.setOnClickListener(this);
+
+ btnRegister = (Button) findViewById(ResourceUtil.getIdentifier(
+ _context, "R.id.btn_register"));
+ btnRegister.setOnClickListener(this);
+
+ etAccount = (EditText) findViewById(ResourceUtil.getIdentifier(
+ _context, "R.id.et_account"));
+
+ etPassword = (EditText) findViewById(ResourceUtil.getIdentifier(
+ _context, "R.id.et_password"));
+ etPasswordConfirm = (EditText) findViewById(ResourceUtil.getIdentifier(
+ _context, "R.id.et_password_confirm"));
+
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view == ivClose) {
+ dismiss();
+ new LoginView(_context, loginCallback).show();
+ } else if (view == btnRegister) {
+ String account = etAccount.getText().toString();
+ String password = etPassword.getText().toString();
+ String password2 = etPasswordConfirm.getText().toString();
+
+ if (checkInputInfo(account, password)) {
+ if (!password2.equals(password)) {
+ showToast("请输入相同的密码");
+ return;
+ }
+ showWait();
+ AccountLogic.registerAccount(account, password,
+ new LoginCallback() {
+
+ @Override
+ public void onCall(boolean success, String uid,
+ String uname, String token) {
+ hideWait();
+ RegisterView.this.loginCallback.onCall(success,
+ uid, uname, token);
+ if (success) {
+ dismiss();
+ }
+
+ }
+ });
+
+ }
+
+ }
+
+ }
+
+ @Override
+ public int getLayoutId() {
+ return ResourceUtil.getIdentifier(_context,
+ "R.layout.sdk_view_register");
+ }
+
+}
diff --git a/zsdk/src/com/zsdk/client/util/DeviceUtil.java b/zsdk/src/com/zsdk/client/util/DeviceUtil.java
new file mode 100644
index 0000000..582393b
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/util/DeviceUtil.java
@@ -0,0 +1,28 @@
+package com.zsdk.client.util;
+
+import java.io.File;
+
+import android.content.Context;
+import android.os.Environment;
+import android.telephony.TelephonyManager;
+
+public class DeviceUtil {
+ public static String getImei(Context context) {
+ String imei = null;
+ TelephonyManager phoneManager = (TelephonyManager) context
+ .getSystemService(Context.TELEPHONY_SERVICE);
+ if (phoneManager != null)
+ imei = phoneManager.getDeviceId();
+ if (imei == null)
+ imei = "";
+ return imei;
+ }
+
+ public static String getWritablePath() {
+ File f = Environment.getExternalStoragePublicDirectory("zsdk");
+ if (!f.exists()) {
+ f.mkdirs();
+ }
+ return f.getAbsolutePath();
+ }
+}
diff --git a/zsdk/src/com/zsdk/client/util/EncryptUtil.java b/zsdk/src/com/zsdk/client/util/EncryptUtil.java
new file mode 100644
index 0000000..0c29485
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/util/EncryptUtil.java
@@ -0,0 +1,57 @@
+package com.zsdk.client.util;
+
+import java.security.MessageDigest;
+
+/**
+ * Created by zhj on 17/3/15.
+ */
+public class EncryptUtil {
+
+ public static String md5(String txt) {
+
+ return encrypt(txt, "md5");
+ }
+
+ public static String sha(String txt) {
+
+ return encrypt(txt, "sha");
+ }
+
+ private static String encrypt(String txt, String algorithName) {
+
+ if (txt == null || txt.trim().length() == 0) {
+ return null;
+ }
+
+ if (algorithName == null || algorithName.trim().length() == 0) {
+ algorithName = "MD5";
+ }
+
+ String result = null;
+
+ try {
+ MessageDigest m = MessageDigest.getInstance(algorithName);
+ m.reset();
+ m.update(txt.getBytes("UTF-8"));
+ byte[] bts = m.digest();
+
+ result = hex(bts);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ private static String hex(byte[] bts) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < bts.length; i++) {
+ sb.append(Integer.toHexString((bts[i] & 0xFF) | 0x100).substring(1,
+ 3));
+ }
+
+ return sb.toString();
+ }
+
+
+}
diff --git a/zsdk/src/com/zsdk/client/util/HttpUtil.java b/zsdk/src/com/zsdk/client/util/HttpUtil.java
new file mode 100644
index 0000000..ca5feae
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/util/HttpUtil.java
@@ -0,0 +1,86 @@
+package com.zsdk.client.util;
+
+import java.io.IOException;
+import java.util.Map;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.zsdk.client.HttpCode;
+import com.zsdk.client.callback.PostCallback;
+
+public class HttpUtil {
+
+ private final static String HOST = "http://192.168.1.103:8081/sdkserver/";
+
+ public static void post(String path, Map map,
+ final PostCallback postCallback) {
+ if (postCallback == null) {
+ return;
+ }
+ JSONObject json = new JSONObject(map);
+
+ RequestBody body = RequestBody.create(
+ MediaType.parse("application/json; charset=utf-8"),
+ json.toString());
+
+ OkHttpClient okHttpClient = new OkHttpClient();
+
+ Request request = new Request.Builder().url(HOST + path).post(body)
+ .build();
+
+ Call call = okHttpClient.newCall(request);
+ call.enqueue(new Callback() {
+ @Override
+ public void onFailure(Call call, IOException e) {
+ e.printStackTrace();
+
+ LogUtil.i("onFailure:", e.getMessage(), "Thread:"
+ + Thread.currentThread().getId());
+
+ postCallback.onCall(HttpCode.HttpCodeNetError, null,
+ "网络出错,请稍后重试");
+
+ }
+
+ @Override
+ public void onResponse(Call call, Response response)
+ throws IOException {
+ String result = response.body().string();
+
+ LogUtil.i("onResponse:", result, "Thread:"
+ + Thread.currentThread().getId());
+
+ try {
+ JSONObject json = new JSONObject(result);
+ int code = json.getInt("code");
+ String msg = json.getString("msg");
+ if (code == 0) {
+ postCallback.onCall(HttpCode.HttpCodeSuccess,
+ json.getJSONObject("data"), msg);
+ } else {
+ postCallback.onCall(HttpCode.HttpCodeLogicError, null,
+ msg);
+ }
+ } catch (JSONException e) {
+
+ e.printStackTrace();
+
+ postCallback.onCall(HttpCode.HttpCodeDataError, null,
+ "数据出错,请稍后重试");
+ }
+
+ }
+
+ });
+
+ }
+}
diff --git a/zsdk/src/com/zsdk/client/util/LogUtil.java b/zsdk/src/com/zsdk/client/util/LogUtil.java
new file mode 100644
index 0000000..75f7170
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/util/LogUtil.java
@@ -0,0 +1,18 @@
+package com.zsdk.client.util;
+
+import android.util.Log;
+
+public class LogUtil {
+
+ private final static String TAG = LogUtil.class.getSimpleName();
+
+ public static void i(Object... list) {
+ StringBuffer sb = new StringBuffer();
+ for (Object str : list) {
+ sb.append(str);
+ }
+
+ Log.i(TAG, sb.toString());
+ }
+
+}
diff --git a/zsdk/src/com/zsdk/client/util/ResourceUtil.java b/zsdk/src/com/zsdk/client/util/ResourceUtil.java
new file mode 100644
index 0000000..1852676
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/util/ResourceUtil.java
@@ -0,0 +1,17 @@
+package com.zsdk.client.util;
+
+import android.content.Context;
+
+public class ResourceUtil {
+ public static int getIdentifier(Context context, String paramString) {
+ if (paramString != null) {
+ String[] splits = paramString.split("\\.", 3);
+ if (splits.length == 3) {
+ return context.getResources().getIdentifier(splits[2],
+ splits[1], context.getPackageName());
+ }
+ }
+
+ return 0;
+ }
+}
diff --git a/zsdk/src/com/zsdk/client/util/StringUtil.java b/zsdk/src/com/zsdk/client/util/StringUtil.java
new file mode 100644
index 0000000..55ee0ac
--- /dev/null
+++ b/zsdk/src/com/zsdk/client/util/StringUtil.java
@@ -0,0 +1,216 @@
+package com.zsdk.client.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * Created by zhj on 17/12/11.
+ */
+public class StringUtil {
+
+ public static String getSignData(Map params,
+ List keys, String connector, String separator) {
+ StringBuffer content = new StringBuffer();
+
+ // 按照自然升序处理
+ Collections.sort(keys);
+
+ for (int i = 0; i < keys.size(); i++) {
+ String key = keys.get(i);
+ String value = params.get(key);
+ if (value != null && value.length() > 0) {
+ content.append((i == 0 ? "" : connector) + key + separator
+ + value);
+ }
+ }
+ return content.toString();
+ }
+
+ /**
+ * 将map中参数生成签名字符串
+ *
+ * @param params
+ * @return
+ */
+ public static String getSignData(Map params) {
+ return getSignData(params, "&");
+ }
+
+ public static String getSignData(Map params,
+ String connector) {
+ return getSignData(params, connector, true);
+ }
+
+ public static String getSignDataWithoutKeySorted(
+ Map params, String connector) {
+ return getSignData(params, connector, false);
+ }
+
+ public static String getSignData(Map params,
+ String connector, String separator) {
+ StringBuffer content = new StringBuffer();
+ List keys = new ArrayList(params.keySet());
+ // 按照自然升序处理
+ Collections.sort(keys);
+
+ for (int i = 0; i < keys.size(); i++) {
+ String key = keys.get(i);
+ String value = params.get(key);
+ if (value != null) {
+ content.append((i == 0 ? "" : connector) + key + separator
+ + value);
+ } else {
+ content.append((i == 0 ? "" : connector) + key + separator);
+ }
+ }
+ return content.toString();
+ }
+
+ public static String getSignDataWithoutKeys(Map params,
+ String connector) {
+ StringBuffer content = new StringBuffer();
+ List keys = new ArrayList(params.keySet());
+ // 按照自然升序处理
+ Collections.sort(keys);
+
+ for (int i = 0; i < keys.size(); i++) {
+ String key = keys.get(i);
+ String value = params.get(key);
+ if (value != null) {
+ content.append((i == 0 ? "" : connector) + value);
+ } else {
+ content.append((i == 0 ? "" : connector));
+ }
+ }
+ return content.toString();
+ }
+
+ public static String getSignData(Map params,
+ String connector, boolean isKeySorted) {
+ StringBuffer content = new StringBuffer();
+ List keys = new ArrayList(params.keySet());
+
+ if (isKeySorted) {
+ // 按照自然升序处理
+ Collections.sort(keys);
+ }
+
+ for (int i = 0; i < keys.size(); i++) {
+ String key = keys.get(i);
+ String value = params.get(key);
+ if (value != null) {
+ content.append((i == 0 ? "" : connector) + key + "=" + value);
+ } else {
+ content.append((i == 0 ? "" : connector) + key + "=");
+ }
+ }
+ return content.toString();
+
+ }
+
+ public static String getSignDataSortByKeyWithValueUrlEncode(
+ Map params) {
+ StringBuffer content = new StringBuffer();
+ List keys = new ArrayList(params.keySet());
+
+ // 按照自然升序处理
+ Collections.sort(keys);
+ for (int i = 0; i < keys.size(); i++) {
+ String key = keys.get(i);
+ String value = params.get(key);
+ try {
+ value = URLEncoder.encode(value, "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ if (value != null) {
+ content.append((i == 0 ? "" : "&") + key + "=" + value);
+ } else {
+ content.append((i == 0 ? "" : "&") + key + "=");
+ }
+ }
+ return content.toString();
+
+ }
+
+ /**
+ * 检查字符串是否是空白:null、空字符串""或只有空白字符。
+ *
+ *