diff options
123 files changed, 4380 insertions, 5332 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index cd71194..bd8fc34 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -5,9 +5,6 @@ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> - <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.lh2"/> - <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.youtube"/> - <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.YouTubeUser"/> <uses-permission android:name="android.permission.SET_WALLPAPER" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> <application android:icon="@drawable/ic_launcher_camera" @@ -34,11 +31,26 @@ <action android:name="android.media.action.IMAGE_CAPTURE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> + <intent-filter> + <action android:name="android.media.action.STILL_IMAGE_CAMERA" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + <activity android:name="VideoCamera" + android:configChanges="orientation|keyboardHidden" + android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" + android:screenOrientation="landscape" + android:clearTaskOnLaunch="true" + android:taskAffinity="android.task.camera"> + <intent-filter> + <action android:name="android.media.action.VIDEO_CAMERA" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> </activity> - <activity android:name="GalleryPicker" android:label="@string/gallery_picker_label" android:configChanges="orientation|keyboardHidden" android:icon="@drawable/ic_launcher_gallery" + android:clearTaskOnLaunch="true" android:taskAffinity="android.task.pictures"> <intent-filter> <action android:name="android.intent.action.MAIN" /> @@ -59,7 +71,11 @@ <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.cursor.dir/image" /> </intent-filter> - + <intent-filter> + <action android:name="android.intent.action.VIEW" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:mimeType="vnd.android.cursor.dir/video" /> + </intent-filter> <intent-filter> <action android:name="android.intent.action.GET_CONTENT" /> <category android:name="android.intent.category.OPENABLE" /> @@ -75,6 +91,7 @@ <action android:name="android.intent.action.PICK" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> + <data android:mimeType="video/*" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.PICK" /> @@ -106,18 +123,33 @@ <data android:mimeType="image/*" /> </intent-filter> </activity> - -<!-- - <activity android:name="ViewVideo" android:label="@string/view_video_label"> + <activity android:name="MovieView" + android:label="@string/movieviewlabel" + android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"> - <intent-filter> + <intent-filter> + <action android:name="android.intent.action.VIEW" /> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> + <data android:scheme="rtsp" /> + </intent-filter> + <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="video/*" /> - </intent-filter> + </intent-filter> + <intent-filter> + <action android:name="android.intent.action.VIEW" /> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> + <data android:scheme="http" /> + <data android:mimeType="video/mp4" /> + <data android:mimeType="video/3gp" /> + <data android:mimeType="video/3gpp" /> + <data android:mimeType="video/3gpp2" /> + </intent-filter> </activity> ---> <activity android:name="CameraSettings" android:label="@string/preferences_label"> <intent-filter> @@ -141,16 +173,6 @@ </intent-filter> </activity> -<!-- - <activity android:name="PwaUpload" android:label="@string/picasa_upload_label"> - <intent-filter> - <action android:name="android.intent.action.SEND" /> - <data android:mimeType="image/*" /> - <category android:name="android.intent.category.DEFAULT" /> - <category android:name="android.intent.category.BROWSABLE" /> - </intent-filter> - </activity> ---> <activity android:name=".Wallpaper" android:label="@string/camera_setas_wallpaper" android:icon="@drawable/ic_launcher_gallery"> @@ -179,29 +201,6 @@ <!--</intent-filter>--> <!--</activity>--> -<!-- - <activity android:name="YouTubeUpload" android:label="@string/youtube_upload_label"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - </intent-filter> - </activity> - - <activity android:name="YouTubeUpload" - android:label="YouTubeUpload" - android:theme="@android:style/Theme.Light"> - - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - - <activity android:name="ErrorScreen" android:label="@string/error_label"> - <intent-filter> - <action android:name="android.intent.action.VIEW" /> - </intent-filter> - </activity> ---> </application> </manifest> diff --git a/res/anim/alpha_in.xml b/res/anim/alpha_in.xml deleted file mode 100644 index 6ad315a..0000000 --- a/res/anim/alpha_in.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - <alpha - android:fromAlpha="0.0" - android:toAlpha="1.0" - android:fillAfter="true" - android:startOffset="900" - android:duration="700" /> -</set> diff --git a/res/anim/alpha_out.xml b/res/anim/alpha_out.xml deleted file mode 100644 index bf6ee89..0000000 --- a/res/anim/alpha_out.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - <alpha - android:fromAlpha="1.0" - android:toAlpha="0.0" - android:fillAfter="true" - android:duration="700" /> -</set> - - diff --git a/res/anim/hyperspace_out.xml b/res/anim/hyperspace_out.xml deleted file mode 100644 index f963156..0000000 --- a/res/anim/hyperspace_out.xml +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - - <scale - android:interpolator="@android:anim/accelerate_decelerate_interpolator" - android:fromXScale="1.0" - android:toXScale="1.4" - android:fromYScale="1.0" - android:toYScale="0.6" - android:pivotX="50%" - android:pivotY="50%" - android:fillAfter="false" - android:duration="700" /> - - - <set - android:interpolator="@android:anim/accelerate_interpolator"> - - <scale - android:fromXScale="1.4" - android:toXScale="0.0" - android:fromYScale="0.6" - android:toYScale="0.0" - android:pivotX="50%" - android:pivotY="50%" - android:startOffset="700" - android:duration="400" - android:fillBefore="false" /> - - <rotate - android:fromDegrees="0" - android:toDegrees="-45" - android:toYScale="0.0" - android:pivotX="50%" - android:pivotY="50%" - android:startOffset="700" - android:duration="400" /> - </set> - -</set> - diff --git a/res/anim/rotate_in.xml b/res/anim/rotate_in.xml deleted file mode 100644 index 25edc8b..0000000 --- a/res/anim/rotate_in.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<rotate xmlns:android="http://schemas.android.com/apk/res/android" - android:fromDegrees="90" - android:toDegrees="0" - android:toYScale="0.0" - android:pivotX="0%" - android:pivotY="100%" - android:startOffset="400" - android:duration="300" /> diff --git a/res/anim/rotate_out.xml b/res/anim/rotate_out.xml deleted file mode 100644 index 4ebf33f..0000000 --- a/res/anim/rotate_out.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<rotate xmlns:android="http://schemas.android.com/apk/res/android" - android:fromDegrees="0" - android:toDegrees="-90" - android:toYScale="0.0" - android:pivotX="0%" - android:pivotY="100%" - android:startOffset="0" - android:duration="300" /> - - diff --git a/res/anim/rotate_shrink_in.xml b/res/anim/rotate_shrink_in.xml deleted file mode 100644 index 3582102..0000000 --- a/res/anim/rotate_shrink_in.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - <scale - android:fromXScale="0.01" - android:toXScale="1.0" - android:fromYScale="0.01" - android:toYScale="1.0" - android:pivotX="50%" - android:pivotY="50%" - android:fillAfter="true" - android:startOffset="400" - android:duration="300" /> - - <rotate - android:fromDegrees="90" - android:toDegrees="0" - android:toYScale="0.0" - android:pivotX="50%" - android:pivotY="50%" - android:fillAfter="true" - android:startOffset="400" - android:duration="300" /> -</set> diff --git a/res/anim/rotate_shrink_out.xml b/res/anim/rotate_shrink_out.xml deleted file mode 100644 index c608a8f..0000000 --- a/res/anim/rotate_shrink_out.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - <scale - android:fromXScale="1.0" - android:toXScale="0.01" - android:fromYScale="1.0" - android:toYScale="0.01" - android:pivotX="50%" - android:pivotY="50%" - android:fillAfter="true" - android:duration="300" /> - - <rotate - android:fromDegrees="0" - android:toDegrees="-90" - android:pivotX="50%" - android:pivotY="50%" - android:fillAfter="true" - android:startOffset="0" - android:duration="300" /> -</set> - - diff --git a/res/drawable/app_camera.png b/res/drawable/app_camera.png Binary files differdeleted file mode 100644 index a2bb888..0000000 --- a/res/drawable/app_camera.png +++ /dev/null diff --git a/res/drawable/app_photos.png b/res/drawable/app_photos.png Binary files differdeleted file mode 100644 index 971a41e..0000000 --- a/res/drawable/app_photos.png +++ /dev/null diff --git a/res/drawable/camera_crop_height.png b/res/drawable/camera_crop_height.png Binary files differindex b089aec..b089aec 100755..100644 --- a/res/drawable/camera_crop_height.png +++ b/res/drawable/camera_crop_height.png diff --git a/res/drawable/camera_crop_width.png b/res/drawable/camera_crop_width.png Binary files differindex 65216af..65216af 100755..100644 --- a/res/drawable/camera_crop_width.png +++ b/res/drawable/camera_crop_width.png diff --git a/res/drawable/carousel_tray_bg.9.png b/res/drawable/carousel_tray_bg.9.png Binary files differdeleted file mode 100644 index d51babe..0000000 --- a/res/drawable/carousel_tray_bg.9.png +++ /dev/null diff --git a/res/drawable/counter_divider.png b/res/drawable/counter_divider.png Binary files differdeleted file mode 100644 index ff35a08..0000000 --- a/res/drawable/counter_divider.png +++ /dev/null diff --git a/res/drawable/delete_image.png b/res/drawable/delete_image.png Binary files differdeleted file mode 100644 index 032e683..0000000 --- a/res/drawable/delete_image.png +++ /dev/null diff --git a/res/drawable/frame_gallery_preview_album.png b/res/drawable/frame_gallery_preview_album.png Binary files differindex 5b92ee2..5b92ee2 100755..100644 --- a/res/drawable/frame_gallery_preview_album.png +++ b/res/drawable/frame_gallery_preview_album.png diff --git a/res/drawable/frame_gallery_preview_album_mask.png b/res/drawable/frame_gallery_preview_album_mask.png Binary files differindex b053f30..b053f30 100755..100644 --- a/res/drawable/frame_gallery_preview_album_mask.png +++ b/res/drawable/frame_gallery_preview_album_mask.png diff --git a/res/drawable/frame_gallery_preview_album_pressed.png b/res/drawable/frame_gallery_preview_album_pressed.png Binary files differindex e3575ff..e3575ff 100755..100644 --- a/res/drawable/frame_gallery_preview_album_pressed.png +++ b/res/drawable/frame_gallery_preview_album_pressed.png diff --git a/res/drawable/frame_gallery_preview_album_selected.png b/res/drawable/frame_gallery_preview_album_selected.png Binary files differindex 222a38a..222a38a 100755..100644 --- a/res/drawable/frame_gallery_preview_album_selected.png +++ b/res/drawable/frame_gallery_preview_album_selected.png diff --git a/res/drawable/frame_gallery_preview_album_sublevel.png b/res/drawable/frame_gallery_preview_album_sublevel.png Binary files differdeleted file mode 100755 index 489a4f4..0000000 --- a/res/drawable/frame_gallery_preview_album_sublevel.png +++ /dev/null diff --git a/res/drawable/frame_gallery_preview_album_sublevel_mask.png b/res/drawable/frame_gallery_preview_album_sublevel_mask.png Binary files differdeleted file mode 100755 index 4eefa03..0000000 --- a/res/drawable/frame_gallery_preview_album_sublevel_mask.png +++ /dev/null diff --git a/res/drawable/frame_gallery_preview_album_sublevel_pressed.png b/res/drawable/frame_gallery_preview_album_sublevel_pressed.png Binary files differdeleted file mode 100755 index 970993f..0000000 --- a/res/drawable/frame_gallery_preview_album_sublevel_pressed.png +++ /dev/null diff --git a/res/drawable/frame_gallery_preview_album_sublevel_selected.png b/res/drawable/frame_gallery_preview_album_sublevel_selected.png Binary files differdeleted file mode 100755 index 70330ce..0000000 --- a/res/drawable/frame_gallery_preview_album_sublevel_selected.png +++ /dev/null diff --git a/res/drawable/frame_gallery_thumb_uploaded_overlay.png b/res/drawable/frame_gallery_thumb_uploaded_overlay.png Binary files differdeleted file mode 100755 index 85b1fc8..0000000 --- a/res/drawable/frame_gallery_thumb_uploaded_overlay.png +++ /dev/null diff --git a/res/drawable/frame_overlay_gallery_camera.png b/res/drawable/frame_overlay_gallery_camera.png Binary files differindex a1fcfff..e0c24a6 100755..100644 --- a/res/drawable/frame_overlay_gallery_camera.png +++ b/res/drawable/frame_overlay_gallery_camera.png diff --git a/res/drawable/frame_overlay_gallery_downloaded.png b/res/drawable/frame_overlay_gallery_downloaded.png Binary files differdeleted file mode 100755 index 70853ec..0000000 --- a/res/drawable/frame_overlay_gallery_downloaded.png +++ /dev/null diff --git a/res/drawable/frame_overlay_gallery_folder.png b/res/drawable/frame_overlay_gallery_folder.png Binary files differnew file mode 100644 index 0000000..05f64cc --- /dev/null +++ b/res/drawable/frame_overlay_gallery_folder.png diff --git a/res/drawable/frame_overlay_gallery_video.png b/res/drawable/frame_overlay_gallery_video.png Binary files differindex 5381146..4b84854 100755..100644 --- a/res/drawable/frame_overlay_gallery_video.png +++ b/res/drawable/frame_overlay_gallery_video.png diff --git a/res/drawable/highlight_unfocus.9.png b/res/drawable/highlight_unfocus.9.png Binary files differdeleted file mode 100644 index 2a505b8..0000000 --- a/res/drawable/highlight_unfocus.9.png +++ /dev/null diff --git a/res/drawable/ic_btn_actionmenu_delete_default.png b/res/drawable/ic_btn_actionmenu_delete_default.png Binary files differnew file mode 100644 index 0000000..d7d4899 --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_delete_default.png diff --git a/res/drawable/ic_btn_actionmenu_delete_pressed.png b/res/drawable/ic_btn_actionmenu_delete_pressed.png Binary files differnew file mode 100644 index 0000000..2a39eb0 --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_delete_pressed.png diff --git a/res/drawable/ic_btn_actionmenu_delete_selected.png b/res/drawable/ic_btn_actionmenu_delete_selected.png Binary files differnew file mode 100644 index 0000000..7d41002 --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_delete_selected.png diff --git a/res/drawable/ic_btn_actionmenu_play_default.png b/res/drawable/ic_btn_actionmenu_play_default.png Binary files differnew file mode 100644 index 0000000..b8724aa --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_play_default.png diff --git a/res/drawable/ic_btn_actionmenu_play_pressed.png b/res/drawable/ic_btn_actionmenu_play_pressed.png Binary files differnew file mode 100644 index 0000000..eaa308b --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_play_pressed.png diff --git a/res/drawable/ic_btn_actionmenu_play_selected.png b/res/drawable/ic_btn_actionmenu_play_selected.png Binary files differnew file mode 100644 index 0000000..c7cbfec --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_play_selected.png diff --git a/res/drawable/ic_btn_actionmenu_set_as_default.png b/res/drawable/ic_btn_actionmenu_set_as_default.png Binary files differnew file mode 100644 index 0000000..f9a5f23 --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_set_as_default.png diff --git a/res/drawable/ic_btn_actionmenu_set_as_pressed.png b/res/drawable/ic_btn_actionmenu_set_as_pressed.png Binary files differnew file mode 100644 index 0000000..5b1fddd --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_set_as_pressed.png diff --git a/res/drawable/ic_btn_actionmenu_set_as_selected.png b/res/drawable/ic_btn_actionmenu_set_as_selected.png Binary files differnew file mode 100644 index 0000000..1e25cf3 --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_set_as_selected.png diff --git a/res/drawable/ic_btn_actionmenu_share_default.png b/res/drawable/ic_btn_actionmenu_share_default.png Binary files differnew file mode 100644 index 0000000..0e806c8 --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_share_default.png diff --git a/res/drawable/ic_btn_actionmenu_share_pressed.png b/res/drawable/ic_btn_actionmenu_share_pressed.png Binary files differnew file mode 100644 index 0000000..e9e5845 --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_share_pressed.png diff --git a/res/drawable/ic_btn_actionmenu_share_selected.png b/res/drawable/ic_btn_actionmenu_share_selected.png Binary files differnew file mode 100644 index 0000000..f9998b6 --- /dev/null +++ b/res/drawable/ic_btn_actionmenu_share_selected.png diff --git a/res/drawable/ic_camera_bar_indicator_record.png b/res/drawable/ic_camera_bar_indicator_record.png Binary files differnew file mode 100644 index 0000000..60f7a01 --- /dev/null +++ b/res/drawable/ic_camera_bar_indicator_record.png diff --git a/res/drawable/ic_camera_flash.png b/res/drawable/ic_camera_flash.png Binary files differdeleted file mode 100755 index 58265bf..0000000 --- a/res/drawable/ic_camera_flash.png +++ /dev/null diff --git a/res/drawable/ic_camera_indicator_flash_auto.png b/res/drawable/ic_camera_indicator_flash_auto.png Binary files differdeleted file mode 100755 index a2809f1..0000000 --- a/res/drawable/ic_camera_indicator_flash_auto.png +++ /dev/null diff --git a/res/drawable/ic_camera_indicator_flash_off.png b/res/drawable/ic_camera_indicator_flash_off.png Binary files differdeleted file mode 100755 index 9a28b10..0000000 --- a/res/drawable/ic_camera_indicator_flash_off.png +++ /dev/null diff --git a/res/drawable/ic_camera_indicator_flash_on.png b/res/drawable/ic_camera_indicator_flash_on.png Binary files differdeleted file mode 100755 index 01fb9a4..0000000 --- a/res/drawable/ic_camera_indicator_flash_on.png +++ /dev/null diff --git a/res/drawable/ic_camera_indicator_memory.9.png b/res/drawable/ic_camera_indicator_memory.9.png Binary files differdeleted file mode 100644 index ba4e1f5..0000000 --- a/res/drawable/ic_camera_indicator_memory.9.png +++ /dev/null diff --git a/res/drawable/ic_camera_indicator_photo.png b/res/drawable/ic_camera_indicator_photo.png Binary files differindex ea981f4..3b0483b 100755..100644 --- a/res/drawable/ic_camera_indicator_photo.png +++ b/res/drawable/ic_camera_indicator_photo.png diff --git a/res/drawable/ic_camera_indicator_video.png b/res/drawable/ic_camera_indicator_video.png Binary files differindex eaaa9e4..a4cb8d0 100755..100644 --- a/res/drawable/ic_camera_indicator_video.png +++ b/res/drawable/ic_camera_indicator_video.png diff --git a/res/drawable/ic_camera_select_image.png b/res/drawable/ic_camera_select_image.png Binary files differdeleted file mode 100755 index 848123c..0000000 --- a/res/drawable/ic_camera_select_image.png +++ /dev/null diff --git a/res/drawable/ic_camera_select_video.png b/res/drawable/ic_camera_select_video.png Binary files differdeleted file mode 100755 index 8d63517..0000000 --- a/res/drawable/ic_camera_select_video.png +++ /dev/null diff --git a/res/drawable/ic_gallery_back_to_entry.png b/res/drawable/ic_gallery_back_to_entry.png Binary files differdeleted file mode 100755 index ad297ae..0000000 --- a/res/drawable/ic_gallery_back_to_entry.png +++ /dev/null diff --git a/res/drawable/ic_gallery_empty.png b/res/drawable/ic_gallery_empty.png Binary files differindex b140f84..b140f84 100755..100644 --- a/res/drawable/ic_gallery_empty.png +++ b/res/drawable/ic_gallery_empty.png diff --git a/res/drawable/ic_gallery_finish.png b/res/drawable/ic_gallery_finish.png Binary files differdeleted file mode 100755 index 550e86a..0000000 --- a/res/drawable/ic_gallery_finish.png +++ /dev/null diff --git a/res/drawable/ic_gallery_picasa_upload.png b/res/drawable/ic_gallery_picasa_upload.png Binary files differdeleted file mode 100755 index 211f93e..0000000 --- a/res/drawable/ic_gallery_picasa_upload.png +++ /dev/null diff --git a/res/drawable/ic_gallery_upload_to.png b/res/drawable/ic_gallery_upload_to.png Binary files differdeleted file mode 100755 index b8a338f..0000000 --- a/res/drawable/ic_gallery_upload_to.png +++ /dev/null diff --git a/res/drawable/ic_gallery_video_overlay.png b/res/drawable/ic_gallery_video_overlay.png Binary files differnew file mode 100644 index 0000000..ae263a7 --- /dev/null +++ b/res/drawable/ic_gallery_video_overlay.png diff --git a/res/drawable/ic_gallery_youtube_upload.png b/res/drawable/ic_gallery_youtube_upload.png Binary files differdeleted file mode 100755 index 21c3820..0000000 --- a/res/drawable/ic_gallery_youtube_upload.png +++ /dev/null diff --git a/res/drawable/ic_launcher_camera.png b/res/drawable/ic_launcher_camera.png Binary files differindex 9bb4c61..9bb4c61 100755..100644 --- a/res/drawable/ic_launcher_camera.png +++ b/res/drawable/ic_launcher_camera.png diff --git a/res/drawable/ic_launcher_gallery.png b/res/drawable/ic_launcher_gallery.png Binary files differindex 965fb71..965fb71 100755..100644 --- a/res/drawable/ic_launcher_gallery.png +++ b/res/drawable/ic_launcher_gallery.png diff --git a/res/drawable/ic_menu_camera.png b/res/drawable/ic_menu_camera.png Binary files differnew file mode 100644 index 0000000..cdf7ca3 --- /dev/null +++ b/res/drawable/ic_menu_camera.png diff --git a/res/drawable/ic_menu_camera_play.xml b/res/drawable/ic_menu_camera_play.xml new file mode 100644 index 0000000..47c3db9 --- /dev/null +++ b/res/drawable/ic_menu_camera_play.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* grid_background.xml +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@drawable/ic_btn_actionmenu_play_pressed" /> + <item android:state_focused="true" android:drawable="@drawable/ic_btn_actionmenu_play_selected" /> + <item android:drawable="@drawable/ic_btn_actionmenu_play_default" /> +</selector> diff --git a/res/drawable/ic_menu_camera_video_view.png b/res/drawable/ic_menu_camera_video_view.png Binary files differnew file mode 100644 index 0000000..f7e52c2 --- /dev/null +++ b/res/drawable/ic_menu_camera_video_view.png diff --git a/res/drawable/ic_menu_delete.xml b/res/drawable/ic_menu_delete.xml new file mode 100644 index 0000000..14ab64f --- /dev/null +++ b/res/drawable/ic_menu_delete.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* grid_background.xml +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@drawable/ic_btn_actionmenu_delete_pressed" /> + <item android:state_focused="true" android:drawable="@drawable/ic_btn_actionmenu_delete_selected" /> + <item android:drawable="@drawable/ic_btn_actionmenu_delete_default" /> +</selector> diff --git a/res/drawable/ic_menu_set_as.xml b/res/drawable/ic_menu_set_as.xml new file mode 100644 index 0000000..7327ce0 --- /dev/null +++ b/res/drawable/ic_menu_set_as.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* grid_background.xml +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@drawable/ic_btn_actionmenu_set_as_pressed" /> + <item android:state_focused="true" android:drawable="@drawable/ic_btn_actionmenu_set_as_selected" /> + <item android:drawable="@drawable/ic_btn_actionmenu_set_as_default" /> +</selector> diff --git a/res/drawable/ic_menu_share.xml b/res/drawable/ic_menu_share.xml new file mode 100644 index 0000000..edd8b62 --- /dev/null +++ b/res/drawable/ic_menu_share.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* grid_background.xml +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@drawable/ic_btn_actionmenu_share_pressed" /> + <item android:state_focused="true" android:drawable="@drawable/ic_btn_actionmenu_share_selected" /> + <item android:drawable="@drawable/ic_btn_actionmenu_share_default" /> +</selector> diff --git a/res/drawable/ic_missing_thumbnail_picture.png b/res/drawable/ic_missing_thumbnail_picture.png Binary files differnew file mode 100644 index 0000000..ebab487 --- /dev/null +++ b/res/drawable/ic_missing_thumbnail_picture.png diff --git a/res/drawable/ic_missing_thumbnail_video.png b/res/drawable/ic_missing_thumbnail_video.png Binary files differnew file mode 100644 index 0000000..b44d821 --- /dev/null +++ b/res/drawable/ic_missing_thumbnail_video.png diff --git a/res/drawable/ic_video_empty.png b/res/drawable/ic_video_empty.png Binary files differdeleted file mode 100755 index 1209f86..0000000 --- a/res/drawable/ic_video_empty.png +++ /dev/null diff --git a/res/drawable/image_border_bg_focus_blue9.png b/res/drawable/image_border_bg_focus_blue9.png Binary files differdeleted file mode 100644 index 89debd2..0000000 --- a/res/drawable/image_border_bg_focus_blue9.png +++ /dev/null diff --git a/res/drawable/image_border_bg_normal9.png b/res/drawable/image_border_bg_normal9.png Binary files differdeleted file mode 100644 index 18e3607..0000000 --- a/res/drawable/image_border_bg_normal9.png +++ /dev/null diff --git a/res/drawable/image_border_bg_pressed_blue9.png b/res/drawable/image_border_bg_pressed_blue9.png Binary files differdeleted file mode 100644 index 94fa74f..0000000 --- a/res/drawable/image_border_bg_pressed_blue9.png +++ /dev/null diff --git a/res/drawable/play_video.png b/res/drawable/play_video.png Binary files differdeleted file mode 100644 index 0c10731..0000000 --- a/res/drawable/play_video.png +++ /dev/null diff --git a/res/drawable/popup_camera_toast.9.png b/res/drawable/popup_camera_toast.9.png Binary files differindex c1f0c1f..c1f0c1f 100755..100644 --- a/res/drawable/popup_camera_toast.9.png +++ b/res/drawable/popup_camera_toast.9.png diff --git a/res/layout/camera.xml b/res/layout/camera.xml index 1bd5a14..40b579b 100644 --- a/res/layout/camera.xml +++ b/res/layout/camera.xml @@ -19,7 +19,7 @@ android:layout_height="fill_parent" android:orientation="horizontal"> - <SurfaceView + <com.android.camera.VideoPreview android:id="@+id/camera_preview" android:layout_width="fill_parent" android:layout_height="fill_parent" @@ -27,10 +27,10 @@ /> <ImageView - android:id="@+id/blackout" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:visibility="invisible" + android:id="@+id/blackout" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:visibility="invisible" /> <ImageView @@ -42,77 +42,68 @@ android:layout_alignParentTop="true" android:layout_marginRight="6dip" android:layout_marginTop="6dip" + android:scaleType="center" + android:visibility="gone"/> + + <ImageView + android:id="@+id/mode_indicator" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/ic_camera_indicator_photo" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:layout_marginRight="5dip" + android:layout_marginTop="15dip" android:scaleType="center"/> <TextView - android:id="@+id/hint_toast" - android:layout_alignParentRight="true" - android:layout_alignParentTop="true" - android:background="@drawable/popup_camera_toast" + android:id="@+id/hint_toast" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:background="@drawable/popup_camera_toast" android:layout_width="200dip" android:layout_height="wrap_content" android:gravity="center" android:text="@string/camera_button_hint" - android:textSize="18sp" - android:visibility="visible"/> + android:textSize="18sp"/> - <AbsoluteLayout - android:background="#CC666666" - android:visibility="invisible" - android:id="@+id/post_picture_panel" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_centerHorizontal="true" + <LinearLayout + android:visibility="gone" + android:id="@+id/post_picture_panel" android:layout_alignParentBottom="true" - android:layout_alignParentRight="false"> - <View android:layout_width="fill_parent" - android:layout_height="1dip" - android:background="@android:drawable/divider_horizontal_dark" /> - <LinearLayout - android:paddingLeft="7dip" - android:paddingRight="7dip" - android:paddingTop="6dip" - android:paddingBottom="6dip" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:background="#00000000" - android:orientation="horizontal"> - <Button - android:id="@+id/save" - android:textSize="18sp" - android:drawableTop="@android:drawable/ic_menu_save" - android:layout_width="112dip" - android:layout_height="wrap_content" - android:text="@string/camera_keep" - /> - <View android:layout_width="6dip" android:layout_height="6dip" /> - <Button - android:id="@+id/setas" - android:textSize="18sp" - android:drawableTop="@android:drawable/ic_menu_set_as" - android:layout_width="112dip" - android:layout_height="wrap_content" - android:text="@string/camera_set" - /> - <View android:layout_width="6dip" android:layout_height="6dip" /> - <Button - android:id="@+id/share" - android:textSize="18sp" - android:drawableTop="@android:drawable/ic_menu_share" - android:layout_width="112dip" - android:layout_height="wrap_content" - android:text="@string/camera_share" - /> - <View android:layout_width="6dip" android:layout_height="6dip" /> - <Button - android:id="@+id/discard" - android:textSize="18sp" - android:drawableTop="@android:drawable/ic_menu_delete" - android:layout_width="112dip" - android:layout_height="wrap_content" - android:text="@string/camera_toss" - /> - </LinearLayout> - </AbsoluteLayout> + android:layout_alignParentRight="true" + android:paddingLeft="7dip" + android:paddingRight="7dip" + android:paddingTop="6dip" + android:paddingBottom="6dip" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal"> + + <com.android.camera.ActionMenuButton + android:id="@+id/setas" + android:drawableTop="@drawable/ic_menu_set_as" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/camera_set" + style="@style/OnscreenActionIcon" + /> + <com.android.camera.ActionMenuButton + android:id="@+id/share" + android:drawableTop="@drawable/ic_menu_share" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/camera_share" + style="@style/OnscreenActionIcon" + /> + <com.android.camera.ActionMenuButton + android:id="@+id/discard" + android:drawableTop="@drawable/ic_menu_delete" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:text="@string/camera_toss" + style="@style/OnscreenActionIcon" + /> + </LinearLayout> </RelativeLayout> diff --git a/res/layout/gallerypicker.xml b/res/layout/gallerypicker.xml index 42dbc7e..fd6f40a 100644 --- a/res/layout/gallerypicker.xml +++ b/res/layout/gallerypicker.xml @@ -24,8 +24,8 @@ android:layout_height="fill_parent" android:paddingTop="2dip" android:numColumns="auto_fit" - android:columnWidth="160dp" - android:stretchMode="spacingWidth" + android:columnWidth="148dp" + android:stretchMode="spacingWidthUniform" android:drawSelectorOnTop="false" /> </AbsoluteLayout> diff --git a/res/layout/gallerysettings.xml b/res/layout/gallerysettings.xml deleted file mode 100644 index b513813..0000000 --- a/res/layout/gallerysettings.xml +++ /dev/null @@ -1,63 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/scroll_view" - android:orientation="vertical" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:background="#1C1C1C"> - - <LinearLayout android:id="@+id/layout" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:paddingTop="30dip" - android:orientation="vertical"> - - <LinearLayout android:orientation="horizontal" - android:layout_width="fill_parent" - android:layout_height="50dip"> - <TextView - android:layout_height="wrap_content" - android:textColor="#FFFFFFFF" - android:layout_width="0dip" - android:textSize="10sp" - android:layout_weight="50" - android:gravity="right" - android:singleLine="false" - android:text="@string/gallerysettings_duration" /> - - <Spinner android:id="@+id/slide_show_speed" - android:layout_width="0dip" - android:layout_weight="50" - android:layout_marginRight="10dip" - android:layout_marginLeft="20dip" - android:layout_height="wrap_content"> - </Spinner> - - </LinearLayout> - - <Button android:id="@+id/done" - android:layout_width="80dip" - android:layout_height="wrap_content" - android:layout_marginTop="70dip" - android:layout_marginRight="10dip" - android:gravity="bottom" - android:layout_gravity="right" - android:text="@string/camerasettings_done" /> - - </LinearLayout> -</ScrollView> - diff --git a/res/layout/image_gallery.xml b/res/layout/image_gallery.xml deleted file mode 100644 index d4b9db6..0000000 --- a/res/layout/image_gallery.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2007 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/root" - android:layout_width="fill_parent" - android:layout_height="fill_parent"> - - <GridView - android:id="@+id/grid" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:padding="12dp" - android:verticalSpacing="8dp" - android:horizontalSpacing="8dp" - android:stretchMode="spacingWidth" - android:gravity="center" - android:drawSelectorOnTop="false" - android:listSelector="@drawable/grid_background" - android:numColumns="auto_fit" - android:columnWidth="64dp" - android:fadingEdge="none" - /> - - <TextView android:id="@+id/NoImageView" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:text="@string/image_gallery_NoImageView_text" - android:textColor="#FFFFFFFF" - /> -</AbsoluteLayout> - diff --git a/res/layout/movie_view.xml b/res/layout/movie_view.xml new file mode 100644 index 0000000..6344d8b --- /dev/null +++ b/res/layout/movie_view.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2007 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + <VideoView + android:id="@+id/surface_view" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_centerInParent="true" + /> + + <LinearLayout android:id="@+id/progress_indicator" + android:orientation="vertical" + android:layout_centerInParent="true" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + + <ProgressBar android:id="@android:id/progress" + style="?android:attr/progressBarStyleLarge" + android:layout_gravity="center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <TextView android:paddingTop="5dip" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:text="@string/loading_video" android:textSize="14sp" + android:textColor="#ffffffff" /> + </LinearLayout> + +</RelativeLayout> diff --git a/res/layout/video_camera.xml b/res/layout/video_camera.xml new file mode 100644 index 0000000..bd84d3d --- /dev/null +++ b/res/layout/video_camera.xml @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2007 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="horizontal"> + + <com.android.camera.VideoPreview + android:id="@+id/camera_preview" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_centerInParent="true" + /> + + <ImageView + android:id="@+id/video_frame" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:visibility="gone" + /> + + <ImageView + android:id="@+id/blackout" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:visibility="invisible" + /> + + <ImageView + android:id="@+id/mode_indicator" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/ic_camera_indicator_video" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:layout_marginRight="5dip" + android:layout_marginTop="15dip" + android:scaleType="center"/> + + <ImageView + android:id="@+id/recording_indicator" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/ic_camera_bar_indicator_record" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:layout_marginRight="15dip" + android:layout_marginTop="15dip" + android:scaleType="center" + android:visibility="gone"/> + + <TextView + android:id="@+id/recording_time" + android:layout_width="90dip" + android:layout_height="wrap_content" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:layout_marginRight="55dip" + android:layout_marginTop="11dip" + android:paddingRight="2dip" + android:shadowColor="#c0000000" + android:shadowDx="1" + android:shadowDy="1" + android:shadowRadius="1" + android:gravity="right" + android:textColor="#ffffffff" + android:textSize="20dip" + android:textStyle="bold" + android:visibility="gone"/> + + <TextView + android:id="@+id/hint_toast" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:background="@drawable/popup_camera_toast" + android:layout_width="200dip" + android:layout_height="wrap_content" + android:gravity="center" + android:text="@string/video_camera_button_hint" + android:textSize="18sp"/> + + <LinearLayout + android:visibility="gone" + android:id="@+id/post_picture_panel" + android:layout_alignParentBottom="true" + android:layout_alignParentRight="true" + android:paddingLeft="7dip" + android:paddingRight="7dip" + android:paddingTop="6dip" + android:paddingBottom="6dip" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal"> + + <com.android.camera.ActionMenuButton + android:id="@+id/play" + android:drawableTop="@drawable/ic_menu_camera_play" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/camera_play" + style="@style/OnscreenActionIcon" + /> + <com.android.camera.ActionMenuButton + android:id="@+id/share" + android:drawableTop="@drawable/ic_menu_share" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/camera_share" + style="@style/OnscreenActionIcon" + /> + <com.android.camera.ActionMenuButton + android:id="@+id/discard" + android:drawableTop="@drawable/ic_menu_delete" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:text="@string/camera_toss" + style="@style/OnscreenActionIcon" + /> + </LinearLayout> +</RelativeLayout> + diff --git a/res/layout/viewvideo.xml b/res/layout/viewvideo.xml deleted file mode 100644 index 49af24b..0000000 --- a/res/layout/viewvideo.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:background="#FF000000" - > - - <VideoView android:id="@+id/video" - android:layout_centerInParent="true" - android:layout_width="fill_parent" - android:layout_height="fill_parent" /> -</RelativeLayout> - diff --git a/res/layout/youtube_upload_info.xml b/res/layout/youtube_upload_info.xml deleted file mode 100644 index fa62a77..0000000 --- a/res/layout/youtube_upload_info.xml +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="wrap_content"> -> - <LinearLayout - android:orientation="vertical" - android:layout_width="fill_parent" - android:layout_height="wrap_content"> - - - <TextView android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/upload_info_title" - android:textSize="12sp" /> - - <EditText android:id="@+id/video_title" - android:layout_width="fill_parent" - android:layout_height="wrap_content" android:autoText="true" - android:capitalize="words" android:textSize="12sp" /> - - <TextView android:layout_width="wrap_content" - android:layout_height="wrap_content" android:paddingTop="10dip" - android:text="@string/details_category_label" - android:textSize="12sp" /> - - <Spinner android:id="@+id/category" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:drawSelectorOnTop="false" android:textSize="12sp" /> - - <TextView android:id="@+id/tags_label" - android:layout_width="fill_parent" android:paddingTop="10dip" - android:layout_height="wrap_content" - android:text="@string/upload_info_tags" android:textSize="12sp" /> - - <EditText android:id="@+id/video_tags" - android:layout_width="fill_parent" - android:layout_height="wrap_content" android:textSize="12sp" - android:autoText="false" android:capitalize="none" /> - - <TextView android:layout_width="fill_parent" - android:paddingTop="10dip" android:layout_height="wrap_content" - android:text="@string/upload_info_description" - android:textSize="12sp" /> - - <EditText android:id="@+id/video_description" - android:layout_width="fill_parent" - android:layout_height="wrap_content" android:autoText="true" - android:capitalize="sentences" android:textSize="12sp" /> - - <LinearLayout android:orientation="horizontal" - android:layout_width="fill_parent" android:paddingTop="10dip" - android:layout_height="wrap_content"> - - <CheckBox android:id="@+id/public_or_private" - android:layout_width="0dip" android:layout_weight="1" - android:layout_height="wrap_content" - android:text="@string/upload_info_private" /> - - <Button android:id="@+id/do_upload" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/upload_info_upload" /> - </LinearLayout> -</LinearLayout> -</ScrollView> diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index de897d6..960787e 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -1,206 +1,141 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="UTF-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="autocrop_before_query">Automaticky nejprve oříznout?</string> - <string name="autocrop_no">Ano</string> - <string name="autocrop_yes">Ano</string> - <string name="best_res">Vysoká</string> - <string name="camera_NoStorageView_text">Před použitím fotoaparátu vložte kartu SD</string> - <string name="camera_ZoomIn_text">Přiblížit</string> - <string name="camera_ZoomOut_text">Oddálit</string> - <string name="camera_button_hint">Stisknutím tlačítka Sejmout pořídíte snímek</string> - <string name="camera_crop">Automaticky oříznout</string> - <string name="camera_done">Nový obrázek</string> - <string name="camera_flash_auto">Automatický blesk</string> - <string name="camera_flash_off">Blesk VYPNUTÝ</string> - <string name="camera_flash_on">Blesk ZAPNUTÝ</string> - <string name="camera_flash_setting">Nastavení blesku</string> - <string name="camera_gallery_photos_text">Obrázky</string> - <string name="camera_gallery_videos_text">Videa</string> - <string name="camera_keeping">Uchovávání\u2026</string> - <string name="camera_label">Fotoaparát</string> - <string name="camera_mode_text">Režim</string> - <string name="camera_movie_record_counter_text">01:30:00</string> - <string name="camera_playvideo">Přehrát</string> - <string name="camera_record_text">Zaznamenat</string> - <string name="camera_selectphoto">Vybrat tento obrázek</string> - <string name="camera_selectvideo">Vybrat video</string> - <string name="camera_set">Nastavit jako\u2026</string> - <string name="camera_setas_contact">Obrázek kontaktu</string> - <string name="camera_setas_myfave">myFaves</string> - <string name="camera_setas_wallpaper">Tapeta</string> - <string name="camera_share">Sdílet</string> - <string name="camera_shareby_email">E-mail</string> - <string name="camera_shareby_mms">MMS</string> - <string name="camera_shareby_picasa">Picasaweb</string> - <string name="camera_shareby_picasa_all">Picasaweb (všechny obrázky)</string> - <string name="camera_switch_to_photo">Přepnout na obrázek</string> - <string name="camera_switch_to_video">Přepnout na video</string> - <string name="camera_takenewphoto">Pořídit nový snímek</string> - <string name="camera_takenewvideo">Pořídit nové video</string> - <string name="camera_toss">Odstranit</string> - <string name="camera_tossing">Odstraňování\u2026</string> - <string name="camera_zoom_1_text">Přiblížit 1,3x</string> - <string name="camera_zoom_2_text">Přiblížit 2x</string> - <string name="camera_zoom_3_text">Přiblížit 4x</string> - <string name="camera_zoom_normal_text">1x</string> - <string name="camerasettings">Nastavení</string> - <string name="camerasettings_autoupload_label">Automaticky odeslat obrázky na web</string> - <string name="camerasettings_done">Hotovo</string> - <string name="camerasettings_duration_label">Doba trvání:</string> - <string name="camerasettings_image_quality_label">Kvalita obrázku:</string> - <string name="camerasettings_no">Ne</string> - <string name="camerasettings_off">Vypnuto</string> - <string name="camerasettings_on">Zapnuto</string> - <string name="camerasettings_play_click_sound_label">Zvuk závěrky</string> - <string name="camerasettings_preferred_view_label">Upřednostňované zobrazení:</string> - <string name="camerasettings_resolution_label">Rozlišení:</string> - <string name="camerasettings_test2_label">test2:</string> - <string name="camerasettings_test3_label">test3:</string> - <string name="camerasettings_test4_label">test4:</string> - <string name="camerasettings_use_sd_card_label">Uložit obrázky na kartu SD</string> - <string name="camerasettings_yes">Ano</string> - <string name="cancel">Storno</string> - <string name="context_menu_header">Možnosti obrázků</string> - <string name="crop_discard_text">Zrušit</string> - <string name="crop_help">Přidržením ALT změňte velikost</string> - <string name="crop_label">Oříznout obrázek</string> - <string name="crop_save_text">Uložit</string> - <string name="delete">Odstranit</string> - <string name="details">Podrobnosti</string> - <string name="details_category_label">Kategorie:</string> - <string name="details_date_taken">Datum pořízení:</string> - <string name="details_description_label">Popis:</string> - <string name="details_description_text">testpopis</string> - <string name="details_file_size">Velikost souboru:</string> - <string name="details_image_resolution">Rozlišení:</string> - <string name="details_language_label">Jazyk:</string> - <string name="details_panel_title">Podrobnosti</string> - <string name="details_privateView_text">Soukromé</string> - <string name="details_publicView_text">Veřejné</string> - <string name="details_save_text">Uložit</string> - <string name="details_tags_label">Značky:</string> - <string name="details_tags_text">monstrum</string> - <string name="details_title_label">Název:</string> - <string name="details_title_text">myvideo</string> - <string name="details_uploaded_text">Úspěšně odesláno</string> - <string name="edit">Upravit</string> - <string name="error_label">Chyba</string> - <string name="gallery_label">Fotografie a videoklipy</string> - <string name="gallery_large">Velký</string> - <string name="gallery_picker_label">Alba</string> - <string name="gallery_small">Malá</string> - <string name="gallerysettings_duration">Doba zobrazení každého snímku v prezentaci</string> - <string name="gallerysettings_speed1">1 sekunda</string> - <string name="gallerysettings_speed2">3 sekundy</string> - <string name="gallerysettings_speed3">5 sekund</string> - <string name="high">Vysoká</string> - <string name="image_gallery_NoImageView_text">Žádné obrázky</string> - <string name="image_gallery_picker_images">Obrázky</string> - <string name="image_gallery_picker_videos">Videa</string> - <string name="low">Nízká</string> - <string name="low_res">Nízká</string> - <string name="med">Střední</string> - <string name="medium_res">Střední</string> - <string name="multiface_crop_help">Vyberte obličej, kterým chcete začít</string> - <string name="no">Ne</string> - <string name="no_images">Album je prázdné</string> - <string name="no_storage">Před použitím fotoaparátu vložte kartu SD</string> - <string name="no_way_to_share_image">Obrázek nelze uložit</string> - <string name="no_way_to_share_video">Toto video nelze sdílet</string> - <string name="not_enough_space">Paměťová karta je plná</string> - <string name="ok">OK</string> - <string name="photos_gallery_title">Obrázky</string> - <string name="picasa_upload_label">Odeslání na web Picasa</string> - <string name="pick_photos_gallery_title">Vybrat obrázek</string> - <string name="pick_videos_gallery_title">Vybrat video</string> - <string name="pref_camera_autoupload_summary">Výběrem nastavíte automatické odesílání obrázků na web Picasa</string> - <string name="pref_camera_autoupload_title">Automaticky odesílat obrázky</string> - <string name="pref_camera_category">Fotoaparát</string> - <string name="pref_camera_recordlocation_summary">Výběrem nastavíte automatický záznam polohy do obrázků</string> - <string name="pref_camera_recordlocation_title">Zaznamenávat polohu do obrázků</string> - <string name="pref_camera_upload_albumname_dialogtitle">Název alba Picasa</string> - <string name="pref_camera_upload_albumname_summary">Zadejte název cílového alba pro obrázky</string> - <string name="pref_camera_upload_albumname_title">Název alba Picasa</string> - <string name="pref_gallery_category">Zobrazení alba obrázků</string> - <string name="pref_gallery_size_dialogtitle">Velikost obrázku</string> - <string name="pref_gallery_size_summary">Vyberte zobrazovanou velikost obrázků v albu</string> - <string name="pref_gallery_size_title">Velikost obrázku</string> - <string name="pref_gallery_slideshow_interval_dialogtitle">Interval prezentace</string> - <string name="pref_gallery_slideshow_interval_summary">Vyberte dobu zobrazení každého snímku v prezentaci</string> - <string name="pref_gallery_slideshow_interval_title">Interval prezentace</string> - <string name="pref_gallery_slideshow_repeat_dialogtitle">Opakovat prezentaci?</string> - <string name="pref_gallery_slideshow_repeat_summary">Výběrem přehrajete prezentaci vícekrát</string> - <string name="pref_gallery_slideshow_repeat_title">Opakovat prezentaci</string> - <string name="pref_gallery_slideshow_shuffle_dialogtitle">Náhodné zobrazování obrázků?</string> - <string name="pref_gallery_slideshow_shuffle_summary">Výběrem nastavíte zobrazování obrázků v náhodném pořadí</string> - <string name="pref_gallery_slideshow_shuffle_title">Náhodné zobrazování snímků</string> - <string name="pref_gallery_slideshow_transition_dialogtitle">Přechod prezentace</string> - <string name="pref_gallery_slideshow_transition_summary">Vyberte efekt, který bude použit při přechodu mezi snímky</string> - <string name="pref_gallery_slideshow_transition_title">Přechod prezentace</string> - <string name="pref_gallery_sort_dialogtitle">Řazení obrázků</string> - <string name="pref_gallery_sort_summary">Vyberte pořadí řazení obrázků v albu</string> - <string name="pref_gallery_sort_title">Řazení obrázků</string> - <string name="pref_slideshow_category">Prezentace</string> - <string name="preferences_label">Nastavení fotoaparátu</string> - <string name="preview">Náhled</string> - <string name="record">Zaznamenat</string> - <string name="rotate">Otočit</string> - <string name="rotate_left">Otočit vlevo</string> - <string name="rotate_right">Otočit vpravo</string> - <string name="runningFaceDetection">Počkejte prosím\u2026</string> - <string name="save">Uložit</string> - <string name="savingImage">Ukládání obrázku</string> - <string name="sec1">1 s</string> - <string name="sec2">2 s</string> - <string name="sec3">3 s</string> - <string name="sec4">4 s</string> - <string name="sec5">5 s</string> - <string name="sendImage">Sdílet tento obrázek prostřednictvím</string> - <string name="sendVideo">Sdílet toto video prostřednictvím</string> - <string name="set_wallpaper">Nastavit jako tapetu</string> - <string name="settings">Nastavení</string> - <string name="share_youtube">YouTube</string> - <string name="slide_show">Prezentace</string> - <string name="stop">Zastavit</string> - <string name="testexif">Test Exif</string> - <string name="upload">Odeslat</string> - <string name="upload_all">Odeslat vše</string> - <string name="upload_default_category_text">Zábava</string> - <string name="upload_default_description_text">místo pro popis</string> - <string name="upload_default_tags_text">video</string> - <string name="upload_dialog_title">Odeslat na web YouTube - zadejte podrobnosti o videoklipu</string> - <string name="upload_info_category">Kategorie:</string> - <string name="upload_info_description">Popis:</string> - <string name="upload_info_private">Není-li zaškrtnuto, uvidíte film jen vy</string> - <string name="upload_info_tags">Značky:</string> - <string name="upload_info_title">Název:</string> - <string name="upload_info_upload">Odeslat</string> - <string name="uploadingNPhotos">Odesílání <xliff:g id="counter">%d</xliff:g> obrázků</string> - <string name="uploadingNVideos">Odesílání <xliff:g id="counter">%d</xliff:g> videoklipů</string> - <string name="uploading_photos">Odesílání obrázků</string> - <string name="uploading_photos_2">Odesílání obrázků</string> - <string name="uploading_videos">Odesílání videoklipů</string> - <string name="uploading_videos_2">Odesílání videoklipů</string> - <string name="video_gallery_NoImageView_text">Žádná videa</string> - <string name="video_play">Přehrát</string> - <string name="videos_gallery_title">Videa</string> - <string name="view_label">Zobrazit obrázek</string> - <string name="view_video_label">Zobrazit video</string> - <string name="viewimage_comments_label_text">Komentáře</string> - <string name="viewimage_datetaken_label_text">Datum</string> - <string name="viewimage_digitalzoom_label_text">Digitální zoom</string> - <string name="viewimage_flash_label_text">Použitý blesk</string> - <string name="viewimage_gps_latitude_label_text">Zeměpisná šířka GPS</string> - <string name="viewimage_gps_longitude_label_text">Zeměpisná délka GPS</string> - <string name="viewimage_make_label_text">Vytvořit</string> - <string name="viewimage_model_label_text">Od</string> - <string name="viewimage_orientation_label_text">Orientace</string> - <string name="viewimage_res_label_text">Rozlišení</string> - <string name="viewimage_status_text">přiblížení tlačítkem Enter nebo mezerníkem</string> - <string name="wait">Počkejte prosím\u2026</string> - <string name="wallpaper">Nastavení tapety, počkejte prosím\u2026</string> - <string name="yes">Ano</string> - <string name="youtube_upload_label">Odeslání na web YouTube</string> - <string name="zoom">Lupa</string> + <!-- no translation found for all_images (7177582020160054334) --> + <skip /> + <string name="camera_label">"Fotoaparát"</string> + <string name="gallery_picker_label">"Alba"</string> + <!-- no translation found for gallery_camera_bucket_name (8410686962557494439) --> + <skip /> + <!-- no translation found for switch_to_video_lable (1350915759804484157) --> + <skip /> + <!-- no translation found for switch_to_camera_lable (1823306882227066007) --> + <skip /> + <string name="crop_label">"Oříznout obrázek"</string> + <string name="view_label">"Zobrazit obrázek"</string> + <string name="preferences_label">"Nastavení fotoaparátu"</string> + <string name="wait">"Počkejte prosím…"</string> + <string name="no_storage">"Před použitím fotoaparátu vložte kartu SD"</string> + <string name="not_enough_space">"Paměťová karta je plná"</string> + <string name="wallpaper">"Nastavení tapety, počkejte prosím…"</string> + <string name="savingImage">"Ukládání obrázku"</string> + <string name="runningFaceDetection">"Počkejte prosím…"</string> + <!-- no translation found for flip_orientation (2488284515852888409) --> + <skip /> + <string name="settings">"Nastavení"</string> + <!-- no translation found for view (4639715088471766970) --> + <skip /> + <string name="details">"Podrobnosti"</string> + <string name="rotate">"Otočit"</string> + <string name="rotate_left">"Otočit vlevo"</string> + <string name="rotate_right">"Otočit vpravo"</string> + <string name="slide_show">"Prezentace"</string> + <string name="crop_save_text">"Uložit"</string> + <string name="crop_discard_text">"Zrušit"</string> + <!-- no translation found for camera_keep (4046418310305917657) --> + <skip /> + <!-- no translation found for confirm_delete_title (8942471980646707642) --> + <skip /> + <!-- no translation found for confirm_delete_message (6944545476499253074) --> + <skip /> + <string name="camera_toss">"Odstranit"</string> + <string name="camera_share">"Sdílet"</string> + <string name="camera_set">"Nastavit jako…"</string> + <!-- no translation found for camera_play (6388821030721929966) --> + <skip /> + <string name="camera_crop">"Automaticky oříznout"</string> + <string name="camera_done">"Nový obrázek"</string> + <string name="camera_tossing">"Odstraňování…"</string> + <string name="no_way_to_share_image">"Obrázek nelze uložit"</string> + <string name="no_way_to_share_video">"Toto video nelze sdílet"</string> + <string name="camera_gallery_photos_text">"Obrázky"</string> + <!-- no translation found for camera_pick_wallpaper (2052155470431167023) --> + <skip /> + <string name="camera_setas_wallpaper">"Tapeta"</string> + <!-- no translation found for camera_setas_wallpaper_drm (787462863614664620) --> + <skip /> + <string name="camera_selectphoto">"Vybrat tento obrázek"</string> + <string name="camera_takenewphoto">"Pořídit nový snímek"</string> + <string name="pref_gallery_category">"Zobrazení alba obrázků"</string> + <string name="pref_slideshow_category">"Prezentace"</string> + <!-- no translation found for pref_camera_general_settings_category (1720434593482716214) --> + <skip /> + <string name="pref_gallery_size_title">"Velikost obrázku"</string> + <string name="pref_gallery_size_summary">"Vyberte zobrazovanou velikost obrázků v albu"</string> + <string name="pref_gallery_size_dialogtitle">"Velikost obrázku"</string> + <!-- no translation found for pref_gallery_size_choices:0 (3341375119334343613) --> + <!-- no translation found for pref_gallery_size_choices:1 (979877976111629768) --> + <string name="pref_gallery_sort_title">"Řazení obrázků"</string> + <string name="pref_gallery_sort_summary">"Vyberte pořadí řazení obrázků v albu"</string> + <string name="pref_gallery_sort_dialogtitle">"Řazení obrázků"</string> + <!-- no translation found for pref_gallery_sort_choices:0 (2009184885742004467) --> + <!-- no translation found for pref_gallery_sort_choices:1 (7253524441061782381) --> + <string name="pref_gallery_slideshow_interval_title">"Interval prezentace"</string> + <string name="pref_gallery_slideshow_interval_summary">"Vyberte dobu zobrazení každého snímku v prezentaci"</string> + <string name="pref_gallery_slideshow_interval_dialogtitle">"Interval prezentace"</string> + <!-- no translation found for pref_gallery_slideshow_interval_choices:0 (3293392256331071955) --> + <!-- no translation found for pref_gallery_slideshow_interval_choices:1 (6762163459545768561) --> + <!-- no translation found for pref_gallery_slideshow_interval_choices:2 (3999753648109312132) --> + <string name="pref_gallery_slideshow_transition_title">"Přechod prezentace"</string> + <string name="pref_gallery_slideshow_transition_summary">"Vyberte efekt, který bude použit při přechodu mezi snímky"</string> + <string name="pref_gallery_slideshow_transition_dialogtitle">"Přechod prezentace"</string> + <!-- no translation found for pref_gallery_slideshow_transition_choices:0 (1917959322875321005) --> + <!-- no translation found for pref_gallery_slideshow_transition_choices:1 (6508707204357284687) --> + <!-- no translation found for pref_gallery_slideshow_transition_choices:2 (5628742586795545287) --> + <!-- no translation found for pref_gallery_slideshow_transition_choices:3 (3350644769941682805) --> + <string name="pref_gallery_slideshow_repeat_title">"Opakovat prezentaci"</string> + <string name="pref_gallery_slideshow_repeat_summary">"Výběrem přehrajete prezentaci vícekrát"</string> + <string name="pref_gallery_slideshow_shuffle_title">"Náhodné zobrazování snímků"</string> + <string name="pref_gallery_slideshow_shuffle_summary">"Výběrem nastavíte zobrazování obrázků v náhodném pořadí"</string> + <string name="pref_camera_recordlocation_title">"Zaznamenávat polohu do obrázků"</string> + <string name="pref_camera_recordlocation_summary">"Výběrem nastavíte automatický záznam polohy do obrázků"</string> + <!-- no translation found for pref_camera_postpicturemenu_title (6273327212867896720) --> + <skip /> + <!-- no translation found for pref_camera_postpicturemenu_summary (7911699118676137405) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_category (7460987936373873411) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_title (2766490880685686012) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_summary (6370975165195010636) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_entry_0 (8088669040921661814) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_entry_1 (3505027746158170269) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_dialogtitle (1836746975783096625) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_category (907203894431470628) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_title (3330800694130697647) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_summary (8269173339100296159) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_dialogtitle (5759217298675791948) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_entry_0 (6259385536148037705) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_entry_1 (3178021263058501227) --> + <skip /> + <string name="camerasettings">"Nastavení"</string> + <string name="image_gallery_NoImageView_text">"Žádné obrázky"</string> + <!-- no translation found for pref_gallery_confirm_delete_title (201485251343856203) --> + <skip /> + <!-- no translation found for pref_gallery_confirm_delete_summary (7235236977784533739) --> + <skip /> + <string name="details_panel_title">"Podrobnosti"</string> + <string name="details_file_size">"Velikost souboru:"</string> + <string name="details_image_resolution">"Rozlišení:"</string> + <string name="details_date_taken">"Datum pořízení:"</string> + <string name="context_menu_header">"Možnosti obrázků"</string> + <string name="multiface_crop_help">"Vyberte obličej, kterým chcete začít"</string> + <string name="camera_button_hint">"Stisknutím tlačítka Sejmout pořídíte snímek"</string> + <string name="photos_gallery_title">"Obrázky"</string> + <string name="pick_photos_gallery_title">"Vybrat obrázek"</string> + <!-- no translation found for loading_progress_format_string (4252016560676330797) --> + <skip /> + <string name="sendImage">"Sdílet tento obrázek prostřednictvím"</string> + <!-- no translation found for setImage (6676791915351726249) --> + <skip /> + <string name="sendVideo">"Sdílet toto video prostřednictvím"</string> </resources> diff --git a/res/values-de-rDE/strings.xml b/res/values-de-rDE/strings.xml deleted file mode 100644 index 2846dea..0000000 --- a/res/values-de-rDE/strings.xml +++ /dev/null @@ -1,229 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="all_images">Alle Bilder</string> - <string name="autocrop_before_query">Vorher zuschneiden?</string> - <string name="autocrop_no">Ja</string> - <string name="autocrop_yes">Ja</string> - <string name="best_res">Hoch</string> - <string name="camera_NoStorageView_text">Setzen Sie eine SD-Karte ein, bevor Sie die Kamera verwenden.</string> - <string name="camera_ZoomIn_text">Tele-Aufnahme</string> - <string name="camera_ZoomOut_text">Weitwinkel-Aufnahme</string> - <string name="camera_button_hint">Drücken Sie auf die Aufnahmetaste, um ein Bild aufzunehmen.</string> - <string name="camera_crop">Zuschneiden</string> - <string name="camera_done">Neues Bild</string> - <string name="camera_flash_auto">Autom. Blitz</string> - <string name="camera_flash_off">Blitz AUS</string> - <string name="camera_flash_on">Blitz EIN</string> - <string name="camera_flash_setting">Blitzeinstellung</string> - <string name="camera_gallery_photos_text">Bilder</string> - <string name="camera_gallery_videos_text">Videoalbum</string> - <string name="camera_keep">Speichern</string> - <string name="camera_keeping">Beibehalten\u2026</string> - <string name="camera_label">Kamera</string> - <string name="camera_mode_text">Modus</string> - <string name="camera_movie_record_counter_text">01:30:00</string> - <string name="camera_pick_wallpaper">Bilder</string> - <string name="camera_playvideo">Abspielen</string> - <string name="camera_record_text">Aufnehmen</string> - <string name="camera_selectphoto">Dieses Bild auswählen</string> - <string name="camera_selectvideo">Dieses Video auswählen</string> - <string name="camera_set">Einstellen als</string> - <string name="camera_setas_contact">Kontaktebild </string> - <string name="camera_setas_myfave">myFaves</string> - <string name="camera_setas_wallpaper">Bildschirmhintergrund</string> - <string name="camera_setas_wallpaper_drm">Gekaufte Bilder</string> - <string name="camera_share">Freigeben</string> - <string name="camera_shareby_email">E-Mail</string> - <string name="camera_shareby_mms">MMS</string> - <string name="camera_shareby_picasa">Picasaweb</string> - <string name="camera_shareby_picasa_all">Picasaweb (alle Bilder)</string> - <string name="camera_switch_to_photo">Zu Bild wechseln</string> - <string name="camera_switch_to_video">Zu Video wechseln</string> - <string name="camera_takenewphoto">Neues Bild aufnehmen</string> - <string name="camera_takenewvideo">Neues Video aufnehmen</string> - <string name="camera_toss">Löschen</string> - <string name="camera_tossing">Löschen\u2026</string> - <string name="camera_zoom_1_text">Zoom 1,3x</string> - <string name="camera_zoom_2_text">Zoom 2x</string> - <string name="camera_zoom_3_text">Zoom 4x</string> - <string name="camera_zoom_normal_text">1x</string> - <string name="camerasettings">Einstellungen</string> - <string name="camerasettings_autoupload_label">Bilder automatisch zum Web hochladen</string> - <string name="camerasettings_done">Fertig</string> - <string name="camerasettings_duration_label">Dauer:</string> - <string name="camerasettings_image_quality_label">Bildqualität:</string> - <string name="camerasettings_no">Nein</string> - <string name="camerasettings_off">Aus</string> - <string name="camerasettings_on">Ein</string> - <string name="camerasettings_play_click_sound_label">Auslöserton</string> - <string name="camerasettings_preferred_view_label">Bevorzugte Ansicht:</string> - <string name="camerasettings_resolution_label">Auflösung:</string> - <string name="camerasettings_test2_label">Test2:</string> - <string name="camerasettings_test3_label">Test3:</string> - <string name="camerasettings_test4_label">Test4:</string> - <string name="camerasettings_use_sd_card_label">Bilder auf SD-Karte speichern</string> - <string name="camerasettings_yes">Ja</string> - <string name="cancel">Abbrechen</string> - <string name="confirm_delete">Löschen bestätigen</string> - <string name="confirm_delete_message">Das Bild wird gelöscht.</string> - <string name="confirm_delete_title">Löschen</string> - <string name="context_menu_header">Bildoptionen</string> - <string name="crop_discard_text">Verwerfen</string> - <string name="crop_help">Für Größenänderung ALT drücken.</string> - <string name="crop_label">Bild zuschneiden</string> - <string name="crop_save_text">Speichern</string> - <string name="default_value_pref_gallery_size">1</string> - <string name="default_value_pref_gallery_slideshow_interval">"2"</string> - <string name="default_value_pref_gallery_slideshow_transition">"0"</string> - <string name="default_value_pref_gallery_sort">Absteigend</string> - <string name="delete">Löschen</string> - <string name="deny_delete">Abbrechen"</string> - <string name="details">Details</string> - <string name="details_category_label">Kategorie:</string> - <string name="details_date_taken">Aufnahmedatum:</string> - <string name="details_description_label">Beschreibung:</string> - <string name="details_description_text">Testbeschreibung</string> - <string name="details_file_size">Dateigröße:</string> - <string name="details_image_resolution">Auflösung:</string> - <string name="details_language_label">Sprache:</string> - <string name="details_panel_title">Details</string> - <string name="details_privateView_text">Privat</string> - <string name="details_publicView_text">Öffentlich</string> - <string name="details_save_text">Speichern</string> - <string name="details_tags_label">Tags:</string> - <string name="details_tags_text">Monster</string> - <string name="details_title_label">Titel:</string> - <string name="details_title_text">Eigenes Video</string> - <string name="details_uploaded_text">Erfolgreich hochgeladen</string> - <string name="edit">Bearbeiten</string> - <string name="flip_orientation">Ausrichtung wechseln</string> - <string name="gallery_label">Bilder</string> - <string name="gallery_large">Groß</string> - <string name="gallery_picker_label">Bilder</string> - <string name="gallery_small">Klein</string> - <string name="gallerysettings_duration">Dauer jedes Bildes in Bildschirmpräsentationen</string> - <string name="gallerysettings_speed1">1 Sekunde</string> - <string name="gallerysettings_speed2">3 Sekunden</string> - <string name="gallerysettings_speed3">5 Sekunden</string> - <string name="high">Hoch</string> - <string name="image_count"><xliff:g id="counter">%d</xliff:g> Bilder</string> - <string name="image_gallery_NoImageView_text">Keine Bilder gefunden.</string> - <string name="image_gallery_picker_images">Bilder</string> - <string name="image_gallery_picker_videos">Videos</string> - <string name="loading_progress_format_string"><xliff:g id="counter">%d</xliff:g> verbleiben</string> - <string name="low">Niedrig</string> - <string name="low_res">Niedrig</string> - <string name="med">Mittel</string> - <string name="medium_res">Mittel</string> - <string name="multiface_crop_help">Tippen Sie auf ein Gesicht, um zu beginnen.</string> - <string name="no">Nein</string> - <string name="no_images">Ihr Album ist leer.</string> - <string name="no_storage">Setzen Sie eine SD-Karte ein, bevor Sie die Kamera verwenden.</string> - <string name="no_way_to_share_image">Dieses Bild kann nicht gespeichert werden.</string> - <string name="no_way_to_share_video">Dieses Video kann nicht freigegeben werden.</string> - <string name="not_enough_space">Ihre SD-Karte ist voll.</string> - <string name="ok">OK</string> - <string name="photos_gallery_title">Bilder</string> - <string name="picasa_upload_label">Nach Picasa hochladen</string> - <string name="pick_photos_gallery_title">Bild auswählen</string> - <string name="pick_videos_gallery_title">Video auswählen</string> - <string name="pref_camera_autoupload_summary">Bilder automatisch nach Picasa hochladen</string> - <string name="pref_camera_autoupload_title">Bilder autom. hochladen</string> - <string name="pref_camera_category">Kamera</string> - <string name="pref_camera_postpicturemenu_summary">Aktionenmenü (Speichern, Löschen, ...) nach Aufnahme anzeigen</string> - <string name="pref_camera_postpicturemenu_title">Hinweis nach Aufnahme</string> - <string name="pref_camera_recordlocation_summary">Ort in Bilddaten aufnehmen</string> - <string name="pref_camera_recordlocation_title">Ort in Bildern speichern</string> - <string name="pref_camera_shuttersound_summary">Signalton bei Aufnahme eines Bildes</string> - <string name="pref_camera_shuttersound_title">Auslöserton abspielen</string> - <string name="pref_camera_upload_albumname_dialogtitle">Picasa-Albumname</string> - <string name="pref_camera_upload_albumname_summary">Zielalbum für Bilder benennen (<xliff:g id="summary">%s</xliff:g>)</string> - <string name="pref_camera_upload_albumname_title">Picasa-Albumname</string> - <string name="pref_gallery_category">Allgemeine Einstellungen</string> - <string name="pref_gallery_confirm_delete_summary">Bestätigung vor Löschen von Bildern anzeigen</string> - <string name="pref_gallery_confirm_delete_title">Löschen bestätigen</string> - <string name="pref_gallery_size_dialogtitle">Bildgröße</string> - <string name="pref_gallery_size_summary">Anzeigegröße für Bilder auswählen</string> - <string name="pref_gallery_size_title">Bildgröße</string> - <string name="pref_gallery_slideshow_interval_dialogtitle">Intervall Diaschau</string> - <string name="pref_gallery_slideshow_interval_summary">Bestimmen Sie, wie lange jedes Bild in der Diaschau angezeigt wird</string> - <string name="pref_gallery_slideshow_interval_title">Intervall Diaschau</string> - <string name="pref_gallery_slideshow_repeat_dialogtitle">Diaschau wiederholen?</string> - <string name="pref_gallery_slideshow_repeat_summary">Diaschau mehr als einmal abspielen</string> - <string name="pref_gallery_slideshow_repeat_title">Diaschau wiederholen</string> - <string name="pref_gallery_slideshow_shuffle_dialogtitle">Bilder zufällig wiedergeben?</string> - <string name="pref_gallery_slideshow_shuffle_summary">Bilder in beliebiger Reihenfolge anzeigen</string> - <string name="pref_gallery_slideshow_shuffle_title">Bilder zufällig wiedergeben</string> - <string name="pref_gallery_slideshow_transition_dialogtitle">Diaschauübergang</string> - <string name="pref_gallery_slideshow_transition_summary">Wählen Sie den Effekt aus, der für den Übergang von einem Bild zum nächsten verwendet werden soll</string> - <string name="pref_gallery_slideshow_transition_title">Diaschauübergang</string> - <string name="pref_gallery_sort_dialogtitle">Bilder sortieren</string> - <string name="pref_gallery_sort_summary">Sortiermethode für Bilder auswählen</string> - <string name="pref_gallery_sort_title">Bilder sortieren</string> - <string name="pref_slideshow_category">Einstellungen Diaschau</string> - <string name="preferences_label">Kameraeinstellungen</string> - <string name="preview">Vorschau</string> - <string name="record">Aufnehmen</string> - <string name="rotate">Drehen</string> - <string name="rotate_left">Links drehen</string> - <string name="rotate_right">Rechts drehen</string> - <string name="runningFaceDetection">Bitte warten\u2026</string> - <string name="save">Speichern</string> - <string name="savingImage">Bild speichern\u2026</string> - <string name="sec1">1 Sek.</string> - <string name="sec2">2 Sek.</string> - <string name="sec3">3 Sek.</string> - <string name="sec4">4 Sek.</string> - <string name="sec5">5 Sek.</string> - <string name="sendImage">Bild freigeben über</string> - <string name="sendVideo">Video freigeben über</string> - <string name="setImage">Bild einstellen als</string> - <string name="set_wallpaper">Als Bildschirmhintergrund einstellen</string> - <string name="settings">Einstellungen</string> - <string name="share_youtube">YouTube</string> - <string name="slide_show">Diaschau</string> - <string name="space_remaining_k"><xliff:g id="counter">%d</xliff:g>K</string> - <string name="stop">Anhalten</string> - <string name="testexif">Exif testen</string> - <string name="upload">Hochladen</string> - <string name="upload_all">Alle hochladen</string> - <string name="upload_default_category_text">Unterhaltung</string> - <string name="upload_default_description_text">Beschreibung hier eingeben</string> - <string name="upload_default_tags_text">Video</string> - <string name="upload_dialog_title">Nach YouTube hochladen - Videodetails eingeben</string> - <string name="upload_info_category">Kategorie:</string> - <string name="upload_info_description">Beschreibung:</string> - <string name="upload_info_private">Wenn dies nicht markiert ist, können nur Sie den Film sehen</string> - <string name="upload_info_tags">Tags:</string> - <string name="upload_info_title">Titel:</string> - <string name="upload_info_upload">Hochladen</string> - <string name="uploadingNPhotos"><xliff:g id="counter">%d</xliff:g> Bilder werden hochgeladen</string> - <string name="uploadingNVideos"><xliff:g id="counter">%d</xliff:g> Videos werden hochgeladen</string> - <string name="uploading_photos">Bilder werden hochgeladen</string> - <string name="uploading_photos_2">Bilder werden hochgeladen</string> - <string name="uploading_videos">Videos werden hochgeladen</string> - <string name="uploading_videos_2">Videos werden hochgeladen</string> - <string name="video_gallery_NoImageView_text">Keine Videos gefunden.</string> - <string name="video_play">Abspielen</string> - <string name="videos_gallery_title">Videos</string> - <string name="view">Ansicht</string> - <string name="view_label">Bild anzeigen</string> - <string name="view_video_label">Video anzeigen</string> - <string name="viewimage_comments_label_text">Kommentare</string> - <string name="viewimage_datetaken_label_text">Datum</string> - <string name="viewimage_digitalzoom_label_text">Digitaler Zoom</string> - <string name="viewimage_flash_label_text">Blitz benutzt</string> - <string name="viewimage_gps_latitude_label_text">GPS-Längengrad</string> - <string name="viewimage_gps_longitude_label_text">GPS-Längengrad</string> - <string name="viewimage_make_label_text">Erstellen</string> - <string name="viewimage_model_label_text">Von</string> - <string name="viewimage_orientation_label_text">Ausrichtung</string> - <string name="viewimage_res_label_text">Auflösung</string> - <string name="viewimage_status_text">Zum Zoomen Eingabe oder Leertaste drücken.</string> - <string name="wait">Bitte warten\u2026</string> - <string name="wallpaper">Bildschirmhintergrund wird eingestellt; bitte warten\u2026</string> - <string name="yes">Ja</string> - <string name="youtube_upload_label">Nach YouTube hochladen</string> - <string name="zoom">Zoom</string> -</resources> diff --git a/res/values-de/arrays.xml b/res/values-de/arrays.xml new file mode 100644 index 0000000..ad36e2f --- /dev/null +++ b/res/values-de/arrays.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- no translation found for pref_camera_videoquality_entries:0 (4155278146225809483) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (2439895494739176281) --> + <!-- no translation found for pref_camera_videoquality_entryvalues:0 (4757859881176606698) --> + <!-- no translation found for pref_camera_videoquality_entryvalues:1 (8585619597157636291) --> + <!-- no translation found for pref_camera_videocodec_entryvalues:0 (3204196627530169058) --> + <!-- no translation found for pref_camera_videocodec_entryvalues:1 (387077728219920411) --> +</resources> diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml new file mode 100644 index 0000000..682c15d --- /dev/null +++ b/res/values-de/strings.xml @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="all_images">"Alle Bilder"</string> + <!-- no translation found for all_videos (3380966619230896013) --> + <skip /> + <string name="camera_label">"Kamera"</string> + <!-- no translation found for gallery_picker_label (3080425245006492787) --> + <skip /> + <!-- no translation found for gallery_camera_bucket_name (2924618424339240831) --> + <skip /> + <!-- no translation found for gallery_camera_videos_bucket_name (3369151581398551623) --> + <skip /> + <!-- no translation found for switch_to_video_lable (4525451949497982385) --> + <skip /> + <!-- no translation found for switch_to_camera_lable (8248495141797448471) --> + <skip /> + <string name="crop_label">"Bild zuschneiden"</string> + <string name="view_label">"Bild anzeigen"</string> + <string name="preferences_label">"Kameraeinstellungen"</string> + <string name="wait">"Bitte warten..."</string> + <string name="no_storage">"Legen Sie vor Verwendung der Kamera eine SD-Karte ein."</string> + <string name="not_enough_space">"Ihre SD-Karte ist voll."</string> + <string name="wallpaper">"Hintergrund wird eingestellt, bitte warten..."</string> + <string name="savingImage">"Bild wird gespeichert..."</string> + <string name="runningFaceDetection">"Bitte warten..."</string> + <string name="flip_orientation">"Ausrichtung drehen"</string> + <string name="settings">"Einstellungen"</string> + <string name="view">"Anzeigen"</string> + <string name="details">"Details"</string> + <string name="rotate">"Drehen"</string> + <string name="rotate_left">"Nach links drehen"</string> + <string name="rotate_right">"Nach rechts drehen"</string> + <string name="slide_show">"Diashow"</string> + <!-- no translation found for capture_picture (4114265595549284643) --> + <skip /> + <!-- no translation found for capture_video (4047046282358697155) --> + <skip /> + <string name="crop_save_text">"Speichern"</string> + <string name="crop_discard_text">"Verwerfen"</string> + <string name="camera_keep">"Speichern"</string> + <string name="confirm_delete_title">"Löschen"</string> + <string name="confirm_delete_message">"Das Bild wird gelöscht."</string> + <!-- no translation found for confirm_delete_video_message (5796154324948010221) --> + <skip /> + <string name="camera_toss">"Löschen"</string> + <string name="camera_share">"Weiterleiten"</string> + <string name="camera_set">"Festlegen als"</string> + <!-- no translation found for camera_play (8248000517869959980) --> + <skip /> + <string name="camera_crop">"Zuschneiden"</string> + <string name="camera_done">"Neues Bild"</string> + <string name="camera_tossing">"Löschvorgang..."</string> + <string name="no_way_to_share_image">"Dieses Bild kann nicht weitergeleitet werden."</string> + <string name="no_way_to_share_video">"Dieses Video kann nicht weitergeleitet werden."</string> + <!-- no translation found for camera_gallery_photos_text (6558048736561932758) --> + <skip /> + <string name="camera_pick_wallpaper">"Bilder"</string> + <string name="camera_setas_wallpaper">"Hintergrund"</string> + <string name="camera_setas_wallpaper_drm">"Gekaufte Bilder"</string> + <string name="camera_selectphoto">"Dieses Bild auswählen"</string> + <string name="camera_takenewphoto">"Neues Bild aufnehmen"</string> + <string name="pref_gallery_category">"Allgemeine Einstellungen"</string> + <string name="pref_slideshow_category">"Einstellungen für Diashow"</string> + <!-- no translation found for pref_camera_general_settings_category (2135384248699549300) --> + <skip /> + <string name="pref_gallery_size_title">"Bildgröße"</string> + <string name="pref_gallery_size_summary">"Anzeigegröße für Bilder auswählen"</string> + <string name="pref_gallery_size_dialogtitle">"Bildgröße"</string> + <string-array name="pref_gallery_size_choices"> + <item>"Groß"</item> + <item>"Klein"</item> + </string-array> + <string name="pref_gallery_sort_title">"Sortierreihenfolge für Bilder"</string> + <string name="pref_gallery_sort_summary">"Sortierreihenfolge für Bilder auswählen"</string> + <string name="pref_gallery_sort_dialogtitle">"Sortierreihenfolge für Bilder"</string> + <string-array name="pref_gallery_sort_choices"> + <item>"Neue zuerst"</item> + <item>"Neue zuletzt"</item> + </string-array> + <string name="pref_gallery_slideshow_interval_title">"Diashow-Intervall"</string> + <string name="pref_gallery_slideshow_interval_summary">"Auswählen, wie lange jedes Bild in der Diashow angezeigt werden soll"</string> + <string name="pref_gallery_slideshow_interval_dialogtitle">"Diashow-Intervall"</string> + <string-array name="pref_gallery_slideshow_interval_choices"> + <item>"2 Sekunden"</item> + <item>"3 Sekunden"</item> + <item>"4 Sekunden"</item> + </string-array> + <string name="pref_gallery_slideshow_transition_title">"Diashow - Übergang"</string> + <string name="pref_gallery_slideshow_transition_summary">"Effekt auswählen, der beim Wechsel zum nächsten Bild angewendet wird"</string> + <string name="pref_gallery_slideshow_transition_dialogtitle">"Diashow - Übergang"</string> + <string-array name="pref_gallery_slideshow_transition_choices"> + <item>"Ein- und ausblenden"</item> + <item>"Einblendung von links - rechts"</item> + <item>"Einblendung von oben - unten"</item> + <item>"Zufällige Auswahl"</item> + </string-array> + <string name="pref_gallery_slideshow_repeat_title">"Diashow erneut anzeigen?"</string> + <string name="pref_gallery_slideshow_repeat_summary">"Diashow mehrmals anzeigen"</string> + <string name="pref_gallery_slideshow_shuffle_title">"Bilder mischen"</string> + <string name="pref_gallery_slideshow_shuffle_summary">"Bilder in zufälliger Reihenfolge anzeigen"</string> + <string name="pref_camera_recordlocation_title">"Aufnahmeort in Bildern speichern"</string> + <string name="pref_camera_recordlocation_summary">"Aufnahmeort in Bilddaten speichern"</string> + <string name="pref_camera_postpicturemenu_title">"Eingabeaufforderung nach Aufnahme"</string> + <string name="pref_camera_postpicturemenu_summary">"Aktionsmenü (Speichern, Löschen...) nach Aufnahme anzeigen"</string> + <!-- no translation found for pref_camera_videoquality_category (2682407964628441297) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_title (4127153321803677407) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_summary (882761255405402886) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_entry_0 (6300182041472826848) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_entry_1 (6742349839919099735) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_dialogtitle (9154437474111181737) --> + <skip /> + <string name="camerasettings">"Einstellungen"</string> + <string name="image_gallery_NoImageView_text">"Keine Bilder gefunden"</string> + <string name="pref_gallery_confirm_delete_title">"Löschvorgang bestätigen"</string> + <string name="pref_gallery_confirm_delete_summary">"Bestätigung vor dem Löschen von Bildern anzeigen"</string> + <string name="details_panel_title">"Details"</string> + <string name="details_file_size">"Dateigröße:"</string> + <string name="details_image_resolution">"Auflösung:"</string> + <string name="details_date_taken">"Aufnahmedatum:"</string> + <string name="context_menu_header">"Bildoptionen"</string> + <!-- no translation found for video_context_menu_header (7318971116949475029) --> + <skip /> + <string name="multiface_crop_help">"Tippen Sie zum Beginnen auf ein Gesicht."</string> + <string name="camera_button_hint">"Drücken Sie zum Fotografieren auf die Aufnahmetaste."</string> + <!-- no translation found for photos_gallery_title (6914406246471015448) --> + <skip /> + <string name="pick_photos_gallery_title">"Bild auswählen"</string> + <!-- no translation found for videos_gallery_title (6150354029982749479) --> + <skip /> + <!-- no translation found for pick_videos_gallery_title (326727095201227333) --> + <skip /> + <string name="loading_progress_format_string">"noch <xliff:g id="COUNTER">%d</xliff:g>"</string> + <string name="sendImage">"Bild weiterleiten via"</string> + <string name="setImage">"Bild festlegen als"</string> + <string name="sendVideo">"Video weiterleiten via"</string> + <!-- no translation found for movieviewlabel (7363495772706775465) --> + <skip /> + <!-- no translation found for loading_video (4013492720121891585) --> + <skip /> + <!-- no translation found for picture_saved (2867013634030333968) --> + <skip /> + <!-- no translation found for picture_deleted (6339411528782927441) --> + <skip /> + <!-- no translation found for video_saved (6750750630389373504) --> + <skip /> + <!-- no translation found for video_deleted (5799599433975142828) --> + <skip /> + <!-- no translation found for spaceIsLow_title (2673833354017115190) --> + <skip /> + <!-- no translation found for spaceIsLow_content (2848517537672543641) --> + <skip /> +</resources> diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index d494400..a2ac176 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -1,229 +1,141 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="UTF-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="all_images">Todas las imágenes</string> - <string name="autocrop_before_query">¿Recortar antes?</string> - <string name="autocrop_no">Sí</string> - <string name="autocrop_yes">Sí</string> - <string name="best_res">Alta</string> - <string name="camera_NoStorageView_text">Inserte una tarjeta SD antes de utilizar la cámara.</string> - <string name="camera_ZoomIn_text">Acercar</string> - <string name="camera_ZoomOut_text">Alejar</string> - <string name="camera_button_hint">Pulse el botón Capturar para sacar una foto.</string> - <string name="camera_crop">Recortar</string> - <string name="camera_done">Nueva imagen</string> - <string name="camera_flash_auto">AutoFlash</string> - <string name="camera_flash_off">Flash desactivado</string> - <string name="camera_flash_on">Flash activado</string> - <string name="camera_flash_setting">Configuración del flash</string> - <string name="camera_gallery_photos_text">Imágenes</string> - <string name="camera_gallery_videos_text">Álbum de vídeos</string> - <string name="camera_keep">Guardar</string> - <string name="camera_keeping">Guardando\u2026</string> - <string name="camera_label">Cámara</string> - <string name="camera_mode_text">Modo</string> - <string name="camera_movie_record_counter_text">01:30:00 a.m.</string> - <string name="camera_pick_wallpaper">Imágenes</string> - <string name="camera_playvideo">Reproducir</string> - <string name="camera_record_text">Grabar</string> - <string name="camera_selectphoto">Seleccionar esta imagen</string> - <string name="camera_selectvideo">Seleccionar este vídeo</string> - <string name="camera_set">Establecer como</string> - <string name="camera_setas_contact">Foto del contacto</string> - <string name="camera_setas_myfave">myFaves</string> - <string name="camera_setas_wallpaper">Papel tapiz</string> - <string name="camera_setas_wallpaper_drm">Imágenes adquiridas</string> - <string name="camera_share">Compartir</string> - <string name="camera_shareby_email">Correo electrónico</string> - <string name="camera_shareby_mms">MMS</string> - <string name="camera_shareby_picasa">Picasaweb</string> - <string name="camera_shareby_picasa_all">Picasaweb (todas las imágenes)</string> - <string name="camera_switch_to_photo">Cambiar a imagen</string> - <string name="camera_switch_to_video">Cambiar a vídeo</string> - <string name="camera_takenewphoto">Capturar nueva imagen</string> - <string name="camera_takenewvideo">Capturar nuevo vídeo</string> - <string name="camera_toss">Eliminar</string> - <string name="camera_tossing">Eliminando\u2026</string> - <string name="camera_zoom_1_text">Zoom 1,3x</string> - <string name="camera_zoom_2_text">Zoom 2x</string> - <string name="camera_zoom_3_text">Zoom 4x</string> - <string name="camera_zoom_normal_text">1x</string> - <string name="camerasettings">Configuración</string> - <string name="camerasettings_autoupload_label">Cargar automáticamente imágenes en la Web</string> - <string name="camerasettings_done">Listo</string> - <string name="camerasettings_duration_label">Duración:</string> - <string name="camerasettings_image_quality_label">Calidad de la imagen:</string> - <string name="camerasettings_no">No</string> - <string name="camerasettings_off">Desactivado</string> - <string name="camerasettings_on">Activado</string> - <string name="camerasettings_play_click_sound_label">Sonido del disparador</string> - <string name="camerasettings_preferred_view_label">Vista preferida:</string> - <string name="camerasettings_resolution_label">Resolución:</string> - <string name="camerasettings_test2_label">prueba2:</string> - <string name="camerasettings_test3_label">prueba3:</string> - <string name="camerasettings_test4_label">prueba4:</string> - <string name="camerasettings_use_sd_card_label">Guardar imágenes en tarjeta SD</string> - <string name="camerasettings_yes">Sí</string> - <string name="cancel">Cancelar</string> - <string name="confirm_delete">Confirmar eliminación</string> - <string name="confirm_delete_message">Se eliminará la imagen.</string> - <string name="confirm_delete_title">Eliminar</string> - <string name="context_menu_header">Opciones de imagen</string> - <string name="crop_discard_text">Rechazar</string> - <string name="crop_help">Pulsar ALT para cambiar el tamaño.</string> - <string name="crop_label">Recortar imagen</string> - <string name="crop_save_text">Guardar</string> - <string name="default_value_pref_gallery_size">1</string> - <string name="default_value_pref_gallery_slideshow_interval">"2"</string> - <string name="default_value_pref_gallery_slideshow_transition">"0"</string> - <string name="default_value_pref_gallery_sort">descendente</string> - <string name="delete">Eliminar</string> - <string name="deny_delete">Cancelar"</string> - <string name="details">Detalles</string> - <string name="details_category_label">Categoría:</string> - <string name="details_date_taken">Fecha de captura:</string> - <string name="details_description_label">Descripción:</string> - <string name="details_description_text">descripción de prueba</string> - <string name="details_file_size">Tamaño de archivo:</string> - <string name="details_image_resolution">Resolución:</string> - <string name="details_language_label">Idioma:</string> - <string name="details_panel_title">Detalles</string> - <string name="details_privateView_text">Privado</string> - <string name="details_publicView_text">Público</string> - <string name="details_save_text">Guardar</string> - <string name="details_tags_label">Etiquetas:</string> - <string name="details_tags_text">monstruo</string> - <string name="details_title_label">Título:</string> - <string name="details_title_text">mivídeo</string> - <string name="details_uploaded_text">Cargado correctamente</string> - <string name="edit">Editar</string> - <string name="flip_orientation">Orientación de volteo</string> - <string name="gallery_label">Imágenes</string> - <string name="gallery_large">Grande</string> - <string name="gallery_picker_label">Imágenes</string> - <string name="gallery_small">Pequeño</string> - <string name="gallerysettings_duration">Duración de cada diapositiva en las presentaciones</string> - <string name="gallerysettings_speed1">1 segundo</string> - <string name="gallerysettings_speed2">3 segundos</string> - <string name="gallerysettings_speed3">5 segundos</string> - <string name="high">Alta</string> - <string name="image_count"><xliff:g id="counter">%d</xliff:g> imágenes</string> - <string name="image_gallery_NoImageView_text">Ninguna imagen encontrada.</string> - <string name="image_gallery_picker_images">Imágenes</string> - <string name="image_gallery_picker_videos">Vídeos</string> - <string name="loading_progress_format_string"><xliff:g id="counter">%d</xliff:g> restante(s)</string> - <string name="low">Baja</string> - <string name="low_res">Baja</string> - <string name="med">Medio</string> - <string name="medium_res">Medio</string> - <string name="multiface_crop_help">Puntee en una cara para empezar.</string> - <string name="no">No</string> - <string name="no_images">Su álbum está vacío.</string> - <string name="no_storage">Inserte una tarjeta SD antes de utilizar la cámara.</string> - <string name="no_way_to_share_image">Esta imagen no se puede guardar.</string> - <string name="no_way_to_share_video">Este vídeo no se puede compartir.</string> - <string name="not_enough_space">Su tarjeta SD está llena.</string> - <string name="ok">Aceptar</string> - <string name="photos_gallery_title">Imágenes</string> - <string name="picasa_upload_label">Carga de Picasa</string> - <string name="pick_photos_gallery_title">Seleccionar imagen</string> - <string name="pick_videos_gallery_title">Seleccionar vídeo</string> - <string name="pref_camera_autoupload_summary">Cargar imágenes automáticamente en Picasa</string> - <string name="pref_camera_autoupload_title">Cargar imágenes automáticamente</string> - <string name="pref_camera_category">Cámara</string> - <string name="pref_camera_postpicturemenu_summary">Mostrar el menú de acción (guardar, eliminar, etc.) después de capturar</string> - <string name="pref_camera_postpicturemenu_title">Preguntar después de la captura</string> - <string name="pref_camera_recordlocation_summary">Registrar ubicación en datos de imagen</string> - <string name="pref_camera_recordlocation_title">Guardar ubicación en imágenes</string> - <string name="pref_camera_shuttersound_summary">Reproducir un sonido al hacer una foto</string> - <string name="pref_camera_shuttersound_title">Reproducir sonido del disparador</string> - <string name="pref_camera_upload_albumname_dialogtitle">Nombre de álbum de Picasa</string> - <string name="pref_camera_upload_albumname_summary">Asigne un nombre al álbum de destino de sus imágenes (<xliff:g id="summary">%s</xliff:g>)</string> - <string name="pref_camera_upload_albumname_title">Nombre de álbum de Picasa</string> - <string name="pref_gallery_category">Configuración generales</string> - <string name="pref_gallery_confirm_delete_summary">Mostrar confirmación antes de eliminar imágenes</string> - <string name="pref_gallery_confirm_delete_title">Confirmar eliminaciones</string> - <string name="pref_gallery_size_dialogtitle">Tamaño de imagen</string> - <string name="pref_gallery_size_summary">Seleccione el tamaño de visualización de las imágenes</string> - <string name="pref_gallery_size_title">Tamaño de imagen</string> - <string name="pref_gallery_slideshow_interval_dialogtitle">Intervalo en presentación de diapositivas</string> - <string name="pref_gallery_slideshow_interval_summary">Seleccione el intervalo entre diapositiva y diapositiva en la presentación</string> - <string name="pref_gallery_slideshow_interval_title">Intervalo en presentación de diapositivas</string> - <string name="pref_gallery_slideshow_repeat_dialogtitle">¿Repetir presentación de diapositivas?</string> - <string name="pref_gallery_slideshow_repeat_summary">Reproduzca la presentación de diapositivas más de una vez</string> - <string name="pref_gallery_slideshow_repeat_title">Repetir presentación de diapositivas</string> - <string name="pref_gallery_slideshow_shuffle_dialogtitle">¿Mostrar imágenes aleatoriamente?</string> - <string name="pref_gallery_slideshow_shuffle_summary">Mostrar imágenes en orden aleatorio</string> - <string name="pref_gallery_slideshow_shuffle_title">Mostrar diapositivas aleatoriamente</string> - <string name="pref_gallery_slideshow_transition_dialogtitle">Transición de presentación de diapositivas</string> - <string name="pref_gallery_slideshow_transition_summary">Seleccione el efecto que desea utilizar al pasar de una diapositiva a otra</string> - <string name="pref_gallery_slideshow_transition_title">Transición de presentación de diapositivas</string> - <string name="pref_gallery_sort_dialogtitle">Orden de las imágenes</string> - <string name="pref_gallery_sort_summary">Seleccionar el orden de clasificación de las imágenes</string> - <string name="pref_gallery_sort_title">Orden de las imágenes</string> - <string name="pref_slideshow_category">Configuración de la presentación de diapositivas</string> - <string name="preferences_label">Configuración de la cámara</string> - <string name="preview">Vista previa</string> - <string name="record">Grabar</string> - <string name="rotate">Girar</string> - <string name="rotate_left">Girar a la izquierda</string> - <string name="rotate_right">Girar a la derecha</string> - <string name="runningFaceDetection">Por favor, espere\u2026</string> - <string name="save">Guardar</string> - <string name="savingImage">Guardando imagen\u2026</string> - <string name="sec1">1 s</string> - <string name="sec2">2 s</string> - <string name="sec3">3 s</string> - <string name="sec4">4 s</string> - <string name="sec5">5 s</string> - <string name="sendImage">Compartir imagen por</string> - <string name="sendVideo">Compartir vídeo por</string> - <string name="setImage">Establecer imagen como</string> - <string name="set_wallpaper">Establecer como papel tapiz</string> - <string name="settings">Configuración</string> - <string name="share_youtube">YouTube</string> - <string name="slide_show">Presentación de diapositivas</string> - <string name="space_remaining_k"><xliff:g id="counter">%d</xliff:g>K</string> - <string name="stop">Detener</string> - <string name="testexif">Prueba de Exif</string> - <string name="upload">Cargar</string> - <string name="upload_all">Cargar todo</string> - <string name="upload_default_category_text">Entretenimiento</string> - <string name="upload_default_description_text">aquí va la descripción</string> - <string name="upload_default_tags_text">vídeo</string> - <string name="upload_dialog_title">Cargar en YouTube - introducir detalles del vídeo</string> - <string name="upload_info_category">Categoría:</string> - <string name="upload_info_description">Descripción:</string> - <string name="upload_info_private">Si esta opción no está activada, sólo podrá ver el vídeo usted</string> - <string name="upload_info_tags">Etiquetas:</string> - <string name="upload_info_title">Título:</string> - <string name="upload_info_upload">Cargar</string> - <string name="uploadingNPhotos">Cargando <xliff:g id="counter">%d</xliff:g> imágenes</string> - <string name="uploadingNVideos">Cargando <xliff:g id="counter">%d</xliff:g> vídeos</string> - <string name="uploading_photos">Cargando imágenes</string> - <string name="uploading_photos_2">Cargando imágenes</string> - <string name="uploading_videos">Cargando vídeos</string> - <string name="uploading_videos_2">Cargando vídeos</string> - <string name="video_gallery_NoImageView_text">No se ha encontrado ningún vídeo.</string> - <string name="video_play">Reproducir</string> - <string name="videos_gallery_title">Vídeos</string> - <string name="view">Ver</string> - <string name="view_label">Ver imagen</string> - <string name="view_video_label">Ver vídeo</string> - <string name="viewimage_comments_label_text">Comentarios</string> - <string name="viewimage_datetaken_label_text">Fecha</string> - <string name="viewimage_digitalzoom_label_text">Zoom digital</string> - <string name="viewimage_flash_label_text">Flash usado</string> - <string name="viewimage_gps_latitude_label_text">Latitud GPS</string> - <string name="viewimage_gps_longitude_label_text">Longitud GPS</string> - <string name="viewimage_make_label_text">Hacer</string> - <string name="viewimage_model_label_text">De</string> - <string name="viewimage_orientation_label_text">Orientación</string> - <string name="viewimage_res_label_text">Resolución</string> - <string name="viewimage_status_text">Pulse Intro o la barra espaciadora para utilizar el zoom.</string> - <string name="wait">Por favor, espere\u2026</string> - <string name="wallpaper">Estableciendo papel tapiz. Por favor, espere\u2026</string> - <string name="yes">Sí</string> - <string name="youtube_upload_label">Carga en YouTube</string> - <string name="zoom">Zoom</string> + <!-- no translation found for all_images (7177582020160054334) --> + <skip /> + <string name="camera_label">"Cámara"</string> + <string name="gallery_picker_label">"Álbumes"</string> + <!-- no translation found for gallery_camera_bucket_name (8410686962557494439) --> + <skip /> + <!-- no translation found for switch_to_video_lable (1350915759804484157) --> + <skip /> + <!-- no translation found for switch_to_camera_lable (1823306882227066007) --> + <skip /> + <string name="crop_label">"Recortar imagen"</string> + <string name="view_label">"Ver imagen"</string> + <string name="preferences_label">"Configuración de la cámara"</string> + <string name="wait">"Por favor, espere…"</string> + <string name="no_storage">"Inserte una tarjeta SD antes de usar la cámara"</string> + <string name="not_enough_space">"Su tarjeta de almacenamiento está llena"</string> + <string name="wallpaper">"Estableciendo papel tapiz. Por favor, espere…"</string> + <string name="savingImage">"Guardando imagen"</string> + <string name="runningFaceDetection">"Por favor, espere…"</string> + <!-- no translation found for flip_orientation (2488284515852888409) --> + <skip /> + <string name="settings">"Configuración"</string> + <!-- no translation found for view (4639715088471766970) --> + <skip /> + <string name="details">"Detalles"</string> + <string name="rotate">"Girar"</string> + <string name="rotate_left">"Girar a la izquierda"</string> + <string name="rotate_right">"Girar a la derecha"</string> + <string name="slide_show">"Presentación de diapositivas"</string> + <string name="crop_save_text">"Guardar"</string> + <string name="crop_discard_text">"Descartar"</string> + <!-- no translation found for camera_keep (4046418310305917657) --> + <skip /> + <!-- no translation found for confirm_delete_title (8942471980646707642) --> + <skip /> + <!-- no translation found for confirm_delete_message (6944545476499253074) --> + <skip /> + <string name="camera_toss">"Eliminar"</string> + <string name="camera_share">"Compartir"</string> + <string name="camera_set">"Establecer como…"</string> + <!-- no translation found for camera_play (6388821030721929966) --> + <skip /> + <string name="camera_crop">"Recorte automático"</string> + <string name="camera_done">"Nueva imagen"</string> + <string name="camera_tossing">"Eliminando…"</string> + <string name="no_way_to_share_image">"Esta imagen no se puede guardar"</string> + <string name="no_way_to_share_video">"Este vídeo no se puede compartir"</string> + <string name="camera_gallery_photos_text">"Imágenes"</string> + <!-- no translation found for camera_pick_wallpaper (2052155470431167023) --> + <skip /> + <string name="camera_setas_wallpaper">"Papel tapiz"</string> + <!-- no translation found for camera_setas_wallpaper_drm (787462863614664620) --> + <skip /> + <string name="camera_selectphoto">"Seleccionar esta imagen"</string> + <string name="camera_takenewphoto">"Capturar nueva imagen"</string> + <string name="pref_gallery_category">"Vista de álbum de imágenes"</string> + <string name="pref_slideshow_category">"Presentación de diapositivas"</string> + <!-- no translation found for pref_camera_general_settings_category (1720434593482716214) --> + <skip /> + <string name="pref_gallery_size_title">"Tamaño de imagen"</string> + <string name="pref_gallery_size_summary">"Seleccione el tamaño de visualización de las imágenes en los álbumes"</string> + <string name="pref_gallery_size_dialogtitle">"Tamaño de imagen"</string> + <!-- no translation found for pref_gallery_size_choices:0 (3341375119334343613) --> + <!-- no translation found for pref_gallery_size_choices:1 (979877976111629768) --> + <string name="pref_gallery_sort_title">"Orden de las imágenes"</string> + <string name="pref_gallery_sort_summary">"Seleccionar el orden de las imágenes en los álbumes"</string> + <string name="pref_gallery_sort_dialogtitle">"Orden de las imágenes"</string> + <!-- no translation found for pref_gallery_sort_choices:0 (2009184885742004467) --> + <!-- no translation found for pref_gallery_sort_choices:1 (7253524441061782381) --> + <string name="pref_gallery_slideshow_interval_title">"Intervalo en presentación de diapositivas"</string> + <string name="pref_gallery_slideshow_interval_summary">"Seleccione el intervalo entre diapositiva y diapositiva en la presentación"</string> + <string name="pref_gallery_slideshow_interval_dialogtitle">"Intervalo en presentación de diapositivas"</string> + <!-- no translation found for pref_gallery_slideshow_interval_choices:0 (3293392256331071955) --> + <!-- no translation found for pref_gallery_slideshow_interval_choices:1 (6762163459545768561) --> + <!-- no translation found for pref_gallery_slideshow_interval_choices:2 (3999753648109312132) --> + <string name="pref_gallery_slideshow_transition_title">"Transición de diapositivas"</string> + <string name="pref_gallery_slideshow_transition_summary">"Seleccione el efecto que desea usar al pasar de una diapositiva a otra"</string> + <string name="pref_gallery_slideshow_transition_dialogtitle">"Transición de diapositivas"</string> + <!-- no translation found for pref_gallery_slideshow_transition_choices:0 (1917959322875321005) --> + <!-- no translation found for pref_gallery_slideshow_transition_choices:1 (6508707204357284687) --> + <!-- no translation found for pref_gallery_slideshow_transition_choices:2 (5628742586795545287) --> + <!-- no translation found for pref_gallery_slideshow_transition_choices:3 (3350644769941682805) --> + <string name="pref_gallery_slideshow_repeat_title">"Repetir presentación de diapositivas"</string> + <string name="pref_gallery_slideshow_repeat_summary">"Seleccione esta opción para reproducir la presentación de diapositivas más de una vez"</string> + <string name="pref_gallery_slideshow_shuffle_title">"Mostrar diapositivas aleatoriamente"</string> + <string name="pref_gallery_slideshow_shuffle_summary">"Seleccione esta opción para mostrar las imágenes en orden aleatorio"</string> + <string name="pref_camera_recordlocation_title">"Registrar ubicación en imágenes"</string> + <string name="pref_camera_recordlocation_summary">"Seleccione esta opción para registrar automáticamente la ubicación en las imágenes"</string> + <!-- no translation found for pref_camera_postpicturemenu_title (6273327212867896720) --> + <skip /> + <!-- no translation found for pref_camera_postpicturemenu_summary (7911699118676137405) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_category (7460987936373873411) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_title (2766490880685686012) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_summary (6370975165195010636) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_entry_0 (8088669040921661814) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_entry_1 (3505027746158170269) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_dialogtitle (1836746975783096625) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_category (907203894431470628) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_title (3330800694130697647) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_summary (8269173339100296159) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_dialogtitle (5759217298675791948) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_entry_0 (6259385536148037705) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_entry_1 (3178021263058501227) --> + <skip /> + <string name="camerasettings">"Configuración"</string> + <string name="image_gallery_NoImageView_text">"Ninguna imagen"</string> + <!-- no translation found for pref_gallery_confirm_delete_title (201485251343856203) --> + <skip /> + <!-- no translation found for pref_gallery_confirm_delete_summary (7235236977784533739) --> + <skip /> + <string name="details_panel_title">"Detalles"</string> + <string name="details_file_size">"Tamaño de archivo:"</string> + <string name="details_image_resolution">"Resolución:"</string> + <string name="details_date_taken">"Fecha de captura:"</string> + <string name="context_menu_header">"Opciones de imagen"</string> + <string name="multiface_crop_help">"Seleccionar cara para empezar"</string> + <string name="camera_button_hint">"Pulse el botón Capturar para sacar una foto"</string> + <string name="photos_gallery_title">"Imágenes"</string> + <string name="pick_photos_gallery_title">"Seleccionar imagen"</string> + <!-- no translation found for loading_progress_format_string (4252016560676330797) --> + <skip /> + <string name="sendImage">"Compartir esta imagen por"</string> + <!-- no translation found for setImage (6676791915351726249) --> + <skip /> + <string name="sendVideo">"Compartir este vídeo por"</string> </resources> diff --git a/res/values-fr-rFR/strings.xml b/res/values-fr-rFR/strings.xml deleted file mode 100644 index 20aa1a7..0000000 --- a/res/values-fr-rFR/strings.xml +++ /dev/null @@ -1,229 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="all_images">Toutes les images</string> - <string name="autocrop_before_query">Rogner avant ?</string> - <string name="autocrop_no">Oui</string> - <string name="autocrop_yes">Oui</string> - <string name="best_res">Haut</string> - <string name="camera_NoStorageView_text">Veuillez insérer une carte SD avant d\'utiliser l\'appareil photo.</string> - <string name="camera_ZoomIn_text">Zoom avant</string> - <string name="camera_ZoomOut_text">Zoom arrière</string> - <string name="camera_button_hint">Appuyez le bouton Capture pour prendre la photo.</string> - <string name="camera_crop">Rogner</string> - <string name="camera_done">Nouvelle image</string> - <string name="camera_flash_auto">FlashAuto</string> - <string name="camera_flash_off">Flash ACT</string> - <string name="camera_flash_on">Flash DÉS</string> - <string name="camera_flash_setting">Paramètre du flash</string> - <string name="camera_gallery_photos_text">Images</string> - <string name="camera_gallery_videos_text">Album vidéo</string> - <string name="camera_keep">Enregistrer</string> - <string name="camera_keeping">Conserver\u2026</string> - <string name="camera_label">Appareil photo</string> - <string name="camera_mode_text">Mode</string> - <string name="camera_movie_record_counter_text">01:30:00</string> - <string name="camera_pick_wallpaper">Images</string> - <string name="camera_playvideo">Lecture</string> - <string name="camera_record_text">Enregistrer</string> - <string name="camera_selectphoto">Sélectionner cette image</string> - <string name="camera_selectvideo">Sélectionner cette vidéo</string> - <string name="camera_set">Définir comme</string> - <string name="camera_setas_contact">Image de contact</string> - <string name="camera_setas_myfave">myFaves</string> - <string name="camera_setas_wallpaper">Papier peint</string> - <string name="camera_setas_wallpaper_drm">Images achetées</string> - <string name="camera_share">Partager</string> - <string name="camera_shareby_email">Email</string> - <string name="camera_shareby_mms">MMS</string> - <string name="camera_shareby_picasa">Picasaweb</string> - <string name="camera_shareby_picasa_all">Picasaweb (toutes les images)</string> - <string name="camera_switch_to_photo">Passer en image</string> - <string name="camera_switch_to_video">Passer en vidéo</string> - <string name="camera_takenewphoto">Capture nouvelle image</string> - <string name="camera_takenewvideo">Capture nouvelle vidéo</string> - <string name="camera_toss">Supprimer</string> - <string name="camera_tossing">Suppression\u2026</string> - <string name="camera_zoom_1_text">Zoom x1,3</string> - <string name="camera_zoom_2_text">Zoom x2</string> - <string name="camera_zoom_3_text">Zoom x4</string> - <string name="camera_zoom_normal_text">x1</string> - <string name="camerasettings">Paramètres</string> - <string name="camerasettings_autoupload_label">Transférer automatiquement les images vers le Web</string> - <string name="camerasettings_done">Terminé</string> - <string name="camerasettings_duration_label">Durée :</string> - <string name="camerasettings_image_quality_label">Qualité d\'image :</string> - <string name="camerasettings_no">Non</string> - <string name="camerasettings_off">Désactivé</string> - <string name="camerasettings_on">Activé</string> - <string name="camerasettings_play_click_sound_label">Son du déclencheur</string> - <string name="camerasettings_preferred_view_label">Vue préférée :</string> - <string name="camerasettings_resolution_label">Résolution :</string> - <string name="camerasettings_test2_label">test2 :</string> - <string name="camerasettings_test3_label">test3 :</string> - <string name="camerasettings_test4_label">test4 :</string> - <string name="camerasettings_use_sd_card_label">Enregistrer les images sur la carte SD</string> - <string name="camerasettings_yes">Oui</string> - <string name="cancel">Annuler</string> - <string name="confirm_delete">Confirmer la suppression</string> - <string name="confirm_delete_message">L\'image sera supprimée.</string> - <string name="confirm_delete_title">Supprimer</string> - <string name="context_menu_header">Options d\'image</string> - <string name="crop_discard_text">Abandonner</string> - <string name="crop_help">Maintenez ALT pour redimensionner.</string> - <string name="crop_label">Rogner l\'image</string> - <string name="crop_save_text">Enregistrer</string> - <string name="default_value_pref_gallery_size">1</string> - <string name="default_value_pref_gallery_slideshow_interval">"2"</string> - <string name="default_value_pref_gallery_slideshow_transition">"0"</string> - <string name="default_value_pref_gallery_sort">décroissant</string> - <string name="delete">Supprimer</string> - <string name="deny_delete">Annuler"</string> - <string name="details">Détails</string> - <string name="details_category_label">Catégorie :</string> - <string name="details_date_taken">Date de prise :</string> - <string name="details_description_label">Description :</string> - <string name="details_description_text">descriptiontest</string> - <string name="details_file_size">Taille du fichier :</string> - <string name="details_image_resolution">Résolution :</string> - <string name="details_language_label">Langue :</string> - <string name="details_panel_title">Détails</string> - <string name="details_privateView_text">Privé</string> - <string name="details_publicView_text">Publique</string> - <string name="details_save_text">Enregistrer</string> - <string name="details_tags_label">Tags :</string> - <string name="details_tags_text">monstre</string> - <string name="details_title_label">Titre :</string> - <string name="details_title_text">mavidéo</string> - <string name="details_uploaded_text">Transfert réussi</string> - <string name="edit">Modifier</string> - <string name="flip_orientation">Retourner l\'orientation</string> - <string name="gallery_label">Images</string> - <string name="gallery_large">Grande</string> - <string name="gallery_picker_label">Images</string> - <string name="gallery_small">Petit</string> - <string name="gallerysettings_duration">Durée de chaque diapo dans les diaporamas</string> - <string name="gallerysettings_speed1">1 seconde</string> - <string name="gallerysettings_speed2">3 secondes</string> - <string name="gallerysettings_speed3">5 secondes</string> - <string name="high">Haut</string> - <string name="image_count"><xliff:g id="counter">%d</xliff:g> images</string> - <string name="image_gallery_NoImageView_text">Aucune image trouvée.</string> - <string name="image_gallery_picker_images">Images</string> - <string name="image_gallery_picker_videos">Vidéos</string> - <string name="loading_progress_format_string"><xliff:g id="counter">%d</xliff:g> restant</string> - <string name="low">Bas</string> - <string name="low_res">Bas</string> - <string name="med">Moyen</string> - <string name="medium_res">Moyen</string> - <string name="multiface_crop_help">Appuyez un visage pour commencer.</string> - <string name="no">Non</string> - <string name="no_images">Votre album est vide.</string> - <string name="no_storage">Veuillez insérer une carte SD avant d\'utiliser l\'appareil photo.</string> - <string name="no_way_to_share_image">Cette image ne peut pas être enregistrée.</string> - <string name="no_way_to_share_video">Cette vidéo ne peut pas être partagée.</string> - <string name="not_enough_space">Votre carte SD est pleine.</string> - <string name="ok">OK</string> - <string name="photos_gallery_title">Images</string> - <string name="picasa_upload_label">Transfert Picasa</string> - <string name="pick_photos_gallery_title">Sélectionner une image</string> - <string name="pick_videos_gallery_title">Sélectionner une vidéo</string> - <string name="pref_camera_autoupload_summary">Transférer les images à Picasa automatiquement</string> - <string name="pref_camera_autoupload_title">Transfert auto des images</string> - <string name="pref_camera_category">Appareil photo</string> - <string name="pref_camera_postpicturemenu_summary">Afficher le menu action (enregistrer, supprimer, ...) après la capture</string> - <string name="pref_camera_postpicturemenu_title">Inviter après la capture</string> - <string name="pref_camera_recordlocation_summary">Enregistrer le lieu dans les données d\'image</string> - <string name="pref_camera_recordlocation_title">Stocker le lieu dans les images</string> - <string name="pref_camera_shuttersound_summary">Émettre un son à la prise d\'une photo</string> - <string name="pref_camera_shuttersound_title">Émettre le son du déclencheur</string> - <string name="pref_camera_upload_albumname_dialogtitle">Nom d\'album Picasa</string> - <string name="pref_camera_upload_albumname_summary">Nommez l\'album de destination pour vos images (<xliff:g id="summary">%s</xliff:g>)</string> - <string name="pref_camera_upload_albumname_title">Nom d\'album Picasa</string> - <string name="pref_gallery_category">Paramètres généraux</string> - <string name="pref_gallery_confirm_delete_summary">Afficher la confirmation avant de supprimer les images</string> - <string name="pref_gallery_confirm_delete_title">Confirmer les suppressions</string> - <string name="pref_gallery_size_dialogtitle">Taille d\'image</string> - <string name="pref_gallery_size_summary">Sélectionnez la taille d\'affichage des images</string> - <string name="pref_gallery_size_title">Taille d\'image</string> - <string name="pref_gallery_slideshow_interval_dialogtitle">Intervalle du diaporama</string> - <string name="pref_gallery_slideshow_interval_summary">Sélectionnez la durée d\'affichage de chaque diapo dans le diaporama</string> - <string name="pref_gallery_slideshow_interval_title">Intervalle du diaporama</string> - <string name="pref_gallery_slideshow_repeat_dialogtitle">Répéter le diaporama ?</string> - <string name="pref_gallery_slideshow_repeat_summary">Lire le diaporama plus d\'une fois</string> - <string name="pref_gallery_slideshow_repeat_title">Répéter le diaporama</string> - <string name="pref_gallery_slideshow_shuffle_dialogtitle">Mélanger les images ?</string> - <string name="pref_gallery_slideshow_shuffle_summary">Afficher les images en ordre aléatoire</string> - <string name="pref_gallery_slideshow_shuffle_title">Mélanger les diapos</string> - <string name="pref_gallery_slideshow_transition_dialogtitle">Transition du diaporama</string> - <string name="pref_gallery_slideshow_transition_summary">Sélectionner l\'effet utilisé lors du passage d\'une diapo à la suivante</string> - <string name="pref_gallery_slideshow_transition_title">Transition du diaporama</string> - <string name="pref_gallery_sort_dialogtitle">Tri des images</string> - <string name="pref_gallery_sort_summary">Sélectionnez l\'ordre de tri des images</string> - <string name="pref_gallery_sort_title">Tri des images</string> - <string name="pref_slideshow_category">Paramètres du diaporama</string> - <string name="preferences_label">Paramètres de l\'appareil photo</string> - <string name="preview">Aperçu</string> - <string name="record">Enregistrer</string> - <string name="rotate">Faire pivoter</string> - <string name="rotate_left">Pivoter à gauche</string> - <string name="rotate_right">Pivoter à droite</string> - <string name="runningFaceDetection">Veuillez attendre\u2026</string> - <string name="save">Enregistrer</string> - <string name="savingImage">Enregistrement de l\'image\u2026</string> - <string name="sec1">1 s</string> - <string name="sec2">2 s</string> - <string name="sec3">3 s</string> - <string name="sec4">4 s</string> - <string name="sec5">5 s</string> - <string name="sendImage">Partager l\'image via</string> - <string name="sendVideo">Partager la vidéo via</string> - <string name="setImage">Définir l\'image comme</string> - <string name="set_wallpaper">Définir comme papier peint</string> - <string name="settings">Paramètres</string> - <string name="share_youtube">YouTube</string> - <string name="slide_show">Diaporama</string> - <string name="space_remaining_k"><xliff:g id="counter">%d</xliff:g>K</string> - <string name="stop">Arrêter</string> - <string name="testexif">Test Exif</string> - <string name="upload">Transférer</string> - <string name="upload_all">Transférer tout</string> - <string name="upload_default_category_text">Divertissement</string> - <string name="upload_default_description_text">la description ici</string> - <string name="upload_default_tags_text">vidéo</string> - <string name="upload_dialog_title">Transférer à YouTube - saisissez les détails de la vidéo</string> - <string name="upload_info_category">Catégorie :</string> - <string name="upload_info_description">Description :</string> - <string name="upload_info_private">Si désélectionné, seul vous pouvez voir le film</string> - <string name="upload_info_tags">Tags :</string> - <string name="upload_info_title">Titre :</string> - <string name="upload_info_upload">Transférer</string> - <string name="uploadingNPhotos">Transfert de <xliff:g id="counter">%d</xliff:g> images</string> - <string name="uploadingNVideos">Transfert de <xliff:g id="counter">%d</xliff:g> vidéos</string> - <string name="uploading_photos">Transfert des images</string> - <string name="uploading_photos_2">Transfert des images</string> - <string name="uploading_videos">Transfert des vidéos</string> - <string name="uploading_videos_2">Transfert des vidéos</string> - <string name="video_gallery_NoImageView_text">Aucune vidéo trouvée.</string> - <string name="video_play">Lecture</string> - <string name="videos_gallery_title">Vidéos</string> - <string name="view">Afficher</string> - <string name="view_label">Afficher l\'image</string> - <string name="view_video_label">Afficher la vidéo</string> - <string name="viewimage_comments_label_text">Commentaires</string> - <string name="viewimage_datetaken_label_text">Date</string> - <string name="viewimage_digitalzoom_label_text">Zoom numérique</string> - <string name="viewimage_flash_label_text">Flash utilisé</string> - <string name="viewimage_gps_latitude_label_text">Latitude GPS</string> - <string name="viewimage_gps_longitude_label_text">Longitude GPS</string> - <string name="viewimage_make_label_text">Faire</string> - <string name="viewimage_model_label_text">De</string> - <string name="viewimage_orientation_label_text">Orientation</string> - <string name="viewimage_res_label_text">Résolution</string> - <string name="viewimage_status_text">Appuyez Entrée ou Espace pour le zoom.</string> - <string name="wait">Veuillez attendre\u2026</string> - <string name="wallpaper">Définition du papier peint, veuillez patienter\u2026</string> - <string name="yes">Oui</string> - <string name="youtube_upload_label">Transfert YouTube</string> - <string name="zoom">Zoom</string> -</resources> diff --git a/res/values-it-rIT/strings.xml b/res/values-it-rIT/strings.xml deleted file mode 100644 index f82048c..0000000 --- a/res/values-it-rIT/strings.xml +++ /dev/null @@ -1,229 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="all_images">Tutte le immagini</string> - <string name="autocrop_before_query">Ritagliare prima?</string> - <string name="autocrop_no">Sì</string> - <string name="autocrop_yes">Sì</string> - <string name="best_res">Alta</string> - <string name="camera_NoStorageView_text">Inserire una scheda SD prima di utilizzare la fotocamera.</string> - <string name="camera_ZoomIn_text">Zoom avanti</string> - <string name="camera_ZoomOut_text">Zoom indietro</string> - <string name="camera_button_hint">Premere il pulsante Acquisisci per acquisire l'immagine.</string> - <string name="camera_crop">Ritaglia</string> - <string name="camera_done">Nuova immagine</string> - <string name="camera_flash_auto">AutoFlash</string> - <string name="camera_flash_off">Flash OFF</string> - <string name="camera_flash_on">Flash ON</string> - <string name="camera_flash_setting">Impostazione Flash</string> - <string name="camera_gallery_photos_text">Immagini</string> - <string name="camera_gallery_videos_text">Album video</string> - <string name="camera_keep">Salva</string> - <string name="camera_keeping">Mantenimento\u2026</string> - <string name="camera_label">Fotocamera</string> - <string name="camera_mode_text">Modalità</string> - <string name="camera_movie_record_counter_text">01:30:00</string> - <string name="camera_pick_wallpaper">Immagini</string> - <string name="camera_playvideo">Riproduci</string> - <string name="camera_record_text">Registra</string> - <string name="camera_selectphoto">Selezionare questa immagine</string> - <string name="camera_selectvideo">Selezionare questo video</string> - <string name="camera_set">Imposta come</string> - <string name="camera_setas_contact">Immagine contatto</string> - <string name="camera_setas_myfave">myFaves</string> - <string name="camera_setas_wallpaper">Sfondo</string> - <string name="camera_setas_wallpaper_drm">Immagini acquistate</string> - <string name="camera_share">Condividi</string> - <string name="camera_shareby_email">Email</string> - <string name="camera_shareby_mms">MMS</string> - <string name="camera_shareby_picasa">Picasaweb</string> - <string name="camera_shareby_picasa_all">Picasaweb (tutte le immagini)</string> - <string name="camera_switch_to_photo">Passa a immagine</string> - <string name="camera_switch_to_video">Passa a video</string> - <string name="camera_takenewphoto">Acquisisci nuova immagine</string> - <string name="camera_takenewvideo">Acquisisci nuovo video</string> - <string name="camera_toss">Elimina</string> - <string name="camera_tossing">Eliminazione in corso\u2026</string> - <string name="camera_zoom_1_text">Zoom 1,3x</string> - <string name="camera_zoom_2_text">Zoom 2x</string> - <string name="camera_zoom_3_text">Zoom 4x</string> - <string name="camera_zoom_normal_text">1x</string> - <string name="camerasettings">Impostazioni</string> - <string name="camerasettings_autoupload_label">Carica automaticamente immagini sul Web</string> - <string name="camerasettings_done">Completato</string> - <string name="camerasettings_duration_label">Durata:</string> - <string name="camerasettings_image_quality_label">Qualità immagine:</string> - <string name="camerasettings_no">No</string> - <string name="camerasettings_off">Disattivato</string> - <string name="camerasettings_on">Attivato</string> - <string name="camerasettings_play_click_sound_label">Suono otturatore</string> - <string name="camerasettings_preferred_view_label">Visualizzazione preferita:</string> - <string name="camerasettings_resolution_label">Risoluzione:</string> - <string name="camerasettings_test2_label">test2:</string> - <string name="camerasettings_test3_label">test3:</string> - <string name="camerasettings_test4_label">test4:</string> - <string name="camerasettings_use_sd_card_label">Salva immagine nella scheda SD</string> - <string name="camerasettings_yes">Sì</string> - <string name="cancel">Annulla</string> - <string name="confirm_delete">Conferma eliminazione</string> - <string name="confirm_delete_message">L'immagine verrà eliminata.</string> - <string name="confirm_delete_title">Elimina</string> - <string name="context_menu_header">Opzioni immagine</string> - <string name="crop_discard_text">Ignora</string> - <string name="crop_help">Tenere premuto ALT per ridimensionare.</string> - <string name="crop_label">Ritaglia immagine</string> - <string name="crop_save_text">Salva</string> - <string name="default_value_pref_gallery_size">1</string> - <string name="default_value_pref_gallery_slideshow_interval">"2"</string> - <string name="default_value_pref_gallery_slideshow_transition">"0"</string> - <string name="default_value_pref_gallery_sort">decrescente</string> - <string name="delete">Elimina</string> - <string name="deny_delete">Annulla"</string> - <string name="details">Dettagli</string> - <string name="details_category_label">Categoria:</string> - <string name="details_date_taken">Data scatto:</string> - <string name="details_description_label">Descrizione:</string> - <string name="details_description_text">descrizionetest</string> - <string name="details_file_size">Dimensione file:</string> - <string name="details_image_resolution">Risoluzione:</string> - <string name="details_language_label">Lingua:</string> - <string name="details_panel_title">Dettagli</string> - <string name="details_privateView_text">Privato</string> - <string name="details_publicView_text">Pubblico</string> - <string name="details_save_text">Salva</string> - <string name="details_tags_label">Tag:</string> - <string name="details_tags_text">monster</string> - <string name="details_title_label">Titolo:</string> - <string name="details_title_text">myvideo</string> - <string name="details_uploaded_text">Caricamento completato</string> - <string name="edit">Modifica</string> - <string name="flip_orientation">Capovolgi orientamento</string> - <string name="gallery_label">Immagini</string> - <string name="gallery_large">Grande</string> - <string name="gallery_picker_label">Immagini</string> - <string name="gallery_small">Piccolo</string> - <string name="gallerysettings_duration">Durata di ogni diapositiva nelle presentazioni</string> - <string name="gallerysettings_speed1">1 secondo</string> - <string name="gallerysettings_speed2">3 secondi</string> - <string name="gallerysettings_speed3">5 secondi</string> - <string name="high">Alta</string> - <string name="image_count"><xliff:g id="counter">%d</xliff:g> immagini</string> - <string name="image_gallery_NoImageView_text">Nessuna immagine trovata.</string> - <string name="image_gallery_picker_images">Immagini</string> - <string name="image_gallery_picker_videos">Video</string> - <string name="loading_progress_format_string"><xliff:g id="counter">%d</xliff:g> rimanente</string> - <string name="low">Bassa</string> - <string name="low_res">Bassa</string> - <string name="med">Supporto</string> - <string name="medium_res">Supporto</string> - <string name="multiface_crop_help">Toccare una faccia per iniziare.</string> - <string name="no">No</string> - <string name="no_images">L'album è vuoto.</string> - <string name="no_storage">Inserire una scheda SD prima di utilizzare la fotocamera.</string> - <string name="no_way_to_share_image">Impossibile salvare questa immagine.</string> - <string name="no_way_to_share_video">Impossibile condividere questo video.</string> - <string name="not_enough_space">La scheda SD è piena.</string> - <string name="ok">OK</string> - <string name="photos_gallery_title">Immagini</string> - <string name="picasa_upload_label">Caricamento Picasa</string> - <string name="pick_photos_gallery_title">Seleziona immagine</string> - <string name="pick_videos_gallery_title">Seleziona video</string> - <string name="pref_camera_autoupload_summary">Carica automaticamente le immagini in Picasa</string> - <string name="pref_camera_autoupload_title">Carica immagini automaticamente</string> - <string name="pref_camera_category">Fotocamera</string> - <string name="pref_camera_postpicturemenu_summary">Visualizza il menu Azione (salva. elimina ecc...) dopo l'acquisizione</string> - <string name="pref_camera_postpicturemenu_title">Prompt dopo acquisizione</string> - <string name="pref_camera_recordlocation_summary">Registra ubicazione nei dati immagine</string> - <string name="pref_camera_recordlocation_title">Memorizza posizione nelle immagini</string> - <string name="pref_camera_shuttersound_summary">Riproduci un suono durante l'acquisizione di un'immagine</string> - <string name="pref_camera_shuttersound_title">Riproduci suono otturatore</string> - <string name="pref_camera_upload_albumname_dialogtitle">Nome album Picasa</string> - <string name="pref_camera_upload_albumname_summary">Assegnare un nome all'album di destinazione delle immagini (<xliff:g id="summary">%s</xliff:g>)</string> - <string name="pref_camera_upload_albumname_title">Nome album Picasa</string> - <string name="pref_gallery_category">Impostazioni generali</string> - <string name="pref_gallery_confirm_delete_summary">Mostra conferma prima di eliminare le immagini</string> - <string name="pref_gallery_confirm_delete_title">Conferma eliminazioni</string> - <string name="pref_gallery_size_dialogtitle">Dimensione immagine</string> - <string name="pref_gallery_size_summary">Selezionare la dimensione di visualizzazione delle immagini</string> - <string name="pref_gallery_size_title">Dimensione immagine</string> - <string name="pref_gallery_slideshow_interval_dialogtitle">Intervallo presentazione</string> - <string name="pref_gallery_slideshow_interval_summary">Selezionare la durata di visualizzazione di ogni diapositiva nella presentazione</string> - <string name="pref_gallery_slideshow_interval_title">Intervallo presentazione</string> - <string name="pref_gallery_slideshow_repeat_dialogtitle">Ripetere la presentazione?</string> - <string name="pref_gallery_slideshow_repeat_summary">Riproduci presentazione più volte</string> - <string name="pref_gallery_slideshow_repeat_title">Ripeti presentazione</string> - <string name="pref_gallery_slideshow_shuffle_dialogtitle">Riprodurre le immagini casualmente?</string> - <string name="pref_gallery_slideshow_shuffle_summary">Mostra le immagini in ordine casuale</string> - <string name="pref_gallery_slideshow_shuffle_title">Riproduzione casuale diapositive</string> - <string name="pref_gallery_slideshow_transition_dialogtitle">Transizione presentazione</string> - <string name="pref_gallery_slideshow_transition_summary">Scegliere l'effetto che si desidera utilizzare durante lo spostamento da una diapositiva all'altra</string> - <string name="pref_gallery_slideshow_transition_title">Transizione presentazione</string> - <string name="pref_gallery_sort_dialogtitle">Ordinamento immagini</string> - <string name="pref_gallery_sort_summary">Selezionare l'ordinamento delle immagini</string> - <string name="pref_gallery_sort_title">Ordinamento immagini</string> - <string name="pref_slideshow_category">Impostazioni presentazione</string> - <string name="preferences_label">Impostazioni fotocamera</string> - <string name="preview">Anteprima</string> - <string name="record">Registra</string> - <string name="rotate">Ruota</string> - <string name="rotate_left">Ruota a sinistra</string> - <string name="rotate_right">Ruota a destra</string> - <string name="runningFaceDetection">Attendere\u2026</string> - <string name="save">Salva</string> - <string name="savingImage">Salvataggio immagine\u2026</string> - <string name="sec1">1 sec</string> - <string name="sec2">2 sec</string> - <string name="sec3">3 sec</string> - <string name="sec4">4 sec</string> - <string name="sec5">5 sec</string> - <string name="sendImage">Condividi immagine via</string> - <string name="sendVideo">Condividi video via</string> - <string name="setImage">Imposta immagine come</string> - <string name="set_wallpaper">Imposta come sfondo</string> - <string name="settings">Impostazioni</string> - <string name="share_youtube">YouTube</string> - <string name="slide_show">Presentazione</string> - <string name="space_remaining_k"><xliff:g id="counter">%d</xliff:g>K</string> - <string name="stop">Interrompi</string> - <string name="testexif">Test Exif</string> - <string name="upload">Carica</string> - <string name="upload_all">Carica tutto</string> - <string name="upload_default_category_text">Intrattenimento</string> - <string name="upload_default_description_text">campo per la descrizione</string> - <string name="upload_default_tags_text">video</string> - <string name="upload_dialog_title">Carica su YouTube - digitare i dettagli video</string> - <string name="upload_info_category">Categoria:</string> - <string name="upload_info_description">Descrizione:</string> - <string name="upload_info_private">Se deselezionata, è possibile visualizzare solo il filmato</string> - <string name="upload_info_tags">Tag:</string> - <string name="upload_info_title">Titolo:</string> - <string name="upload_info_upload">Carica</string> - <string name="uploadingNPhotos">Caricamento di <xliff:g id="counter">%d</xliff:g> immagini</string> - <string name="uploadingNVideos">Caricamento di <xliff:g id="counter">%d</xliff:g> video</string> - <string name="uploading_photos">Caricamento immagini in corso</string> - <string name="uploading_photos_2">Caricamento immagini in corso</string> - <string name="uploading_videos">Caricamento video in corso</string> - <string name="uploading_videos_2">Caricamento video in corso</string> - <string name="video_gallery_NoImageView_text">Nessun video trovato.</string> - <string name="video_play">Riproduci</string> - <string name="videos_gallery_title">Video</string> - <string name="view">Visualizza</string> - <string name="view_label">Visualizza immagine</string> - <string name="view_video_label">Visualizza video</string> - <string name="viewimage_comments_label_text">Commenti</string> - <string name="viewimage_datetaken_label_text">Data</string> - <string name="viewimage_digitalzoom_label_text">Zoom digitale</string> - <string name="viewimage_flash_label_text">Flash utilizzato</string> - <string name="viewimage_gps_latitude_label_text">Latitudine GPS</string> - <string name="viewimage_gps_longitude_label_text">Longitudine GPS</string> - <string name="viewimage_make_label_text">Crea</string> - <string name="viewimage_model_label_text">Da</string> - <string name="viewimage_orientation_label_text">Orientamento</string> - <string name="viewimage_res_label_text">Risoluzione</string> - <string name="viewimage_status_text">Premere Invio o Barra spaziatrice per eseguire lo zoom.</string> - <string name="wait">Attendere\u2026</string> - <string name="wallpaper">Impostazione dello sfondo in corso. Attendere\u2026</string> - <string name="yes">Sì</string> - <string name="youtube_upload_label">Caricamento YouTube</string> - <string name="zoom">Zoom</string> -</resources> diff --git a/res/values-ja/arrays.xml b/res/values-ja/arrays.xml new file mode 100644 index 0000000..ad36e2f --- /dev/null +++ b/res/values-ja/arrays.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- no translation found for pref_camera_videoquality_entries:0 (4155278146225809483) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (2439895494739176281) --> + <!-- no translation found for pref_camera_videoquality_entryvalues:0 (4757859881176606698) --> + <!-- no translation found for pref_camera_videoquality_entryvalues:1 (8585619597157636291) --> + <!-- no translation found for pref_camera_videocodec_entryvalues:0 (3204196627530169058) --> + <!-- no translation found for pref_camera_videocodec_entryvalues:1 (387077728219920411) --> +</resources> diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml new file mode 100644 index 0000000..44800c1 --- /dev/null +++ b/res/values-ja/strings.xml @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="all_images">"すべての写真"</string> + <!-- no translation found for all_videos (3380966619230896013) --> + <skip /> + <string name="camera_label">"カメラ"</string> + <!-- no translation found for gallery_picker_label (3080425245006492787) --> + <skip /> + <!-- no translation found for gallery_camera_bucket_name (2924618424339240831) --> + <skip /> + <!-- no translation found for gallery_camera_videos_bucket_name (3369151581398551623) --> + <skip /> + <!-- no translation found for switch_to_video_lable (4525451949497982385) --> + <skip /> + <!-- no translation found for switch_to_camera_lable (8248495141797448471) --> + <skip /> + <string name="crop_label">"写真のトリミング"</string> + <string name="view_label">"写真を表示"</string> + <string name="preferences_label">"カメラ設定"</string> + <string name="wait">"お待ちください..."</string> + <string name="no_storage">"カメラを使用する前にSDカードを挿入してください。"</string> + <string name="not_enough_space">"SDカードがいっぱいです。"</string> + <string name="wallpaper">"壁紙を設定しています。しばらくお待ちください..."</string> + <string name="savingImage">"写真を保存中..."</string> + <string name="runningFaceDetection">"お待ちください..."</string> + <string name="flip_orientation">"画面の向きを変更"</string> + <string name="settings">"設定"</string> + <string name="view">"表示"</string> + <string name="details">"詳細"</string> + <string name="rotate">"回転"</string> + <string name="rotate_left">"左に回転"</string> + <string name="rotate_right">"右に回転"</string> + <string name="slide_show">"スライドショー"</string> + <!-- no translation found for capture_picture (4114265595549284643) --> + <skip /> + <!-- no translation found for capture_video (4047046282358697155) --> + <skip /> + <string name="crop_save_text">"保存"</string> + <string name="crop_discard_text">"破棄"</string> + <string name="camera_keep">"保存"</string> + <string name="confirm_delete_title">"削除"</string> + <string name="confirm_delete_message">"写真を削除します。"</string> + <!-- no translation found for confirm_delete_video_message (5796154324948010221) --> + <skip /> + <string name="camera_toss">"削除"</string> + <string name="camera_share">"共有"</string> + <string name="camera_set">"設定"</string> + <!-- no translation found for camera_play (8248000517869959980) --> + <skip /> + <string name="camera_crop">"トリミング"</string> + <string name="camera_done">"新しい写真"</string> + <string name="camera_tossing">"削除中..."</string> + <string name="no_way_to_share_image">"この写真は共有できません。"</string> + <string name="no_way_to_share_video">"この動画は共有できません。"</string> + <!-- no translation found for camera_gallery_photos_text (6558048736561932758) --> + <skip /> + <string name="camera_pick_wallpaper">"写真"</string> + <string name="camera_setas_wallpaper">"壁紙"</string> + <string name="camera_setas_wallpaper_drm">"購入した写真"</string> + <string name="camera_selectphoto">"この写真を選択"</string> + <string name="camera_takenewphoto">"新しい写真を撮る"</string> + <string name="pref_gallery_category">"全般設定"</string> + <string name="pref_slideshow_category">"スライドショー設定"</string> + <!-- no translation found for pref_camera_general_settings_category (2135384248699549300) --> + <skip /> + <string name="pref_gallery_size_title">"写真サイズ"</string> + <string name="pref_gallery_size_summary">"写真の表示サイズを選択"</string> + <string name="pref_gallery_size_dialogtitle">"写真サイズ"</string> + <string-array name="pref_gallery_size_choices"> + <item>"大"</item> + <item>"小"</item> + </string-array> + <string name="pref_gallery_sort_title">"写真の並べ替え"</string> + <string name="pref_gallery_sort_summary">"写真の表示順を選択"</string> + <string name="pref_gallery_sort_dialogtitle">"写真の並べ替え"</string> + <string-array name="pref_gallery_sort_choices"> + <item>"日付の新しい順"</item> + <item>"日付の古い順"</item> + </string-array> + <string name="pref_gallery_slideshow_interval_title">"スライドショーの間隔"</string> + <string name="pref_gallery_slideshow_interval_summary">"各スライドを表示する時間を選択"</string> + <string name="pref_gallery_slideshow_interval_dialogtitle">"スライドショーの間隔"</string> + <string-array name="pref_gallery_slideshow_interval_choices"> + <item>"2秒"</item> + <item>"3秒"</item> + <item>"4秒"</item> + </string-array> + <string name="pref_gallery_slideshow_transition_title">"スライドショーのトランジション"</string> + <string name="pref_gallery_slideshow_transition_summary">"スライドが切り替わるときの効果を選択"</string> + <string name="pref_gallery_slideshow_transition_dialogtitle">"スライドショーのトランジション"</string> + <string-array name="pref_gallery_slideshow_transition_choices"> + <item>"フェードイン&アウト"</item> + <item>"左右にスライド"</item> + <item>"上下にスライド"</item> + <item>"ランダムに選択"</item> + </string-array> + <string name="pref_gallery_slideshow_repeat_title">"スライドショーを繰り返す"</string> + <string name="pref_gallery_slideshow_repeat_summary">"スライドショーを繰り返す"</string> + <string name="pref_gallery_slideshow_shuffle_title">"スライドのシャッフル"</string> + <string name="pref_gallery_slideshow_shuffle_summary">"写真をランダムに表示"</string> + <string name="pref_camera_recordlocation_title">"位置を写真に保存"</string> + <string name="pref_camera_recordlocation_summary">"写真データに位置情報を記録します"</string> + <string name="pref_camera_postpicturemenu_title">"撮影後に確認"</string> + <string name="pref_camera_postpicturemenu_summary">"撮影後に操作メニュー (保存や削除など) を表示"</string> + <!-- no translation found for pref_camera_videoquality_category (2682407964628441297) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_title (4127153321803677407) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_summary (882761255405402886) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_entry_0 (6300182041472826848) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_entry_1 (6742349839919099735) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_dialogtitle (9154437474111181737) --> + <skip /> + <string name="camerasettings">"設定"</string> + <string name="image_gallery_NoImageView_text">"写真がありません。"</string> + <string name="pref_gallery_confirm_delete_title">"削除を確認"</string> + <string name="pref_gallery_confirm_delete_summary">"写真を削除する前に確認メッセージを表示"</string> + <string name="details_panel_title">"詳細"</string> + <string name="details_file_size">"ファイルサイズ:"</string> + <string name="details_image_resolution">"解像度:"</string> + <string name="details_date_taken">"撮影日:"</string> + <string name="context_menu_header">"写真オプション"</string> + <!-- no translation found for video_context_menu_header (7318971116949475029) --> + <skip /> + <string name="multiface_crop_help">"顔を選択して開始します。"</string> + <string name="camera_button_hint">"写真を撮るには[撮影]ボタンを押してください。"</string> + <!-- no translation found for video_camera_button_hint (8134161307608750427) --> + <skip /> + <!-- no translation found for photos_gallery_title (6914406246471015448) --> + <skip /> + <string name="pick_photos_gallery_title">"写真を選択"</string> + <!-- no translation found for videos_gallery_title (6150354029982749479) --> + <skip /> + <!-- no translation found for pick_videos_gallery_title (326727095201227333) --> + <skip /> + <string name="loading_progress_format_string">"残り<xliff:g id="COUNTER">%d</xliff:g>件"</string> + <string name="sendImage">"写真を共有"</string> + <string name="setImage">"写真を設定"</string> + <string name="sendVideo">"動画を共有"</string> + <!-- no translation found for movieviewlabel (7363495772706775465) --> + <skip /> + <!-- no translation found for loading_video (4013492720121891585) --> + <skip /> + <!-- no translation found for picture_saved (2867013634030333968) --> + <skip /> + <!-- no translation found for picture_deleted (6339411528782927441) --> + <skip /> + <!-- no translation found for video_saved (6750750630389373504) --> + <skip /> + <!-- no translation found for video_deleted (5799599433975142828) --> + <skip /> + <!-- no translation found for spaceIsLow_title (2673833354017115190) --> + <skip /> + <!-- no translation found for spaceIsLow_content (2848517537672543641) --> + <skip /> +</resources> diff --git a/res/values-nl-rNL/strings.xml b/res/values-nl-rNL/strings.xml index c2e7ce1..ed0e00d 100644 --- a/res/values-nl-rNL/strings.xml +++ b/res/values-nl-rNL/strings.xml @@ -1,206 +1,141 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="UTF-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="autocrop_before_query">Vooraf automatisch inkorten?</string> - <string name="autocrop_no">Ja</string> - <string name="autocrop_yes">Ja</string> - <string name="best_res">Hoog</string> - <string name="camera_NoStorageView_text">Plaats een sd-kaart voordat u de camera gebruikt</string> - <string name="camera_ZoomIn_text">Inzoomen</string> - <string name="camera_ZoomOut_text">Uitzoomen</string> - <string name="camera_button_hint">Druk op de Vastlegtoets om een foto te maken</string> - <string name="camera_crop">Automatisch inkorten</string> - <string name="camera_done">Nieuwe foto</string> - <string name="camera_flash_auto">AutoFlits</string> - <string name="camera_flash_off">Flits UIT</string> - <string name="camera_flash_on">Flits AAN</string> - <string name="camera_flash_setting">Flitsinstelling</string> - <string name="camera_gallery_photos_text">Afbeeldingen</string> - <string name="camera_gallery_videos_text">Video's</string> - <string name="camera_keeping">Aanhoudend\u2026</string> - <string name="camera_label">Camera</string> - <string name="camera_mode_text">Modus</string> - <string name="camera_movie_record_counter_text">01:30:00</string> - <string name="camera_playvideo">Afspelen</string> - <string name="camera_record_text">Opname</string> - <string name="camera_selectphoto">Dit beeld selecteren</string> - <string name="camera_selectvideo">Deze video selecteren</string> - <string name="camera_set">Instellen als\u2026</string> - <string name="camera_setas_contact">Afbeelding contactpersoon </string> - <string name="camera_setas_myfave">myFaves</string> - <string name="camera_setas_wallpaper">Achtergrond</string> - <string name="camera_share">Delen</string> - <string name="camera_shareby_email">E-mail</string> - <string name="camera_shareby_mms">MMS</string> - <string name="camera_shareby_picasa">Picasaweb</string> - <string name="camera_shareby_picasa_all">Picasaweb (alle foto's)</string> - <string name="camera_switch_to_photo">Schakelen naar foto</string> - <string name="camera_switch_to_video">Schakelen naar video</string> - <string name="camera_takenewphoto">Nieuwe afbeelding maken</string> - <string name="camera_takenewvideo">Nieuwe video maken</string> - <string name="camera_toss">Verwijderen</string> - <string name="camera_tossing">Bezig met verwijderen\u2026</string> - <string name="camera_zoom_1_text">Zoom 1.3x</string> - <string name="camera_zoom_2_text">Zoom 2x</string> - <string name="camera_zoom_3_text">Zoom 4x</string> - <string name="camera_zoom_normal_text">1x</string> - <string name="camerasettings">Instellingen</string> - <string name="camerasettings_autoupload_label">Afbeeldingen automatisch uploaden</string> - <string name="camerasettings_done">Gereed</string> - <string name="camerasettings_duration_label">Duur:</string> - <string name="camerasettings_image_quality_label">Beeldkwaliteit:</string> - <string name="camerasettings_no">Nee</string> - <string name="camerasettings_off">Uit</string> - <string name="camerasettings_on">Aan</string> - <string name="camerasettings_play_click_sound_label">Sluitergeluid</string> - <string name="camerasettings_preferred_view_label">Voorkeursweergave:</string> - <string name="camerasettings_resolution_label">Resolutie:</string> - <string name="camerasettings_test2_label">test2:</string> - <string name="camerasettings_test3_label">test3:</string> - <string name="camerasettings_test4_label">test4:</string> - <string name="camerasettings_use_sd_card_label">Afbeeldingen opslaan op sd-kaart</string> - <string name="camerasettings_yes">Ja</string> - <string name="cancel">Annuleren</string> - <string name="context_menu_header">Beeldopties</string> - <string name="crop_discard_text">Wissen</string> - <string name="crop_help">ALT ingedrukt houden om grootte te wijzigen</string> - <string name="crop_label">Afbeelding inkorten</string> - <string name="crop_save_text">Opslaan</string> - <string name="delete">Verwijderen</string> - <string name="details">Details</string> - <string name="details_category_label">Categorie:</string> - <string name="details_date_taken">Genomen op:</string> - <string name="details_description_label">Beschrijving:</string> - <string name="details_description_text">testbeschrijving</string> - <string name="details_file_size">Bestandsgrootte:</string> - <string name="details_image_resolution">Resolutie:</string> - <string name="details_language_label">Taal:</string> - <string name="details_panel_title">Details</string> - <string name="details_privateView_text">Privé</string> - <string name="details_publicView_text">Openbaar</string> - <string name="details_save_text">Opslaan</string> - <string name="details_tags_label">Labels:</string> - <string name="details_tags_text">monster</string> - <string name="details_title_label">Titel:</string> - <string name="details_title_text">mijnvideo</string> - <string name="details_uploaded_text">Uploaden gelukt</string> - <string name="edit">Bewerken</string> - <string name="error_label">Fout</string> - <string name="gallery_label">Foto's en video's</string> - <string name="gallery_large">Groot</string> - <string name="gallery_picker_label">Albums</string> - <string name="gallery_small">Klein</string> - <string name="gallerysettings_duration">Tijdsduur van elke dia in diashows</string> - <string name="gallerysettings_speed1">1 seconde</string> - <string name="gallerysettings_speed2">3 seconden</string> - <string name="gallerysettings_speed3">5 seconden</string> - <string name="high">Hoog</string> - <string name="image_gallery_NoImageView_text">Geen afbeeldingen</string> - <string name="image_gallery_picker_images">Afbeeldingen</string> - <string name="image_gallery_picker_videos">Video's</string> - <string name="low">Laag</string> - <string name="low_res">Laag</string> - <string name="med">Normaal</string> - <string name="medium_res">Normaal</string> - <string name="multiface_crop_help">Gezicht kiezen om te starten</string> - <string name="no">Nee</string> - <string name="no_images">Het album is leeg</string> - <string name="no_storage">Plaats een sd-kaart voordat u de camera gebruikt</string> - <string name="no_way_to_share_image">De afbeelding kan niet worden opgeslagen</string> - <string name="no_way_to_share_video">Deze video kan niet worden gedeeld</string> - <string name="not_enough_space">Deze geheugenkaart is vol</string> - <string name="ok">OK</string> - <string name="photos_gallery_title">Afbeeldingen</string> - <string name="picasa_upload_label">Uploaden naar Picasa</string> - <string name="pick_photos_gallery_title">Afbeelding selecteren</string> - <string name="pick_videos_gallery_title">Video selecteren</string> - <string name="pref_camera_autoupload_summary">Selecteren om afbeeldingen automatisch naar Picasa te uploaden</string> - <string name="pref_camera_autoupload_title">Afbeeldingen automatisch uploaden</string> - <string name="pref_camera_category">Camera</string> - <string name="pref_camera_recordlocation_summary">Selecteren om de locatie automatisch op te nemen bij foto's</string> - <string name="pref_camera_recordlocation_title">Locatie in afbeeldingen opnemen</string> - <string name="pref_camera_upload_albumname_dialogtitle">Picasa albumnaam</string> - <string name="pref_camera_upload_albumname_summary">Geef een naam aan het bestemmingsalbum voor afbeeldingen</string> - <string name="pref_camera_upload_albumname_title">Picasa albumnaam</string> - <string name="pref_gallery_category">Fotoalbumweergave</string> - <string name="pref_gallery_size_dialogtitle">Afbeeldinggrootte</string> - <string name="pref_gallery_size_summary">Selecteer de grootte van afbeeldingen in albums</string> - <string name="pref_gallery_size_title">Afbeeldinggrootte</string> - <string name="pref_gallery_slideshow_interval_dialogtitle">Diashowinterval</string> - <string name="pref_gallery_slideshow_interval_summary">Kies hoe lang elke dia wordt weergegeven</string> - <string name="pref_gallery_slideshow_interval_title">Diashowinterval</string> - <string name="pref_gallery_slideshow_repeat_dialogtitle">Diashow herhalen?</string> - <string name="pref_gallery_slideshow_repeat_summary">Selecteren om de diashow meer dan eenmaal af te spelen</string> - <string name="pref_gallery_slideshow_repeat_title">Diashow herhalen</string> - <string name="pref_gallery_slideshow_shuffle_dialogtitle">Willekeurige volgorde?</string> - <string name="pref_gallery_slideshow_shuffle_summary">Selecteren om afbeeldingen in willekeurige volgorde af te spelen</string> - <string name="pref_gallery_slideshow_shuffle_title">Willekeurige volgorde</string> - <string name="pref_gallery_slideshow_transition_dialogtitle">Diashowovergang</string> - <string name="pref_gallery_slideshow_transition_summary">Kies het effect als van de ene naar de andere dia wordt gewisseld</string> - <string name="pref_gallery_slideshow_transition_title">Diashowovergang</string> - <string name="pref_gallery_sort_dialogtitle">Afbeelding sorteren</string> - <string name="pref_gallery_sort_summary">Selecteer de volgorde van afbeeldingen in albums</string> - <string name="pref_gallery_sort_title">Afbeelding sorteren</string> - <string name="pref_slideshow_category">Diavoorstelling</string> - <string name="preferences_label">Camera-instellingen</string> - <string name="preview">Voorbld</string> - <string name="record">Opname</string> - <string name="rotate">Draaien</string> - <string name="rotate_left">Links draaien</string> - <string name="rotate_right">Rechts draaien</string> - <string name="runningFaceDetection">Een ogenblik geduld\u2026</string> - <string name="save">Opslaan</string> - <string name="savingImage">Afbeelding opslaan</string> - <string name="sec1">1 sec</string> - <string name="sec2">2 sec</string> - <string name="sec3">3 sec</string> - <string name="sec4">4 sec</string> - <string name="sec5">5 sec</string> - <string name="sendImage">Deze afbeelding delen via</string> - <string name="sendVideo">Deze video delen via</string> - <string name="set_wallpaper">Instellen als achtergrond</string> - <string name="settings">Instellingen</string> - <string name="share_youtube">YouTube</string> - <string name="slide_show">Diavoorstelling</string> - <string name="stop">Stoppen</string> - <string name="testexif">Exif testen</string> - <string name="upload">Uploaden</string> - <string name="upload_all">Alles uploaden</string> - <string name="upload_default_category_text">Entertainment</string> - <string name="upload_default_description_text">hier komt beschrijving</string> - <string name="upload_default_tags_text">video</string> - <string name="upload_dialog_title">Uploaden naar YouTube - voer videodetails in</string> - <string name="upload_info_category">Categorie:</string> - <string name="upload_info_description">Beschrijving:</string> - <string name="upload_info_private">Indien niet aangevinkt, zie je alleen de film</string> - <string name="upload_info_tags">Labels:</string> - <string name="upload_info_title">Titel:</string> - <string name="upload_info_upload">Uploaden</string> - <string name="uploadingNPhotos">Bezig met uploaden van <xliff:g id="counter">%d</xliff:g> afbeeldingen</string> - <string name="uploadingNVideos">Bezig met uploaden van <xliff:g id="counter">%d</xliff:g> video's</string> - <string name="uploading_photos">Afbeeldingen worden geüpload</string> - <string name="uploading_photos_2">Afbeeldingen worden geüpload</string> - <string name="uploading_videos">Video's worden geüpload</string> - <string name="uploading_videos_2">Video's worden geüpload</string> - <string name="video_gallery_NoImageView_text">Geen video's</string> - <string name="video_play">Afspelen</string> - <string name="videos_gallery_title">Video's</string> - <string name="view_label">Afbeelding weergeven</string> - <string name="view_video_label">Video weergeven</string> - <string name="viewimage_comments_label_text">Opmerkingen</string> - <string name="viewimage_datetaken_label_text">Datum</string> - <string name="viewimage_digitalzoom_label_text">Digitale zoom</string> - <string name="viewimage_flash_label_text">Flits gebruikt</string> - <string name="viewimage_gps_latitude_label_text">Gps-breedtegraad</string> - <string name="viewimage_gps_longitude_label_text">Gps-lengtegraad</string> - <string name="viewimage_make_label_text">Maken</string> - <string name="viewimage_model_label_text">Van</string> - <string name="viewimage_orientation_label_text">Afdrukstand</string> - <string name="viewimage_res_label_text">Resolutie</string> - <string name="viewimage_status_text">Druk op Enter of Spatie om in te zoomen</string> - <string name="wait">Een ogenblik geduld\u2026</string> - <string name="wallpaper">Achtergrond wordt ingesteld, een ogenblik geduld\u2026</string> - <string name="yes">Ja</string> - <string name="youtube_upload_label">Uploaden naar YouTube</string> - <string name="zoom">In-/uitzoomen</string> + <!-- no translation found for all_images (7177582020160054334) --> + <skip /> + <string name="camera_label">"Camera"</string> + <string name="gallery_picker_label">"Albums"</string> + <!-- no translation found for gallery_camera_bucket_name (8410686962557494439) --> + <skip /> + <!-- no translation found for switch_to_video_lable (1350915759804484157) --> + <skip /> + <!-- no translation found for switch_to_camera_lable (1823306882227066007) --> + <skip /> + <string name="crop_label">"Afbeelding inkorten"</string> + <string name="view_label">"Afbeelding weergeven"</string> + <string name="preferences_label">"Camera-instellingen"</string> + <string name="wait">"Een ogenblik geduld…"</string> + <string name="no_storage">"Plaats een sd-kaart voordat u de camera gebruikt"</string> + <string name="not_enough_space">"Deze geheugenkaart is vol"</string> + <string name="wallpaper">"Achtergrond wordt ingesteld, een ogenblik geduld…"</string> + <string name="savingImage">"Afbeelding opslaan"</string> + <string name="runningFaceDetection">"Een ogenblik geduld…"</string> + <!-- no translation found for flip_orientation (2488284515852888409) --> + <skip /> + <string name="settings">"Instellingen"</string> + <!-- no translation found for view (4639715088471766970) --> + <skip /> + <string name="details">"Details"</string> + <string name="rotate">"Draaien"</string> + <string name="rotate_left">"Links draaien"</string> + <string name="rotate_right">"Rechts draaien"</string> + <string name="slide_show">"Diavoorstelling"</string> + <string name="crop_save_text">"Opslaan"</string> + <string name="crop_discard_text">"Wissen"</string> + <!-- no translation found for camera_keep (4046418310305917657) --> + <skip /> + <!-- no translation found for confirm_delete_title (8942471980646707642) --> + <skip /> + <!-- no translation found for confirm_delete_message (6944545476499253074) --> + <skip /> + <string name="camera_toss">"Verwijderen"</string> + <string name="camera_share">"Delen"</string> + <string name="camera_set">"Instellen als…"</string> + <!-- no translation found for camera_play (6388821030721929966) --> + <skip /> + <string name="camera_crop">"Automatisch inkorten"</string> + <string name="camera_done">"Nieuwe foto"</string> + <string name="camera_tossing">"Bezig met verwijderen…"</string> + <string name="no_way_to_share_image">"De afbeelding kan niet worden opgeslagen"</string> + <string name="no_way_to_share_video">"Deze video kan niet worden gedeeld"</string> + <string name="camera_gallery_photos_text">"Afbeeldingen"</string> + <!-- no translation found for camera_pick_wallpaper (2052155470431167023) --> + <skip /> + <string name="camera_setas_wallpaper">"Achtergrond"</string> + <!-- no translation found for camera_setas_wallpaper_drm (787462863614664620) --> + <skip /> + <string name="camera_selectphoto">"Dit beeld selecteren"</string> + <string name="camera_takenewphoto">"Nieuwe afbeelding maken"</string> + <string name="pref_gallery_category">"Fotoalbumweergave"</string> + <string name="pref_slideshow_category">"Diavoorstelling"</string> + <!-- no translation found for pref_camera_general_settings_category (1720434593482716214) --> + <skip /> + <string name="pref_gallery_size_title">"Afbeeldinggrootte"</string> + <string name="pref_gallery_size_summary">"Selecteer de grootte van afbeeldingen in albums"</string> + <string name="pref_gallery_size_dialogtitle">"Afbeeldinggrootte"</string> + <!-- no translation found for pref_gallery_size_choices:0 (3341375119334343613) --> + <!-- no translation found for pref_gallery_size_choices:1 (979877976111629768) --> + <string name="pref_gallery_sort_title">"Afbeelding sorteren"</string> + <string name="pref_gallery_sort_summary">"Selecteer de volgorde van afbeeldingen in albums"</string> + <string name="pref_gallery_sort_dialogtitle">"Afbeelding sorteren"</string> + <!-- no translation found for pref_gallery_sort_choices:0 (2009184885742004467) --> + <!-- no translation found for pref_gallery_sort_choices:1 (7253524441061782381) --> + <string name="pref_gallery_slideshow_interval_title">"Diashowinterval"</string> + <string name="pref_gallery_slideshow_interval_summary">"Kies hoe lang elke dia wordt weergegeven"</string> + <string name="pref_gallery_slideshow_interval_dialogtitle">"Diashowinterval"</string> + <!-- no translation found for pref_gallery_slideshow_interval_choices:0 (3293392256331071955) --> + <!-- no translation found for pref_gallery_slideshow_interval_choices:1 (6762163459545768561) --> + <!-- no translation found for pref_gallery_slideshow_interval_choices:2 (3999753648109312132) --> + <string name="pref_gallery_slideshow_transition_title">"Diashowovergang"</string> + <string name="pref_gallery_slideshow_transition_summary">"Kies het effect als van de ene naar de andere dia wordt gewisseld"</string> + <string name="pref_gallery_slideshow_transition_dialogtitle">"Diashowovergang"</string> + <!-- no translation found for pref_gallery_slideshow_transition_choices:0 (1917959322875321005) --> + <!-- no translation found for pref_gallery_slideshow_transition_choices:1 (6508707204357284687) --> + <!-- no translation found for pref_gallery_slideshow_transition_choices:2 (5628742586795545287) --> + <!-- no translation found for pref_gallery_slideshow_transition_choices:3 (3350644769941682805) --> + <string name="pref_gallery_slideshow_repeat_title">"Diashow herhalen"</string> + <string name="pref_gallery_slideshow_repeat_summary">"Selecteren om de diashow meer dan eenmaal af te spelen"</string> + <string name="pref_gallery_slideshow_shuffle_title">"Willekeurige volgorde"</string> + <string name="pref_gallery_slideshow_shuffle_summary">"Selecteren om afbeeldingen in willekeurige volgorde af te spelen"</string> + <string name="pref_camera_recordlocation_title">"Locatie in afbeeldingen opnemen"</string> + <string name="pref_camera_recordlocation_summary">"Selecteren om de locatie automatisch op te nemen bij fotos"</string> + <!-- no translation found for pref_camera_postpicturemenu_title (6273327212867896720) --> + <skip /> + <!-- no translation found for pref_camera_postpicturemenu_summary (7911699118676137405) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_category (7460987936373873411) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_title (2766490880685686012) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_summary (6370975165195010636) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_entry_0 (8088669040921661814) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_entry_1 (3505027746158170269) --> + <skip /> + <!-- no translation found for pref_camera_videoquality_dialogtitle (1836746975783096625) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_category (907203894431470628) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_title (3330800694130697647) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_summary (8269173339100296159) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_dialogtitle (5759217298675791948) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_entry_0 (6259385536148037705) --> + <skip /> + <!-- no translation found for pref_camera_videocodec_entry_1 (3178021263058501227) --> + <skip /> + <string name="camerasettings">"Instellingen"</string> + <string name="image_gallery_NoImageView_text">"Geen afbeeldingen"</string> + <!-- no translation found for pref_gallery_confirm_delete_title (201485251343856203) --> + <skip /> + <!-- no translation found for pref_gallery_confirm_delete_summary (7235236977784533739) --> + <skip /> + <string name="details_panel_title">"Details"</string> + <string name="details_file_size">"Bestandsgrootte:"</string> + <string name="details_image_resolution">"Resolutie:"</string> + <string name="details_date_taken">"Genomen op:"</string> + <string name="context_menu_header">"Beeldopties"</string> + <string name="multiface_crop_help">"Gezicht kiezen om te starten"</string> + <string name="camera_button_hint">"Druk op de Vastlegtoets om een foto te maken"</string> + <string name="photos_gallery_title">"Afbeeldingen"</string> + <string name="pick_photos_gallery_title">"Afbeelding selecteren"</string> + <!-- no translation found for loading_progress_format_string (4252016560676330797) --> + <skip /> + <string name="sendImage">"Deze afbeelding delen via"</string> + <!-- no translation found for setImage (6676791915351726249) --> + <skip /> + <string name="sendVideo">"Deze video delen via"</string> </resources> diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml deleted file mode 100644 index 32c1e51..0000000 --- a/res/values-zh-rTW/strings.xml +++ /dev/null @@ -1,229 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="all_images">所有圖片</string> - <string name="autocrop_before_query">先裁剪?</string> - <string name="autocrop_no">是</string> - <string name="autocrop_yes">是</string> - <string name="best_res">高</string> - <string name="camera_NoStorageView_text">請先插入 SD 卡再使用相機。</string> - <string name="camera_ZoomIn_text">拉近</string> - <string name="camera_ZoomOut_text">拉遠</string> - <string name="camera_button_hint">按下拍攝鍵即可拍攝圖片。</string> - <string name="camera_crop">裁剪</string> - <string name="camera_done">新增圖片</string> - <string name="camera_flash_auto">閃光燈自動</string> - <string name="camera_flash_off">閃光燈關閉</string> - <string name="camera_flash_on">閃光燈開啟</string> - <string name="camera_flash_setting">閃光燈設定</string> - <string name="camera_gallery_photos_text">圖片</string> - <string name="camera_gallery_videos_text">影片輯</string> - <string name="camera_keep">儲存</string> - <string name="camera_keeping">正在保留\u2026</string> - <string name="camera_label">相機</string> - <string name="camera_mode_text">模式</string> - <string name="camera_movie_record_counter_text">01:30:00</string> - <string name="camera_pick_wallpaper">圖片</string> - <string name="camera_playvideo">播放</string> - <string name="camera_record_text">錄音</string> - <string name="camera_selectphoto">選取此圖片</string> - <string name="camera_selectvideo">選取此影片</string> - <string name="camera_set">設成</string> - <string name="camera_setas_contact">連絡人圖片</string> - <string name="camera_setas_myfave">我的最愛</string> - <string name="camera_setas_wallpaper">桌布</string> - <string name="camera_setas_wallpaper_drm">購買的圖片</string> - <string name="camera_share">共用</string> - <string name="camera_shareby_email">電子郵件</string> - <string name="camera_shareby_mms">多媒體簡訊</string> - <string name="camera_shareby_picasa">Picasa 網路相簿</string> - <string name="camera_shareby_picasa_all">Picasa 網路相簿 (所有圖片)</string> - <string name="camera_switch_to_photo">切換到圖片</string> - <string name="camera_switch_to_video">切換到影片</string> - <string name="camera_takenewphoto">拍攝新圖片</string> - <string name="camera_takenewvideo">拍攝新影片</string> - <string name="camera_toss">刪除</string> - <string name="camera_tossing">正在刪除\u2026</string> - <string name="camera_zoom_1_text">顯示比例 1.3x</string> - <string name="camera_zoom_2_text">顯示比例 2x</string> - <string name="camera_zoom_3_text">顯示比例 4x</string> - <string name="camera_zoom_normal_text">1x</string> - <string name="camerasettings">設定</string> - <string name="camerasettings_autoupload_label">自動將圖片上傳到網頁</string> - <string name="camerasettings_done">完成</string> - <string name="camerasettings_duration_label">持續期間:</string> - <string name="camerasettings_image_quality_label">圖片品質:</string> - <string name="camerasettings_no">否</string> - <string name="camerasettings_off">關閉</string> - <string name="camerasettings_on">開啟</string> - <string name="camerasettings_play_click_sound_label">快門聲</string> - <string name="camerasettings_preferred_view_label">偏好的檢視:</string> - <string name="camerasettings_resolution_label">解析度:</string> - <string name="camerasettings_test2_label">測試 2:</string> - <string name="camerasettings_test3_label">測試 3:</string> - <string name="camerasettings_test4_label">測試 4:</string> - <string name="camerasettings_use_sd_card_label">將圖片儲存到 SD 卡</string> - <string name="camerasettings_yes">是</string> - <string name="cancel">取消</string> - <string name="confirm_delete">確認刪除</string> - <string name="confirm_delete_message">將會刪除此圖片。</string> - <string name="confirm_delete_title">刪除</string> - <string name="context_menu_header">圖片選項</string> - <string name="crop_discard_text">放棄</string> - <string name="crop_help">按住 ALT 調整大小。</string> - <string name="crop_label">裁剪圖片</string> - <string name="crop_save_text">儲存</string> - <string name="default_value_pref_gallery_size">1</string> - <string name="default_value_pref_gallery_slideshow_interval">"2"</string> - <string name="default_value_pref_gallery_slideshow_transition">"0"</string> - <string name="default_value_pref_gallery_sort">遞減</string> - <string name="delete">刪除</string> - <string name="deny_delete">取消"</string> - <string name="details">詳細資料</string> - <string name="details_category_label">類別:</string> - <string name="details_date_taken">拍攝日期:</string> - <string name="details_description_label">說明:</string> - <string name="details_description_text">測試說明</string> - <string name="details_file_size">檔案大小:</string> - <string name="details_image_resolution">解析度:</string> - <string name="details_language_label">語言:</string> - <string name="details_panel_title">詳細資料</string> - <string name="details_privateView_text">私人</string> - <string name="details_publicView_text">公開</string> - <string name="details_save_text">儲存</string> - <string name="details_tags_label">標籤:</string> - <string name="details_tags_text">monster</string> - <string name="details_title_label">標題:</string> - <string name="details_title_text">我的影片</string> - <string name="details_uploaded_text">上傳成功</string> - <string name="edit">編輯</string> - <string name="flip_orientation">翻轉方向</string> - <string name="gallery_label">圖片</string> - <string name="gallery_large">大</string> - <string name="gallery_picker_label">圖片</string> - <string name="gallery_small">小</string> - <string name="gallerysettings_duration">投影片放映中每張投影片顯示的持續時間</string> - <string name="gallerysettings_speed1">1 秒</string> - <string name="gallerysettings_speed2">3 秒</string> - <string name="gallerysettings_speed3">5 秒</string> - <string name="high">高</string> - <string name="image_count"><xliff:g id="counter">%d</xliff:g> 張圖片</string> - <string name="image_gallery_NoImageView_text">找不到圖片。</string> - <string name="image_gallery_picker_images">圖片</string> - <string name="image_gallery_picker_videos">影片</string> - <string name="loading_progress_format_string">剩餘 <xliff:g id="counter">%d</xliff:g></string> - <string name="low">低</string> - <string name="low_res">低</string> - <string name="med">中</string> - <string name="medium_res">中</string> - <string name="multiface_crop_help">點選臉部開始。</string> - <string name="no">否</string> - <string name="no_images">空白的相簿。</string> - <string name="no_storage">請先插入 SD 卡再使用相機。</string> - <string name="no_way_to_share_image">無法儲存此圖片。</string> - <string name="no_way_to_share_video">無法共用此影片。</string> - <string name="not_enough_space">SD 卡已滿。</string> - <string name="ok">確定</string> - <string name="photos_gallery_title">圖片</string> - <string name="picasa_upload_label">上傳到 Picasa</string> - <string name="pick_photos_gallery_title">選取圖片</string> - <string name="pick_videos_gallery_title">選取影片</string> - <string name="pref_camera_autoupload_summary">自動將圖片上傳到 Picasa</string> - <string name="pref_camera_autoupload_title">自動上傳圖片</string> - <string name="pref_camera_category">相機</string> - <string name="pref_camera_postpicturemenu_summary">拍攝之後顯示動作功能表 (儲存、刪除...)</string> - <string name="pref_camera_postpicturemenu_title">拍攝之後提示</string> - <string name="pref_camera_recordlocation_summary">在圖片資料中記錄位置</string> - <string name="pref_camera_recordlocation_title">將位置儲存在圖片中</string> - <string name="pref_camera_shuttersound_summary">拍攝圖片時播放聲音</string> - <string name="pref_camera_shuttersound_title">播放快門聲</string> - <string name="pref_camera_upload_albumname_dialogtitle">Picasa 相簿名稱</string> - <string name="pref_camera_upload_albumname_summary">命名圖片的目的相簿 (<xliff:g id="summary">%s</xliff:g>)</string> - <string name="pref_camera_upload_albumname_title">Picasa 相簿名稱</string> - <string name="pref_gallery_category">一般設定</string> - <string name="pref_gallery_confirm_delete_summary">刪除圖片之前顯示確認</string> - <string name="pref_gallery_confirm_delete_title">確認刪除</string> - <string name="pref_gallery_size_dialogtitle">圖片大小</string> - <string name="pref_gallery_size_summary">選取圖片的顯示大小</string> - <string name="pref_gallery_size_title">圖片大小</string> - <string name="pref_gallery_slideshow_interval_dialogtitle">投影片放映間隔</string> - <string name="pref_gallery_slideshow_interval_summary">選取投影片放映中每張投影片顯示的時間</string> - <string name="pref_gallery_slideshow_interval_title">投影片放映間隔</string> - <string name="pref_gallery_slideshow_repeat_dialogtitle">重複投影片放映?</string> - <string name="pref_gallery_slideshow_repeat_summary">投影片放映次數超過一次</string> - <string name="pref_gallery_slideshow_repeat_title">重複投影片放映</string> - <string name="pref_gallery_slideshow_shuffle_dialogtitle">隨機播放圖片?</string> - <string name="pref_gallery_slideshow_shuffle_summary">以隨機順序顯示圖片</string> - <string name="pref_gallery_slideshow_shuffle_title">隨機播放投影片</string> - <string name="pref_gallery_slideshow_transition_dialogtitle">投影片放映轉換</string> - <string name="pref_gallery_slideshow_transition_summary">選取從一張投影片移動到下一張投影片時所使用的特效</string> - <string name="pref_gallery_slideshow_transition_title">投影片放映轉換</string> - <string name="pref_gallery_sort_dialogtitle">圖片排序</string> - <string name="pref_gallery_sort_summary">選取圖片的排序方式</string> - <string name="pref_gallery_sort_title">圖片排序</string> - <string name="pref_slideshow_category">投影片放映設定</string> - <string name="preferences_label">相機設定</string> - <string name="preview">預覽</string> - <string name="record">錄音</string> - <string name="rotate">旋轉</string> - <string name="rotate_left">向左旋轉</string> - <string name="rotate_right">向右旋轉</string> - <string name="runningFaceDetection">請稍候\u2026</string> - <string name="save">儲存</string> - <string name="savingImage">正在儲存圖片\u2026</string> - <string name="sec1">1 秒</string> - <string name="sec2">2 秒</string> - <string name="sec3">3 秒</string> - <string name="sec4">4 秒</string> - <string name="sec5">5 秒</string> - <string name="sendImage">共用圖片</string> - <string name="sendVideo">共用影片</string> - <string name="setImage">將圖片設成</string> - <string name="set_wallpaper">設成桌布</string> - <string name="settings">設定</string> - <string name="share_youtube">YouTube</string> - <string name="slide_show">投影片放映</string> - <string name="space_remaining_k"><xliff:g id="counter">%d</xliff:g>K</string> - <string name="stop">停止</string> - <string name="testexif">測試 Exif</string> - <string name="upload">上傳</string> - <string name="upload_all">全部上傳</string> - <string name="upload_default_category_text">娛樂</string> - <string name="upload_default_description_text">在此輸入說明</string> - <string name="upload_default_tags_text">影片</string> - <string name="upload_dialog_title">上傳到 YouTube - 輸入影片詳細資料</string> - <string name="upload_info_category">類別:</string> - <string name="upload_info_description">說明:</string> - <string name="upload_info_private">如果取消勾選此選項,則只有您可以觀看此電影</string> - <string name="upload_info_tags">標籤:</string> - <string name="upload_info_title">標題:</string> - <string name="upload_info_upload">上傳</string> - <string name="uploadingNPhotos">正在上傳 <xliff:g id="counter">%d</xliff:g> 張圖片</string> - <string name="uploadingNVideos">正在上傳 <xliff:g id="counter">%d</xliff:g> 段影片</string> - <string name="uploading_photos">正在上傳圖片</string> - <string name="uploading_photos_2">正在上傳圖片</string> - <string name="uploading_videos">正在上傳影片</string> - <string name="uploading_videos_2">正在上傳影片</string> - <string name="video_gallery_NoImageView_text">找不到影片。</string> - <string name="video_play">播放</string> - <string name="videos_gallery_title">影片</string> - <string name="view">檢視</string> - <string name="view_label">檢視圖片</string> - <string name="view_video_label">檢視影片</string> - <string name="viewimage_comments_label_text">註解</string> - <string name="viewimage_datetaken_label_text">日期</string> - <string name="viewimage_digitalzoom_label_text">數位顯示比例</string> - <string name="viewimage_flash_label_text">使用 Flash</string> - <string name="viewimage_gps_latitude_label_text">GPS 緯度</string> - <string name="viewimage_gps_longitude_label_text">GPS 經度</string> - <string name="viewimage_make_label_text">製造</string> - <string name="viewimage_model_label_text">從</string> - <string name="viewimage_orientation_label_text">方向</string> - <string name="viewimage_res_label_text">解析度</string> - <string name="viewimage_status_text">按下 Enter 或 Space 來顯示比例。</string> - <string name="wait">請稍候\u2026</string> - <string name="wallpaper">正在設定桌布,請稍候\u2026</string> - <string name="yes">是</string> - <string name="youtube_upload_label">YouTube 上傳</string> - <string name="zoom">顯示比例</string> -</resources> diff --git a/res/values/arrays.xml b/res/values/arrays.xml new file mode 100644 index 0000000..95501e4 --- /dev/null +++ b/res/values/arrays.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + --> + +<resources> + <!-- Camera Preferences Video Quality dialog box entries --> + <string-array name="pref_camera_videoquality_entries"> + <item>@string/pref_camera_videoquality_entry_0</item> + <item>@string/pref_camera_videoquality_entry_1</item> + </string-array> + + <!-- Do not localize entryvalues --> + <string-array name="pref_camera_videoquality_entryvalues"> + <item>0</item> + <item>1</item> + </string-array> + +</resources> diff --git a/res/values/colors.xml b/res/values/colors.xml new file mode 100644 index 0000000..d07f3b9 --- /dev/null +++ b/res/values/colors.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/assets/res/any/colors.xml +** +** Copyright 2008, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<resources> + <color name="bubble_dark_background">#B2191919</color> +</resources> diff --git a/res/values/ids.xml b/res/values/ids.xml index d60f413..367bfa2 100644 --- a/res/values/ids.xml +++ b/res/values/ids.xml @@ -17,17 +17,6 @@ */ --> <resources> - <item type="id" name="autoupload" /> - <item type="id" name="duration" /> - <item type="id" name="imagequality" /> - <item type="id" name="playclicksound" /> - <item type="id" name="preferred_gallery_view" /> - <item type="id" name="resolution" /> - <item type="id" name="t2" /> - <item type="id" name="t3" /> - <item type="id" name="t4" /> - <item type="id" name="usesd" /> - <item type="id" name="slideshowdelay" /> </resources> diff --git a/res/values/strings.xml b/res/values/strings.xml index e5b47fb..d465c52 100755..100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -17,352 +17,413 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- General strings --> + <!-- label for the icon meaning 'show me all the images' --> <string name="all_images">All pictures</string> - <string name="image_count"><xliff:g id="counter">%d</xliff:g> pictures</string> + <!-- label for the icon meaning 'show me all the videos' --> + <string name="all_videos">All videos</string> + + <!-- label for the icon meaning 'show me all the images that were taken with the camera' --> <string name="camera_label">Camera</string> - <string name="gallery_picker_label">Pictures</string> + + <!-- label for the 'pictures application shown in the top level 'all applications' --> + <string name="gallery_picker_label">Gallery</string> + + <!-- unused (do not translate) --> <string name="gallery_label">Pictures</string> + + <!-- label for the folder that contains Camera pictures in the gallery --> + <string name="gallery_camera_bucket_name">Camera pictures</string> + + <!-- label for the folder that contains Camera videos in the gallery --> + <string name="gallery_camera_videos_bucket_name">Camera videos</string> + + <!-- menu pick: switch to Video cam mode --> + <string name="switch_to_video_lable">Switch to video</string> + + <!-- menu pick: switch to camera mode --> + <string name="switch_to_camera_lable">Switch to camera</string> + + <!-- menu pick: crop the currently selected image --> <string name="crop_label">Crop picture</string> + + <!-- menu pick: view the currently selected image --> <string name="view_label">View picture</string> - <string name="view_video_label">View video</string> + + <!-- menu pick: go to the preferences screen for the camera or image gallery --> <string name="preferences_label">Camera settings</string> - <string name="picasa_upload_label">Picasa upload</string> - <string name="youtube_upload_label">YouTube upload</string> - - <string name="ok">OK</string> - <string name="stop">Stop</string> - <string name="record">Record</string> + + <!-- alert to the user to wait for some operation to complete --> <string name="wait">Please wait\u2026</string> + + <!-- alert to the user to that an SD card must be installed before using the camera --> <string name="no_storage">Please insert an SD card before using the camera.</string> + + <!-- alert to the user to that the SD card is too full to complete the operation --> <string name="not_enough_space">Your SD card is full.</string> - <string name="no_images">Your album is empty.</string> + + <!-- Toast/alert after saving wallpaper --> <string name="wallpaper">Setting wallpaper, please wait\u2026</string> - <string name="gallery_small">Small</string> - <string name="gallery_large">Large</string> <!-- Settings stuff --> - <string name="high">High</string> - <string name="med">Medium</string> - <string name="low">Low</string> - - <string name="best_res">High</string> - <string name="medium_res">Medium</string> - <string name="low_res">Low</string> - - <string name="sec1">1 sec</string> - <string name="sec2">2 secs</string> - <string name="sec3">3 secs</string> - <string name="sec4">4 secs</string> - <string name="sec5">5 secs</string> - - <string name="yes">Yes</string> - <string name="no">No</string> + <!-- Toast/alert that the image is being saved to the SD card --> <string name="savingImage">Saving picture\u2026</string> - <string name="runningFaceDetection">Please wait\u2026</string> + + <!-- Toast/alert that the face detection is being run --> + <string name="runningFaceDetection">Please wait\u2026</string> - <!-- Menu stuff --> + <!-- Menu items: --> + <!-- menu pick to change the orientation of the screen --> <string name="flip_orientation">Flip orientation</string> + + <!-- menu pick to go to the settings screen --> <string name="settings">Settings</string> - <string name="zoom">Zoom</string> - <string name="testexif">Test Exif</string> - + + <!-- menu pick to view the currently selected image --> <string name="view">View</string> - <string name="delete">Delete</string> + + <!-- menu pick to view the details of the currently selected image --> <string name="details">Details</string> + + <!-- menu pick to rotate the currently selected image (brings up submenu) --> <string name="rotate">Rotate</string> + + <!-- menu pick to rotate the currently selected image to the left --> <string name="rotate_left">Rotate left</string> + + <!-- menu pick to rotate the currently selected image to the right --> <string name="rotate_right">Rotate right</string> - <string name="set_wallpaper">Set as wallpaper</string> + + <!-- menu pick to start a slide show --> <string name="slide_show">Slideshow</string> - <string name="confirm_delete">Confirm delete</string> - <string name="deny_delete">Cancel"</string> + <!-- menu pick to go to camera mode to capture a picture --> + <string name="capture_picture">Capture picture</string> + <!-- menu pick to go to video mode to capture a video --> + <string name="capture_video">Capture video</string> - <string name="upload">Upload</string> - <string name="upload_all">Upload all</string> - <string name="uploading_photos">Uploading pictures</string> - <string name="uploading_photos_2">Uploading pictures</string> - <string name="uploading_videos">Uploading videos</string> - <string name="uploading_videos_2">Uploading videos</string> - <string name="uploadingNPhotos">Uploading <xliff:g id="counter">%d</xliff:g> pictures</string> - <string name="uploadingNVideos">Uploading <xliff:g id="counter">%d</xliff:g> videos</string> - - <string name="preview">Preview</string> - <string name="edit">Edit</string> - <string name="cancel">Cancel</string> - <string name="save">Save</string> - - <string name="crop_help">Hold ALT to resize.</string> + <!-- button indicating that the cropped image should be saved --> <string name="crop_save_text">Save</string> + <!-- button indicating that the cropped image should be reverted back to the original --> <string name="crop_discard_text">Discard</string> - - <string name="camera_mode_text">Mode</string> - <string name="camera_record_text">Record</string> - <string name="camera_keep">Save</string> + <!-- Confirmation dialog title after deleting a picture --> <string name="confirm_delete_title">Delete</string> + <!-- Confirmation dialog message after deleting a picture --> <string name="confirm_delete_message">The picture will be deleted.</string> - + <!-- Confirmation dialog message after deleting a video --> + <string name="confirm_delete_video_message">The video will be deleted.</string> + <!-- button indicating that the picture just taken should be deleted --> <string name="camera_toss">Delete</string> + + <!-- button indicating that the picture just taken should be shared by email, mms, etc --> <string name="camera_share">Share</string> + + <!-- button indicating that the picture just taken should be set as a contact photo, wallpaper, etc --> <string name="camera_set">Set as</string> - <string name="camera_crop">Crop</string> - <string name="camera_done">New picture</string> + + <!-- button indicating that the video just taken should be played --> + <string name="camera_play">Play</string> + <!-- button indicating that the picture just taken should be cropped --> + <string name="camera_crop">Crop</string> + + <!-- Toast after deleting a picture --> <string name="camera_tossing">Deleting\u2026</string> - <string name="camera_keeping">Keeping\u2026</string> - <string name="camera_flash_setting">Flash setting</string> - <string name="no_way_to_share_image">This picture cannot be saved.</string> + <!-- Toast after trying to share a picture indicating that there are no applications which are capable of so doing. --> + <string name="no_way_to_share_image">This picture cannot be shared.</string> + + <!-- Toast after trying to share a video indicating that there are no applications which are capable of so doing. --> <string name="no_way_to_share_video">This video cannot be shared.</string> - <string name="autocrop_before_query">Crop before?</string> - <string name="autocrop_yes">Yes</string> - <string name="autocrop_no">Yes</string> + <!-- Do not translate --> <string name="video_play">Play</string> - <string name="share_youtube">YouTube</string> - <string name="camera_switch_to_video">Switch to video</string> - <string name="camera_switch_to_photo">Switch to picture</string> + <!-- Button indicating to go to the image gallery --> + <string name="camera_gallery_photos_text">Gallery</string> - <string name="camera_NoStorageView_text">Please insert an SD card before using the camera.</string> - <string name="camera_ZoomIn_text">Zoom in</string> - <string name="camera_ZoomOut_text">Zoom out</string> - <string name="camera_movie_record_counter_text">01:30:00</string> - <string name="camera_gallery_photos_text">Pictures</string> - <string name="camera_gallery_videos_text">Video Album</string> - - <string name="camera_shareby_email">Email</string> - <string name="camera_shareby_mms">MMS</string> - <string name="camera_shareby_picasa">Picasaweb</string> - <string name="camera_shareby_picasa_all">Picasaweb (all pictures)</string> - - <string name="camera_flash_auto">AutoFlash</string> - <string name="camera_flash_on">Flash ON</string> - <string name="camera_flash_off">Flash OFF</string> - + <!-- String indicating an action of picking a picture to use as wallpaper (e.g. set wallpaper from "Pictures") --> <string name="camera_pick_wallpaper">Pictures</string> <string name="camera_setas_wallpaper">Wallpaper</string> <string name="camera_setas_wallpaper_drm">Purchased pictures</string> - <string name="camera_setas_contact">Contact picture</string> - <string name="camera_setas_myfave">myFaves</string> <string name="camera_selectphoto">Select this picture</string> + + <!-- Button indicating to skip the picture just taken and take another one (this is used + when the camera is invoked for the purpose of returning a picture to another activity + such as a contacts photo). --> <string name="camera_takenewphoto">Capture new picture</string> - <string name="camera_selectvideo">Select this video</string> + <!-- Do not translate --> <string name="camera_takenewvideo">Capture new video</string> - <string name="camera_playvideo">Play</string> + <!-- Settings screen, section heading --> <string name="pref_gallery_category">General settings</string> + + <!-- Settings screen, section heading --> <string name="pref_slideshow_category">Slideshow settings</string> - <string name="pref_camera_category">Camera</string> + <string name="pref_camera_general_settings_category">General settings</string> + <!-- Settings screen, setting summary text --> <string name="pref_gallery_size_title">Picture size</string> + + <!-- Settings screen, title for preference for image size to be used in the im --> <string name="pref_gallery_size_summary">Select the display size of pictures</string> + <!-- Title of dialog that appears after selecting Picture size setting option --> <string name="pref_gallery_size_dialogtitle">Picture size</string> + <!-- Options in dialog that appears after selecting Picture size setting option --> <string-array name="pref_gallery_size_choices"> + <!-- size choice of "large" --> <item>Large</item> + <!-- size choice of "small" --> <item>Small</item> </string-array> - + <!-- Do not translate. Option values in dialog that appears after selecting Picture size setting option --> <string-array name="pref_gallery_size_values"> + <!-- do not translate --> <item>1</item> + <!-- do not translate --> <item>0</item> </string-array> + <!-- Do not translate. Default option value in dialog that appears after selecting Picture size setting option --> <string name="default_value_pref_gallery_size">1</string> - + <!-- Settings screen, setting option name --> <string name="pref_gallery_sort_title">Picture sort</string> + <!-- Settings screen, setting summary text --> <string name="pref_gallery_sort_summary">Select the sort order of pictures</string> + <!-- Title of dialog that appears after selecting Picture sort setting option --> <string name="pref_gallery_sort_dialogtitle">Picture sort</string> + <!-- Options in dialog that appears after selecting Picture sort setting option --> <string-array name="pref_gallery_sort_choices"> + <!-- Preference choice to show "newest first" --> <item>Newest first</item> + <!-- Preference choice to show "newest last" --> <item>Newest last</item> </string-array> - + <!-- Do not translate. Option values in dialog that appears after selecting Picture sort setting option --> <string-array name="pref_gallery_sort_values"> + <!-- do not translate --> <item>descending</item> + <!-- do not translate --> <item>ascending</item> </string-array> + <!-- Do not translate. Default option value in dialog that appears after selecting Picture sort setting option --> <string name="default_value_pref_gallery_sort">descending</string> - + <!-- Settings screen, setting option name --> <string name="pref_gallery_slideshow_interval_title">Slideshow interval</string> + <!-- Settings screen, setting summary text --> <string name="pref_gallery_slideshow_interval_summary">Select how long each slide displays in the show</string> + <!-- Title of dialog that appears after selecting Slideshow interval setting option --> <string name="pref_gallery_slideshow_interval_dialogtitle">Slideshow interval</string> + <!-- Options in dialog that appears after selecting Slideshow interval + setting option --> <string-array name="pref_gallery_slideshow_interval_choices"> - <item>2 seconds</item> + <!-- slide show interval "N seconds" where N is 2 --> + <item>2 seconds</item> + <!-- slide show interval "N seconds" where N is 3 --> <item>3 seconds</item> + <!-- slide show interval "N seconds" where N is 4 --> <item>4 seconds</item> </string-array> - + <!-- Do not translate. Option values in dialog that appears after selecting Slideshow interval setting option --> <string-array name="pref_gallery_slideshow_interval_values"> - <item>"2"</item> + <!-- do not translate --> + <item>"2"</item> + <!-- do not translate --> <item>"3"</item> + <!-- do not translate --> <item>"4"</item> </string-array> + <!-- Do not translate. Default option value in dialog that appears after selecting Slideshow interval setting option --> <string name="default_value_pref_gallery_slideshow_interval">"2"</string> - + <!-- Settings screen, setting option name --> <string name="pref_gallery_slideshow_transition_title">Slideshow transition</string> + <!-- Settings screen, setting summary text --> <string name="pref_gallery_slideshow_transition_summary">Select the effect used when moving from one slide to the next</string> + <!-- Title of dialog that appears after selecting Slideshow transition setting option --> <string name="pref_gallery_slideshow_transition_dialogtitle">Slideshow transition</string> + <!-- Options in dialog that appears after selecting Slideshow transition + setting option --> <string-array name="pref_gallery_slideshow_transition_choices"> - <item>Fade in & out</item> + <!-- Slide show transition to fade in and fade out --> + <item>Fade in & out</item> + <!-- Slide show transition to slide in and out from the left and right --> <item>Slide left - right</item> + <!-- Slide show transition to slide in and out from the top and bottom --> <item>Slide up - down</item> + <!-- Slide show transition to be chosen randomly --> <item>Random selection</item> </string-array> - + <!-- Do not translate. Option values in dialog that appears after selecting Slideshow transition setting option --> <string-array name="pref_gallery_slideshow_transition_values"> - <item>"0"</item> - <item>"1"</item> + <!-- do not translate --> + <item>"0"</item> + <!-- do not translate --> + <item>"1"</item> + <!-- do not translate --> <item>"2"</item> + <!-- do not translate --> <item>"-1"</item> </string-array> + <!-- Do not translate. Default option value in dialog that appears after selecting Slideshow transition setting option --> <string name="default_value_pref_gallery_slideshow_transition">"0"</string> - + + <!-- Settings screen, setting check box name --> <string name="pref_gallery_slideshow_repeat_title">Repeat slideshow</string> + + <!-- Settings screen, setting summary text --> <string name="pref_gallery_slideshow_repeat_summary">Play slideshow more than once</string> - <string name="pref_gallery_slideshow_repeat_dialogtitle">Repeat slideshow?</string> - + + <!-- Settings screen, setting check box name --> <string name="pref_gallery_slideshow_shuffle_title">Shuffle slides</string> + + <!-- Settings screen, setting summary text --> <string name="pref_gallery_slideshow_shuffle_summary">Show pictures in random order</string> - <string name="pref_gallery_slideshow_shuffle_dialogtitle">Shuffle pictures?</string> - - <string name="pref_camera_autoupload_title">Auto-upload pictures</string> - <string name="pref_camera_autoupload_summary">Upload pictures to Picasa automatically</string> + <!-- Settings screen, setting title text --> <string name="pref_camera_recordlocation_title">Store location in pictures</string> - <string name="pref_camera_recordlocation_summary">Record location in picture data</string> - <string name="pref_camera_shuttersound_title">Play shutter sound</string> - <string name="pref_camera_shuttersound_summary">Play a sound when taking a picture</string> + <!-- Settings screen, setting summary text --> + <string name="pref_camera_recordlocation_summary">Record location in picture data</string> + <!-- Do not translate --> <string name="pref_camera_upload_albumname_title">Picasa album name</string> + + <!-- Do not translate --> <string name="pref_camera_upload_albumname_summary">Name the destination album for your pictures (<xliff:g id="summary">%s</xliff:g>)</string> + + <!-- Do not translate --> <string name="pref_camera_upload_albumname_dialogtitle">Picasa album name</string> + <!-- Settings screen, setting title text --> <string name="pref_camera_postpicturemenu_title">Prompt after capture</string> - <string name="pref_camera_postpicturemenu_summary">Display action menu (save, delete, ...) after capture</string> - <string name="camerasettings_preferred_view_label">Preferred view:</string> + <!-- Settings screen, setting summary text --> + <string name="pref_camera_postpicturemenu_summary">Display action menu (save, delete, \u2026) after capture</string> + + <!-- Settings screen, Video quality category title --> + <string name="pref_camera_videoquality_category">Video quality</string> + + <!-- Default video quality setting. A numerical value. Do not translate. --> + <string name="pref_camera_videoquality_default">0</string> + + <!-- Settings screen, Video quality title --> + <string name="pref_camera_videoquality_title">Video quality</string> + + <!-- Settings screen, Video quality summary --> + <string name="pref_camera_videoquality_summary">Select video quality level</string> + + <!-- Settings screen, Video quality dialog radio button choices --> + <string name="pref_camera_videoquality_entry_0">Low (for MMS messages)</string> + <string name="pref_camera_videoquality_entry_1">High (for SD card)</string> + + <!-- Settings screen, Video codec dialog title --> + <string name="pref_camera_videoquality_dialogtitle">Video quality</string> + + <!-- Menu item to go to the settings screen --> <string name="camerasettings">Settings</string> - <string name="camerasettings_autoupload_label">Automatically upload pictures to Web</string> - <string name="camerasettings_test2_label">test2:</string> - <string name="camerasettings_test3_label">test3:</string> - <string name="camerasettings_play_click_sound_label">Shutter sound</string> - <string name="camerasettings_resolution_label">Resolution:</string> - <string name="camerasettings_test4_label">test4:</string> - <string name="camerasettings_duration_label">Duration:</string> - <string name="camerasettings_use_sd_card_label">Save pictures to SD card</string> - <string name="camerasettings_image_quality_label">Picture quality:</string> - <string name="camerasettings_on">On</string> - <string name="camerasettings_off">Off</string> - <string name="camerasettings_yes">Yes</string> - <string name="camerasettings_no">No</string> - <string name="camerasettings_done">Done</string> - - <string name="gallerysettings_duration">Duration of each slide in slideshows</string> - - <!-- The actual seconds are hardwired in GallerySettings.java. These are just labels. --> - <string name="gallerysettings_speed1">1 second</string> - <string name="gallerysettings_speed2">3 seconds</string> - <string name="gallerysettings_speed3">5 seconds</string> - - <string name="image_gallery_status_text"></string> - <string name="image_gallery_NoImageView_text">No pictures found.</string> - <string name="video_gallery_NoImageView_text">No videos found.</string> - <string name="image_gallery_picker_images">Pictures</string> - <string name="image_gallery_picker_videos">Videos</string> + <!-- Text message indicating that there are no pictures on the SD card --> + <string name="image_gallery_NoImageView_text">No pictures found.</string> + <!-- Preference title for whether the user should be prompted form confirmation when deleting images --> <string name="pref_gallery_confirm_delete_title">Confirm deletions</string> + + <!-- Preference summary for whether the user should be prompted form confirmation when deleting images --> <string name="pref_gallery_confirm_delete_summary">Show confirmation before deleting pictures</string> - <string name="viewimage_gps_latitude_label_text">GPS latitude</string> - <string name="viewimage_res_label_text">Resolution</string> - <string name="viewimage_make_label_text">Make</string> - <string name="viewimage_comments_text"></string> - <string name="viewimage_digitalzoom_text"></string> - <string name="viewimage_orientation_label_text">Orientation</string> - <string name="viewimage_res_text"></string> - <string name="viewimage_gps_longitude_label_text">GPS longitude</string> - <string name="viewimage_model_text"></string> - <string name="viewimage_gps_longitude_text"></string> - <string name="viewimage_make_text"></string> - <string name="viewimage_status_text">Press Enter or Space to zoom.</string> - <string name="viewimage_comments_label_text">Comments</string> - <string name="viewimage_flash_text"></string> - <string name="viewimage_digitalzoom_label_text">Digital zoom</string> - <string name="viewimage_orientation_text"></string> - <string name="viewimage_flash_label_text">Flash used</string> - <string name="viewimage_gps_latitude_text"></string> - <string name="viewimage_datetaken_text"></string> - <string name="viewimage_model_label_text">From</string> - <string name="viewimage_datetaken_label_text">Date</string> - - <string name="camera_zoom_3_text">Zoom 4x</string> - <string name="camera_zoom_2_text">Zoom 2x</string> - <string name="camera_zoom_1_text">Zoom 1.3x</string> - <string name="camera_zoom_normal_text">1x</string> - - <!-- Details stuff --> + <!-- Details stuff --> + <!-- Do not translate --> <string name="details_title_text">myvideo</string> - <string name="details_uploaded_text">Successfully uploaded</string> + <!-- Do not translate --> <string name="details_tags_text">monster</string> + <!-- Do not translate --> <string name="details_category_label">Category:</string> + <!-- Do not translate --> <string name="details_description_label">Description:</string> + <!-- Do not translate --> <string name="details_publicView_text">Public</string> + <!-- Do not translate --> <string name="details_tags_label">Tags:</string> + <!-- Do not translate --> <string name="details_description_text">testdescription</string> + <!-- Do not translate --> <string name="details_title_label">Title:</string> + <!-- Do not translate --> <string name="details_save_text">Save</string> + <!-- Do not translate --> <string name="details_language_label">Language:</string> + <!-- Do not translate --> <string name="details_privateView_text">Private</string> + + <!-- Title of Details dialog --> + <string name="details_panel_title">Details</string> + <!-- Label in message of Details dialog --> + <string name="details_file_size">File size:</string> + <!-- Label in message of Details dialog --> + <string name="details_image_resolution">Resolution:</string> + <!-- Label in message of Details dialog --> + <string name="details_date_taken">Date taken:</string> - <!-- Upload stuff --> - <string name="upload_default_tags_text">video</string> - <string name="upload_default_description_text">description goes here</string> - <string name="upload_default_category_text">Entertainment</string> - - <string name="details_panel_title">Details</string> - - <string name="details_file_size">File size:</string> - <string name="details_image_resolution">Resolution:</string> - <string name="details_date_taken">Date taken:</string> - - <string name="context_menu_header">Picture options</string> - - <string name="multiface_crop_help">Tap a face to begin.</string> - <string name="camera_button_hint">Press Capture button to take picture.</string> - - <string name="photos_gallery_title">Pictures</string> - <string name="videos_gallery_title">Videos</string> - <string name="pick_photos_gallery_title">Select picture</string> - <string name="pick_videos_gallery_title">Select video</string> + <!-- Text of context menu when an image is selected --> + <string name="context_menu_header">Picture options</string> + <!-- Text of context menu when a video is selected --> + <string name="video_context_menu_header">Video options</string> + <!-- Hint that appears when cropping an image with more than one face --> + <string name="multiface_crop_help">Tap a face to begin.</string> + <!-- Hint/toast that appears when user first opens capture screen on still picture camera --> + <string name="camera_button_hint">Press Capture button to take picture.</string> + <!-- Hint/toast that appears when user first opens capture screen on video camera --> + <string name="video_camera_button_hint">Press Capture button to record video.</string> - <!-- YouTube upload stuff --> - <string name="upload_info_title">Title:</string> - <string name="upload_info_description">Description:</string> - <string name="upload_info_category">Category:</string> - <string name="upload_info_tags">Tags:</string> - <string name="upload_info_upload">Upload</string> - <string name="upload_info_private">If unchecked, only you can see the movie</string> - <string name="upload_dialog_title">Upload to YouTube - type video details</string> + <!-- Activity title when in the image gallery to see pictures --> + <string name="photos_gallery_title">Gallery</string> + + <!-- Activity title when in the image gallery to select a picture --> + <string name="pick_photos_gallery_title">Select picture</string> + + <!-- Activity title when in the image gallery to see videos --> + <string name="videos_gallery_title">Gallery</string> + + <!-- Activity title when in the image gallery to select a video --> + <string name="pick_videos_gallery_title">Select video</string> + <!-- onscreen text indicating the progress of generating thumbnails. Basically some number followed by the word "remaining" --> <string name="loading_progress_format_string"><xliff:g id="counter">%d</xliff:g> remaining</string> - <string name="space_remaining_k"><xliff:g id="counter">%d</xliff:g>K</string> - - <!-- Displayed in the title of the chooser for things to do with an image that - is to be sent to another application. --> + <!-- Displayed in the title of the dialog for things to do with a picture that + is to be sent to another application: --> <string name="sendImage">Share picture via</string> + + <!-- Displayed in the title of the dialog for things to do with a picture that + is to be "set as" (e.g. set as contact photo or set as wallpaper) --> <string name="setImage">Set picture as</string> - <!-- Displayed in the title of the chooser for things to do with a video that + <!-- Displayed in the title of the dialog for things to do with a video that is to be sent to another application. --> <string name="sendVideo">Share video via</string> + + <!-- Activity label. This might show up in the activity-picker --> + <string name="movieviewlabel">Movies</string> + <!-- shown in the video player view while the video is being loaded, before it starts playing --> + <string name="loading_video">Loading video\u2026</string> + + <!-- Displayed as a toast when a picture is saved --> + <string name="picture_saved">Picture saved to SD card.</string> + <!-- Displayed as a toast when a picture is deleted --> + <string name="picture_deleted">Picture deleted.</string> + + <!-- Displayed as a toast when a video is saved --> + <string name="video_saved">Video saved to SD card.</string> + <!-- Displayed as a toast when a video is deleted --> + <string name="video_deleted">Video deleted.</string> + + <!-- Low-memory dialog title --> + <string name="spaceIsLow_title">Space is low</string> + <!-- Low-memory dialog message --> + <string name="spaceIsLow_content">Your SD card is running out of space. Change the quality setting or delete items from Gallery.</string> </resources> diff --git a/res/values/styles.xml b/res/values/styles.xml new file mode 100644 index 0000000..726a952 --- /dev/null +++ b/res/values/styles.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +* Copyright (C) 2008 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +--> + +<resources xmlns:android="http://schemas.android.com/apk/res/android"> + <style name="OnscreenActionIcon"> + <item name="android:focusable">true</item> + <item name="android:clickable">true</item> + <item name="android:textSize">13dip</item> + <item name="android:singleLine">true</item> + <item name="android:ellipsize">marquee</item> + <item name="android:shadowColor">#FF000000</item> + <item name="android:shadowRadius">2.0</item> + <item name="android:textColor">#FFF</item> + <item name="android:gravity">center_horizontal</item> + <item name="android:layout_width">fill_parent</item> + <item name="android:layout_height">fill_parent</item> + <item name="android:paddingLeft">5dip</item> + <item name="android:paddingRight">5dip</item> + <item name="android:drawablePadding">3dip</item> + <item name="android:paddingTop">2dip</item> + <item name="android:layout_marginLeft">10dip</item> + <item name="android:layout_marginRight">10dip</item> + </style> +</resources> diff --git a/res/xml/camera_preferences.xml b/res/xml/camera_preferences.xml index c4dab52..77c01b3 100644 --- a/res/xml/camera_preferences.xml +++ b/res/xml/camera_preferences.xml @@ -19,7 +19,7 @@ xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory - android:title="@string/pref_camera_category"> + android:title="@string/pref_camera_general_settings_category"> <!-- <CheckBoxPreference android:key="pref_camera_autoupload_key" @@ -49,5 +49,16 @@ android:summary="@string/pref_camera_postpicturemenu_summary" android:defaultValue="true"/> </PreferenceCategory> - + + <PreferenceCategory + android:title="@string/pref_camera_videoquality_category"> + <ListPreference + android:key="pref_camera_videoquality_key" + android:defaultValue="@string/pref_camera_videoquality_default" + android:title="@string/pref_camera_videoquality_title" + android:summary="@string/pref_camera_videoquality_summary" + android:entries="@array/pref_camera_videoquality_entries" + android:entryValues="@array/pref_camera_videoquality_entryvalues" + android:dialogTitle="@string/pref_camera_videoquality_dialogtitle" /> + </PreferenceCategory> </PreferenceScreen> diff --git a/src/com/android/camera/ActionMenuButton.java b/src/com/android/camera/ActionMenuButton.java new file mode 100644 index 0000000..65e1f0e --- /dev/null +++ b/src/com/android/camera/ActionMenuButton.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import android.text.Layout; +import android.util.AttributeSet; +import android.widget.TextView; + +/** + * TextView that draws a bubble behind the text. We cannot use a LineBackgroundSpan + * because we want to make the bubble taller than the text and TextView's clip is + * too aggressive. + */ +public class ActionMenuButton extends TextView { + private static final float CORNER_RADIUS = 8.0f; + private static final float PADDING_H = 5.0f; + private static final float PADDING_V = 1.0f; + + private final RectF mRect = new RectF(); + private Paint mPaint; + + public ActionMenuButton(Context context) { + super(context); + init(); + } + + public ActionMenuButton(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public ActionMenuButton(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + private void init() { + setFocusable(true); + + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPaint.setColor(getContext().getResources().getColor(R.color.bubble_dark_background)); + } + + @Override + protected void drawableStateChanged() { + invalidate(); + super.drawableStateChanged(); + } + + @Override + public void draw(Canvas canvas) { + final Layout layout = getLayout(); + final RectF rect = mRect; + final int left = getCompoundPaddingLeft(); + final int top = getExtendedPaddingTop(); + + rect.set(left + layout.getLineLeft(0) - PADDING_H, + top + layout.getLineTop(0) - PADDING_V, + Math.min(left + layout.getLineRight(0) + PADDING_H, mScrollX + mRight - mLeft), + top + layout.getLineBottom(0) + PADDING_V); + canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, mPaint); + + super.draw(canvas); + } +} diff --git a/src/com/android/camera/BufferedInputStream.java b/src/com/android/camera/BufferedInputStream.java deleted file mode 100644 index 1505e87..0000000 --- a/src/com/android/camera/BufferedInputStream.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.camera; -/* -* This file derives from the Apache version of the BufferedInputStream. -* Mods to support passing in the buffer rather than creating one directly. -*/ -import java.io.InputStream; -import java.io.FilterInputStream; -import java.io.IOException; - -public class BufferedInputStream extends FilterInputStream { - protected byte[] buf; - protected int count; - protected int marklimit; - protected int markpos = -1; - protected int pos; - - private boolean closed = false; - - public BufferedInputStream(InputStream in, byte [] buffer) { - super(in); - buf = buffer; - if (buf == null) { - throw new java.security.InvalidParameterException(); - } - } - - @Override - public synchronized int available() throws IOException { - return count - pos + in.available(); - } - - @Override - public synchronized void close() throws IOException { - if (null != in) { - super.close(); - in = null; - } - buf = null; - closed = true; - } - - private int fillbuf() throws IOException { - if (markpos == -1 || (pos - markpos >= marklimit)) { - /* Mark position not set or exceeded readlimit */ - int result = in.read(buf); - if (result > 0) { - markpos = -1; - pos = 0; - count = result == -1 ? 0 : result; - } - return result; - } - if (markpos == 0 && marklimit > buf.length) { - /* Increase buffer size to accomodate the readlimit */ - int newLength = buf.length * 2; - if (newLength > marklimit) { - newLength = marklimit; - } - byte[] newbuf = new byte[newLength]; - System.arraycopy(buf, 0, newbuf, 0, buf.length); - buf = newbuf; - } else if (markpos > 0) { - System.arraycopy(buf, markpos, buf, 0, buf.length - markpos); - } - /* Set the new position and mark position */ - pos -= markpos; - count = markpos = 0; - int bytesread = in.read(buf, pos, buf.length - pos); - count = bytesread <= 0 ? pos : pos + bytesread; - return bytesread; - } - - @Override - public synchronized void mark(int readlimit) { - marklimit = readlimit; - markpos = pos; - } - - @Override - public boolean markSupported() { - return true; - } - - @Override - public synchronized int read() throws IOException { - if (in == null) { - // K0059=Stream is closed - throw new IOException(); //$NON-NLS-1$ - } - - /* Are there buffered bytes available? */ - if (pos >= count && fillbuf() == -1) { - return -1; /* no, fill buffer */ - } - - /* Did filling the buffer fail with -1 (EOF)? */ - if (count - pos > 0) { - return buf[pos++] & 0xFF; - } - return -1; - } - - @Override - public synchronized int read(byte[] buffer, int offset, int length) - throws IOException { - if (closed) { - // K0059=Stream is closed - throw new IOException(); //$NON-NLS-1$ - } - // avoid int overflow - if (offset > buffer.length - length || offset < 0 || length < 0) { - throw new IndexOutOfBoundsException(); - } - if (length == 0) { - return 0; - } - if (null == buf) { - throw new IOException(); //$NON-NLS-1$ - } - - int required; - if (pos < count) { - /* There are bytes available in the buffer. */ - int copylength = count - pos >= length ? length : count - pos; - System.arraycopy(buf, pos, buffer, offset, copylength); - pos += copylength; - if (copylength == length || in.available() == 0) { - return copylength; - } - offset += copylength; - required = length - copylength; - } else { - required = length; - } - - while (true) { - int read; - /* - * If we're not marked and the required size is greater than the - * buffer, simply read the bytes directly bypassing the buffer. - */ - if (markpos == -1 && required >= buf.length) { - read = in.read(buffer, offset, required); - if (read == -1) { - return required == length ? -1 : length - required; - } - } else { - if (fillbuf() == -1) { - return required == length ? -1 : length - required; - } - read = count - pos >= required ? required : count - pos; - System.arraycopy(buf, pos, buffer, offset, read); - pos += read; - } - required -= read; - if (required == 0) { - return length; - } - if (in.available() == 0) { - return length - required; - } - offset += read; - } - } - - @Override - public synchronized void reset() throws IOException { - if (closed) { - // K0059=Stream is closed - throw new IOException(); //$NON-NLS-1$ - } - if (-1 == markpos) { - // K005a=Mark has been invalidated. - throw new IOException(); //$NON-NLS-1$ - } - pos = markpos; - } - - @Override - public synchronized long skip(long amount) throws IOException { - if (null == in) { - // K0059=Stream is closed - throw new IOException(); //$NON-NLS-1$ - } - if (amount < 1) { - return 0; - } - - if (count - pos >= amount) { - pos += amount; - return amount; - } - long read = count - pos; - pos = count; - - if (markpos != -1) { - if (amount <= marklimit) { - if (fillbuf() == -1) { - return read; - } - if (count - pos >= amount - read) { - pos += amount - read; - return amount; - } - // Couldn't get all the bytes, skip what we read - read += (count - pos); - pos = count; - return read; - } - markpos = -1; - } - return read + in.skip(amount - read); - } -} diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java index ef99842..b79e7d1 100644 --- a/src/com/android/camera/Camera.java +++ b/src/com/android/camera/Camera.java @@ -16,8 +16,16 @@ package com.android.camera; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; + import android.app.Activity; import android.app.ProgressDialog; +import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -46,11 +54,10 @@ import android.os.Handler; import android.os.Message; import android.os.StatFs; import android.os.SystemClock; -import android.pim.DateFormat; import android.preference.PreferenceManager; import android.provider.MediaStore; import android.provider.MediaStore.Images; -import android.provider.MediaStore.Video; +import android.text.format.DateFormat; import android.util.Config; import android.util.Log; import android.view.KeyEvent; @@ -69,57 +76,60 @@ import android.view.animation.AnimationUtils; import android.widget.ImageView; import android.widget.Toast; -import java.util.ArrayList; - public class Camera extends Activity implements View.OnClickListener, SurfaceHolder.Callback { - + private static final String TAG = "camera"; - + private static final boolean DEBUG = false; - + private static final int CROP_MSG = 1; private static final int KEEP = 2; private static final int RESTART_PREVIEW = 3; private static final int CLEAR_SCREEN_DELAY = 4; - + private static final int SCREEN_DELAY = 2 * 60 * 1000; + private static final int POST_PICTURE_ALERT_TIMEOUT = 6 * 1000; private static final int FOCUS_BEEP_VOLUME = 100; private static final int NO_STORAGE_ERROR = -1; private static final int CANNOT_STAT_ERROR = -2; - + public static final int MENU_SWITCH_TO_VIDEO = 0; - public static final int MENU_FLASH_SETTING = 1; - public static final int MENU_FLASH_AUTO = 2; - public static final int MENU_FLASH_ON = 3; - public static final int MENU_FLASH_OFF = 4; - public static final int MENU_SETTINGS = 5; - public static final int MENU_GALLERY_PHOTOS = 6; + public static final int MENU_SWITCH_TO_CAMERA = 1; + public static final int MENU_FLASH_SETTING = 2; + public static final int MENU_FLASH_AUTO = 3; + public static final int MENU_FLASH_ON = 4; + public static final int MENU_FLASH_OFF = 5; + public static final int MENU_SETTINGS = 6; + public static final int MENU_GALLERY_PHOTOS = 7; + public static final int MENU_GALLERY_VIDEOS = 8; public static final int MENU_SAVE_SELECT_PHOTOS = 30; public static final int MENU_SAVE_NEW_PHOTO = 31; public static final int MENU_SAVE_SELECTVIDEO = 32; public static final int MENU_SAVE_TAKE_NEW_VIDEO = 33; public static final int MENU_SAVE_GALLERY_PHOTO = 34; - public static final int MENU_SAVE_GALLERY_VIDEO_PHOTO = 35; - public static final int MENU_SAVE_CAMERA_DONE = 36; + public static final int MENU_SAVE_GALLERY_VIDEO_PHOTO = 35; + public static final int MENU_SAVE_CAMERA_DONE = 36; public static final int MENU_SAVE_CAMERA_VIDEO_DONE = 37; - + Toast mToast; OrientationListener mOrientationListener; int mLastOrientation = OrientationListener.ORIENTATION_UNKNOWN; SharedPreferences mPreferences; - + static final int IDLE = 1; static final int SNAPSHOT_IN_PROGRESS = 2; static final int SNAPSHOT_COMPLETED = 3; - + int mStatus = IDLE; + static final String sTempCropFilename = "crop-temp"; android.hardware.Camera mCameraDevice; - SurfaceView mSurfaceView; + VideoPreview mSurfaceView; SurfaceHolder mSurfaceHolder = null; ImageView mBlackout = null; + int mOriginalViewFinderWidth, mOriginalViewFinderHeight; int mViewFinderWidth, mViewFinderHeight; boolean mPreviewing = false; @@ -127,7 +137,7 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol Capturer mCaptureObject; ImageCapture mImageCapture = null; - + boolean mPausing = false; boolean mIsFocusing = false; @@ -139,43 +149,39 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol boolean mDidRegister = false; int mCurrentZoomIndex = 0; - - private static final int STILL_MODE = 1; - private static final int VIDEO_MODE = 2; - private int mMode = STILL_MODE; ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>(); - + boolean mMenuSelectionMade; - + View mPostPictureAlert; LocationManager mLocationManager = null; private Animation mFocusBlinkAnimation; private View mFocusIndicator; private ToneGenerator mFocusToneGenerator; - + + private ShutterCallback mShutterCallback = new ShutterCallback(); private RawPictureCallback mRawPictureCallback = new RawPictureCallback(); - private JpegPictureCallback mJpegPictureCallback = new JpegPictureCallback(); private AutoFocusCallback mAutoFocusCallback = new AutoFocusCallback(); private long mShutterPressTime; private int mPicturesRemaining; private boolean mKeepAndRestartPreview; - private Handler mHandler = new MainHandler(); + private Handler mHandler = new MainHandler(); private ProgressDialog mSavingProgress; - + interface Capturer { - Uri getLastCaptureUri(); - void onSnap(); + Uri getLastCaptureUri(); + void onSnap(); void dismissFreezeFrame(boolean keep); - void cancelSave(); - void cancelAutoDismiss(); - void setDone(boolean wait); + void cancelSave(); + void cancelAutoDismiss(); + void setDone(boolean wait); } - + private void cancelSavingNotification() { if (mToast != null) { mToast.cancel(); @@ -194,15 +200,15 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol mSavingProgress.cancel(); mSavingProgress = null; } - + mKeepAndRestartPreview = true; - + if (msg.obj != null) { mHandler.post((Runnable)msg.obj); } break; } - + case RESTART_PREVIEW: { if (mStatus == SNAPSHOT_IN_PROGRESS) { // We are still in the processing of taking the picture, wait. @@ -210,11 +216,12 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol // TODO remove polling mHandler.sendEmptyMessageDelayed(RESTART_PREVIEW, 100); } else if (mStatus == SNAPSHOT_COMPLETED){ + hidePostPictureAlert(); mCaptureObject.dismissFreezeFrame(true); } break; } - + case CLEAR_SCREEN_DELAY: { getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); break; @@ -222,13 +229,13 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } } }; - + LocationListener [] mLocationListeners = new LocationListener[] { new LocationListener(LocationManager.GPS_PROVIDER), new LocationListener(LocationManager.NETWORK_PROVIDER) }; - + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -248,17 +255,17 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } } }; - + private class LocationListener implements android.location.LocationListener { Location mLastLocation; boolean mValid = false; String mProvider; - + public LocationListener(String provider) { mProvider = provider; mLastLocation = new Location(mProvider); } - + public void onLocationChanged(Location newLocation) { if (newLocation.getLatitude() == 0.0 && newLocation.getLongitude() == 0.0) { // Hack to filter out 0.0,0.0 locations @@ -267,7 +274,7 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol mLastLocation.set(newLocation); mValid = true; } - + public void onProviderEnabled(String provider) { } @@ -280,12 +287,12 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol mValid = false; } } - + public Location current() { return mValid ? mLastLocation : null; } }; - + private long mRawPictureCallbackTime; private boolean mImageSavingItem = false; @@ -302,25 +309,31 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } } }; - - private final class RawPictureCallback implements PictureCallback { + + private final class RawPictureCallback implements PictureCallback { public void onPictureTaken(byte [] rawData, android.hardware.Camera camera) { if (Config.LOGV) Log.v(TAG, "got RawPictureCallback..."); mRawPictureCallbackTime = System.currentTimeMillis(); mBlackout.setVisibility(View.INVISIBLE); if (!isPickIntent() && mPreferences.getBoolean("pref_camera_postpicturemenu_key", true)) { - mPostPictureAlert.setVisibility(View.VISIBLE); + showPostPictureAlert(); } } }; - + private final class JpegPictureCallback implements PictureCallback { + Location mLocation; + + public JpegPictureCallback(Location loc) { + mLocation = loc; + } + public void onPictureTaken(byte [] jpegData, android.hardware.Camera camera) { if (Config.LOGV) Log.v(TAG, "got JpegPictureCallback..."); - mImageCapture.storeImage(jpegData, camera); + mImageCapture.storeImage(jpegData, camera, mLocation); mStatus = SNAPSHOT_COMPLETED; @@ -335,15 +348,15 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol if (mKeepAndRestartPreview) { mKeepAndRestartPreview = false; mPostPictureAlert.setVisibility(View.INVISIBLE); - + // Post this message so that we can finish processing the request. This also // prevents the preview from showing up before mPostPictureAlert is dismissed. mHandler.sendEmptyMessage(RESTART_PREVIEW); } - + } }; - + private final class AutoFocusCallback implements android.hardware.Camera.AutoFocusCallback { public void onAutoFocus(boolean focused, android.hardware.Camera camera) { mIsFocusing = false; @@ -354,42 +367,44 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol mCaptureObject.onSnap(); clearFocus(); } else { - mFocusToneGenerator.startTone(ToneGenerator.TONE_PROP_BEEP2); + ToneGenerator tg = mFocusToneGenerator; + if (tg != null) + tg.startTone(ToneGenerator.TONE_PROP_BEEP2); } mCaptureOnFocus = false; } updateFocusIndicator(); } }; - + private class ImageCapture implements Capturer { - + private boolean mCancel = false; private boolean mCapturing = false; - + private Uri mLastContentUri; private ImageManager.IAddImage_cancelable mAddImageCancelable; Bitmap mCaptureOnlyBitmap; - + /** These member variables are used for various debug timings */ private long mThreadTimeStart; private long mThreadTimeEnd; private long mWallTimeStart; private long mWallTimeEnd; - + public ImageCapture() { } - /** + /** * This method sets whether or not we are capturing a picture. This method must be called * with the ImageCapture.this lock held. */ public void setCapturingLocked(boolean capturing) { mCapturing = capturing; } - + /* * Tell the ImageCapture thread to exit when possible. */ @@ -409,7 +424,7 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } else { Toast.makeText(Camera.this, R.string.camera_tossing, Toast.LENGTH_SHORT).show(); } - + if (mStatus == SNAPSHOT_IN_PROGRESS) { // If we are still in the process of taking a picture, then just post a message. mHandler.sendEmptyMessage(RESTART_PREVIEW); @@ -417,31 +432,31 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol restartPreview(); } } - + private void startTiming() { mWallTimeStart = SystemClock.elapsedRealtime(); mThreadTimeStart = Debug.threadCpuTimeNanos(); } - + private void stopTiming() { mThreadTimeEnd = Debug.threadCpuTimeNanos(); mWallTimeEnd = SystemClock.elapsedRealtime(); } - - private void storeImage(byte[] data) { + + private void storeImage(byte[] data, Location loc) { try { if (DEBUG) { startTiming(); } - + long dateTaken = System.currentTimeMillis(); mLastContentUri = ImageManager.instance().addImage( Camera.this, mContentResolver, - DateFormat.format("yyyy-MM-dd kk.mm.ss", System.currentTimeMillis()).toString(), + createName(dateTaken), "", - System.currentTimeMillis(), + dateTaken, // location for the database goes here - null, + loc, 0, // the dsp will use the right orientation so don't "double set it" ImageManager.CAMERA_IMAGE_BUCKET_NAME, null); @@ -456,46 +471,46 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol mAddImageCancelable.get(); mAddImageCancelable = null; } - + if (DEBUG) { stopTiming(); Log.d(TAG, "Storing image took " + (mWallTimeEnd - mWallTimeStart) + " ms. " + - "Thread time was " + ((mThreadTimeEnd - mThreadTimeStart) / 1000000) + + "Thread time was " + ((mThreadTimeEnd - mThreadTimeStart) / 1000000) + " ms."); } } catch (Exception ex) { Log.e(TAG, "Exception while compressing image.", ex); } } - - public void storeImage(byte[] data, android.hardware.Camera camera) { + + public void storeImage(byte[] data, android.hardware.Camera camera, Location loc) { boolean captureOnly = isPickIntent(); - + if (!captureOnly) { - storeImage(data); + storeImage(data, loc); sendBroadcast(new Intent("com.android.camera.NEW_PICTURE", mLastContentUri)); } else { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 4; - + if (DEBUG) { startTiming(); } - + mCaptureOnlyBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options); - + if (DEBUG) { stopTiming(); Log.d(TAG, "Decoded mCaptureOnly bitmap (" + mCaptureOnlyBitmap.getWidth() + - "x" + mCaptureOnlyBitmap.getHeight() + " ) in " + - (mWallTimeEnd - mWallTimeStart) + " ms. Thread time was " + + "x" + mCaptureOnlyBitmap.getHeight() + " ) in " + + (mWallTimeEnd - mWallTimeStart) + " ms. Thread time was " + ((mThreadTimeEnd - mThreadTimeStart) / 1000000) + " ms."); } - + openOptionsMenu(); } - - + + mCapturing = false; if (mPausing) { closeCamera(); @@ -510,9 +525,9 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol if (!mCapturing) { return; } - + mCancel = true; - + if (mAddImageCancelable != null) { mAddImageCancelable.cancel(); } @@ -526,25 +541,25 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol if (mCameraDevice == null) { return; } - + mCancel = false; mCapturing = true; capture(captureOnly); } - + public Uri getLastCaptureUri() { return mLastContentUri; } - + public Bitmap getLastBitmap() { return mCaptureOnlyBitmap; } - + private void capture(boolean captureOnly) { mPreviewing = false; mCaptureOnlyBitmap = null; - + final int latchedOrientation = ImageManager.roundOrientation(mLastOrientation + 90); Boolean recordLocation = mPreferences.getBoolean("pref_camera_recordlocation_key", false); @@ -554,35 +569,38 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol // get large. 85 is a good compromise between the two. parameters.set("jpeg-quality", 85); parameters.set("rotation", latchedOrientation); + + parameters.remove("gps-latitude"); + parameters.remove("gps-longitude"); + parameters.remove("gps-altitude"); + parameters.remove("gps-timestamp"); + if (loc != null) { - parameters.set("gps-latitude", String.valueOf(loc.getLatitude())); - parameters.set("gps-longitude", String.valueOf(loc.getLongitude())); - parameters.set("gps-altitude", String.valueOf(loc.getAltitude())); - parameters.set("gps-timestamp", String.valueOf(loc.getTime())); - } else { - parameters.remove("gps-latitude"); - parameters.remove("gps-longitude"); - parameters.remove("gps-altitude"); - parameters.remove("gps-timestamp"); + double lat = loc.getLatitude(); + double lon = loc.getLongitude(); + + if (lat != 0D && lon != 0d) { + parameters.set("gps-latitude", String.valueOf(lat)); + parameters.set("gps-longitude", String.valueOf(lon)); + if (loc.hasAltitude()) + parameters.set("gps-altitude", String.valueOf(loc.getAltitude())); + if (loc.getTime() != 0) + parameters.set("gps-timestamp", String.valueOf(loc.getTime())); + } else { + loc = null; + } } Size pictureSize = parameters.getPictureSize(); - Size previewSize = parameters.getPreviewSize(); // resize the SurfaceView to the aspect-ratio of the still image // and so that we can see the full image that was taken - ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams(); - if (pictureSize.width*previewSize.height < previewSize.width*pictureSize.height) { - lp.width = (pictureSize.width * previewSize.height) / pictureSize.height; - } else { - lp.height = (pictureSize.height * previewSize.width) / pictureSize.width; - } - mSurfaceView.requestLayout(); + mSurfaceView.setAspectRatio(pictureSize.width, pictureSize.height); mCameraDevice.setParameters(parameters); - - mCameraDevice.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback); - + + mCameraDevice.takePicture(mShutterCallback, mRawPictureCallback, new JpegPictureCallback(loc)); + mBlackout.setVisibility(View.VISIBLE); // Comment this out for now until we can decode the preview frame. This currently // just animates black-on-black because the surface flinger blacks out the surface @@ -612,7 +630,7 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol showStorageToast(); return; } - + mStatus = SNAPSHOT_IN_PROGRESS; mKeepAndRestartPreview = !mPreferences.getBoolean("pref_camera_postpicturemenu_key", true); @@ -626,6 +644,11 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } } + + static private String createName(long dateTaken) { + return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString(); + } + static public Matrix GetDisplayMatrix(Bitmap b, ImageView v) { Matrix m = new Matrix(); float bw = (float)b.getWidth(); @@ -649,12 +672,12 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol private void postAfterKeep(final Runnable r) { Resources res = getResources(); - + if (mSavingProgress != null) { - mSavingProgress = ProgressDialog.show(this, res.getString(R.string.savingImage), + mSavingProgress = ProgressDialog.show(this, res.getString(R.string.savingImage), res.getString(R.string.wait)); } - + Message msg = mHandler.obtainMessage(KEEP); msg.obj = r; msg.sendToTarget(); @@ -672,38 +695,35 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); requestWindowFeature(Window.FEATURE_PROGRESS); - + Window win = getWindow(); win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.camera); - mSurfaceView = (SurfaceView) findViewById(R.id.camera_preview); - + mSurfaceView = (VideoPreview) findViewById(R.id.camera_preview); + // don't set mSurfaceHolder here. We have it set ONLY within // surfaceCreated / surfaceDestroyed, other parts of the code // assume that when it is set, the surface is also set. SurfaceHolder holder = mSurfaceView.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); - + mBlackout = (ImageView) findViewById(R.id.blackout); mBlackout.setBackgroundDrawable(new ColorDrawable(0xFF000000)); mPostPictureAlert = findViewById(R.id.post_picture_panel); View b; - - b = findViewById(R.id.save); - b.setOnClickListener(this); - + b = findViewById(R.id.discard); b.setOnClickListener(this); - + b = findViewById(R.id.share); b.setOnClickListener(this); b = findViewById(R.id.setas); b.setOnClickListener(this); - + try { mClickSound = new MediaPlayer(); AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.camera_click); @@ -719,27 +739,27 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } catch (Exception ex) { Log.w(TAG, "Couldn't create click sound", ex); } - + mOrientationListener = new OrientationListener(this) { public void onOrientationChanged(int orientation) { mLastOrientation = orientation; } }; - + mFocusIndicator = findViewById(R.id.focus_indicator); mFocusBlinkAnimation = AnimationUtils.loadAnimation(this, R.anim.auto_focus_blink); mFocusBlinkAnimation.setRepeatCount(Animation.INFINITE); mFocusBlinkAnimation.setRepeatMode(Animation.REVERSE); } - + @Override public void onStart() { super.onStart(); - + final View hintView = findViewById(R.id.hint_toast); if (hintView != null) hintView.setVisibility(View.GONE); - + Thread t = new Thread(new Runnable() { public void run() { final boolean storageOK = calculatePicturesRemaining() > 0; @@ -761,7 +781,7 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol hintView.setVisibility(View.GONE); } }, 3000); - } else { + } else { mHandler.post(new Runnable() { public void run() { hintView.setVisibility(View.GONE); @@ -773,15 +793,17 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol }); t.start(); } - + public void onClick(View v) { switch (v.getId()) { + /* case R.id.save: { - mPostPictureAlert.setVisibility(View.INVISIBLE); + mPostPictureAlert.setVisibility(View.GONE); postAfterKeep(null); break; } - + */ + case R.id.discard: { if (mCaptureObject != null) { mCaptureObject.cancelSave(); @@ -791,12 +813,12 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } mCaptureObject.dismissFreezeFrame(true); } - mPostPictureAlert.setVisibility(View.INVISIBLE); + mPostPictureAlert.setVisibility(View.GONE); break; } - + case R.id.share: { - mPostPictureAlert.setVisibility(View.INVISIBLE); + mPostPictureAlert.setVisibility(View.GONE); postAfterKeep(new Runnable() { public void run() { Uri u = mCaptureObject.getLastCaptureUri(); @@ -807,15 +829,15 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol try { startActivity(Intent.createChooser(intent, getText(R.string.sendImage))); } catch (android.content.ActivityNotFoundException ex) { - Toast.makeText(Camera.this, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show(); + Toast.makeText(Camera.this, R.string.no_way_to_share_image, Toast.LENGTH_SHORT).show(); } } }); break; } - + case R.id.setas: { - mPostPictureAlert.setVisibility(View.INVISIBLE); + mPostPictureAlert.setVisibility(View.GONE); postAfterKeep(new Runnable() { public void run() { Uri u = mCaptureObject.getLastCaptureUri(); @@ -831,9 +853,6 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } } } - - void keepVideo() { - }; private void showStorageToast() { String noStorageText = null; @@ -854,14 +873,10 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol public void onResume() { super.onResume(); mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); - + mPausing = false; mOrientationListener.enable(); - if (isPickIntent()) { - mMode = STILL_MODE; - } - // install an intent filter to receive SD card related events. IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); @@ -874,14 +889,19 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol mImageCapture = new ImageCapture(); restartPreview(); - + if (mPreferences.getBoolean("pref_camera_recordlocation_key", false)) startReceivingLocationUpdates(); - + updateFocusIndicator(); - mFocusToneGenerator = new ToneGenerator(AudioManager.STREAM_SYSTEM, FOCUS_BEEP_VOLUME); - + try { + mFocusToneGenerator = new ToneGenerator(AudioManager.STREAM_SYSTEM, FOCUS_BEEP_VOLUME); + } catch (RuntimeException e) { + Log.w(TAG, "Exception caught while creating local tone generator: " + e); + mFocusToneGenerator = null; + } + mBlackout.setVisibility(View.INVISIBLE); } @@ -905,7 +925,7 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol mPausing = true; mOrientationListener.disable(); - + stopPreview(); if (!mImageCapture.mCapturing) { @@ -916,8 +936,11 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol mDidRegister = false; } stopReceivingLocationUpdates(); - mFocusToneGenerator.release(); - mFocusToneGenerator = null; + + if (mFocusToneGenerator != null) { + mFocusToneGenerator.release(); + mFocusToneGenerator = null; + } super.onPause(); } @@ -935,6 +958,10 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } setResult(resultCode, intent); finish(); + + File path = getFileStreamPath(sTempCropFilename); + path.delete(); + break; } } @@ -950,13 +977,13 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } } } - + private void clearFocus() { mIsFocusing = false; mIsFocused = false; mIsFocusButtonPressed = false; } - + private void updateFocusIndicator() { mHandler.post(new Runnable() { public void run() { @@ -976,10 +1003,12 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol }); } + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + switch (keyCode) { case KeyEvent.KEYCODE_BACK: if (mStatus == SNAPSHOT_IN_PROGRESS || mStatus == SNAPSHOT_COMPLETED) { @@ -1049,12 +1078,10 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { - if (mMode == STILL_MODE) { - // if we're creating the surface, start the preview as well. - boolean preview = holder.isCreating(); - setViewFinder(w, h, preview); - mCaptureObject = mImageCapture; - } + // if we're creating the surface, start the preview as well. + boolean preview = holder.isCreating(); + setViewFinder(w, h, preview); + mCaptureObject = mImageCapture; } public void surfaceCreated(SurfaceHolder holder) { @@ -1065,7 +1092,7 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol stopPreview(); mSurfaceHolder = null; } - + private void closeCamera() { if (mCameraDevice != null) { mCameraDevice.release(); @@ -1073,26 +1100,23 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol mPreviewing = false; } } - + private boolean ensureCameraDevice() { if (mCameraDevice == null) { mCameraDevice = android.hardware.Camera.open(); } return mCameraDevice != null; } - + private void restartPreview() { - SurfaceView surfaceView = mSurfaceView; - if (surfaceView == null || + VideoPreview surfaceView = mSurfaceView; + if (surfaceView == null || surfaceView.getWidth() == 0 || surfaceView.getHeight() == 0) { return; } // make sure the surfaceview fills the whole screen when previewing - ViewGroup.LayoutParams lp = surfaceView.getLayoutParams(); - lp.width = ViewGroup.LayoutParams.FILL_PARENT; - lp.height = ViewGroup.LayoutParams.FILL_PARENT; - surfaceView.requestLayout(); - setViewFinder(mViewFinderWidth, mViewFinderHeight, true); + surfaceView.setAspectRatio(VideoPreview.DONT_CARE); + setViewFinder(mOriginalViewFinderWidth, mOriginalViewFinderHeight, true); mStatus = IDLE; // Calculate this in advance of each shot so we don't add to shutter latency. It's true that @@ -1102,37 +1126,41 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol // let the user take a picture, and delete that file if needed to save the new photo. calculatePicturesRemaining(); } - + private void setViewFinder(int w, int h, boolean startPreview) { if (mPausing) return; - - if (mPreviewing && - w == mViewFinderWidth && + + if (mPreviewing && + w == mViewFinderWidth && h == mViewFinderHeight) { return; } - + if (!ensureCameraDevice()) return; - + if (mSurfaceHolder == null) return; - + if (isFinishing()) return; - + if (mPausing) return; - + // remember view finder size mViewFinderWidth = w; mViewFinderHeight = h; + if (mOriginalViewFinderHeight == 0) { + mOriginalViewFinderWidth = w; + mOriginalViewFinderHeight = h; + } if (startPreview == false) return; - /* + /* * start the preview if we're asked to... */ @@ -1140,21 +1168,31 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol // stop the preview first (this will blank the screen). if (mPreviewing) stopPreview(); - + // this blanks the screen if the surface changed, no-op otherwise - mCameraDevice.setPreviewDisplay(mSurfaceHolder); - + try { + mCameraDevice.setPreviewDisplay(mSurfaceHolder); + } catch (IOException exception) { + mCameraDevice.release(); + mCameraDevice = null; + // TODO: add more exception handling logic here + return; + } // request the preview size, the hardware may not honor it, // if we depended on it we would have to query the size again android.hardware.Camera.Parameters p = mCameraDevice.getParameters(); p.setPreviewSize(w, h); - mCameraDevice.setParameters(p); - - + try { + mCameraDevice.setParameters(p); + } catch (IllegalArgumentException e) { + // Ignore this error, it happens in the simulator. + } + + final long wallTimeStart = SystemClock.elapsedRealtime(); final long threadTimeStart = Debug.threadCpuTimeNanos(); - + final Object watchDogSync = new Object(); Thread watchDog = new Thread(new Runnable() { public void run() { @@ -1169,7 +1207,7 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } if (mPreviewing) break; - + int delay = (int) (SystemClock.elapsedRealtime() - wallTimeStart) / 1000; if (delay >= next_warning) { if (delay < 120) { @@ -1194,19 +1232,24 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol if (Config.LOGV) Log.v(TAG, "calling mCameraDevice.startPreview"); - mCameraDevice.startPreview(); + try { + mCameraDevice.startPreview(); + } catch (Throwable e) { + // TODO: change Throwable to IOException once android.hardware.Camera.startPreview + // properly declares that it throws IOException. + } mPreviewing = true; - + synchronized (watchDogSync) { watchDogSync.notify(); } - + long threadTimeEnd = Debug.threadCpuTimeNanos(); long wallTimeEnd = SystemClock.elapsedRealtime(); if ((wallTimeEnd - wallTimeStart) > 3000) { Log.w(TAG, "startPreview() to " + (wallTimeEnd - wallTimeStart) + " ms. Thread time was" + (threadTimeEnd - threadTimeStart) / 1000000 + " ms."); - } + } } private void stopPreview() { @@ -1217,10 +1260,13 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } void gotoGallery() { - Uri target = mMode == STILL_MODE ? Images.Media.INTERNAL_CONTENT_URI - : Video.Media.INTERNAL_CONTENT_URI; + Uri target = Images.Media.INTERNAL_CONTENT_URI; Intent intent = new Intent(Intent.ACTION_VIEW, target); - startActivity(intent); + try { + startActivity(intent); + } catch (ActivityNotFoundException e) { + Log.e(TAG, "Could not start gallery activity", e); + } } void keep() { @@ -1236,27 +1282,27 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol mCaptureObject.cancelSave(); } }; - + private ImageManager.IImage getImageForURI(Uri uri) { ImageManager.IImageList list = ImageManager.instance().allImages( this, - mContentResolver, - dataLocation(), - ImageManager.INCLUDE_IMAGES, + mContentResolver, + dataLocation(), + ImageManager.INCLUDE_IMAGES, ImageManager.SORT_ASCENDING); ImageManager.IImage image = list.getImageForUri(uri); list.deactivate(); return image; } - - + + private void startReceivingLocationUpdates() { if (mLocationManager != null) { try { mLocationManager.requestLocationUpdates( - LocationManager.NETWORK_PROVIDER, - 1000, - 0F, + LocationManager.NETWORK_PROVIDER, + 1000, + 0F, mLocationListeners[1]); } catch (java.lang.SecurityException ex) { // ok @@ -1267,9 +1313,9 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } try { mLocationManager.requestLocationUpdates( - LocationManager.GPS_PROVIDER, - 1000, - 0F, + LocationManager.GPS_PROVIDER, + 1000, + 0F, mLocationListeners[0]); } catch (java.lang.SecurityException ex) { // ok @@ -1280,7 +1326,7 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } } } - + private void stopReceivingLocationUpdates() { if (mLocationManager != null) { for (int i = 0; i < mLocationListeners.length; i++) { @@ -1292,18 +1338,20 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } } } - + private Location getCurrentLocation() { Location l = null; - - // go in worst to best order - for (int i = 0; i < mLocationListeners.length && l == null; i++) { + + // go in best to worst order + for (int i = 0; i < mLocationListeners.length; i++) { l = mLocationListeners[i].current(); + if (l != null) + break; } - + return l; } - + @Override public void onOptionsMenuClosed(Menu menu) { super.onOptionsMenuClosed(menu); @@ -1315,7 +1363,7 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol mHandler.sendEmptyMessage(RESTART_PREVIEW); } } - + @Override public boolean onMenuOpened(int featureId, Menu menu) { if (featureId == Window.FEATURE_OPTIONS_PANEL) { @@ -1327,28 +1375,25 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } return super.onMenuOpened(featureId, menu); } - + @Override public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); mMenuSelectionMade = false; - + for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) { if (i != MenuHelper.GENERIC_ITEM) { menu.setGroupVisible(i, false); } } - - if (mMode == STILL_MODE) { - if (mStatus == SNAPSHOT_IN_PROGRESS || mStatus == SNAPSHOT_COMPLETED) { - menu.setGroupVisible(MenuHelper.IMAGE_SAVING_ITEM, true); - mImageSavingItem = true; - } else { - menu.setGroupVisible(MenuHelper.IMAGE_MODE_ITEM, true); - mImageSavingItem = false; - } - } else if (mMode == VIDEO_MODE) { + + if (mStatus == SNAPSHOT_IN_PROGRESS || mStatus == SNAPSHOT_COMPLETED) { + menu.setGroupVisible(MenuHelper.IMAGE_SAVING_ITEM, true); + mImageSavingItem = true; + } else { + menu.setGroupVisible(MenuHelper.IMAGE_MODE_ITEM, true); + mImageSavingItem = false; } if (mCaptureObject != null) @@ -1361,7 +1406,7 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol String action = getIntent().getAction(); return (Intent.ACTION_PICK.equals(action) || MediaStore.ACTION_IMAGE_CAPTURE.equals(action)); } - + @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); @@ -1372,39 +1417,106 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol Bitmap bitmap = mImageCapture.getLastBitmap(); mCaptureObject.setDone(true); - // TODO scale the image down to something ridiculous until IPC gets straightened out - float scale = .5F; - Matrix m = new Matrix(); - m.setScale(scale, scale); + String cropValue = null; + Uri saveUri = null; - bitmap = Bitmap.createBitmap(bitmap, 0, 0, - bitmap.getWidth(), - bitmap.getHeight(), - m, true); - Bundle myExtras = getIntent().getExtras(); - String cropValue = myExtras != null ? myExtras.getString("crop") : null; - if (cropValue != null) { + if (myExtras != null) { + saveUri = (Uri) myExtras.getParcelable("output"); + cropValue = myExtras.getString("crop"); + } + + + if (cropValue == null) { + /* + * First handle the no crop case -- just return the value. If the caller + * specifies a "save uri" then write the data to it's stream. Otherwise, + * pass back a scaled down version of the bitmap directly in the extras. + */ + if (saveUri != null) { + OutputStream outputStream = null; + try { + outputStream = mContentResolver.openOutputStream(saveUri); + bitmap.compress(Bitmap.CompressFormat.JPEG, 75, outputStream); + outputStream.close(); + + setResult(RESULT_OK); + finish(); + } catch (IOException ex) { + // + } finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException ex) { + + } + } + } + } else { + float scale = .5F; + Matrix m = new Matrix(); + m.setScale(scale, scale); + + bitmap = Bitmap.createBitmap(bitmap, 0, 0, + bitmap.getWidth(), + bitmap.getHeight(), + m, true); + + setResult(RESULT_OK, new Intent("inline-data").putExtra("data", bitmap)); + finish(); + } + } + else { + /* + * Save the image to a temp file and invoke the cropper + */ + Uri tempUri = null; + FileOutputStream tempStream = null; + try { + File path = getFileStreamPath(sTempCropFilename); + path.delete(); + tempStream = openFileOutput(sTempCropFilename, 0); + bitmap.compress(Bitmap.CompressFormat.JPEG, 75, tempStream); + tempStream.close(); + tempUri = Uri.fromFile(path); + } catch (FileNotFoundException ex) { + setResult(Activity.RESULT_CANCELED); + finish(); + return true; + } catch (IOException ex) { + setResult(Activity.RESULT_CANCELED); + finish(); + return true; + } finally { + if (tempStream != null) { + try { + tempStream.close(); + } catch (IOException ex) { + + } + } + } + Bundle newExtras = new Bundle(); if (cropValue.equals("circle")) newExtras.putString("circleCrop", "true"); - newExtras.putParcelable("data", bitmap); + if (saveUri != null) + newExtras.putParcelable("output", saveUri); + else + newExtras.putBoolean("return-data", true); Intent cropIntent = new Intent(); cropIntent.setClass(Camera.this, CropImage.class); + cropIntent.setData(tempUri); cropIntent.putExtras(newExtras); + startActivityForResult(cropIntent, CROP_MSG); - } else { - Bundle extras = new Bundle(); - extras.putParcelable("data", bitmap); - setResult(RESULT_OK, new Intent("inline-data") - .putExtra("data", bitmap)); - finish(); } return true; } }); - + menu.add(MenuHelper.IMAGE_SAVING_ITEM, MENU_SAVE_NEW_PHOTO, 0, R.string.camera_takenewphoto).setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { keep(); @@ -1422,9 +1534,10 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol MenuHelper.addImageMenuItems( menu, MenuHelper.INCLUDE_ALL & ~MenuHelper.INCLUDE_ROTATE_MENU, + true, Camera.this, mHandler, - + // Handler for deletion new Runnable() { public void run() { @@ -1461,20 +1574,12 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } }); gallery.setIcon(android.R.drawable.ic_menu_gallery); - - mGalleryItems.add(menu.add(MenuHelper.VIDEO_SAVING_ITEM, MENU_SAVE_GALLERY_VIDEO_PHOTO, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - keepVideo(); - gotoGallery(); - return true; - } - })); - } + } return true; } - + SelectedImageGetter mSelectedImageGetter = - new SelectedImageGetter() { + new SelectedImageGetter() { public ImageManager.IImage getCurrentImage() { return getImageForURI(getCurrentImageUri()); } @@ -1502,16 +1607,29 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol } return mPicturesRemaining; } - + private void addBaseMenuItems(Menu menu) { - MenuItem gallery = menu.add(MenuHelper.IMAGE_MODE_ITEM, MENU_GALLERY_PHOTOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - gotoGallery(); - return true; - } - }); - gallery.setIcon(android.R.drawable.ic_menu_gallery); - mGalleryItems.add(gallery); + MenuHelper.addSwitchModeMenuItem(menu, this, true); + { + MenuItem gallery = menu.add(MenuHelper.IMAGE_MODE_ITEM, MENU_GALLERY_PHOTOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + gotoGallery(); + return true; + } + }); + gallery.setIcon(android.R.drawable.ic_menu_gallery); + mGalleryItems.add(gallery); + } + { + MenuItem gallery = menu.add(MenuHelper.VIDEO_MODE_ITEM, MENU_GALLERY_VIDEOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + gotoGallery(); + return true; + } + }); + gallery.setIcon(android.R.drawable.ic_menu_gallery); + mGalleryItems.add(gallery); + } MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, R.string.settings).setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { @@ -1523,5 +1641,20 @@ public class Camera extends Activity implements View.OnClickListener, SurfaceHol }); item.setIcon(android.R.drawable.ic_menu_preferences); } + + private void showPostPictureAlert() { + mPostPictureAlert.setVisibility(View.VISIBLE); + mHandler.sendEmptyMessageDelayed(RESTART_PREVIEW, POST_PICTURE_ALERT_TIMEOUT); + } + + private void hidePostPictureAlert() { + cancelRestartPreviewTimeout(); + mPostPictureAlert.setVisibility(View.INVISIBLE); + } + + private void cancelRestartPreviewTimeout() { + mHandler.removeMessages(RESTART_PREVIEW); + } + } diff --git a/src/com/android/camera/CameraButtonIntentReceiver.java b/src/com/android/camera/CameraButtonIntentReceiver.java index ccf5821..5e4d3c3 100644 --- a/src/com/android/camera/CameraButtonIntentReceiver.java +++ b/src/com/android/camera/CameraButtonIntentReceiver.java @@ -19,11 +19,9 @@ package com.android.camera; import android.content.Context; import android.content.Intent; import android.content.BroadcastReceiver; -import android.util.Config; -import android.util.Log; import android.view.KeyEvent; -class CameraButtonIntentReceiver extends BroadcastReceiver { +public class CameraButtonIntentReceiver extends BroadcastReceiver { public CameraButtonIntentReceiver() { } diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java index fb77e34..0c0f31b 100644 --- a/src/com/android/camera/CameraSettings.java +++ b/src/com/android/camera/CameraSettings.java @@ -16,50 +16,29 @@ package com.android.camera; -import android.content.SharedPreferences; import android.os.Bundle; -import android.preference.Preference; import android.preference.PreferenceActivity; -import android.content.Context; /** * CameraSettings */ -class CameraSettings extends PreferenceActivity +public class CameraSettings extends PreferenceActivity { public CameraSettings() { } - + protected int resourceId() { return R.xml.camera_preferences; } - + /** Called with the activity is first created. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); addPreferencesFromResource(resourceId()); - - Preference p = findPreference("pref_camera_upload_albumname_key"); - if (p != null) { - SharedPreferences sp = p.getSharedPreferences(); - p.setSummary( - String.format(getResources().getString(R.string.pref_camera_upload_albumname_summary), - p.getSharedPreferences().getString(p.getKey(), UploadService.sUploadAlbumName))); - p.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - public boolean onPreferenceChange(Preference p, Object newObjValue) { - String newValue = (String) newObjValue; - if (newValue == null || newValue.length() == 0) - return false; - if (android.util.Config.LOGV) - android.util.Log.v("camera", "onPreferenceChange ... " + newValue); - p.setSummary(String.format(getResources().getString(R.string.pref_camera_upload_albumname_summary), newValue)); - return true; - } - }); - } + } } diff --git a/src/com/android/camera/ExifInterface.java b/src/com/android/camera/ExifInterface.java index de2fd5c..2db021a 100644 --- a/src/com/android/camera/ExifInterface.java +++ b/src/com/android/camera/ExifInterface.java @@ -59,7 +59,7 @@ public class ExifInterface { private HashMap<String, String> mCachedAttributes = null; static { - System.loadLibrary("exif"); + System.loadLibrary("exif"); } public ExifInterface(String fileName) { diff --git a/src/com/android/camera/GalleryPicker.java b/src/com/android/camera/GalleryPicker.java index 9f1664b..da946a0 100644 --- a/src/com/android/camera/GalleryPicker.java +++ b/src/com/android/camera/GalleryPicker.java @@ -29,6 +29,7 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; +import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; @@ -56,29 +57,31 @@ import android.widget.AdapterView.AdapterContextMenuInfo; import java.util.ArrayList; import java.util.HashMap; +import java.util.Map; public class GalleryPicker extends Activity { static private final String TAG = "GalleryPicker"; - + GridView mGridView; Drawable mFrameGalleryMask; Drawable mCellOutline; + Drawable mVideoOverlay; BroadcastReceiver mReceiver; GalleryPickerAdapter mAdapter; - + Dialog mMediaScanningDialog; - + MenuItem mFlipItem; SharedPreferences mPrefs; - + boolean mPausing = false; - + private static long LOW_STORAGE_THRESHOLD = 1024 * 1024 * 2; - + public GalleryPicker() { } - + private void rebake(boolean unmounted, boolean scanning) { if (mMediaScanningDialog != null) { mMediaScanningDialog.cancel(); @@ -86,16 +89,16 @@ public class GalleryPicker extends Activity { } if (scanning) { mMediaScanningDialog = ProgressDialog.show( - this, - null, - getResources().getString(R.string.wait), - true, + this, + null, + getResources().getString(R.string.wait), + true, true); } mAdapter.notifyDataSetChanged(); mAdapter.init(!unmounted && !scanning); } - + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -103,12 +106,12 @@ public class GalleryPicker extends Activity { mPrefs = PreferenceManager.getDefaultSharedPreferences(this); setContentView(R.layout.gallerypicker); - - mGridView = (GridView) findViewById(R.id.albums); + + mGridView = (GridView) findViewById(R.id.albums); mGridView.setSelector(android.R.color.transparent); mReceiver = new BroadcastReceiver() { - + @Override public void onReceive(Context context, Intent intent) { if (Config.LOGV) Log.v(TAG, "onReceiveIntent " + intent.getAction()); @@ -136,7 +139,7 @@ public class GalleryPicker extends Activity { } } }; - + mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { launchFolderGallery(position); @@ -144,34 +147,35 @@ public class GalleryPicker extends Activity { }); mGridView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { public void onCreateContextMenu(ContextMenu menu, View v, final ContextMenu.ContextMenuInfo menuInfo) { - menu.setHeaderTitle( - mAdapter.baseTitleForPosition(((AdapterContextMenuInfo)menuInfo).position)); - menu.add(0, 207, 0, R.string.slide_show) - .setOnMenuItemClickListener(new OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo; - int position = info.position; - - Uri targetUri; - synchronized (mAdapter.mFirstImageUris) { - if (position >= mAdapter.mFirstImageUris.size()) { - // the list of ids does not include the "all" list - targetUri = mAdapter.firstImageUri(mAdapter.mIds.get(position-1)); - } else { + int position = ((AdapterContextMenuInfo)menuInfo).position; + menu.setHeaderTitle(mAdapter.baseTitleForPosition(position)); + if ((mAdapter.getIncludeMediaTypes(position) & ImageManager.INCLUDE_IMAGES) != 0) { + menu.add(0, 207, 0, R.string.slide_show) + .setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo; + int position = info.position; + + Uri targetUri; + synchronized (mAdapter.mItems) { + if (position < 0 || position >= mAdapter.mItems.size()) { + return true; + } // the mFirstImageUris list includes the "all" uri - targetUri = mAdapter.mFirstImageUris.get(position); + targetUri = mAdapter.mItems.get(position).mFirstImageUri; } + if (targetUri != null && position > 0) { + targetUri = targetUri.buildUpon().appendQueryParameter("bucketId", + mAdapter.mItems.get(info.position).mId).build(); + } + // Log.v(TAG, "URI to launch slideshow " + targetUri); + Intent intent = new Intent(Intent.ACTION_VIEW, targetUri); + intent.putExtra("slideshow", true); + startActivity(intent); + return true; } - if (targetUri != null && position > 0) { - targetUri = targetUri.buildUpon().appendQueryParameter("bucketId", mAdapter.mIds.get(info.position-1)).build(); - } -// Log.v(TAG, "URI to launch slideshow " + targetUri); - Intent intent = new Intent(Intent.ACTION_VIEW, targetUri); - intent.putExtra("slideshow", true); - startActivity(intent); - return true; - } - }); + }); + } menu.add(0, 208, 0, R.string.view) .setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { @@ -183,56 +187,118 @@ public class GalleryPicker extends Activity { } }); } - + private void launchFolderGallery(int position) { - android.net.Uri uri = Images.Media.INTERNAL_CONTENT_URI; - if (position > 0) { - uri = uri.buildUpon().appendQueryParameter("bucketId", mAdapter.mIds.get(position-1)).build(); - } - Intent intent = new Intent(Intent.ACTION_VIEW, uri); - if (position > 0) { - intent.putExtra("windowTitle", mAdapter.mNames.get(position-1)); - } - startActivity(intent); + mAdapter.mItems.get(position).launch(this); } - + class ItemInfo { Bitmap bitmap; int count; - int overlayId; } - + + static class Item implements Comparable<Item>{ + // The type is also used as the sort order + public final static int TYPE_ALL_IMAGES = 0; + public final static int TYPE_ALL_VIDEOS = 1; + public final static int TYPE_CAMERA_IMAGES = 2; + public final static int TYPE_CAMERA_VIDEOS = 3; + public final static int TYPE_NORMAL_FOLDERS = 4; + + public int mType; + public String mId; + public String mName; + public Uri mFirstImageUri; + public ItemInfo mThumb; + + public Item(int type, String id, String name) { + mType = type; + mId = id; + mName = name; + } + + public boolean needsBucketId() { + return mType >= TYPE_CAMERA_IMAGES; + } + + public void launch(Activity activity) { + android.net.Uri uri = Images.Media.INTERNAL_CONTENT_URI; + if (needsBucketId()) { + uri = uri.buildUpon().appendQueryParameter("bucketId",mId).build(); + } + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + intent.putExtra("windowTitle", mName); + intent.putExtra("mediaTypes", getIncludeMediaTypes()); + activity.startActivity(intent); + } + + public int getIncludeMediaTypes() { + return convertItemTypeToIncludedMediaType(mType); + } + + public static int convertItemTypeToIncludedMediaType(int itemType) { + switch (itemType) { + case TYPE_ALL_IMAGES: + case TYPE_CAMERA_IMAGES: + return ImageManager.INCLUDE_IMAGES; + case TYPE_ALL_VIDEOS: + case TYPE_CAMERA_VIDEOS: + return ImageManager.INCLUDE_VIDEOS; + case TYPE_NORMAL_FOLDERS: + default: + return ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS; + } + } + + public int getOverlay() { + switch (mType) { + case TYPE_ALL_IMAGES: + case TYPE_CAMERA_IMAGES: + return R.drawable.frame_overlay_gallery_camera; + case TYPE_ALL_VIDEOS: + case TYPE_CAMERA_VIDEOS: + return R.drawable.frame_overlay_gallery_video; + case TYPE_NORMAL_FOLDERS: + return R.drawable.frame_overlay_gallery_folder; + default: + return -1; + } + } + + // sort based on the sort order, then the case-insensitive display name, then the id. + public int compareTo(Item other) { + int x = mType - other.mType; + if (x == 0) { + x = mName.compareToIgnoreCase(other.mName); + if (x == 0) { + x = mId.compareTo(other.mId); + } + } + return x; + } + } + class GalleryPickerAdapter extends BaseAdapter { - ArrayList<String> mIds = new ArrayList<String>(); - ArrayList<String> mNames = new ArrayList<String>(); - ArrayList<Uri> mFirstImageUris = new ArrayList<Uri>(); - - ArrayList<View> mAllViews = new ArrayList<View>(); - SparseArray<ItemInfo> mThumbs = new SparseArray<ItemInfo>(); - + ArrayList<Item> mItems = new ArrayList<Item>(); + boolean mDone = false; CameraThread mWorkerThread; public void init(boolean assumeMounted) { - mAllViews.clear(); - mThumbs.clear(); - + mItems.clear(); + ImageManager.IImageList images; if (assumeMounted) { images = ImageManager.instance().allImages( GalleryPicker.this, - getContentResolver(), - ImageManager.DataLocation.ALL, - ImageManager.INCLUDE_IMAGES, + getContentResolver(), + ImageManager.DataLocation.ALL, + ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS, ImageManager.SORT_DESCENDING); } else { images = ImageManager.instance().emptyImageList(); } - mIds.clear(); - mNames.clear(); - mFirstImageUris.clear(); - if (mWorkerThread != null) { try { mDone = true; @@ -243,72 +309,56 @@ public class GalleryPicker extends Activity { mWorkerThread = null; } } - + String cameraItem = ImageManager.CAMERA_IMAGE_BUCKET_ID; final HashMap<String, String> hashMap = images.getBucketIds(); String cameraBucketId = null; - for (String key : hashMap.keySet()) { + for (Map.Entry<String, String> entry: hashMap.entrySet()) { + String key = entry.getKey(); if (key.equals(cameraItem)) { cameraBucketId = key; } else { - mIds.add(key); + mItems.add(new Item(Item.TYPE_NORMAL_FOLDERS, key, entry.getValue())); } } images.deactivate(); notifyDataSetInvalidated(); - - // sort baesd on the display name. if two display names compare equal - // then sort based on the id - java.util.Collections.sort(mIds, new java.util.Comparator<String>() { - public int compare(String first, String second) { - int x = hashMap.get(first).compareTo(hashMap.get(second)); - if (x == 0) - x = first.compareTo(second); - return x; - } - }); - for (String s : mIds) { - mNames.add(hashMap.get(s)); - } + // If just one + addBucketIfNotEmpty(Item.TYPE_ALL_IMAGES, null, R.string.all_images); + addBucketIfNotEmpty(Item.TYPE_ALL_VIDEOS, null, R.string.all_videos); if (cameraBucketId != null) { - mIds.add(0, cameraBucketId); - mNames.add(0, "Camera"); + addBucketIfNotEmpty(Item.TYPE_CAMERA_IMAGES, cameraBucketId, + R.string.gallery_camera_bucket_name); + addBucketIfNotEmpty(Item.TYPE_CAMERA_VIDEOS, cameraBucketId, + R.string.gallery_camera_videos_bucket_name); } - final boolean foundCameraBucket = cameraBucketId != null; - + + java.util.Collections.sort(mItems); + mDone = false; mWorkerThread = new CameraThread(new Runnable() { public void run() { try { // no images, nothing to do - if (mIds.size() == 0) + if (mItems.size() == 0) return; - - for (int i = 0; i < mIds.size() + 1 && !mDone; i++) { - String id = i == 0 ? null : mIds.get(i-1); - ImageManager.IImageList list = ImageManager.instance().allImages( - GalleryPicker.this, - getContentResolver(), - ImageManager.DataLocation.ALL, - ImageManager.INCLUDE_IMAGES, - ImageManager.SORT_DESCENDING, - id); + + for (int i = 0; i < mItems.size() && !mDone; i++) { + final Item item = mItems.get(i); + ImageManager.IImageList list = createImageList( + item.getIncludeMediaTypes(), item.mId); try { if (mPausing) { break; } if (list.getCount() > 0) - mFirstImageUris.add(i, list.getImageAt(0).fullSizeImageUri()); + item.mFirstImageUri = list.getImageAt(0).fullSizeImageUri(); - int overlay = -1; - if (i == 1 && foundCameraBucket) - overlay = R.drawable.frame_overlay_gallery_camera; final Bitmap b = makeMiniThumbBitmap(142, 142, list); final int pos = i; final int count = list.getCount(); - final int overlayId = overlay; final Thread currentThread = Thread.currentThread(); mHandler.post(new Runnable() { public void run() { @@ -318,19 +368,18 @@ public class GalleryPicker extends Activity { } return; } - + ItemInfo info = new ItemInfo(); info.bitmap = b; info.count = count; - info.overlayId = overlayId; - mThumbs.put(pos, info); - + item.mThumb = info; + final GridView grid = GalleryPicker.this.mGridView; final int firstVisible = grid.getFirstVisiblePosition(); - + // Minor optimization -- only notify if the specified position is visible if ((pos >= firstVisible) && (pos < firstVisible + grid.getChildCount())) { - GalleryPickerAdapter.this.notifyDataSetChanged(); + GalleryPickerAdapter.this.notifyDataSetChanged(); } } }); @@ -339,29 +388,22 @@ public class GalleryPicker extends Activity { } } } catch (Exception ex) { - Log.e(TAG, "got exception generating collage views " + ex.toString()); + Log.e(TAG, "got exception generating collage views ", ex); } } }); mWorkerThread.start(); mWorkerThread.toBackground(); } - - Uri firstImageUri(String id) { - ImageManager.IImageList list = ImageManager.instance().allImages( - GalleryPicker.this, - getContentResolver(), - ImageManager.DataLocation.ALL, - ImageManager.INCLUDE_IMAGES, - ImageManager.SORT_DESCENDING, - id); - Uri uri = list.getImageAt(0).fullSizeImageUri(); - list.deactivate(); - return uri; + + private void addBucketIfNotEmpty(int itemType, String bucketId, int labelId) { + if (!isEmptyBucket(Item.convertItemTypeToIncludedMediaType(itemType), bucketId)) { + mItems.add(new Item(itemType, bucketId, getResources().getString(labelId))); + } } public int getCount() { - return mIds.size() + 1; // add 1 for the everything bucket + return mItems.size(); } public Object getItem(int position) { @@ -371,41 +413,39 @@ public class GalleryPicker extends Activity { public long getItemId(int position) { return position; } - + private String baseTitleForPosition(int position) { - if (position == 0) { - return getResources().getString(R.string.all_images); - } else { - return mNames.get(position-1); - } + return mItems.get(position).mName; + } + + private int getIncludeMediaTypes(int position) { + return mItems.get(position).getIncludeMediaTypes(); } public View getView(final int position, View convertView, ViewGroup parent) { View v; - + if (convertView == null) { LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.gallery_picker_item, null); } else { v = convertView; } - + TextView titleView = (TextView) v.findViewById(R.id.title); - GalleryPickerItem iv = (GalleryPickerItem) v.findViewById(R.id.thumbnail); - ItemInfo info = mThumbs.get(position); + iv.setOverlay(mItems.get(position).getOverlay()); + ItemInfo info = mItems.get(position).mThumb; if (info != null) { iv.setImageBitmap(info.bitmap); - iv.setOverlay(info.overlayId); String title = baseTitleForPosition(position) + " (" + info.count + ")"; titleView.setText(title); } else { iv.setImageResource(android.R.color.transparent); - iv.setOverlay(-1); titleView.setText(baseTitleForPosition(position)); } - + return v; } }; @@ -415,13 +455,13 @@ public class GalleryPicker extends Activity { super.onPause(); mPausing = true; unregisterReceiver(mReceiver); - + // free up some ram mAdapter = null; mGridView.setAdapter(null); System.gc(); } - + @Override public void onResume() { super.onResume(); @@ -433,7 +473,7 @@ public class GalleryPicker extends Activity { boolean scanning = ImageManager.isMediaScannerScanning(this); rebake(false, scanning); - + // install an intent filter to receive SD card related events. IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); @@ -455,10 +495,10 @@ public class GalleryPicker extends Activity { StatFs stat = new StatFs(storageDirectory); long remaining = (long)stat.getAvailableBlocks() * (long)stat.getBlockSize(); if (remaining < LOW_STORAGE_THRESHOLD) { - + mHandler.post(new Runnable() { public void run() { - Toast.makeText(GalleryPicker.this.getApplicationContext(), + Toast.makeText(GalleryPicker.this.getApplicationContext(), R.string.not_enough_space, 5000).show(); } }); @@ -467,8 +507,10 @@ public class GalleryPicker extends Activity { } }); t.start(); - - if (!scanning && mAdapter.mIds.size() <= 1) { + + // If we just have one folder, open it. (Probably never triggered because we always have + // At least two folders now.) + if (!scanning && mAdapter.mItems.size() <= 1) { android.net.Uri uri = Images.Media.INTERNAL_CONTENT_URI; Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); @@ -476,26 +518,27 @@ public class GalleryPicker extends Activity { return; } } - + private void setBackgrounds(Resources r) { mFrameGalleryMask = r.getDrawable(R.drawable.frame_gallery_preview_album_mask); mCellOutline = r.getDrawable(android.R.drawable.gallery_thumb); + mVideoOverlay = r.getDrawable(R.drawable.ic_gallery_video_overlay); } - + Handler mHandler = new Handler(); - + private void placeImage(Bitmap image, Canvas c, Paint paint, int imageWidth, int widthPadding, int imageHeight, int heightPadding, int offsetX, int offsetY, int pos) { int row = pos / 2; int col = pos - (row * 2); - + int xPos = (col * (imageWidth + widthPadding)) - offsetX; int yPos = (row * (imageHeight + heightPadding)) - offsetY; - + c.drawBitmap(image, xPos, yPos, paint); } - + private Bitmap makeMiniThumbBitmap(int width, int height, ImageManager.IImageList images) { int count = images.getCount(); // We draw three different version of the folder image depending on the number of images in the folder. @@ -507,30 +550,20 @@ public class GalleryPicker extends Activity { int imageHeight = height; int offsetWidth = 0; int offsetHeight = 0; - if (count < 4) { - count = 1; - // uncomment for 2 pictures per frame -// if (count == 2 || count == 3) { -// count = 2; -// imageWidth = imageWidth * 2 / 3; -// imageHeight = imageHeight * 2 / 3; -// offsetWidth = imageWidth / 3 - padding; -// offsetHeight = -imageHeight / 3 + padding * 2; - } else if (count >= 4) { - count = 4; - imageWidth = (imageWidth - padding) / 2; // 2 here because we show two images - imageHeight = (imageHeight - padding) / 2; // per row and column - } + + imageWidth = (imageWidth - padding) / 2; // 2 here because we show two images + imageHeight = (imageHeight - padding) / 2; // per row and column + final Paint p = new Paint(); final Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); final Canvas c = new Canvas(b); - + final Matrix m = new Matrix(); - + // draw the whole canvas as transparent p.setColor(0x00000000); c.drawPaint(p); - + // draw the mask normally p.setColor(0xFFFFFFFF); mFrameGalleryMask.setBounds(0, 0, width, height); @@ -542,17 +575,34 @@ public class GalleryPicker extends Activity { pdpaint.setStyle(Paint.Style.FILL); c.drawRect(0, 0, width, height, pdpaint); - - for (int i = 0; i < count; i++) { + + for (int i = 0; i < 4; i++) { if (mPausing) { return null; } + + Bitmap temp = null; ImageManager.IImage image = i < count ? images.getImageAt(i) : null; - if (image == null) { - break; + + if (image != null) { + temp = image.miniThumbBitmap(); } - Bitmap temp = image.miniThumbBitmap(); + if (temp != null) { + if (ImageManager.isVideo(image)) { + Bitmap newMap = temp.copy(temp.getConfig(), true); + Canvas overlayCanvas = new Canvas(newMap); + int overlayWidth = mVideoOverlay.getIntrinsicWidth(); + int overlayHeight = mVideoOverlay.getIntrinsicHeight(); + int left = (newMap.getWidth() - overlayWidth) / 2; + int top = (newMap.getHeight() - overlayHeight) / 2; + Rect newBounds = new Rect(left, top, left + overlayWidth, top + overlayHeight); + mVideoOverlay.setBounds(newBounds); + mVideoOverlay.draw(overlayCanvas); + temp.recycle(); + temp = newMap; + } + Bitmap temp2 = ImageLoader.transform(m, temp, imageWidth, imageHeight, true); if (temp2 != temp) temp.recycle(); @@ -567,22 +617,24 @@ public class GalleryPicker extends Activity { mCellOutline.draw(tempCanvas); placeImage(thumb, c, pdpaint, imageWidth, padding, imageHeight, padding, offsetWidth, offsetHeight, i); - + thumb.recycle(); - + if (temp != null) temp.recycle(); } + return b; } - + @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); - + + MenuHelper.addCaptureMenuItems(menu, this); mFlipItem = MenuHelper.addFlipOrientation(menu, this, mPrefs); - menu.add(0, 0, 0, R.string.camerasettings) + menu.add(0, 0, 5, R.string.camerasettings) .setOnMenuItemClickListener(new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { Intent preferences = new Intent(); @@ -597,11 +649,32 @@ public class GalleryPicker extends Activity { return true; } - @Override + @Override public boolean onPrepareOptionsMenu(android.view.Menu menu) { int keyboard = getResources().getConfiguration().keyboardHidden; mFlipItem.setEnabled(keyboard == android.content.res.Configuration.KEYBOARDHIDDEN_YES); return true; } + + private boolean isEmptyBucket(int mediaTypes, String bucketId) { + // TODO: Find a more efficient way of calculating this + ImageManager.IImageList list = createImageList(mediaTypes, bucketId); + try { + return list.isEmpty(); + } + finally { + list.deactivate(); + } + } + + private ImageManager.IImageList createImageList(int mediaTypes, String bucketId) { + return ImageManager.instance().allImages( + this, + getContentResolver(), + ImageManager.DataLocation.ALL, + mediaTypes, + ImageManager.SORT_DESCENDING, + bucketId); + } } diff --git a/src/com/android/camera/GallerySettings.java b/src/com/android/camera/GallerySettings.java index 3af6867..8cbeba2 100644 --- a/src/com/android/camera/GallerySettings.java +++ b/src/com/android/camera/GallerySettings.java @@ -25,7 +25,7 @@ import android.content.Context; /** * GallerySettings */ -class GallerySettings extends CameraSettings +public class GallerySettings extends CameraSettings { public GallerySettings() { diff --git a/src/com/android/camera/HighlightView.java b/src/com/android/camera/HighlightView.java index 594bab6..408beab 100644 --- a/src/com/android/camera/HighlightView.java +++ b/src/com/android/camera/HighlightView.java @@ -376,35 +376,35 @@ public class HighlightView float heightUnits = widthUnits; switch (keyCode) - { - case KeyEvent.KEYCODE_DPAD_LEFT: - if (mMode == ModifyMode.Move) - moveBy(-widthUnits, 0); - else if (mMode == ModifyMode.Grow) - growBy(-widthUnits, 0); - break; - - case KeyEvent.KEYCODE_DPAD_RIGHT: - if (mMode == ModifyMode.Move) - moveBy(widthUnits, 0); + { + case KeyEvent.KEYCODE_DPAD_LEFT: + if (mMode == ModifyMode.Move) + moveBy(-widthUnits, 0); else if (mMode == ModifyMode.Grow) - growBy(widthUnits, 0); - break; - - case KeyEvent.KEYCODE_DPAD_UP: - if (mMode == ModifyMode.Move) - moveBy(0, -heightUnits); + growBy(-widthUnits, 0); + break; + + case KeyEvent.KEYCODE_DPAD_RIGHT: + if (mMode == ModifyMode.Move) + moveBy(widthUnits, 0); + else if (mMode == ModifyMode.Grow) + growBy(widthUnits, 0); + break; + + case KeyEvent.KEYCODE_DPAD_UP: + if (mMode == ModifyMode.Move) + moveBy(0, -heightUnits); else if (mMode == ModifyMode.Grow) - growBy(0, -heightUnits); - break; + growBy(0, -heightUnits); + break; - case KeyEvent.KEYCODE_DPAD_DOWN: - if (mMode == ModifyMode.Move) - moveBy(0, heightUnits); + case KeyEvent.KEYCODE_DPAD_DOWN: + if (mMode == ModifyMode.Move) + moveBy(0, heightUnits); else if (mMode == ModifyMode.Grow) - growBy(0, heightUnits); - break; - } + growBy(0, heightUnits); + break; + } } enum ModifyMode { None, Move,Grow }; diff --git a/src/com/android/camera/ImageGallery2.java b/src/com/android/camera/ImageGallery2.java index c8abdae..44d297b 100644 --- a/src/com/android/camera/ImageGallery2.java +++ b/src/com/android/camera/ImageGallery2.java @@ -24,6 +24,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; @@ -51,11 +52,14 @@ import android.view.Window; import android.widget.TextView; import android.widget.Toast; import android.preference.PreferenceManager; +import android.provider.MediaStore; import android.widget.Scroller; import java.util.Calendar; import java.util.GregorianCalendar; +import com.android.camera.ImageManager.IImage; + public class ImageGallery2 extends Activity { private static final String TAG = "ImageGallery2"; private ImageManager.IImageList mAllImages; @@ -66,10 +70,11 @@ public class ImageGallery2 extends Activity { public final static int VIEW_MSG = 3; private static final String INSTANCE_STATE_TAG = "scrollY"; - + private Dialog mMediaScanningDialog; - + private MenuItem mFlipItem; + private MenuItem mSlideShowItem; private SharedPreferences mPrefs; public ImageGallery2() { @@ -115,11 +120,15 @@ public class ImageGallery2 extends Activity { } }); - menu.setHeaderTitle(R.string.context_menu_header); - if ((mInclusion & ImageManager.INCLUDE_IMAGES) != 0) { + boolean isImage = ImageManager.isImage(mSelectedImageGetter.getCurrentImage()); + + menu.setHeaderTitle(isImage ? R.string.context_menu_header + : R.string.video_context_menu_header); + if ((mInclusion & (ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS)) != 0) { MenuHelper.MenuItemsResult r = MenuHelper.addImageMenuItems( menu, MenuHelper.INCLUDE_ALL, + isImage, ImageGallery2.this, mHandler, mDeletePhotoRunnable, @@ -136,37 +145,15 @@ public class ImageGallery2 extends Activity { if (r != null) r.gettingReadyToOpen(menu, mSelectedImageGetter.getCurrentImage()); - addSlideShowMenu(menu, 1000); - } - - if ((mInclusion & ImageManager.INCLUDE_VIDEOS) != 0) { - MenuHelper.MenuItemsResult r = MenuHelper.addVideoMenuItems( - menu, - MenuHelper.INCLUDE_ALL, - ImageGallery2.this, - mHandler, - mSelectedImageGetter, - new Runnable() { - public void run() { - ImageManager.IImage image = mSelectedImageGetter.getCurrentImage(); - if (image != null) { - mGvs.clearCache(); - mAllImages.removeImage(mSelectedImageGetter.getCurrentImage()); - mGvs.invalidate(); - mGvs.start(); - mNoImagesView.setVisibility(mAllImages.getCount() > 0 ? View.GONE : View.VISIBLE); - } - } - }, - null, null); - if (r != null) - r.gettingReadyToOpen(menu, mSelectedImageGetter.getCurrentImage()); + if (isImage) { + addSlideShowMenu(menu, 1000); + } } } }); } } - + private MenuItem addSlideShowMenu(Menu menu, int position) { return menu.add(0, 207, position, R.string.slide_show) .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @@ -194,7 +181,7 @@ public class ImageGallery2 extends Activity { }) .setIcon(android.R.drawable.ic_menu_slideshow); } - + private Runnable mDeletePhotoRunnable = new Runnable() { public void run() { mGvs.clearCache(); @@ -204,7 +191,7 @@ public class ImageGallery2 extends Activity { mNoImagesView.setVisibility(mAllImages.getCount() > 0 ? View.GONE : View.VISIBLE); } }; - + private SelectedImageGetter mSelectedImageGetter = new SelectedImageGetter() { public Uri getCurrentImageUri() { ImageManager.IImage image = getCurrentImage(); @@ -227,20 +214,20 @@ public class ImageGallery2 extends Activity { super.onConfigurationChanged(newConfig); mTargetScroll = mGvs.getScrollY(); } - + private Runnable mLongPressCallback = new Runnable() { public void run() { mGvs.showContextMenu(); } }; - + @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { // The keyUp doesn't get called when the longpress menu comes up. We only get here when the user // lets go of the center key before the longpress menu comes up. mHandler.removeCallbacks(mLongPressCallback); - + // open the photo if (mSelectedImageGetter.getCurrentImage() != null) { mGvs.onSelect(mGvs.mCurrentSelection); @@ -282,7 +269,8 @@ public class ImageGallery2 extends Activity { mHandler.postDelayed(mLongPressCallback, ViewConfiguration.getLongPressTimeout()); break; case KeyEvent.KEYCODE_DEL: - MenuHelper.deletePhoto(this, mDeletePhotoRunnable); + MenuHelper.deleteImage(this, mDeletePhotoRunnable, + mSelectedImageGetter.getCurrentImage()); break; default: handled = false; @@ -402,10 +390,10 @@ public class ImageGallery2 extends Activity { } if (scanning) { mMediaScanningDialog = ProgressDialog.show( - this, - null, - getResources().getString(R.string.wait), - true, + this, + null, + getResources().getString(R.string.wait), + true, true); mAllImages = ImageManager.instance().emptyImageList(); } else { @@ -418,7 +406,7 @@ public class ImageGallery2 extends Activity { checkThumbnails(); } } - + @Override protected void onSaveInstanceState(Bundle state) { super.onSaveInstanceState(state); @@ -431,7 +419,7 @@ public class ImageGallery2 extends Activity { super.onRestoreInstanceState(state); mTargetScroll = state.getInt(INSTANCE_STATE_TAG, 0); } - + int mTargetScroll; @Override @@ -474,7 +462,7 @@ public class ImageGallery2 extends Activity { rebake(true, false); } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { Toast.makeText(ImageGallery2.this, getResources().getString(R.string.wait), 5000); - rebake(false, true); + rebake(false, true); } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { if (Config.LOGV) Log.v(TAG, "rebake because of ACTION_MEDIA_SCANNER_FINISHED"); @@ -489,10 +477,10 @@ public class ImageGallery2 extends Activity { registerReceiver(mReceiver, intentFilter); MenuHelper.requestOrientation(this, mPrefs); - + rebake(false, ImageManager.isMediaScannerScanning(this)); } - + private void stopCheckingThumbnails() { mStopThumbnailChecking = true; if (mThumbnailCheckThread != null) { @@ -523,7 +511,7 @@ public class ImageGallery2 extends Activity { if (mStopThumbnailChecking) { return false; } - + if (!mLayoutComplete) { return true; } @@ -563,11 +551,11 @@ public class ImageGallery2 extends Activity { Log.v(TAG, "check thumbnails thread finishing; took " + (t2-t1)); } }); - + mThumbnailCheckThread.setName("check_thumbnails"); mThumbnailCheckThread.start(); mThumbnailCheckThread.toBackground(); - + ImageManager.IImageList list = allImages(true); mNoImagesView.setVisibility(list.getCount() > 0 ? View.GONE : View.VISIBLE); } @@ -575,21 +563,12 @@ public class ImageGallery2 extends Activity { @Override public boolean onCreateOptionsMenu(android.view.Menu menu) { MenuItem item; - if (false) { - if ((mInclusion & ImageManager.INCLUDE_IMAGES) != 0) { - item = menu.add(0, 0, 0, R.string.upload_all); - item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - UploadAction.uploadImage(ImageGallery2.this, null); - return true; - } - }); - item.setIcon(android.R.drawable.ic_menu_upload); - } - } - addSlideShowMenu(menu, 0); + MenuHelper.addCaptureMenuItems(menu, this); + if ((mInclusion & ImageManager.INCLUDE_IMAGES) != 0) { + mSlideShowItem = addSlideShowMenu(menu, 5); - mFlipItem = MenuHelper.addFlipOrientation(menu, this, mPrefs); + mFlipItem = MenuHelper.addFlipOrientation(menu, this, mPrefs); + } item = menu.add(0, 0, 1000, R.string.camerasettings); item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @@ -605,15 +584,32 @@ public class ImageGallery2 extends Activity { return true; } - - @Override + + @Override public boolean onPrepareOptionsMenu(android.view.Menu menu) { - int keyboard = getResources().getConfiguration().keyboardHidden; - mFlipItem.setEnabled(keyboard == android.content.res.Configuration.KEYBOARDHIDDEN_YES); + if ((mInclusion & ImageManager.INCLUDE_IMAGES) != 0) { + boolean imageSelected = isImageSelected(); + boolean videoSelected = isVideoSelected(); + int keyboard = getResources().getConfiguration().keyboardHidden; + mFlipItem.setEnabled(imageSelected + && (keyboard == android.content.res.Configuration.KEYBOARDHIDDEN_YES)); + // TODO: Only enable slide show if there is at least one image in the folder. + mSlideShowItem.setEnabled(!videoSelected); + } return true; } + private boolean isImageSelected() { + IImage image = mSelectedImageGetter.getCurrentImage(); + return (image != null) && ImageManager.isImage(image); + } + + private boolean isVideoSelected() { + IImage image = mSelectedImageGetter.getCurrentImage(); + return (image != null) && ImageManager.isVideo(image); + } + private synchronized ImageManager.IImageList allImages(boolean assumeMounted) { if (mAllImages == null) { mNoImagesView = findViewById(R.id.no_images); @@ -636,6 +632,11 @@ public class ImageGallery2 extends Activity { leftText.setText(R.string.photos_gallery_title); } if (type.equals("vnd.android.cursor.dir/video") || type.equals("video/*")) { + mInclusion = ImageManager.INCLUDE_VIDEOS; + if (isPickIntent()) + leftText.setText(R.string.pick_videos_gallery_title); + else + leftText.setText(R.string.videos_gallery_title); } } Bundle extras = intent.getExtras(); @@ -644,6 +645,11 @@ public class ImageGallery2 extends Activity { leftText.setText(title); } + if (extras != null) { + mInclusion = (ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS) + & extras.getInt("mediaTypes", mInclusion); + } + if (extras != null && extras.getBoolean("pick-drm")) { Log.d(TAG, "pick-drm is true"); mInclusion = ImageManager.INCLUDE_DRM_IMAGES; @@ -651,7 +657,8 @@ public class ImageGallery2 extends Activity { } } if (Config.LOGV) - Log.v(TAG, "computing images... mSortAscending is " + mSortAscending + "; assumeMounted is " + assumeMounted); + Log.v(TAG, "computing images... mSortAscending is " + mSortAscending + + "; assumeMounted is " + assumeMounted); Uri uri = getIntent().getData(); if (!assumeMounted) { mAllImages = ImageManager.instance().emptyImageList(); @@ -758,7 +765,7 @@ public class ImageGallery2 extends Activity { velocityY = maxVelocity; else if (velocityY < -maxVelocity) velocityY = -maxVelocity; - + select(-1); if (mFling) { mScroller = new Scroller(getContext()); @@ -891,8 +898,8 @@ public class ImageGallery2 extends Activity { if (mGallery.isFinishing() || mGallery.mPausing) { return; - } - + } + clearCache(); mCurrentSpec = mCellSizeChoices[mSizeChoice]; @@ -905,7 +912,7 @@ public class ImageGallery2 extends Activity { mCurrentSpec.mLeftEdgePadding = ((right - left) - ((mCurrentSpec.mColumns - 1) * mCurrentSpec.mCellSpacing) - (mCurrentSpec.mColumns * mCurrentSpec.mCellWidth)) / 2; mCurrentSpec.mRightEdgePadding = mCurrentSpec.mLeftEdgePadding; - + int rows = (mGallery.mAllImages.getCount() + mCurrentSpec.mColumns - 1) / mCurrentSpec.mColumns; mMaxScrollY = mCurrentSpec.mCellSpacing + (rows * (mCurrentSpec.mCellSpacing + mCurrentSpec.mCellHeight)) - (bottom - top) + mMaxOvershoot; mMinScrollY = 0 - mMaxOvershoot; @@ -950,9 +957,10 @@ public class ImageGallery2 extends Activity { private int mWorkCounter = 0; private boolean mDone = false; - + private Thread mWorkerThread; - private Bitmap mErrorBitmap; + private Bitmap mMissingImageThumbnailBitmap; + private Bitmap mMissingVideoThumbnailBitmap; public void dump() { synchronized (ImageBlockManager.this) { @@ -1027,12 +1035,20 @@ public class ImageGallery2 extends Activity { } // Create this bitmap lazily, and only once for all the ImageBlocks to use - public Bitmap getErrorBitmap() { - if (mErrorBitmap == null) { - mErrorBitmap = BitmapFactory.decodeResource(GridViewSpecial.this.getResources(), - android.R.drawable.ic_menu_report_image); + public Bitmap getErrorBitmap(ImageManager.IImage image) { + if (ImageManager.isImage(image)) { + if (mMissingImageThumbnailBitmap == null) { + mMissingImageThumbnailBitmap = BitmapFactory.decodeResource(GridViewSpecial.this.getResources(), + R.drawable.ic_missing_thumbnail_picture); + } + return mMissingImageThumbnailBitmap; + } else { + if (mMissingVideoThumbnailBitmap == null) { + mMissingVideoThumbnailBitmap = BitmapFactory.decodeResource(GridViewSpecial.this.getResources(), + R.drawable.ic_missing_thumbnail_video); + } + return mMissingVideoThumbnailBitmap; } - return mErrorBitmap; } private ImageBlock getBlockForPos(int pos) { @@ -1299,6 +1315,7 @@ public class ImageGallery2 extends Activity { int mRequestedMask; // columns which have been requested to the loader int mCompletedMask; // columns which have been completed from the loader boolean mIsVisible; + Drawable mVideoOverlay; public void dump(StringBuilder line1, StringBuilder line2) { synchronized (ImageBlock.this) { @@ -1315,7 +1332,7 @@ public class ImageGallery2 extends Activity { mBlockNumber = -1; mCellOutline = GridViewSpecial.this.getResources().getDrawable(android.R.drawable.gallery_thumb); } - + private void recycleBitmaps() { synchronized (ImageBlock.this) { mBitmap.recycle(); @@ -1434,13 +1451,13 @@ public class ImageGallery2 extends Activity { // change in the future. int w = mCurrentSpec.mCellWidth; int h = mCurrentSpec.mCellHeight; - + int bw = b.getWidth(); int bh = b.getHeight(); int deltaW = bw - w; int deltaH = bh - h; - + if (deltaW < 10 && deltaH < 10) { int halfDeltaW = deltaW / 2; int halfDeltaH = deltaH / 2; @@ -1460,7 +1477,7 @@ public class ImageGallery2 extends Activity { } } else { // If the thumbnail cannot be drawn, put up an error icon instead - Bitmap error = mImageBlockManager.getErrorBitmap(); + Bitmap error = mImageBlockManager.getErrorBitmap(image); int width = error.getWidth(); int height = error.getHeight(); Rect source = new Rect(0, 0, width, height); @@ -1469,6 +1486,19 @@ public class ImageGallery2 extends Activity { Rect dest = new Rect(left, top, left + width, top + height); mCanvas.drawBitmap(error, source, dest, mPaint); } + if (ImageManager.isVideo(image)) { + if (mVideoOverlay == null) { + mVideoOverlay = getResources().getDrawable( + R.drawable.ic_gallery_video_overlay); + } + int width = mVideoOverlay.getIntrinsicWidth(); + int height = mVideoOverlay.getIntrinsicHeight(); + int left = (mCurrentSpec.mCellWidth - width) / 2 + xPos; + int top = (mCurrentSpec.mCellHeight - height) / 2 + yPos; + Rect newBounds = new Rect(left, top, left + width, top + height); + mVideoOverlay.setBounds(newBounds); + mVideoOverlay.draw(mCanvas); + } paintSel(base + baseOffset, xPos, yPos); } @@ -1524,7 +1554,7 @@ public class ImageGallery2 extends Activity { // Log.v(TAG, "wanted block " + mBlockNumber + " but got " + startBlock); return; } - + if (mBitmap == null) { return; } @@ -1644,11 +1674,11 @@ public class ImageGallery2 extends Activity { } Intent intent = new Intent(Intent.ACTION_VIEW, targetUri); - // this should be unnecessary but if you remove this line then executing - // the subsequent startActivity causes the user to have to choose among - // ViewImage and a number of bogus entries (like attaching the image to - // a contact). - intent.setClass(mContext, ViewImage.class); + if (img instanceof ImageManager.VideoObject) { + intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, + ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + } + try { mContext.startActivity(intent); } catch (Exception ex) { diff --git a/src/com/android/camera/ImageManager.java b/src/com/android/camera/ImageManager.java index 8d3f90a..1fe93b5 100755 --- a/src/com/android/camera/ImageManager.java +++ b/src/com/android/camera/ImageManager.java @@ -25,8 +25,11 @@ import android.database.Cursor; import android.database.DataSetObserver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Canvas; import android.graphics.Matrix; import android.location.Location; +import android.media.MediaMetadataRetriever; +import android.media.MediaPlayer; import android.net.Uri; import android.os.Environment; import android.os.Handler; @@ -36,8 +39,10 @@ import android.provider.DrmStore; import android.provider.MediaStore; import android.provider.MediaStore.Images.ImageColumns; import android.provider.MediaStore.Images.Thumbnails; +import android.provider.MediaStore.Video.VideoColumns; import android.provider.MediaStore.Images; import android.provider.MediaStore.MediaColumns; +import android.provider.MediaStore.Video; import android.util.Config; import android.util.Log; @@ -69,7 +74,7 @@ public class ImageManager { private static final String TAG = "ImageManager"; private static final int MINI_THUMB_DATA_FILE_VERSION = 3; - + static public void debug_where(String tag, String msg) { try { throw new Exception(); @@ -98,11 +103,11 @@ public class ImageManager { private static int computeSampleSize(BitmapFactory.Options options, int target) { int w = options.outWidth; int h = options.outHeight; - + int candidateW = w / target; int candidateH = h / target; int candidate = Math.max(candidateW, candidateH); - + if (candidate == 0) return 1; @@ -110,7 +115,7 @@ public class ImageManager { if ((w > target) && (w / candidate) < target) candidate -= 1; } - + if (candidate > 1) { if ((h > target) && (h / candidate) < target) candidate -= 1; @@ -121,7 +126,7 @@ public class ImageManager { return candidate; } - /* + /* * All implementors of ICancelable should inherit from BaseCancelable * since it provides some convenience methods such as acknowledgeCancel * and checkCancel. @@ -129,10 +134,10 @@ public class ImageManager { public abstract class BaseCancelable implements ICancelable { boolean mCancel = false; boolean mFinished = false; - + /* * Subclasses should call acknowledgeCancel when they're finished with - * their operation. + * their operation. */ protected void acknowledgeCancel() { synchronized (this) { @@ -161,7 +166,7 @@ public class ImageManager { } catch (InterruptedException ex) { // now what??? TODO } - + return retVal; } } @@ -205,13 +210,13 @@ public class ImageManager { protected BaseImage(long id, long miniThumbId, ContentResolver cr, BaseImageList container, int cursorRow) { mContentResolver = cr; mId = id; - mMiniThumbMagic = miniThumbId; + mMiniThumbMagic = miniThumbId; mContainer = container; mCursorRow = cursorRow; } - + abstract Bitmap.CompressFormat compressionType(); - + public void commitChanges() { Cursor c = getCursor(); synchronized (c) { @@ -221,7 +226,7 @@ public class ImageManager { } } } - + /** * Take a given bitmap and compress it to a file as described * by the Uri parameter. @@ -248,7 +253,7 @@ public class ImageManager { } return false; } - + public boolean get() { try { long t1 = System.currentTimeMillis(); @@ -297,7 +302,7 @@ public class ImageManager { return false; if (!(other instanceof Image)) return false; - + return fullSizeImageUri().equals(((Image)other).fullSizeImageUri()); } @@ -327,11 +332,11 @@ public class ImageManager { ParcelFileDescriptor mPFD; BitmapFactory.Options mOptions = new BitmapFactory.Options(); long mCancelInitiationTime; - + public LoadBitmapCancelable(ParcelFileDescriptor pfdInput) { mPFD = pfdInput; } - + public boolean doCancelWork() { if (VERBOSE) Log.v(TAG, "requesting bitmap load cancel"); @@ -339,7 +344,7 @@ public class ImageManager { mOptions.requestCancelDecode(); return true; } - + public Bitmap get() { try { Bitmap b = makeBitmap(targetWidthHeight, fullSizeImageUri(), mPFD, mOptions); @@ -386,7 +391,7 @@ public class ImageManager { return null; } } - + public long fullSizeImageId() { return mId; } @@ -394,11 +399,11 @@ public class ImageManager { public Uri fullSizeImageUri() { return mContainer.contentUri(mId); } - + public IImageList getContainer() { return mContainer; } - + Cursor getCursor() { return mContainer.getCursor(); } @@ -411,7 +416,7 @@ public class ImageManager { return c.getLong(mContainer.indexDateTaken()); } } - + protected int getDegreesRotated() { return 0; } @@ -597,7 +602,7 @@ public class ImageManager { } } } - + public int getHeight() { ParcelFileDescriptor input = null; try { @@ -660,7 +665,7 @@ public class ImageManager { protected Bitmap makeBitmap(int targetWidthHeight, Uri uri, ParcelFileDescriptor pfdInput, BitmapFactory.Options options) { return mContainer.makeBitmap(targetWidthHeight, uri, pfdInput, options); } - + /* (non-Javadoc) * @see com.android.camera.IImage#thumb1() */ @@ -702,7 +707,7 @@ public class ImageManager { return null; } } - + public void onRemove() { mContainer.mCache.remove(mId); } @@ -736,7 +741,7 @@ public class ImageManager { } } } - + /* (non-Javadoc) * @see com.android.camera.IImage#setName() */ @@ -748,7 +753,7 @@ public class ImageManager { } } } - + public void setPicasaId(String id) { Cursor c = null; try { @@ -772,7 +777,7 @@ public class ImageManager { c.close(); } } - + /* (non-Javadoc) * @see com.android.camera.IImage#thumbUri() */ @@ -782,7 +787,7 @@ public class ImageManager { uri = uri.buildUpon().appendQueryParameter("thumb", "1").build(); return uri; } - + @Override public String toString() { return fullSizeImageUri().toString(); @@ -810,16 +815,17 @@ public class ImageManager { mSort = sort; mUri = uri; mBaseUri = uri; + mBucketId = bucketId; mContentResolver = cr; } - + String randomAccessFilePath(int version) { String directoryName = Environment.getExternalStorageDirectory().toString() + "/dcim/.thumbnails"; String path = directoryName + "/.thumbdata" + version + "-" + mUri.hashCode(); return path; } - + RandomAccessFile miniThumbDataFile() { if (mMiniThumbData == null) { String path = randomAccessFilePath(MINI_THUMB_DATA_FILE_VERSION); @@ -834,7 +840,7 @@ public class ImageManager { try { mMiniThumbData = new RandomAccessFile(f, "rw"); } catch (IOException ex) { - + } } return mMiniThumbData; @@ -853,14 +859,14 @@ public class ImageManager { return thumb; } OutputStream thumbOut = mContentResolver.openOutputStream(uri); - thumb.compress(Bitmap.CompressFormat.JPEG, 60, thumbOut); + thumb.compress(Bitmap.CompressFormat.JPEG, 60, thumbOut); thumbOut.close(); return thumb; } catch (Exception ex) { Log.d(TAG, "unable to store thumbnail: " + ex); return thumb; - } + } } /** @@ -924,11 +930,11 @@ public class ImageManager { } return uri; } - + java.util.Random mRandom = new java.util.Random(System.currentTimeMillis()); protected SomewhatFairLock mLock = new SomewhatFairLock(); - + class SomewhatFairLock { private Object mSync = new Object(); private boolean mLocked = false; @@ -954,7 +960,7 @@ public class ImageManager { mLocked = true; } } - + void unlock() { // if (VERBOSE) Log.v(TAG, "unlocking... thread " + Thread.currentThread().getId()); synchronized (mSync) { @@ -991,7 +997,7 @@ public class ImageManager { // which will produce much better scaling quality // and is significantly faster. options.inSampleSize = computeSampleSize(options, THUMBNAIL_TARGET_SIZE); - + if (VERBOSE) { Log.v(TAG, "in createThumbnailFromExif using inSampleSize of " + options.inSampleSize); } @@ -1019,7 +1025,20 @@ public class ImageManager { } return bitmap; } - + + private Bitmap createVideoThumbnail(String filePath) { + Bitmap bitmap = null; + MediaMetadataRetriever retriever = new MediaMetadataRetriever(); + try { + retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY); + retriever.setDataSource(filePath); + bitmap = retriever.captureFrame(); + } finally { + retriever.release(); + } + return bitmap; + } + // returns id public long checkThumbnail(BaseImage existingImage, Cursor c, int i) { long magic, fileMagic = 0, id; @@ -1042,7 +1061,7 @@ public class ImageManager { } if (magic != 0) { - // check the mini thumb file for the right data. Right is defined as + // check the mini thumb file for the right data. Right is defined as // having the right magic number at the offset reserved for this "id". RandomAccessFile r = miniThumbDataFile(); if (r != null) { @@ -1072,18 +1091,23 @@ public class ImageManager { // If we can't retrieve the thumbnail, first check if there is one embedded in the // EXIF data. If not, or it's not big enough, decompress the full size image. Bitmap bitmap = null; - + String filePath = null; synchronized (c) { if (c.moveToPosition(i)) { filePath = c.getString(indexData()); } } - if (filePath != null) { bitmap = createThumbnailFromEXIF(filePath, id); if (bitmap == null) { - bitmap = createThumbnailFromUri(c, id); + String mimeType = c.getString(indexMimeType()); + boolean isVideo = isVideoMimeType(mimeType); + if (isVideo) { + bitmap = createVideoThumbnail(filePath); + } else { + bitmap = createThumbnailFromUri(c, id); + } } synchronized (c) { int degrees = 0; @@ -1141,7 +1165,7 @@ public class ImageManager { Log.v(TAG, ">>>>>>>>>>> need to check " + c.getCount() + " rows"); c.close(); - + if (!ImageManager.hasStorage()) { if (VERBOSE) Log.v(TAG, "bailing from the image checker thread -- no storage"); @@ -1158,7 +1182,7 @@ public class ImageManager { return; } } - + c = getCursor(); try { if (VERBOSE) Log.v(TAG, "checkThumbnails found " + c.getCount()); @@ -1188,7 +1212,7 @@ public class ImageManager { } } } - + public void commitChanges() { synchronized (mCursor) { mCursor.commitUpdates(); @@ -1208,16 +1232,21 @@ public class ImageManager { return ContentUris.withAppendedId(mBaseUri, id); } } - + public void deactivate() { mCursorDeactivated = true; - mCursor.deactivate(); + try { + mCursor.deactivate(); + } catch (IllegalStateException e) { + // IllegalStateException may be thrown if the cursor is stale. + Log.e(TAG, "Caught exception while deactivating cursor.", e); + } if (mMiniThumbData != null) { try { mMiniThumbData.close(); mMiniThumbData = null; } catch (IOException ex) { - + } } } @@ -1244,6 +1273,11 @@ public class ImageManager { return 0; } } + + public boolean isEmpty() { + return getCount() == 0; + } + protected Cursor getCursor() { synchronized (mCursor) { if (mCursorDeactivated) { @@ -1252,11 +1286,11 @@ public class ImageManager { return mCursor; } } - + protected void activateCursor() { requery(); } - + public IImage getImageAt(int i) { Cursor c = getCursor(); synchronized (c) { @@ -1307,7 +1341,7 @@ public class ImageManager { RandomAccessFile r = miniThumbDataFile(); if (r == null) return null; - + long pos = id * sBytesPerMiniThumb; RandomAccessFile f = r; synchronized (f) { @@ -1349,7 +1383,7 @@ public class ImageManager { } index += 1; } while (c.moveToNext()); - } + } return -1; } } @@ -1368,7 +1402,7 @@ public class ImageManager { protected abstract int indexTitle(); protected abstract int indexDisplayName(); protected abstract int indexThumbId(); - + protected IImage make(long id, long miniThumbId, ContentResolver cr, IImageList list, long timestamp, int index, int rotation) { return null; } @@ -1400,7 +1434,7 @@ public class ImageManager { return false; } - + /* (non-Javadoc) * @see com.android.camera.IImageList#removeImageAt(int) */ @@ -1460,7 +1494,7 @@ public class ImageManager { } r.seek(pos); r.writeByte(0); // we have no data in this slot - + // if magic is 0 then leave it alone if (magic == 0) r.skipBytes(8); @@ -1468,11 +1502,11 @@ public class ImageManager { r.writeLong(magic); r.writeInt(data.length); r.write(data); - // f.flush(); + // f.flush(); r.seek(pos); r.writeByte(1); // we have data in this slot long t3 = System.currentTimeMillis(); - + if (VERBOSE) Log.v(TAG, "saveMiniThumbToFile took " + (t3-t0) + "; " + (t1-t0) + " " + (t2-t1) + " " + (t3-t2)); } } catch (IOException ex) { @@ -1486,9 +1520,9 @@ public class ImageManager { mHandler = h; } } - + public class CanceledException extends Exception { - + } public enum DataLocation { NONE, INTERNAL, EXTERNAL, ALL } @@ -1502,17 +1536,17 @@ public class ImageManager { * from an ICancelable can be retrieved using the get* method. If the * operation was canceled then null is returned. The act of canceling * is to call "cancel" -- from another thread. - * - * In general an object which implements ICancelable will need to + * + * In general an object which implements ICancelable will need to * check, periodically, whether they are canceled or not. This works * well for some things and less well for others. - * + * * Right now the actual jpeg encode does not check cancelation but * the part of encoding which writes the data to disk does. Note, * though, that there is what appears to be a bug in the jpeg encoder * in that if the stream that's being written is closed it crashes * rather than returning an error. TODO fix that. - * + * * When an object detects that it is canceling it must, before exiting, * call acknowledgeCancel. This is necessary because the caller of * cancel() will block until acknowledgeCancel is called. @@ -1526,7 +1560,7 @@ public class ImageManager { */ public boolean cancel(); } - + public interface IGetBitmap_cancelable extends ICancelable { // returns the bitmap or null if there was an error or we were canceled public Bitmap get(); @@ -1543,9 +1577,9 @@ public class ImageManager { * @return the bitmap for the full size image. */ public abstract Bitmap fullSizeBitmap(int targetWidthOrHeight); - + /** - * + * * @return an object which can be canceled while the bitmap is loading */ public abstract IGetBitmap_cancelable fullSizeBitmap_cancelable(int targetWidthOrHeight); @@ -1589,7 +1623,7 @@ public class ImageManager { public abstract String getDisplayName(); public abstract String getPicasaId(); - + public abstract int getRow(); public abstract int getWidth(); @@ -1599,13 +1633,13 @@ public class ImageManager { public abstract long imageId(); public abstract boolean isReadonly(); - + public abstract boolean isDrm(); - + public abstract Bitmap miniThumbBitmap(); - + public abstract void onRemove(); - + public abstract boolean rotateImageBy(int degrees); /** @@ -1622,26 +1656,27 @@ public class ImageManager { * Sets the name of the image. */ public abstract void setName(String name); - + public abstract void setPicasaId(String id); - + /** * Get the bitmap for the medium thumbnail. * @return the bitmap for the medium thumbnail. */ public abstract Bitmap thumbBitmap(); - + public abstract Uri thumbUri(); - + public abstract String getDataPath(); } + public interface IImageList { public HashMap<String, String> getBucketIds(); public interface OnChange { public void onChange(IImageList list); } - + public interface ThumbCheckCallback { public boolean checking(int current, int count); } @@ -1658,7 +1693,13 @@ public class ImageManager { * @return the number of images */ public abstract int getCount(); - + + /** + * @return true if the count of image objects is zero. + */ + + public abstract boolean isEmpty(); + /** * Returns the image at the ith position. * @@ -1666,7 +1707,7 @@ public class ImageManager { * @return the image at the ith position */ public abstract IImage getImageAt(int i); - + /** * Returns the image with a particular Uri. * @@ -1674,40 +1715,26 @@ public class ImageManager { * @return the image with a particular Uri. */ public abstract IImage getImageForUri(Uri uri);; - + public abstract boolean removeImage(IImage image); /** * Removes the image at the ith position. * @param i the position */ public abstract void removeImageAt(int i); - + public abstract void removeOnChangeListener(OnChange changeCallback); public abstract void setOnChangeListener(OnChange changeCallback, Handler h); } - - class VideoObject extends Image { - public VideoObject() { - super(0, 0, null, null, 0, 0); - } - - public String getTags() { - return null; - } - - public String setTags(String tags) { - return null; - } - } class Image extends BaseImage implements IImage { int mRotation; - + protected Image(long id, long miniThumbId, ContentResolver cr, BaseImageList container, int cursorRow, int rotation) { super(id, miniThumbId, cr, container, cursorRow); mRotation = rotation; } - + public String getDataPath() { String path = null; Cursor c = getCursor(); @@ -1724,7 +1751,7 @@ public class ImageManager { protected int getDegreesRotated() { return mRotation; } - + protected void setDegreesRotated(int degrees) { Cursor c = getCursor(); mRotation = degrees; @@ -1743,12 +1770,12 @@ public class ImageManager { String mimeType = getMimeType(); if (mimeType == null) return Bitmap.CompressFormat.JPEG; - + if (mimeType.equals("image/png")) return Bitmap.CompressFormat.PNG; else if (mimeType.equals("image/png")) return Bitmap.CompressFormat.PNG; - + return Bitmap.CompressFormat.JPEG; } @@ -1782,16 +1809,16 @@ public class ImageManager { } return 0; } - + public boolean isReadonly() { String mimeType = getMimeType(); return !"image/jpeg".equals(mimeType) && !"image/png".equals(mimeType); } - + public boolean isDrm() { return false; } - + /** * Remove tag if already there. Otherwise, does nothing. * @param tag @@ -1822,17 +1849,17 @@ public class ImageManager { * @see com.android.camera.IImage#saveModifiedImage(android.graphics.Bitmap) */ public IGetBoolean_cancelable saveImageContents( - final Bitmap image, + final Bitmap image, final byte [] jpegData, final int orientation, final boolean newFile, final Cursor cursor) { final class SaveImageContentsCancelable extends BaseCancelable implements IGetBoolean_cancelable { IGetBoolean_cancelable mCurrentCancelable = null; - + SaveImageContentsCancelable() { } - + public boolean doCancelWork() { synchronized (this) { if (mCurrentCancelable != null) @@ -1840,22 +1867,22 @@ public class ImageManager { } return true; } - + public boolean get() { try { Bitmap thumbnail = null; - + long t1 = System.currentTimeMillis(); Uri uri = mContainer.contentUri(mId); synchronized (this) { checkCanceled(); mCurrentCancelable = compressImageToFile(image, jpegData, uri); } - + long t2 = System.currentTimeMillis(); if (!mCurrentCancelable.get()) return false; - + synchronized (this) { String filePath; synchronized (cursor) { @@ -1890,7 +1917,7 @@ public class ImageManager { saveMiniThumb(rotate(thumbnail, orientation)); long t5 = System.currentTimeMillis(); checkCanceled(); - + if (VERBOSE) Log.v(TAG, String.format("Timing data %d %d %d %d", t2-t1, t3-t2, t4-t3, t5-t4)); return true; } catch (CanceledException ex) { @@ -1911,7 +1938,7 @@ public class ImageManager { } return new SaveImageContentsCancelable(); } - + private void setExifRotation(int degrees) { try { Cursor c = getCursor(); @@ -1952,7 +1979,7 @@ public class ImageManager { Log.e(TAG, "unable to save exif data with new orientation " + fullSizeImageUri()); } } - + /** * Save the rotated image by updating the Exif "Orientation" tag. * @param degrees @@ -1979,10 +2006,10 @@ public class ImageManager { if (mContainer.mThumbUri != null) { try { c = mContentResolver.query( - mContainer.mThumbUri, - THUMB_PROJECTION, - Thumbnails.IMAGE_ID + "=?", - new String[] { String.valueOf(fullSizeImageId()) }, + mContainer.mThumbUri, + THUMB_PROJECTION, + Thumbnails.IMAGE_ID + "=?", + new String[] { String.valueOf(fullSizeImageId()) }, null); if (c != null && c.moveToFirst()) { Uri thumbUri = ContentUris.withAppendedId(mContainer.mThumbUri, c.getLong(((ImageList)mContainer).INDEX_THUMB_ID)); @@ -2011,7 +2038,7 @@ public class ImageManager { c.close(); } } - + if (bitmap == null) { bitmap = fullSizeBitmap(THUMBNAIL_TARGET_SIZE, false); if (VERBOSE) { @@ -2038,7 +2065,7 @@ public class ImageManager { final static private String sWhereClause = "(" + Images.Media.MIME_TYPE + "=? or " + Images.Media.MIME_TYPE + "=?" + ")"; final static private String[] sAcceptableImageTypes = new String[] { "image/jpeg", "image/png" }; - + private static final String[] IMAGE_PROJECTION = new String[] { "_id", "_data", @@ -2047,7 +2074,7 @@ public class ImageManager { ImageColumns.ORIENTATION, ImageColumns.MIME_TYPE }; - + /** * Represents an ordered collection of Image objects. * Provides an api to add and remove an image. @@ -2059,7 +2086,7 @@ public class ImageManager { final int INDEX_DATE_TAKEN = indexOf(IMAGE_PROJECTION, ImageColumns.DATE_TAKEN); final int INDEX_MINI_THUMB_MAGIC = indexOf(IMAGE_PROJECTION, ImageColumns.MINI_THUMB_MAGIC); final int INDEX_ORIENTATION = indexOf(IMAGE_PROJECTION, ImageColumns.ORIENTATION); - + final int INDEX_THUMB_ID = indexOf(THUMB_PROJECTION, BaseColumns._ID); final int INDEX_THUMB_IMAGE_ID = indexOf(THUMB_PROJECTION, Images.Thumbnails.IMAGE_ID); final int INDEX_THUMB_WIDTH = indexOf(THUMB_PROJECTION, Images.Thumbnails.WIDTH); @@ -2068,12 +2095,12 @@ public class ImageManager { boolean mIsRegistered = false; ContentObserver mContentObserver; DataSetObserver mDataSetObserver; - + public HashMap<String, String> getBucketIds() { Cursor c = Images.Media.query( mContentResolver, mBaseUri.buildUpon().appendQueryParameter("distinct", "true").build(), - new String[] { + new String[] { ImageColumns.BUCKET_DISPLAY_NAME, ImageColumns.BUCKET_ID }, @@ -2098,7 +2125,6 @@ public class ImageManager { mBaseUri = imageUri; mThumbUri = thumbUri; mSort = sort; - mBucketId = bucketId; mContentResolver = cr; @@ -2118,7 +2144,7 @@ public class ImageManager { // For now ignore them since there shouldn't be anyone modifying the database on the fly. if (true) return; - + synchronized (mCursor) { requery(); } @@ -2126,7 +2152,7 @@ public class ImageManager { mListener.onChange(ImageList.this); } }; - + mContentObserver = new ContentObserver(null) { @Override public boolean deliverSelfNotifications() { @@ -2139,7 +2165,7 @@ public class ImageManager { updateRunnable.run(); } }; - + mDataSetObserver = new DataSetObserver() { @Override public void onChanged() { @@ -2152,23 +2178,23 @@ public class ImageManager { if (VERBOSE) Log.v(TAG, "MyDataSetObserver.onInvalidated: " + mCursorDeactivated); } }; - + registerObservers(); } - + private void registerObservers() { if (mIsRegistered) return; - + mCursor.registerContentObserver(mContentObserver); mCursor.registerDataSetObserver(mDataSetObserver); mIsRegistered = true; } - + private void unregisterObservers() { if (!mIsRegistered) return; - + mCursor.unregisterContentObserver(mContentObserver); mCursor.unregisterDataSetObserver(mDataSetObserver); mIsRegistered = false; @@ -2183,21 +2209,21 @@ public class ImageManager { super.activateCursor(); registerObservers(); } - + protected String whereClause() { if (mBucketId != null) { - return sWhereClause + " and " + Images.Media.BUCKET_ID + " = " + mBucketId; + return sWhereClause + " and " + Images.Media.BUCKET_ID + " = '" + mBucketId + "'"; } else { return sWhereClause; } } - + protected String[] whereClauseArgs() { return sAcceptableImageTypes; } - + protected Cursor createCursor() { - Cursor c = + Cursor c = Images.Media.query( mContentResolver, mBaseUri, @@ -2209,7 +2235,7 @@ public class ImageManager { Log.v(TAG, "createCursor got cursor with count " + (c == null ? -1 : c.getCount())); return c; } - + protected int indexOrientation() { return INDEX_ORIENTATION; } protected int indexDateTaken() { return INDEX_DATE_TAKEN; } protected int indexDescription() { return -1; } @@ -2225,7 +2251,7 @@ public class ImageManager { protected int indexTitle() { return -1; } protected int indexDisplayName() { return -1; } protected int indexThumbId() { return INDEX_THUMB_ID; } - + protected IImage make(long id, long miniThumbId, ContentResolver cr, IImageList list, long timestamp, int index, int rotation) { return new Image(id, miniThumbId, mContentResolver, this, index, rotation); } @@ -2234,12 +2260,12 @@ public class ImageManager { Bitmap b = null; try { - if (pfd == null) + if (pfd == null) pfd = makeInputStream(uri); if (pfd == null) return null; - + if (options == null) options = new BitmapFactory.Options(); @@ -2272,7 +2298,7 @@ public class ImageManager { } return b; } - + private ParcelFileDescriptor makeInputStream(Uri uri) { try { return mContentResolver.openFileDescriptor(uri, "r"); @@ -2286,11 +2312,11 @@ public class ImageManager { // which could happen, I suppose, if the first two values were // duplicated String ascending = (mSort == SORT_ASCENDING ? " ASC" : " DESC"); - return + return Images.Media.DATE_TAKEN + ascending + "," + Images.Media._ID + ascending; } - + } /** @@ -2301,11 +2327,11 @@ public class ImageManager { DrmStore.Audio._ID, DrmStore.Audio.DATA, DrmStore.Audio.MIME_TYPE, - }; - + }; + final int INDEX_ID = indexOf(DRM_IMAGE_PROJECTION, DrmStore.Audio._ID); final int INDEX_MIME_TYPE = indexOf(DRM_IMAGE_PROJECTION, DrmStore.Audio.MIME_TYPE); - + public DrmImageList(Context ctx, ContentResolver cr, Uri imageUri, int sort, String bucketId) { super(ctx, cr, imageUri, null, sort, bucketId); } @@ -2323,16 +2349,16 @@ public class ImageManager { public long checkThumbnail(BaseImage existingImage, Cursor c, int i) { return 0; } - + class DrmImage extends Image { protected DrmImage(long id, ContentResolver cr, BaseImageList container, int cursorRow) { super(id, 0, cr, container, cursorRow, 0); } - + public boolean isDrm() { return true; } - + public boolean isReadonly() { return true; } @@ -2340,16 +2366,21 @@ public class ImageManager { public Bitmap miniThumbBitmap() { return fullSizeBitmap(MINI_THUMB_TARGET_SIZE); } - + public Bitmap thumbBitmap() { return fullSizeBitmap(THUMBNAIL_TARGET_SIZE); } + + public String getDisplayName() { + return getTitle(); + } } - - protected IImage make(long id, long miniThumbId, ContentResolver cr, IImageList list, long timestamp, int index) { + + @Override + protected IImage make(long id, long miniThumbId, ContentResolver cr, IImageList list, long timestamp, int index, int rotation) { return new DrmImage(id, mContentResolver, this, index); } - + protected int indexOrientation() { return -1; } protected int indexDateTaken() { return -1; } protected int indexDescription() { return -1; } @@ -2363,11 +2394,11 @@ public class ImageManager { protected int indexTitle() { return -1; } protected int indexDisplayName() { return -1; } protected int indexThumbId() { return -1; } - + // TODO review this probably should be based on DATE_TAKEN same as images private String sortOrder() { String ascending = (mSort == SORT_ASCENDING ? " ASC" : " DESC"); - return + return DrmStore.Images.TITLE + ascending + "," + DrmStore.Images._ID; } @@ -2385,7 +2416,7 @@ public class ImageManager { // The second component indicates which sublist we're referring // to (an int which is used to index into mSubList). ArrayList<Long> mSkipList = null; - + int [] mSkipCounts = null; public HashMap<String, String> getBucketIds() { @@ -2395,7 +2426,7 @@ public class ImageManager { } return hashMap; } - + public ImageListUber(IImageList [] sublist, int sort) { mSubList = sublist.clone(); mSort = sort; @@ -2412,7 +2443,7 @@ public class ImageManager { } } } - + public void checkThumbnails(ThumbCheckCallback cb) { // TODO this isn't quite right because we need to get the // total from each sub item and provide that in the callback @@ -2421,7 +2452,7 @@ public class ImageManager { for (int i = 0; i < length; i++) sublist[i].checkThumbnails(cb); } - + public void commitChanges() { final IImageList sublist[] = mSubList; final int length = sublist.length; @@ -2448,6 +2479,17 @@ public class ImageManager { return count; } + public boolean isEmpty() { + final IImageList sublist[] = mSubList; + final int length = sublist.length; + for (int i = 0; i < length; i++) { + if (! sublist[i].isEmpty()) { + return false; + } + } + return true; + } + // mSkipCounts is used to tally the counts as we traverse // the mSkipList. It's a member variable only so that // we don't have to allocate each time through. Otherwise @@ -2456,7 +2498,7 @@ public class ImageManager { public synchronized IImage getImageAt(int index) { if (index < 0 || index > getCount()) throw new IndexOutOfBoundsException("index " + index + " out of range max is " + getCount()); - + // first make sure our allocations are in order if (mSkipCounts == null || mSubList.length > mSkipCounts.length) mSkipCounts = new int[mSubList.length]; @@ -2610,7 +2652,7 @@ public class ImageManager { if (changeCallback == mListener) mListener = null; } - + public void setOnChangeListener(OnChange changeCallback, Handler h) { mListener = changeCallback; mHandler = h; @@ -2642,7 +2684,7 @@ public class ImageManager { public long getDateTaken() { return 0; } - + public String getMimeType() { throw new UnsupportedOperationException(); } @@ -2658,7 +2700,7 @@ public class ImageManager { public double getLatitude() { return 0D; } - + public double getLongitude() { return 0D; } @@ -2678,7 +2720,7 @@ public class ImageManager { public int getRow() { throw new UnsupportedOperationException(); } - + public int getHeight() { return 0; } @@ -2686,7 +2728,7 @@ public class ImageManager { public int getWidth() { return 0; } - + public boolean hasLatLong() { return false; } @@ -2694,7 +2736,7 @@ public class ImageManager { public boolean isReadonly() { return true; } - + public boolean isDrm() { return false; } @@ -2706,7 +2748,7 @@ public class ImageManager { public boolean rotateImageBy(int degrees) { return false; } - + public void setDescription(String description) { throw new UnsupportedOperationException(); } @@ -2718,13 +2760,13 @@ public class ImageManager { public void setName(String name) { throw new UnsupportedOperationException(); } - + public void setPicasaId(long id) { } public void setPicasaId(String id) { } - + public Uri thumbUri() { throw new UnsupportedOperationException(); } @@ -2739,11 +2781,11 @@ public class ImageManager { UriImage() { } - + public String getDataPath() { return mUri.getPath(); } - + InputStream getInputStream() { try { if (mUri.getScheme().equals("file")) { @@ -2758,7 +2800,7 @@ public class ImageManager { return null; } } - + ParcelFileDescriptor getPFD() { try { if (mUri.getScheme().equals("file")) { @@ -2773,7 +2815,7 @@ public class ImageManager { return null; } } - + /* (non-Javadoc) * @see com.android.camera.ImageManager.IImage#fullSizeBitmap(int) */ @@ -2790,7 +2832,7 @@ public class ImageManager { options.inJustDecodeBounds = false; options.inDither = false; options.inPreferredConfig = Bitmap.Config.ARGB_8888; - + Bitmap b = BitmapFactory.decodeFileDescriptor(pfdInput.getFileDescriptor(), null, options); if (VERBOSE) { Log.v(TAG, "B: got bitmap " + b + " with sampleSize " + options.inSampleSize); @@ -2808,11 +2850,11 @@ public class ImageManager { ParcelFileDescriptor pfdInput; BitmapFactory.Options mOptions = new BitmapFactory.Options(); long mCancelInitiationTime; - + public LoadBitmapCancelable(ParcelFileDescriptor pfd) { pfdInput = pfd; } - + public boolean doCancelWork() { if (VERBOSE) Log.v(TAG, "requesting bitmap load cancel"); @@ -2820,7 +2862,7 @@ public class ImageManager { mOptions.requestCancelDecode(); return true; } - + public Bitmap get() { try { Bitmap b = makeBitmap(targetWidthOrHeight, fullSizeImageUri(), pfdInput, mOptions); @@ -2848,12 +2890,12 @@ public class ImageManager { return null; } } - + @Override public Uri fullSizeImageUri() { return mUri; } - + @Override public InputStream fullSizeImageData() { return getInputStream(); @@ -2862,26 +2904,26 @@ public class ImageManager { public long imageId() { return 0; } - + public Bitmap miniThumbBitmap() { return thumbBitmap(); } - + @Override public String getTitle() { return mUri.toString(); } - + @Override public String getDisplayName() { return getTitle(); } - - @Override + + @Override public String getDescription() { return ""; } - + public Bitmap thumbBitmap() { Bitmap b = fullSizeBitmap(THUMBNAIL_TARGET_SIZE); if (b != null) { @@ -2894,7 +2936,7 @@ public class ImageManager { return null; } } - + private BitmapFactory.Options snifBitmapOptions() { ParcelFileDescriptor input = getPFD(); if (input == null) @@ -2920,13 +2962,13 @@ public class ImageManager { BitmapFactory.Options options = snifBitmapOptions(); return (options!=null) ? options.outMimeType : ""; } - + @Override public int getHeight() { BitmapFactory.Options options = snifBitmapOptions(); return (options!=null) ? options.outHeight : 0; } - + @Override public int getWidth() { BitmapFactory.Options options = snifBitmapOptions(); @@ -2948,11 +2990,15 @@ public class ImageManager { public void deactivate() { // nothing to do here } - + public int getCount() { return 1; } + public boolean isEmpty() { + return false; + } + public IImage getImageAt(int i) { if (i == 0) return mSingleImage; @@ -2980,7 +3026,7 @@ public class ImageManager { protected int indexDateTaken() { return -1; } - + @Override protected int indexMimeType() { return -1; @@ -2990,12 +3036,12 @@ public class ImageManager { protected int indexDescription() { return -1; } - + @Override protected int indexId() { return -1; } - + @Override protected int indexData() { return -1; @@ -3040,7 +3086,7 @@ public class ImageManager { protected int indexThumbId() { return -1; } - + private InputStream makeInputStream(Uri uri) { InputStream input = null; try { @@ -3087,14 +3133,14 @@ public class ImageManager { public ThreadSafeOutputStream(OutputStream delegate) { mDelegateStream = delegate; } - + @Override synchronized public void close() throws IOException { try { mClosed = true; mDelegateStream.close(); } catch (IOException ex) { - + } } @@ -3113,7 +3159,7 @@ public class ImageManager { synchronized (this) { if (mClosed) return; - + int writeLength = Math.min(8192, length); mDelegateStream.write(b, offset, writeLength); offset += writeLength; @@ -3129,14 +3175,349 @@ public class ImageManager { mDelegateStream.write(oneByte); } } - + + class VideoList extends BaseImageList implements IImageList { + private final String[] sProjection = new String[] { + Video.Media._ID, + Video.Media.DATA, + Video.Media.DATE_TAKEN, + Video.Media.TITLE, + Video.Media.DISPLAY_NAME, + Video.Media.DESCRIPTION, + Video.Media.IS_PRIVATE, + Video.Media.TAGS, + Video.Media.CATEGORY, + Video.Media.LANGUAGE, + Video.Media.LATITUDE, + Video.Media.LONGITUDE, + Video.Media.MINI_THUMB_MAGIC, + Video.Media.MIME_TYPE, + }; + + final int INDEX_ID = indexOf(sProjection, Video.Media._ID); + final int INDEX_DATA = indexOf(sProjection, Video.Media.DATA); + final int INDEX_DATE_TAKEN = indexOf(sProjection, Video.Media.DATE_TAKEN); + final int INDEX_TITLE = indexOf(sProjection, Video.Media.TITLE); + final int INDEX_DISPLAY_NAME = indexOf(sProjection, Video.Media.DISPLAY_NAME); + final int INDEX_MIME_TYPE = indexOf(sProjection, Video.Media.MIME_TYPE); + final int INDEX_DESCRIPTION = indexOf(sProjection, Video.Media.DESCRIPTION); + final int INDEX_PRIVATE = indexOf(sProjection, Video.Media.IS_PRIVATE); + final int INDEX_TAGS = indexOf(sProjection, Video.Media.TAGS); + final int INDEX_CATEGORY = indexOf(sProjection, Video.Media.CATEGORY); + final int INDEX_LANGUAGE = indexOf(sProjection, Video.Media.LANGUAGE); + final int INDEX_LATITUDE = indexOf(sProjection, Video.Media.LATITUDE); + final int INDEX_LONGITUDE = indexOf(sProjection, Video.Media.LONGITUDE); + final int INDEX_MINI_THUMB_MAGIC = indexOf(sProjection, Video.Media.MINI_THUMB_MAGIC); + final int INDEX_THUMB_ID = indexOf(sProjection, BaseColumns._ID); + + public VideoList(Context ctx, ContentResolver cr, Uri uri, Uri thumbUri, + int sort, String bucketId) { + super(ctx, cr, uri, sort, bucketId); + + mCursor = createCursor(); + if (mCursor == null) { + Log.e(TAG, "unable to create video cursor for " + mBaseUri); + throw new UnsupportedOperationException(); + } + + if (Config.LOGV) { + Log.v(TAG, "for " + mUri.toString() + " got cursor " + mCursor + " with length " + + (mCursor != null ? mCursor.getCount() : -1)); + } + + if (mCursor == null) { + throw new UnsupportedOperationException(); + } + if (mCursor != null && mCursor.moveToFirst()) { + int row = 0; + do { + long imageId = mCursor.getLong(indexId()); + long dateTaken = mCursor.getLong(indexDateTaken()); + long miniThumbId = mCursor.getLong(indexMiniThumbId()); + mCache.put(imageId, new VideoObject(imageId, miniThumbId, mContentResolver, + this, dateTaken, row++)); + } while (mCursor.moveToNext()); + } + } + + public HashMap<String, String> getBucketIds() { + Cursor c = Images.Media.query( + mContentResolver, + mBaseUri.buildUpon().appendQueryParameter("distinct", "true").build(), + new String[] { + VideoColumns.BUCKET_DISPLAY_NAME, + VideoColumns.BUCKET_ID + }, + whereClause(), + whereClauseArgs(), + sortOrder()); + + HashMap<String, String> hash = new HashMap<String, String>(); + if (c != null && c.moveToFirst()) { + do { + Log.e(TAG, "id: " + c.getString(1) + " display_name: " + c.getString(0)); + hash.put(c.getString(1), c.getString(0)); + } while (c.moveToNext()); + } + return hash; + } + + protected String whereClause() { + if (mBucketId != null) { + return Images.Media.BUCKET_ID + " = '" + mBucketId + "'"; + } else { + return null; + } + } + + protected String[] whereClauseArgs() { + return null; + } + + protected Cursor createCursor() { + Cursor c = + Images.Media.query( + mContentResolver, + mBaseUri, + sProjection, + whereClause(), + whereClauseArgs(), + sortOrder()); + if (VERBOSE) + Log.v(TAG, "createCursor got cursor with count " + (c == null ? -1 : c.getCount())); + return c; + } + + protected int indexOrientation() { return -1; } + protected int indexDateTaken() { return INDEX_DATE_TAKEN; } + protected int indexDescription() { return INDEX_DESCRIPTION; } + protected int indexMimeType() { return INDEX_MIME_TYPE; } + protected int indexData() { return INDEX_DATA; } + protected int indexId() { return INDEX_ID; } + protected int indexLatitude() { return INDEX_LATITUDE; } + protected int indexLongitude() { return INDEX_LONGITUDE; } + protected int indexMiniThumbId() { return INDEX_MINI_THUMB_MAGIC; } + protected int indexPicasaWeb() { return -1; } + protected int indexPrivate() { return INDEX_PRIVATE; } + protected int indexTitle() { return INDEX_TITLE; } + protected int indexDisplayName() { return -1; } + protected int indexThumbId() { return INDEX_THUMB_ID; } + + protected IImage make(long id, long miniThumbId, ContentResolver cr, IImageList list, + long timestamp, int index) { + return new VideoObject(id, miniThumbId, mContentResolver, this, timestamp, index); + } + + @Override + protected Bitmap makeBitmap(int targetWidthHeight, Uri uri, ParcelFileDescriptor pfdInput, + BitmapFactory.Options options) { + MediaPlayer mp = new MediaPlayer(); + Bitmap thumbnail = sDefaultThumbnail; + try { + mp.setDataSource(mContext, uri); +// int duration = mp.getDuration(); +// int at = duration > 2000 ? 1000 : duration / 2; + int at = 1000; + thumbnail = mp.getFrameAt(at); + if (Config.LOGV) { + if ( thumbnail != null) { + Log.v(TAG, "getFrameAt @ " + at + " returned " + thumbnail + "; " + + thumbnail.getWidth() + " " + thumbnail.getHeight()); + } else { + Log.v(TAG, "getFrame @ " + at + " failed for " + uri); + } + } + } catch (IOException ex) { + } catch (IllegalArgumentException ex) { + } catch (SecurityException ex) { + } finally { + mp.release(); + } + return thumbnail; + } + + private final Bitmap sDefaultThumbnail = Bitmap.createBitmap(32, 32, Bitmap.Config.RGB_565); + + private String sortOrder() { + return Video.Media.DATE_MODIFIED + (mSort == SORT_ASCENDING ? " ASC " : " DESC"); + } + } + + /** + * Represents a particular video and provides access + * to the underlying data and two thumbnail bitmaps + * as well as other information such as the id, and + * the path to the actual video data. + */ + class VideoObject extends BaseImage implements IImage { + /** + * Constructor. + * + * @param id the image id of the image + * @param cr the content resolver + */ + protected VideoObject(long id, long miniThumbId, ContentResolver cr, VideoList container, + long dateTaken, int row) { + super(id, miniThumbId, cr, container, row); + } + + protected Bitmap.CompressFormat compressionType() { + return Bitmap.CompressFormat.JPEG; + } + + @Override + public boolean equals(Object other) { + if (other == null) + return false; + if (!(other instanceof VideoObject)) + return false; + + return fullSizeImageUri().equals(((VideoObject)other).fullSizeImageUri()); + } + + public String getDataPath() { + String path = null; + Cursor c = getCursor(); + synchronized (c) { + if (c.moveToPosition(getRow())) { + int column = ((VideoList)getContainer()).indexData(); + if (column >= 0) + path = c.getString(column); + } + } + return path; + } + + /* (non-Javadoc) + * @see com.android.camera.IImage#fullSizeBitmap() + */ + public Bitmap fullSizeBitmap(int targetWidthHeight) { + return sNoImageBitmap; + } + + public IGetBitmap_cancelable fullSizeBitmap_cancelable(int targetWidthHeight) { + return null; + } + + /* (non-Javadoc) + * @see com.android.camera.IImage#fullSizeImageData() + */ + public InputStream fullSizeImageData() { + try { + InputStream input = mContentResolver.openInputStream( + fullSizeImageUri()); + return input; + } catch (IOException ex) { + return null; + } + } + + /* (non-Javadoc) + * @see com.android.camera.IImage#fullSizeImageId() + */ + public long fullSizeImageId() { + return mId; + } + + public String getCategory() { + return getStringEntry(((VideoList)mContainer).INDEX_CATEGORY); + } + + public int getHeight() { + return 0; + } + + public String getLanguage() { + return getStringEntry(((VideoList)mContainer).INDEX_LANGUAGE); + } + + public String getPicasaId() { + return null; + } + + private String getStringEntry(int entryName) { + String entry = null; + Cursor c = getCursor(); + synchronized(c) { + if (c.moveToPosition(getRow())) { + entry = c.getString(entryName); + } + } + return entry; + } + + public String getTags() { + return getStringEntry(((VideoList)mContainer).INDEX_TAGS); + } + + public int getWidth() { + return 0; + } + + /* (non-Javadoc) + * @see com.android.camera.IImage#imageId() + */ + public long imageId() { + return mId; + } + + public boolean isReadonly() { + return false; + } + + public boolean isDrm() { + return false; + } + + public boolean rotateImageBy(int degrees) { + return false; + } + + public void setCategory(String category) { + setStringEntry(category, ((VideoList)mContainer).INDEX_CATEGORY); + } + + public void setLanguage(String language) { + setStringEntry(language, ((VideoList)mContainer).INDEX_LANGUAGE); + } + + private void setStringEntry(String entry, int entryName) { + Cursor c = getCursor(); + synchronized (c) { + if (c.moveToPosition(getRow())) { + c.updateString(entryName, entry); + } + } + } + + public void setTags(String tags) { + setStringEntry(tags, ((VideoList)mContainer).INDEX_TAGS); + } + + /* (non-Javadoc) + * @see com.android.camera.IImage#thumb1() + */ + public Bitmap thumbBitmap() { + return fullSizeBitmap(320); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("" + mId); + return sb.toString(); + } + + private final Bitmap sNoImageBitmap = Bitmap.createBitmap(128, 128, Bitmap.Config.RGB_565); + } + /* * How much quality to use when storing the thumbnail. */ private static ImageManager sInstance = null; private static final int MINI_THUMB_TARGET_SIZE = 96; private static final int THUMBNAIL_TARGET_SIZE = 320; - + private static final String[] THUMB_PROJECTION = new String[] { BaseColumns._ID, // 0 Images.Thumbnails.IMAGE_ID, // 1 @@ -3147,6 +3528,10 @@ public class ImageManager { private static Uri sStorageURI = Images.Media.EXTERNAL_CONTENT_URI; private static Uri sThumbURI = Images.Thumbnails.EXTERNAL_CONTENT_URI; + + private static Uri sVideoStorageURI = Uri.parse("content://media/external/video/media"); + + private static Uri sVideoThumbURI = Uri.parse("content://media/external/video/thumbnails"); /** * Returns an ImageList object that contains * all of the images. @@ -3157,13 +3542,13 @@ public class ImageManager { * @return the singleton ImageList */ static final public int SORT_ASCENDING = 1; - + static final public int SORT_DESCENDING = 2; static final public int INCLUDE_IMAGES = (1 << 0); static final public int INCLUDE_DRM_IMAGES = (1 << 1); static final public int INCLUDE_VIDEOS = (1 << 2); - + static public DataLocation getDefaultDataLocation() { return DataLocation.EXTERNAL; } @@ -3190,7 +3575,7 @@ public class ImageManager { static public byte [] miniThumbData(Bitmap source) { if (source == null) return null; - + float scale; if (source.getWidth() < source.getHeight()) { scale = MINI_THUMB_TARGET_SIZE / (float)source.getWidth(); @@ -3199,7 +3584,7 @@ public class ImageManager { } Matrix matrix = new Matrix(); matrix.setScale(scale, scale); - Bitmap miniThumbnail = ImageLoader.transform(matrix, source, + Bitmap miniThumbnail = ImageLoader.transform(matrix, source, MINI_THUMB_TARGET_SIZE, MINI_THUMB_TARGET_SIZE, false); if (miniThumbnail != source) { @@ -3223,7 +3608,7 @@ public class ImageManager { if (degrees != 0 && b != null) { Matrix m = new Matrix(); m.setRotate(degrees, (float) b.getWidth() / 2, (float) b.getHeight() / 2); - + Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true); // TODO should recycle here but that needs more testing/verification // b.recycle(); @@ -3231,12 +3616,12 @@ public class ImageManager { } return b; } - + public static int roundOrientation(int orientationInput) { int orientation = orientationInput; if (orientation == -1) orientation = 0; - + orientation = orientation % 360; int retVal; if (orientation < (0*90) + 45) { @@ -3255,6 +3640,35 @@ public class ImageManager { return retVal; } + + /** + * @return true if the mimetype is an image mimetype. + */ + public static boolean isImageMimeType(String mimeType) { + return mimeType.startsWith("image/"); + } + + /** + * @return true if the mimetype is a video mimetype. + */ + public static boolean isVideoMimeType(String mimeType) { + return mimeType.startsWith("video/"); + } + + /** + * @return true if the image is an image. + */ + public static boolean isImage(IImage image) { + return isImageMimeType(image.getMimeType()); + } + + /** + * @return true if the image is a video. + */ + public static boolean isVideo(IImage image) { + return isVideoMimeType(image.getMimeType()); + } + public Uri addImage( final Context ctx, final ContentResolver cr, @@ -3274,11 +3688,12 @@ public class ImageManager { values.put(Images.Media.ORIENTATION, orientation); File parentFile = new File(directory); + // Lowercase the path for hashing. This avoids duplicate buckets if the filepath + // case is changed externally. + // Keep the original case for display. String path = parentFile.toString().toLowerCase(); - String name = parentFile.getName().toLowerCase(); - - values.put(Images.ImageColumns.BUCKET_ID, path.hashCode()); - values.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, name); + String name = parentFile.getName(); + if (VERBOSE) Log.v(TAG, "addImage id is " + path.hashCode() + "; name " + name + "; path is " + path); if (location != null) { @@ -3288,24 +3703,24 @@ public class ImageManager { values.put(Images.Media.LATITUDE, location.getLatitude()); values.put(Images.Media.LONGITUDE, location.getLongitude()); } - + if (directory != null && filename != null) { String value = directory + "/" + filename; values.put("_data", value); } - + long t3 = System.currentTimeMillis(); Uri uri = cr.insert(sStorageURI, values); - + // The line above will create a filename that ends in .jpg // That filename is what will be handed to gmail when a user shares a photo. // Gmail gets the name of the picture attachment from the "DISPLAY_NAME" field. // Extract the filename and jam it into the display name. Cursor c = cr.query( - uri, - new String [] { ImageColumns._ID, Images.Media.DISPLAY_NAME, "_data" }, - null, - null, + uri, + new String [] { ImageColumns._ID, Images.Media.DISPLAY_NAME, "_data" }, + null, + null, null); if (c.moveToFirst()) { String filePath = c.getString(2); @@ -3331,7 +3746,7 @@ public class ImageManager { final byte [] jpegData) { class AddImageCancelable extends BaseCancelable implements IAddImage_cancelable { private IGetBoolean_cancelable mSaveImageCancelable; - + public boolean doCancelWork() { if (VERBOSE) { Log.v(TAG, "calling AddImageCancelable.cancel() " + mSaveImageCancelable); @@ -3347,7 +3762,7 @@ public class ImageManager { if (source == null && jpegData == null) { throw new IllegalArgumentException("source cannot be null"); } - + try { long t1 = System.currentTimeMillis(); synchronized (this) { @@ -3356,15 +3771,15 @@ public class ImageManager { } } long id = ContentUris.parseId(uri); - + BaseImageList il = new ImageList(ctx, cr, sStorageURI, sThumbURI, SORT_ASCENDING, null); ImageManager.Image image = new Image(id, 0, cr, il, il.getCount(), 0); long t5 = System.currentTimeMillis(); Cursor c = cr.query( - uri, - new String [] { ImageColumns._ID, ImageColumns.MINI_THUMB_MAGIC, "_data" }, - null, - null, + uri, + new String [] { ImageColumns._ID, ImageColumns.MINI_THUMB_MAGIC, "_data" }, + null, + null, null); c.moveToPosition(0); @@ -3372,7 +3787,7 @@ public class ImageManager { checkCanceled(); mSaveImageCancelable = image.saveImageContents(source, jpegData, orientation, true, c); } - + if (mSaveImageCancelable.get()) { long t6 = System.currentTimeMillis(); if (VERBOSE) Log.v(TAG, "saveImageContents took " + (t6-t5)); @@ -3403,7 +3818,7 @@ public class ImageManager { } return new AddImageCancelable(); } - + static public IImageList makeImageList(Uri uri, Context ctx, int sort) { ContentResolver cr = ctx.getContentResolver(); String uriString = (uri != null) ? uri.toString() : ""; @@ -3411,7 +3826,7 @@ public class ImageManager { // DRM images in a better way. Is there a constant // for content://drm somewhere?? IImageList imageList; - + if (uriString.startsWith("content://drm")) { imageList = ImageManager.instance().allImages( ctx, @@ -3435,7 +3850,7 @@ public class ImageManager { } return imageList; } - + public IImageList emptyImageList() { return new IImageList() { @@ -3456,6 +3871,10 @@ public class ImageManager { return 0; } + public boolean isEmpty() { + return true; + } + public IImage getImageAt(int i) { return null; } @@ -3476,10 +3895,10 @@ public class ImageManager { public void setOnChangeListener(com.android.camera.ImageManager.IImageList.OnChange changeCallback, Handler h) { } - + }; } - + public IImageList allImages(Context ctx, ContentResolver cr, DataLocation location, int inclusion, int sort) { return allImages(ctx, cr, location, inclusion, sort, null, null); } @@ -3487,12 +3906,12 @@ public class ImageManager { public IImageList allImages(Context ctx, ContentResolver cr, DataLocation location, int inclusion, int sort, String bucketId) { return allImages(ctx, cr, location, inclusion, sort, bucketId, null); } - + public IImageList allImages(Context ctx, ContentResolver cr, DataLocation location, int inclusion, int sort, String bucketId, Uri specificImageUri) { if (VERBOSE) { Log.v(TAG, "allImages " + location + " " + ((inclusion&INCLUDE_IMAGES)!=0) + " + v=" + ((inclusion&INCLUDE_VIDEOS)!=0)); } - + if (cr == null) { return null; } else { @@ -3510,7 +3929,7 @@ public class ImageManager { try { if (specificImageUri.getScheme().equalsIgnoreCase("content")) l.add(new ImageList(ctx, cr, specificImageUri, sThumbURI, sort, bucketId)); - else + else l.add(new SingleImageList(cr, specificImageUri)); } catch (UnsupportedOperationException ex) { } @@ -3522,11 +3941,17 @@ public class ImageManager { } catch (UnsupportedOperationException ex) { } } + if ((inclusion & INCLUDE_VIDEOS) != 0) { + try { + l.add(new VideoList(ctx, cr, sVideoStorageURI, sVideoThumbURI, sort, bucketId)); + } catch (UnsupportedOperationException ex) { + } + } } if (location == DataLocation.INTERNAL || location == DataLocation.ALL) { if ((inclusion & INCLUDE_IMAGES) != 0) { try { - l.add(new ImageList(ctx, cr, Images.Media.INTERNAL_CONTENT_URI, + l.add(new ImageList(ctx, cr, Images.Media.INTERNAL_CONTENT_URI, Images.Thumbnails.INTERNAL_CONTENT_URI, sort, bucketId)); } catch (UnsupportedOperationException ex) { } @@ -3546,7 +3971,7 @@ public class ImageManager { if (haveSdCard && location != DataLocation.INTERNAL) { return new ImageList(ctx, cr, sStorageURI, sThumbURI, sort, bucketId); } else { - return new ImageList(ctx, cr, Images.Media.INTERNAL_CONTENT_URI, + return new ImageList(ctx, cr, Images.Media.INTERNAL_CONTENT_URI, Images.Thumbnails.INTERNAL_CONTENT_URI, sort, bucketId); } } @@ -3577,7 +4002,7 @@ public class ImageManager { return false; } } - + static public boolean hasStorage() { return hasStorage(true); } @@ -3610,20 +4035,20 @@ public class ImageManager { } catch (UnsupportedOperationException ex) { return null; } - + } - + public static boolean isMediaScannerScanning(Context context) { boolean result = false; - Cursor cursor = query(context, MediaStore.getMediaScannerUri(), + Cursor cursor = query(context, MediaStore.getMediaScannerUri(), new String [] { MediaStore.MEDIA_SCANNER_VOLUME }, null, null, null); if (cursor != null) { if (cursor.getCount() == 1) { cursor.moveToFirst(); result = "external".equals(cursor.getString(0)); } - cursor.close(); - } + cursor.close(); + } if (VERBOSE) Log.v(TAG, ">>>>>>>>>>>>>>>>>>>>>>>>> isMediaScannerScanning returning " + result); diff --git a/src/com/android/camera/ImageViewTouchBase.java b/src/com/android/camera/ImageViewTouchBase.java index 9993373..7cdf55e 100644 --- a/src/com/android/camera/ImageViewTouchBase.java +++ b/src/com/android/camera/ImageViewTouchBase.java @@ -13,6 +13,7 @@ import android.util.Config; import android.util.Log; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; +import android.view.KeyEvent; import android.widget.ImageView; abstract public class ImageViewTouchBase extends ImageView { @@ -91,6 +92,17 @@ abstract public class ImageViewTouchBase extends ImageView { } } + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK && getScale() > 1.0f) { + // If we're zoomed in, pressing Back jumps out to show the entire image, otherwise Back + // returns the user to the gallery. + zoomTo(1.0f); + return true; + } + return super.onKeyDown(keyCode, event); + } + protected Handler mHandler = new Handler(); protected int mLastXTouchPos; diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java index 033fc9c..9e4fb82 100644 --- a/src/com/android/camera/MenuHelper.java +++ b/src/com/android/camera/MenuHelper.java @@ -23,12 +23,14 @@ import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Handler; +import android.provider.MediaStore; import android.util.Config; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import android.view.View; +import android.view.MenuItem.OnMenuItemClickListener; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; @@ -39,16 +41,18 @@ import android.widget.Toast; import java.util.ArrayList; +import com.android.camera.ImageManager.IImage; + public class MenuHelper { static private final String TAG = "MenuHelper"; - + static public final int GENERIC_ITEM = 1; static public final int IMAGE_SAVING_ITEM = 2; static public final int VIDEO_SAVING_ITEM = 3; static public final int IMAGE_MODE_ITEM = 4; static public final int VIDEO_MODE_ITEM = 5; static public final int MENU_ITEM_MAX = 5; - + static public final int INCLUDE_ALL = 0xFFFFFFFF; static public final int INCLUDE_VIEWPLAY_MENU = (1 << 0); static public final int INCLUDE_SHARE_MENU = (1 << 1); @@ -57,84 +61,52 @@ public class MenuHelper { static public final int INCLUDE_DELETE_MENU = (1 << 4); static public final int INCLUDE_ROTATE_MENU = (1 << 5); static public final int INCLUDE_DETAILS_MENU = (1 << 5); - + + static public final int MENU_SWITCH_CAMERA_MODE = 0; + static public final int MENU_CAPTURE_PICTURE = 1; + static public final int MENU_CAPTURE_VIDEO = 2; static public final int MENU_IMAGE_SHARE = 10; - static public final int MENU_IMAGE_SHARE_EMAIL = 11; - static public final int MENU_IMAGE_SHARE_MMS = 12; - static public final int MENU_IMAGE_SHARE_PICASA =13; static public final int MENU_IMAGE_SET = 14; static public final int MENU_IMAGE_SET_WALLPAPER = 15; static public final int MENU_IMAGE_SET_CONTACT = 16; static public final int MENU_IMAGE_SET_MYFAVE = 17; static public final int MENU_IMAGE_CROP = 18; static public final int MENU_IMAGE_ROTATE = 19; - static public final int MENU_IMAGE_ROTATE_LEFT = 20; + static public final int MENU_IMAGE_ROTATE_LEFT = 20; static public final int MENU_IMAGE_ROTATE_RIGHT = 21; static public final int MENU_IMAGE_TOSS = 22; static public final int MENU_VIDEO_PLAY = 23; static public final int MENU_VIDEO_SHARE = 24; - static public final int MENU_VIDEO_SHARE_MMS = 25; - static public final int MENU_VIDEO_SHARE_YOUTUBE = 26; static public final int MENU_VIDEO_TOSS = 27; - static public final int MENU_IMAGE_SHARE_PICASA_ALL =28; - + public interface MenuItemsResult { public void gettingReadyToOpen(Menu menu, ImageManager.IImage image); public void aboutToCall(MenuItem item, ImageManager.IImage image); } - + public interface MenuInvoker { public void run(MenuCallback r); } - + public interface MenuCallback { public void run(Uri uri, ImageManager.IImage image); } static MenuItemsResult addImageMenuItems( - Menu menu, + Menu menu, int inclusions, + final boolean isImage, final Activity activity, final Handler handler, final Runnable onDelete, final MenuInvoker onInvoke) { - final ArrayList<MenuItem> requiresWriteAccessItems = new ArrayList<MenuItem>(); - final ArrayList<MenuItem> requiresNoDrmAccessItems = new ArrayList<MenuItem>(); - if ((inclusions & INCLUDE_SHARE_MENU) != 0) { - if (Config.LOGV) - Log.v(TAG, ">>>>> add share"); - MenuItem item = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_SHARE, 10, - R.string.camera_share).setOnMenuItemClickListener( - new MenuItem.OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - onInvoke.run(new MenuCallback() { - public void run(Uri u, ImageManager.IImage image) { - if (image == null) - return; - - Intent intent = new Intent(); - intent.setAction(Intent.ACTION_SEND); - intent.setType(image.getMimeType()); - intent.putExtra(Intent.EXTRA_STREAM, u); - try { - activity.startActivity(Intent.createChooser(intent, - activity.getText(R.string.sendImage))); - } catch (android.content.ActivityNotFoundException ex) { - Toast.makeText(activity, R.string.no_way_to_share_image, Toast.LENGTH_SHORT).show(); - } - } - }); - return true; - } - }); - item.setIcon(android.R.drawable.ic_menu_share); - requiresNoDrmAccessItems.add(item); - } + final ArrayList<MenuItem> requiresWriteAccessItems = new ArrayList<MenuItem>(); + final ArrayList<MenuItem> requiresNoDrmAccessItems = new ArrayList<MenuItem>(); - if ((inclusions & INCLUDE_ROTATE_MENU) != 0) { + if (isImage && ((inclusions & INCLUDE_ROTATE_MENU) != 0)) { SubMenu rotateSubmenu = menu.addSubMenu(IMAGE_SAVING_ITEM, MENU_IMAGE_ROTATE, 40, R.string.rotate).setIcon(android.R.drawable.ic_menu_rotate); - // Don't show the rotate submenu if the item at hand is read only + // Don't show the rotate submenu if the item at hand is read only // since the items within the submenu won't be shown anyway. This is // really a framework bug in that it shouldn't show the submenu if // the submenu has no visible items. @@ -158,7 +130,7 @@ public class MenuHelper { public void run(Uri u, ImageManager.IImage image) { if (image == null || image.isReadonly()) return; - + image.rotateImageBy(90); } }); @@ -167,21 +139,8 @@ public class MenuHelper { }).setAlphabeticShortcut('r')); } } - - if ((inclusions & INCLUDE_DELETE_MENU) != 0) { - MenuItem deleteItem = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_TOSS, 70, R.string.camera_toss); - requiresWriteAccessItems.add(deleteItem); - deleteItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - deletePhoto(activity, onDelete); - return true; - } - }) - .setAlphabeticShortcut('d') - .setIcon(android.R.drawable.ic_menu_delete); - } - - if ((inclusions & INCLUDE_CROP_MENU) != 0) { + + if (isImage && ((inclusions & INCLUDE_CROP_MENU) != 0)) { MenuItem autoCrop = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_CROP, 73, R.string.camera_crop).setOnMenuItemClickListener( new MenuItem.OnMenuItemClickListener() { @@ -190,7 +149,7 @@ public class MenuHelper { public void run(Uri u, ImageManager.IImage image) { if (u == null) return; - + Intent cropIntent = new Intent(); cropIntent.setClass(activity, CropImage.class); cropIntent.setData(u); @@ -203,8 +162,8 @@ public class MenuHelper { autoCrop.setIcon(android.R.drawable.ic_menu_crop); requiresWriteAccessItems.add(autoCrop); } - - if ((inclusions & INCLUDE_SET_MENU) != 0) { + + if (isImage && ((inclusions & INCLUDE_SET_MENU) != 0)) { MenuItem setMenu = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_SET, 75, R.string.camera_set); setMenu.setIcon(android.R.drawable.ic_menu_set_as); @@ -214,7 +173,7 @@ public class MenuHelper { public void run(Uri u, ImageManager.IImage image) { if (u == null || image == null) return; - + if (Config.LOGV) Log.v(TAG, "in callback u is " + u + "; mime type is " + image.getMimeType()); Intent intent = new Intent(Intent.ACTION_ATTACH_DATA); @@ -228,6 +187,56 @@ public class MenuHelper { }); } + if ((inclusions & INCLUDE_SHARE_MENU) != 0) { + if (Config.LOGV) + Log.v(TAG, ">>>>> add share"); + MenuItem item1 = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_SHARE, 10, + R.string.camera_share).setOnMenuItemClickListener( + new MenuItem.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + onInvoke.run(new MenuCallback() { + public void run(Uri u, ImageManager.IImage image) { + if (image == null) + return; + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_SEND); + String mimeType = image.getMimeType(); + intent.setType(mimeType); + intent.putExtra(Intent.EXTRA_STREAM, u); + boolean isImage = ImageManager.isImageMimeType(mimeType); + try { + activity.startActivity(Intent.createChooser(intent, + activity.getText( + isImage ? R.string.sendImage : R.string.sendVideo))); + } catch (android.content.ActivityNotFoundException ex) { + Toast.makeText(activity, + isImage ? R.string.no_way_to_share_image + : R.string.no_way_to_share_video, + Toast.LENGTH_SHORT).show(); + } + } + }); + return true; + } + }); + item1.setIcon(android.R.drawable.ic_menu_share); + MenuItem item = item1; + requiresNoDrmAccessItems.add(item); + } + + if ((inclusions & INCLUDE_DELETE_MENU) != 0) { + MenuItem deleteItem = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_TOSS, 70, R.string.camera_toss); + requiresWriteAccessItems.add(deleteItem); + deleteItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + deleteImageImpl(activity, onDelete, isImage); + return true; + } + }) + .setAlphabeticShortcut('d') + .setIcon(android.R.drawable.ic_menu_delete); + } + if ((inclusions & INCLUDE_DETAILS_MENU) != 0) { MenuItem detailsMenu = menu.add(0, 0, 80, R.string.details).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { @@ -237,9 +246,9 @@ public class MenuHelper { return; AlertDialog.Builder builder = new AlertDialog.Builder(activity); - + final View d = View.inflate(activity, R.layout.detailsview, null); - + ImageView imageView = (ImageView) d.findViewById(R.id.details_thumbnail_image); imageView.setImageBitmap(image.miniThumbBitmap()); @@ -250,8 +259,8 @@ public class MenuHelper { String lengthString = ""; try { long length = data.available(); - lengthString = - android.content.Formatter.formatFileSize(activity, length); + lengthString = + android.text.format.Formatter.formatFileSize(activity, length); data.close(); } catch (java.io.IOException ex) { @@ -260,9 +269,14 @@ public class MenuHelper { ((TextView)d.findViewById(R.id.details_attrname_1)).setText(R.string.details_file_size); ((TextView)d.findViewById(R.id.details_attrvalu_1)).setText(lengthString); - String dimensionsString = String.valueOf(image.getWidth() + " X " + image.getHeight()); - ((TextView)d.findViewById(R.id.details_attrname_2)).setText(R.string.details_image_resolution); - ((TextView)d.findViewById(R.id.details_attrvalu_2)).setText(dimensionsString); + if (isImage) { + String dimensionsString = String.valueOf(image.getWidth() + " X " + image.getHeight()); + ((TextView)d.findViewById(R.id.details_attrname_2)).setText(R.string.details_image_resolution); + ((TextView)d.findViewById(R.id.details_attrvalu_2)).setText(dimensionsString); + } else { + d.findViewById(R.id.details_attrname_2).setVisibility(View.GONE); + d.findViewById(R.id.details_attrvalu_2).setVisibility(View.GONE); + } String dateString = ""; long dateTaken = image.getDateTaken(); @@ -270,19 +284,19 @@ public class MenuHelper { java.util.Date date = new java.util.Date(image.getDateTaken()); java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat(); dateString = dateFormat.format(date); - + ((TextView)d.findViewById(R.id.details_attrname_3)).setText(R.string.details_date_taken); ((TextView)d.findViewById(R.id.details_attrvalu_3)).setText(dateString); } else { d.findViewById(R.id.details_daterow).setVisibility(View.GONE); } - + builder.setIcon(android.R.drawable.ic_dialog_info) .setTitle(R.string.details_panel_title) .setView(d) .show(); - + } }); return true; @@ -290,7 +304,23 @@ public class MenuHelper { }); detailsMenu.setIcon(R.drawable.ic_menu_view_details); } - + + if ((!isImage) && ((inclusions & INCLUDE_VIEWPLAY_MENU) != 0)) { + menu.add(VIDEO_SAVING_ITEM, MENU_VIDEO_PLAY, 0, R.string.video_play) + .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + onInvoke.run(new MenuCallback() { + public void run(Uri uri, IImage image) { + Intent intent = new Intent(Intent.ACTION_VIEW, + image.fullSizeImageUri()); + activity.startActivity(intent); + }}); + return true; + } + }); + } + + return new MenuItemsResult() { public void gettingReadyToOpen(Menu menu, ImageManager.IImage image) { // protect against null here. this isn't strictly speaking required @@ -321,94 +351,25 @@ public class MenuHelper { }; } - static MenuItemsResult addVideoMenuItems( - Menu menu, - int inclusions, - final Activity activity, - final Handler handler, - final SelectedImageGetter mGetter, - final Runnable onDelete, - final Runnable preWork, - final Runnable postWork) { - - if ((inclusions & INCLUDE_VIEWPLAY_MENU) != 0) { - menu.add(VIDEO_SAVING_ITEM, MENU_VIDEO_PLAY, 0, R.string.video_play).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - if (preWork != null) - preWork.run(); - - Intent intent = new Intent(Intent.ACTION_VIEW, mGetter.getCurrentImageUri()); - activity.startActivity(intent); - - // don't do the postWork since we're launching another activity - return true; - } - }); - } - - if ((inclusions & INCLUDE_SHARE_MENU) != 0) { - MenuItem item = menu.add(VIDEO_SAVING_ITEM, 0, 0, R.string.camera_share).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - Uri u = mGetter.getCurrentImageUri(); - if (u == null) - return true; - - if (preWork != null) - preWork.run(); - - Intent intent = new Intent(); - intent.setAction(Intent.ACTION_SEND); - intent.setType(mGetter.getCurrentImage().getMimeType()); - intent.putExtra(Intent.EXTRA_STREAM, u); - try { - activity.startActivity(Intent.createChooser(intent, - activity.getText(R.string.sendVideo))); - } catch (android.content.ActivityNotFoundException ex) { - Toast.makeText(activity, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show(); - - if (postWork != null) - postWork.run(); - } - return true; - } - }); - item.setIcon(android.R.drawable.ic_menu_share); - } - - if ((inclusions & INCLUDE_DELETE_MENU) != 0) { - MenuItem deleteMenu = menu.add(VIDEO_SAVING_ITEM, MENU_VIDEO_TOSS, 0, R.string.camera_toss).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - if (preWork != null) - preWork.run(); - - activity.getContentResolver().delete(mGetter.getCurrentImageUri(), null, null); - - if (onDelete != null) - onDelete.run(); - - if (postWork != null) - postWork.run(); - - return true; - } - }); - deleteMenu.setIcon(android.R.drawable.ic_menu_delete); - deleteMenu.setAlphabeticShortcut('d'); - } + static void deletePhoto(Activity activity, Runnable onDelete) { + deleteImageImpl(activity, onDelete, true); + } - return null; + static void deleteImage(Activity activity, Runnable onDelete, IImage image) { + deleteImageImpl(activity, onDelete, ImageManager.isImage(image)); } - - static void deletePhoto(Activity activity, final Runnable onDelete) { + + private static void deleteImageImpl(Activity activity, final Runnable onDelete, boolean isPhoto) { boolean confirm = android.preference.PreferenceManager.getDefaultSharedPreferences(activity).getBoolean("pref_gallery_confirm_delete_key", true); if (!confirm) { if (onDelete != null) onDelete.run(); } else { android.app.AlertDialog.Builder b = new android.app.AlertDialog.Builder(activity); - b.setIcon(R.drawable.delete_image); + b.setIcon(android.R.drawable.ic_dialog_alert); b.setTitle(R.string.confirm_delete_title); - b.setMessage(R.string.confirm_delete_message); + b.setMessage(isPhoto? R.string.confirm_delete_message + : R.string.confirm_delete_video_message); b.setPositiveButton(android.R.string.ok, new android.content.DialogInterface.OnClickListener() { public void onClick(android.content.DialogInterface v, int x) { if (onDelete != null) @@ -423,7 +384,62 @@ public class MenuHelper { b.create().show(); } } - + + static void addSwitchModeMenuItem(Menu menu, final Activity activity, + final boolean switchToVideo) { + int group = switchToVideo ? MenuHelper.IMAGE_MODE_ITEM : MenuHelper.VIDEO_MODE_ITEM; + int labelId = switchToVideo ? R.string.switch_to_video_lable + : R.string.switch_to_camera_lable; + int iconId = switchToVideo ? R.drawable.ic_menu_camera_video_view + : R.drawable.ic_menu_camera; + MenuItem item = menu.add(group, MENU_SWITCH_CAMERA_MODE, 0, + labelId).setOnMenuItemClickListener( + new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + String action = switchToVideo ? MediaStore.INTENT_ACTION_VIDEO_CAMERA + : MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA; + Intent intent = new Intent(action); + intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); + activity.finish(); + activity.startActivity(intent); + return true; + } + }); + item.setIcon(iconId); + } + + static void addCaptureMenuItems(Menu menu, final Activity activity) { + + menu.add(0, MENU_CAPTURE_PICTURE, 1, R.string.capture_picture) + .setOnMenuItemClickListener( + new MenuItem.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); + try { + activity.startActivity(intent); + } catch (android.content.ActivityNotFoundException e) { + // Ignore exception + } + return true; + } + }) + .setIcon(R.drawable.ic_menu_camera); + + menu.add(0, MENU_CAPTURE_VIDEO, 2, R.string.capture_video) + .setOnMenuItemClickListener( + new MenuItem.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA); + try { + activity.startActivity(intent); + } catch (android.content.ActivityNotFoundException e) { + // Ignore exception + } + return true; + } + }) + .setIcon(R.drawable.ic_menu_camera_video_view); + } static MenuItem addFlipOrientation(Menu menu, final Activity activity, final SharedPreferences prefs) { // position 41 after rotate return menu @@ -457,65 +473,5 @@ public class MenuHelper { ? android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER : req); } - - static public class YouTubeUploadInfoDialog extends Dialog { - private CheckBox mPrivate; - private ImageManager.VideoObject mVideo; - private EditText mTitle; - private EditText mTags; - private EditText mDescription; - private Spinner mCategory; - private Button mUpload; - - public YouTubeUploadInfoDialog(final Activity activity, - final ArrayList<String> categoriesShort, - final ArrayList<String> categoriesLong, - ImageManager.VideoObject video, - final Runnable postRunnable) { - super(activity, android.R.style.Theme_Dialog); - mVideo = video; - setContentView(R.layout.youtube_upload_info); - setTitle(R.string.upload_dialog_title); - - mPrivate = (CheckBox)findViewById(R.id.public_or_private); - if (!mPrivate.isChecked()) { - mPrivate.setChecked(true); - } - - mTitle = (EditText)findViewById(R.id.video_title); - mTags = (EditText)findViewById(R.id.video_tags); - mDescription = (EditText)findViewById(R.id.video_description); - mCategory = (Spinner)findViewById(R.id.category); - - if (Config.LOGV) - Log.v(TAG, "setting categories in adapter"); - android.widget.ArrayAdapter<String> categories = new android.widget.ArrayAdapter<String>(activity, android.R.layout.simple_spinner_item, categoriesLong); - categories.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mCategory.setAdapter(categories); - - if (mVideo != null) { - mTitle.setText(mVideo.getTitle()); - mTags.setText(mVideo.getTags()); - mDescription.setText(mVideo.getDescription()); - } - - mUpload = (Button)findViewById(R.id.do_upload); - mUpload.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) - { - if (mVideo != null) { - mVideo.setName(mTitle.getText().toString()); - mVideo.setDescription(mDescription.getText().toString()); - mVideo.setTags(mTags.getText().toString()); - } - - YouTubeUploadInfoDialog.this.dismiss(); - UploadAction.uploadImage(activity, mVideo); - if (postRunnable != null) - postRunnable.run(); - } - }); - } - } } diff --git a/src/com/android/camera/MovieView.java b/src/com/android/camera/MovieView.java new file mode 100644 index 0000000..58e80df --- /dev/null +++ b/src/com/android/camera/MovieView.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera; + + +import android.app.Activity; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.media.MediaPlayer; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.provider.MediaStore; +import android.view.View; +import android.widget.MediaController; +import android.widget.VideoView; + +public class MovieView extends Activity implements MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener +{ + private static final String TAG = "MovieView"; + // Copied from MediaPlaybackService in the Music Player app. Should be public, but isn't. + private static final String SERVICECMD = "com.android.music.musicservicecommand"; + private static final String CMDNAME = "command"; + private static final String CMDPAUSE = "pause"; + + private VideoView mVideoView; + private View mProgressView; + private boolean mFinishOnCompletion; + public MovieView() + { + } + + @Override + public void onCreate(Bundle icicle) + { + super.onCreate(icicle); + + setContentView(R.layout.movie_view); + + mVideoView = (VideoView) findViewById(R.id.surface_view); + mProgressView = findViewById(R.id.progress_indicator); + Intent intent = getIntent(); + if (intent.hasExtra(MediaStore.EXTRA_SCREEN_ORIENTATION)) { + int orientation = intent.getIntExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, + ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + if (orientation != getRequestedOrientation()) { + setRequestedOrientation(orientation); + } + } + mFinishOnCompletion = intent.getBooleanExtra(MediaStore.EXTRA_FINISH_ON_COMPLETION, true); + Uri uri = intent.getData(); + + // For streams that we expect to be slow to start up, show a + // progress spinner until playback starts. + String scheme = uri.getScheme(); + if ("http".equalsIgnoreCase(scheme) || + "rtsp".equalsIgnoreCase(scheme)) { + mHandler.postDelayed(mPlayingChecker, 250); + } else { + mProgressView.setVisibility(View.GONE); + } + + mVideoView.setOnErrorListener(this); + mVideoView.setOnCompletionListener(this); + mVideoView.setVideoURI(uri); + mVideoView.setMediaController(new MediaController(this)); + mVideoView.requestFocus(); // make the video view handle keys for seeking and pausing + + Intent i = new Intent(SERVICECMD); + i.putExtra(CMDNAME, CMDPAUSE); + sendBroadcast(i); + + mVideoView.start(); + } + + @Override + public void onPause() { + mHandler.removeCallbacksAndMessages(null); + super.onPause(); + } + + Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + } + }; + + Runnable mPlayingChecker = new Runnable() { + public void run() { + if (mVideoView.isPlaying()) { + mProgressView.setVisibility(View.GONE); + } else { + mHandler.postDelayed(mPlayingChecker, 250); + } + } + }; + + public boolean onError(MediaPlayer player, int arg1, int arg2) { + mHandler.removeCallbacksAndMessages(null); + mProgressView.setVisibility(View.GONE); + return false; + } + + public void onCompletion(MediaPlayer mp) { + if (mFinishOnCompletion) { + finish(); + } + } +} diff --git a/src/com/android/camera/PwaUpload.java b/src/com/android/camera/PwaUpload.java deleted file mode 100644 index 8df08df..0000000 --- a/src/com/android/camera/PwaUpload.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.camera; - -import android.content.Intent; -import android.app.Activity; -import android.os.Bundle; -import android.util.Log; -import android.net.Uri; - -/** - * - */ -public class PwaUpload extends Activity -{ - private static final String TAG = "camera"; - - @Override public void onCreate(Bundle icicle) { - super.onCreate(icicle); - ImageManager.IImageList imageList = ImageManager.instance().allImages( - this, - getContentResolver(), - ImageManager.DataLocation.ALL, - ImageManager.INCLUDE_IMAGES|ImageManager.INCLUDE_VIDEOS, - ImageManager.SORT_ASCENDING); - Uri uri = (Uri) getIntent().getParcelableExtra(Intent.EXTRA_STREAM); - if (android.util.Config.LOGV) - Log.v(TAG, "uri is " + uri); - ImageManager.IImage imageObj = imageList.getImageForUri(uri); - - if (android.util.Config.LOGV) - Log.v(TAG, "imageObj is " + imageObj); - if (imageObj != null) { - UploadAction.uploadImage(this, imageObj); - } - finish(); - } - - @Override public void onResume() { - super.onResume(); - } -} diff --git a/src/com/android/camera/SlideShow.java b/src/com/android/camera/SlideShow.java index ee6c7be..2be99ac 100644 --- a/src/com/android/camera/SlideShow.java +++ b/src/com/android/camera/SlideShow.java @@ -60,21 +60,21 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory private int mCurrentPosition = 0; private ImageView mSwitcher; private boolean mPosted = false; - + @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); Window wp = getWindow(); wp.setFlags(FLAG_KEEP_SCREEN_ON, FLAG_KEEP_SCREEN_ON); - + setContentView(R.layout.slide_show); - + mSwitcher = (ImageView)findViewById(R.id.imageview); if (android.util.Config.LOGV) Log.v(TAG, "mSwitcher " + mSwitcher); } - + @Override protected void onResume() { @@ -86,13 +86,13 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory } loadImage(); } - + @Override protected void onPause() { super.onPause(); cancelPost(); } - + static public class ImageViewTouch extends ImageView { class xy { public xy(float xIn, float yIn) { @@ -108,26 +108,26 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory float x,y; long timeAdded; } - + SlideShow mSlideShow; Paint mPaints[] = new Paint[1]; ArrayList<xy> mPoints = new ArrayList<xy>(); boolean mDown; - + public ImageViewTouch(Context context) { super(context); mSlideShow = (SlideShow) context; setScaleType(ImageView.ScaleType.CENTER); setupPaint(); } - + public ImageViewTouch(Context context, AttributeSet attrs) { super(context, attrs); mSlideShow = (SlideShow) context; setScaleType(ImageView.ScaleType.CENTER); setupPaint(); } - + private void setupPaint() { for (int i = 0; i < mPaints.length; i++) { Paint p = new Paint(); @@ -138,7 +138,7 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory mPaints[i] = p; } } - + private void addEvent(MotionEvent event) { long now = System.currentTimeMillis(); mPoints.add(new xy(event)); @@ -151,7 +151,7 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory mPoints.remove(0); } } - + public boolean onTouchEvent(MotionEvent event) { addEvent(event); switch (event.getAction()) { @@ -182,7 +182,7 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory long delta = now - ev.timeAdded; if (delta > sLag) continue; - + int alpha2 = Math.max(0, 255 - (255 * (int)delta / sLag)); if (alpha2 == 0) continue; @@ -195,7 +195,7 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory } } - + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { @@ -203,14 +203,14 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory cancelPost(); loadPreviousImage(); return true; - + case KeyEvent.KEYCODE_DPAD_RIGHT: cancelPost(); loadNextImage(); return true; - + case KeyEvent.KEYCODE_DPAD_CENTER: - if (mPosted) + if (mPosted) cancelPost(); else loadNextImage(); @@ -218,12 +218,12 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory } return super.onKeyDown(keyCode, event); } - + private void cancelPost() { mHandler.removeCallbacks(mNextImageRunnable); mPosted = false; } - + private void post() { mHandler.postDelayed(mNextImageRunnable, sNextImageInterval); mPosted = true; @@ -233,7 +233,7 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory ImageManager.IImage image = mImageList.getImageAt(mCurrentPosition); if (image == null) return; - + Bitmap bitmap = image.thumbBitmap(); if (bitmap == null) return; @@ -241,7 +241,7 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory mSwitcher.setImageDrawable(new BitmapDrawable(bitmap)); post(); } - + private Runnable mNextImageRunnable = new Runnable() { public void run() { if (android.util.Config.LOGV) @@ -249,13 +249,13 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory loadNextImage(); } }; - + private void loadNextImage() { if (++mCurrentPosition >= mImageList.getCount()) mCurrentPosition = 0; loadImage(); } - + private void loadPreviousImage() { if (mCurrentPosition == 0) mCurrentPosition = mImageList.getCount() - 1; @@ -272,7 +272,7 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory i.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); return i; } - + private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { @@ -286,22 +286,22 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory public void checkThumbnails(ThumbCheckCallback cb) { // TODO Auto-generated method stub - + } public void commitChanges() { // TODO Auto-generated method stub - + } public void removeOnChangeListener(OnChange changeCallback) { // TODO Auto-generated method stub - + } public void setOnChangeListener(OnChange changeCallback, Handler h) { // TODO Auto-generated method stub - + } private ArrayList<FileImage> mImages = new ArrayList<FileImage>(); @@ -320,7 +320,7 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory public long imageId() { return mId; } - + public String getDataPath() { return mPath; } @@ -332,7 +332,7 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory public IGetBitmap_cancelable fullSizeBitmap_cancelable(int targetWidthOrHeight) { return null; } - + public Bitmap thumbBitmap() { Bitmap b = fullSizeBitmap(320); Matrix m = new Matrix(); @@ -341,7 +341,7 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory Bitmap scaledBitmap = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true); return scaledBitmap; } - + public Bitmap miniThumbBitmap() { return thumbBitmap(); } @@ -416,7 +416,11 @@ public class SlideShow extends Activity implements ViewSwitcher.ViewFactory public int getCount() { return mImages.size(); } - + + public boolean isEmpty() { + return mImages.isEmpty(); + } + public void deactivate() { // nothing to do here } diff --git a/src/com/android/camera/UploadAction.java b/src/com/android/camera/UploadAction.java deleted file mode 100644 index 41cc351..0000000 --- a/src/com/android/camera/UploadAction.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.camera; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.util.Config; -import android.util.Log; - -public class UploadAction { - static private final String TAG = "UploadAction"; - - static public void uploadImage(Activity activity, ImageManager.IImage image) { - Bundle args = new Bundle(); - if (image != null) - args.putString("imageuri", image.fullSizeImageUri().toString()); - activity.startService(new Intent(activity, UploadService.class).putExtras(args)); - } -} diff --git a/src/com/android/camera/UploadService.java b/src/com/android/camera/UploadService.java deleted file mode 100644 index 9c7d2b0..0000000 --- a/src/com/android/camera/UploadService.java +++ /dev/null @@ -1,1181 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.camera; - -import com.android.camera.ImageManager.IImage; -import com.android.internal.http.multipart.Part; -import com.android.internal.http.multipart.MultipartEntity; -import com.android.internal.http.multipart.PartBase; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.Service; -import android.content.ComponentName; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.Uri; -import android.os.Binder; -import android.os.IBinder; -import android.os.Parcel; -import android.preference.PreferenceManager; -import android.sax.Element; -import android.sax.ElementListener; -import android.sax.EndTextElementListener; -import android.sax.RootElement; -import android.util.Config; -import android.util.Log; -import android.util.Xml; - -import com.google.android.googleapps.GoogleLoginCredentialsResult; -import com.google.android.googlelogin.GoogleLoginServiceBlockingHelper; -import com.google.android.googlelogin.GoogleLoginServiceConstants; -import com.google.android.googlelogin.GoogleLoginServiceNotFoundException; - -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.SAXException; - -import android.net.http.AndroidHttpClient; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpGet; -import com.android.internal.http.multipart.StringPart; - -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.entity.StringEntity; -import org.apache.http.message.BasicHeader; -import org.apache.http.params.HttpParams; -import org.apache.http.protocol.HTTP; -import org.apache.http.util.EncodingUtils; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.HashMap; - -public class UploadService extends Service implements Runnable { - private static final String TAG = "UploadService"; - - static final boolean DEBUG = false; - private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; - - private GoogleLoginServiceBlockingHelper mGls; - static public final int MSG_STATUS = 3; - static public final int EVENT_UPLOAD_ERROR = 400; - - static public final String sPicasaService = "lh2"; - static public final String sYouTubeService = "youtube"; - static public final String sYouTubeUserService = "YouTubeUser"; - - static public final String sUploadAlbumName = "android_upload"; - HashMap<String, Album> mAlbums; - ArrayList<String> mAndroidUploadAlbumPhotos = null; - HashMap<String, String> mGDataAuthTokenMap = new HashMap<String, String>(); - - int mStartId; - Thread mThread; - - android.os.Handler mHandler = new android.os.Handler() { - - }; - - ArrayList<Runnable> mStatusListeners = new ArrayList<Runnable>(); - - ArrayList<Uri> mUploadList = new ArrayList<Uri>(); - - ImageManager.IImageList mImageList = null; - - String mPicasaUsername; - String mPicasaAuthToken; - String mYouTubeUsername; - String mYouTubeAuthToken; - - AndroidHttpClient mClient = AndroidHttpClient.newInstance("Android-Camera/0.1"); - - private static final ComponentName sLogin = new ComponentName( - "com.google.android.googleapps", - "com.google.android.googleapps.GoogleLoginService"); - - public UploadService() { - if (LOCAL_LOGV) - Log.v(TAG, "UploadService Constructor !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - } - - private void computeAuthToken() { - if (LOCAL_LOGV) Log.v(TAG, "computeAuthToken()"); - if (mPicasaAuthToken != null) return; - - try { - String account = mGls.getAccount(GoogleLoginServiceConstants.REQUIRE_GOOGLE); - GoogleLoginCredentialsResult result = - mGls.getCredentials(account, sPicasaService, true); - mPicasaAuthToken = result.getCredentialsString(); - mPicasaUsername = result.getAccount(); - if (Config.LOGV) - Log.v(TAG, "mPicasaUsername is " + mPicasaUsername); - } catch (GoogleLoginServiceNotFoundException e) { - Log.e(TAG, "Could not get auth token", e); - } - } - - private void computeYouTubeAuthToken() { - if (LOCAL_LOGV) Log.v(TAG, "computeYouTubeAuthToken()"); - if (mYouTubeAuthToken != null) return; - - try { - String account = mGls.getAccount(GoogleLoginServiceConstants.REQUIRE_GOOGLE); - GoogleLoginCredentialsResult result = - mGls.getCredentials(account, sYouTubeService, true); - mYouTubeAuthToken = result.getCredentialsString(); - mYouTubeUsername = result.getAccount(); - if (mYouTubeAuthToken.equals("NoLinkedYouTubeAccount")) { - // we successfully logged in to the google account, but it - // is not linked to a YouTube username. - if (Config.LOGV) - Log.v(TAG, "account " + mYouTubeUsername + " is not linked to a youtube account"); - mYouTubeAuthToken = null; - return; - } - - mYouTubeUsername = mGls.peekCredentials(mYouTubeUsername, sYouTubeUserService); - // now mYouTubeUsername is the YouTube username linked to the - // google account, which is probably what we want to display. - - if (Config.LOGV) - Log.v(TAG, "3 mYouTubeUsername: " + mYouTubeUsername); - } catch (GoogleLoginServiceNotFoundException e) { - Log.e(TAG, "Could not get auth token", e); - } - } - - NotificationManager mNotificationManager; - - @Override - public void onCreate() { - - try { - mGls = new GoogleLoginServiceBlockingHelper(this); - } catch (GoogleLoginServiceNotFoundException e) { - Log.e(TAG, "Could not find google login service, stopping service"); - stopSelf(); - } - - if (mThread == null) { - mThread = new Thread(this); - mThread.start(); - } - mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); - - IntentFilter intentFilter = new IntentFilter("com.android.camera.NEW_PICTURE"); - b = new android.content.BroadcastReceiver() { - public void onReceive(android.content.Context ctx, Intent intent) { - android.content.SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); - if (prefs.getBoolean("pref_camera_autoupload_key", false)) { - if (Config.LOGV) - Log.v(TAG, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> auto upload " + intent.getData()); - } - } - }; - registerReceiver(b, intentFilter); - } - - android.content.BroadcastReceiver b = null; - - @Override - public void onDestroy() { - mGls.close(); - if (b != null) { - unregisterReceiver(b); - } - } - - @Override - public void onStart(Intent intent, int startId) { - if (LOCAL_LOGV) - Log.v(TAG, "UploadService.onStart; this is " + hashCode()); - - if (mImageList == null) { - mImageList = ImageManager.instance().allImages( - this, - getContentResolver(), - ImageManager.DataLocation.ALL, - ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS, - ImageManager.SORT_ASCENDING); - mImageList.setOnChangeListener(new ImageManager.IImageList.OnChange() { - public void onChange(ImageManager.IImageList list) { - /* - Log.v(TAG, "onChange <<<<<<<<<<<<<<<<<<<<<<<<<"); - for (int i = 0; i < list.getCount(); i++) { - ImageManager.IImage img = list.getImageAt(i); - Log.v(TAG, "pos " + i + " " + img.fullSizeImageUri()); - String picasaId = img.getPicasaId(); - if (picasaId == null || picasaId.length() == 0) { - synchronized (mUploadList) { - Uri uri = img.fullSizeImageUri(); - if (mUploadList.contains(uri)) { - mUploadList.add(img.fullSizeImageUri()); - mUploadList.notify(); - } - } - } - } - */ - } - }, mHandler); - } - - if (LOCAL_LOGV) - Log.v(TAG, "got image list with count " + mImageList.getCount()); - - synchronized (mUploadList) { - mStartId = startId; - String uriString = intent.getStringExtra("imageuri"); - - if (LOCAL_LOGV) - Log.v(TAG, "starting UploadService; startId = " + startId + " start uri: " + uriString); - - if (uriString != null) { - Uri uri = Uri.parse(uriString); - IImage image = mImageList.getImageForUri(uri); - if (!mUploadList.contains(uri)) { - if (LOCAL_LOGV) - Log.v(TAG, "queing upload of " + image.fullSizeImageUri()); - mUploadList.add(uri); - } - } else { - // for now upload all applies to images only, not videos - for (int i = 0; i < mImageList.getCount(); i++) { - IImage image = mImageList.getImageAt(i); - if (image instanceof ImageManager.Image) { - Uri uri = image.fullSizeImageUri(); - if (!mUploadList.contains(uri)) { - if (LOCAL_LOGV) - Log.v(TAG, "queing upload of " + image.fullSizeImageUri()); - mUploadList.add(uri); - } - } - } - } - updateNotification(); - } - - synchronized(mUploadList) { - mUploadList.notify(); - } - } - - void updateNotification() { - int videosCount = 0, imagesCount = 0; - for (int i = 0;i < mUploadList.size(); i++) { - // TODO yes this is a hack - Uri uri = mUploadList.get(i); - if (uri.toString().contains("video")) - videosCount += 1; - else - imagesCount += 1; - } - updateNotification(imagesCount, videosCount); - } - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - // This is the object that recieves interactions from clients. - private final IBinder mBinder = new Binder() { - protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) { - return true; - } - }; - - private void updateNotification(int pendingImagesCount, int pendingVideosCount) { - final int mVideoUploadId = 1; - final int mImageUploadId = 2; - if (pendingImagesCount == 0) { - if (mNotificationManager != null) - mNotificationManager.cancel(mImageUploadId); - } else { - String detailedMsg = String.format(getResources().getString(R.string.uploadingNPhotos), pendingImagesCount); - Notification n = new Notification( - this, - android.R.drawable.stat_sys_upload, - getResources().getString(R.string.uploading_photos), - System.currentTimeMillis(), - getResources().getString(R.string.uploading_photos_2), - detailedMsg, - null); - mNotificationManager.notify(mImageUploadId, n); - } - if (pendingVideosCount == 0) { - if (mNotificationManager != null) - mNotificationManager.cancel(mVideoUploadId); - } else { - String detailedMsg = String.format(getResources().getString(R.string.uploadingNVideos), pendingImagesCount); - Notification n = new Notification( - this, - android.R.drawable.stat_sys_upload, - getResources().getString(R.string.uploading_videos), - System.currentTimeMillis(), - getResources().getString(R.string.uploading_videos_2), - detailedMsg, - null); - mNotificationManager.notify(mVideoUploadId, n); - } - } - - public void run() { - try { - if (Config.LOGV) - Log.v(TAG, "running upload thread..."); - while (true) { - IImage image = null; - synchronized (mUploadList) { - if (LOCAL_LOGV) - Log.v(TAG, "mUploadList.size() is " + mUploadList.size()); - if (mUploadList.size() == 0) { - try { - updateNotification(0, 0); - if (Config.LOGV) - Log.v(TAG, "waiting..."); - mUploadList.wait(60000); - if (Config.LOGV) - Log.v(TAG, "done waiting..."); - } catch (InterruptedException ex) { - } - if (mUploadList.size() == 0) { -// if (LOCAL_LOGV) Log.v(TAG, "exiting run, stoping service"); -// stopSelf(mStartId); -// break; - continue; - } - } - Uri uri = mUploadList.get(0); - image = mImageList.getImageForUri(uri); - if (Config.LOGV) - Log.v(TAG, "got uri " + uri + " " + image); - } - - boolean success = false; - if (image != null) { - updateNotification(); - - long t1 = System.currentTimeMillis(); - success = uploadItem(image); - long t2 = System.currentTimeMillis(); - if (LOCAL_LOGV) Log.v(TAG, "upload took " + (t2-t1) + "; success = " + success); - } - - synchronized (mUploadList) { - mUploadList.remove(0); - if (!success && image != null) { - mUploadList.add(image.fullSizeImageUri()); - } - } - if (!success) { - int retryDelay = 30000; - if (LOCAL_LOGV) - Log.v(TAG, "failed to upload " + image.fullSizeImageUri() + " trying again in " + retryDelay + " ms"); - try { - synchronized (mUploadList) { - long t1x = System.currentTimeMillis(); - mUploadList.wait(retryDelay); - long t2x = System.currentTimeMillis(); - if (Config.LOGV) - Log.v(TAG, "retry waited " + (t2x-t1x)); - } - } catch (InterruptedException ex) { - if (Config.LOGV) - Log.v(TAG, "ping, was waiting but now retry again"); - }; - } - } - } catch (Exception ex) { - Log.e(TAG, "got exception in upload thread", ex); - } - finally { - if (LOCAL_LOGV) - Log.v(TAG, "finished task"); - } - } - - private String getLatLongString(IImage image) { - if (image.hasLatLong()) { - return "<georss:where><gml:Point><gml:pos>" - + image.getLatitude() - + " " - + image.getLongitude() - + "</gml:pos></gml:Point></georss:where>"; - } else { - return ""; - } - } - - private String uploadAlbumName() { - android.content.SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - String s = prefs.getString("pref_camera_upload_albumname_key", sUploadAlbumName); - return s; - } - - private boolean uploadItem(IImage image) { - if (LOCAL_LOGV) - Log.v(TAG, "starting work on " + image); - - if (image instanceof ImageManager.VideoObject) { - if (LOCAL_LOGV) - Log.v(TAG, "Uploading video"); - computeYouTubeAuthToken(); - return (new VideoUploadTask(image)).upload(); - } else { - if (LOCAL_LOGV) - Log.v(TAG, "Uploading photo"); - - computeAuthToken(); - // handle photos - if (mAlbums == null) - mAlbums = getAlbums(); - - String albumName = uploadAlbumName(); - if (mAlbums == null || !mAlbums.containsKey(albumName)) { - Album a = createAlbum(albumName, uploadAlbumName()); - if (a == null) { - return false; - } - if (LOCAL_LOGV) - Log.v(TAG, "made new album: " + a.getAlbumName() + "; " + a.getAlbumId()); - mAlbums.put(a.getAlbumName(), a); - } - - if (mAndroidUploadAlbumPhotos == null) - mAndroidUploadAlbumPhotos = getAlbumContents(albumName); - - if (mAndroidUploadAlbumPhotos != null) { - String previousUploadId = image.getPicasaId(); - if (previousUploadId != null) { - if (mAndroidUploadAlbumPhotos.contains(previousUploadId)) { - if (Config.LOGV) - Log.v(TAG, "already have id " + previousUploadId); - return true; - } - } - } - Album album = mAlbums.get(albumName); - return (new ImageUploadTask(image)).upload(album); - } - } - -// void broadcastError(int error) { -// HashMap map = new HashMap(); -// map.put("error", new Integer(error)); -// -// Message send = Message.obtain(); -// send.what = EVENT_UPLOAD_ERROR; -// send.setData(map); -// -// if (mBroadcaster == null) { -// mBroadcaster = new Broadcaster(); -// } -// mBroadcaster.broadcast(send); -// } - - class Album { - String mAlbumName; - - String mAlbumId; - - public Album() { - } - - public void setAlbumName(String albumName) { - mAlbumName = albumName; - } - - public void setAlbumId(String albumId) { - mAlbumId = albumId; - } - - public String getAlbumName() { - return mAlbumName; - } - - public String getAlbumId() { - return mAlbumId; - } - } - - static private String stringFromResponse(HttpResponse response) { - try { - HttpEntity entity = response.getEntity(); - InputStream inputStream = entity.getContent(); - StringWriter s = new StringWriter(); - while (true) { - int c = inputStream.read(); - if (c == -1) - break; - s.write((char)c); - } - inputStream.close(); - String retval = s.toString(); - if (Config.LOGV) - Log.v(TAG, "got resposne " + retval); - return retval; - } catch (Exception ex) { - return null; - } - } - - abstract class UploadTask { - IImage mImageObj; - - public UploadTask(IImage image) { - mImageObj = image; - } - - public class UploadResponse { - private HttpResponse mStatus; - private String mBody; - - public UploadResponse(HttpResponse status) { - mStatus = status; - mBody = stringFromResponse(status); - } - - public int getStatus() { - return mStatus.getStatusLine().getStatusCode(); - } - - public String getResponse() { - return mBody; - } - } - - class StreamPart extends PartBase { - InputStream mInputStream; - long mLength; - - StreamPart(String name, InputStream inputStream, String contentType) { - super(name, - contentType == null ? "application/octet-stream" : contentType, - "ISO-8859-1", - "binary" - ); - mInputStream = inputStream; - try { - mLength = inputStream.available(); - } catch (IOException ex) { - - } - } - - @Override - protected long lengthOfData() throws IOException { - return mLength; - } - - @Override - protected void sendData(OutputStream out) throws IOException { - byte [] buffer = new byte[4096]; - while (true) { - int got = mInputStream.read(buffer); - if (got == -1) - break; - out.write(buffer, 0, got); - } - mInputStream.close(); - } - - @Override - protected void sendDispositionHeader(OutputStream out) throws IOException { - } - - @Override - protected void sendContentTypeHeader(OutputStream out) throws IOException { - String contentType = getContentType(); - if (contentType != null) { - out.write(CONTENT_TYPE_BYTES); - out.write(EncodingUtils.getAsciiBytes(contentType)); - String charSet = getCharSet(); - if (charSet != null) { - out.write(CHARSET_BYTES); - out.write(EncodingUtils.getAsciiBytes(charSet)); - } - } - } - } - - public class StringPartX extends StringPart { - public StringPartX(String name, String value, String charset) { - super(name, value, charset); - setContentType("application/atom+xml"); - } - - @Override - protected void sendDispositionHeader(OutputStream out) throws IOException { - } - - @Override - protected void sendContentTypeHeader(OutputStream out) throws IOException { - String contentType = getContentType(); - if (contentType != null) { - out.write(CONTENT_TYPE_BYTES); - out.write(EncodingUtils.getAsciiBytes(contentType)); - String charSet = getCharSet(); - if (charSet != null) { - out.write(CHARSET_BYTES); - out.write(EncodingUtils.getAsciiBytes(charSet)); - } - } - } - } - - public class MultipartEntityX extends MultipartEntity { - public MultipartEntityX(Part[] parts, HttpParams params) { - super(parts, params); - } - - @Override - public Header getContentType() { - StringBuilder buffer = new StringBuilder(); - buffer.append("multipart/related; boundary="); - buffer.append(EncodingUtils.getAsciiString(getMultipartBoundary())); - return new BasicHeader(HTTP.CONTENT_TYPE, buffer.toString()); - } - - } - - protected UploadResponse doUpload(String uploadUrl, - String mimeType, - String data, - IImage imageObj, - String authToken, - String title, - String filename, - boolean youTubeAuthenticate) { - if (authToken == null) - return null; - - FileInputStream inputStream = (FileInputStream)mImageObj.fullSizeImageData(); - try { - HttpPost post = new HttpPost(uploadUrl); - post.addHeader(new BasicHeader("Authorization", "GoogleLogin auth=" + authToken)); - if (youTubeAuthenticate) { - // TODO: remove hardwired key? - This is our official YouTube issued developer key to Android. - String youTubeDeveloperKey = "key=AI39si5Cr35CiD1IgDqD9Ua6N4dSbY-oibnLUPITmBN_rFW6qRz-hd8sTqNzRf1gzNwSYZbDuS31Txa4iKyjAV77507O4tq7JA"; - post.addHeader("X-GData-Key", youTubeDeveloperKey); - post.addHeader("Slug", filename); - } - - Part p1 = new StringPartX("param_name", data, null); - Part p2 = new StreamPart("field_uploadfile", inputStream, mimeType); - - MultipartEntity mpe = new MultipartEntityX(new Part[] { p1, p2 }, post.getParams()); - post.setEntity(mpe); - HttpResponse status = mClient.execute(post); - if (LOCAL_LOGV) Log.v(TAG, "doUpload response is " + status.getStatusLine()); - return new UploadResponse(status); - } catch (java.io.IOException ex) { - if (LOCAL_LOGV) Log.v(TAG, "IOException in doUpload", ex); - return null; - } - } - - class ResponseHandler implements ElementListener { - private static final String ATOM_NAMESPACE - = "http://www.w3.org/2005/Atom"; - private static final String PICASSA_NAMESPACE - = "http://schemas.google.com/photos/2007"; - - private ContentHandler mHandler = null; - private String mId = null; - - public ResponseHandler() { - RootElement root = new RootElement(ATOM_NAMESPACE, "entry"); - Element entry = root; - entry.setElementListener(this); - - entry.getChild(PICASSA_NAMESPACE, "id") - .setEndTextElementListener(new EndTextElementListener() { - public void end(String body) { - mId = body; - } - }); - - mHandler = root.getContentHandler(); - } - - public void start(Attributes attributes) { - } - - public void end() { - } - - ContentHandler getContentHandler() { - return mHandler; - } - - public String getId() { - return mId; - } - } - } - - private class VideoUploadTask extends UploadTask { - public VideoUploadTask(IImage image) { - super(image); - } - protected String getYouTubeBaseUrl() { - return "http://gdata.youtube.com"; - } - - public boolean upload() { - String uploadUrl = "http://uploads.gdata.youtube.com" - + "/feeds/users/" - + mYouTubeUsername - + "/uploads?client=ytapi-google-android"; - - String title = mImageObj.getTitle(); - String isPrivate = ""; - String keywords = ""; - String category = ""; - if (mImageObj instanceof ImageManager.VideoObject) { - ImageManager.VideoObject video = (ImageManager.VideoObject)mImageObj; - if (mImageObj.getIsPrivate()) { - isPrivate = "<yt:private/>"; - } - keywords = video.getTags(); - if (keywords == null || keywords.trim().length() == 0) { - // there must be a keyword or YouTube will reject the video - keywords = getResources().getString(R.string.upload_default_tags_text); - } - // TODO: use the real category when we have the category spinner in details -// category = video.getCategory(); - category = ""; - if (category == null || category.trim().length() == 0) { - // there must be a description or YouTube will get an internal error and return 500 - category = getResources().getString(R.string.upload_default_category_text); - } - } - String description = mImageObj.getDescription(); - if (description == null || description.trim().length() == 0) { - // there must be a description or YouTube will get an internal error and return 500 - description = getResources().getString(R.string.upload_default_description_text); - } - String data = "<?xml version='1.0'?>\n" - + "<entry xmlns='http://www.w3.org/2005/Atom'\n" - + " xmlns:media='http://search.yahoo.com/mrss/'\n" - + " xmlns:yt='http://gdata.youtube.com/schemas/2007'>\n" - + " <media:group>\n" - + " <media:title type='plain'>" + title + "</media:title>\n" // TODO: need user entered title - + " <media:description type='plain'>" + description + "</media:description>\n" - + isPrivate - + " <media:category scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>\n" - + category - + " </media:category>\n" - + " <media:keywords>" + keywords + "</media:keywords>\n" - + " </media:group>\n" - + "</entry>"; - - if (LOCAL_LOGV) Log.v("youtube", "uploadUrl: " + uploadUrl); - if (LOCAL_LOGV) Log.v("youtube", "GData: " + data); - - UploadResponse result = doUpload(uploadUrl, - "video/3gpp2", - data, - null, - mYouTubeAuthToken, - title, - mImageObj.fullSizeImageUri().getLastPathSegment(), - true); - - boolean success = false; - if (result != null) { - switch (result.getStatus()) { - case 401: - if (result.getResponse().contains("Token expired")) { - // When we tried to upload a video to YouTube, the youtube server told us - // our auth token was expired. Get a new one and try again. - try { - mGls.invalidateAuthToken(mYouTubeAuthToken); - } catch (GoogleLoginServiceNotFoundException e) { - Log.e(TAG, "Could not invalidate youtube auth token", e); - } - mYouTubeAuthToken = null; // Forces computeYouTubeAuthToken to get a new token. - computeYouTubeAuthToken(); - } - break; - - case 200: - case 201: - case 202: - case 203: - case 204: - case 205: - case 206: - success = true; - break; - - } - } - return success; - } - } - - private class ImageUploadTask extends UploadTask { - public ImageUploadTask(IImage image) { - super(image); - } - - public boolean upload(Album album) { - String uploadUrl = getServiceBaseUrl() - + mPicasaUsername - + "/album/" - + album.getAlbumId(); - - String name = mImageObj.getTitle(); - String description = mImageObj.getDescription(); - String data = "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:georss='http://www.georss.org/georss' xmlns:gml='http://www.opengis.net/gml'><title>" - + name - + "</title>" - + "<summary>" - + (description != null ? description : "") - + "</summary>" - + getLatLongString(mImageObj) - + "<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#photo'/></entry>\n"; - - if (LOCAL_LOGV) - Log.v(TAG, "xml for image is " + data); - UploadResponse response = doUpload(uploadUrl, - "image/jpeg", - data, - mImageObj, - mPicasaAuthToken, - name, - name, - false); - - if (response != null) { - int status = response.getStatus(); - if (status == HttpStatus.SC_UNAUTHORIZED || - status == HttpStatus.SC_FORBIDDEN || - status == HttpStatus.SC_INTERNAL_SERVER_ERROR) { - try { - mGls.invalidateAuthToken(mPicasaAuthToken); - } catch (GoogleLoginServiceNotFoundException e) { - Log.e(TAG, "Could not invalidate picasa auth token", e); - } - mPicasaAuthToken = null; - } else { - ResponseHandler h = new ResponseHandler(); - try { - Xml.parse(response.getResponse(), h.getContentHandler()); - String id = h.getId(); - if (id != null && mImageObj != null) { - mImageObj.setPicasaId(id); - mAndroidUploadAlbumPhotos.add(id); - return true; - } - } catch (org.xml.sax.SAXException ex) { - Log.e(TAG, "SAXException in doUpload " + ex.toString()); - } - } - } - return false; - } - } - - private Album createAlbum(String name, String summary) { - String authToken = mPicasaAuthToken; - if (authToken == null) - return null; - - try { - String url = getServiceBaseUrl() + mPicasaUsername; - HttpPost post = new HttpPost(url); - String entryString = "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/' xmlns:gphoto='http://schemas.google.com/photos/2007'>" - + "<title type='text'>" - + name - + "</title>" - + "<summary>" - + summary - + "</summary>" - + "<gphoto:access>private</gphoto:access>" - + "<gphoto:commentingEnabled>true</gphoto:commentingEnabled>" - + "<gphoto:timestamp>" - + String.valueOf(System.currentTimeMillis()) - + "</gphoto:timestamp>" - + "<category scheme=\"http://schemas.google.com/g/2005#kind\" term=\"http://schemas.google.com/photos/2007#album\"/>" - + "</entry>\n"; - - StringEntity entity = new StringEntity(entryString); - entity.setContentType(new BasicHeader("Content-Type", "application/atom+xml")); - post.setEntity(entity); - post.addHeader(new BasicHeader("Authorization", "GoogleLogin auth=" + authToken)); - HttpResponse status = mClient.execute(post); - if (LOCAL_LOGV) - Log.v(TAG, "status is " + status.getStatusLine()); - if (status.getStatusLine().getStatusCode() < 200 || status.getStatusLine().getStatusCode() >= 300) { - return null; - } - Album album = new Album(); - Xml.parse(stringFromResponse(status), new PicasaAlbumHandler(album).getContentHandler()); - return album; - } catch (java.io.UnsupportedEncodingException ex) { - Log.e(TAG, "gak, UnsupportedEncodingException " + ex.toString()); - } catch (java.io.IOException ex) { - Log.e(TAG, "IOException " + ex.toString()); - } catch (org.xml.sax.SAXException ex) { - Log.e(TAG, "XmlPullParserException " + ex.toString()); - } - return null; - } - - public static String streamToString(InputStream stream, int maxChars, boolean reset) - throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(stream), 8192); - StringBuilder sb = new StringBuilder(); - String line = null; - - while ((line = reader.readLine()) != null - && (maxChars == -1 || sb.length() < maxChars)) { - sb.append(line); - } - reader.close(); - if (reset) stream.reset(); - return sb.toString(); - } - - InputStream get(String url) { - try { - if (LOCAL_LOGV) Log.v(TAG, "url is " + url); - - for (int i = 0; i < 2; ++i) { - HttpGet get = new HttpGet(url); - get.setHeader(new BasicHeader("Authorization", - "GoogleLogin auth=" + mPicasaAuthToken)); - - HttpResponse response = mClient.execute(get); - if (LOCAL_LOGV) Log.v(TAG, "response is " + response.getStatusLine()); - switch (response.getStatusLine().getStatusCode()) { - case HttpStatus.SC_UNAUTHORIZED: - case HttpStatus.SC_FORBIDDEN: - case HttpStatus.SC_INTERNAL_SERVER_ERROR: // http://b/1151576 - try { - mGls.invalidateAuthToken(mPicasaAuthToken); - } catch (GoogleLoginServiceNotFoundException e) { - Log.e(TAG, "Could not invalidate picasa auth token", e); - } - mPicasaAuthToken = null; - computeAuthToken(); - if (mPicasaAuthToken != null) { - // retry fetch after getting new token - continue; - } - break; - } - - InputStream inputStream = response.getEntity().getContent(); - return inputStream; - } - return null; - } catch (java.io.IOException ex) { - Log.e(TAG, "IOException"); - } - return null; - } - - private HashMap<String, Album> getAlbums() { - if (LOCAL_LOGV) - Log.v(TAG, "getAlbums"); - - PicasaAlbumHandler h = new PicasaAlbumHandler(); - try { - String url = getServiceBaseUrl() + mPicasaUsername + "?kind=album"; - InputStream inputStream = get(url); - if (inputStream == null) { - if (Config.LOGV) - Log.v(TAG, "can't get " + url + "; bail from getAlbums()"); - mPicasaAuthToken = null; - return null; - } - - Xml.parse(inputStream, Xml.findEncodingByName("UTF-8"), h.getContentHandler()); - if (LOCAL_LOGV) - Log.v(TAG, "done getting albums"); - inputStream.close(); - } catch (IOException e) { - Log.e(TAG, "got exception " + e.toString()); - e.printStackTrace(); - } catch (SAXException e) { - Log.e(TAG, "got exception " + e.toString()); - e.printStackTrace(); - } - if (LOCAL_LOGV) { - java.util.Iterator it = h.getAlbums().keySet().iterator(); - while (it.hasNext()) { - if (Config.LOGV) - Log.v(TAG, "album: " + (String) it.next()); - } - } - return h.getAlbums(); - } - - ArrayList<String> getAlbumContents(String albumName) { - String url = getServiceBaseUrl() + mPicasaUsername + "/album/" + albumName + "?kind=photo&max-results=10000"; - try { - InputStream inputStream = get(url); - if (inputStream == null) - return null; - - AlbumContentsHandler ah = new AlbumContentsHandler(); - Xml.parse(inputStream, Xml.findEncodingByName("UTF-8"), ah.getContentHandler()); - ArrayList<String> photos = ah.getPhotos(); - inputStream.close(); - return photos; - } catch (IOException e) { - Log.e(TAG, "got IOException " + e.toString()); - e.printStackTrace(); - } catch (SAXException e) { - Log.e(TAG, "got SAXException " + e.toString()); - e.printStackTrace(); - } - return null; - } - - class AlbumContentsHandler implements ElementListener { - private static final String ATOM_NAMESPACE - = "http://www.w3.org/2005/Atom"; - private static final String PICASA_NAMESPACE - = "http://schemas.google.com/photos/2007"; - - private ContentHandler mHandler = null; - private ArrayList<String> mPhotos = new ArrayList<String>(); - - public AlbumContentsHandler() { - RootElement root = new RootElement(ATOM_NAMESPACE, "feed"); - Element entry = root.getChild(ATOM_NAMESPACE, "entry"); - - entry.setElementListener(this); - - entry.getChild(PICASA_NAMESPACE, "id") - .setEndTextElementListener(new EndTextElementListener() { - public void end(String body) { - mPhotos.add(body); - } - }); - - mHandler = root.getContentHandler(); - } - - public void start(Attributes attributes) { - } - - public void end() { - } - - ContentHandler getContentHandler() { - return mHandler; - } - - public ArrayList<String> getPhotos() { - return mPhotos; - } - } - - private String getServiceBaseUrl() { - return "http://picasaweb.google.com/data/feed/api/user/"; - } - - - class PicasaAlbumHandler implements ElementListener { - private Album mAlbum; - private HashMap<String, Album> mAlbums = new HashMap<String, Album>(); - private boolean mJustOne; - private static final String ATOM_NAMESPACE - = "http://www.w3.org/2005/Atom"; - private static final String PICASSA_NAMESPACE - = "http://schemas.google.com/photos/2007"; - private ContentHandler handler = null; - - public PicasaAlbumHandler() { - mJustOne = false; - init(); - } - - public HashMap<String, Album> getAlbums() { - return mAlbums; - } - - public PicasaAlbumHandler(Album album) { - mJustOne = true; - mAlbum = album; - init(); - } - - private void init() { - Element entry; - RootElement root; - if (mJustOne) { - root = new RootElement(ATOM_NAMESPACE, "entry"); - entry = root; - } else { - root = new RootElement(ATOM_NAMESPACE, "feed"); - entry = root.getChild(ATOM_NAMESPACE, "entry"); - } - entry.setElementListener(this); - - entry.getChild(ATOM_NAMESPACE, "title") - .setEndTextElementListener(new EndTextElementListener() { - public void end(String body) { - mAlbum.setAlbumName(body); - } - }); - - entry.getChild(PICASSA_NAMESPACE, "name") - .setEndTextElementListener(new EndTextElementListener() { - public void end(String body) { - mAlbum.setAlbumId(body); - } - }); - - this.handler = root.getContentHandler(); - } - - public void start(Attributes attributes) { - if (!mJustOne) { - mAlbum = new Album(); - } - } - - public void end() { - if (!mJustOne) { - mAlbums.put(mAlbum.getAlbumName(), mAlbum); - mAlbum = null; - } - } - - ContentHandler getContentHandler() { - return handler; - } - } -} diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java new file mode 100644 index 0000000..7fcab9a --- /dev/null +++ b/src/com/android/camera/VideoCamera.java @@ -0,0 +1,810 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera; + +import java.io.File; +import java.util.ArrayList; +import java.io.IOException; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.ActivityNotFoundException; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.ColorDrawable; +import android.location.LocationManager; +import android.media.MediaMetadataRetriever; +import android.media.MediaRecorder; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.os.Message; +import android.os.StatFs; +import android.os.SystemClock; +import android.preference.PreferenceManager; +import android.provider.MediaStore.Images; +import android.provider.MediaStore.Video; +import android.text.format.DateFormat; +import android.util.Log; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.view.MenuItem.OnMenuItemClickListener; +import android.view.animation.Animation; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; +import android.widget.RelativeLayout.LayoutParams; + +public class VideoCamera extends Activity implements View.OnClickListener, SurfaceHolder.Callback { + + private static final String TAG = "videocamera"; + + private static final boolean DEBUG = true; + private static final boolean DEBUG_SUPPRESS_AUDIO_RECORDING = DEBUG && true; + private static final boolean DEBUG_DO_NOT_REUSE_MEDIA_RECORDER = DEBUG && true; + + private static final int KEEP = 2; + private static final int CLEAR_SCREEN_DELAY = 4; + private static final int UPDATE_RECORD_TIME = 5; + private static final int RESTART_PREVIEW = 6; + + private static final int SCREEN_DELAY = 2 * 60 * 1000; + private static final int POST_PICTURE_ALERT_TIMEOUT = 6 * 1000; + + private static final int NO_STORAGE_ERROR = -1; + private static final int CANNOT_STAT_ERROR = -2; + + public static final int MENU_SWITCH_TO_VIDEO = 0; + public static final int MENU_SWITCH_TO_CAMERA = 1; + public static final int MENU_SETTINGS = 6; + public static final int MENU_GALLERY_PHOTOS = 7; + public static final int MENU_GALLERY_VIDEOS = 8; + public static final int MENU_SAVE_SELECT_PHOTOS = 30; + public static final int MENU_SAVE_NEW_PHOTO = 31; + public static final int MENU_SAVE_SELECTVIDEO = 32; + public static final int MENU_SAVE_TAKE_NEW_VIDEO = 33; + public static final int MENU_SAVE_GALLERY_PHOTO = 34; + public static final int MENU_SAVE_GALLERY_VIDEO_PHOTO = 35; + public static final int MENU_SAVE_CAMERA_DONE = 36; + public static final int MENU_SAVE_CAMERA_VIDEO_DONE = 37; + + Toast mToast; + SharedPreferences mPreferences; + + private static final float VIDEO_ASPECT_RATIO = 176.0f / 144.0f; + VideoPreview mVideoPreview; + SurfaceHolder mSurfaceHolder = null; + ImageView mBlackout = null; + ImageView mVideoFrame; + Bitmap mVideoFrameBitmap; + + private MediaRecorder mMediaRecorder; + private boolean mMediaRecorderRecording = false; + private long mRecordingStartTime; + private String mCurrentVideoFilename; + private Uri mCurrentVideoUri; + + boolean mPausing = false; + + static ContentResolver mContentResolver; + boolean mDidRegister = false; + + int mCurrentZoomIndex = 0; + + private ImageView mModeIndicatorView; + private ImageView mRecordingIndicatorView; + private TextView mRecordingTimeView; + + ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>(); + + View mPostPictureAlert; + LocationManager mLocationManager = null; + + private int mPicturesRemaining; + + private Handler mHandler = new MainHandler(); + + private void cancelSavingNotification() { + if (mToast != null) { + mToast.cancel(); + mToast = null; + } + } + + /** This Handler is used to post message back onto the main thread of the application */ + private class MainHandler extends Handler { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case KEEP: { + keep(); + + if (msg.obj != null) { + mHandler.post((Runnable)msg.obj); + } + break; + } + + case CLEAR_SCREEN_DELAY: { + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + break; + } + + case UPDATE_RECORD_TIME: { + if (mMediaRecorderRecording) { + long now = SystemClock.uptimeMillis(); + long delta = now - mRecordingStartTime; + long seconds = delta / 1000; + long minutes = seconds / 60; + long remainderSeconds = seconds - (minutes * 60); + + String secondsString = Long.toString(remainderSeconds); + if (secondsString.length() < 2) { + secondsString = "0" + secondsString; + } + String minutesString = Long.toString(minutes); + if (minutesString.length() < 2) { + minutesString = "0" + minutesString; + } + String text = minutesString + ":" + secondsString; + mRecordingTimeView.setText(text); + mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME, 1000); + } + break; + } + + case RESTART_PREVIEW: + hideVideoFrameAndStartPreview(); + break; + + default: + Log.v(TAG, "Unhandled message: " + msg.what); + break; + } + } + }; + + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { + // SD card available + // TODO put up a "please wait" message + // TODO also listen for the media scanner finished message + showStorageToast(); + } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) { + // SD card unavailable + showStorageToast(); + } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { + Toast.makeText(VideoCamera.this, getResources().getString(R.string.wait), 5000); + } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { + showStorageToast(); + } + } + }; + + static private String createName(long dateTaken) { + return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString(); + } + + private void postAfterKeep(final Runnable r) { + Message msg = mHandler.obtainMessage(KEEP); + msg.obj = r; + msg.sendToTarget(); + } + + /** Called with the activity is first created. */ + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + + mPreferences = PreferenceManager.getDefaultSharedPreferences(this); + mContentResolver = getContentResolver(); + + //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); + requestWindowFeature(Window.FEATURE_PROGRESS); + + Window win = getWindow(); + win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + setContentView(R.layout.video_camera); + + mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview); + mVideoPreview.setAspectRatio(VIDEO_ASPECT_RATIO); + + // don't set mSurfaceHolder here. We have it set ONLY within + // surfaceCreated / surfaceDestroyed, other parts of the code + // assume that when it is set, the surface is also set. + SurfaceHolder holder = mVideoPreview.getHolder(); + holder.addCallback(this); + holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + + mBlackout = (ImageView) findViewById(R.id.blackout); + mBlackout.setBackgroundDrawable(new ColorDrawable(0xFF000000)); + + mPostPictureAlert = findViewById(R.id.post_picture_panel); + View b; + + b = findViewById(R.id.play); + b.setOnClickListener(this); + + b = findViewById(R.id.share); + b.setOnClickListener(this); + + b = findViewById(R.id.discard); + b.setOnClickListener(this); + + mModeIndicatorView = (ImageView) findViewById(R.id.mode_indicator); + mRecordingIndicatorView = (ImageView) findViewById(R.id.recording_indicator); + mRecordingTimeView = (TextView) findViewById(R.id.recording_time); + mVideoFrame = (ImageView) findViewById(R.id.video_frame); + } + + @Override + public void onStart() { + super.onStart(); + + final View hintView = findViewById(R.id.hint_toast); + if (hintView != null) + hintView.setVisibility(View.GONE); + + Thread t = new Thread(new Runnable() { + public void run() { + final boolean storageOK = calculatePicturesRemaining() > 0; + if (hintView == null) + return; + + if (storageOK) { + mHandler.post(new Runnable() { + public void run() { + hintView.setVisibility(View.VISIBLE); + } + }); + mHandler.postDelayed(new Runnable() { + public void run() { + Animation a = new android.view.animation.AlphaAnimation(1F, 0F); + a.setDuration(500); + a.startNow(); + hintView.setAnimation(a); + hintView.setVisibility(View.GONE); + } + }, 3000); + } else { + mHandler.post(new Runnable() { + public void run() { + hintView.setVisibility(View.GONE); + showStorageToast(); + } + }); + } + } + }); + t.start(); + } + + public void onClick(View v) { + switch (v.getId()) { + case R.id.discard: { + File f = new File(mCurrentVideoFilename); + f.delete(); + mContentResolver.delete(mCurrentVideoUri, null, null); + + hideVideoFrameAndStartPreview(); + break; + } + + case R.id.share: { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_SEND); + intent.setType("video/3gpp"); + intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri); + try { + startActivity(Intent.createChooser(intent, getText(R.string.sendVideo))); + } catch (android.content.ActivityNotFoundException ex) { + Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show(); + } + + break; + } + + case R.id.play: { + Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri); + try { + startActivity(intent); + } catch (android.content.ActivityNotFoundException ex) { + Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex); + } + break; + } + } + } + + private void showStorageToast() { + String noStorageText = null; + int remaining = calculatePicturesRemaining(); + + if (remaining == NO_STORAGE_ERROR) { + noStorageText = getString(R.string.no_storage); + } else if (remaining < 1) { + noStorageText = getString(R.string.not_enough_space); + } + + if (noStorageText != null) { + Toast.makeText(this, noStorageText, 5000).show(); + } + } + + @Override + public void onResume() { + super.onResume(); + mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); + + mPausing = false; + + // install an intent filter to receive SD card related events. + IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); + intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); + intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); + intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); + intentFilter.addDataScheme("file"); + registerReceiver(mReceiver, intentFilter); + mDidRegister = true; + + mBlackout.setVisibility(View.INVISIBLE); + if (mVideoFrameBitmap == null) { + initializeVideo(); + } else { + showPostRecordingAlert(); + } + } + + @Override + public void onStop() { + Log.v(TAG, "onStop"); + stopVideoRecording(); + keep(); + mHandler.removeMessages(CLEAR_SCREEN_DELAY); + super.onStop(); + } + + @Override + protected void onPause() { + Log.v(TAG, "onPause"); + stopVideoRecording(); + keep(); + hidePostPictureAlert(); + + mPausing = true; + + if (mDidRegister) { + unregisterReceiver(mReceiver); + mDidRegister = false; + } + + super.onPause(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + switch (keyCode) { + case KeyEvent.KEYCODE_BACK: + if (mMediaRecorderRecording) { + Log.v(TAG, "onKeyBack"); + stopVideoRecordingAndDisplayDialog(); + return true; + } else if(isPostRecordingAlertVisible()) { + hideVideoFrameAndStartPreview(); + return true; + } + break; + case KeyEvent.KEYCODE_FOCUS: + return true; + case KeyEvent.KEYCODE_CAMERA: + case KeyEvent.KEYCODE_DPAD_CENTER: + if (event.getRepeatCount() == 0) { + if (!mMediaRecorderRecording) { + startVideoRecording(); + } else { + stopVideoRecordingAndDisplayDialog(); + } + return true; + } + return true; + case KeyEvent.KEYCODE_MENU: + if (mMediaRecorderRecording) { + stopVideoRecordingAndDisplayDialog(); + return true; + } + hideVideoFrameAndStartPreview(); + break; + } + + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onTrackballEvent(MotionEvent event) { + cancelRestartPreviewTimeout(); + return super.onTrackballEvent(event); + } + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + stopVideoRecording(); + initializeVideo(); + } + + public void surfaceCreated(SurfaceHolder holder) { + mSurfaceHolder = holder; + } + + public void surfaceDestroyed(SurfaceHolder holder) { + mSurfaceHolder = null; + } + + void gotoGallery() { + Uri target = Video.Media.INTERNAL_CONTENT_URI; + Intent intent = new Intent(Intent.ACTION_VIEW, target); + try { + startActivity(intent); + } catch (ActivityNotFoundException e) { + Log.e(TAG, "Could not start gallery activity", e); + } + } + + void keep() { + cancelSavingNotification(); + }; + + void toss() { + cancelSavingNotification(); + }; + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + + for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) { + if (i != MenuHelper.GENERIC_ITEM) { + menu.setGroupVisible(i, false); + } + } + + menu.setGroupVisible(MenuHelper.VIDEO_MODE_ITEM, true); + + return true; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + + addBaseMenuItems(menu); + MenuHelper.addImageMenuItems( + menu, + MenuHelper.INCLUDE_ALL & ~MenuHelper.INCLUDE_ROTATE_MENU, + false, + VideoCamera.this, + mHandler, + + // Handler for deletion + new Runnable() { + public void run() { + // What do we do here? + // mContentResolver.delete(uri, null, null); + } + }, + new MenuHelper.MenuInvoker() { + public void run(final MenuHelper.MenuCallback cb) { + } + }); + + MenuItem gallery = menu.add(MenuHelper.IMAGE_SAVING_ITEM, MENU_SAVE_GALLERY_PHOTO, 0, + R.string.camera_gallery_photos_text).setOnMenuItemClickListener( + new MenuItem.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + postAfterKeep(new Runnable() { + public void run() { + gotoGallery(); + } + }); + return true; + } + }); + gallery.setIcon(android.R.drawable.ic_menu_gallery); + return true; + } + + private int calculatePicturesRemaining() { + try { + if (!ImageManager.hasStorage()) { + mPicturesRemaining = NO_STORAGE_ERROR; + } else { + String storageDirectory = Environment.getExternalStorageDirectory().toString(); + StatFs stat = new StatFs(storageDirectory); + float remaining = ((float)stat.getAvailableBlocks() * (float)stat.getBlockSize()) / 400000F; + mPicturesRemaining = (int)remaining; + } + } catch (Exception ex) { + // if we can't stat the filesystem then we don't know how many + // pictures are remaining. it might be zero but just leave it + // blank since we really don't know. + mPicturesRemaining = CANNOT_STAT_ERROR; + } + return mPicturesRemaining; + } + + private void initializeVideo() { + Log.v(TAG, "initializeVideo"); + releaseMediaRecorder(); + + if (mSurfaceHolder == null) { + Log.v(TAG, "SurfaceHolder is null"); + return; + } + + mMediaRecorder = new MediaRecorder(); + + if (DEBUG_SUPPRESS_AUDIO_RECORDING) { + Log.v(TAG, "DEBUG_SUPPRESS_AUDIO_RECORDING is true."); + } else { + mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + } + mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); + mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); + Log.v(TAG, "before setOutputFile"); + createVideoPath(); + mMediaRecorder.setOutputFile(mCurrentVideoFilename); + Boolean videoQualityLow = getIntPreference("pref_camera_videoquality_key") == 0; + + // Use the same frame rate for both, since internally + // if the frame rate is too large, it can cause camera to become + // unstable. We need to fix the MediaRecorder to disable the support + // of setting frame rate for now. + mMediaRecorder.setVideoFrameRate(20); + if (videoQualityLow) { + mMediaRecorder.setVideoSize(176,144); + } else { + mMediaRecorder.setVideoSize(352,288); + } + mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); + if (!DEBUG_SUPPRESS_AUDIO_RECORDING) { + mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); + } + Log.v(TAG, "before setPreviewDisplay"); + mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); + try { + mMediaRecorder.prepare(); + } catch (IOException exception) { + Log.e(TAG, "prepare failed for " + mCurrentVideoFilename); + releaseMediaRecorder(); + // TODO: add more exception handling logic here + return; + } + mMediaRecorderRecording = false; + } + + private void releaseMediaRecorder() { + Log.v(TAG, "Releasing media recorder."); + if (mMediaRecorder != null) { + mMediaRecorder.reset(); + mMediaRecorder.release(); + mMediaRecorder = null; + } + } + + private void restartPreview() { + if (DEBUG_DO_NOT_REUSE_MEDIA_RECORDER) { + Log.v(TAG, "DEBUG_DO_NOT_REUSE_MEDIA_RECORDER recreating mMediaRecorder."); + initializeVideo(); + } else { + try { + mMediaRecorder.prepare(); + } catch (IOException exception) { + Log.e(TAG, "prepare failed for " + mCurrentVideoFilename); + releaseMediaRecorder(); + // TODO: add more exception handling logic here + } + } + } + + private int getIntPreference(String key) { + String s = mPreferences.getString(key, "0"); + return Integer.parseInt(s); + } + + private void createVideoPath() { + long dateTaken = System.currentTimeMillis(); + String title = createName(dateTaken); + String displayName = title + ".3gp"; // Used when emailing. + String filename = ImageManager.CAMERA_IMAGE_BUCKET_NAME + "/" + + Long.toString(dateTaken) + ".3gp"; + ContentValues values = new ContentValues(7); + values.put(Video.Media.TITLE, title); + values.put(Video.Media.DISPLAY_NAME, displayName); + values.put(Video.Media.DESCRIPTION, ""); + values.put(Video.Media.DATE_TAKEN, dateTaken); + values.put(Video.Media.MIME_TYPE, "video/3gpp"); + values.put(Video.Media.DATA, filename); + Uri videoTable = Uri.parse("content://media/external/video/media"); + Uri item = mContentResolver.insert(videoTable, values); + mCurrentVideoFilename = filename; + mCurrentVideoUri = item; + } + + private void addBaseMenuItems(Menu menu) { + MenuHelper.addSwitchModeMenuItem(menu, this, false); + { + MenuItem gallery = menu.add(MenuHelper.IMAGE_MODE_ITEM, MENU_GALLERY_PHOTOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + gotoGallery(); + return true; + } + }); + gallery.setIcon(android.R.drawable.ic_menu_gallery); + mGalleryItems.add(gallery); + } + { + MenuItem gallery = menu.add(MenuHelper.VIDEO_MODE_ITEM, MENU_GALLERY_VIDEOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + gotoGallery(); + return true; + } + }); + gallery.setIcon(android.R.drawable.ic_menu_gallery); + mGalleryItems.add(gallery); + } + + MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, R.string.settings).setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + Intent intent = new Intent(); + intent.setClass(VideoCamera.this, CameraSettings.class); + startActivity(intent); + return true; + } + }); + item.setIcon(android.R.drawable.ic_menu_preferences); + } + + private void startVideoRecording() { + Log.v(TAG, "startVideoRecording"); + if (!mMediaRecorderRecording) { + + // Check mMediaRecorder to see whether it is initialized or not. + if (mMediaRecorder == null) { + initializeVideo(); + } + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + try { + mMediaRecorder.start(); // Recording is now started + } catch (RuntimeException e) { + Log.e(TAG, "Could not start media recorder. ", e); + return; + } + mMediaRecorderRecording = true; + mRecordingStartTime = SystemClock.uptimeMillis(); + mModeIndicatorView.setVisibility(View.GONE); + mRecordingIndicatorView.setVisibility(View.VISIBLE); + mRecordingTimeView.setText(""); + mRecordingTimeView.setVisibility(View.VISIBLE); + mHandler.sendEmptyMessage(UPDATE_RECORD_TIME); + } + } + + private void stopVideoRecordingAndDisplayDialog() { + Log.v(TAG, "stopVideoRecordingAndDisplayDialog"); + if (mMediaRecorderRecording) { + stopVideoRecording(); + acquireAndShowVideoFrame(); + showPostRecordingAlert(); + } + } + + private void showPostRecordingAlert() { + cancelRestartPreviewTimeout(); + mPostPictureAlert.setVisibility(View.VISIBLE); + mHandler.sendEmptyMessageDelayed(RESTART_PREVIEW, POST_PICTURE_ALERT_TIMEOUT); + } + + private void hidePostPictureAlert() { + cancelRestartPreviewTimeout(); + mPostPictureAlert.setVisibility(View.INVISIBLE); + } + + private void cancelRestartPreviewTimeout() { + mHandler.removeMessages(RESTART_PREVIEW); + } + + private boolean isPostRecordingAlertVisible() { + return mPostPictureAlert.getVisibility() == View.VISIBLE; + } + + private void stopVideoRecording() { + Log.v(TAG, "stopVideoRecording"); + if (mMediaRecorderRecording || mMediaRecorder != null) { + if (mMediaRecorderRecording) { + mMediaRecorder.stop(); + } + releaseMediaRecorder(); + mMediaRecorderRecording = false; + mModeIndicatorView.setVisibility(View.VISIBLE); + mRecordingIndicatorView.setVisibility(View.GONE); + mRecordingTimeView.setVisibility(View.GONE); + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + + private void hideVideoFrameAndStartPreview() { + hidePostPictureAlert(); + hideVideoFrame(); + restartPreview(); + } + + private void acquireAndShowVideoFrame() { + recycleVideoFrameBitmap(); + mVideoFrameBitmap = createVideoThumbnail(mCurrentVideoFilename); + mVideoFrame.setImageBitmap(mVideoFrameBitmap); + mVideoFrame.setVisibility(View.VISIBLE); + } + + private void hideVideoFrame() { + recycleVideoFrameBitmap(); + mVideoFrame.setVisibility(View.GONE); + } + + private void recycleVideoFrameBitmap() { + if (mVideoFrameBitmap != null) { + mVideoFrame.setImageDrawable(null); + mVideoFrameBitmap.recycle(); + mVideoFrameBitmap = null; + } + } + + private Bitmap createVideoThumbnail(String filePath) { + Bitmap bitmap = null; + MediaMetadataRetriever retriever = new MediaMetadataRetriever(); + try { + retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY); + retriever.setDataSource(filePath); + bitmap = retriever.captureFrame(); + } finally { + retriever.release(); + } + return bitmap; + } + +} + diff --git a/src/com/android/camera/VideoPreview.java b/src/com/android/camera/VideoPreview.java new file mode 100644 index 0000000..aed1e89 --- /dev/null +++ b/src/com/android/camera/VideoPreview.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.Log; +import android.view.SurfaceView; +import android.view.View.MeasureSpec; + +class VideoPreview extends SurfaceView { + private float mAspectRatio; + private int mHorizontalTileSize = 1; + private int mVerticalTileSize = 1; + + /** + * Setting the aspect ratio to this value means to not enforce an aspect ratio. + */ + public static float DONT_CARE = 0.0f; + + public VideoPreview(Context context) { + super(context); + } + + public VideoPreview(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public VideoPreview(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public void setTileSize(int horizontalTileSize, int verticalTileSize) { + if ((mHorizontalTileSize != horizontalTileSize) + || (mVerticalTileSize != verticalTileSize)) { + mHorizontalTileSize = horizontalTileSize; + mVerticalTileSize = verticalTileSize; + requestLayout(); + invalidate(); + } + } + + public void setAspectRatio(int width, int height) { + setAspectRatio(((float) width) / ((float) height)); + } + + public void setAspectRatio(float aspectRatio) { + if (mAspectRatio != aspectRatio) { + mAspectRatio = aspectRatio; + requestLayout(); + invalidate(); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (mAspectRatio != DONT_CARE) { + int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); + int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); + + int width = widthSpecSize; + int height = heightSpecSize; + + if (width > 0 && height > 0) { + float defaultRatio = ((float) width) / ((float) height); + if (defaultRatio < mAspectRatio) { + // Need to reduce height + height = (int) (width / mAspectRatio); + } else if (defaultRatio > mAspectRatio) { + width = (int) (height * mAspectRatio); + } + width = roundUpToTile(width, mHorizontalTileSize, widthSpecSize); + height = roundUpToTile(height, mVerticalTileSize, heightSpecSize); + Log.i("VideoPreview", "ar " + mAspectRatio + " setting size: " + width + 'x' + height); + setMeasuredDimension(width, height); + return; + } + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + private int roundUpToTile(int dimension, int tileSize, int maxDimension) { + return Math.min(((dimension + tileSize - 1) / tileSize) * tileSize, maxDimension); + } +} diff --git a/src/com/android/camera/ViewImage.java b/src/com/android/camera/ViewImage.java index 4b9eb58..9579f19 100644 --- a/src/com/android/camera/ViewImage.java +++ b/src/com/android/camera/ViewImage.java @@ -102,8 +102,8 @@ public class ViewImage extends Activity private Animation mHidePrevImageViewAnimation = new AlphaAnimation(1F, 0F); private Animation mShowNextImageViewAnimation = new AlphaAnimation(0F, 1F); private Animation mShowPrevImageViewAnimation = new AlphaAnimation(0F, 1F); - - + + static final int sPadding = 20; static final int sHysteresis = sPadding * 2; static final int sBaseScrollDuration = 1000; // ms @@ -127,17 +127,17 @@ public class ViewImage extends Activity Runnable mDismissOnScreenControlsRunnable; ZoomControls mZoomControls; - + public ViewImage() { } - + private void updateNextPrevControls() { boolean showPrev = mCurrentPosition > 0; boolean showNext = mCurrentPosition < mAllImages.getCount() - 1; - + boolean prevIsVisible = mPrevImageView.getVisibility() == View.VISIBLE; boolean nextIsVisible = mNextImageView.getVisibility() == View.VISIBLE; - + if (showPrev && !prevIsVisible) { Animation a = mShowPrevImageViewAnimation; a.setDuration(500); @@ -205,7 +205,7 @@ public class ViewImage extends Activity mDismissOnScreenControlsRunnable = new Runnable() { public void run() { mZoomControls.hide(); - + if (mNextImageView.getVisibility() == View.VISIBLE) { Animation a = mHideNextImageViewAnimation; a.setDuration(500); @@ -213,7 +213,7 @@ public class ViewImage extends Activity mNextImageView.setAnimation(a); mNextImageView.setVisibility(View.INVISIBLE); } - + if (mPrevImageView.getVisibility() == View.VISIBLE) { Animation a = mHidePrevImageViewAnimation; a.setDuration(500); @@ -252,14 +252,14 @@ public class ViewImage extends Activity static public class ImageViewTouch extends ImageViewTouchBase { private ViewImage mViewImage; - + private static int TOUCH_STATE_REST = 0; private static int TOUCH_STATE_LEFT_PRESS = 1; - private static int TOUCH_STATE_RIGHT_PRESS = 2; - private static int TOUCH_STATE_PANNING = 3; - + private static int TOUCH_STATE_RIGHT_PRESS = 2; + private static int TOUCH_STATE_PANNING = 3; + private static int TOUCH_AREA_WIDTH = 60; - + private int mTouchState = TOUCH_STATE_REST; public ImageViewTouch(Context context) { @@ -300,7 +300,7 @@ public class ViewImage extends Activity mLastYTouchPos = y; mTouchState = TOUCH_STATE_REST; break; - case MotionEvent.ACTION_MOVE: + case MotionEvent.ACTION_MOVE: if (x < TOUCH_AREA_WIDTH) { if (mTouchState == TOUCH_STATE_REST) { mTouchState = TOUCH_STATE_LEFT_PRESS; @@ -325,10 +325,10 @@ public class ViewImage extends Activity mTouchState = TOUCH_STATE_PANNING; viewImage.mPrevImageView.setPressed(false); viewImage.mNextImageView.setPressed(false); - + int deltaX; int deltaY; - + if (mLastXTouchPos == -1) { deltaX = 0; deltaY = 0; @@ -342,7 +342,7 @@ public class ViewImage extends Activity if (mBitmapDisplayed == null) return true; - + if (deltaX != 0) { // Second. Pan to whatever degree is possible. if (getScale() > 1F) { @@ -357,7 +357,7 @@ public class ViewImage extends Activity int nextImagePos = -1; if (mTouchState == TOUCH_STATE_LEFT_PRESS && x < TOUCH_AREA_WIDTH) { nextImagePos = viewImage.mCurrentPosition - 1; - } else if (mTouchState == TOUCH_STATE_RIGHT_PRESS && + } else if (mTouchState == TOUCH_STATE_RIGHT_PRESS && x > viewWidth - TOUCH_AREA_WIDTH) { nextImagePos = viewImage.mCurrentPosition + 1; } @@ -546,7 +546,7 @@ public class ViewImage extends Activity private void animateScrollTo(int xNew, int yNew) { mScroller.startScrollTo(xNew, yNew); } - + @Override public boolean onCreateOptionsMenu(Menu menu) { @@ -564,9 +564,8 @@ public class ViewImage extends Activity }); item.setIcon(android.R.drawable.ic_menu_slideshow); } - + mFlipItem = MenuHelper.addFlipOrientation(menu, ViewImage.this, mPrefs); - mFlipItem.setIcon(android.R.drawable.ic_menu_always_landscape_portrait); final SelectedImageGetter selectedImageGetter = new SelectedImageGetter() { public ImageManager.IImage getCurrentImage() { @@ -581,6 +580,7 @@ public class ViewImage extends Activity mImageMenuRunnable = MenuHelper.addImageMenuItems( menu, MenuHelper.INCLUDE_ALL, + true, ViewImage.this, mHandler, mDeletePhotoRunnable, @@ -641,7 +641,7 @@ public class ViewImage extends Activity setImage(mCurrentPosition); } }; - + @Override public boolean onPrepareOptionsMenu(Menu menu) { @@ -663,7 +663,7 @@ public class ViewImage extends Activity private boolean isCurrentImageShareable() { IImage image = mAllImages.getImageAt(mCurrentPosition); if (image != null){ - Uri uri = image.fullSizeImageUri(); + Uri uri = image.fullSizeImageUri(); String fullUri = uri.toString(); return fullUri.startsWith(MediaStore.Images.Media.INTERNAL_CONTENT_URI.toString()) || fullUri.startsWith(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString()); @@ -674,10 +674,12 @@ public class ViewImage extends Activity @Override public void onConfigurationChanged(android.content.res.Configuration newConfig) { super.onConfigurationChanged(newConfig); - for (ImageViewTouchBase iv: mImageViews) { - iv.setImageBitmapResetBase(null, false, true); + if (newConfig.orientation != getResources().getConfiguration().orientation) { + for (ImageViewTouchBase iv: mImageViews) { + iv.setImageBitmapResetBase(null, false, true); + } + MenuHelper.requestOrientation(this, mPrefs); } - MenuHelper.requestOrientation(this, mPrefs); } @Override @@ -839,7 +841,7 @@ public class ViewImage extends Activity if (mLoad != null) { long t1; if (Config.LOGV) t1 = System.currentTimeMillis(); - + Bitmap b = null; try { b = mLoad.get(); @@ -941,7 +943,7 @@ public class ViewImage extends Activity for (ImageViewTouchBase ivtb : mImageViews) ivtb.dump(); } - + if (!mFirst) { if (left) { mImageViews[2].copyFrom(mImageViews[1]); @@ -977,7 +979,7 @@ public class ViewImage extends Activity } else { mScroller.scrollTo(to, 0); } - + ImageGetterCallback cb = new ImageGetterCallback() { public void completed(boolean wasCanceled) { mImageViews[1].setFocusableInTouchMode(true); @@ -1064,7 +1066,7 @@ public class ViewImage extends Activity mSlideShowImageViews[i].setImageBitmapResetBase(null, true, true); mSlideShowImageViews[i].setVisibility(View.INVISIBLE); } - + Uri uri = getIntent().getData(); if (Config.LOGV) @@ -1132,7 +1134,7 @@ public class ViewImage extends Activity for (ImageViewTouchBase ivt: mImageViews) { ivt.clear(); } - + if (false) { Log.v(TAG, "current is " + this.mSlideShowImageCurrent); this.mSlideShowImageViews[0].dump(); @@ -1161,7 +1163,7 @@ public class ViewImage extends Activity Log.v(TAG, "read prefs... animidx: " + mAnimationIndex); Log.v(TAG, "read prefs... interval: " + mSlideShowInterval); } - + if (mUseShuffleOrder) { generateShuffleOrder(); } @@ -1345,16 +1347,16 @@ public class ViewImage extends Activity public void onSaveInstanceState(Bundle b) { super.onSaveInstanceState(b); ImageManager.IImage image = mAllImages.getImageAt(mCurrentPosition); - + if (image != null){ - Uri uri = image.fullSizeImageUri(); - String bucket = null; - if(getIntent()!= null && getIntent().getData()!=null) - bucket = getIntent().getData().getQueryParameter("bucketId"); - - if(bucket!=null) - uri = uri.buildUpon().appendQueryParameter("bucketId", bucket).build(); - + Uri uri = image.fullSizeImageUri(); + String bucket = null; + if(getIntent()!= null && getIntent().getData()!=null) + bucket = getIntent().getData().getQueryParameter("bucketId"); + + if(bucket!=null) + uri = uri.buildUpon().appendQueryParameter("bucketId", bucket).build(); + b.putString("uri", uri.toString()); } if (mMode == MODE_SLIDESHOW) @@ -1364,8 +1366,15 @@ public class ViewImage extends Activity @Override public void onResume() { - super.onResume(); - + super.onResume(); + + // normally this will never be zero but if one "backs" into this + // activity after removing the sdcard it could be zero. in that + // case just "finish" since there's nothing useful that can happen. + if (mAllImages.getCount() == 0) { + finish(); + } + ImageManager.IImage image = mAllImages.getImageAt(mCurrentPosition); String sortOrder = mPrefs.getString("pref_gallery_sort_key", null); @@ -1376,7 +1385,7 @@ public class ViewImage extends Activity if (sortAscending != mSortAscending) { init(image.fullSizeImageUri()); } - + if (mGetter == null) { makeGetter(); } @@ -1394,20 +1403,13 @@ public class ViewImage extends Activity }); setImage(mCurrentPosition); - // normally this will never be zero but if one "backs" into this - // activity after removing the sdcard it could be zero. in that - // case just "finish" since there's nothing useful that can happen. - if (mAllImages.getCount() == 0) { - finish(); - } else { - MenuHelper.requestOrientation(this, mPrefs); - } + MenuHelper.requestOrientation(this, mPrefs); } @Override public void onPause() { - super.onPause(); + super.onPause(); mGetter.cancelCurrent(); mGetter.stop(); @@ -1415,18 +1417,18 @@ public class ViewImage extends Activity setMode(MODE_NORMAL); mAllImages.deactivate(); - + for (ImageViewTouchBase iv: mImageViews) { iv.recycleBitmaps(); iv.setImageBitmap(null, true); } - + for (ImageViewTouchBase iv: mSlideShowImageViews) { iv.recycleBitmaps(); iv.setImageBitmap(null, true); } } - + @Override public void onStop() { super.onStop(); diff --git a/src/com/android/camera/ViewVideo.java b/src/com/android/camera/ViewVideo.java deleted file mode 100644 index 527f0bb..0000000 --- a/src/com/android/camera/ViewVideo.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.camera; - -import android.media.MediaPlayer; -import android.app.Activity; -import android.os.Bundle; -import android.content.ContentResolver; -import android.content.Context; -import android.net.Uri; -import android.os.PowerManager; -import android.util.Log; -import android.view.Menu; -import android.view.View; -import android.view.WindowManager; -import android.widget.MediaController; -import android.view.Window; -import android.widget.VideoView; -import android.util.Config; - -class ViewVideo extends Activity -{ - static final String TAG = "ViewVideo"; - - private ImageManager.IImageList mAllVideos; - private PowerManager.WakeLock mWakeLock; - private ContentResolver mContentResolver; - private VideoView mVideoView; - private ImageManager.IImage mVideo; - private int mCurrentPosition = -1; - private MediaController mMediaController; - - // if the activity gets paused the stash the current position here - int mPausedPlaybackPosition = 0; - - - public ViewVideo() - { - } - - @Override - public void onCreate(Bundle icicle) - { - super.onCreate(icicle); - if (Config.LOGV) - Log.v(TAG, "onCreate"); - //getWindow().setFormat(android.graphics.PixelFormat.TRANSLUCENT); - - PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); - - mContentResolver = getContentResolver(); - - setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); - setContentView(R.layout.viewvideo); - - mMediaController = new MediaController(this); - mVideoView = (VideoView) findViewById(R.id.video); - mVideoView.setMediaController(mMediaController); - mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { - public void onCompletion(MediaPlayer mp) { - // TODO what do we really want to do at the end of playback? - finish(); - } - }); - } - - @Override - public void onSaveInstanceState(Bundle b) { - if (Config.LOGV) - Log.v(TAG, "onSaveInstanceState"); - b.putInt("playback_position", mPausedPlaybackPosition); - } - - @Override - public void onRestoreInstanceState(Bundle b) { - if (Config.LOGV) - Log.v(TAG, "onRestoreInstanceState"); - mPausedPlaybackPosition = b.getInt("playback_position", 0); - } - - @Override - public void onPause() { - super.onPause(); - if (Config.LOGV) - Log.v(TAG, "onPause"); - mAllVideos.deactivate(); - - mVideoView.pause(); - mPausedPlaybackPosition = mVideoView.getCurrentPosition(); - mVideoView.setVideoURI(null); - } - - @Override - public void onStop() { - super.onStop(); - if (Config.LOGV) - Log.v(TAG, "onStop"); - } - - @Override - public void onResume() - { - super.onResume(); - if (Config.LOGV) - Log.v(TAG, "onResume"); - - mAllVideos = ImageManager.instance().allImages( - ViewVideo.this, - mContentResolver, - ImageManager.DataLocation.ALL, - ImageManager.INCLUDE_VIDEOS, - ImageManager.SORT_DESCENDING); - - // TODO smarter/faster here please - Uri uri = getIntent().getData(); - if (mVideo == null) { - for (int i = 0; i < mAllVideos.getCount(); i++) { - ImageManager.IImage video = mAllVideos.getImageAt(i); - if (video.fullSizeImageUri().equals(uri)) { - mCurrentPosition = i; - mVideo = video; - break; - } - } - } - - if (mCurrentPosition != -1) { - mMediaController.setPrevNextListeners( - new android.view.View.OnClickListener() { - public void onClick(View v) { - if (++mCurrentPosition == mAllVideos.getCount()) - mCurrentPosition = 0; - ImageManager.IImage video = mAllVideos.getImageAt(mCurrentPosition); - mVideo = video; - mVideoView.setVideoURI(video.fullSizeImageUri()); - mVideoView.start(); - } - }, - new android.view.View.OnClickListener() { - public void onClick(View v) { - if (--mCurrentPosition == -1) - mCurrentPosition = mAllVideos.getCount() - 1; - ImageManager.IImage video = mAllVideos.getImageAt(mCurrentPosition); - mVideo = video; - mVideoView.setVideoURI(video.fullSizeImageUri()); - mVideoView.start(); - } - }); - } - if (Config.LOGV) - android.util.Log.v("camera", "seekTo " + mPausedPlaybackPosition); - mVideoView.setVideoURI(uri); - mVideoView.seekTo(mPausedPlaybackPosition); - mVideoView.start(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) - { - super.onCreateOptionsMenu(menu); - MenuHelper.addVideoMenuItems( - menu, - MenuHelper.INCLUDE_ALL & ~MenuHelper.INCLUDE_VIEWPLAY_MENU, - ViewVideo.this, // activity - null, // handler - new SelectedImageGetter() { - public ImageManager.IImage getCurrentImage() { - return mVideo; - } - public Uri getCurrentImageUri() { - return mVideo.fullSizeImageUri(); - } - }, - - // deletion case - new Runnable() { - public void run() { - mAllVideos.removeImage(mVideo); - finish(); - } - }, - - // pre-work - null, - - // post-work - null); - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) - { - return super.onPrepareOptionsMenu(menu); - } -} diff --git a/src/com/android/camera/YouTubeUpload.java b/src/com/android/camera/YouTubeUpload.java deleted file mode 100644 index 0963d09..0000000 --- a/src/com/android/camera/YouTubeUpload.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.camera; - -import android.content.Intent; -import android.net.Uri; -import android.app.Activity; -import android.app.ProgressDialog; -import android.net.http.AndroidHttpClient; -import android.os.Bundle; -import android.widget.TextView; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - -import android.util.Log; -import android.util.Xml; - - -public class YouTubeUpload extends Activity -{ - private static final String TAG = "YouTubeUpload"; - - private static final String ATOM_NAMESPACE = "http://www.w3.org/2005/Atom"; - private static final boolean mDevServer = false; - - private ArrayList<String> mCategoriesShort = new ArrayList<String>(); - private ArrayList<String> mCategoriesLong = new ArrayList<String>(); - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - TextView tv = new TextView(this); - tv.setText(""); - setContentView(tv); - } - - @Override - public void onResume() { - super.onResume(); - - final ProgressDialog pd = ProgressDialog.show(this, "please wait", ""); - - final ImageManager.IImageList all = ImageManager.instance().allImages( - YouTubeUpload.this, - getContentResolver(), - ImageManager.DataLocation.ALL, - ImageManager.INCLUDE_VIDEOS, - ImageManager.SORT_ASCENDING); - - android.net.Uri uri = getIntent().getData(); - if (uri == null) { - uri = (Uri) getIntent().getParcelableExtra(Intent.EXTRA_STREAM); - } - if (uri != null) { - final ImageManager.VideoObject vid = (ImageManager.VideoObject) all.getImageForUri(uri); - if (vid != null) { - new Thread(new Runnable() { - public void run() { - getCategories(); - runOnUiThread(new Runnable() { - public void run() { - pd.cancel(); - MenuHelper.YouTubeUploadInfoDialog infoDialog = new MenuHelper.YouTubeUploadInfoDialog( - YouTubeUpload.this, - mCategoriesShort, - mCategoriesLong, - vid, - new Runnable() { - public void run() { - finish(); - } - }); - infoDialog.show(); - } - }); - } - }).start(); - } - } - } - - protected String getYouTubeBaseUrl() { - if (mDevServer) { - return "http://dev.gdata.youtube.com"; - } else { - return "http://gdata.youtube.com"; - } - } - - public void getCategories() { - String uri = getYouTubeBaseUrl() + "/schemas/2007/categories.cat"; - AndroidHttpClient mClient = AndroidHttpClient.newInstance("Android-Camera/0.1"); - - try { - org.apache.http.HttpResponse r = mClient.execute(new org.apache.http.client.methods.HttpGet(uri)); - processReturnedData(r.getEntity().getContent()); - } catch (Exception ex) { - Log.e(TAG, "got exception getting categories... " + ex.toString()); - } - } - - public void processReturnedData(InputStream s) throws IOException, SAXException, XmlPullParserException { - try { - Xml.parse(s, Xml.findEncodingByName(null), new DefaultHandler() { - @Override - public void startElement(String uri, String localName, String qName, - Attributes attributes) throws SAXException { - if (ATOM_NAMESPACE.equals(uri)) { - if ("category".equals(localName)) { - String catShortName = attributes.getValue("", "term"); - String catLongName = attributes.getValue("", "label"); - mCategoriesLong .add(catLongName); - mCategoriesShort.add(catShortName); - return; - } - } - } - }); - } catch (SAXException e) { - e.printStackTrace(); - } - } -} diff --git a/tests/Android.mk b/tests/Android.mk index 168bcd9..714e078 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -6,8 +6,6 @@ LOCAL_CERTIFICATE := media LOCAL_JAVA_LIBRARIES := android.test.runner -LOCAL_STATIC_JAVA_LIBRARIES := googlelogin-client - # Include all test java files. LOCAL_SRC_FILES := $(call all-java-files-under, src) |