滑动下载图片并同步保存为文件

时间:2019-07-12 14:17:07

标签: java android kotlin android-glide

我正在尝试使用Glide从URL下载图像并获取文件的路径,然后将其转发到WallpaperManager.getCropAndSetWallpaperIntent以设置为墙纸。

我发现可以使用asFile的Glide方法来完成

科特琳:

val data = Glide
    .with(context)
    .asFile()
    .load(url)
    .submit()

但是当我打电话给data.get()时,我得到了错误消息

java.lang.IllegalArgumentException: You must call this method on a background thread

因此遵循了this的答案并实施了MyAsyncTask

interface AsyncResponse {
    fun processFinish(output: File?)
}

class MyAsyncTask(delegate: AsyncResponse) : AsyncTask<FutureTarget<File>, Void, File?>() {
    override fun doInBackground(vararg p0: FutureTarget<File>?): File? {
        return p0[0]?.get()
    }

    private var delegate: AsyncResponse? = null

    init {
        this.delegate = delegate
    }

    override fun onPostExecute(result: File?) {
        delegate!!.processFinish(result)
    }
}

我现在正在这样做

fun getFile(context: Context, url: String) : File {
    val data = Glide
        .with(context)
        .asFile()
        .load(url)
        .submit()

    val asyncTask = MyAsyncTask(object : AsyncResponse {
        override fun processFinish(output: File?) {
            println(output?.path)
        }
    }).execute(data)

  return asyncTask.get()
}

但是我似乎无法获得File

编辑: 工作正常,但是现在出现了新错误

 android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.service.wallpaper.CROP_AND_SET_WALLPAPER dat=content://com.rithvij.scrolltest.provider/cache/image_manager_disk_cache/efebce47b249d7d92fd17340ecf91eb6b7ff86f91d71aabf50468f9e74d0e324.0 flg=0x1 pkg=is.shortcut }

完整堆栈跟踪

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.rithvij.scrolltest, PID: 2760
    android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.service.wallpaper.CROP_AND_SET_WALLPAPER dat=content://com.rithvij.scrolltest.provider/cache/image_manager_disk_cache/efebce47b249d7d92fd17340ecf91eb6b7ff86f91d71aabf50468f9e74d0e324.0 flg=0x1 pkg=is.shortcut }
        at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1816)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1525)
        at android.app.Activity.startActivityForResult(Activity.java:4396)
        at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
        at android.app.Activity.startActivityForResult(Activity.java:4355)
        at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
        at android.app.Activity.startActivity(Activity.java:4679)
        at android.app.Activity.startActivity(Activity.java:4647)
        at com.rithvij.scrolltest.MainActivity$onCreate$1.onClick(MainActivity.kt:71)
        at android.view.View.performClick(View.java:5619)
        at android.view.View$PerformClick.run(View.java:22298)
        at android.os.Handler.handleCallback(Handler.java:754)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:165)
        at android.app.ActivityThread.main(ActivityThread.java:6375)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
  1. 现在我的问题是,这是从网址设置墙纸的首选方法吗?
  2. 如何处理另一个错误?

2 个答案:

答案 0 :(得分:0)

关于第一个有关从url获取图像的问题,建议您不要使用asFile,而应使用方法downloadOnly()。然后,无需使用AsyncTask,而是可以利用RequestListener在加载资源时获取异步回调。

关于第二个问题,您正在广播一个隐式意图,该隐式意图未由操作系统或设备上的任何应用程序注册。您可以尝试利用WallpaperManager系统服务,而不是传播意图。

答案 1 :(得分:0)

回答我自己的问题

  1. 最好按照Elli White downloadOnly()的建议使用here。 但是我浪费了足够的时间研究这个问题,并且找到了可行的解决方案,因此我决定不从头开始。

  2. 我得到的错误是因为Glide正在返回图像文件名。

我通过将文件复制到某处并将其用作源来修复它。

        val file = asyncTask.get()
//        copy file
        val tempFile = File.createTempFile("image", ".png")
        copyFile(file!!.inputStream(), FileOutputStream(tempFile))

在我的用例中,即将图像设置为墙纸,在这种情况下,只要指定图像为.png,就不必担心文件扩展名。