1 package jp.osdn.gokigen.thetaview.liveview.storeimage
3 import android.content.ContentValues
4 import android.database.DatabaseUtils
5 import android.graphics.Bitmap
6 import android.os.Build
7 import android.os.Environment
8 import android.provider.MediaStore
9 import android.util.Log
10 import androidx.fragment.app.FragmentActivity
11 import jp.osdn.gokigen.thetaview.R
12 import jp.osdn.gokigen.thetaview.liveview.image.IImageProvider
13 import jp.osdn.gokigen.thetaview.preference.IPreferencePropertyAccessor
14 import jp.osdn.gokigen.thetaview.preference.PreferenceAccessWrapper
17 import java.io.FileOutputStream
18 import java.text.SimpleDateFormat
21 class StoreImage(private val context: FragmentActivity, private val imageProvider: IImageProvider, private val dumpLog : Boolean = false) : IStoreImage
24 override fun doStore(target: Bitmap?)
28 // 保存処理(プログレスダイアログ(「保存中...」)を表示
30 val bitmapToStore = target ?: imageProvider.getImage()
31 val isLocalLocation = PreferenceAccessWrapper(context).getBoolean(IPreferencePropertyAccessor.PREFERENCE_SAVE_LOCAL_LOCATION, IPreferencePropertyAccessor.PREFERENCE_SAVE_LOCAL_LOCATION_DEFAULT_VALUE)
34 saveImageLocal(bitmapToStore)
38 saveImageExternal(bitmapToStore)
41 // 保存処理(プログレスダイアログ(「保存中...」)を削除
49 private fun storeImageImpl(target: Bitmap)
52 // 保存処理(プログレスダイアログ(「保存中...」)を表示して処理する)
53 val saveDialog = ProgressDialog(context)
54 saveDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER)
55 saveDialog.setMessage(context!!.getString(R.string.data_saving))
56 saveDialog.isIndeterminate = true
57 saveDialog.setCancelable(false)
77 val isLocalLocation = PreferenceAccessWrapper(context).getBoolean(IPreferencePropertyAccessor.PREFERENCE_SAVE_LOCAL_LOCATION, IPreferencePropertyAccessor.PREFERENCE_SAVE_LOCAL_LOCATION_DEFAULT_VALUE)
80 saveImageLocal(target)
84 saveImageExternal(target)
93 private fun prepareLocalOutputDirectory(): File
95 val mediaDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
97 return (if (mediaDir != null && mediaDir.exists()) mediaDir else context.filesDir)
101 * ビットマップイメージをファイルに出力する
103 * @param targetImage 出力するビットマップイメージ
105 private fun saveImageLocal(targetImage: Bitmap)
109 val fileName = "L" + SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(System.currentTimeMillis()) + ".jpg"
110 val photoFile = File(prepareLocalOutputDirectory(), fileName)
111 val outputStream = FileOutputStream(photoFile)
112 targetImage.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
122 private fun getExternalOutputDirectory(): File
124 @Suppress("DEPRECATION") val directoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).path + "/" + context.getString(R.string.app_location) + "/"
125 val target = File(directoryPath)
136 Log.v(TAG, " ----- RECORD Directory PATH : $directoryPath -----")
142 * ビットマップイメージを外部ストレージのファイルに出力する
144 * @param targetImage 出力するビットマップイメージ
146 private fun saveImageExternal(targetImage: Bitmap)
150 if (!isExternalStorageWritable())
153 saveImageLocal(targetImage)
157 val outputDir = getExternalOutputDirectory()
158 val resolver = context.contentResolver
159 val mimeType = "image/jpeg"
160 val now = System.currentTimeMillis()
161 val path = Environment.DIRECTORY_DCIM + File.separator + context.getString(R.string.app_location) // Environment.DIRECTORY_PICTURES + File.separator + "gokigen" //"DCIM/aira01a/"
162 val fileName = "L" + SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(now) + ".jpg"
164 val values = ContentValues()
165 values.put(MediaStore.Images.Media.TITLE, fileName)
166 values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
167 values.put(MediaStore.Images.Media.MIME_TYPE, mimeType)
168 val extStorageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
169 values.put(MediaStore.Images.Media.RELATIVE_PATH, path)
170 values.put(MediaStore.Images.Media.IS_PENDING, true)
171 MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
173 @Suppress("DEPRECATION")
174 values.put(MediaStore.Images.Media.DATA, outputDir.absolutePath + File.separator + fileName)
175 MediaStore.Images.Media.EXTERNAL_CONTENT_URI
177 val imageUri = resolver.insert(extStorageUri, values)
178 if (imageUri != null)
180 //resolver.update(imageUri, values, null, null)
181 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
183 Log.v(TAG, " ===== StorageOperationWithPermission() : $imageUri =====")
184 //StorageOperationWithPermission(context).requestAndroidRMediaPermission(imageUri)
187 ////////////////////////////////////////////////////////////////
190 val cursor = resolver.query(imageUri, null, null, null, null)
191 DatabaseUtils.dumpCursor(cursor)
194 ////////////////////////////////////////////////////////////////
196 val outputStream = resolver.openOutputStream(imageUri)
197 if (outputStream != null)
199 targetImage.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
203 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
205 values.put(MediaStore.Images.Media.IS_PENDING, false)
206 resolver.update(imageUri, values, null, null)
217 private fun isExternalStorageWritable(): Boolean
219 return (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED)
224 private val TAG = this.toString()
225 private const val FILENAME_FORMAT = "yyyyMMdd_HHmmss"