Commit cc209be0 by Kim Jinsung

#37841 360編集THETA連携

parent 167856d7
...@@ -128,4 +128,9 @@ public class ABookKeys { ...@@ -128,4 +128,9 @@ public class ABookKeys {
public static final String CMD_EDIT_ATTACHED = "editAttached"; //再編集のためのcmdパラメタ public static final String CMD_EDIT_ATTACHED = "editAttached"; //再編集のためのcmdパラメタ
public static final String EDITABLE = "editable"; //commonAttachedDataUrl()で編集可否を判別するパラメタをWebからもらう。 public static final String EDITABLE = "editable"; //commonAttachedDataUrl()で編集可否を判別するパラメタをWebからもらう。
public static final String FILE_PATH = "filePath"; //再編集する場合、クリックしたイマージのパスのパラメタ public static final String FILE_PATH = "filePath"; //再編集する場合、クリックしたイマージのパスのパラメタ
//THETA端末関連
public static final String THETA_FILE_ID = "OBJECT_ID";
public static final String THETA_THUMBNAIL = "THUMBNAIL";
public static final String THETA_OLD_VERSION_FLG = "thetaOldVersionFlg"; //true:API2.0利用、false:API2.1利用
} }
package jp.agentec.abook.abv.bl.common.constant;
public class ABookValues {
public static final String THETA_IP_ADDRESS = "192.168.1.1";
public static final String THETA_MODEL_NAME_THETA = "THETA";
public static final String THETA_MODEL_NAME_THETA_SC = "THETA SC";
public static final String THETA_MODEL_NAME_THETA_S = "THETA S";
public static final String SUCCESS = "success";
public static final String FAIL = "fail";
}
...@@ -191,6 +191,16 @@ ...@@ -191,6 +191,16 @@
android:configChanges="keyboardHidden|orientation|screenSize" android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/> android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
<activity android:name="jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaCameraActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
<activity android:name="jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaImageListActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
<activity android:name="jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaImagePreviewActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
<activity android:name="jp.agentec.abook.abv.ui.home.activity.ABookSettingActivity" android:theme="@android:style/Theme.NoTitleBar"/> <activity android:name="jp.agentec.abook.abv.ui.home.activity.ABookSettingActivity" android:theme="@android:style/Theme.NoTitleBar"/>
<activity android:name="jp.agentec.abook.abv.ui.home.activity.ChangePasswordActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/> <activity android:name="jp.agentec.abook.abv.ui.home.activity.ChangePasswordActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
<activity android:name="jp.agentec.abook.abv.ui.home.activity.ChangePasswordActivityDialog" android:theme="@style/Theme.MyTheme.ModalDialog"/> <activity android:name="jp.agentec.abook.abv.ui.home.activity.ChangePasswordActivityDialog" android:theme="@style/Theme.MyTheme.ModalDialog"/>
......
...@@ -1425,4 +1425,59 @@ ...@@ -1425,4 +1425,59 @@
<string name="msg_image_select_send_success">シーン画像の登録に成功しました。</string> <string name="msg_image_select_send_success">シーン画像の登録に成功しました。</string>
<string name="msg_image_select_send_fail_retry">シーン画像の登録に失敗しました。再度登録処理を実行しますか?</string> <string name="msg_image_select_send_fail_retry">シーン画像の登録に失敗しました。再度登録処理を実行しますか?</string>
<string name="msg_access_registing">登録中</string> <string name="msg_access_registing">登録中</string>
<string name="title_theta_camera">THETAカメラ</string>
<string name="title_theta_camera_shoot">撮影</string>
<string name="title_theta_camera_image">画像選択</string>
<string name="title_theta_library">THETAライブラリ</string>
<string name="title_theta_image_preview">THETAプレビュー</string>
<string name="title_theta_connect">カメラ選択</string>
<string name="msg_no_save_theta">カメラ情報がありません。</string>
<string name="msg_no_save_theta_info">THETAカメラを先に登録してください。\n</string>
<string name="msg_theta_connect_info">THETAカメラと接続するにはWIFI設定をONにする必要があります。</string>
<string name="title_theta_register">カメラ登録</string>
<string name="msg_theta_register_info">接続するThetaのシリアルNOとパスワードを入力してください。</string>
<string name="title_serial_number">シリアルNO</string>
<string name="msg_wifi_connecting">Wi-Fi接続中...</string>
<string name="msg_no_exists_theta_wifi">THETAカメラのWi-Fi機能をONにしてください。</string>
<string name="msg_fail_connect_theta_wifi">THETAカメラに接続失敗しました。THETAカメラのWi-Fi設定を確認してください。</string>
<string name="msg_fail_input_all_null">全ての情報を入力してください。</string>
<string name="title_theta_wifi_saved">登録済みの端末</string>
<string name="title_theta_wifi_not_saved">未登録の端末</string>
<string name="title_theta_image_save">転送</string>
<string name="msg_theta_image_send_confirm">この画像を転送しますか?</string>
<string name="msg_theta_image_send_success">画像転送に成功しました。</string>
<string name="msg_theta_image_send_fail">画像転送に失敗しました。\nWi-Fi接続状態を確認してください。</string>
<string name="msg_theta_image_delete_confirm">この画像を削除しますか?</string>
<string name="msg_theta_image_delete_success">画像削除に成功しました。</string>
<string name="msg_theta_image_delete_fail">画像削除に失敗しました。\nWi-Fi接続状態を確認してください。</string>
<string name="msg_theta_image_load_fail">画像情報取得に失敗しました。\nWi-Fi接続状態を確認してください。</string>
<string name="msg_deleting">削除中...</string>
<string name="msg_theta_shoot_fail">THETAカメラの撮影に失敗しました。\nWi-Fi接続状態を確認してください。</string>
<string name="msg_transferred">転送済み</string>
<string name="msg_error_device_wifi_off">端末のWi-FiをONにしてください。</string>
<string name="msg_transferring">転送中...</string>
<!--TheTa関連 開始 -->
<string name="menu_configuration">inertia</string>
<string name="menu_connection">connection</string>
<string name="rotate_inertia">rotation inertia</string>
<string name="inertia_0">none</string>
<string name="inertia_50">weak</string>
<string name="inertia_100">strong</string>
<string name="delete_dialog_message">Delete this file?</string>
<string name="dialog_positive_button">OK</string>
<string name="label_btn_image_size">Image Size</string>
<string name="image_size_2048x1024">2048 x 1024</string>
<string name="image_size_5376x2688">5376 x 2688</string>
<!--TheTa関連 終了 -->
</resources> </resources>
...@@ -1432,4 +1432,50 @@ ...@@ -1432,4 +1432,50 @@
<string name="msg_image_select_send_success">장면 이미지 등록에 성공하였습니다.</string> <string name="msg_image_select_send_success">장면 이미지 등록에 성공하였습니다.</string>
<string name="msg_image_select_send_fail_retry">장면 이미지 등록에 실패하였습니다. 다시 등록 처리를 실행 하시겠습니까?</string> <string name="msg_image_select_send_fail_retry">장면 이미지 등록에 실패하였습니다. 다시 등록 처리를 실행 하시겠습니까?</string>
<string name="msg_access_registing">등록중</string> <string name="msg_access_registing">등록중</string>
<string name="title_theta_camera">THETA카메라</string>
<string name="title_theta_camera_shoot">촬영</string>
<string name="title_theta_camera_image">이미지선택</string>
<string name="title_theta_library">THETA라이브러리</string>
<string name="title_theta_image_preview">THETA 미리보기</string>
<string name="title_theta_connect">카메라 선택</string>
<string name="msg_no_save_theta">카메라 정보가 없습니다.</string>
<string name="msg_no_save_theta_info">THETA단말기를 먼저 등록해 주세요.\n</string>
<string name="msg_theta_connect_info">THETA카메라와 접속하기 위해서는 Wifi설정을 ON으로 설정해야 합니다.</string>
<string name="title_theta_register">카메라 등록</string>
<string name="msg_theta_register_info">Theta카메라 접속에 필요한 시리얼 번호와 패스워드를 입력해 주세요.</string>
<string name="title_serial_number">시리얼 번호</string>
<string name="msg_wifi_connecting">Wi-Fi 접속중...</string>
<string name="msg_no_exists_theta_wifi">THETA카메라의 Wi-Fi기능을 ON으로 설정해 주세요.</string>
<string name="msg_fail_connect_theta_wifi">THETA카메라 접속 실패 하였습니다. THETA카메라의 Wi-Fi설정을 확이해 주세요.</string>
<string name="msg_fail_input_all_null">모든 정보를 입력해 주세요.</string>
<string name="title_theta_wifi_saved">등록된 단말기</string>
<string name="title_theta_wifi_not_saved">등록되지 않은 단말기</string>
<string name="title_theta_image_save">전송</string>
<string name="msg_theta_image_send_confirm">이미지를 전송 하시겠습니까?</string>
<string name="msg_theta_image_delete_confirm">이미지를 삭제 하시겠습니까?</string>
<string name="msg_theta_image_send_success">이미지 전송에 성공하였습니다.</string>
<string name="msg_theta_image_send_fail">이미지 전송에 실패하였습니다.\nWi-Fi접속 상태를 확인해 주세요.</string>
<string name="msg_theta_image_delete_success">이미지 삭제에 성공하였습니다.</string>
<string name="msg_theta_image_delete_fail">이미지 삭제에 실패하였습니다.\nWi-Fi접속 상태를 확인해 주세요.</string>
<string name="msg_theta_image_load_fail">이미지 정보 취득에 실패하였습니다.\nWi-Fi접속 상태를 확인해 주세요.</string>
<string name="msg_deleting">삭제중...</string>
<string name="msg_theta_shoot_fail">THETA카메라 촬영에 실패하였습니다.\nWi-Fi접속 상태를 확인해 주세요.</string>
<string name="msg_transferred">전송 완료</string>
<string name="msg_error_device_wifi_off">단말기의 Wi-Fi를 ON으로 설정해 주세요.</string>
<string name="msg_transferring">전송중...</string>
<!--TheTa関連 開始 -->
<string name="menu_configuration">inertia</string>
<string name="menu_connection">connection</string>
<string name="rotate_inertia">rotation inertia</string>
<string name="inertia_0">none</string>
<string name="inertia_50">weak</string>
<string name="inertia_100">strong</string>
<string name="delete_dialog_message">Delete this file?</string>
<string name="dialog_positive_button">OK</string>
<string name="label_btn_image_size">Image Size</string>
<string name="image_size_2048x1024">2048 x 1024</string>
<string name="image_size_5376x2688">5376 x 2688</string>
<!--TheTa関連 終了 -->
</resources> </resources>
\ No newline at end of file
...@@ -89,4 +89,10 @@ ...@@ -89,4 +89,10 @@
<color name="operation_bg">#FFFFFF</color> <color name="operation_bg">#FFFFFF</color>
<color name="bottom_toolbar">#F2F2F2</color> <color name="bottom_toolbar">#F2F2F2</color>
<color name="dialog_text_color">#000000</color>
<color name="theta_wifi_connect_dialog_background">#F7F7F7</color>
<color name="theta_wifi_connect_dialog_title_color">#989898</color>
</resources> </resources>
\ No newline at end of file
...@@ -1431,4 +1431,49 @@ ...@@ -1431,4 +1431,49 @@
<string name="msg_image_select_send_success">You have successfully registered a scene image.</string> <string name="msg_image_select_send_success">You have successfully registered a scene image.</string>
<string name="msg_image_select_send_fail_retry">Registration of the scene image failed. Do you want to register again?</string> <string name="msg_image_select_send_fail_retry">Registration of the scene image failed. Do you want to register again?</string>
<string name="msg_access_registing">Registring</string> <string name="msg_access_registing">Registring</string>
<string name="title_theta_camera">THETA Camera</string>
<string name="title_theta_camera_shoot">Shoot</string>
<string name="title_theta_camera_image">Image Select</string>
<string name="title_theta_library">THETA Library</string>
<string name="title_theta_image_preview">THETA Preview</string>
<string name="title_theta_connect">Camera Select</string>
<string name="msg_no_save_theta">There is no camera information.</string>
<string name="msg_no_save_theta_info">Register the THETA Device first.\n </string>
<string name="msg_theta_connect_info">To connect with THETA camera, WIFI setting must be ON.</string>
<string name="title_theta_register">Camera Register</string>
<string name="msg_theta_register_info">Enter the Serial Number and password of Theta to connect.</string>
<string name="title_serial_number">Serial Number</string>
<string name="msg_wifi_connecting">Wi-Fi connecting...</string>
<string name="msg_no_exists_theta_wifi">Set the THEA camera Wi-Fi function to ON.</string>
<string name="msg_fail_connect_theta_wifi">THETA camera connection failed. Check the Wi-Fi settings of THETA camera.</string>
<string name="msg_fail_input_all_null">Please enter all information.</string>
<string name="title_theta_wifi_saved">Registered device</string>
<string name="title_theta_wifi_not_saved">Unregistered device</string>
<string name="title_theta_image_save">transfer</string>
<string name="msg_theta_image_send_confirm">Would you like to transfer this image?</string>
<string name="msg_theta_image_delete_confirm">Are you sure you want to delete this image?</string>
<string name="msg_theta_image_send_success">Image transfer successful.</string>
<string name="msg_theta_image_send_fail">Image transfer failed.\nPlease check the Wi-Fi connection status.</string>
<string name="msg_theta_image_delete_success">Image delete successful.</string>
<string name="msg_theta_image_delete_fail">Image delete failed.\nPlease check the Wi-Fi connection status.</string>
<string name="msg_theta_image_load_fail">Failed to load image.\nPlease check the Wi-Fi connection status.</string>
<string name="msg_deleting">Deleting...</string>
<string name="msg_theta_shoot_fail">The THETA camera failed to shoot.\nPlease check the Wi-Fi connection status.</string>
<string name="msg_transferred">Transferred</string>
<string name="msg_error_device_wifi_off">Set the Wi-Fi of the device to ON.</string>
<string name="msg_transferring">transferring...</string>
<!--TheTa関連 開始 -->
<string name="menu_configuration">inertia</string>
<string name="menu_connection">connection</string>
<string name="rotate_inertia">rotation inertia</string>
<string name="inertia_0">none</string>
<string name="inertia_50">weak</string>
<string name="inertia_100">strong</string>
<string name="delete_dialog_message">Delete this file?</string>
<string name="dialog_positive_button">OK</string>
<string name="label_btn_image_size">Image Size</string>
<string name="image_size_2048x1024">2048 x 1024</string>
<string name="image_size_5376x2688">5376 x 2688</string>
<!--TheTa関連 終了 -->
</resources> </resources>
\ No newline at end of file
...@@ -16,4 +16,7 @@ ...@@ -16,4 +16,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Wifi使用権限 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
</manifest> </manifest>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/background">
<shape android:shape="rectangle">
<solid android:color="#D3D3D3"/>
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<scale
android:scaleWidth="100%" >
<shape android:shape="rectangle">
<solid android:color="#D3D3D3"/>
</shape>
</scale>
</item>
<item android:id="@android:id/progress">
<scale
android:scaleWidth="100%" >
<shape android:shape="rectangle">
<solid android:color="#D3D3D3"/>
</shape>
</scale>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="-6dp"
android:left="-3dp"
android:top="-6dp">
<shape android:shape="rectangle">
<solid android:color="@android:color/white" />
<stroke
android:width="2dp"
android:color="#D3D3D3" />
</shape>
</item>
</layer-list>
\ No newline at end of file
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
android:orientation="vertical"> android:orientation="vertical">
<RelativeLayout <RelativeLayout
android:id="@+id/device_image_list_list_toolbar" android:id="@+id/device_connect_toolbar"
style="@style/OperationSearchToolBar" style="@style/OperationSearchToolBar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="50dp"> android:layout_height="50dp">
...@@ -20,6 +20,15 @@ ...@@ -20,6 +20,15 @@
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:text="@string/label_entry" /> android:text="@string/label_entry" />
<Button
android:id="@+id/theta_camera"
android:layout_width="87dp"
android:layout_height="45dp"
android:layout_toRightOf="@id/regist"
android:layout_centerVertical="true"
android:layout_alignParentBottom="true"
android:text="camera" />
<TextView <TextView
android:id="@+id/device_image_list_title" android:id="@+id/device_image_list_title"
style="@style/DialogToolBarTitle" style="@style/DialogToolBarTitle"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/device_connect_toolbar"
style="@style/OperationSearchToolBar"
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:id="@+id/theta_camera_title"
style="@style/DialogToolBarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/title_theta_camera"
android:textColor="@color/edt_text"
android:textSize="@dimen/opeartion_title_text_size" />
<Button
android:id="@+id/btn_close"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/ic_operation_close"
android:contentDescription="@string/cont_desc" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.theta.view.MJpegView
android:id="@+id/live_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:alpha="0.3"
android:background="@android:color/black">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_exposure"
android:layout_width="55dp"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="EV:1.3"
android:textSize="18sp" />
<SeekBar
android:id="@+id/sb_exposure_old"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:background="@android:color/transparent"
android:max="12"
android:maxHeight="2dp"
android:minHeight="2dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:progress="2"
android:progressDrawable="@drawable/theta_exposure_progress_drawable"
android:thumb="@android:drawable/radiobutton_off_background"/>
<SeekBar
android:id="@+id/sb_exposure"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:background="@android:color/transparent"
android:max="12"
android:maxHeight="2dp"
android:minHeight="2dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:progress="2"
android:progressDrawable="@drawable/theta_exposure_progress_drawable"
android:thumb="@drawable/seek_handler"
android:tickMark="@drawable/theta_exposure_tickmark" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_theta_camera_image_list"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/btn_theta_list" />
<Button
android:id="@+id/btn_theta_camera_shoot"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:background="@drawable/btn_theta_shoot" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/device_connect_toolbar"
style="@style/OperationSearchToolBar"
android:layout_width="match_parent"
android:layout_height="50dp">
<Button
android:id="@+id/btn_back"
android:layout_width="87dp"
android:layout_height="45dp"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="@string/back" />
<TextView
android:id="@+id/theta_library_title"
style="@style/DialogToolBarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/title_theta_library"
android:textColor="@color/edt_text"
android:textSize="@dimen/opeartion_title_text_size" />
</RelativeLayout>
<ListView
android:id="@+id/lv_theta_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:divider="@android:color/darker_gray"
android:dividerHeight="1px"
/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/device_connect_toolbar"
style="@style/OperationSearchToolBar"
android:layout_width="match_parent"
android:layout_height="50dp">
<Button
android:id="@+id/btn_back"
android:layout_width="87dp"
android:layout_height="45dp"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="@string/back" />
<TextView
android:id="@+id/theta_imagePreview_title"
style="@style/DialogToolBarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/title_theta_image_preview"
android:textColor="@color/edt_text"
android:textSize="@dimen/opeartion_title_text_size" />
<Button
android:id="@+id/btn_theta_image_save"
android:layout_width="87dp"
android:layout_height="45dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="@string/save"/>
</RelativeLayout>
<com.theta.glview.GLPhotoView
android:id="@+id/photo_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/darker_gray"
android:dividerHeight="1px" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/configuration"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:minHeight="47dp"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rotate_inertia"
android:id="@+id/textView" />
<RadioGroup
android:id="@+id/rotation_inertia"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RadioButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/inertia_0"
android:id="@+id/inertia_0"
android:checked="false" />
<RadioButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/inertia_50"
android:id="@+id/inertia_50"
android:checked="false" />
<RadioButton
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/inertia_100"
android:id="@+id/inertia_100"
android:checked="false" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/dialog_positive_button"
android:id="@+id/btn_commit" />
</RadioGroup>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_item"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginLeft="5dp"
android:gravity="center_vertical"
android:text="TextView" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/object_list_row"
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false">
<ImageView
android:id="@+id/object_thumbnail"
android:layout_width="120dp"
android:layout_height="80dp"
android:layout_gravity="center_vertical"
android:scaleType="fitXY" />
<LinearLayout
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@id/object_thumbnail"
android:orientation="vertical">
<TextView
android:id="@+id/tv_file_name"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:textColor="@android:color/black" />
<TextView
android:id="@+id/tv_create_date"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:textColor="@android:color/black" />
<TextView
android:id="@+id/tv_transferred_status"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:text="@string/msg_transferred"
android:textColor="@android:color/holo_red_dark" />
</LinearLayout>
<Button
android:id="@+id/btn_theta_image_save"
android:layout_width="85dp"
android:layout_height="45dp"
android:layout_toLeftOf="@+id/btn_theta_image_delete"
android:layout_centerVertical="true"
android:text="@string/title_theta_image_save" />
<Button
android:id="@+id/btn_theta_image_delete"
android:layout_width="85dp"
android:layout_height="45dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="10dp"
android:text="@string/delete" />
</RelativeLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/theta_wifi_connect_dialog_background"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/device_connect_toolbar"
style="@style/OperationSearchToolBar"
android:layout_width="match_parent"
android:layout_height="50dp">
<Button
android:id="@+id/btn_theta_update"
android:layout_width="87dp"
android:layout_height="45dp"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="@string/content_update"
android:textSize="@dimen/dialog_button_text_size"/>
<TextView
android:id="@+id/theta_camera_connect"
style="@style/DialogToolBarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/title_theta_connect"
android:textColor="@android:color/black"
android:textSize="@dimen/dialog_title_text_size"/>
<Button
android:id="@+id/btn_close"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@drawable/ic_operation_close"
android:contentDescription="@string/cont_desc"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title_theta_wifi_saved"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/title_theta_wifi_saved"
android:textColor="@color/theta_wifi_connect_dialog_title_color"
android:textSize="@dimen/dialog_text_size" />
<ListView
android:id="@+id/lv_theta_wifi_saved"
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@android:color/white"
android:divider="@null"
android:dividerHeight="0dp"
android:minHeight="150dp" />
<TextView
android:id="@+id/tv_title_theta_wifi_not_saved"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:text="@string/title_theta_wifi_not_saved"
android:textColor="@color/theta_wifi_connect_dialog_title_color"
android:textSize="@dimen/dialog_text_size" />
<ListView
android:id="@+id/lv_theta_wifi_not_saved"
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@android:color/white"
android:divider="@null"
android:dividerHeight="0dp"
android:minHeight="150dp" />
</LinearLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<dimen name="opeartion_title_text_size" /> <dimen name="opeartion_title_text_size" />
<dimen name="dialog_title_text_size">18dp</dimen>
<dimen name="dialog_text_size">15dp</dimen>
<dimen name="dialog_button_text_size">13dp</dimen>
</resources> </resources>
\ No newline at end of file
...@@ -60,7 +60,7 @@ public class ImageCache { ...@@ -60,7 +60,7 @@ public class ImageCache {
private static final int DEFAULT_MEM_CACHE_SIZE = 1024 * 5; // 5MB private static final int DEFAULT_MEM_CACHE_SIZE = 1024 * 5; // 5MB
// Default disk cache size in bytes // Default disk cache size in bytes
private static final int DEFAULT_DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB private static final int DEFAULT_DISK_CACHE_SIZE = 1024 * 1024 * 100; // 100MB
// Compression settings when writing images to disk cache // Compression settings when writing images to disk cache
private static final CompressFormat DEFAULT_COMPRESS_FORMAT = CompressFormat.JPEG; private static final CompressFormat DEFAULT_COMPRESS_FORMAT = CompressFormat.JPEG;
...@@ -114,10 +114,13 @@ public class ImageCache { ...@@ -114,10 +114,13 @@ public class ImageCache {
imageCache = new ImageCache(cacheParams); imageCache = new ImageCache(cacheParams);
mRetainFragment.setObject(imageCache); mRetainFragment.setObject(imageCache);
} }
return imageCache;
}
public static ImageCache getInstance(ImageCacheParams cacheParams) {
ImageCache imageCache = new ImageCache(cacheParams);
return imageCache; return imageCache;
} }
/** /**
* Initialize the cache, providing all parameters. * Initialize the cache, providing all parameters.
* *
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package com.imagepicker; package com.imagepicker;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Bitmap; import android.graphics.Bitmap;
...@@ -25,13 +26,19 @@ import android.graphics.drawable.BitmapDrawable; ...@@ -25,13 +26,19 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable; import android.graphics.drawable.TransitionDrawable;
import android.os.Looper;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.util.Log; import android.util.Log;
import android.widget.ImageView; import android.widget.ImageView;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import jp.agentec.abook.abv.bl.common.log.Logger;
/** /**
* This class wraps up completing some arbitrary long running work when loading a bitmap to an * This class wraps up completing some arbitrary long running work when loading a bitmap to an
* ImageView. It handles things like using a memory and disk cache, running the work in a background * ImageView. It handles things like using a memory and disk cache, running the work in a background
...@@ -77,16 +84,19 @@ public abstract class ImageWorker { ...@@ -77,16 +84,19 @@ public abstract class ImageWorker {
return; return;
} }
BitmapDrawable value = null; // BitmapDrawable value = null;
Bitmap value = null;
if (mImageCache != null) { if (mImageCache != null) {
value = mImageCache.getBitmapFromMemCache(String.valueOf(data)); value = mImageCache.getBitmapFromDiskCache(String.valueOf(data));
} }
if (value != null) { if (value != null) {
Logger.d(TAG, "Bitmap found in memory cache");
// Bitmap found in memory cache // Bitmap found in memory cache
imageView.setImageDrawable(value); // imageView.setImageDrawable(value);
imageView.setImageBitmap(value);
} else if (cancelPotentialWork(data, imageView)) { } else if (cancelPotentialWork(data, imageView)) {
Logger.d(TAG, "Bitmap not found in memory cache");
//BEGIN_INCLUDE(execute_background_task) //BEGIN_INCLUDE(execute_background_task)
final BitmapWorkerTask task = new BitmapWorkerTask(data, imageView, orientation); final BitmapWorkerTask task = new BitmapWorkerTask(data, imageView, orientation);
final AsyncDrawable asyncDrawable = final AsyncDrawable asyncDrawable =
...@@ -98,6 +108,8 @@ public abstract class ImageWorker { ...@@ -98,6 +108,8 @@ public abstract class ImageWorker {
// for more info on what was changed. // for more info on what was changed.
task.executeOnExecutor(AsyncTask.DUAL_THREAD_EXECUTOR); task.executeOnExecutor(AsyncTask.DUAL_THREAD_EXECUTOR);
//END_INCLUDE(execute_background_task) //END_INCLUDE(execute_background_task)
} else {
Logger.d(TAG, "****Bitmap not found in memory cache");
} }
} }
...@@ -145,6 +157,12 @@ public abstract class ImageWorker { ...@@ -145,6 +157,12 @@ public abstract class ImageWorker {
new CacheAsyncTask().execute(MESSAGE_INIT_DISK_CACHE); new CacheAsyncTask().execute(MESSAGE_INIT_DISK_CACHE);
} }
public void addImageCache(Context context, String diskCacheDirectoryName) {
mImageCacheParams = new ImageCache.ImageCacheParams(context, diskCacheDirectoryName);
mImageCache = ImageCache.getInstance(mImageCacheParams);
new CacheAsyncTask().execute(MESSAGE_INIT_DISK_CACHE);
}
/** /**
* If set to true, the image will fade-in once it has been loaded by the background thread. * If set to true, the image will fade-in once it has been loaded by the background thread.
*/ */
......
package com.theta.glview;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.widget.Scroller;
import com.theta.model.Constants;
import com.theta.model.Photo;
import com.theta.model.RotateInertia;
/**
* View class for photo display
*/
public class GLPhotoView extends GLSurfaceView {
private static final int ANIMATION_INTERVAL = 10;
private GLRenderer mRenderer = null;
private GestureDetector mGestureDetector;
private ScaleGestureDetector mScaleGestureDetector;
private Scroller mScroller = null;
private float mPrevX, mPrevY;
private RotateInertia mRotateInertia = RotateInertia.INERTIA_0;
/**
* Constructor
* @param context Context
*/
public GLPhotoView(Context context) {
this(context, null);
}
/**
* Constructor
* @param context Context
* @param attrs Argument for resource
*/
public GLPhotoView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context);
}
/**
* onTouchEvent Event listener
* @param event Event object
* @return Process continuation judgment value
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean ret = false;
mScaleGestureDetector.onTouchEvent(event);
if (!mScaleGestureDetector.isInProgress()) {
ret = mGestureDetector.onTouchEvent(event);
if (!ret) {
super.onTouchEvent(event);
}
}
return ret;
}
private void initialize(Context context) {
setEGLContextClientVersion(2);
mRenderer = new GLRenderer();
setRenderer(mRenderer);
setLongClickable(true);
mGestureDetector = new GestureDetector(context, new GestureDetector.OnGestureListener() {
private final int SWIPE_MAX_OF_PATH_X = 100;
private final int SWIPE_MAX_OF_PATH_Y = 100;
final Handler handler = new Handler();
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
return;
}
@Override
public void onLongPress(MotionEvent e) {
return;
}
@Override
public boolean onDown(MotionEvent e) {
if (null != mScroller && !mScroller.isFinished()) {
mScroller.abortAnimation();
handler.removeCallbacksAndMessages(null);
}
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
boolean ret = false;
if (null != mScroller && !mScroller.isFinished()) {
mScroller.abortAnimation();
}
if ((Math.abs(distanceX) > SWIPE_MAX_OF_PATH_X ) || (Math.abs(distanceY) > SWIPE_MAX_OF_PATH_Y )) {
ret = false;
} else {
float diffX = distanceX / Constants.ON_SCROLL_DIVIDER_X;
float diffY = distanceY / Constants.ON_SCROLL_DIVIDER_Y;
if (Math.abs(diffX) < Constants.THRESHOLD_SCROLL_X) {
diffX = 0.0f;
}
if (Math.abs(diffY) < Constants.THRESHOLD_SCROLL_Y) {
diffY = 0.0f;
}
if (null != mRenderer) {
mRenderer.rotate(diffX, -diffY);
}
ret = true;
}
return ret;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
mScroller.fling((int)e2.getX(), (int)e2.getY(), (int)velocityX, (int)velocityY, 0, getWidth(), 0, getHeight());
mPrevX = e2.getX();
mPrevY = e2.getY();
handler.post(new Runnable() {
@Override
public void run() {
if (mRotateInertia == RotateInertia.INERTIA_0) {
// do nothing
}
else {
mScroller.computeScrollOffset();
float diffX = mScroller.getCurrX() - mPrevX;
float diffY = mScroller.getCurrY() - mPrevY;
mPrevX = mScroller.getCurrX();
mPrevY = mScroller.getCurrY();
if (mRotateInertia == RotateInertia.INERTIA_50) {
diffX = diffX / Constants.ON_FLING_DIVIDER_X_FOR_INERTIA_50;
diffY = diffY / Constants.ON_FLING_DIVIDER_Y_FOR_INERTIA_50;
}
else {
diffX = diffX / Constants.ON_FLING_DIVIDER_X_FOR_INERTIA_100;
diffY = diffY / Constants.ON_FLING_DIVIDER_Y_FOR_INERTIA_100;
}
mRenderer.rotate((float) -diffX, (float) diffY);
if (!mScroller.isFinished()) {
handler.postDelayed(this, ANIMATION_INTERVAL);
}
}
}
});
return true;
}
});
mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener() {
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scale = detector.getScaleFactor();
if (null != mRenderer) {
mRenderer.scale(scale);
}
return true;
}
});
mScroller = new Scroller(context);
return;
}
/**
* Texture setting method
* @param thumbnail Photo object for texture
*/
public void setTexture(Photo thumbnail) {
mRenderer.setTexture(thumbnail);
return;
}
/**
* Inertia setting method
* @param mRotateInertia Setting inertia value
*/
public void setmRotateInertia(RotateInertia mRotateInertia) {
this.mRotateInertia = mRotateInertia;
return;
}
}
\ No newline at end of file
package com.theta.glview.model;
import android.opengl.GLES20;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
/**
* UV sphere model class
*/
public class UVSphere {
private final int COORDS_PER_VERTEX = 3;
private final int TEXTURE_COORDS_PER_VERTEX = 2;
private int mStrips;
private int mStripePointsNum;
private ArrayList<FloatBuffer> mVertices;
private ArrayList<FloatBuffer> mTextureCoords;
private final int vertexStride = COORDS_PER_VERTEX * 4;
private final int textureStride = TEXTURE_COORDS_PER_VERTEX * 4;
private UVSphere() {
mVertices = new ArrayList<FloatBuffer>();
mTextureCoords = new ArrayList<FloatBuffer>();
}
/**
* Constructor
* Sphere is displayed according to the number of partitions.
* The longitude is created from the number of partitions which is half the number of
* latitude lines 1 and the number of polygons which is double the number of
* partitions set in the radius specified as the origin coordinates.
* @param radius Radius
* @param divide Number of partitions (must be an even number)
* @param eastSide true is east side of sphere, otherwise is west side
*/
public UVSphere(float radius, int divide, boolean eastSide) {
this();
if (radius <= 0 || divide <= 0 || 0 != (divide % 2)) {
throw new IllegalArgumentException();
}
mStrips = divide/2;
mStripePointsNum = (divide+1)*2;
makeSphereVertices(radius, divide, eastSide);
}
/**
* Sphere drawing method
* @param mPositionHandle Handler value tied to gl_Position in vertex shader
* @param mUVHandle Handler value tied to the UV coordinates provided to the fragment shader via the varyig variable
*/
public void draw(int mPositionHandle, int mUVHandle) {
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glEnableVertexAttribArray(mUVHandle);
for (int i = 0; i < this.mStrips; i++) {
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, mVertices.get(i));
GLES20.glVertexAttribPointer(mUVHandle, TEXTURE_COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, textureStride, mTextureCoords.get(i));
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, mStripePointsNum);
}
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mUVHandle);
return;
}
private void makeSphereVertices(float radius, int divide, boolean eastSide) {
float altitude = 0.0f;
float altitudeDelta = 0.0f;
float azimuth = 0.0f;
float ex = 0.0f;
float ey = 0.0f;
float ez = 0.0f;
Double startPoint;
if (eastSide) {
startPoint = 0.0d;
} else {
startPoint = Math.PI;
}
for(int i = 0; i < divide/2; ++i)
{
altitude = (float) (Math.PI/2.0 - i * (Math.PI*2) / divide);
altitudeDelta = (float) (Math.PI/2.0 - (i + 1) * (Math.PI*2) / divide);
float[] vertices = new float[divide*6+6];
float[] texCoords = new float[divide*4+4];
for(int j = 0; j <= divide/2; ++j)
{
azimuth = (float) (startPoint - (j * (Math.PI*2) / divide));
// first point
ex = (float) (Math.cos(altitudeDelta) * Math.cos(azimuth));
ey = (float) Math.sin(altitudeDelta);
ez = (float) (Math.cos(altitudeDelta) * Math.sin(azimuth));
vertices[6*j+0] = radius * ex;
vertices[6*j+1] = radius * ey;
vertices[6*j+2] = radius * ez;
texCoords[4*j+0] = 1.0f-(2*j/(float)divide);
texCoords[4*j+1] = 2*(i+1)/(float)divide;
// second point
ex = (float) (Math.cos(altitude) * Math.cos(azimuth));
ey = (float) Math.sin(altitude);
ez = (float) (Math.cos(altitude) * Math.sin(azimuth));
vertices[6*j+3] = radius * ex;
vertices[6*j+4] = radius * ey;
vertices[6*j+5] = radius * ez;
texCoords[4*j+2] = 1.0f-(2*j/(float)divide);
texCoords[4*j+3] = 2*i/(float)divide;
}
mVertices.add(makeFloatBufferFromArray(vertices));
mTextureCoords.add(makeFloatBufferFromArray(texCoords));
}
return;
}
private FloatBuffer makeFloatBufferFromArray(float[] array) {
FloatBuffer fb = ByteBuffer.allocateDirect(array.length*Float.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
fb.put(array);
fb.position(0);
return fb;
}
}
package com.theta.model;
/**
* Constant used by the program
*/
public interface Constants {
/** Radius of sphere for photo */
static final int TEXTURE_SHELL_RADIUS = 2;
/** Number of sphere polygon partitions for photo, which must be an even number */
static final int SHELL_DIVIDES = 40;
/** Maximum value that can be specified as the camera FOV variable */
static final int CAMERA_FOV_DEGREE_MAX = 100;
/** Minimum value that can be specified as the camera FOV variable */
static final int CAMERA_FOV_DEGREE_MIN = 30;
/** Pitch width of zoom in process */
static final float SCALE_RATIO_TICK_EXPANSION = 1.05f;
/** Pitch width of zoom out process */
static final float SCALE_RATIO_TICK_REDUCTION = 0.95f;
/** Rotation threshold for scroll (X axis direction) */
static final double THRESHOLD_SCROLL_X = 0.02;
/** Rotation threshold for scroll (Y axis direction) */
static final double THRESHOLD_SCROLL_Y = 0.02;
/** Rotation amount derivative parameter for scroll (X axis direction) */
static final float ON_SCROLL_DIVIDER_X = 400.0f;
/** Rotation amount derivative parameter for scroll (Y axis direction) */
static final float ON_SCROLL_DIVIDER_Y = 400.0f;
/** Movement amount derivative parameter when inertia setting is small (X axis direction) */
static final float ON_FLING_DIVIDER_X_FOR_INERTIA_50 = 650.0f;
/** Movement amount derivative parameter when inertia setting is small (Y axis direction) */
static final float ON_FLING_DIVIDER_Y_FOR_INERTIA_50 = (650.0f*3.0f);
/** Movement amount derivative parameter when inertia setting is large (X axis direction) */
static final float ON_FLING_DIVIDER_X_FOR_INERTIA_100 = 65.0f;
/** Movement amount derivative parameter when inertia setting is large (Y axis direction) */
static final float ON_FLING_DIVIDER_Y_FOR_INERTIA_100 = (65.0f*10.0f);
}
\ No newline at end of file
package com.theta.model;
/**
* Image size type
*/
public enum ImageSize {
/** 2048x1024 */
IMAGE_SIZE_2048x1024,
/** 5376x2688 */
IMAGE_SIZE_5376x2688
}
package com.theta.model;
import android.graphics.Bitmap;
/**
* Photo object storage class
*/
public class Photo {
private Double mOrientationAngle;
private Double mElevationAngle;
private Double mHorizontalAngle;
private Bitmap mPhoto;
private Photo() {
}
/**
* Constructor
* @param photo Photo object
*/
public Photo(Bitmap photo) {
this(photo, null, null, null);
}
/**
* Constructor
* @param photo Photo object
* @param orientationAngle Orientation angle
* @param elevationAngle Elevation angle
* @param horizontalAngle Horizontal angle
*/
public Photo(Bitmap photo, Double orientationAngle, Double elevationAngle, Double horizontalAngle) {
this();
mOrientationAngle = orientationAngle;
mElevationAngle = elevationAngle;
mHorizontalAngle = horizontalAngle;
mPhoto = photo;
}
/**
* Acquires the orientation angle
* @return Orientation angle
*/
public Double getOrientationAngle() {
return mOrientationAngle;
}
/**
* Acquires the elevation angle
* @return Elevation angle
*/
public Double getElevetionAngle() {
return mElevationAngle;
}
/**
* Acquires the horizontal angle
* @return Horizontal angle
*/
public Double getHorizontalAngle() {
return mHorizontalAngle;
}
/**
* Acquires the photo object
* @return Photo object
*/
public Bitmap getPhoto() {
return mPhoto;
}
/**
* Updates the photo object
* @param drawable Photo object
*/
public void updatePhoto(Bitmap drawable) {
mPhoto = drawable;
}
}
\ No newline at end of file
package com.theta.model;
/**
* Indicates the rotation inertia
*/
public enum RotateInertia {
/** none */
INERTIA_0,
/** weak */
INERTIA_50,
/** strong */
INERTIA_100,;
}
\ No newline at end of file
package com.theta.network;
/**
* HTTP communication download listener class
*/
public interface HttpDownloadListener {
/**
* Total byte count
*/
void onTotalSize(long totalSize);
/**
* Received byte count
*/
void onDataReceived(int size);
}
package com.theta.network;
/**
* HTTP communication event listener class
*/
public interface HttpEventListener {
/**
* Notifies you of the device status check results
* @param newStatus true:Update available, false;No update available
*/
void onCheckStatus(boolean newStatus);
/**
* Notifies you when the file is saved
* @param latestCapturedFileId ID of saved file
*/
void onObjectChanged(String latestCapturedFileId);
/**
* Notify on completion of event
*/
void onCompleted();
/**
* Notify in the event of an error
*/
void onError(String errorMessage);
}
package com.theta.network;
/**
* Image data class
*/
public class ImageData {
private byte[] mRawData;
private Double pitch = 0.0d;
private Double roll = 0.0d;
private Double yaw = 0.0d;
/**
* Acquire raw data of image
* @return Raw data of image
*/
public byte[] getRawData() {
return mRawData;
}
/**
* Set raw data of image
* @param rawData Raw data of image
*/
public void setRawData(byte[] rawData) {
mRawData = rawData;
}
/**
* Acquire pitch angle
* @return Pitch angle
*/
public Double getPitch() {
return pitch;
}
/**
* Set pitch angle
* @param pitch Pitch angle (value must be between -90 and 90)
*/
public void setPitch(Double pitch) {
this.pitch = pitch;
}
/**
* Acquire roll angle
* @return Roll angle
*/
public Double getRoll() {
return roll;
}
/**
* Set roll angle
* @param roll Roll angle (value must be between -180 and 180)
*/
public void setRoll(Double roll) {
this.roll = roll;
}
/**
* Acquire yaw angle
* @return Yaw angle
*/
public Double getYaw() {
return yaw;
}
/**
* Set yaw angle
* @param yaw Yaw angle (value must be between 0 and 360)
*/
public void setYaw(Double yaw) {
this.yaw = yaw;
}
}
package com.theta.network;
/**
* Information class of media file
*/
public class ImageInfo {
public static String FILE_FORMAT_CODE_EXIF_JPEG = "JPEG";
public static String FILE_FORMAT_CODE_EXIF_MPEG = "MPEG";
private String mFileName;
private String mFileId;
private long mFileSize;
private String mCaptureDate;
private String mFileFormat;
private int mWidth;
private int mHeight;
/**
* Acquire file name
* @return File name
*/
public String getFileName() {
return mFileName;
}
/**
* Set file name
* @param fileName File name
*/
public void setFileName(String fileName) {
mFileName = fileName;
}
/**
* Acquire File ID
* @return File ID
*/
public String getFileId() {
return mFileId;
}
/**
* Set File ID
* @param fileId File ID
*/
public void setFileId(String fileId) {
mFileId = fileId;
}
/**
* Acquire file size
* @return File size (unit: bytes)
*/
public long getFileSize() {
return mFileSize;
}
/**
* Set file size
* @param fileSize File size (unit: bytes)
*/
public void setFileSize(long fileSize) {
mFileSize = fileSize;
}
/**
* Acquire shooting time
* @return Shooting time
*/
public String getCaptureDate() {
return mCaptureDate;
}
/**
* Set shooting time
* @param captureDate Shooting time
*/
public void setCaptureDate(String captureDate) {
mCaptureDate = captureDate;
}
/**
* Acquire media format
* @return Media format
*/
public String getFileFormat() {
return mFileFormat;
}
/**
* Set media format<p>
* Set {@link ImageInfo#FILE_FORMAT_CODE_EXIF_JPEG} or {@link ImageInfo#FILE_FORMAT_CODE_EXIF_MPEG}.
* @param fileFormat Media format
*/
public void setFileFormat(String fileFormat) {
mFileFormat = fileFormat;
}
/**
* Acquire image width
* @return Image width
*/
public int getWidth() {
return mWidth;
}
/**
* Set image width
* @param width Image width
*/
public void setWidth(int width) {
mWidth = width;
}
/**
* Acquire image height
* @return Image height
*/
public int getHeight() {
return mHeight;
}
/**
* Set image height
* @param height Image height
*/
public void setHeight(int height) {
mHeight = height;
}
}
package com.theta.network;
/**
* Information class of device storage
*/
public class StorageInfo {
int mRemainingPictures = 0;
long mRemainingSpace = 0;
long mTotalSpace = 0;
/**
* Acquire remaining number of images that can be shot
* @return Remaining number of images that can be shot
*/
public int getFreeSpaceInImages() {
return mRemainingPictures;
}
/**
* Set remaining number of images that can be shot
* @param remainingPictures Remaining number of images that can be shot
*/
public void setFreeSpaceInImages(int remainingPictures) {
mRemainingPictures = remainingPictures;
}
/**
* Acquire remaining capacity
* @return Remaining capacity (unit: bytes)
*/
public long getFreeSpaceInBytes() {
return mRemainingSpace;
}
/**
* Set remaining capacity
* @param remainingSpace Remaining capacity (unit: bytes)
*/
public void setFreeSpaceInBytes(long remainingSpace) {
mRemainingSpace = remainingSpace;
}
/**
* Acquire total capacity of device
* @return Total capacity of device (unit: bytes)
*/
public long getMaxCapacity() {
return mTotalSpace;
}
/**
* Set total capacity of device
* @param totalSpace Total capacity of device (unit: bytes)
*/
public void setMaxCapacity(long totalSpace) {
mTotalSpace = totalSpace;
}
}
package com.theta.network;
/**
* Device information class
*/
public class ThetaDeviceInfo {
private String mModel = "";
private String mDeviceVersion = "";
private String mSerialNumber = "";
private String mSSID = "";
private int mNetworkId = -1;
/**
* Constructor
*/
public ThetaDeviceInfo() {
}
/**
* Acquire model name
* @return Model name
*/
public String getModel() {
return mModel;
}
/**
* Set model name
* @param model Model name
*/
public void setModel(String model) {
mModel = model;
}
/**
* Acquire serial number
* @return Serial number
*/
public String getSerialNumber() {
return mSerialNumber;
}
/**
* Set serial number
* @param serialNumber Serial number
*/
public void setSerialNumber(String serialNumber) {
mSerialNumber = serialNumber;
}
/**
* Acquire firmware version
* @return Firmware version
*/
public String getDeviceVersion() {
return mDeviceVersion;
}
/**
* Set firmware version
* @param version Firmware version
*/
public void setDeviceVersion(String version) {
mDeviceVersion = version;
}
/**
* Acquire SSID
* @return SSID
*/
public String getSSID() {
return mSSID;
}
/**
* Set SSID
* @param ssid SSID
*/
public void setSSID(String ssid) {
mSSID = ssid;
}
/**
* Acquire network ID
* @return network ID
*/
public int getNetworkId() {
return mNetworkId;
}
/**
* Set network ID
* @param networkId network ID
*/
public void setNetworkId(int networkId) {
mNetworkId = networkId;
}
}
package com.theta.network;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.StringReader;
/**
* XMP data class
*/
public class XMP {
private final static String XMP_START_ELEMENT = "<x:xmpmeta";
private final static String XMP_END_ELEMENT = "</x:xmpmeta>";
private final static String XMP_TAG_NAME_PITCH = "PosePitchDegrees";
private final static String XMP_TAG_NAME_ROLL = "PoseRollDegrees";
private Double mPosePitchDegrees;
private Double mPoseRollDegrees;
/**
* Constructor
* @param original Raw data of image
*/
public XMP(byte[] original) {
int startXmpIndex = indexOf(original, XMP_START_ELEMENT.getBytes(), 0);
int endXmpIndex = indexOf(original, XMP_END_ELEMENT.getBytes(), startXmpIndex);
String xmpData = new String(original, startXmpIndex, endXmpIndex - startXmpIndex + XMP_END_ELEMENT.length());
XmlPullParser parser = Xml.newPullParser();
try {
parser.setInput(new StringReader(xmpData));
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
String tagName = parser.getName();
if (tagName.equals(XMP_TAG_NAME_PITCH)) {
String pitchInXml = parser.nextText();
mPosePitchDegrees = Double.valueOf(pitchInXml);
} else if (tagName.equals(XMP_TAG_NAME_ROLL)) {
String rollInXml = parser.nextText();
mPoseRollDegrees = Double.valueOf(rollInXml);
}
break;
case XmlPullParser.START_DOCUMENT:
case XmlPullParser.END_TAG:
case XmlPullParser.TEXT:
// do nothing
break;
}
eventType = parser.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Acquire pitch angle set for XMP
* @return Pitch angle
*/
public Double getPosePitchDegrees() {
return mPosePitchDegrees;
}
/**
* Acquire roll angle set for XMP
* @return Roll angle
*/
public Double getPoseRollDegrees() {
return mPoseRollDegrees;
}
/**
* Search position of specific data pattern
* @param original Search target data
* @param sub Searched data
* @param startIndex Search start position
* @return The position where the searched data starts. "-1" is returned if there are no hits.
*/
private int indexOf(byte[] original, byte[] sub, int startIndex)
{
int subIndex = 0;
for(int originalIndex = startIndex; originalIndex < original.length; originalIndex++) {
if(original[originalIndex] == sub[subIndex]) {
if(subIndex == sub.length - 1) {
return originalIndex - subIndex;
}
subIndex++;
} else {
subIndex = 0;
}
}
return -1;
}
}
package com.theta.view;
import android.app.*;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.RadioGroup;
import jp.agentec.abook.abv.launcher.android.R;
import com.theta.model.RotateInertia;
/**
* Setting dialog fragment
*/
public class ConfigurationDialog extends DialogFragment {
private RotateInertia mRotateInertia;
private DialogBtnListener mListener = null;
/**
*
*/
public ConfigurationDialog() {
super();
}
/**
* onCreateDialog Method
* @param savedInstanceState onCreateDialog Status value
* @return Dialog instance
*/
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
final View layout = inflater.inflate(R.layout.dialog_glphotoview_config, null);
if (null != layout) {
Button btn = (Button)layout.findViewById(R.id.btn_commit);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != mListener) {
mListener.onDialogCommitClick(mRotateInertia);
}
dismiss();
}
});
}
mRotateInertia = (RotateInertia) getArguments().getSerializable("rotate_inertia");
if (null != mRotateInertia) {
assert layout != null;
RadioGroup rg = (RadioGroup) layout.findViewById(R.id.rotation_inertia);
if (null != rg) {
switch (mRotateInertia) {
case INERTIA_0:
rg.check(R.id.inertia_0);
break;
case INERTIA_50:
rg.check(R.id.inertia_50);
break;
case INERTIA_100:
rg.check(R.id.inertia_100);
break;
default:
break;
}
rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId == R.id.inertia_0) {
mRotateInertia = RotateInertia.INERTIA_0;
} else if (checkedId == R.id.inertia_50) {
mRotateInertia = RotateInertia.INERTIA_50;
} else if (checkedId == R.id.inertia_100) {
mRotateInertia = RotateInertia.INERTIA_100;
} else {
mRotateInertia = null;
}
}
});
}
}
builder.setView(layout);
return builder.create();
}
/**
* Dialog display method
* @param mgr Fragment manager object
* @param inertia Inertia settings for rotation process
*/
public static void show(FragmentManager mgr, RotateInertia inertia) {
ConfigurationDialog dialog = new ConfigurationDialog();
Bundle bundle = new Bundle();
bundle.putSerializable("rotate_inertia", inertia);
dialog.setArguments(bundle);
dialog.show(mgr, ConfigurationDialog.class.getSimpleName());
}
/**
* onAttach Method
* @param activity Attached activity object
*/
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (DialogBtnListener) activity;
}
catch (ClassCastException e) {
e.printStackTrace();
mListener = null;
}
}
/**
* Event listener interface for when a dialog is exited
* If a selection value is required in this dialog, it is necessary to attach the activity that implemented this method
*/
public interface DialogBtnListener {
void onDialogCommitClick(RotateInertia inertia);
}
}
package com.theta.view;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.List;
import jp.agentec.abook.abv.launcher.android.R;
/**
* Adapter class for photo list display
*/
public class ImageListArrayAdapter extends ArrayAdapter<ImageRow> {
private List<ImageRow> rows;
private LayoutInflater inflater;
/**
* Constructor
* @param context Context
* @param resourceIdOfListLayout Resource ID for specifying line information
* @param rows Line object
*/
public ImageListArrayAdapter(Context context, int resourceIdOfListLayout, List<ImageRow> rows) {
super(context, resourceIdOfListLayout, rows);
this.rows = rows;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**
* getView Method
* @param position Acquisition position
* @param convertView convertView object
* @param parent Parent object for list
* @return View instance
*/
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.listlayout_object, null);
holder = new ViewHolder();
holder.thumbnail = convertView.findViewById(R.id.object_thumbnail);
holder.fileNameTextView = convertView.findViewById(R.id.tv_file_name);
holder.creatDateTextView = convertView.findViewById(R.id.tv_create_date);
holder.saveButton = convertView.findViewById(R.id.btn_theta_image_save);
holder.deleteButton = convertView.findViewById(R.id.btn_theta_image_delete);
holder.transferredTextView = convertView.findViewById(R.id.tv_transferred_status);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final ImageRow row = rows.get(position);
if (row.isPhoto()) {
byte[] thumbnailImage = row.getThumbnail();
holder.thumbnail.setImageBitmap(BitmapFactory.decodeByteArray(thumbnailImage, 0, thumbnailImage.length));
} else {
holder.thumbnail.setImageBitmap(null);
}
holder.fileNameTextView.setText(row.getFileName());
holder.creatDateTextView.setText(row.getCaptureDate());
holder.saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((ListView) parent).performItemClick(v, position, R.id.btn_theta_image_save);
}
});
holder.deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((ListView) parent).performItemClick(v, position, R.id.btn_theta_image_save);
}
});
if (row.isTransferred()) {
holder.transferredTextView.setVisibility(View.VISIBLE);
} else {
holder.transferredTextView.setVisibility(View.INVISIBLE);
}
return convertView;
}
public void setListItem(List<ImageRow> changeRows) {
this.rows = changeRows;
}
static class ViewHolder {
Button deleteButton;
Button saveButton;
TextView fileNameTextView;
TextView creatDateTextView;
TextView transferredTextView;
ImageView thumbnail;
}
}
package com.theta.view;
/**
* Line object for list when photo list is displayed
*/
public class ImageRow {
private String fileId;
private long fileSize;
private boolean isPhoto;
private byte[] thumbnail;
private String fileName;
private String captureDate;
private boolean isTransferred;
/**
* Identifier value acquisition method for photo object
* @return Handle value for photo object
*/
public String getFileId() {
return fileId;
}
/**
* Identifier value setting method for photo object
* @param fileId identifier value for photo object
*/
public void setFileId(String fileId) {
this.fileId = fileId;
}
/**
* Acquire file size
* @return File size
*/
public long getFileSize() {
return fileSize;
}
/**
* Set file size
* @param fileSize File size
*/
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
/**
* Photo information feasibility value acquisition method
* @return Photo information feasibility value
*/
public boolean isPhoto() {
return isPhoto;
}
/**
* Photo information feasibility value setting method
* @param isPhoto Photo information feasibility value
*/
public void setIsPhoto(boolean isPhoto) {
this.isPhoto = isPhoto;
}
/**
* Thumbnail information acquisition method
* @return Thumbnail information
*/
public byte[] getThumbnail() {
return thumbnail;
}
/**
* Thumbnail information setting method
* @param thumbnail Thumbnail information
*/
public void setThumbnail(byte[] thumbnail) {
this.thumbnail = thumbnail;
}
/**
* File name acquisition method
* @return File name
*/
public String getFileName() {
return fileName;
}
/**
* File name setting method
* @param fileName File name
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* Capture date and time acquisition method
* @return Capture date and time
*/
public String getCaptureDate() {
return captureDate;
}
/**
* Capture date and time setting method
* @param captureDate Capture date and time
*/
public void setCaptureDate(String captureDate) {
this.captureDate = captureDate;
}
/**
* Photo Transferred value value acquisition method
* @return Photo Transferred value
*/
public boolean isTransferred() {
return isTransferred;
}
/**
* Photo Transferred value value setting method
* @param isTransferred Photo Transferred value
*/
public void setIsTransferred(boolean isTransferred) {
this.isTransferred = isTransferred;
}
}
package com.theta.view;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;
import android.widget.TextView;
/**
* View for log display
*/
public class LogView extends ScrollView {
private TextView textView;
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
/**
* Constructor
* @param context Context
* @param attrs Argument for resource
*/
public LogView(Context context, AttributeSet attrs) {
super(context, attrs);
setFillViewport(true);
textView = new TextView(context);
textView.setBackgroundResource(android.R.color.darker_gray);
textView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
this.addView(textView);
}
/**
* Log output request method
* @param newLine Output log
*/
public void append(CharSequence newLine) {
textView.append(newLine);
textView.append(LINE_SEPARATOR);
fullScroll(FOCUS_DOWN);
}
}
package com.theta.view;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* Input stream for motion JPEG data
*/
public class MJpegInputStream extends DataInputStream {
private final byte[] SOI_MARKER = {(byte) 0xFF, (byte) 0xD8};
private final byte[] EOF_MARKER = {(byte) 0xFF, (byte) 0xD9};
private final static String CONTENT_LENGTH = "Content-Length";
private final static int HEADER_MAX_LENGTH = 100;
private final static int FRAME_MAX_LENGTH = 40000 + HEADER_MAX_LENGTH;
/**
* Constructor
* @param inputStream Input stream for receiving data
*/
public MJpegInputStream(InputStream inputStream) {
super(new BufferedInputStream(inputStream, FRAME_MAX_LENGTH));
}
/**
* Acquire end position of specified character string
* @param dataInputStream Input stream for receiving data
* @param sequence Specified character string
* @return End position of specified character string
* @throws IOException
*/
private int getEndOfSequence(DataInputStream dataInputStream, byte[] sequence) throws IOException {
int sequenceIndex = 0;
byte readByteData;
for(int index = 0; index < FRAME_MAX_LENGTH; index++) {
readByteData = (byte) dataInputStream.readUnsignedByte();
if(readByteData == sequence[sequenceIndex]) {
sequenceIndex++;
if(sequenceIndex == sequence.length) {
return index + 1;
}
} else {
sequenceIndex = 0;
}
}
return -1;
}
/**
* Acquire start position of specified character string
* @param dataInputStream Input stream for receiving data
* @param sequence Specified character string
* @return Start position of specified character string
* @throws IOException
*/
private int getStartOfSequence(DataInputStream dataInputStream, byte[] sequence) throws IOException {
int endIndex = getEndOfSequence(dataInputStream, sequence);
return (endIndex < 0) ? (-1) : (endIndex - sequence.length);
}
/**
* Acquire data length from header
* @param headerByteData Header data
* @return Data length
* @throws IOException
* @throws NumberFormatException
*/
private int parseContentLength(byte[] headerByteData) throws IOException, NumberFormatException {
ByteArrayInputStream bais = new ByteArrayInputStream(headerByteData);
Properties properties = new Properties();
properties.load(bais);
return Integer.parseInt(properties.getProperty(CONTENT_LENGTH));
}
/**
* Acquire image data for 1 frame
* @return Image data for 1 frame
* @throws IOException
*/
public Bitmap readMJpegFrame() throws IOException {
mark(FRAME_MAX_LENGTH);
int headerLength = getStartOfSequence(this, SOI_MARKER);
int contentLength;
reset();
byte[] headerData = new byte[headerLength];
readFully(headerData);
try {
contentLength = parseContentLength(headerData);
} catch (NumberFormatException e) {
e.getStackTrace();
contentLength = getEndOfSequence(this, EOF_MARKER);
}
reset();
byte[] frameData = new byte[contentLength];
skipBytes(headerLength);
readFully(frameData);
return BitmapFactory.decodeStream(new ByteArrayInputStream(frameData));
}
}
package com.theta.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
/**
* Motion JPEG view
*/
public class MJpegView extends SurfaceView implements SurfaceHolder.Callback {
private MJpegViewThread mMJpegViewThread = null;
private MJpegInputStream mMJpegInputStream = null;
private boolean existSurface = false;
private int mDisplayWidth;
private int mDisplayHeight;
/**
* Constructor
* @param context
*/
public MJpegView(Context context) {
super(context);
init();
}
/**
* Constructor
* @param context
* @param attrs
*/
public MJpegView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
/**
* Constructor
* @param context
* @param attrs
* @param defStyleAttr
*/
public MJpegView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
/**
* Initialization process
*/
private void init() {
SurfaceHolder holder = getHolder();
holder.addCallback(this);
setFocusable(true);
mDisplayWidth = getWidth();
mDisplayHeight = getHeight();
}
/**
* Start playback
*/
public void play() {
if (mMJpegViewThread != null) {
stopPlay();
}
if(mMJpegInputStream != null) {
if (mMJpegViewThread != null) {
if (mMJpegViewThread.getState() == Thread.State.NEW) {
mMJpegViewThread.start();
}
} else {
mMJpegViewThread = new MJpegViewThread(getHolder());
mMJpegViewThread.start();
}
}
}
/**
* Stop playback
*/
public void stopPlay() {
if (mMJpegViewThread != null) {
mMJpegViewThread.cancel();
boolean retry = true;
while (retry) {
try {
mMJpegViewThread.join();
retry = false;
mMJpegViewThread = null;
} catch (InterruptedException e) {
e.getStackTrace();
}
}
}
}
/**
* Set source stream for receiving motion JPEG
* @param source Source stream
*/
public void setSource(MJpegInputStream source) {
mMJpegInputStream = source;
play();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
existSurface = true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
synchronized(holder) {
mDisplayWidth = width;
mDisplayHeight = height;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
existSurface = false;
stopPlay();
}
/**
* Thread class for receiving motion JPEG
*/
private class MJpegViewThread extends Thread {
private final SurfaceHolder mSurfaceHolder;
private boolean keepRunning = true;
/**
* Constructor
* @param surfaceHolder
*/
public MJpegViewThread(SurfaceHolder surfaceHolder) {
mSurfaceHolder = surfaceHolder;
}
/**
* Acquire image size according to display area<p>
* Calculates the size that fits the display area while maintaining the aspect ratio of the motion JPEG.
* @param bitmapWidth Width of motion JPEG
* @param bitmapHeight Height of motion JPEG
* @return Image size
*/
private Rect getImageRect(int bitmapWidth, int bitmapHeight) {
float bitmapAspectRatio = (float) bitmapWidth / (float) bitmapHeight;
bitmapWidth = mDisplayWidth;
bitmapHeight = (int) (mDisplayWidth / bitmapAspectRatio);
if (bitmapHeight > mDisplayHeight) {
bitmapHeight = mDisplayHeight;
bitmapWidth = (int) (mDisplayHeight * bitmapAspectRatio);
}
int bitmapX = (mDisplayWidth / 2) - (bitmapWidth / 2);
int bitmapY = (mDisplayHeight / 2) - (bitmapHeight / 2);
return new Rect(0, bitmapY, mDisplayWidth, bitmapHeight + bitmapY);
}
/**
* Abort thread
*/
public void cancel() {
keepRunning = false;
}
@Override
public void run() {
Bitmap bitmap;
Rect bitmapRect;
Canvas bitmapCanvas = null;
while (keepRunning) {
if (existSurface) {
try {
bitmapCanvas = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder) {
try {
if ((mMJpegInputStream != null) && (bitmapCanvas != null)) {
bitmap = mMJpegInputStream.readMJpegFrame();
bitmapRect = getImageRect(bitmap.getWidth(), bitmap.getHeight());
bitmapCanvas.drawColor(Color.BLACK);
bitmapCanvas.drawBitmap(bitmap, null, bitmapRect, new Paint());
bitmap.recycle();
}
} catch (IOException e) {
e.getStackTrace();
keepRunning = false;
}
}
} finally {
if (bitmapCanvas != null) {
mSurfaceHolder.unlockCanvasAndPost(bitmapCanvas);
}
}
}
}
bitmapCanvas = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder) {
if (bitmapCanvas != null) {
bitmapCanvas.drawColor(Color.BLACK);
}
}
if (bitmapCanvas != null) {
mSurfaceHolder.unlockCanvasAndPost(bitmapCanvas);
}
if (mMJpegInputStream != null) {
try {
mMJpegInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
...@@ -253,4 +253,17 @@ public class DeviceInfo { ...@@ -253,4 +253,17 @@ public class DeviceInfo {
//noinspection deprecation(API18から非推奨になった。無視) //noinspection deprecation(API18から非推奨になった。無視)
return (long)stat.getBlockSize() * stat.getAvailableBlocks(); return (long)stat.getBlockSize() * stat.getAvailableBlocks();
} }
/**
* デバイスのWifi有効・無効チェック
* @return true:有効, false:無効
*/
public static boolean isDeviceWifiEnabled(Context context) {
WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (wifiManager == null) {
return false;
}
return true;
}
} }
...@@ -169,6 +169,12 @@ public abstract class ABVActivity extends Activity { ...@@ -169,6 +169,12 @@ public abstract class ABVActivity extends Activity {
showProgressPopup(getResources().getString(R.string.progress)); showProgressPopup(getResources().getString(R.string.progress));
} }
public void changeProgressPopup(String msg) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.setMessage(msg);
}
}
public void closeProgressPopup() { public void closeProgressPopup() {
handler.post(new Runnable() { handler.post(new Runnable() {
@Override @Override
...@@ -807,6 +813,13 @@ public abstract class ABVActivity extends Activity { ...@@ -807,6 +813,13 @@ public abstract class ABVActivity extends Activity {
PreferenceUtil.putUserPref(this, UserPrefKey.LEAVE_APP, System.currentTimeMillis()); PreferenceUtil.putUserPref(this, UserPrefKey.LEAVE_APP, System.currentTimeMillis());
} }
public void showSimpleAlertDialog(final int bodyId) {
showSimpleAlertDialog(getString(R.string.app_name), getString(bodyId));
}
public void showSimpleAlertDialog(final String body) {
showSimpleAlertDialog(getString(R.string.app_name), body);
}
public void showSimpleAlertDialog(final int titleResId, final int bodyResId) { public void showSimpleAlertDialog(final int titleResId, final int bodyResId) {
showSimpleAlertDialog(getString(titleResId), getString(bodyResId)); showSimpleAlertDialog(getString(titleResId), getString(bodyResId));
} }
......
...@@ -115,6 +115,9 @@ public abstract class ABVAuthenticatedActivity extends ABVActivity implements Co ...@@ -115,6 +115,9 @@ public abstract class ABVAuthenticatedActivity extends ABVActivity implements Co
public static final String FILEPATH = "FILEPATH"; public static final String FILEPATH = "FILEPATH";
//連続タップ防止用のボタン活性化するタイム
protected static final int BUTTON_ENABLE_DELAY_MILLIS = 500;
protected ContentDao contentDao = AbstractDao.getDao(ContentDao.class); protected ContentDao contentDao = AbstractDao.getDao(ContentDao.class);
protected MemoLogic memoLogic = AbstractLogic.getLogic(MemoLogic.class); protected MemoLogic memoLogic = AbstractLogic.getLogic(MemoLogic.class);
...@@ -777,4 +780,20 @@ public abstract class ABVAuthenticatedActivity extends ABVActivity implements Co ...@@ -777,4 +780,20 @@ public abstract class ABVAuthenticatedActivity extends ABVActivity implements Co
public void stopContentRefresher() { public void stopContentRefresher() {
contentRefresher.stopRefresh(); contentRefresher.stopRefresh();
} }
/**
* @version 1.2.300
* ダブルタップ制御用
* @param button ダブルタップ防止ボタン
*/
protected void buttonDoubleTapControl(Button button) {
final Button finalButton = button;
finalButton.setEnabled(false);
handler.postDelayed(new Runnable() {
@Override
public void run() {
finalButton.setEnabled(true);
}
}, BUTTON_ENABLE_DELAY_MILLIS);
}
} }
...@@ -72,6 +72,12 @@ import java.util.List; ...@@ -72,6 +72,12 @@ import java.util.List;
public abstract class ABVUIActivity extends ABVAuthenticatedActivity { public abstract class ABVUIActivity extends ABVAuthenticatedActivity {
private final static String TAG = "ABVUIActivity"; private final static String TAG = "ABVUIActivity";
//タブレットでダイアログ表示の画面サイズ調整スケール
protected static final float DIALOG_WINDOW_RESIZE_SCALE_06 = 0.6f;
protected static final float DIALOG_WINDOW_RESIZE_SCALE_07 = 0.7f;
protected static final float DIALOG_WINDOW_RESIZE_SCALE_08 = 0.8f;
protected static final float DIALOG_WINDOW_RESIZE_SCALE_09 = 0.9f;
private boolean startRefresh; //自動リフレッシュはネットワークエラー表示しないように private boolean startRefresh; //自動リフレッシュはネットワークエラー表示しないように
protected ImageView mRefreshImage; // add by jang protected ImageView mRefreshImage; // add by jang
protected TextView mUpdatedDate; // add by jang protected TextView mUpdatedDate; // add by jang
......
package jp.agentec.abook.abv.ui.common.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.List;
import jp.agentec.abook.abv.launcher.android.R;
public class SimpleTextViewAdapter extends BaseAdapter {
private List<String> mListItem;
private LayoutInflater mInflater;
public SimpleTextViewAdapter(Context context, List<String> listItem) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mListItem = listItem;
}
@Override
public int getCount() {
return mListItem.size();
}
@Override
public Object getItem(int position) {
return mListItem.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_simple_textview, null);
}
TextView textView = convertView.findViewById(R.id.tv_item);
textView.setText(mListItem.get(position));
return convertView;
}
}
...@@ -4,8 +4,6 @@ import android.app.Activity; ...@@ -4,8 +4,6 @@ import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
...@@ -13,7 +11,6 @@ import android.widget.ImageButton; ...@@ -13,7 +11,6 @@ import android.widget.ImageButton;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import java.io.File;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -22,29 +19,22 @@ import jp.agentec.abook.abv.bl.acms.client.json.content.ContentJSON; ...@@ -22,29 +19,22 @@ import jp.agentec.abook.abv.bl.acms.client.json.content.ContentJSON;
import jp.agentec.abook.abv.bl.acms.type.OperationType; import jp.agentec.abook.abv.bl.acms.type.OperationType;
import jp.agentec.abook.abv.bl.common.ABVEnvironment; import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.Callback; import jp.agentec.abook.abv.bl.common.Callback;
import jp.agentec.abook.abv.bl.common.CommonExecutor;
import jp.agentec.abook.abv.bl.common.Constant; import jp.agentec.abook.abv.bl.common.Constant;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys; import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.exception.ABVExceptionCode;
import jp.agentec.abook.abv.bl.common.exception.AcmsException;
import jp.agentec.abook.abv.bl.common.log.Logger; import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.dao.AbstractDao; import jp.agentec.abook.abv.bl.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.data.dao.ContentDao; import jp.agentec.abook.abv.bl.data.dao.ContentDao;
import jp.agentec.abook.abv.bl.dto.ContentDto; import jp.agentec.abook.abv.bl.dto.ContentDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic; import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.ContentObjectLogLogic; import jp.agentec.abook.abv.bl.logic.ContentObjectLogLogic;
import jp.agentec.abook.abv.bl.logic.OperationLogic;
import jp.agentec.abook.abv.cl.util.ContentLogUtil; import jp.agentec.abook.abv.cl.util.ContentLogUtil;
import jp.agentec.abook.abv.cl.util.PreferenceUtil; import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.R; import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVContentViewActivity; import jp.agentec.abook.abv.ui.common.activity.ABVContentViewActivity;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType; import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.constant.ErrorCode;
import jp.agentec.abook.abv.ui.common.constant.ErrorMessage;
import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog; import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil; import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.common.util.PatternStringUtil; import jp.agentec.abook.abv.ui.common.util.PatternStringUtil;
import jp.agentec.abook.abv.ui.home.helper.ABookCheckWebViewHelper;
import jp.agentec.abook.abv.ui.home.helper.ABookPermissionHelper; import jp.agentec.abook.abv.ui.home.helper.ABookPermissionHelper;
import jp.agentec.abook.abv.ui.home.helper.ActivityHandlingHelper; import jp.agentec.abook.abv.ui.home.helper.ActivityHandlingHelper;
import jp.agentec.abook.abv.ui.home.helper.ContentViewHelper; import jp.agentec.abook.abv.ui.home.helper.ContentViewHelper;
...@@ -70,6 +60,7 @@ public class ParentWebViewActivity extends ABVContentViewActivity { ...@@ -70,6 +60,7 @@ public class ParentWebViewActivity extends ABVContentViewActivity {
private ProgressBar m_progress; private ProgressBar m_progress;
protected ContentDto mContentDto; protected ContentDto mContentDto;
protected void commonOnCreate() { protected void commonOnCreate() {
mContentDto = AbstractDao.getDao(ContentDao.class).getContent(contentId); mContentDto = AbstractDao.getDao(ContentDao.class).getContent(contentId);
historyLayout = (LinearLayout) findViewById(R.id.historyLayout); historyLayout = (LinearLayout) findViewById(R.id.historyLayout);
...@@ -102,7 +93,6 @@ public class ParentWebViewActivity extends ABVContentViewActivity { ...@@ -102,7 +93,6 @@ public class ParentWebViewActivity extends ABVContentViewActivity {
ABookPermissionHelper helper = new ABookPermissionHelper(context, Constant.ABookPermissionType.ReadExternalStorage, null); ABookPermissionHelper helper = new ABookPermissionHelper(context, Constant.ABookPermissionType.ReadExternalStorage, null);
if (helper.checkMultiPermissions(true)) { if (helper.checkMultiPermissions(true)) {
//シーン画像選択画面表示 //シーン画像選択画面表示
Logger.d("test");
Intent intent = new Intent(); Intent intent = new Intent();
intent.putExtra(ABookKeys.CONTENT_ID, contentId); intent.putExtra(ABookKeys.CONTENT_ID, contentId);
String className = DeviceImageListActivity.class.getName(); String className = DeviceImageListActivity.class.getName();
...@@ -130,6 +120,10 @@ public class ParentWebViewActivity extends ABVContentViewActivity { ...@@ -130,6 +120,10 @@ public class ParentWebViewActivity extends ABVContentViewActivity {
} }
} }
protected void commonProgressChanged(int progress) { protected void commonProgressChanged(int progress) {
setVisbilityProgress(true); setVisbilityProgress(true);
if (progress >= 100) { if (progress >= 100) {
......
package jp.agentec.abook.abv.ui.viewer.activity.theta;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import com.theta.helper.ThetaHelper;
import com.theta.network.ImageData;
import com.theta.view.ImageListArrayAdapter;
import com.theta.view.ImageRow;
import java.util.List;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVUIActivity;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.viewer.activity.theta.task.DeleteImageTask;
import jp.agentec.abook.abv.ui.viewer.activity.theta.task.ImageListTask;
import jp.agentec.abook.abv.ui.viewer.activity.theta.task.LoadPhotoTask;
/**
* THETAライブラリ画面
* @version 1.2.300
* @since 2020/05/19
* @author 金鎭星
*/
public class ThetaImageListActivity extends ABVUIActivity {
private static final String TAG = "ThetaImageListActivity";
private ListView mImageListView;
private ThetaHelper mThetaHelper = new ThetaHelper(this);
private List<ImageRow> mImageRows;
private int mSelectedPosition;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ac_theta_image_list);
mImageListView = findViewById(R.id.lv_theta_image);
// 戻るボタン
Button backBtn = findViewById(R.id.btn_back);
backBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
showProgressPopup();
new ImageListTask(this).execute();
}
//端末の戻るボタン禁止
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
Logger.v(TAG, "dispatchKeyEvent %s", event);
if (event.getAction()==KeyEvent.ACTION_UP) { // 戻るボタンを抑止
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_BACK:
return true;
}
}
return super.dispatchKeyEvent(event);
}
/**
* THETAカメラから全ての画像情報取得するImageListTaskTask終了時に呼ばれる
* @param imageRows 画像データ配列
*/
public void imageListTaskFinish(List<ImageRow> imageRows) {
if (imageRows != null) {
mImageRows = imageRows;
ImageListArrayAdapter imageListArrayAdapter = new ImageListArrayAdapter(ThetaImageListActivity.this, R.layout.listlayout_object, imageRows);
mImageListView.setAdapter(imageListArrayAdapter);
mImageListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
final ImageRow selectedItem = (ImageRow) parent.getItemAtPosition(position);
int viewId = view.getId();
if (viewId == R.id.btn_theta_image_save) { //保存ボタン
buttonDoubleTapControl((Button) view);
AlertDialogUtil.showAlertDialog(ThetaImageListActivity.this, R.string.app_name, R.string.msg_theta_image_send_confirm, false, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
showProgressPopup(getString(R.string.msg_transferring));
mSelectedPosition = position;
//画像情報を取得
new LoadPhotoTask(ThetaImageListActivity.this, selectedItem.getFileId()).execute();
}
});
} else if (viewId == R.id.btn_theta_image_delete) { //削除ボタン
buttonDoubleTapControl((Button) view);
AlertDialogUtil.showAlertDialog(ThetaImageListActivity.this, R.string.app_name, R.string.msg_theta_image_delete_confirm, false, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
showProgressPopup(getString(R.string.msg_deleting));
mSelectedPosition = position;
new DeleteImageTask(ThetaImageListActivity.this).execute(selectedItem.getFileId());
}
});
} else { //通常アイテムタップ時
if (selectedItem.isPhoto()) {
Intent intent = new Intent();
intent.putExtra(ABookKeys.THETA_FILE_ID, selectedItem.getFileId());
intent.setClassName(getPackageName(), ThetaImagePreviewActivity.class.getName());
startActivity(intent);
} else {
Logger.e(TAG, "is not Photo");
}
}
}
});
} else {
showSimpleAlertDialog(R.string.msg_theta_image_load_fail);
Logger.e(TAG, "failed to get image list");
}
closeProgressPopup();
}
/**
* THETAカメラから画像情報取得するLoadPhotoTask終了時に呼ばれる
* 画像データがある場合、ローカルに保存する
* @param imageData 画像データ
*/
public void loadPhotoTaskFinish(ImageData imageData, String fileId) {
if (imageData != null) {
byte[] dataObject = imageData.getRawData();
if (dataObject == null) {
return;
}
Bitmap bitmap = BitmapFactory.decodeByteArray(dataObject, 0, dataObject.length);
if (mThetaHelper.thetaImageLocalSave(bitmap, fileId)) {
showSimpleAlertDialog(R.string.msg_theta_image_send_success);
ImageRow imageRow = mImageRows.get(mSelectedPosition);
imageRow.setIsTransferred(true);
ImageListArrayAdapter imageListArrayAdapter = (ImageListArrayAdapter)mImageListView.getAdapter();
imageListArrayAdapter.setListItem(mImageRows);
imageListArrayAdapter.notifyDataSetChanged();
} else {
Logger.e(TAG,"failed to local save image");
showSimpleAlertDialog(R.string.msg_theta_image_send_fail);
}
} else {
Logger.e(TAG,"failed to download image");
showSimpleAlertDialog(R.string.msg_theta_image_load_fail);
}
closeProgressPopup();
}
/**
* THETAカメラから画像を削除するDeleteImageTask終了時に呼ばれる
* @param isSuccess 削除結果(true:成功、false:失敗)
*/
public void deleteImageTaskFinish(boolean isSuccess) {
if (isSuccess) {
AlertDialogUtil.showAlertDialog(ThetaImageListActivity.this, R.string.app_name, R.string.msg_theta_image_delete_success, true, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mImageRows.remove(mSelectedPosition);
ImageListArrayAdapter imageListArrayAdapter = (ImageListArrayAdapter)mImageListView.getAdapter();
imageListArrayAdapter.setListItem(mImageRows);
imageListArrayAdapter.notifyDataSetChanged();
}
});
} else {
showSimpleAlertDialog(R.string.msg_theta_image_delete_fail);
Logger.e(TAG,"failed to delete image");
}
closeProgressPopup();
}
}
package jp.agentec.abook.abv.ui.viewer.activity.theta;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import com.theta.glview.GLPhotoView;
import com.theta.helper.ThetaHelper;
import com.theta.model.Photo;
import com.theta.model.RotateInertia;
import com.theta.network.ImageData;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVUIActivity;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.viewer.activity.theta.task.LoadPhotoTask;
/**
* THETAプレビュー画面
* @version 1.2.300
* @since 2020/05/19
* @author 金鎭星
*/
public class ThetaImagePreviewActivity extends ABVUIActivity {
private static final String TAG = "ThetaImagePreviewActivity";
private RotateInertia mRotateInertia = RotateInertia.INERTIA_0;
private Button mSaveBtn;
private GLPhotoView mGLPhotoView;
private Photo mTexture;
private String mFileId;
private ThetaHelper mThetaHelper = new ThetaHelper(this);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ac_theta_image_preview);
// 戻るボタン
Button backBtn = findViewById(R.id.btn_back);
backBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
// 転送ボタン
mSaveBtn = findViewById(R.id.btn_theta_image_save);
mSaveBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
buttonDoubleTapControl(mSaveBtn);
AlertDialogUtil.showAlertDialog(ThetaImagePreviewActivity.this, R.string.app_name, R.string.msg_theta_image_send_confirm, false, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
showProgressPopup();
if (mThetaHelper.thetaImageLocalSave(mTexture.getPhoto(), mFileId)) {
showSimpleAlertDialog(R.string.app_name, R.string.msg_theta_image_send_success);
} else {
showSimpleAlertDialog(R.string.app_name, R.string.msg_theta_image_send_fail);
}
closeProgressPopup();
}
});
}
});
Intent intent = getIntent();
this.mFileId = intent.getStringExtra(ABookKeys.THETA_FILE_ID);
mGLPhotoView = findViewById(R.id.photo_image);
mGLPhotoView.setmRotateInertia(mRotateInertia);
LoadPhotoTask loadPhotoTask = new LoadPhotoTask(this, mFileId);
loadPhotoTask.execute();
}
//端末の戻るボタン禁止
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
Logger.v(TAG, "dispatchKeyEvent %s", event);
if (event.getAction()==KeyEvent.ACTION_UP) { // 戻るボタンを抑止
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_BACK:
return true;
}
}
return super.dispatchKeyEvent(event);
}
/**
* THETAカメラから画像情報取得するLoadPhotoTask終了時に呼ばれる
* @param imageData 画像データ
*/
public void loadPhotoTaskFinish(ImageData imageData) {
if (imageData != null) {
byte[] dataObject = imageData.getRawData();
if (dataObject == null) {
return;
}
Bitmap __bitmap = BitmapFactory.decodeByteArray(dataObject, 0, dataObject.length);
Double yaw = imageData.getYaw();
Double pitch = imageData.getPitch();
Double roll = imageData.getRoll();
mTexture = new Photo(__bitmap, yaw, pitch, roll);
if (null != mGLPhotoView) {
mGLPhotoView.setTexture(mTexture);
}
closeProgressPopup();
} else {
showSimpleAlertDialog(R.string.app_name, R.string.msg_theta_image_load_fail);
Logger.e("failed to download image");
}
}
}
package jp.agentec.abook.abv.ui.viewer.activity.theta.task;
import android.os.AsyncTask;
import com.theta.network.HttpConnector;
import com.theta.network.HttpEventListener;
import java.lang.ref.WeakReference;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.constant.ABookValues;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaImageListActivity;
public class DeleteImageTask extends AsyncTask<String, String, Void> {
private static final String TAG = "DeleteImageTask";
private final WeakReference<ThetaImageListActivity> refActivity;
public DeleteImageTask(ThetaImageListActivity refActivity) {
this.refActivity = new WeakReference<>(refActivity);
}
@Override
protected Void doInBackground(String... fileId) {
Logger.d(TAG, "doInBackground delete " + fileId[0]);
DeleteEventListener deleteListener = new DeleteEventListener();
boolean isOldApi = PreferenceUtil.getUserPref(refActivity.get(),ABookKeys.THETA_OLD_VERSION_FLG, false);
HttpConnector camera = new HttpConnector(ABookValues.THETA_IP_ADDRESS, isOldApi);
camera.deleteFile(fileId[0], deleteListener);
return null;
}
private class DeleteEventListener implements HttpEventListener {
@Override
public void onCheckStatus(boolean newStatus) {
if (newStatus) {
Logger.d(TAG, "onCheckStatus deleteFile:FINISHED");
} else {
Logger.d(TAG,"onCheckStatus deleteFile:IN PROGRESS");
}
}
@Override
public void onObjectChanged(String latestCapturedFileId) {
Logger.d(TAG, "onObjectChanged delete " + latestCapturedFileId);
}
@Override
public void onCompleted() {
Logger.e(TAG, "onCompleted deleted.");
refActivity.get().runOnUiThread(new Runnable() {
@Override
public void run() {
ThetaImageListActivity imageListActivity = refActivity.get();
imageListActivity.deleteImageTaskFinish(true);
}
});
}
@Override
public void onError(String errorMessage) {
Logger.e(TAG, "delete error " + errorMessage);
refActivity.get().runOnUiThread(new Runnable() {
@Override
public void run() {
ThetaImageListActivity imageListActivity = refActivity.get();
imageListActivity.deleteImageTaskFinish(false);
}
});
}
}
}
package jp.agentec.abook.abv.ui.viewer.activity.theta.task;
import android.os.AsyncTask;
import com.theta.network.ThetaDeviceInfo;
import com.theta.network.HttpConnector;
import java.lang.ref.WeakReference;
import jp.agentec.abook.abv.bl.common.constant.ABookValues;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.ui.viewer.activity.DeviceImageListActivity;
public class DeviceInfoTask extends AsyncTask<Void, String, ThetaDeviceInfo> {
private static final String TAG = "DeviceInfoTask";
private final WeakReference<DeviceImageListActivity> refActivity;
public static final int FAIL_RETRAY_DELAY_MILLIS = 2000;
public DeviceInfoTask(DeviceImageListActivity refActivity) {
this.refActivity = new WeakReference<>(refActivity);
}
@Override
protected ThetaDeviceInfo doInBackground(Void... params) {
Logger.d(TAG, "doInBackground");
HttpConnector camera = new HttpConnector(ABookValues.THETA_IP_ADDRESS);
final int MAX_RETRY_COUNT = 5;
ThetaDeviceInfo deviceInfo = null;
//Wifi切り替え時間が必要なので、失敗した場合、5回リトライする。
for (int retryCount = 0; retryCount < MAX_RETRY_COUNT; retryCount++) {
deviceInfo = camera.getDeviceInfo();
if (deviceInfo.getModel() == null || deviceInfo.getModel().length() == 0) {
try {
Thread.sleep(FAIL_RETRAY_DELAY_MILLIS);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} else {
retryCount = MAX_RETRY_COUNT;
}
}
return deviceInfo;
}
@Override
protected void onPostExecute(ThetaDeviceInfo deviceInfo) {
Logger.d(TAG, "onPostExecute");
DeviceImageListActivity activity = refActivity.get();
activity.thetaDeviceInfoTaskFinish(deviceInfo);
}
}
package jp.agentec.abook.abv.ui.viewer.activity.theta.task;
import android.os.AsyncTask;
import com.theta.network.HttpConnector;
import java.lang.ref.WeakReference;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.constant.ABookValues;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaCameraActivity;
public class FinishWlanTask extends AsyncTask<Void, String, String> {
private static final String TAG = "FinishWlanTask";
private static final int SLEEP_TIME = 2000;
private final WeakReference<ThetaCameraActivity> refActivity;
public FinishWlanTask(ThetaCameraActivity refActivity) {
this.refActivity = new WeakReference<>(refActivity);
}
@Override
protected String doInBackground(Void... params) {
Logger.d(TAG, "doInBackground");
boolean isOldApi = PreferenceUtil.getUserPref(refActivity.get(), ABookKeys.THETA_OLD_VERSION_FLG, false);
HttpConnector camera = new HttpConnector(ABookValues.THETA_IP_ADDRESS, isOldApi);
if (camera.cameraFinishWlan()) {
try {
// Wifi切り替える時間2秒スリップ
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
Logger.e(TAG, "sleep error" + e.toString());
}
return ABookValues.SUCCESS;
}
return ABookValues.FAIL;
}
@Override
protected void onPostExecute(String result) {
Logger.d(TAG, "onPostExecute");
ThetaCameraActivity activity = refActivity.get();
activity.finishWlanTaskFinish(result);
}
}
package jp.agentec.abook.abv.ui.viewer.activity.theta.task;
import android.os.AsyncTask;
import com.theta.network.HttpConnector;
import java.lang.ref.WeakReference;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.constant.ABookValues;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaCameraActivity;
public class GetOptionExposureTask extends AsyncTask<Void, String, String> {
private static final String TAG = "GetOptionExposureTask";
private final WeakReference<ThetaCameraActivity> refActivity;
public GetOptionExposureTask(ThetaCameraActivity refActivity) {
this.refActivity = new WeakReference<>(refActivity);
}
@Override
protected String doInBackground(Void... params) {
Logger.d(TAG, "doInBackground");
boolean isOldApi = PreferenceUtil.getUserPref(refActivity.get(), ABookKeys.THETA_OLD_VERSION_FLG, false);
HttpConnector camera = new HttpConnector(ABookValues.THETA_IP_ADDRESS, isOldApi);
return camera.getOptionExposure();
}
@Override
protected void onPostExecute(String exposure) {
Logger.d(TAG, "onPostExecute");
ThetaCameraActivity activity = refActivity.get();
activity.getOptionExposureTaskFinish(exposure);
}
}
package jp.agentec.abook.abv.ui.viewer.activity.theta.task;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Toast;
import com.theta.helper.ThetaHelper;
import com.theta.network.HttpConnector;
import com.theta.network.ImageInfo;
import com.theta.view.ImageListArrayAdapter;
import com.theta.view.ImageRow;
import java.io.ByteArrayOutputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.constant.ABookValues;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaCameraActivity;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaImageListActivity;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaImagePreviewActivity;
/**
* THETAカメラ内の画像情報取得スレッド
* @version 1.2.300
* @author kimjinsung
* @since 2020/05/29
*/
public class ImageListTask extends AsyncTask<Void, String, List<ImageRow>> {
private static final String TAG = "ImageListTask";
private final WeakReference<ThetaImageListActivity> refActivity;
public ImageListTask(ThetaImageListActivity refActivity) {
this.refActivity = new WeakReference<>(refActivity);
}
@Override
protected void onPreExecute() {
Logger.d(TAG, "onPreExecute");
}
@Override
protected List<ImageRow> doInBackground(Void... params) {
try {
Logger.d(TAG, "doInBackground");
boolean isOldApi = PreferenceUtil.getUserPref(refActivity.get(), ABookKeys.THETA_OLD_VERSION_FLG, false);
HttpConnector camera = new HttpConnector(ABookValues.THETA_IP_ADDRESS, isOldApi);
List<ImageRow> imageRows = new ArrayList<>();
ArrayList<ImageInfo> objects = camera.getList();
int objectSize = objects.size();
ThetaHelper thetaHelper = new ThetaHelper(refActivity.get());
for (int i = 0; i < objectSize; i++) {
ImageInfo object = objects.get(i);
//動画ファイルは除外
if (object.getFileFormat().equals(ImageInfo.FILE_FORMAT_CODE_EXIF_MPEG)) {
continue;
}
ImageRow imageRow = new ImageRow();
imageRow.setFileId(object.getFileId());
imageRow.setFileSize(object.getFileSize());
imageRow.setFileName(object.getFileName());
imageRow.setCaptureDate(object.getCaptureDate());
imageRow.setIsPhoto(true);
Bitmap thumbnail = camera.getThumb(object.getFileId());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, baos);
final byte[] thumbnailImage = baos.toByteArray();
imageRow.setThumbnail(thumbnailImage);
if (thetaHelper.transferredImage(object.getFileId())) {
imageRow.setIsTransferred(true);
} else {
imageRow.setIsTransferred(false);
}
imageRows.add(imageRow);
}
return imageRows;
} catch (Throwable throwable) {
String errorLog = Log.getStackTraceString(throwable);
Logger.e(errorLog);
return null;
}
}
@Override
protected void onProgressUpdate(String... values) {
for (String log : values) {
Logger.d(TAG, "onProgressUpdate" + log);
}
}
@Override
protected void onPostExecute(List<ImageRow> imageRows) {
Logger.d(TAG, "onPostExecute");
ThetaImageListActivity activity = refActivity.get();
activity.imageListTaskFinish(imageRows);
}
@Override
protected void onCancelled() {
Logger.e(TAG, "onCancelled");
ThetaImageListActivity activity = refActivity.get();
activity.imageListTaskFinish(null);
}
}
package jp.agentec.abook.abv.ui.viewer.activity.theta.task;
import android.app.Activity;
import android.os.AsyncTask;
import android.util.Log;
import com.theta.network.HttpConnector;
import com.theta.network.HttpDownloadListener;
import com.theta.network.ImageData;
import java.lang.ref.WeakReference;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.constant.ABookValues;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaImageListActivity;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaImagePreviewActivity;
/**
* THETAカメラ内の1つの画像情報を取得スレッド
* @version 1.2.300
* @author kimjinsung
* @since 2020/05/29
*/
public class LoadPhotoTask extends AsyncTask<Void, Object, ImageData> {
private static final String TAG = "LoadPhotoTask";
private final WeakReference<Activity> refActivity;
private String mFileId;
private long fileSize;
private long receivedDataSize = 0;
public LoadPhotoTask(Activity refActivity, String fileId) {
this.refActivity = new WeakReference<>(refActivity);
this.mFileId = fileId;
}
@Override
protected void onPreExecute() {
Logger.d(TAG, "onPreExecute");
Activity activity = refActivity.get();
if (activity instanceof ThetaImagePreviewActivity) {
ThetaImagePreviewActivity previewActivity = (ThetaImagePreviewActivity)activity;
previewActivity.showProgressView(activity.getString(R.string.progress));
}
}
@Override
protected ImageData doInBackground(Void... params) {
try {
Logger.d(TAG,"start to download image" + mFileId);
boolean isOldApi = PreferenceUtil.getUserPref(refActivity.get(), ABookKeys.THETA_OLD_VERSION_FLG, false);
HttpConnector camera = new HttpConnector(ABookValues.THETA_IP_ADDRESS, isOldApi);
ImageData resizedImageData = camera.getImage(mFileId, new HttpDownloadListener() {
@Override
public void onTotalSize(long totalSize) {
fileSize = totalSize;
}
@Override
public void onDataReceived(int size) {
receivedDataSize += size;
if (fileSize != 0) {
int progressPercentage = (int) (receivedDataSize * 100 / fileSize);
publishProgress(progressPercentage);
}
}
});
return resizedImageData;
} catch (Throwable throwable) {
String errorLog = Log.getStackTraceString(throwable);
Logger.e(errorLog);
return null;
}
}
@Override
protected void onProgressUpdate(Object... values) {
Activity activity = refActivity.get();
if (activity instanceof ThetaImagePreviewActivity) {
ThetaImagePreviewActivity previewActivity = (ThetaImagePreviewActivity)activity;
for (Object param : values) {
if (param instanceof Integer) {
Logger.d(TAG, "onProgressUpdate progress = " + param);
previewActivity.progressDialogHorizontal.setProgress((Integer) param);
} else if (param instanceof String) {
Logger.d(TAG, "onProgressUpdate param = " + param);
}
}
}
}
@Override
protected void onPostExecute(ImageData imageData) {
Logger.d(TAG, "onPostExecute");
Activity activity = refActivity.get();
if (activity instanceof ThetaImagePreviewActivity) {
ThetaImagePreviewActivity previewActivity = (ThetaImagePreviewActivity)activity;
previewActivity.loadPhotoTaskFinish(imageData);
} else if (activity instanceof ThetaImageListActivity) {
ThetaImageListActivity imageListActivity = (ThetaImageListActivity)activity;
imageListActivity.loadPhotoTaskFinish(imageData, mFileId);
}
}
}
package jp.agentec.abook.abv.ui.viewer.activity.theta.task;
import android.os.AsyncTask;
import com.theta.network.HttpConnector;
import java.lang.ref.WeakReference;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.constant.ABookValues;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaCameraActivity;
public class SetOptionExposureTask extends AsyncTask<String, String, String> {
private static final String TAG = "SetOptionExposureTask";
private final WeakReference<ThetaCameraActivity> refActivity;
public SetOptionExposureTask(ThetaCameraActivity refActivity) {
this.refActivity = new WeakReference<>(refActivity);
}
@Override
protected String doInBackground(String... params) {
Logger.d(TAG, "doInBackground");
boolean isOldApi = PreferenceUtil.getUserPref(refActivity.get(), ABookKeys.THETA_OLD_VERSION_FLG, false);
HttpConnector camera = new HttpConnector(ABookValues.THETA_IP_ADDRESS, isOldApi);
if (camera.setOptionExposure(params[0])) {
return ABookValues.SUCCESS;
}
return ABookValues.FAIL;
}
@Override
protected void onPostExecute(String exposure) {
Logger.d(TAG, "onPostExecute");
ThetaCameraActivity activity = refActivity.get();
activity.setOptionExposureTaskFinish(exposure);
}
}
package jp.agentec.abook.abv.ui.viewer.activity.theta.task;
import android.os.AsyncTask;
import com.theta.network.HttpConnector;
import com.theta.network.HttpEventListener;
import java.lang.ref.WeakReference;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.constant.ABookValues;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaCameraActivity;
/**
* THETAカメラ撮影スレッド
* @version 1.2.300
* @author kimjinsung
* @since 2020/05/29
*/
public class ShootTask extends AsyncTask<Void, Void, HttpConnector.ShootResult> {
private static final String TAG = "ShootTask";
private final WeakReference<ThetaCameraActivity> refActivity;
public ShootTask(ThetaCameraActivity refActivity) {
this.refActivity = new WeakReference<>(refActivity);
}
@Override
protected void onPreExecute() {
Logger.d(TAG, "takePicture");
}
@Override
protected HttpConnector.ShootResult doInBackground(Void... params) {
Logger.d(TAG, "doInBackground");
CaptureListener postviewListener = new CaptureListener();
boolean isOldApi = PreferenceUtil.getUserPref(refActivity.get(), ABookKeys.THETA_OLD_VERSION_FLG, false);
HttpConnector camera = new HttpConnector(ABookValues.THETA_IP_ADDRESS, isOldApi);
HttpConnector.ShootResult result = camera.takePicture(postviewListener);
return result;
}
@Override
protected void onPostExecute(HttpConnector.ShootResult result) {
if (result == HttpConnector.ShootResult.FAIL_CAMERA_DISCONNECTED) {
Logger.d(TAG, "takePicture:FAIL_CAMERA_DISCONNECTED");
} else if (result == HttpConnector.ShootResult.FAIL_STORE_FULL) {
Logger.d(TAG, "takePicture:FAIL_STORE_FULL");
} else if (result == HttpConnector.ShootResult.FAIL_DEVICE_BUSY) {
Logger.d(TAG, "takePicture:FAIL_DEVICE_BUSY");
} else if (result == HttpConnector.ShootResult.SUCCESS) {
Logger.d(TAG, "takePicture:SUCCESS");
}
}
private class CaptureListener implements HttpEventListener {
private String latestCapturedFileId;
private boolean ImageAdd = false;
@Override
public void onCheckStatus(boolean newStatus) {
if (newStatus) {
Logger.d(TAG, "takePicture:FINISHED");
} else {
Logger.d(TAG, "takePicture:PROGRESS");
}
}
@Override
public void onObjectChanged(String latestCapturedFileId) {
this.ImageAdd = true;
this.latestCapturedFileId = latestCapturedFileId;
Logger.d(TAG, "ImageAdd:FileId " + this.latestCapturedFileId);
}
@Override
public void onCompleted() {
Logger.d(TAG, "CaptureComplete");
if (ImageAdd) {
ThetaCameraActivity activity = refActivity.get();
activity.shootTaskFinish(latestCapturedFileId);
}
}
@Override
public void onError(String errorMessage) {
Logger.e(TAG, "CaptureError " + errorMessage);
ThetaCameraActivity activity = refActivity.get();
activity.shootTaskFinish(ABookValues.FAIL);
}
}
}
package jp.agentec.abook.abv.ui.viewer.activity.theta.task;
import android.os.AsyncTask;
import com.theta.network.HttpConnector;
import com.theta.view.MJpegInputStream;
import org.json.JSONException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
import jp.agentec.abook.abv.bl.common.constant.ABookValues;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaCameraActivity;
/**
* THETAカメラライブ映像取得スレッド
* @version 1.2.300
* @author kimjinsung
* @since 2020/05/29
*/
public class ShowLiveViewTask extends AsyncTask<Void, String, MJpegInputStream> {
private static final String TAG = "ShowLiveViewTask";
public static final int FAIL_RETRAY_DELAY_MILLIS = 500;
private final WeakReference<ThetaCameraActivity> refActivity;
public ShowLiveViewTask(ThetaCameraActivity refActivity) {
this.refActivity = new WeakReference<>(refActivity);
}
@Override
protected MJpegInputStream doInBackground(Void... params) {
Logger.d(TAG, "doInBackground");
MJpegInputStream mjis = null;
final int MAX_RETRY_COUNT = 5;
for (int retryCount = 0; retryCount < MAX_RETRY_COUNT; retryCount++) {
try {
boolean isOldApi = PreferenceUtil.getUserPref(refActivity.get(), ABookKeys.THETA_OLD_VERSION_FLG, false);
HttpConnector camera = new HttpConnector(ABookValues.THETA_IP_ADDRESS, isOldApi);
InputStream is = camera.getLivePreview();
mjis = new MJpegInputStream(is);
retryCount = MAX_RETRY_COUNT;
} catch (IOException e) {
try {
Thread.sleep(FAIL_RETRAY_DELAY_MILLIS);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} catch (JSONException e) {
try {
Thread.sleep(FAIL_RETRAY_DELAY_MILLIS);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
return mjis;
}
@Override
protected void onProgressUpdate(String... values) {
for (String log : values) {
Logger.d(TAG, log);
}
}
@Override
protected void onPostExecute(MJpegInputStream mJpegInputStream) {
Logger.d(TAG, "onPostExecute");
ThetaCameraActivity activity = refActivity.get();
activity.showLiveViewTaskFinish(mJpegInputStream);
}
}
package jp.agentec.abook.abv.ui.viewer.adapter;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.theta.network.ThetaDeviceInfo;
import java.util.List;
import jp.agentec.abook.abv.launcher.android.R;
public class WifiThetaConnectAdapter extends BaseAdapter {
private List<ThetaDeviceInfo> mListItem;
private LayoutInflater mInflater;
public WifiThetaConnectAdapter(Context context, List<ThetaDeviceInfo> listItem) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mListItem = listItem;
}
public void setListItem(List<ThetaDeviceInfo> listItem) {
mListItem = listItem;
}
@Override
public int getCount() {
return mListItem.size();
}
@Override
public Object getItem(int position) {
return mListItem.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_simple_textview, null);
}
TextView textView = convertView.findViewById(R.id.tv_item);
textView.setTextColor(Color.parseColor("#1C6C9B"));
ThetaDeviceInfo info = mListItem.get(position);
textView.setText(info.getSSID());
return convertView;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment