Commit cc209be0 by Kim Jinsung

#37841 360編集THETA連携

parent 167856d7
......@@ -128,4 +128,9 @@ public class ABookKeys {
public static final String CMD_EDIT_ATTACHED = "editAttached"; //再編集のためのcmdパラメタ
public static final String EDITABLE = "editable"; //commonAttachedDataUrl()で編集可否を判別するパラメタをWebからもらう。
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 @@
android:configChanges="keyboardHidden|orientation|screenSize"
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.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"/>
......
......@@ -1425,4 +1425,59 @@
<string name="msg_image_select_send_success">シーン画像の登録に成功しました。</string>
<string name="msg_image_select_send_fail_retry">シーン画像の登録に失敗しました。再度登録処理を実行しますか?</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>
......@@ -1432,4 +1432,50 @@
<string name="msg_image_select_send_success">장면 이미지 등록에 성공하였습니다.</string>
<string name="msg_image_select_send_fail_retry">장면 이미지 등록에 실패하였습니다. 다시 등록 처리를 실행 하시겠습니까?</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>
\ No newline at end of file
......@@ -89,4 +89,10 @@
<color name="operation_bg">#FFFFFF</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>
\ No newline at end of file
......@@ -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_fail_retry">Registration of the scene image failed. Do you want to register again?</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>
\ No newline at end of file
......@@ -16,4 +16,7 @@
<uses-permission android:name="android.permission.WRITE_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>
<?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 @@
android:orientation="vertical">
<RelativeLayout
android:id="@+id/device_image_list_list_toolbar"
android:id="@+id/device_connect_toolbar"
style="@style/OperationSearchToolBar"
android:layout_width="match_parent"
android:layout_height="50dp">
......@@ -20,6 +20,15 @@
android:layout_centerHorizontal="true"
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
android:id="@+id/device_image_list_title"
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"?>
<resources>
<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>
\ No newline at end of file
......@@ -60,7 +60,7 @@ public class ImageCache {
private static final int DEFAULT_MEM_CACHE_SIZE = 1024 * 5; // 5MB
// 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
private static final CompressFormat DEFAULT_COMPRESS_FORMAT = CompressFormat.JPEG;
......@@ -114,10 +114,13 @@ public class ImageCache {
imageCache = new ImageCache(cacheParams);
mRetainFragment.setObject(imageCache);
}
return imageCache;
}
public static ImageCache getInstance(ImageCacheParams cacheParams) {
ImageCache imageCache = new ImageCache(cacheParams);
return imageCache;
}
/**
* Initialize the cache, providing all parameters.
*
......
......@@ -16,6 +16,7 @@
package com.imagepicker;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
......@@ -25,13 +26,19 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Looper;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.widget.ImageView;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
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
* 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 {
return;
}
BitmapDrawable value = null;
// BitmapDrawable value = null;
Bitmap value = null;
if (mImageCache != null) {
value = mImageCache.getBitmapFromMemCache(String.valueOf(data));
value = mImageCache.getBitmapFromDiskCache(String.valueOf(data));
}
if (value != null) {
Logger.d(TAG, "Bitmap found in memory cache");
// Bitmap found in memory cache
imageView.setImageDrawable(value);
// imageView.setImageDrawable(value);
imageView.setImageBitmap(value);
} else if (cancelPotentialWork(data, imageView)) {
Logger.d(TAG, "Bitmap not found in memory cache");
//BEGIN_INCLUDE(execute_background_task)
final BitmapWorkerTask task = new BitmapWorkerTask(data, imageView, orientation);
final AsyncDrawable asyncDrawable =
......@@ -98,6 +108,8 @@ public abstract class ImageWorker {
// for more info on what was changed.
task.executeOnExecutor(AsyncTask.DUAL_THREAD_EXECUTOR);
//END_INCLUDE(execute_background_task)
} else {
Logger.d(TAG, "****Bitmap not found in memory cache");
}
}
......@@ -145,6 +157,12 @@ public abstract class ImageWorker {
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.
*/
......
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;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.opengl.Matrix;
import android.util.Log;
import com.theta.glview.model.UVSphere;
import com.theta.model.Constants;
import com.theta.model.Photo;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
* Renderer class for photo display
*/
public class GLRenderer implements Renderer {
private final String VSHADER_SRC =
"attribute vec4 aPosition;\n" +
"attribute vec2 aUV;\n" +
"uniform mat4 uProjection;\n" +
"uniform mat4 uView;\n" +
"uniform mat4 uModel;\n" +
"varying vec2 vUV;\n" +
"void main() {\n" +
" gl_Position = uProjection * uView * uModel * aPosition;\n" +
" vUV = aUV;\n" +
"}\n";
private final String FSHADER_SRC =
"precision mediump float;\n" +
"varying vec2 vUV;\n" +
"uniform sampler2D uTex;\n" +
"void main() {\n" +
" gl_FragColor = texture2D(uTex, vUV);\n" +
"}\n";
private static final float Z_NEAR = 0.1f;
private static final float Z_FAR = 100.0f;
private UVSphere mEastShell = null;
private UVSphere mWestShell = null;
private double mRotationAngleY;
private double mRotationAngleXZ;
private Photo mTexture;
private boolean mTextureUpdate = false;
private float mScreenAspectRatio;
private float mCameraPosX = 0.0f;
private float mCameraPosY = 0.0f;
private float mCameraPosZ = 0.0f;
private float mCameraDirectionX = 0.0f;
private float mCameraDirectionY = 0.0f;
private float mCameraDirectionZ = 1.0f;
//既存ソース
// private float mCameraFovDegree = 45;
private float mCameraFovDegree = 100;
private int[] mTextures = new int[2];
private int mPositionHandle;
private int mProjectionMatrixHandle;
private int mViewMatrixHandle;
private int mUVHandle;
private int mTexHandle;
private int mModelMatrixHandle;
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];
private final float[] mModelMatrix = new float[16];
/**
* Constructor
*/
public GLRenderer() {
mEastShell = new UVSphere(Constants.TEXTURE_SHELL_RADIUS, Constants.SHELL_DIVIDES, true);
mWestShell = new UVSphere(Constants.TEXTURE_SHELL_RADIUS, Constants.SHELL_DIVIDES, false);
mRotationAngleY = 0.0f;
mRotationAngleXZ = 0.0f;
}
/**
* onDrawFrame Method
* @param gl GLObject (not used)
*/
@Override
public void onDrawFrame(final GL10 gl) {
if (mTexture == null) {
return;
}
mCameraDirectionX = (float) (Math.cos(mRotationAngleXZ)*Math.cos(mRotationAngleY));
mCameraDirectionZ = (float) (Math.sin(mRotationAngleXZ)*Math.cos(mRotationAngleY));
mCameraDirectionY = (float) Math.sin(mRotationAngleY);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.setIdentityM(mViewMatrix, 0);
Matrix.setIdentityM(mProjectionMatrix, 0);
if (mTextureUpdate && null != mTexture && !mTexture.getPhoto().isRecycled()) {
Log.d("", "load texture1");
loadTexture(mTexture.getPhoto());
mTextureUpdate = false;
}
Matrix.setLookAtM(mViewMatrix, 0, mCameraPosX, mCameraPosY, mCameraPosZ, mCameraDirectionX, mCameraDirectionY, mCameraDirectionZ, 0.0f, 1.0f, 0.0f);
Matrix.perspectiveM(mProjectionMatrix, 0, mCameraFovDegree, mScreenAspectRatio, Z_NEAR, Z_FAR);
if (null != mTexture.getElevetionAngle()) {
float elevationAngle = mTexture.getElevetionAngle().floatValue();
Matrix.rotateM(mModelMatrix, 0, (float) elevationAngle, 0, 0, 1);
}
if (null != mTexture.getHorizontalAngle()) {
float horizontalAngle = mTexture.getHorizontalAngle().floatValue();
Matrix.rotateM(mModelMatrix, 0, horizontalAngle, 1, 0, 0);
}
GLES20.glUniformMatrix4fv(mModelMatrixHandle, 1, false, mModelMatrix, 0);
GLES20.glUniformMatrix4fv(mProjectionMatrixHandle, 1, false, mProjectionMatrix, 0);
GLES20.glUniformMatrix4fv(mViewMatrixHandle, 1, false, mViewMatrix, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
GLES20.glUniform1i(mTexHandle, 0);
mEastShell.draw(mPositionHandle, mUVHandle);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[1]);
GLES20.glUniform1i(mTexHandle, 0);
mWestShell.draw(mPositionHandle, mUVHandle);
return;
}
/**
* onSurfaceChanged Method
* @param gl GLObject (not used)
* @param width Screen width
* @param height Screen height
*/
@Override
public void onSurfaceChanged(final GL10 gl, final int width, final int height) {
//既存ソース
// int _height = height/2;
// mScreenAspectRatio = (float) width / (float) (_height == 0 ? 1 : _height);
// GLES20.glViewport(0, _height / 2, width, _height);
//全画面表示のため、ソース修正
int _height = height;
mScreenAspectRatio = (float) width / (float) (_height == 0 ? 1 : _height);
GLES20.glViewport(0, 0, width, _height);
Matrix.setLookAtM(mViewMatrix, 0, mCameraPosX, mCameraPosY, mCameraPosZ, mCameraDirectionX, mCameraDirectionY, mCameraDirectionZ, 0.0f, 1.0f, 0.0f);
Matrix.perspectiveM(mProjectionMatrix, 0, mCameraFovDegree, mScreenAspectRatio, Z_NEAR, Z_FAR);
return;
}
/**
* onSurfaceCreated Method
* @param gl GLObject (not used)
* @param config EGL Setting Object
*/
@Override
public void onSurfaceCreated(final GL10 gl, final EGLConfig config) {
int vShader;
int fShader;
int program;
vShader = loadShader(GLES20.GL_VERTEX_SHADER, VSHADER_SRC);
fShader = loadShader(GLES20.GL_FRAGMENT_SHADER, FSHADER_SRC);
program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vShader);
GLES20.glAttachShader(program, fShader);
GLES20.glLinkProgram(program);
GLES20.glUseProgram(program);
mPositionHandle = GLES20.glGetAttribLocation(program, "aPosition");
mUVHandle = GLES20.glGetAttribLocation(program, "aUV");
mProjectionMatrixHandle = GLES20.glGetUniformLocation(program, "uProjection");
mViewMatrixHandle = GLES20.glGetUniformLocation(program, "uView");
mTexHandle = GLES20.glGetUniformLocation(program, "uTex");
mModelMatrixHandle = GLES20.glGetUniformLocation(program, "uModel");
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
return;
}
/**
* Rotation process method
* @param xz X axis direction rotation value
* @param y Y axis direction rotation value
*/
public void rotate(float xz, float y) {
mRotationAngleXZ += xz;
mRotationAngleY += y;
if (mRotationAngleY > (Math.PI/2)) {
mRotationAngleY = (Math.PI/2);
}
if (mRotationAngleY < -(Math.PI/2)) {
mRotationAngleY = -(Math.PI/2);
}
return;
}
/**
* Zoom in/Zoom out method
* @param ratio Scale value: Zoom in process performed if the value is 1.0 or more; zoom out process is performed if the value is less than 1.0
*/
public void scale(float ratio) {
if (ratio < 1.0) {
mCameraFovDegree = mCameraFovDegree * (Constants.SCALE_RATIO_TICK_EXPANSION);
if (mCameraFovDegree > Constants.CAMERA_FOV_DEGREE_MAX) {
mCameraFovDegree = Constants.CAMERA_FOV_DEGREE_MAX;
}
}
else {
mCameraFovDegree = mCameraFovDegree * (Constants.SCALE_RATIO_TICK_REDUCTION);
if (mCameraFovDegree < Constants.CAMERA_FOV_DEGREE_MIN) {
mCameraFovDegree = Constants.CAMERA_FOV_DEGREE_MIN;
}
}
return;
}
/**
* Sets the texture for the sphere
* @param texture Photo object for texture
*/
public void setTexture(Photo texture) {
mTexture = texture;
mTextureUpdate = true;
return;
}
/**
* Acquires the set texture
* @return Photo object for texture
*/
public Photo getTexture() {
return mTexture;
}
/**
* GL error judgment method for debugging
* @param TAG TAG output character string
* @param glOperation Message output character string
*/
public static void checkGlError(String TAG, String glOperation) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e(TAG, glOperation + ": glError " + error);
throw new RuntimeException(glOperation + ": glError " + error);
}
return;
}
/**
* Texture setting method
* @param texture Setting texture
*/
public void loadTexture(final Bitmap texture) {
final Bitmap bitmap = texture;
int dividedWidth = bitmap.getWidth() / 2;
GLES20.glGenTextures(2, mTextures, 0);
for (int textureIndex = 0; textureIndex < 2; textureIndex++) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[textureIndex]);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
Bitmap dividedBitmap = Bitmap.createBitmap(bitmap, (dividedWidth * textureIndex), 0, dividedWidth, bitmap.getHeight());
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, dividedBitmap, 0);
dividedBitmap.recycle();
}
return;
}
private int loadShader(int type, String shaderCode){
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
\ 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.helper;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.provider.MediaStore;
import com.theta.network.ThetaDeviceInfo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import jp.agentec.abook.abv.bl.common.constant.ABookValues;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.adf.util.DateTimeUtil;
/**
* @version 1.2.300
* THETAカメラ関連ヘルパークラス
*
* @author kimjinsung
*/
public class ThetaHelper {
private static final String TAG = "ThetaHelper";
private static final String THETA_IMAGE_SAVE_PATH = Environment.getExternalStorageDirectory() + "/" + Environment.DIRECTORY_PICTURES + "/RICOH THETA/";
private Context mContext;
public ThetaHelper(Context context) {
mContext = context;
}
/**
* THETAカメラがすでに接続状態チェック
* @return true:接続中, false:非接続中
*/
public boolean connectedDeviceWifiThetaCamera() {
WifiManager wifiManager = (WifiManager)mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (wifiManager == null) {
return false;
}
wifiManager.startScan();
boolean connectedWifi = false;
for (ScanResult result : wifiManager.getScanResults()) {
String scanSSID = result.SSID.replace("\"", "");
int index = scanSSID.indexOf(ABookValues.THETA_MODEL_NAME_THETA);
if (index != -1) {
for (WifiConfiguration configuration : wifiManager.getConfiguredNetworks()) {
// Android4.2以降よりダブルクォーテーションが付いてくるので除去
String resultSSID = configuration.SSID.replace("\"", "");
if (resultSSID.equals(scanSSID)) {
if (configuration.status == WifiConfiguration.Status.CURRENT) {
connectedWifi = true;
}
break;
}
}
}
if (connectedWifi) {
break;
}
}
return connectedWifi;
}
/**
* THETAカメラWi-Fi情報を取得する。
* @param savedFlg Wifi保存フラグ
* @return THETAカメラWi-Fi情報配列
*/
public List<ThetaDeviceInfo> getThetaWifiList(boolean savedFlg) {
WifiManager wifiManager = (WifiManager)mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
List<ThetaDeviceInfo> wifiList = new ArrayList<>();
if (wifiManager == null) {
Logger.e(TAG, "wifiManager == null");
return wifiList;
}
wifiManager.startScan();
boolean connectedWifi = false;
for (ScanResult scanResult : wifiManager.getScanResults()) {
String scanResultSSID = scanResult.SSID.replace("\"", "");
int index = scanResultSSID.indexOf(ABookValues.THETA_MODEL_NAME_THETA);
Logger.d(TAG, "scanResultSSID = "+ scanResultSSID);
if (index != -1) {
String saveSsid = "";
for (WifiConfiguration configuration : wifiManager.getConfiguredNetworks()) {
String configurationSSID = configuration.SSID.replace("\"", "");
if (scanResultSSID.equals(configurationSSID)) {
if (savedFlg) {//登録済みの端末情報
ThetaDeviceInfo info = new ThetaDeviceInfo();
info.setSSID(scanResultSSID);
//保存データがないので、-1に設定
info.setNetworkId(configuration.networkId);
wifiList.add(info);
Logger.d(TAG, "saved ssid = "+ scanResultSSID);
break;
}
saveSsid = scanResultSSID;
}
}
if (!savedFlg && saveSsid.length() == 0) { //未登録の端末情報
ThetaDeviceInfo info = new ThetaDeviceInfo();
info.setSSID(scanResultSSID);
//保存データがないので、-1に設定
info.setNetworkId(-1);
wifiList.add(info);
Logger.d(TAG, "not saved ssid = "+ scanResultSSID);
}
}
}
return wifiList;
}
/**
* THETAカメラWi-Fi接続
* @param networkId ネットワークID
* @return true:接続成功、false:接続失敗
*/
public boolean connectThetaCameraWifi(int networkId) {
WifiManager wifiManager = (WifiManager)mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (wifiManager == null) {
Logger.e(TAG, "wifiManager == null");
return false;
}
wifiManager.disconnect();
boolean result = wifiManager.enableNetwork(networkId, true);
wifiManager.reconnect();
return result;
}
/**
* THETAカメラWi-Fi接続
* @param ssid ネットワーク SSID
* @return networkIdを返す(-1は失敗)
*/
public int saveThetaCameraWifi(String ssid) {
WifiManager wifiManager = (WifiManager)mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (wifiManager == null) {
Logger.e(TAG, "wifiManager == null");
return -1;
}
//保存する前にSSIDがWi-Fiリストに存在するかチェック
if (!checkWifiNetwork(ssid)) {
return -1;
}
String password = getPassword(ssid);
//Wi-Fi情報を保存
WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"" + ssid + "\"";
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.preSharedKey = "\"" + password + "\"";
int networkId = wifiManager.addNetwork(config); // 失敗した場合は-1となります
if (networkId != -1) {
wifiManager.saveConfiguration();
wifiManager.updateNetwork(config);
}
return networkId;
}
/**
* SSIDがAndroid端末のWifiリストに存在するかチェック
* @param ssid アクセスポイント
* @return 存在有無(true:存在する,false:存在しない)
*/
private boolean checkWifiNetwork(String ssid) {
WifiManager wifiManager = (WifiManager)mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
List<ThetaDeviceInfo> wifiList = new ArrayList<>();
if (wifiManager == null) {
Logger.e(TAG, "wifiManager == null");
return false;
}
wifiManager.startScan();
boolean hasWifiList = false;
for (ScanResult scanResult : wifiManager.getScanResults()) {
String scanResultSSID = scanResult.SSID.replace("\"", "");
int index = scanResultSSID.indexOf(ABookValues.THETA_MODEL_NAME_THETA);
Logger.d(TAG, "scanResultSSID = " + scanResultSSID);
if (index != -1) {
hasWifiList = true;
}
}
return hasWifiList;
}
/**
* SSIDからパスワード情報を取り出す
* @param ssid アクセスポイント
* @return
*/
private String getPassword(String ssid) {
String password = ssid.replace("THETA","");
password = password.replace(".OSC","");
return password.substring(2, password.length());
}
/**
* Thetaカメラから選択した画像をローカルフォットライブラリに保存
* @param bitmap 選択した画像データ
* @param fileId Thetaカメラの選択したファイルパス
* @return 保存結果(true:成功、false:失敗)
*/
public boolean thetaImageLocalSave(Bitmap bitmap, String fileId) {
boolean isSuccess = false;
try {
File file = new File(fileId);
// 日付をファイル名につける。
String fileName = DateTimeUtil.toString_yyyyMMddHHmmss_none(new Date()) + "_" + file.getName();
//[/storage/emulated/0/Pictures/RICOH THETA/]ファイル保存フォルダ指定及び作成
String saveFullPath = THETA_IMAGE_SAVE_PATH + fileName;
File thetaSavePathFile = new File(THETA_IMAGE_SAVE_PATH);
if (!thetaSavePathFile.exists()) {
thetaSavePathFile.mkdir();
if (!thetaSavePathFile.mkdirs()) {
Logger.e(TAG, "Directory not created");
return false;
}
}
// 保存処理開始
FileOutputStream fos = new FileOutputStream(new File(thetaSavePathFile, fileName));
// jpegで保存
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
// 保存処理終了
fos.close();
// アルバムに反映
addGallery(fileName, saveFullPath);
isSuccess = true;
} catch (Exception e) {
Logger.e(TAG, e.toString());
}
return isSuccess;
}
/**
* 保存した画像をギャラリーに追加
* @param fileName 保存ファイル名
* @param fileFullPath 保存フルファイルパス
*/
private void addGallery(String fileName, String fileFullPath) {
try {
ContentValues values = new ContentValues();
ContentResolver contentResolver = mContext.getContentResolver();
values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.TITLE, fileName);
values.put("_data", fileFullPath);
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} catch (Exception e) {
Logger.e(TAG, e.toString());
}
}
/**
* Imageファイルが転送済みかのチェック
* @param fileName Theta Image FileName
* @return 転送結果(true:転送済み)
*/
public boolean transferredImage(final String fileName) {
final File imageFile = new File(fileName);
File savePath = new File(THETA_IMAGE_SAVE_PATH);
File[] saveImageFiles = savePath.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(imageFile.getName());
}
});
return saveImageFiles.length != 0;
}
}
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;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import com.theta.model.ImageSize;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;
import jp.agentec.abook.abv.bl.common.log.Logger;
/**
* HTTP connection to device
*/
public class HttpConnector {
private static final String TAG = "HttpConnector";
private final static long CHECK_STATUS_PERIOD_MS = 50;
private final static int HTTP_CONNECT_TIME_OUT = 5000;
private String mIpAddress = null;
private String mFingerPrint = null;
private Timer mCheckStatusTimer = null;
private HttpEventListener mHttpEventListener = null;
private boolean mIsOldApi = false; //true:api2.0, false:api2.1
//API2.0利用
private String mSessionId = null;
private String mContinuationToken = null;
public enum ShootResult {
SUCCESS, FAIL_CAMERA_DISCONNECTED, FAIL_STORE_FULL, FAIL_DEVICE_BUSY
}
/**
* Constructor
* @param cameraIpAddress IP address of connection destination
*/
public HttpConnector(String cameraIpAddress) {
mIpAddress = cameraIpAddress;
}
/**
* Constructor
* @param cameraIpAddress IP address of connection destination
* @param isOldApi true:api2.0, false:api2.1
*/
public HttpConnector(String cameraIpAddress, boolean isOldApi) {
mIpAddress = cameraIpAddress;
mIsOldApi = isOldApi;
}
/**
* Connect to device
* @return Session ID (null is returned if the connection fails)
*/
private String connect() {
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
String responseData;
String sessionId = null;
InputStream is = null;
try {
// send HTTP POST
input.put("name", "camera.startSession");
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
String status = output.getString("state");
if (status.equals("done")) {
JSONObject results = output.getJSONObject("results");
sessionId = results.getString("sessionId");
} else if (status.equals("error")) {
JSONObject errors = output.getJSONObject("error");
String errorCode = errors.getString("code");
if (errorCode.equals("invalidSessionId")) {
sessionId = null;
}
}
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return sessionId;
}
/**
* Acquire storage information of device
* @return Storage information
*/
public StorageInfo getStorageInfo() {
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
String responseData;
StorageInfo storageInfo = new StorageInfo();
InputStream is = null;
try {
// send HTTP POST
input.put("name", "camera.getOptions");
JSONObject parameters = new JSONObject();
JSONArray optionNames = new JSONArray();
optionNames.put("remainingPictures");
optionNames.put("remainingSpace");
optionNames.put("totalSpace");
parameters.put("optionNames", optionNames);
input.put("parameters", parameters);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
String status = output.getString("state");
if (status.equals("done")) {
JSONObject results = output.getJSONObject("results");
JSONObject options = results.getJSONObject("options");
int remainingPictures = options.getInt("remainingPictures");
storageInfo.setFreeSpaceInImages(remainingPictures);
long remainingSpace = options.getLong("remainingSpace");
storageInfo.setFreeSpaceInBytes(remainingSpace);
long totalSpace = options.getLong("totalSpace");
storageInfo.setMaxCapacity(totalSpace);
}
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return storageInfo;
}
/**
* Acquire device information
* @return Device information
*/
public ThetaDeviceInfo getDeviceInfo() {
HttpURLConnection getConnection = createHttpConnection("GET", "/osc/info");
String responseData;
ThetaDeviceInfo deviceInfo = new ThetaDeviceInfo();
InputStream is = null;
try {
// send HTTP GET
// this protocol has no input.
getConnection.connect();
is = getConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
String model = output.getString("model");
deviceInfo.setModel(model);
String version = output.getString("firmwareVersion");
deviceInfo.setDeviceVersion(version);
String serialNumber = output.getString("serialNumber");
deviceInfo.setSerialNumber(serialNumber);
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return deviceInfo;
}
/**
* Acquire list of media files on device
* @return Media file list
*/
public ArrayList<ImageInfo> getList() {
ArrayList<ImageInfo> imageInfos = new ArrayList<>();
for (int continuation = 0; continuation < 10; continuation++) {
ArrayList<ImageInfo> receivedImageInfo = getListInternal(50, imageInfos.size());
imageInfos.addAll(receivedImageInfo);
if (mIsOldApi) {
//API2.0
if (mContinuationToken == null) {
break;
}
} else {
//API2.1
if (receivedImageInfo.size() < 50) {
break;
}
}
}
return imageInfos;
}
/**
* Acquire media file list (limited number of items)
* @param maxReceiveEntry Maximum number of files that can be acquired at once
* @param startPosition Set the previously acquired token to continue. Set null if acquiring for the first time.
* @return List of specified number of media files
*/
private ArrayList<ImageInfo> getListInternal(int maxReceiveEntry, int startPosition) {
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
String responseData;
ArrayList<ImageInfo> imageInfos = new ArrayList<>();
InputStream is = null;
try {
JSONObject parameters = new JSONObject();
//AIP2.0
if (mIsOldApi) {
input.put("name", "camera._listAll");
if (mContinuationToken != null) {
parameters.put("continuationToken", mContinuationToken);
}
} else {
input.put("name", "camera.listFiles");
parameters.put("fileType", "all");
parameters.put("maxThumbSize", 0);
parameters.put("startPosition", startPosition);
}
parameters.put("entryCount", maxReceiveEntry);
input.put("parameters", parameters);
//AIP2.1
// send HTTP POST
// input.put("name", "camera.listFiles");
// JSONObject parameters = new JSONObject();
// parameters.put("entryCount", maxReceiveEntry);
// parameters.put("fileType", "all");
// parameters.put("maxThumbSize", 0);
// parameters.put("startPosition", startPosition);
// input.put("parameters", parameters);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
String status = output.getString("state");
if (status.equals("done")) {
JSONObject results = output.getJSONObject("results");
JSONArray entries = results.getJSONArray("entries");
int entrySize = entries.length();
if (mIsOldApi) {
mContinuationToken = results.getString("continuationToken");
}
for (int index = 0; index < entrySize; index++) {
JSONObject entry = entries.getJSONObject(index);
ImageInfo imageInfo = new ImageInfo();
String name = entry.getString("name");
imageInfo.setFileName(name);
//API2.0
String id = null;
if (mIsOldApi) {
id = entry.getString("uri");
} else {
id = entry.getString("fileUrl");
}
imageInfo.setFileId(id);
long size = Long.parseLong(entry.getString("size"));
imageInfo.setFileSize(size);
String date = entry.getString("dateTimeZone");
imageInfo.setCaptureDate(date);
int width = entry.getInt("width");
imageInfo.setWidth(width);
int height = entry.getInt("height");
imageInfo.setHeight(height);
try {
//API2.0
if (mIsOldApi) {
entry.getInt("recordTime");
} else {
entry.getInt("_recordTime");
}
imageInfo.setFileFormat(ImageInfo.FILE_FORMAT_CODE_EXIF_MPEG);
} catch (JSONException e) {
imageInfo.setFileFormat(ImageInfo.FILE_FORMAT_CODE_EXIF_JPEG);
}
imageInfos.add(imageInfo);
}
}
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return imageInfos;
}
/**
* Acquire thumbnail image(Only API2.0)
* @param fileId File ID
* @return Thumbnail (null is returned if acquisition fails)
*/
private Bitmap getThumbOld(String fileId) {
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
Bitmap thumbnail = null;
InputStream is = null;
try {
// send HTTP POST
input.put("name", "camera.getImage");
JSONObject parameters = new JSONObject();
parameters.put("fileUri", fileId);
parameters.put("_type", "thumb");
input.put("parameters", parameters);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
thumbnail = BitmapFactory.decodeStream(bis);
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return thumbnail;
}
/**
* Acquire thumbnail image
* @param fileId File ID
* @return Thumbnail (null is returned if acquisition fails)
*/
public Bitmap getThumb(String fileId) {
//API2.0
if (mIsOldApi) {
return getThumbOld(fileId);
}
HttpURLConnection postConnection = null;
try {
postConnection = (HttpURLConnection)new URL(fileId+"?type=thumb").openConnection();
} catch (IOException e) {
Logger.e(TAG, e);
}
JSONObject input = new JSONObject();
Bitmap thumbnail = null;
InputStream is = null;
try {
// send HTTP GET
assert postConnection != null;
postConnection.connect();
is = postConnection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
thumbnail = BitmapFactory.decodeStream(bis);
} catch (IOException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return thumbnail;
}
/**
* Take photo<p>
* After shooting, the status is checked for each {@link HttpConnector#CHECK_STATUS_PERIOD_MS} and the listener notifies you of the status.
* @param listener Post-shooting event listener
* @return Shooting request results
*/
public ShootResult takePicture(HttpEventListener listener) {
ShootResult result = ShootResult.FAIL_DEVICE_BUSY;
//API2.0 start
if (mIsOldApi) {
mSessionId = connect();
if (mSessionId == null) {
listener.onError("cannot get to start session");
result = ShootResult.FAIL_DEVICE_BUSY;
return result;
}
}
// set capture mode to image
String errorMessage = setImageCaptureMode();
if (errorMessage != null) {
listener.onError(errorMessage);
result = ShootResult.FAIL_DEVICE_BUSY;
return result;
}
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
String responseData;
mHttpEventListener = listener;
InputStream is = null;
try {
// send HTTP POST
input.put("name", "camera.takePicture");
//API2.0 start
if (mIsOldApi) {
JSONObject parameters = new JSONObject();
parameters.put("sessionId", mSessionId);
input.put("parameters", parameters);
}
//API2.0 end
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
String status = output.getString("state");
String commandId = output.getString("id");
if (status.equals("inProgress")) {
mCheckStatusTimer = new Timer(true);
CapturedTimerTask capturedTimerTask = new CapturedTimerTask();
capturedTimerTask.setCommandId(commandId);
mCheckStatusTimer.scheduleAtFixedRate(capturedTimerTask, CHECK_STATUS_PERIOD_MS, CHECK_STATUS_PERIOD_MS);
result = ShootResult.SUCCESS;
} else if (status.equals("done")) {
JSONObject results = output.getJSONObject("results");
String lastFileId = results.getString("fileUri");
mHttpEventListener.onObjectChanged(lastFileId);
mHttpEventListener.onCompleted();
result = ShootResult.SUCCESS;
}
} catch (IOException e) {
Logger.e(TAG, e);
result = ShootResult.FAIL_DEVICE_BUSY;
} catch (JSONException e) {
Logger.e(TAG, e);
result = ShootResult.FAIL_DEVICE_BUSY;
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return result;
}
private class CapturedTimerTask extends TimerTask {
private String mCommandId;
public void setCommandId(String commandId) {
mCommandId = commandId;
}
@Override
public void run() {
String capturedFileId = checkCaptureStatus(mCommandId);
if (capturedFileId != null) {
mHttpEventListener.onCheckStatus(true);
mCheckStatusTimer.cancel();
mHttpEventListener.onObjectChanged(capturedFileId);
mHttpEventListener.onCompleted();
} else {
mHttpEventListener.onCheckStatus(false);
}
}
}
/**
* Check still image shooting status
* @param commandId Command ID for shooting still images
* @return ID of saved file (null is returned if the file is not saved)
*/
private String checkCaptureStatus(String commandId) {
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/status");
JSONObject input = new JSONObject();
String responseData;
String capturedFileId = null;
InputStream is = null;
try {
// send HTTP POST
input.put("id", commandId);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
String status = output.getString("state");
if (status.equals("done")) {
JSONObject results = output.getJSONObject("results");
//API2.0
if (mIsOldApi) {
capturedFileId = results.getString("fileUri");
} else {
capturedFileId = results.getString("fileUrl");
}
}
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return capturedFileId;
}
/**
* Acquire raw data of specified image (Only API2.0)
* @param fileId File ID
* @param listener Listener for receiving received data count
* @return Image data
*/
public ImageData getImageOld(String fileId, HttpDownloadListener listener) {
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
ImageData imageData = new ImageData();
int totalSize = 0;
InputStream is = null;
try {
// send HTTP POST
input.put("name", "camera.getImage");
JSONObject parameters = new JSONObject();
parameters.put("fileUri", fileId);
parameters.put("_type", "full");
input.put("parameters", parameters);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
totalSize = postConnection.getContentLength();
listener.onTotalSize(totalSize);
is = postConnection.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[2048];
int length;
while ((length = is.read(buffer)) >= 0) {
baos.write(buffer, 0, length);
listener.onDataReceived(length);
}
byte[] rawData = baos.toByteArray();
imageData.setRawData(rawData);
XMP xmp = new XMP(rawData);
imageData.setPitch(xmp.getPosePitchDegrees());
imageData.setRoll(xmp.getPoseRollDegrees());
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return imageData;
}
/**
* Acquire raw data of specified image
* @param fileId File ID
* @param listener Listener for receiving received data count
* @return Image data
*/
public ImageData getImage(String fileId, HttpDownloadListener listener) {
//API2.0
if (mIsOldApi) {
return getImageOld(fileId, listener);
}
HttpURLConnection postConnection = null;
try {
postConnection = (HttpURLConnection)new URL(fileId).openConnection();
postConnection.setConnectTimeout(HTTP_CONNECT_TIME_OUT);
} catch (IOException e) {
Logger.e(TAG, e);
}
ImageData imageData = new ImageData();
int totalSize = 0;
InputStream is = null;
try {
if (postConnection == null) {
return null;
}
// send HTTP GET
postConnection.connect();
totalSize = postConnection.getContentLength();
listener.onTotalSize(totalSize);
is = postConnection.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[2048];
int length;
while ((length = is.read(buffer)) >= 0) {
baos.write(buffer, 0, length);
listener.onDataReceived(length);
}
byte[] rawData = baos.toByteArray();
imageData.setRawData(rawData);
XMP xmp = new XMP(rawData);
imageData.setPitch(xmp.getPosePitchDegrees());
imageData.setRoll(xmp.getPoseRollDegrees());
} catch (IOException e) {
Logger.e(TAG, e);
return null;
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return imageData;
}
/**
* Acquire live view stream
* @return Stream for receiving data
* @throws IOException
*/
public InputStream getLivePreview() throws IOException, JSONException {
//API2.0
if (mIsOldApi) {
mSessionId = connect();
}
// set capture mode to image
setImageCaptureMode();
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
InputStream is = null;
try {
JSONObject parameters = new JSONObject();
//API2.0
if (mIsOldApi) {
input.put("name", "camera._getLivePreview");
parameters.put("sessionId", mSessionId);
} else {
input.put("name", "camera.getLivePreview");
}
input.put("parameters", parameters);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
} catch (IOException e) {
Logger.e(TAG, e);
String errorMessage = null;
InputStream es = postConnection.getErrorStream();
try {
if (es != null) {
String errorData = InputStreamToString(es);
JSONObject output = new JSONObject(errorData);
JSONObject errors = output.getJSONObject("error");
errorMessage = errors.getString("message");
Logger.e(TAG, errorMessage);
}
} catch (IOException e1) {
e1.printStackTrace();
Logger.e(TAG, e1);
} catch (JSONException e1) {
e1.printStackTrace();
Logger.e(TAG, e1);
} finally {
if (es != null) {
try {
es.close();
} catch (IOException e1) {
e1.printStackTrace();
Logger.e(TAG, e1);
}
}
}
throw e;
} catch (JSONException e) {
Logger.e(TAG, e);
throw e;
}
return is;
}
/**
* Delete specified file
* @param deletedFileId File ID
* @param listener Listener for receiving deletion results
*/
public void deleteFile(String deletedFileId, HttpEventListener listener) {
//API2.0
if (mIsOldApi) {
mSessionId = connect();
}
// set capture mode to image
String errorMessage = setImageCaptureMode();
if (errorMessage != null) {
listener.onError(errorMessage);
return;
}
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
String responseData;
mHttpEventListener = listener;
InputStream is = null;
try {
// send HTTP POST
input.put("name", "camera.delete");
JSONObject parameters = new JSONObject();
if (mIsOldApi) {
parameters.put("fileUri", deletedFileId);
} else {
JSONArray ja = new JSONArray();
ja.put(deletedFileId);
parameters.put("fileUrls", ja);
}
input.put("parameters", parameters);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
String status = output.getString("state");
if (status.equals("inProgress")) {
getState();
mCheckStatusTimer = new Timer(true);
DeletedTimerTask deletedTimerTask = new DeletedTimerTask();
deletedTimerTask.setDeletedFileId(deletedFileId);
mCheckStatusTimer.scheduleAtFixedRate(deletedTimerTask, CHECK_STATUS_PERIOD_MS, CHECK_STATUS_PERIOD_MS);
} else if (status.equals("done")) {
mHttpEventListener.onObjectChanged(deletedFileId);
mHttpEventListener.onCompleted();
mFingerPrint = null;
}
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
}
/**
* Status check class for file deletion
*/
private class DeletedTimerTask extends TimerTask {
private String mDeletedFileId = null;
public void setDeletedFileId(String deletedFileId) {
mDeletedFileId = deletedFileId;
}
@Override
public void run() {
boolean update = isUpdate();
mHttpEventListener.onCheckStatus(update);
if (update) {
mCheckStatusTimer.cancel();
getState();
mHttpEventListener.onObjectChanged(mDeletedFileId);
mHttpEventListener.onCompleted();
mFingerPrint = null;
}
}
}
/**
* Specify shooting size
* @param imageSize Shooting size
*/
public void setImageSize(ImageSize imageSize) {
int width;
int height;
switch (imageSize) {
case IMAGE_SIZE_2048x1024:
width = 2048;
height = 1024;
break;
default:
case IMAGE_SIZE_5376x2688:
width = 5376;
height = 2688;
break;
}
// set capture mode to image
setImageCaptureMode();
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
String responseData;
InputStream is = null;
try {
// send HTTP POST
input.put("name", "camera.setOptions");
JSONObject parameters = new JSONObject();
JSONObject options = new JSONObject();
JSONObject fileFormat = new JSONObject();
fileFormat.put("type", "jpeg");
fileFormat.put("width", width);
fileFormat.put("height", height);
options.put("fileFormat", fileFormat);
parameters.put("options", options);
input.put("parameters", parameters);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
}
/**
* Acquire currently set shooting size
* @return Shooting size (null is returned if acquisition fails)
*/
public ImageSize getImageSize() {
// set capture mode to image
setImageCaptureMode();
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
String responseData;
ImageSize imageSize = null;
InputStream is = null;
try {
// send HTTP POST
input.put("name", "camera.getOptions");
JSONObject parameters = new JSONObject();
JSONArray optionNames = new JSONArray();
optionNames.put("fileFormat");
parameters.put("optionNames", optionNames);
input.put("parameters", parameters);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
String status = output.getString("state");
if (status.equals("done")) {
JSONObject results = output.getJSONObject("results");
JSONObject options = results.getJSONObject("options");
JSONObject fileFormat = options.getJSONObject("fileFormat");
int width = fileFormat.getInt("width");
if (width == 2048) {
imageSize = ImageSize.IMAGE_SIZE_2048x1024;
} else {
imageSize = ImageSize.IMAGE_SIZE_5376x2688;
}
}
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return imageSize;
}
/**
* Set still image as shooting mode
* @return Error message (null is returned if successful)
*/
private String setImageCaptureMode() {
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
String responseData;
String errorMessage = null;
InputStream is = null;
try {
// send HTTP POST
input.put("name", "camera.setOptions");
JSONObject parameters = new JSONObject();
JSONObject options = new JSONObject();
options.put("captureMode", "image");
//API2.0
if (mSessionId != null) {
parameters.put("sessionId", mSessionId);
}
parameters.put("options", options);
input.put("parameters", parameters);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
String status = output.getString("state");
if (status.equals("error")) {
JSONObject errors = output.getJSONObject("error");
errorMessage = errors.getString("message");
}
} catch (IOException e) {
Logger.e(TAG, e);
errorMessage = e.toString();
InputStream es = postConnection.getErrorStream();
try {
if (es != null) {
String errorData = InputStreamToString(es);
JSONObject output = new JSONObject(errorData);
JSONObject errors = output.getJSONObject("error");
errorMessage = errors.getString("message");
}
} catch (IOException e1) {
e1.printStackTrace();
} catch (JSONException e1) {
e1.printStackTrace();
} finally {
if (es != null) {
try {
es.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
} catch (JSONException e) {
Logger.e(TAG, e);
errorMessage = e.toString();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return errorMessage;
}
/**
* Acquire device status
* @return Last saved file
*/
private String getState() {
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/state");
String responseData;
String lastFile = "";
InputStream is = null;
try {
// send HTTP POST
postConnection.connect();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
mFingerPrint = output.getString("fingerprint");
JSONObject status = output.getJSONObject("state");
lastFile = status.getString("_latestFileUri");
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return lastFile;
}
/**
* Check for updates to device status
* @return true:Update available, false:No update available
*/
private boolean isUpdate() {
boolean update = false;
InputStream is = null;
if (mFingerPrint == null) {
return update;
}
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/checkForUpdates");
JSONObject input = new JSONObject();
String responseData = null;
try {
// send HTTP POST
input.put("stateFingerprint", mFingerPrint);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
String currentFingerPrint = output.getString("stateFingerprint");
if (!currentFingerPrint.equals(mFingerPrint)) {
mFingerPrint = currentFingerPrint;
update = true;
}
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return update;
}
/**
* Generate connection destination URL
* @param path Path
* @return URL
*/
private String createUrl(String path) {
StringBuilder sb = new StringBuilder();
sb.append("http://");
sb.append(mIpAddress);
sb.append(path);
return sb.toString();
}
/**
* Generate HTTP connection
* @param method Method
* @param path Path
* @return HTTP Connection instance
*/
private HttpURLConnection createHttpConnection(String method, String path) {
HttpURLConnection connection = null;
try {
URL url = new URL(createUrl(path));
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
connection.setRequestProperty("Accept", "application/json");
connection.setDoInput(true);
connection.setConnectTimeout(HTTP_CONNECT_TIME_OUT);
if (method.equals("POST")) {
connection.setRequestMethod(method);
connection.setDoOutput(true);
}
} catch (MalformedURLException e) {
Logger.e(TAG, e);
} catch (IOException e) {
Logger.e(TAG, e);
}
return connection;
}
/**
* Convert input stream to string
* @param is InputStream
* @return String
* @throws IOException IO error
*/
private String InputStreamToString(InputStream is) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
StringBuilder sb = new StringBuilder();
String lineData;
while ((lineData = br.readLine()) != null) {
sb.append(lineData);
}
br.close();
return sb.toString();
}
/**
* THETAカメラのWi-Fi機能をOFFに設定
* @return 結果値(true:成功、false:失敗)
*/
public boolean cameraFinishWlan() {
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
String responseData;
String errorMessage = null;
InputStream is = null;
boolean isSuccess = false;
try {
// send HTTP POST
input.put("name", "camera._finishWlan");
//API2.0
if (mIsOldApi) {
mSessionId = connect();
if (mSessionId != null) {
JSONObject parameters = new JSONObject();
parameters.put("sessionId", mSessionId);
input.put("parameters", parameters);
}
}
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
InputStreamToString(is);
isSuccess = true;
} catch (IOException e) {
Logger.e(TAG, e);
Logger.e(TAG, e.toString());
InputStream es = postConnection.getErrorStream();
try {
if (es != null) {
String errorData = InputStreamToString(es);
JSONObject output = new JSONObject(errorData);
JSONObject errors = output.getJSONObject("error");
Logger.e(TAG, errors.getString("message"));
}
} catch (IOException e1) {
Logger.e(TAG, e1);
} catch (JSONException e1) {
Logger.e(TAG, e1);
} finally {
if (es != null) {
try {
es.close();
} catch (IOException e1) {
Logger.e(TAG, e1);
}
}
}
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return isSuccess;
}
/**
* THETAカメラの露出情報を取得
* @return 文字列型の露出値
*/
public String getOptionExposure() {
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
String responseData;
InputStream is = null;
String exposureCompensation = null;
try {
// send HTTP POST
input.put("name", "camera.getOptions");
JSONObject parameters = new JSONObject();
JSONArray optionNames = new JSONArray();
optionNames.put("exposureCompensation");
//API2.0
if (mIsOldApi) {
mSessionId = connect();
if (mSessionId != null) {
parameters.put("sessionId", mSessionId);
}
}
parameters.put("optionNames", optionNames);
input.put("parameters", parameters);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
responseData = InputStreamToString(is);
// parse JSON data
JSONObject output = new JSONObject(responseData);
String status = output.getString("state");
if (status.equals("done")) {
JSONObject results = output.getJSONObject("results");
JSONObject options = results.getJSONObject("options");
exposureCompensation = options.getString("exposureCompensation");
}
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return exposureCompensation;
}
/**
* THETAカメラの露出情報を設定
* @param exposure 露出値
* @return 結果値(true:成功、false:失敗)
*/
public boolean setOptionExposure(String exposure) {
HttpURLConnection postConnection = createHttpConnection("POST", "/osc/commands/execute");
JSONObject input = new JSONObject();
String responseData;
InputStream is = null;
String exposureCompensation = null;
boolean isSuccess = false;
try {
// send HTTP POST
input.put("name", "camera.setOptions");
JSONObject parameters = new JSONObject();
JSONObject options = new JSONObject();
options.put("exposureCompensation", Double.parseDouble(exposure));
//API2.0 start
if (mIsOldApi) {
mSessionId = connect();
if (mSessionId != null) {
parameters.put("sessionId", mSessionId);
}
}
parameters.put("options", options);
input.put("parameters", parameters);
OutputStream os = postConnection.getOutputStream();
os.write(input.toString().getBytes());
postConnection.connect();
os.flush();
os.close();
is = postConnection.getInputStream();
InputStreamToString(is);
isSuccess = true;
} catch (IOException e) {
Logger.e(TAG, e);
} catch (JSONException e) {
Logger.e(TAG, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Logger.e(TAG, e);
}
}
}
return isSuccess;
}
}
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 {
//noinspection deprecation(API18から非推奨になった。無視)
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 {
showProgressPopup(getResources().getString(R.string.progress));
}
public void changeProgressPopup(String msg) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.setMessage(msg);
}
}
public void closeProgressPopup() {
handler.post(new Runnable() {
@Override
......@@ -807,6 +813,13 @@ public abstract class ABVActivity extends Activity {
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) {
showSimpleAlertDialog(getString(titleResId), getString(bodyResId));
}
......
......@@ -115,6 +115,9 @@ public abstract class ABVAuthenticatedActivity extends ABVActivity implements Co
public static final String FILEPATH = "FILEPATH";
//連続タップ防止用のボタン活性化するタイム
protected static final int BUTTON_ENABLE_DELAY_MILLIS = 500;
protected ContentDao contentDao = AbstractDao.getDao(ContentDao.class);
protected MemoLogic memoLogic = AbstractLogic.getLogic(MemoLogic.class);
......@@ -777,4 +780,20 @@ public abstract class ABVAuthenticatedActivity extends ABVActivity implements Co
public void stopContentRefresher() {
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;
public abstract class ABVUIActivity extends ABVAuthenticatedActivity {
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; //自動リフレッシュはネットワークエラー表示しないように
protected ImageView mRefreshImage; // 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;
}
}
package jp.agentec.abook.abv.ui.viewer.activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
......@@ -10,12 +11,16 @@ import android.os.Bundle;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ListView;
import com.imagepicker.ImageInternalFetcher;
import com.theta.helper.ThetaHelper;
import com.theta.network.ThetaDeviceInfo;
import java.io.File;
import java.util.ArrayList;
......@@ -28,25 +33,30 @@ 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.ABookKeys;
import jp.agentec.abook.abv.bl.common.constant.ABookValues;
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.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.OperationLogic;
import jp.agentec.abook.abv.cl.environment.DeviceInfo;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVUIActivity;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.common.util.PatternStringUtil;
import jp.agentec.abook.abv.ui.home.helper.ABookPermissionHelper;
import jp.agentec.abook.abv.ui.viewer.activity.theta.ThetaCameraActivity;
import jp.agentec.abook.abv.ui.viewer.activity.theta.task.DeviceInfoTask;
import jp.agentec.abook.abv.ui.viewer.adapter.ImageGalleryAdapter;
import jp.agentec.abook.abv.ui.viewer.adapter.WifiThetaConnectAdapter;
import jp.agentec.abook.abv.ui.viewer.view.CustomImage;
public class DeviceImageListActivity extends ABVUIActivity {
private static final String TAG = "DeviceImageListActivity";
//表示画像の解像度(低くなると画質が悪くなる)
private static final int THUMBNALE_SIZE = 1000;
private static final int THUMBNALE_SIZE = 700;
//タブレットの1行最大表示数
private static final int TABLET_COLUMNS = 4;
//タブレットの縦表示時、1行最大表示数
......@@ -55,24 +65,35 @@ public class DeviceImageListActivity extends ABVUIActivity {
private static final int PHONE_COLUMNS_LANDSCAPE = 5;
//画像選択最大数
private static final int IMAGE_SELECT_MAX_COUNT = 20;
//タブレット表示の画面サイズ調整スケール
public static final double WINDOW_RESIZE_SCALE = 0.9;
//連続タップ防止用のボタン活性化するタイム
public static final int BUTTON_ENABLE_DELAY_MILLIS = 500;
//登録完了後、100%プログレスバー表示のため、完了ダイアログ表示タイム
public static final int SEND_FINISH_DIALOG_DELAY_MILLIS = 200;
//THETAカメラWIFI接続後、切り替える時間が必要のため、カメラ情報取得ディレータイム
private static final int GET_THETA_CAMERA_INFO_DELAY = 1500;
//サムネイルの保存するとき、キャッシュの中のフォルダ名
private static final String THUMB_IMAGE_CACHE_DIRECTORY_NAME = "thumb";
GridView mGalleryGridView;
ImageGalleryAdapter mGalleryAdapter;
private Set<String> mSelectedImages;
private List<CustomImage>mLocalImageList;
private Set<String>mLocalImageUriList;
public ImageInternalFetcher mImageFetcher;
private Button mRegistBtn;
private Button mCameraBtn;
private int mGridViewRowHeight;
private boolean mIsOnResume;
private Long mContentId;
private Dialog mThetaDeviceConnectDialog;
private ListView notSavedListView;
private ListView savedListView;
private boolean isBaseSceneUpload = false;
private ThetaHelper mThetaHelper = new ThetaHelper(this);
@Override
public void onCreate(Bundle savedInstanceState) {
Logger.i(TAG, "onCreate");
......@@ -81,11 +102,17 @@ public class DeviceImageListActivity extends ABVUIActivity {
Intent intent = getIntent();
mContentId = intent.getLongExtra(ABookKeys.CONTENT_ID, -1);
if (mContentId == -1) {
isBaseSceneUpload = true;
}
mSelectedImages = new HashSet<>();
mLocalImageList = new ArrayList<>();
mLocalImageUriList = new HashSet<>();
mImageFetcher = new ImageInternalFetcher(this, THUMBNALE_SIZE);
mImageFetcher.addImageCache(this, THUMB_IMAGE_CACHE_DIRECTORY_NAME);
mImageFetcher.clearCache();
mIsOnResume = false;
mGalleryGridView = findViewById(R.id.gallery_grid);
......@@ -94,6 +121,8 @@ public class DeviceImageListActivity extends ABVUIActivity {
@Override
public void onClick(View v) {
Logger.v(TAG, "CloseBtn.onClick");
//キャッシュをクリア
mImageFetcher.clearCache();
finish();
}
});
......@@ -102,8 +131,8 @@ public class DeviceImageListActivity extends ABVUIActivity {
@Override
public void onClick(View v) {
Logger.v(TAG, "RegistBtn.onClick");
buttonDoubleTapControl(mRegistBtn);
if (checkNetworkConnected()) {
mRegistBtn.setEnabled(false);
AlertDialogUtil.showAlertDialog(DeviceImageListActivity.this, R.string.app_name, R.string.msg_image_select_send_comfirm, false, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
......@@ -112,19 +141,35 @@ public class DeviceImageListActivity extends ABVUIActivity {
}
}
});
//連続タップ防止
handler.postDelayed(new Runnable() {
@Override
public void run() {
mRegistBtn.setEnabled(true);
}
}, BUTTON_ENABLE_DELAY_MILLIS);
}
}
});
mRegistBtn.setEnabled(false);
mCameraBtn = findViewById(R.id.theta_camera);
mCameraBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Logger.v(TAG, "RegistBtn.onClick");
buttonDoubleTapControl(mCameraBtn);
if (deviceWifiEnable()) {
//位置情報権限チェック
ABookPermissionHelper helper = new ABookPermissionHelper(DeviceImageListActivity.this, Constant.ABookPermissionType.AccessFineLocation, null);
if (helper.checkMultiPermissions(true)) {
if (mThetaHelper.connectedDeviceWifiThetaCamera()) {
//カメラ選択
showProgressPopup(getString(R.string.msg_wifi_connecting));
new DeviceInfoTask(DeviceImageListActivity.this).execute();
} else {
showThetaDeviceConnectDialog();
}
}
}
}
});
//表示中にストレージ権限がなくなった場合、シーン画像選択画面を非表示
final Callback resultCallback = new Callback() {
@Override
......@@ -166,8 +211,8 @@ public class DeviceImageListActivity extends ABVUIActivity {
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int widthPixels = (int) (getResources().getDisplayMetrics().widthPixels * WINDOW_RESIZE_SCALE) ;
int heightPixels = (int) (getResources().getDisplayMetrics().heightPixels * WINDOW_RESIZE_SCALE);
int widthPixels = (int) (getResources().getDisplayMetrics().widthPixels * DIALOG_WINDOW_RESIZE_SCALE_09) ;
int heightPixels = (int) (getResources().getDisplayMetrics().heightPixels * DIALOG_WINDOW_RESIZE_SCALE_09);
int numColumn;
if (isNormalSize()) { //スマートフォン
if (widthPixels > heightPixels) {
......@@ -382,8 +427,166 @@ public class DeviceImageListActivity extends ABVUIActivity {
if (checkNetworkConnected()) {
sendImageList(needSendImages);
}
}
});
}
/**
* THETAカメラ接続ダイアログを表示
*/
private void showThetaDeviceConnectDialog() {
if (mThetaDeviceConnectDialog == null) {
mThetaDeviceConnectDialog = new Dialog(DeviceImageListActivity.this);
mThetaDeviceConnectDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
mThetaDeviceConnectDialog.setCanceledOnTouchOutside(false);
mThetaDeviceConnectDialog.setContentView(R.layout.theta_device_connect_dialog);
}
//更新ボタン
final Button registerButton = mThetaDeviceConnectDialog.findViewById(R.id.btn_theta_update);
registerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
buttonDoubleTapControl(registerButton);
if (deviceWifiEnable()) {
//THETA接続チェック
if (mThetaHelper.connectedDeviceWifiThetaCamera()) {
showProgressPopup(getString(R.string.msg_wifi_connecting));
new DeviceInfoTask(DeviceImageListActivity.this).execute();
} else {
//Wi-Fi情報を再度取得し、再描画
List<ThetaDeviceInfo> savedList = mThetaHelper.getThetaWifiList(true);
WifiThetaConnectAdapter savedAdapter = (WifiThetaConnectAdapter) savedListView.getAdapter();
savedAdapter.setListItem(savedList);
savedAdapter.notifyDataSetChanged();
List<ThetaDeviceInfo> notSaveList = mThetaHelper.getThetaWifiList(false);
WifiThetaConnectAdapter notSaveAdapter = (WifiThetaConnectAdapter) notSavedListView.getAdapter();
notSaveAdapter.setListItem(notSaveList);
notSaveAdapter.notifyDataSetChanged();
}
}
}
});
//閉じるボタン
final Button viewCloseButton = mThetaDeviceConnectDialog.findViewById(R.id.btn_close);
viewCloseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
buttonDoubleTapControl(viewCloseButton);
mThetaDeviceConnectDialog.dismiss();
}
});
//登録済みの端末リスト表示
savedListView = mThetaDeviceConnectDialog.findViewById(R.id.lv_theta_wifi_saved);
List<ThetaDeviceInfo> savedList = mThetaHelper.getThetaWifiList(true);
WifiThetaConnectAdapter wifiSavedAdapter = new WifiThetaConnectAdapter(this, savedList);
savedListView.setAdapter(wifiSavedAdapter);
savedListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (deviceWifiEnable()) {
ThetaDeviceInfo info = (ThetaDeviceInfo) parent.getItemAtPosition(position);
connectThetaWifi(info.getSSID(), info.getNetworkId());
}
}
});
//未登録の端末リスト表示
notSavedListView = mThetaDeviceConnectDialog.findViewById(R.id.lv_theta_wifi_not_saved);
List<ThetaDeviceInfo> notSaveList = mThetaHelper.getThetaWifiList(false);
WifiThetaConnectAdapter wifiNotSaveAdapter = new WifiThetaConnectAdapter(this, notSaveList);
notSavedListView.setAdapter(wifiNotSaveAdapter);
notSavedListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (deviceWifiEnable()) {
ThetaDeviceInfo info = (ThetaDeviceInfo) parent.getItemAtPosition(position);
connectThetaWifi(info.getSSID(), -1);
}
}
});
mThetaDeviceConnectDialog.show();
}
/**
* THETAカメラへ接続
* @param ssid アクセスポイント
* @param networkId 接続可能なネットワークID
*/
private void connectThetaWifi(String ssid, int networkId) {
showProgressPopup(getString(R.string.msg_wifi_connecting));
if (networkId == -1) {
networkId = mThetaHelper.saveThetaCameraWifi(ssid);
if (networkId == -1) {
closeProgressPopup();
showSimpleAlertDialog(getString(R.string.msg_fail_connect_theta_wifi));
return;
}
}
boolean isSuccess = mThetaHelper.connectThetaCameraWifi(networkId);
if (isSuccess) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
new DeviceInfoTask(DeviceImageListActivity.this).execute();
}
}, GET_THETA_CAMERA_INFO_DELAY);
} else {
closeProgressPopup();
showSimpleAlertDialog(getString(R.string.msg_fail_connect_theta_wifi));
}
}
/**
* THETAカメラ情報取得完了後、呼ばれる
* 成功:利用するAPI情報保存後、THETAカメラ画面表示
* 失敗:エラーアラート表示
* @param deviceInfo THETAカメラ情報
*/
public void thetaDeviceInfoTaskFinish(ThetaDeviceInfo deviceInfo) {
closeProgressPopup();
if (deviceInfo != null && deviceInfo.getModel().length() != 0) {
if (deviceInfo.getModel().equals(ABookValues.THETA_MODEL_NAME_THETA_S) || deviceInfo.getModel().equals(ABookValues.THETA_MODEL_NAME_THETA_SC)) {
putUserPref(ABookKeys.THETA_OLD_VERSION_FLG, true);
Logger.d(TAG, "thetaDeviceInfoTaskFinish use API2.0");
} else {
putUserPref(ABookKeys.THETA_OLD_VERSION_FLG, false);
Logger.d(TAG, "thetaDeviceInfoTaskFinish use API2.1");
}
if (mThetaDeviceConnectDialog != null && mThetaDeviceConnectDialog.isShowing()) {
mThetaDeviceConnectDialog.dismiss();
}
//THETAカメラ画面表示
Intent intent = new Intent();
intent.setClassName(getPackageName(), ThetaCameraActivity.class.getName());
startActivity(intent);
} else {
if (mThetaDeviceConnectDialog != null && mThetaDeviceConnectDialog.isShowing()) {
showSimpleAlertDialog(getString(R.string.msg_fail_connect_theta_wifi));
} else {
showThetaDeviceConnectDialog();
}
}
}
/**
* デバイスのWifi有効・無効チェックし
* 無効の場合、ダイアログ表示
* @return true:有効, false:無効
*/
private boolean deviceWifiEnable() {
if (DeviceInfo.isDeviceWifiEnabled(DeviceImageListActivity.this)) {
return true;
} else {
showSimpleAlertDialog(R.string.msg_error_device_wifi_off);
return false;
}
}
}
......@@ -4,8 +4,6 @@ import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
......@@ -13,7 +11,6 @@ import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
......@@ -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.common.ABVEnvironment;
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.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.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.data.dao.ContentDao;
import jp.agentec.abook.abv.bl.dto.ContentDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
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.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.R;
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.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.util.AlertDialogUtil;
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.ActivityHandlingHelper;
import jp.agentec.abook.abv.ui.home.helper.ContentViewHelper;
......@@ -70,6 +60,7 @@ public class ParentWebViewActivity extends ABVContentViewActivity {
private ProgressBar m_progress;
protected ContentDto mContentDto;
protected void commonOnCreate() {
mContentDto = AbstractDao.getDao(ContentDao.class).getContent(contentId);
historyLayout = (LinearLayout) findViewById(R.id.historyLayout);
......@@ -102,7 +93,6 @@ public class ParentWebViewActivity extends ABVContentViewActivity {
ABookPermissionHelper helper = new ABookPermissionHelper(context, Constant.ABookPermissionType.ReadExternalStorage, null);
if (helper.checkMultiPermissions(true)) {
//シーン画像選択画面表示
Logger.d("test");
Intent intent = new Intent();
intent.putExtra(ABookKeys.CONTENT_ID, contentId);
String className = DeviceImageListActivity.class.getName();
......@@ -130,6 +120,10 @@ public class ParentWebViewActivity extends ABVContentViewActivity {
}
}
protected void commonProgressChanged(int progress) {
setVisbilityProgress(true);
if (progress >= 100) {
......
package jp.agentec.abook.abv.ui.viewer.activity.theta;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import com.theta.helper.ThetaHelper;
import com.theta.view.MJpegInputStream;
import com.theta.view.MJpegView;
import java.util.ArrayList;
import java.util.Arrays;
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.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVUIActivity;
import jp.agentec.abook.abv.ui.viewer.activity.theta.task.FinishWlanTask;
import jp.agentec.abook.abv.ui.viewer.activity.theta.task.GetOptionExposureTask;
import jp.agentec.abook.abv.ui.viewer.activity.theta.task.SetOptionExposureTask;
import jp.agentec.abook.abv.ui.viewer.activity.theta.task.ShootTask;
import jp.agentec.abook.abv.ui.viewer.activity.theta.task.ShowLiveViewTask;
/**
* THETAカメラ画面
* @version 1.2.300
* @since 2020/05/19
* @author 金鎭星
*/
public class ThetaCameraActivity extends ABVUIActivity {
private static final String TAG = "ThetaCameraActivity";
//画面表示後、ライブビューア取得を0.5秒後に取得
private static final int LIVE_VIEW_START_DELAY = 500;
//閉じる時にWi-Fi切り替える時間を2秒後に閉じる
private static final int WIFI_CHANGE_TIME_DELAY = 2000;
private MJpegView mLiveView;
private ShowLiveViewTask mLivePreviewTask;
private Button mShootBtn;
private Button mImageListBtn;
TextView mExposureTextView;
SeekBar mExposureSeekBar;
int mCurrentSeekBarProgress;
private static final List<String> mExposureValues = new ArrayList<>(Arrays.asList("-2.0", "-1.7", "-1.3", "-1.0", "-0.7", "-0.3", "0.0", "0.3", "0.7", "1.0", "1.3", "1.7", "2.0"));
private ThetaHelper mThetaHelper = new ThetaHelper(this);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ac_theta_camera);
mLiveView = findViewById(R.id.live_view);
// 閉じるボタン
Button closeBtn = findViewById(R.id.btn_close);
closeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Logger.v(TAG, "CloseBtn.onClick");
mLiveView.stopPlay();
//現在接続状態なのかチェック
if (mThetaHelper.connectedDeviceWifiThetaCamera()) {
showProgressPopup();
//THETAカメラのWi-Fi機能をOFFに設定
new FinishWlanTask(ThetaCameraActivity.this).execute();
}
}
});
//撮影ボタン
mShootBtn = findViewById(R.id.btn_theta_camera_shoot);
mShootBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mShootBtn.setEnabled(false);
showProgressPopup();
new ShootTask(ThetaCameraActivity.this).execute();
//連続タップ防止
handler.postDelayed(new Runnable() {
@Override
public void run() {
mShootBtn.setEnabled(true);
}
}, BUTTON_ENABLE_DELAY_MILLIS);
}
});
//画像選択ボタン
mImageListBtn = findViewById(R.id.btn_theta_camera_image_list);
mImageListBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mImageListBtn.setEnabled(false);
Intent intent = new Intent();
intent.setClassName(getPackageName(), ThetaImageListActivity.class.getName());
startActivity(intent);
//連続タップ防止
handler.postDelayed(new Runnable() {
@Override
public void run() {
mImageListBtn.setEnabled(true);
}
}, BUTTON_ENABLE_DELAY_MILLIS);
}
});
//露出シークバー
settingSeekbar();
showProgressPopup();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mLivePreviewTask = new ShowLiveViewTask(ThetaCameraActivity.this);
mLivePreviewTask.execute();
}
}, LIVE_VIEW_START_DELAY);
}
//端末の戻るボタン禁止
@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);
}
@Override
protected void onPause() {
super.onPause();
mLiveView.stopPlay();
}
@Override
protected void onResume() {
super.onResume();
mLiveView.play();
if (mLivePreviewTask != null) {
mLivePreviewTask.cancel(true);
mLivePreviewTask = new ShowLiveViewTask(this);
mLivePreviewTask.execute();
}
}
@Override
protected void onDestroy() {
if (mLivePreviewTask != null) {
mLivePreviewTask.cancel(true);
}
super.onDestroy();
}
/**
* シークバーを描画及び初期値設定
*/
private void settingSeekbar() {
mExposureTextView = findViewById(R.id.tv_exposure);
//Android6.0以下の場合、古いシークバー利用
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
mExposureSeekBar = findViewById(R.id.sb_exposure_old);
findViewById(R.id.sb_exposure).setVisibility(View.GONE);
} else {
mExposureSeekBar = findViewById(R.id.sb_exposure);
findViewById(R.id.sb_exposure_old).setVisibility(View.GONE);
}
mExposureSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mExposureTextView.setText("EV:" + mExposureValues.get(progress));
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int progress = seekBar.getProgress();
if (progress != mCurrentSeekBarProgress) {
mCurrentSeekBarProgress = progress;
String exposure = mExposureValues.get(progress);
//サーバ通信
new SetOptionExposureTask(ThetaCameraActivity.this).execute(exposure);
Logger.d(TAG, "exposure" + exposure);
}
Logger.d(TAG, "progress = " + progress + ", mCurrentSeekBarProgress = " + mCurrentSeekBarProgress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
});
}
/**
* THETAカメラの撮影するShootTaskスレッド終了後に呼ばれる
* @param fileId ファイルID
*/
public void shootTaskFinish(final String fileId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
closeProgressPopup();
mShootBtn.setEnabled(true);
if (fileId.equals(ABookValues.FAIL)) {
//TODO:失敗エラーアラート
showSimpleAlertDialog(R.string.msg_theta_shoot_fail);
} else {
Intent intent = new Intent();
intent.putExtra(ABookKeys.THETA_FILE_ID, fileId);
intent.setClassName(getPackageName(), ThetaImagePreviewActivity.class.getName());
startActivity(intent);
}
}
});
}
/**
* THETAカメラのライブ映像情報を取得するShowLiveViewTaskスレッド終了後に呼ばれる
* @param mJpegInputStream Live画像データ
*/
public void showLiveViewTaskFinish(MJpegInputStream mJpegInputStream) {
closeProgressPopup();
if (mJpegInputStream != null) {
mLiveView.setSource(mJpegInputStream);
new GetOptionExposureTask(ThetaCameraActivity.this).execute();
} else {
//TODO:失敗ダイアログ
Logger.e("failed to start live view");
}
}
/**
* THETAカメラのWi-Fi機能OFFにするFinishWlanTaskスレッド終了後に呼ばれる
* @param result Wi-Fi設定OFF結果
*/
public void finishWlanTaskFinish(String result) {
closeProgressPopup();
finish();
}
/**
* THETAカメラの露出値を取得するGetOptionExposureTaskの終了時呼ばれる
* @param exposure 露出値
*/
public void getOptionExposureTaskFinish(String exposure) {
int progress = mExposureValues.indexOf(exposure);
if (progress != 1) {
mExposureSeekBar.setProgress(progress);
}
mExposureTextView.setText("EV:" + exposure);
}
/**
*HETAカメラの露出値を設定するSetOptionExposureTaskの終了時呼ばれる
* @param result 送信結果(Success:成功、fail:失敗)
*/
public void setOptionExposureTaskFinish(String result) {
if (ABookValues.SUCCESS.equals(result)) {
//
} else {
//TODO:エラーアラート
}
}
}
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