Add setting and get config

pull/1/head
FongMi 4 years ago
parent 6dc3f130d0
commit b94665b48a
  1. 1
      app/build.gradle
  2. 6
      app/src/main/AndroidManifest.xml
  3. 44
      app/src/main/java/com/fongmi/bear/App.java
  4. 151
      app/src/main/java/com/fongmi/bear/bean/Config.java
  5. 7
      app/src/main/java/com/fongmi/bear/net/Callback.java
  6. 30
      app/src/main/java/com/fongmi/bear/net/OKHttp.java
  7. 112
      app/src/main/java/com/fongmi/bear/net/SSLSocketFactoryCompat.java
  8. 46
      app/src/main/java/com/fongmi/bear/net/Task.java
  9. 18
      app/src/main/java/com/fongmi/bear/ui/HomeActivity.java
  10. 34
      app/src/main/java/com/fongmi/bear/ui/SettingActivity.java
  11. 28
      app/src/main/java/com/fongmi/bear/ui/SplashActivity.java
  12. 41
      app/src/main/java/com/fongmi/bear/utils/Prefers.java
  13. 5
      app/src/main/res/drawable-nodpi/selector_item.xml
  14. 15
      app/src/main/res/drawable-nodpi/shape_item_normal.xml
  15. 19
      app/src/main/res/drawable-nodpi/shape_item_selected.xml
  16. 60
      app/src/main/res/layout/activity_setting.xml
  17. 4
      app/src/main/res/values-zh-rCN/strings.xml
  18. 2
      app/src/main/res/values-zh-rTW/strings.xml
  19. 2
      app/src/main/res/values/colors.xml
  20. 2
      app/src/main/res/values/strings.xml

@ -43,6 +43,7 @@ dependencies {
implementation 'com.google.android.exoplayer:extension-rtmp:2.17.1'
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'org.jsoup:jsoup:1.14.3'
implementation 'com.orhanobut:logger:2.2.0'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
annotationProcessor 'androidx.room:room-compiler:2.4.2'
}

@ -48,6 +48,7 @@
android:screenOrientation="sensorLandscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
@ -58,5 +59,10 @@
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:screenOrientation="sensorLandscape" />
<activity
android:name=".ui.SettingActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:screenOrientation="sensorLandscape" />
</application>
</manifest>

@ -2,15 +2,45 @@ package com.fongmi.bear;
import android.app.Application;
import com.fongmi.bear.bean.Config;
import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.LogAdapter;
import com.orhanobut.logger.Logger;
import com.orhanobut.logger.PrettyFormatStrategy;
public class App extends Application {
private static App instance;
private static App instance;
private Config config;
public App() {
instance = this;
}
public static App get() {
return instance;
}
public Config getConfig() {
return config;
}
public void setConfig(Config config) {
this.config = config;
}
public App() {
instance = this;
}
@Override
public void onCreate() {
super.onCreate();
Logger.addLogAdapter(getLogAdapter());
}
public static App get() {
return instance;
}
private LogAdapter getLogAdapter() {
return new AndroidLogAdapter(PrettyFormatStrategy.newBuilder().showThreadInfo(false).tag("").build()) {
@Override
public boolean isLoggable(int priority, String tag) {
return BuildConfig.DEBUG;
}
};
}
}

@ -0,0 +1,151 @@
package com.fongmi.bear.bean;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class Config {
@SerializedName("sites")
private List<Sites> sites;
@SerializedName("lives")
private List<Lives> lives;
@SerializedName("parses")
private List<Parses> parses;
@SerializedName("flags")
private List<String> flags;
@SerializedName("spider")
private String spider;
public static Config objectFrom(String str) {
return new Gson().fromJson(str, Config.class);
}
public List<Sites> getSites() {
return sites;
}
public List<Lives> getLives() {
return lives;
}
public List<Parses> getParses() {
return parses;
}
public List<String> getFlags() {
return flags;
}
public String getSpider() {
return spider;
}
public static class Sites {
@SerializedName("key")
private String key;
@SerializedName("name")
private String name;
@SerializedName("type")
private Integer type;
@SerializedName("api")
private String api;
@SerializedName("searchable")
private Integer searchable;
@SerializedName("quickSearch")
private Integer quickSearch;
@SerializedName("filterable")
private Integer filterable;
@SerializedName("ext")
private String ext;
public String getKey() {
return key;
}
public String getName() {
return name;
}
public Integer getType() {
return type;
}
public String getApi() {
return api;
}
public Integer getSearchable() {
return searchable;
}
public Integer getQuickSearch() {
return quickSearch;
}
public Integer getFilterable() {
return filterable;
}
public String getExt() {
return ext;
}
}
public static class Lives {
@SerializedName("group")
private String group;
@SerializedName("channels")
private List<Channels> channels;
public String getGroup() {
return group;
}
public List<Channels> getChannels() {
return channels;
}
public static class Channels {
@SerializedName("name")
private String name;
@SerializedName("urls")
private List<String> urls;
public String getName() {
return name;
}
public List<String> getUrls() {
return urls;
}
}
}
public static class Parses {
@SerializedName("name")
private String name;
@SerializedName("type")
private Integer type;
@SerializedName("url")
private String url;
public String getName() {
return name;
}
public Integer getType() {
return type;
}
public String getUrl() {
return url;
}
}
}

@ -0,0 +1,7 @@
package com.fongmi.bear.net;
public abstract class Callback {
public void onResponse(String result) {
}
}

@ -0,0 +1,30 @@
package com.fongmi.bear.net;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
public class OKHttp {
private final OkHttpClient client;
private static class Loader {
static volatile OKHttp INSTANCE = new OKHttp();
}
public static OKHttp get() {
return Loader.INSTANCE;
}
public OKHttp() {
client = getBuilder().build();
}
private OkHttpClient.Builder getBuilder() {
return new OkHttpClient.Builder().readTimeout(15, TimeUnit.SECONDS).writeTimeout(15, TimeUnit.SECONDS).connectTimeout(15, TimeUnit.SECONDS).retryOnConnectionFailure(true).sslSocketFactory(new SSLSocketFactoryCompat(SSLSocketFactoryCompat.trustAllCert), SSLSocketFactoryCompat.trustAllCert);
}
public OkHttpClient client() {
return client;
}
}

@ -0,0 +1,112 @@
package com.fongmi.bear.net;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
import java.util.LinkedList;
import java.util.List;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
public class SSLSocketFactoryCompat extends SSLSocketFactory {
public static final X509TrustManager trustAllCert = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
};
static String[] protocols = null;
static String[] cipherSuites = null;
static {
try {
SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket();
if (socket != null) {
List<String> protocols = new LinkedList<>();
for (String protocol : socket.getSupportedProtocols()) if (!protocol.toUpperCase().contains("SSL")) protocols.add(protocol);
SSLSocketFactoryCompat.protocols = protocols.toArray(new String[protocols.size()]);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private final SSLSocketFactory defaultFactory;
public SSLSocketFactoryCompat(X509TrustManager tm) {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, (tm != null) ? new X509TrustManager[]{tm} : null, null);
defaultFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
throw new AssertionError(); // The system has no TLS. Just give up.
}
}
private void upgradeTLS(SSLSocket ssl) {
if (protocols != null) {
ssl.setEnabledProtocols(protocols);
}
}
@Override
public String[] getDefaultCipherSuites() {
return cipherSuites;
}
@Override
public String[] getSupportedCipherSuites() {
return cipherSuites;
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
Socket ssl = defaultFactory.createSocket(s, host, port, autoClose);
if (ssl instanceof SSLSocket) upgradeTLS((SSLSocket) ssl);
return ssl;
}
@Override
public Socket createSocket(String host, int port) throws IOException {
Socket ssl = defaultFactory.createSocket(host, port);
if (ssl instanceof SSLSocket) upgradeTLS((SSLSocket) ssl);
return ssl;
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
Socket ssl = defaultFactory.createSocket(host, port, localHost, localPort);
if (ssl instanceof SSLSocket) upgradeTLS((SSLSocket) ssl);
return ssl;
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
Socket ssl = defaultFactory.createSocket(host, port);
if (ssl instanceof SSLSocket) upgradeTLS((SSLSocket) ssl);
return ssl;
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
Socket ssl = defaultFactory.createSocket(address, port, localAddress, localPort);
if (ssl instanceof SSLSocket) upgradeTLS((SSLSocket) ssl);
return ssl;
}
}

@ -0,0 +1,46 @@
package com.fongmi.bear.net;
import android.os.Handler;
import android.os.Looper;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import okhttp3.Request;
import okhttp3.Response;
public class Task {
private final ExecutorService executor;
private final Callback callback;
private final Handler handler;
public static Task create(Callback callback) {
return new Task(callback);
}
public Task(Callback callback) {
this.executor = Executors.newSingleThreadExecutor();
this.handler = new Handler(Looper.getMainLooper());
this.callback = callback;
}
public void run(String url) {
executor.submit(() -> doInBackground(url));
}
private void doInBackground(String url) {
try {
Response res = OKHttp.get().client().newCall(new Request.Builder().url(url).build()).execute();
onPostExecute(res.body().string());
} catch (Exception e) {
onPostExecute("");
}
}
private void onPostExecute(String result) {
handler.post(() -> {
if (callback != null) callback.onResponse(result);
});
}
}

@ -1,15 +1,33 @@
package com.fongmi.bear.ui;
import android.app.Activity;
import android.content.Intent;
import androidx.viewbinding.ViewBinding;
import com.fongmi.bear.App;
import com.fongmi.bear.databinding.ActivityHomeBinding;
public class HomeActivity extends BaseActivity {
private ActivityHomeBinding binding;
public static void newInstance(Activity activity) {
activity.startActivity(new Intent(activity, HomeActivity.class));
activity.finish();
}
@Override
protected ViewBinding getBinding() {
return binding = ActivityHomeBinding.inflate(getLayoutInflater());
}
@Override
protected void initView() {
if (App.get().getConfig() == null) {
SettingActivity.newInstance(this);
} else {
}
}
}

@ -0,0 +1,34 @@
package com.fongmi.bear.ui;
import android.app.Activity;
import android.content.Intent;
import android.widget.Toast;
import androidx.viewbinding.ViewBinding;
import com.fongmi.bear.databinding.ActivitySettingBinding;
import com.fongmi.bear.utils.Prefers;
public class SettingActivity extends BaseActivity {
private ActivitySettingBinding binding;
public static void newInstance(Activity activity) {
activity.startActivity(new Intent(activity, SettingActivity.class));
}
@Override
protected ViewBinding getBinding() {
return binding = ActivitySettingBinding.inflate(getLayoutInflater());
}
@Override
protected void initView() {
binding.url.setText(Prefers.getString("url"));
}
@Override
protected void initEvent() {
binding.config.setOnClickListener(view -> Toast.makeText(SettingActivity.this, "config", Toast.LENGTH_SHORT).show());
}
}

@ -1,12 +1,18 @@
package com.fongmi.bear.ui;
import android.content.Intent;
import android.annotation.SuppressLint;
import android.os.Handler;
import androidx.viewbinding.ViewBinding;
import com.fongmi.bear.App;
import com.fongmi.bear.bean.Config;
import com.fongmi.bear.databinding.ActivitySplashBinding;
import com.fongmi.bear.net.Callback;
import com.fongmi.bear.net.Task;
import com.fongmi.bear.utils.Prefers;
@SuppressLint("CustomSplashScreen")
public class SplashActivity extends BaseActivity {
@Override
@ -16,18 +22,22 @@ public class SplashActivity extends BaseActivity {
@Override
protected void initView() {
loadConfig();
openHome();
String url = Prefers.getString("url");
if (url.isEmpty()) openHome();
else Task.create(getCallback()).run(url);
}
private void loadConfig() {
private Callback getCallback() {
return new Callback() {
@Override
public void onResponse(String result) {
App.get().setConfig(Config.objectFrom(result));
openHome();
}
};
}
private void openHome() {
new Handler().postDelayed(() -> {
startActivity(new Intent(this, HomeActivity.class));
finish();
}, 2000);
new Handler().postDelayed(() -> HomeActivity.newInstance(this), 2000);
}
}

@ -8,35 +8,30 @@ import com.fongmi.bear.App;
public class Prefers {
private static SharedPreferences getPreferences() {
private static SharedPreferences getPrefers() {
return PreferenceManager.getDefaultSharedPreferences(App.get());
}
private static String getString(String key, String defaultValue) {
return getPreferences().getString(key, defaultValue);
public static String getString(String key) {
return getString(key, "");
}
private static void putString(String key, String value) {
getPreferences().edit().putString(key, value).apply();
public static String getString(String key, String defaultValue) {
return getPrefers().getString(key, defaultValue);
}
private static int getInt(String key, int defaultValue) {
return getPreferences().getInt(key, defaultValue);
}
private static void putInt(String key, int value) {
getPreferences().edit().putInt(key, value).apply();
}
private static boolean getBoolean(String key) {
return getBoolean(key, false);
}
private static boolean getBoolean(String key, boolean defaultValue) {
return getPreferences().getBoolean(key, defaultValue);
}
private static void putBoolean(String key, boolean value) {
getPreferences().edit().putBoolean(key, value).apply();
public static void put(String key, Object obj) {
if (obj == null) return;
if (obj instanceof String) {
getPrefers().edit().putString(key, (String) obj).apply();
} else if (obj instanceof Boolean) {
getPrefers().edit().putBoolean(key, (Boolean) obj).apply();
} else if (obj instanceof Float) {
getPrefers().edit().putFloat(key, (Float) obj).apply();
} else if (obj instanceof Integer) {
getPrefers().edit().putInt(key, (Integer) obj).apply();
} else if (obj instanceof Long) {
getPrefers().edit().putLong(key, (Long) obj).apply();
}
}
}

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/shape_item_selected" android:state_focused="true" />
<item android:drawable="@drawable/shape_item_normal" />
</selector>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/trans_20" />
<corners android:radius="4dp" />
<padding
android:bottom="8dp"
android:left="12dp"
android:right="12dp"
android:top="8dp" />
</shape>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/trans_25" />
<corners android:radius="4dp" />
<padding
android:bottom="8dp"
android:left="12dp"
android:right="12dp"
android:top="8dp" />
<stroke
android:width="1dp"
android:color="@color/white" />
</shape>

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/wallpaper_1"
android:orientation="vertical"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/config"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:background="@drawable/selector_item"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:text="@string/setting_url"
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:id="@+id/url"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="18sp"
tools:ignore="NestedWeights"
tools:text="https://" />
</LinearLayout>
<TextView
android:id="@+id/history"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector_item"
android:focusable="true"
android:focusableInTouchMode="true"
android:text="@string/setting_history"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>

@ -1,5 +1,7 @@
<resources>
<string name="app_name">熊爱影视</string>
<string name="setting_url">配置接口</string>
<string name="setting_history">历史配置</string>
</resources>

@ -1,5 +1,7 @@
<resources>
<string name="app_name">熊愛影視</string>
<string name="setting_url">配置接口</string>
<string name="setting_history">歷史配置</string>
</resources>

@ -12,5 +12,7 @@
<color name="grey_900">#212121</color>
<color name="green_400">#66BB6A</color>
<color name="transparent">#00000000</color>
<color name="trans_20">#33000000</color>
<color name="trans_25">#40000000</color>
</resources>

@ -1,5 +1,7 @@
<resources>
<string name="app_name">BearTV</string>
<string name="setting_url">Configure</string>
<string name="setting_history">History</string>
</resources>
Loading…
Cancel
Save