├── .gitignore
├── .idea
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
├── release
│ ├── app-release.apk
│ └── output.json
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── legend
│ │ └── tbs
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── legend
│ │ │ └── tbs
│ │ │ ├── LuncherActivity.java
│ │ │ ├── TbsActivity.java
│ │ │ ├── common
│ │ │ ├── BaseFragment.java
│ │ │ ├── CircleImageView.java
│ │ │ ├── MyWebViewClient.java
│ │ │ ├── adapter
│ │ │ │ ├── MainFragmentAdapter.java
│ │ │ │ └── TbsAdapter.java
│ │ │ ├── model
│ │ │ │ └── TbsBean.java
│ │ │ ├── net
│ │ │ │ ├── IHttpClient.java
│ │ │ │ ├── IRequest.java
│ │ │ │ ├── IResponse.java
│ │ │ │ └── impl
│ │ │ │ │ ├── OkHttpClientImpl.java
│ │ │ │ │ ├── RequestImpl.java
│ │ │ │ │ └── ResponseImpl.java
│ │ │ └── utils
│ │ │ │ └── Calculate.java
│ │ │ ├── contract
│ │ │ └── BaseContract.java
│ │ │ └── fragment
│ │ │ ├── BaseModel.java
│ │ │ ├── FriendTbsFragment.java
│ │ │ ├── FriendTbsPresenter.java
│ │ │ ├── SelfTbsFragment.java
│ │ │ └── SelfTbsPresenter.java
│ └── res
│ │ ├── anim
│ │ └── loading_animation.xml
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_loading_public.xml
│ │ └── shape.xml
│ │ ├── layout
│ │ ├── activity_luncher.xml
│ │ ├── activity_main.xml
│ │ ├── fragment_friend.xml
│ │ ├── fragments_self.xml
│ │ ├── item_tbs.xml
│ │ └── loading_dialog.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── values-v21
│ │ ├── attrs.xml
│ │ └── styles.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ └── values-v21
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── legend
│ └── tbs
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | 1.8
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | (已失效,加密应该是放到服务器端去了)
2 | # TBS
3 | ## 一、开篇
4 | 最近坦白说也是异常的火,作为开发者的我也去赶紧跑过去蹭了一下热度,写了个安卓的,加载了头像,点击后直接跳转到QQ资料卡页面,并且优化了已有的解密的算法(已有的大多数情况不能完全解密),目前还没发现解密出现问题的。
5 | 看看图
6 | 
7 |
8 |
9 | ## 二、分析
10 | 首先,要拿到数据的接口,得先拿到对应的token,而这个token就是使用skey进行一系列计算得出的,这个skey就是登录QQ空间后从返回的cookie中可以获取的。计算出token后,就可以放到这个接口,以获取好友的数据为例
11 | ```
12 | https://ti.qq.com/cgi-node/honest-say/receive/friends?_client_version=0.0.7&token=
13 | ```
14 | 这样就可以拿到返回后的Json数据,然后就开始操作了
15 | ```
16 | {
17 | "code": 0,
18 | "data": {
19 | "confesses": [],
20 | "maxUnread": 0,
21 | "cookie": "CIsB",
22 | "finish": 0
23 | }
24 | }
25 | ```
26 | 看看,这段数据就是返回后的Json数据,confesses就是返回后的数据列表,注意这里面的cookie,也就是进行分页加载需要传递的参数,如果没有数据了,这个finish就会变为1,cookie直接加到后面
27 | ```
28 | https://ti.qq.com/cgi-node/honest-say/receive/friends?_client_version=0.0.7&token=计算的token&cookie=CIsB
29 | ```
30 | 这样就能加载完整的数据了,然后关键是解密,这里的话已经有公开的,但是解密不完整,这里我花了一些时间,这个解密的规则是先2位加密的字符对应一位数,然后2位数字就是1位对应1位,3个数字一组,下一组就又是2位对应1位,也就是对应4个加密后的字符,这样的规则,但是问题就出在了尾数,基本现在的这些就是尾数会解密出错,尾数又是使用的不同解密方式,经过多次测试,还是发现了规律,如图,这是尾数刚好对应3位一组的第前2位的。
31 | 
32 |
33 | 这就是经过多次的对比,总结出的,但这里又有一个问题,就是不知道qq的位数和尾数的加密有没有关联,目前解密已经没发现问题了,这些就不多说了,体验地址
34 | [下载](https://github.com/Xchuanshuo/TBS/blob/master/app/release/app-release.apk),给出[github](https://github.com/Xchuanshuo/TBS)地址,喜欢的欢迎给个star。
35 |
36 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | defaultConfig {
6 | applicationId "com.legend.tbs"
7 | minSdkVersion 21
8 | targetSdkVersion 26
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 | implementation 'com.android.support:appcompat-v7:26.1.0'
24 | compile "com.google.code.gson:gson:2.8.0"
25 | implementation 'com.android.support:cardview-v7:26.1.0'
26 | implementation 'com.github.bumptech.glide:glide:3.7.0'
27 | implementation 'com.jcodecraeer:xrecyclerview:1.5.2'
28 | testImplementation 'junit:junit:4.12'
29 | androidTestImplementation 'com.android.support.test:runner:1.0.1'
30 | compile 'com.squareup.okhttp3:okhttp:3.7.0'
31 | implementation 'com.android.support:design:26.1.0'
32 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
33 | }
34 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/release/app-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/app/release/app-release.apk
--------------------------------------------------------------------------------
/app/release/output.json:
--------------------------------------------------------------------------------
1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1},"path":"app-release.apk","properties":{"packageId":"com.legend.tbs","split":"","minSdkVersion":"21"}}]
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/legend/tbs/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.legend.tbs", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/LuncherActivity.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.support.annotation.Nullable;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.text.TextUtils;
10 | import android.util.Log;
11 | import android.webkit.ValueCallback;
12 | import android.webkit.WebSettings;
13 | import android.webkit.WebView;
14 |
15 | import com.legend.tbs.common.MyWebViewClient;
16 |
17 | import static com.legend.tbs.common.MyWebViewClient.COOKIE;
18 | import static com.legend.tbs.common.MyWebViewClient.SKEY;
19 |
20 |
21 | /**
22 | * @author Legend
23 | * @data by on 2018/4/6.
24 | * @description
25 | */
26 |
27 | public class LuncherActivity extends AppCompatActivity {
28 |
29 | private WebView mWebView;
30 | private static String token;
31 |
32 | @Override
33 | protected void onCreate(@Nullable Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_luncher);
36 | initView();
37 |
38 | }
39 |
40 | private void initView() {
41 | mWebView = findViewById(R.id.webView);
42 | WebSettings webSettings = mWebView.getSettings();
43 | webSettings.setJavaScriptEnabled(true);
44 | webSettings.setAllowContentAccess(true);
45 | webSettings.setAppCacheEnabled(false);
46 | webSettings.setBuiltInZoomControls(false);
47 | webSettings.setUseWideViewPort(true);
48 | webSettings.setLoadWithOverviewMode(true);
49 | webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
50 | mWebView.loadUrl("https://ui.ptlogin2.qq.com/cgi-bin/login?pt_hide_ad=1&style=9&pt_ttype=1&appid=549000929&pt_no_auth=1&pt_wxtest=1&daid=5&s_url=https%3A%2F%2Fh5.qzone.qq.com%2Fmqzone%2Findex\n");
51 | mWebView.setWebViewClient(new MyWebViewClient());
52 |
53 |
54 | final Handler handler = new Handler();
55 | final Runnable runnable = new Runnable() {
56 | @SuppressLint("JavascriptInterface")
57 | @Override
58 | public void run() {
59 | final String skey = MyWebViewClient.getSkey();
60 | if (!TextUtils.isEmpty(skey)&&skey.length() > 5) {
61 | // 计算skey
62 | final String str = "function o() {\n" +
63 | " for (var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : \"\", e = 5381, n = 0, r = t.length; n < r; ++n)\n" +
64 | " e += (e << 5) + t.charAt(n).charCodeAt();\n" +
65 | " return 2147483647 & e\n" +
66 | "}" +
67 | "o('"+skey+"');";
68 | mWebView.evaluateJavascript(str, new ValueCallback() {
69 | @Override
70 | public void onReceiveValue(String value) {
71 | Log.d("strtr",str+""+value);
72 | // Toast.makeText(LuncherActivity.this, "结果是:" + value,
73 | // Toast.LENGTH_LONG).show();
74 | token = value;
75 | Intent intent = new Intent();
76 | intent.setClass(LuncherActivity.this, TbsActivity.class);
77 | intent.putExtra(SKEY,token);
78 | intent.putExtra(COOKIE,MyWebViewClient.getCookie());
79 |
80 | startActivity(intent);
81 | }
82 | });
83 |
84 | if (!TextUtils.isEmpty(token)) {
85 | handler.removeCallbacks(this);
86 | Intent intent = new Intent();
87 | intent.setClass(LuncherActivity.this, TbsActivity.class);
88 | intent.putExtra(SKEY,token);
89 | intent.putExtra(COOKIE,MyWebViewClient.getCookie());
90 |
91 | startActivity(intent);
92 | }
93 | } else {
94 | handler.postDelayed(this,1000);
95 | }
96 | }
97 | };
98 | handler.postDelayed(runnable,1000);
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/TbsActivity.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs;
2 |
3 | import android.app.Dialog;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.support.design.widget.TabLayout;
7 | import android.support.v4.view.ViewPager;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.support.v7.widget.Toolbar;
10 |
11 | import com.legend.tbs.common.adapter.MainFragmentAdapter;
12 | import com.legend.tbs.common.utils.Calculate;
13 |
14 | import static com.legend.tbs.common.MyWebViewClient.COOKIE;
15 | import static com.legend.tbs.common.MyWebViewClient.SKEY;
16 |
17 | /**
18 | * @author HP
19 | */
20 | public class TbsActivity extends AppCompatActivity {
21 |
22 | private ViewPager mViewPager;
23 | private TabLayout tabLayout;
24 | private MainFragmentAdapter adapter;
25 | private Toolbar mToolbar;
26 | public static String token;
27 | public static String cookie;
28 | public static Dialog dialog;
29 |
30 | @Override
31 | protected void onCreate(Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | setContentView(R.layout.activity_main);
34 | initView();
35 | }
36 |
37 | private void initView() {
38 | mToolbar = findViewById(R.id.toolbar);
39 | setSupportActionBar(mToolbar);
40 | adapter = new MainFragmentAdapter(getSupportFragmentManager());
41 | mViewPager = findViewById(R.id.mViewPager);
42 | mViewPager.setAdapter(adapter);
43 | tabLayout = findViewById(R.id.tab_layout);
44 | tabLayout.setupWithViewPager(mViewPager,true);
45 | Intent intent = getIntent();
46 | token = intent.getStringExtra(SKEY);
47 | cookie = intent.getStringExtra(COOKIE);
48 | dialog = Calculate.createLoadingDialog(this,"正在努力加载中");
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.LinearLayout;
12 |
13 | import com.jcodecraeer.xrecyclerview.ProgressStyle;
14 | import com.jcodecraeer.xrecyclerview.XRecyclerView;
15 |
16 | /**
17 | * @author Legend
18 | * @data by on 2018/1/27.
19 | * @description
20 | */
21 | abstract public class BaseFragment extends Fragment {
22 |
23 | private View mView;
24 | private Context mContext;
25 | private XRecyclerView mRecyclerView;
26 | @Nullable
27 | @Override
28 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
29 | mView = inflater.inflate(setResourceLayoutId(),container,false);
30 | mContext = getContext();
31 | initView();
32 | mRecyclerView = $(setRecyclerViewId());
33 | if (mRecyclerView != null) {
34 | init();
35 | }
36 | initListener();
37 | refreshData();
38 | return mView;
39 | }
40 | private void init() {
41 | mRecyclerView.setFootViewText("正在玩命加载中...⌇●﹏●⌇","亲(o~.~o) 我也是有底线的哦");
42 | mRecyclerView.setRefreshProgressStyle(ProgressStyle.BallClipRotateMultiple);
43 | mRecyclerView.setLoadingMoreProgressStyle(ProgressStyle.BallClipRotateMultiple);
44 | mRecyclerView.getFootView().setMinimumHeight(200);
45 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mView.getContext());
46 | linearLayoutManager.setOrientation(LinearLayout.VERTICAL);
47 | mRecyclerView.setLayoutManager(linearLayoutManager);
48 | }
49 |
50 | public abstract int setResourceLayoutId();
51 |
52 | public abstract int setRecyclerViewId();
53 |
54 | public abstract void initView();
55 |
56 | public abstract void initListener();
57 |
58 | public abstract void refreshData();
59 |
60 |
61 |
62 | public T $(int id) {
63 | return (T)mView.findViewById(id);
64 | }
65 |
66 | public View getmView() {
67 | return mView;
68 | }
69 |
70 | public XRecyclerView getmRecyclerView() {
71 | return mRecyclerView;
72 | }
73 | public Context getmContext() {
74 | return mContext;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/CircleImageView.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapShader;
7 | import android.graphics.Canvas;
8 | import android.graphics.Color;
9 | import android.graphics.ColorFilter;
10 | import android.graphics.Matrix;
11 | import android.graphics.Paint;
12 | import android.graphics.RectF;
13 | import android.graphics.Shader;
14 | import android.graphics.drawable.BitmapDrawable;
15 | import android.graphics.drawable.ColorDrawable;
16 | import android.graphics.drawable.Drawable;
17 | import android.net.Uri;
18 | import android.support.annotation.ColorInt;
19 | import android.support.annotation.ColorRes;
20 | import android.support.annotation.DrawableRes;
21 | import android.support.v7.widget.AppCompatImageView;
22 | import android.util.AttributeSet;
23 |
24 | import com.legend.tbs.R;
25 |
26 | /**
27 | *
28 | * @author wxy
29 | * @date 16/6/27
30 | */
31 | public class CircleImageView extends AppCompatImageView {
32 | private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
33 |
34 | private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
35 | private static final int COLORDRAWABLE_DIMENSION = 2;
36 |
37 | private static final int DEFAULT_BORDER_WIDTH = 0;
38 | private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
39 | private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;
40 | private static final boolean DEFAULT_BORDER_OVERLAY = false;
41 |
42 | private final RectF mDrawableRect = new RectF();
43 | private final RectF mBorderRect = new RectF();
44 |
45 | private final Matrix mShaderMatrix = new Matrix();
46 | private final Paint mBitmapPaint = new Paint();
47 | private final Paint mBorderPaint = new Paint();
48 | private final Paint mFillPaint = new Paint();
49 |
50 | private int mBorderColor = DEFAULT_BORDER_COLOR;
51 | private int mBorderWidth = DEFAULT_BORDER_WIDTH;
52 | private int mFillColor = DEFAULT_FILL_COLOR;
53 |
54 | private Bitmap mBitmap;
55 | private BitmapShader mBitmapShader;
56 | private int mBitmapWidth;
57 | private int mBitmapHeight;
58 |
59 | private float mDrawableRadius;
60 | private float mBorderRadius;
61 |
62 | private ColorFilter mColorFilter;
63 |
64 | private boolean mReady;
65 | private boolean mSetupPending;
66 | private boolean mBorderOverlay;
67 | private boolean mDisableCircularTransformation;
68 |
69 | public CircleImageView(Context context) {
70 | super(context);
71 |
72 | init();
73 | }
74 |
75 | public CircleImageView(Context context, AttributeSet attrs) {
76 | this(context, attrs, 0);
77 | }
78 |
79 | public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
80 | super(context, attrs, defStyle);
81 |
82 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
83 |
84 | mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);
85 | mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);
86 | mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);
87 | mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR);
88 |
89 | a.recycle();
90 |
91 | init();
92 | }
93 |
94 | private void init() {
95 | super.setScaleType(SCALE_TYPE);
96 | mReady = true;
97 |
98 | if (mSetupPending) {
99 | setup();
100 | mSetupPending = false;
101 | }
102 | }
103 |
104 | @Override
105 | public ScaleType getScaleType() {
106 | return SCALE_TYPE;
107 | }
108 |
109 | @Override
110 | public void setScaleType(ScaleType scaleType) {
111 | if (scaleType != SCALE_TYPE) {
112 | throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
113 | }
114 | }
115 |
116 | @Override
117 | public void setAdjustViewBounds(boolean adjustViewBounds) {
118 | if (adjustViewBounds) {
119 | throw new IllegalArgumentException("adjustViewBounds not supported.");
120 | }
121 | }
122 |
123 | @Override
124 | protected void onDraw(Canvas canvas) {
125 | if (mDisableCircularTransformation) {
126 | super.onDraw(canvas);
127 | return;
128 | }
129 |
130 | if (mBitmap == null) {
131 | return;
132 | }
133 |
134 | if (mFillColor != Color.TRANSPARENT) {
135 | canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mFillPaint);
136 | }
137 | canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint);
138 | if (mBorderWidth > 0) {
139 | canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint);
140 | }
141 | }
142 |
143 | @Override
144 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
145 | super.onSizeChanged(w, h, oldw, oldh);
146 | setup();
147 | }
148 |
149 | public int getBorderColor() {
150 | return mBorderColor;
151 | }
152 |
153 | public void setBorderColor(@ColorInt int borderColor) {
154 | if (borderColor == mBorderColor) {
155 | return;
156 | }
157 |
158 | mBorderColor = borderColor;
159 | mBorderPaint.setColor(mBorderColor);
160 | invalidate();
161 | }
162 |
163 | /**
164 | * @deprecated Use {@link #setBorderColor(int)} instead
165 | */
166 | @Deprecated
167 | public void setBorderColorResource(@ColorRes int borderColorRes) {
168 | setBorderColor(getContext().getResources().getColor(borderColorRes));
169 | }
170 |
171 | /**
172 | * Return the color drawn behind the circle-shaped drawable.
173 | *
174 | * @return The color drawn behind the drawable
175 | *
176 | * @deprecated Fill color support is going to be removed in the future
177 | */
178 | @Deprecated
179 | public int getFillColor() {
180 | return mFillColor;
181 | }
182 |
183 | /**
184 | * Set a color to be drawn behind the circle-shaped drawable. Note that
185 | * this has no effect if the drawable is opaque or no drawable is set.
186 | *
187 | * @param fillColor The color to be drawn behind the drawable
188 | *
189 | * @deprecated Fill color support is going to be removed in the future
190 | */
191 | @Deprecated
192 | public void setFillColor(@ColorInt int fillColor) {
193 | if (fillColor == mFillColor) {
194 | return;
195 | }
196 |
197 | mFillColor = fillColor;
198 | mFillPaint.setColor(fillColor);
199 | invalidate();
200 | }
201 |
202 | /**
203 | * Set a color to be drawn behind the circle-shaped drawable. Note that
204 | * this has no effect if the drawable is opaque or no drawable is set.
205 | *
206 | * @param fillColorRes The color resource to be resolved to a color and
207 | * drawn behind the drawable
208 | *
209 | * @deprecated Fill color support is going to be removed in the future
210 | */
211 | @Deprecated
212 | public void setFillColorResource(@ColorRes int fillColorRes) {
213 | setFillColor(getContext().getResources().getColor(fillColorRes));
214 | }
215 |
216 | public int getBorderWidth() {
217 | return mBorderWidth;
218 | }
219 |
220 | public void setBorderWidth(int borderWidth) {
221 | if (borderWidth == mBorderWidth) {
222 | return;
223 | }
224 |
225 | mBorderWidth = borderWidth;
226 | setup();
227 | }
228 |
229 | public boolean isBorderOverlay() {
230 | return mBorderOverlay;
231 | }
232 |
233 | public void setBorderOverlay(boolean borderOverlay) {
234 | if (borderOverlay == mBorderOverlay) {
235 | return;
236 | }
237 |
238 | mBorderOverlay = borderOverlay;
239 | setup();
240 | }
241 |
242 | public boolean isDisableCircularTransformation() {
243 | return mDisableCircularTransformation;
244 | }
245 |
246 | public void setDisableCircularTransformation(boolean disableCircularTransformation) {
247 | if (mDisableCircularTransformation == disableCircularTransformation) {
248 | return;
249 | }
250 |
251 | mDisableCircularTransformation = disableCircularTransformation;
252 | initializeBitmap();
253 | }
254 |
255 | @Override
256 | public void setImageBitmap(Bitmap bm) {
257 | super.setImageBitmap(bm);
258 | initializeBitmap();
259 | }
260 |
261 | @Override
262 | public void setImageDrawable(Drawable drawable) {
263 | super.setImageDrawable(drawable);
264 | initializeBitmap();
265 | }
266 |
267 | @Override
268 | public void setImageResource(@DrawableRes int resId) {
269 | super.setImageResource(resId);
270 | initializeBitmap();
271 | }
272 |
273 | @Override
274 | public void setImageURI(Uri uri) {
275 | super.setImageURI(uri);
276 | initializeBitmap();
277 | }
278 |
279 | @Override
280 | public void setColorFilter(ColorFilter cf) {
281 | if (cf == mColorFilter) {
282 | return;
283 | }
284 |
285 | mColorFilter = cf;
286 | applyColorFilter();
287 | invalidate();
288 | }
289 |
290 | @Override
291 | public ColorFilter getColorFilter() {
292 | return mColorFilter;
293 | }
294 |
295 | private void applyColorFilter() {
296 | if (mBitmapPaint != null) {
297 | mBitmapPaint.setColorFilter(mColorFilter);
298 | }
299 | }
300 |
301 | private Bitmap getBitmapFromDrawable(Drawable drawable) {
302 | if (drawable == null) {
303 | return null;
304 | }
305 |
306 | if (drawable instanceof BitmapDrawable) {
307 | return ((BitmapDrawable) drawable).getBitmap();
308 | }
309 |
310 | try {
311 | Bitmap bitmap;
312 |
313 | if (drawable instanceof ColorDrawable) {
314 | bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
315 | } else {
316 | bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
317 | }
318 |
319 | Canvas canvas = new Canvas(bitmap);
320 | drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
321 | drawable.draw(canvas);
322 | return bitmap;
323 | } catch (Exception e) {
324 | e.printStackTrace();
325 | return null;
326 | }
327 | }
328 |
329 | private void initializeBitmap() {
330 | if (mDisableCircularTransformation) {
331 | mBitmap = null;
332 | } else {
333 | mBitmap = getBitmapFromDrawable(getDrawable());
334 | }
335 | setup();
336 | }
337 |
338 | private void setup() {
339 | if (!mReady) {
340 | mSetupPending = true;
341 | return;
342 | }
343 |
344 | if (getWidth() == 0 && getHeight() == 0) {
345 | return;
346 | }
347 |
348 | if (mBitmap == null) {
349 | invalidate();
350 | return;
351 | }
352 |
353 | mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
354 |
355 | mBitmapPaint.setAntiAlias(true);
356 | mBitmapPaint.setShader(mBitmapShader);
357 |
358 | mBorderPaint.setStyle(Paint.Style.STROKE);
359 | mBorderPaint.setAntiAlias(true);
360 | mBorderPaint.setColor(mBorderColor);
361 | mBorderPaint.setStrokeWidth(mBorderWidth);
362 |
363 | mFillPaint.setStyle(Paint.Style.FILL);
364 | mFillPaint.setAntiAlias(true);
365 | mFillPaint.setColor(mFillColor);
366 |
367 | mBitmapHeight = mBitmap.getHeight();
368 | mBitmapWidth = mBitmap.getWidth();
369 |
370 | mBorderRect.set(calculateBounds());
371 | mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);
372 |
373 | mDrawableRect.set(mBorderRect);
374 | if (!mBorderOverlay && mBorderWidth > 0) {
375 | mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f);
376 | }
377 | mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);
378 |
379 | applyColorFilter();
380 | updateShaderMatrix();
381 | invalidate();
382 | }
383 |
384 | private RectF calculateBounds() {
385 | int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();
386 | int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();
387 |
388 | int sideLength = Math.min(availableWidth, availableHeight);
389 |
390 | float left = getPaddingLeft() + (availableWidth - sideLength) / 2f;
391 | float top = getPaddingTop() + (availableHeight - sideLength) / 2f;
392 |
393 | return new RectF(left, top, left + sideLength, top + sideLength);
394 | }
395 |
396 | private void updateShaderMatrix() {
397 | float scale;
398 | float dx = 0;
399 | float dy = 0;
400 |
401 | mShaderMatrix.set(null);
402 |
403 | if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
404 | scale = mDrawableRect.height() / (float) mBitmapHeight;
405 | dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
406 | } else {
407 | scale = mDrawableRect.width() / (float) mBitmapWidth;
408 | dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
409 | }
410 |
411 | mShaderMatrix.setScale(scale, scale);
412 | mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
413 | mBitmapShader.setLocalMatrix(mShaderMatrix);
414 | }
415 |
416 | }
417 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/MyWebViewClient.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common;
2 |
3 | import android.content.Context;
4 | import android.text.TextUtils;
5 | import android.util.Log;
6 | import android.webkit.CookieManager;
7 | import android.webkit.WebView;
8 | import android.webkit.WebViewClient;
9 |
10 | import java.util.regex.Matcher;
11 | import java.util.regex.Pattern;
12 |
13 | /**
14 | * @author Legend
15 | * @data by on 2018/4/6.
16 | * @description
17 | */
18 |
19 | public class MyWebViewClient extends WebViewClient {
20 |
21 | public static final String SKEY = "skey";
22 | public static final String COOKIE = "cookie";
23 | private static String skey;
24 | private static String cookie;
25 | private static Context context;
26 |
27 | @Override
28 | public boolean shouldOverrideUrlLoading(WebView webview, String url) {
29 | webview.loadUrl(url);
30 | context = webview.getContext();
31 | return true;
32 | }
33 |
34 | @Override
35 | public void onPageFinished(WebView view, String url) {
36 | CookieManager cookieManager = CookieManager.getInstance();
37 | cookie = cookieManager.getCookie(url);
38 | Log.i("Cookies", "Cookies = " + cookie);
39 | getSkey();
40 | super.onPageFinished(view, url);
41 | }
42 |
43 | public static String getCookie() {
44 | return cookie;
45 | }
46 |
47 | // 从返回的cookie中正则提取skey
48 | public static String getSkey() {
49 |
50 | String regex = "skey=(.*?);";
51 | Pattern pattern = Pattern.compile(regex);
52 | if (!TextUtils.isEmpty(cookie)) {
53 | Matcher matcher = pattern.matcher(cookie);
54 | if (matcher.find()) {
55 | skey = matcher.group(1);
56 | Log.d("SKEYSKEY",skey);
57 | }
58 | } else {
59 | skey = "";
60 | }
61 | return skey;
62 | }
63 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/adapter/MainFragmentAdapter.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common.adapter;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 |
7 | import com.legend.tbs.fragment.FriendTbsFragment;
8 | import com.legend.tbs.fragment.SelfTbsFragment;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | /**
14 | * @author Legend
15 | * @data by on 2018/4/5.
16 | * @description
17 | */
18 |
19 | public class MainFragmentAdapter extends FragmentPagerAdapter {
20 |
21 | private List mFragments;
22 | private String[] titles = new String[]{"我收到的", "好友收到的"};
23 |
24 | public MainFragmentAdapter(FragmentManager fragmentManager) {
25 | super(fragmentManager);
26 | mFragments = new ArrayList<>();
27 | SelfTbsFragment selfTbsFragment = new SelfTbsFragment();
28 | FriendTbsFragment friendTbsFragment = new FriendTbsFragment();
29 | mFragments.add(selfTbsFragment);
30 | mFragments.add(friendTbsFragment);
31 | }
32 | @Override
33 | public Fragment getItem(int position) {
34 | return mFragments.get(position);
35 | }
36 |
37 | @Override
38 | public int getCount() {
39 | return 2;
40 | }
41 |
42 | @Override
43 | public CharSequence getPageTitle(int position) {
44 | return titles[position];
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/adapter/TbsAdapter.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common.adapter;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.support.v7.widget.AppCompatTextView;
7 | import android.support.v7.widget.CardView;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.util.Log;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.widget.TextView;
14 | import android.widget.Toast;
15 |
16 | import com.bumptech.glide.Glide;
17 | import com.bumptech.glide.load.engine.DiskCacheStrategy;
18 | import com.legend.tbs.R;
19 | import com.legend.tbs.common.CircleImageView;
20 | import com.legend.tbs.common.model.TbsBean;
21 | import com.legend.tbs.common.utils.Calculate;
22 |
23 | import java.util.List;
24 |
25 | /**
26 | * @author Legend
27 | * @data by on 2018/4/5.
28 | * @description
29 | */
30 |
31 | public class TbsAdapter extends RecyclerView.Adapter {
32 |
33 | private List mTbsList;
34 | private Context mContext;
35 | private static String nick="";
36 | private static String qqImage="";
37 | private static String qq="";
38 | public static final String GET_NICK = "http://r.pengyou.com/fcg-bin/cgi_get_portrait.fcg?uins=";
39 |
40 |
41 |
42 | public TbsAdapter(List tbsList) {
43 | this.mTbsList = tbsList;
44 | }
45 |
46 | @Override
47 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
48 | if (mContext == null) {
49 | mContext = parent.getContext();
50 | }
51 | View view = LayoutInflater.from(mContext).inflate(R.layout.item_tbs,parent,false);
52 | final ViewHolder viewHolder = new ViewHolder(view);
53 | viewHolder.tbsItem.setOnClickListener(new View.OnClickListener() {
54 | @Override
55 | public void onClick(View v) {
56 | String qq = String.valueOf(viewHolder.fromQQ.getText());
57 | if (Calculate.checkApkExist(mContext,"com.tencent.mobileqq")) {
58 | mContext.startActivity(new Intent(Intent.ACTION_VIEW,
59 | Uri.parse("mqqapi://card/show_pslcard?src_type=internal&version=1&uin="+qq.substring(4)+"&card_type=person&source=qrcode")));
60 | } else {
61 | Toast.makeText(mContext,"请安装QQ后再次尝试哦",Toast.LENGTH_SHORT).show();
62 | }
63 | }
64 | });
65 | return viewHolder;
66 | }
67 |
68 | @Override
69 | public synchronized void onBindViewHolder(ViewHolder holder, int position) {
70 | synchronized (this) {
71 | TbsBean tbs = mTbsList.get(position);
72 | qq = Calculate.decode(tbs.getFromEncodeUin());
73 | Glide.with(mContext)
74 | .load("http://q2.qlogo.cn/headimg_dl?dst_uin=+"+qq+"&spec=100")
75 | .placeholder(R.drawable.ic_loading_public)
76 | .diskCacheStrategy(DiskCacheStrategy.ALL)
77 | .crossFade()
78 | .error(R.drawable.ic_loading_public)
79 | .into(holder.qqImage);
80 | holder.topicName.setText(tbs.getToNick() + " " + tbs.getTopicName());
81 | holder.fromNick.setText("来自:" + tbs.getFromNick());
82 | holder.fromQQ.setText("QQ号:" + qq);
83 | holder.realName.setText("未完待续" + nick.replace("\"",""));
84 | Log.d("昵称",nick+qqImage);
85 | }
86 | nick = "";
87 | }
88 |
89 | @Override
90 | public int getItemCount() {
91 | return mTbsList.size();
92 | }
93 |
94 | static class ViewHolder extends RecyclerView.ViewHolder {
95 |
96 | TextView topicName;
97 | TextView realName,fromNick;
98 | CardView tbsItem;
99 | AppCompatTextView fromQQ;
100 | CircleImageView qqImage;
101 |
102 | public ViewHolder(View itemView) {
103 | super(itemView);
104 | topicName = itemView.findViewById(R.id.topic_name);
105 | realName = itemView.findViewById(R.id.real_nick);
106 | tbsItem = itemView.findViewById(R.id.cardview);
107 | fromNick = itemView.findViewById(R.id.from_Nick);
108 | fromQQ = itemView.findViewById(R.id.from_qq);
109 | qqImage = itemView.findViewById(R.id.qq_image);
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/model/TbsBean.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common.model;
2 |
3 | /**
4 | * @author Legend
5 | * @data by on 2018/4/5.
6 | * @description
7 | */
8 |
9 | public class TbsBean {
10 |
11 | /**
12 | * fromNick : 一个认识2个月的男生
13 | * fromEncodeUin : *S1*ow4lNKSk7ecq7c
14 | * fromFaceUrl : man.png
15 | * fromGender : 0
16 | * toUin : 2414605975
17 | * toNick :
18 | * topicId : 50
19 | * topicName : 宅舞爱好者
20 | * timestamp : 1522912148
21 | */
22 |
23 | private String fromNick;
24 | private String fromEncodeUin;
25 | private String fromFaceUrl;
26 | private int fromGender;
27 | private long toUin;
28 | private String toNick;
29 | private int topicId;
30 | private String topicName;
31 | private int timestamp;
32 |
33 | public String getFromNick() {
34 | return fromNick;
35 | }
36 |
37 | public void setFromNick(String fromNick) {
38 | this.fromNick = fromNick;
39 | }
40 |
41 | public String getFromEncodeUin() {
42 | return fromEncodeUin;
43 | }
44 |
45 | public void setFromEncodeUin(String fromEncodeUin) {
46 | this.fromEncodeUin = fromEncodeUin;
47 | }
48 |
49 | public String getFromFaceUrl() {
50 | return fromFaceUrl;
51 | }
52 |
53 | public void setFromFaceUrl(String fromFaceUrl) {
54 | this.fromFaceUrl = fromFaceUrl;
55 | }
56 |
57 | public int getFromGender() {
58 | return fromGender;
59 | }
60 |
61 | public void setFromGender(int fromGender) {
62 | this.fromGender = fromGender;
63 | }
64 |
65 | public long getToUin() {
66 | return toUin;
67 | }
68 |
69 | public void setToUin(long toUin) {
70 | this.toUin = toUin;
71 | }
72 |
73 | public String getToNick() {
74 | return toNick;
75 | }
76 |
77 | public void setToNick(String toNick) {
78 | this.toNick = toNick;
79 | }
80 |
81 | public int getTopicId() {
82 | return topicId;
83 | }
84 |
85 | public void setTopicId(int topicId) {
86 | this.topicId = topicId;
87 | }
88 |
89 | public String getTopicName() {
90 | return topicName;
91 | }
92 |
93 | public void setTopicName(String topicName) {
94 | this.topicName = topicName;
95 | }
96 |
97 | public int getTimestamp() {
98 | return timestamp;
99 | }
100 |
101 | public void setTimestamp(int timestamp) {
102 | this.timestamp = timestamp;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/net/IHttpClient.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common.net;
2 |
3 | import java.io.File;
4 | import java.util.Map;
5 |
6 | /**
7 | * @author Legend
8 | * @data by on 2018/1/3.
9 | * @description
10 | */
11 |
12 | public interface IHttpClient {
13 |
14 | IResponse get(IRequest request);
15 |
16 | /**
17 | * json格式的post
18 | * @param request
19 | * @return
20 | */
21 | IResponse post(IRequest request);
22 |
23 | /**
24 | * 表单类型的post
25 | * @param request
26 | * @param map
27 | * @param file
28 | * @return
29 | */
30 | IResponse upload_image_post(IRequest request, Map map, File file);
31 | IResponse delete(IRequest request);
32 | IResponse put(IRequest request);
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/net/IRequest.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common.net;
2 |
3 | import java.util.Map;
4 |
5 | /**
6 | * @author Legend
7 | * @data by on 2018/1/3.
8 | * @description
9 | */
10 |
11 | public interface IRequest {
12 | public static final String POST = "POST";
13 | public static final String GET = "GET";
14 | public static final String DELETE = "DELETE";
15 | public static final String PUT = "PUT";
16 |
17 | /**
18 | * 请求方式
19 | * @param method
20 | */
21 | void setMethod(String method);
22 |
23 | /**
24 | * 指定请求头
25 | * @param key
26 | * @param value
27 | */
28 | void setHeader(String key, String value);
29 |
30 | /**
31 | * 指定请求信息
32 | * @param key
33 | * @param value
34 | */
35 | void setBody(String key, Object value);
36 |
37 | /**
38 | * 提供给执行库请求行URL
39 | * @return
40 | */
41 | String getUrl();
42 |
43 | /**
44 | * 提供给执行库请求行URL
45 | * @return
46 | */
47 | Map getHeader();
48 |
49 | /**
50 | * 请求体
51 | * @return
52 | */
53 | String getBody();
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/net/IResponse.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common.net;
2 |
3 | /**
4 | * @author Legend
5 | * @data by on 2018/1/3.
6 | * @description
7 | */
8 |
9 | public interface IResponse {
10 |
11 | /**
12 | * 响应码
13 | * @return
14 | */
15 | int getCode();
16 |
17 | /**
18 | * 返回的数据
19 | * @return
20 | */
21 | String getData();
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/net/impl/OkHttpClientImpl.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common.net.impl;
2 |
3 |
4 | import com.legend.tbs.common.net.IHttpClient;
5 | import com.legend.tbs.common.net.IRequest;
6 | import com.legend.tbs.common.net.IResponse;
7 |
8 | import java.io.File;
9 | import java.io.IOException;
10 | import java.util.Map;
11 |
12 | import okhttp3.MediaType;
13 | import okhttp3.MultipartBody;
14 | import okhttp3.OkHttpClient;
15 | import okhttp3.Request;
16 | import okhttp3.RequestBody;
17 | import okhttp3.Response;
18 |
19 | import static java.lang.String.valueOf;
20 |
21 | /**
22 | * @author Legend
23 | * @data by on 2017/11/23.
24 | * @description
25 | */
26 |
27 | public class OkHttpClientImpl implements IHttpClient {
28 | OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
29 | .build();
30 |
31 | @Override
32 | public IResponse get(IRequest request) {
33 | /**
34 | * 解析业务参数
35 | */
36 | // 指定请求方式
37 | request.setMethod(IRequest.GET);
38 | Map header = request.getHeader();
39 |
40 | Request.Builder builder = new Request.Builder();
41 | for (String key : header.keySet()) {
42 | builder.header(key,header.get(key));
43 | }
44 | builder.url(request.getUrl()
45 | ).get();
46 | Request okRequest = builder.build();
47 | return execute(okRequest);
48 | }
49 |
50 | @Override
51 | public IResponse post(IRequest request) {
52 | request.setMethod(IRequest.POST);
53 | MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
54 | RequestBody requestBody = RequestBody.create(mediaType,request.getBody().toString());
55 |
56 | Map header = request.getHeader();
57 | Request.Builder builder = new Request.Builder();
58 | for (String key : header.keySet()) {
59 | builder.header(key,header.get(key));
60 | }
61 | builder.url(request.getUrl())
62 | .post(requestBody);
63 | Request okRequest = builder.build();
64 | return execute(okRequest);
65 | }
66 |
67 | @Override
68 | public IResponse upload_image_post(IRequest request,Map map,File file) {
69 | /**
70 | * 实现文件上传
71 | */
72 | request.setMethod(IRequest.POST);
73 | MediaType MEDIA_TYPE_IMAGE = MediaType.parse("image/*");
74 | MultipartBody.Builder requestBody = new MultipartBody
75 | .Builder().setType(MultipartBody.FORM);
76 | if (file != null) {
77 | requestBody.addFormDataPart("image",file.getName(),
78 | RequestBody.create(MEDIA_TYPE_IMAGE,file));
79 | }
80 | if (map != null) {
81 | // map 里面是请求中所需要的 key 和 value
82 | for (Map.Entry entry : map.entrySet()) {
83 | requestBody.addFormDataPart(valueOf(entry.getKey()), valueOf(entry.getValue()));
84 | }
85 | }
86 | Map header = request.getHeader();
87 | Request.Builder builder = new Request.Builder();
88 | for (String key : header.keySet()) {
89 | builder.header(key,header.get(key));
90 | }
91 | builder.url(request.getUrl())
92 | .post(requestBody.build());
93 | Request okRequest = builder.build();
94 | return execute(okRequest);
95 | }
96 |
97 | @Override
98 | public IResponse delete(IRequest request) {
99 | request.setMethod(IRequest.DELETE);
100 | Map header = request.getHeader();
101 | Request.Builder builder = new Request.Builder();
102 | for (String key : header.keySet()) {
103 | builder.header(key,header.get(key));
104 | }
105 | builder.url(request.getUrl())
106 | .delete(null);
107 | Request okRequest = builder.build();
108 | return execute(okRequest);
109 | }
110 |
111 | @Override
112 | public IResponse put(IRequest request) {
113 | request.setMethod(IRequest.PUT);
114 | MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
115 | RequestBody requestBody = RequestBody.create(mediaType,request.getBody().toString());
116 |
117 | Map header = request.getHeader();
118 | Request.Builder builder = new Request.Builder();
119 | for (String key : header.keySet()) {
120 | builder.header(key,header.get(key));
121 | }
122 | builder.url(request.getUrl())
123 | .put(requestBody);
124 | Request okRequest = builder.build();
125 | return execute(okRequest);
126 | }
127 |
128 | private IResponse execute(Request request) {
129 | ResponseImpl commonResponse = new ResponseImpl();
130 | try {
131 | Response response = mOkHttpClient.newCall(request).execute();
132 | // 设置状态码
133 | commonResponse.setCode(response.code());
134 | String body = response.body().string();
135 | // 设置响应数据
136 | commonResponse.setData(body);
137 | } catch (IOException e) {
138 | e.printStackTrace();
139 | commonResponse.setCode(ResponseImpl.STATE_UNKNOW_ERROR);
140 | commonResponse.setData(e.getMessage());
141 | }
142 | return commonResponse;
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/net/impl/RequestImpl.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common.net.impl;
2 |
3 | import com.google.gson.Gson;import com.legend.tbs.common.net.IRequest;
4 |
5 | import java.util.HashMap;
6 | import java.util.Map;
7 |
8 | /**
9 | * @author Legend
10 | * @data by on 2017/11/23.
11 | * @description
12 | */
13 |
14 | public class RequestImpl implements IRequest {
15 |
16 | private String method = POST;
17 | private String url;
18 | private Map header;
19 | private Map body;
20 |
21 | public RequestImpl(String url) {
22 | /**
23 | * 初始化公共参数和头部信息
24 | */
25 | this.url = url;
26 | header = new HashMap();
27 | body = new HashMap<>();
28 | }
29 | @Override
30 | public void setMethod(String method) {
31 | this.method = method;
32 | }
33 |
34 | @Override
35 | public void setHeader(String key, String value) {
36 | header.put(key,value);
37 | }
38 |
39 | @Override
40 | public void setBody(String key, Object value) {
41 | body.put(key,value);
42 | }
43 |
44 | @Override
45 | public String getUrl() {
46 | if (GET.equals(method)) {
47 | // 组装post请求参数
48 | for (String key : body.keySet()) {
49 | url = url.replace("${"+key+"}",body.get(key).toString());
50 | }
51 | }
52 | return url;
53 | }
54 |
55 | @Override
56 | public Map getHeader() {
57 | return header;
58 | }
59 |
60 | @Override
61 | public String getBody() {
62 | // 组装post请求参数
63 | if (body != null) {
64 | return new Gson().toJson(this.body,HashMap.class);
65 | } else {
66 | return "{}";
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/net/impl/ResponseImpl.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common.net.impl;
2 |
3 |
4 | import com.legend.tbs.common.net.IResponse;
5 |
6 | /**
7 | * @author Legend
8 | * @data by on 2017/11/23.
9 | * @description
10 | */
11 |
12 | public class ResponseImpl implements IResponse {
13 | public static final int STATE_UNKNOW_ERROR = 100001;
14 | public static int STATE_OK = 200;
15 | private int code;
16 | private String data;
17 |
18 | @Override
19 | public String getData() {
20 | return data;
21 | }
22 | @Override
23 | public int getCode () {
24 | return code;
25 | }
26 | public void setCode(int code) {
27 | this.code = code;
28 | }
29 | public void setData(String data) {
30 | this.data = data;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/common/utils/Calculate.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.common.utils;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.content.pm.ApplicationInfo;
6 | import android.content.pm.PackageManager;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.animation.Animation;
10 | import android.view.animation.AnimationUtils;
11 | import android.widget.ImageView;
12 | import android.widget.LinearLayout;
13 | import android.widget.TextView;
14 |
15 | import com.legend.tbs.R;
16 |
17 | import java.util.HashMap;
18 |
19 | /**
20 | * @author Legend
21 | * @data by on 2018/4/6.
22 | * @description
23 | */
24 | //function o() {
25 | // for (var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "", e = 5381, n = 0, r = t.length; n < r; ++n)
26 | // e += (e << 5) + t.charAt(n).charCodeAt();
27 | // return 2147483647 & e
28 | // }
29 | // console.log(o('@WDFlsZeEG'));
30 |
31 | public class Calculate {
32 |
33 | private static final String[] words = new String[]
34 | {"oe", "n", "z",
35 | "oK", "6", "5",
36 | "ow", "-", "A",
37 | "oi", "o", "i",
38 | "7e", "v", "P",
39 | "7K", "4", "k",
40 | "7w", "C", "s",
41 | "7i", "S", "l",
42 | "Ne", "c", "F",
43 | "NK", "E", "q"};
44 | private static final String[] endStr = {"on","ov","oc","oz",
45 | "7n","7v","7c","7z",
46 | "Nn","Nv"};
47 |
48 | private static HashMap[] maps = new HashMap[3];
49 |
50 | static {
51 | for (int Dici = 0; Dici < 3; Dici++) {
52 | maps[Dici] = new HashMap<>();
53 | for (int Wordi = 0; Wordi < 10; Wordi++) {
54 | maps[Dici].put(words[Dici + 3 * Wordi], Wordi);
55 | }
56 | }
57 | // 尾数加密的规则
58 | for (int i=0;i < 10;i++) {
59 | maps[0].put(endStr[i],i);
60 | }
61 | }
62 |
63 | /**
64 | * 解密方法
65 | * @param str 传入skey
66 | * @return
67 | */
68 | public static String decode(String str) {
69 | StringBuilder sb = new StringBuilder();
70 | char[] chars = str.substring(4, str.length()).toCharArray();
71 | int flag = 0;
72 | for (int i = 0; i < chars.length; i++) {
73 | String key;
74 | if (flag == 0)
75 | {
76 | key = String.valueOf(chars[i]) + chars[i + 1];
77 | i++;
78 | } else {
79 | key = String.valueOf(chars[i]);
80 | }
81 | if(maps[flag].containsKey(key)){
82 | sb.append(maps[flag].get(key));
83 | }else{
84 | sb.append("0");
85 | }
86 | flag = (flag < 2) ? flag + 1 : 0;
87 | }
88 | return sb.toString();
89 | }
90 |
91 | public static Dialog createLoadingDialog(Context context, String msg) {
92 |
93 | LayoutInflater inflater = LayoutInflater.from(context);
94 | View v = inflater.inflate(R.layout.loading_dialog, null);
95 | LinearLayout layout = v.findViewById(R.id.dialog_view);
96 | // main.xml中的ImageView
97 | ImageView spaceshipImage = v.findViewById(R.id.img);
98 | TextView tipTextView = v.findViewById(R.id.tipTextView);
99 | // 加载动画
100 | Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(
101 | context, R.anim.loading_animation);
102 | // 使用ImageView显示动画
103 | spaceshipImage.startAnimation(hyperspaceJumpAnimation);
104 | tipTextView.setText(msg);
105 | // 创建自定义样式dialog
106 | Dialog loadingDialog = new Dialog(context, R.style.loading_dialog);
107 |
108 | loadingDialog.setCancelable(false);
109 | loadingDialog.setContentView(layout, new LinearLayout.LayoutParams(
110 | LinearLayout.LayoutParams.WRAP_CONTENT,
111 | LinearLayout.LayoutParams.WRAP_CONTENT));
112 | return loadingDialog;
113 | }
114 |
115 | public static boolean checkApkExist(Context context, String packageName) {
116 | if (packageName == null || "".equals(packageName)) {
117 | return false;
118 | }
119 | try {
120 | ApplicationInfo info = context.getPackageManager()
121 | .getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
122 | return true;
123 | } catch (PackageManager.NameNotFoundException e) {
124 | e.printStackTrace();
125 | return false;
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/contract/BaseContract.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.contract;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @author Legend
7 | * @data by on 2018/4/5.
8 | * @description
9 | */
10 |
11 | public interface BaseContract {
12 |
13 | interface Model {
14 | /**
15 | * 请求获取数据
16 | * @param url
17 | * @param token
18 | * @param cookie
19 | * @param type 是好友还是自己的的
20 | * @param callback 回调
21 | */
22 | void Request(String url, String token, String cookie, int type,Callback callback);
23 | }
24 |
25 | interface View {
26 |
27 | void showLoading();
28 |
29 | void hideLoading();
30 | }
31 |
32 | /**
33 | * 发起请求
34 | */
35 | interface Presenter {
36 | void sendRequest(String url, String token, String cookie);
37 | }
38 |
39 | /**
40 | * 结果回调的接口
41 | * @param
42 | */
43 | interface Callback {
44 |
45 | void onStart();
46 |
47 | void onSuccess(List tList);
48 |
49 | void onFailure();
50 |
51 | void onFinished();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/fragment/BaseModel.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.fragment;
2 |
3 | import android.os.AsyncTask;
4 | import android.util.Log;
5 |
6 | import com.google.gson.Gson;
7 | import com.google.gson.reflect.TypeToken;
8 | import com.legend.tbs.common.model.TbsBean;
9 | import com.legend.tbs.common.net.IHttpClient;
10 | import com.legend.tbs.common.net.IRequest;
11 | import com.legend.tbs.common.net.IResponse;
12 | import com.legend.tbs.common.net.impl.OkHttpClientImpl;
13 | import com.legend.tbs.common.net.impl.RequestImpl;
14 | import com.legend.tbs.contract.BaseContract;
15 |
16 | import org.json.JSONArray;
17 | import org.json.JSONException;
18 | import org.json.JSONObject;
19 |
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | /**
24 | * @author Legend
25 | * @data by on 2018/4/5.
26 | * @description
27 | */
28 |
29 | public class BaseModel implements BaseContract.Model {
30 |
31 | public static final int RESULT_OK = 200;
32 | private BaseContract.Callback callback;
33 | private int type;
34 | private List list = new ArrayList<>();
35 | private static String cookie="";
36 | public static int finished = 0;
37 |
38 | @Override
39 | public void Request(String url, String token,String cookie, int type, BaseContract.Callback callback) {
40 | this.callback = callback;
41 | this.type = type;
42 | new TbsAsyncTask().execute(url,token,cookie);
43 | }
44 |
45 | class TbsAsyncTask extends AsyncTask {
46 |
47 | @Override
48 | protected void onPreExecute() {
49 | super.onPreExecute();
50 | callback.onStart();
51 | }
52 |
53 | @Override
54 | protected IResponse doInBackground(String... strings) {
55 | IRequest request;
56 | if (type == 0) {
57 | request = new RequestImpl(strings[0]+strings[1]);
58 | } else {
59 | request = new RequestImpl(strings[0]+strings[1]+"&cookie="+cookie);
60 | }
61 | request.setHeader("cookie",strings[2]);
62 | IHttpClient mHttpClient = new OkHttpClientImpl();
63 | IResponse response = mHttpClient.get(request);
64 | Log.d("ResponseData",response.getData().toString());
65 | return response;
66 | }
67 |
68 | @Override
69 | protected void onPostExecute(IResponse iResponse) {
70 | super.onPostExecute(iResponse);
71 | Gson gson = new Gson();
72 | if (iResponse.getCode() == RESULT_OK) {
73 | String result = iResponse.getData().toString();
74 | try {
75 | JSONObject jsonObject = new JSONObject(result);
76 | String data = jsonObject.getString("data");
77 | JSONObject jsonObject1 = new JSONObject(data);
78 | cookie = jsonObject1.getString("cookie");
79 | finished = Integer.parseInt(jsonObject1.getString("finish"));
80 | JSONArray jsonArray;
81 | synchronized (this) {
82 | if (type == 0) {
83 | jsonArray = jsonObject1.getJSONArray("list");
84 | } else {
85 | jsonArray = jsonObject1.getJSONArray("confesses");
86 | }
87 | }
88 | List tbsBeanList =
89 | gson.fromJson(jsonArray.toString(), new TypeToken>() {
90 | }.getType());
91 | Log.d("ResponseData",tbsBeanList.toString());
92 | callback.onSuccess(tbsBeanList);
93 | } catch (JSONException e) {
94 | e.printStackTrace();
95 | }
96 | } else {
97 | callback.onFailure();
98 | }
99 | callback.onFinished();
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/fragment/FriendTbsFragment.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.fragment;
2 |
3 | import com.jcodecraeer.xrecyclerview.XRecyclerView;
4 | import com.legend.tbs.R;
5 | import com.legend.tbs.common.BaseFragment;
6 | import com.legend.tbs.contract.BaseContract;
7 |
8 | import java.lang.ref.WeakReference;
9 |
10 | import static com.legend.tbs.TbsActivity.cookie;
11 | import static com.legend.tbs.TbsActivity.token;
12 | import static com.legend.tbs.fragment.BaseModel.finished;
13 | import static com.legend.tbs.fragment.FriendTbsPresenter.mFriendAdapter;
14 |
15 | /**
16 | * @author Legend
17 | * @data by on 2018/4/5.
18 | * @description
19 | */
20 |
21 | public class FriendTbsFragment extends BaseFragment implements BaseContract.View {
22 |
23 | private BaseContract.Model model;
24 | private BaseContract.Presenter presenter;
25 | private XRecyclerView mRecyclerView;
26 |
27 | public static final String FRIEND_URL = "https://ti.qq.com/cgi-node/honest-say/receive/friends?_client_version=0.0.7&token=";
28 |
29 | @Override
30 | public int setResourceLayoutId() {
31 | return R.layout.fragment_friend;
32 | }
33 |
34 | @Override
35 | public int setRecyclerViewId() {
36 | return R.id.mRecyclerView;
37 | }
38 |
39 | @Override
40 | public void initView() {
41 | model = new BaseModel();
42 | WeakReference reference = new WeakReference<>(this);
43 | presenter = new FriendTbsPresenter(reference.get(),model);
44 | }
45 |
46 | @Override
47 | public void initListener() {
48 | mRecyclerView = getmRecyclerView();
49 | mRecyclerView.setAdapter(mFriendAdapter);
50 | mRecyclerView.setPullRefreshEnabled(false);
51 | mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
52 | @Override
53 | public void onRefresh() {
54 |
55 | }
56 |
57 | @Override
58 | public void onLoadMore() {
59 | refreshData();
60 | }
61 | });
62 | }
63 |
64 | @Override
65 | public void refreshData() {
66 | presenter.sendRequest(FRIEND_URL,token,cookie);
67 | }
68 |
69 | @Override
70 | public void showLoading() {
71 |
72 | }
73 |
74 | @Override
75 | public void hideLoading() {
76 | mRecyclerView.refreshComplete();
77 | if (finished == 1) {
78 | mRecyclerView.setNoMore(true);
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/fragment/FriendTbsPresenter.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.fragment;
2 |
3 | import android.util.Log;
4 |
5 | import com.legend.tbs.common.adapter.TbsAdapter;
6 | import com.legend.tbs.common.model.TbsBean;
7 | import com.legend.tbs.contract.BaseContract;
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | import static com.legend.tbs.fragment.BaseModel.finished;
13 |
14 | /**
15 | * @author Legend
16 | * @data by on 2018/4/7.
17 | * @description
18 | */
19 |
20 | public class FriendTbsPresenter implements BaseContract.Presenter {
21 |
22 |
23 | private BaseContract.View view;
24 | private BaseContract.Model model;
25 | public static TbsAdapter mFriendAdapter;
26 | private List tbsBeanList;
27 |
28 | public FriendTbsPresenter(BaseContract.View view, BaseContract.Model model) {
29 | this.view = view;
30 | this.model = model;
31 | tbsBeanList = new ArrayList<>();
32 | mFriendAdapter = new TbsAdapter(tbsBeanList);
33 | }
34 |
35 | @Override
36 | public void sendRequest(String url, String token, String cookie) {
37 |
38 | model.Request(url, token, cookie,1, new BaseContract.Callback() {
39 | @Override
40 | public void onStart() {
41 | view.showLoading();
42 | }
43 |
44 | @Override
45 | public void onSuccess(List list) {
46 | if (finished == 0) {
47 | tbsBeanList.addAll(list);
48 | }
49 | Log.d("SIZE", String.valueOf(mFriendAdapter.getItemCount()));
50 | }
51 |
52 | @Override
53 | public void onFailure() {
54 | }
55 |
56 | @Override
57 | public void onFinished() {
58 | mFriendAdapter.notifyDataSetChanged();
59 | view.hideLoading();
60 | }
61 | });
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/fragment/SelfTbsFragment.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.fragment;
2 |
3 | import android.os.Handler;
4 | import android.support.v4.widget.SwipeRefreshLayout;
5 |
6 | import com.jcodecraeer.xrecyclerview.XRecyclerView;
7 | import com.legend.tbs.R;
8 | import com.legend.tbs.common.BaseFragment;
9 | import com.legend.tbs.contract.BaseContract;
10 |
11 | import java.lang.ref.WeakReference;
12 |
13 | import static com.legend.tbs.TbsActivity.cookie;
14 | import static com.legend.tbs.TbsActivity.dialog;
15 | import static com.legend.tbs.TbsActivity.token;
16 | import static com.legend.tbs.fragment.SelfTbsPresenter.mSelfAdapter;
17 |
18 | /**
19 | * @author Legend
20 | * @data by on 2018/4/5.
21 | * @description
22 | */
23 |
24 | public class SelfTbsFragment extends BaseFragment implements BaseContract.View {
25 |
26 | private BaseContract.Model model;
27 | private BaseContract.Presenter presenter;
28 | private XRecyclerView mRecyclerView;
29 | private SwipeRefreshLayout mSwipeRefresh;
30 |
31 | public static final String SELF_URL = "https://ti.qq.com/cgi-node/honest-say/receive/mine?/cgi-node/honest-say/activity/choose?_client_version=0.0.7&_t=1522927164526&token=";
32 |
33 |
34 | @Override
35 | public int setResourceLayoutId() {
36 | return R.layout.fragments_self;
37 | }
38 |
39 | @Override
40 | public int setRecyclerViewId() {
41 | return R.id.mRecyclerView;
42 | }
43 |
44 | @Override
45 | public void initView() {
46 | model = new BaseModel();
47 | WeakReference reference = new WeakReference<>(this);
48 | presenter = new SelfTbsPresenter(reference.get(),model);
49 | }
50 |
51 | @Override
52 | public void initListener() {
53 | mRecyclerView = getmRecyclerView();
54 | mRecyclerView.setAdapter(mSelfAdapter);
55 | mRecyclerView.setLoadingMoreEnabled(false);
56 | mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() {
57 | @Override
58 | public void onRefresh() {
59 | refreshData();
60 | }
61 |
62 | @Override
63 | public void onLoadMore() {
64 |
65 | }
66 | });
67 | }
68 |
69 | @Override
70 | public void refreshData() {
71 | new Handler().postDelayed(new Runnable() {
72 | @Override
73 | public void run() {
74 | presenter.sendRequest(SELF_URL,token,cookie);
75 | }
76 | },800);
77 |
78 | }
79 |
80 |
81 | @Override
82 | public void showLoading() {
83 | dialog.show();
84 | }
85 |
86 | @Override
87 | public void hideLoading() {
88 | mRecyclerView.refreshComplete();
89 | dialog.dismiss();
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/src/main/java/com/legend/tbs/fragment/SelfTbsPresenter.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs.fragment;
2 |
3 | import android.util.Log;
4 |
5 | import com.legend.tbs.common.adapter.TbsAdapter;
6 | import com.legend.tbs.common.model.TbsBean;
7 | import com.legend.tbs.contract.BaseContract;
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | /**
13 | * @author Legend
14 | * @data by on 2018/4/5.
15 | * @description
16 | */
17 |
18 | public class SelfTbsPresenter implements BaseContract.Presenter {
19 |
20 | private BaseContract.View view;
21 | private BaseContract.Model model;
22 | public static TbsAdapter mSelfAdapter;
23 | private List tbsBeanList;
24 |
25 | public SelfTbsPresenter(BaseContract.View view, BaseContract.Model model) {
26 | this.view = view;
27 | this.model = model;
28 | tbsBeanList = new ArrayList<>();
29 | mSelfAdapter = new TbsAdapter(tbsBeanList);
30 | }
31 |
32 | @Override
33 | public void sendRequest(String url, String token, String cookie) {
34 |
35 | model.Request(url, token, cookie, 0,new BaseContract.Callback() {
36 | @Override
37 | public void onStart() {
38 | view.showLoading();
39 | }
40 |
41 | @Override
42 | public void onSuccess(List list) {
43 | tbsBeanList.clear();
44 | tbsBeanList.addAll(list);
45 | Log.d("SIZE", String.valueOf(mSelfAdapter.getItemCount()));
46 | }
47 |
48 | @Override
49 | public void onFailure() {
50 | }
51 |
52 | @Override
53 | public void onFinished() {
54 | mSelfAdapter.notifyDataSetChanged();
55 | view.hideLoading();
56 | }
57 | });
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/loading_animation.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_loading_public.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_luncher.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
22 |
23 |
31 |
32 |
33 |
34 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_friend.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragments_self.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_tbs.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
18 |
27 |
28 |
35 |
44 |
45 |
54 |
55 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/loading_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
17 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #03A9F4
4 | #0288D1
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 10dp
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 坦白说揭露者
3 | 登录后才能获取哦
4 | 我的坦白说
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
16 |
17 |
18 |
25 |
26 |
27 |
28 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/values/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/test/java/com/legend/tbs/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.legend.tbs;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.0'
11 |
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Xchuanshuo/TBS/d3e6b1d11e61e535a97b1ce6e0385cf22a1b8995/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Apr 05 19:48:57 GMT+08:00 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------