update
@ -32,7 +32,13 @@ dependencies {
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.11.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
implementation project(path:":netlibs")
|
||||
|
||||
api 'com.squareup.okhttp3:okhttp:3.14.9'
|
||||
api 'com.squareup.retrofit2:retrofit:2.3.0'
|
||||
api 'com.alibaba.fastjson2:fastjson2:2.0.47'
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
@ -9,8 +9,28 @@
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.NetTools"
|
||||
tools:targetApi="31" />
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
|
||||
<data android:scheme="um.64e40ee55488fe7b3afa2c96" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
24
app/src/main/java/com/yutou/nettools/Api.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.yutou.nettools;
|
||||
|
||||
|
||||
import com.yutou.netlibs.http.API;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Api extends API<HttpApi> {
|
||||
|
||||
public Api(String url) {
|
||||
super(url);
|
||||
}
|
||||
|
||||
public Api(String url, HashMap<String, String> params) {
|
||||
super(url, params);
|
||||
|
||||
}
|
||||
public static HttpApi getInstance(HashMap<String, String> params){
|
||||
return new Api("http://tools.yutou233.cn",params).createAPI(HttpApi.class);
|
||||
}
|
||||
public static HttpApi getInstance(){
|
||||
return new Api("http://tools.yutou233.cn").createAPI(HttpApi.class);
|
||||
}
|
||||
}
|
34
app/src/main/java/com/yutou/nettools/Bean.java
Normal file
@ -0,0 +1,34 @@
|
||||
package com.yutou.nettools;
|
||||
|
||||
|
||||
public class Bean {
|
||||
String url;
|
||||
String version;
|
||||
|
||||
public Bean() {
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Bean{" +
|
||||
"url='" + url + '\'' +
|
||||
", version='" + version + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
24
app/src/main/java/com/yutou/nettools/HttpApi.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.yutou.nettools;
|
||||
|
||||
|
||||
import com.yutou.netlibs.http.HttpBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.Field;
|
||||
import retrofit2.http.FormUrlEncoded;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
public interface HttpApi {
|
||||
@GET("/public/request.do")
|
||||
Call<HttpBody<Bean>> getVersion();
|
||||
@GET("tools/password/type/get/list.do")
|
||||
Call<HttpBody<List<Password>>> getList(@Query("token")String token);
|
||||
@FormUrlEncoded
|
||||
@POST("/public/request.do")
|
||||
Call<HttpBody<Bean>> postVersion(@Field("test")String data);
|
||||
|
||||
}
|
48
app/src/main/java/com/yutou/nettools/MainActivity.java
Normal file
@ -0,0 +1,48 @@
|
||||
package com.yutou.nettools;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.yutou.netlibs.http.HttpBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
findViewById(R.id.button)
|
||||
.setOnClickListener(v -> {
|
||||
Api.getInstance().getList("")
|
||||
.enqueue(new Callback<HttpBody<List<Password>>>() {
|
||||
@Override
|
||||
public void onResponse(Call<HttpBody<List<Password>>> call, Response<HttpBody<List<Password>>> response) {
|
||||
System.out.println("response = " + response.body().getData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<HttpBody<List<Password>>> call, Throwable t) {
|
||||
|
||||
}
|
||||
});
|
||||
Api.getInstance().getVersion().enqueue(new Callback<HttpBody<Bean>>() {
|
||||
@Override
|
||||
public void onResponse(Call<HttpBody<Bean>> call, Response<HttpBody<Bean>> response) {
|
||||
System.out.println("response = " + response.body().getData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<HttpBody<Bean>> call, Throwable t) {
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
101
app/src/main/java/com/yutou/nettools/Password.java
Normal file
@ -0,0 +1,101 @@
|
||||
package com.yutou.nettools;
|
||||
|
||||
|
||||
public class Password {
|
||||
private int id;
|
||||
private String info;
|
||||
private String password; // 实际应用中,密码不应该以明文形式存储或传输
|
||||
private String title;
|
||||
private String titlePinyin;
|
||||
private int type;
|
||||
private int uid;
|
||||
private String url;
|
||||
private String username;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
public void setInfo(String info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getTitlePinyin() {
|
||||
return titlePinyin;
|
||||
}
|
||||
|
||||
public void setTitlePinyin(String titlePinyin) {
|
||||
this.titlePinyin = titlePinyin;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void setUid(int uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Password{" +
|
||||
"id=" + id +
|
||||
", info='" + info + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", title='" + title + '\'' +
|
||||
", titlePinyin='" + titlePinyin + '\'' +
|
||||
", type=" + type +
|
||||
", uid=" + uid +
|
||||
", url='" + url + '\'' +
|
||||
", username='" + username + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
18
app/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="306dp"
|
||||
android:text="Button"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -19,3 +19,8 @@ android.useAndroidX=true
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
|
||||
systemProp.http.proxyHost=127.0.0.1
|
||||
systemProp.https.proxyHost=127.0.0.1
|
||||
systemProp.https.proxyPort=7980
|
||||
systemProp.http.proxyPort=7890
|
1
netlibs/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
42
netlibs/build.gradle
Normal file
@ -0,0 +1,42 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.yutou.netlibs'
|
||||
compileSdk 34
|
||||
|
||||
defaultConfig {
|
||||
minSdk 28
|
||||
targetSdk 34
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.11.0'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.14.9'
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
|
||||
implementation 'com.alibaba.fastjson2:fastjson2:2.0.47'
|
||||
|
||||
}
|
21
netlibs/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
@ -0,0 +1,26 @@
|
||||
package com.yutou.netlibs;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("com.yutou.netlibs", appContext.getPackageName());
|
||||
}
|
||||
}
|
12
netlibs/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.NetTools" />
|
||||
|
||||
</manifest>
|
@ -0,0 +1,19 @@
|
||||
package com.yutou.netlibs.converter;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import retrofit2.CallAdapter;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class JsonCallAdapter extends CallAdapter.Factory{
|
||||
public static JsonCallAdapter create(){
|
||||
return new JsonCallAdapter();
|
||||
}
|
||||
@Nullable
|
||||
@Override
|
||||
public CallAdapter<?, ?> get(Type type, Annotation[] annotations, Retrofit retrofit) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.yutou.netlibs.converter;
|
||||
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.ResponseBody;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import retrofit2.Converter;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class JsonConverterFactory extends Converter.Factory {
|
||||
public static JsonConverterFactory create() {
|
||||
return new JsonConverterFactory();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
|
||||
// return super.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
|
||||
return new JsonRequestBodyConverter<>();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
|
||||
// return super.responseBodyConverter(type, annotations, retrofit);
|
||||
return new JsonResponseBodyConverter<>();
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.yutou.netlibs.converter;
|
||||
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.RequestBody;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import retrofit2.Converter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class JsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
|
||||
@Nullable
|
||||
@Override
|
||||
public RequestBody convert(T t) throws IOException {
|
||||
return RequestBody.create(MediaType.parse("application/json);charset=UTF-8"), t.toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.yutou.netlibs.converter;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.yutou.netlibs.http.HttpBody;
|
||||
|
||||
import okhttp3.ResponseBody;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import retrofit2.Converter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class JsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
|
||||
@Nullable
|
||||
@Override
|
||||
public T convert(ResponseBody responseBody) throws IOException {
|
||||
String string = new String(responseBody.bytes());
|
||||
responseBody.close();
|
||||
HttpBody body ;
|
||||
try {
|
||||
body = JSONObject.parseObject(string, HttpBody.class);
|
||||
return (T) body;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
body = new HttpBody();
|
||||
body.setSrc(string);
|
||||
}
|
||||
return (T) body;
|
||||
|
||||
}
|
||||
}
|
56
netlibs/src/main/java/com/yutou/netlibs/http/API.java
Normal file
@ -0,0 +1,56 @@
|
||||
package com.yutou.netlibs.http;
|
||||
|
||||
import com.yutou.netlibs.converter.JsonCallAdapter;
|
||||
import com.yutou.netlibs.converter.JsonConverterFactory;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class API<T> extends BaseAPI<T> {
|
||||
private String URL;
|
||||
private HashMap<String, String> params;
|
||||
|
||||
public API(String url, HashMap<String, String> params) {
|
||||
this.URL = url;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public API(String url) {
|
||||
this.URL = url;
|
||||
this.params = new HashMap<>();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T createAPI(Class<T> t) {
|
||||
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("http");
|
||||
loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
OkHttpClient.Builder builder = new OkHttpClient()
|
||||
.newBuilder()
|
||||
|
||||
.addInterceptor(initQuery())
|
||||
.addInterceptor(loggingInterceptor);
|
||||
return create(builder.build(),
|
||||
JsonConverterFactory.create(),
|
||||
JsonCallAdapter.create(),
|
||||
URL,
|
||||
t);
|
||||
}
|
||||
|
||||
public Interceptor initQuery() {
|
||||
Interceptor addQueryParameterInterceptor = new Interceptor() {
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
//配置公共参数
|
||||
request = new ParamsContext(params,request).getInRequest();
|
||||
return chain.proceed(request);
|
||||
}
|
||||
};
|
||||
return addQueryParameterInterceptor;
|
||||
}
|
||||
}
|
45
netlibs/src/main/java/com/yutou/netlibs/http/BaseAPI.java
Normal file
@ -0,0 +1,45 @@
|
||||
package com.yutou.netlibs.http;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import retrofit2.CallAdapter;
|
||||
import retrofit2.Converter;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
public abstract class BaseAPI<T> {
|
||||
public abstract T createAPI(Class<T> t);
|
||||
/**
|
||||
* 创建一个接口方法
|
||||
*
|
||||
* @param okHttpClient okhttp客户端
|
||||
* @param converterFactory 处理工厂类
|
||||
* @param callAdapterFactory 请求适配器工厂
|
||||
* @param baseUrl 基础地质
|
||||
* @param service 接口
|
||||
* @param <T> 接口泛型
|
||||
* @return 接口
|
||||
*/
|
||||
public T create(OkHttpClient okHttpClient,
|
||||
Converter.Factory converterFactory,
|
||||
CallAdapter.Factory callAdapterFactory,
|
||||
String baseUrl,
|
||||
Class<T> service) {
|
||||
Retrofit.Builder builder = new Retrofit.Builder()
|
||||
//基础url
|
||||
.baseUrl(baseUrl)
|
||||
//客户端OKHttp
|
||||
.client(okHttpClient);
|
||||
//添加转换工厂
|
||||
if (null != converterFactory) {
|
||||
builder.addConverterFactory(converterFactory);
|
||||
}
|
||||
//添加请求工厂
|
||||
if (null != callAdapterFactory) {
|
||||
builder.addCallAdapterFactory(callAdapterFactory);
|
||||
}
|
||||
//创建retrofit对象
|
||||
Retrofit retrofit = builder.build();
|
||||
|
||||
//返回创建的api
|
||||
return retrofit.create(service);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.yutou.netlibs.http;
|
||||
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.Request;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class GetRequestParams implements IRequestParam {
|
||||
/**
|
||||
* 构建Request
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Request getRequest(HashMap<String, String> map, Request request) {
|
||||
//添加公共参数
|
||||
HttpUrl.Builder builder = request.url().newBuilder();
|
||||
for (String key : map.keySet()) {
|
||||
builder.addQueryParameter(key, String.valueOf(map.get(key)));
|
||||
}
|
||||
return request.newBuilder().url(builder.build()).build();
|
||||
}
|
||||
}
|
40
netlibs/src/main/java/com/yutou/netlibs/http/HttpBody.java
Normal file
@ -0,0 +1,40 @@
|
||||
package com.yutou.netlibs.http;
|
||||
|
||||
public class HttpBody<T> {
|
||||
private String msg;
|
||||
private int code;
|
||||
private T data;
|
||||
private String src;
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getSrc() {
|
||||
return src;
|
||||
}
|
||||
|
||||
public void setSrc(String src) {
|
||||
this.src = src;
|
||||
}
|
||||
}
|
@ -0,0 +1,213 @@
|
||||
package com.yutou.netlibs.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import okhttp3.Connection;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Protocol;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.internal.http.HttpHeaders;
|
||||
import okio.Buffer;
|
||||
|
||||
public class HttpLoggingInterceptor implements Interceptor {
|
||||
|
||||
private static final String TAG = "HttpLog";
|
||||
private static final Charset UTF8 = StandardCharsets.UTF_8;
|
||||
|
||||
private volatile Level printLevel = Level.NONE;
|
||||
private java.util.logging.Level colorLevel;
|
||||
private Logger logger;
|
||||
|
||||
public enum Level {
|
||||
NONE, //不打印log
|
||||
BASIC, //只打印 请求首行 和 响应首行
|
||||
HEADERS, //打印请求和响应的所有 Header
|
||||
BODY //所有数据全部打印
|
||||
}
|
||||
|
||||
public HttpLoggingInterceptor(String tag) {
|
||||
logger = Logger.getLogger(tag);
|
||||
colorLevel = java.util.logging.Level.ALL;
|
||||
}
|
||||
|
||||
public void setPrintLevel(Level level) {
|
||||
if (printLevel == null)
|
||||
throw new NullPointerException("printLevel == null. Use Level.NONE instead.");
|
||||
printLevel = level;
|
||||
}
|
||||
|
||||
public void setColorLevel(java.util.logging.Level level) {
|
||||
colorLevel = level;
|
||||
}
|
||||
|
||||
private void log(String message) {
|
||||
logger.log(colorLevel, message);
|
||||
System.err.println(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
if (printLevel == Level.NONE) {
|
||||
return chain.proceed(request);
|
||||
}
|
||||
|
||||
//请求日志拦截
|
||||
// logForRequest(request, chain.connection());
|
||||
|
||||
//执行请求,计算请求时间
|
||||
long startNs = System.nanoTime();
|
||||
Response response;
|
||||
try {
|
||||
response = chain.proceed(request);
|
||||
} catch (Exception e) {
|
||||
log("<-- HTTP FAILED: " + e);
|
||||
throw e;
|
||||
}
|
||||
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
|
||||
|
||||
//响应日志拦截
|
||||
return logForResponse(request, response, tookMs);
|
||||
}
|
||||
|
||||
private void logForRequest(Request request, Connection connection) throws IOException {
|
||||
boolean logBody = (printLevel == Level.BODY);
|
||||
boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);
|
||||
RequestBody requestBody = request.body();
|
||||
boolean hasRequestBody = requestBody != null;
|
||||
Protocol protocol = connection != null ? connection.protocol() : Protocol.HTTP_1_1;
|
||||
try {
|
||||
String requestStartMessage = "--> " + request.method() + ' ' + request.url() + ' ' + protocol;
|
||||
log(requestStartMessage);
|
||||
|
||||
if (logHeaders) {
|
||||
if (hasRequestBody) {
|
||||
// Request body headers are only present when installed as a network interceptor. Force
|
||||
// them to be included (when available) so there values are known.
|
||||
if (requestBody.contentType() != null) {
|
||||
log("\tContent-Type: " + requestBody.contentType());
|
||||
}
|
||||
if (requestBody.contentLength() != -1) {
|
||||
log("\tContent-Length: " + requestBody.contentLength());
|
||||
}
|
||||
}
|
||||
Headers headers = request.headers();
|
||||
for (int i = 0, count = headers.size(); i < count; i++) {
|
||||
String name = headers.name(i);
|
||||
// Skip headers from the request body as they are explicitly logged above.
|
||||
if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
|
||||
log("\t" + name + ": " + headers.value(i));
|
||||
}
|
||||
}
|
||||
|
||||
log(" ");
|
||||
if (logBody && hasRequestBody) {
|
||||
if (isPlaintext(requestBody.contentType())) {
|
||||
bodyToString(request);
|
||||
} else {
|
||||
log("\tbody: maybe [binary body], omitted!");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(colorLevel, "error", e);
|
||||
} finally {
|
||||
log("--> END " + request.method());
|
||||
}
|
||||
}
|
||||
|
||||
private Response logForResponse(Request request, Response response, long tookMs) {
|
||||
Response.Builder builder = response.newBuilder();
|
||||
Response clone = builder.build();
|
||||
ResponseBody responseBody = clone.body();
|
||||
RequestBody requestBody = request.body();
|
||||
boolean hasRequestBody = requestBody != null;
|
||||
boolean logBody = (printLevel == Level.BODY);
|
||||
boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);
|
||||
|
||||
try {
|
||||
log("<-- " + clone.code() + ' ' + clone.message() + ' ' + clone.request().url() + " (" + tookMs + "ms)");
|
||||
if (logHeaders) {
|
||||
Headers headers = clone.headers();
|
||||
for (int i = 0, count = headers.size(); i < count; i++) {
|
||||
log("\t" + headers.name(i) + ": " + headers.value(i));
|
||||
}
|
||||
log(" ");
|
||||
if (logBody && hasRequestBody) {
|
||||
if (isPlaintext(requestBody.contentType())) {
|
||||
bodyToString(request);
|
||||
} else {
|
||||
log("\trequest: maybe [binary body], omitted!");
|
||||
}
|
||||
}
|
||||
if (logBody && HttpHeaders.hasBody(clone)) {
|
||||
if (responseBody == null) return response;
|
||||
|
||||
if (isPlaintext(responseBody.contentType())) {
|
||||
byte[] bytes = responseBody.bytes();// IOUtils.toByteArray(responseBody.byteStream());
|
||||
MediaType contentType = responseBody.contentType();
|
||||
String body = new String(bytes, getCharset(contentType));
|
||||
log("\tbody:" + body);
|
||||
responseBody = ResponseBody.create(responseBody.contentType(), bytes);
|
||||
return response.newBuilder().body(responseBody).build();
|
||||
} else {
|
||||
log("\tbody: maybe [binary body], omitted!");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(colorLevel, "error", e);
|
||||
} finally {
|
||||
log("<-- END HTTP");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
private static Charset getCharset(MediaType contentType) {
|
||||
Charset charset = contentType != null ? contentType.charset(UTF8) : UTF8;
|
||||
if (charset == null) charset = UTF8;
|
||||
return charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the body in question probably contains human readable text. Uses a small sample
|
||||
* of code points to detect unicode control characters commonly used in binary file signatures.
|
||||
*/
|
||||
private static boolean isPlaintext(MediaType mediaType) {
|
||||
if (mediaType == null) return false;
|
||||
if (mediaType.type() != null && mediaType.type().equals("text")) {
|
||||
return true;
|
||||
}
|
||||
String subtype = mediaType.subtype();
|
||||
if (subtype != null) {
|
||||
subtype = subtype.toLowerCase();
|
||||
if (subtype.contains("x-www-form-urlencoded") || subtype.contains("json") || subtype.contains("xml") || subtype.contains("html")) //
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void bodyToString(Request request) {
|
||||
try {
|
||||
Request copy = request.newBuilder().build();
|
||||
RequestBody body = copy.body();
|
||||
if (body == null) return;
|
||||
Buffer buffer = new Buffer();
|
||||
body.writeTo(buffer);
|
||||
Charset charset = getCharset(body.contentType());
|
||||
log("\tbody:" + buffer.readString(charset));
|
||||
} catch (Exception e) {
|
||||
logger.log(colorLevel, "error", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.yutou.netlibs.http;
|
||||
|
||||
import okhttp3.Request;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public interface IRequestParam {
|
||||
Request getRequest(HashMap<String,String> map, Request request);
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.yutou.netlibs.http;
|
||||
|
||||
|
||||
import okhttp3.Request;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ParamsContext {
|
||||
private IRequestParam iRequestParam;
|
||||
private Request request;
|
||||
private HashMap<String,String> map;
|
||||
|
||||
public ParamsContext(HashMap<String,String> map,Request request) {
|
||||
this.map=map;
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public Request getInRequest() {
|
||||
switch (request.method()) {
|
||||
case "GET":
|
||||
iRequestParam = new GetRequestParams();
|
||||
break;
|
||||
case "POST":
|
||||
iRequestParam = new PostRequestParams();
|
||||
break;
|
||||
}
|
||||
return iRequestParam.getRequest(map,request);
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package com.yutou.netlibs.http;
|
||||
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
|
||||
import okhttp3.*;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class PostRequestParams implements IRequestParam {
|
||||
@Override
|
||||
public Request getRequest(HashMap<String, String> map, Request request) {
|
||||
if (request.body() instanceof FormBody) {
|
||||
FormBody.Builder bodyBuilder = new FormBody.Builder();
|
||||
FormBody formBody = (FormBody) request.body();
|
||||
|
||||
for (int i = 0; i < formBody.size(); i++) {
|
||||
bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
|
||||
}
|
||||
for (String key : map.keySet()) {
|
||||
bodyBuilder.addEncoded(key, String.valueOf(map.get(key)));
|
||||
}
|
||||
formBody = bodyBuilder.build();
|
||||
request = request.newBuilder().post(formBody).build();
|
||||
} else if (request.body() != null) {
|
||||
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),toUrlParams(map));
|
||||
request = request.newBuilder().post(request.body())
|
||||
.post(requestBody).build();
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
public static String toUrlParams(JSONObject json) {
|
||||
StringBuilder string = new StringBuilder();
|
||||
Set<String> keys = json.keySet();
|
||||
for (String key : keys) {
|
||||
try {
|
||||
string.append("&").append(key).append("=").append(URLEncoder.encode(json.getString(key), "UTF-8"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
string.append("&").append(URLEncoder.encode(key,"UTF-8")).append("=");
|
||||
// string += "&" + key + "=";
|
||||
} catch (Exception e1) {
|
||||
string.append("&").append(key).append("=");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string = new StringBuilder(string.substring(1, string.length()).replaceAll(" ", ""));
|
||||
return string.toString();
|
||||
}
|
||||
|
||||
public static String toUrlParams(Map<String, String> map) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (String key : map.keySet()) {
|
||||
builder.append(key).append("=").append(map.get(key)).append("&");
|
||||
}
|
||||
return builder.substring(0, builder.length() - 1);
|
||||
}
|
||||
}
|
170
netlibs/src/main/res/drawable/ic_launcher_background.xml
Normal file
@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
30
netlibs/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
6
netlibs/src/main/res/mipmap-anydpi/ic_launcher.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
6
netlibs/src/main/res/mipmap-anydpi/ic_launcher_round.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
BIN
netlibs/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
netlibs/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
netlibs/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 982 B |
BIN
netlibs/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
netlibs/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
netlibs/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
netlibs/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
netlibs/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
netlibs/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
netlibs/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 7.6 KiB |
16
netlibs/src/main/res/values-night/themes.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.NetTools" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_200</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/black</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_200</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
10
netlibs/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
3
netlibs/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">NetLibs</string>
|
||||
</resources>
|
16
netlibs/src/main/res/values/themes.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.NetTools" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
17
netlibs/src/test/java/com/yutou/netlibs/ExampleUnitTest.java
Normal file
@ -0,0 +1,17 @@
|
||||
package com.yutou.netlibs;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
@ -15,3 +15,4 @@ dependencyResolutionManagement {
|
||||
|
||||
rootProject.name = "NetTools"
|
||||
include ':app'
|
||||
include ':netlibs'
|
||||
|