简体   繁体   English

来自图库的所选图像的Kotlin错误

[英]Kotlin error on selected image from gallery

I can not load the selected image. 我无法加载所选图像。 is loading the default template image. 正在加载默认模板图像。 I edited it with the complete fragment code in the post, could you guide me which parameter to use to upload to the selected image? 我使用帖子中的完整片段代码对其进行了编辑,您能指导我使用哪个参数上传到所选图像吗?

The following updated code works but only uploads the pre-defined image, I can not upload the selected image, I do not know which parameter to use on that line 以下更新的代码有效但只上传了预定义的图像,我无法上传所选的图像,我不知道在该行上使用哪个参数

if (this.imageUri != imageUri && requestCode == IMAGE_PICK_CODE && resultCode == RESULT_OK) { if(this.imageUri!= imageUri && requestCode == IMAGE_PICK_CODE && resultCode == RESULT_OK){

class  ReportFragment : Fragment(), OnMapReadyCallback, GoogleMap.OnMapClickListener, GoogleMap.OnCameraIdleListener {
    private var mMapView: MapView? = null
    private var map: GoogleMap? = null
    val CAMERA_PERMISSION_CODE = 0
    val CAMERA_REQUEST_CODE = 10
    lateinit var imageFilePath: String
    private var imgThumb: ImageView? = null
    private var spinner: Spinner? = null
    private var currentLocation: LatLng? = null  // TODO: get current location as static variable
    private var midLatLng: LatLng? = null
    private var lat: Double? = null
    private var lng: Double? = null
    private var objectValues: Array<String>? = null
    private var imageUri: Uri? = null
    private var pictureTaken: Boolean = false
    private var progress: ProgressBar? = null
    val PERMISSION_CODE_READ = 1001
    val PERMISSION_CODE_WRITE = 1002
    val IMAGE_PICK_CODE = 1000
    private val database: FirebaseDatabase? = FirebaseDatabase.getInstance()
    private val markersRef: DatabaseReference? = database!!.getReference("markers")
    private val storage = FirebaseStorage.getInstance()
    private val storageRef: StorageReference = storage.reference
    private var imagesRef: StorageReference? = null
    private val permissoes = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
    inner class GenericFileProvider : FileProvider()


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        ContextCompat.checkSelfPermission(this.context,
                Manifest.permission.READ_EXTERNAL_STORAGE)
        ContextCompat.checkSelfPermission(this.context,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
        Permissoes.validarPermissoes(permissoes, this.activity, 1)
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_report, container, false)

        if (arguments != null && arguments.getDouble("lat") != null) {
            this.lat = arguments.getDouble("lat")
            this.lng = arguments.getDouble("lng")
        }
        this.objectValues = resources.getStringArray(R.array.object_values) // for dropdown

        // TODO       this.currentLocation = Utils.currentLocation
        this.progress = view.findViewById(R.id.progressBar) as ProgressBar

        // Needs to call MapsInitializer before doing any CameraUpdateFactory calls
        try {
            initMap(view, savedInstanceState)
        } catch (e: GooglePlayServicesNotAvailableException) {
            e.printStackTrace()
        }
        this.imgThumb = view.findViewById(R.id.takePictureThumbnail) as ImageButton
        val camBtn = view.findViewById(R.id.takePictureBtn) as ImageButton
        val createBtn = view.findViewById(R.id.createIssueBtn) as Button
        camBtn.setOnClickListener{
            pickImageFromGallery()
        }
        this.imgThumb!!.setOnClickListener{
            takePicture()
        }

        this.spinner = view.findViewById<Spinner>(R.id.object_types_spinner)
        // Create an ArrayAdapter using the string array and a default spinner layout
        val adapter = ArrayAdapter.createFromResource(context, R.array.object_types, android.R.layout.simple_spinner_item)
        // Specify the layout to use when the list of choices appears
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        this.spinner!!.adapter = adapter

        createBtn.setOnClickListener{
            createIssue(view)
        }

        return view
    }

    fun createIssue(view: View) {
        this.progress!!.visibility = View.VISIBLE
        val layout = view.findViewById<LinearLayout>(R.id.reportLinearLayout)
        layout.alpha = 0.4f

        val random = UUID.randomUUID().toString()
        val imgUrl = "images/issue$random+.jpg"
        val name = view.findViewById<EditText>(R.id.issueNameEditText).text.toString()
        val desc = view.findViewById<EditText>(R.id.issueDescriptionEditText).text.toString()
        val type = this.objectValues!![this.spinner!!.selectedItemPosition]
        var issue = Issue(name, type, this.midLatLng!!.latitude, this.midLatLng!!.longitude, desc, imgUrl, null)

        this.imagesRef = storageRef.child(imgUrl)

        var uploadTask: UploadTask = this.imagesRef!!.putBytes(putImgToBytearray())

        uploadTask.addOnSuccessListener { taskSnapshot ->
            this.progress!!.visibility = View.GONE
            Toast.makeText(context,"upload Done",Toast.LENGTH_LONG).show()
            markersRef!!.child(random).setValue(issue)
            goToDetailsView(issue)
        }.addOnFailureListener {
            this.progress!!.visibility = View.GONE
            Toast.makeText(context,"upload failed",Toast.LENGTH_LONG).show()
        }.addOnProgressListener {
            var prog: Double  = (100.0 * it.bytesTransferred )/ it.totalByteCount
            Log.i("transfer", prog.toString())
            //this.progress!!.setProgress(prog.toInt(), true)
        }
    }

    private fun goToDetailsView(issue: Issue) {
        val args = Bundle()

        val detailsFragment = IssueDetailsFragment()
        args.putDouble("lat", issue.lat)
        args.putDouble("lng", issue.lng)
        args.putString("description", issue.description)
        args.putString("name", issue.name)
        args.putString("type", issue.type)
        args.putString("imgUrl", issue.imgUrl)

        detailsFragment.arguments = args
        val ft = fragmentManager.beginTransaction()
        ft.replace(R.id.main_fragment_content, detailsFragment)
                .setTransition(android.app.FragmentTransaction.TRANSIT_FRAGMENT_FADE)
                .addToBackStack(null).commit()
    }
    private fun putImgToBytearray(): ByteArray {
        val stream = ByteArrayOutputStream()
        val drawable = this.imgThumb!!.drawable as BitmapDrawable
        val bitmap = drawable.bitmap
        bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream)
        return stream.toByteArray()
    }

    private fun initMap(view: View, savedInstanceState: Bundle?) {
        MapsInitializer.initialize(this.activity)
        mMapView = view.findViewById(R.id.mapView)
        mMapView!!.onCreate(savedInstanceState)
        mMapView!!.onResume() //without this, map showed but was empty
        mMapView!!.getMapAsync(this)
    }
    override fun onMapClick(latLan: LatLng) {
        this.map!!.addMarker(MarkerOptions().position(latLan).title("Marker"))
    }

    /**
     * Open a camera activity with the picture returned as a result to onActivityResult
     */
    fun openCamera() {
        try {
            val imageFile = createImageFile()
            val callCameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            if(callCameraIntent.resolveActivity(activity.packageManager) != null) {
                val authorities = activity.packageName + ".fileprovider"
                this.imageUri = FileProvider.getUriForFile(context, authorities, imageFile)
                callCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
                startActivityForResult(callCameraIntent, IMAGE_PICK_CODE)
            }
        } catch (e: IOException) {
            Toast.makeText(context, "Could not create file!", Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * take a picture but check for camera permissions first
     */
    fun takePicture() {
        val permissionGranted = ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
        if  (permissionGranted) {
            openCamera()
        } else {
            ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.CAMERA), CAMERA_PERMISSION_CODE)
        }
    }
    private fun checkPermissionForImage() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if ((checkSelfPermission(this.context, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED)
                    && (checkSelfPermission(this.context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED)
            ) {
                val permission = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
                val permissionCoarse = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)

                requestPermissions(permission, PERMISSION_CODE_READ) // GIVE AN INTEGER VALUE FOR PERMISSION_CODE_READ LIKE 1001
                requestPermissions(permissionCoarse, PERMISSION_CODE_WRITE) // GIVE AN INTEGER VALUE FOR PERMISSION_CODE_WRITE LIKE 1002
            } else {
                pickImageFromGallery()
            }
        }
    }
    private fun pickImageFromGallery() {
        val intent = Intent(Intent.ACTION_PICK)
        intent.type = "image/*"
        startActivityForResult(intent, IMAGE_PICK_CODE ) // GIVE AN INTEGER VALUE FOR IMAGE_PICK_CODE LIKE 1000
    }

    /**
     * Open the camera after obtaining the permission
     */
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        when (requestCode) {
            CAMERA_PERMISSION_CODE -> {
                if (grantResults.isEmpty() || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    Log.i("CAMERA", "Permission has been denied by user")
                } else {
                    openCamera()
                    Log.i("CAMERA", "Permission has been granted by user")
                }
            }
        }
    }

    /**
     * Save the picture to the thumbnail after taking it
     */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (this.imageUri != imageUri && requestCode == IMAGE_PICK_CODE && resultCode == RESULT_OK) {


            try {
                pickImageFromGallery()
                //Getting the Bitmap from Gallery
                val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, this.imageUri) as Bitmap
                this.imgThumb!!.setImageBitmap(bitmap)
                this.pictureTaken = true
            } catch (e:IOException) {
                e.printStackTrace()
            }
        } else {
            Toast.makeText(context, "Error loading image", Toast.LENGTH_LONG)
        }
    }

    @Throws(IOException::class)
    fun createImageFile(): File {
        val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        val imageFileName: String = "JPEG_" + timeStamp + "_"
        val storageDir: File = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        if(!storageDir.exists()) storageDir.mkdirs()
        val imageFile = File.createTempFile(imageFileName, ".jpg", storageDir)
        imageFilePath = imageFile.absolutePath
        return imageFile
    }

    /**
     * update the the coordinated of the map center when moving the map
     */
    override fun onCameraIdle() {
        this.midLatLng = this.map!!.cameraPosition.target
    }

    override fun onMapReady(googleMap: GoogleMap?) {
        this.map = googleMap
        this.map!!.setOnCameraIdleListener(this)
        this.map!!.setOnMapClickListener(this)
        if (this.lat != null) {
            this.map!!.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(this.lat!!, this.lng!!), 8f))
        } else if(this.currentLocation != null) { // TODO
            this.map!!.moveCamera(CameraUpdateFactory.newLatLngZoom(this.currentLocation, 8f))
        } else {
            this.map!!.moveCamera(CameraUpdateFactory.newLatLngZoom(Utils.vienna, 8f)) // Vienna
        }
    }
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }
    override fun onResume() {
        super.onResume()
        mMapView!!.onResume()
    }

    override fun onStart() {
        super.onStart()
        mMapView!!.onStart()
    }
    override fun onPause() {
        super.onPause()
        mMapView!!.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        mMapView!!.onDestroy()
    }

    override fun onLowMemory() {
        super.onLowMemory();
        mMapView!!.onLowMemory();
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        mMapView!!.onSaveInstanceState(outState)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onDetach() {
        super.onDetach()
    }

}// Required empty public constructor

This is a null pointer exception. 这是一个空指针异常。 imageUri is null imageUri为null

MediaStore.Images.Media.getBitmap(context.contentResolver, this.imageUri) as Bitmap

If you check the implementation of getBitmap(). 如果检查getBitmap()的实现。

See 看到

public static final Bitmap getBitmap(ContentResolver cr, Uri url)
                throws FileNotFoundException, IOException {
            InputStream input = cr.openInputStream(url);
            Bitmap bitmap = BitmapFactory.decodeStream(input);
            input.close();
            return bitmap;
        }

You will find that it calls the openInputStream() which requires a not null uri. 你会发现它调用openInputStream(),它需要一个非null的uri。

public final @Nullable InputStream openInputStream(@NonNull Uri uri)


   override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (this.imageUri != null && requestCode == IMAGE_PICK_CODE && resultCode == RESULT_OK) {

            try {
                //Getting the Bitmap from Gallery
                val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, this.imageUri) as Bitmap
                this.imgThumb!!.setImageBitmap(bitmap)
                this.pictureTaken = true
            } catch (e:IOException) {
                e.printStackTrace()
            }
        } else {
            Toast.makeText(context, "Error loading image", Toast.LENGTH_LONG)
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM