方向更改时文件未保存

时间:2018-07-05 02:34:50

标签: android kotlin onsaveinstancestate

最近,当我在处理RecyclerView的片段中遇到此语义错误时,我正在创建一个测试应用程序以熟悉Palette和Android Palette库。当我在片段中拍照时,它会将照片保存在File中,以当前方向保存,以横向保存,但是当我将手机旋转回纵向时,File重置为{{ 1}}。我是根据我的Log测试和读取堆栈跟踪发现的。

当前,我已将null的绝对路径包装在null检查中,以防止进一步的错误,但是我不确定如何继续。以下是我的Kotlin文件。

null

如果有帮助,清单中也有我的class PicFragment : Fragment() { private var imgFile: File? = null private lateinit var cameraPic: ImageView private lateinit var cycleLayout: View private var swatchIndex: Int = 0 override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view: View? = inflater?.inflate(R.layout.camera_fragment, container, false) // init val cameraButton: ImageButton = view!!.findViewById(R.id.click_pic) val colorCycler: ImageButton = view.findViewById(R.id.color_clicker) cameraPic = view.findViewById(R.id.camera_pic) cycleLayout = view.findViewById(R.id.color_selector) val swatchDisplay: ImageView = view.findViewById(R.id.main_color) val swatchName: TextView = view.findViewById(R.id.main_color_name) // restoring the picture taken if it exists if(savedInstanceState != null){ val path: String? = savedInstanceState.getString("imageFile") swatchIndex = savedInstanceState.getInt("swatchIndex") if(path != null) { val bm: Bitmap = BitmapFactory.decodeFile(path) cameraPic.setImageBitmap(bm) animateColorSlides(cycleLayout, duration = 500) } } // taking the picture (full size) cameraButton.setOnClickListener { _ -> val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) if (intent.resolveActivity(context.packageManager) != null){ imgFile = createFileName() val photoURI = FileProvider.getUriForFile(context, "com.github.astronoodles.provider", imgFile) grantUriPermissions(intent, photoURI) intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI) startActivityForResult(intent, 3) } } // Palette Button (click to go through color values) colorCycler.setOnClickListener { _ -> if(cameraPic.drawable is BitmapDrawable){ val img: Bitmap = (cameraPic.drawable as BitmapDrawable).bitmap Palette.from(img).generate { palette -> val swatches = palette.swatches Log.d(MainActivity.TAG, "Swatch Size: ${swatches.size}") Log.d(MainActivity.TAG, "Counter: $swatchIndex") val hexCode = "#${Integer.toHexString(swatches[swatchIndex++ % swatches.size].rgb)}" swatchName.text = hexCode animateColorDrawableFade(context, swatchDisplay, hexCode) } } else Log.e(MainActivity.TAG, "No bitmap found! Cannot cycle images...") } return view } override fun onSaveInstanceState(outState: Bundle?) { super.onSaveInstanceState(outState) outState?.putString("imageFile", imgFile?.absolutePath) outState?.putInt("swatchIndex", swatchIndex) } /** * Animates the color of an ImageView using its image drawable * @author Michael + StackOverflow * @since 6/24/18 * @param ctx Context needed to load the animations * @param target Target ImageView for switching colors * @param hexCode The hex code of the colors switching in */ private fun animateColorDrawableFade(ctx: Context, target: ImageView, hexCode: String){ val fadeOut = AnimationUtils.loadAnimation(ctx, android.R.anim.fade_out) val fadeIn = AnimationUtils.loadAnimation(ctx, android.R.anim.fade_in) fadeOut.setAnimationListener(object: Animation.AnimationListener { override fun onAnimationStart(animation: Animation?) {} override fun onAnimationRepeat(animation: Animation?) {} override fun onAnimationEnd(animation: Animation?) { target.setImageDrawable(ColorDrawable(Color.parseColor(hexCode))) target.startAnimation(fadeIn) } }) target.startAnimation(fadeOut) } /** * Helper method for animating a layout's visibility from invisible and visible * @author Michael * @param layout The layout to animate * @param duration The length of the alpha animation. */ private fun animateColorSlides(layout: View, duration: Long){ layout.alpha = 0f layout.visibility = View.VISIBLE layout.animate().alpha(1f).setListener(null).duration = duration } /** * Creates an unique name for the file as suggested here using a SimpleDateFormat * @author Michael * @returns A (temporary?) file linking to where the photo will be saved. */ private fun createFileName(): File { val timeStamp: String = SimpleDateFormat("yyyyMd_km", Locale.US).format(Date()) val jpegTitle = "JPEG_${timeStamp}_" val directory: File = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) try { return File.createTempFile(jpegTitle, ".png", directory) } catch (e: IOException) { e.printStackTrace() } return File(directory, "$jpegTitle.jpg") } /** * Grants URI permissions for the file provider to successfully save the full size file. <br> * Code borrowed from https://stackoverflow.com/questions/18249007/how-to-use-support-fileprovider-for-sharing-content-to-other-apps * @param intent The intent to send the photo * @param uri The URI retrieved from the FileProvider * @author Michael and Leszek */ private fun grantUriPermissions(intent: Intent, uri: Uri){ val intentHandleList: List<ResolveInfo> = context.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY) intentHandleList.forEach { val packageName: String = it.activityInfo.packageName context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION) } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { if(requestCode == 3 && resultCode == Activity.RESULT_OK){ val bitmap: Bitmap = BitmapFactory.decodeFile(imgFile!!.absolutePath) cameraPic.setImageBitmap(bitmap) animateColorSlides(cycleLayout, duration = 2000) } } } 权限。

谢谢。

1 个答案:

答案 0 :(得分:0)

Android activity lifecycle documentation中,这是相关部分:

  

如果重写onSaveInstanceState(),则要让默认实现保存视图层次结构的状态,必须调用超类实现

哪个会给你这样的东西

override fun onSaveInstanceState(outState: Bundle?) {
    outState?.putString("imageFile", imgFile?.absolutePath)
    outState?.putInt("swatchIndex", swatchIndex)

    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(outState)
}