diff options
33 files changed, 445 insertions, 195 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index ee36428..66ef99e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -210,6 +210,14 @@ <action android:name="android.gadget.action.GADGET_CONFIGURE" /> </intent-filter> </activity> + + <!-- We also allow direct binding where the caller provides a bitmap and + gadgetId to bind. We require the permission because this changes our + internal database without user confirmation. --> + <activity android:name="PhotoGadgetBind" android:exported="true" + android:theme="@android:style/Theme.NoDisplay" + android:permission="android.permission.BIND_GADGET" /> + </application> </manifest> diff --git a/res/values-cs/arrays.xml b/res/values-cs/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-cs/arrays.xml +++ b/res/values-cs/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index d720d15..b0e06c1 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"Začít znovu"</string> <string name="gadget_title">"Rámeček fotografie"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-de/arrays.xml b/res/values-de/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-de/arrays.xml +++ b/res/values-de/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 765659f..c166287 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"Starten"</string> <string name="gadget_title">"Bildrahmen"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-es/arrays.xml b/res/values-es/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-es/arrays.xml +++ b/res/values-es/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index ae347e9..5225151 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -108,7 +108,7 @@ <string name="pref_camera_videoquality_entry_1">"Alta (para tarjeta SD)"</string> <string name="pref_camera_videoquality_dialogtitle">"Calidad de vídeo"</string> <string name="camerasettings">"Ajustes"</string> - <string name="image_gallery_NoImageView_text">"No se ha encontrado ningún medio."</string> + <string name="image_gallery_NoImageView_text">"No se ha encontrado ningún elemento."</string> <string name="pref_gallery_confirm_delete_title">"Confirmar eliminaciones"</string> <string name="pref_gallery_confirm_delete_summary">"Mostrar confirmación antes de eliminar una imagen o un vídeo"</string> <string name="details_panel_title">"Detalles"</string> @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"Volver a reproducir"</string> <string name="gadget_title">"Picture frame"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-fr/arrays.xml b/res/values-fr/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-fr/arrays.xml +++ b/res/values-fr/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index a416bb1..f0e6a1f 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -17,23 +17,23 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="all_images">"Toutes les images"</string> <string name="all_videos">"Toutes les vidéos"</string> - <string name="camera_label">"Caméra"</string> + <string name="camera_label">"Appareil photo"</string> <string name="gallery_picker_label">"Galerie"</string> - <string name="gallery_camera_bucket_name">"Photos de l\'appareil photo"</string> - <string name="gallery_camera_videos_bucket_name">"Vidéos de l\'appareil photo"</string> + <string name="gallery_camera_bucket_name">"Photos de l\'appareil"</string> + <string name="gallery_camera_videos_bucket_name">"Vidéos de la caméra"</string> <string name="switch_to_video_lable">"Passer en mode vidéo"</string> <string name="switch_to_camera_lable">"Passer en mode appareil photo"</string> <string name="crop_label">"Rogner l\'image"</string> <string name="view_label">"Afficher l\'image"</string> - <string name="preferences_label">"Paramètres de la caméra"</string> + <string name="preferences_label">"Paramètres de l\'appareil photo"</string> <string name="wait">"Veuillez patienter..."</string> - <string name="no_storage">"Veuillez insérer une carte SD avant d\'utiliser la caméra."</string> + <string name="no_storage">"Veuillez insérer une carte SD avant d\'utiliser l\'appareil photo."</string> <string name="not_enough_space">"Votre carte SD est pleine."</string> <string name="preparing_sd">"Préparation de la carte SD..."</string> <string name="wallpaper">"Configuration de l\'arrière-plan en cours. Veuillez patienter..."</string> <string name="savingImage">"Enregistrement de l\'image"</string> <string name="runningFaceDetection">"Veuillez patienter..."</string> - <string name="flip_orientation">"Changer l\'orientation"</string> + <string name="flip_orientation">"Orientation"</string> <string name="settings">"Paramètres"</string> <string name="view">"Afficher"</string> <string name="details">"Détails"</string> @@ -42,7 +42,7 @@ <string name="rotate_right">"Faire pivoter à droite"</string> <string name="slide_show">"Diaporama"</string> <string name="capture_picture">"Prendre une photo"</string> - <string name="capture_video">"Faire une vidéo"</string> + <string name="capture_video">"Prendre une vidéo"</string> <string name="crop_save_text">"Enregistrer"</string> <string name="crop_discard_text">"Annuler"</string> <string name="confirm_delete_title">"Supprimer"</string> @@ -51,7 +51,7 @@ <string name="camera_toss">"Supprimer"</string> <string name="camera_gallery">"Galerie"</string> <string name="camera_share">"Partager"</string> - <string name="camera_set">"Définir en tant que"</string> + <string name="camera_set">"Définir comme"</string> <string name="camera_play">"Lire"</string> <string name="camera_attach">"Joindre"</string> <string name="camera_cancel">"Annuler"</string> @@ -76,7 +76,7 @@ <string name="pref_gallery_sort_summary">"Sélectionner l\'ordre de tri des images et des vidéos"</string> <string name="pref_gallery_sort_dialogtitle">"Trier les images"</string> <string-array name="pref_gallery_sort_choices"> - <item>"Les plus récentes d\'abord"</item> + <item>"La plus récente en premier"</item> <item>"La plus récente en dernier"</item> </string-array> <string name="pref_gallery_slideshow_interval_title">"Intervalle du diaporama"</string> @@ -92,24 +92,24 @@ <string name="pref_gallery_slideshow_transition_dialogtitle">"Transition du diaporama"</string> <string-array name="pref_gallery_slideshow_transition_choices"> <item>"Ouverture et fermeture en fondu"</item> - <item>"Glisser vers la gauche - la droite"</item> - <item>"Glisser vers le haut - le bas"</item> + <item>"Glisser de gauche à droite"</item> + <item>"Glisser de haut en bas"</item> <item>"Sélection aléatoire"</item> </string-array> <string name="pref_gallery_slideshow_repeat_title">"Rejouer le diaporama"</string> <string name="pref_gallery_slideshow_repeat_summary">"Rejouer le diaporama plusieurs fois"</string> - <string name="pref_gallery_slideshow_shuffle_title">"Lecture aléatoire des diapositives"</string> + <string name="pref_gallery_slideshow_shuffle_title">"Lecture aléatoire"</string> <string name="pref_gallery_slideshow_shuffle_summary">"Afficher les images"</string> - <string name="pref_camera_recordlocation_title">"Enregistrer un emplacement dans les images"</string> - <string name="pref_camera_recordlocation_summary">"Enregistrer un emplacement dans les données d\'image"</string> - <string name="pref_camera_videoquality_category">"Qualité vidéo"</string> - <string name="pref_camera_videoquality_title">"Sélectionnez le niveau de qualité vidéo"</string> + <string name="pref_camera_recordlocation_title">"Enregistrer le lieu"</string> + <string name="pref_camera_recordlocation_summary">"Enregistrer la position géographique dans les données d\'image"</string> + <string name="pref_camera_videoquality_category">"Paramètres vidéo"</string> + <string name="pref_camera_videoquality_title">"Qualité vidéo"</string> <string name="pref_camera_videoquality_entry_0">"Basse (pour les MMS)"</string> <string name="pref_camera_videoquality_entry_1">"Haute (pour la carte SD)"</string> <string name="pref_camera_videoquality_dialogtitle">"Qualité vidéo"</string> <string name="camerasettings">"Paramètres"</string> - <string name="image_gallery_NoImageView_text">"Aucun fichier média trouvé."</string> - <string name="pref_gallery_confirm_delete_title">"Confirmer les suppressions"</string> + <string name="image_gallery_NoImageView_text">"Aucun fichier trouvé."</string> + <string name="pref_gallery_confirm_delete_title">"Confirmer suppressions"</string> <string name="pref_gallery_confirm_delete_summary">"Afficher une confirmation avant de supprimer une image ou une vidéo"</string> <string name="details_panel_title">"Détails"</string> <string name="details_file_size">"Taille du fichier :"</string> @@ -123,7 +123,7 @@ <string name="details_dimension_x">"%1$d x %2$d"</string> <string name="details_ms">"%1$02d:%2$02d"</string> <string name="details_hms">"%1$d:%2$02d:%3$02d"</string> - <string name="details_fps">"%1$d fps"</string> + <string name="details_fps">"%1$d ips"</string> <string name="details_kbps">"%1$d Kbits/s"</string> <string name="details_mbps">"%1$g Mbits/s"</string> <string name="details_ok">"OK"</string> @@ -131,12 +131,12 @@ <string name="video_context_menu_header">"Options vidéo"</string> <string name="multiface_crop_help">"Cliquez sur un visage pour commencer."</string> <string name="photos_gallery_title">"Galerie"</string> - <string name="pick_photos_gallery_title">"Sélectionner l\'image"</string> + <string name="pick_photos_gallery_title">"Sélectionnez une image"</string> <string name="videos_gallery_title">"Galerie"</string> <string name="pick_videos_gallery_title">"Sélectionnez une vidéo"</string> <string name="loading_progress_format_string">"<xliff:g id="COUNTER">%d</xliff:g> vignettes restantes"</string> <string name="sendImage">"Partager l\'image via"</string> - <string name="setImage">"Définir l\'image en tant que"</string> + <string name="setImage">"Définir l\'image comme"</string> <string name="sendVideo">"Partager la vidéo via"</string> <string name="movieviewlabel">"Films"</string> <string name="loading_video">"Chargement de la vidéo..."</string> @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"Démarrer"</string> <string name="gadget_title">"Cadre d\'image"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-it/arrays.xml b/res/values-it/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-it/arrays.xml +++ b/res/values-it/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 23bd952..3db66bc 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -44,7 +44,7 @@ <string name="capture_picture">"Scatta foto"</string> <string name="capture_video">"Registra video"</string> <string name="crop_save_text">"Salva"</string> - <string name="crop_discard_text">"Ignora"</string> + <string name="crop_discard_text">"Annulla"</string> <string name="confirm_delete_title">"Elimina"</string> <string name="confirm_delete_message">"La foto verrà eliminata."</string> <string name="confirm_delete_video_message">"Il video verrà eliminato."</string> @@ -89,7 +89,7 @@ </string-array> <string name="pref_gallery_slideshow_transition_title">"Transizione presentazione"</string> <string name="pref_gallery_slideshow_transition_summary">"Seleziona l\'effetto da usare per passare da una diapositiva all\'altra"</string> - <string name="pref_gallery_slideshow_transition_dialogtitle">"Transizione presentazione"</string> + <string name="pref_gallery_slideshow_transition_dialogtitle">"Transizione diapositive"</string> <string-array name="pref_gallery_slideshow_transition_choices"> <item>"Dissolvenza"</item> <item>"Da sinistra a destra"</item> @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"Ricomincia"</string> <string name="gadget_title">"Cornice immagine"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-ja/arrays.xml b/res/values-ja/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-ja/arrays.xml +++ b/res/values-ja/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 928ec24..f5e5b1b 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"最初から再生"</string> <string name="gadget_title">"写真フレーム"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-ko/arrays.xml b/res/values-ko/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-ko/arrays.xml +++ b/res/values-ko/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 4f4980a..304b544 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"시작"</string> <string name="gadget_title">"사진 프레임"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 7359acf..c268ecb 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -149,4 +149,8 @@ <string name="gadget_title">"Bilderamme"</string> <!-- no translation found for video_file_name_format (8555507706353616970) --> <skip /> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-nl/arrays.xml b/res/values-nl/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-nl/arrays.xml +++ b/res/values-nl/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index c48f738..c02a861 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"Opnieuw starten"</string> <string name="gadget_title">"Fotolijstje"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-pl/arrays.xml b/res/values-pl/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-pl/arrays.xml +++ b/res/values-pl/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 8a35c58..7023e80 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -16,13 +16,13 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="all_images">"Wszystkie zdjęcia"</string> - <string name="all_videos">"Wszystkie filmy wideo"</string> + <string name="all_videos">"Wszystkie filmy"</string> <string name="camera_label">"Aparat"</string> <string name="gallery_picker_label">"Galeria"</string> <string name="gallery_camera_bucket_name">"Zdjęcia z aparatu"</string> - <string name="gallery_camera_videos_bucket_name">"Filmy wideo z aparatu"</string> + <string name="gallery_camera_videos_bucket_name">"Filmy z aparatu"</string> <string name="switch_to_video_lable">"Przełącz na wideo"</string> - <string name="switch_to_camera_lable">"Przełącz na aparat fotograficzny"</string> + <string name="switch_to_camera_lable">"Przełącz na aparat"</string> <string name="crop_label">"Przytnij zdjęcie"</string> <string name="view_label">"Wyświetl zdjęcie"</string> <string name="preferences_label">"Ustawienia aparatu"</string> @@ -65,9 +65,9 @@ <string name="pref_gallery_category">"Ustawienia ogólne"</string> <string name="pref_slideshow_category">"Ustawienia pokazu slajdów"</string> <string name="pref_camera_general_settings_category">"Ustawienia ogólne"</string> - <string name="pref_gallery_size_title">"Rozmiar wyświetlacza"</string> + <string name="pref_gallery_size_title">"Rozmiar zdjęć i filmów"</string> <string name="pref_gallery_size_summary">"Ustaw wyświetlany rozmiar zdjęć i filmów"</string> - <string name="pref_gallery_size_dialogtitle">"Rozmiar zdjęć"</string> + <string name="pref_gallery_size_dialogtitle">"Rozmiar"</string> <string-array name="pref_gallery_size_choices"> <item>"Duży"</item> <item>"Mały"</item> @@ -76,24 +76,24 @@ <string name="pref_gallery_sort_summary">"Wybierz kolejność sortowania zdjęć i filmów"</string> <string name="pref_gallery_sort_dialogtitle">"Sortowanie zdjęć"</string> <string-array name="pref_gallery_sort_choices"> - <item>"Najpierw najnowsze"</item> + <item>"Od najnowszego"</item> <item>"Od najstarszego"</item> </string-array> - <string name="pref_gallery_slideshow_interval_title">"Pokaz slajdów — odstęp czasu"</string> + <string name="pref_gallery_slideshow_interval_title">"Pokaz slajdów – interwał"</string> <string name="pref_gallery_slideshow_interval_summary">"Wybierz, jak długo mają być wyświetlane poszczególne zdjęcia w pokazie slajdów"</string> - <string name="pref_gallery_slideshow_interval_dialogtitle">"Pokaz slajdów — odstęp czasu"</string> + <string name="pref_gallery_slideshow_interval_dialogtitle">"Pokaz slajdów – interwał"</string> <string-array name="pref_gallery_slideshow_interval_choices"> <item>"2 sekundy"</item> <item>"3 sekundy"</item> <item>"4 sekundy"</item> </string-array> - <string name="pref_gallery_slideshow_transition_title">"Pokaz slajdów — efekt przejścia"</string> + <string name="pref_gallery_slideshow_transition_title">"Pokaz slajdów – efekty"</string> <string name="pref_gallery_slideshow_transition_summary">"Wybierz efekt używany przy przejściu z jednego zdjęcia do kolejnego"</string> - <string name="pref_gallery_slideshow_transition_dialogtitle">"Pokaz slajdów — efekt przejścia"</string> + <string name="pref_gallery_slideshow_transition_dialogtitle">"Pokaz slajdów – efekty"</string> <string-array name="pref_gallery_slideshow_transition_choices"> - <item>"Wyłanianie się i zanikanie zdjęć"</item> + <item>"Pojawianie i znikanie"</item> <item>"Przesuwanie z lewa w prawo"</item> - <item>"Przesuwanie z góry na dół"</item> + <item>"Przesuwanie góra-dół"</item> <item>"Wybór losowy"</item> </string-array> <string name="pref_gallery_slideshow_repeat_title">"Powtórz pokaz slajdów"</string> @@ -108,7 +108,7 @@ <string name="pref_camera_videoquality_entry_1">"Wysoka (dla karty SD)"</string> <string name="pref_camera_videoquality_dialogtitle">"Jakość wideo"</string> <string name="camerasettings">"Ustawienia"</string> - <string name="image_gallery_NoImageView_text">"Nie znaleziono nośnika."</string> + <string name="image_gallery_NoImageView_text">"Brak plików."</string> <string name="pref_gallery_confirm_delete_title">"Potwierdzanie usuwania"</string> <string name="pref_gallery_confirm_delete_summary">"Wyświetl potwierdzenie przed usunięciem zdjęcia lub filmu"</string> <string name="details_panel_title">"Szczegóły"</string> @@ -139,7 +139,7 @@ <string name="setImage">"Ustaw zdjęcie jako"</string> <string name="sendVideo">"Prześlij film następującą drogą:"</string> <string name="movieviewlabel">"Filmy"</string> - <string name="loading_video">"Ładowanie filmu wideo..."</string> + <string name="loading_video">"Ładowanie filmu..."</string> <string name="spaceIsLow_title">"Miejsca jest mało"</string> <string name="spaceIsLow_content">"Na karcie SD brakuje miejsca. Zmień ustawienie jakości lub usuń elementy z Galerii."</string> <string name="resume_playing_title">"Wznów film"</string> @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"Rozpocznij"</string> <string name="gadget_title">"Ramka zdjęcia"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-ru/arrays.xml b/res/values-ru/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-ru/arrays.xml +++ b/res/values-ru/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index f3fb789..34cbfd3 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"Начать с начала"</string> <string name="gadget_title">"Рамка фотографии"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-zh-rCN/arrays.xml b/res/values-zh-rCN/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-zh-rCN/arrays.xml +++ b/res/values-zh-rCN/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 67104a0..f89c694 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"重新开始"</string> <string name="gadget_title">"相框"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/res/values-zh-rTW/arrays.xml b/res/values-zh-rTW/arrays.xml index dfbf090..0583b87 100644 --- a/res/values-zh-rTW/arrays.xml +++ b/res/values-zh-rTW/arrays.xml @@ -15,8 +15,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_entries:0 (4921712231611437934) --> + <!-- no translation found for pref_camera_videoquality_entries:1 (3206329580124804732) --> <string-array name="pref_camera_videoquality_entryvalues"> <item>"0"</item> <item>"1"</item> diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 4ddb816..c311294 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -148,4 +148,8 @@ <string name="resume_playing_restart">"重新開始"</string> <string name="gadget_title">"相框"</string> <string name="video_file_name_format">"\'video\'-yyyy-MM-dd-HH-mm-ss"</string> + <!-- no translation found for file_info_title (1628963357466012538) --> + <skip /> + <!-- no translation found for video_exceed_mms_limit (3835075281230780010) --> + <skip /> </resources> diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java index 04a30cf..d0eb1b3 100644 --- a/src/com/android/camera/Camera.java +++ b/src/com/android/camera/Camera.java @@ -258,7 +258,7 @@ public class Camera extends Activity implements View.OnClickListener, String action = intent.getAction(); if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { // SD card available - updateStorageHint(); + updateStorageHint(calculatePicturesRemaining()); } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED) || action.equals(Intent.ACTION_MEDIA_CHECKING)) { // SD card unavailable @@ -832,7 +832,7 @@ public class Camera extends Activity implements View.OnClickListener, loadServiceThread.join(); } catch (InterruptedException ex) { } - + ImageManager.ensureOSXCompatibleFolder(); } @@ -1355,6 +1355,40 @@ public class Camera extends Activity implements View.OnClickListener, } return mCameraDevice != null; } + + private boolean isLastPictureValid() { + boolean isValid = true; + if (mLastPictureUri == null) return false; + try { + mContentResolver.openFileDescriptor(mLastPictureUri, "r").close(); + } + catch (Exception ex) { + isValid = false; + Log.e(TAG, ex.toString()); + } + return isValid; + } + + private void updateLastImage() { + ImageManager.IImageList list = ImageManager.instance().allImages( + this, + mContentResolver, + dataLocation(), + ImageManager.INCLUDE_IMAGES, + ImageManager.SORT_ASCENDING, + ImageManager.CAMERA_IMAGE_BUCKET_ID); + int count = list.getCount(); + if (count > 0) { + ImageManager.IImage image = list.getImageAt(count-1); + mLastPictureUri = image.fullSizeImageUri(); + Log.v(TAG, "updateLastImage: count="+ count + + ", lastPictureUri="+mLastPictureUri); + setLastPictureThumb(image.miniThumbBitmap(), mLastPictureUri); + } else { + mLastPictureUri = null; + } + list.deactivate(); + } private void restartPreview() { VideoPreview surfaceView = mSurfaceView; @@ -1371,6 +1405,10 @@ public class Camera extends Activity implements View.OnClickListener, // let the user take a picture, and delete that file if needed to save the new photo. calculatePicturesRemaining(); + if (!isLastPictureValid()) { + updateLastImage(); + } + if (mShouldShowLastPictureButton) { mShouldShowLastPictureButton = false; mLastPictureButton.setVisibility(View.VISIBLE); @@ -1523,7 +1561,7 @@ public class Camera extends Activity implements View.OnClickListener, private void viewLastImage() { Uri targetUri = mLastPictureUri; - if (targetUri != null) { + if (targetUri != null && isLastPictureValid()) { targetUri = targetUri.buildUpon(). appendQueryParameter("bucketId", ImageManager.CAMERA_IMAGE_BUCKET_ID).build(); Intent intent = new Intent(Intent.ACTION_VIEW, targetUri); @@ -1538,6 +1576,8 @@ public class Camera extends Activity implements View.OnClickListener, } catch (android.content.ActivityNotFoundException ex) { // ignore. } + } else { + Log.e(TAG, "Can't view last image."); } } diff --git a/src/com/android/camera/ImageManager.java b/src/com/android/camera/ImageManager.java index cc76e83..99e5366 100755 --- a/src/com/android/camera/ImageManager.java +++ b/src/com/android/camera/ImageManager.java @@ -1835,7 +1835,7 @@ public class ImageManager { if (mimeType.equals("image/png")) return Bitmap.CompressFormat.PNG; - else if (mimeType.equals("image/png")) + else if (mimeType.equals("image/gif")) return Bitmap.CompressFormat.PNG; return Bitmap.CompressFormat.JPEG; @@ -2130,8 +2130,8 @@ 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" }; + final static private String sWhereClause = "(" + Images.Media.MIME_TYPE + " in (?, ?, ?))"; + final static private String[] sAcceptableImageTypes = new String[] { "image/jpeg", "image/png", "image/gif" }; final static private String sMiniThumbIsNull = "mini_thumb_magic isnull"; private static final String[] IMAGE_PROJECTION = new String[] { @@ -2360,10 +2360,14 @@ public class ImageManager { if (VERBOSE) { Log.v(TAG, "A: got bitmap " + b + " with sampleSize " + options.inSampleSize + " took " + (t2-t1)); } - pfd.close(); - } catch (IOException ex) { - if (VERBOSE) Log.v(TAG, "got io exception " + ex); + } catch (OutOfMemoryError ex) { + if (VERBOSE) Log.v(TAG, "got oom exception " + ex); return null; + } finally { + try { + pfd.close(); + } catch (IOException ex) { + } } return b; } @@ -3193,10 +3197,14 @@ public class ImageManager { if (VERBOSE) { Log.v(TAG, "C: got bitmap " + b + " with sampleSize " + options.inSampleSize); } - pfdInput.close(); - } catch (IOException ex) { - if (VERBOSE) Log.v(TAG, "got io exception " + ex); + } catch (OutOfMemoryError ex) { + if (VERBOSE) Log.v(TAG, "got oom exception " + ex); return null; + } finally { + try { + pfdInput.close(); + } catch (IOException ex) { + } } return b; } diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java index ffb99ef..7148cd6 100644 --- a/src/com/android/camera/MenuHelper.java +++ b/src/com/android/camera/MenuHelper.java @@ -434,9 +434,11 @@ public class MenuHelper { 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); + if (image != null) { + Intent intent = new Intent(Intent.ACTION_VIEW, + image.fullSizeImageUri()); + activity.startActivity(intent); + } }}); return true; } diff --git a/src/com/android/camera/MovieView.java b/src/com/android/camera/MovieView.java index 091cc28..bf0e6ca 100644 --- a/src/com/android/camera/MovieView.java +++ b/src/com/android/camera/MovieView.java @@ -127,37 +127,46 @@ public class MovieView extends Activity implements MediaPlayer.OnErrorListener, } } + private static boolean uriSupportsBookmarks(Uri uri) { + String scheme = uri.getScheme(); + String authority = uri.getAuthority(); + return ("content".equalsIgnoreCase(scheme) + && MediaStore.AUTHORITY.equalsIgnoreCase(authority)); + } + private Integer getBookmark() { - String scheme = mUri.getScheme(); - if ("content".equalsIgnoreCase(scheme)) { - String[] projection = new String[]{Video.VideoColumns.DURATION, - Video.VideoColumns.BOOKMARK}; - try { - Cursor cursor = getContentResolver().query(mUri, projection, null, null, null); - if (cursor != null) { - try { - if ( cursor.moveToFirst() ) { - int duration = getCursorInteger(cursor, 0); - int bookmark = getCursorInteger(cursor, 1); - final int ONE_MINUTE = 60 * 1000; - final int TWO_MINUTES = 2 * ONE_MINUTE; - final int FIVE_MINUTES = 5 * ONE_MINUTE; - if ((bookmark < TWO_MINUTES) - || (duration < FIVE_MINUTES) - || (bookmark > (duration - ONE_MINUTE))) { - return null; - } - - return new Integer(bookmark); + if (!uriSupportsBookmarks(mUri)) { + return null; + } + + String[] projection = new String[]{Video.VideoColumns.DURATION, + Video.VideoColumns.BOOKMARK}; + try { + Cursor cursor = getContentResolver().query(mUri, projection, null, null, null); + if (cursor != null) { + try { + if ( cursor.moveToFirst() ) { + int duration = getCursorInteger(cursor, 0); + int bookmark = getCursorInteger(cursor, 1); + final int ONE_MINUTE = 60 * 1000; + final int TWO_MINUTES = 2 * ONE_MINUTE; + final int FIVE_MINUTES = 5 * ONE_MINUTE; + if ((bookmark < TWO_MINUTES) + || (duration < FIVE_MINUTES) + || (bookmark > (duration - ONE_MINUTE))) { + return null; } - } finally { - cursor.close(); + + return new Integer(bookmark); } + } finally { + cursor.close(); } - } catch (SQLiteException e) { - // ignore } + } catch (SQLiteException e) { + // ignore } + return null; } @@ -173,19 +182,22 @@ public class MovieView extends Activity implements MediaPlayer.OnErrorListener, } private void setBookmark(int bookmark) { - String scheme = mUri.getScheme(); - if ("content".equalsIgnoreCase(scheme)) { - ContentValues values = new ContentValues(); - values.put(Video.VideoColumns.BOOKMARK, Integer.toString(bookmark)); - try { - getContentResolver().update(mUri, values, null, null); - } catch (SecurityException ex) { - // Ignore, can happen if we try to set the bookmark on a read-only resource - // such as a video attached to GMail. - } catch (SQLiteException e) { - // ignore. can happen if the content doesn't support a bookmark column. - } - } + if (!uriSupportsBookmarks(mUri)) { + return; + } + + ContentValues values = new ContentValues(); + values.put(Video.VideoColumns.BOOKMARK, Integer.toString(bookmark)); + try { + getContentResolver().update(mUri, values, null, null); + } catch (SecurityException ex) { + // Ignore, can happen if we try to set the bookmark on a read-only resource + // such as a video attached to GMail. + } catch (SQLiteException e) { + // ignore. can happen if the content doesn't support a bookmark column. + } catch (UnsupportedOperationException e) { + // ignore. can happen if the external volume is already detached. + } } @Override diff --git a/src/com/android/camera/PhotoGadgetBind.java b/src/com/android/camera/PhotoGadgetBind.java new file mode 100644 index 0000000..fff19de --- /dev/null +++ b/src/com/android/camera/PhotoGadgetBind.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2009 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.PhotoGadgetProvider.PhotoDatabaseHelper; + +import android.app.Activity; +import android.content.Intent; +import android.gadget.GadgetManager; +import android.graphics.Bitmap; +import android.os.Bundle; +import android.util.Log; +import android.widget.RemoteViews; + +import java.util.ArrayList; + +public class PhotoGadgetBind extends Activity { + static final String TAG = "PhotoGadgetBind"; + + static final String EXTRA_GADGET_BITMAPS = "com.android.camera.gadgetbitmaps"; + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + finish(); + + // The caller has requested that we bind a given bitmap to a specific + // gadgetId, which probably is happening during a Launcher upgrade. This + // is dangerous because the caller could set bitmaps on gadgetIds they + // don't own, so we guard this call at the manifest level by requiring + // the BIND_GADGET permission. + + final Intent intent = getIntent(); + final Bundle extras = intent.getExtras(); + + final int[] gadgetIds = extras.getIntArray(GadgetManager.EXTRA_GADGET_IDS); + final ArrayList<Bitmap> bitmaps = extras.getParcelableArrayList(EXTRA_GADGET_BITMAPS); + + if (gadgetIds == null || bitmaps == null || + gadgetIds.length != bitmaps.size()) { + Log.e(TAG, "Problem parsing photo gadget bind request"); + return; + } + + GadgetManager gadgetManager = GadgetManager.getInstance(this); + PhotoDatabaseHelper helper = new PhotoDatabaseHelper(this); + for (int i = 0; i < gadgetIds.length; i++) { + // Store the cropped photo in our database + int gadgetId = gadgetIds[i]; + helper.setPhoto(gadgetId, bitmaps.get(i)); + + // Push newly updated gadget to surface + RemoteViews views = PhotoGadgetProvider.buildUpdate(this, gadgetId, helper); + gadgetManager.updateGadget(new int[] { gadgetId }, views); + } + helper.close(); + + } +} diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java index 05e33a6..0479e8b 100644 --- a/src/com/android/camera/VideoCamera.java +++ b/src/com/android/camera/VideoCamera.java @@ -67,7 +67,7 @@ import android.widget.TextView; import android.widget.Toast; public class VideoCamera extends Activity implements View.OnClickListener, - ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback { + ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback, MediaRecorder.OnErrorListener { private static final String TAG = "videocamera"; @@ -104,7 +104,6 @@ public class VideoCamera extends Activity implements View.OnClickListener, private MediaRecorder mMediaRecorder; private boolean mMediaRecorderRecording = false; - private boolean mNeedToRegisterRecording; private long mRecordingStartTime; // The video file that the hardware camera is about to record into // (or is recording into.) @@ -195,16 +194,22 @@ public class VideoCamera extends Activity implements View.OnClickListener, @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { + if (action.equals(Intent.ACTION_MEDIA_EJECT)) { + mHasSdCard = false; + stopVideoRecording(); + initializeVideo(); + } else 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 updateStorageHint(); mHasSdCard = true; + initializeVideo(); } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) { // SD card unavailable updateStorageHint(); mHasSdCard = false; + releaseMediaRecorder(); } 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)) { @@ -408,6 +413,7 @@ public class VideoCamera extends Activity implements View.OnClickListener, // install an intent filter to receive SD card related events. IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); + intentFilter.addAction(Intent.ACTION_MEDIA_EJECT); intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); @@ -669,7 +675,6 @@ public class VideoCamera extends Activity implements View.OnClickListener, } mMediaRecorder = new MediaRecorder(); - mNeedToRegisterRecording = false; if (DEBUG_SUPPRESS_AUDIO_RECORDING) { Log.v(TAG, "DEBUG_SUPPRESS_AUDIO_RECORDING is true."); @@ -679,18 +684,21 @@ public class VideoCamera extends Activity implements View.OnClickListener, mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); - // We try Uri in intent first. If it doesn't work, use our own instead. - if (mCameraVideoFileDescriptor != null) { - mMediaRecorder.setOutputFile(mCameraVideoFileDescriptor); + if (!mHasSdCard) { + mMediaRecorder.setOutputFile("/dev/null"); } else { - createVideoPath(); - mMediaRecorder.setOutputFile(mCameraVideoFilename); + // We try Uri in intent first. If it doesn't work, use our own instead. + if (mCameraVideoFileDescriptor != null) { + mMediaRecorder.setOutputFile(mCameraVideoFileDescriptor); + } else { + createVideoPath(); + mMediaRecorder.setOutputFile(mCameraVideoFilename); + } } boolean videoQualityHigh = getBooleanPreference(CameraSettings.KEY_VIDEO_QUALITY, CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE); - if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) { int extraVideoQuality = intent.getIntExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); videoQualityHigh = (extraVideoQuality > 0); @@ -849,6 +857,15 @@ public class VideoCamera extends Activity implements View.OnClickListener, item.setIcon(android.R.drawable.ic_menu_preferences); } + // from MediaRecorder.OnErrorListener + public void onError(MediaRecorder mr, int what, int extra) { + if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { + // We may have run out of space on the sdcard. + stopVideoRecording(); + updateStorageHint(); + } + } + private void startVideoRecording() { Log.v(TAG, "startVideoRecording"); if (!mMediaRecorderRecording) { @@ -859,10 +876,10 @@ public class VideoCamera extends Activity implements View.OnClickListener, } // Check mMediaRecorder to see whether it is initialized or not. - if (mMediaRecorder == null) { - initializeVideo(); - } + if (mMediaRecorder == null) initializeVideo(); + try { + mMediaRecorder.setOnErrorListener(this); mMediaRecorder.start(); // Recording is now started } catch (RuntimeException e) { Log.e(TAG, "Could not start media recorder. ", e); @@ -932,12 +949,18 @@ public class VideoCamera extends Activity implements View.OnClickListener, private void stopVideoRecording() { Log.v(TAG, "stopVideoRecording"); + boolean needToRegisterRecording = false; if (mMediaRecorderRecording || mMediaRecorder != null) { if (mMediaRecorderRecording && mMediaRecorder != null) { - mMediaRecorder.stop(); + try { + mMediaRecorder.setOnErrorListener(null); + mMediaRecorder.stop(); + } catch (RuntimeException e) { + Log.e(TAG, "stop fail: " + e.getMessage()); + } mCurrentVideoFilename = mCameraVideoFilename; Log.v(TAG, "Setting current video filename: " + mCurrentVideoFilename); - mNeedToRegisterRecording = true; + needToRegisterRecording = true; mMediaRecorderRecording = false; } releaseMediaRecorder(); @@ -945,10 +968,8 @@ public class VideoCamera extends Activity implements View.OnClickListener, mRecordingTimeView.setVisibility(View.GONE); setScreenTimeoutLong(); } - if (mNeedToRegisterRecording) { - registerVideo(); - mNeedToRegisterRecording = false; - } + if (needToRegisterRecording && mHasSdCard) registerVideo(); + mCameraVideoFilename = null; mCameraVideoFileDescriptor = null; } diff --git a/src/com/android/camera/ViewImage.java b/src/com/android/camera/ViewImage.java index ad27ae3..07d396f 100644 --- a/src/com/android/camera/ViewImage.java +++ b/src/com/android/camera/ViewImage.java @@ -34,7 +34,7 @@ import android.provider.MediaStore; import android.util.AttributeSet; import android.util.Config; import android.util.Log; -import android.view.GestureDetector; +import android.view.GestureDetector; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; @@ -48,6 +48,7 @@ import android.view.animation.AnimationUtils; import android.widget.LinearLayout; import android.widget.Scroller; import android.widget.Toast; +import android.widget.ZoomButtonsController; import android.widget.ZoomRingController; import com.android.camera.ImageManager.IImage; @@ -127,6 +128,9 @@ public class ViewImage extends Activity implements View.OnClickListener private Runnable mDismissOnScreenControlsRunnable; private boolean mCameraReviewMode; + private int mCurrentOrientation; + + public ViewImage() { } @@ -226,38 +230,41 @@ public class ViewImage extends Activity implements View.OnClickListener private ViewImage mViewImage; private boolean mEnableTrackballScroll; private GestureDetector mGestureDetector; - - private static int TOUCH_AREA_WIDTH = 60; - // Returns current scale step (numbered from 0 to 10). + private static int TOUCH_AREA_WIDTH = 60; + + // The zoom ring setup: + // We limit the thumb on the zoom ring in the range 0 to 5/3*PI. The + // last PI/3 of the ring is left as a region that the thumb can't go in. + // The 5/3*PI range is divided into 60 steps. Each step scales the image + // by mScaleRate. We make mScaleRate^60 = maxZoom(). + + // This is the max step value we can have for the zoom ring. + private static int MAX_STEP = 60; + // This is the angle we used to separate each step. + private static float STEP_ANGLE = (5 * (float) Math.PI / 3) / MAX_STEP; + // The scale rate for each step. + private float mScaleRate; + + // Returns current scale step (numbered from 0 to MAX_STEP). private int getCurrentStep() { float s = getScale(); - float b = sScaleRate; + float b = mScaleRate; int step = (int)Math.round(Math.log(s) / Math.log(b)); - return Math.max(0, Math.min(10, step)); + return Math.max(0, Math.min(MAX_STEP, step)); } - // Returns the max scale step this image can use. - private int getMaxStep() { - float s = maxZoom(); - float b = sScaleRate; - int step = (int)Math.ceil(Math.log(s) / Math.log(b)); - return Math.max(0, Math.min(10, step)); - } - - // The setup we use here is to have 12 steps (only 0 to 10 are used), - // each separated by angle PI/6. We allow clockwise rotation (zoom-in) - // from the beginning position only. So we set counter clockwise bound - // to 0 and set clockwise bound to (2 - N/6) * PI. (clockwise angle - // is negative, and we need to mod 2*PI for the API to work.) + // Limit the thumb on the zoom ring in the range 0 to 5/3*PI. (clockwise + // angle is negative, and we need to mod 2*PI for the API to work.) private void setZoomRingBounds() { - int max_step = getMaxStep(); - float max_angle = (2 - max_step / 6F) * (float)Math.PI; - mZoomRingController.setResetThumbAutomatically(false); - mZoomRingController.setThumbClockwiseBound(max_angle); + mScaleRate = (float) Math.pow(maxZoom(), 1.0 / MAX_STEP); + float limit = (2 - 5 / 3F) * (float) Math.PI; + mZoomRingController.setThumbClockwiseBound(limit); mZoomRingController.setThumbCounterclockwiseBound(0); } + private ZoomButtonsController mZoomButtonsController; + // The zoom ring is set to visible by a double tap. private ZoomRingController mZoomRingController; private ZoomRingController.OnZoomListener mZoomListener = @@ -276,17 +283,17 @@ public class ViewImage extends Activity implements View.OnClickListener public void onEndPan() { } - + // The clockwise angle is negative, so we need to mod 2*PI private float stepToAngle(int step) { - float angle = step * (float)Math.PI / 6; - angle = (float)Math.PI * 2 - angle; + float angle = step * STEP_ANGLE; + angle = (float) Math.PI * 2 - angle; return angle; } - + private int angleToStep(double angle) { angle = Math.PI * 2 - angle; - int step = (int)Math.round(angle / (Math.PI / 6)); + int step = (int)Math.round(angle / STEP_ANGLE); return step; } @@ -320,14 +327,11 @@ public class ViewImage extends Activity implements View.OnClickListener int deltaY = getHeight() / 2 - centerY; panBy(deltaX, deltaY); - // Do zoom in/out. - while (deltaStep > 0) { - zoomIn(); - deltaStep--; - } - while (deltaStep < 0) { - zoomOut(); - deltaStep++; + // Do zoom in/out. + if (deltaStep > 0) { + zoomIn((float) Math.pow(mScaleRate, deltaStep)); + } else if (deltaStep < 0) { + zoomOut((float) Math.pow(mScaleRate, -deltaStep)); } // Reverse the first centering. @@ -356,9 +360,31 @@ public class ViewImage extends Activity implements View.OnClickListener private void setup(Context context) { mViewImage = (ViewImage) context; mZoomRingController = new ZoomRingController(context, this); + mZoomRingController.setVibration(false); + mZoomRingController.setZoomCallbackThreshold(STEP_ANGLE); + mZoomRingController.setResetThumbAutomatically(false); mZoomRingController.setCallback(mZoomListener); - mGestureDetector = new GestureDetector(new MyGestureListener()); + mGestureDetector = new GestureDetector(getContext(), new MyGestureListener()); mGestureDetector.setOnDoubleTapListener(new MyDoubleTapListener()); + mZoomButtonsController = new ZoomButtonsController(context, this); + mZoomButtonsController.setOverviewVisible(false); + mZoomButtonsController.setCallback(new ZoomButtonsController.OnZoomListener() { + + public void onCenter(int x, int y) { + mZoomListener.onCenter(x, y); + } + + public void onOverview() { + } + + public void onVisibilityChanged(boolean visible) { + mZoomListener.onVisibilityChanged(visible); + } + + public void onZoom(boolean zoomIn) { + mZoomListener.onSimpleZoom(zoomIn); + } + }); } public void setEnableTrackballScroll(boolean enable) { @@ -393,34 +419,40 @@ public class ViewImage extends Activity implements View.OnClickListener return true; } } - + private class MyDoubleTapListener implements GestureDetector.OnDoubleTapListener { // On single tap, we show the arrows. We also change to the - // prev/next image if the user taps on the left/right region. + // prev/next image if the user taps on the left/right region. public boolean onSingleTapConfirmed(MotionEvent e) { ViewImage viewImage = mViewImage; int viewWidth = getWidth(); int x = (int) e.getX(); - int y = (int) e.getY(); + int y = (int) e.getY(); if (x < TOUCH_AREA_WIDTH) { viewImage.moveNextOrPrevious(-1); } else if (x > viewWidth - TOUCH_AREA_WIDTH) { viewImage.moveNextOrPrevious(1); } - + viewImage.setMode(MODE_NORMAL); viewImage.showOnScreenControls(); return true; } - + // On double tap, we show the zoom ring control. public boolean onDoubleTapEvent(MotionEvent e) { mViewImage.setMode(MODE_NORMAL); - mZoomRingController.setVisible(true); + mZoomRingController.handleDoubleTapEvent(e); + mZoomButtonsController.handleDoubleTapEvent(e); return true; } + + public boolean onDoubleTap(MotionEvent e) { + return false; + } + } @Override @@ -524,6 +556,7 @@ public class ViewImage extends Activity implements View.OnClickListener @Override protected void onDetachedFromWindow() { mZoomRingController.setVisible(false); + mZoomButtonsController.setVisible(false); } } @@ -704,28 +737,27 @@ public class ViewImage extends Activity implements View.OnClickListener mImageMenuRunnable.gettingReadyToOpen(menu, mAllImages.getImageAt(mCurrentPosition)); } - menu.findItem(MenuHelper.MENU_IMAGE_SHARE).setEnabled(isCurrentImageShareable()); - - return true; - } - - private boolean isCurrentImageShareable() { - IImage image = mAllImages.getImageAt(mCurrentPosition); - if (image != null){ - 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()); - } return true; } @Override public void onConfigurationChanged(android.content.res.Configuration newConfig) { super.onConfigurationChanged(newConfig); - if (newConfig.orientation != getResources().getConfiguration().orientation) { + boolean changed = mCurrentOrientation != newConfig.orientation; + mCurrentOrientation = newConfig.orientation; + if (changed) { + if (mGetter != null) { + // kill off any background image fetching + mGetter.cancelCurrent(); + mGetter.stop(); + } + makeGetter(); + mFirst = true; + + // clear off the current set of images since we need to reload + // them at the right size for (ImageViewTouchBase iv: mImageViews) { - iv.setImageBitmapResetBase(null, false, true); + iv.clear(); } MenuHelper.requestOrientation(this, mPrefs); } @@ -1090,6 +1122,7 @@ public class ViewImage extends Activity implements View.OnClickListener mShowActionIcons = intent.getBooleanExtra(MediaStore.EXTRA_SHOW_ACTION_ICONS, false); mPrefs = PreferenceManager.getDefaultSharedPreferences(this); + mCurrentOrientation = getResources().getConfiguration().orientation; setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); requestWindowFeature(Window.FEATURE_NO_TITLE); @@ -1196,9 +1229,6 @@ public class ViewImage extends Activity implements View.OnClickListener } setOrientation(); - - // Show a tutorial for the new zoom interaction (the method ensure we only show it once) - ZoomRingController.showZoomTutorialOnce(this); } private void setOrientation() { @@ -1527,6 +1557,9 @@ public class ViewImage extends Activity implements View.OnClickListener setImage(mCurrentPosition); setOrientation(); + + // Show a tutorial for the new zoom interaction (the method ensure we only show it once) + ZoomRingController.showZoomTutorialOnce(this); } @Override @@ -1550,6 +1583,7 @@ public class ViewImage extends Activity implements View.OnClickListener iv.recycleBitmaps(); iv.setImageBitmap(null, true); } + ZoomRingController.finishZoomTutorial(this, false); } @Override |