@ -1 +0,0 @@ |
|||||||
/build |
|
@ -1,65 +0,0 @@ |
|||||||
apply plugin: 'com.android.application' |
|
||||||
|
|
||||||
apply plugin: 'kotlin-android' |
|
||||||
|
|
||||||
apply plugin: 'kotlin-android-extensions' |
|
||||||
|
|
||||||
android { |
|
||||||
compileSdkVersion 28 |
|
||||||
defaultConfig { |
|
||||||
applicationId "com.example.open_nsfw_android" |
|
||||||
minSdkVersion 19 |
|
||||||
targetSdkVersion 28 |
|
||||||
versionCode 5 |
|
||||||
versionName "1.3.2" |
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" |
|
||||||
} |
|
||||||
buildTypes { |
|
||||||
debug { |
|
||||||
minifyEnabled false //开启混淆 |
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' |
|
||||||
} |
|
||||||
} |
|
||||||
aaptOptions { |
|
||||||
noCompress "tflite" |
|
||||||
} |
|
||||||
|
|
||||||
//添加 |
|
||||||
compileOptions { |
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8 |
|
||||||
targetCompatibility JavaVersion.VERSION_1_8 |
|
||||||
} |
|
||||||
// To inline the bytecode built with JVM target 1.8 into |
|
||||||
// bytecode that is being built with JVM target 1.6. (e.g. navArgs) |
|
||||||
|
|
||||||
|
|
||||||
kotlinOptions { |
|
||||||
jvmTarget = "1.8" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
dependencies { |
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs') |
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" |
|
||||||
implementation 'com.android.support:appcompat-v7:28.0.0' |
|
||||||
implementation 'com.android.support.constraint:constraint-layout:1.1.3' |
|
||||||
implementation 'com.android.support:design:28.0.0' |
|
||||||
implementation 'android.arch.navigation:navigation-fragment-ktx:1.0.0' |
|
||||||
implementation 'android.arch.navigation:navigation-ui-ktx:1.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' |
|
||||||
|
|
||||||
|
|
||||||
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50' |
|
||||||
implementation 'com.github.LuckSiege.PictureSelector:picture_library:2.2.5' |
|
||||||
implementation 'com.camerakit:camerakit:1.0.0-beta3.11' |
|
||||||
implementation 'com.camerakit:jpegkit:0.1.0' |
|
||||||
// implementation project(path: ':nsfw') |
|
||||||
// implementation project(path: ':OpenNSFW') |
|
||||||
implementation 'com.github.devzwy:open_nsfw_android:1.3.2' |
|
||||||
|
|
||||||
implementation 'com.squareup.okhttp3:okhttp:4.7.2' |
|
||||||
implementation "org.koin:koin-android:2.1.5" |
|
||||||
implementation 'com.google.code.gson:gson:2.8.6' |
|
||||||
} |
|
@ -1,20 +0,0 @@ |
|||||||
# 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. |
|
@ -1,22 +0,0 @@ |
|||||||
package com.example.open_nsfw_android |
|
||||||
|
|
||||||
import android.support.test.InstrumentationRegistry |
|
||||||
import android.support.test.runner.AndroidJUnit4 |
|
||||||
import org.junit.Assert.assertEquals |
|
||||||
import org.junit.Test |
|
||||||
import org.junit.runner.RunWith |
|
||||||
|
|
||||||
/** |
|
||||||
* Instrumented test, which will execute on an Android device. |
|
||||||
* |
|
||||||
* See [testing documentation](http://d.android.com/tools/testing). |
|
||||||
*/ |
|
||||||
@RunWith(AndroidJUnit4::class) |
|
||||||
class ExampleInstrumentedTest { |
|
||||||
@Test |
|
||||||
fun useAppContext() { |
|
||||||
// Context of the app under test. |
|
||||||
val appContext = InstrumentationRegistry.getTargetContext() |
|
||||||
assertEquals("com.example.open_nsfw_android", appContext.packageName) |
|
||||||
} |
|
||||||
} |
|
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 30 KiB |
@ -1,32 +0,0 @@ |
|||||||
package com.example.open_nsfw_android |
|
||||||
|
|
||||||
import android.app.Application |
|
||||||
import com.example.open_nsfw_android.view.mModules |
|
||||||
import com.zwy.opennsfw.core.Classifier |
|
||||||
import okhttp3.OkHttp |
|
||||||
import okhttp3.OkHttpClient |
|
||||||
import okhttp3.Request |
|
||||||
import org.koin.android.ext.koin.androidContext |
|
||||||
import org.koin.android.ext.koin.androidFileProperties |
|
||||||
import org.koin.android.ext.koin.androidLogger |
|
||||||
import org.koin.core.context.startKoin |
|
||||||
import org.koin.core.logger.PrintLogger |
|
||||||
import org.koin.core.qualifier.qualifier |
|
||||||
import org.koin.dsl.module |
|
||||||
|
|
||||||
class DemoApplication : Application() { |
|
||||||
override fun onCreate() { |
|
||||||
super.onCreate() |
|
||||||
|
|
||||||
startKoin { |
|
||||||
modules(mModules) |
|
||||||
} |
|
||||||
Classifier.Build() |
|
||||||
.context(this) //必须调用 否则会有异常抛出 |
|
||||||
// .isOpenGPU(true)//默认不开启GPU加速 部分机型开启会奔溃,自行选择,默认false |
|
||||||
// .numThreads(10) //分配的线程数 根据手机配置设置,默认1 |
|
||||||
.build() |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,51 +0,0 @@ |
|||||||
package com.example.open_nsfw_android.util |
|
||||||
|
|
||||||
import android.annotation.SuppressLint |
|
||||||
import android.support.v4.content.ContextCompat |
|
||||||
import android.widget.ImageView |
|
||||||
import android.widget.RelativeLayout |
|
||||||
import android.widget.TextView |
|
||||||
import com.bumptech.glide.Glide |
|
||||||
import com.chad.library.adapter.base.BaseQuickAdapter |
|
||||||
import com.chad.library.adapter.base.BaseViewHolder |
|
||||||
import com.example.open_nsfw_android.R |
|
||||||
import getNsfwScore |
|
||||||
import kotlinx.android.synthetic.main.activity_main2.* |
|
||||||
import java.math.RoundingMode |
|
||||||
import java.text.DecimalFormat |
|
||||||
|
|
||||||
class MainAdapter(nsfwList: List<MyNsfwBean>?) : |
|
||||||
BaseQuickAdapter<MyNsfwBean, BaseViewHolder>(R.layout.main_item, nsfwList) { |
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n") |
|
||||||
override fun convert(helper: BaseViewHolder, item2: MyNsfwBean) { |
|
||||||
|
|
||||||
val textView = helper.getView<TextView>(R.id.tv_text) |
|
||||||
val imageView = helper.getView<ImageView>(R.id.iv) |
|
||||||
val view = helper.getView<RelativeLayout>(R.id.view) |
|
||||||
|
|
||||||
var color = ContextCompat.getColor(mContext, R.color.nsfw1) |
|
||||||
when (item2.nsfw) { |
|
||||||
in 0.0..0.2 -> { |
|
||||||
color = ContextCompat.getColor(mContext, R.color.nsfw3) |
|
||||||
} |
|
||||||
in 0.2..0.8 -> { |
|
||||||
color = ContextCompat.getColor(mContext, R.color.nsfw2) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
val floatFormat = DecimalFormat("0.0000000") |
|
||||||
floatFormat.roundingMode = RoundingMode.HALF_UP |
|
||||||
|
|
||||||
textView.text = |
|
||||||
"\n适宜度(非色情程度):${floatFormat.format(item2.sfw * 100)}%\n\n不适宜度(涉黄程度):${floatFormat.format( |
|
||||||
item2.nsfw * 100 |
|
||||||
)}%" |
|
||||||
if (item2.imgUrl != null && item2.imgUrl.isNotBlank()) { |
|
||||||
Glide.with(imageView).load(item2.imgUrl).into(imageView) |
|
||||||
} else { |
|
||||||
imageView.setImageBitmap(item2.bitmap) |
|
||||||
} |
|
||||||
view.setBackgroundColor(color) |
|
||||||
} |
|
||||||
} |
|
@ -1,77 +0,0 @@ |
|||||||
package com.example.open_nsfw_android.util |
|
||||||
|
|
||||||
import android.content.Context |
|
||||||
import android.content.pm.PackageManager |
|
||||||
|
|
||||||
object PackageUtils { |
|
||||||
/** |
|
||||||
* 获取版本名称 |
|
||||||
* |
|
||||||
* @param context 上下文 |
|
||||||
* |
|
||||||
* @return 版本名称 |
|
||||||
*/ |
|
||||||
fun getVersionName(context: Context): String? { |
|
||||||
|
|
||||||
//获取包管理器 |
|
||||||
val pm = context.packageManager |
|
||||||
//获取包信息 |
|
||||||
try { |
|
||||||
val packageInfo = |
|
||||||
pm.getPackageInfo(context.packageName, 0) |
|
||||||
//返回版本号 |
|
||||||
return packageInfo.versionName |
|
||||||
} catch (e: PackageManager.NameNotFoundException) { |
|
||||||
e.printStackTrace() |
|
||||||
} |
|
||||||
return null |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取版本号 |
|
||||||
* |
|
||||||
* @param context 上下文 |
|
||||||
* |
|
||||||
* @return 版本号 |
|
||||||
*/ |
|
||||||
fun getVersionCode(context: Context): Int { |
|
||||||
|
|
||||||
//获取包管理器 |
|
||||||
val pm = context.packageManager |
|
||||||
//获取包信息 |
|
||||||
try { |
|
||||||
val packageInfo = |
|
||||||
pm.getPackageInfo(context.packageName, 0) |
|
||||||
//返回版本号 |
|
||||||
return packageInfo.versionCode |
|
||||||
} catch (e: PackageManager.NameNotFoundException) { |
|
||||||
e.printStackTrace() |
|
||||||
} |
|
||||||
return 0 |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取App的名称 |
|
||||||
* |
|
||||||
* @param context 上下文 |
|
||||||
* |
|
||||||
* @return 名称 |
|
||||||
*/ |
|
||||||
fun getAppName(context: Context): String? { |
|
||||||
val pm = context.packageManager |
|
||||||
//获取包信息 |
|
||||||
try { |
|
||||||
val packageInfo = |
|
||||||
pm.getPackageInfo(context.packageName, 0) |
|
||||||
//获取应用 信息 |
|
||||||
val applicationInfo = packageInfo.applicationInfo |
|
||||||
//获取albelRes |
|
||||||
val labelRes = applicationInfo.labelRes |
|
||||||
//返回App的名称 |
|
||||||
return context.resources.getString(labelRes) |
|
||||||
} catch (e: PackageManager.NameNotFoundException) { |
|
||||||
e.printStackTrace() |
|
||||||
} |
|
||||||
return null |
|
||||||
} |
|
||||||
} |
|
@ -1,11 +0,0 @@ |
|||||||
package com.example.open_nsfw_android.util |
|
||||||
|
|
||||||
import android.graphics.Bitmap |
|
||||||
|
|
||||||
data class MyNsfwBean( |
|
||||||
var sfw: Float, |
|
||||||
var nsfw: Float, |
|
||||||
val path: String, |
|
||||||
val bitmap: Bitmap?, |
|
||||||
val imgUrl: String? = "" |
|
||||||
) |
|
@ -1,198 +0,0 @@ |
|||||||
package com.example.open_nsfw_android.view |
|
||||||
|
|
||||||
import android.annotation.SuppressLint |
|
||||||
import android.graphics.BitmapFactory |
|
||||||
import android.graphics.ImageFormat |
|
||||||
import android.graphics.Rect |
|
||||||
import android.graphics.YuvImage |
|
||||||
import android.hardware.Camera |
|
||||||
import android.os.Bundle |
|
||||||
import android.support.v7.app.AppCompatActivity |
|
||||||
import android.view.SurfaceHolder |
|
||||||
import android.view.Window |
|
||||||
import android.view.WindowManager |
|
||||||
import android.widget.Toast |
|
||||||
import com.example.open_nsfw_android.R |
|
||||||
import getNsfwScore |
|
||||||
import kotlinx.android.synthetic.main.cameraaty.* |
|
||||||
import java.io.ByteArrayOutputStream |
|
||||||
import java.io.IOException |
|
||||||
import java.util.* |
|
||||||
|
|
||||||
class CameraActivity : AppCompatActivity(), SurfaceHolder.Callback, Camera.PreviewCallback { |
|
||||||
|
|
||||||
lateinit var mSurfaceHolder: SurfaceHolder |
|
||||||
lateinit var mCamera: Camera |
|
||||||
private var cameraId = 1 |
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) { |
|
||||||
super.onCreate(savedInstanceState) |
|
||||||
requestWindowFeature(Window.FEATURE_NO_TITLE); |
|
||||||
window.setFlags( |
|
||||||
WindowManager.LayoutParams.FLAG_FULLSCREEN, |
|
||||||
WindowManager.LayoutParams.FLAG_FULLSCREEN |
|
||||||
) |
|
||||||
setContentView(R.layout.cameraaty) |
|
||||||
|
|
||||||
mSurfaceHolder = surfaceView.holder |
|
||||||
mSurfaceHolder.addCallback(this) |
|
||||||
iv_back.setOnClickListener { |
|
||||||
try { |
|
||||||
mCamera.setPreviewCallback(null) |
|
||||||
mCamera.stopPreview() |
|
||||||
mCamera.release() |
|
||||||
} catch (e: Exception) { |
|
||||||
} |
|
||||||
finish() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
override fun onBackPressed() { |
|
||||||
try { |
|
||||||
mCamera.setPreviewCallback(null) |
|
||||||
mCamera.stopPreview() |
|
||||||
mCamera.release() |
|
||||||
} catch (e: Exception) { |
|
||||||
} |
|
||||||
super.onBackPressed() |
|
||||||
} |
|
||||||
|
|
||||||
//翻转摄像机 |
|
||||||
fun cameraSwitch() { |
|
||||||
cameraId = if (cameraId == 1) 0 else 1 |
|
||||||
mCamera.setPreviewCallback(null) |
|
||||||
mCamera.stopPreview() |
|
||||||
mCamera.release() |
|
||||||
CameraOpen() |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
//打开照相机 |
|
||||||
fun CameraOpen() { |
|
||||||
try { |
|
||||||
//打开摄像机 |
|
||||||
mCamera = Camera.open(cameraId) |
|
||||||
mCamera.setDisplayOrientation(90) |
|
||||||
//绑定Surface并开启预览 |
|
||||||
mCamera.setPreviewDisplay(mSurfaceHolder) |
|
||||||
val parameters = mCamera.parameters |
|
||||||
// val focusModes = parameters.supportedFocusModes |
|
||||||
// val size = calculatePerfectSize( |
|
||||||
// parameters.supportedPreviewSizes, |
|
||||||
// 1024, 1024 |
|
||||||
// ) |
|
||||||
// surfaceView.layoutParams.width = size!!.width |
|
||||||
// surfaceView.layoutParams.height = size.height |
|
||||||
// |
|
||||||
// parameters.setPreviewSize(size.width, size.height) |
|
||||||
parameters.focusMode = "fixed" |
|
||||||
mCamera.parameters = parameters |
|
||||||
mCamera.startPreview() |
|
||||||
mCamera.setPreviewCallback(this) |
|
||||||
iv_change.setOnClickListener { cameraSwitch() } |
|
||||||
} catch (e: IOException) { |
|
||||||
mCamera.release() |
|
||||||
Toast.makeText(this, "视图创建失败", Toast.LENGTH_SHORT).show() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) { |
|
||||||
val parameters = mCamera.parameters |
|
||||||
mCamera.parameters = parameters |
|
||||||
mCamera.startPreview() |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 计算最完美的Size |
|
||||||
* @param sizes |
|
||||||
* @param expectWidth |
|
||||||
* @param expectHeight |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
fun calculatePerfectSize( |
|
||||||
sizes: List<Camera.Size>, expectWidth: Int, |
|
||||||
expectHeight: Int |
|
||||||
): Camera.Size? { |
|
||||||
sortList(sizes) // 根据宽度进行排序 |
|
||||||
var result = sizes[0] |
|
||||||
var widthOrHeight = false // 判断存在宽或高相等的Size |
|
||||||
// 辗转计算宽高最接近的值 |
|
||||||
for (size in sizes) { |
|
||||||
// 如果宽高相等,则直接返回 |
|
||||||
if (size.width == expectWidth && size.height == expectHeight) { |
|
||||||
result = size |
|
||||||
break |
|
||||||
} |
|
||||||
// 仅仅是宽度相等,计算高度最接近的size |
|
||||||
if (size.width == expectWidth) { |
|
||||||
widthOrHeight = true |
|
||||||
if (Math.abs(result.height - expectHeight) |
|
||||||
> Math.abs(size.height - expectHeight) |
|
||||||
) { |
|
||||||
result = size |
|
||||||
} |
|
||||||
} else if (size.height == expectHeight) { |
|
||||||
widthOrHeight = true |
|
||||||
if (Math.abs(result.width - expectWidth) |
|
||||||
> Math.abs(size.width - expectWidth) |
|
||||||
) { |
|
||||||
result = size |
|
||||||
} |
|
||||||
} else if (!widthOrHeight) { |
|
||||||
if (Math.abs(result.width - expectWidth) |
|
||||||
> Math.abs(size.width - expectWidth) |
|
||||||
&& Math.abs(result.height - expectHeight) |
|
||||||
> Math.abs(size.height - expectHeight) |
|
||||||
) { |
|
||||||
result = size |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return result |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 排序 |
|
||||||
* @param list |
|
||||||
*/ |
|
||||||
private fun sortList(list: List<Camera.Size>) { |
|
||||||
Collections.sort(list, object : Comparator<Camera.Size?> { |
|
||||||
|
|
||||||
override fun compare(pre: Camera.Size?, after: Camera.Size?): Int { |
|
||||||
if (pre!!.width > after!!.width) { |
|
||||||
return 1 |
|
||||||
} else if (pre.width < after.width) { |
|
||||||
return -1 |
|
||||||
} |
|
||||||
return 0 |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
override fun surfaceDestroyed(holder: SurfaceHolder?) { |
|
||||||
mCamera.stopPreview() |
|
||||||
mCamera.release() |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
override fun surfaceCreated(holder: SurfaceHolder?) { |
|
||||||
CameraOpen() |
|
||||||
} |
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n") |
|
||||||
override fun onPreviewFrame(data: ByteArray?, camera: Camera?) { |
|
||||||
mCamera.addCallbackBuffer(data) |
|
||||||
|
|
||||||
val size = mCamera.parameters.previewSize; |
|
||||||
val image = YuvImage(data, ImageFormat.NV21, size.width, size.height, null); |
|
||||||
val stream = ByteArrayOutputStream() |
|
||||||
image.compressToJpeg(Rect(0, 0, size.width, size.height), 80, stream) |
|
||||||
val bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size()) |
|
||||||
bmp.getNsfwScore() |
|
||||||
val spText = bmp.getNsfwScore().toString().split(",") |
|
||||||
textView.text = spText[0] + "\n" + spText[1] |
|
||||||
stream.close() |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,49 +0,0 @@ |
|||||||
package com.example.open_nsfw_android.view |
|
||||||
|
|
||||||
import android.graphics.BitmapFactory |
|
||||||
import android.os.Bundle |
|
||||||
import android.support.v7.app.AppCompatActivity |
|
||||||
import android.widget.Toast |
|
||||||
import com.bumptech.glide.Glide |
|
||||||
import com.example.open_nsfw_android.R |
|
||||||
import getNsfwScore |
|
||||||
|
|
||||||
import kotlinx.android.synthetic.main.activity_main2.* |
|
||||||
import java.math.RoundingMode |
|
||||||
import java.text.DecimalFormat |
|
||||||
|
|
||||||
class Main2Activity : AppCompatActivity() { |
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) { |
|
||||||
super.onCreate(savedInstanceState) |
|
||||||
setContentView(R.layout.activity_main2) |
|
||||||
bt.setOnClickListener { |
|
||||||
if (et.text.toString().isNotBlank()) { |
|
||||||
Thread(Runnable { |
|
||||||
try { |
|
||||||
val file = Glide.with(this) |
|
||||||
.load(et.text.toString()) |
|
||||||
.downloadOnly(120, 120).get() |
|
||||||
val nsfwBean = file.getNsfwScore() |
|
||||||
runOnUiThread { |
|
||||||
iv.setImageBitmap(BitmapFactory.decodeFile(file.path)) |
|
||||||
val floatFormat = DecimalFormat("0.0000000") |
|
||||||
floatFormat.roundingMode = RoundingMode.HALF_UP |
|
||||||
|
|
||||||
tv.text = |
|
||||||
"\n适宜度(非色情程度):${floatFormat.format(nsfwBean.sfw * 100)}%\n\n不适宜度(涉黄程度):${floatFormat.format( |
|
||||||
nsfwBean.nsfw * 100 |
|
||||||
)}%" |
|
||||||
} |
|
||||||
} catch (e: Exception) { |
|
||||||
runOnUiThread { |
|
||||||
Toast.makeText(this, "图片载入失败,请重试", 0).show() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
}).start() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -1,258 +0,0 @@ |
|||||||
package com.example.open_nsfw_android.view |
|
||||||
|
|
||||||
import android.Manifest |
|
||||||
import android.annotation.SuppressLint |
|
||||||
import android.content.Intent |
|
||||||
import android.content.pm.PackageManager |
|
||||||
import android.graphics.BitmapFactory |
|
||||||
import android.os.Bundle |
|
||||||
import android.support.v4.app.ActivityCompat |
|
||||||
import android.support.v4.content.ContextCompat |
|
||||||
import android.support.v7.app.AppCompatActivity |
|
||||||
import android.support.v7.widget.LinearLayoutManager |
|
||||||
import android.widget.Toast |
|
||||||
import com.bumptech.glide.Glide |
|
||||||
import com.example.open_nsfw_android.R |
|
||||||
import com.example.open_nsfw_android.util.MainAdapter |
|
||||||
import com.example.open_nsfw_android.util.MyNsfwBean |
|
||||||
import com.example.open_nsfw_android.util.PackageUtils |
|
||||||
import com.google.gson.Gson |
|
||||||
import com.google.gson.reflect.TypeToken |
|
||||||
import com.luck.picture.lib.PictureSelector |
|
||||||
import com.luck.picture.lib.config.PictureConfig |
|
||||||
import com.luck.picture.lib.config.PictureMimeType |
|
||||||
import com.luck.picture.lib.entity.LocalMedia |
|
||||||
import getNsfwScore |
|
||||||
import kotlinx.android.synthetic.main.activity_main.* |
|
||||||
import okhttp3.* |
|
||||||
import org.koin.android.ext.android.inject |
|
||||||
import java.io.File |
|
||||||
import java.io.IOException |
|
||||||
import java.lang.reflect.Type |
|
||||||
|
|
||||||
class MainAty : AppCompatActivity() { |
|
||||||
|
|
||||||
var selectList: List<LocalMedia>? = null |
|
||||||
|
|
||||||
lateinit var mMainAdapter: MainAdapter |
|
||||||
|
|
||||||
val httpClient: OkHttpClient by inject() |
|
||||||
|
|
||||||
val gson: Gson by inject() |
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) { |
|
||||||
super.onCreate(savedInstanceState) |
|
||||||
setContentView(R.layout.activity_main) |
|
||||||
|
|
||||||
init() |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n") |
|
||||||
fun init() { |
|
||||||
//检测权限 |
|
||||||
checkPermissions() |
|
||||||
//初始化适配器 |
|
||||||
initAdapter() |
|
||||||
//识别assets目录 |
|
||||||
bt_sc_assets.setOnClickListener { assetsListSc() } |
|
||||||
//选择相册进行扫描 |
|
||||||
bt_sc_from_other.setOnClickListener { selectImgFromD(0x01) } |
|
||||||
//跳转网络图片识别页面 |
|
||||||
bt_sc_from_internet.setOnClickListener { |
|
||||||
startActivity( |
|
||||||
Intent( |
|
||||||
this, |
|
||||||
Main2Activity::class.java |
|
||||||
) |
|
||||||
) |
|
||||||
} |
|
||||||
//实时扫描 |
|
||||||
bt_sc_from_cam.setOnClickListener { scCamera() } |
|
||||||
//调用Api获取测试图片 |
|
||||||
bt_sc_from_api.setOnClickListener { |
|
||||||
httpClient.newCall(Request.Builder().get().url(GetImageListURL).build()) |
|
||||||
.enqueue(object : Callback { |
|
||||||
override fun onFailure(call: Call, e: IOException) { |
|
||||||
runOnUiThread { |
|
||||||
Toast.makeText(this@MainAty, "请求失败,请重试", Toast.LENGTH_SHORT).show() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
override fun onResponse(call: Call, response: Response) { |
|
||||||
val str = response.body?.string() |
|
||||||
val type: Type? = object : TypeToken<List<NSFWImage>>() {}.type |
|
||||||
val list = gson.fromJson<List<NSFWImage>>(str, type) |
|
||||||
val l = ArrayList<MyNsfwBean>() |
|
||||||
//迭代数据并获取涉黄程度 |
|
||||||
list.forEach { |
|
||||||
System.out.println(it) |
|
||||||
val file = Glide.with(this@MainAty) |
|
||||||
.load(it.imgUrl) |
|
||||||
.downloadOnly(120, 120).get() |
|
||||||
val nsfwBean = file.getNsfwScore() |
|
||||||
//填充数据到适配器 |
|
||||||
l.add( |
|
||||||
MyNsfwBean( |
|
||||||
sfw = nsfwBean.sfw, |
|
||||||
nsfw = nsfwBean.nsfw, |
|
||||||
path = it.createTime, |
|
||||||
imgUrl = it.imgUrl, |
|
||||||
bitmap = null |
|
||||||
) |
|
||||||
) |
|
||||||
} |
|
||||||
runOnUiThread { |
|
||||||
mMainAdapter.setNewData(null) |
|
||||||
mMainAdapter.setNewData(l) |
|
||||||
} |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
bt_upload.setOnClickListener { |
|
||||||
selectImgFromD(0x02) |
|
||||||
} |
|
||||||
tv_version.text = "当前版本号:${PackageUtils.getVersionName(this)}" |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 实时扫描 |
|
||||||
*/ |
|
||||||
private fun scCamera() { |
|
||||||
|
|
||||||
startActivity(Intent(this, CameraActivity::class.java)) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
private fun initAdapter() { |
|
||||||
mMainAdapter = MainAdapter(null) |
|
||||||
rv.layoutManager = LinearLayoutManager(this) |
|
||||||
rv.adapter = mMainAdapter |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 相册选择 |
|
||||||
*/ |
|
||||||
private fun selectImgFromD(requestCode: Int) { |
|
||||||
PictureSelector.create(this) |
|
||||||
.openGallery(PictureMimeType.ofImage())//全部.ofAll()、图片.、视频.ofVideo()、音频.ofAudio() |
|
||||||
.maxSelectNum(20)// 最大图片选择数量 int |
|
||||||
.minSelectNum(1)// 最小选择数量 int |
|
||||||
.imageSpanCount(3)// 每行显示个数 int |
|
||||||
.selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选 or PictureConfig.SINGLE |
|
||||||
.previewImage(true)// 是否可预览图片 true or false |
|
||||||
.isCamera(false)// 是否显示拍照按钮 true or false |
|
||||||
.isZoomAnim(true)// 图片列表点击 缩放效果 默认true |
|
||||||
.selectionMedia(selectList) |
|
||||||
.sizeMultiplier(0.5f)// glide 加载图片大小 0~1之间 如设置 .glideOverride()无效 |
|
||||||
.previewEggs(true)// 预览图片时 是否增强左右滑动图片体验(图片滑动一半即可看到上一张是否选中) true or false |
|
||||||
.forResult(requestCode);//结果回调onActivityResult code } |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 扫描assets目录 |
|
||||||
*/ |
|
||||||
private fun assetsListSc() { |
|
||||||
mMainAdapter.setNewData(null) |
|
||||||
Toast.makeText(this, "请稍等...", Toast.LENGTH_LONG).show() |
|
||||||
Thread(Runnable { |
|
||||||
resources.assets.list("img")?.forEach { |
|
||||||
val bitmap = BitmapFactory.decodeStream(resources.assets.open("img/$it")) |
|
||||||
val nsfwScore = bitmap.getNsfwScore() |
|
||||||
addDataToAdapter( |
|
||||||
MyNsfwBean( |
|
||||||
nsfwScore.sfw, |
|
||||||
nsfwScore.nsfw, |
|
||||||
"img/$it", |
|
||||||
bitmap |
|
||||||
) |
|
||||||
) |
|
||||||
} |
|
||||||
}).start() |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
private fun addDataToAdapter(mMyNsfwBean: MyNsfwBean) { |
|
||||||
runOnUiThread { mMainAdapter.addData(mMyNsfwBean) } |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 检测权限 |
|
||||||
*/ |
|
||||||
private fun checkPermissions() { |
|
||||||
if (ContextCompat.checkSelfPermission( |
|
||||||
this, |
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE |
|
||||||
) != PackageManager.PERMISSION_GRANTED |
|
||||||
) { |
|
||||||
ActivityCompat.requestPermissions( |
|
||||||
this, |
|
||||||
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), |
|
||||||
1 |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
if (ContextCompat.checkSelfPermission( |
|
||||||
this, |
|
||||||
Manifest.permission.CAMERA |
|
||||||
) != PackageManager.PERMISSION_GRANTED |
|
||||||
) { |
|
||||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 1); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { |
|
||||||
super.onActivityResult(requestCode, resultCode, data) |
|
||||||
if (requestCode == 0x01 && resultCode == RESULT_OK) { |
|
||||||
selectList = PictureSelector.obtainMultipleResult(data) |
|
||||||
selectList?.let { |
|
||||||
mMainAdapter.setNewData(null) |
|
||||||
Toast.makeText(this, "请稍等...", Toast.LENGTH_LONG).show() |
|
||||||
} |
|
||||||
Thread(Runnable { |
|
||||||
selectList?.forEach { |
|
||||||
val file = File(it.path) |
|
||||||
val nsfwScore = file.getNsfwScore() |
|
||||||
addDataToAdapter( |
|
||||||
MyNsfwBean( |
|
||||||
nsfwScore.sfw, |
|
||||||
nsfwScore.nsfw, |
|
||||||
it.path, |
|
||||||
BitmapFactory.decodeStream(file.inputStream()) |
|
||||||
) |
|
||||||
) |
|
||||||
} |
|
||||||
}).start() |
|
||||||
|
|
||||||
} |
|
||||||
if (requestCode == 0x02 && resultCode == RESULT_OK) { |
|
||||||
selectList = PictureSelector.obtainMultipleResult(data) |
|
||||||
val builder = MultipartBody.Builder().setType(MultipartBody.FORM) |
|
||||||
// selectList?.let { |
|
||||||
// mMainAdapter.setNewData(null) |
|
||||||
// Toast.makeText(this, "请稍等...", Toast.LENGTH_LONG).show() |
|
||||||
// } |
|
||||||
// Thread(Runnable { |
|
||||||
// selectList?.forEach { |
|
||||||
// val file = File(it.path) |
|
||||||
// val nsfwScore = file.getNsfwScore() |
|
||||||
// addDataToAdapter( |
|
||||||
// MyNsfwBean( |
|
||||||
// nsfwScore.sfw, |
|
||||||
// nsfwScore.nsfw, |
|
||||||
// it.path, |
|
||||||
// BitmapFactory.decodeStream(file.inputStream()) |
|
||||||
// ) |
|
||||||
// ) |
|
||||||
// } |
|
||||||
// }).start() |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,32 +0,0 @@ |
|||||||
package com.example.open_nsfw_android.view |
|
||||||
|
|
||||||
import com.google.gson.Gson |
|
||||||
import okhttp3.OkHttpClient |
|
||||||
import okhttp3.Request |
|
||||||
import org.koin.core.qualifier.qualifier |
|
||||||
import org.koin.dsl.module |
|
||||||
|
|
||||||
val BaseUrl = "http://114.116.213.202:7777/" |
|
||||||
val GetImageListURL = "${BaseUrl}imageList.do" |
|
||||||
val UploadImageURL = "${BaseUrl}imageList.do" |
|
||||||
|
|
||||||
|
|
||||||
val mModules = module { |
|
||||||
single<OkHttpClient> { |
|
||||||
OkHttpClient.Builder().build() |
|
||||||
} |
|
||||||
single<Gson> { |
|
||||||
Gson() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
data class NSFWImage( |
|
||||||
val createTime: String, |
|
||||||
val id: Int, |
|
||||||
val imgUrl: String |
|
||||||
) { |
|
||||||
override fun toString(): String { |
|
||||||
return Gson().toJson(this) |
|
||||||
} |
|
||||||
} |
|
@ -1,34 +0,0 @@ |
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
xmlns:aapt="http://schemas.android.com/aapt" |
|
||||||
android:width="108dp" |
|
||||||
android:height="108dp" |
|
||||||
android:viewportWidth="108" |
|
||||||
android:viewportHeight="108"> |
|
||||||
<path |
|
||||||
android: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:strokeWidth="1" |
|
||||||
android:strokeColor="#00000000"> |
|
||||||
<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:strokeWidth="1" |
|
||||||
android:strokeColor="#00000000" /> |
|
||||||
</vector> |
|
@ -1,29 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
android:width="108dp" |
|
||||||
android:height="108dp" |
|
||||||
android:viewportWidth="1148.6849" |
|
||||||
android:viewportHeight="1148.6849" |
|
||||||
android:tint="#4749FF"> |
|
||||||
<group |
|
||||||
android:translateX="219.66045" |
|
||||||
android:translateY="484.58157"> |
|
||||||
<group android:translateY="147.79688"> |
|
||||||
<path |
|
||||||
android:pathData="M86.4,-98.208L86.4,-83.52C85.968,-41.616,71.424,-11.232,42.768,7.776L51.264,15.408C80.928,-5.472,96.048,-38.448,96.624,-83.52L96.624,-98.208L123.12,-98.208C122.832,-54.72,122.256,-28.8,121.392,-20.16C119.952,-5.76,114.624,1.584,105.552,1.584C100.944,1.584,95.328,1.296,88.992,1.008L91.584,10.512C98.784,10.8,103.968,11.088,107.136,11.088C121.536,11.088,129.744,2.016,131.472,-16.128C132.768,-27.792,133.488,-58.464,133.488,-108.144L58.32,-108.144L58.32,-98.208L86.4,-98.208ZM64.8,-85.248L34.704,-79.2L34.704,-115.632L24.048,-115.632L24.048,-77.04L5.04,-73.296L6.624,-63.216L24.048,-66.672L24.048,-25.056C24.048,-21.6,22.176,-19.152,18.432,-17.712L21.456,-7.632C37.872,-13.248,51.408,-19.584,62.352,-26.496L59.76,-35.856C51.408,-30.96,43.056,-26.784,34.704,-23.328L34.704,-68.832L66.528,-75.168L64.8,-85.248Z" |
|
||||||
android:fillColor="#000000" /> |
|
||||||
<path |
|
||||||
android:pathData="M273.168,-77.904L247.68,-77.904C252,-83.808,256.32,-91.008,260.496,-99.36L260.496,-106.848L229.968,-106.848C231.696,-110.16,233.136,-113.616,234.432,-117.216L224.352,-118.512C219.168,-104.832,209.376,-93.168,194.976,-83.664L201.024,-75.6C210.528,-82.08,218.448,-89.568,224.496,-97.92L249.552,-97.92C245.52,-90.288,241.344,-83.664,237.168,-77.904L204.336,-77.904L204.336,-38.736L194.112,-38.736L194.112,-29.232L227.664,-29.232C221.904,-14.832,209.232,-3.024,189.648,6.192L196.416,14.832C217.728,3.6,231.408,-10.368,237.456,-27.072C245.52,-9.792,259.2,4.32,278.208,14.976L282.96,5.184C265.968,-3.168,253.584,-14.544,245.952,-29.232L282.24,-29.232L282.24,-38.736L273.168,-38.736L273.168,-77.904ZM213.552,-38.736L213.552,-68.832L233.568,-68.832C233.28,-57.168,232.272,-47.088,230.544,-38.736L213.552,-38.736ZM240.48,-38.736C241.92,-46.8,242.784,-56.88,243.072,-68.832L263.952,-68.832L263.952,-38.736L240.48,-38.736ZM166.608,12.816C174.96,12.816,179.136,8.496,179.136,0L179.136,-41.616C184.32,-43.92,189.36,-46.512,194.4,-49.104L194.4,-59.616C189.36,-56.736,184.32,-54.144,179.136,-51.84L179.136,-81.216L193.824,-81.216L193.824,-91.152L179.136,-91.152L179.136,-117.504L168.768,-117.504L168.768,-91.152L151.632,-91.152L151.632,-81.216L168.768,-81.216L168.768,-47.664C162.288,-45.216,155.664,-43.2,148.896,-41.472L151.488,-31.104C157.248,-32.976,163.008,-34.992,168.768,-37.296L168.768,-2.592C168.768,1.44,166.752,3.6,163.008,3.6C159.552,3.6,155.952,3.312,152.208,2.88L154.368,12.816L166.608,12.816Z" |
|
||||||
android:fillColor="#000000" /> |
|
||||||
<path |
|
||||||
android:pathData="M310.032,13.104C318.24,13.104,322.416,8.928,322.416,0.864L322.416,-41.328C326.736,-43.344,330.912,-45.648,335.088,-47.952L335.088,-58.176C330.912,-55.728,326.736,-53.424,322.416,-51.408L322.416,-80.208L336.096,-80.208L336.096,-89.856L322.416,-89.856L322.416,-117.216L312.048,-117.216L312.048,-89.856L295.92,-89.856L295.92,-80.208L312.048,-80.208L312.048,-46.8C306,-44.352,299.664,-42.336,293.328,-40.608L295.92,-30.672C301.392,-32.4,306.72,-34.416,312.048,-36.72L312.048,-1.872C312.048,1.872,310.176,3.888,306.432,3.888C303.408,3.888,300.24,3.6,296.784,3.168L298.944,13.104L310.032,13.104ZM339.12,-112.608L339.12,-104.256L351.216,-104.256L351.216,-60.48C346.896,-60.48,342.432,-60.336,337.824,-60.048L339.84,-52.128C360.288,-52.992,379.728,-53.856,398.448,-54.864L398.448,-48.24L408.384,-48.24L408.384,-55.44L421.92,-56.304L421.92,-64.368C417.456,-64.08,412.992,-63.792,408.384,-63.36L408.384,-104.256L420.048,-104.256L420.048,-112.608L339.12,-112.608ZM361.008,-60.912L361.008,-71.28L398.448,-71.28L398.448,-62.784C386.208,-62.064,373.68,-61.488,361.008,-60.912ZM361.008,-78.192L361.008,-87.552L398.448,-87.552L398.448,-78.192L361.008,-78.192ZM361.008,-94.608L361.008,-104.256L398.448,-104.256L398.448,-94.608L361.008,-94.608ZM343.584,-30.096L337.248,-23.904C342.72,-19.152,347.616,-14.4,352.224,-9.792C347.04,-3.168,340.272,2.304,331.92,6.768L337.392,15.12C345.888,10.512,353.088,4.608,358.992,-2.592C362.448,1.296,365.472,5.184,368.208,8.928L375.264,1.728C371.952,-2.304,368.352,-6.336,364.464,-10.512C368.496,-17.712,371.52,-25.92,373.392,-35.28L373.392,-43.776L337.392,-43.776L337.392,-34.848L364.32,-34.848C362.736,-28.512,360.432,-22.752,357.552,-17.568C353.232,-21.744,348.48,-25.92,343.584,-30.096ZM379.152,-43.776L379.152,-34.848L382.752,-34.848C385.056,-24.624,389.232,-15.408,395.568,-7.2C390.096,-1.728,383.472,3.024,375.552,6.912L380.88,15.12C388.944,11.088,396,6.048,402.048,0.144C407.232,5.328,413.424,9.936,420.912,14.256L426.096,6.048C419.04,2.304,412.992,-1.872,407.808,-6.624C413.856,-14.688,418.032,-24.336,420.48,-35.28L420.48,-43.776L379.152,-43.776ZM391.248,-34.848L410.976,-34.848C408.816,-27.072,405.504,-20.16,401.184,-13.968C396.432,-20.16,393.12,-27.072,391.248,-34.848Z" |
|
||||||
android:fillColor="#000000" /> |
|
||||||
<path |
|
||||||
android:pathData="M482.256,-83.376L482.256,-57.456L505.872,-57.456C498.384,-50.4,487.872,-45.36,474.192,-42.48L478.08,-33.84C492.192,-37.008,503.712,-42.624,512.352,-50.544C514.368,-48.24,516.384,-45.792,518.112,-43.2C507.744,-34.272,493.056,-26.928,474.048,-21.168L479.088,-12.672C497.232,-18.72,511.632,-26.64,522.288,-36.144C523.584,-33.408,524.736,-30.384,525.744,-27.216C513.36,-15.696,496.08,-6.192,473.616,1.008L478.8,9.936C498.96,2.736,515.232,-6.624,527.616,-17.856C527.76,-16.128,527.904,-14.4,527.904,-12.528C527.904,-5.616,526.896,-1.008,525.168,1.296C523.152,3.6,520.56,4.752,517.392,5.04C514.512,5.184,511.056,5.328,506.88,5.328L509.904,14.688C513.072,14.688,515.952,14.544,518.544,14.256C525.744,13.392,530.784,11.232,533.52,8.064C536.688,4.176,538.272,-2.736,538.272,-12.528C537.984,-18,537.12,-23.184,535.68,-28.368C537.552,-29.232,539.424,-30.096,541.44,-30.96C546.048,-16.704,553.536,-3.744,564.048,8.064L570.816,-0.432C560.448,-10.512,553.248,-22.032,549.216,-34.992C554.688,-38.016,559.584,-41.472,564.048,-45.36L557.28,-53.136C550.656,-46.8,542.304,-41.472,532.512,-37.152C529.344,-44.352,524.592,-50.976,518.4,-57.312L518.544,-57.456L561.6,-57.456L561.6,-88.848L534.816,-88.848C538.56,-92.448,542.304,-96.624,546.048,-101.52L546.048,-108.288L509.904,-108.288C511.92,-110.736,513.792,-113.328,515.808,-116.208L505.152,-118.656C496.224,-105.84,484.56,-95.472,470.448,-87.696L476.784,-79.92C478.512,-81.072,480.24,-82.224,482.256,-83.376ZM521.712,-88.848L489.888,-88.848C494.208,-92.304,498.528,-96.048,502.704,-100.224L533.952,-100.224C529.92,-96.192,525.888,-92.304,521.712,-88.848ZM551.52,-65.952L523.728,-65.952C525.744,-70.272,527.472,-75.168,528.624,-80.352L551.52,-80.352L551.52,-65.952ZM512.784,-65.952L492.336,-65.952L492.336,-80.352L518.544,-80.352C517.392,-75.168,515.376,-70.416,512.784,-65.952ZM454.32,-66.816L454.32,14.256L464.832,14.256L464.832,-85.392C469.152,-94.32,472.896,-103.824,475.776,-113.76L466.128,-118.368C460.08,-96.192,450.576,-76.464,437.328,-59.328L440.64,-48.384C445.536,-54.288,450.144,-60.48,454.32,-66.816Z" |
|
||||||
android:fillColor="#000000" /> |
|
||||||
<path |
|
||||||
android:pathData="M585.936,-50.112L585.936,-40.032L646.848,-40.032C644.544,-34.272,641.664,-28.944,638.208,-24.048C628.416,-11.808,610.848,-2.016,585.792,5.472L591.408,14.256C616.464,6.768,634.464,-3.456,645.552,-16.704C647.136,-18.864,648.72,-21.168,650.16,-23.472C672.336,-10.224,689.76,2.448,702.72,14.256L710.208,6.912C695.088,-5.76,676.512,-18.576,654.48,-31.392C655.776,-34.128,656.928,-37.008,657.936,-40.032L710.928,-40.032L710.928,-50.112L660.672,-50.112C662.256,-57.312,663.264,-65.088,663.552,-73.728L663.552,-117.36L653.04,-117.36L653.04,-73.728C652.752,-65.376,651.744,-57.456,650.016,-50.112L585.936,-50.112ZM597.6,-86.544L592.128,-78.48C603.216,-73.728,614.016,-67.248,624.528,-59.184L630.144,-67.68C620.352,-75.168,609.408,-81.36,597.6,-86.544ZM613.44,-109.728L607.968,-101.664C617.472,-97.632,626.688,-92.16,635.76,-84.96L641.232,-93.312C632.88,-99.648,623.52,-105.12,613.44,-109.728Z" |
|
||||||
android:fillColor="#000000" /> |
|
||||||
</group> |
|
||||||
</group> |
|
||||||
</vector> |
|
@ -1,170 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<vector android:height="108dp" |
|
||||||
android:width="108dp" |
|
||||||
android:viewportHeight="108" |
|
||||||
android:viewportWidth="108" |
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"> |
|
||||||
<path |
|
||||||
android:fillColor="#3DDC84" |
|
||||||
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> |
|
@ -1,11 +0,0 @@ |
|||||||
<vector android:alpha="0.57" |
|
||||||
android:height="24dp" |
|
||||||
android:tint="#0A0033" |
|
||||||
android:viewportHeight="24.0" |
|
||||||
android:viewportWidth="24.0" |
|
||||||
android:width="24dp" |
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"> |
|
||||||
<path |
|
||||||
android:fillColor="#FF000000" |
|
||||||
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" /> |
|
||||||
</vector> |
|
@ -1,11 +0,0 @@ |
|||||||
<vector android:alpha="0.57" |
|
||||||
android:height="24dp" |
|
||||||
android:tint="#FB2516" |
|
||||||
android:viewportHeight="24.0" |
|
||||||
android:viewportWidth="24.0" |
|
||||||
android:width="24dp" |
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"> |
|
||||||
<path |
|
||||||
android:fillColor="#FF000000" |
|
||||||
android:pathData="M9.4,10.5l4.77,-8.26C13.47,2.09 12.75,2 12,2c-2.4,0 -4.6,0.85 -6.32,2.25l3.66,6.35 0.06,-0.1zM21.54,9c-0.92,-2.92 -3.15,-5.26 -6,-6.34L11.88,9h9.66zM21.8,10h-7.49l0.29,0.5 4.76,8.25C21,16.97 22,14.61 22,12c0,-0.69 -0.07,-1.35 -0.2,-2zM8.54,12l-3.9,-6.75C3.01,7.03 2,9.39 2,12c0,0.69 0.07,1.35 0.2,2h7.49l-1.15,-2zM2.46,15c0.92,2.92 3.15,5.26 6,6.34L12.12,15L2.46,15zM13.73,15l-3.9,6.76c0.7,0.15 1.42,0.24 2.17,0.24 2.4,0 4.6,-0.85 6.32,-2.25l-3.66,-6.35 -0.93,1.6z" /> |
|
||||||
</vector> |
|
@ -1,136 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="match_parent" |
|
||||||
android:orientation="vertical"> |
|
||||||
|
|
||||||
<android.support.v4.widget.NestedScrollView |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="match_parent"> |
|
||||||
|
|
||||||
<LinearLayout |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="match_parent" |
|
||||||
android:orientation="vertical"> |
|
||||||
|
|
||||||
<LinearLayout |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:orientation="horizontal"> |
|
||||||
|
|
||||||
<Button |
|
||||||
android:id="@+id/bt_sc_assets" |
|
||||||
android:layout_width="0dp" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_gravity="center" |
|
||||||
android:layout_weight="1" |
|
||||||
android:gravity="center" |
|
||||||
android:padding="15dp" |
|
||||||
android:text="@string/str_bt1" |
|
||||||
android:textSize="12sp" /> |
|
||||||
|
|
||||||
<Button |
|
||||||
android:id="@+id/bt_sc_from_other" |
|
||||||
android:layout_width="0dp" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_gravity="center" |
|
||||||
android:layout_weight="1" |
|
||||||
android:gravity="center" |
|
||||||
android:padding="15dp" |
|
||||||
android:text="从相册选取" |
|
||||||
android:textSize="14sp" /> |
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout> |
|
||||||
|
|
||||||
<LinearLayout |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:orientation="horizontal"> |
|
||||||
|
|
||||||
|
|
||||||
<Button |
|
||||||
android:id="@+id/bt_sc_from_cam" |
|
||||||
android:layout_width="0dp" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_gravity="center" |
|
||||||
android:layout_weight="1" |
|
||||||
android:gravity="center" |
|
||||||
android:padding="15dp" |
|
||||||
android:text="实时扫描" |
|
||||||
android:textSize="14sp" /> |
|
||||||
|
|
||||||
<Button |
|
||||||
android:id="@+id/bt_sc_from_internet" |
|
||||||
android:layout_width="0dp" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_gravity="center" |
|
||||||
android:layout_weight="1" |
|
||||||
android:gravity="center" |
|
||||||
android:padding="15dp" |
|
||||||
android:text="识别网络图片" |
|
||||||
android:textSize="14sp" /> |
|
||||||
</LinearLayout> |
|
||||||
|
|
||||||
<LinearLayout |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:orientation="horizontal"> |
|
||||||
|
|
||||||
<Button |
|
||||||
android:id="@+id/bt_sc_from_api" |
|
||||||
android:layout_width="0dp" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_gravity="center" |
|
||||||
android:layout_weight="1" |
|
||||||
android:gravity="center" |
|
||||||
android:padding="15dp" |
|
||||||
android:text="测试狼友上传的图片" |
|
||||||
android:textSize="14sp" /> |
|
||||||
|
|
||||||
<Button |
|
||||||
android:id="@+id/bt_upload" |
|
||||||
android:layout_width="0dp" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_gravity="center" |
|
||||||
android:layout_weight="1" |
|
||||||
android:gravity="center" |
|
||||||
android:padding="15dp" |
|
||||||
android:text="我有资源可以提供" |
|
||||||
android:textSize="14sp" /> |
|
||||||
</LinearLayout> |
|
||||||
|
|
||||||
<TextView |
|
||||||
android:id="@+id/tv_version" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:gravity="center" |
|
||||||
android:padding="5dp" |
|
||||||
android:text="版本号:" |
|
||||||
android:textColor="@color/blue" |
|
||||||
android:textSize="15sp" /> |
|
||||||
|
|
||||||
<TextView |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:padding="15dp" |
|
||||||
android:text="sfw:适宜在公共场所浏览,nsfw:不适宜在公共场所浏览,两者都是0-1中间的浮点型值,nsfw数值越大表示色情程度越高,sfw反之" |
|
||||||
android:textSize="14sp" /> |
|
||||||
|
|
||||||
<TextView |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:padding="15dp" |
|
||||||
android:text="所有图片均来源百度,如有侵权请联系我删除。大尺度图片请自行google来测试" |
|
||||||
android:textColor="#FF0404" |
|
||||||
android:textSize="12sp" /> |
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView |
|
||||||
android:id="@+id/rv" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" /> |
|
||||||
</LinearLayout> |
|
||||||
|
|
||||||
|
|
||||||
</android.support.v4.widget.NestedScrollView> |
|
||||||
</LinearLayout> |
|
@ -1,50 +0,0 @@ |
|||||||
<?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:orientation="vertical" |
|
||||||
tools:context=".Main2Activity"> |
|
||||||
|
|
||||||
<LinearLayout |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:orientation="horizontal"> |
|
||||||
|
|
||||||
<EditText |
|
||||||
android:id="@+id/et" |
|
||||||
android:layout_width="0dp" |
|
||||||
android:layout_height="50dp" |
|
||||||
android:layout_weight="1" |
|
||||||
android:background="@null" |
|
||||||
android:hint="粘贴网络图片路径" |
|
||||||
android:padding="15dp" /> |
|
||||||
|
|
||||||
<Button |
|
||||||
android:id="@+id/bt" |
|
||||||
android:layout_width="0dp" |
|
||||||
android:layout_height="50dp" |
|
||||||
android:layout_weight="0.3" |
|
||||||
android:text="识别" /> |
|
||||||
</LinearLayout> |
|
||||||
|
|
||||||
<View |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="1dp" |
|
||||||
android:background="#504d4d4d" /> |
|
||||||
|
|
||||||
<TextView |
|
||||||
android:id="@+id/tv" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:gravity="center" |
|
||||||
android:textColor="#FA3C00" |
|
||||||
android:padding="20dp" |
|
||||||
android:text="这里显示检测结果" /> |
|
||||||
|
|
||||||
<ImageView |
|
||||||
android:id="@+id/iv" |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:padding="15dp" /> |
|
||||||
</LinearLayout> |
|
@ -1,40 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="match_parent"> |
|
||||||
|
|
||||||
<SurfaceView |
|
||||||
android:id="@+id/surfaceView" |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:padding="25dp" /> |
|
||||||
|
|
||||||
<ImageView |
|
||||||
android:id="@+id/iv_back" |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_marginLeft="25dp" |
|
||||||
android:layout_marginTop="25dp" |
|
||||||
android:src="@drawable/ic_arrow_back_black_24dp" /> |
|
||||||
|
|
||||||
<ImageView |
|
||||||
android:id="@+id/iv_change" |
|
||||||
android:layout_width="45dp" |
|
||||||
android:layout_height="45dp" |
|
||||||
android:layout_alignParentBottom="true" |
|
||||||
android:layout_centerHorizontal="true" |
|
||||||
android:layout_marginRight="20dp" |
|
||||||
android:layout_marginBottom="20dp" |
|
||||||
android:src="@drawable/ic_camera_black_24dp" /> |
|
||||||
|
|
||||||
<TextView |
|
||||||
android:id="@+id/textView" |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_above="@+id/iv_change" |
|
||||||
android:layout_alignParentBottom="true" |
|
||||||
android:layout_centerHorizontal="true" |
|
||||||
android:layout_marginBottom="93dp" |
|
||||||
android:text="适宜度:\n不适宜度:" |
|
||||||
android:textColor="#008DFD" /> |
|
||||||
</RelativeLayout> |
|
@ -1,22 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:id="@+id/view" |
|
||||||
android:layout_marginTop="5dp" |
|
||||||
android:padding="20dp" |
|
||||||
|
|
||||||
android:layout_height="wrap_content"> |
|
||||||
|
|
||||||
<TextView |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:id="@+id/tv_text" |
|
||||||
android:layout_toLeftOf="@+id/iv" |
|
||||||
android:layout_height="wrap_content" /> |
|
||||||
|
|
||||||
<ImageView |
|
||||||
android:layout_width="100dp" |
|
||||||
android:layout_height="100dp" |
|
||||||
android:id="@+id/iv" |
|
||||||
android:scaleType="centerCrop" |
|
||||||
android:layout_alignParentRight="true" /> |
|
||||||
</RelativeLayout> |
|
@ -1,5 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |
|
||||||
<background android:drawable="@drawable/change_background" /> |
|
||||||
<foreground android:drawable="@drawable/ch" /> |
|
||||||
</adaptive-icon> |
|
@ -1,5 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |
|
||||||
<background android:drawable="@drawable/change_background" /> |
|
||||||
<foreground android:drawable="@drawable/ch" /> |
|
||||||
</adaptive-icon> |
|
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 15 KiB |
@ -1,10 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<resources> |
|
||||||
<color name="colorPrimary">#008577</color> |
|
||||||
<color name="colorPrimaryDark">#00574B</color> |
|
||||||
<color name="semi_transparent">#66000000</color> |
|
||||||
<color name="nsfw1">#96CC1B1B</color> |
|
||||||
<color name="nsfw2">#00BCD4</color> |
|
||||||
<color name="nsfw3">#4CAF50</color> |
|
||||||
<color name="colorAccent">#FF0000</color> |
|
||||||
</resources> |
|
@ -1,3 +0,0 @@ |
|||||||
<resources> |
|
||||||
<dimen name="fab_margin">16dp</dimen> |
|
||||||
</resources> |
|
@ -1,5 +0,0 @@ |
|||||||
<resources> |
|
||||||
<string name="app_name">离线鉴黄</string> |
|
||||||
<string name="str_bt1">识别Assets下图片</string> |
|
||||||
<string name="title_activity_main2">网络图片识别,你懂的</string> |
|
||||||
</resources> |
|
@ -1,20 +0,0 @@ |
|||||||
<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> |
|
||||||
|
|
||||||
<style name="AppTheme.NoActionBar"> |
|
||||||
<item name="windowActionBar">false</item> |
|
||||||
<item name="windowNoTitle">true</item> |
|
||||||
</style> |
|
||||||
|
|
||||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> |
|
||||||
|
|
||||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" /> |
|
||||||
|
|
||||||
</resources> |
|
@ -1,16 +0,0 @@ |
|||||||
package com.example.open_nsfw_android |
|
||||||
|
|
||||||
import org.junit.Assert.assertEquals |
|
||||||
import org.junit.Test |
|
||||||
|
|
||||||
/** |
|
||||||
* Example local unit test, which will execute on the development machine (host). |
|
||||||
* |
|
||||||
* See [testing documentation](http://d.android.com/tools/testing). |
|
||||||
*/ |
|
||||||
class ExampleUnitTest { |
|
||||||
@Test |
|
||||||
fun addition_isCorrect() { |
|
||||||
assertEquals(4, 2 + 2) |
|
||||||
} |
|
||||||
} |
|
@ -1,34 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
package="com.zwy.demo"> |
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.CAMERA" /> |
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
|
||||||
<uses-permission android:name="android.permission.INTERNET" /> |
|
||||||
|
|
||||||
<application |
|
||||||
android:name=".NSFWApplication" |
|
||||||
android:allowBackup="true" |
|
||||||
android:icon="@mipmap/launch" |
|
||||||
android:label="@string/app_name" |
|
||||||
android:networkSecurityConfig="@xml/network_security_config" |
|
||||||
android:roundIcon="@mipmap/launch" |
|
||||||
android:supportsRtl="true" |
|
||||||
android:theme="@style/AppTheme" |
|
||||||
android:usesCleartextTraffic="true"> |
|
||||||
|
|
||||||
<activity |
|
||||||
android:name=".views.MainActivity" |
|
||||||
android:label="@string/main_aty_name"> |
|
||||||
<intent-filter> |
|
||||||
<action android:name="android.intent.action.MAIN" /> |
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" /> |
|
||||||
</intent-filter> |
|
||||||
</activity> |
|
||||||
<activity android:name=".views.ScanPicActivity" |
|
||||||
android:label="@string/myscan"/> |
|
||||||
</application> |
|
||||||
|
|
||||||
</manifest> |
|
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 37 KiB |
@ -1,54 +0,0 @@ |
|||||||
package com.zwy.demo |
|
||||||
|
|
||||||
import android.content.Context |
|
||||||
import androidx.multidex.MultiDexApplication |
|
||||||
import com.zwy.demo.utils.ActivityLifecycleCallback |
|
||||||
import com.zwy.demo.utils.networkModule |
|
||||||
import com.zwy.demo.utils.repositoryModule |
|
||||||
import com.zwy.demo.utils.viewModelModules |
|
||||||
import com.zwy.opennsfw.core.Classifier |
|
||||||
import org.koin.android.ext.koin.androidContext |
|
||||||
import org.koin.android.ext.koin.androidLogger |
|
||||||
import org.koin.core.context.startKoin |
|
||||||
import java.util.* |
|
||||||
|
|
||||||
|
|
||||||
class NSFWApplication : MultiDexApplication() { |
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate() { |
|
||||||
super.onCreate() |
|
||||||
|
|
||||||
startTime = Date().time |
|
||||||
|
|
||||||
context = this |
|
||||||
|
|
||||||
//全局配置actionbar title |
|
||||||
registerActivityLifecycleCallbacks(ActivityLifecycleCallback()) |
|
||||||
|
|
||||||
//初始化鉴黄库NSFW |
|
||||||
Classifier.Build() |
|
||||||
.context(this) //1.3.4版本可不用调用该代码。其他版本必须调用,否则会有异常抛出 |
|
||||||
// .isOpenGPU(true)//默认不开启GPU加速,默认为true |
|
||||||
// .numThreads(100) //分配的线程数 根据手机配置设置,默认1 |
|
||||||
// .nsfwModuleFilePath("/data/user/0/com.zwy.demo/files/nsfw.tflite") //1.3.4版本必须配置模型存放路径,否则会有异常抛出 |
|
||||||
.build() |
|
||||||
//全局注入对象 |
|
||||||
startKoin { |
|
||||||
androidContext(this@NSFWApplication) |
|
||||||
androidLogger() |
|
||||||
modules(networkModule) |
|
||||||
modules(repositoryModule) |
|
||||||
modules(viewModelModules) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
companion object { |
|
||||||
lateinit var context: Context |
|
||||||
var startTime: Long = 0 |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
@ -1,111 +0,0 @@ |
|||||||
package com.zwy.demo.base |
|
||||||
|
|
||||||
import android.app.Dialog |
|
||||||
import android.content.DialogInterface |
|
||||||
import android.os.Bundle |
|
||||||
import android.util.Log |
|
||||||
import androidx.appcompat.app.AppCompatActivity |
|
||||||
import androidx.databinding.DataBindingUtil |
|
||||||
import androidx.databinding.ViewDataBinding |
|
||||||
import androidx.lifecycle.Observer |
|
||||||
import com.gyf.immersionbar.ImmersionBar |
|
||||||
import com.zwy.demo.R |
|
||||||
import org.jetbrains.anko.indeterminateProgressDialog |
|
||||||
import org.koin.java.KoinJavaComponent.get |
|
||||||
import java.lang.reflect.ParameterizedType |
|
||||||
import java.lang.reflect.Type |
|
||||||
|
|
||||||
abstract class BaseActivity<V : ViewDataBinding, VM : BaseViewModel> : AppCompatActivity(), |
|
||||||
DialogInterface.OnCancelListener { |
|
||||||
|
|
||||||
lateinit var binding: V |
|
||||||
lateinit var viewModel: VM |
|
||||||
var dialog: Dialog? = null |
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) { |
|
||||||
super.onCreate(savedInstanceState) |
|
||||||
ImmersionBar.with(this).fitsSystemWindows(true).statusBarColor(R.color.colorPrimary).init() |
|
||||||
initViewDataBinding(savedInstanceState) |
|
||||||
registorUIChangeLiveDataCallBack() |
|
||||||
initData() |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 注入绑定 |
|
||||||
*/ |
|
||||||
private fun initViewDataBinding(savedInstanceState: Bundle?) { |
|
||||||
binding = DataBindingUtil.setContentView(this, initContentView(savedInstanceState)) |
|
||||||
val type: Type = javaClass.genericSuperclass!! |
|
||||||
viewModel = get((type as ParameterizedType).actualTypeArguments[1] as Class<VM>) |
|
||||||
binding.lifecycleOwner = this |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 注册ViewModel与View的契约UI回调事件 |
|
||||||
*/ |
|
||||||
protected open fun registorUIChangeLiveDataCallBack() { |
|
||||||
|
|
||||||
viewModel.appLiveData.observe(this, Observer { |
|
||||||
|
|
||||||
when (it.type) { |
|
||||||
0 -> { |
|
||||||
//加载进度条 |
|
||||||
if (it.text.isNotBlank()) initDialog(it.text) |
|
||||||
dialog?.show() |
|
||||||
} |
|
||||||
1 -> { |
|
||||||
//取消进度条 |
|
||||||
if (dialog != null && dialog?.isShowing == true) { |
|
||||||
dialog?.dismiss() |
|
||||||
} |
|
||||||
} |
|
||||||
2 -> { |
|
||||||
//关闭页面 |
|
||||||
finish() |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
* 父类onCreate执行完成后调用 |
|
||||||
*/ |
|
||||||
abstract fun initData() |
|
||||||
|
|
||||||
/** |
|
||||||
* 初始化根布局 |
|
||||||
* |
|
||||||
* @return 布局layout的id |
|
||||||
*/ |
|
||||||
abstract fun initContentView(savedInstanceState: Bundle?): Int |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 初始化进度条 |
|
||||||
*/ |
|
||||||
private fun initDialog(msg: String) { |
|
||||||
dialog = indeterminateProgressDialog(msg, "提示") |
|
||||||
dialog?.setCanceledOnTouchOutside(false) |
|
||||||
dialog?.setOnCancelListener(this) |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 页面进度条对话框被取消后的回掉 |
|
||||||
*/ |
|
||||||
override fun onCancel(dialog: DialogInterface?) { |
|
||||||
Log.d(com.zwy.demo.utils.TAG, "进度条销毁回掉") |
|
||||||
} |
|
||||||
|
|
||||||
override fun onDestroy() { |
|
||||||
super.onDestroy() |
|
||||||
binding.unbind() |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
@ -1,99 +0,0 @@ |
|||||||
package com.zwy.demo.db; |
|
||||||
|
|
||||||
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) { |
|
||||||
HomeTitleDao.createTable(db, ifNotExists); |
|
||||||
ImageBeanDao.createTable(db, ifNotExists); |
|
||||||
} |
|
||||||
|
|
||||||
/** Drops underlying database table using DAOs. */ |
|
||||||
public static void dropAllTables(Database db, boolean ifExists) { |
|
||||||
HomeTitleDao.dropTable(db, ifExists); |
|
||||||
ImageBeanDao.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(HomeTitleDao.class); |
|
||||||
registerDaoClass(ImageBeanDao.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); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,62 +0,0 @@ |
|||||||
package com.zwy.demo.db; |
|
||||||
|
|
||||||
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.zwy.demo.dbbean.HomeTitle; |
|
||||||
import com.zwy.demo.dbbean.ImageBean; |
|
||||||
|
|
||||||
import com.zwy.demo.db.HomeTitleDao; |
|
||||||
import com.zwy.demo.db.ImageBeanDao; |
|
||||||
|
|
||||||
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
|
|
||||||
|
|
||||||
/** |
|
||||||
* {@inheritDoc} |
|
||||||
* |
|
||||||
* @see org.greenrobot.greendao.AbstractDaoSession |
|
||||||
*/ |
|
||||||
public class DaoSession extends AbstractDaoSession { |
|
||||||
|
|
||||||
private final DaoConfig homeTitleDaoConfig; |
|
||||||
private final DaoConfig imageBeanDaoConfig; |
|
||||||
|
|
||||||
private final HomeTitleDao homeTitleDao; |
|
||||||
private final ImageBeanDao imageBeanDao; |
|
||||||
|
|
||||||
public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig> |
|
||||||
daoConfigMap) { |
|
||||||
super(db); |
|
||||||
|
|
||||||
homeTitleDaoConfig = daoConfigMap.get(HomeTitleDao.class).clone(); |
|
||||||
homeTitleDaoConfig.initIdentityScope(type); |
|
||||||
|
|
||||||
imageBeanDaoConfig = daoConfigMap.get(ImageBeanDao.class).clone(); |
|
||||||
imageBeanDaoConfig.initIdentityScope(type); |
|
||||||
|
|
||||||
homeTitleDao = new HomeTitleDao(homeTitleDaoConfig, this); |
|
||||||
imageBeanDao = new ImageBeanDao(imageBeanDaoConfig, this); |
|
||||||
|
|
||||||
registerDao(HomeTitle.class, homeTitleDao); |
|
||||||
registerDao(ImageBean.class, imageBeanDao); |
|
||||||
} |
|
||||||
|
|
||||||
public void clear() { |
|
||||||
homeTitleDaoConfig.clearIdentityScope(); |
|
||||||
imageBeanDaoConfig.clearIdentityScope(); |
|
||||||
} |
|
||||||
|
|
||||||
public HomeTitleDao getHomeTitleDao() { |
|
||||||
return homeTitleDao; |
|
||||||
} |
|
||||||
|
|
||||||
public ImageBeanDao getImageBeanDao() { |
|
||||||
return imageBeanDao; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,129 +0,0 @@ |
|||||||
package com.zwy.demo.db; |
|
||||||
|
|
||||||
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.zwy.demo.dbbean.HomeTitle; |
|
||||||
|
|
||||||
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
|
|
||||||
/** |
|
||||||
* DAO for table "HOME_TITLE". |
|
||||||
*/ |
|
||||||
public class HomeTitleDao extends AbstractDao<HomeTitle, Long> { |
|
||||||
|
|
||||||
public static final String TABLENAME = "HOME_TITLE"; |
|
||||||
|
|
||||||
/** |
|
||||||
* Properties of entity HomeTitle.<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 Title = new Property(1, String.class, "title", false, "TITLE"); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public HomeTitleDao(DaoConfig config) { |
|
||||||
super(config); |
|
||||||
} |
|
||||||
|
|
||||||
public HomeTitleDao(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 + "\"HOME_TITLE\" (" + //
|
|
||||||
"\"_id\" INTEGER PRIMARY KEY ," + // 0: id
|
|
||||||
"\"TITLE\" TEXT);"); // 1: title
|
|
||||||
} |
|
||||||
|
|
||||||
/** Drops the underlying database table. */ |
|
||||||
public static void dropTable(Database db, boolean ifExists) { |
|
||||||
String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"HOME_TITLE\""; |
|
||||||
db.execSQL(sql); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected final void bindValues(DatabaseStatement stmt, HomeTitle entity) { |
|
||||||
stmt.clearBindings(); |
|
||||||
|
|
||||||
Long id = entity.getId(); |
|
||||||
if (id != null) { |
|
||||||
stmt.bindLong(1, id); |
|
||||||
} |
|
||||||
|
|
||||||
String title = entity.getTitle(); |
|
||||||
if (title != null) { |
|
||||||
stmt.bindString(2, title); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected final void bindValues(SQLiteStatement stmt, HomeTitle entity) { |
|
||||||
stmt.clearBindings(); |
|
||||||
|
|
||||||
Long id = entity.getId(); |
|
||||||
if (id != null) { |
|
||||||
stmt.bindLong(1, id); |
|
||||||
} |
|
||||||
|
|
||||||
String title = entity.getTitle(); |
|
||||||
if (title != null) { |
|
||||||
stmt.bindString(2, title); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Long readKey(Cursor cursor, int offset) { |
|
||||||
return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public HomeTitle readEntity(Cursor cursor, int offset) { |
|
||||||
HomeTitle entity = new HomeTitle( //
|
|
||||||
cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
|
|
||||||
cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1) // title
|
|
||||||
); |
|
||||||
return entity; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void readEntity(Cursor cursor, HomeTitle entity, int offset) { |
|
||||||
entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0)); |
|
||||||
entity.setTitle(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1)); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected final Long updateKeyAfterInsert(HomeTitle entity, long rowId) { |
|
||||||
entity.setId(rowId); |
|
||||||
return rowId; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Long getKey(HomeTitle entity) { |
|
||||||
if(entity != null) { |
|
||||||
return entity.getId(); |
|
||||||
} else { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasKey(HomeTitle entity) { |
|
||||||
return entity.getId() != null; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected final boolean isEntityUpdateable() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,171 +0,0 @@ |
|||||||
package com.zwy.demo.db; |
|
||||||
|
|
||||||
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.zwy.demo.dbbean.ImageBean; |
|
||||||
|
|
||||||
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
|
|
||||||
/** |
|
||||||
* DAO for table "IMAGE_BEAN". |
|
||||||
*/ |
|
||||||
public class ImageBeanDao extends AbstractDao<ImageBean, Long> { |
|
||||||
|
|
||||||
public static final String TABLENAME = "IMAGE_BEAN"; |
|
||||||
|
|
||||||
/** |
|
||||||
* Properties of entity ImageBean.<br/> |
|
||||||
* Can be used for QueryBuilder and for referencing column names. |
|
||||||
*/ |
|
||||||
public static class Properties { |
|
||||||
public final static Property CreateTime = new Property(0, String.class, "createTime", false, "CREATE_TIME"); |
|
||||||
public final static Property Id = new Property(1, Long.class, "id", true, "_id"); |
|
||||||
public final static Property ImgUrl = new Property(2, String.class, "imgUrl", false, "IMG_URL"); |
|
||||||
public final static Property Nsfw = new Property(3, Float.class, "nsfw", false, "NSFW"); |
|
||||||
public final static Property Sfw = new Property(4, Float.class, "sfw", false, "SFW"); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public ImageBeanDao(DaoConfig config) { |
|
||||||
super(config); |
|
||||||
} |
|
||||||
|
|
||||||
public ImageBeanDao(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 + "\"IMAGE_BEAN\" (" + //
|
|
||||||
"\"CREATE_TIME\" TEXT," + // 0: createTime
|
|
||||||
"\"_id\" INTEGER PRIMARY KEY ," + // 1: id
|
|
||||||
"\"IMG_URL\" TEXT," + // 2: imgUrl
|
|
||||||
"\"NSFW\" REAL," + // 3: nsfw
|
|
||||||
"\"SFW\" REAL);"); // 4: sfw
|
|
||||||
} |
|
||||||
|
|
||||||
/** Drops the underlying database table. */ |
|
||||||
public static void dropTable(Database db, boolean ifExists) { |
|
||||||
String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"IMAGE_BEAN\""; |
|
||||||
db.execSQL(sql); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected final void bindValues(DatabaseStatement stmt, ImageBean entity) { |
|
||||||
stmt.clearBindings(); |
|
||||||
|
|
||||||
String createTime = entity.getCreateTime(); |
|
||||||
if (createTime != null) { |
|
||||||
stmt.bindString(1, createTime); |
|
||||||
} |
|
||||||
|
|
||||||
Long id = entity.getId(); |
|
||||||
if (id != null) { |
|
||||||
stmt.bindLong(2, id); |
|
||||||
} |
|
||||||
|
|
||||||
String imgUrl = entity.getImgUrl(); |
|
||||||
if (imgUrl != null) { |
|
||||||
stmt.bindString(3, imgUrl); |
|
||||||
} |
|
||||||
|
|
||||||
Float nsfw = entity.getNsfw(); |
|
||||||
if (nsfw != null) { |
|
||||||
stmt.bindDouble(4, nsfw); |
|
||||||
} |
|
||||||
|
|
||||||
Float sfw = entity.getSfw(); |
|
||||||
if (sfw != null) { |
|
||||||
stmt.bindDouble(5, sfw); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected final void bindValues(SQLiteStatement stmt, ImageBean entity) { |
|
||||||
stmt.clearBindings(); |
|
||||||
|
|
||||||
String createTime = entity.getCreateTime(); |
|
||||||
if (createTime != null) { |
|
||||||
stmt.bindString(1, createTime); |
|
||||||
} |
|
||||||
|
|
||||||
Long id = entity.getId(); |
|
||||||
if (id != null) { |
|
||||||
stmt.bindLong(2, id); |
|
||||||
} |
|
||||||
|
|
||||||
String imgUrl = entity.getImgUrl(); |
|
||||||
if (imgUrl != null) { |
|
||||||
stmt.bindString(3, imgUrl); |
|
||||||
} |
|
||||||
|
|
||||||
Float nsfw = entity.getNsfw(); |
|
||||||
if (nsfw != null) { |
|
||||||
stmt.bindDouble(4, nsfw); |
|
||||||
} |
|
||||||
|
|
||||||
Float sfw = entity.getSfw(); |
|
||||||
if (sfw != null) { |
|
||||||
stmt.bindDouble(5, sfw); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Long readKey(Cursor cursor, int offset) { |
|
||||||
return cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public ImageBean readEntity(Cursor cursor, int offset) { |
|
||||||
ImageBean entity = new ImageBean( //
|
|
||||||
cursor.isNull(offset + 0) ? null : cursor.getString(offset + 0), // createTime
|
|
||||||
cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1), // id
|
|
||||||
cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2), // imgUrl
|
|
||||||
cursor.isNull(offset + 3) ? null : cursor.getFloat(offset + 3), // nsfw
|
|
||||||
cursor.isNull(offset + 4) ? null : cursor.getFloat(offset + 4) // sfw
|
|
||||||
); |
|
||||||
return entity; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void readEntity(Cursor cursor, ImageBean entity, int offset) { |
|
||||||
entity.setCreateTime(cursor.isNull(offset + 0) ? null : cursor.getString(offset + 0)); |
|
||||||
entity.setId(cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1)); |
|
||||||
entity.setImgUrl(cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2)); |
|
||||||
entity.setNsfw(cursor.isNull(offset + 3) ? null : cursor.getFloat(offset + 3)); |
|
||||||
entity.setSfw(cursor.isNull(offset + 4) ? null : cursor.getFloat(offset + 4)); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected final Long updateKeyAfterInsert(ImageBean entity, long rowId) { |
|
||||||
entity.setId(rowId); |
|
||||||
return rowId; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Long getKey(ImageBean entity) { |
|
||||||
if(entity != null) { |
|
||||||
return entity.getId(); |
|
||||||
} else { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean hasKey(ImageBean entity) { |
|
||||||
return entity.getId() != null; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected final boolean isEntityUpdateable() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,42 +0,0 @@ |
|||||||
package com.zwy.demo.dbbean; |
|
||||||
|
|
||||||
import org.greenrobot.greendao.annotation.Entity; |
|
||||||
import org.greenrobot.greendao.annotation.Generated; |
|
||||||
import org.greenrobot.greendao.annotation.Id; |
|
||||||
|
|
||||||
@Entity |
|
||||||
public class HomeTitle { |
|
||||||
@Id |
|
||||||
private Long id; |
|
||||||
private String title; |
|
||||||
|
|
||||||
@Generated(hash = 2016918462) |
|
||||||
public HomeTitle(Long id, String title) { |
|
||||||
this.id = id; |
|
||||||
this.title = title; |
|
||||||
} |
|
||||||
|
|
||||||
@Generated(hash = 869810785) |
|
||||||
public HomeTitle() { |
|
||||||
} |
|
||||||
|
|
||||||
public HomeTitle(String title) { |
|
||||||
this.title = title; |
|
||||||
} |
|
||||||
|
|
||||||
public Long getId() { |
|
||||||
return this.id; |
|
||||||
} |
|
||||||
|
|
||||||
public void setId(Long id) { |
|
||||||
this.id = id; |
|
||||||
} |
|
||||||
|
|
||||||
public String getTitle() { |
|
||||||
return this.title; |
|
||||||
} |
|
||||||
|
|
||||||
public void setTitle(String title) { |
|
||||||
this.title = title; |
|
||||||
} |
|
||||||
} |
|
@ -1,78 +0,0 @@ |
|||||||
package com.zwy.demo.dbbean; |
|
||||||
|
|
||||||
import org.greenrobot.greendao.annotation.Entity; |
|
||||||
import org.greenrobot.greendao.annotation.Generated; |
|
||||||
import org.greenrobot.greendao.annotation.Id; |
|
||||||
|
|
||||||
@Entity |
|
||||||
public class ImageBean { |
|
||||||
private String createTime; |
|
||||||
@Id |
|
||||||
private Long id; |
|
||||||
private String imgUrl = ""; |
|
||||||
private Float nsfw = 0.0f; |
|
||||||
private Float sfw = 0.0f; |
|
||||||
|
|
||||||
|
|
||||||
@Generated(hash = 716432991) |
|
||||||
public ImageBean(String createTime, Long id, String imgUrl, Float nsfw, |
|
||||||
Float sfw) { |
|
||||||
this.createTime = createTime; |
|
||||||
this.id = id; |
|
||||||
this.imgUrl = imgUrl; |
|
||||||
this.nsfw = nsfw; |
|
||||||
this.sfw = sfw; |
|
||||||
} |
|
||||||
|
|
||||||
public ImageBean(String imgUrl, Float nsfw, |
|
||||||
Float sfw) { |
|
||||||
this.imgUrl = imgUrl; |
|
||||||
this.nsfw = nsfw; |
|
||||||
this.sfw = sfw; |
|
||||||
} |
|
||||||
|
|
||||||
@Generated(hash = 645668394) |
|
||||||
public ImageBean() { |
|
||||||
} |
|
||||||
|
|
||||||
public String getCreateTime() { |
|
||||||
return this.createTime; |
|
||||||
} |
|
||||||
|
|
||||||
public void setCreateTime(String createTime) { |
|
||||||
this.createTime = createTime; |
|
||||||
} |
|
||||||
|
|
||||||
public Long getId() { |
|
||||||
return this.id; |
|
||||||
} |
|
||||||
|
|
||||||
public void setId(Long id) { |
|
||||||
this.id = id; |
|
||||||
} |
|
||||||
|
|
||||||
public String getImgUrl() { |
|
||||||
return this.imgUrl; |
|
||||||
} |
|
||||||
|
|
||||||
public void setImgUrl(String imgUrl) { |
|
||||||
this.imgUrl = imgUrl; |
|
||||||
} |
|
||||||
|
|
||||||
public Float getNsfw() { |
|
||||||
return this.nsfw; |
|
||||||
} |
|
||||||
|
|
||||||
public void setNsfw(Float nsfw) { |
|
||||||
this.nsfw = nsfw; |
|
||||||
} |
|
||||||
|
|
||||||
public Float getSfw() { |
|
||||||
return this.sfw; |
|
||||||
} |
|
||||||
|
|
||||||
public void setSfw(Float sfw) { |
|
||||||
this.sfw = sfw; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,19 +0,0 @@ |
|||||||
package com.zwy.demo.models |
|
||||||
|
|
||||||
import androidx.lifecycle.MutableLiveData |
|
||||||
import com.zwy.demo.base.BaseViewModel |
|
||||||
import com.zwy.demo.dbbean.HomeTitle |
|
||||||
import com.zwy.demo.repositorys.AppRepository |
|
||||||
|
|
||||||
class MainViewModel constructor(val mAppRepository: AppRepository) : |
|
||||||
BaseViewModel() { |
|
||||||
|
|
||||||
var titles = MutableLiveData<List<HomeTitle>>() |
|
||||||
|
|
||||||
|
|
||||||
fun getTitles() { |
|
||||||
this.titles.value = mAppRepository.getHomeTitles() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
@ -1,87 +0,0 @@ |
|||||||
package com.zwy.demo.models |
|
||||||
|
|
||||||
import android.annotation.SuppressLint |
|
||||||
import android.app.Application |
|
||||||
import android.content.Context |
|
||||||
import android.graphics.BitmapFactory |
|
||||||
import androidx.lifecycle.MutableLiveData |
|
||||||
import com.bumptech.glide.Glide |
|
||||||
import com.zwy.demo.NSFWApplication |
|
||||||
import com.zwy.demo.base.BaseViewModel |
|
||||||
import com.zwy.demo.dbbean.ImageBean |
|
||||||
import com.zwy.demo.repositorys.AppRepository |
|
||||||
import com.zwy.demo.utils.AppLiveData |
|
||||||
import getNsfwScore |
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers |
|
||||||
import io.reactivex.schedulers.Schedulers |
|
||||||
import org.koin.java.KoinJavaComponent.inject |
|
||||||
|
|
||||||
class ScanPicViewModel constructor(val mAppRepository: AppRepository) : |
|
||||||
BaseViewModel() { |
|
||||||
|
|
||||||
|
|
||||||
var imgData = MutableLiveData<List<ImageBean>>() |
|
||||||
|
|
||||||
val context: Context by inject(Application::class.java) |
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("CheckResult") |
|
||||||
fun startScann(pageIndex: Int) { |
|
||||||
mAppRepository.startScann(pageIndex) |
|
||||||
.subscribeOn(Schedulers.io()) |
|
||||||
.doOnSubscribe { |
|
||||||
addSubscribe(it) |
|
||||||
appLiveData.value = |
|
||||||
AppLiveData(0, if (pageIndex == 0x03) "多图下载较慢,请耐心等待......." else "描中请稍后.......") |
|
||||||
} |
|
||||||
.map { |
|
||||||
return@map when (pageIndex) { |
|
||||||
0x01 -> { |
|
||||||
it.filter { |
|
||||||
val bitmap = |
|
||||||
BitmapFactory.decodeStream(context.resources.assets.open(it.imgUrl)) |
|
||||||
val nsfwScore = bitmap.getNsfwScore() |
|
||||||
it.nsfw = nsfwScore.nsfw |
|
||||||
it.sfw = nsfwScore.sfw |
|
||||||
bitmap.recycle() |
|
||||||
true |
|
||||||
} |
|
||||||
} |
|
||||||
0x02 -> { |
|
||||||
it |
|
||||||
} |
|
||||||
0x03 -> { |
|
||||||
it.filter { |
|
||||||
val nsfwBean = |
|
||||||
Glide.with(NSFWApplication.context).asBitmap().load(it.imgUrl) |
|
||||||
.submit().get().getNsfwScore() |
|
||||||
it.sfw = nsfwBean.sfw |
|
||||||
it.nsfw = nsfwBean.nsfw |
|
||||||
true |
|
||||||
} |
|
||||||
if (it.size > 10) it.subList(it.size - 10, it.size) |
|
||||||
else it |
|
||||||
|
|
||||||
} |
|
||||||
else -> { |
|
||||||
it |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
.observeOn(AndroidSchedulers.mainThread()) |
|
||||||
.subscribe({ |
|
||||||
appLiveData.value = AppLiveData(1, "") |
|
||||||
imgData.value = it |
|
||||||
}, { |
|
||||||
appLiveData.value = AppLiveData(1, "") |
|
||||||
print(it) |
|
||||||
}) |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
@ -1,16 +0,0 @@ |
|||||||
package com.zwy.demo.repositorys |
|
||||||
|
|
||||||
import com.zwy.demo.dbbean.ImageBean |
|
||||||
import io.reactivex.Observable |
|
||||||
import retrofit2.http.GET |
|
||||||
|
|
||||||
/** |
|
||||||
* 网络请求类 |
|
||||||
*/ |
|
||||||
interface ApiService { |
|
||||||
|
|
||||||
@GET("/imageList.do") |
|
||||||
fun getImageList(): Observable<List<ImageBean>> |
|
||||||
|
|
||||||
|
|
||||||
} |
|
@ -1,56 +0,0 @@ |
|||||||
package com.zwy.demo.repositorys |
|
||||||
|
|
||||||
import android.annotation.SuppressLint |
|
||||||
import android.app.Application |
|
||||||
import com.google.gson.Gson |
|
||||||
import com.zwy.demo.dbbean.HomeTitle |
|
||||||
import com.zwy.demo.dbbean.ImageBean |
|
||||||
import com.zwy.demo.utils.DBHelper |
|
||||||
import io.reactivex.Observable |
|
||||||
import org.koin.java.KoinJavaComponent.inject |
|
||||||
|
|
||||||
/** |
|
||||||
* 数据源 这里决定是从缓存获取还是从网络获取 |
|
||||||
*/ |
|
||||||
class AppRepository constructor( |
|
||||||
private val mApiService: ApiService, |
|
||||||
private val mDBHelper: DBHelper, |
|
||||||
val mGson: Gson |
|
||||||
) : |
|
||||||
Repository { |
|
||||||
|
|
||||||
val context: Application by inject(Application::class.java) |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取首页list标题 |
|
||||||
*/ |
|
||||||
override fun getHomeTitles(): List<HomeTitle> = mDBHelper.getTitles() |
|
||||||
|
|
||||||
/** |
|
||||||
* 扫描图片 |
|
||||||
*/ |
|
||||||
@SuppressLint("CheckResult") |
|
||||||
override fun startScann(index: Int): Observable<List<ImageBean>> { |
|
||||||
|
|
||||||
return when (index) { |
|
||||||
0x01 -> { |
|
||||||
val list = arrayListOf<ImageBean>() |
|
||||||
context.resources.assets.list("img")!!.forEach { |
|
||||||
list.add(ImageBean("img/$it", 0.0f, 0.0f)) |
|
||||||
} |
|
||||||
Observable.just(list) |
|
||||||
} |
|
||||||
0x02 -> { |
|
||||||
Observable.just(emptyList()) |
|
||||||
} |
|
||||||
0x03 -> { |
|
||||||
mApiService.getImageList() |
|
||||||
} |
|
||||||
else -> { |
|
||||||
Observable.just(emptyList()) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
@ -1,17 +0,0 @@ |
|||||||
package com.zwy.demo.repositorys |
|
||||||
|
|
||||||
import com.zwy.demo.dbbean.HomeTitle |
|
||||||
import com.zwy.demo.dbbean.ImageBean |
|
||||||
import io.reactivex.Observable |
|
||||||
|
|
||||||
interface Repository { |
|
||||||
/** |
|
||||||
* 获取首页list标题 |
|
||||||
*/ |
|
||||||
fun getHomeTitles(): List<HomeTitle> |
|
||||||
|
|
||||||
/** |
|
||||||
* 扫描图片 |
|
||||||
*/ |
|
||||||
fun startScann(index: Int): Observable<List<ImageBean>> |
|
||||||
} |
|
@ -1,40 +0,0 @@ |
|||||||
package com.zwy.demo.utils |
|
||||||
|
|
||||||
import android.app.Activity |
|
||||||
import android.app.Application |
|
||||||
import android.os.Bundle |
|
||||||
import android.view.View |
|
||||||
import androidx.appcompat.widget.AppCompatImageView |
|
||||||
import androidx.appcompat.widget.AppCompatTextView |
|
||||||
import com.zwy.demo.R |
|
||||||
|
|
||||||
class ActivityLifecycleCallback : Application.ActivityLifecycleCallbacks { |
|
||||||
override fun onActivityPaused(activity: Activity) { |
|
||||||
} |
|
||||||
|
|
||||||
override fun onActivityStarted(activity: Activity) { |
|
||||||
} |
|
||||||
|
|
||||||
override fun onActivityDestroyed(activity: Activity) { |
|
||||||
} |
|
||||||
|
|
||||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) { |
|
||||||
} |
|
||||||
|
|
||||||
override fun onActivityStopped(activity: Activity) { |
|
||||||
} |
|
||||||
|
|
||||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { |
|
||||||
} |
|
||||||
|
|
||||||
override fun onActivityResumed(activity: Activity) { |
|
||||||
activity.findViewById<AppCompatTextView>(R.id.actionBarTitle)?.text = activity.title |
|
||||||
|
|
||||||
activity.findViewById<AppCompatImageView>(R.id.iv_back).also { |
|
||||||
if (activity.title == "离线鉴黄") it?.visibility = View.GONE |
|
||||||
it?.setOnClickListener { |
|
||||||
activity.finish() |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,17 +0,0 @@ |
|||||||
package com.zwy.demo.utils |
|
||||||
|
|
||||||
/** |
|
||||||
* 常量 请求超时时间 |
|
||||||
*/ |
|
||||||
const val NETWORK_TIMEOUT = 60L |
|
||||||
|
|
||||||
/** |
|
||||||
* 常量 baseurl |
|
||||||
*/ |
|
||||||
const val BASE_URL = "http://114.116.213.202:7777" |
|
||||||
|
|
||||||
|
|
||||||
const val TAG = "鉴黄Demo日志" |
|
||||||
|
|
||||||
|
|
||||||
const val ParmKey2ScanPicAty = "ParmKey2ScanPicAty" |
|
@ -1,64 +0,0 @@ |
|||||||
package com.zwy.demo.utils |
|
||||||
|
|
||||||
import com.zwy.demo.NSFWApplication |
|
||||||
import com.zwy.demo.db.DaoMaster |
|
||||||
import com.zwy.demo.db.DaoSession |
|
||||||
import com.zwy.demo.dbbean.HomeTitle |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 数据库操作类 |
|
||||||
*/ |
|
||||||
class DBHelper private constructor(val mDaoSession: DaoSession) { |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取全部已缓存的图片列表 |
|
||||||
*/ |
|
||||||
fun getImageListFromDB() = mDaoSession.imageBeanDao.queryBuilder().list() |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取首页列表数据 |
|
||||||
*/ |
|
||||||
fun getTitles() = mDaoSession.homeTitleDao.queryBuilder().list() |
|
||||||
|
|
||||||
companion object { |
|
||||||
private var instance: DBHelper? = null |
|
||||||
get() { |
|
||||||
if (field == null) { |
|
||||||
field = DBHelper(initDB()) |
|
||||||
} |
|
||||||
return field |
|
||||||
} |
|
||||||
|
|
||||||
private fun initDB(): DaoSession { |
|
||||||
return DaoMaster( |
|
||||||
DaoMaster.DevOpenHelper( |
|
||||||
NSFWApplication.context, |
|
||||||
"nsfw_db" |
|
||||||
).writableDatabase |
|
||||||
).newSession().apply { |
|
||||||
//插入默认数据 |
|
||||||
if (this.homeTitleDao.queryBuilder().list().size == 0) { |
|
||||||
arrayListOf( |
|
||||||
"识别Assets目录图片", |
|
||||||
"识别相册图片", |
|
||||||
"实时扫描识别", |
|
||||||
"测试网络图片库中的大尺度资源", |
|
||||||
"我有资源贡献", |
|
||||||
"如果项目对您有帮助", |
|
||||||
"请给我一个Star吧" |
|
||||||
).forEach { |
|
||||||
System.out.println("数据写入成功") |
|
||||||
this.homeTitleDao.insert(HomeTitle(it)) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Synchronized |
|
||||||
fun get(): DBHelper { |
|
||||||
return instance!! |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,144 +0,0 @@ |
|||||||
package com.zwy.demo.utils |
|
||||||
|
|
||||||
import android.content.Intent |
|
||||||
import android.net.Uri |
|
||||||
import android.view.LayoutInflater |
|
||||||
import android.widget.ImageView |
|
||||||
import android.widget.LinearLayout |
|
||||||
import android.widget.TextView |
|
||||||
import androidx.cardview.widget.CardView |
|
||||||
import androidx.databinding.BindingAdapter |
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager |
|
||||||
import androidx.recyclerview.widget.RecyclerView |
|
||||||
import com.bumptech.glide.Glide |
|
||||||
import com.chad.library.adapter.base.BaseQuickAdapter |
|
||||||
import com.chad.library.adapter.base.animation.ScaleInAnimation |
|
||||||
import com.chad.library.adapter.base.viewholder.BaseViewHolder |
|
||||||
import com.zwy.demo.R |
|
||||||
import com.zwy.demo.dbbean.HomeTitle |
|
||||||
import com.zwy.demo.dbbean.ImageBean |
|
||||||
import com.zwy.demo.views.ScanPicActivity |
|
||||||
import org.jetbrains.anko.startActivity |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 首页列表适配器填充 |
|
||||||
*/ |
|
||||||
@BindingAdapter("bindHomeData") |
|
||||||
fun RecyclerView.bindData(data: List<HomeTitle>?) { |
|
||||||
|
|
||||||
val mContext = this.context |
|
||||||
|
|
||||||
val homeAdapter = |
|
||||||
object : |
|
||||||
BaseQuickAdapter<HomeTitle, BaseViewHolder>(R.layout.tem_home, data?.toMutableList()) { |
|
||||||
override fun convert(holder: BaseViewHolder, item: HomeTitle) { |
|
||||||
holder.setText(R.id.tv_title, item.title) |
|
||||||
} |
|
||||||
} |
|
||||||
homeAdapter.animationEnable = true |
|
||||||
homeAdapter.isAnimationFirstOnly = false |
|
||||||
homeAdapter.adapterAnimation = ScaleInAnimation() |
|
||||||
|
|
||||||
homeAdapter.addHeaderView(LayoutInflater.from(mContext) |
|
||||||
.inflate(R.layout.item_home_head, LinearLayout(mContext)).apply { |
|
||||||
findViewById<TextView>(R.id.tv_info).text = |
|
||||||
mContext.getString(R.string.versionstr, PackageUtils.getVersionName(mContext)) |
|
||||||
}) |
|
||||||
|
|
||||||
homeAdapter.addFooterView(LayoutInflater.from(mContext) |
|
||||||
.inflate(R.layout.item_home_head, LinearLayout(mContext)).apply { |
|
||||||
this.setPadding(20, 0, 20, 0) |
|
||||||
findViewById<TextView>(R.id.tv_info).apply { |
|
||||||
setTextColor(mContext.resources.getColor(R.color.red)) |
|
||||||
text = context.getString(R.string.nsfw_info) |
|
||||||
} |
|
||||||
}) |
|
||||||
|
|
||||||
this.layoutManager = LinearLayoutManager(mContext) |
|
||||||
this.adapter = homeAdapter |
|
||||||
|
|
||||||
homeAdapter.setOnItemClickListener { adapter, view, position -> |
|
||||||
when (position) { |
|
||||||
0 -> { |
|
||||||
//识别Assets目录 |
|
||||||
mContext.startActivity<ScanPicActivity>(ParmKey2ScanPicAty to 0x01) |
|
||||||
} |
|
||||||
1 -> { |
|
||||||
//识别相册 |
|
||||||
mContext.startActivity<ScanPicActivity>(ParmKey2ScanPicAty to 0x02) |
|
||||||
} |
|
||||||
2 -> { |
|
||||||
//实时扫描 |
|
||||||
} |
|
||||||
3 -> { |
|
||||||
//Api获取图片测试 |
|
||||||
mContext.startActivity<ScanPicActivity>(ParmKey2ScanPicAty to 0x03) |
|
||||||
} |
|
||||||
4 -> { |
|
||||||
//上传文件 |
|
||||||
} |
|
||||||
5 -> { |
|
||||||
//跳转GitHub首页 |
|
||||||
mContext.startActivity( |
|
||||||
Intent( |
|
||||||
Intent.ACTION_VIEW, |
|
||||||
Uri.parse("https://github.com/devzwy/open_nsfw_android") |
|
||||||
) |
|
||||||
) |
|
||||||
} |
|
||||||
6 -> { |
|
||||||
//跳转GitHub首页 |
|
||||||
mContext.startActivity( |
|
||||||
Intent( |
|
||||||
Intent.ACTION_VIEW, |
|
||||||
Uri.parse("https://github.com/devzwy/open_nsfw_android") |
|
||||||
) |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 首页列表适配器填充 |
|
||||||
*/ |
|
||||||
@BindingAdapter("bindScanPicListData") |
|
||||||
fun RecyclerView.bindData2(data: List<ImageBean>?) { |
|
||||||
|
|
||||||
val mContext = this.context |
|
||||||
|
|
||||||
val pathBase = "file:///android_asset/" |
|
||||||
val scannAdapter = |
|
||||||
object : |
|
||||||
BaseQuickAdapter<ImageBean, BaseViewHolder>( |
|
||||||
R.layout.item_scann, |
|
||||||
data?.toMutableList() |
|
||||||
) { |
|
||||||
override fun convert(holder: BaseViewHolder, item: ImageBean) { |
|
||||||
holder.getView<TextView>(R.id.tv_sss).apply { |
|
||||||
text = "NSFW 分值:${item.nsfw} \nSFW 分值:${item.sfw}" |
|
||||||
// textColorResource = if (item.nsfw > 0.5) R.color.white else R.color.colorPrimary |
|
||||||
} |
|
||||||
holder.getView<CardView>(R.id.cardview) |
|
||||||
.setBackgroundResource(if (item.nsfw > 0.5) R.color.nsfw else R.color.colorPrimary) |
|
||||||
val imageView = holder.getView<ImageView>(R.id.iv_item) |
|
||||||
if (item.imgUrl.contains("http")) { |
|
||||||
Glide.with(imageView).load(item.imgUrl).into(imageView) |
|
||||||
} else { |
|
||||||
Glide.with(imageView).load("${pathBase}${item.imgUrl}").into(imageView) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
scannAdapter.animationEnable = true |
|
||||||
scannAdapter.isAnimationFirstOnly = false |
|
||||||
scannAdapter.adapterAnimation = ScaleInAnimation() |
|
||||||
|
|
||||||
|
|
||||||
this.layoutManager = LinearLayoutManager(mContext) |
|
||||||
this.adapter = scannAdapter |
|
||||||
|
|
||||||
} |
|
||||||
|
|
@ -1,77 +0,0 @@ |
|||||||
package com.zwy.demo.utils |
|
||||||
|
|
||||||
import android.content.Context |
|
||||||
import android.content.pm.PackageManager |
|
||||||
|
|
||||||
object PackageUtils { |
|
||||||
/** |
|
||||||
* 获取版本名称 |
|
||||||
* |
|
||||||
* @param context 上下文 |
|
||||||
* |
|
||||||
* @return 版本名称 |
|
||||||
*/ |
|
||||||
fun getVersionName(context: Context): String? { |
|
||||||
|
|
||||||
//获取包管理器 |
|
||||||
val pm = context.packageManager |
|
||||||
//获取包信息 |
|
||||||
try { |
|
||||||
val packageInfo = |
|
||||||
pm.getPackageInfo(context.packageName, 0) |
|
||||||
//返回版本号 |
|
||||||
return packageInfo.versionName |
|
||||||
} catch (e: PackageManager.NameNotFoundException) { |
|
||||||
e.printStackTrace() |
|
||||||
} |
|
||||||
return null |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取版本号 |
|
||||||
* |
|
||||||
* @param context 上下文 |
|
||||||
* |
|
||||||
* @return 版本号 |
|
||||||
*/ |
|
||||||
fun getVersionCode(context: Context): Int { |
|
||||||
|
|
||||||
//获取包管理器 |
|
||||||
val pm = context.packageManager |
|
||||||
//获取包信息 |
|
||||||
try { |
|
||||||
val packageInfo = |
|
||||||
pm.getPackageInfo(context.packageName, 0) |
|
||||||
//返回版本号 |
|
||||||
return packageInfo.versionCode |
|
||||||
} catch (e: PackageManager.NameNotFoundException) { |
|
||||||
e.printStackTrace() |
|
||||||
} |
|
||||||
return 0 |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取App的名称 |
|
||||||
* |
|
||||||
* @param context 上下文 |
|
||||||
* |
|
||||||
* @return 名称 |
|
||||||
*/ |
|
||||||
fun getAppName(context: Context): String? { |
|
||||||
val pm = context.packageManager |
|
||||||
//获取包信息 |
|
||||||
try { |
|
||||||
val packageInfo = |
|
||||||
pm.getPackageInfo(context.packageName, 0) |
|
||||||
//获取应用 信息 |
|
||||||
val applicationInfo = packageInfo.applicationInfo |
|
||||||
//获取albelRes |
|
||||||
val labelRes = applicationInfo.labelRes |
|
||||||
//返回App的名称 |
|
||||||
return context.resources.getString(labelRes) |
|
||||||
} catch (e: PackageManager.NameNotFoundException) { |
|
||||||
e.printStackTrace() |
|
||||||
} |
|
||||||
return null |
|
||||||
} |
|
||||||
} |
|
@ -1,4 +0,0 @@ |
|||||||
package com.zwy.demo.utils |
|
||||||
|
|
||||||
|
|
||||||
data class AppLiveData(var type: Int = -1, var text: String = "") |
|
@ -1,25 +0,0 @@ |
|||||||
package com.zwy.demo.utils |
|
||||||
|
|
||||||
import android.app.Activity |
|
||||||
import com.luck.picture.lib.PictureSelector |
|
||||||
import com.luck.picture.lib.config.PictureConfig |
|
||||||
import com.luck.picture.lib.config.PictureMimeType |
|
||||||
|
|
||||||
/** |
|
||||||
* 相册选择 |
|
||||||
*/ |
|
||||||
fun Activity.selectImgFromD(requestCode: Int) { |
|
||||||
PictureSelector.create(this) |
|
||||||
.openGallery(PictureMimeType.ofImage())//全部.ofAll()、图片.、视频.ofVideo()、音频.ofAudio() |
|
||||||
.maxSelectNum(if (requestCode == 0) 20 else 1)// 最大图片选择数量 int |
|
||||||
.minSelectNum(1)// 最小选择数量 int |
|
||||||
.imageSpanCount(3)// 每行显示个数 int |
|
||||||
.selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选 or PictureConfig.SINGLE |
|
||||||
.previewImage(true)// 是否可预览图片 true or false |
|
||||||
.isCamera(false)// 是否显示拍照按钮 true or false |
|
||||||
.isZoomAnim(true)// 图片列表点击 缩放效果 默认true |
|
||||||
// .selectionMedia(selectList) |
|
||||||
.sizeMultiplier(0.5f)// glide 加载图片大小 0~1之间 如设置 .glideOverride()无效 |
|
||||||
.previewEggs(true)// 预览图片时 是否增强左右滑动图片体验(图片滑动一半即可看到上一张是否选中) true or false |
|
||||||
.forResult(requestCode);//结果回调onActivityResult code } |
|
||||||
} |
|
@ -1,74 +0,0 @@ |
|||||||
package com.zwy.demo.views |
|
||||||
|
|
||||||
import android.app.Activity |
|
||||||
import android.os.Bundle |
|
||||||
import com.zwy.demo.R |
|
||||||
import com.zwy.demo.base.BaseActivity |
|
||||||
import com.zwy.demo.databinding.MainLayoutBinding |
|
||||||
import com.zwy.demo.models.MainViewModel |
|
||||||
import d |
|
||||||
import org.jetbrains.anko.toast |
|
||||||
import java.io.File |
|
||||||
import java.io.FileOutputStream |
|
||||||
import java.io.IOException |
|
||||||
import java.io.InputStream |
|
||||||
|
|
||||||
class MainActivity : BaseActivity<MainLayoutBinding, MainViewModel>() { |
|
||||||
/** |
|
||||||
* 初始化根布局 |
|
||||||
* |
|
||||||
* @return 布局layout的id |
|
||||||
*/ |
|
||||||
override fun initContentView(savedInstanceState: Bundle?): Int = R.layout.activity_main |
|
||||||
|
|
||||||
|
|
||||||
override fun initData() { |
|
||||||
binding.titles = viewModel.titles |
|
||||||
viewModel.getTitles() |
|
||||||
// copyAssetsFile2Phone(this,"nsfw.tflite") |
|
||||||
} |
|
||||||
|
|
||||||
private var mExitTime: Long = 0 |
|
||||||
|
|
||||||
override fun onBackPressed() { |
|
||||||
if (System.currentTimeMillis() - mExitTime < 2000) { |
|
||||||
super.onBackPressed(); |
|
||||||
} else { |
|
||||||
mExitTime = System.currentTimeMillis(); |
|
||||||
toast("再按一次返回键退出应用") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
// /** |
|
||||||
// * 将文件从assets目录,考贝到 /data/data/包名/files/ 目录中。assets 目录中的文件,会不经压缩打包至APK包中,使用时还应从apk包中导出来 |
|
||||||
// * @param fileName 文件名,如aaa.txt |
|
||||||
// */ |
|
||||||
// fun copyAssetsFile2Phone(activity: Activity, fileName: String) { |
|
||||||
// try { |
|
||||||
// val inputStream: InputStream = activity.assets.open(fileName) |
|
||||||
// //getFilesDir() 获得当前APP的安装路径 /data/data/包名/files 目录 |
|
||||||
// val file = File( |
|
||||||
// activity.filesDir.absolutePath + File.separator.toString() + fileName |
|
||||||
// ) |
|
||||||
// if (!file.exists() || file.length()==0L) { |
|
||||||
// val fos = FileOutputStream(file) //如果文件不存在,FileOutputStream会自动创建文件 |
|
||||||
// var len = -1 |
|
||||||
// val buffer = ByteArray(1024) |
|
||||||
// while (inputStream.read(buffer).also({ len = it }) != -1) { |
|
||||||
// fos.write(buffer, 0, len) |
|
||||||
// } |
|
||||||
// fos.flush() //刷新缓存区 |
|
||||||
// inputStream.close() |
|
||||||
// fos.close() |
|
||||||
// "模型文件复制完毕".d() |
|
||||||
// } else { |
|
||||||
// "模型文件已存在,无需复制".d() |
|
||||||
// } |
|
||||||
// } catch (e: IOException) { |
|
||||||
// e.printStackTrace() |
|
||||||
// } |
|
||||||
// } |
|
||||||
|
|
||||||
|
|
||||||
} |
|
@ -1,77 +0,0 @@ |
|||||||
package com.zwy.demo.views |
|
||||||
|
|
||||||
import android.Manifest |
|
||||||
import android.os.Bundle |
|
||||||
import com.zwy.demo.R |
|
||||||
import com.zwy.demo.base.BaseActivity |
|
||||||
import com.zwy.demo.databinding.ScanPicBindingView |
|
||||||
import com.zwy.demo.models.ScanPicViewModel |
|
||||||
import com.zwy.demo.utils.ParmKey2ScanPicAty |
|
||||||
import com.zwy.demo.utils.selectImgFromD |
|
||||||
import pub.devrel.easypermissions.EasyPermissions |
|
||||||
import pub.devrel.easypermissions.PermissionRequest |
|
||||||
|
|
||||||
class ScanPicActivity : BaseActivity<ScanPicBindingView, ScanPicViewModel>() { |
|
||||||
|
|
||||||
val requestCode = 0x01 |
|
||||||
private fun _requestPermissions() { |
|
||||||
if (!EasyPermissions.hasPermissions( |
|
||||||
this, |
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE |
|
||||||
) |
|
||||||
) { |
|
||||||
EasyPermissions.requestPermissions( |
|
||||||
PermissionRequest.Builder( |
|
||||||
this, |
|
||||||
0x01, |
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE |
|
||||||
).build() |
|
||||||
) |
|
||||||
return |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
override fun initData() { |
|
||||||
_requestPermissions() |
|
||||||
binding.dataList = viewModel.imgData |
|
||||||
intent.getIntExtra(ParmKey2ScanPicAty, 0x00).let { |
|
||||||
if (it == 1 || it == 3) |
|
||||||
viewModel.startScann(it) |
|
||||||
else selectImgFromD(requestCode) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 初始化根布局 |
|
||||||
* |
|
||||||
* @return 布局layout的id |
|
||||||
*/ |
|
||||||
override fun initContentView(savedInstanceState: Bundle?): Int = R.layout.activity_scan_pic |
|
||||||
|
|
||||||
|
|
||||||
// override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { |
|
||||||
// super.onActivityResult(requestCode, resultCode, data) |
|
||||||
// if (requestCode == 0x01 && resultCode == RESULT_OK) { |
|
||||||
// PictureSelector.obtainMultipleResult(data)?.let { |
|
||||||
// mMainAdapter.setNewData(null) |
|
||||||
// Toast.makeText(this, "请稍等...", Toast.LENGTH_LONG).show() |
|
||||||
// } |
|
||||||
// Thread(Runnable { |
|
||||||
// selectList?.forEach { |
|
||||||
// val file = File(it.path) |
|
||||||
// val nsfwScore = file.getNsfwScore() |
|
||||||
// addDataToAdapter( |
|
||||||
// MyNsfwBean( |
|
||||||
// nsfwScore.sfw, |
|
||||||
// nsfwScore.nsfw, |
|
||||||
// it.path, |
|
||||||
// BitmapFactory.decodeStream(file.inputStream()) |
|
||||||
// ) |
|
||||||
// ) |
|
||||||
// } |
|
||||||
// }).start() |
|
||||||
// |
|
||||||
// } |
|
||||||
// } |
|
||||||
} |
|
||||||
|
|
@ -1,11 +0,0 @@ |
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
android:width="24dp" |
|
||||||
android:height="24dp" |
|
||||||
android:viewportWidth="24" |
|
||||||
android:viewportHeight="24" |
|
||||||
android:tint="#FFFFFF" |
|
||||||
android:alpha="0.8"> |
|
||||||
<path |
|
||||||
android:fillColor="@android:color/white" |
|
||||||
android:pathData="M11.67,3.87L9.9,2.1 0,12l9.9,9.9 1.77,-1.77L3.54,12z"/> |
|
||||||
</vector> |
|
Before Width: | Height: | Size: 163 B |
Before Width: | Height: | Size: 121 B |
Before Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 291 B |
@ -1,45 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"> |
|
||||||
|
|
||||||
<data class="MainLayoutBinding"> |
|
||||||
|
|
||||||
<import type="com.zwy.demo.dbbean.HomeTitle" /> |
|
||||||
|
|
||||||
<import type="java.util.List" /> |
|
||||||
|
|
||||||
<import type="androidx.lifecycle.MutableLiveData" /> |
|
||||||
|
|
||||||
<variable |
|
||||||
name="titles" |
|
||||||
type="MutableLiveData<List<HomeTitle>>" /> |
|
||||||
</data> |
|
||||||
|
|
||||||
<RelativeLayout xmlns:tools="http://schemas.android.com/tools" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="match_parent" |
|
||||||
tools:context=".views.MainActivity"> |
|
||||||
|
|
||||||
|
|
||||||
<include layout="@layout/include_actionbar" /> |
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView |
|
||||||
bindHomeData="@{titles}" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="match_parent" |
|
||||||
android:layout_above="@+id/tv_b" |
|
||||||
android:layout_below="@+id/mActionBar" |
|
||||||
android:background="@color/bgmain" /> |
|
||||||
|
|
||||||
<TextView |
|
||||||
android:id="@+id/tv_b" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:background="@color/blackT" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_alignParentBottom="true" |
|
||||||
android:gravity="center" |
|
||||||
android:padding="5dp" |
|
||||||
android:text="@string/info" |
|
||||||
android:textColor="@color/black" |
|
||||||
android:textSize="12sp" /> |
|
||||||
</RelativeLayout> |
|
||||||
</layout> |
|
@ -1,30 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"> |
|
||||||
|
|
||||||
<data class="ScanPicBindingView"> |
|
||||||
|
|
||||||
<import type="com.zwy.demo.dbbean.ImageBean" /> |
|
||||||
|
|
||||||
<import type="java.util.List" /> |
|
||||||
|
|
||||||
<import type="androidx.lifecycle.MutableLiveData" /> |
|
||||||
|
|
||||||
<variable |
|
||||||
name="dataList" |
|
||||||
type="MutableLiveData<List<ImageBean>>" /> |
|
||||||
</data> |
|
||||||
|
|
||||||
<RelativeLayout |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="match_parent"> |
|
||||||
|
|
||||||
<include layout="@layout/include_actionbar" /> |
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView |
|
||||||
android:background="@color/bgmain" |
|
||||||
bindScanPicListData="@{dataList}" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="match_parent" |
|
||||||
android:layout_below="@+id/mActionBar" /> |
|
||||||
</RelativeLayout> |
|
||||||
</layout> |
|
@ -1,23 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
android:id="@+id/mActionBar" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="?attr/actionBarSize" |
|
||||||
android:layout_alignParentTop="true" |
|
||||||
android:background="@color/colorPrimary"> |
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView |
|
||||||
android:id="@+id/iv_back" |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_centerVertical="true" |
|
||||||
android:layout_marginLeft="15dp" |
|
||||||
android:background="@drawable/ic_back" /> |
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView |
|
||||||
android:id="@+id/actionBarTitle" |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_centerInParent="true" |
|
||||||
android:textColor="#ffffff" /> |
|
||||||
</RelativeLayout> |
|
@ -1,16 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_margin="10dp" |
|
||||||
android:layout_marginTop="5dp"> |
|
||||||
|
|
||||||
<TextView |
|
||||||
android:id="@+id/tv_info" |
|
||||||
android:layout_width="wrap_content" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_centerInParent="true" |
|
||||||
android:text="当前版本号:1.0.0" |
|
||||||
android:lineSpacingExtra="10dp" |
|
||||||
android:textColor="@color/colorPrimary" /> |
|
||||||
</RelativeLayout> |
|
@ -1,35 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:layout_marginLeft="5dp" |
|
||||||
android:id="@+id/cardview" |
|
||||||
android:layout_marginRight="5dp" |
|
||||||
android:layout_marginTop="5dp" |
|
||||||
android:background="@color/white"> |
|
||||||
|
|
||||||
<LinearLayout |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:orientation="horizontal"> |
|
||||||
|
|
||||||
<ImageView |
|
||||||
android:id="@+id/iv_item" |
|
||||||
android:layout_width="120dp" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:scaleType="centerCrop" |
|
||||||
android:layout_alignParentLeft="true" |
|
||||||
android:minHeight="120dp" |
|
||||||
android:padding="10dp" |
|
||||||
android:src="@mipmap/launch" /> |
|
||||||
|
|
||||||
<TextView |
|
||||||
android:id="@+id/tv_sss" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="wrap_content" |
|
||||||
android:textColor="@color/white" |
|
||||||
android:layout_gravity="center" |
|
||||||
android:gravity="left" /> |
|
||||||
</LinearLayout> |
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView> |
|
@ -1,15 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:background="@color/white" |
|
||||||
android:layout_marginLeft="5dp" |
|
||||||
android:layout_marginRight="5dp" |
|
||||||
android:layout_marginBottom="5dp" |
|
||||||
android:layout_height="50dp"> |
|
||||||
|
|
||||||
<TextView |
|
||||||
android:id="@+id/tv_title" |
|
||||||
android:layout_width="match_parent" |
|
||||||
android:layout_height="match_parent" |
|
||||||
android:gravity="center" /> |
|
||||||
</androidx.cardview.widget.CardView> |
|
Before Width: | Height: | Size: 83 KiB |
@ -1,14 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<resources> |
|
||||||
<color name="colorPrimary">#2196F3</color> |
|
||||||
<color name="colorPrimaryDark">#00B0FF</color> |
|
||||||
<color name="colorAccent">#03DAC5</color> |
|
||||||
<color name="bgmain">#FAFAFA</color> |
|
||||||
<color name="white">#FAFAFA</color> |
|
||||||
<color name="black">#202020</color> |
|
||||||
<color name="red">#F30606</color> |
|
||||||
<color name="blackT">#50202020</color> |
|
||||||
|
|
||||||
<color name="nsfw">#F33D03</color> |
|
||||||
|
|
||||||
</resources> |
|
@ -1,9 +0,0 @@ |
|||||||
<resources> |
|
||||||
<string name="app_name">Demo</string> |
|
||||||
<string name="main_aty_name">离线鉴黄</string> |
|
||||||
<string name="info">所有图片均来源百度,如有侵权请联系我删除</string> |
|
||||||
<string name="nsfw_info">网络接收图像并给出输出概率(分数在0-1之间),该概率可用于过滤不适合工作图像的图像。得分小于 0.2表示该图像很可能是安全的。得分大于 0.8表示该图像很有可能是NSFW。中间范围的分数可以针对不同的NSFW级别进行分类。 |
|
||||||
根据数据集,用例和图像类型,我们建议开发人员选择合适的阈值。由于问题的困难性质,会出现错误,具体取决于NSFW的用例/定义/容忍度。理想情况下,开发人员应根据对他们的应用程序安全的定义来创建评估集,然后按原样使用模型拟合ROC曲线以选择合适的阈值。</string> |
|
||||||
<string name="versionstr">当前最新版本:%s</string> |
|
||||||
<string name="myscan">自定义扫描</string> |
|
||||||
</resources> |
|
@ -1,12 +0,0 @@ |
|||||||
<resources> |
|
||||||
|
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> |
|
||||||
<!-- Customize your theme here. --> |
|
||||||
<item name="colorPrimary">@color/colorPrimary</item> |
|
||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> |
|
||||||
<item name="colorAccent">@color/colorAccent</item> |
|
||||||
<item name="android:windowContentOverlay">@null</item> |
|
||||||
<item name="android:windowBackground">@android:color/white</item> |
|
||||||
</style> |
|
||||||
|
|
||||||
</resources> |
|
@ -1,4 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||||
<network-security-config> |
|
||||||
<base-config cleartextTrafficPermitted="true" /> |
|
||||||
</network-security-config> |
|