<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
+ <JetCodeStyleSettings>
+ <option name="PACKAGES_TO_USE_STAR_IMPORTS">
+ <value>
+ <package name="java.util" alias="false" withSubpackages="false" />
+ <package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
+ <package name="io.ktor" alias="false" withSubpackages="true" />
+ </value>
+ </option>
+ <option name="PACKAGES_IMPORT_LAYOUT">
+ <value>
+ <package name="" alias="false" withSubpackages="true" />
+ <package name="java" alias="false" withSubpackages="true" />
+ <package name="javax" alias="false" withSubpackages="true" />
+ <package name="kotlin" alias="false" withSubpackages="true" />
+ <package name="" alias="true" withSubpackages="true" />
+ </value>
+ </option>
+ </JetCodeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="name" value="maven" />
<option name="url" value="https://maven.google.com" />
</remote-repository>
+ <remote-repository>
+ <option name="id" value="MavenRepo" />
+ <option name="name" value="MavenRepo" />
+ <option name="url" value="https://repo.maven.apache.org/maven2/" />
+ </remote-repository>
</component>
</project>
\ No newline at end of file
apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
android {
compileSdkVersion 29
applicationId "net.osdn.gokigen.a01d"
minSdkVersion 14
targetSdkVersion 29
- versionCode 10901
- versionName "1.9.1"
+ versionCode 10902
+ versionName "1.9.2"
}
buildTypes {
release {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation 'androidx.exifinterface:exifinterface:1.2.0'
+ implementation 'androidx.exifinterface:exifinterface:1.3.0'
implementation 'androidx.preference:preference:1.1.1'
- implementation 'com.google.android.material:material:1.2.0'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'com.google.android.material:material:1.2.1'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
api files('libs/olycamerakit.jar')
+ implementation "androidx.core:core-ktx:1.3.1"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
+repositories {
+ mavenCentral()
}
private final KodakCameraInformation cameraInformation;
private KodakCaptureControl captureControl;
private KodakFocusingControl focusingControl;
- private KodakConnection canonConnection;
+ private KodakConnection kodakConnection;
private KodakCommandCommunicator commandPublisher;
private KodakLiveViewControl liveViewControl;
private KodakZoomLensControl zoomControl;
commandPublisher = new KodakCommandCommunicator(this, ipAddress, controlPort, true, false);
liveViewControl = new KodakLiveViewControl(context, ipAddress, liveviewPort);
statusChecker = new KodakStatusChecker();
- canonConnection = new KodakConnection(context, provider, this, statusChecker);
+ kodakConnection = new KodakConnection(context, provider, this, statusChecker);
cameraInformation = new KodakCameraInformation();
zoomControl = new KodakZoomLensControl(commandPublisher);
this.statusListener = statusListener;
@Override
public ICameraConnection getCameraConnection()
{
- return (canonConnection);
+ return (kodakConnection);
}
@Override
break;
case SEQ_CONNECT_04:
interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.kodak_connect_connecting4), false, false, 0);
+ // ここで、パスワードの Base64情報を切り出す(FC 03 の応答、 0x0058 ~ 64バイトの文字列を切り出して、Base64エンコードする)
commandIssuer.enqueueCommand(new KodakConnectSequence05(this));
break;
case SEQ_CONNECT_05:
interfaceProvider.getInformationReceiver().updateMessage(context.getString(R.string.kodak_connect_connecting5), false, false, 0);
+ // ここで、パスワードの情報を切り出す (FE 03 の応答、 0x0078 ~ 文字列を切り出す。)
commandIssuer.enqueueCommand(new KodakConnectSequence06(this));
break;
case SEQ_CONNECT_06:
private void initComponent(Context context)
{
prepareFile();
- storeImage = new StoreImage(context);
+ storeImage = new StoreImage(context, false);
ShowMessageHolder messageHolder = new ShowMessageHolder();
this.messageHolder = messageHolder;
messageDrawer = messageHolder;
--- /dev/null
+package net.osdn.gokigen.a01d.liveview
+import android.content.ContentValues
+import android.content.Context
+import android.database.DatabaseUtils
+import android.graphics.Bitmap
+import android.net.Uri
+import android.os.Build
+import android.os.Environment
+import android.provider.MediaStore
+import android.util.Log
+import androidx.preference.PreferenceManager
+import net.osdn.gokigen.a01d.R
+import net.osdn.gokigen.a01d.preference.IPreferencePropertyAccessor
+import java.io.File
+import java.io.FileOutputStream
+import java.text.SimpleDateFormat
+import java.util.*
+
+class StoreImage(private val context: Context, private val dumpLog : Boolean = false) : IStoreImage
+{
+ private val TAG = toString()
+ private val FILENAME_FORMAT = "yyyyMMdd_HHmmss"
+
+ override fun doStore(bitmapToStore: Bitmap)
+ {
+ try
+ {
+ // 保存処理(プログレスダイアログ(「保存中...」)を表示
+
+ val preference = PreferenceManager.getDefaultSharedPreferences(context)
+ val isLocalLocation = preference.getBoolean(
+ IPreferencePropertyAccessor.SAVE_LOCAL_LOCATION,
+ IPreferencePropertyAccessor.SAVE_LOCAL_LOCATION_DEFAULT_VALUE
+ )
+ if (isLocalLocation)
+ {
+ saveImageLocal(bitmapToStore)
+ }
+ else
+ {
+ saveImageExternal(bitmapToStore)
+ }
+
+ // 保存処理(プログレスダイアログ(「保存中...」)を削除
+ }
+ catch (t: Throwable)
+ {
+ t.printStackTrace()
+ }
+ }
+
+ private fun prepareLocalOutputDirectory(): File
+ {
+ val mediaDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
+ mediaDir?.mkdirs()
+ return (if (mediaDir != null && mediaDir.exists()) mediaDir else context.filesDir)
+ }
+
+ /**
+ * ビットマップイメージをファイルに出力する
+ *
+ * @param targetImage 出力するビットマップイメージ
+ */
+ private fun saveImageLocal(targetImage: Bitmap)
+ {
+ try
+ {
+ val fileName = "L" + SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(System.currentTimeMillis()) + ".jpg"
+ val photoFile = File(prepareLocalOutputDirectory(), fileName)
+ val outputStream = FileOutputStream(photoFile)
+ targetImage.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
+ outputStream.flush()
+ outputStream.close()
+ }
+ catch (t: Throwable)
+ {
+ t.printStackTrace()
+ }
+ }
+
+ @Suppress("DEPRECATION")
+ private fun getExternalOutputDirectory(): File
+ {
+ val directoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).path + "/" + context.getString(R.string.app_name2) + "/"
+ val target = File(directoryPath)
+ try
+ {
+ target.mkdirs()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ if (dumpLog)
+ {
+ Log.v(TAG, " ----- RECORD Directory PATH : $directoryPath -----")
+ }
+ return (target)
+ }
+
+ /**
+ * ビットマップイメージを外部ストレージのファイルに出力する
+ *
+ * @param targetImage 出力するビットマップイメージ
+ */
+ @Suppress("DEPRECATION")
+ private fun saveImageExternal(targetImage: Bitmap)
+ {
+ try
+ {
+ if (!isExternalStorageWritable())
+ {
+ saveImageLocal(targetImage)
+ return
+ }
+
+ val outputDir = getExternalOutputDirectory()
+ val resolver = context.contentResolver
+ val mimeType = "image/jpeg"
+ //val now = System.currentTimeMillis()
+ val path = Environment.DIRECTORY_DCIM + File.separator + context.getString(R.string.app_name2)
+ val fileName = SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(Calendar.getInstance().time) + ".jpg"
+
+ val extStorageUri : Uri
+ val values = ContentValues()
+ values.put(MediaStore.Images.Media.TITLE, fileName)
+ values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
+ values.put(MediaStore.Images.Media.MIME_TYPE, mimeType)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+ {
+ values.put(MediaStore.Images.Media.RELATIVE_PATH, path)
+ values.put(MediaStore.Images.Media.IS_PENDING, true)
+ extStorageUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
+ }
+ else
+ {
+ values.put(MediaStore.Images.Media.DATA, outputDir.absolutePath + File.separator + fileName)
+ extStorageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ }
+ val imageUri = resolver.insert(extStorageUri, values)
+ if (imageUri != null)
+ {
+ resolver.update(imageUri, values, null, null)
+
+ ////////////////////////////////////////////////////////////////
+ if (dumpLog)
+ {
+ val cursor = resolver.query(imageUri, null, null, null, null)
+ DatabaseUtils.dumpCursor(cursor)
+ cursor!!.close()
+ }
+ ////////////////////////////////////////////////////////////////
+
+ val outputStream = resolver.openOutputStream(imageUri)
+ if (outputStream != null)
+ {
+ targetImage.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
+ outputStream.flush()
+ outputStream.close()
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+ {
+ values.put(MediaStore.Images.Media.IS_PENDING, false)
+ resolver.update(imageUri, values, null, null)
+
+ }
+ }
+ }
+ catch (t: Throwable)
+ {
+ t.printStackTrace()
+ }
+ }
+
+ private fun isExternalStorageWritable(): Boolean
+ {
+ return (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED)
+ }
+
+}
* 画像の保管クラス
*
*/
-class StoreImage implements IStoreImage
+class StoreImageOld implements IStoreImage
{
private final String TAG = toString();
private final Context context;
- StoreImage(Context context)
+ StoreImageOld(Context context)
{
this.context = context;
}
String KODAK_LIVEVIEW_PORT = "kodak_liveview_port";
String KODAK_LIVEVIEW_PORT_DEFAULT_VALUE = "9176";
+ String SAVE_LOCAL_LOCATION = "save_local_location";
+ boolean SAVE_LOCAL_LOCATION_DEFAULT_VALUE = false;
/*
int CHOICE_SPLASH_SCREEN = 10;
{
editor.putString(IPreferencePropertyAccessor.KODAK_FLASH_MODE, IPreferencePropertyAccessor.KODAK_FLASH_MODE_DEFAULT_VALUE);
}
+ if (!items.containsKey(IPreferencePropertyAccessor.SAVE_LOCAL_LOCATION))
+ {
+ editor.putBoolean(IPreferencePropertyAccessor.SAVE_LOCAL_LOCATION, IPreferencePropertyAccessor.SAVE_LOCAL_LOCATION_DEFAULT_VALUE);
+ }
editor.apply();
}
catch (Exception e)
Log.v(TAG, " " + key + " , " + value);
break;
+ case IPreferencePropertyAccessor.SAVE_LOCAL_LOCATION:
+ value = preferences.getBoolean(key, IPreferencePropertyAccessor.SAVE_LOCAL_LOCATION_DEFAULT_VALUE);
+ Log.v(TAG, " " + key + " , " + value);
+ break;
+
default:
String strValue = preferences.getString(key, "");
setListPreference(key, key, strValue);
setBooleanPreference(IPreferencePropertyAccessor.CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW, IPreferencePropertyAccessor.CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW, defaultValue);
setBooleanPreference(IPreferencePropertyAccessor.CAPTURE_ONLY_LIVE_VIEW, IPreferencePropertyAccessor.CAPTURE_ONLY_LIVE_VIEW, false);
setBooleanPreference(IPreferencePropertyAccessor.CACHE_LIVEVIEW_PICTURES, IPreferencePropertyAccessor.CACHE_LIVEVIEW_PICTURES, false);
+ setBooleanPreference(IPreferencePropertyAccessor.SAVE_LOCAL_LOCATION, IPreferencePropertyAccessor.SAVE_LOCAL_LOCATION, IPreferencePropertyAccessor.SAVE_LOCAL_LOCATION_DEFAULT_VALUE);
}
catch (Exception e)
{
<string name="pref_kodak_liveview_port">カメラライブビューポート番号</string>
<string name="pref_summary_kodak_liveview_port">通常、変更は不要です (初期値:9176)</string>
+ <string name="pref_save_local_location">ライブビュー画像をアプリ固有領域に保存</string>
+ <string name="pref_summary_save_local_location">ライブビューイメージの保存先をアプリ固有領域にします。</string>
+
</resources>
<string name="pref_kodak_liveview_port">Camera Liveview Port</string>
<string name="pref_summary_kodak_liveview_port">default: 9176 </string>
+ <string name="pref_save_local_location">Save local location(Liveview Image)</string>
+ <string name="pref_summary_save_local_location">The liveview image saves in application local location.</string>
+
</resources>
android:summary="@string/pref_summary_capture_only_live_view" />
<CheckBoxPreference
+ android:key="save_local_location"
+ android:title="@string/pref_save_local_location"
+ android:summary="@string/pref_summary_save_local_location"/>
+
+ <CheckBoxPreference
android:key="cache_liveview_pictures"
android:title="@string/pref_cache_liveview_pictures"
android:summary="@string/pref_summary_cache_liveview_pictures" />
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
+ ext.kotlin_version = '1.4.10'
repositories {
jcenter()
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.0.0'
+ classpath 'com.android.tools.build:gradle:4.0.1'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files