Commit 9e579db1 by 王文龙

Initial commit

parents
*.iml
.gradle
/local.properties
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
.DS_Store
/build
/captures
.externalNativeBuild
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
</code_scheme>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="5">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.offcn.live.tsdm"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
// GreenDao
/**
* schemaVersion--> 指定数据库schema版本号,迁移等操作会用到;
* daoPackage --> dao的包名,包名默认是entity所在的包;
* targetGenDir --> 生成数据库文件的目录;
*/
greendao {
schemaVersion 1
daoPackage 'com.offcn.live.tsdm.greendao.gen'
targetGenDir 'src/main/java'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
compile("com.offcn.live:base:1.1.0-snapshot-1@aar") { transitive = true }
// Retrofit/Rx
compile 'com.google.code.gson:gson:2.8.1'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:converter-scalars:2.3.0'
compile 'com.squareup.okhttp3:okhttp:3.11.0'
compile 'io.reactivex.rxjava2:rxjava:2.1.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.11.0'
// 添加数据库
implementation 'org.greenrobot:greendao:3.2.2'
}
# 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
package tsdm.live.offcn.com.tsdownloadermanager;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.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.getTargetContext();
assertEquals("tsdm.live.offcn.com.tsdownloadermanager", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="tsdm.live.offcn.com.tsdownloadermanager">
<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/AppTheme" />
</manifest>
package com.maning.updatelibrary;
import android.support.v4.content.FileProvider;
/**
* <pre>
* author : maning
* e-mail : xxx@xx
* time : 2018/01/08
* desc : 更新专用FileProvider
* version: 1.0
* </pre>
*/
public class MNUpdateApkFileProvider extends FileProvider {
}
package com.maning.updatelibrary.http;
/**
* @author : maning
* @desc : 文件下载监听
*/
public abstract class AbsFileProgressCallback {
/**
* 下载成功
*/
public abstract void onSuccess(String result);
/**
*/
public abstract void onProgress(long bytesRead, long contentLength, boolean done);
/**
* 下载失败
*/
public abstract void onFailed(String errorMsg);
/**
* 下载开始
*/
public abstract void onStart();
/**
* 下载取消
*/
public abstract void onCancle();
}
package com.maning.updatelibrary.http;
import java.util.Map;
/**
* @author : maning
* @desc : 请求参数相关
*/
public class DownloadModel {
/**
* 请求地址
*/
private String httpUrl;
/**
* 请求头
*/
private Map<String, String> headersMap;
/**
* 请求Tag
*/
private Object tag;
/**
* 下载文件保存的路径
*/
private String downloadPath;
/**
* 文件下载进度
*/
private AbsFileProgressCallback fileProgressCallback;
public String getHttpUrl() {
return httpUrl;
}
public void setHttpUrl(String httpUrl) {
this.httpUrl = httpUrl;
}
public Map<String, String> getHeadersMap() {
return headersMap;
}
public void setHeadersMap(Map<String, String> headersMap) {
this.headersMap = headersMap;
}
public Object getTag() {
return tag;
}
public void setTag(Object tag) {
this.tag = tag;
}
public String getDownloadPath() {
return downloadPath;
}
public void setDownloadPath(String downloadPath) {
this.downloadPath = downloadPath;
}
public AbsFileProgressCallback getFileProgressCallback() {
return fileProgressCallback;
}
public void setFileProgressCallback(AbsFileProgressCallback fileProgressCallback) {
this.fileProgressCallback = fileProgressCallback;
}
}
package com.maning.updatelibrary.http;
import android.os.Handler;
import android.os.Looper;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;
/**
* @author : maning
* @desc : 下载监听所用
*/
public class ProgressResponseBody extends ResponseBody {
private final ResponseBody responseBody;
private final AbsFileProgressCallback progressListener;
private BufferedSource bufferedSource;
private Handler mUIHandler = new Handler(Looper.getMainLooper());
public ProgressResponseBody(ResponseBody mResponseBody, AbsFileProgressCallback mProgressListener) {
responseBody = mResponseBody;
progressListener = mProgressListener;
}
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() {
return responseBody.contentLength();
}
@Override
public BufferedSource source() {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
// read() returns the number of bytes read, or -1 if this source is exhausted.
totalBytesRead += bytesRead != -1 ? bytesRead : 0;
final long finalBytesRead = bytesRead;
mUIHandler.post(new Runnable() {
@Override
public void run() {
progressListener.onProgress(totalBytesRead, responseBody.contentLength(), finalBytesRead == -1);
}
});
return bytesRead;
}
};
}
public interface ProgressListener {
void update(long bytesRead, long contentLength, boolean done);
}
}
package com.maning.updatelibrary.utils;
import android.content.Intent;
/**
* author : maning
* time : 2018/06/04
* desc :
* version: 1.0
*/
public interface ActForResultCallback {
void onActivityResult(int resultCode, Intent data);
}
package com.maning.updatelibrary.utils;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
/**
* author : maning
* time : 2018/06/04
* desc :
* version: 1.0
*/
public class ActResultRequest {
private OnActResultEventDispatcherFragment fragment;
public ActResultRequest(Activity activity) {
fragment = getEventDispatchFragment(activity);
}
private OnActResultEventDispatcherFragment getEventDispatchFragment(Activity activity) {
final FragmentManager fragmentManager = activity.getFragmentManager();
OnActResultEventDispatcherFragment fragment = findEventDispatchFragment(fragmentManager);
if (fragment == null) {
fragment = new OnActResultEventDispatcherFragment();
fragmentManager
.beginTransaction()
.add(fragment, OnActResultEventDispatcherFragment.TAG)
.commitAllowingStateLoss();
fragmentManager.executePendingTransactions();
}
return fragment;
}
private OnActResultEventDispatcherFragment findEventDispatchFragment(FragmentManager manager) {
return (OnActResultEventDispatcherFragment) manager.findFragmentByTag(OnActResultEventDispatcherFragment.TAG);
}
public void startForResult(Intent intent, ActForResultCallback callback) {
fragment.startForResult(intent, callback);
}
}
package com.maning.updatelibrary.utils;
import android.content.Context;
import android.os.Environment;
import java.io.File;
import java.io.IOException;
/**
* author : maning
* time : 2018/03/30
* desc : 工具类
* version: 1.0
*/
public class MNUtils {
/**
* 获取app缓存路径 SDCard/Android/data/你的应用的包名/cache
*
* @param context
* @return
*/
public static String getCachePath(Context context) {
String cachePath;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|| !Environment.isExternalStorageRemovable()) {
//外部存储可用
cachePath = context.getExternalCacheDir().getPath();
} else {
//外部存储不可用
cachePath = context.getCacheDir().getPath();
}
return cachePath;
}
//参照:APK放到data/data/下面提示解析失败 (http://blog.csdn.net/lonely_fireworks/article/details/27693073)
public static void changeApkFileMode(File file) {
try {
//apk放在缓存目录时,低版本安装提示权限错误,需要对父级目录和apk文件添加权限
String cmd1 = "chmod 777 " + file.getParent();
Runtime.getRuntime().exec(cmd1);
String cmd = "chmod 777 " + file.getAbsolutePath();
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.maning.updatelibrary.utils;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.util.SparseArray;
/**
* author : maning
* time : 2018/06/04
* desc :
* version: 1.0
*/
public class OnActResultEventDispatcherFragment extends Fragment {
public static final String TAG = "on_act_result_event_dispatcher";
private SparseArray<ActForResultCallback> mCallbacks = new SparseArray<>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
public void startForResult(Intent intent, ActForResultCallback callback) {
mCallbacks.put(callback.hashCode(), callback);
startActivityForResult(intent, callback.hashCode());
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ActForResultCallback callback = mCallbacks.get(requestCode);
mCallbacks.remove(requestCode);
if (callback != null) {
callback.onActivityResult(resultCode, data);
}
}
}
package com.offcn.live.tsdm.api;
/**
* 接口地址
*
* @author wangwenlong
* @date 2018/7/26
*/
class APIConstants {
/**
* 正式地址
*/
private static final String HOST = "https://api.live.offcncloud.com/";
// private static final String HOST = "https://live.offcncloud.com/api/";
/**
* 协议版本号
*/
private static final String VERSION = "v1/";
/**
* 请求地址
*/
public static final String BASE = HOST;
/**
* 用户相关接口
*/
interface LiveUser {
// 登录
String userLogin = VERSION + "users";
}
/**
* 播放相关接口
*/
interface LiveVideo {
// 获取播放地址
String videoUrl = VERSION + "pull";
// 获取是否有在推流
String stream = VERSION + "room_stream";
// 获取播放信息
String roomInfo = VERSION + "room_info";
// 获取单个用户信息
String userInfo = VERSION + "users/{uuid}";
// 获取老师信息
String teacherInfo = VERSION + "get_teacher_info";
// 获取文件列表
String files = VERSION + "room_files";
// 获取提问列表
String questions = VERSION + "questions";
// 获取公告列表
String announce = VERSION + "announce?title=te";
// 发言间隔时间
String bannedTime = VERSION + "banned_time";
// 房间状态
String roomState = VERSION + "room_status";
// 运营信息
String operationInfo = VERSION + "operation_info";
// 意见反馈
String suggest = VERSION + "suggest";
// 意见反馈
String suggest_type = VERSION + "suggest_type";
// 配置:服务器地址
String config = VERSION + "get_config";
// 回放:回放信息
String playback = "user/on_demand";
// 答题弹窗:是否答过此题
String answerOrNot = VERSION + "answer/{qNo}";
// 答题弹窗:获取当前房间正在进行的答题
String answerCur = VERSION + "topic";
// 评价:提交
String evaluatePost = VERSION + "appraise_add";
// 评价:是否评价过
String evaluateOrNot = VERSION + "appraise_check";
// 评价:是否放弃过
String evaluateGiveUp = VERSION + "appraise_giveup";
// 评价:点击评价按钮
String evaluateClick = VERSION + "appraise_click";
// 签到:是否签到过
String signInCheck = VERSION + "sign_check";
// 签到:上报签到
String signIn = VERSION + "sign";
// 签到:当前房间是否正在签到
String signInNow = VERSION + "sign_in";
// 抽奖:当前房间是否正在抽奖
String lotteryNow = VERSION + "lottery";
// 聊天记录:历史聊天记录
String chatHistory = "user/getChats";
// 回放:是否存在回放视频
String playbackExist = VERSION + "record_check/{account}";
// 连麦:是否允许举手
String handsEnabled = VERSION + "check_handsup";
// 连麦:是否正在连麦
String handsGoing = VERSION + "check_calling";
// 连麦:告知服务器连麦失败
String handsFailed2Server = VERSION + "set_call";
}
}
package com.offcn.live.tsdm.api;
import android.content.Context;
import android.os.Build;
import com.jyall.base.util.DeviceUtils;
import com.offcn.live.tsdm.util.ZGLCacheManager;
import com.offcn.live.tsdm.util.ZGLUserInfoHelper;
import java.util.HashMap;
import tsdm.live.offcn.com.tsdownloadermanager.BuildConfig;
/**
* 通用网络请求头部信息
*
* @author wangwenlong
* @date 2018/8/2
*/
class CommonHeaders {
/**
* 通用的http请求头 header
*/
private static HashMap<String, String> sCommonHeaders = new HashMap<>();
/**
* 设置通用的http请求的header
*/
public static HashMap<String, String> getCommonHeaders(Context context) {
//此处可以添加通用头
sCommonHeaders.put("zgl-clienttype", "ZgLiveStudent");
sCommonHeaders.put("zgl-clientversion", BuildConfig.VERSION_NAME);
sCommonHeaders.put("zgl-systemtype", "Android");
sCommonHeaders.put("zgl-systemversion", String.valueOf(Build.VERSION.RELEASE));
sCommonHeaders.put("zgl-phonekey", DeviceUtils.getUniqueId(context));
sCommonHeaders.put("zgl-phonetype", DeviceUtils.getPhoneType());
sCommonHeaders.put("zgl-resolution", DeviceUtils.getScreenWidth(context) + "x" + DeviceUtils.getScreenHeight(context));
HashMap<String, String> signMap = new HashMap<>(sCommonHeaders);
// 目前只存在 access_token
if (ZGLUserInfoHelper.getInstance().isLogin()) {
signMap.put("Authorization", "Bearer " + ZGLCacheManager.getInstance(context).getUserInfo().access_token);
} else {
signMap.remove("Authorization");
}
return signMap;
}
}
package com.offcn.live.api;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
/**
* https证书 <b>出处不详</b>
* @author wangwenlong
* @date 2018/8/2
*/
public class HttpsCert {
public static class SSLParams {
public SSLSocketFactory sSLSocketFactory;
public X509TrustManager trustManager;
}
public static SSLParams getSslSocketFactory(InputStream[] certificates, InputStream bksFile, String password) {
SSLParams sslParams = new SSLParams();
try {
TrustManager[] trustManagers = prepareTrustManager(certificates);
KeyManager[] keyManagers = prepareKeyManager(bksFile, password);
SSLContext sslContext = SSLContext.getInstance("TLS");
X509TrustManager trustManager = null;
if (trustManagers != null) {
trustManager = new MyTrustManager(chooseTrustManager(trustManagers));
} else {
trustManager = new UnSafeTrustManager();
}
sslContext.init(keyManagers, new TrustManager[]{trustManager}, null);
sslParams.sSLSocketFactory = sslContext.getSocketFactory();
sslParams.trustManager = trustManager;
return sslParams;
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
} catch (KeyManagementException e) {
throw new AssertionError(e);
} catch (KeyStoreException e) {
throw new AssertionError(e);
}
}
private class UnSafeHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
private static class UnSafeTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}
private static TrustManager[] prepareTrustManager(InputStream... certificates) {
if (certificates == null || certificates.length <= 0) return null;
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
int index = 0;
for (InputStream certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
try {
if (certificate != null)
certificate.close();
} catch (IOException e)
{
}
}
TrustManagerFactory trustManagerFactory = null;
trustManagerFactory = TrustManagerFactory.
getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
return trustManagers;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static KeyManager[] prepareKeyManager(InputStream bksFile, String password) {
try {
if (bksFile == null || password == null) return null;
KeyStore clientKeyStore = KeyStore.getInstance("BKS");
clientKeyStore.load(bksFile, password.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(clientKeyStore, password.toCharArray());
return keyManagerFactory.getKeyManagers();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers) {
for (TrustManager trustManager : trustManagers) {
if (trustManager instanceof X509TrustManager) {
return (X509TrustManager) trustManager;
}
}
return null;
}
private static class MyTrustManager implements X509TrustManager {
private X509TrustManager defaultTrustManager;
private X509TrustManager localTrustManager;
public MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException {
TrustManagerFactory var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
var4.init((KeyStore) null);
defaultTrustManager = chooseTrustManager(var4.getTrustManagers());
this.localTrustManager = localTrustManager;
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
try {
defaultTrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException ce) {
localTrustManager.checkServerTrusted(chain, authType);
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
}
package com.offcn.live.tsdm.api;
import com.offcn.live.tsdm.api.network.ResponseBean;
import com.offcn.live.tsdm.bean.ZGLPlaybackBean;
import com.offcn.live.tsdm.bean.ZGLSignInBean;
import java.util.List;
import java.util.Map;
import io.reactivex.Observable;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;
import retrofit2.http.Url;
/**
* 接口实现
*
* @author wangwenlong
* @date 2018/8/2
*/
public interface LiveApi {
/**
* 获取回放信息
*
* @return
*/
@FormUrlEncoded
@POST(APIConstants.LiveVideo.playback)
Observable<Response<ResponseBean<ZGLPlaybackBean>>> getPlaybackInfo(@FieldMap Map<String, String> map);
/**
* 获取回放视频位于服务器的文件
*
* @param url
* @return
*/
@GET
Call<ResponseBody> getPlaybackInfoFile(@Url String url);
/**
* 检测是否在回放视频
*
* @return
*/
@GET(APIConstants.LiveVideo.playbackExist)
Observable<Response<ResponseBean<ZGLSignInBean>>> getPlaybackExist(@Path("account") String account);
}
package com.offcn.live.tsdm.api;
import android.content.Context;
import com.google.gson.Gson;
import com.jyall.base.log.LogUtils;
import com.offcn.live.tsdm.api.LiveApi;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
/**
* http 工具类
*
* @author wangwenlong
* @date 2018/7/27
*/
public class RetrofitManager {
private static final String TAG = RetrofitManager.class.getSimpleName();
// 超时时间
private static final long TIME_OUT = 1000 * 30;
private static LiveApi liveApi;
private static volatile Retrofit retrofit;
private static OkHttpClient okHttpClient;
private static Context mContext;
public static LiveApi getInstance(Context context) {
if (retrofit == null) {
synchronized (RetrofitManager.class) {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(APIConstants.BASE)
.addConverterFactory(GsonConverterFactory.create(new Gson()))
.addConverterFactory(ScalarsConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
.client(getClient())
.build();
liveApi = retrofit.create(LiveApi.class);
mContext = context;
}
}
}
return liveApi;
}
private static OkHttpClient getClient() {
if (okHttpClient == null) {
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder()
.connectTimeout(TIME_OUT, TimeUnit.MILLISECONDS)
.readTimeout(TIME_OUT, TimeUnit.MILLISECONDS)
.addInterceptor(getCommonHeaderInterceptor())
.addInterceptor(getLogInterceptor());
// 添加 https 信任
com.offcn.live.api.HttpsCert.SSLParams sslParams = com.offcn.live.api.HttpsCert.getSslSocketFactory(null, null, null);
okHttpClientBuilder.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager);
okHttpClient = okHttpClientBuilder.build();
}
return okHttpClient;
}
/**
* 打印 retrofit 日志
*/
private static HttpLoggingInterceptor getLogInterceptor() {
return new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
LogUtils.e(TAG, "retrofit = " + message);
}
}).setLevel(HttpLoggingInterceptor.Level.BODY);
}
/**
* 增加通用的请求头
*/
private static Interceptor getCommonHeaderInterceptor() {
return new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
// 增加拦截器,用以加入 http 头部请求信息
Request.Builder builder = chain.request().newBuilder();
builder.headers(Headers.of(CommonHeaders.getCommonHeaders(mContext)));
Request request = builder.build();
return chain.proceed(request);
}
};
}
}
package com.offcn.live.tsdm.api.network;
import android.support.annotation.NonNull;
/**
* 通用接口返回处理
*
* @author wangwenlong
* @date 2018/7/27
*/
class CommonCodeHelper {
static <T> boolean processCode(@NonNull ResponseBean<T> errorResponseBean) {
switch (errorResponseBean.code) {
// 登录失效
case ResponseCode.ACCESS_TOKEN_INVALID:
return true;
// 强制升级
case ResponseCode.UPDATE_FORCE:
return true;
case ResponseCode.NOT_FOUND:
break;
}
return false;
}
}
package com.offcn.live.tsdm.api.network;
import android.content.Context;
import android.text.TextUtils;
import com.jyall.base.util.CommonUtils;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import retrofit2.Response;
import tsdm.live.offcn.com.tsdownloadermanager.R;
/**
* RxJava 请求回调类
*
* @author wangwenlong
* @date 2018/7/27
*/
public abstract class ProgressSubscriber<T> implements Observer<Response<ResponseBean<T>>> {
private Context mContext;
private ProgressSubscriber() {
}
public ProgressSubscriber(Context context) {
this.mContext = context;
}
/**
* 不要重写此方法,这个是给Rx调用
*/
@Override
@Deprecated
public void onError(Throwable e) {
try {
// 若不重写 onError(int, string) 方法,则直接 toast 提示
if (!onError(999, e.getMessage())) {
CommonUtils.showToast(mContext, e.getMessage());
}
} catch (Exception exception) {
CommonUtils.showToast(mContext, R.string.server_error);
}
}
@Override
public void onComplete() {
}
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Response<ResponseBean<T>> response) {
if (response.errorBody() != null) {
// 外部错误。若不重写 onError 则直接 toast 错误提示
if (!onError(response.code(), response.message())) {
CommonUtils.showToast(mContext, response.message());
}
} else {
// 内部处理
ResponseBean responseBean = response.body();
if (responseBean != null) {
if (responseBean.code == 200) {
onResponse((T) responseBean.data);
} else {
// 是否有通用接口返回处理
if (!CommonCodeHelper.processCode(responseBean)) {
if (!onError(responseBean.code, responseBean.msg)) {
if (!TextUtils.isEmpty(responseBean.msg)) {
CommonUtils.showToast(mContext, responseBean.msg);
}
}
}
}
} else {
// 返回为空
onResponse(null);
}
}
}
/**
* 请求返回错误
*
* @return 如果处理了这个错误信息,返回true, 如果不处理这个错误,而是直接走统一处理(弹Toast),那么就返回false
*/
public boolean onError(int code, String error) {
return false;
}
public abstract void onResponse(T result);
}
package com.offcn.live.tsdm.api.network;
/**
* 请求返回实体
*
* @author wangwenlong
* @date 2018/7/26
*/
public class ResponseBean<T> {
public int code;
public String msg;
public T data;
@Override
public String toString() {
return "code: " + code + ", msg: " + msg;
}
}
package com.offcn.live.tsdm.api.network;
/**
* 请求返回码
*
* @author wangwenlong
* @date 2018/7/26
*/
class ResponseCode {
/**
* 业务正确
*/
public static final int SUCCESS = 0;
/**
* 业务错误
*/
public static final int BAD_REQUEST = 400;
/**
* 404
*/
public static final int NOT_FOUND = 404;
/**
* 强制更新
*/
public static final int UPDATE_FORCE = 400009000;
/**
* token过期 需要强制登录
*/
public static final int ACCESS_TOKEN_INVALID = 400001045;
/**
* 其它错误
*/
public static final int OTHER = 9999;
}
package com.offcn.live.tsdm.bean;
import com.offcn.live.tsdm.ZGLDownLoaderManager;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Unique;
import java.io.File;
/**
* 视频下载实体
*
* @author wangwenlong
* @date 2019/1/21
*/
@Entity
public class ZGLDownLoaderBean {
@Id
private Long id;
@Unique
private String code; // 下载文件的唯一标识,房间口令
private String roomName; // 房间名称
private String downloadPath; // 下载地址
private int status; // 下载文件的当前状态,默认为0未下载成功 1已下载 2下载中 3暂停中
private String progress; // 下载进度
private String extensionId; // 扩展参数:外部提供的id,与code一一对应
@Generated(hash = 1512665455)
public ZGLDownLoaderBean(Long id, String code, String roomName,
String downloadPath, int status, String progress, String extensionId) {
this.id = id;
this.code = code;
this.roomName = roomName;
this.downloadPath = downloadPath;
this.status = status;
this.progress = progress;
this.extensionId = extensionId;
}
@Generated(hash = 304727487)
public ZGLDownLoaderBean() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
public String getRoomName() {
return this.roomName;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
public String getDownloadPath() {
return this.downloadPath;
}
public void setDownloadPath(String downloadPath) {
this.downloadPath = downloadPath;
}
public int getStatus() {
return this.status;
}
public ZGLDownloadStatusEnum getStatusEnum() {
ZGLDownloadStatusEnum statusEnum = ZGLDownloadStatusEnum.NOT;
switch (status) {
case 0:
statusEnum = ZGLDownloadStatusEnum.NOT;
break;
case 1:
statusEnum = ZGLDownloadStatusEnum.DOWNLOADED;
break;
case 2:
statusEnum = ZGLDownloadStatusEnum.DOWNLOADING;
break;
case 3:
statusEnum = ZGLDownloadStatusEnum.PAUSED;
break;
}
return statusEnum;
}
public void setStatus(int status) {
this.status = status;
}
public boolean isLocalM3u8Exist() {
String localM3u8Path = downloadPath + ZGLDownLoaderManager.NAME_M3U8;
File localM3u8File = new File(localM3u8Path);
if (localM3u8File.isFile() && localM3u8File.exists()) {
return true;
}
return false;
}
public boolean isDownloaded() {
return 1 == status;
}
public boolean isDownloading() {
return 2 == status;
}
public boolean isPaused() {
return 3 == status;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ZGLDownLoaderBean) {
return ((ZGLDownLoaderBean) obj).code.equals(this.code);
}
return false;
}
public String getProgress() {
return this.progress;
}
public void setProgress(String progress) {
this.progress = progress;
}
public String getExtensionId() {
return this.extensionId;
}
public void setExtensionId(String extensionId) {
this.extensionId = extensionId;
}
}
package com.offcn.live.tsdm.bean;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
/**
* 视频下载的ts片实体
*
* @author wangwenlong
* @date 2019/1/21
*/
@Entity
public class ZGLDownLoaderFileBean {
@Id
private Long id;
private String code; // 房间口令标识
private String downloadUrl; // 下载地址
private int status; // 0未下载 1已下载
private String extensionId; // 扩展id
@Generated(hash = 1619330277)
public ZGLDownLoaderFileBean(Long id, String code, String downloadUrl, int status,
String extensionId) {
this.id = id;
this.code = code;
this.downloadUrl = downloadUrl;
this.status = status;
this.extensionId = extensionId;
}
@Generated(hash = 226575781)
public ZGLDownLoaderFileBean() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
public String getDownloadUrl() {
return this.downloadUrl;
}
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
public int getStatus() {
return this.status;
}
public void setStatus(int status) {
this.status = status;
}
public String getName() {
return downloadUrl.substring(downloadUrl.lastIndexOf("/"), downloadUrl.length());
}
public String getExtensionId() {
return this.extensionId;
}
public void setExtensionId(String extensionId) {
this.extensionId = extensionId;
}
}
package com.offcn.live.tsdm.bean;
public enum ZGLDownloadStatusEnum {
NOT("不存在"),
DOWNLOADED("下载完成"),
DOWNLOADING("下载中"),
PAUSED("暂停中");
ZGLDownloadStatusEnum(String s) {
}
}
package com.offcn.live.tsdm.bean;
import java.util.List;
/**
* 回放视频实体
*
* @author wangwenlong
* @date 2019/1/21
*/
public class ZGLPlayBackVideoBean {
public String code; // 房间口令
public List<String> urls; // 各个ts片的下载地址
}
package com.offcn.live.tsdm.bean;
import android.text.TextUtils;
/**
* 回放信息
*
* @author wangwenlong
* @date 2018/11/7
*/
public class ZGLPlaybackBean {
public String room_name;
public String vod; // 文件内容带有 http 的 ts 片的文件地址,用来下载
public String vodName; // 文件内容不带 http 的 ts 片的文件地址,用来本地播放
public String sqlite; // 聊天历史记录sqlite文件下载地址
/**
* 获取回放地址,ts地址里面带有http
*
* @return
*/
public String getServerUrl() {
if (TextUtils.isEmpty(vod)) {
return "";
}
if (vod.startsWith("http:") || vod.startsWith("https:")) {
return vod;
}
return "http:" + vod;
}
/**
* 获取回放地址,ts地址不带http
*
* @return
*/
public String getLocalUrl() {
return vodName;
}
/**
* 获取历史聊天记录sqlite文件
*
* @return
*/
public String getSqliteUrl() {
return sqlite;
}
}
package com.offcn.live.tsdm.bean;
/**
* 签到实体
*
* @author wangwenlong
* @date 2019/1/14
*/
public class ZGLSignInBean {
public boolean active; // true 已经签到过
}
package com.offcn.live.tsdm.bean;
/**
* 用户信息实体
*
* @author wangwenlong
* @date 2018/7/27
*/
public class ZGLUserBean {
public String userName;
public String userPassword;
public String access_token;
public String uuid;
public ZGLUserBean(String access_token) {
this.access_token = access_token;
}
public ZGLUserBean(String access_token, String uuid) {
this.access_token = access_token;
this.uuid = uuid;
}
public ZGLUserBean(String access_token, String uuid, String userPassword) {
this.userPassword = userPassword;
this.access_token = access_token;
this.uuid = uuid;
}
}
package com.offcn.live.tsdm.greendao.gen;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;
import org.greenrobot.greendao.AbstractDaoMaster;
import org.greenrobot.greendao.database.StandardDatabase;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.database.DatabaseOpenHelper;
import org.greenrobot.greendao.identityscope.IdentityScopeType;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* Master of DAO (schema version 1): knows all DAOs.
*/
public class DaoMaster extends AbstractDaoMaster {
public static final int SCHEMA_VERSION = 1;
/** Creates underlying database table using DAOs. */
public static void createAllTables(Database db, boolean ifNotExists) {
ZGLDownLoaderBeanDao.createTable(db, ifNotExists);
ZGLDownLoaderFileBeanDao.createTable(db, ifNotExists);
}
/** Drops underlying database table using DAOs. */
public static void dropAllTables(Database db, boolean ifExists) {
ZGLDownLoaderBeanDao.dropTable(db, ifExists);
ZGLDownLoaderFileBeanDao.dropTable(db, ifExists);
}
/**
* WARNING: Drops all table on Upgrade! Use only during development.
* Convenience method using a {@link DevOpenHelper}.
*/
public static DaoSession newDevSession(Context context, String name) {
Database db = new DevOpenHelper(context, name).getWritableDb();
DaoMaster daoMaster = new DaoMaster(db);
return daoMaster.newSession();
}
public DaoMaster(SQLiteDatabase db) {
this(new StandardDatabase(db));
}
public DaoMaster(Database db) {
super(db, SCHEMA_VERSION);
registerDaoClass(ZGLDownLoaderBeanDao.class);
registerDaoClass(ZGLDownLoaderFileBeanDao.class);
}
public DaoSession newSession() {
return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);
}
public DaoSession newSession(IdentityScopeType type) {
return new DaoSession(db, type, daoConfigMap);
}
/**
* Calls {@link #createAllTables(Database, boolean)} in {@link #onCreate(Database)} -
*/
public static abstract class OpenHelper extends DatabaseOpenHelper {
public OpenHelper(Context context, String name) {
super(context, name, SCHEMA_VERSION);
}
public OpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory, SCHEMA_VERSION);
}
@Override
public void onCreate(Database db) {
Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION);
createAllTables(db, false);
}
}
/** WARNING: Drops all table on Upgrade! Use only during development. */
public static class DevOpenHelper extends OpenHelper {
public DevOpenHelper(Context context, String name) {
super(context, name);
}
public DevOpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
dropAllTables(db, true);
onCreate(db);
}
}
}
package com.offcn.live.tsdm.greendao.gen;
import java.util.Map;
import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.AbstractDaoSession;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.identityscope.IdentityScopeType;
import org.greenrobot.greendao.internal.DaoConfig;
import com.offcn.live.tsdm.bean.ZGLDownLoaderBean;
import com.offcn.live.tsdm.bean.ZGLDownLoaderFileBean;
import com.offcn.live.tsdm.greendao.gen.ZGLDownLoaderBeanDao;
import com.offcn.live.tsdm.greendao.gen.ZGLDownLoaderFileBeanDao;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* {@inheritDoc}
*
* @see org.greenrobot.greendao.AbstractDaoSession
*/
public class DaoSession extends AbstractDaoSession {
private final DaoConfig zGLDownLoaderBeanDaoConfig;
private final DaoConfig zGLDownLoaderFileBeanDaoConfig;
private final ZGLDownLoaderBeanDao zGLDownLoaderBeanDao;
private final ZGLDownLoaderFileBeanDao zGLDownLoaderFileBeanDao;
public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>
daoConfigMap) {
super(db);
zGLDownLoaderBeanDaoConfig = daoConfigMap.get(ZGLDownLoaderBeanDao.class).clone();
zGLDownLoaderBeanDaoConfig.initIdentityScope(type);
zGLDownLoaderFileBeanDaoConfig = daoConfigMap.get(ZGLDownLoaderFileBeanDao.class).clone();
zGLDownLoaderFileBeanDaoConfig.initIdentityScope(type);
zGLDownLoaderBeanDao = new ZGLDownLoaderBeanDao(zGLDownLoaderBeanDaoConfig, this);
zGLDownLoaderFileBeanDao = new ZGLDownLoaderFileBeanDao(zGLDownLoaderFileBeanDaoConfig, this);
registerDao(ZGLDownLoaderBean.class, zGLDownLoaderBeanDao);
registerDao(ZGLDownLoaderFileBean.class, zGLDownLoaderFileBeanDao);
}
public void clear() {
zGLDownLoaderBeanDaoConfig.clearIdentityScope();
zGLDownLoaderFileBeanDaoConfig.clearIdentityScope();
}
public ZGLDownLoaderBeanDao getZGLDownLoaderBeanDao() {
return zGLDownLoaderBeanDao;
}
public ZGLDownLoaderFileBeanDao getZGLDownLoaderFileBeanDao() {
return zGLDownLoaderFileBeanDao;
}
}
package com.offcn.live.tsdm.greendao.gen;
import android.database.Cursor;
import android.database.sqlite.SQLiteStatement;
import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.Property;
import org.greenrobot.greendao.internal.DaoConfig;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.database.DatabaseStatement;
import com.offcn.live.tsdm.bean.ZGLDownLoaderBean;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* DAO for table "ZGLDOWN_LOADER_BEAN".
*/
public class ZGLDownLoaderBeanDao extends AbstractDao<ZGLDownLoaderBean, Long> {
public static final String TABLENAME = "ZGLDOWN_LOADER_BEAN";
/**
* Properties of entity ZGLDownLoaderBean.<br/>
* Can be used for QueryBuilder and for referencing column names.
*/
public static class Properties {
public final static Property Id = new Property(0, Long.class, "id", true, "_id");
public final static Property Code = new Property(1, String.class, "code", false, "CODE");
public final static Property RoomName = new Property(2, String.class, "roomName", false, "ROOM_NAME");
public final static Property DownloadPath = new Property(3, String.class, "downloadPath", false, "DOWNLOAD_PATH");
public final static Property Status = new Property(4, int.class, "status", false, "STATUS");
public final static Property Progress = new Property(5, String.class, "progress", false, "PROGRESS");
public final static Property ExtensionId = new Property(6, String.class, "extensionId", false, "EXTENSION_ID");
}
public ZGLDownLoaderBeanDao(DaoConfig config) {
super(config);
}
public ZGLDownLoaderBeanDao(DaoConfig config, DaoSession daoSession) {
super(config, daoSession);
}
/** Creates the underlying database table. */
public static void createTable(Database db, boolean ifNotExists) {
String constraint = ifNotExists? "IF NOT EXISTS ": "";
db.execSQL("CREATE TABLE " + constraint + "\"ZGLDOWN_LOADER_BEAN\" (" + //
"\"_id\" INTEGER PRIMARY KEY ," + // 0: id
"\"CODE\" TEXT UNIQUE ," + // 1: code
"\"ROOM_NAME\" TEXT," + // 2: roomName
"\"DOWNLOAD_PATH\" TEXT," + // 3: downloadPath
"\"STATUS\" INTEGER NOT NULL ," + // 4: status
"\"PROGRESS\" TEXT," + // 5: progress
"\"EXTENSION_ID\" TEXT);"); // 6: extensionId
}
/** Drops the underlying database table. */
public static void dropTable(Database db, boolean ifExists) {
String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"ZGLDOWN_LOADER_BEAN\"";
db.execSQL(sql);
}
@Override
protected final void bindValues(DatabaseStatement stmt, ZGLDownLoaderBean entity) {
stmt.clearBindings();
Long id = entity.getId();
if (id != null) {
stmt.bindLong(1, id);
}
String code = entity.getCode();
if (code != null) {
stmt.bindString(2, code);
}
String roomName = entity.getRoomName();
if (roomName != null) {
stmt.bindString(3, roomName);
}
String downloadPath = entity.getDownloadPath();
if (downloadPath != null) {
stmt.bindString(4, downloadPath);
}
stmt.bindLong(5, entity.getStatus());
String progress = entity.getProgress();
if (progress != null) {
stmt.bindString(6, progress);
}
String extensionId = entity.getExtensionId();
if (extensionId != null) {
stmt.bindString(7, extensionId);
}
}
@Override
protected final void bindValues(SQLiteStatement stmt, ZGLDownLoaderBean entity) {
stmt.clearBindings();
Long id = entity.getId();
if (id != null) {
stmt.bindLong(1, id);
}
String code = entity.getCode();
if (code != null) {
stmt.bindString(2, code);
}
String roomName = entity.getRoomName();
if (roomName != null) {
stmt.bindString(3, roomName);
}
String downloadPath = entity.getDownloadPath();
if (downloadPath != null) {
stmt.bindString(4, downloadPath);
}
stmt.bindLong(5, entity.getStatus());
String progress = entity.getProgress();
if (progress != null) {
stmt.bindString(6, progress);
}
String extensionId = entity.getExtensionId();
if (extensionId != null) {
stmt.bindString(7, extensionId);
}
}
@Override
public Long readKey(Cursor cursor, int offset) {
return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);
}
@Override
public ZGLDownLoaderBean readEntity(Cursor cursor, int offset) {
ZGLDownLoaderBean entity = new ZGLDownLoaderBean( //
cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1), // code
cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2), // roomName
cursor.isNull(offset + 3) ? null : cursor.getString(offset + 3), // downloadPath
cursor.getInt(offset + 4), // status
cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5), // progress
cursor.isNull(offset + 6) ? null : cursor.getString(offset + 6) // extensionId
);
return entity;
}
@Override
public void readEntity(Cursor cursor, ZGLDownLoaderBean entity, int offset) {
entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));
entity.setCode(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));
entity.setRoomName(cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2));
entity.setDownloadPath(cursor.isNull(offset + 3) ? null : cursor.getString(offset + 3));
entity.setStatus(cursor.getInt(offset + 4));
entity.setProgress(cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5));
entity.setExtensionId(cursor.isNull(offset + 6) ? null : cursor.getString(offset + 6));
}
@Override
protected final Long updateKeyAfterInsert(ZGLDownLoaderBean entity, long rowId) {
entity.setId(rowId);
return rowId;
}
@Override
public Long getKey(ZGLDownLoaderBean entity) {
if(entity != null) {
return entity.getId();
} else {
return null;
}
}
@Override
public boolean hasKey(ZGLDownLoaderBean entity) {
return entity.getId() != null;
}
@Override
protected final boolean isEntityUpdateable() {
return true;
}
}
package com.offcn.live.tsdm.greendao.gen;
import android.database.Cursor;
import android.database.sqlite.SQLiteStatement;
import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.Property;
import org.greenrobot.greendao.internal.DaoConfig;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.database.DatabaseStatement;
import com.offcn.live.tsdm.bean.ZGLDownLoaderFileBean;
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/**
* DAO for table "ZGLDOWN_LOADER_FILE_BEAN".
*/
public class ZGLDownLoaderFileBeanDao extends AbstractDao<ZGLDownLoaderFileBean, Long> {
public static final String TABLENAME = "ZGLDOWN_LOADER_FILE_BEAN";
/**
* Properties of entity ZGLDownLoaderFileBean.<br/>
* Can be used for QueryBuilder and for referencing column names.
*/
public static class Properties {
public final static Property Id = new Property(0, Long.class, "id", true, "_id");
public final static Property Code = new Property(1, String.class, "code", false, "CODE");
public final static Property DownloadUrl = new Property(2, String.class, "downloadUrl", false, "DOWNLOAD_URL");
public final static Property Status = new Property(3, int.class, "status", false, "STATUS");
public final static Property ExtensionId = new Property(4, String.class, "extensionId", false, "EXTENSION_ID");
}
public ZGLDownLoaderFileBeanDao(DaoConfig config) {
super(config);
}
public ZGLDownLoaderFileBeanDao(DaoConfig config, DaoSession daoSession) {
super(config, daoSession);
}
/** Creates the underlying database table. */
public static void createTable(Database db, boolean ifNotExists) {
String constraint = ifNotExists? "IF NOT EXISTS ": "";
db.execSQL("CREATE TABLE " + constraint + "\"ZGLDOWN_LOADER_FILE_BEAN\" (" + //
"\"_id\" INTEGER PRIMARY KEY ," + // 0: id
"\"CODE\" TEXT," + // 1: code
"\"DOWNLOAD_URL\" TEXT," + // 2: downloadUrl
"\"STATUS\" INTEGER NOT NULL ," + // 3: status
"\"EXTENSION_ID\" TEXT);"); // 4: extensionId
}
/** Drops the underlying database table. */
public static void dropTable(Database db, boolean ifExists) {
String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"ZGLDOWN_LOADER_FILE_BEAN\"";
db.execSQL(sql);
}
@Override
protected final void bindValues(DatabaseStatement stmt, ZGLDownLoaderFileBean entity) {
stmt.clearBindings();
Long id = entity.getId();
if (id != null) {
stmt.bindLong(1, id);
}
String code = entity.getCode();
if (code != null) {
stmt.bindString(2, code);
}
String downloadUrl = entity.getDownloadUrl();
if (downloadUrl != null) {
stmt.bindString(3, downloadUrl);
}
stmt.bindLong(4, entity.getStatus());
String extensionId = entity.getExtensionId();
if (extensionId != null) {
stmt.bindString(5, extensionId);
}
}
@Override
protected final void bindValues(SQLiteStatement stmt, ZGLDownLoaderFileBean entity) {
stmt.clearBindings();
Long id = entity.getId();
if (id != null) {
stmt.bindLong(1, id);
}
String code = entity.getCode();
if (code != null) {
stmt.bindString(2, code);
}
String downloadUrl = entity.getDownloadUrl();
if (downloadUrl != null) {
stmt.bindString(3, downloadUrl);
}
stmt.bindLong(4, entity.getStatus());
String extensionId = entity.getExtensionId();
if (extensionId != null) {
stmt.bindString(5, extensionId);
}
}
@Override
public Long readKey(Cursor cursor, int offset) {
return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);
}
@Override
public ZGLDownLoaderFileBean readEntity(Cursor cursor, int offset) {
ZGLDownLoaderFileBean entity = new ZGLDownLoaderFileBean( //
cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1), // code
cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2), // downloadUrl
cursor.getInt(offset + 3), // status
cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4) // extensionId
);
return entity;
}
@Override
public void readEntity(Cursor cursor, ZGLDownLoaderFileBean entity, int offset) {
entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));
entity.setCode(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));
entity.setDownloadUrl(cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2));
entity.setStatus(cursor.getInt(offset + 3));
entity.setExtensionId(cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4));
}
@Override
protected final Long updateKeyAfterInsert(ZGLDownLoaderFileBean entity, long rowId) {
entity.setId(rowId);
return rowId;
}
@Override
public Long getKey(ZGLDownLoaderFileBean entity) {
if(entity != null) {
return entity.getId();
} else {
return null;
}
}
@Override
public boolean hasKey(ZGLDownLoaderFileBean entity) {
return entity.getId() != null;
}
@Override
protected final boolean isEntityUpdateable() {
return true;
}
}
package com.offcn.live.tsdm.util;
import android.content.Context;
import com.offcn.live.tsdm.bean.ZGLUserBean;
/**
* 缓存类,比如用户信息,或其它配置
*
* @author wangwenlong
* @date 2018/10/17
*/
public class ZGLCacheManager {
private static volatile ZGLCacheManager INSTANCE;
private Context mContext;
private ZGLCacheManager(Context context) {
this.mContext = context.getApplicationContext();
}
public static ZGLCacheManager getInstance(Context context) {
if (INSTANCE == null) {
synchronized (ZGLCacheManager.class) {
if (INSTANCE == null) {
INSTANCE = new ZGLCacheManager(context);
}
}
}
return INSTANCE;
}
// 用户信息
private ZGLUserBean mUserInfo;
/**
* 统一清除缓存方法,退出登录时调用
*/
public void clear() {
setUserInfo(null);
ZGLSPUtils.clear(mContext);
}
/**
* 设置用户信息
*/
public void setUserInfo(ZGLUserBean userInfo) {
this.mUserInfo = userInfo;
ZGLUserInfoHelper.getInstance().saveUserInfo(mContext, userInfo);
}
public ZGLUserBean getUserInfo() {
if (null == mUserInfo) {
mUserInfo = ZGLUserInfoHelper.getInstance().getUserInfo(mContext);
}
return mUserInfo;
}
}
package com.offcn.live.tsdm.util;
import com.google.gson.Gson;
import java.util.List;
/**
* 解析工具类
*
* @author wangwenlong
* @date 2018/7/27
*/
public class ZGLParseUtils {
/**
* 解析成对象
*
* @param source
* @param clazz
* @param <T>
* @return
*/
public static <T> T parseObjectByGson(String source, Class<T> clazz) {
return new Gson().fromJson(source, clazz);
}
/**
* 解析成数组
*
* @param source
* @param clazz
* @param <T>
* @return
*/
public static <T> List<T> parseArrayByGson(String source, Class<T> clazz) {
try {
return (List<T>) new Gson().fromJson(source, clazz);
} catch (Exception e) {
return null;
}
}
/**
* 解析成 json 字符串
*
* @param object
* @return
*/
public static String parseToJson(Object object) {
return new Gson().toJson(object);
}
}
package com.offcn.live.tsdm.util;
import android.content.Context;
import android.text.TextUtils;
import com.jyall.base.util.SharedPrefUtils;
import com.offcn.live.tsdm.bean.ZGLUserBean;
/**
* SP工具类
*
* @author wangwenlong
* @date 2018/7/27
*/
public class ZGLSPUtils {
// 用户信息
private static final String USER_INFO = "user_info";
// 清空,注意有需要保留的要提前取出来再清空,再重新赋值
public static void clear(Context context) {
setUserInfo(context, "");
}
// 用户信息
public static void setUserInfo(Context context, ZGLUserBean userInfo) {
SharedPrefUtils.setParam(context, USER_INFO, userInfo);
}
public static void setUserInfo(Context context, String userInfo) {
SharedPrefUtils.setParam(context, USER_INFO, userInfo);
}
public static ZGLUserBean getUserInfo(Context context) {
String result = String.valueOf(SharedPrefUtils.getParam(context, USER_INFO, ""));
if (TextUtils.isEmpty(result)) {
return null;
} else {
return ZGLParseUtils.parseObjectByGson(result, ZGLUserBean.class);
}
}
}
package com.offcn.live.tsdm.util;
import android.content.Context;
import android.text.TextUtils;
import com.offcn.live.tsdm.bean.ZGLUserBean;
/**
* 用户信息工具类
*
* @author wangwenlong
* @date 2018/8/2
*/
public class ZGLUserInfoHelper {
private static final ZGLUserInfoHelper userInfoHelper = new ZGLUserInfoHelper();
private ZGLUserBean mUserInfo;
private boolean isLogin;
public static ZGLUserInfoHelper getInstance() {
return userInfoHelper;
}
/**
* 是否已经登录
*
* @return
*/
public boolean isLogin() {
return isLogin;
}
/**
* 获取token
*
* @return
*/
public String getToken() {
return mUserInfo.access_token;
}
private boolean isNull() {
return mUserInfo == null || TextUtils.isEmpty(mUserInfo.access_token);
}
/**
* 保存用户信息
*/
public void saveUserInfo(Context context, ZGLUserBean mUserInfo) {
this.mUserInfo = mUserInfo;
ZGLSPUtils.setUserInfo(context, mUserInfo);
isLogin = !isNull();
}
public ZGLUserBean getUserInfo(Context context) {
if (null == mUserInfo) {
mUserInfo = ZGLSPUtils.getUserInfo(context);
}
return mUserInfo;
}
public void deleteUserInfo(Context context) {
this.mUserInfo = null;
isLogin = false;
ZGLSPUtils.setUserInfo(context, "");
}
}
package com.offcn.live.tsdm.util;
import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.text.TextUtils;
import android.view.View;
import com.jyall.base.log.LogUtils;
import com.jyall.base.util.ValidateUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import okhttp3.ResponseBody;
/**
* 本项目中用到的工具类
*
* @author wangwenlong
* @date 2018/8/18
*/
public class ZGLUtils {
/**
* 获取文件夹大小
*
* @param file File实例
* @return long
*/
public static long getFolderSize(File file) {
long size = 0;
try {
File[] fileList = file.listFiles();
for (int i = 0; i < fileList.length; i++) {
if (fileList[i].isFile() && fileList[i].getName().endsWith(".ts")) {
size = size + fileList[i].length();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return size;
}
/**
* 格式化文件大小
*
* @param size
* @return
*/
public static String getFormattedSize(long size) {
if (size <= 0) return "0";
final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
return new DecimalFormat("###0.##").format(size / Math.pow(1024, digitGroups)) + units[digitGroups];
}
/**
* 写文件入SD卡
*
* @param futureStudioIconFile
* @param body
* @return
*/
public static boolean writeResponseBodyToDisk(File futureStudioIconFile, ResponseBody body) {
try {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
inputStream = body.byteStream();
outputStream = new FileOutputStream(futureStudioIconFile);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
LogUtils.e("", "file download: " + fileSizeDownloaded + " of " + fileSize);
}
outputStream.flush();
return true;
} catch (Exception e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (Exception e) {
return false;
}
}
}
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
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="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
</vector>
<?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" />
</adaptive-icon>
\ No newline at end of file
<?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" />
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
<resources>
<string name="app_name">TsDownloaderManager</string>
<string name="net_off" >暂无网络</string>
<string name="server_error">服务器异常</string>
</resources>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
package tsdm.live.offcn.com.tsdownloadermanager;
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);
}
}
\ No newline at end of file
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
maven {
url 'http://s2.wawaps.com:8081/nexus/content/repositories/thirdparty/'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven {
url 'http://s2.wawaps.com:8081/nexus/content/repositories/thirdparty/'
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Wed Jun 26 09:38:45 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
include ':app'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment