@@ -3,17 +3,31 @@ package cn.org.bjca.trust.pushdemo | |||
import android.os.Bundle | |||
import android.widget.TextView | |||
import androidx.appcompat.app.AppCompatActivity | |||
import androidx.lifecycle.lifecycleScope | |||
import cn.org.bjca.trust.push.PushSdk | |||
import cn.org.bjca.trust.push.common.FileHelper | |||
import cn.org.bjca.trust.push.api.PushService | |||
import cn.org.bjca.trust.push.common.LogHelper | |||
import cn.org.bjca.trust.push.common.SendMessageHelper | |||
import cn.org.bjca.trust.push.di.manager.HttpManager | |||
import com.xuqm.base.extensions.http | |||
class MainActivity : AppCompatActivity() { | |||
override fun onCreate(savedInstanceState: Bundle?) { | |||
super.onCreate(savedInstanceState) | |||
setContentView(R.layout.activity_main) | |||
PushSdk.instance.register("xuqinmin") | |||
findViewById<TextView>(R.id.register).setOnClickListener { | |||
FileHelper.openFile() | |||
lifecycleScope.http( | |||
request = { | |||
HttpManager.getApi( | |||
HttpManager.getAppComponent("http://192.168.115.173:8080"), | |||
PushService::class.java | |||
) | |||
.getArticle(231231) | |||
}, | |||
resp = { LogHelper.d(it) } | |||
) | |||
} | |||
findViewById<TextView>(R.id.send).setOnClickListener { | |||
SendMessageHelper.sendTextMessage("xuqinmin", "你好啊${System.currentTimeMillis()}") | |||
@@ -74,8 +74,23 @@ dependencies { | |||
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5' | |||
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1' | |||
//网络请求 | |||
implementation 'com.squareup.retrofit2:retrofit:2.9.0' | |||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0' | |||
api 'com.squareup.okhttp3:logging-interceptor:4.9.1' | |||
implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1' | |||
//Dagger | |||
implementation 'com.google.dagger:hilt-android:2.40.5' | |||
kapt 'com.google.dagger:hilt-android-compiler:2.40.5' | |||
//Coroutine | |||
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4" | |||
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4" | |||
api "androidx.lifecycle:lifecycle-runtime-ktx:2.5.0-alpha05" | |||
//gson | |||
implementation 'com.google.code.gson:gson:2.9.0' | |||
api 'com.google.code.gson:gson:2.9.0' | |||
// 小米推送 | |||
// implementation (name: 'MiPush_SDK_Client_5_3_0-C_3rd', ext: 'aar') | |||
@@ -0,0 +1,40 @@ | |||
package cn.org.bjca.trust.push.api; | |||
public class HttpResult<T> { | |||
private String status; | |||
private String msg; | |||
private T data; | |||
public String getStatus() { | |||
return status; | |||
} | |||
public void setStatus(String status) { | |||
this.status = status; | |||
} | |||
public T getData() { | |||
return data; | |||
} | |||
public void setData(T data) { | |||
this.data = data; | |||
} | |||
public String getMsg() { | |||
return msg; | |||
} | |||
public void setMsg(String msg) { | |||
this.msg = msg; | |||
} | |||
@Override | |||
public String toString() { | |||
return "HttpResult{" + | |||
"status='" + status + '\'' + | |||
", msg='" + msg + '\'' + | |||
", data=" + data + | |||
'}'; | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
package cn.org.bjca.trust.push.api | |||
import retrofit2.http.GET | |||
import retrofit2.http.Path | |||
interface PushService { | |||
@GET("hello/{id}") | |||
suspend fun getArticle(@Path("id") id: Int): HttpResult<String> | |||
} |
@@ -10,27 +10,27 @@ object LogHelper { | |||
* e | |||
*/ | |||
@JvmStatic | |||
fun e(message: String) { | |||
fun e(message: Any?) { | |||
e(message, null, null) | |||
} | |||
@JvmStatic | |||
fun e(message: String, tag: String) { | |||
fun e(message: Any?, tag: String) { | |||
e(message, null, tag) | |||
} | |||
@JvmStatic | |||
fun e(message: String, tr: Throwable) { | |||
fun e(message: Any?, tr: Throwable) { | |||
e(message, tr, null) | |||
} | |||
@JvmStatic | |||
fun e(message: String, tr: Throwable?, tag: String?) { | |||
println(tr, tag) { | |||
fun e(message: Any?, tr: Throwable?, tag: String?) { | |||
println(tag, tr) { | |||
if (tr != null) { | |||
Log.e(TAG, message, tr) | |||
Log.e(TAG, CommonHelper.anyToString(message), tr) | |||
} else { | |||
Log.e(TAG, message) | |||
Log.e(TAG, CommonHelper.anyToString(message)) | |||
} | |||
} | |||
} | |||
@@ -39,32 +39,32 @@ object LogHelper { | |||
* d | |||
*/ | |||
@JvmStatic | |||
fun d(message: String) { | |||
fun d(message: Any?) { | |||
d(message, null, null) | |||
} | |||
@JvmStatic | |||
fun d(message: String, tag: String) { | |||
fun d(message: Any?, tag: String) { | |||
d(message, null, tag) | |||
} | |||
@JvmStatic | |||
fun d(message: String, tr: Throwable) { | |||
fun d(message: Any?, tr: Throwable) { | |||
d(message, tr, null) | |||
} | |||
@JvmStatic | |||
fun d(message: String, tr: Throwable?, tag: String?) { | |||
println(tr, tag) { | |||
fun d(message: Any?, tr: Throwable?, tag: String?) { | |||
println(tag, tr) { | |||
if (tr != null) { | |||
Log.d(TAG, message, tr) | |||
Log.d(TAG, CommonHelper.anyToString(message), tr) | |||
} else { | |||
Log.d(TAG, message) | |||
Log.d(TAG, CommonHelper.anyToString(message)) | |||
} | |||
} | |||
} | |||
private fun println(tr: Throwable?, tag: String?, log: () -> Unit) { | |||
private fun println(tag: String?, tr: Throwable?, log: () -> Unit) { | |||
if (!showLog) return | |||
Log.d( | |||
TAG, "" | |||
@@ -6,6 +6,7 @@ import cn.org.bjca.trust.push.message.ImManager | |||
import cn.org.bjca.trust.push.message.bean.* | |||
import cn.org.bjca.trust.push.message.msg.Message | |||
import cn.org.bjca.trust.push.message.msg.SendMessage | |||
import java.io.File | |||
object SendMessageHelper { | |||
private fun sendMessage(message: Message) { | |||
@@ -30,6 +31,13 @@ object SendMessageHelper { | |||
@JvmStatic | |||
fun sendImageMessage( | |||
toUserId: String, | |||
file: File | |||
) { | |||
} | |||
@JvmStatic | |||
fun sendImageMessage( | |||
toUserId: String, | |||
imageStorageId: String, | |||
thumbnail: String, | |||
thumbnailWidth: Int, | |||
@@ -0,0 +1,21 @@ | |||
package cn.org.bjca.trust.push.common | |||
import android.content.Context | |||
import android.content.SharedPreferences | |||
object SharedPreferencesHelper { | |||
private lateinit var preferences: SharedPreferences | |||
fun getPreferences(context: Context): SharedPreferences { | |||
if (!::preferences.isInitialized) { | |||
preferences = context.getSharedPreferences("CookiePersistence", Context.MODE_PRIVATE) | |||
} | |||
return preferences | |||
} | |||
fun getPreferences(): SharedPreferences { | |||
if (!::preferences.isInitialized) { | |||
throw Throwable("未初始化") | |||
} | |||
return preferences | |||
} | |||
} |
@@ -0,0 +1,270 @@ | |||
package cn.org.bjca.trust.push.common; | |||
import android.content.Context; | |||
import android.text.Editable; | |||
import android.text.TextUtils; | |||
import android.text.TextWatcher; | |||
import android.view.View; | |||
import android.widget.EditText; | |||
import android.widget.Toast; | |||
import com.google.android.material.snackbar.Snackbar; | |||
import com.google.android.material.textfield.TextInputLayout; | |||
import java.lang.reflect.Field; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
public class ToolsHelper { | |||
public static boolean isNull(Object obj) { | |||
if (null == obj) | |||
return true; | |||
String str = obj.toString(); | |||
if (str.isEmpty()) | |||
return true; | |||
return str.equalsIgnoreCase("null"); | |||
} | |||
public static Long toLong(Object obj) { | |||
if (isNull(obj)) | |||
return 0L; | |||
try { | |||
return Long.parseLong(obj.toString()); | |||
} catch (Exception e) { | |||
return 0L; | |||
} | |||
} | |||
public static int toInt(Object obj) { | |||
if (isNull(obj)) | |||
return 0; | |||
try { | |||
return Integer.parseInt(obj.toString()); | |||
} catch (Exception e) { | |||
return 0; | |||
} | |||
} | |||
public static Double toDouble(Object obj) { | |||
if (isNull(obj)) | |||
return 0.0; | |||
try { | |||
return Double.parseDouble(obj.toString()); | |||
} catch (Exception e) { | |||
return 0D; | |||
} | |||
} | |||
public static String toString(Object obj) { | |||
if (isNull(obj)) | |||
return ""; | |||
return obj.toString(); | |||
} | |||
/** | |||
* 格式化json字符串 | |||
* | |||
* @param jsonStr 需要格式化的json串 | |||
* @return 格式化后的json串 | |||
*/ | |||
public static String formatJson(String jsonStr) { | |||
if (null == jsonStr || "".equals(jsonStr)) return ""; | |||
StringBuilder sb = new StringBuilder(); | |||
char last = '\0'; | |||
char current = '\0'; | |||
int indent = 0; | |||
for (int i = 0; i < jsonStr.length(); i++) { | |||
last = current; | |||
current = jsonStr.charAt(i); | |||
//遇到{ [换行,且下一行缩进 | |||
switch (current) { | |||
case '{': | |||
case '[': | |||
sb.append(current); | |||
sb.append('\n'); | |||
indent++; | |||
addIndentBlank(sb, indent); | |||
break; | |||
//遇到} ]换行,当前行缩进 | |||
case '}': | |||
case ']': | |||
sb.append('\n'); | |||
indent--; | |||
addIndentBlank(sb, indent); | |||
sb.append(current); | |||
break; | |||
//遇到,换行 | |||
case ',': | |||
sb.append(current); | |||
if (last != '\\') { | |||
sb.append('\n'); | |||
addIndentBlank(sb, indent); | |||
} | |||
break; | |||
default: | |||
sb.append(current); | |||
} | |||
} | |||
return sb.toString(); | |||
} | |||
/** | |||
* 添加space | |||
*/ | |||
private static void addIndentBlank(StringBuilder sb, int indent) { | |||
for (int i = 0; i < indent; i++) { | |||
sb.append('\t'); | |||
} | |||
} | |||
/** | |||
* http 请求数据返回 json 中中文字符为 unicode 编码转汉字转码 | |||
* | |||
* @param theString | |||
* @return 转化后的结果. | |||
*/ | |||
public static String decodeUnicode(String theString) { | |||
char aChar; | |||
int len = theString.length(); | |||
StringBuilder outBuffer = new StringBuilder(len); | |||
for (int x = 0; x < len; ) { | |||
aChar = theString.charAt(x++); | |||
if (aChar == '\\') { | |||
aChar = theString.charAt(x++); | |||
if (aChar == 'u') { | |||
int value = 0; | |||
for (int i = 0; i < 4; i++) { | |||
aChar = theString.charAt(x++); | |||
switch (aChar) { | |||
case '0': | |||
case '1': | |||
case '2': | |||
case '3': | |||
case '4': | |||
case '5': | |||
case '6': | |||
case '7': | |||
case '8': | |||
case '9': | |||
value = (value << 4) + aChar - '0'; | |||
break; | |||
case 'a': | |||
case 'b': | |||
case 'c': | |||
case 'd': | |||
case 'e': | |||
case 'f': | |||
value = (value << 4) + 10 + aChar - 'a'; | |||
break; | |||
case 'A': | |||
case 'B': | |||
case 'C': | |||
case 'D': | |||
case 'E': | |||
case 'F': | |||
value = (value << 4) + 10 + aChar - 'A'; | |||
break; | |||
default: | |||
throw new IllegalArgumentException( | |||
"Malformed \\uxxxx encoding."); | |||
} | |||
} | |||
outBuffer.append((char) value); | |||
} else { | |||
if (aChar == 't') { | |||
aChar = '\t'; | |||
} else if (aChar != 'r') { | |||
if (aChar == 'n') { | |||
aChar = '\n'; | |||
} else if (aChar == 'f') { | |||
aChar = '\f'; | |||
} | |||
} else { | |||
aChar = '\r'; | |||
} | |||
outBuffer.append(aChar); | |||
} | |||
} else { | |||
outBuffer.append(aChar); | |||
} | |||
} | |||
return outBuffer.toString(); | |||
} | |||
/** | |||
* 弹出提示信息 感觉比Toast好看点 不过Toast不需要依赖view | |||
* | |||
* @param view 绑定一个view才能展示 | |||
* @param content 需要展示的内容 | |||
*/ | |||
public static void snack(View view, CharSequence content) { | |||
Snackbar.make(view, content, Snackbar.LENGTH_SHORT).show(); | |||
} | |||
public static void showMessage(Context context, CharSequence content) { | |||
Toast.makeText(context, content, Toast.LENGTH_SHORT).show(); | |||
} | |||
/** | |||
* EditText绑定TextInputLayout,处理一下 | |||
* | |||
* @param editText editText | |||
* @param textInputLayout textInputLayout | |||
*/ | |||
public static void addTextChangedListener(EditText editText, TextInputLayout textInputLayout) { | |||
editText.addTextChangedListener(new TextWatcher() { | |||
@Override | |||
public void beforeTextChanged(CharSequence s, int start, int count, int after) { | |||
} | |||
@Override | |||
public void onTextChanged(CharSequence s, int start, int before, int count) { | |||
} | |||
@Override | |||
public void afterTextChanged(Editable s) { | |||
if (!TextUtils.isEmpty(textInputLayout.getError())) {//输入的时候不提示错误信息 | |||
textInputLayout.setErrorEnabled(true); | |||
textInputLayout.setError(""); | |||
textInputLayout.setErrorEnabled(false); | |||
} | |||
} | |||
}); | |||
} | |||
/** | |||
* 使用 TextInputLayout 提示错误信息 | |||
* | |||
* @param textInputLayout TextInputLayout | |||
* @param msg 错判的内容 | |||
*/ | |||
public static void showError(TextInputLayout textInputLayout, String msg) { | |||
textInputLayout.setErrorEnabled(true); | |||
textInputLayout.setError(msg); | |||
} | |||
/** | |||
* 将Object对象里面的属性和值转化成Map对象 | |||
* | |||
* @param obj | |||
* @return | |||
* @throws IllegalAccessException | |||
*/ | |||
public static <T> Map<String, T> objectToMap(Object obj) throws IllegalAccessException { | |||
Map<String, T> map = new HashMap<>(); | |||
Class<?> clazz = obj.getClass(); | |||
for (Field field : clazz.getDeclaredFields()) { | |||
field.setAccessible(true); | |||
String fieldName = field.getName(); | |||
T value = (T) field.get(obj); | |||
if (null != value) | |||
map.put(fieldName, value); | |||
} | |||
return map; | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
package cn.org.bjca.trust.push.di.component; | |||
import com.franmontiel.persistentcookiejar.PersistentCookieJar; | |||
import java.util.List; | |||
import javax.inject.Singleton; | |||
import cn.org.bjca.trust.push.di.module.NetworkModule; | |||
import dagger.Component; | |||
import okhttp3.Cookie; | |||
import okhttp3.OkHttpClient; | |||
import retrofit2.Retrofit; | |||
/** | |||
* 可以获取到Retrofit、OkHttpClient、PersistentCookieJar、cookies | |||
*/ | |||
@Singleton | |||
@Component(modules = NetworkModule.class) | |||
public interface AppComponent { | |||
Retrofit retrofit(); | |||
OkHttpClient okHttpClient(); | |||
PersistentCookieJar persistentCookieJar(); | |||
List<Cookie> cookies(); | |||
} |
@@ -0,0 +1,28 @@ | |||
package cn.org.bjca.trust.push.di.interceptor; | |||
import cn.org.bjca.trust.push.common.LogHelper; | |||
import cn.org.bjca.trust.push.common.ToolsHelper; | |||
import okhttp3.logging.HttpLoggingInterceptor; | |||
public class HttpLogger implements HttpLoggingInterceptor.Logger { | |||
private StringBuilder mMessage = new StringBuilder(); | |||
@Override | |||
public void log(String message) { | |||
// 请求或者响应开始 | |||
if (message.startsWith("--> POST")) { | |||
mMessage.setLength(0); | |||
} | |||
// 以{}或者[]形式的说明是响应结果的json数据,需要进行格式化 | |||
if ((message.startsWith("{") && message.endsWith("}")) | |||
|| (message.startsWith("[") && message.endsWith("]"))) { | |||
message = ToolsHelper.formatJson(ToolsHelper.decodeUnicode(message)); | |||
} | |||
mMessage.append(message.concat("\n")); | |||
// 响应结束,打印整条日志 | |||
if (message.startsWith("<-- END HTTP")) { | |||
LogHelper.d("___http",mMessage.toString()); | |||
} | |||
} | |||
} |
@@ -0,0 +1,56 @@ | |||
package cn.org.bjca.trust.push.di.interceptor; | |||
import static java.nio.charset.StandardCharsets.UTF_8; | |||
import java.io.IOException; | |||
import java.nio.charset.Charset; | |||
import cn.org.bjca.trust.push.common.LogHelper; | |||
import okhttp3.Interceptor; | |||
import okhttp3.MediaType; | |||
import okhttp3.Request; | |||
import okhttp3.Response; | |||
import okhttp3.ResponseBody; | |||
import okio.Buffer; | |||
public class LoggingInterceptor implements Interceptor { | |||
String TAG = "_____Http"; | |||
@Override | |||
public Response intercept(Chain chain) throws IOException { | |||
Request request = chain.request(); | |||
long startTime = System.currentTimeMillis(); | |||
Response response = chain.proceed(chain.request()); | |||
long endTime = System.currentTimeMillis(); | |||
long duration = endTime - startTime; | |||
ResponseBody responseBody = response.body(); | |||
if (responseBody == null) { | |||
return response; | |||
} | |||
okhttp3.MediaType mediaType = responseBody.contentType(); | |||
String content = response.body().string(); | |||
LogHelper.e(request.toString(), TAG); | |||
LogHelper.e(response.code() + " : " + response.message(), TAG); | |||
String method = request.method(); | |||
if ("POST".equals(method)) { | |||
Buffer buffer = new Buffer(); | |||
try { | |||
request.body().writeTo(buffer); | |||
Charset charset = Charset.forName("UTF-8"); | |||
MediaType contentType = request.body().contentType(); | |||
if (contentType != null) { | |||
charset = contentType.charset(UTF_8); | |||
} | |||
String params = buffer.readString(charset); | |||
LogHelper.e(params, TAG); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
LogHelper.d(content, TAG); | |||
LogHelper.e("耗时: " + duration + "毫秒", TAG); | |||
return response.newBuilder().body(okhttp3.ResponseBody.create(mediaType, content)).build(); | |||
} | |||
} |
@@ -0,0 +1,68 @@ | |||
package cn.org.bjca.trust.push.di.manager; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import cn.org.bjca.trust.push.di.component.AppComponent; | |||
import cn.org.bjca.trust.push.di.component.DaggerAppComponent; | |||
import cn.org.bjca.trust.push.di.interceptor.HttpLogger; | |||
import cn.org.bjca.trust.push.di.module.NetworkModule; | |||
import okhttp3.Interceptor; | |||
import okhttp3.logging.HttpLoggingInterceptor; | |||
/** | |||
* 网络访问的管理类, | |||
*/ | |||
public class HttpManager { | |||
private static Map<String, Object> apis = new HashMap<>(); | |||
private static Map<String, AppComponent> appComponentMap = new HashMap<>(); | |||
/** | |||
* 根据给定的appComponent和service获取一个service实例 | |||
* appComponent可以使用{@link #getAppComponent(String)} 方法获得 | |||
* service 可以参照retrofit的使用方法 | |||
* | |||
* @param appComponent {@link #getAppComponent(String)} | |||
* @param service service | |||
* @param <T> service实例class类型 | |||
* @return service实例 | |||
*/ | |||
public static <T> T getApi(AppComponent appComponent, final Class<T> service) { | |||
String key = appComponent.hashCode() + service.getCanonicalName(); | |||
if (!apis.containsKey(key)) | |||
synchronized (HttpManager.class) { | |||
if (!apis.containsKey(key)) | |||
apis.put(key, appComponent.retrofit().create(service)); | |||
} | |||
return (T) apis.get(key); | |||
} | |||
/** | |||
* 根据指定的baseUrl 获取一个{@link AppComponent} 用来做后续事件 | |||
* | |||
* @param baseUrl 换地地址 例如 | |||
* @return AppComponent | |||
*/ | |||
public static AppComponent getAppComponent(String baseUrl) { | |||
return getAppComponent(baseUrl, new HttpLoggingInterceptor(new HttpLogger()).setLevel(HttpLoggingInterceptor.Level.BASIC)); | |||
} | |||
/** | |||
* 根据指定的baseUrl 获取一个{@link AppComponent} 用来做后续事件 | |||
* | |||
* @param baseUrl 换地地址 | |||
* @param interceptor 自定义拦截器 | |||
* @return AppComponent | |||
*/ | |||
public static AppComponent getAppComponent(String baseUrl, Interceptor... interceptor) { | |||
if (!appComponentMap.containsKey(baseUrl)) | |||
synchronized (HttpManager.class) { | |||
if (!appComponentMap.containsKey(baseUrl)) | |||
appComponentMap.put(baseUrl, DaggerAppComponent.builder().networkModule(new NetworkModule(baseUrl, interceptor)).build()); | |||
} | |||
return appComponentMap.get(baseUrl); | |||
} | |||
} |
@@ -0,0 +1,100 @@ | |||
package cn.org.bjca.trust.push.di.module; | |||
import com.franmontiel.persistentcookiejar.PersistentCookieJar; | |||
import com.franmontiel.persistentcookiejar.cache.SetCookieCache; | |||
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
import java.util.concurrent.TimeUnit; | |||
import javax.inject.Singleton; | |||
import cn.org.bjca.trust.push.common.SharedPreferencesHelper; | |||
import cn.org.bjca.trust.push.di.interceptor.HttpLogger; | |||
import dagger.Module; | |||
import dagger.Provides; | |||
import dagger.hilt.InstallIn; | |||
import dagger.hilt.components.SingletonComponent; | |||
import okhttp3.Cookie; | |||
import okhttp3.Interceptor; | |||
import okhttp3.OkHttpClient; | |||
import okhttp3.logging.HttpLoggingInterceptor; | |||
import retrofit2.Retrofit; | |||
import retrofit2.converter.gson.GsonConverterFactory; | |||
@Module | |||
@InstallIn(SingletonComponent.class) | |||
public class NetworkModule { | |||
private String BaseUrl = "https://xuqinmin.com/"; | |||
private final List<Interceptor> interceptor = new ArrayList<>(); | |||
public NetworkModule() { | |||
} | |||
public NetworkModule(String baseUrl, Interceptor... interceptor) { | |||
BaseUrl = baseUrl; | |||
this.interceptor.clear(); | |||
if (null != interceptor) | |||
this.interceptor.addAll(Arrays.asList(interceptor)); | |||
} | |||
@Provides | |||
@Singleton | |||
Retrofit provideRetrofit(OkHttpClient okHttpClient) { | |||
return new Retrofit.Builder() | |||
.baseUrl(BaseUrl) | |||
.client(okHttpClient) | |||
.addConverterFactory(GsonConverterFactory.create()) | |||
// .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) | |||
.build(); | |||
} | |||
@Provides | |||
@Singleton | |||
OkHttpClient provideOkHttpClient(HttpLoggingInterceptor httpLoggingInterceptor, PersistentCookieJar persistentCookieJar) { | |||
OkHttpClient.Builder builder = new OkHttpClient.Builder() | |||
.connectTimeout(30, TimeUnit.SECONDS) | |||
.pingInterval(5, TimeUnit.SECONDS) | |||
.readTimeout(60, TimeUnit.SECONDS) | |||
.writeTimeout(60, TimeUnit.SECONDS); | |||
// builder.addNetworkInterceptor(httpLoggingInterceptor); | |||
if (0 != interceptor.size()) { | |||
for (Interceptor interceptor1 : this.interceptor) { | |||
builder.addInterceptor(interceptor1); | |||
} | |||
} | |||
return builder.cookieJar(persistentCookieJar) | |||
.build(); | |||
} | |||
@Provides | |||
@Singleton | |||
HttpLoggingInterceptor provideHttpLoggingInterceptor() { | |||
return new HttpLoggingInterceptor(new HttpLogger()).setLevel(HttpLoggingInterceptor.Level.BASIC); | |||
} | |||
@Provides | |||
@Singleton | |||
PersistentCookieJar providePersistentCookieJar(SharedPrefsCookiePersistor sharedPrefsCookiePersistor) { | |||
return new PersistentCookieJar(new SetCookieCache(), sharedPrefsCookiePersistor); | |||
} | |||
@Provides | |||
@Singleton | |||
SharedPrefsCookiePersistor provideSharedPrefsCookiePersistor() { | |||
return new SharedPrefsCookiePersistor(SharedPreferencesHelper.INSTANCE.getPreferences()); | |||
} | |||
@Provides | |||
@Singleton | |||
List<Cookie> provideCookies(SharedPrefsCookiePersistor sharedPrefsCookiePersistor) { | |||
return sharedPrefsCookiePersistor.loadAll(); | |||
} | |||
} |
@@ -0,0 +1,174 @@ | |||
package com.xuqm.base.extensions | |||
import android.app.Activity | |||
import android.content.Context | |||
import android.view.inputmethod.InputMethodManager | |||
import androidx.annotation.NonNull | |||
import androidx.appcompat.app.AlertDialog | |||
import androidx.fragment.app.Fragment | |||
import cn.org.bjca.trust.push.BuildConfig | |||
import cn.org.bjca.trust.push.api.HttpResult | |||
import cn.org.bjca.trust.push.common.LogHelper | |||
import kotlinx.coroutines.CoroutineScope | |||
import kotlinx.coroutines.Job | |||
import kotlinx.coroutines.launch | |||
fun Any.log(message: Any) { | |||
LogHelper.d(message) | |||
} | |||
fun Any.loge(message: Any) { | |||
LogHelper.e(message) | |||
} | |||
fun Any.log() { | |||
LogHelper.d(this) | |||
} | |||
fun Any.loge() { | |||
LogHelper.e(this) | |||
} | |||
/** | |||
* 弹出窗口 | |||
* @param title 标题 | |||
* @param message 提示信息 | |||
* @param confirm 点击确认按钮 | |||
* @param cancel 点击取消按钮的事件 | |||
*/ | |||
fun Activity.showDialog(title: String, message: String, confirm: () -> Unit, cancel: () -> Unit) { | |||
AlertDialog.Builder(this).setTitle(title) | |||
.setMessage(message) | |||
.setPositiveButton( | |||
"确定" | |||
) { _, _ -> | |||
confirm() | |||
} | |||
.setNegativeButton( | |||
"取消" | |||
) { _, _ -> | |||
cancel() | |||
}.create().show() | |||
} | |||
/** | |||
* 弹出窗口---只有一个确认按钮 | |||
* @param title 标题 | |||
* @param message 提示信息 | |||
* @param confirm 点击确认按钮 | |||
*/ | |||
fun Activity.showDialog(title: String, message: String, confirm: () -> Unit) { | |||
AlertDialog.Builder(this).setTitle(title) | |||
.setMessage(message) | |||
.setPositiveButton( | |||
"确定" | |||
) { _, _ -> | |||
confirm() | |||
}.create().show() | |||
} | |||
/* | |||
隐藏软键盘 | |||
*/ | |||
fun Activity.hideSoftInput() { | |||
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager | |||
imm.hideSoftInputFromWindow(window.decorView.windowToken, 0) | |||
} | |||
fun Fragment.hideSoftInput() { | |||
activity?.hideSoftInput() | |||
} | |||
fun Context.putInt(key: String, value: Int) { | |||
val sharedPref = | |||
getSharedPreferences(BuildConfig.versionName, Context.MODE_PRIVATE) ?: return | |||
with(sharedPref.edit()) { | |||
putInt(key, value) | |||
apply() | |||
} | |||
} | |||
fun Context.getIntForPreferences(key: String): Int { | |||
val sharedPref = | |||
getSharedPreferences(BuildConfig.versionName, Context.MODE_PRIVATE) | |||
return sharedPref?.getInt(key, -1) ?: -1 | |||
} | |||
fun Context.getIntForPreferences(key: String, @NonNull defValue: Int): Int { | |||
val sharedPref = | |||
getSharedPreferences(BuildConfig.versionName, Context.MODE_PRIVATE) | |||
return sharedPref?.getInt(key, defValue) ?: defValue | |||
} | |||
fun Context.putLong(key: String, value: Long) { | |||
val sharedPref = | |||
getSharedPreferences(BuildConfig.versionName, Context.MODE_PRIVATE) ?: return | |||
with(sharedPref.edit()) { | |||
putLong(key, value) | |||
apply() | |||
} | |||
} | |||
fun Context.getLongForPreferences(key: String): Long { | |||
val sharedPref = | |||
getSharedPreferences(BuildConfig.versionName, Context.MODE_PRIVATE) | |||
return sharedPref?.getLong(key, -1) ?: -1 | |||
} | |||
fun Context.getLongForPreferences(key: String, @NonNull defValue: Long): Long { | |||
val sharedPref = | |||
getSharedPreferences(BuildConfig.versionName, Context.MODE_PRIVATE) | |||
return sharedPref?.getLong(key, defValue) ?: defValue | |||
} | |||
fun Context.putString(key: String, value: String) { | |||
val sharedPref = | |||
getSharedPreferences(BuildConfig.versionName, Context.MODE_PRIVATE) ?: return | |||
with(sharedPref.edit()) { | |||
putString(key, value) | |||
apply() | |||
} | |||
} | |||
fun Context.getStringForPreferences(key: String): String { | |||
val sharedPref = | |||
getSharedPreferences(BuildConfig.versionName, Context.MODE_PRIVATE) | |||
return sharedPref?.getString(key, "") ?: "" | |||
} | |||
fun Context.getStringForPreferences(key: String, @NonNull defValue: String): String { | |||
val sharedPref = | |||
getSharedPreferences(BuildConfig.versionName, Context.MODE_PRIVATE) | |||
return sharedPref?.getString(key, defValue) ?: defValue | |||
} | |||
/** | |||
* http 请求扩展 | |||
*/ | |||
fun <T> CoroutineScope.http( | |||
start: () -> Unit = {}, | |||
request: suspend CoroutineScope.() -> HttpResult<T>, | |||
resp: (T?) -> Unit, | |||
err: (String) -> Unit = {}, | |||
end: () -> Unit = {} | |||
): Job { | |||
return launch { | |||
try { | |||
start() | |||
val data = request() | |||
if (data.status == "200") { | |||
resp(data.data) | |||
} else { | |||
err(data.msg) | |||
} | |||
} catch (e: Exception) { | |||
err(e.message ?: "") //可根据具体异常显示具体错误提示 | |||
LogHelper.e(e, "CoroutineScope::") | |||
} finally { | |||
end() | |||
} | |||
} | |||
} | |||
@@ -2,13 +2,17 @@ package cn.org.bjca.trust.push.manager | |||
import android.content.Context | |||
import cn.org.bjca.trust.push.BuildConfig | |||
import cn.org.bjca.trust.push.api.PushService | |||
import cn.org.bjca.trust.push.common.DeviceHelper | |||
import cn.org.bjca.trust.push.common.LogHelper | |||
import cn.org.bjca.trust.push.di.manager.HttpManager | |||
import cn.org.bjca.trust.push.enums.OsType | |||
import cn.org.bjca.trust.push.kit.SdkInterface | |||
import cn.org.bjca.trust.push.message.ImCallback | |||
import cn.org.bjca.trust.push.message.ImManager | |||
import cn.org.bjca.trust.push.message.callback.CallbackListener | |||
import cn.org.bjca.trust.push.message.client.ImConnectOptions | |||
import kotlinx.coroutines.runBlocking | |||
class PushSdkManager : SdkInterface { | |||
@@ -21,6 +25,17 @@ class PushSdkManager : SdkInterface { | |||
private fun registerPush(userId: String) {} | |||
private fun registerIm(userId: String) { | |||
runBlocking { | |||
HttpManager.getApi( | |||
HttpManager.getAppComponent("http://192.168.115.173:8080"), | |||
PushService::class.java | |||
) | |||
.getArticle(42) | |||
}.also { | |||
LogHelper.e(it, "初始化登录") | |||
} | |||
//先关闭已有连接 | |||
if (ImManager.instance.isConnect() || ImManager.instance.isConnecting()) { | |||
ImManager.instance.disConnect() | |||
@@ -10,6 +10,7 @@ import androidx.sqlite.db.SupportSQLiteQueryBuilder | |||
import cn.org.bjca.trust.push.CrashHandler | |||
import cn.org.bjca.trust.push.common.CommonHelper | |||
import cn.org.bjca.trust.push.common.LogHelper | |||
import cn.org.bjca.trust.push.common.SharedPreferencesHelper | |||
import cn.org.bjca.trust.push.db.DbHelper | |||
import cn.org.bjca.trust.push.db.device.Device | |||
import com.huawei.hms.push.HmsMessaging | |||
@@ -28,6 +29,7 @@ class PushProvider : ContentProvider() { | |||
} | |||
override fun onCreate(): Boolean { | |||
context?.let { SharedPreferencesHelper.getPreferences(it) } | |||
// 初始化数据库 | |||
initDb() | |||
//初始化日志收集系统 | |||