Skip to content

Commit e08a944

Browse files
authored
Merge pull request #930 from alvince/android/dev
feat: [Android] support floating-icon edge pinned
2 parents 4adcc4d + ad7e43e commit e08a944

5 files changed

Lines changed: 248 additions & 167 deletions

File tree

Android/app/src/main/java/com/didichuxing/doraemondemo/MainDebugActivityOkhttpV3.kt

Lines changed: 49 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,34 @@ import android.text.format.Formatter
1717
import android.util.Log
1818
import android.view.View
1919
import android.widget.ImageView
20-
import android.widget.TextView
2120
import android.widget.Toast
2221
import androidx.lifecycle.lifecycleScope
2322
import androidx.recyclerview.widget.LinearLayoutManager
24-
import androidx.recyclerview.widget.RecyclerView
2523
import coil.imageLoader
2624
import coil.request.CachePolicy
2725
import coil.transform.CircleCropTransformation
2826
import com.amap.api.location.AMapLocationListener
2927
import com.blankj.utilcode.util.ConvertUtils
3028
import com.blankj.utilcode.util.ThreadUtils
3129
import com.bumptech.glide.Glide
30+
import com.bumptech.glide.RequestBuilder
3231
import com.bumptech.glide.load.engine.DiskCacheStrategy
3332
import com.bumptech.glide.load.resource.bitmap.CircleCrop
3433
import com.didichuxing.doraemondemo.amap.AMapRouterFragment
3534
import com.didichuxing.doraemondemo.comm.CommLauncher
35+
import com.didichuxing.doraemondemo.databinding.ActivityMainBinding
3636
import com.didichuxing.doraemondemo.mc.MCActivity
3737
import com.didichuxing.doraemondemo.retrofit.GithubService
3838
import com.didichuxing.doraemonkit.DoKit
3939
import com.facebook.drawee.backends.pipeline.Fresco
40-
import com.facebook.drawee.view.SimpleDraweeView
4140
import com.lzy.okgo.OkGo
4241
import com.lzy.okgo.callback.StringCallback
4342
import com.lzy.okgo.model.Response
4443
import com.nostra13.universalimageloader.core.ImageLoader
4544
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration
4645
import com.squareup.picasso.MemoryPolicy
4746
import com.squareup.picasso.Picasso
47+
import com.squareup.picasso.RequestCreator
4848
import io.reactivex.schedulers.Schedulers
4949
import kotlinx.coroutines.*
5050
import okhttp3.*
@@ -61,8 +61,8 @@ import kotlin.coroutines.resume
6161
/**
6262
* @author jintai
6363
*/
64-
class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
65-
CoroutineScope by MainScope() {
64+
class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener, CoroutineScope by MainScope() {
65+
6666
private var okHttpClient: OkHttpClient? = null
6767
private var mLocationManager: LocationManager? = null
6868
private val UPDATE_UI = 100
@@ -79,19 +79,20 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
7979
*/
8080
private var githubService: GithubService? = null
8181

82+
private var _binding: ActivityMainBinding? = null
83+
8284
@SuppressLint("HandlerLeak")
8385
private val mHandler: Handler = object : Handler() {
8486
override fun handleMessage(msg: Message) {
8587
super.handleMessage(msg)
8688
when (msg.what) {
87-
100 -> (findViewById<View>(R.id.iv_picasso) as ImageView).setImageBitmap(msg.obj as Bitmap)
89+
100 -> _binding?.ivPicasso?.setImageBitmap(msg.obj as Bitmap)
8890
else -> {
8991
}
9092
}
9193
}
9294
}
9395

94-
9596
val datas = mutableListOf(
9697
"测试",
9798
"显示/隐藏Dokit入口",
@@ -119,25 +120,21 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
119120
it.resume("sleep 1000ms")
120121
}
121122

122-
123123
fun sleep2(): String {
124124
Thread.sleep(5000)
125125
return "sleep 1000ms"
126126
}
127127

128128
override fun onCreate(savedInstanceState: Bundle?) {
129129
super.onCreate(savedInstanceState)
130-
setContentView(R.layout.activity_main)
131-
val tvEnv = findViewById<TextView>(R.id.tv_env)
132-
tvEnv.text = "${getString(R.string.app_build_types)}:Debug"
133-
val rv = findViewById<RecyclerView>(R.id.rv)
134-
rv.layoutManager = LinearLayoutManager(this)
135-
mAdapter = MainAdapter(R.layout.item_main_rv, datas)
136-
rv.adapter = mAdapter
130+
_binding = ActivityMainBinding.inflate(layoutInflater).also {
131+
setContentView(it.root)
132+
mAdapter = MainAdapter(R.layout.item_main_rv, datas)
133+
it.initView(this)
134+
}
137135
mAdapter.setOnItemClickListener { _, _, position ->
138136
when (datas[position]) {
139137
"测试" -> {
140-
lifecycleScope
141138
// lifecycleScope.launch {
142139
// val helloworld = async {
143140
// "Hello world!!"
@@ -180,7 +177,10 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
180177
DoKit.showToolPanel()
181178
}
182179
"获取已安装的app" -> {
183-
packageManager.getInstalledApplications(PackageManager.MATCH_UNINSTALLED_PACKAGES)
180+
packageManager.getInstalledApplications(
181+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) PackageManager.MATCH_UNINSTALLED_PACKAGES
182+
else PackageManager.GET_UNINSTALLED_PACKAGES
183+
)
184184
}
185185
"跳转其他Activity" -> {
186186
startActivity(Intent(this, SecondActivity::class.java))
@@ -274,7 +274,7 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
274274
)
275275
}
276276
"模拟Crash" -> {
277-
testCrash()!!.length
277+
checkNotNull(testCrash())
278278
}
279279
"创建数据库" -> {
280280
val dbHelper = MyDatabaseHelper(this, "BookStore.db", null, 1)
@@ -291,7 +291,6 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
291291
}
292292
}
293293
}
294-
findViewById<View>(R.id.btn_load_img).setOnClickListener(this)
295294

296295
okHttpClient = OkHttpClient().newBuilder().build()
297296
//获取定位服务
@@ -312,8 +311,13 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
312311
ImageLoader.getInstance().init(config)
313312

314313
githubService = retrofit.create(GithubService::class.java)
314+
}
315315

316-
316+
private fun ActivityMainBinding.initView(context: Context) {
317+
tvEnv.text = "${getString(R.string.app_build_types)}:Debug"
318+
rv.layoutManager = LinearLayoutManager(context)
319+
rv.adapter = mAdapter
320+
btnLoadImg.setOnClickListener(this@MainDebugActivityOkhttpV3)
317321
}
318322

319323
private fun test1() {
@@ -387,7 +391,6 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
387391
)
388392
}
389393

390-
391394
@SuppressLint("MissingPermission")
392395
override fun onClick(v: View) {
393396
when (v.id) {
@@ -408,7 +411,7 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
408411
.memoryPolicy(MemoryPolicy.NO_CACHE)
409412
.placeholder(R.mipmap.cat)
410413
.error(R.mipmap.cat)
411-
.into(findViewById<View>(R.id.iv_picasso) as ImageView)
414+
.intoOrCancel(_binding?.ivPicasso)
412415
Glide.with(this@MainDebugActivityOkhttpV3)
413416
.asBitmap()
414417
.load(glideImageUrl)
@@ -417,9 +420,9 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
417420
.diskCacheStrategy(DiskCacheStrategy.NONE)
418421
.skipMemoryCache(true)
419422
.transform(CircleCrop())
420-
.into((findViewById<View>(R.id.iv_glide) as ImageView))
423+
.intoOrCancel(_binding?.ivGlide)
421424
//coil
422-
findViewById<ImageView>(R.id.iv_coil).apply {
425+
_binding?.ivCoil?.apply {
423426
val request = coil.request.ImageRequest.Builder(this.context)
424427
.memoryCachePolicy(CachePolicy.DISABLED)
425428
.transformations(CircleCropTransformation())
@@ -431,13 +434,9 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
431434
}
432435
//imageLoader
433436
val imageLoader = ImageLoader.getInstance()
434-
imageLoader.displayImage(
435-
imageLoaderImageUrl,
436-
findViewById<View>(R.id.iv_imageloader) as ImageView
437-
)
437+
imageLoader.displayImageOrNot(imageLoaderImageUrl, _binding?.ivImageloader)
438438
//fresco
439-
val frescoImageView = findViewById<SimpleDraweeView>(R.id.iv_fresco)
440-
frescoImageView.setImageURI(Uri.parse(frescoImageUrl))
439+
_binding?.ivFresco?.setImageURI(Uri.parse(frescoImageUrl))
441440
val imagePipeline = Fresco.getImagePipeline()
442441
// combines above two lines
443442
imagePipeline.clearCaches()
@@ -567,18 +566,16 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
567566
}
568567

569568
private fun inputStream2File(`is`: InputStream, saveFile: File) {
570-
try {
571-
var len: Int
572-
val buf = ByteArray(2048)
573-
val fos = FileOutputStream(saveFile)
574-
while (`is`.read(buf).also { len = it } != -1) {
575-
fos.write(buf, 0, len)
569+
var len: Int
570+
val buf = ByteArray(2048)
571+
val fos = FileOutputStream(saveFile)
572+
`is`.use { input ->
573+
fos.use { output ->
574+
while (input.read(buf).also { len = it } != -1) {
575+
output.write(buf, 0, len)
576+
}
577+
output.flush()
576578
}
577-
fos.flush()
578-
fos.close()
579-
`is`.close()
580-
} catch (e: Exception) {
581-
e.printStackTrace()
582579
}
583580
}
584581

@@ -612,12 +609,19 @@ class MainDebugActivityOkhttpV3 : BaseActivity(), View.OnClickListener,
612609
}
613610
}
614611

615-
override fun onWindowFocusChanged(hasFocus: Boolean) {
616-
super.onWindowFocusChanged(hasFocus)
612+
private fun RequestCreator.intoOrCancel(target: ImageView?) {
613+
target?.also { into(it) }
614+
}
615+
616+
private fun RequestBuilder<*>.intoOrCancel(target: ImageView?) {
617+
target?.also { into(it) }
618+
}
619+
620+
private fun ImageLoader.displayImageOrNot(url: String, target: ImageView?) {
621+
target?.also { displayImage(url, it) }
617622
}
618623

619624
companion object {
620625
const val TAG = "MainDebugActivity"
621-
622626
}
623-
}
627+
}

Android/dokit/src/main/java/com/didichuxing/doraemonkit/DoKitEnv.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.didichuxing.doraemonkit
22

33
import android.app.Application
4+
import android.graphics.Point
45

56
/**
67
* Created by alvince on 2021/9/29
@@ -12,6 +13,8 @@ internal object DoKitEnv {
1213
@Volatile
1314
var app: Application? = null
1415

16+
val windowSize: Point= Point()
17+
1518
@JvmStatic
1619
fun requireApp(): Application {
1720
return app ?: throw IllegalStateException("Dokit app no set")

Android/dokit/src/main/java/com/didichuxing/doraemonkit/DokitActivityLifecycleCallbacks.kt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.app.Activity
44
import android.app.Application
55
import android.content.Context
66
import android.os.Bundle
7+
import android.view.View
78
import android.widget.Toast
89
import androidx.fragment.app.FragmentActivity
910
import androidx.fragment.app.FragmentManager
@@ -173,17 +174,21 @@ class DokitActivityLifecycleCallbacks : Application.ActivityLifecycleCallbacks {
173174
* @param activity
174175
*/
175176
private fun dispatchOnActivityResumed(activity: Activity) {
177+
activity.window.decorView.also {
178+
it.post { DoKitEnv.windowSize.set(it.width, it.height) }
179+
}
176180
if (DoKitManager.IS_NORMAL_FLOAT_MODE) {
177181
//显示内置dokitView icon
178182
DokitViewManager.INSTANCE.dispatchOnActivityResumed(activity)
183+
return
184+
}
185+
// FIXME: consider handle permission down to activity-layer, just dispatch resumed-event here
186+
//悬浮窗权限 vivo 华为可以不需要动态权限 小米需要
187+
if (DoKitPermissionUtil.canDrawOverlays(activity)) {
188+
DokitViewManager.INSTANCE.dispatchOnActivityResumed(activity)
179189
} else {
180-
//悬浮窗权限 vivo 华为可以不需要动态权限 小米需要
181-
if (DoKitPermissionUtil.canDrawOverlays(activity)) {
182-
DokitViewManager.INSTANCE.dispatchOnActivityResumed(activity)
183-
} else {
184-
//请求悬浮窗权限
185-
requestPermission(activity)
186-
}
190+
//请求悬浮窗权限
191+
requestPermission(activity)
187192
}
188193
}
189194

0 commit comments

Comments
 (0)