Как сохранить Inte rnet изображение с URL на SD-карте (Android Kotlin) - PullRequest
0 голосов
/ 16 января 2020

У меня есть ошибка в этом коде (

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter result)

И я не сохранил изображение, я дам вам весь код:

MainActivity код:

package com.masreta87.backhussian

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.masreta87.backhussian.models.BlogPost
import com.masreta87.backhussian.models.DataSource
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
private lateinit var blogAdapter:BlogRecyclerAdapter
    lateinit var data: List<BlogPost>
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initRecyclerView()
        addDataSet()

    }
    private fun addDataSet(){
        data=DataSource.createDataSet()
        blogAdapter.submitList(data)
    }
    private fun initRecyclerView(){
        recycler_view.apply {
            layoutManager=LinearLayoutManager(this@MainActivity)
            blogAdapter=BlogRecyclerAdapter()
            adapter=blogAdapter
        }

    }
}

и BlogRecyclerAdapter.kt

    package com.masreta87.backhussian

import android.content.Context
import android.graphics.Bitmap
import android.os.AsyncTask
import android.os.Environment
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.masreta87.backhussian.models.BlogPost
import kotlinx.android.synthetic.main.layout_blog_list_item.view.*
import java.net.URL
import android.os.Environment.getExternalStorageDirectory
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy
import java.io.File
import java.io.FileOutputStream
import java.lang.ref.WeakReference
import android.widget.Toast
import android.content.Intent
import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.net.Uri
import com.squareup.picasso.Picasso
import java.io.IOException


class BlogRecyclerAdapter :RecyclerView.Adapter<RecyclerView.ViewHolder>(){
    private  var items:List <BlogPost> = ArrayList()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return  BlogViewHolder(
            LayoutInflater.from(parent.context).inflate(R.layout.layout_blog_list_item,parent,false)

        )
    }

    override fun getItemCount(): Int {
        return items.size
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when(holder){

            is BlogViewHolder ->{
                holder.bind(items.get(position))
            }
        }
    }
    fun submitList(blogList: List<BlogPost>){
        items = blogList
    }
    class BlogViewHolder constructor(
        itemView:View

    ):RecyclerView.ViewHolder(itemView){
        val blogImage:ImageView =itemView.blog_image
        fun bind(blogPost:BlogPost){
            val requestOptions =RequestOptions()
                .placeholder(R.drawable.ic_launcher_background)
                .error(R.drawable.ic_launcher_background)
            Glide.with(itemView.context)
                .applyDefaultRequestOptions(requestOptions)
                .load(blogPost.image)
                .into(blogImage)
            itemView.setOnClickListener{
                SaveImage(itemView.context,blogPost.image.toString() );
            }

        }

    }


}

private fun SaveImage(context: Context, MyUrl: String) {
    val progress = ProgressDialog(context)

    class SaveThisImage : AsyncTask<Void, Void, Void>() {
        override fun onPreExecute() {
            super.onPreExecute()
            progress.setTitle("Processing")
            progress.setMessage("Please Wait...")
            progress.setCancelable(false)
            progress.show()
        }

        override fun doInBackground(vararg arg0: Void): Void? {
            try {

                val sdCard = Environment.getExternalStorageDirectory()
                @SuppressLint("DefaultLocale") val fileName =
                    String.format("%dm.png", System.currentTimeMillis())
                val dir = File(sdCard.absolutePath + "/Image")
                dir.mkdirs()
                val myImageFile = File(dir,fileName) // Create image file
                **var fos:FileOutputStream? = null**
                try {
                    Log.d("ala",myImageFile.toString())
                    **fos = FileOutputStream(myImageFile)**

                    val bitmap = Picasso.get().load(MyUrl).get()
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)

                    val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
                    intent.data = Uri.fromFile(myImageFile)
                    context.sendBroadcast(intent)
                } catch (e: IOException) {
                    e.printStackTrace()
                } finally {
                    try {
                        fos!!.close()
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }

                }
            } catch (e: Exception) {
            }

            return null
        }

        override fun onPostExecute(result: Void) {
            super.onPostExecute(result)
            if (progress.isShowing) {
                progress.dismiss()
            }
            Toast.makeText(context, "Saved", Toast.LENGTH_SHORT).show()
        }
    }

    val shareimg = SaveThisImage()
    shareimg.execute()
}

И BlogPost.class

    package com.masreta87.backhussian.models

data class BlogPost(

                  var image:String

)

{

}

И DataStore.class

    package com.masreta87.backhussian.models


class DataSource{

    companion object{

        fun createDataSet(): ArrayList<BlogPost>{
            val list = ArrayList<BlogPost>()
            list.add(
                BlogPost(
                    "https://firebasestorage.googleapis.com/v0/b/databaseim-56ef5.appspot.com/o/rpic%20(2).jpg?alt=media&token=138c2c3b-33ce-4a96-a7f5-74816af21809"
                )
            )
            list.add(
                BlogPost(
                    "https://firebasestorage.googleapis.com/v0/b/databaseim-56ef5.appspot.com/o/v1.png?alt=media&token=2e80d218-eb48-4c51-b51a-0fac43f76da7"
                )
            )

            list.add(
                BlogPost(
                    "https://firebasestorage.googleapis.com/v0/b/databaseim-56ef5.appspot.com/o/v10.jpg?alt=media&token=5e7207eb-1dac-41c0-bb3b-95abf9a54a2e"
                )
            )
            list.add(
                BlogPost(
                    "https://firebasestorage.googleapis.com/v0/b/databaseim-56ef5.appspot.com/o/v11.jpg?alt=media&token=2ab2b0c4-5ca1-4042-85c5-6d3e58181f45"
                )
            )

            return list
        }
    }
}

И Mainifest

<uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

И Activity_main. xml

    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:id="@+id/recycler_view"/>

</androidx.constraintlayout.widget.ConstraintLayout>

И layout_blog_list_item. xml

   <?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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:cardElevation="10dp"
    app:cardCornerRadius="2dp"
    app:cardPreventCornerOverlap="false"
    >

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="610dp"
            app:layout_constraintTop_toTopOf="parent"
            android:id="@+id/blog_image"
            android:background="@drawable/boder_image"
            android:padding="10dp"
            android:layout_margin="0dp"
            android:adjustViewBounds="true"
            android:scaleType="fitXY"
            />






    </androidx.constraintlayout.widget.ConstraintLayout>


</androidx.cardview.widget.CardView>

и полная ошибка:

2020-01-15 21 . jvm.internal. ) в android .os.AsyncTask.fini sh (AsyncTask. java : 695) в android .os.AsyncTask.-wrap1 (Неизвестный источник: 0) в android .os.AsyncTask $ InternalHandler.handleMessage (AsyncTask. java: 712) в android .os.Handler. dispatchMessage (Handler. java: 105) в android .os.Looper.l oop (Looper. java: 164) в android .app.ActivityThread.main (ActivityThread. java: 6541 ) в java .lang.reflect.Method.invoke (собственный метод) в com. android .internal.os.Zygote $ MethodAndArgsCaller.run (Zygote. java: 240) в com. android .internal .os.ZygoteInit.main (ZygoteInit. java: 767)

это полная ошибка в приложении

1 Ответ

0 голосов
/ 16 января 2020

Измените тип параметра в

override fun onPostExecute(result: Void)

на

override fun onPostExecute(result: Void?).

И как Ахиль sh Кумар упомянутый здесь вы также должны изменить

class SaveThisImage : AsyncTask<Void, Void, Void>()

на

class SaveThisImage : AsyncTask<Void, Void, Void?>()

Это потому, что doInBackground в вашем коде возвращает обнуляемый тип Void?. Возвращаемое значение doInBackground передается в качестве аргумента onPostExcecute, но ваш onPostExecute принимает ненулевое значение Void вместо обнуляемого Void?.

. следует использовать Unit вместо Void в Kotlin

EDIT

Чтобы отобразить сохраненное изображение, базу данных мультимедиа необходимо обновить. База данных мультимедиа обновляется, когда вы перезагружаете ваше устройство или по прошествии некоторого времени оно будет отображаться в месте сохранения. Для немедленного обновления медиабазы ​​вы можете использовать объект MediaScannerConnection.

Попробуйте передать сохраненный файл этой функции после bitmap.compress и передайте myImageFile

/**
 * Updates the Pictures gallery to include the newly created file.
 * @param fileObj: file path to be scanned so that the new file will appear in the gallery
 */
private fun refreshPhoneGallery(fileObj: File)
{

    /* Scan the specified file path so that the new file will appear in gallery */
    MediaScannerConnection.scanFile(
        yourContext,
        arrayOf(fileObj.path),
        null,
        object : MediaScannerConnection.OnScanCompletedListener
        {
            override fun onScanCompleted(scannedFilePath: String?, p1: Uri?)
            {
                // Do whatever
            }
        }
    )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...