+++ /dev/null
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := eng development
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_PACKAGE_NAME := SoundRecorder
-
-include $(BUILD_PACKAGE)
+++ /dev/null
-<?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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.soundrecorder">
- <uses-permission android:name="android.permission.RECORD_AUDIO" />
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
- <application android:label="@string/app_name"
- android:icon="@drawable/ic_launcher_soundrecorder">
- <activity android:name="SoundRecorder"
- android:configChanges="orientation|keyboardHidden">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.GET_CONTENT" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.OPENABLE" />
- <data android:mimeType="audio/amr" />
- <data android:mimeType="audio/3gpp" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.provider.MediaStore.RECORD_SOUND" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
- </application>
-</manifest>
+++ /dev/null
-
- Copyright (c) 2005-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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical">
-
- <ImageView
- android:src="@android:drawable/divider_horizontal_dark"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:scaleType="fitXY"/>
-
- <RelativeLayout android:id="@+id/timerViewLayout"
- android:layout_width="fill_parent"
- android:layout_height="134dip"
- android:background="@drawable/gradient_bg">
-
- <TextView android:id="@+id/timerView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="115dip"
- android:layout_alignParentRight="true"
- android:layout_marginTop="-4dip"
- android:layout_marginRight="10dip"
- style="@android:style/TextAppearance.Large" />
-
- <LinearLayout android:id="@+id/stateMessage2Layout"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:baselineAligned="false"
- android:layout_marginLeft="10dip"
- android:layout_marginTop="20dip">
-
- <ImageView android:id="@+id/stateLED"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical" />
-
- <TextView android:id="@+id/stateMessage2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/recording"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="5px"
- style="@android:style/TextAppearance.Medium"/>
-
- </LinearLayout>
-
- <TextView android:id="@+id/stateMessage1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@+id/stateMessage2Layout"
- android:layout_marginLeft="30dip"
- style="@android:style/TextAppearance.Small" />
-
- <ProgressBar android:id="@+id/stateProgressBar"
- android:orientation="horizontal"
- android:layout_width="135dip"
- android:layout_height="wrap_content"
- android:max="100"
- android:progress="0"
- android:layout_alignParentLeft="true"
- android:layout_marginLeft="10dip"
- android:layout_marginTop="20dip"
- style="?android:attr/progressBarStyleHorizontal" />
-
- </RelativeLayout>
-
- <ImageView
- android:src="@android:drawable/divider_horizontal_dark"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:scaleType="fitXY"/>
-
- <FrameLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1">
-
- <LinearLayout android:id="@+id/exitButtons"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- android:layout_gravity="center_vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true" >
-
- <Button android:id="@+id/acceptButton"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/accept"
- android:layout_weight="1"
- android:layout_marginRight="2dip"
- android:layout_marginLeft="50dip" />
-
- <Button android:id="@+id/discardButton"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/discard"
- android:layout_weight="1"
- android:layout_marginLeft="2dip"
- android:layout_marginRight="50dip" />
-
- </LinearLayout>
-
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <com.android.soundrecorder.VUMeter android:id="@+id/uvMeter"
- android:layout_width="150px"
- android:layout_height="60px"
- android:layout_centerInParent="true" />
- </RelativeLayout>
-
- </FrameLayout>
-
- <ImageView
- android:src="@android:drawable/divider_horizontal_dark"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:scaleType="fitXY"/>
-
-
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="60dip"
- android:background="@android:drawable/title_bar"
- android:gravity="center_horizontal"
- android:orientation="vertical">
-
- <LinearLayout
- android:layout_marginTop="4dip"
- android:layout_marginBottom="4dip"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" >
-
- <ImageButton android:id="@+id/recordButton"
- android:layout_height="fill_parent"
- style="@android:style/MediaButton"
- android:src="@drawable/record" />
-
- <ImageButton android:id="@+id/playButton"
- android:layout_height="fill_parent"
- style="@android:style/MediaButton"
- android:src="@drawable/play" />
-
- <ImageButton android:id="@+id/stopButton"
- android:layout_height="fill_parent"
- style="@android:style/MediaButton"
- android:src="@drawable/stop" />
-
- </LinearLayout>
-
- </LinearLayout>
-
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical">
-
- <ImageView
- android:src="@android:drawable/divider_horizontal_dark"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:scaleType="fitXY"/>
-
- <RelativeLayout android:id="@+id/timerViewLayout"
- android:layout_width="fill_parent"
- android:layout_height="242dip"
- android:background="@drawable/gradient_bg">
-
- <TextView android:id="@+id/timerView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="112dip"
- android:layout_centerInParent="true"
- style="@android:style/TextAppearance.Large" />
-
- <LinearLayout android:id="@+id/stateMessage2Layout"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_above="@+id/timerView"
- android:layout_centerHorizontal="true"
- android:baselineAligned="false">
-
- <ImageView android:id="@+id/stateLED"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical" />
-
- <TextView android:id="@+id/stateMessage2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/recording"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="5px"
- style="@android:style/TextAppearance.Medium"/>
-
- </LinearLayout>
-
- <TextView android:id="@+id/stateMessage1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@+id/stateMessage2Layout"
- android:layout_centerHorizontal="true"
- style="@android:style/TextAppearance.Small" />
-
- <ProgressBar android:id="@+id/stateProgressBar"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_above="@+id/timerView"
- android:max="100"
- android:progress="0"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- style="?android:attr/progressBarStyleHorizontal" />
-
- </RelativeLayout>
-
- <ImageView
- android:src="@android:drawable/divider_horizontal_dark"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:scaleType="fitXY"/>
-
- <FrameLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1">
-
- <LinearLayout android:id="@+id/exitButtons"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- android:layout_gravity="center_vertical"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true" >
-
- <Button android:id="@+id/acceptButton"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/accept"
- android:layout_weight="1"
- android:layout_marginLeft="15dip"
- android:layout_marginRight="2dip" />
-
- <Button android:id="@+id/discardButton"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/discard"
- android:layout_weight="1"
- android:layout_marginLeft="2dip"
- android:layout_marginRight="15dip" />
-
- </LinearLayout>
-
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <com.android.soundrecorder.VUMeter android:id="@+id/uvMeter"
- android:layout_width="200px"
- android:layout_height="80px"
- android:layout_centerInParent="true" />
- </RelativeLayout>
-
- </FrameLayout>
-
- <ImageView
- android:src="@android:drawable/divider_horizontal_dark"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:scaleType="fitXY"/>
-
-
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="60dip"
- android:background="@android:drawable/title_bar"
- android:gravity="center_horizontal"
- android:orientation="vertical">
-
- <LinearLayout
- android:layout_marginTop="4dip"
- android:layout_marginBottom="4dip"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" >
-
- <ImageButton android:id="@+id/recordButton"
- android:layout_height="fill_parent"
- style="@android:style/MediaButton"
- android:src="@drawable/record" />
-
- <ImageButton android:id="@+id/playButton"
- android:layout_height="fill_parent"
- style="@android:style/MediaButton"
- android:src="@drawable/play" />
-
- <ImageButton android:id="@+id/stopButton"
- android:layout_height="fill_parent"
- style="@android:style/MediaButton"
- android:src="@drawable/stop" />
-
- </LinearLayout>
-
- </LinearLayout>
-
-</LinearLayout>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"Záznam zvuku"</string>
- <string name="record_your_message">"Zaznamenejte svou zprávu"</string>
- <string name="message_recorded">"Zpráva byla zaznamenána"</string>
- <string name="review_message">"Zkontrolovat zprávu"</string>
- <string name="recording">"Zaznamenává se"</string>
- <string name="recording_stopped">"Záznam byl zastaven"</string>
- <string name="storage_is_full">"Úložiště je plné"</string>
- <string name="max_length_reached">"Byla dosažena maximální povolená délka"</string>
- <string name="insert_sd_card">"Vložte prosím kartu SD"</string>
- <string name="min_available">"K dispozici: <xliff:g id="MINUTES">%d</xliff:g> min"</string>
- <string name="sec_available">"K dispozici <xliff:g id="SECONDS">%d</xliff:g> s"</string>
- <string name="accept">"Použít tento záznam"</string>
- <string name="discard">"Zahodit"</string>
- <string name="button_ok">"OK"</string>
- <string name="press_record">"Stiskněte tlačítko Záznam"</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"Vaše záznamy"</string>
- <string name="audio_db_album_name">"Zvukové záznamy"</string>
- <string name="audio_db_playlist_name">"Mé záznamy"</string>
- <string name="error_sdcard_access">"Nelze získat přístup ke kartě SD"</string>
- <string name="error_app_internal">"Vnitřní chyba aplikace"</string>
- <string name="error_mediadb_new_record">"Zaznamenaný zvuk nelze uložit"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"Soundrekorder"</string>
- <string name="record_your_message">"Ihre Nachricht aufnehmen"</string>
- <string name="message_recorded">"Nachricht aufgezeichnet"</string>
- <string name="review_message">"Nachricht erneut anhören"</string>
- <string name="recording">"Aufnahme"</string>
- <string name="recording_stopped">"Aufnahme beendet"</string>
- <string name="storage_is_full">"Speicher ist voll"</string>
- <string name="max_length_reached">"Maximale Länge erreicht"</string>
- <string name="insert_sd_card">"SD-Karte einlegen"</string>
- <string name="min_available">"<xliff:g id="MINUTES">%d</xliff:g> Min. verfügbar"</string>
- <string name="sec_available">"<xliff:g id="SECONDS">%d</xliff:g> Sek. verfügbar"</string>
- <string name="accept">"Diese Aufnahme verwenden"</string>
- <string name="discard">"Verwerfen"</string>
- <string name="button_ok">"OK"</string>
- <string name="press_record">"Aufnahmetaste drücken"</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"Ihre Aufnahmen"</string>
- <string name="audio_db_album_name">"Audioaufnahmen"</string>
- <string name="audio_db_playlist_name">"Meine Aufnahmen"</string>
- <string name="error_sdcard_access">"Kein Zugriff auf SD-Karte möglich."</string>
- <string name="error_app_internal">"Interner Anwendungsfehler"</string>
- <string name="error_mediadb_new_record">"Aufgenommenen Audioinhalt speichern"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"Grabadora de sonidos"</string>
- <string name="record_your_message">"Grabar mensaje"</string>
- <string name="message_recorded">"Mensaje grabado"</string>
- <string name="review_message">"Revisar mensaje"</string>
- <string name="recording">"Grabando..."</string>
- <string name="recording_stopped">"Grabación detenida"</string>
- <string name="storage_is_full">"Espacio insuficiente"</string>
- <string name="max_length_reached">"Duración máxima alcanzada"</string>
- <string name="insert_sd_card">"Inserta una tarjeta SD."</string>
- <string name="min_available">"<xliff:g id="MINUTES">%d</xliff:g> minutos disponibles"</string>
- <string name="sec_available">"<xliff:g id="SECONDS">%d</xliff:g> segundos disponibles"</string>
- <string name="accept">"Utilizar esta grabación"</string>
- <string name="discard">"Descartar"</string>
- <string name="button_ok">"Aceptar"</string>
- <string name="press_record">"Pulsa el botón de grabación."</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"Tus grabaciones"</string>
- <string name="audio_db_album_name">"Grabaciones de audio"</string>
- <string name="audio_db_playlist_name">"Mis grabaciones"</string>
- <string name="error_sdcard_access">"No se puede acceder a la tarjeta SD."</string>
- <string name="error_app_internal">"Error interno de la aplicación"</string>
- <string name="error_mediadb_new_record">"No se puede guardar el audio grabado."</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"Magnétophone"</string>
- <string name="record_your_message">"Enregistrez votre message"</string>
- <string name="message_recorded">"Message enregistré"</string>
- <string name="review_message">"Revoir le message"</string>
- <string name="recording">"Enregistrement audio"</string>
- <string name="recording_stopped">"Enregistrement audio interrompu"</string>
- <string name="storage_is_full">"La mémoire est pleine"</string>
- <string name="max_length_reached">"Taille maximale atteinte"</string>
- <string name="insert_sd_card">"Insérez une carte SD"</string>
- <string name="min_available">"<xliff:g id="MINUTES">%d</xliff:g> mn disponible(s)"</string>
- <string name="sec_available">"<xliff:g id="SECONDS">%d</xliff:g> s disponible(s)"</string>
- <string name="accept">"Utiliser cet enregistrement audio"</string>
- <string name="discard">"Supprimer"</string>
- <string name="button_ok">"OK"</string>
- <string name="press_record">"Appuyez sur \"Enregistrer\""</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"Vos enregistrements audio"</string>
- <string name="audio_db_album_name">"Enregistrements audio"</string>
- <string name="audio_db_playlist_name">"Mes enregistrements audio"</string>
- <string name="error_sdcard_access">"Impossible d\'accéder à la carte SD"</string>
- <string name="error_app_internal">"Erreur d\'application interne"</string>
- <string name="error_mediadb_new_record">"Impossible de sauvegarder la piste audio enregistrée"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"Registratore suoni"</string>
- <string name="record_your_message">"Registra il messaggio"</string>
- <string name="message_recorded">"Messaggio registrato"</string>
- <string name="review_message">"Controlla messaggio"</string>
- <string name="recording">"Registrazione in corso"</string>
- <string name="recording_stopped">"Registrazione interrotta"</string>
- <string name="storage_is_full">"La memoria è piena"</string>
- <string name="max_length_reached">"Lunghezza massima raggiunta"</string>
- <string name="insert_sd_card">"Inserisci una scheda SD"</string>
- <string name="min_available">"<xliff:g id="MINUTES">%d</xliff:g> min a disposizione"</string>
- <string name="sec_available">"<xliff:g id="SECONDS">%d</xliff:g> a disposizione"</string>
- <string name="accept">"Usa questa registrazione"</string>
- <string name="discard">"Ignora"</string>
- <string name="button_ok">"OK"</string>
- <string name="press_record">"Premi Registra"</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"Registrazioni"</string>
- <string name="audio_db_album_name">"Registrazioni audio"</string>
- <string name="audio_db_playlist_name">"Registrazioni personali"</string>
- <string name="error_sdcard_access">"Impossibile accedere alla scheda SD"</string>
- <string name="error_app_internal">"Errore interno dell\'applicazione"</string>
- <string name="error_mediadb_new_record">"Impossibile salvare l\'audio registrato"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"音声レコーダー"</string>
- <string name="record_your_message">"メッセージの録音"</string>
- <string name="message_recorded">"メッセージを録音しました"</string>
- <string name="review_message">"メッセージの確認"</string>
- <string name="recording">"録音中"</string>
- <string name="recording_stopped">"録音を停止しました"</string>
- <string name="storage_is_full">"メモリがいっぱいです"</string>
- <string name="max_length_reached">"最大サイズに達しました"</string>
- <string name="insert_sd_card">"SDカードを挿入してください"</string>
- <string name="min_available">"<xliff:g id="MINUTES">%d</xliff:g>分録音可能"</string>
- <string name="sec_available">"<xliff:g id="SECONDS">%d</xliff:g>秒録音可能"</string>
- <string name="accept">"この録音を使用"</string>
- <string name="discard">"破棄"</string>
- <string name="button_ok">"OK"</string>
- <string name="press_record">"録音ボタンを押して録音"</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"録音リスト"</string>
- <string name="audio_db_album_name">"録音"</string>
- <string name="audio_db_playlist_name">"マイ録音"</string>
- <string name="error_sdcard_access">"SDカードにアクセスできません"</string>
- <string name="error_app_internal">"アプリケーションの内部エラー"</string>
- <string name="error_mediadb_new_record">"録音を保存できません"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"Sound Recorder"</string>
- <string name="record_your_message">"메시지 녹음"</string>
- <string name="message_recorded">"메시지 녹음됨"</string>
- <string name="review_message">"메시지 재생"</string>
- <string name="recording">"녹음 중"</string>
- <string name="recording_stopped">"녹음이 중지되었습니다."</string>
- <string name="storage_is_full">"저장공간이 꽉 찼습니다."</string>
- <string name="max_length_reached">"최대 길이에 도달했습니다."</string>
- <string name="insert_sd_card">"SD 카드를 삽입하세요."</string>
- <string name="min_available">"<xliff:g id="MINUTES">%d</xliff:g>분 녹음 가능"</string>
- <string name="sec_available">"<xliff:g id="SECONDS">%d</xliff:g>초 녹음 가능"</string>
- <string name="accept">"이 녹음 메시지 사용"</string>
- <string name="discard">"삭제"</string>
- <string name="button_ok">"확인"</string>
- <string name="press_record">"녹음 누르기"</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"녹음"</string>
- <string name="audio_db_album_name">"오디오 녹음"</string>
- <string name="audio_db_playlist_name">"내 녹음"</string>
- <string name="error_sdcard_access">"SD 카드에 액세스할 수 없습니다."</string>
- <string name="error_app_internal">"내부 응용프로그램 오류"</string>
- <string name="error_mediadb_new_record">"녹음된 오디오를 저장할 수 없습니다."</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"Lydopptak"</string>
- <string name="record_your_message">"Ta opp en melding"</string>
- <string name="message_recorded">"Melding tatt opp"</string>
- <string name="review_message">"Spill tilbake melding"</string>
- <string name="recording">"Tar opp"</string>
- <string name="recording_stopped">"Opptak avbrutt"</string>
- <string name="storage_is_full">"Tomt for plass"</string>
- <string name="max_length_reached">"Makslengde nådd"</string>
- <string name="insert_sd_card">"Sett inn et minnekort"</string>
- <string name="min_available">"<xliff:g id="MINUTES">%d</xliff:g> min tilgjengelig"</string>
- <string name="sec_available">"<xliff:g id="SECONDS">%d</xliff:g>s tilgjengelig"</string>
- <string name="accept">"Bruk dette opptaket"</string>
- <string name="discard">"Forkast"</string>
- <string name="button_ok">"OK"</string>
- <string name="press_record">"Trykk «ta opp»"</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"Dine opptak"</string>
- <string name="audio_db_album_name">"Lydopptak"</string>
- <string name="audio_db_playlist_name">"Mine opptak"</string>
- <string name="error_sdcard_access">"Kunne ikke aksessere minnekort"</string>
- <string name="error_app_internal">"Intern programfeil"</string>
- <string name="error_mediadb_new_record">"Kunne ikke lagre lyd som ble tatt opp"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"Geluidsrecorder"</string>
- <string name="record_your_message">"Uw bericht opnemen"</string>
- <string name="message_recorded">"Bericht opgenomen"</string>
- <string name="review_message">"Bericht controleren"</string>
- <string name="recording">"Opnemen"</string>
- <string name="recording_stopped">"Opname gestopt"</string>
- <string name="storage_is_full">"Opslagruimte is vol"</string>
- <string name="max_length_reached">"Maximumlengte is bereikt"</string>
- <string name="insert_sd_card">"Plaats een SD-kaart"</string>
- <string name="min_available">"<xliff:g id="MINUTES">%d</xliff:g> min beschikbaar"</string>
- <string name="sec_available">"<xliff:g id="SECONDS">%d</xliff:g>s beschikbaar"</string>
- <string name="accept">"Deze opname gebruiken"</string>
- <string name="discard">"Weggooien"</string>
- <string name="button_ok">"OK"</string>
- <string name="press_record">"Druk op \'Opnemen\'"</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"Uw opnamen"</string>
- <string name="audio_db_album_name">"Audio-opnamen"</string>
- <string name="audio_db_playlist_name">"Mijn opnamen"</string>
- <string name="error_sdcard_access">"Geen toegang tot SD-kaart"</string>
- <string name="error_app_internal">"Interne toepassingsfout"</string>
- <string name="error_mediadb_new_record">"Kan opgenomen audio niet opslaan"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"Rejestrator dźwięku"</string>
- <string name="record_your_message">"Nagraj wiadomość"</string>
- <string name="message_recorded">"Wiadomość została nagrana"</string>
- <string name="review_message">"Przejrzyj wiadomość"</string>
- <string name="recording">"Nagrywanie"</string>
- <string name="recording_stopped">"Nagrywanie zostało zatrzymane"</string>
- <string name="storage_is_full">"Pamięć jest pełna"</string>
- <string name="max_length_reached">"Osiągnięto maksymalną długość"</string>
- <string name="insert_sd_card">"Włóż kartę SD"</string>
- <string name="min_available">"Zostało <xliff:g id="MINUTES">%d</xliff:g> minut"</string>
- <string name="sec_available">"Zostało <xliff:g id="SECONDS">%d</xliff:g> sekund"</string>
- <string name="accept">"Użyj tego nagrania"</string>
- <string name="discard">"Odrzuć"</string>
- <string name="button_ok">"OK"</string>
- <string name="press_record">"Naciśnij przycisk nagrywania"</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"Twoje nagrania"</string>
- <string name="audio_db_album_name">"Nagrania audio"</string>
- <string name="audio_db_playlist_name">"Moje nagrania"</string>
- <string name="error_sdcard_access">"Nie można uzyskać dostępu do karty SD"</string>
- <string name="error_app_internal">"Błąd wewnętrzny programu"</string>
- <string name="error_mediadb_new_record">"Nie można zapisać nagrania"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"Запись звука"</string>
- <string name="record_your_message">"Запись сообщения"</string>
- <string name="message_recorded">"Сообщение записано"</string>
- <string name="review_message">"Проверка сообщения"</string>
- <string name="recording">"Запись"</string>
- <string name="recording_stopped">"Запись остановлена"</string>
- <string name="storage_is_full">"Память полна"</string>
- <string name="max_length_reached">"Достигнут максимальный размер"</string>
- <string name="insert_sd_card">"Вставьте карту SD"</string>
- <string name="min_available">"осталось <xliff:g id="MINUTES">%d</xliff:g> мин."</string>
- <string name="sec_available">"осталось <xliff:g id="SECONDS">%d</xliff:g> сек."</string>
- <string name="accept">"Использовать эту запись"</string>
- <string name="discard">"Закрыть"</string>
- <string name="button_ok">"ОК"</string>
- <string name="press_record">"Нажмите \"Запись\""</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"Ваши записи"</string>
- <string name="audio_db_album_name">"Звуковые записи"</string>
- <string name="audio_db_playlist_name">"Мои записи"</string>
- <string name="error_sdcard_access">"Нет доступа к карте SD"</string>
- <string name="error_app_internal">"Внутренняя ошибка приложения"</string>
- <string name="error_mediadb_new_record">"Не удается сохранить записанный звук"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"录音机"</string>
- <string name="record_your_message">"为您的消息录音"</string>
- <string name="message_recorded">"消息已记录"</string>
- <string name="review_message">"查看消息"</string>
- <string name="recording">"正在录音"</string>
- <string name="recording_stopped">"录音已停止"</string>
- <string name="storage_is_full">"存储空间已满"</string>
- <string name="max_length_reached">"已达到长度上限"</string>
- <string name="insert_sd_card">"请插入 SD 卡"</string>
- <string name="min_available">"还剩 <xliff:g id="MINUTES">%d</xliff:g> 分钟"</string>
- <string name="sec_available">"还剩 <xliff:g id="SECONDS">%d</xliff:g> 秒"</string>
- <string name="accept">"使用此录音"</string>
- <string name="discard">"放弃"</string>
- <string name="button_ok">"确定"</string>
- <string name="press_record">"按录音键"</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"您的录音"</string>
- <string name="audio_db_album_name">"录音"</string>
- <string name="audio_db_playlist_name">"我的录音"</string>
- <string name="error_sdcard_access">"无法访问 SD 卡"</string>
- <string name="error_app_internal">"内部应用程序错误"</string>
- <string name="error_mediadb_new_record">"无法保存录制的音频"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name">"錄音程式"</string>
- <string name="record_your_message">"錄製簡訊"</string>
- <string name="message_recorded">"已錄製簡訊"</string>
- <string name="review_message">"檢視簡訊"</string>
- <string name="recording">"錄音中"</string>
- <string name="recording_stopped">"停止錄音"</string>
- <string name="storage_is_full">"儲存空間已滿"</string>
- <string name="max_length_reached">"已達長度上限"</string>
- <string name="insert_sd_card">"請插入 SD 卡"</string>
- <string name="min_available">"還可錄製 <xliff:g id="MINUTES">%d</xliff:g> 分鐘"</string>
- <string name="sec_available">"還可錄製 <xliff:g id="SECONDS">%d</xliff:g> 秒"</string>
- <string name="accept">"使用此錄音"</string>
- <string name="discard">"放棄"</string>
- <string name="button_ok">"確定"</string>
- <string name="press_record">"按下 [錄音]"</string>
- <!-- no translation found for audio_db_title_format (7912182366970749312) -->
- <skip />
- <string name="audio_db_artist_name">"您的錄音"</string>
- <string name="audio_db_album_name">"錄音"</string>
- <string name="audio_db_playlist_name">"我的錄音"</string>
- <string name="error_sdcard_access">"無法存取 SD 卡"</string>
- <string name="error_app_internal">"內部應用程式錯誤"</string>
- <string name="error_mediadb_new_record">"無法儲存錄製的音訊"</string>
-</resources>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- application name and title of error dialogs-->
- <string name="app_name">Sound Recorder</string>
-
- <!-- Screen title before and during recording -->
- <string name="record_your_message">Record your message</string>
- <!-- Screen title after recording -->
- <string name="message_recorded">Message recorded</string>
- <!-- Screen title while playing back a recording -->
- <string name="review_message">Review message</string>
- <!-- Label shown during recording -->
- <string name="recording">Recording</string>
- <!-- Label shown when the recording is stopped for a reason other than the user stopping it (e.g. the sd card was removed) -->
- <string name="recording_stopped">Recording stopped</string>
- <!-- label shown when there is not enough space to record something -->
- <string name="storage_is_full">Storage is full</string>
- <!-- label shown when the recording has reached maximum allowed file size -->
- <string name="max_length_reached">Maximum length reached</string>
- <!-- label shown when there is no sd card available to record to -->
- <string name="insert_sd_card">Please insert an SD card</string>
- <!-- label shown when there is more than 1 minute but less than 9 minutes of space left to record -->
- <string name="min_available"><xliff:g id="minutes">%d</xliff:g> min available</string>
- <!-- label shown when there is less than 1 minute of space left to record -->
- <string name="sec_available"><xliff:g id="seconds">%d</xliff:g>s available</string>
-
- <!-- button to accept the current recording and return it to the caller -->
- <string name="accept">Use this recording</string>
- <!-- button to discard the current recording and return to the caller -->
- <string name="discard">Discard</string>
- <!-- acknowlegement button in a number of dialogs -->
- <string name="button_ok">OK</string>
- <!-- Do not translate. Format of the timer that shows how much has been recorded so far -->
- <string name="timer_format"><xliff:g id="format">%02d:%02d</xliff:g></string>
- <!-- label shown before the user has recorded anything -->
- <string name="press_record">Press record</string>
-
- <!-- the name under which recordings will be visible in the media database is formatted like this -->
- <string name="audio_db_title_format"><xliff:g id="format">yyyy-MM-dd HH:mm:ss</xliff:g></string>
- <!-- all recordings will show up in the media database with this 'artist' name -->
- <string name="audio_db_artist_name">Your recordings</string>
- <!-- all recordings will show up in the media database with this 'album' name -->
- <string name="audio_db_album_name">Audio recordings</string>
- <!-- all recordings will show up in the media database in a playlist with this name -->
- <string name="audio_db_playlist_name">My recordings</string>
-
- <!-- shown as the message in a dialog when an error occured because of an error accessing the sd card -->
- <string name="error_sdcard_access">Unable to access SD card</string>
- <!-- shown as the message in a dialog when the app encountered an unspecified internal error -->
- <string name="error_app_internal">Internal application error</string>
- <!-- shown as the message in a dialog when the recording could not be added to the media database -->
- <string name="error_mediadb_new_record">Unable to save recorded audio</string>
-</resources>
+++ /dev/null
-package com.android.soundrecorder;
-
-import java.io.File;
-import java.io.IOException;
-
-import android.media.MediaPlayer;
-import android.media.MediaRecorder;
-import android.media.MediaPlayer.OnCompletionListener;
-import android.media.MediaPlayer.OnErrorListener;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.Log;
-
-public class Recorder implements OnCompletionListener, OnErrorListener {
- static final String SAMPLE_PREFIX = "recording";
- static final String SAMPLE_PATH_KEY = "sample_path";
- static final String SAMPLE_LENGTH_KEY = "sample_length";
-
- public static final int IDLE_STATE = 0;
- public static final int RECORDING_STATE = 1;
- public static final int PLAYING_STATE = 2;
-
- int mState = IDLE_STATE;
-
- public static final int NO_ERROR = 0;
- public static final int SDCARD_ACCESS_ERROR = 1;
- public static final int INTERNAL_ERROR = 2;
-
- public interface OnStateChangedListener {
- public void onStateChanged(int state);
- public void onError(int error);
- }
- OnStateChangedListener mOnStateChangedListener = null;
-
- long mSampleStart = 0; // time at which latest record or play operation started
- int mSampleLength = 0; // length of current sample
- File mSampleFile = null;
-
- MediaRecorder mRecorder = null;
- MediaPlayer mPlayer = null;
-
- public Recorder() {
- }
-
- public void saveState(Bundle recorderState) {
- recorderState.putString(SAMPLE_PATH_KEY, mSampleFile.getAbsolutePath());
- recorderState.putInt(SAMPLE_LENGTH_KEY, mSampleLength);
- }
-
- public int getMaxAmplitude() {
- if (mState != RECORDING_STATE)
- return 0;
- return mRecorder.getMaxAmplitude();
- }
-
- public void restoreState(Bundle recorderState) {
- String samplePath = recorderState.getString(SAMPLE_PATH_KEY);
- if (samplePath == null)
- return;
- int sampleLength = recorderState.getInt(SAMPLE_LENGTH_KEY, -1);
- if (sampleLength == -1)
- return;
-
- File file = new File(samplePath);
- if (!file.exists())
- return;
- if (mSampleFile != null
- && mSampleFile.getAbsolutePath().compareTo(file.getAbsolutePath()) == 0)
- return;
-
- delete();
- mSampleFile = file;
- mSampleLength = sampleLength;
-
- signalStateChanged(IDLE_STATE);
- }
-
- public void setOnStateChangedListener(OnStateChangedListener listener) {
- mOnStateChangedListener = listener;
- }
-
- public int state() {
- return mState;
- }
-
- public int progress() {
- if (mState == RECORDING_STATE || mState == PLAYING_STATE)
- return (int) ((System.currentTimeMillis() - mSampleStart)/1000);
- return 0;
- }
-
- public int sampleLength() {
- return mSampleLength;
- }
-
- public File sampleFile() {
- return mSampleFile;
- }
-
- /**
- * Resets the recorder state. If a sample was recorded, the file is deleted.
- */
- public void delete() {
- stop();
-
- if (mSampleFile != null)
- mSampleFile.delete();
-
- mSampleFile = null;
- mSampleLength = 0;
-
- signalStateChanged(IDLE_STATE);
- }
-
- /**
- * Resets the recorder state. If a sample was recorded, the file is left on disk and will
- * be reused for a new recording.
- */
- public void clear() {
- stop();
-
- mSampleLength = 0;
-
- signalStateChanged(IDLE_STATE);
- }
-
- public void startRecording(int outputfileformat, String extension) {
- stop();
-
- if (mSampleFile == null) {
- File sampleDir = Environment.getExternalStorageDirectory();
- if (!sampleDir.canWrite()) // Workaround for broken sdcard support on the device.
- sampleDir = new File("/sdcard/sdcard");
-
- try {
- mSampleFile = File.createTempFile(SAMPLE_PREFIX, extension, sampleDir);
- } catch (IOException e) {
- setError(SDCARD_ACCESS_ERROR);
- return;
- }
- }
-
- mRecorder = new MediaRecorder();
- mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- mRecorder.setOutputFormat(outputfileformat);
- mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- mRecorder.setOutputFile(mSampleFile.getAbsolutePath());
-
- // Handle IOException
- try {
- mRecorder.prepare();
- } catch(IOException exception) {
- setError(INTERNAL_ERROR);
- mRecorder.reset();
- mRecorder.release();
- mRecorder = null;
- return;
- }
- mRecorder.start();
-
- mSampleStart = System.currentTimeMillis();
- setState(RECORDING_STATE);
- }
-
- public void stopRecording() {
- if (mRecorder == null)
- return;
-
- mRecorder.stop();
- mRecorder.release();
- mRecorder = null;
-
- mSampleLength = (int)( (System.currentTimeMillis() - mSampleStart)/1000 );
- setState(IDLE_STATE);
- }
-
- public void startPlayback() {
- stop();
-
- mPlayer = new MediaPlayer();
- try {
- mPlayer.setDataSource(mSampleFile.getAbsolutePath());
- mPlayer.setOnCompletionListener(this);
- mPlayer.setOnErrorListener(this);
- mPlayer.prepare();
- mPlayer.start();
- } catch (IllegalArgumentException e) {
- setError(INTERNAL_ERROR);
- mPlayer = null;
- return;
- } catch (IOException e) {
- setError(SDCARD_ACCESS_ERROR);
- mPlayer = null;
- return;
- }
-
- mSampleStart = System.currentTimeMillis();
- setState(PLAYING_STATE);
- }
-
- public void stopPlayback() {
- if (mPlayer == null) // we were not in playback
- return;
-
- mPlayer.stop();
- mPlayer.release();
- mPlayer = null;
- setState(IDLE_STATE);
- }
-
- public void stop() {
- stopRecording();
- stopPlayback();
- }
-
- public boolean onError(MediaPlayer mp, int what, int extra) {
- stop();
- setError(SDCARD_ACCESS_ERROR);
- return true;
- }
-
- public void onCompletion(MediaPlayer mp) {
- stop();
- }
-
- private void setState(int state) {
- if (state == mState)
- return;
-
- mState = state;
- signalStateChanged(mState);
- }
-
- private void signalStateChanged(int state) {
- if (mOnStateChangedListener != null)
- mOnStateChangedListener.onStateChanged(state);
- }
-
- private void setError(int error) {
- if (mOnStateChangedListener != null)
- mOnStateChangedListener.onError(error);
- }
-}
+++ /dev/null
-package com.android.soundrecorder;
-
-import java.io.File;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.content.Context;
-import android.content.IntentFilter;
-import android.content.BroadcastReceiver;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.media.MediaRecorder;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.PowerManager;
-import android.os.StatFs;
-import android.os.PowerManager.WakeLock;
-import android.provider.MediaStore;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.Button;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-/**
- * Calculates remaining recording time based on available disk space and
- * optionally a maximum recording file size.
- *
- * The reason why this is not trivial is that the file grows in blocks
- * every few seconds or so, while we want a smooth countdown.
- */
-
-class RemainingTimeCalculator {
- public static final int UNKNOWN_LIMIT = 0;
- public static final int FILE_SIZE_LIMIT = 1;
- public static final int DISK_SPACE_LIMIT = 2;
-
- // which of the two limits we will hit (or have fit) first
- private int mCurrentLowerLimit = UNKNOWN_LIMIT;
-
- private File mSDCardDirectory;
-
- // State for tracking file size of recording.
- private File mRecordingFile;
- private long mMaxBytes;
-
- // Rate at which the file grows
- private int mBytesPerSecond;
-
- // time at which number of free blocks last changed
- private long mBlocksChangedTime;
- // number of available blocks at that time
- private long mLastBlocks;
-
- // time at which the size of the file has last changed
- private long mFileSizeChangedTime;
- // size of the file at that time
- private long mLastFileSize;
-
- public RemainingTimeCalculator() {
- mSDCardDirectory = Environment.getExternalStorageDirectory();
- }
-
- /**
- * If called, the calculator will return the minimum of two estimates:
- * how long until we run out of disk space and how long until the file
- * reaches the specified size.
- *
- * @param file the file to watch
- * @param maxBytes the limit
- */
-
- public void setFileSizeLimit(File file, long maxBytes) {
- mRecordingFile = file;
- mMaxBytes = maxBytes;
- }
-
- /**
- * Resets the interpolation.
- */
- public void reset() {
- mCurrentLowerLimit = UNKNOWN_LIMIT;
- mBlocksChangedTime = -1;
- mFileSizeChangedTime = -1;
- }
-
- /**
- * Returns how long (in seconds) we can continue recording.
- */
- public long timeRemaining() {
- // Calculate how long we can record based on free disk space
-
- StatFs fs = new StatFs(mSDCardDirectory.getAbsolutePath());
- long blocks = fs.getAvailableBlocks();
- long blockSize = fs.getBlockSize();
- long now = System.currentTimeMillis();
-
- if (mBlocksChangedTime == -1 || blocks != mLastBlocks) {
- mBlocksChangedTime = now;
- mLastBlocks = blocks;
- }
-
- /* The calculation below always leaves one free block, since free space
- in the block we're currently writing to is not added. This
- last block might get nibbled when we close and flush the file, but
- we won't run out of disk. */
-
- // at mBlocksChangedTime we had this much time
- long result = mLastBlocks*blockSize/mBytesPerSecond;
- // so now we have this much time
- result -= (now - mBlocksChangedTime)/1000;
-
- if (mRecordingFile == null) {
- mCurrentLowerLimit = DISK_SPACE_LIMIT;
- return result;
- }
-
- // If we have a recording file set, we calculate a second estimate
- // based on how long it will take us to reach mMaxBytes.
-
- mRecordingFile = new File(mRecordingFile.getAbsolutePath());
- long fileSize = mRecordingFile.length();
- if (mFileSizeChangedTime == -1 || fileSize != mLastFileSize) {
- mFileSizeChangedTime = now;
- mLastFileSize = fileSize;
- }
-
- long result2 = (mMaxBytes - fileSize)/mBytesPerSecond;
- result2 -= (now - mFileSizeChangedTime)/1000;
- result2 -= 1; // just for safety
-
- mCurrentLowerLimit = result < result2
- ? DISK_SPACE_LIMIT : FILE_SIZE_LIMIT;
-
- return Math.min(result, result2);
- }
-
- /**
- * Indicates which limit we will hit (or have hit) first, by returning one
- * of FILE_SIZE_LIMIT or DISK_SPACE_LIMIT or UNKNOWN_LIMIT. We need this to
- * display the correct message to the user when we hit one of the limits.
- */
- public int currentLowerLimit() {
- return mCurrentLowerLimit;
- }
-
- /**
- * Is there any point of trying to start recording?
- */
- public boolean diskSpaceAvailable() {
- StatFs fs = new StatFs(mSDCardDirectory.getAbsolutePath());
- // keep one free block
- return fs.getAvailableBlocks() > 1;
- }
-
- /**
- * Sets the bit rate used in the interpolation.
- *
- * @param bitRate the bit rate to set in bits/sec.
- */
- public void setBitRate(int bitRate) {
- mBytesPerSecond = bitRate/8;
- }
-}
-
-public class SoundRecorder extends Activity
- implements Button.OnClickListener, Recorder.OnStateChangedListener {
- static final String TAG = "SoundRecorder";
- static final String STATE_FILE_NAME = "soundrecorder.state";
- static final String RECORDER_STATE_KEY = "recorder_state";
- static final String SAMPLE_INTERRUPTED_KEY = "sample_interrupted";
- static final String MAX_FILE_SIZE_KEY = "max_file_size";
-
- static final String AUDIO_3GPP = "audio/3gpp";
- static final String AUDIO_AMR = "audio/amr";
- static final String AUDIO_ANY = "audio/*";
-
- static final int BITRATE_AMR = 5900; // bits/sec
- static final int BITRATE_3GPP = 5900;
-
- WakeLock mWakeLock;
- String mRequestedType = AUDIO_ANY;
- Recorder mRecorder;
- boolean mSampleInterrupted = false;
- String mErrorUiMessage = null; // Some error messages are displayed in the UI,
- // not a dialog. This happens when a recording
- // is interrupted for some reason.
-
- long mMaxFileSize = -1; // can be specified in the intent
- RemainingTimeCalculator mRemainingTimeCalculator;
-
- String mTimerFormat;
- final Handler mHandler = new Handler();
- Runnable mUpdateTimer = new Runnable() {
- public void run() { updateTimerView(); }
- };
-
- ImageButton mRecordButton;
- ImageButton mPlayButton;
- ImageButton mStopButton;
-
- ImageView mStateLED;
- TextView mStateMessage1;
- TextView mStateMessage2;
- ProgressBar mStateProgressBar;
- TextView mTimerView;
-
- LinearLayout mExitButtons;
- Button mAcceptButton;
- Button mDiscardButton;
- VUMeter mVUMeter;
- private BroadcastReceiver mSDCardMountEventReceiver = null;
-
- @Override
- public void onCreate(Bundle icycle) {
- super.onCreate(icycle);
-
- Intent i = getIntent();
- if (i != null) {
- String s = i.getType();
- if (AUDIO_AMR.equals(s) || AUDIO_3GPP.equals(s) || AUDIO_ANY.equals(s)) {
- mRequestedType = s;
- } else if (s != null) {
- // we only support amr and 3gpp formats right now
- setResult(RESULT_CANCELED);
- finish();
- return;
- }
-
- final String EXTRA_MAX_BYTES
- = android.provider.MediaStore.Audio.Media.EXTRA_MAX_BYTES;
- mMaxFileSize = i.getLongExtra(EXTRA_MAX_BYTES, -1);
- }
-
- if (AUDIO_ANY.equals(mRequestedType)) {
- mRequestedType = AUDIO_3GPP;
- }
-
- setContentView(R.layout.main);
-
- mRecorder = new Recorder();
- mRecorder.setOnStateChangedListener(this);
- mRemainingTimeCalculator = new RemainingTimeCalculator();
-
- PowerManager pm
- = (PowerManager) getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,
- "SoundRecorder");
-
- initResourceRefs();
-
- setResult(RESULT_CANCELED);
- registerExternalStorageListener();
- if (icycle != null) {
- Bundle recorderState = icycle.getBundle(RECORDER_STATE_KEY);
- if (recorderState != null) {
- mRecorder.restoreState(recorderState);
- mSampleInterrupted = recorderState.getBoolean(SAMPLE_INTERRUPTED_KEY, false);
- mMaxFileSize = recorderState.getLong(MAX_FILE_SIZE_KEY, -1);
- }
- }
-
- updateUi();
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
-
- setContentView(R.layout.main);
- initResourceRefs();
- updateUi();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
-
- if (mRecorder.sampleLength() == 0)
- return;
-
- Bundle recorderState = new Bundle();
-
- mRecorder.saveState(recorderState);
- recorderState.putBoolean(SAMPLE_INTERRUPTED_KEY, mSampleInterrupted);
- recorderState.putLong(MAX_FILE_SIZE_KEY, mMaxFileSize);
-
- outState.putBundle(RECORDER_STATE_KEY, recorderState);
- }
-
- /*
- * Whenever the UI is re-created (due f.ex. to orientation change) we have
- * to reinitialize references to the views.
- */
- private void initResourceRefs() {
- mRecordButton = (ImageButton) findViewById(R.id.recordButton);
- mPlayButton = (ImageButton) findViewById(R.id.playButton);
- mStopButton = (ImageButton) findViewById(R.id.stopButton);
-
- mStateLED = (ImageView) findViewById(R.id.stateLED);
- mStateMessage1 = (TextView) findViewById(R.id.stateMessage1);
- mStateMessage2 = (TextView) findViewById(R.id.stateMessage2);
- mStateProgressBar = (ProgressBar) findViewById(R.id.stateProgressBar);
- mTimerView = (TextView) findViewById(R.id.timerView);
-
- mExitButtons = (LinearLayout) findViewById(R.id.exitButtons);
- mAcceptButton = (Button) findViewById(R.id.acceptButton);
- mDiscardButton = (Button) findViewById(R.id.discardButton);
- mVUMeter = (VUMeter) findViewById(R.id.uvMeter);
-
- mRecordButton.setOnClickListener(this);
- mPlayButton.setOnClickListener(this);
- mStopButton.setOnClickListener(this);
- mAcceptButton.setOnClickListener(this);
- mDiscardButton.setOnClickListener(this);
-
- mTimerFormat = getResources().getString(R.string.timer_format);
-
- mVUMeter.setRecorder(mRecorder);
- }
-
- /*
- * Handle the buttons.
- */
- public void onClick(View button) {
- if (!button.isEnabled())
- return;
-
- switch (button.getId()) {
- case R.id.recordButton:
- mRemainingTimeCalculator.reset();
- if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- mSampleInterrupted = true;
- mErrorUiMessage = getResources().getString(R.string.insert_sd_card);
- updateUi();
- } else if (!mRemainingTimeCalculator.diskSpaceAvailable()) {
- mSampleInterrupted = true;
- mErrorUiMessage = getResources().getString(R.string.storage_is_full);
- updateUi();
- } else {
- if (AUDIO_AMR.equals(mRequestedType)) {
- mRemainingTimeCalculator.setBitRate(BITRATE_AMR);
- mRecorder.startRecording(MediaRecorder.OutputFormat.RAW_AMR, ".amr");
- } else if (AUDIO_3GPP.equals(mRequestedType)) {
- mRemainingTimeCalculator.setBitRate(BITRATE_3GPP);
- mRecorder.startRecording(MediaRecorder.OutputFormat.THREE_GPP, ".3gpp");
- } else {
- throw new IllegalArgumentException("Invalid output file type requested");
- }
-
- if (mMaxFileSize != -1) {
- mRemainingTimeCalculator.setFileSizeLimit(
- mRecorder.sampleFile(), mMaxFileSize);
- }
- }
- break;
- case R.id.playButton:
- mRecorder.startPlayback();
- break;
- case R.id.stopButton:
- mRecorder.stop();
- break;
- case R.id.acceptButton:
- mRecorder.stop();
- saveSample();
- finish();
- break;
- case R.id.discardButton:
- mRecorder.delete();
- finish();
- break;
- }
- }
-
- /*
- * Handle the "back" hardware key.
- */
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- switch (mRecorder.state()) {
- case Recorder.IDLE_STATE:
- if (mRecorder.sampleLength() > 0)
- saveSample();
- finish();
- break;
- case Recorder.PLAYING_STATE:
- mRecorder.stop();
- saveSample();
- break;
- case Recorder.RECORDING_STATE:
- mRecorder.clear();
- break;
- }
- return true;
- } else {
- return super.onKeyDown(keyCode, event);
- }
- }
-
- @Override
- public void onStop() {
- mRecorder.stop();
- super.onStop();
- }
-
- @Override
- protected void onPause() {
- mSampleInterrupted = mRecorder.state() == Recorder.RECORDING_STATE;
- mRecorder.stop();
-
- super.onPause();
- }
-
- /*
- * If we have just recorded a smaple, this adds it to the media data base
- * and sets the result to the sample's URI.
- */
- private void saveSample() {
- if (mRecorder.sampleLength() == 0)
- return;
- Uri uri = null;
- try {
- uri = this.addToMediaDB(mRecorder.sampleFile());
- } catch(UnsupportedOperationException ex) { // Database manipulation failure
- return;
- }
- if (uri == null) {
- return;
- }
- setResult(RESULT_OK, new Intent().setData(uri));
- }
-
- /*
- * Called on destroy to unregister the SD card mount event receiver.
- */
- @Override
- public void onDestroy() {
- if (mSDCardMountEventReceiver != null) {
- unregisterReceiver(mSDCardMountEventReceiver);
- mSDCardMountEventReceiver = null;
- }
- super.onDestroy();
- }
-
- /*
- * Registers an intent to listen for ACTION_MEDIA_EJECT/ACTION_MEDIA_MOUNTED
- * notifications.
- */
- private void registerExternalStorageListener() {
- if (mSDCardMountEventReceiver == null) {
- mSDCardMountEventReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
- mRecorder.delete();
- } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
- mSampleInterrupted = false;
- updateUi();
- }
- }
- };
- IntentFilter iFilter = new IntentFilter();
- iFilter.addAction(Intent.ACTION_MEDIA_EJECT);
- iFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);
- iFilter.addDataScheme("file");
- registerReceiver(mSDCardMountEventReceiver, iFilter);
- }
- }
-
- /*
- * A simple utility to do a query into the databases.
- */
- private Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
- try {
- ContentResolver resolver = getContentResolver();
- if (resolver == null) {
- return null;
- }
- return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
- } catch (UnsupportedOperationException ex) {
- return null;
- }
- }
-
- /*
- * Add the given audioId to the playlist with the given playlistId; and maintain the
- * play_order in the playlist.
- */
- private void addToPlaylist(ContentResolver resolver, int audioId, long playlistId) {
- String[] cols = new String[] {
- "count(*)"
- };
- Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
- Cursor cur = resolver.query(uri, cols, null, null, null);
- cur.moveToFirst();
- final int base = cur.getInt(0);
- cur.close();
- ContentValues values = new ContentValues();
- values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer.valueOf(base + audioId));
- values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, audioId);
- resolver.insert(uri, values);
- }
-
- /*
- * Obtain the id for the default play list from the audio_playlists table.
- */
- private int getPlaylistId(Resources res) {
- Uri uri = MediaStore.Audio.Playlists.getContentUri("external");
- final String[] ids = new String[] { MediaStore.Audio.Playlists._ID };
- final String where = MediaStore.Audio.Playlists.NAME + "=?";
- final String[] args = new String[] { res.getString(R.string.audio_db_playlist_name) };
- Cursor cursor = query(uri, ids, where, args, null);
- if (cursor == null) {
- Log.v(TAG, "query returns null");
- }
- int id = -1;
- if (cursor != null) {
- cursor.moveToFirst();
- if (!cursor.isAfterLast()) {
- id = cursor.getInt(0);
- }
- }
- cursor.close();
- return id;
- }
-
- /*
- * Create a playlist with the given default playlist name, if no such playlist exists.
- */
- private Uri createPlaylist(Resources res, ContentResolver resolver) {
- ContentValues cv = new ContentValues();
- cv.put(MediaStore.Audio.Playlists.NAME, res.getString(R.string.audio_db_playlist_name));
- Uri uri = resolver.insert(MediaStore.Audio.Playlists.getContentUri("external"), cv);
- if (uri == null) {
- new AlertDialog.Builder(this)
- .setTitle(R.string.app_name)
- .setMessage(R.string.error_mediadb_new_record)
- .setPositiveButton(R.string.button_ok, null)
- .setCancelable(false)
- .show();
- }
- return uri;
- }
-
- /*
- * Adds file and returns content uri.
- */
- private Uri addToMediaDB(File file) {
- Resources res = getResources();
- ContentValues cv = new ContentValues();
- long current = System.currentTimeMillis();
- long modDate = file.lastModified();
- Date date = new Date(current);
- SimpleDateFormat formatter = new SimpleDateFormat(
- res.getString(R.string.audio_db_title_format));
- String title = formatter.format(date);
-
- // Lets label the recorded audio file as NON-MUSIC so that the file
- // won't be displayed automatically, except for in the playlist.
- cv.put(MediaStore.Audio.Media.IS_MUSIC, "0");
-
- cv.put(MediaStore.Audio.Media.TITLE, title);
- cv.put(MediaStore.Audio.Media.DATA, file.getAbsolutePath());
- cv.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
- cv.put(MediaStore.Audio.Media.DATE_MODIFIED, (int) (modDate / 1000));
- cv.put(MediaStore.Audio.Media.MIME_TYPE, mRequestedType);
- cv.put(MediaStore.Audio.Media.ARTIST,
- res.getString(R.string.audio_db_artist_name));
- cv.put(MediaStore.Audio.Media.ALBUM,
- res.getString(R.string.audio_db_album_name));
- Log.d(TAG, "Inserting audio record: " + cv.toString());
- ContentResolver resolver = getContentResolver();
- Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
- Log.d(TAG, "ContentURI: " + base);
- Uri result = resolver.insert(base, cv);
- if (result == null) {
- new AlertDialog.Builder(this)
- .setTitle(R.string.app_name)
- .setMessage(R.string.error_mediadb_new_record)
- .setPositiveButton(R.string.button_ok, null)
- .setCancelable(false)
- .show();
- return null;
- }
- if (getPlaylistId(res) == -1) {
- createPlaylist(res, resolver);
- }
- int audioId = Integer.valueOf(result.getLastPathSegment());
- addToPlaylist(resolver, audioId, getPlaylistId(res));
-
- // Notify those applications such as Music listening to the
- // scanner events that a recorded audio file just created.
- sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
- return result;
- }
-
- /**
- * Update the big MM:SS timer. If we are in playback, also update the
- * progress bar.
- */
- private void updateTimerView() {
- Resources res = getResources();
- int state = mRecorder.state();
-
- boolean ongoing = state == Recorder.RECORDING_STATE || state == Recorder.PLAYING_STATE;
-
- long time = ongoing ? mRecorder.progress() : mRecorder.sampleLength();
- String timeStr = String.format(mTimerFormat, time/60, time%60);
- mTimerView.setText(timeStr);
-
- if (state == Recorder.PLAYING_STATE) {
- mStateProgressBar.setProgress((int)(100*time/mRecorder.sampleLength()));
- } else if (state == Recorder.RECORDING_STATE) {
- updateTimeRemaining();
- }
-
- if (ongoing)
- mHandler.postDelayed(mUpdateTimer, 1000);
- }
-
- /*
- * Called when we're in recording state. Find out how much longer we can
- * go on recording. If it's under 5 minutes, we display a count-down in
- * the UI. If we've run out of time, stop the recording.
- */
- private void updateTimeRemaining() {
- long t = mRemainingTimeCalculator.timeRemaining();
-
- if (t <= 0) {
- mSampleInterrupted = true;
-
- int limit = mRemainingTimeCalculator.currentLowerLimit();
- switch (limit) {
- case RemainingTimeCalculator.DISK_SPACE_LIMIT:
- mErrorUiMessage
- = getResources().getString(R.string.storage_is_full);
- break;
- case RemainingTimeCalculator.FILE_SIZE_LIMIT:
- mErrorUiMessage
- = getResources().getString(R.string.max_length_reached);
- break;
- default:
- mErrorUiMessage = null;
- break;
- }
-
- mRecorder.stop();
- return;
- }
-
- Resources res = getResources();
- String timeStr = "";
-
- if (t < 60)
- timeStr = String.format(res.getString(R.string.sec_available), t);
- else if (t < 540)
- timeStr = String.format(res.getString(R.string.min_available), t/60 + 1);
-
- mStateMessage1.setText(timeStr);
- }
-
- /**
- * Shows/hides the appropriate child views for the new state.
- */
- private void updateUi() {
- Resources res = getResources();
-
- switch (mRecorder.state()) {
- case Recorder.IDLE_STATE:
- if (mRecorder.sampleLength() == 0) {
- mRecordButton.setEnabled(true);
- mRecordButton.setFocusable(true);
- mPlayButton.setEnabled(false);
- mPlayButton.setFocusable(false);
- mStopButton.setEnabled(false);
- mStopButton.setFocusable(false);
- mRecordButton.requestFocus();
-
- mStateMessage1.setVisibility(View.INVISIBLE);
- mStateLED.setVisibility(View.VISIBLE);
- mStateLED.setImageResource(R.drawable.idle_led);
- mStateMessage2.setVisibility(View.VISIBLE);
- mStateMessage2.setText(res.getString(R.string.press_record));
-
- mExitButtons.setVisibility(View.INVISIBLE);
- mVUMeter.setVisibility(View.VISIBLE);
-
- mStateProgressBar.setVisibility(View.INVISIBLE);
-
- setTitle(res.getString(R.string.record_your_message));
- } else {
- mRecordButton.setEnabled(true);
- mRecordButton.setFocusable(true);
- mPlayButton.setEnabled(true);
- mPlayButton.setFocusable(true);
- mStopButton.setEnabled(false);
- mStopButton.setFocusable(false);
-
- mStateMessage1.setVisibility(View.INVISIBLE);
- mStateLED.setVisibility(View.INVISIBLE);
- mStateMessage2.setVisibility(View.INVISIBLE);
-
- mExitButtons.setVisibility(View.VISIBLE);
- mVUMeter.setVisibility(View.INVISIBLE);
-
- mStateProgressBar.setVisibility(View.INVISIBLE);
-
- setTitle(res.getString(R.string.message_recorded));
- }
-
- if (mSampleInterrupted) {
- mStateMessage2.setVisibility(View.VISIBLE);
- mStateMessage2.setText(res.getString(R.string.recording_stopped));
- mStateLED.setImageResource(R.drawable.idle_led);
- mStateLED.setVisibility(View.VISIBLE);
- }
-
- if (mErrorUiMessage != null) {
- mStateMessage1.setText(mErrorUiMessage);
- mStateMessage1.setVisibility(View.VISIBLE);
- }
-
- break;
- case Recorder.RECORDING_STATE:
- mRecordButton.setEnabled(false);
- mRecordButton.setFocusable(false);
- mPlayButton.setEnabled(false);
- mPlayButton.setFocusable(false);
- mStopButton.setEnabled(true);
- mStopButton.setFocusable(true);
-
- mStateMessage1.setVisibility(View.VISIBLE);
- mStateLED.setVisibility(View.VISIBLE);
- mStateLED.setImageResource(R.drawable.recording_led);
- mStateMessage2.setVisibility(View.VISIBLE);
- mStateMessage2.setText(res.getString(R.string.recording));
-
- mExitButtons.setVisibility(View.INVISIBLE);
- mVUMeter.setVisibility(View.VISIBLE);
-
- mStateProgressBar.setVisibility(View.INVISIBLE);
-
- setTitle(res.getString(R.string.record_your_message));
-
- break;
-
- case Recorder.PLAYING_STATE:
- mRecordButton.setEnabled(true);
- mRecordButton.setFocusable(true);
- mPlayButton.setEnabled(false);
- mPlayButton.setFocusable(false);
- mStopButton.setEnabled(true);
- mStopButton.setFocusable(true);
-
- mStateMessage1.setVisibility(View.INVISIBLE);
- mStateLED.setVisibility(View.INVISIBLE);
- mStateMessage2.setVisibility(View.INVISIBLE);
-
- mExitButtons.setVisibility(View.VISIBLE);
- mVUMeter.setVisibility(View.INVISIBLE);
-
- mStateProgressBar.setVisibility(View.VISIBLE);
-
- setTitle(res.getString(R.string.review_message));
-
- break;
- }
-
- updateTimerView();
- mVUMeter.invalidate();
- }
-
- /*
- * Called when Recorder changed it's state.
- */
- public void onStateChanged(int state) {
- if (state == Recorder.PLAYING_STATE || state == Recorder.RECORDING_STATE) {
- mSampleInterrupted = false;
- mErrorUiMessage = null;
- }
-
- if (state == Recorder.RECORDING_STATE) {
- mWakeLock.acquire(); // we don't want to go to sleep while recording
- } else {
- if (mWakeLock.isHeld())
- mWakeLock.release();
- }
-
- updateUi();
- }
-
- /*
- * Called when MediaPlayer encounters an error.
- */
- public void onError(int error) {
- Resources res = getResources();
-
- String message = null;
- switch (error) {
- case Recorder.SDCARD_ACCESS_ERROR:
- message = res.getString(R.string.error_sdcard_access);
- break;
- case Recorder.INTERNAL_ERROR:
- message = res.getString(R.string.error_app_internal);
- break;
- }
- if (message != null) {
- new AlertDialog.Builder(this)
- .setTitle(R.string.app_name)
- .setMessage(message)
- .setPositiveButton(R.string.button_ok, null)
- .setCancelable(false)
- .show();
- }
- }
-}
+++ /dev/null
-package com.android.soundrecorder;
-
-import java.util.Map;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.View;
-
-public class VUMeter extends View {
- static final float PIVOT_RADIUS = 3.5f;
- static final float PIVOT_Y_OFFSET = 10f;
- static final float SHADOW_OFFSET = 2.0f;
- static final float DROPOFF_STEP = 0.18f;
- static final float SURGE_STEP = 0.35f;
- static final long ANIMATION_INTERVAL = 70;
-
- Paint mPaint, mShadow;
- float mCurrentAngle;
-
- Recorder mRecorder;
-
- public VUMeter(Context context) {
- super(context);
- init(context);
- }
-
- public VUMeter(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- void init(Context context) {
- Drawable background = context.getResources().getDrawable(R.drawable.vumeter);
- setBackgroundDrawable(background);
-
- mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mPaint.setColor(Color.WHITE);
- mShadow = new Paint(Paint.ANTI_ALIAS_FLAG);
- mShadow.setColor(Color.argb(60, 0, 0, 0));
-
- mRecorder = null;
-
- mCurrentAngle = 0;
- }
-
- public void setRecorder(Recorder recorder) {
- mRecorder = recorder;
- invalidate();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- final float minAngle = (float)Math.PI/8;
- final float maxAngle = (float)Math.PI*7/8;
-
- float angle = minAngle;
- if (mRecorder != null)
- angle += (float)(maxAngle - minAngle)*mRecorder.getMaxAmplitude()/32768;
-
- if (angle > mCurrentAngle)
- mCurrentAngle = angle;
- else
- mCurrentAngle = Math.max(angle, mCurrentAngle - DROPOFF_STEP);
-
- mCurrentAngle = Math.min(maxAngle, mCurrentAngle);
-
- float w = getWidth();
- float h = getHeight();
- float pivotX = w/2;
- float pivotY = h - PIVOT_RADIUS - PIVOT_Y_OFFSET;
- float l = h*4/5;
- float sin = (float) Math.sin(mCurrentAngle);
- float cos = (float) Math.cos(mCurrentAngle);
- float x0 = pivotX - l*cos;
- float y0 = pivotY - l*sin;
- canvas.drawLine(x0 + SHADOW_OFFSET, y0 + SHADOW_OFFSET, pivotX + SHADOW_OFFSET, pivotY + SHADOW_OFFSET, mShadow);
- canvas.drawCircle(pivotX + SHADOW_OFFSET, pivotY + SHADOW_OFFSET, PIVOT_RADIUS, mShadow);
- canvas.drawLine(x0, y0, pivotX, pivotY, mPaint);
- canvas.drawCircle(pivotX, pivotY, PIVOT_RADIUS, mPaint);
-
- if (mRecorder != null && mRecorder.state() == Recorder.RECORDING_STATE)
- postInvalidateDelayed(ANIMATION_INTERVAL);
- }
-}