diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 6090c84a..f97b9142 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -17,6 +17,7 @@ android {
targetSdk = 34
versionCode = 38
versionName = "2.8.2"
+ multiDexEnabled = true
}
buildTypes {
@@ -70,6 +71,9 @@ android {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
+ packagingOptions.resources.excludes.add("META-INF/*")
+ packagingOptions.resources.excludes.add("mozilla/*")
+ packagingOptions.resources.excludes.add("META-INF/*/*")
kotlinOptions {
jvmTarget = "1.8"
@@ -105,6 +109,8 @@ dependencies {
implementation("com.github.delight-im:Android-AdvancedWebView:v3.2.1")
implementation(project(":library"))
implementation(project(":utils"))
+// implementation ("org.apache.tika:tika-parsers:1.12")
+
implementation ("androidx.media:media:1.7.0")
// implementation ("me.everything:providers-android:1.0.1")
// implementation ("me.everything:providers-core:1.0.1")
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c68d50b6..ded19f3d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -72,7 +72,7 @@
android:enableOnBackInvokedCallback="true"
android:largeHeap="true"
android:networkSecurityConfig="@xml/network_security_config"
- android:hardwareAccelerated="true"
+ android:hardwareAccelerated="false"
android:usesCleartextTraffic="true"
android:screenOrientation="nosensor"
android:windowSoftInputMode="adjustResize"
@@ -191,11 +191,22 @@
-
+
+
+
+
+
+
+
+
+
+
+
= ArrayList()
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ LogUtil.e("intent >>>> ${intent}")
+ if (intent.action.equals(Intent.ACTION_VIEW)) {
+ intent.data.toString()?.let {
+ loadWithIntent = true
+ load(it)
+ }
+ } else {
+ loadWithIntent = false
+ }
+ }
+
override fun onResume() {
super.onResume()
webView?.setOnGenericMotionListener(this)
}
+ override fun onNewIntent(intent: Intent?) {
+ super.onNewIntent(intent)
+ if (intent?.action?.equals(Intent.ACTION_VIEW) == true) {
+ intent?.data?.toString()?.let {
+ loadWithIntent = true
+ load(it)
+ }
+ } else {}
+ }
+
var lasteventTime = 0L
override fun onGenericMotion(p0: View?, ev: MotionEvent?): Boolean {
if (ev?.device?.name?.contains("SM-031N Mouse") == true) {
@@ -172,15 +202,30 @@ class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListene
}
fun vote(){
- Blog.LOGE("Arrow Center Click")
- WorkersDb.getRealm().apply {
- writeBlocking {
- val result = query().query("originPage == $0", rssId).find()
- if(result.size > 0) {
- result.forEach { it.vote = true }
+ if (!loadWithIntent) {
+
+ Blog.LOGE("Arrow Center Click")
+ WorkersDb.getRealm().apply {
+ writeBlocking {
+ val result = query().query("originPage == $0", rssId).find()
+ if (result.size > 0) {
+ result.forEach { it.vote = true }
+ }
}
}
+ webView?.evaluateJavascript("document.documentElement.outerHTML",
+ object : ValueCallback {
+ override fun onReceiveValue(value: String?) {
+ val html = value?.replace("\\u003C", "<")
+ onHtml(html, false)
+ }
+ })
+ } else {
+ finish()
}
+ }
+
+ fun doNextPage() {
rssList.remove(rssId)
if (currentIdx < rssList.size - 1) {
currentIdx += 1
@@ -198,31 +243,21 @@ class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListene
}
registCancelSearch()
}
+
fun hideRss() {
- Blog.LOGE("make no show")
- WorkersDb.getRealm().apply {
- writeBlocking {
- val result =
- query().query("originPage == $0", rssId)
- .find()
- if (result.size > 0) {
- result.forEach { it.read += 5 }
+ if (!loadWithIntent) {
+ Blog.LOGE("make no show")
+ WorkersDb.getRealm().apply {
+ writeBlocking {
+ val result =
+ query().query("originPage == $0", rssId)
+ .find()
+ if (result.size > 0) {
+ result.forEach { it.read += 5 }
+ }
}
}
- }
- rssList.remove(rssId)
- if (currentIdx < rssList.size - 1) {
- currentIdx += 1
- rssId = rssList.get(currentIdx)
- Blog.LOGE("Arrow Right Click ${currentIdx} ${rssId}")
- load(rssId)
- registCancelSearch()
- } else if (currentIdx > 0) {
- currentIdx -= 1
- rssId = rssList.get(currentIdx)
- Blog.LOGE("Arrow Left Click ${currentIdx} ${rssId}")
- load(rssId)
- registCancelSearch()
+ doNextPage()
} else {
finish()
}
@@ -265,13 +300,23 @@ class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListene
override var pdfListner : PDFPrint.OnPDFPrintListener? = object : PDFPrint.OnPDFPrintListener {
override fun onSuccess(file: File?) {
LogUtil.e("file.absolutePath >>> ${file?.absolutePath}")
+
+ Toast.makeText(
+ applicationContext,
+ resources.getString(
+ stringResPhotoSavedTo
+ ) + file?.absolutePath,
+ Toast.LENGTH_LONG
+ ).apply {
+
+ }.show()
}
override fun onError(exception: Exception?) {
}
}
-
+// val tika: Tika = Tika()
override fun dispatchGenericMotionEvent(ev: MotionEvent?): Boolean {
if (ev?.device?.name?.contains("BLE-M3") == true) {
Blog.LOGE("keyEvent >>>>> dispatchGenericMotionEvent ${ev}")
@@ -344,6 +389,7 @@ class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListene
registCancelSearch()
}
protected fun load(newUrl: String) {
+ LogUtil.e("newUrl >>> ${newUrl}")
newUrl.toUri().host?.let {
val splits = it.replace("http://","").replace("https://","").split(".")
when(splits.size) {
@@ -380,81 +426,332 @@ class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListene
}
}
- override fun onHtml(value: String?) {
+ fun ByteArray.toHex() = joinToString(separator = "") { byte -> "%02x".format(byte) }
+
+ fun hashString(str: String, algorithm: String): ByteArray =
+ MessageDigest.getInstance(algorithm).digest(str.toByteArray(UTF_8))
+
+ fun getBase64ImageData(fileName : String) : String {
+ val inputStream: InputStream =
+ FileInputStream(fileName) // You can get an inputStream using any I/O API
+ val bytes: ByteArray
+ val buffer = ByteArray(8192)
+ var bytesRead: Int
+ val output = ByteArrayOutputStream()
+
+ try {
+ while ((inputStream.read(buffer).also { bytesRead = it }) != -1) {
+ output.write(buffer, 0, bytesRead)
+ }
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+
+ bytes = output.toByteArray()
+ return Base64.encodeToString(bytes, Base64.DEFAULT)
+ }
+
+ fun run(value : String, autoCheck : Boolean) {
+ webView!!.setOnScrollChangeListener(null)
+ var mediaUrls = arrayListOf()
+ mediaUrls.addAll(this.mediaUrls)
+ CookieSyncManager.createInstance(applicationContext)
+ CookieSyncManager.getInstance().sync()
+ val cookieManager =
+ CookieManager.getInstance()
+ val cookie =
+ cookieManager.getCookie(webView!!.url)
+
val agent = webView!!.settings.userAgentString
val current = webView!!.url
+ val newPath = hashString(current!!, "MD5").toHex()
+
CoroutineScope(Dispatchers.IO).launch {
- mediaUrls.forEach {
+ LogUtil.e("onHtml value >> ${value}")
+ val path = File(
+ Environment.getExternalStorageDirectory(),
+ "bums"
+ )
+ val filePath = "index.html"
+ val newFolder = File(path, newPath).apply { mkdirs() }
+ var htmlString = trimHtnl(value!!)
+ val targetFile = File(newFolder, filePath)
+ var reqCount = 0
+ var endOfLooPCheck = false
+ var urlPathMap = hashMapOf()
+ var newFile = File(
+ path,
+ newPath.plus(SimpleDateFormat("yyyMMdd").format(Date())).plus(".html")
+ )
+ fun moveFile() {
+ indexSave(htmlString, targetFile)
+
+ targetFile.copyTo(newFile)
+ if (targetFile.parentFile.isDirectory) {
+ targetFile.parentFile.listFiles().forEach {
+ it.delete()
+ }
+ targetFile.parentFile.delete()
+ }
+ targetFile.delete()
+ }
+ fun enofLoop() {
+ CoroutineScope(Dispatchers.IO).launch {
+ LogUtil.e("on it enofLoop")
+ urlPathMap.forEach { t, u ->
+ val file = File(u)
+ var contentsUriString = FileProvider.getUriForFile(
+ this@RssViewerActivity,
+ "${this@RssViewerActivity.packageName}.fileprovider",
+ file
+ ).toString()
+
+
+// try {
+// val detectedType: String = tika.detect(file)
+// e("Detected type: $detectedType")
+// } catch (e: IOException) {
+// e("Error detecting type: " + e.message)
+// }
+ var targetString = t
+ var targetIdx = htmlString.indexOf(targetString)
+ if (targetIdx > 0) {
+ htmlString?.replace(
+ targetIdx,
+ targetIdx.plus(targetString.length),
+ contentsUriString
+ )
+ }
+ targetString = t.replace("&", "&")
+ targetIdx = htmlString.indexOf(targetString)
+ if (targetIdx > 0) {
+ htmlString?.replace(
+ targetIdx,
+ targetIdx.plus(targetString.length),
+ contentsUriString
+ )
+ }
+ }
+
+ if (autoCheck) {
+ LogUtil.e("on it enofLoop autoCheck ${autoCheck}")
+ webView?.postDelayed({
+ hideBlock()
+ webView?.setOnScrollChangeListener(null)
+ moveFile()
+ startActivity(Intent(this@RssViewerActivity,RssViewerActivity::class.java).apply {
+ action = Intent.ACTION_VIEW
+ data = FileProvider.getUriForFile(
+ this@RssViewerActivity,
+ "${this@RssViewerActivity.packageName}.fileprovider",
+ newFile
+ )
+ })
+ }, defaultTime.times(4))
+ } else {
+ runOnUiThread {
+ moveFile()
+ Toast.makeText(
+ applicationContext,
+ resources.getString(
+ stringResPhotoSavedTo
+ ) + targetFile.absolutePath,
+ Toast.LENGTH_LONG
+ ).show()
+ hideBlock()
+ doNextPage()
+ LogUtil.e("on it enofLoop autoCheck ${autoCheck}")
+ }
+ }
+ }
+
+ }
+
+ val lDownFinishListener = object : DownFinishListener {
+ override fun onDownFinish(url: String, path: String) {
+ LogUtil.e("Url >> ${url} path >> ${path}")
+ urlPathMap.put(url, path)
+ reqCount -= 1
+ if (reqCount == 0 && endOfLooPCheck) {
+ enofLoop()
+ }
+ }
+
+ override fun onError() {
+ if (showToastPhotoSavedOrFailed) {
+ Toast.makeText(
+ applicationContext,
+ resources.getString(
+ stringResPhotoSaveFailed
+ ),
+ Toast.LENGTH_LONG
+ ).show()
+ }
+ reqCount -= 1
+ if (reqCount == 0 && endOfLooPCheck) {
+ enofLoop()
+ }
+ }
+ }
+
+ mediaUrls.forEach { url ->
+ var downPic = false
try {
- LogUtil.e("try Jsoup.parse ${it}")
- Jsoup.parse(URL(it), 3000)?.let {
+ LogUtil.e("try Jsoup.parse ${url}")
+ Jsoup.parse(URL(url), defaultTime.times(4).toInt()).let {
try {
LogUtil.e("onit Jsoup.parse ${it.title()}")
- it.getElementsByTag("video")?.forEach {
- it.attribute("src").value?.let {
- var url = if (it.startsWith("http")) {
- it
- } else {
- "https:".plus(it)
+ if (it.select("svg").size > 0) {
+ try {
+ downPic(url, agent, current!!, cookie!!, lDownFinishListener)
+ reqCount += 1
+ } catch (e : Exception) {
+ e.printStackTrace()
+ }
+ } else {
+ it.getElementsByTag("video")?.forEach {
+ it.attribute("src").value?.let {
+ var url = if (it.startsWith("http")) {
+ it
+ } else {
+ "https:".plus(it)
+ }
+ try {
+ downMp4(url, agent, current!!, cookie!!, lDownFinishListener)
+ reqCount += 1
+ } catch (e : Exception) {
+ e.printStackTrace()
+ }
+
}
-
- val cookieManager =
- CookieManager.getInstance()
- val cookie =
- cookieManager.getCookie(current)
- DownPicUtil.downMp4(
- File(
- Environment.getExternalStorageDirectory(),
- "bums"
- ).path,
- url,
- agent,
- current,
- cookie,
- object : DownFinishListener {
- override fun onDownFinish(path: String) {
- if (showToastPhotoSavedOrFailed) {
- Toast.makeText(
- applicationContext,
- resources.getString(
- stringResPhotoSavedTo
- ) + path,
- Toast.LENGTH_LONG
- ).show()
- }
- // 最后通知图库更新
- applicationContext.sendBroadcast(
- Intent(
- Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
- Uri.parse("file://$path")
- )
- )
- }
-
- override fun onError() {
- if (showToastPhotoSavedOrFailed) {
- Toast.makeText(
- applicationContext,
- resources.getString(
- stringResPhotoSaveFailed
- ),
- Toast.LENGTH_LONG
- ).show()
- }
- }
- })
}
}
- } catch (e : UnsupportedMimeTypeException) {
-
- } catch (e : Exception){}
+ } catch (e: UnsupportedMimeTypeException) {
+ LogUtil.e("e.message3 ${e.message}")
+ } catch (e: Exception) {
+ LogUtil.e("e.message4 ${e.message}")
+ }
}
- } catch (e : UnsupportedMimeTypeException) {
+ } catch (e: UnsupportedMimeTypeException) {
+ LogUtil.e("e.message ${e.message}")
+ LogUtil.e("e.message ${e.localizedMessage}")
+ if (e.message?.contains("Must be text") == true) {
+ downPic = true
+ }
+ } catch (e: Exception) {
+ if (url.contains("dcimg") == true) {
+ downPic = true
+ }
+ LogUtil.e("e.message2 ${e.message}")
+ } finally {
+ if (downPic) {
+ try {
+ downPic(url, agent, current!!, cookie!!, lDownFinishListener)
+ reqCount += 1
+ } catch (e : Exception) {
+ e.printStackTrace()
+ }
- } catch (e : Exception){}
+ }
+ }
+ sleep(defaultTime)
+ }
+ LogUtil.e("END OF LOOP ${reqCount}")
+ endOfLooPCheck = true
+ if (reqCount <= 0) {
+ webView?.postDelayed({
+ enofLoop()
+ },defaultTime.times(4))
}
}
}
+ val defaultTime = 200L
+ override fun onHtml(value: String?, autoCheck : Boolean) {
+ chechHandler.removeCallbacks(cancelSearch)
+ if (loadWithIntent){
+ return
+ }
+ showBlock()
+ var count = (webView!!.contentHeight / (webView!!.height * 0.3).toInt())
+ LogUtil.e("count >>>> ${count} webView!!.contentHeight >>>> ${webView!!.contentHeight} , webView!!.height >>>> ${webView!!.height} :: ${(webView!!.height * 0.3).toInt()}")
+ webView!!.postDelayed({
+ webView!!.pageDown(false)
+
+ },defaultTime)
+
+
+ webView!!.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
+ val measuredHeight: Int = v.measuredHeight
+ if(measuredHeight + scrollY == webView!!.computeVerticalScrollRange()){
+ webView!!.postDelayed({
+ webView!!.evaluateJavascript("document.documentElement.outerHTML",object : ValueCallback {
+ override fun onReceiveValue(value: String?) {
+ val html = value?.replace("\\u003C", "<")
+ this@RssViewerActivity.run(html!!, autoCheck)
+ }
+ })
+ },defaultTime.times(2))
+ } else {
+ webView!!.postDelayed({
+ webView!!.pageDown(false)
+ },defaultTime)
+ }
+ }
+ }
+
+ fun trimHtnl(target : String) : StringBuffer {
+ var result = target.replace("\\\"","\"").replace("\\n\\t\\t\\t","").replace("\\n\\t\\t","").replace("\\n\\t","").replace("\\t", "").replace("\\n", "").replace("\"\"\"","").replace("href=\"//","href=\"https://").replace("src=\"//","src=\"https://").replace("url(\"//","url(\"https://").replace("url("//","url("https://")
+ if (host?.contains("clien") == true) {
+ result = result.replace("href=\"/service","href=\"https://m.clien.net/service").replace("href=\"\\"/service","href=\"\\"https://m.clien.net/service")
+ }
+ return StringBuffer(result)
+ }
+
+
+ fun indexSave(htmlString:StringBuffer, targetFile :File) {
+ BufferedWriter(FileWriter(targetFile)).use { writer ->
+ trimHtnl(htmlString.toString())?.let { result ->
+ writer.write(result.toString())
+ }
+ }
+ }
+
+ fun downMp4(url : String, agent : String, current : String,cookie : String, listner :DownFinishListener) {
+ LogUtil.e("try imageFile down ${url}")
+ val path = File(
+ Environment.getExternalStorageDirectory(),
+ "bums"
+ )
+ DownPicUtil.downMp4(
+ File(
+ path,"private_mp4"
+ ).path,
+ url,
+ agent,
+ current,
+ cookie,
+ listner
+ )
+ }
+ fun downPic( url : String, agent : String, current : String,cookie : String, listner :DownFinishListener) {
+ LogUtil.e("try imageFile down ${url}")
+ val cookieManager =
+ CookieManager.getInstance()
+ val cookie =
+ cookieManager.getCookie(current)
+ val path = File(
+ Environment.getExternalStorageDirectory(),
+ "bums"
+ )
+
+ DownPicUtil.downPic(
+ File(path, "private_img").path,
+ url,
+ agent,
+ current,
+ cookie,
+ listner)
+ }
override fun webviewOnPageFinished() {
double = false
if(hasYoutubePlayer) {
@@ -473,14 +770,35 @@ class RssViewerActivity : AwesomeWebViewActivity(), View.OnGenericMotionListene
}
}
registCancelSearch()
-
+ //
+ if (loadWithIntent) {
+ webView?.evaluateJavascript(
+ "try{document.querySelector('meta[name=viewport]').setAttribute('content','initial-scale=1.0')}catch(e){}",
+ null
+ )
+ webView?.evaluateJavascript(
+ "try{document.querySelector('meta[name=viewport]').setAttribute('content','initial-scale=1.0')}catch(e){}",
+ null
+ )
+ webView?.settings?.useWideViewPort = true
+ }
if (webView?.url?.contains("dcinside") == true){
webView?.evaluateJavascript("try{document.querySelector('#div_adnmore_area').hidden = true;}catch(e){}",null)
} else if(webView?.url?.contains("fmkorea") == true) {
- webView?.postDelayed({
- webView?.evaluateJavascript("try{document.querySelector('.m_rd_nav_side').hidden = true;}catch(e){}",null)
- webView?.evaluateJavascript("try{document.querySelector(\"[class*='bd bd_mobile ']\").remove();}catch(e){}",null)
- },500L)
+ if (loadWithIntent) {
+
+ } else {
+ webView?.postDelayed({
+ webView?.evaluateJavascript(
+ "try{document.querySelector('.m_rd_nav_side').hidden = true;}catch(e){}",
+ null
+ )
+ webView?.evaluateJavascript(
+ "try{document.querySelector('[class*='bd bd_mobile ']').remove();}catch(e){}",
+ null
+ )
+ }, 500L)
+ }
}
}
}
\ No newline at end of file
diff --git a/library/build.gradle.kts b/library/build.gradle.kts
index 892b769a..73490f77 100644
--- a/library/build.gradle.kts
+++ b/library/build.gradle.kts
@@ -41,6 +41,7 @@ dependencies {
implementation ("androidx.annotation:annotation:1.9.1")
implementation ("androidx.appcompat:appcompat:1.7.0")
implementation ("com.google.android.material:material:1.12.0")
+// implementation ("org.apache.tika:tika-parsers:1.24")
// implementation ("com.nineoldandroids:library:2.4.0")
implementation ("androidx.core:core-ktx:1.15.0")
implementation(project(":utils"))
diff --git a/library/src/main/java/kr/lunaticbum/awesomewebview/AwesomeWebViewActivity.kt b/library/src/main/java/kr/lunaticbum/awesomewebview/AwesomeWebViewActivity.kt
index 03412f9b..050f3271 100644
--- a/library/src/main/java/kr/lunaticbum/awesomewebview/AwesomeWebViewActivity.kt
+++ b/library/src/main/java/kr/lunaticbum/awesomewebview/AwesomeWebViewActivity.kt
@@ -99,6 +99,7 @@ import kotlin.math.abs
open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
Handler.Callback {
+ var loadWithIntent : Boolean = false
var mediaUrls = arrayListOf()
protected var key: Int = 0
@@ -258,7 +259,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
// protected var back: AppCompatImageButton? = null
// protected var forward: AppCompatImageButton? = null
// protected var more: AppCompatImageButton? = null
- protected var webView: WebView? = null
+ protected var webView: VideoEnabledWebView? = null
protected var webChromeClient: WebChromeClient? = null
protected var webViewClient: WebViewClient? = null
// protected var gradient: View? = null
@@ -577,7 +578,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
fun fast() {
chechHandler.removeCallbacks(cancelSearch)
- chechHandler.postDelayed(cancelSearch, 6000L)
+ chechHandler.postDelayed(cancelSearch, 90000L)
}
fun registCancelSearch() {
@@ -799,12 +800,14 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
LogUtil.e("hitTestResult.type >>> ${hitTestResult.type}")
LogUtil.e("hitTestResult.extra >>> ${hitTestResult.extra}")
+ LogUtil.e("hitTestResult >>> ${mediaUrls.size}")
if(hitTestResult.type==0) {
- webView?.evaluateJavascript("document.getElementsByTagName('iframe')",
+
+ webView?.evaluateJavascript("document.documentElement.outerHTML",
object : ValueCallback {
override fun onReceiveValue(value: String?) {
val html = value?.replace("\\u003C", "<")
- onHtml(html)
+ onHtml(html, true)
}
})
}
@@ -839,7 +842,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
webView!!.url,
cookie,
object : DownFinishListener {
- override fun onDownFinish(path: String) {
+ override fun onDownFinish(url : String ,path: String) {
if (showToastPhotoSavedOrFailed) {
Toast.makeText(
applicationContext,
@@ -1243,11 +1246,19 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
}
}
- open protected fun onHtml(value: String?) {
+ open protected fun onHtml(value: String?, autoCheck : Boolean) {
}
- protected fun buildWebView(): WebView {
+ protected fun showBlock() {
+ binding.blocking.visibility = View.VISIBLE
+ }
+
+ protected fun hideBlock() {
+ binding.blocking.visibility = View.GONE
+ }
+
+ protected fun buildWebView(): VideoEnabledWebView {
return VideoEnabledWebView(this)
}
@@ -1874,10 +1885,10 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
+
var skipResource =
(host != null) && ((request.url?.host?.contains(host!!) ?: true) == false)
if (skipResource && request.url.toString().contains("gif")) {
- LogUtil.e("shouldInterceptRequest request block gif resource >>> ${request.url.toString()}")
return WebResourceResponse(
"text/plain", "utf-8",
ByteArrayInputStream("".toByteArray())
@@ -1885,13 +1896,27 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
}
val url = request.url.toString()
+ if (url.contains("streamable.com") ||
+ url.contains("img-cdn.theqoo") ||
+ url.contains("embed/player/") ||
+ url.contains("dcinside.co.kr/viewimage") ||
+ url.contains("daumcdn.net/cafeattach") ||
+ url.toLowerCase(Locale.ROOT).contains(".jpg") ||
+ url.toLowerCase(Locale.ROOT).contains(".png") ||
+ url.toLowerCase(Locale.ROOT).contains(".gif") ||
+ url.toLowerCase(Locale.ROOT).contains(".svg") ||
+ url.toLowerCase(Locale.ROOT).contains(".webp")) {
+ mediaUrls.add(url)
+ LogUtil.e("mediaUrls >>>>> add(${url})")
+ }
+
if(!hasYoutubePlayer) {
hasYoutubePlayer = url.toLowerCase(Locale.ROOT)
.contains("https://www.youtube.com/s/player".toLowerCase(Locale.ROOT))
}
- if (url.contains("streamable.com")) {
- mediaUrls.add(url)
- }
+
+ //https://t1.daumcdn.net/cafeattach/mEr9/adc6e81a386099c4cc06f77f8b7eea15675de0d4
+
if (url.toLowerCase(Locale.ROOT)
.contains("ads".toLowerCase(Locale.ROOT))) {
LogUtil.e("shouldInterceptRequest request url contains ads >>> ${request.url.toString()}")
@@ -1900,7 +1925,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
val adblock = adblockKeyWords.filter { url.toLowerCase(Locale.ROOT).contains(it.toLowerCase(Locale.ROOT)) }.size > 0
return if(adblock) {
try {
- LogUtil.e("shouldInterceptRequest request block adblockKeyWords resource >>> ${request.url.toString()}")
+// LogUtil.e("shouldInterceptRequest request block adblockKeyWords resource >>> ${request.url.toString()}")
WebResourceResponse("text/plain", "utf-8", ByteArrayInputStream("".toByteArray()))
} catch (e : Exception) {
super.shouldInterceptRequest(view, url)
@@ -1909,7 +1934,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
try {
val bitmap = Glide.with(this@AwesomeWebViewActivity).asBitmap().timeout(30000).diskCacheStrategy(DiskCacheStrategy.ALL).load(url).submit().get()
WebResourceResponse("image/jpg", "UTF-8",getBitmapInputStream(bitmap,Bitmap.CompressFormat.JPEG)).apply {
- LogUtil.e("shouldInterceptRequest request url down from Glide >>> ${request.url.toString()}")
+// LogUtil.e("shouldInterceptRequest request url down from Glide >>> ${request.url.toString()}")
}
} catch (e : Exception) {
super.shouldInterceptRequest(view, url)
@@ -1918,7 +1943,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
try {
val bitmap = Glide.with(this@AwesomeWebViewActivity).asBitmap().timeout(30000).diskCacheStrategy(DiskCacheStrategy.ALL).load(url).submit().get()
WebResourceResponse("image/png", "UTF-8",getBitmapInputStream(bitmap,Bitmap.CompressFormat.PNG)).apply {
- LogUtil.e("shouldInterceptRequest request url down from Glide >>> ${request.url.toString()}")
+// LogUtil.e("shouldInterceptRequest request url down from Glide >>> ${request.url.toString()}")
}
} catch (e : Exception) {
super.shouldInterceptRequest(view, url)
@@ -1950,6 +1975,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
// }
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
+ mediaUrls.clear()
BroadCastManager.onPageStarted(this@AwesomeWebViewActivity, key, url)
if (!url.contains("docs.google.com") && url.endsWith(".pdf")) {
webView!!.loadUrl("http://docs.google.com/gview?embedded=true&url=$url")
@@ -1973,7 +1999,9 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
BroadCastManager.onPageFinished(this@AwesomeWebViewActivity, key, url)
if (updateTitleFromHtml) binding.toolbarContent.title.text = view.title
- binding.toolbarContent.url.text = UrlParser.getHost(url)
+ try {
+ binding.toolbarContent.url.text = UrlParser.getHost(url)
+ }catch (e :Exception) {e.printStackTrace()}
requestCenterLayout()
if (view.canGoBack() || view.canGoForward()) {
@@ -2006,7 +2034,7 @@ open class AwesomeWebViewActivity : AppCompatActivity(), View.OnClickListener,
handler.sendEmptyMessage(MSG_CLICK_ON_URL)
var skipResource = host!= null && ((url.contains(host!!) ?: true) == false) && (host!!.contains("google") == false)
- if (skipResource) {
+ if (skipResource || loadWithIntent) {
LogUtil.e("shouldOverrideUrlLoading block url $url , host >>>> $host ")
val alertDialog = AlertDialog.Builder(view.context).create()
alertDialog.setCancelable(false)
diff --git a/library/src/main/java/kr/lunaticbum/awesomewebview/helpers/DownPicUtil.java b/library/src/main/java/kr/lunaticbum/awesomewebview/helpers/DownPicUtil.java
index f1ad5519..e4f84d42 100644
--- a/library/src/main/java/kr/lunaticbum/awesomewebview/helpers/DownPicUtil.java
+++ b/library/src/main/java/kr/lunaticbum/awesomewebview/helpers/DownPicUtil.java
@@ -4,9 +4,14 @@ package kr.lunaticbum.awesomewebview.helpers;
* Created by wuzongheng on 2018/2/18.
*/
+import static java.sql.DriverManager.println;
+
+import android.media.MediaMetadataRetriever;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.text.TextUtils;
+import android.util.Log;
import androidx.annotation.Nullable;
@@ -19,6 +24,11 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import kr.lunaticbum.utils.log.LogUtil;
/**
* 图片下载的工具类
@@ -46,6 +56,10 @@ public class DownPicUtil {
}
loadPic(file.getPath(), url, userAgent, referer, cookie, downFinishListener, false);
} else {
+ File file = new File(path);
+ if (!file.exists()) {
+ file.mkdirs();
+ }
loadPic(path, url, userAgent, referer, cookie, downFinishListener, false);
}
}
@@ -59,24 +73,53 @@ public class DownPicUtil {
}
loadPic(file.getPath(), url, userAgent, referer, cookie, downFinishListener, true);
} else {
+ File file = new File(path);
+ if (!file.exists()) {
+ file.mkdirs();
+ }
loadPic(path, url, userAgent, referer, cookie, downFinishListener, true);
}
}
+ public static String toHex(byte[] bytes) {
+ StringBuilder sb = new StringBuilder();
+ for (byte b : bytes) {
+ sb.append(String.format("%02x", b));
+ }
+ return sb.toString();
+ }
+
+ public static byte[] hashString(String str, String algorithm) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance(algorithm);
+ return digest.digest(str.getBytes(StandardCharsets.UTF_8));
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
private static void loadPic(final String filePath, final String url, final String userAgent, final String referer, final String cookie, final DownFinishListener downFinishListener, boolean isMp4) {
new AsyncTask(){
String fileName;
InputStream is;
OutputStream out;
-
+ private String replaceDcUrl(String origin) {
+ String result = origin;
+ for (int i = 0; i < 20; i++) {
+ result = result.replace(String.format("dcimg%d.",i),"dcimg2.");
+ }
+ return result;
+ }
@Override
protected String doInBackground(Void... voids) {
// 原文件名
String[] split = url.split("/");
- fileName = split[split.length - 1];
+ byte[] dd = hashString(url, "MD5");
+ fileName = dd == null ? split[split.length - 1] : toHex(dd);
// 创建目标文件,使用时间戳作为临时文件名,确保可以不重复
String now = String.valueOf(System.currentTimeMillis());
@@ -90,7 +133,13 @@ public class DownPicUtil {
byte[] image = base64ImgHelper.decode();
is = new ByteArrayInputStream(image); //处理服务器的响应结果
} else {
- URL picUrl = new URL(url);
+ URL picUrl = null;
+ if (url.contains("dcimg")) {
+ picUrl = new URL(replaceDcUrl(url));
+ } else {
+ picUrl = new URL(url);
+ }
+
//通过图片的链接打开输入流
HttpURLConnection httpURLConnection = (HttpURLConnection) picUrl.openConnection();
httpURLConnection.setConnectTimeout(10000); //设置连接超时时间
@@ -99,13 +148,26 @@ public class DownPicUtil {
httpURLConnection.setDoOutput(false); //Get请求不需要DoOutPut
httpURLConnection.setRequestMethod("GET"); //设置以Get方式请求数据
httpURLConnection.setUseCaches(false); //不使用缓存
+
//设置请求体的类型是文本类型
+
+// if (url.contains("dcimg")) {
+//// httpURLConnection.setRequestProperty("authority", Uri.parse(url).getHost());
+// httpURLConnection.setRequestProperty("Accept", "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8");
+// httpURLConnection.setRequestProperty("Accept-encoding", "gzip, deflate, br, zstd");
+// httpURLConnection.setRequestProperty("Sec-Fetch-Dest","image");
+// httpURLConnection.setRequestProperty("Sec-Fetch-Mode","no-cors");
+// httpURLConnection.setRequestProperty("Sec-Fetch-Site","cross-site");
+// }
+
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+
if (!TextUtils.isEmpty(userAgent)) {
httpURLConnection.setRequestProperty("User-Agent", userAgent);
}
if (!TextUtils.isEmpty(referer)) {
httpURLConnection.setRequestProperty("Referer", referer);
+ println("referer>>>> " + referer);
}
if (!TextUtils.isEmpty(cookie)) {
httpURLConnection.setRequestProperty("Cookie", cookie);
@@ -148,9 +210,7 @@ public class DownPicUtil {
// 提取文件格式真实拓展名
String extension = FormatHelper.getExtension(picFile);
- if (isMp4) {
- extension = "mp4";
- }
+
// 提取不包含拓展名的原文件名
String[] extensions = fileName.split("\\.");
int splitLength = extensions.length;
@@ -160,6 +220,9 @@ public class DownPicUtil {
} else {
newFileNameNoExtension = fileName;
}
+ if (isVideoFileByMetadata(picFile) && extension == null && isMp4) {
+ extension = "mp4";
+ }
// 重命名文件
if (extension == null) {
@@ -171,21 +234,24 @@ public class DownPicUtil {
// 无拓展名,整个文件名递增重命名
return renamePic(picFile, filePath, newFileNameNoExtension, null, MODE.MODE_INCREMENT);
}
+ } else {
+ return renamePic(picFile, filePath, newFileNameNoExtension, extension, MODE.MODE_IGNORE);
}
// 支持解析的格式,使用md5文件名、真实拓展名
- String md5 = Md5Helper.getFileMD5ToString(picFile);
- if (TextUtils.isEmpty(md5)) {
- return renamePic(picFile, filePath, newFileNameNoExtension, extension, MODE.MODE_INCREMENT);
- } else {
- return renamePic(picFile, filePath, md5.substring(0, 16), extension, MODE.MODE_IGNORE);
- }
+// return picFile.getPath();
+// String md5 = Md5Helper.getFileMD5ToString(picFile);
+// if (TextUtils.isEmpty(md5)) {
+// return renamePic(picFile, filePath, newFileNameNoExtension, extension, MODE.MODE_INCREMENT);
+// } else {
+// return renamePic(picFile, filePath, md5.substring(0, 16), extension, MODE.MODE_IGNORE);
+// }
}
@Override
protected void onPostExecute(String path) {
super.onPostExecute(path);
if(path!=null){
- downFinishListener.onDownFinish(path);
+ downFinishListener.onDownFinish(url,path);
} else {
downFinishListener.onError();
}
@@ -208,6 +274,26 @@ public class DownPicUtil {
MODE_OVERRIDE
}
+
+ private static Boolean isVideoFileByMetadata(File file) {
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ try {
+ retriever.setDataSource(file.getAbsolutePath());
+ println("retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE) >>> " + retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE));
+ String duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
+ return duration != null;
+ } catch (Exception e) {
+ return false;
+ } finally {
+ try {
+ retriever.release();
+ } catch (IOException e) {
+
+ e.printStackTrace();
+ }
+ }
+ }
+
private static String renamePic(File picFile, String filePath, String newFileNameNoExtension, String extension, MODE mode) {
String extensionWithPoint = TextUtils.isEmpty(extension)? "": "." + extension;
String newFileName = newFileNameNoExtension + extensionWithPoint;
@@ -262,7 +348,7 @@ public class DownPicUtil {
//下载完成回调的接口
public interface DownFinishListener{
- void onDownFinish(String path);
+ void onDownFinish(String srcUrl ,String path);
void onError();
}
}
\ No newline at end of file
diff --git a/library/src/main/java/kr/lunaticbum/awesomewebview/helpers/FormatHelper.java b/library/src/main/java/kr/lunaticbum/awesomewebview/helpers/FormatHelper.java
index 58d166aa..d3b317b5 100644
--- a/library/src/main/java/kr/lunaticbum/awesomewebview/helpers/FormatHelper.java
+++ b/library/src/main/java/kr/lunaticbum/awesomewebview/helpers/FormatHelper.java
@@ -6,6 +6,8 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import kr.lunaticbum.utils.log.LogUtil;
+
public class FormatHelper {
private FormatHelper() {
@@ -13,6 +15,7 @@ public class FormatHelper {
public static String getExtension(File file) {
try {
+
// long fileLength = file.length();
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
@@ -81,7 +84,34 @@ public class FormatHelper {
start[5] == (byte) 0x61) {
return "gif";
}
+ bufferedInputStream.reset();
+ start = new byte[6];
+ bufferedInputStream.read(start);
+ if (start[0] == (byte) 0x47 &&
+ start[1] == (byte) 0x49 &&
+ start[2] == (byte) 0x46 &&
+ start[3] == (byte) 0x38 &&
+ start[4] == (byte) 0x37 &&
+ start[5] == (byte) 0x61) {
+ return "gif";
+ }
+ bufferedInputStream.reset();
+ start = new byte[100];
+ bufferedInputStream.read(start);
+ String xmlDeclaration = new String(start, 0, 100, "UTF-8");
+ LogUtil.INSTANCE.e("Path " + file.getAbsolutePath() + " ::: HEADE" + xmlDeclaration + ";");
+ if (xmlDeclaration.contains("") ||
+ xmlDeclaration.contains("http://www.w3.org/2000/svg")) {
+ return "svg";
+ }else if (xmlDeclaration.contains("iso") &&
+ xmlDeclaration.contains("mp4")) {
+ return "mp4";
+ }
+ bufferedInputStream.reset();
+
+
+ LogUtil.INSTANCE.e("Path " + file.getAbsolutePath() + " ::: HEADE" + start[0] + "," + start[1] + "," + start[2] + "," + start[3] + "," + start[4] + "," + start[5] + ";");
bufferedInputStream.close();
fileInputStream.close();
} catch (FileNotFoundException e) {
diff --git a/library/src/main/java/kr/lunaticbum/awesomewebview/views/VideoEnabledWebView.java b/library/src/main/java/kr/lunaticbum/awesomewebview/views/VideoEnabledWebView.java
index eb3e4ff1..f7b665e8 100644
--- a/library/src/main/java/kr/lunaticbum/awesomewebview/views/VideoEnabledWebView.java
+++ b/library/src/main/java/kr/lunaticbum/awesomewebview/views/VideoEnabledWebView.java
@@ -97,5 +97,54 @@ public class VideoEnabledWebView extends WebView
videoJsHelper.addJavascriptInterface(this);
super.loadUrl(url, additionalHttpHeaders);
}
+ private boolean topReached = false;
+ private boolean bottomReached = false;
+ @Override
+ public int computeVerticalScrollRange() {
+
+ int readerViewHeight = getMeasuredHeight();
+
+ int verticalScrollRange = super.computeVerticalScrollRange();
+
+
+ if (readerViewHeight >= verticalScrollRange) {
+
+ topReached = true;
+
+ bottomReached = true;
+
+ }
+
+ return verticalScrollRange;
+ }
+
+ @Override
+ public void onScrollChanged(int newLeft, int newTop, int oldLeft, int oldTop) {
+
+
+ topReached = false;
+
+ bottomReached = false;
+
+
+ int readerViewHeight = getMeasuredHeight();
+
+ int contentHeight = getContentHeight();
+
+ if (newTop == 0) {
+
+
+ topReached = true;
+
+ } else if (newTop + readerViewHeight >= contentHeight) {
+
+
+ bottomReached = true;
+
+ }
+
+ super.onScrollChanged(newLeft, newTop, oldLeft, oldTop);
+
+ }
}
diff --git a/library/src/main/res/layout/awesome_web_view.xml b/library/src/main/res/layout/awesome_web_view.xml
index 1c96e60d..6a0d9d12 100644
--- a/library/src/main/res/layout/awesome_web_view.xml
+++ b/library/src/main/res/layout/awesome_web_view.xml
@@ -82,6 +82,31 @@
android:visibility="invisible" /> -->
+
+
+
+
\ No newline at end of file
diff --git a/utils/src/androidTest/java/com/thefinestartist/utils/ApplicationTest.java b/utils/src/androidTest/java/com/thefinestartist/utils/ApplicationTest.java
deleted file mode 100644
index 89235ec2..00000000
--- a/utils/src/androidTest/java/com/thefinestartist/utils/ApplicationTest.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.thefinestartist.utils;
-
-import android.app.Application;
-import android.test.ApplicationTestCase;
-
-/**
- * Testing Fundamentals
- */
-public class ApplicationTest extends ApplicationTestCase {
- public ApplicationTest() {
- super(Application.class);
- }
-}
\ No newline at end of file
diff --git a/utils/src/androidTest/java/com/thefinestartist/utils/etc/PreferencesUtilTest.java b/utils/src/androidTest/java/com/thefinestartist/utils/etc/PreferencesUtilTest.java
deleted file mode 100755
index 959a050f..00000000
--- a/utils/src/androidTest/java/com/thefinestartist/utils/etc/PreferencesUtilTest.java
+++ /dev/null
@@ -1,278 +0,0 @@
-package com.thefinestartist.utils.etc;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import kr.lunaticbum.Base;
-import kr.lunaticbum.utils.preferences.PreferencesUtil;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Tests of the {@link PreferencesUtil} class.
- *
- * @author Robin Gustafsson
- */
-public class PreferencesUtilTest extends AndroidTestCase {
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- Base.initialize(getContext());
- }
-
- @SmallTest
- public void testSetGetDefaultName() {
- final String expected = "TEST_DEFAULT_NAME";
-
- PreferencesUtil.setDefaultName(expected);
- String actual = PreferencesUtil.getDefaultName();
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testDifferentNames() {
- final String name1 = "TEST_DIFFERENTNAMES_NAME1";
- final String name2 = "TEST_DIFFERENTNAMES_NAME2";
- final String key = "TEST_DIFFERENTNAMES_KEY";
- final boolean value = true;
- final boolean expected = false;
-
- PreferencesUtil.put(name1, key, value);
- boolean actual = PreferencesUtil.get(name2, key, expected);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreBoolean() {
- final String key = "TEST_BOOLEAN";
- final boolean expected = true;
- final boolean defValue = false;
-
- PreferencesUtil.put(key, expected);
- boolean actual = PreferencesUtil.get(key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreBooleanNamed() {
- final String name = "TEST_NAMED";
- final String key = "TEST_BOOLEAN";
- final boolean expected = true;
- final boolean defValue = false;
-
- PreferencesUtil.put(name, key, expected);
- boolean actual = PreferencesUtil.get(name, key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreInt() {
- final String key = "TEST_INT";
- final int expected = 321;
- final int defValue = 0;
-
- PreferencesUtil.put(key, expected);
- int actual = PreferencesUtil.get(key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreIntNamed() {
- final String name = "TEST_NAMED";
- final String key = "TEST_INT";
- final int expected = 321;
- final int defValue = 0;
-
- PreferencesUtil.put(name, key, expected);
- int actual = PreferencesUtil.get(name, key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreFloat() {
- final String key = "TEST_FLOAT";
- final float expected = 12.3f;
- final float defValue = 0.0f;
-
- PreferencesUtil.put(key, expected);
- float actual = PreferencesUtil.get(key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreFloatNamed() {
- final String name = "TEST_NAMED";
- final String key = "TEST_FLOAT";
- final float expected = 12.3f;
- final float defValue = 0.0f;
-
- PreferencesUtil.put(name, key, expected);
- float actual = PreferencesUtil.get(name, key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreLong() {
- final String key = "TEST_LONG";
- final long expected = 321L;
- final long defValue = 0L;
-
- PreferencesUtil.put(key, expected);
- long actual = PreferencesUtil.get(key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreLongNamed() {
- final String name = "TEST_NAMED";
- final String key = "TEST_LONG";
- final long expected = 321L;
- final long defValue = 0L;
-
- PreferencesUtil.put(name, key, expected);
- long actual = PreferencesUtil.get(name, key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreString() {
- final String key = "TEST_STRING";
- final String expected = "Lorem ipsum";
- final String defValue = null;
-
- PreferencesUtil.put(key, expected);
- String actual = PreferencesUtil.get(key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreStringNamed() {
- final String name = "TEST_NAMED";
- final String key = "TEST_STRING";
- final String expected = "Lorem ipsum";
- final String defValue = null;
-
- PreferencesUtil.put(name, key, expected);
- String actual = PreferencesUtil.get(name, key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreStringSet() {
- final String key = "TEST_STRINGSET";
- final Set expected = new HashSet<>();
- expected.add("Lorem ipsum");
- expected.add("dolor sit amet");
- expected.add("consectetur adipiscing elit");
- final Set defValue = null;
-
- PreferencesUtil.put(key, expected);
- Set actual = PreferencesUtil.get(key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testStoreStringSetNamed() {
- final String name = "TEST_NAMED";
- final String key = "TEST_STRINGSET";
- final Set expected = new HashSet<>();
- expected.add("Lorem ipsum");
- expected.add("dolor sit amet");
- expected.add("consectetur adipiscing elit");
- final Set defValue = null;
-
- PreferencesUtil.put(name, key, expected);
- Set actual = PreferencesUtil.get(name, key, defValue);
- assertEquals(expected, actual);
- }
-
- @MediumTest
- public void testStoreSerializable() {
- final String key = "TEST_SERIALIZABLE";
- final ArrayList expected = new ArrayList<>();
- expected.add("Lorem ipsum");
- expected.add("dolor sit amet");
- expected.add("consectetur adipiscing elit");
- final ArrayList defValue = new ArrayList<>();
- defValue.add("Proin mollis dictum");
-
- PreferencesUtil.put(key, expected);
- ArrayList actual = PreferencesUtil.get(key, defValue);
- assertEquals(expected, actual);
- }
-
- @MediumTest
- public void testStoreSerializableNamed() {
- final String name = "TEST_NAMED";
- final String key = "TEST_SERIALIZABLE";
- final ArrayList expected = new ArrayList<>();
- expected.add("Lorem ipsum");
- expected.add("dolor sit amet");
- expected.add("consectetur adipiscing elit");
- final ArrayList defValue = new ArrayList<>();
- defValue.add("Proin mollis dictum");
-
- PreferencesUtil.put(name, key, expected);
- ArrayList actual = PreferencesUtil.get(name, key, defValue);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testRemove() {
- final String key = "TEST_REMOVE";
- final String expected = null;
-
- PreferencesUtil.put(key, "Lorem ipsum");
- PreferencesUtil.remove(key);
- String actual = PreferencesUtil.get(key, expected);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testRemoveNamed() {
- final String name = "TEST_NAMED";
- final String key = "TEST_REMOVE";
- final String expected = null;
-
- PreferencesUtil.put(name, key, "Lorem ipsum");
- PreferencesUtil.remove(name, key);
- String actual = PreferencesUtil.get(name, key, expected);
- assertEquals(expected, actual);
- }
-
- @SmallTest
- public void testClear() {
- final String[] keys = {"TEST_REMOVE_1", "TEST_REMOVE_2", "TEST_REMOVE_2"};
- final String expected = null;
-
- for (String key : keys) {
- PreferencesUtil.put(key, "Lorem ipsum");
- }
- PreferencesUtil.clear();
- for (String key : keys) {
- String actual = PreferencesUtil.get(key, expected);
- assertEquals(expected, actual);
- }
- }
-
- @SmallTest
- public void testClearNamed() {
- final String name = "TEST_NAMED";
- final String[] keys = {"TEST_REMOVE_1", "TEST_REMOVE_2", "TEST_REMOVE_2"};
- final String expected = null;
-
- for (String key : keys) {
- PreferencesUtil.put(name, key, "Lorem ipsum");
- }
- PreferencesUtil.clear(name);
- for (String key : keys) {
- String actual = PreferencesUtil.get(name, key, expected);
- assertEquals(expected, actual);
- }
- }
-
-}
diff --git a/utils/src/test/java/com/thefinestartist/helpers/ExampleUnitTest.java b/utils/src/test/java/com/thefinestartist/helpers/ExampleUnitTest.java
deleted file mode 100644
index 99a00220..00000000
--- a/utils/src/test/java/com/thefinestartist/helpers/ExampleUnitTest.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.thefinestartist.utils;
-
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-
-/**
- * To work on unit tests, switch the Test Artifact in the Build Variants view.
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() throws Exception {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file