diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-02-19 10:57:31 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-02-19 10:57:31 -0800 |
commit | 3001a035439d8134a7d70d796376d1dfbff3cdcd (patch) | |
tree | 343ccdba15a594ff6e50c874a145232753315a30 /core | |
parent | da996f390e17e16f2dfa60e972e7ebc4f868f37e (diff) | |
download | frameworks_base-3001a035439d8134a7d70d796376d1dfbff3cdcd.zip frameworks_base-3001a035439d8134a7d70d796376d1dfbff3cdcd.tar.gz frameworks_base-3001a035439d8134a7d70d796376d1dfbff3cdcd.tar.bz2 |
auto import from //branches/cupcake/...@132276
Diffstat (limited to 'core')
121 files changed, 5086 insertions, 4016 deletions
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index b59e9dc..1bed706 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -426,13 +426,9 @@ public final class PendingIntent implements Parcelable { */ @Override public boolean equals(Object otherObj) { - if (otherObj == null) { - return false; - } - try { + if (otherObj instanceof PendingIntent) { return mTarget.asBinder().equals(((PendingIntent)otherObj) .mTarget.asBinder()); - } catch (ClassCastException e) { } return false; } @@ -442,6 +438,13 @@ public final class PendingIntent implements Parcelable { return mTarget.asBinder().hashCode(); } + @Override + public String toString() { + return "PendingIntent{" + + Integer.toHexString(System.identityHashCode(this)) + + " target " + (mTarget != null ? mTarget.asBinder() : null) + "}"; + } + public int describeContents() { return 0; } diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index 5744ddc..7b8256c 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -31,8 +31,6 @@ import android.database.Cursor; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; -import android.os.Handler; -import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; @@ -64,7 +62,6 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemSelectedListener; import java.lang.ref.WeakReference; -import java.util.List; import java.util.concurrent.atomic.AtomicLong; /** @@ -538,9 +535,9 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS testIntent = mVoiceAppSearchIntent; } if (testIntent != null) { - List<ResolveInfo> list = getContext().getPackageManager(). - queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY); - if (list.size() > 0) { + ResolveInfo ri = getContext().getPackageManager(). + resolveActivity(testIntent, PackageManager.MATCH_DEFAULT_ONLY); + if (ri != null) { visibility = View.VISIBLE; } } diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java index 72692f4..a6a436f 100644 --- a/core/java/android/app/Service.java +++ b/core/java/android/app/Service.java @@ -327,11 +327,15 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac } /** - * Print the Service's state into the given stream. + * Print the Service's state into the given stream. This gets invoked if + * you run "adb shell dumpsys activity service <yourservicename>". + * This is distinct from "dumpsys <servicename>", which only works for + * named system services and which invokes the {@link IBinder#dump} method + * on the {@link IBinder} interface registered with ServiceManager. * * @param fd The raw file descriptor that the dump is being sent to. * @param writer The PrintWriter to which you should dump your state. This will be - * closed for you after you return. + * closed for you after you return. * @param args additional arguments to the dump request. */ protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { diff --git a/core/java/android/bluetooth/ScoSocket.java b/core/java/android/bluetooth/ScoSocket.java index 75b3329..a43a08b 100644 --- a/core/java/android/bluetooth/ScoSocket.java +++ b/core/java/android/bluetooth/ScoSocket.java @@ -16,17 +16,12 @@ package android.bluetooth; -import android.content.Context; import android.os.Handler; import android.os.Message; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.util.Log; -import java.io.IOException; -import java.lang.Thread; - - /** * The Android Bluetooth API is not finalized, and *will* change. Use at your * own risk. @@ -56,7 +51,7 @@ public class ScoSocket { private int mConnectedCode; private int mClosedCode; - private WakeLock mWakeLock; // held while STATE_CONNECTING or STATE_CONNECTED + private WakeLock mWakeLock; // held while in STATE_CONNECTING static { classInitNative(); @@ -130,6 +125,7 @@ public class ScoSocket { public synchronized void close() { if (DBG) log(this + " SCO OBJECT close() mState = " + mState); + acquireWakeLock(); mState = STATE_CLOSED; closeNative(); releaseWakeLock(); @@ -152,19 +148,16 @@ public class ScoSocket { mState = STATE_CLOSED; } mHandler.obtainMessage(mConnectedCode, mState, -1, this).sendToTarget(); - if (result < 0) { - releaseWakeLock(); - } + releaseWakeLock(); } private synchronized void onAccepted(int result) { if (VDBG) log("onAccepted() " + this); if (mState != STATE_ACCEPT) { - if (DBG) log("Strange state" + this); + if (DBG) log("Strange state " + this); return; } if (result >= 0) { - acquireWakeLock(); mState = STATE_CONNECTED; } else { mState = STATE_CLOSED; @@ -184,13 +177,13 @@ public class ScoSocket { private void acquireWakeLock() { if (!mWakeLock.isHeld()) { mWakeLock.acquire(); - if (VDBG) log("mWakeLock.acquire()" + this); + if (VDBG) log("mWakeLock.acquire() " + this); } } private void releaseWakeLock() { if (mWakeLock.isHeld()) { - if (VDBG) log("mWakeLock.release()" + this); + if (VDBG) log("mWakeLock.release() " + this); mWakeLock.release(); } } diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java index ee08eea..08f6191 100644 --- a/core/java/android/content/BroadcastReceiver.java +++ b/core/java/android/content/BroadcastReceiver.java @@ -79,7 +79,7 @@ import android.util.Log; * <p>The BroadcastReceiver class (when launched as a component through * a manifest's {@link android.R.styleable#AndroidManifestReceiver <receiver>} * tag) is an important part of an - * <a href="{@docRoot}intro/lifecycle.html">application's overall lifecycle</a>.</p> + * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">application's overall lifecycle</a>.</p> * * <p>Topics covered here: * <ol> @@ -135,7 +135,7 @@ import android.util.Log; * tag in their <code>AndroidManifest.xml</code>) will be able to send an * Intent to the receiver. * - * <p>See the <a href="{@docRoot}devel/security.html">Security Model</a> + * <p>See the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> * document for more information on permissions and security in general. * * <a name="ProcessLifecycle"></a> diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 226c5ab..3a64cee 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -41,8 +41,8 @@ import java.io.FileNotFoundException; * multiple applications you can use a database directly via * {@link android.database.sqlite.SQLiteDatabase}. * - * <p>See <a href="{@docRoot}devel/data/contentproviders.html">this page</a> for more information on - * content providers.</p> + * <p>For more information, read <a href="{@docRoot}guide/topics/providers/content-providers.html">Content + * Providers</a>.</p> * * <p>When a request is made via * a {@link ContentResolver} the system inspects the authority of the given URI and passes the @@ -226,9 +226,9 @@ public abstract class ContentProvider implements ComponentCallbacks { /** * Return the name of the permission required for read-only access to * this content provider. This method can be called from multiple - * threads, as described in the - * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of - * the Application Model overview</a>. + * threads, as described in + * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals: + * Processes and Threads</a>. */ public final String getReadPermission() { return mReadPermission; @@ -248,9 +248,9 @@ public abstract class ContentProvider implements ComponentCallbacks { /** * Return the name of the permission required for read/write access to * this content provider. This method can be called from multiple - * threads, as described in the - * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of - * the Application Model overview</a>. + * threads, as described in + * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals: + * Processes and Threads</a>. */ public final String getWritePermission() { return mWritePermission; @@ -273,9 +273,9 @@ public abstract class ContentProvider implements ComponentCallbacks { * Receives a query request from a client in a local process, and * returns a Cursor. This is called internally by the {@link ContentResolver}. * This method can be called from multiple - * threads, as described in the - * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of - * the Application Model overview</a>. + * threads, as described in + * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals: + * Processes and Threads</a>. * <p> * Example client call:<p> * <pre>// Request a specific record. @@ -330,9 +330,9 @@ public abstract class ContentProvider implements ComponentCallbacks { * <code>vnd.android.cursor.item</code> for a single record, * or <code>vnd.android.cursor.dir/</code> for multiple items. * This method can be called from multiple - * threads, as described in the - * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of - * the Application Model overview</a>. + * threads, as described in + * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals: + * Processes and Threads</a>. * * @param uri the URI to query. * @return a MIME type string, or null if there is no type. @@ -344,9 +344,9 @@ public abstract class ContentProvider implements ComponentCallbacks { * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()} * after inserting. * This method can be called from multiple - * threads, as described in the - * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of the - * Application Model overview</a>. + * threads, as described in + * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals: + * Processes and Threads</a>. * @param uri The content:// URI of the insertion request. * @param values A set of column_name/value pairs to add to the database. * @return The URI for the newly inserted item. @@ -359,9 +359,9 @@ public abstract class ContentProvider implements ComponentCallbacks { * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()} * after inserting. * This method can be called from multiple - * threads, as described in the - * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of - * the Application Model overview</a>. + * threads, as described in + * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals: + * Processes and Threads</a>. * * @param uri The content:// URI of the insertion request. * @param values An array of sets of column_name/value pairs to add to the database. @@ -382,9 +382,9 @@ public abstract class ContentProvider implements ComponentCallbacks { * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyDelete()} * after deleting. * This method can be called from multiple - * threads, as described in the - * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of the - * Application Model overview</a>. + * threads, as described in + * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals: + * Processes and Threads</a>. * * <p>The implementation is responsible for parsing out a row ID at the end * of the URI, if a specific row is being deleted. That is, the client would @@ -405,9 +405,9 @@ public abstract class ContentProvider implements ComponentCallbacks { * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()} * after updating. * This method can be called from multiple - * threads, as described in the - * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of the - * Application Model overview</a>. + * threads, as described in + * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals: + * Processes and Threads</a>. * * @param uri The URI to query. This can potentially have a record ID if this * is an update request for a specific record. @@ -422,9 +422,9 @@ public abstract class ContentProvider implements ComponentCallbacks { /** * Open a file blob associated with a content URI. * This method can be called from multiple - * threads, as described in the - * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of the - * Application Model overview</a>. + * threads, as described in + * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals: + * Processes and Threads</a>. * * <p>Returns a * ParcelFileDescriptor, from which you can obtain a @@ -507,9 +507,9 @@ public abstract class ContentProvider implements ComponentCallbacks { * This is intended for use by the sync system. If null then this * content provider is considered not syncable. * This method can be called from multiple - * threads, as described in the - * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of - * the Application Model overview</a>. + * threads, as described in + * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals: + * Processes and Threads</a>. * * @return the SyncAdapter that is to be used by this ContentProvider, or null * if this ContentProvider is not syncable diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index c4d3f9d..c1c3b49 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1766,9 +1766,9 @@ public class Intent implements Parcelable { * next task activity) defines an atomic group of activities that the * user can move to. Tasks can be moved to the foreground and background; * all of the activities inside of a particular task always remain in - * the same order. See the - * <a href="{@docRoot}intro/appmodel.html">Application Model</a> - * documentation for more details on tasks. + * the same order. See + * <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals: + * Activities and Tasks</a> for more details on tasks. * * <p>This flag is generally used by activities that want * to present a "launcher" style behavior: they give the user a list of @@ -1801,9 +1801,8 @@ public class Intent implements Parcelable { * <p>This flag is ignored if * {@link #FLAG_ACTIVITY_NEW_TASK} is not set. * - * <p>See the - * <a href="{@docRoot}intro/appmodel.html">Application Model</a> - * documentation for more details on tasks. + * <p>See <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals: + * Activities and Tasks</a> for more details on tasks. */ public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000; /** @@ -1831,9 +1830,8 @@ public class Intent implements Parcelable { * especially useful, for example, when launching an activity from the * notification manager. * - * <p>See the - * <a href="{@docRoot}intro/appmodel.html">Application Model</a> - * documentation for more details on tasks. + * <p>See <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals: + * Activities and Tasks</a> for more details on tasks. */ public static final int FLAG_ACTIVITY_CLEAR_TOP = 0x04000000; /** @@ -3919,8 +3917,8 @@ public class Intent implements Parcelable { * FLAG_RECEIVER_* flags are all for use with * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}. * - * <p>See the <a href="{@docRoot}intro/appmodel.html">Application Model</a> - * documentation for important information on how some of these options impact + * <p>See the <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals: + * Activities and Tasks</a> documentation for important information on how some of these options impact * the behavior of your application. * * @param flags The desired flags. @@ -4195,14 +4193,11 @@ public class Intent implements Parcelable { @Override public boolean equals(Object obj) { - Intent other; - try { - other = ((FilterComparison)obj).mIntent; - } catch (ClassCastException e) { - return false; + if (obj instanceof FilterComparison) { + Intent other = ((FilterComparison)obj).mIntent; + return mIntent.filterEquals(other); } - - return mIntent.filterEquals(other); + return false; } @Override diff --git a/core/java/android/content/package.html b/core/java/android/content/package.html index 7b3e8cf..dd5360f 100644 --- a/core/java/android/content/package.html +++ b/core/java/android/content/package.html @@ -50,9 +50,9 @@ an application's resources and transfer data between applications.</p> <p>This topic includes a terminology list associated with resources, and a series of examples of using resources in code. For a complete guide on creating and - using resources, see the document on <a href="{@docRoot}devel/resources-i18n.html">Resources + using resources, see the document on <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources and Internationalization</a>. For a reference on the supported Android resource types, - see <a href="{@docRoot}reference/available-resources.html">Available Resource Types</a>.</p> + see <a href="{@docRoot}guide/topics/resources/available-resources.html">Available Resource Types</a>.</p> <p>The Android resource system keeps track of all non-code assets associated with an application. You use the {@link android.content.res.Resources Resources} class to access your @@ -175,7 +175,8 @@ download files with new appearances.</p> <p>This section gives a few quick examples you can use to make your own resources. For more details on how to define and use resources, see <a - href="{@docRoot}devel/resources-i18n.html">Resources</a>. </p> + href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources and + Internationalization</a>. </p> <a name="UsingSystemResources"></a> <h4>Using System Resources</h4> diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index 994afc8..d9326f2 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -29,6 +29,20 @@ public class PackageInfo implements Parcelable { public String versionName; /** + * The shared user ID name of this package, as specified by the <manifest> + * tag's {@link android.R.styleable#AndroidManifest_sharedUserId sharedUserId} + * attribute. + */ + public String sharedUserId; + + /** + * The shared user ID label of this package, as specified by the <manifest> + * tag's {@link android.R.styleable#AndroidManifest_sharedUserLabel sharedUserLabel} + * attribute. + */ + public int sharedUserLabel; + + /** * Information collected from the <application> tag, or null if * there was none. */ @@ -130,6 +144,8 @@ public class PackageInfo implements Parcelable { dest.writeString(packageName); dest.writeInt(versionCode); dest.writeString(versionName); + dest.writeString(sharedUserId); + dest.writeInt(sharedUserLabel); if (applicationInfo != null) { dest.writeInt(1); applicationInfo.writeToParcel(dest, parcelableFlags); @@ -163,6 +179,8 @@ public class PackageInfo implements Parcelable { packageName = source.readString(); versionCode = source.readInt(); versionName = source.readString(); + sharedUserId = source.readString(); + sharedUserLabel = source.readInt(); int hasApp = source.readInt(); if (hasApp != 0) { applicationInfo = ApplicationInfo.CREATOR.createFromParcel(source); diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index e08f1d1..4ae8b08 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -101,6 +101,8 @@ public class PackageParser { pi.packageName = p.packageName; pi.versionCode = p.mVersionCode; pi.versionName = p.mVersionName; + pi.sharedUserId = p.mSharedUserId; + pi.sharedUserLabel = p.mSharedUserLabel; pi.applicationInfo = p.applicationInfo; if ((flags&PackageManager.GET_GIDS) != 0) { pi.gids = gids; @@ -585,6 +587,8 @@ public class PackageParser { return null; } pkg.mSharedUserId = str.intern(); + pkg.mSharedUserLabel = sa.getResourceId( + com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0); } sa.recycle(); @@ -2045,6 +2049,9 @@ public class PackageParser { // The shared user id that this package wants to use. public String mSharedUserId; + // The shared user label that this package wants to use. + public int mSharedUserLabel; + // Signatures that were read from the package. public Signature mSignatures[]; diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java index 2ff7294..10f3806 100644 --- a/core/java/android/database/DatabaseUtils.java +++ b/core/java/android/database/DatabaseUtils.java @@ -84,6 +84,7 @@ public class DatabaseUtils { code = 9; } else { reply.writeException(e); + Log.e(TAG, "Writing exception to parcel", e); return; } reply.writeInt(code); diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java index d9f10a9..52f8209 100644 --- a/core/java/android/inputmethodservice/ExtractEditText.java +++ b/core/java/android/inputmethodservice/ExtractEditText.java @@ -102,7 +102,7 @@ public class ExtractEditText extends EditText { * highlight and cursor will be displayed. */ @Override public boolean hasWindowFocus() { - return true; + return this.isEnabled() ? true : false; } /** @@ -110,7 +110,7 @@ public class ExtractEditText extends EditText { * highlight and cursor will be displayed. */ @Override public boolean isFocused() { - return true; + return this.isEnabled() ? true : false; } /** @@ -118,7 +118,6 @@ public class ExtractEditText extends EditText { * highlight and cursor will be displayed. */ @Override public boolean hasFocus() { - return true; + return this.isEnabled() ? true : false; } - } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index c884120..4be1fc7 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -229,9 +229,11 @@ public class InputMethodService extends AbstractInputMethodService { InputConnection mStartedInputConnection; EditorInfo mInputEditorInfo; + int mShowInputFlags; boolean mShowInputRequested; boolean mLastShowInputRequested; int mCandidatesVisibility; + CompletionInfo[] mCurCompletions; boolean mShowInputForced; @@ -328,6 +330,7 @@ public class InputMethodService extends AbstractInputMethodService { */ public void hideSoftInput() { if (DEBUG) Log.v(TAG, "hideSoftInput()"); + mShowInputFlags = 0; mShowInputRequested = false; mShowInputForced = false; hideWindow(); @@ -338,7 +341,10 @@ public class InputMethodService extends AbstractInputMethodService { */ public void showSoftInput(int flags) { if (DEBUG) Log.v(TAG, "showSoftInput()"); - onShowRequested(flags); + mShowInputFlags = 0; + if (onShowInputRequested(flags, false)) { + showWindow(true); + } } } @@ -364,6 +370,7 @@ public class InputMethodService extends AbstractInputMethodService { if (!isEnabled()) { return; } + mCurCompletions = completions; onDisplayCompletions(completions); } @@ -557,8 +564,9 @@ public class InputMethodService extends AbstractInputMethodService { super.onConfigurationChanged(newConfig); boolean visible = mWindowVisible; + int showFlags = mShowInputFlags; boolean showingInput = mShowInputRequested; - boolean showingForced = mShowInputForced; + CompletionInfo[] completions = mCurCompletions; initViews(); mInputViewStarted = false; mCandidatesViewStarted = false; @@ -567,19 +575,24 @@ public class InputMethodService extends AbstractInputMethodService { getCurrentInputEditorInfo(), true); } if (visible) { - if (showingForced) { - // If we are showing the full soft keyboard, then go through - // this path to take care of current decisions about fullscreen - // etc. - onShowRequested(InputMethod.SHOW_FORCED|InputMethod.SHOW_EXPLICIT); - } else if (showingInput) { - // If we are showing the full soft keyboard, then go through - // this path to take care of current decisions about fullscreen - // etc. - onShowRequested(InputMethod.SHOW_EXPLICIT); - } else { - // Otherwise just put it back for its candidates. + if (showingInput) { + // If we were last showing the soft keyboard, try to do so again. + if (onShowInputRequested(showFlags, true)) { + showWindow(true); + if (completions != null) { + mCurCompletions = completions; + onDisplayCompletions(completions); + } + } else { + hideWindow(); + } + } else if (mCandidatesVisibility == View.VISIBLE) { + // If the candidates are currently visible, make sure the + // window is shown for them. showWindow(false); + } else { + // Otherwise hide the window. + hideWindow(); } } } @@ -1065,36 +1078,42 @@ public class InputMethodService extends AbstractInputMethodService { * The system has decided that it may be time to show your input method. * This is called due to a corresponding call to your * {@link InputMethod#showSoftInput(int) InputMethod.showSoftInput(int)} - * method. The default implementation simply calls - * {@link #showWindow(boolean)}, except if the - * {@link InputMethod#SHOW_EXPLICIT InputMethod.SHOW_EXPLICIT} flag is - * not set and the input method is running in fullscreen mode. + * method. The default implementation uses + * {@link #onEvaluateInputViewShown()}, {@link #onEvaluateFullscreenMode()}, + * and the current configuration to decide whether the input view should + * be shown at this point. * * @param flags Provides additional information about the show request, * as per {@link InputMethod#showSoftInput(int) InputMethod.showSoftInput(int)}. + * @param configChange This is true if we are re-showing due to a + * configuration change. + * @return Returns true to indicate that the window should be shown. */ - public void onShowRequested(int flags) { + public boolean onShowInputRequested(int flags, boolean configChange) { if (!onEvaluateInputViewShown()) { - return; + return false; } if ((flags&InputMethod.SHOW_EXPLICIT) == 0) { - if (onEvaluateFullscreenMode()) { + if (!configChange && onEvaluateFullscreenMode()) { // Don't show if this is not explicitly requested by the user and // the input method is fullscreen. That would be too disruptive. - return; + // However, we skip this change for a config change, since if + // the IME is already shown we do want to go into fullscreen + // mode at this point. + return false; } Configuration config = getResources().getConfiguration(); if (config.keyboard != Configuration.KEYBOARD_NOKEYS) { // And if the device has a hard keyboard, even if it is // currently hidden, don't show the input method implicitly. // These kinds of devices don't need it that much. - return; + return false; } } if ((flags&InputMethod.SHOW_FORCED) != 0) { mShowInputForced = true; } - showWindow(true); + return true; } public void showWindow(boolean showInput) { @@ -1106,7 +1125,6 @@ public class InputMethodService extends AbstractInputMethodService { + " mInputStarted=" + mInputStarted); boolean doShowInput = false; boolean wasVisible = mWindowVisible; - boolean wasCreated = mWindowCreated; mWindowVisible = true; if (!mShowInputRequested) { if (mInputStarted) { @@ -1240,6 +1258,7 @@ public class InputMethodService extends AbstractInputMethodService { } mInputStarted = false; mStartedInputConnection = null; + mCurCompletions = null; } void doStartInput(InputConnection ic, EditorInfo attribute, boolean restarting) { @@ -1550,7 +1569,11 @@ public class InputMethodService extends AbstractInputMethodService { eet.setInputType(inputType); eet.setHint(mInputEditorInfo.hintText); if (mExtractedText != null) { + eet.setEnabled(true); eet.setExtractedText(mExtractedText); + } else { + eet.setEnabled(false); + eet.setText(""); } } finally { eet.finishInternalChanges(); @@ -1586,7 +1609,8 @@ public class InputMethodService extends AbstractInputMethodService { p.println(" mShowInputRequested=" + mShowInputRequested + " mLastShowInputRequested=" + mLastShowInputRequested - + " mShowInputForced=" + mShowInputForced); + + " mShowInputForced=" + mShowInputForced + + " mShowInputFlags=0x" + Integer.toHexString(mShowInputFlags)); p.println(" mCandidatesVisibility=" + mCandidatesVisibility + " mFullscreenApplied=" + mFullscreenApplied + " mIsFullscreen=" + mIsFullscreen); diff --git a/core/java/android/inputmethodservice/Keyboard.java b/core/java/android/inputmethodservice/Keyboard.java index 228acbe..6a560ce 100755 --- a/core/java/android/inputmethodservice/Keyboard.java +++ b/core/java/android/inputmethodservice/Keyboard.java @@ -132,7 +132,19 @@ public class Keyboard { /** Keyboard mode, or zero, if none. */ private int mKeyboardMode; + + // Variables for pre-computing nearest keys. + private static final int GRID_WIDTH = 10; + private static final int GRID_HEIGHT = 5; + private static final int GRID_SIZE = GRID_WIDTH * GRID_HEIGHT; + private int mCellWidth; + private int mCellHeight; + private int[][] mGridNeighbors; + private int mProximityThreshold; + /** Number of key widths from current touch point to search for nearest keys. */ + private static float SEARCH_DISTANCE = 1.4f; + /** * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate. * Some of the key size defaults can be overridden per row from what the {@link Keyboard} @@ -637,6 +649,52 @@ public class Keyboard { public int getShiftKeyIndex() { return mShiftKeyIndex; } + + private void computeNearestNeighbors() { + // Round-up so we don't have any pixels outside the grid + mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH; + mCellHeight = (getHeight() + GRID_HEIGHT - 1) / GRID_HEIGHT; + mGridNeighbors = new int[GRID_SIZE][]; + int[] indices = new int[mKeys.size()]; + final int gridWidth = GRID_WIDTH * mCellWidth; + final int gridHeight = GRID_HEIGHT * mCellHeight; + for (int x = 0; x < gridWidth; x += mCellWidth) { + for (int y = 0; y < gridHeight; y += mCellHeight) { + int count = 0; + for (int i = 0; i < mKeys.size(); i++) { + final Key key = mKeys.get(i); + if (key.squaredDistanceFrom(x, y) < mProximityThreshold || + key.squaredDistanceFrom(x + mCellWidth - 1, y) < mProximityThreshold || + key.squaredDistanceFrom(x + mCellWidth - 1, y + mCellHeight - 1) + < mProximityThreshold || + key.squaredDistanceFrom(x, y + mCellHeight - 1) < mProximityThreshold) { + indices[count++] = i; + } + } + int [] cell = new int[count]; + System.arraycopy(indices, 0, cell, 0, count); + mGridNeighbors[(y / mCellHeight) * GRID_WIDTH + (x / mCellWidth)] = cell; + } + } + } + + /** + * Returns the indices of the keys that are closest to the given point. + * @param x the x-coordinate of the point + * @param y the y-coordinate of the point + * @return the array of integer indices for the nearest keys to the given point. If the given + * point is out of range, then an array of size zero is returned. + */ + public int[] getNearestKeys(int x, int y) { + if (mGridNeighbors == null) computeNearestNeighbors(); + if (x >= 0 && x < getMinWidth() && y >= 0 && y < getHeight()) { + int index = (y / mCellHeight) * GRID_WIDTH + (x / mCellWidth); + if (index < GRID_SIZE) { + return mGridNeighbors[index]; + } + } + return new int[0]; + } protected Row createRowFromXml(Resources res, XmlResourceParser parser) { return new Row(res, this, parser); @@ -738,6 +796,8 @@ public class Keyboard { mDefaultVerticalGap = getDimensionOrFraction(a, com.android.internal.R.styleable.Keyboard_verticalGap, mDisplayHeight, 0); + mProximityThreshold = (int) (mDefaultWidth * SEARCH_DISTANCE); + mProximityThreshold = mProximityThreshold * mProximityThreshold; // Square it for comparison a.recycle(); } diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java index b8bd10d..886e688 100755 --- a/core/java/android/inputmethodservice/KeyboardView.java +++ b/core/java/android/inputmethodservice/KeyboardView.java @@ -159,6 +159,9 @@ public class KeyboardView extends View implements View.OnClickListener { private static final int MSG_REPEAT = 3; private static final int MSG_LONGPRESS = 4; + private static final int DELAY_BEFORE_PREVIEW = 70; + private static final int DELAY_AFTER_PREVIEW = 60; + private int mVerticalCorrection; private int mProximityThreshold; @@ -219,7 +222,7 @@ public class KeyboardView extends View implements View.OnClickListener { public void handleMessage(Message msg) { switch (msg.what) { case MSG_SHOW_PREVIEW: - mPreviewText.setVisibility(VISIBLE); + showKey(msg.arg1); break; case MSG_REMOVE_PREVIEW: mPreviewText.setVisibility(INVISIBLE); @@ -234,7 +237,6 @@ public class KeyboardView extends View implements View.OnClickListener { openPopupIfRequired((MotionEvent) msg.obj); break; } - } }; @@ -533,10 +535,10 @@ public class KeyboardView extends View implements View.OnClickListener { dimensionSum += Math.min(key.width, key.height) + key.gap; } if (dimensionSum < 0 || length == 0) return; - mProximityThreshold = (int) (dimensionSum * 1.5f / length); + mProximityThreshold = (int) (dimensionSum * 1.4f / length); mProximityThreshold *= mProximityThreshold; // Square it } - + @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); @@ -647,9 +649,10 @@ public class KeyboardView extends View implements View.OnClickListener { int closestKey = NOT_A_KEY; int closestKeyDist = mProximityThreshold + 1; java.util.Arrays.fill(mDistances, Integer.MAX_VALUE); - final int keyCount = keys.length; + int [] nearestKeyIndices = mKeyboard.getNearestKeys(x, y); + final int keyCount = nearestKeyIndices.length; for (int i = 0; i < keyCount; i++) { - final Key key = keys[i]; + final Key key = keys[nearestKeyIndices[i]]; int dist = 0; boolean isInside = key.isInside(x,y); if (((mProximityCorrectOn @@ -660,7 +663,7 @@ public class KeyboardView extends View implements View.OnClickListener { final int nCodes = key.codes.length; if (dist < closestKeyDist) { closestKeyDist = dist; - closestKey = i; + closestKey = nearestKeyIndices[i]; } if (allKeys == null) continue; @@ -674,9 +677,6 @@ public class KeyboardView extends View implements View.OnClickListener { allKeys.length - j - nCodes); for (int c = 0; c < nCodes; c++) { allKeys[j + c] = key.codes[c]; - if (shifted) { - //allKeys[j + c] = Character.toUpperCase(key.codes[c]); - } mDistances[j + c] = dist; } break; @@ -685,7 +685,7 @@ public class KeyboardView extends View implements View.OnClickListener { } if (isInside) { - primaryIndex = i; + primaryIndex = nearestKeyIndices[i]; } } if (primaryIndex == NOT_A_KEY) { @@ -696,7 +696,7 @@ public class KeyboardView extends View implements View.OnClickListener { private void detectAndSendKey(int x, int y, long eventTime) { int index = mCurrentKey; - if (index != NOT_A_KEY) { + if (index != NOT_A_KEY && index < mKeys.length) { final Key key = mKeys[index]; if (key.text != null) { for (int i = 0; i < key.text.length(); i++) { @@ -763,70 +763,83 @@ public class KeyboardView extends View implements View.OnClickListener { if (previewPopup.isShowing()) { if (keyIndex == NOT_A_KEY) { mHandler.sendMessageDelayed(mHandler - .obtainMessage(MSG_REMOVE_PREVIEW), 60); + .obtainMessage(MSG_REMOVE_PREVIEW), + DELAY_AFTER_PREVIEW); } } if (keyIndex != NOT_A_KEY) { - Key key = keys[keyIndex]; - if (key.icon != null) { - mPreviewText.setCompoundDrawables(null, null, null, - key.iconPreview != null ? key.iconPreview : key.icon); - mPreviewText.setText(null); - } else { - mPreviewText.setCompoundDrawables(null, null, null, null); - mPreviewText.setText(getPreviewText(key)); - if (key.label.length() > 1 && key.codes.length < 2) { - mPreviewText.setTextSize(mLabelTextSize); - mPreviewText.setTypeface(Typeface.DEFAULT_BOLD); - } else { - mPreviewText.setTextSize(mPreviewTextSizeLarge); - mPreviewText.setTypeface(Typeface.DEFAULT); - } - } - mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), - MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.width - + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight()); - final int popupHeight = mPreviewHeight; - LayoutParams lp = mPreviewText.getLayoutParams(); - if (lp != null) { - lp.width = popupWidth; - lp.height = popupHeight; - } - if (!mPreviewCentered) { - mPopupPreviewX = key.x - mPreviewText.getPaddingLeft() + mPaddingLeft; - mPopupPreviewY = key.y - popupHeight + mPreviewOffset; - } else { - // TODO: Fix this if centering is brought back - mPopupPreviewX = 160 - mPreviewText.getMeasuredWidth() / 2; - mPopupPreviewY = - mPreviewText.getMeasuredHeight(); - } - mHandler.removeMessages(MSG_REMOVE_PREVIEW); - if (mOffsetInWindow == null) { - mOffsetInWindow = new int[2]; - getLocationInWindow(mOffsetInWindow); - mOffsetInWindow[0] += mMiniKeyboardOffsetX; // Offset may be zero - mOffsetInWindow[1] += mMiniKeyboardOffsetY; // Offset may be zero - } - // Set the preview background state - mPreviewText.getBackground().setState( - key.popupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET); - if (previewPopup.isShowing()) { - previewPopup.update(mPopupPreviewX + mOffsetInWindow[0], - mPopupPreviewY + mOffsetInWindow[1], - popupWidth, popupHeight); + if (previewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) { + // Show right away, if it's already visible and finger is moving around + showKey(keyIndex); } else { - previewPopup.setWidth(popupWidth); - previewPopup.setHeight(popupHeight); - previewPopup.showAtLocation(mPopupParent, Gravity.NO_GRAVITY, - mPopupPreviewX + mOffsetInWindow[0], - mPopupPreviewY + mOffsetInWindow[1]); + mHandler.sendMessageDelayed( + mHandler.obtainMessage(MSG_SHOW_PREVIEW, keyIndex, 0), + DELAY_BEFORE_PREVIEW); } - mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_PREVIEW, keyIndex, 0), - ViewConfiguration.getTapTimeout()); } } } + + private void showKey(final int keyIndex) { + final PopupWindow previewPopup = mPreviewPopup; + final Key[] keys = mKeys; + Key key = keys[keyIndex]; + if (key.icon != null) { + mPreviewText.setCompoundDrawables(null, null, null, + key.iconPreview != null ? key.iconPreview : key.icon); + mPreviewText.setText(null); + } else { + mPreviewText.setCompoundDrawables(null, null, null, null); + mPreviewText.setText(getPreviewText(key)); + if (key.label.length() > 1 && key.codes.length < 2) { + mPreviewText.setTextSize(mLabelTextSize); + mPreviewText.setTypeface(Typeface.DEFAULT_BOLD); + } else { + mPreviewText.setTextSize(mPreviewTextSizeLarge); + mPreviewText.setTypeface(Typeface.DEFAULT); + } + } + mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); + int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.width + + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight()); + final int popupHeight = mPreviewHeight; + LayoutParams lp = mPreviewText.getLayoutParams(); + if (lp != null) { + lp.width = popupWidth; + lp.height = popupHeight; + } + if (!mPreviewCentered) { + mPopupPreviewX = key.x - mPreviewText.getPaddingLeft() + mPaddingLeft; + mPopupPreviewY = key.y - popupHeight + mPreviewOffset; + } else { + // TODO: Fix this if centering is brought back + mPopupPreviewX = 160 - mPreviewText.getMeasuredWidth() / 2; + mPopupPreviewY = - mPreviewText.getMeasuredHeight(); + } + mHandler.removeMessages(MSG_REMOVE_PREVIEW); + if (mOffsetInWindow == null) { + mOffsetInWindow = new int[2]; + getLocationInWindow(mOffsetInWindow); + mOffsetInWindow[0] += mMiniKeyboardOffsetX; // Offset may be zero + mOffsetInWindow[1] += mMiniKeyboardOffsetY; // Offset may be zero + } + // Set the preview background state + mPreviewText.getBackground().setState( + key.popupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET); + if (previewPopup.isShowing()) { + previewPopup.update(mPopupPreviewX + mOffsetInWindow[0], + mPopupPreviewY + mOffsetInWindow[1], + popupWidth, popupHeight); + } else { + previewPopup.setWidth(popupWidth); + previewPopup.setHeight(popupHeight); + previewPopup.showAtLocation(mPopupParent, Gravity.NO_GRAVITY, + mPopupPreviewX + mOffsetInWindow[0], + mPopupPreviewY + mOffsetInWindow[1]); + } + mPreviewText.setVisibility(VISIBLE); + } private void invalidateKey(int keyIndex) { if (keyIndex < 0 || keyIndex >= mKeys.length) { diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 017b14d..6f9d6c6 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -1,18 +1,20 @@ package android.os; -import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Formatter; import java.util.Map; +import android.util.Log; +import android.util.Printer; import android.util.SparseArray; /** * A class providing access to battery usage statistics, including information on * wakelocks, processes, packages, and services. All times are represented in microseconds * except where indicated otherwise. + * @hide */ -public abstract class BatteryStats { +public abstract class BatteryStats implements Parcelable { /** * A constant indicating a partial wake lock timer. @@ -96,6 +98,11 @@ public abstract class BatteryStats { * @return a time in microseconds */ public abstract long getTotalTime(long now, int which); + + /** + * Temporary for debugging. + */ + public abstract void logState(); } /** @@ -154,10 +161,10 @@ public abstract class BatteryStats { public abstract long getTcpBytesSent(int which); public static abstract class Sensor { - /** - * {@hide} - */ - public abstract String getName(); + // Magic sensor number for the GPS. + public static final int GPS = -10000; + + public abstract int getHandle(); public abstract Timer getSensorTime(); } @@ -260,6 +267,11 @@ public abstract class BatteryStats { public abstract long getPluggedScreenOnTime(); /** + * Return whether we are currently running on battery. + */ + public abstract boolean getIsOnBattery(); + + /** * Returns a SparseArray containing the statistics for each uid. */ public abstract SparseArray<? extends Uid> getUidStats(); @@ -457,7 +469,7 @@ public abstract class BatteryStats { * @param pw * @param which */ - private final void dumpCheckinLocked(FileDescriptor fd, PrintWriter pw, int which) { + private final void dumpCheckinLocked(PrintWriter pw, int which) { long uSecTime = SystemClock.elapsedRealtime() * 1000; final long uSecNow = getBatteryUptime(uSecTime); @@ -578,35 +590,18 @@ public abstract class BatteryStats { } @SuppressWarnings("unused") - private final void dumpLocked(FileDescriptor fd, PrintWriter pw, String prefix, int which) { + private final void dumpLocked(Printer pw, String prefix, int which) { long uSecTime = SystemClock.elapsedRealtime() * 1000; final long uSecNow = getBatteryUptime(uSecTime); StringBuilder sb = new StringBuilder(128); - switch (which) { - case STATS_TOTAL: - pw.println(prefix + "Current and Historic Battery Usage Statistics:"); - pw.println(prefix + " System starts: " + getStartCount()); - break; - case STATS_LAST: - pw.println(prefix + "Last Battery Usage Statistics:"); - break; - case STATS_UNPLUGGED: - pw.println(prefix + "Last Unplugged Battery Usage Statistics:"); - break; - case STATS_CURRENT: - pw.println(prefix + "Current Battery Usage Statistics:"); - break; - default: - throw new IllegalArgumentException("which = " + which); - } long batteryUptime = computeBatteryUptime(uSecNow, which); long batteryRealtime = computeBatteryRealtime(getBatteryRealtime(uSecTime), which); long elapsedRealtime = computeRealtime(uSecTime, which); long uptime = computeUptime(SystemClock.uptimeMillis() * 1000, which); pw.println(prefix - + " On battery: " + formatTimeMs(batteryUptime / 1000) + "(" + + " Time on battery: " + formatTimeMs(batteryUptime / 1000) + "(" + formatRatioLocked(batteryUptime, elapsedRealtime) + ") uptime, " + formatTimeMs(batteryRealtime / 1000) + "(" @@ -618,7 +613,7 @@ public abstract class BatteryStats { + "uptime, " + formatTimeMs(elapsedRealtime / 1000) + "realtime"); - + pw.println(" "); SparseArray<? extends Uid> uidStats = getUidStats(); @@ -629,8 +624,12 @@ public abstract class BatteryStats { pw.println(prefix + " #" + uid + ":"); boolean uidActivity = false; - pw.println(prefix + " Network: " + u.getTcpBytesReceived(which) + " bytes received, " - + u.getTcpBytesSent(which) + " bytes sent"); + long tcpReceived = u.getTcpBytesReceived(which); + long tcpSent = u.getTcpBytesSent(which); + if (tcpReceived != 0 || tcpSent != 0) { + pw.println(prefix + " Network: " + tcpReceived + " bytes received, " + + tcpSent + " bytes sent"); + } Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats(); if (wakelocks.size() > 0) { @@ -648,7 +647,9 @@ public abstract class BatteryStats { "partial", which, linePrefix); linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), uSecNow, "window", which, linePrefix); - if (linePrefix.equals(": ")) { + if (!linePrefix.equals(": ")) { + sb.append(" realtime"); + } else { sb.append(": (nothing executed)"); } pw.println(sb.toString()); @@ -665,23 +666,30 @@ public abstract class BatteryStats { sb.setLength(0); sb.append(prefix); sb.append(" Sensor "); - sb.append(sensorNumber); + int handle = se.getHandle(); + if (handle == Uid.Sensor.GPS) { + sb.append("GPS"); + } else { + sb.append(handle); + } + sb.append(": "); Timer timer = se.getSensorTime(); if (timer != null) { // Convert from microseconds to milliseconds with rounding long totalTime = (timer.getTotalTime(uSecNow, which) + 500) / 1000; int count = timer.getCount(which); + //timer.logState(); if (totalTime != 0) { - sb.append(": "); sb.append(formatTimeMs(totalTime)); - sb.append(' '); - sb.append('('); + sb.append("realtime ("); sb.append(count); sb.append(" times)"); + } else { + sb.append("(not used)"); } } else { - sb.append(": (none used)"); + sb.append("(not used)"); } pw.println(sb.toString()); @@ -734,8 +742,9 @@ public abstract class BatteryStats { int launches = ss.getLaunches(which); if (startTime != 0 || starts != 0 || launches != 0) { pw.println(prefix + " Service " + sent.getKey() + ":"); - pw.println(prefix + " Time spent started: " - + formatTimeMs(startTime / 1000)); + pw.println(prefix + " Created for: " + + formatTimeMs(startTime / 1000) + + " uptime"); pw.println(prefix + " Starts: " + starts + ", launches: " + launches); apkActivity = true; @@ -757,36 +766,30 @@ public abstract class BatteryStats { /** * Dumps a human-readable summary of the battery statistics to the given PrintWriter. * - * @param fd a FileDescriptor, currently unused. - * @param pw a PrintWriter to receive the dump output. - * @param args an array of Strings, currently unused. + * @param pw a Printer to receive the dump output. */ @SuppressWarnings("unused") - public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) { - boolean isCheckin = false; - if (args != null) { - for (String arg : args) { - if ("-c".equals(arg)) { - isCheckin = true; - break; - } - } - } - synchronized (this) { - if (isCheckin) { - dumpCheckinLocked(fd, pw, STATS_TOTAL); - dumpCheckinLocked(fd, pw, STATS_LAST); - dumpCheckinLocked(fd, pw, STATS_UNPLUGGED); - dumpCheckinLocked(fd, pw, STATS_CURRENT); - } else { - dumpLocked(fd, pw, "", STATS_TOTAL); - pw.println(""); - dumpLocked(fd, pw, "", STATS_LAST); - pw.println(""); - dumpLocked(fd, pw, "", STATS_UNPLUGGED); - pw.println(""); - dumpLocked(fd, pw, "", STATS_CURRENT); - } - } + public void dumpLocked(Printer pw) { + pw.println("Total Statistics (Current and Historic):"); + pw.println(" System starts: " + getStartCount() + + ", currently on battery: " + getIsOnBattery()); + dumpLocked(pw, "", STATS_TOTAL); + pw.println(""); + pw.println("Last Run Statistics (Previous run of system):"); + dumpLocked(pw, "", STATS_LAST); + pw.println(""); + pw.println("Current Battery Statistics (Currently running system):"); + dumpLocked(pw, "", STATS_CURRENT); + pw.println(""); + pw.println("Unplugged Statistics (Since last unplugged from power):"); + dumpLocked(pw, "", STATS_UNPLUGGED); + } + + @SuppressWarnings("unused") + public void dumpCheckinLocked(PrintWriter pw, String[] args) { + dumpCheckinLocked(pw, STATS_TOTAL); + dumpCheckinLocked(pw, STATS_LAST); + dumpCheckinLocked(pw, STATS_UNPLUGGED); + dumpCheckinLocked(pw, STATS_CURRENT); } } diff --git a/core/java/android/os/ICheckinService.aidl b/core/java/android/os/ICheckinService.aidl index 11becc4..e56b55d 100644 --- a/core/java/android/os/ICheckinService.aidl +++ b/core/java/android/os/ICheckinService.aidl @@ -26,7 +26,13 @@ import android.os.IParentalControlCallback; * {@hide} */ interface ICheckinService { - /** Synchronously attempt a checkin with the server, return true on success. */ + /** Synchronously attempt a checkin with the server, return true + * on success. + * @throws IllegalStateException whenever an error occurs. The + * cause of the exception will be the real exception: + * IOException for network errors, JSONException for invalid + * server responses, etc. + */ boolean checkin(); /** Direct submission of crash data; returns after writing the crash. */ diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index e48f152..5486920 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -29,4 +29,5 @@ interface IPowerManager void setStayOnSetting(int val); long getScreenOnTime(); void preventScreenOn(boolean prevent); + void setScreenBrightnessOverride(int brightness); } diff --git a/core/java/android/preference/PreferenceGroupAdapter.java b/core/java/android/preference/PreferenceGroupAdapter.java index 02ab1da..14c0054 100644 --- a/core/java/android/preference/PreferenceGroupAdapter.java +++ b/core/java/android/preference/PreferenceGroupAdapter.java @@ -242,7 +242,7 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn mHasReturnedViewTypeCount = true; } - return mPreferenceClassNames.size(); + return Math.max(1, mPreferenceClassNames.size()); } } diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java index 5767c65..688e19a 100644 --- a/core/java/android/provider/Checkin.java +++ b/core/java/android/provider/Checkin.java @@ -97,6 +97,7 @@ public final class Checkin { SETUP_RETRIES_EXHAUSTED, SETUP_SERVER_ERROR, SETUP_SERVER_TIMEOUT, + SETUP_NO_DATA_NETWORK, SYSTEM_APP_NOT_RESPONDING, SYSTEM_BOOT, SYSTEM_LAST_KMSG, diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index c6a7b40..4a784c8 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2321,6 +2321,13 @@ public final class Settings { public static final String GMAIL_SEND_IMMEDIATELY = "gmail_send_immediately"; /** + * Controls whether gmail buffers server responses. Possible values are "memory", for a + * memory-based buffer, or "file", for a temp-file-based buffer. All other values + * (including not set) disable buffering. + */ + public static final String GMAIL_BUFFER_SERVER_RESPONSE = "gmail_buffer_server_response"; + + /** * Hostname of the GTalk server. */ public static final String GTALK_SERVICE_HOSTNAME = "gtalk_hostname"; diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java index 7c15045..86d5a1e 100644 --- a/core/java/android/server/BluetoothDeviceService.java +++ b/core/java/android/server/BluetoothDeviceService.java @@ -111,9 +111,19 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub { private native int isEnabledNative(); /** - * Disable bluetooth. Returns true on success. + * Bring down bluetooth and disable BT in settings. Returns true on success. */ - public synchronized boolean disable() { + public boolean disable() { + return disable(true); + } + + /** + * Bring down bluetooth. Returns true on success. + * + * @param saveSetting If true, disable BT in settings + * + */ + public synchronized boolean disable(boolean saveSetting) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); @@ -137,7 +147,9 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub { mContext.sendBroadcast(intent, BLUETOOTH_PERM); mIsEnabled = false; - persistBluetoothOnSetting(false); + if (saveSetting) { + persistBluetoothOnSetting(false); + } mIsDiscovering = false; intent = new Intent(BluetoothIntent.DISABLED_ACTION); mContext.sendBroadcast(intent, BLUETOOTH_PERM); @@ -145,13 +157,27 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub { } /** + * Bring up bluetooth, asynchronously, and enable BT in settings. + * This turns on/off the underlying hardware. + * + * @return True on success (so far), guaranteeing the callback with be + * notified when complete. + */ + public boolean enable(IBluetoothDeviceCallback callback) { + return enable(callback, true); + } + + /** * Enable this Bluetooth device, asynchronously. * This turns on/off the underlying hardware. * - * @return True on success (so far), guarenteeing the callback with be + * @param saveSetting If true, enable BT in settings + * + * @return True on success (so far), guaranteeing the callback with be * notified when complete. */ - public synchronized boolean enable(IBluetoothDeviceCallback callback) { + public synchronized boolean enable(IBluetoothDeviceCallback callback, + boolean saveSetting) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); @@ -165,7 +191,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub { if (mEnableThread != null && mEnableThread.isAlive()) { return false; } - mEnableThread = new EnableThread(callback); + mEnableThread = new EnableThread(callback, saveSetting); mEnableThread.start(); return true; } @@ -189,8 +215,10 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub { private class EnableThread extends Thread { private final IBluetoothDeviceCallback mEnableCallback; - public EnableThread(IBluetoothDeviceCallback callback) { + private final boolean mSaveSetting; + public EnableThread(IBluetoothDeviceCallback callback, boolean saveSetting) { mEnableCallback = callback; + mSaveSetting = saveSetting; } public void run() { boolean res = (enableNative() == 0); @@ -208,7 +236,9 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub { if (res) { mIsEnabled = true; - persistBluetoothOnSetting(true); + if (mSaveSetting) { + persistBluetoothOnSetting(true); + } mIsDiscovering = false; Intent intent = new Intent(BluetoothIntent.ENABLED_ACTION); mBondState.loadBondState(); @@ -952,9 +982,9 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub { // If bluetooth is currently expected to be on, then enable or disable bluetooth if (Settings.Secure.getInt(resolver, Settings.Secure.BLUETOOTH_ON, 0) > 0) { if (enabled) { - enable(null); + enable(null, false); } else { - disable(); + disable(false); } } } diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java index b5e4090..187ec2c 100644 --- a/core/java/android/server/BluetoothEventLoop.java +++ b/core/java/android/server/BluetoothEventLoop.java @@ -359,10 +359,10 @@ class BluetoothEventLoop { private void onGetRemoteServiceChannelResult(String address, int channel) { IBluetoothDeviceCallback callback = mGetRemoteServiceChannelCallbacks.get(address); if (callback != null) { + mGetRemoteServiceChannelCallbacks.remove(address); try { callback.onGetRemoteServiceChannelResult(address, channel); } catch (RemoteException e) {} - mGetRemoteServiceChannelCallbacks.remove(address); } } diff --git a/core/java/android/speech/srec/MicrophoneInputStream.java b/core/java/android/speech/srec/MicrophoneInputStream.java index 160a003..fab77a9 100644 --- a/core/java/android/speech/srec/MicrophoneInputStream.java +++ b/core/java/android/speech/srec/MicrophoneInputStream.java @@ -1,5 +1,5 @@ /*---------------------------------------------------------------------------* - * MicrophoneInputStream.java * + * MicrophoneInputStream.java * * * * Copyright 2007 Nuance Communciations, Inc. * * * @@ -45,8 +45,12 @@ public final class MicrophoneInputStream extends InputStream { */ public MicrophoneInputStream(int sampleRate, int fifoDepth) throws IOException { mAudioRecord = AudioRecordNew(sampleRate, fifoDepth); - if (mAudioRecord == 0) throw new IllegalStateException("not open"); - AudioRecordStart(mAudioRecord); + if (mAudioRecord == 0) throw new IOException("AudioRecord constructor failed - busy?"); + int status = AudioRecordStart(mAudioRecord); + if (status != 0) { + close(); + throw new IOException("AudioRecord start failed: " + status); + } } @Override @@ -99,7 +103,7 @@ public final class MicrophoneInputStream extends InputStream { // AudioRecord JNI interface // private static native int AudioRecordNew(int sampleRate, int fifoDepth); - private static native void AudioRecordStart(int audioRecord); + private static native int AudioRecordStart(int audioRecord); private static native int AudioRecordRead(int audioRecord, byte[] b, int offset, int length) throws IOException; private static native void AudioRecordStop(int audioRecord) throws IOException; private static native void AudioRecordDelete(int audioRecord) throws IOException; diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java index 5bf9b20..daa99c2 100644 --- a/core/java/android/text/format/Time.java +++ b/core/java/android/text/format/Time.java @@ -394,6 +394,7 @@ public class Time { * * @param s the string to parse * @return true if the resulting time value is in UTC time + * @throws android.util.TimeFormatException if s cannot be parsed. */ public boolean parse(String s) { if (nativeParse(s)) { diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java index 2eebc0d..efb88a0 100644 --- a/core/java/android/text/style/ImageSpan.java +++ b/core/java/android/text/style/ImageSpan.java @@ -44,8 +44,9 @@ public class ImageSpan extends DynamicDrawableSpan { public ImageSpan(Bitmap b, int verticalAlignment) { super(verticalAlignment); mDrawable = new BitmapDrawable(b); - mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(), - mDrawable.getIntrinsicHeight()); + int width = mDrawable.getIntrinsicWidth(); + int height = mDrawable.getIntrinsicHeight(); + mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0); } public ImageSpan(Drawable d) { diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java index 610cfd4..9ab3b53 100644 --- a/core/java/android/util/SparseIntArray.java +++ b/core/java/android/util/SparseIntArray.java @@ -73,13 +73,20 @@ public class SparseIntArray { int i = binarySearch(mKeys, 0, mSize, key); if (i >= 0) { - System.arraycopy(mKeys, i + 1, mKeys, i, mSize - (i + 1)); - System.arraycopy(mValues, i + 1, mValues, i, mSize - (i + 1)); - mSize--; + removeAt(i); } } /** + * Removes the mapping at the given index. + */ + public void removeAt(int index) { + System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1)); + System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1)); + mSize--; + } + + /** * Adds a mapping from the specified key to the specified value, * replacing the previous mapping from the specified key if there * was one. diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java index a472689..679c683 100644 --- a/core/java/android/view/GestureDetector.java +++ b/core/java/android/view/GestureDetector.java @@ -163,7 +163,7 @@ public class GestureDetector { private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout(); // TODO make new double-tap timeout, and define its events (i.e. either time // between down-down or time between up-down) - private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getJumpTapTimeout(); + private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout(); // constants for Message.what used by GestureHandler below private static final int SHOW_PRESS = 1; @@ -174,11 +174,13 @@ public class GestureDetector { private final OnGestureListener mListener; private OnDoubleTapListener mDoubleTapListener; + private boolean mStillDown; private boolean mInLongPress; private boolean mAlwaysInTapRegion; private boolean mAlwaysInBiggerTapRegion; private MotionEvent mCurrentDownEvent; + private MotionEvent mPreviousUpEvent; /** * True when the user is still touching for the second tap (down, move, and @@ -217,7 +219,8 @@ public class GestureDetector { break; case TAP: - if (mDoubleTapListener != null) { + // If the user's finger is still down, do not count it as a tap + if (mDoubleTapListener != null && !mStillDown) { mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent); } break; @@ -378,8 +381,10 @@ public class GestureDetector { switch (action) { case MotionEvent.ACTION_DOWN: if (mDoubleTapListener != null) { - mHandler.removeMessages(TAP); - if (mCurrentDownEvent != null && isConsideredDoubleTap(mCurrentDownEvent, ev)) { + boolean hadTapMessage = mHandler.hasMessages(TAP); + if (hadTapMessage) mHandler.removeMessages(TAP); + if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage && + isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) { // This is a second tap mIsDoubleTapping = true; handled = mDoubleTapListener.onDoubleTapEvent(ev); @@ -394,6 +399,7 @@ public class GestureDetector { mCurrentDownEvent = MotionEvent.obtain(ev); mAlwaysInTapRegion = true; mAlwaysInBiggerTapRegion = true; + mStillDown = true; mInLongPress = false; if (mIsLongpressEnabled) { @@ -422,6 +428,7 @@ public class GestureDetector { mLastMotionX = x; mLastMotionY = y; mAlwaysInTapRegion = false; + mHandler.removeMessages(TAP); mHandler.removeMessages(SHOW_PRESS); mHandler.removeMessages(LONG_PRESS); } @@ -436,6 +443,7 @@ public class GestureDetector { break; case MotionEvent.ACTION_UP: + mStillDown = false; MotionEvent currentUpEvent = MotionEvent.obtain(ev); if (mIsDoubleTapping) { handled = mDoubleTapListener.onDoubleTapEvent(ev); @@ -461,6 +469,7 @@ public class GestureDetector { handled = mListener.onFling(mCurrentDownEvent, currentUpEvent, velocityX, velocityY); } } + mPreviousUpEvent = MotionEvent.obtain(ev); mVelocityTracker.recycle(); mVelocityTracker = null; mHandler.removeMessages(SHOW_PRESS); @@ -472,6 +481,7 @@ public class GestureDetector { mHandler.removeMessages(TAP); mVelocityTracker.recycle(); mVelocityTracker = null; + mStillDown = false; if (mInLongPress) { mInLongPress = false; break; @@ -480,12 +490,13 @@ public class GestureDetector { return handled; } - private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent secondDown) { + private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent firstUp, + MotionEvent secondDown) { if (!mAlwaysInBiggerTapRegion) { return false; } - if (secondDown.getEventTime() - firstDown.getEventTime() > DOUBLE_TAP_TIMEOUT) { + if (secondDown.getEventTime() - firstUp.getEventTime() > DOUBLE_TAP_TIMEOUT) { return false; } @@ -495,6 +506,7 @@ public class GestureDetector { } private void dispatchLongPress() { + mHandler.removeMessages(TAP); mInLongPress = true; mListener.onLongPress(mCurrentDownEvent); } diff --git a/core/java/android/view/OrientationEventListener.java b/core/java/android/view/OrientationEventListener.java new file mode 100755 index 0000000..cddec11 --- /dev/null +++ b/core/java/android/view/OrientationEventListener.java @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.util.Config; +import android.util.Log; + +/** + * Helper class for receiving notifications from the SensorManager when + * the orientation of the device has changed. + */ +public abstract class OrientationEventListener { + private static final String TAG = "OrientationEventListener"; + private static final boolean DEBUG = false; + private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; + private int mOrientation = ORIENTATION_UNKNOWN; + private SensorManager mSensorManager; + private boolean mEnabled = false; + private int mRate; + private Sensor mSensor; + private SensorEventListener mSensorEventListener; + private OrientationListener mOldListener; + + /** + * Returned from onOrientationChanged when the device orientation cannot be determined + * (typically when the device is in a close to flat position). + * + * @see #onOrientationChanged + */ + public static final int ORIENTATION_UNKNOWN = -1; + + /** + * Creates a new OrientationEventListener. + * + * @param context for the OrientationEventListener. + */ + public OrientationEventListener(Context context) { + this(context, SensorManager.SENSOR_DELAY_NORMAL); + } + + /** + * Creates a new OrientationEventListener. + * + * @param context for the OrientationEventListener. + * @param rate at which sensor events are processed (see also + * {@link android.hardware.SensorManager SensorManager}). Use the default + * value of {@link android.hardware.SensorManager#SENSOR_DELAY_NORMAL + * SENSOR_DELAY_NORMAL} for simple screen orientation change detection. + */ + public OrientationEventListener(Context context, int rate) { + mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); + mRate = rate; + mSensorEventListener = new SensorEventListenerImpl(); + mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + } + + void registerListener(OrientationListener lis) { + mOldListener = lis; + } + + /** + * Enables the OrientationEventListener so it will monitor the sensor and call + * {@link #onOrientationChanged} when the device orientation changes. + */ + public void enable() { + if (mEnabled == false) { + if (localLOGV) Log.d(TAG, "OrientationEventListener enabled"); + mSensorManager.registerListener(mSensorEventListener, mSensor, mRate); + mEnabled = true; + } + } + + /** + * Disables the OrientationEventListener. + */ + public void disable() { + if (mEnabled == true) { + if (localLOGV) Log.d(TAG, "OrientationEventListener disabled"); + mSensorManager.unregisterListener(mSensorEventListener); + mEnabled = false; + } + } + + class SensorEventListenerImpl implements SensorEventListener { + private static final int _DATA_X = 0; + private static final int _DATA_Y = 1; + private static final int _DATA_Z = 2; + + public void onSensorChanged(SensorEvent event) { + float[] values = event.values; + int orientation = ORIENTATION_UNKNOWN; + float X = -values[_DATA_X]; + float Y = -values[_DATA_Y]; + float Z = -values[_DATA_Z]; + float magnitude = X*X + Y*Y; + // Don't trust the angle if the magnitude is small compared to the y value + if (magnitude * 4 >= Z*Z) { + float OneEightyOverPi = 57.29577957855f; + float angle = (float)Math.atan2(-Y, X) * OneEightyOverPi; + orientation = 90 - (int)Math.round(angle); + // normalize to 0 - 359 range + while (orientation >= 360) { + orientation -= 360; + } + while (orientation < 0) { + orientation += 360; + } + } + if (mOldListener != null) { + mOldListener.onSensorChanged(Sensor.TYPE_ACCELEROMETER, event.values); + } + if (orientation != mOrientation) { + mOrientation = orientation; + onOrientationChanged(orientation); + } + } + + public void onAccuracyChanged(Sensor sensor, int accuracy) { + + } + } + + /** + * Called when the orientation of the device has changed. + * orientation parameter is in degrees, ranging from 0 to 359. + * orientation is 0 degrees when the device is oriented in its natural position, + * 90 degrees when its left side is at the top, 180 degrees when it is upside down, + * and 270 degrees when its right side is to the top. + * {@link #ORIENTATION_UNKNOWN} is returned when the device is close to flat + * and the orientation cannot be determined. + * + * @param orientation The new orientation of the device. + * + * @see #ORIENTATION_UNKNOWN + */ + abstract public void onOrientationChanged(int orientation); +} diff --git a/core/java/android/view/OrientationListener.java b/core/java/android/view/OrientationListener.java index 974c2e8..ce8074e 100644 --- a/core/java/android/view/OrientationListener.java +++ b/core/java/android/view/OrientationListener.java @@ -18,23 +18,16 @@ package android.view; import android.content.Context; import android.hardware.SensorListener; -import android.hardware.SensorManager; -import android.util.Config; -import android.util.Log; /** * Helper class for receiving notifications from the SensorManager when * the orientation of the device has changed. + * @deprecated use {@link android.view.OrientationEventListener} instead. + * This class internally uses the OrientationEventListener. */ +@Deprecated public abstract class OrientationListener implements SensorListener { - - private static final String TAG = "OrientationListener"; - private static final boolean DEBUG = false; - private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; - private SensorManager mSensorManager; - private int mOrientation = ORIENTATION_UNKNOWN; - private boolean mEnabled = false; - private int mRate; + private OrientationEventListener mOrientationEventLis; /** * Returned from onOrientationChanged when the device orientation cannot be determined @@ -42,7 +35,7 @@ public abstract class OrientationListener implements SensorListener { * * @see #onOrientationChanged */ - public static final int ORIENTATION_UNKNOWN = -1; + public static final int ORIENTATION_UNKNOWN = OrientationEventListener.ORIENTATION_UNKNOWN; /** * Creates a new OrientationListener. @@ -50,8 +43,7 @@ public abstract class OrientationListener implements SensorListener { * @param context for the OrientationListener. */ public OrientationListener(Context context) { - mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); - mRate = SensorManager.SENSOR_DELAY_NORMAL; + mOrientationEventLis = new OrientationEventListenerInternal(context); } /** @@ -64,78 +56,55 @@ public abstract class OrientationListener implements SensorListener { * SENSOR_DELAY_NORMAL} for simple screen orientation change detection. */ public OrientationListener(Context context, int rate) { - mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); - mRate = rate; + mOrientationEventLis = new OrientationEventListenerInternal(context, rate); } - + + class OrientationEventListenerInternal extends OrientationEventListener { + OrientationEventListenerInternal(Context context) { + super(context); + } + + OrientationEventListenerInternal(Context context, int rate) { + super(context, rate); + // register so that onSensorChanged gets invoked + registerListener(OrientationListener.this); + } + + public void onOrientationChanged(int orientation) { + OrientationListener.this.onOrientationChanged(orientation); + } + } + /** * Enables the OrientationListener so it will monitor the sensor and call * {@link #onOrientationChanged} when the device orientation changes. */ public void enable() { - if (mEnabled == false) { - if (localLOGV) Log.d(TAG, "OrientationListener enabled"); - mSensorManager.registerListener(this, SensorManager.SENSOR_ACCELEROMETER, mRate); - mEnabled = true; - } + mOrientationEventLis.enable(); } /** * Disables the OrientationListener. */ public void disable() { - if (mEnabled == true) { - if (localLOGV) Log.d(TAG, "OrientationListener disabled"); - mSensorManager.unregisterListener(this); - mEnabled = false; - } + mOrientationEventLis.disable(); } - - /** - * - */ + + public void onAccuracyChanged(int sensor, int accuracy) { + } + public void onSensorChanged(int sensor, float[] values) { - int orientation = ORIENTATION_UNKNOWN; - float X = values[SensorManager.RAW_DATA_X]; - float Y = values[SensorManager.RAW_DATA_Y]; - float Z = values[SensorManager.RAW_DATA_Z]; - float magnitude = X*X + Y*Y; - // Don't trust the angle if the magnitude is small compared to the y value - if (magnitude * 4 >= Z*Z) { - float OneEightyOverPi = 57.29577957855f; - float angle = (float)Math.atan2(-Y, X) * OneEightyOverPi; - orientation = 90 - (int)Math.round(angle); - // normalize to 0 - 359 range - while (orientation >= 360) { - orientation -= 360; - } - while (orientation < 0) { - orientation += 360; - } - } - - if (orientation != mOrientation) { - mOrientation = orientation; - onOrientationChanged(orientation); - } + // just ignore the call here onOrientationChanged is invoked anyway } - public void onAccuracyChanged(int sensor, int accuracy) { - // TODO Auto-generated method stub - } /** - * Called when the orientation of the device has changed. - * orientation parameter is in degrees, ranging from 0 to 359. - * orientation is 0 degrees when the device is oriented in its natural position, - * 90 degrees when its left side is at the top, 180 degrees when it is upside down, - * and 270 degrees when its right side is to the top. - * {@link #ORIENTATION_UNKNOWN} is returned when the device is close to flat - * and the orientation cannot be determined. - * + * Look at {@link android.view.OrientationEventListener#onOrientationChanged} + * for method description and usage * @param orientation The new orientation of the device. * * @see #ORIENTATION_UNKNOWN */ abstract public void onOrientationChanged(int orientation); + } diff --git a/core/java/android/os/HandlerInterface.java b/core/java/android/view/RemotableViewMethod.java index 62dc273..4318290 100644 --- a/core/java/android/os/HandlerInterface.java +++ b/core/java/android/view/RemotableViewMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 The Android Open Source Project + * 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. @@ -14,14 +14,22 @@ * limitations under the License. */ -package android.os; +package android.view; -/** - * @hide - * @deprecated +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @hide + * This annotation indicates that a method on a subclass of View + * is alllowed to be used with the {@link android.widget.RemoteViews} mechanism. */ -public interface HandlerInterface -{ - void handleMessage(Message msg); +@Target({ ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface RemotableViewMethod { } + + diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1d5e7cd..5ed3a7e 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2674,6 +2674,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback { * @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}. * @attr ref android.R.styleable#View_visibility */ + @RemotableViewMethod public void setVisibility(int visibility) { setFlags(visibility, VISIBILITY_MASK); if (mBGDrawable != null) mBGDrawable.setVisible(visibility == VISIBLE, false); @@ -4016,6 +4017,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback { */ protected void onScrollChanged(int l, int t, int oldl, int oldt) { mBackgroundSizeChanged = true; + + final AttachInfo ai = mAttachInfo; + if (ai != null) { + ai.mViewScrollChanged = true; + } } /** @@ -7948,6 +7954,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback { boolean mViewVisibilityChanged; /** + * Set to true if a view has been scrolled. + */ + boolean mViewScrollChanged; + + /** * Global to the view hierarchy used as a temporary for dealing with * x/y points in the transparent region computations. */ diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 7153ea1..2f7b0d1 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -67,6 +67,13 @@ public class ViewConfiguration { * considered to be a tap. */ private static final int JUMP_TAP_TIMEOUT = 500; + + /** + * Defines the duration in milliseconds between the first tap's up event and + * the second tap's down event for an interaction to be considered a + * double-tap. + */ + private static final int DOUBLE_TAP_TIMEOUT = 300; /** * Defines the duration in milliseconds we want to display zoom controls in response @@ -82,7 +89,7 @@ public class ViewConfiguration { /** * Distance a touch can wander before we think the user is scrolling in pixels */ - private static final int TOUCH_SLOP = 12; + private static final int TOUCH_SLOP = 25; /** * Distance between the first touch and second touch to still be considered a double tap @@ -257,6 +264,16 @@ public class ViewConfiguration { } /** + * @return Defines the duration in milliseconds between the first tap's up event and + * the second tap's down event for an interaction to be considered a + * double-tap. + * @hide pending API council + */ + public static int getDoubleTapTimeout() { + return DOUBLE_TAP_TIMEOUT; + } + + /** * @return Inset in pixels to look for touchable content when the user touches the edge of the * screen * diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index c758662..70cc2a9 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -27,6 +27,7 @@ import android.graphics.Rect; import android.graphics.Region; import android.graphics.RectF; import android.os.Parcelable; +import android.os.SystemClock; import android.util.AttributeSet; import android.util.EventLog; import android.util.Log; @@ -1023,6 +1024,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ @Override void dispatchDetachedFromWindow() { + // If we still have a motion target, we are still in the process of + // dispatching motion events to a child; we need to get rid of that + // child to avoid dispatching events to it after the window is torn + // down. To make sure we keep the child in a consistent state, we + // first send it an ACTION_CANCEL motion event. + if (mMotionTarget != null) { + final long now = SystemClock.uptimeMillis(); + final MotionEvent event = MotionEvent.obtain(now, now, + MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0); + mMotionTarget.dispatchTouchEvent(event); + event.recycle(); + mMotionTarget = null; + } + final int count = mChildrenCount; final View[] children = mChildren; for (int i = 0; i < count; i++) { @@ -1331,6 +1346,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final Animation a = child.getAnimation(); boolean concatMatrix = false; + final int childWidth = cr - cl; + final int childHeight = cb - ct; + if (a != null) { if (mInvalidateRegion == null) { mInvalidateRegion = new RectF(); @@ -1339,8 +1357,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final boolean initialized = a.isInitialized(); if (!initialized) { - a.initialize(cr - cl, cb - ct, getWidth(), getHeight()); - a.initializeInvalidateRegion(cl, ct, cr, cb); + a.initialize(childWidth, childHeight, getWidth(), getHeight()); + a.initializeInvalidateRegion(0, 0, childWidth, childHeight); child.onAnimationStart(); } @@ -1364,7 +1382,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager invalidate(cl, ct, cr, cb); } } else { - a.getInvalidateRegion(cl, ct, cr, cb, region, transformToApply); + a.getInvalidateRegion(0, 0, childWidth, childHeight, region, transformToApply); // The child need to draw an animation, potentially offscreen, so // make sure we do not cancel invalidate requests @@ -1372,8 +1390,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // Enlarge the invalidate region to account for rounding errors // in Animation#getInvalidateRegion(); Using 0.5f is unfortunately // not enough for some types of animations (e.g. scale down.) - invalidate((int) (region.left - 1.0f), (int) (region.top - 1.0f), - (int) (region.right + 1.0f), (int) (region.bottom + 1.0f)); + final int left = cl + (int) (region.left - 1.0f); + final int top = ct + (int) (region.top - 1.0f); + invalidate(left, top, + left + (int) (region.width() + 1.0f), + top + (int) (region.height() + 1.0f)); } } } else if ((flags & FLAG_SUPPORT_STATIC_TRANSFORMATIONS) == @@ -1453,9 +1474,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if ((flags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) { if (hasNoCache) { - canvas.clipRect(sx, sy, sx + cr - cl, sy + cb - ct); + canvas.clipRect(sx, sy, sx + childWidth, sy + childHeight); } else { - canvas.clipRect(0, 0, cr - cl, cb - ct); + canvas.clipRect(0, 0, childWidth, childHeight); } } diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index ccfa6bf..db8829f 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -33,6 +33,7 @@ import android.util.Config; import android.util.Log; import android.util.EventLog; import android.util.SparseArray; +import android.util.DisplayMetrics; import android.view.View.MeasureSpec; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; @@ -184,6 +185,7 @@ public final class ViewRoot extends Handler implements ViewParent, */ AudioManager mAudioManager; + private final float mDensity; public ViewRoot(Context context) { super(); @@ -226,6 +228,7 @@ public final class ViewRoot extends Handler implements ViewParent, mAdded = false; mAttachInfo = new View.AttachInfo(sWindowSession, mWindow, this, this); mViewConfiguration = ViewConfiguration.get(context); + mDensity = context.getResources().getDisplayMetrics().density; } @Override @@ -1077,6 +1080,11 @@ public final class ViewRoot extends Handler implements ViewParent, } scrollToRectOrFocus(null, false); + + if (mAttachInfo.mViewScrollChanged) { + mAttachInfo.mViewScrollChanged = false; + mAttachInfo.mTreeObserver.dispatchOnScrollChanged(); + } int yoff; final boolean scrolling = mScroller != null @@ -1090,7 +1098,7 @@ public final class ViewRoot extends Handler implements ViewParent, mCurScrollY = yoff; fullRedrawNeeded = true; } - + Rect dirty = mDirty; if (mUseGL) { if (!dirty.isEmpty()) { @@ -1126,7 +1134,6 @@ public final class ViewRoot extends Handler implements ViewParent, return; } - if (fullRedrawNeeded) dirty.union(0, 0, mWidth, mHeight); @@ -1138,22 +1145,22 @@ public final class ViewRoot extends Handler implements ViewParent, + surface + " surface.isValid()=" + surface.isValid()); } - if (!dirty.isEmpty()) { - Canvas canvas; - try { - canvas = surface.lockCanvas(dirty); - // TODO: Do this in native - canvas.setDensityScale(mView.getResources().getDisplayMetrics().density); - } catch (Surface.OutOfResourcesException e) { - Log.e("ViewRoot", "OutOfResourcesException locking surface", e); - // TODO: we should ask the window manager to do something! - // for now we just do nothing - return; - } + Canvas canvas; + try { + canvas = surface.lockCanvas(dirty); + // TODO: Do this in native + canvas.setDensityScale(mDensity); + } catch (Surface.OutOfResourcesException e) { + Log.e("ViewRoot", "OutOfResourcesException locking surface", e); + // TODO: we should ask the window manager to do something! + // for now we just do nothing + return; + } - long startTime; + try { + if (!dirty.isEmpty()) { + long startTime; - try { if (DEBUG_ORIENTATION || DEBUG_DRAW) { Log.v("ViewRoot", "Surface " + surface + " drawing to bitmap w=" + canvas.getWidth() + ", h=" + canvas.getHeight()); @@ -1169,7 +1176,7 @@ public final class ViewRoot extends Handler implements ViewParent, // properly re-composite its drawing on a transparent // background. This automatically respects the clip/dirty region if (!canvas.isOpaque()) { - canvas.drawColor(0, PorterDuff.Mode.CLEAR); + canvas.drawColor(0xff0000ff, PorterDuff.Mode.CLEAR); } else if (yoff != 0) { // If we are applying an offset, we need to clear the area // where the offset doesn't appear to avoid having garbage @@ -1192,35 +1199,18 @@ public final class ViewRoot extends Handler implements ViewParent, sDrawTime = now; } - } finally { - surface.unlockCanvasAndPost(canvas); - } - - if (PROFILE_DRAWING) { - EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime); - } - - if (LOCAL_LOGV) { - Log.v("ViewRoot", "Surface " + surface + " unlockCanvasAndPost"); + if (PROFILE_DRAWING) { + EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime); + } } - } else if (mWidth == 0 || mHeight == 0) { - // This is a special case where a window dimension is 0 -- we - // normally wouldn't draw anything because we have an empty - // dirty rect, but the surface flinger may be waiting for us to - // draw the window before it stops freezing the screen, so we - // need to diddle it like this to keep it from getting stuck. - Canvas canvas; - try { - canvas = surface.lockCanvas(dirty); - } catch (Surface.OutOfResourcesException e) { - Log.e("ViewRoot", "OutOfResourcesException locking surface", e); - // TODO: we should ask the window manager to do something! - // for now we just do nothing - return; - } + } finally { surface.unlockCanvasAndPost(canvas); } + + if (LOCAL_LOGV) { + Log.v("ViewRoot", "Surface " + surface + " unlockCanvasAndPost"); + } if (scrolling) { mFullRedrawNeeded = true; @@ -1401,14 +1391,22 @@ public final class ViewRoot extends Handler implements ViewParent, void dispatchDetachedFromWindow() { if (Config.LOGV) Log.v("ViewRoot", "Detaching in " + this + " of " + mSurface); + if (mView != null) { mView.dispatchDetachedFromWindow(); } + mView = null; mAttachInfo.mRootView = null; + if (mUseGL) { destroyGL(); } + + try { + sWindowSession.remove(mWindow); + } catch (RemoteException e) { + } } /** @@ -1609,16 +1607,20 @@ public final class ViewRoot extends Handler implements ViewParent, } } } + + InputMethodManager imm = InputMethodManager.peekInstance(); if (mView != null) { + if (hasWindowFocus && imm != null) { + imm.startGettingWindowFocus(); + } mView.dispatchWindowFocusChanged(hasWindowFocus); } // Note: must be done after the focus change callbacks, // so all of the view state is set up correctly. if (hasWindowFocus) { - InputMethodManager imm = InputMethodManager.peekInstance(); if (imm != null) { - imm.onWindowFocus(mView.findFocus(), + imm.onWindowFocus(mView, mView.findFocus(), mWindowAttributes.softInputMode, !mHasHadWindowFocus, mWindowAttributes.flags); } @@ -2289,10 +2291,6 @@ public final class ViewRoot extends Handler implements ViewParent, } if (mAdded) { mAdded = false; - try { - sWindowSession.remove(mWindow); - } catch (RemoteException e) { - } if (immediate) { dispatchDetachedFromWindow(); } else if (mView != null) { diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java index 05f5fa2..47b52e4 100644 --- a/core/java/android/view/ViewTreeObserver.java +++ b/core/java/android/view/ViewTreeObserver.java @@ -35,6 +35,7 @@ public final class ViewTreeObserver { private ArrayList<OnPreDrawListener> mOnPreDrawListeners; private ArrayList<OnTouchModeChangeListener> mOnTouchModeChangeListeners; private ArrayList<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners; + private ArrayList<OnScrollChangedListener> mOnScrollChangedListeners; private boolean mAlive = true; @@ -99,6 +100,20 @@ public final class ViewTreeObserver { } /** + * Interface definition for a callback to be invoked when + * something in the view tree has been scrolled. + * + * @hide pending API council approval + */ + public interface OnScrollChangedListener { + /** + * Callback method to be invoked when something in the view tree + * has been scrolled. + */ + public void onScrollChanged(); + } + + /** * Parameters used with OnComputeInternalInsetsListener. * {@hide pending API Council approval} */ @@ -361,6 +376,44 @@ public final class ViewTreeObserver { } /** + * Register a callback to be invoked when a view has been scrolled. + * + * @param listener The callback to add + * + * @throws IllegalStateException If {@link #isAlive()} returns false + * + * @hide pending API council approval + */ + public void addOnScrollChangedListener(OnScrollChangedListener listener) { + checkIsAlive(); + + if (mOnScrollChangedListeners == null) { + mOnScrollChangedListeners = new ArrayList<OnScrollChangedListener>(); + } + + mOnScrollChangedListeners.add(listener); + } + + /** + * Remove a previously installed scroll-changed callback + * + * @param victim The callback to remove + * + * @throws IllegalStateException If {@link #isAlive()} returns false + * + * @see #addOnScrollChangedListener(OnScrollChangedListener) + * + * @hide pending API council approval + */ + public void removeOnScrollChangedListener(OnScrollChangedListener victim) { + checkIsAlive(); + if (mOnScrollChangedListeners == null) { + return; + } + mOnScrollChangedListeners.remove(victim); + } + + /** * Register a callback to be invoked when the invoked when the touch mode changes. * * @param listener The callback to add @@ -525,6 +578,19 @@ public final class ViewTreeObserver { } /** + * Notifies registered listeners that something has scrolled. + */ + final void dispatchOnScrollChanged() { + final ArrayList<OnScrollChangedListener> listeners = mOnScrollChangedListeners; + + if (listeners != null) { + for (OnScrollChangedListener scl : mOnScrollChangedListeners) { + scl.onScrollChanged(); + } + } + } + + /** * Returns whether there are listeners for computing internal insets. */ final boolean hasComputeInternalInsetsListeners() { diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 406af3e3..b87cc42 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -513,26 +513,33 @@ public interface WindowManager extends ViewManager { /** * Visibility state for {@link #softInputMode}: please hide any soft input - * area. + * area when normally appropriate (when the user is navigating + * forward to your window). */ public static final int SOFT_INPUT_STATE_HIDDEN = 2; /** + * Visibility state for {@link #softInputMode}: please always hide any + * soft input area when this window receives focus. + */ + public static final int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3; + + /** * Visibility state for {@link #softInputMode}: please show the soft * input area when normally appropriate (when the user is navigating * forward to your window). */ - public static final int SOFT_INPUT_STATE_VISIBLE = 3; + public static final int SOFT_INPUT_STATE_VISIBLE = 4; /** * Visibility state for {@link #softInputMode}: please always make the * soft input area visible when this window receives input focus. */ - public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 4; + public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5; /** * Mask for {@link #softInputMode} of the bits that determine the - * way that the window should be adjusted to accomodate the soft + * way that the window should be adjusted to accommodate the soft * input window. */ public static final int SOFT_INPUT_MASK_ADJUST = 0xf0; @@ -634,6 +641,14 @@ public interface WindowManager extends ViewManager { public float dimAmount = 1.0f; /** + * This can be used to override the user's preferred brightness of + * the screen. A value of less than 0, the default, means to use the + * preferred screen brightness. 0 to 1 adjusts the brightness from + * dark to full bright. + */ + public float screenBrightness = -1.0f; + + /** * Identifier for this window. This will usually be filled in for * you. */ @@ -729,6 +744,7 @@ public interface WindowManager extends ViewManager { out.writeInt(windowAnimations); out.writeFloat(alpha); out.writeFloat(dimAmount); + out.writeFloat(screenBrightness); out.writeStrongBinder(token); out.writeString(packageName); TextUtils.writeToParcel(mTitle, out, parcelableFlags); @@ -763,6 +779,7 @@ public interface WindowManager extends ViewManager { windowAnimations = in.readInt(); alpha = in.readFloat(); dimAmount = in.readFloat(); + screenBrightness = in.readFloat(); token = in.readStrongBinder(); packageName = in.readString(); mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); @@ -780,6 +797,7 @@ public interface WindowManager extends ViewManager { public static final int MEMORY_TYPE_CHANGED = 1<<8; public static final int SOFT_INPUT_MODE_CHANGED = 1<<9; public static final int SCREEN_ORIENTATION_CHANGED = 1<<10; + public static final int SCREEN_BRIGHTNESS_CHANGED = 1<<11; public final int copyFrom(LayoutParams o) { int changes = 0; @@ -874,6 +892,10 @@ public interface WindowManager extends ViewManager { dimAmount = o.dimAmount; changes |= DIM_AMOUNT_CHANGED; } + if (screenBrightness != o.screenBrightness) { + screenBrightness = o.screenBrightness; + changes |= SCREEN_BRIGHTNESS_CHANGED; + } if (screenOrientation != o.screenOrientation) { screenOrientation = o.screenOrientation; diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java new file mode 100755 index 0000000..4aa3f7a --- /dev/null +++ b/core/java/android/view/WindowOrientationListener.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.util.Config; +import android.util.Log; + +/** + * A special helper class used by the WindowManager + * for receiving notifications from the SensorManager when + * the orientation of the device has changed. + * @hide + */ +public abstract class WindowOrientationListener { + private static final String TAG = "WindowOrientationListener"; + private static final boolean DEBUG = false; + private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; + private int mOrientation = ORIENTATION_UNKNOWN; + private SensorManager mSensorManager; + private boolean mEnabled = false; + private int mRate; + private Sensor mSensor; + private SensorEventListener mSensorEventListener; + + /** + * Returned from onOrientationChanged when the device orientation cannot be determined + * (typically when the device is in a close to flat position). + * + * @see #onOrientationChanged + */ + public static final int ORIENTATION_UNKNOWN = -1; + /* + * Returned when the device is almost lying flat on a surface + */ + public static final int ORIENTATION_FLAT = -2; + + /** + * Creates a new WindowOrientationListener. + * + * @param context for the WindowOrientationListener. + */ + public WindowOrientationListener(Context context) { + this(context, SensorManager.SENSOR_DELAY_NORMAL); + } + + /** + * Creates a new WindowOrientationListener. + * + * @param context for the WindowOrientationListener. + * @param rate at which sensor events are processed (see also + * {@link android.hardware.SensorManager SensorManager}). Use the default + * value of {@link android.hardware.SensorManager#SENSOR_DELAY_NORMAL + * SENSOR_DELAY_NORMAL} for simple screen orientation change detection. + */ + public WindowOrientationListener(Context context, int rate) { + mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); + mRate = rate; + mSensorEventListener = new SensorEventListenerImpl(); + mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + } + + /** + * Enables the WindowOrientationListener so it will monitor the sensor and call + * {@link #onOrientationChanged} when the device orientation changes. + */ + public void enable() { + if (mEnabled == false) { + if (localLOGV) Log.d(TAG, "WindowOrientationListener enabled"); + mSensorManager.registerListener(mSensorEventListener, mSensor, mRate); + mEnabled = true; + } + } + + /** + * Disables the WindowOrientationListener. + */ + public void disable() { + if (mEnabled == true) { + if (localLOGV) Log.d(TAG, "WindowOrientationListener disabled"); + mSensorManager.unregisterListener(mSensorEventListener); + mEnabled = false; + } + } + + class SensorEventListenerImpl implements SensorEventListener { + private static final int _DATA_X = 0; + private static final int _DATA_Y = 1; + private static final int _DATA_Z = 2; + + public void onSensorChanged(SensorEvent event) { + float[] values = event.values; + int orientation = ORIENTATION_UNKNOWN; + float X = values[_DATA_X]; + float Y = values[_DATA_Y]; + float Z = values[_DATA_Z]; + float OneEightyOverPi = 57.29577957855f; + float gravity = (float) Math.sqrt(X*X+Y*Y+Z*Z); + float zyangle = Math.abs((float)Math.asin(Z/gravity)*OneEightyOverPi); + // The device is considered flat if the angle is more than 75 + // if the angle is less than 40, its considered too flat to switch + // orientation. if the angle is between 40 - 75, the orientation is unknown + if (zyangle < 40) { + // Check orientation only if the phone is flat enough + // Don't trust the angle if the magnitude is small compared to the y value + float angle = (float)Math.atan2(Y, -X) * OneEightyOverPi; + orientation = 90 - (int)Math.round(angle); + // normalize to 0 - 359 range + while (orientation >= 360) { + orientation -= 360; + } + while (orientation < 0) { + orientation += 360; + } + } else if (zyangle >= 75){ + orientation = ORIENTATION_FLAT; + } + + if (orientation != mOrientation) { + mOrientation = orientation; + onOrientationChanged(orientation); + } + } + + public void onAccuracyChanged(Sensor sensor, int accuracy) { + + } + } + + /** + * Called when the orientation of the device has changed. + * orientation parameter is in degrees, ranging from 0 to 359. + * orientation is 0 degrees when the device is oriented in its natural position, + * 90 degrees when its left side is at the top, 180 degrees when it is upside down, + * and 270 degrees when its right side is to the top. + * {@link #ORIENTATION_UNKNOWN} is returned when the device is close to flat + * and the orientation cannot be determined. + * + * @param orientation The new orientation of the device. + * + * @see #ORIENTATION_UNKNOWN + */ + abstract public void onOrientationChanged(int orientation); +} diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java index c96b3e5..b9c8ec3 100644 --- a/core/java/android/view/animation/Animation.java +++ b/core/java/android/view/animation/Animation.java @@ -179,6 +179,7 @@ public abstract class Animation implements Cloneable { private boolean mOneMoreTime = true; RectF mPreviousRegion = new RectF(); + RectF mRegion = new RectF(); Transformation mTransformation = new Transformation(); Transformation mPreviousTransformation = new Transformation(); @@ -226,6 +227,7 @@ public abstract class Animation implements Cloneable { protected Animation clone() throws CloneNotSupportedException { final Animation animation = (Animation) super.clone(); animation.mPreviousRegion = new RectF(); + animation.mRegion = new RectF(); animation.mTransformation = new Transformation(); animation.mPreviousTransformation = new Transformation(); return animation; @@ -799,14 +801,15 @@ public abstract class Animation implements Cloneable { public void getInvalidateRegion(int left, int top, int right, int bottom, RectF invalidate, Transformation transformation) { + final RectF tempRegion = mRegion; final RectF previousRegion = mPreviousRegion; invalidate.set(left, top, right, bottom); transformation.getMatrix().mapRect(invalidate); + tempRegion.set(invalidate); invalidate.union(previousRegion); - previousRegion.set(left, top, right, bottom); - transformation.getMatrix().mapRect(previousRegion); + previousRegion.set(tempRegion); final Transformation tempTransformation = mTransformation; final Transformation previousTransformation = mPreviousTransformation; diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index 9509b15..6fbc174 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -525,9 +525,6 @@ public class BaseInputConnection implements InputConnection { setComposingSpans(sp); } - // Adjust newCursorPosition to be relative the start of the text. - newCursorPosition += a; - if (DEBUG) Log.v(TAG, "Replacing from " + a + " to " + b + " with \"" + text + "\", composing=" + composing + ", type=" + text.getClass().getCanonicalName()); @@ -540,11 +537,21 @@ public class BaseInputConnection implements InputConnection { TextUtils.dumpSpans(text, lp, " "); } - content.replace(a, b, text); + // Position the cursor appropriately, so that after replacing the + // desired range of text it will be located in the correct spot. + // This allows us to deal with filters performing edits on the text + // we are providing here. + if (newCursorPosition > 0) { + newCursorPosition += b - 1; + } else { + newCursorPosition += a; + } if (newCursorPosition < 0) newCursorPosition = 0; if (newCursorPosition > content.length()) newCursorPosition = content.length(); Selection.setSelection(content, newCursorPosition); + + content.replace(a, b, text); if (DEBUG) { LogPrinter lp = new LogPrinter(Log.VERBOSE, TAG); diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java index 13173f6..530127d 100644 --- a/core/java/android/view/inputmethod/InputConnection.java +++ b/core/java/android/view/inputmethod/InputConnection.java @@ -148,8 +148,14 @@ public interface InputConnection { * object to the text. {#link android.text.SpannableString} and * {#link android.text.SpannableStringBuilder} are two * implementations of the interface {#link android.text.Spanned}. - * @param newCursorPosition The new cursor position within the - * <var>text</var>. + * @param newCursorPosition The new cursor position around the text. If + * > 0, this is relative to the end of the text - 1; if <= 0, this + * is relative to the start of the text. So a value of 1 will + * always advance you to the position after the full text being + * inserted. Note that this means you can't position the cursor + * within the text, because the editor can make modifications to + * the text you are providing so it is not possible to correctly + * specify locations there. * * @return Returns true on success, false if the input connection is no longer * valid. @@ -170,8 +176,14 @@ public interface InputConnection { * automatically. * * @param text The committed text. - * @param newCursorPosition The new cursor position within the - * <var>text</var>. + * @param newCursorPosition The new cursor position around the text. If + * > 0, this is relative to the end of the text - 1; if <= 0, this + * is relative to the start of the text. So a value of 1 will + * always advance you to the position after the full text being + * inserted. Note that this means you can't position the cursor + * within the text, because the editor can make modifications to + * the text you are providing so it is not possible to correctly + * specify locations there. * * * @return Returns true on success, false if the input connection is no longer diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index fe14166..91fa211 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -226,6 +226,10 @@ public final class InputMethodManager { * regardless of the state of setting that up. */ View mServedView; + /* + * Keep track of the view that was set when our window gained focus. + */ + View mWindowFocusedView; /** * For evaluating the state after a focus change, this is the view that * had focus. @@ -466,8 +470,8 @@ public final class InputMethodManager { } /** @hide */ - public void setFullscreenMode(boolean enabled) { - mFullscreenMode = true; + public void setFullscreenMode(boolean fullScreen) { + mFullscreenMode = fullScreen; } /** @@ -828,19 +832,23 @@ public final class InputMethodManager { */ public void focusIn(View view) { synchronized (mH) { - if (DEBUG) Log.v(TAG, "focusIn: " + view); - // Okay we have a new view that is being served. - if (mServedView != view) { - mCurrentTextBoxAttribute = null; - } - mServedView = view; - mCompletions = null; - mServedConnecting = true; + focusInLocked(view); } startInputInner(); } + void focusInLocked(View view) { + if (DEBUG) Log.v(TAG, "focusIn: " + view); + // Okay we have a new view that is being served. + if (mServedView != view) { + mCurrentTextBoxAttribute = null; + } + mServedView = view; + mCompletions = null; + mServedConnecting = true; + } + /** * Call this when a view loses focus. * @hide @@ -908,16 +916,28 @@ public final class InputMethodManager { * Called by ViewRoot the first time it gets window focus. * @hide */ - public void onWindowFocus(View focusedView, int softInputMode, + public void onWindowFocus(View rootView, View focusedView, int softInputMode, boolean first, int windowFlags) { + boolean needStartInput = false; synchronized (mH) { if (DEBUG) Log.v(TAG, "onWindowFocus: " + focusedView + " softInputMode=" + softInputMode + " first=" + first + " flags=#" + Integer.toHexString(windowFlags)); + if (mWindowFocusedView == null) { + focusInLocked(focusedView != null ? focusedView : rootView); + needStartInput = true; + } + } + + if (needStartInput) { + startInputInner(); + } + + synchronized (mH) { try { final boolean isTextEditor = focusedView != null && - focusedView.onCheckIsTextEditor(); + focusedView.onCheckIsTextEditor(); mService.windowGainedFocus(mClient, focusedView != null, isTextEditor, softInputMode, first, windowFlags); } catch (RemoteException e) { @@ -925,6 +945,13 @@ public final class InputMethodManager { } } + /** @hide */ + public void startGettingWindowFocus() { + synchronized (mH) { + mWindowFocusedView = null; + } + } + /** * Report the current selection range. */ diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index 1dd37be..451af6d 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -51,7 +51,7 @@ class BrowserFrame extends Handler { private final Context mContext; private final WebViewDatabase mDatabase; private final WebViewCore mWebViewCore; - private boolean mLoadInitFromJava; + /* package */ boolean mLoadInitFromJava; private int mLoadType; private boolean mFirstLayoutDone = true; private boolean mCommitted = true; diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java index 3694969..dfae17d 100644 --- a/core/java/android/webkit/LoadListener.java +++ b/core/java/android/webkit/LoadListener.java @@ -575,7 +575,7 @@ class LoadListener extends Handler implements EventHandler { mRequestHandle.getMethod().equals("POST")) { sendMessageInternal(obtainMessage( MSG_LOCATION_CHANGED_REQUEST)); - } else if (mMethod.equals("POST")) { + } else if (mMethod != null && mMethod.equals("POST")) { sendMessageInternal(obtainMessage( MSG_LOCATION_CHANGED_REQUEST)); } else { diff --git a/core/java/android/webkit/TextDialog.java b/core/java/android/webkit/TextDialog.java index 9af30c5..c2620a5 100644 --- a/core/java/android/webkit/TextDialog.java +++ b/core/java/android/webkit/TextDialog.java @@ -291,6 +291,25 @@ import java.util.ArrayList; } /** + * Create a fake touch up event at (x,y) with respect to this TextDialog. + * This is used by WebView to act as though a touch event which happened + * before we placed the TextDialog actually hit it, so that it can place + * the cursor accordingly. + */ + /* package */ void fakeTouchEvent(float x, float y) { + // We need to ensure that there is a Layout, since the Layout is used + // in determining where to place the cursor. + if (getLayout() == null) { + measure(mWidthSpec, mHeightSpec); + } + // Create a fake touch up, which is used to place the cursor. + MotionEvent ev = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, + x, y, 0); + onTouchEvent(ev); + ev.recycle(); + } + + /** * Determine whether this TextDialog currently represents the node * represented by ptr. * @param ptr Pointer to a node to compare to. @@ -461,9 +480,8 @@ import java.util.ArrayList; */ public void setAdapterCustom(AutoCompleteAdapter adapter) { if (adapter != null) { - adapter.setTextView(this); - } else { setInputType(EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE); + adapter.setTextView(this); } super.setAdapter(adapter); } diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index bdbf38a..4d9a8fb 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -45,6 +45,8 @@ import android.util.AttributeSet; import android.util.Config; import android.util.Log; import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -234,6 +236,9 @@ public class WebView extends AbsoluteLayout */ VelocityTracker mVelocityTracker; + private static boolean mShowZoomRingTutorial = true; + private static final int ZOOM_RING_TUTORIAL_DURATION = 3000; + /** * Touch mode */ @@ -284,9 +289,7 @@ public class WebView extends AbsoluteLayout // In the browser, if it switches out of tap too soon, jump tap won't work. private static final int TAP_TIMEOUT = 200; // The duration in milliseconds we will wait to see if it is a double tap. - // With a limited survey, the time between the first tap up and the second - // tap down in the double tap case is around 70ms - 120ms. - private static final int DOUBLE_TAP_TIMEOUT = 200; + private static final int DOUBLE_TAP_TIMEOUT = 250; // This should be ViewConfiguration.getLongPressTimeout() // But system time out is 500ms, which is too short for the browser. // With a short timeout, it's difficult to treat trigger a short press. @@ -315,6 +318,9 @@ public class WebView extends AbsoluteLayout private int mContentWidth; // cache of value from WebViewCore private int mContentHeight; // cache of value from WebViewCore + static int MAX_FLOAT_CONTENT_WIDTH = 480; + private int mMinContentWidth; + // Need to have the separate control for horizontal and vertical scrollbar // style than the View's single scrollbar style private boolean mOverlayHorizontalScrollbar = true; @@ -348,6 +354,7 @@ public class WebView extends AbsoluteLayout private static final int UPDATE_TEXT_ENTRY_ADAPTER = 6; private static final int SWITCH_TO_ENTER = 7; private static final int RESUME_WEBCORE_UPDATE = 8; + private static final int DISMISS_ZOOM_RING_TUTORIAL = 9; //! arg1=x, arg2=y static final int SCROLL_TO_MSG_ID = 10; @@ -370,12 +377,46 @@ public class WebView extends AbsoluteLayout static final int WEBCORE_NEED_TOUCH_EVENTS = 25; // obj=Rect in doc coordinates static final int INVAL_RECT_MSG_ID = 26; + + static final String[] HandlerDebugString = { + "REMEMBER_PASSWORD", // = 1; + "NEVER_REMEMBER_PASSWORD", // = 2; + "SWITCH_TO_SHORTPRESS", // = 3; + "SWITCH_TO_LONGPRESS", // = 4; + "RELEASE_SINGLE_TAP", // = 5; + "UPDATE_TEXT_ENTRY_ADAPTER", // = 6; + "SWITCH_TO_ENTER", // = 7; + "RESUME_WEBCORE_UPDATE", // = 8; + "9", + "SCROLL_TO_MSG_ID", // = 10; + "SCROLL_BY_MSG_ID", // = 11; + "SPAWN_SCROLL_TO_MSG_ID", // = 12; + "SYNC_SCROLL_TO_MSG_ID", // = 13; + "NEW_PICTURE_MSG_ID", // = 14; + "UPDATE_TEXT_ENTRY_MSG_ID", // = 15; + "WEBCORE_INITIALIZED_MSG_ID", // = 16; + "UPDATE_TEXTFIELD_TEXT_MSG_ID", // = 17; + "DID_FIRST_LAYOUT_MSG_ID", // = 18; + "RECOMPUTE_FOCUS_MSG_ID", // = 19; + "NOTIFY_FOCUS_SET_MSG_ID", // = 20; + "MARK_NODE_INVALID_ID", // = 21; + "UPDATE_CLIPBOARD", // = 22; + "LONG_PRESS_ENTER", // = 23; + "PREVENT_TOUCH_ID", // = 24; + "WEBCORE_NEED_TOUCH_EVENTS", // = 25; + "INVAL_RECT_MSG_ID" // = 26; + }; // width which view is considered to be fully zoomed out static final int ZOOM_OUT_WIDTH = 1024; - private static final float DEFAULT_MAX_ZOOM_SCALE = 4; - private static final float DEFAULT_MIN_ZOOM_SCALE = 0.25f; + private static final float MAX_ZOOM_RING_ANGLE = (float) (Math.PI * 2 / 3); + private static final int ZOOM_RING_STEPS = 4; + private static final float ZOOM_RING_ANGLE_UNIT = MAX_ZOOM_RING_ANGLE + / ZOOM_RING_STEPS; + + private static final float DEFAULT_MAX_ZOOM_SCALE = 2; + private static final float DEFAULT_MIN_ZOOM_SCALE = (float) 1/3; // scale limit, which can be set through viewport meta tag in the web page private float mMaxZoomScale = DEFAULT_MAX_ZOOM_SCALE; private float mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE; @@ -505,6 +546,8 @@ public class WebView extends AbsoluteLayout } private ZoomRingController mZoomRingController; + private ImageView mZoomRingOverview; + private Animation mZoomRingOverviewExitAnimation; // These keep track of the center point of the zoom ring. They are used to // determine the point around which we should zoom. @@ -519,51 +562,83 @@ public class WebView extends AbsoluteLayout // in this callback } + public void onBeginPan() { + setZoomOverviewVisible(false); + } + public boolean onPan(int deltaX, int deltaY) { return pinScrollBy(deltaX, deltaY, false, 0); } + public void onEndPan() { + } + public void onVisibilityChanged(boolean visible) { if (visible) { - mZoomControls.show(false, canZoomScrollOut()); - } else { - mZoomControls.hide(); + switchOutDrawHistory(); + float angle = 0f; + if (mActualScale > 1) { + angle = -(float) Math.round(ZOOM_RING_STEPS + * (mActualScale - 1) / (mMaxZoomScale - 1)) + / ZOOM_RING_STEPS; + } else if (mActualScale < 1) { + angle = (float) Math.round(ZOOM_RING_STEPS + * (1 - mActualScale) / (1 - mMinZoomScale)) + / ZOOM_RING_STEPS; + } + mZoomRingController.setThumbAngle(angle * MAX_ZOOM_RING_ANGLE); + + // Show the zoom overview tab on the ring + setZoomOverviewVisible(true); } } - - public void onBeginDrag(float startAngle) { + + public void onBeginDrag() { mPreviewZoomOnly = true; + setZoomOverviewVisible(false); } - public void onEndDrag(float endAngle) { + public void onEndDrag() { mPreviewZoomOnly = false; setNewZoomScale(mActualScale, true); } public boolean onDragZoom(int deltaZoomLevel, int centerX, int centerY, float startAngle, float curAngle) { - - if (mZoomScale == mMinZoomScale && deltaZoomLevel < 0 || - mZoomScale == mMaxZoomScale && deltaZoomLevel > 0 || - deltaZoomLevel == 0) { + if (deltaZoomLevel < 0 + && Math.abs(mActualScale - mMinZoomScale) < 0.01f + || deltaZoomLevel > 0 + && Math.abs(mActualScale - mMaxZoomScale) < 0.01f + || deltaZoomLevel == 0) { return false; } mZoomCenterX = (float) centerX; mZoomCenterY = (float) centerY; - while (deltaZoomLevel != 0) { - if (deltaZoomLevel > 0) { - if (!zoomIn()) return false; - deltaZoomLevel--; + float scale = 1.0f; + if (curAngle > (float) Math.PI) + curAngle -= (float) 2 * Math.PI; + if (curAngle > 0) { + if (curAngle >= MAX_ZOOM_RING_ANGLE) { + scale = mMinZoomScale; + } else { + scale = 1 - (float) Math.round(curAngle + / ZOOM_RING_ANGLE_UNIT) / ZOOM_RING_STEPS + * (1 - mMinZoomScale); + } + } else if (curAngle < 0) { + if (curAngle <= -MAX_ZOOM_RING_ANGLE) { + scale = mMaxZoomScale; } else { - if (!zoomOut()) return false; - deltaZoomLevel++; + scale = 1 + (float) Math.round(-curAngle + / ZOOM_RING_ANGLE_UNIT) / ZOOM_RING_STEPS + * (mMaxZoomScale - 1); } } - + zoomWithPreview(scale); return true; } - + public void onSimpleZoom(boolean zoomIn) { if (zoomIn) { zoomIn(); @@ -571,6 +646,7 @@ public class WebView extends AbsoluteLayout zoomOut(); } } + }; /** @@ -610,7 +686,14 @@ public class WebView extends AbsoluteLayout mFocusData.mY = 0; mScroller = new Scroller(context); mZoomRingController = new ZoomRingController(context, this); + mZoomRingController.setResetThumbAutomatically(false); + mZoomRingController.setThumbClockwiseBound( + (float) (2 * Math.PI - MAX_ZOOM_RING_ANGLE)); + mZoomRingController.setThumbCounterclockwiseBound(MAX_ZOOM_RING_ANGLE); mZoomRingController.setCallback(mZoomListener); + mZoomRingController.setZoomRingTrack( + com.android.internal.R.drawable.zoom_ring_track_absolute); + createZoomRingOverviewTab(); } private void init() { @@ -625,6 +708,63 @@ public class WebView extends AbsoluteLayout mMinLockSnapReverseDistance = slop; } + private void createZoomRingOverviewTab() { + Context context = getContext(); + + mZoomRingOverviewExitAnimation = AnimationUtils.loadAnimation(context, + com.android.internal.R.anim.fade_out); + + mZoomRingOverview = new ImageView(context); + mZoomRingOverview.setBackgroundResource( + com.android.internal.R.drawable.zoom_ring_overview_tab); + mZoomRingOverview.setImageResource(com.android.internal.R.drawable.btn_zoom_page); + + FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.WRAP_CONTENT, + FrameLayout.LayoutParams.WRAP_CONTENT, + Gravity.CENTER); + // TODO: magic constant that's based on the zoom ring radius + some offset + lp.topMargin = 208; + mZoomRingOverview.setLayoutParams(lp); + mZoomRingOverview.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + // Hide the zoom ring + mZoomRingController.setVisible(false); + zoomScrollOut(); + }}); + + // Measure the overview View to figure out its height + mZoomRingOverview.forceLayout(); + mZoomRingOverview.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); + + ViewGroup container = mZoomRingController.getContainer(); + // Find the index of the zoom ring in the container + View zoomRing = container.findViewById(mZoomRingController.getZoomRingId()); + int zoomRingIndex; + for (zoomRingIndex = container.getChildCount() - 1; zoomRingIndex >= 0; zoomRingIndex--) { + if (container.getChildAt(zoomRingIndex) == zoomRing) break; + } + // Add the overview tab below the zoom ring (so we don't steal its events) + container.addView(mZoomRingOverview, zoomRingIndex); + // Since we use margins to adjust the vertical placement of the tab, the widget + // ends up getting clipped off. Ensure the container is big enough for + // us. + int myHeight = mZoomRingOverview.getMeasuredHeight() + lp.topMargin / 2; + // Multiplied by 2 b/c the zoom ring needs to be centered on the screen + container.setMinimumHeight(myHeight * 2); + } + + private void setZoomOverviewVisible(boolean visible) { + int newVisibility = visible ? View.VISIBLE : View.INVISIBLE; + if (mZoomRingOverview.getVisibility() == newVisibility) return; + + if (!visible) { + mZoomRingOverview.startAnimation(mZoomRingOverviewExitAnimation); + } + mZoomRingOverview.setVisibility(newVisibility); + } + /* package */ boolean onSavePassword(String schemePlusHost, String username, String password, final Message resumeMsg) { boolean rVal = false; @@ -1653,7 +1793,8 @@ public class WebView extends AbsoluteLayout * @return true if new values were sent */ private boolean sendViewSizeZoom() { - int newWidth = Math.round(getViewWidth() * mInvActualScale); + int viewWidth = getViewWidth(); + int newWidth = Math.round(viewWidth * mInvActualScale); int newHeight = Math.round(getViewHeight() * mInvActualScale); /* * Because the native side may have already done a layout before the @@ -1669,7 +1810,7 @@ public class WebView extends AbsoluteLayout // Avoid sending another message if the dimensions have not changed. if (newWidth != mLastWidthSent || newHeight != mLastHeightSent) { mWebViewCore.sendMessage(EventHub.VIEW_SIZE_CHANGED, - newWidth, newHeight, new Float(mActualScale)); + newWidth, newHeight, new Integer(viewWidth)); mLastWidthSent = newWidth; mLastHeightSent = newHeight; return true; @@ -1968,7 +2109,7 @@ public class WebView extends AbsoluteLayout // Scale from content to view coordinates, and pin. // Also called by jni webview.cpp - private void setContentScrollBy(int cx, int cy) { + private void setContentScrollBy(int cx, int cy, boolean animate) { if (mDrawHistory) { // disallow WebView to change the scroll position as History Picture // is used in the view system. @@ -1992,10 +2133,10 @@ public class WebView extends AbsoluteLayout // vertical scroll? // Log.d(LOGTAG, "setContentScrollBy cy=" + cy); if (cy == 0 && cx != 0) { - pinScrollBy(cx, 0, true, 0); + pinScrollBy(cx, 0, animate, 0); } } else { - pinScrollBy(cx, cy, true, 0); + pinScrollBy(cx, cy, animate, 0); } } @@ -2205,7 +2346,8 @@ public class WebView extends AbsoluteLayout // state. // If mNativeClass is 0, we should not reach here, so we do not // need to check it again. - nativeRecordButtons(mTouchMode == TOUCH_SHORTPRESS_START_MODE + nativeRecordButtons(hasFocus() && hasWindowFocus(), + mTouchMode == TOUCH_SHORTPRESS_START_MODE || mTrackballDown || mGotEnterDown, false); drawCoreAndFocusRing(canvas, mBackgroundColor, mDrawFocusRing); } @@ -2254,6 +2396,8 @@ public class WebView extends AbsoluteLayout invalidate(); } else { zoomScale = mZoomScale; + // set mZoomScale to be 0 as we have done animation + mZoomScale = 0; } float scale = (mActualScale - zoomScale) * mInvActualScale; float tx = scale * (mZoomCenterX + mScrollX); @@ -2775,6 +2919,17 @@ public class WebView extends AbsoluteLayout getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(mTextEntry, 0); mTextEntry.enableScrollOnScreen(true); + // Now we need to fake a touch event to place the cursor where the + // user touched. + AbsoluteLayout.LayoutParams lp = (AbsoluteLayout.LayoutParams) + mTextEntry.getLayoutParams(); + if (lp != null) { + // Take the last touch and adjust for the location of the + // TextDialog. + float x = mLastTouchX - lp.x; + float y = mLastTouchY - lp.y; + mTextEntry.fakeTouchEvent(x, y); + } } private void updateTextEntry() { @@ -2987,7 +3142,9 @@ public class WebView extends AbsoluteLayout mGotEnterDown = true; mPrivateHandler.sendMessageDelayed(mPrivateHandler .obtainMessage(LONG_PRESS_ENTER), LONG_PRESS_TIMEOUT); - nativeRecordButtons(true, true); + // Already checked mNativeClass, so we do not need to check it + // again. + nativeRecordButtons(hasFocus() && hasWindowFocus(), true, true); return true; } // Bubble up the key event as WebView doesn't handle it @@ -3198,6 +3355,9 @@ public class WebView extends AbsoluteLayout ViewGroup p = (ViewGroup) parent; p.setOnHierarchyChangeListener(null); } + + // Clean up the zoom ring + mZoomRingController.setVisible(false); } // Implementation for OnHierarchyChangeListener @@ -3234,16 +3394,25 @@ public class WebView extends AbsoluteLayout if (mNeedsUpdateTextEntry) { updateTextEntry(); } + if (mNativeClass != 0) { + nativeRecordButtons(true, false, true); + } } else { // If our window gained focus, but we do not have it, do not // draw the focus ring. mDrawFocusRing = false; + // We do not call nativeRecordButtons here because we assume + // that when we lost focus, or window focus, it got called with + // false for the first parameter } } else { // If our window has lost focus, stop drawing the focus ring mDrawFocusRing = false; mGotKeyDown = false; mShiftIsPressed = false; + if (mNativeClass != 0) { + nativeRecordButtons(false, false, true); + } } invalidate(); super.onWindowFocusChanged(hasWindowFocus); @@ -3264,12 +3433,22 @@ public class WebView extends AbsoluteLayout updateTextEntry(); mNeedsUpdateTextEntry = false; } + if (mNativeClass != 0) { + nativeRecordButtons(true, false, true); + } + //} else { + // The WebView has gained focus while we do not have + // windowfocus. When our window lost focus, we should have + // called nativeRecordButtons(false...) } } else { // When we lost focus, unless focus went to the TextView (which is // true if we are in editing mode), stop drawing the focus ring. if (!inEditingMode()) { mDrawFocusRing = false; + if (mNativeClass != 0) { + nativeRecordButtons(false, false, true); + } } mGotKeyDown = false; } @@ -3285,6 +3464,22 @@ public class WebView extends AbsoluteLayout // the new zoom ring controller mZoomCenterX = getViewWidth() * .5f; mZoomCenterY = getViewHeight() * .5f; + + // update mMinZoomScale + if (mMinContentWidth > MAX_FLOAT_CONTENT_WIDTH) { + boolean atMin = Math.abs(mActualScale - mMinZoomScale) < 0.01f; + mMinZoomScale = (float) getViewWidth() / mMinContentWidth; + if (atMin) { + // if the WebView was at the minimum zoom scale, keep it. e,g., + // the WebView was at the minimum zoom scale at the portrait + // mode, rotate it to the landscape modifying the scale to the + // new minimum zoom scale, when rotating back, we would like to + // keep the minimum zoom scale instead of keeping the same scale + // as normally we do. + mActualScale = mMinZoomScale; + } + } + // we always force, in case our height changed, in which case we still // want to send the notification over to webkit setNewZoomScale(mActualScale, true); @@ -3340,6 +3535,14 @@ public class WebView extends AbsoluteLayout return false; } + if (mShowZoomRingTutorial && mMinZoomScale < mMaxZoomScale) { + ZoomRingController.showZoomTutorialOnce(mContext); + mShowZoomRingTutorial = false; + mPrivateHandler.sendMessageDelayed(mPrivateHandler + .obtainMessage(DISMISS_ZOOM_RING_TUTORIAL), + ZOOM_RING_TUTORIAL_DURATION); + } + if (LOGV_ENABLED) { Log.v(LOGTAG, ev + " at " + ev.getEventTime() + " mTouchMode=" + mTouchMode); @@ -3749,7 +3952,7 @@ public class WebView extends AbsoluteLayout mPrivateHandler.removeMessages(SWITCH_TO_ENTER); mTrackballDown = true; if (mNativeClass != 0) { - nativeRecordButtons(true, true); + nativeRecordButtons(hasFocus() && hasWindowFocus(), true, true); } if (time - mLastFocusTime <= TRACKBALL_TIMEOUT && !mLastFocusBounds.equals(nativeGetFocusRingBounds())) { @@ -4148,6 +4351,9 @@ public class WebView extends AbsoluteLayout }); zoomControls.setOnZoomMagnifyClickListener(new OnClickListener() { public void onClick(View v) { + // Hide the zoom ring + mZoomRingController.setVisible(false); + mPrivateHandler.removeCallbacks(mZoomControlRunnable); mPrivateHandler.postDelayed(mZoomControlRunnable, ZOOM_CONTROLS_TIMEOUT); @@ -4200,6 +4406,12 @@ public class WebView extends AbsoluteLayout } } + // Called by JNI to handle a touch on a node representing an email address, + // address, or phone number + private void overrideLoading(String url) { + mCallbackProxy.uiOverrideUrlLoading(url); + } + @Override public boolean requestFocus(int direction, Rect previouslyFocusedRect) { boolean result = false; @@ -4372,6 +4584,11 @@ public class WebView extends AbsoluteLayout class PrivateHandler extends Handler { @Override public void handleMessage(Message msg) { + if (LOGV_ENABLED) { + Log.v(LOGTAG, msg.what < REMEMBER_PASSWORD || msg.what + > INVAL_RECT_MSG_ID ? Integer.toString(msg.what) + : HandlerDebugString[msg.what - REMEMBER_PASSWORD]); + } switch (msg.what) { case REMEMBER_PASSWORD: { mDatabase.setUsernamePassword( @@ -4413,7 +4630,7 @@ public class WebView extends AbsoluteLayout , KeyEvent.KEYCODE_ENTER)); break; case SCROLL_BY_MSG_ID: - setContentScrollBy(msg.arg1, msg.arg2); + setContentScrollBy(msg.arg1, msg.arg2, (Boolean) msg.obj); break; case SYNC_SCROLL_TO_MSG_ID: if (mUserScroll) { @@ -4451,6 +4668,11 @@ public class WebView extends AbsoluteLayout 0, 0); } } + mMinContentWidth = msg.arg1; + if (mMinContentWidth > MAX_FLOAT_CONTENT_WIDTH) { + mMinZoomScale = (float) getViewWidth() + / mMinContentWidth; + } // We update the layout (i.e. request a layout from the // view system) if the last view size that we sent to // WebCore matches the view size of the picture we just @@ -4638,6 +4860,10 @@ public class WebView extends AbsoluteLayout } break; + case DISMISS_ZOOM_RING_TUTORIAL: + mZoomRingController.finishZoomTutorial(); + break; + default: super.handleMessage(msg); break; @@ -5018,8 +5244,8 @@ public class WebView extends AbsoluteLayout private native void nativeRecomputeFocus(); // Like many other of our native methods, you must make sure that // mNativeClass is not null before calling this method. - private native void nativeRecordButtons(boolean pressed, - boolean invalidate); + private native void nativeRecordButtons(boolean focused, + boolean pressed, boolean invalidate); private native void nativeResetFocus(); private native void nativeResetNavClipBounds(); private native void nativeSelectBestAt(Rect rect); diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index b979032..45113ab 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -271,6 +271,11 @@ final class WebViewCore { static native String nativeFindAddress(String addr); /** + * Rebuild the nav cache if the dom changed. + */ + private native void nativeCheckNavCache(); + + /** * Empty the picture set. */ private native void nativeClearContent(); @@ -317,7 +322,7 @@ final class WebViewCore { should this be called nativeSetViewPortSize? */ private native void nativeSetSize(int width, int height, int screenWidth, - float scale); + float scale, int realScreenWidth, int screenHeight); private native int nativeGetContentMinPrefWidth(); @@ -501,6 +506,51 @@ final class WebViewCore { int mY; } + static final String[] HandlerDebugString = { + "LOAD_URL", // = 100; + "STOP_LOADING", // = 101; + "RELOAD", // = 102; + "KEY_DOWN", // = 103; + "KEY_UP", // = 104; + "VIEW_SIZE_CHANGED", // = 105; + "GO_BACK_FORWARD", // = 106; + "SET_SCROLL_OFFSET", // = 107; + "RESTORE_STATE", // = 108; + "PAUSE_TIMERS", // = 109; + "RESUME_TIMERS", // = 110; + "CLEAR_CACHE", // = 111; + "CLEAR_HISTORY", // = 112; + "SET_SELECTION", // = 113; + "REPLACE_TEXT", // = 114; + "PASS_TO_JS", // = 115; + "SET_GLOBAL_BOUNDS", // = 116; + "UPDATE_CACHE_AND_TEXT_ENTRY", // = 117; + "CLICK", // = 118; + "119", + "DOC_HAS_IMAGES", // = 120; + "SET_SNAP_ANCHOR", // = 121; + "DELETE_SELECTION", // = 122; + "LISTBOX_CHOICES", // = 123; + "SINGLE_LISTBOX_CHOICE", // = 124; + "125", + "SET_BACKGROUND_COLOR", // = 126; + "UNBLOCK_FOCUS", // = 127; + "SAVE_DOCUMENT_STATE", // = 128; + "GET_SELECTION", // = 129; + "WEBKIT_DRAW", // = 130; + "SYNC_SCROLL", // = 131; + "REFRESH_PLUGINS", // = 132; + "SPLIT_PICTURE_SET", // = 133; + "CLEAR_CONTENT", // = 134; + "SET_FINAL_FOCUS", // = 135; + "SET_KIT_FOCUS", // = 136; + "REQUEST_FOCUS_HREF", // = 137; + "ADD_JS_INTERFACE", // = 138; + "LOAD_DATA", // = 139; + "TOUCH_UP", // = 140; + "TOUCH_EVENT", // = 141; + }; + class EventHub { // Message Ids static final int LOAD_URL = 100; @@ -595,6 +645,11 @@ final class WebViewCore { mHandler = new Handler() { @Override public void handleMessage(Message msg) { + if (LOGV_ENABLED) { + Log.v(LOGTAG, msg.what < LOAD_URL || msg.what + > TOUCH_EVENT ? Integer.toString(msg.what) + : HandlerDebugString[msg.what - LOAD_URL]); + } switch (msg.what) { case WEBKIT_DRAW: webkitDraw(); @@ -675,7 +730,7 @@ final class WebViewCore { case VIEW_SIZE_CHANGED: viewSizeChanged(msg.arg1, msg.arg2, - ((Float) msg.obj).floatValue()); + ((Integer) msg.obj).intValue()); break; case SET_SCROLL_OFFSET: @@ -1131,12 +1186,22 @@ final class WebViewCore { private int mCurrentViewWidth = 0; private int mCurrentViewHeight = 0; + // Define a minimum screen width so that we won't wrap the paragraph to one + // word per line during zoom-in. + private static final int MIN_SCREEN_WIDTH = 160; + // notify webkit that our virtual view size changed size (after inv-zoom) - private void viewSizeChanged(int w, int h, float scale) { + private void viewSizeChanged(int w, int h, int viewWidth) { if (LOGV_ENABLED) Log.v(LOGTAG, "CORE onSizeChanged"); + if (w == 0) { + Log.w(LOGTAG, "skip viewSizeChanged as w is 0"); + return; + } + float scale = (float) viewWidth / w; if (mSettings.getUseWideViewPort() && (w < mViewportWidth || mViewportWidth == -1)) { int width = mViewportWidth; + int screenWidth = Math.max(w, MIN_SCREEN_WIDTH); if (mViewportWidth == -1) { if (mSettings.getLayoutAlgorithm() == WebSettings.LayoutAlgorithm.NORMAL) { @@ -1154,12 +1219,21 @@ final class WebViewCore { * In the worse case, the native width will be adjusted when * next zoom or screen orientation change happens. */ - width = Math.max(w, nativeGetContentMinPrefWidth()); + int minContentWidth = nativeGetContentMinPrefWidth(); + if (minContentWidth > WebView.MAX_FLOAT_CONTENT_WIDTH) { + // keep the same width and screen width so that there is + // no reflow when zoom-out + width = minContentWidth; + screenWidth = Math.min(screenWidth, viewWidth); + } else { + width = Math.max(w, minContentWidth); + } } } - nativeSetSize(width, Math.round((float) width * h / w), w, scale); + nativeSetSize(width, Math.round((float) width * h / w), + screenWidth, scale, w, h); } else { - nativeSetSize(w, h, w, scale); + nativeSetSize(w, h, w, scale, w, h); } // Remember the current width and height boolean needInvalidate = (mCurrentViewWidth == 0); @@ -1219,7 +1293,9 @@ final class WebViewCore { draw.mViewPoint = new Point(mCurrentViewWidth, mCurrentViewHeight); if (LOGV_ENABLED) Log.v(LOGTAG, "webkitDraw NEW_PICTURE_MSG_ID"); Message.obtain(mWebView.mPrivateHandler, - WebView.NEW_PICTURE_MSG_ID, draw).sendToTarget(); + WebView.NEW_PICTURE_MSG_ID, nativeGetContentMinPrefWidth(), + 0, draw).sendToTarget(); + nativeCheckNavCache(); if (mWebkitScrollX != 0 || mWebkitScrollY != 0) { // as we have the new picture, try to sync the scroll position Message.obtain(mWebView.mPrivateHandler, @@ -1324,7 +1400,9 @@ final class WebViewCore { for (int i = 0; i < size; i++) { list.getItemAtIndex(i).inflate(mBrowserFrame.mNativeFrame); } + mBrowserFrame.mLoadInitFromJava = true; list.restoreIndex(mBrowserFrame.mNativeFrame, index); + mBrowserFrame.mLoadInitFromJava = false; } //------------------------------------------------------------------------- @@ -1349,14 +1427,15 @@ final class WebViewCore { } // called by JNI - private void contentScrollBy(int dx, int dy) { + private void contentScrollBy(int dx, int dy, boolean animate) { if (!mBrowserFrame.firstLayoutDone()) { // Will this happen? If yes, we need to do something here. return; } if (mWebView != null) { Message.obtain(mWebView.mPrivateHandler, - WebView.SCROLL_BY_MSG_ID, dx, dy).sendToTarget(); + WebView.SCROLL_BY_MSG_ID, dx, dy, + new Boolean(animate)).sendToTarget(); } } @@ -1461,7 +1540,7 @@ final class WebViewCore { // current scale mEventHub.sendMessage(Message.obtain(null, EventHub.VIEW_SIZE_CHANGED, mWebView.mLastWidthSent, - mWebView.mLastHeightSent, -1.0f)); + mWebView.mLastHeightSent, new Integer(-1))); } mBrowserFrame.didFirstLayout(); diff --git a/core/java/android/webkit/gears/HttpRequestAndroid.java b/core/java/android/webkit/gears/HttpRequestAndroid.java deleted file mode 100644 index 30f855f..0000000 --- a/core/java/android/webkit/gears/HttpRequestAndroid.java +++ /dev/null @@ -1,745 +0,0 @@ -// Copyright 2008, The Android Open Source Project -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// 3. Neither the name of Google Inc. nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package android.webkit.gears; - -import android.net.http.Headers; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.util.Log; -import android.webkit.CacheManager; -import android.webkit.CacheManager.CacheResult; -import android.webkit.CookieManager; - -import org.apache.http.conn.ssl.StrictHostnameVerifier; -import org.apache.http.impl.cookie.DateUtils; -import org.apache.http.util.CharArrayBuffer; - -import java.io.*; -import java.net.*; -import java.util.*; -import javax.net.ssl.*; - -/** - * Performs the underlying HTTP/HTTPS GET and POST requests. - * <p> These are performed synchronously (blocking). The caller should - * ensure that it is in a background thread if asynchronous behavior - * is required. All data is pushed, so there is no need for JNI native - * callbacks. - * <p> This uses the java.net.HttpURLConnection class to perform most - * of the underlying network activity. The Android brower's cache, - * android.webkit.CacheManager, is also used when caching is enabled, - * and updated with new data. The android.webkit.CookieManager is also - * queried and updated as necessary. - * <p> The public interface is designed to be called by native code - * through JNI, and to simplify coding none of the public methods will - * surface a checked exception. Unchecked exceptions may still be - * raised but only if the system is in an ill state, such as out of - * memory. - * <p> TODO: This isn't plumbed into LocalServer yet. Mutually - * dependent on LocalServer - will attach the two together once both - * are submitted. - */ -public final class HttpRequestAndroid { - /** Debug logging tag. */ - private static final String LOG_TAG = "Gears-J"; - /** HTTP response header line endings are CR-LF style. */ - private static final String HTTP_LINE_ENDING = "\r\n"; - /** Safe MIME type to use whenever it isn't specified. */ - private static final String DEFAULT_MIME_TYPE = "text/plain"; - /** Case-sensitive header keys */ - public static final String KEY_CONTENT_LENGTH = "Content-Length"; - public static final String KEY_EXPIRES = "Expires"; - public static final String KEY_LAST_MODIFIED = "Last-Modified"; - public static final String KEY_ETAG = "ETag"; - public static final String KEY_LOCATION = "Location"; - public static final String KEY_CONTENT_TYPE = "Content-Type"; - /** Number of bytes to send and receive on the HTTP connection in - * one go. */ - private static final int BUFFER_SIZE = 4096; - /** The first element of the String[] value in a headers map is the - * unmodified (case-sensitive) key. */ - public static final int HEADERS_MAP_INDEX_KEY = 0; - /** The second element of the String[] value in a headers map is the - * associated value. */ - public static final int HEADERS_MAP_INDEX_VALUE = 1; - - /** Enable/disable all logging in this class. */ - private static boolean logEnabled = false; - /** The underlying HTTP or HTTPS network connection. */ - private HttpURLConnection connection; - /** HTTP body stream, setup after connection. */ - private InputStream inputStream; - /** The complete response line e.g "HTTP/1.0 200 OK" */ - private String responseLine; - /** Request headers, as a lowercase key -> [ unmodified key, value ] map. */ - private Map<String, String[]> requestHeaders = - new HashMap<String, String[]>(); - /** Response headers, as a lowercase key -> [ unmodified key, value ] map. */ - private Map<String, String[]> responseHeaders; - /** True if the child thread is in performing blocking IO. */ - private boolean inBlockingOperation = false; - /** True when the thread acknowledges the abort. */ - private boolean abortReceived = false; - /** The URL used for createCacheResult() */ - private String cacheResultUrl; - /** CacheResult being saved into, if inserting a new cache entry. */ - private CacheResult cacheResult; - /** Initialized by initChildThread(). Used to target abort(). */ - private Thread childThread; - - /** - * Convenience debug function. Calls Android logging mechanism. - * @param str String to log to the Android console. - */ - private static void log(String str) { - if (logEnabled) { - Log.i(LOG_TAG, str); - } - } - - /** - * Turn on/off logging in this class. - * @param on Logging enable state. - */ - public static void enableLogging(boolean on) { - logEnabled = on; - } - - /** - * Initialize childThread using the TLS value of - * Thread.currentThread(). Called on start up of the native child - * thread. - */ - public synchronized void initChildThread() { - childThread = Thread.currentThread(); - } - - /** - * Analagous to the native-side HttpRequest::open() function. This - * initializes an underlying java.net.HttpURLConnection, but does - * not go to the wire. On success, this enables a call to send() to - * initiate the transaction. - * - * @param method The HTTP method, e.g GET or POST. - * @param url The URL to open. - * @return True on success with a complete HTTP response. - * False on failure. - */ - public synchronized boolean open(String method, String url) { - if (logEnabled) - log("open " + method + " " + url); - // Reset the response between calls to open(). - inputStream = null; - responseLine = null; - responseHeaders = null; - if (!method.equals("GET") && !method.equals("POST")) { - log("Method " + method + " not supported"); - return false; - } - // Setup the connection. This doesn't go to the wire yet - it - // doesn't block. - try { - URL url_object = new URL(url); - // Check that the protocol is indeed HTTP(S). - String protocol = url_object.getProtocol(); - if (protocol == null) { - log("null protocol for URL " + url); - return false; - } - protocol = protocol.toLowerCase(); - if (!"http".equals(protocol) && !"https".equals(protocol)) { - log("Url has wrong protocol: " + url); - return false; - } - - connection = (HttpURLConnection) url_object.openConnection(); - connection.setRequestMethod(method); - // Manually follow redirects. - connection.setInstanceFollowRedirects(false); - // Manually cache. - connection.setUseCaches(false); - // Enable data output in POST method requests. - connection.setDoOutput(method.equals("POST")); - // Enable data input in non-HEAD method requests. - // TODO: HEAD requests not tested. - connection.setDoInput(!method.equals("HEAD")); - if (connection instanceof javax.net.ssl.HttpsURLConnection) { - // Verify the certificate matches the origin. - ((HttpsURLConnection) connection).setHostnameVerifier( - new StrictHostnameVerifier()); - } - return true; - } catch (IOException e) { - log("Got IOException in open: " + e.toString()); - return false; - } - } - - /** - * Interrupt a blocking IO operation. This will cause the child - * thread to expediently return from an operation if it was stuck at - * the time. Note that this inherently races, and unfortunately - * requires the caller to loop. - */ - public synchronized void interrupt() { - if (childThread == null) { - log("interrupt() called but no child thread"); - return; - } - synchronized (this) { - if (inBlockingOperation) { - log("Interrupting blocking operation"); - childThread.interrupt(); - } else { - log("Nothing to interrupt"); - } - } - } - - /** - * Set a header to send with the HTTP request. Will not take effect - * on a transaction already in progress. The key is associated - * case-insensitive, but stored case-sensitive. - * @param name The name of the header, e.g "Set-Cookie". - * @param value The value for this header, e.g "text/html". - */ - public synchronized void setRequestHeader(String name, String value) { - String[] mapValue = { name, value }; - requestHeaders.put(name.toLowerCase(), mapValue); - } - - /** - * Returns the value associated with the given request header. - * @param name The name of the request header, non-null, case-insensitive. - * @return The value associated with the request header, or null if - * not set, or error. - */ - public synchronized String getRequestHeader(String name) { - String[] value = requestHeaders.get(name.toLowerCase()); - if (value != null) { - return value[HEADERS_MAP_INDEX_VALUE]; - } else { - return null; - } - } - - /** - * Returns the value associated with the given response header. - * @param name The name of the response header, non-null, case-insensitive. - * @return The value associated with the response header, or null if - * not set or error. - */ - public synchronized String getResponseHeader(String name) { - if (responseHeaders != null) { - String[] value = responseHeaders.get(name.toLowerCase()); - if (value != null) { - return value[HEADERS_MAP_INDEX_VALUE]; - } else { - return null; - } - } else { - log("getResponseHeader() called but response not received"); - return null; - } - } - - /** - * Set a response header and associated value. The key is associated - * case-insensitively, but stored case-sensitively. - * @param name Case sensitive request header key. - * @param value The associated value. - */ - private void setResponseHeader(String name, String value) { - if (logEnabled) - log("Set response header " + name + ": " + value); - String mapValue[] = { name, value }; - responseHeaders.put(name.toLowerCase(), mapValue); - } - - /** - * Apply the contents of the Map requestHeaders to the connection - * object. Calls to setRequestHeader() after this will not affect - * the connection. - */ - private synchronized void applyRequestHeadersToConnection() { - Iterator<String[]> it = requestHeaders.values().iterator(); - while (it.hasNext()) { - // Set the key case-sensitive. - String[] entry = it.next(); - connection.setRequestProperty( - entry[HEADERS_MAP_INDEX_KEY], - entry[HEADERS_MAP_INDEX_VALUE]); - } - } - - /** - * Return all response headers, separated by CR-LF line endings, and - * ending with a trailing blank line. This mimics the format of the - * raw response header up to but not including the body. - * @return A string containing the entire response header. - */ - public synchronized String getAllResponseHeaders() { - if (responseHeaders == null) { - log("getAllResponseHeaders() called but response not received"); - return null; - } - String result = new String(); - Iterator<String[]> it = responseHeaders.values().iterator(); - while (it.hasNext()) { - String[] entry = it.next(); - // Output the "key: value" lines. - result += entry[HEADERS_MAP_INDEX_KEY] + ": " - + entry[HEADERS_MAP_INDEX_VALUE] + HTTP_LINE_ENDING; - } - result += HTTP_LINE_ENDING; - return result; - } - - /** - * Get the complete response line of the HTTP request. Only valid on - * completion of the transaction. - * @return The complete HTTP response line, e.g "HTTP/1.0 200 OK". - */ - public synchronized String getResponseLine() { - return responseLine; - } - - /** - * Get the cookie for the given URL. - * @param url The fully qualified URL. - * @return A string containing the cookie for the URL if it exists, - * or null if not. - */ - public static String getCookieForUrl(String url) { - // Get the cookie for this URL, set as a header - return CookieManager.getInstance().getCookie(url); - } - - /** - * Set the cookie for the given URL. - * @param url The fully qualified URL. - * @param cookie The new cookie value. - * @return A string containing the cookie for the URL if it exists, - * or null if not. - */ - public static void setCookieForUrl(String url, String cookie) { - // Get the cookie for this URL, set as a header - CookieManager.getInstance().setCookie(url, cookie); - } - - /** - * Perform a request using LocalServer if possible. Initializes - * class members so that receive() will obtain data from the stream - * provided by the response. - * @param url The fully qualified URL to try in LocalServer. - * @return True if the url was found and is now setup to receive. - * False if not found, with no side-effect. - */ - public synchronized boolean useLocalServerResult(String url) { - UrlInterceptHandlerGears handler = UrlInterceptHandlerGears.getInstance(); - if (handler == null) { - return false; - } - UrlInterceptHandlerGears.ServiceResponse serviceResponse = - handler.getServiceResponse(url, requestHeaders); - if (serviceResponse == null) { - log("No response in LocalServer"); - return false; - } - // LocalServer will handle this URL. Initialize stream and - // response. - inputStream = serviceResponse.getInputStream(); - responseLine = serviceResponse.getStatusLine(); - responseHeaders = serviceResponse.getResponseHeaders(); - if (logEnabled) - log("Got response from LocalServer: " + responseLine); - return true; - } - - /** - * Perform a request using the cache result if present. Initializes - * class members so that receive() will obtain data from the cache. - * @param url The fully qualified URL to try in the cache. - * @return True is the url was found and is now setup to receive - * from cache. False if not found, with no side-effect. - */ - public synchronized boolean useCacheResult(String url) { - // Try the browser's cache. CacheManager wants a Map<String, String>. - Map<String, String> cacheRequestHeaders = new HashMap<String, String>(); - Iterator<Map.Entry<String, String[]>> it = - requestHeaders.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry<String, String[]> entry = it.next(); - cacheRequestHeaders.put( - entry.getKey(), - entry.getValue()[HEADERS_MAP_INDEX_VALUE]); - } - CacheResult cacheResult = - CacheManager.getCacheFile(url, cacheRequestHeaders); - if (cacheResult == null) { - if (logEnabled) - log("No CacheResult for " + url); - return false; - } - if (logEnabled) - log("Got CacheResult from browser cache"); - // Check for expiry. -1 is "never", otherwise milliseconds since 1970. - // Can be compared to System.currentTimeMillis(). - long expires = cacheResult.getExpires(); - if (expires >= 0 && System.currentTimeMillis() >= expires) { - log("CacheResult expired " - + (System.currentTimeMillis() - expires) - + " milliseconds ago"); - // Cache hit has expired. Do not return it. - return false; - } - // Setup the inputStream to come from the cache. - inputStream = cacheResult.getInputStream(); - if (inputStream == null) { - // Cache result may have gone away. - log("No inputStream for CacheResult " + url); - return false; - } - // Cache hit. Parse headers. - synthesizeHeadersFromCacheResult(cacheResult); - return true; - } - - /** - * Take the limited set of headers in a CacheResult and synthesize - * response headers. - * @param cacheResult A CacheResult to populate responseHeaders with. - */ - private void synthesizeHeadersFromCacheResult(CacheResult cacheResult) { - int statusCode = cacheResult.getHttpStatusCode(); - // The status message is informal, so we can greatly simplify it. - String statusMessage; - if (statusCode >= 200 && statusCode < 300) { - statusMessage = "OK"; - } else if (statusCode >= 300 && statusCode < 400) { - statusMessage = "MOVED"; - } else { - statusMessage = "UNAVAILABLE"; - } - // Synthesize the response line. - responseLine = "HTTP/1.1 " + statusCode + " " + statusMessage; - if (logEnabled) - log("Synthesized " + responseLine); - // Synthesize the returned headers from cache. - responseHeaders = new HashMap<String, String[]>(); - String contentLength = Long.toString(cacheResult.getContentLength()); - setResponseHeader(KEY_CONTENT_LENGTH, contentLength); - long expires = cacheResult.getExpires(); - if (expires >= 0) { - // "Expires" header is valid and finite. Milliseconds since 1970 - // epoch, formatted as RFC-1123. - String expiresString = DateUtils.formatDate(new Date(expires)); - setResponseHeader(KEY_EXPIRES, expiresString); - } - String lastModified = cacheResult.getLastModified(); - if (lastModified != null) { - // Last modification time of the page. Passed end-to-end, but - // not used by us. - setResponseHeader(KEY_LAST_MODIFIED, lastModified); - } - String eTag = cacheResult.getETag(); - if (eTag != null) { - // Entity tag. A kind of GUID to identify identical resources. - setResponseHeader(KEY_ETAG, eTag); - } - String location = cacheResult.getLocation(); - if (location != null) { - // If valid, refers to the location of a redirect. - setResponseHeader(KEY_LOCATION, location); - } - String mimeType = cacheResult.getMimeType(); - if (mimeType == null) { - // Use a safe default MIME type when none is - // specified. "text/plain" is safe to render in the browser - // window (even if large) and won't be intepreted as anything - // that would cause execution. - mimeType = DEFAULT_MIME_TYPE; - } - String encoding = cacheResult.getEncoding(); - // Encoding may not be specified. No default. - String contentType = mimeType; - if (encoding != null && encoding.length() > 0) { - contentType += "; charset=" + encoding; - } - setResponseHeader(KEY_CONTENT_TYPE, contentType); - } - - /** - * Create a CacheResult for this URL. This enables the repsonse body - * to be sent in calls to appendCacheResult(). - * @param url The fully qualified URL to add to the cache. - * @param responseCode The response code returned for the request, e.g 200. - * @param mimeType The MIME type of the body, e.g "text/plain". - * @param encoding The encoding, e.g "utf-8". Use "" for unknown. - */ - public synchronized boolean createCacheResult( - String url, int responseCode, String mimeType, String encoding) { - if (logEnabled) - log("Making cache entry for " + url); - // Take the headers and parse them into a format needed by - // CacheManager. - Headers cacheHeaders = new Headers(); - Iterator<Map.Entry<String, String[]>> it = - responseHeaders.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry<String, String[]> entry = it.next(); - // Headers.parseHeader() expects lowercase keys. - String keyValue = entry.getKey() + ": " - + entry.getValue()[HEADERS_MAP_INDEX_VALUE]; - CharArrayBuffer buffer = new CharArrayBuffer(keyValue.length()); - buffer.append(keyValue); - // Parse it into the header container. - cacheHeaders.parseHeader(buffer); - } - cacheResult = CacheManager.createCacheFile( - url, responseCode, cacheHeaders, mimeType, true); - if (cacheResult != null) { - if (logEnabled) - log("Saving into cache"); - cacheResult.setEncoding(encoding); - cacheResultUrl = url; - return true; - } else { - log("Couldn't create cacheResult"); - return false; - } - } - - /** - * Add data from the response body to the CacheResult created with - * createCacheResult(). - * @param data A byte array of the next sequential bytes in the - * response body. - * @param bytes The number of bytes to write from the start of - * the array. - * @return True if all bytes successfully written, false on failure. - */ - public synchronized boolean appendCacheResult(byte[] data, int bytes) { - if (cacheResult == null) { - log("appendCacheResult() called without a CacheResult initialized"); - return false; - } - try { - cacheResult.getOutputStream().write(data, 0, bytes); - } catch (IOException ex) { - log("Got IOException writing cache data: " + ex); - return false; - } - return true; - } - - /** - * Save the completed CacheResult into the CacheManager. This must - * have been created first with createCacheResult(). - * @return Returns true if the entry has been successfully saved. - */ - public synchronized boolean saveCacheResult() { - if (cacheResult == null || cacheResultUrl == null) { - log("Tried to save cache result but createCacheResult not called"); - return false; - } - if (logEnabled) - log("Saving cache result"); - CacheManager.saveCacheFile(cacheResultUrl, cacheResult); - cacheResult = null; - cacheResultUrl = null; - return true; - } - - /** - * Perform an HTTP request on the network. The underlying - * HttpURLConnection is connected to the remote server and the - * response headers are received. - * @return True if the connection succeeded and headers have been - * received. False on connection failure. - */ - public boolean connectToRemote() { - synchronized (this) { - // Transfer a snapshot of our internally maintained map of request - // headers to the connection object. - applyRequestHeadersToConnection(); - // Note blocking I/O so abort() can interrupt us. - inBlockingOperation = true; - } - boolean success; - try { - if (logEnabled) - log("Connecting to remote"); - connection.connect(); - if (logEnabled) - log("Connected"); - success = true; - } catch (IOException e) { - log("Got IOException in connect(): " + e.toString()); - success = false; - } finally { - synchronized (this) { - // No longer blocking. - inBlockingOperation = false; - } - } - return success; - } - - /** - * Receive all headers from the server and populate - * responseHeaders. This converts from the slightly odd format - * returned by java.net.HttpURLConnection to a simpler - * java.util.Map. - * @return True if headers are successfully received, False on - * connection error. - */ - public synchronized boolean parseHeaders() { - responseHeaders = new HashMap<String, String[]>(); - /* HttpURLConnection contains a null terminated list of - * key->value response pairs. If the key is null, then the value - * contains the complete status line. If both key and value are - * null for an index, we've reached the end. - */ - for (int i = 0; ; ++i) { - String key = connection.getHeaderFieldKey(i); - String value = connection.getHeaderField(i); - if (logEnabled) - log("header " + key + " -> " + value); - if (key == null && value == null) { - // End of list. - break; - } else if (key == null) { - // The pair with null key has the complete status line in - // the value, e.g "HTTP/1.0 200 OK". - responseLine = value; - } else if (value != null) { - // If key and value are non-null, this is a response pair, e.g - // "Content-Length" -> "5". Use setResponseHeader() to - // correctly deal with case-insensitivity of the key. - setResponseHeader(key, value); - } else { - // The key is non-null but value is null. Unexpected - // condition. - return false; - } - } - return true; - } - - /** - * Receive the next sequential bytes of the response body after - * successful connection. This will receive up to the size of the - * provided byte array. If there is no body, this will return 0 - * bytes on the first call after connection. - * @param buf A pre-allocated byte array to receive data into. - * @return The number of bytes from the start of the array which - * have been filled, 0 on EOF, or negative on error. - */ - public int receive(byte[] buf) { - if (inputStream == null) { - // If this is the first call, setup the InputStream. This may - // fail if there were headers, but no body returned by the - // server. - try { - inputStream = connection.getInputStream(); - } catch (IOException inputException) { - log("Failed to connect InputStream: " + inputException); - // Not unexpected. For example, 404 response return headers, - // and sometimes a body with a detailed error. Try the error - // stream. - inputStream = connection.getErrorStream(); - if (inputStream == null) { - // No error stream either. Treat as a 0 byte response. - log("No InputStream"); - return 0; // EOF. - } - } - } - synchronized (this) { - // Note blocking I/O so abort() can interrupt us. - inBlockingOperation = true; - } - int ret; - try { - int got = inputStream.read(buf); - if (got > 0) { - // Got some bytes, not EOF. - ret = got; - } else { - // EOF. - inputStream.close(); - ret = 0; - } - } catch (IOException e) { - // An abort() interrupts us by calling close() on our stream. - log("Got IOException in inputStream.read(): " + e.toString()); - ret = -1; - } finally { - synchronized (this) { - // No longer blocking. - inBlockingOperation = false; - } - } - return ret; - } - - /** - * For POST method requests, send a stream of data provided by the - * native side in repeated callbacks. - * @param data A byte array containing the data to sent, or null - * if indicating EOF. - * @param bytes The number of bytes from the start of the array to - * send, or 0 if indicating EOF. - * @return True if all bytes were successfully sent, false on error. - */ - public boolean sendPostData(byte[] data, int bytes) { - synchronized (this) { - // Note blocking I/O so abort() can interrupt us. - inBlockingOperation = true; - } - boolean success; - try { - OutputStream outputStream = connection.getOutputStream(); - if (data == null && bytes == 0) { - outputStream.close(); - } else { - outputStream.write(data, 0, bytes); - } - success = true; - } catch (IOException e) { - log("Got IOException in post: " + e.toString()); - success = false; - } finally { - synchronized (this) { - // No longer blocking. - inBlockingOperation = false; - } - } - return success; - } -} diff --git a/core/java/android/webkit/gears/UrlInterceptHandlerGears.java b/core/java/android/webkit/gears/UrlInterceptHandlerGears.java index 288240e..2a5cbe9 100644 --- a/core/java/android/webkit/gears/UrlInterceptHandlerGears.java +++ b/core/java/android/webkit/gears/UrlInterceptHandlerGears.java @@ -64,11 +64,11 @@ public class UrlInterceptHandlerGears implements UrlInterceptHandler { /** The unmodified (case-sensitive) key in the headers map is the * same index as used by HttpRequestAndroid. */ public static final int HEADERS_MAP_INDEX_KEY = - HttpRequestAndroid.HEADERS_MAP_INDEX_KEY; + ApacheHttpRequestAndroid.HEADERS_MAP_INDEX_KEY; /** The associated value in the headers map is the same index as * used by HttpRequestAndroid. */ public static final int HEADERS_MAP_INDEX_VALUE = - HttpRequestAndroid.HEADERS_MAP_INDEX_VALUE; + ApacheHttpRequestAndroid.HEADERS_MAP_INDEX_VALUE; /** * Object passed to the native side, containing information about @@ -382,7 +382,7 @@ public class UrlInterceptHandlerGears implements UrlInterceptHandler { // browser's cache for too long. long now_ms = System.currentTimeMillis(); String expires = DateUtils.formatDate(new Date(now_ms + CACHE_EXPIRY_MS)); - response.setResponseHeader(HttpRequestAndroid.KEY_EXPIRES, expires); + response.setResponseHeader(ApacheHttpRequestAndroid.KEY_EXPIRES, expires); // The browser is only interested in a small subset of headers, // contained in a Headers object. Iterate the map of all headers // and add them to Headers. diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index c012e25..f362e22 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -41,7 +41,7 @@ import android.view.ViewConfiguration; import android.view.ViewDebug; import android.view.ViewGroup; import android.view.ViewTreeObserver; -import android.view.WindowManagerImpl; +import android.view.inputmethod.InputMethodManager; import android.view.ContextMenu.ContextMenuInfo; import com.android.internal.R; @@ -425,6 +425,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private int mTouchSlop; + private float mDensityScale; + /** * Interface definition for a callback to be invoked when the list or grid * has been scrolled. @@ -567,7 +569,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ @Override protected boolean isVerticalScrollBarHidden() { - return mFastScroller != null ? mFastScroller.isVisible() : false; + return mFastScroller != null && mFastScroller.isVisible(); } /** @@ -709,6 +711,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te setScrollingCacheEnabled(true); mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop(); + mDensityScale = getContext().getResources().getDisplayMetrics().density; } private void useDefaultSelector() { @@ -891,14 +894,26 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } // Don't restore the type filter window when there is no keyboard - int keyboardHidden = getContext().getResources().getConfiguration().keyboardHidden; - if (keyboardHidden != Configuration.KEYBOARDHIDDEN_YES) { + if (acceptFilter()) { String filterText = ss.filter; setFilterText(filterText); } + requestLayout(); } + private boolean acceptFilter() { + final Context context = mContext; + final Configuration configuration = context.getResources().getConfiguration(); + final boolean keyboardShowing = configuration.keyboardHidden != + Configuration.KEYBOARDHIDDEN_YES; + final boolean hasKeyboard = configuration.keyboard != Configuration.KEYBOARD_NOKEYS; + final InputMethodManager inputManager = (InputMethodManager) + context.getSystemService(Context.INPUT_METHOD_SERVICE); + return (hasKeyboard && keyboardShowing) || + (!hasKeyboard && !inputManager.isFullscreenMode()); + } + /** * Sets the initial value for the text filter. * @param filterText The text to use for the filter. @@ -906,6 +921,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @see #setTextFilterEnabled */ public void setFilterText(String filterText) { + // TODO: Should we check for acceptFilter()? if (mTextFilterEnabled && filterText != null && filterText.length() > 0) { createTextFilter(false); // This is going to call our listener onTextChanged, but we might not @@ -1076,6 +1092,24 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mInLayout = false; } + /** + * @hide + */ + @Override + protected boolean setFrame(int left, int top, int right, int bottom) { + final boolean changed = super.setFrame(left, top, right, bottom); + + // Reposition the popup when the frame has changed. This includes + // translating the widget, not just changing its dimension. The + // filter popup needs to follow the widget. + if (mFiltered && changed && getWindowVisibility() == View.VISIBLE && mPopup != null && + mPopup.isShowing()) { + positionPopup(true); + } + + return changed; + } + protected void layoutChildren() { } @@ -2587,10 +2621,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te clearScrollingCache(); mSpecificTop = selectedTop; selectedPos = lookForSelectablePosition(selectedPos, down); - if (selectedPos >= 0) { + if (selectedPos >= firstPosition && selectedPos <= getLastVisiblePosition()) { mLayoutMode = LAYOUT_SPECIFIC; setSelectionInt(selectedPos); invokeOnItemScrollListener(); + } else { + selectedPos = INVALID_POSITION; } reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); @@ -2727,19 +2763,27 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private void showPopup() { // Make sure we have a window before showing the popup if (getWindowVisibility() == View.VISIBLE) { - int screenHeight = WindowManagerImpl.getDefault().getDefaultDisplay().getHeight(); - final int[] xy = new int[2]; - getLocationOnScreen(xy); - // TODO: The 20 below should come from the theme and be expressed in dip - final float scale = getContext().getResources().getDisplayMetrics().density; - int bottomGap = screenHeight - xy[1] - getHeight() + (int) (scale * 20); - mPopup.showAtLocation(this, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, - xy[0], bottomGap); + positionPopup(false); // Make sure we get focus if we are showing the popup checkFocus(); } } + private void positionPopup(boolean update) { + int screenHeight = getResources().getDisplayMetrics().heightPixels; + final int[] xy = new int[2]; + getLocationOnScreen(xy); + // TODO: The 20 below should come from the theme and be expressed in dip + // TODO: And the gravity should be defined in the theme as well + final int bottomGap = screenHeight - xy[1] - getHeight() + (int) (mDensityScale * 20); + if (!update) { + mPopup.showAtLocation(this, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, + xy[0], bottomGap); + } else { + mPopup.update(xy[0], bottomGap, -1, -1); + } + } + /** * What is the distance between the source and destination rectangles given the direction of * focus navigation between them? The direction basically helps figure out more quickly what is @@ -2831,7 +2875,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te break; } - if (okToSend) { + if (okToSend && acceptFilter()) { createTextFilter(true); KeyEvent forwardEvent = event; @@ -2873,6 +2917,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTextFilter.addTextChangedListener(this); p.setFocusable(false); p.setTouchable(false); + p.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); p.setContentView(mTextFilter); p.setWidth(LayoutParams.WRAP_CONTENT); p.setHeight(LayoutParams.WRAP_CONTENT); diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java index 7086ae2..369221e 100644 --- a/core/java/android/widget/Chronometer.java +++ b/core/java/android/widget/Chronometer.java @@ -46,6 +46,18 @@ import java.util.Locale; public class Chronometer extends TextView { private static final String TAG = "Chronometer"; + /** + * A callback that notifies when the chronometer has incremented on its own. + */ + public interface OnChronometerTickListener { + + /** + * Notification that the chronometer has changed. + */ + void onChronometerTick(Chronometer chronometer); + + } + private long mBase; private boolean mVisible; private boolean mStarted; @@ -56,6 +68,7 @@ public class Chronometer extends TextView { private Locale mFormatterLocale; private Object[] mFormatterArgs = new Object[1]; private StringBuilder mFormatBuilder; + private OnChronometerTickListener mOnChronometerTickListener; /** * Initialize this Chronometer object. @@ -99,6 +112,7 @@ public class Chronometer extends TextView { * * @param base Use the {@link SystemClock#elapsedRealtime} time base. */ + @android.view.RemotableViewMethod public void setBase(long base) { mBase = base; updateText(SystemClock.elapsedRealtime()); @@ -122,6 +136,7 @@ public class Chronometer extends TextView { * * @param format the format string. */ + @android.view.RemotableViewMethod public void setFormat(String format) { mFormat = format; if (format != null && mFormatBuilder == null) { @@ -137,6 +152,23 @@ public class Chronometer extends TextView { } /** + * Sets the listener to be called when the chronometer changes. + * + * @param listener The listener. + */ + public void setOnChronometerTickListener(OnChronometerTickListener listener) { + mOnChronometerTickListener = listener; + } + + /** + * @return The listener (may be null) that is listening for chronometer change + * events. + */ + public OnChronometerTickListener getOnChronometerTickListener() { + return mOnChronometerTickListener; + } + + /** * Start counting up. This does not affect the base as set from {@link #setBase}, just * the view display. * @@ -161,6 +193,15 @@ public class Chronometer extends TextView { updateRunning(); } + /** + * The same as calling {@link #start} or {@link #stop}. + */ + @android.view.RemotableViewMethod + public void setStarted(boolean started) { + mStarted = started; + updateRunning(); + } + @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); @@ -216,8 +257,15 @@ public class Chronometer extends TextView { public void handleMessage(Message m) { if (mStarted) { updateText(SystemClock.elapsedRealtime()); + dispatchChronometerTick(); sendMessageDelayed(Message.obtain(), 1000); } } }; + + void dispatchChronometerTick() { + if (mOnChronometerTickListener != null) { + mOnChronometerTickListener.onChronometerTick(this); + } + } } diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java index b4ed3ba..8aafee2 100644 --- a/core/java/android/widget/FrameLayout.java +++ b/core/java/android/widget/FrameLayout.java @@ -93,6 +93,7 @@ public class FrameLayout extends ViewGroup { * * @attr ref android.R.styleable#FrameLayout_foregroundGravity */ + @android.view.RemotableViewMethod public void setForegroundGravity(int foregroundGravity) { if (mForegroundGravity != foregroundGravity) { if ((foregroundGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) { @@ -348,6 +349,7 @@ public class FrameLayout extends ViewGroup { * * @attr ref android.R.styleable#FrameLayout_measureAllChildren */ + @android.view.RemotableViewMethod public void setMeasureAllChildren(boolean measureAll) { mMeasureAllChildren = measureAll; } diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index 4ae322e..94d1bd1 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -193,6 +193,7 @@ public class ImageView extends View { * * @attr ref android.R.styleable#ImageView_adjustViewBounds */ + @android.view.RemotableViewMethod public void setAdjustViewBounds(boolean adjustViewBounds) { mAdjustViewBounds = adjustViewBounds; if (adjustViewBounds) { @@ -217,6 +218,7 @@ public class ImageView extends View { * * @attr ref android.R.styleable#ImageView_maxWidth */ + @android.view.RemotableViewMethod public void setMaxWidth(int maxWidth) { mMaxWidth = maxWidth; } @@ -238,6 +240,7 @@ public class ImageView extends View { * * @attr ref android.R.styleable#ImageView_maxHeight */ + @android.view.RemotableViewMethod public void setMaxHeight(int maxHeight) { mMaxHeight = maxHeight; } @@ -256,6 +259,7 @@ public class ImageView extends View { * * @attr ref android.R.styleable#ImageView_src */ + @android.view.RemotableViewMethod public void setImageResource(int resId) { if (mUri != null || mResource != resId) { updateDrawable(null); @@ -272,6 +276,7 @@ public class ImageView extends View { * * @param uri The Uri of an image */ + @android.view.RemotableViewMethod public void setImageURI(Uri uri) { if (mResource != 0 || (mUri != uri && @@ -306,6 +311,7 @@ public class ImageView extends View { * * @param bm The bitmap to set */ + @android.view.RemotableViewMethod public void setImageBitmap(Bitmap bm) { // if this is used frequently, may handle bitmaps explicitly // to reduce the intermediate drawable object @@ -327,6 +333,7 @@ public class ImageView extends View { resizeFromDrawable(); } + @android.view.RemotableViewMethod public void setImageLevel(int level) { mLevel = level; if (mDrawable != null) { diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java index 85a7339..a9822f8 100644 --- a/core/java/android/widget/LinearLayout.java +++ b/core/java/android/widget/LinearLayout.java @@ -136,6 +136,7 @@ public class LinearLayout extends ViewGroup { * * @attr ref android.R.styleable#LinearLayout_baselineAligned */ + @android.view.RemotableViewMethod public void setBaselineAligned(boolean baselineAligned) { mBaselineAligned = baselineAligned; } @@ -208,6 +209,7 @@ public class LinearLayout extends ViewGroup { * * @attr ref android.R.styleable#LinearLayout_baselineAlignedChildIndex */ + @android.view.RemotableViewMethod public void setBaselineAlignedChildIndex(int i) { if ((i < 0) || (i >= getChildCount())) { throw new IllegalArgumentException("base aligned child index out " @@ -265,6 +267,7 @@ public class LinearLayout extends ViewGroup { * to 0.0f if the weight sum should be computed from the children's * layout_weight */ + @android.view.RemotableViewMethod public void setWeightSum(float weightSum) { mWeightSum = Math.max(0.0f, weightSum); } @@ -1149,6 +1152,7 @@ public class LinearLayout extends ViewGroup { * * @attr ref android.R.styleable#LinearLayout_gravity */ + @android.view.RemotableViewMethod public void setGravity(int gravity) { if (mGravity != gravity) { if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) { @@ -1164,6 +1168,7 @@ public class LinearLayout extends ViewGroup { } } + @android.view.RemotableViewMethod public void setHorizontalGravity(int horizontalGravity) { final int gravity = horizontalGravity & Gravity.HORIZONTAL_GRAVITY_MASK; if ((mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != gravity) { @@ -1172,6 +1177,7 @@ public class LinearLayout extends ViewGroup { } } + @android.view.RemotableViewMethod public void setVerticalGravity(int verticalGravity) { final int gravity = verticalGravity & Gravity.VERTICAL_GRAVITY_MASK; if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != gravity) { diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 9c7f600..4e5989c 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -2179,6 +2179,10 @@ public class ListView extends AbsListView { && !isViewAncestorOf(selectedView, this)) { selectedView = null; hideSelector(); + + // but we don't want to set the ressurect position (that would make subsequent + // unhandled key events bring back the item we just scrolled off!) + mResurrectToPosition = INVALID_POSITION; } if (needToRedraw) { diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index dada105..4a5cea1 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -24,6 +24,8 @@ import android.view.View; import android.view.WindowManager; import android.view.Gravity; import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.View.OnTouchListener; import android.graphics.PixelFormat; import android.graphics.Rect; @@ -33,6 +35,8 @@ import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; +import java.lang.ref.WeakReference; + /** * <p>A popup window that can be used to display an arbitrary view. The popup * windows is a floating container that appears on top of the current @@ -109,7 +113,23 @@ public class PopupWindow { private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] { com.android.internal.R.attr.state_above_anchor }; - + + private WeakReference<View> mAnchor; + private OnScrollChangedListener mOnScrollChangedListener = + new OnScrollChangedListener() { + public void onScrollChanged() { + View anchor = mAnchor.get(); + if (anchor != null && mPopupView != null) { + WindowManager.LayoutParams p = (WindowManager.LayoutParams) + mPopupView.getLayoutParams(); + + mAboveAnchor = findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff); + update(p.x, p.y, -1, -1, true); + } + } + }; + private int mAnchorXoff, mAnchorYoff; + /** * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> * @@ -579,6 +599,8 @@ public class PopupWindow { return; } + unregisterForScrollChanged(); + mIsShowing = true; mIsDropdown = false; @@ -617,6 +639,8 @@ public class PopupWindow { * the popup in its entirety, this method tries to find a parent scroll * view to scroll. If no parent scroll view can be scrolled, the bottom-left * corner of the popup is pinned at the top left corner of the anchor view.</p> + * <p>If the view later scrolls to move <code>anchor</code> to a different + * location, the popup will be moved correspondingly.</p> * * @param anchor the view on which to pin the popup window * @@ -627,6 +651,8 @@ public class PopupWindow { return; } + registerForScrollChanged(anchor, xoff, yoff); + mIsShowing = true; mIsDropdown = true; @@ -894,6 +920,8 @@ public class PopupWindow { */ public void dismiss() { if (isShowing() && mPopupView != null) { + unregisterForScrollChanged(); + mWindowManager.removeView(mPopupView); if (mPopupView != mContentView && mPopupView instanceof ViewGroup) { ((ViewGroup) mPopupView).removeView(mContentView); @@ -962,6 +990,25 @@ public class PopupWindow { * @param height the new height, can be -1 to ignore */ public void update(int x, int y, int width, int height) { + update(x, y, width, height, false); + } + + /** + * <p>Updates the position and the dimension of the popup window. Width and + * height can be set to -1 to update location only. Calling this function + * also updates the window with the current popup state as + * described for {@link #update()}.</p> + * + * @param x the new x location + * @param y the new y location + * @param width the new width, can be -1 to ignore + * @param height the new height, can be -1 to ignore + * @param force reposition the window even if the specified position + * already seems to correspond to the LayoutParams + * + * @hide pending API council approval + */ + public void update(int x, int y, int width, int height, boolean force) { if (width != -1) { mLastWidth = width; setWidth(width); @@ -979,7 +1026,7 @@ public class PopupWindow { WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams(); - boolean update = false; + boolean update = force; final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth; if (width != -1 && p.width != finalWidth) { @@ -1039,6 +1086,8 @@ public class PopupWindow { * height can be set to -1 to update location only. Calling this function * also updates the window with the current popup state as * described for {@link #update()}.</p> + * <p>If the view later scrolls to move <code>anchor</code> to a different + * location, the popup will be moved correspondingly.</p> * * @param anchor the popup's anchor view * @param xoff x offset from the view's left edge @@ -1051,6 +1100,12 @@ public class PopupWindow { return; } + WeakReference<View> oldAnchor = mAnchor; + if (oldAnchor == null || oldAnchor.get() != anchor || + mAnchorXoff != xoff || mAnchorYoff != yoff) { + registerForScrollChanged(anchor, xoff, yoff); + } + WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams(); @@ -1065,10 +1120,10 @@ public class PopupWindow { mPopupHeight = height; } - findDropDownPosition(anchor, p, xoff, yoff); + mAboveAnchor = findDropDownPosition(anchor, p, xoff, yoff); update(p.x, p.y, width, height); } - + /** * Listener that is called when this popup window is dismissed. */ @@ -1078,7 +1133,33 @@ public class PopupWindow { */ public void onDismiss(); } - + + private void unregisterForScrollChanged() { + WeakReference<View> anchorRef = mAnchor; + View anchor = null; + if (anchorRef != null) { + anchor = anchorRef.get(); + } + if (anchor != null) { + ViewTreeObserver vto = anchor.getViewTreeObserver(); + vto.removeOnScrollChangedListener(mOnScrollChangedListener); + } + mAnchor = null; + } + + private void registerForScrollChanged(View anchor, int xoff, int yoff) { + unregisterForScrollChanged(); + + mAnchor = new WeakReference<View>(anchor); + ViewTreeObserver vto = anchor.getViewTreeObserver(); + if (vto != null) { + vto.addOnScrollChangedListener(mOnScrollChangedListener); + } + + mAnchorXoff = xoff; + mAnchorYoff = yoff; + } + private class PopupViewContainer extends FrameLayout { public PopupViewContainer(Context context) { diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 434e9f3..dd2570a 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -344,6 +344,7 @@ public class ProgressBar extends View { * * @param indeterminate true to enable the indeterminate mode */ + @android.view.RemotableViewMethod public synchronized void setIndeterminate(boolean indeterminate) { if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) { mIndeterminate = indeterminate; @@ -529,6 +530,7 @@ public class ProgressBar extends View { setProgress(progress, false); } + @android.view.RemotableViewMethod synchronized void setProgress(int progress, boolean fromUser) { if (mIndeterminate) { return; @@ -560,6 +562,7 @@ public class ProgressBar extends View { * @see #getSecondaryProgress() * @see #incrementSecondaryProgressBy(int) */ + @android.view.RemotableViewMethod public synchronized void setSecondaryProgress(int secondaryProgress) { if (mIndeterminate) { return; @@ -633,6 +636,7 @@ public class ProgressBar extends View { * @see #setProgress(int) * @see #setSecondaryProgress(int) */ + @android.view.RemotableViewMethod public synchronized void setMax(int max) { if (max < 0) { max = 0; diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index 9ded52b..ba63ec3 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -168,6 +168,7 @@ public class RelativeLayout extends ViewGroup { * * @attr ref android.R.styleable#RelativeLayout_ignoreGravity */ + @android.view.RemotableViewMethod public void setIgnoreGravity(int viewId) { mIgnoreGravity = viewId; } @@ -183,6 +184,7 @@ public class RelativeLayout extends ViewGroup { * * @attr ref android.R.styleable#RelativeLayout_gravity */ + @android.view.RemotableViewMethod public void setGravity(int gravity) { if (mGravity != gravity) { if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) { @@ -198,6 +200,7 @@ public class RelativeLayout extends ViewGroup { } } + @android.view.RemotableViewMethod public void setHorizontalGravity(int horizontalGravity) { final int gravity = horizontalGravity & Gravity.HORIZONTAL_GRAVITY_MASK; if ((mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != gravity) { @@ -206,6 +209,7 @@ public class RelativeLayout extends ViewGroup { } } + @android.view.RemotableViewMethod public void setVerticalGravity(int verticalGravity) { final int gravity = verticalGravity & Gravity.VERTICAL_GRAVITY_MASK; if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != gravity) { diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 25afee8..e000d2e 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -31,6 +31,7 @@ import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; +import android.view.RemotableViewMethod; import android.view.View; import android.view.ViewGroup; import android.view.LayoutInflater.Filter; @@ -38,10 +39,13 @@ import android.view.View.OnClickListener; import android.view.animation.Animation; import android.view.animation.AnimationUtils; +import java.lang.Class; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; @@ -80,19 +84,22 @@ public class RemoteViews implements Parcelable, Filter { /** - * This annotation indicates that a subclass of View is alllowed to be used with the - * {@link android.widget.RemoteViews} mechanism. + * This annotation indicates that a subclass of View is alllowed to be used + * with the {@link android.widget.RemoteViews} mechanism. */ @Target({ ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface RemoteView { } - + /** * Exception to send when something goes wrong executing an action * */ public static class ActionException extends RuntimeException { + public ActionException(Exception ex) { + super(ex); + } public ActionException(String message) { super(message); } @@ -110,274 +117,7 @@ public class RemoteViews implements Parcelable, Filter { return 0; } }; - - /** - * Equivalent to calling View.setVisibility - */ - private class SetViewVisibility extends Action { - public SetViewVisibility(int id, int vis) { - viewId = id; - visibility = vis; - } - - public SetViewVisibility(Parcel parcel) { - viewId = parcel.readInt(); - visibility = parcel.readInt(); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(TAG); - dest.writeInt(viewId); - dest.writeInt(visibility); - } - - @Override - public void apply(View root) { - View target = root.findViewById(viewId); - if (target != null) { - target.setVisibility(visibility); - } - } - - private int viewId; - private int visibility; - public final static int TAG = 0; - } - - /** - * Equivalent to calling TextView.setText - */ - private class SetTextViewText extends Action { - public SetTextViewText(int id, CharSequence t) { - viewId = id; - text = t; - } - - public SetTextViewText(Parcel parcel) { - viewId = parcel.readInt(); - text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(TAG); - dest.writeInt(viewId); - TextUtils.writeToParcel(text, dest, flags); - } - - @Override - public void apply(View root) { - TextView target = (TextView) root.findViewById(viewId); - if (target != null) { - target.setText(text); - } - } - - int viewId; - CharSequence text; - public final static int TAG = 1; - } - - /** - * Equivalent to calling ImageView.setResource - */ - private class SetImageViewResource extends Action { - public SetImageViewResource(int id, int src) { - viewId = id; - srcId = src; - } - - public SetImageViewResource(Parcel parcel) { - viewId = parcel.readInt(); - srcId = parcel.readInt(); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(TAG); - dest.writeInt(viewId); - dest.writeInt(srcId); - } - - @Override - public void apply(View root) { - ImageView target = (ImageView) root.findViewById(viewId); - Drawable d = mContext.getResources().getDrawable(srcId); - if (target != null) { - target.setImageDrawable(d); - } - } - - int viewId; - int srcId; - public final static int TAG = 2; - } - - /** - * Equivalent to calling ImageView.setImageURI - */ - private class SetImageViewUri extends Action { - public SetImageViewUri(int id, Uri u) { - viewId = id; - uri = u; - } - - public SetImageViewUri(Parcel parcel) { - viewId = parcel.readInt(); - uri = Uri.CREATOR.createFromParcel(parcel); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(TAG); - dest.writeInt(viewId); - Uri.writeToParcel(dest, uri); - } - - @Override - public void apply(View root) { - ImageView target = (ImageView) root.findViewById(viewId); - if (target != null) { - target.setImageURI(uri); - } - } - - int viewId; - Uri uri; - public final static int TAG = 3; - } - - /** - * Equivalent to calling ImageView.setImageBitmap - */ - private class SetImageViewBitmap extends Action { - public SetImageViewBitmap(int id, Bitmap src) { - viewId = id; - bitmap = src; - } - - public SetImageViewBitmap(Parcel parcel) { - viewId = parcel.readInt(); - bitmap = Bitmap.CREATOR.createFromParcel(parcel); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(TAG); - dest.writeInt(viewId); - if (bitmap != null) { - bitmap.writeToParcel(dest, flags); - } - } - - @Override - public void apply(View root) { - if (bitmap != null) { - ImageView target = (ImageView) root.findViewById(viewId); - Drawable d = new BitmapDrawable(bitmap); - if (target != null) { - target.setImageDrawable(d); - } - } - } - int viewId; - Bitmap bitmap; - public final static int TAG = 4; - } - - /** - * Equivalent to calling Chronometer.setBase, Chronometer.setFormat, - * and Chronometer.start/stop. - */ - private class SetChronometer extends Action { - public SetChronometer(int id, long base, String format, boolean running) { - this.viewId = id; - this.base = base; - this.format = format; - this.running = running; - } - - public SetChronometer(Parcel parcel) { - viewId = parcel.readInt(); - base = parcel.readLong(); - format = parcel.readString(); - running = parcel.readInt() != 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(TAG); - dest.writeInt(viewId); - dest.writeLong(base); - dest.writeString(format); - dest.writeInt(running ? 1 : 0); - } - - @Override - public void apply(View root) { - Chronometer target = (Chronometer) root.findViewById(viewId); - if (target != null) { - target.setBase(base); - target.setFormat(format); - if (running) { - target.start(); - } else { - target.stop(); - } - } - } - - int viewId; - boolean running; - long base; - String format; - - public final static int TAG = 5; - } - - /** - * Equivalent to calling ProgressBar.setMax, ProgressBar.setProgress and - * ProgressBar.setIndeterminate - */ - private class SetProgressBar extends Action { - public SetProgressBar(int id, int max, int progress, boolean indeterminate) { - this.viewId = id; - this.progress = progress; - this.max = max; - this.indeterminate = indeterminate; - } - - public SetProgressBar(Parcel parcel) { - viewId = parcel.readInt(); - progress = parcel.readInt(); - max = parcel.readInt(); - indeterminate = parcel.readInt() != 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(TAG); - dest.writeInt(viewId); - dest.writeInt(progress); - dest.writeInt(max); - dest.writeInt(indeterminate ? 1 : 0); - } - - @Override - public void apply(View root) { - ProgressBar target = (ProgressBar) root.findViewById(viewId); - if (target != null) { - target.setIndeterminate(indeterminate); - if (!indeterminate) { - target.setMax(max); - target.setProgress(progress); - } - } - } - - int viewId; - boolean indeterminate; - int progress; - int max; - - public final static int TAG = 6; - } - /** * Equivalent to calling * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)} @@ -421,7 +161,7 @@ public class RemoteViews implements Parcelable, Filter { int viewId; PendingIntent pendingIntent; - public final static int TAG = 7; + public final static int TAG = 1; } /** @@ -511,92 +251,215 @@ public class RemoteViews implements Parcelable, Filter { PorterDuff.Mode filterMode; int level; - public final static int TAG = 8; + public final static int TAG = 3; } /** - * Equivalent to calling {@link android.widget.TextView#setTextColor(int)}. + * Base class for the reflection actions. */ - private class SetTextColor extends Action { - public SetTextColor(int id, int color) { - this.viewId = id; - this.color = color; - } - - public SetTextColor(Parcel parcel) { - viewId = parcel.readInt(); - color = parcel.readInt(); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(TAG); - dest.writeInt(viewId); - dest.writeInt(color); - } - - @Override - public void apply(View root) { - final View target = root.findViewById(viewId); - if (target instanceof TextView) { - final TextView textView = (TextView) target; - textView.setTextColor(color); + private class ReflectionAction extends Action { + static final int TAG = 2; + + static final int BOOLEAN = 1; + static final int BYTE = 2; + static final int SHORT = 3; + static final int INT = 4; + static final int LONG = 5; + static final int FLOAT = 6; + static final int DOUBLE = 7; + static final int CHAR = 8; + static final int STRING = 9; + static final int CHAR_SEQUENCE = 10; + static final int URI = 11; + static final int BITMAP = 12; + + int viewId; + String methodName; + int type; + Object value; + + ReflectionAction(int viewId, String methodName, int type, Object value) { + this.viewId = viewId; + this.methodName = methodName; + this.type = type; + this.value = value; + } + + ReflectionAction(Parcel in) { + this.viewId = in.readInt(); + this.methodName = in.readString(); + this.type = in.readInt(); + if (false) { + Log.d("RemoteViews", "read viewId=0x" + Integer.toHexString(this.viewId) + + " methodName=" + this.methodName + " type=" + this.type); + } + switch (this.type) { + case BOOLEAN: + this.value = in.readInt() != 0; + break; + case BYTE: + this.value = in.readByte(); + break; + case SHORT: + this.value = (short)in.readInt(); + break; + case INT: + this.value = in.readInt(); + break; + case LONG: + this.value = in.readLong(); + break; + case FLOAT: + this.value = in.readFloat(); + break; + case DOUBLE: + this.value = in.readDouble(); + break; + case CHAR: + this.value = (char)in.readInt(); + break; + case STRING: + this.value = in.readString(); + break; + case CHAR_SEQUENCE: + this.value = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); + break; + case URI: + this.value = Uri.CREATOR.createFromParcel(in); + break; + case BITMAP: + this.value = Bitmap.CREATOR.createFromParcel(in); + break; + default: + break; } } - - int viewId; - int color; - public final static int TAG = 9; - } - - /** - * Equivalent to calling {@link android.widget.ViewFlipper#startFlipping()} - * or {@link android.widget.ViewFlipper#stopFlipping()} along with - * {@link android.widget.ViewFlipper#setFlipInterval(int)}. - */ - private class SetFlipping extends Action { - public SetFlipping(int id, boolean flipping, int milliseconds) { - this.viewId = id; - this.flipping = flipping; - this.milliseconds = milliseconds; - } - - public SetFlipping(Parcel parcel) { - viewId = parcel.readInt(); - flipping = parcel.readInt() != 0; - milliseconds = parcel.readInt(); + public void writeToParcel(Parcel out, int flags) { + out.writeInt(TAG); + out.writeInt(this.viewId); + out.writeString(this.methodName); + out.writeInt(this.type); + if (false) { + Log.d("RemoteViews", "write viewId=0x" + Integer.toHexString(this.viewId) + + " methodName=" + this.methodName + " type=" + this.type); + } + switch (this.type) { + case BOOLEAN: + out.writeInt(((Boolean)this.value).booleanValue() ? 1 : 0); + break; + case BYTE: + out.writeByte(((Byte)this.value).byteValue()); + break; + case SHORT: + out.writeInt(((Short)this.value).shortValue()); + break; + case INT: + out.writeInt(((Integer)this.value).intValue()); + break; + case LONG: + out.writeLong(((Long)this.value).longValue()); + break; + case FLOAT: + out.writeFloat(((Float)this.value).floatValue()); + break; + case DOUBLE: + out.writeDouble(((Double)this.value).doubleValue()); + break; + case CHAR: + out.writeInt((int)((Character)this.value).charValue()); + break; + case STRING: + out.writeString((String)this.value); + break; + case CHAR_SEQUENCE: + TextUtils.writeToParcel((CharSequence)this.value, out, flags); + break; + case URI: + ((Uri)this.value).writeToParcel(out, flags); + break; + case BITMAP: + ((Bitmap)this.value).writeToParcel(out, flags); + break; + default: + break; + } } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(TAG); - dest.writeInt(viewId); - dest.writeInt(flipping ? 1 : 0); - dest.writeInt(milliseconds); + + private Class getParameterType() { + switch (this.type) { + case BOOLEAN: + return boolean.class; + case BYTE: + return byte.class; + case SHORT: + return short.class; + case INT: + return int.class; + case LONG: + return long.class; + case FLOAT: + return float.class; + case DOUBLE: + return double.class; + case CHAR: + return char.class; + case STRING: + return String.class; + case CHAR_SEQUENCE: + return CharSequence.class; + case URI: + return Uri.class; + case BITMAP: + return Bitmap.class; + default: + return null; + } } - + @Override public void apply(View root) { - final View target = root.findViewById(viewId); - if (target instanceof ViewFlipper) { - final ViewFlipper flipper = (ViewFlipper) target; - if (milliseconds != -1) { - flipper.setFlipInterval(milliseconds); - } - if (flipping) { - flipper.startFlipping(); - } else { - flipper.stopFlipping(); + final View view = root.findViewById(viewId); + if (view == null) { + throw new ActionException("can't find view: 0x" + Integer.toHexString(viewId)); + } + + Class param = getParameterType(); + if (param == null) { + throw new ActionException("bad type: " + this.type); + } + + Class klass = view.getClass(); + Method method = null; + try { + method = klass.getMethod(this.methodName, getParameterType()); + } + catch (NoSuchMethodException ex) { + throw new ActionException("view: " + klass.getName() + " doesn't have method: " + + this.methodName + "(" + param.getName() + ")"); + } + + if (!method.isAnnotationPresent(RemotableViewMethod.class)) { + throw new ActionException("view: " + klass.getName() + + " can't use method with RemoteViews: " + + this.methodName + "(" + param.getName() + ")"); + } + + try { + if (false) { + Log.d("RemoteViews", "view: " + klass.getName() + " calling method: " + + this.methodName + "(" + param.getName() + ") with " + + (this.value == null ? "null" : this.value.getClass().getName())); } + method.invoke(view, this.value); + } + catch (Exception ex) { + throw new ActionException(ex); } } - - int viewId; - boolean flipping; - int milliseconds; - - public final static int TAG = 10; } + /** * Create a new RemoteViews object that will display the views contained * in the specified layout file. @@ -623,41 +486,17 @@ public class RemoteViews implements Parcelable, Filter { for (int i=0; i<count; i++) { int tag = parcel.readInt(); switch (tag) { - case SetViewVisibility.TAG: - mActions.add(new SetViewVisibility(parcel)); - break; - case SetTextViewText.TAG: - mActions.add(new SetTextViewText(parcel)); - break; - case SetImageViewResource.TAG: - mActions.add(new SetImageViewResource(parcel)); - break; - case SetImageViewUri.TAG: - mActions.add(new SetImageViewUri(parcel)); - break; - case SetImageViewBitmap.TAG: - mActions.add(new SetImageViewBitmap(parcel)); - break; - case SetChronometer.TAG: - mActions.add(new SetChronometer(parcel)); - break; - case SetProgressBar.TAG: - mActions.add(new SetProgressBar(parcel)); - break; case SetOnClickPendingIntent.TAG: mActions.add(new SetOnClickPendingIntent(parcel)); break; case SetDrawableParameters.TAG: mActions.add(new SetDrawableParameters(parcel)); break; - case SetTextColor.TAG: - mActions.add(new SetTextColor(parcel)); - break; - case SetFlipping.TAG: - mActions.add(new SetFlipping(parcel)); + case ReflectionAction.TAG: + mActions.add(new ReflectionAction(parcel)); break; default: - throw new ActionException("Tag " + tag + "not found"); + throw new ActionException("Tag " + tag + " not found"); } } } @@ -690,7 +529,7 @@ public class RemoteViews implements Parcelable, Filter { * @param visibility The new visibility for the view */ public void setViewVisibility(int viewId, int visibility) { - addAction(new SetViewVisibility(viewId, visibility)); + setInt(viewId, "setVisibility", visibility); } /** @@ -700,7 +539,7 @@ public class RemoteViews implements Parcelable, Filter { * @param text The new text for the view */ public void setTextViewText(int viewId, CharSequence text) { - addAction(new SetTextViewText(viewId, text)); + setCharSequence(viewId, "setText", text); } /** @@ -710,7 +549,7 @@ public class RemoteViews implements Parcelable, Filter { * @param srcId The new resource id for the drawable */ public void setImageViewResource(int viewId, int srcId) { - addAction(new SetImageViewResource(viewId, srcId)); + setInt(viewId, "setImageResource", srcId); } /** @@ -720,7 +559,7 @@ public class RemoteViews implements Parcelable, Filter { * @param uri The Uri for the image */ public void setImageViewUri(int viewId, Uri uri) { - addAction(new SetImageViewUri(viewId, uri)); + setUri(viewId, "setImageURI", uri); } /** @@ -730,7 +569,7 @@ public class RemoteViews implements Parcelable, Filter { * @param bitmap The new Bitmap for the drawable */ public void setImageViewBitmap(int viewId, Bitmap bitmap) { - addAction(new SetImageViewBitmap(viewId, bitmap)); + setBitmap(viewId, "setImageBitmap", bitmap); } /** @@ -745,16 +584,20 @@ public class RemoteViews implements Parcelable, Filter { * {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()}. * @param format The Chronometer format string, or null to * simply display the timer value. - * @param running True if you want the clock to be running, false if not. + * @param started True if you want the clock to be started, false if not. */ - public void setChronometer(int viewId, long base, String format, boolean running) { - addAction(new SetChronometer(viewId, base, format, running)); + public void setChronometer(int viewId, long base, String format, boolean started) { + setLong(viewId, "setBase", base); + setString(viewId, "setFormat", format); + setBoolean(viewId, "setStarted", started); } /** * Equivalent to calling {@link ProgressBar#setMax ProgressBar.setMax}, * {@link ProgressBar#setProgress ProgressBar.setProgress}, and * {@link ProgressBar#setIndeterminate ProgressBar.setIndeterminate} + * + * If indeterminate is true, then the values for max and progress are ignored. * * @param viewId The id of the view whose text should change * @param max The 100% value for the progress bar @@ -764,7 +607,11 @@ public class RemoteViews implements Parcelable, Filter { */ public void setProgressBar(int viewId, int max, int progress, boolean indeterminate) { - addAction(new SetProgressBar(viewId, max, progress, indeterminate)); + setBoolean(viewId, "setIndeterminate", indeterminate); + if (!indeterminate) { + setInt(viewId, "setMax", max); + setInt(viewId, "setProgress", progress); + } } /** @@ -780,6 +627,7 @@ public class RemoteViews implements Parcelable, Filter { } /** + * @hide * Equivalent to calling a combination of {@link Drawable#setAlpha(int)}, * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)}, * and/or {@link Drawable#setLevel(int)} on the {@link Drawable} of a given @@ -818,23 +666,55 @@ public class RemoteViews implements Parcelable, Filter { * focused) to be this color. */ public void setTextColor(int viewId, int color) { - addAction(new SetTextColor(viewId, color)); + setInt(viewId, "setTextColor", color); } - /** - * Equivalent to calling {@link android.widget.ViewFlipper#startFlipping()} - * or {@link android.widget.ViewFlipper#stopFlipping()} along with - * {@link android.widget.ViewFlipper#setFlipInterval(int)}. - * - * @param viewId The id of the view to apply changes to - * @param flipping True means we should - * {@link android.widget.ViewFlipper#startFlipping()}, otherwise - * {@link android.widget.ViewFlipper#stopFlipping()}. - * @param milliseconds How long to wait before flipping to the next view, or - * -1 to leave unchanged. - */ - public void setFlipping(int viewId, boolean flipping, int milliseconds) { - addAction(new SetFlipping(viewId, flipping, milliseconds)); + public void setBoolean(int viewId, String methodName, boolean value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BOOLEAN, value)); + } + + public void setByte(int viewId, String methodName, byte value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BYTE, value)); + } + + public void setShort(int viewId, String methodName, short value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.SHORT, value)); + } + + public void setInt(int viewId, String methodName, int value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INT, value)); + } + + public void setLong(int viewId, String methodName, long value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.LONG, value)); + } + + public void setFloat(int viewId, String methodName, float value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.FLOAT, value)); + } + + public void setDouble(int viewId, String methodName, double value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.DOUBLE, value)); + } + + public void setChar(int viewId, String methodName, char value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR, value)); + } + + public void setString(int viewId, String methodName, String value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.STRING, value)); + } + + public void setCharSequence(int viewId, String methodName, CharSequence value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR_SEQUENCE, value)); + } + + public void setUri(int viewId, String methodName, Uri value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.URI, value)); + } + + public void setBitmap(int viewId, String methodName, Bitmap value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BITMAP, value)); } /** diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java index da4a077..dc2c70d 100644 --- a/core/java/android/widget/TabHost.java +++ b/core/java/android/widget/TabHost.java @@ -405,7 +405,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1"); * Specify a label and icon as the tab indicator. */ public TabSpec setIndicator(CharSequence label, Drawable icon) { - mIndicatorStrategy = new LabelAndIconIndicatorStategy(label, icon); + mIndicatorStrategy = new LabelAndIconIndicatorStrategy(label, icon); return this; } @@ -497,12 +497,12 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1"); /** * How we create a tab indicator that has a label and an icon */ - private class LabelAndIconIndicatorStategy implements IndicatorStrategy { + private class LabelAndIconIndicatorStrategy implements IndicatorStrategy { private final CharSequence mLabel; private final Drawable mIcon; - private LabelAndIconIndicatorStategy(CharSequence label, Drawable icon) { + private LabelAndIconIndicatorStrategy(CharSequence label, Drawable icon) { mLabel = label; mIcon = icon; } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 2ae5d4e..bdc54ff 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -87,6 +87,7 @@ import android.view.ViewDebug; import android.view.ViewTreeObserver; import android.view.ViewGroup.LayoutParams; import android.view.animation.AnimationUtils; +import android.view.inputmethod.BaseInputConnection; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; @@ -1521,6 +1522,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_textSize */ + @android.view.RemotableViewMethod public void setTextSize(float size) { setTextSize(TypedValue.COMPLEX_UNIT_SP, size); } @@ -1572,6 +1574,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_textScaleX */ + @android.view.RemotableViewMethod public void setTextScaleX(float size) { if (size != mTextPaint.getTextScaleX()) { mTextPaint.setTextScaleX(size); @@ -1620,6 +1623,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_textColor */ + @android.view.RemotableViewMethod public void setTextColor(int color) { mTextColor = ColorStateList.valueOf(color); updateTextColors(); @@ -1662,6 +1666,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_textColorHighlight */ + @android.view.RemotableViewMethod public void setHighlightColor(int color) { if (mHighlightColor != color) { mHighlightColor = color; @@ -1703,6 +1708,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_autoLink */ + @android.view.RemotableViewMethod public final void setAutoLinkMask(int mask) { mAutoLinkMask = mask; } @@ -1715,6 +1721,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_linksClickable */ + @android.view.RemotableViewMethod public final void setLinksClickable(boolean whether) { mLinksClickable = whether; } @@ -1751,6 +1758,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_textColorHint */ + @android.view.RemotableViewMethod public final void setHintTextColor(int color) { mHintTextColor = ColorStateList.valueOf(color); updateTextColors(); @@ -1789,6 +1797,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_textColorLink */ + @android.view.RemotableViewMethod public final void setLinkTextColor(int color) { mLinkTextColor = ColorStateList.valueOf(color); updateTextColors(); @@ -1876,6 +1885,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * reflows the text if they are different from the old flags. * @see Paint#setFlags */ + @android.view.RemotableViewMethod public void setPaintFlags(int flags) { if (mTextPaint.getFlags() != flags) { mTextPaint.setFlags(flags); @@ -1909,6 +1919,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_minLines */ + @android.view.RemotableViewMethod public void setMinLines(int minlines) { mMinimum = minlines; mMinMode = LINES; @@ -1922,6 +1933,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_minHeight */ + @android.view.RemotableViewMethod public void setMinHeight(int minHeight) { mMinimum = minHeight; mMinMode = PIXELS; @@ -1935,6 +1947,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_maxLines */ + @android.view.RemotableViewMethod public void setMaxLines(int maxlines) { mMaximum = maxlines; mMaxMode = LINES; @@ -1948,6 +1961,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_maxHeight */ + @android.view.RemotableViewMethod public void setMaxHeight(int maxHeight) { mMaximum = maxHeight; mMaxMode = PIXELS; @@ -1961,6 +1975,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_lines */ + @android.view.RemotableViewMethod public void setLines(int lines) { mMaximum = mMinimum = lines; mMaxMode = mMinMode = LINES; @@ -1976,6 +1991,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_height */ + @android.view.RemotableViewMethod public void setHeight(int pixels) { mMaximum = mMinimum = pixels; mMaxMode = mMinMode = PIXELS; @@ -1989,6 +2005,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_minEms */ + @android.view.RemotableViewMethod public void setMinEms(int minems) { mMinWidth = minems; mMinWidthMode = EMS; @@ -2002,6 +2019,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_minWidth */ + @android.view.RemotableViewMethod public void setMinWidth(int minpixels) { mMinWidth = minpixels; mMinWidthMode = PIXELS; @@ -2015,6 +2033,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_maxEms */ + @android.view.RemotableViewMethod public void setMaxEms(int maxems) { mMaxWidth = maxems; mMaxWidthMode = EMS; @@ -2028,6 +2047,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_maxWidth */ + @android.view.RemotableViewMethod public void setMaxWidth(int maxpixels) { mMaxWidth = maxpixels; mMaxWidthMode = PIXELS; @@ -2041,6 +2061,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_ems */ + @android.view.RemotableViewMethod public void setEms(int ems) { mMaxWidth = mMinWidth = ems; mMaxWidthMode = mMinWidthMode = EMS; @@ -2056,6 +2077,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_width */ + @android.view.RemotableViewMethod public void setWidth(int pixels) { mMaxWidth = mMinWidth = pixels; mMaxWidthMode = mMinWidthMode = PIXELS; @@ -2321,6 +2343,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_freezesText */ + @android.view.RemotableViewMethod public void setFreezesText(boolean freezesText) { mFreezesText = freezesText; } @@ -2366,6 +2389,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_text */ + @android.view.RemotableViewMethod public final void setText(CharSequence text) { setText(text, mBufferType); } @@ -2378,6 +2402,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @see #setText(CharSequence) */ + @android.view.RemotableViewMethod public final void setTextKeepState(CharSequence text) { setTextKeepState(text, mBufferType); } @@ -2648,6 +2673,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } + @android.view.RemotableViewMethod public final void setText(int resid) { setText(getContext().getResources().getText(resid)); } @@ -2666,6 +2692,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_hint */ + @android.view.RemotableViewMethod public final void setHint(CharSequence hint) { mHint = TextUtils.stringOrSpannedString(hint); @@ -2686,6 +2713,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_hint */ + @android.view.RemotableViewMethod public final void setHint(int resid) { setHint(getContext().getResources().getText(resid)); } @@ -2896,6 +2924,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * <code>error</code> is <code>null</code>, the error message and icon * will be cleared. */ + @android.view.RemotableViewMethod public void setError(CharSequence error) { if (error == null) { setError(null, null); @@ -2954,10 +2983,28 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (mPopup == null) { LayoutInflater inflater = LayoutInflater.from(getContext()); - TextView err = (TextView) inflater.inflate(com.android.internal.R.layout.textview_hint, + final TextView err = (TextView) inflater.inflate(com.android.internal.R.layout.textview_hint, null); - mPopup = new PopupWindow(err, 200, 50); + mPopup = new PopupWindow(err, 200, 50) { + private boolean mAbove = false; + + @Override + public void update(int x, int y, int w, int h, boolean force) { + super.update(x, y, w, h, force); + + boolean above = isAboveAnchor(); + if (above != mAbove) { + mAbove = above; + + if (above) { + err.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error_above); + } else { + err.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error); + } + } + } + }; mPopup.setFocusable(false); } @@ -5094,6 +5141,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_singleLine */ + @android.view.RemotableViewMethod public void setSingleLine(boolean singleLine) { if ((mInputType&EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) { @@ -5168,6 +5216,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_selectAllOnFocus */ + @android.view.RemotableViewMethod public void setSelectAllOnFocus(boolean selectAllOnFocus) { mSelectAllOnFocus = selectAllOnFocus; @@ -5181,6 +5230,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * * @attr ref android.R.styleable#TextView_cursorVisible */ + @android.view.RemotableViewMethod public void setCursorVisible(boolean visible) { mCursorVisible = visible; invalidate(); @@ -5730,6 +5780,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener startStopMarquee(hasWindowFocus); } + /** + * Use {@link BaseInputConnection#removeComposingSpans + * BaseInputConnection.removeComposingSpans()} to remove any IME composing + * state from this text view. + */ + public void clearComposingText() { + if (mText instanceof Spannable) { + BaseInputConnection.removeComposingSpans((Spannable)mText); + } + } + @Override public void setSelected(boolean selected) { boolean wasSelected = isSelected(); diff --git a/core/java/android/widget/ViewFlipper.java b/core/java/android/widget/ViewFlipper.java index e20bfdf..8a7946b 100644 --- a/core/java/android/widget/ViewFlipper.java +++ b/core/java/android/widget/ViewFlipper.java @@ -31,7 +31,6 @@ import android.widget.RemoteViews.RemoteView; * * @attr ref android.R.styleable#ViewFlipper_flipInterval */ -@RemoteView public class ViewFlipper extends ViewAnimator { private int mFlipInterval = 3000; private boolean mKeepFlipping = false; @@ -56,6 +55,7 @@ public class ViewFlipper extends ViewAnimator { * @param milliseconds * time in milliseconds */ + @android.view.RemotableViewMethod public void setFlipInterval(int milliseconds) { mFlipInterval = milliseconds; } diff --git a/core/java/android/widget/ZoomRing.java b/core/java/android/widget/ZoomRing.java index be3b1fb..22881b3 100644 --- a/core/java/android/widget/ZoomRing.java +++ b/core/java/android/widget/ZoomRing.java @@ -7,7 +7,11 @@ import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.graphics.drawable.RotateDrawable; +import android.os.Handler; +import android.os.Message; +import android.os.SystemClock; import android.util.AttributeSet; +import android.util.Log; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; @@ -19,10 +23,8 @@ import android.view.ViewConfiguration; public class ZoomRing extends View { // TODO: move to ViewConfiguration? - static final int DOUBLE_TAP_DISMISS_TIMEOUT = ViewConfiguration.getJumpTapTimeout(); + static final int DOUBLE_TAP_DISMISS_TIMEOUT = ViewConfiguration.getDoubleTapTimeout(); // TODO: get from theme - private static final int DISABLED_ALPHA = 160; - private static final String TAG = "ZoomRing"; // TODO: Temporary until the trail is done @@ -32,15 +34,26 @@ public class ZoomRing extends View { private static final int THUMB_DISTANCE = 63; /** To avoid floating point calculations, we multiply radians by this value. */ - public static final int RADIAN_INT_MULTIPLIER = 100000000; + public static final int RADIAN_INT_MULTIPLIER = 10000; + public static final int RADIAN_INT_ERROR = 100; /** PI using our multiplier. */ public static final int PI_INT_MULTIPLIED = (int) (Math.PI * RADIAN_INT_MULTIPLIER); + public static final int TWO_PI_INT_MULTIPLIED = PI_INT_MULTIPLIED * 2; /** PI/2 using our multiplier. */ private static final int HALF_PI_INT_MULTIPLIED = PI_INT_MULTIPLIED / 2; private int mZeroAngle = HALF_PI_INT_MULTIPLIED * 3; + + private static final int THUMB_GRAB_SLOP = PI_INT_MULTIPLIED / 8; + private static final int THUMB_DRAG_SLOP = PI_INT_MULTIPLIED / 12; - private static final int THUMB_GRAB_SLOP = PI_INT_MULTIPLIED / 4; + /** + * Includes error because we compare this to the result of + * getDelta(getClosestTickeAngle(..), oldAngle) which ends up having some + * rounding error. + */ + private static final int MAX_ABS_JUMP_DELTA_ANGLE = (2 * PI_INT_MULTIPLIED / 3) + + RADIAN_INT_ERROR; /** The cached X of our center. */ private int mCenterX; @@ -49,10 +62,13 @@ public class ZoomRing extends View { /** The angle of the thumb (in int radians) */ private int mThumbAngle; - private boolean mIsThumbAngleValid; private int mThumbHalfWidth; private int mThumbHalfHeight; - + + private int mThumbCwBound = Integer.MIN_VALUE; + private int mThumbCcwBound = Integer.MIN_VALUE; + private boolean mEnforceMaxAbsJump = true; + /** The inner radius of the track. */ private int mBoundInnerRadiusSquared = 0; /** The outer radius of the track. */ @@ -63,8 +79,23 @@ public class ZoomRing extends View { private boolean mDrawThumb = true; private Drawable mThumbDrawable; - + + /** Shown beneath the thumb if we can still zoom in. */ + private Drawable mThumbPlusArrowDrawable; + /** Shown beneath the thumb if we can still zoom out. */ + private Drawable mThumbMinusArrowDrawable; + private static final int THUMB_ARROWS_FADE_DURATION = 300; + private long mThumbArrowsFadeStartTime; + private int mThumbArrowsAlpha = 255; + private static final int MODE_IDLE = 0; + + /** + * User has his finger down somewhere on the ring (besides the thumb) and we + * are waiting for him to move the slop amount before considering him in the + * drag thumb state. + */ + private static final int MODE_WAITING_FOR_DRAG_THUMB = 5; private static final int MODE_DRAG_THUMB = 1; /** * User has his finger down, but we are waiting for him to pass the touch @@ -74,24 +105,47 @@ public class ZoomRing extends View { private static final int MODE_WAITING_FOR_MOVE_ZOOM_RING = 4; private static final int MODE_MOVE_ZOOM_RING = 2; private static final int MODE_TAP_DRAG = 3; + /** Ignore the touch interaction. Reset to MODE_IDLE after up/cancel. */ + private static final int MODE_IGNORE_UNTIL_UP = 6; private int mMode; - private long mPreviousDownTime; + private long mPreviousUpTime; private int mPreviousDownX; private int mPreviousDownY; - private Disabler mDisabler = new Disabler(); - + private int mWaitingForDragThumbDownAngle; + private OnZoomRingCallback mCallback; private int mPreviousCallbackAngle; private int mCallbackThreshold = Integer.MAX_VALUE; private boolean mResetThumbAutomatically = true; private int mThumbDragStartAngle; + private final int mTouchSlop; + private Drawable mTrail; private double mAcculumalatedTrailAngle; - + + private Scroller mThumbScroller; + + private static final int MSG_THUMB_SCROLLER_TICK = 1; + private static final int MSG_THUMB_ARROWS_FADE_TICK = 2; + private Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_THUMB_SCROLLER_TICK: + onThumbScrollerTick(); + break; + + case MSG_THUMB_ARROWS_FADE_TICK: + onThumbArrowsFadeTick(); + break; + } + } + }; + public ZoomRing(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); @@ -101,6 +155,10 @@ public class ZoomRing extends View { // TODO get drawables from style instead Resources res = context.getResources(); mThumbDrawable = res.getDrawable(R.drawable.zoom_ring_thumb); + mThumbPlusArrowDrawable = res.getDrawable(R.drawable.zoom_ring_thumb_plus_arrow_rotatable). + mutate(); + mThumbMinusArrowDrawable = res.getDrawable(R.drawable.zoom_ring_thumb_minus_arrow_rotatable). + mutate(); if (DRAW_TRAIL) { mTrail = res.getDrawable(R.drawable.zoom_ring_trail).mutate(); } @@ -108,7 +166,7 @@ public class ZoomRing extends View { // TODO: add padding to drawable setBackgroundResource(R.drawable.zoom_ring_track); // TODO get from style - setBounds(30, Integer.MAX_VALUE); + setRingBounds(30, Integer.MAX_VALUE); mThumbHalfHeight = mThumbDrawable.getIntrinsicHeight() / 2; mThumbHalfWidth = mThumbDrawable.getIntrinsicWidth() / 2; @@ -134,7 +192,7 @@ public class ZoomRing extends View { } // TODO: from XML too - public void setBounds(int innerRadius, int outerRadius) { + public void setRingBounds(int innerRadius, int outerRadius) { mBoundInnerRadiusSquared = innerRadius * innerRadius; if (mBoundInnerRadiusSquared < innerRadius) { // Prevent overflow @@ -148,7 +206,64 @@ public class ZoomRing extends View { } } + public void setThumbClockwiseBound(int angle) { + if (angle < 0) { + mThumbCwBound = Integer.MIN_VALUE; + } else { + mThumbCwBound = getClosestTickAngle(angle); + } + setEnforceMaxAbsJump(); + } + + public void setThumbCounterclockwiseBound(int angle) { + if (angle < 0) { + mThumbCcwBound = Integer.MIN_VALUE; + } else { + mThumbCcwBound = getClosestTickAngle(angle); + } + setEnforceMaxAbsJump(); + } + + private void setEnforceMaxAbsJump() { + // If there are bounds in both direction, there is no reason to restrict + // the amount that a user can absolute jump to + mEnforceMaxAbsJump = + mThumbCcwBound == Integer.MIN_VALUE || mThumbCwBound == Integer.MIN_VALUE; + } + + public int getThumbAngle() { + return mThumbAngle; + } + public void setThumbAngle(int angle) { + angle = getValidAngle(angle); + mPreviousCallbackAngle = getClosestTickAngle(angle); + setThumbAngleAuto(angle, false, false); + } + + /** + * Sets the thumb angle. If already animating, will continue the animation, + * otherwise it will do a direct jump. + * + * @param angle + * @param useDirection Whether to use the ccw parameter + * @param ccw Whether going counterclockwise (only used if useDirection is true) + */ + private void setThumbAngleAuto(int angle, boolean useDirection, boolean ccw) { + if (mThumbScroller == null + || mThumbScroller.isFinished() + || Math.abs(getDelta(angle, getThumbScrollerAngle())) < THUMB_GRAB_SLOP) { + setThumbAngleInt(angle); + } else { + if (useDirection) { + setThumbAngleAnimated(angle, 0, ccw); + } else { + setThumbAngleAnimated(angle, 0); + } + } + } + + private void setThumbAngleInt(int angle) { mThumbAngle = angle; int unoffsetAngle = angle + mZeroAngle; int thumbCenterX = (int) (Math.cos(1f * unoffsetAngle / RADIAN_INT_MULTIPLIER) * @@ -161,6 +276,10 @@ public class ZoomRing extends View { thumbCenterX + mThumbHalfWidth, thumbCenterY + mThumbHalfHeight); + if (mThumbArrowsAlpha > 0) { + setThumbArrowsAngle(angle); + } + if (DRAW_TRAIL) { double degrees; degrees = Math.min(359.0, Math.abs(mAcculumalatedTrailAngle)); @@ -174,10 +293,66 @@ public class ZoomRing extends View { invalidate(); } + + /** + * + * @param angle + * @param duration The animation duration, or 0 for the default duration. + */ + public void setThumbAngleAnimated(int angle, int duration) { + // The angle when going from the current angle to the new angle + int deltaAngle = getDelta(mThumbAngle, angle); + // Counter clockwise if the new angle is more the current angle + boolean counterClockwise = deltaAngle > 0; + + if (deltaAngle > PI_INT_MULTIPLIED || deltaAngle < -PI_INT_MULTIPLIED) { + // It's quicker to go the other direction + counterClockwise = !counterClockwise; + } + + setThumbAngleAnimated(angle, duration, counterClockwise); + } + + public void setThumbAngleAnimated(int angle, int duration, boolean counterClockwise) { + if (mThumbScroller == null) { + mThumbScroller = new Scroller(mContext); + } + + int startAngle = mThumbAngle; + int endAngle = getValidAngle(angle); + int deltaAngle = getDelta(startAngle, endAngle, counterClockwise); + if (startAngle + deltaAngle < 0) { + // Keep our angles positive + startAngle += TWO_PI_INT_MULTIPLIED; + } + + if (!mThumbScroller.isFinished()) { + duration = mThumbScroller.getDuration() - mThumbScroller.timePassed(); + } else if (duration == 0) { + duration = getAnimationDuration(deltaAngle); + } + mThumbScroller.startScroll(startAngle, 0, deltaAngle, 0, duration); + onThumbScrollerTick(); + } + + private int getAnimationDuration(int deltaAngle) { + if (deltaAngle < 0) deltaAngle *= -1; + return 300 + deltaAngle * 300 / RADIAN_INT_MULTIPLIER; + } + + private void onThumbScrollerTick() { + if (!mThumbScroller.computeScrollOffset()) return; + setThumbAngleInt(getThumbScrollerAngle()); + mHandler.sendEmptyMessage(MSG_THUMB_SCROLLER_TICK); + } + private int getThumbScrollerAngle() { + return mThumbScroller.getCurrX() % TWO_PI_INT_MULTIPLIED; + } + public void resetThumbAngle(int angle) { mPreviousCallbackAngle = angle; - setThumbAngle(angle); + setThumbAngleInt(angle); } public void resetThumbAngle() { @@ -185,7 +360,7 @@ public class ZoomRing extends View { resetThumbAngle(0); } } - + public void setResetThumbAutomatically(boolean resetThumbAutomatically) { mResetThumbAutomatically = resetThumbAutomatically; } @@ -214,6 +389,9 @@ public class ZoomRing extends View { if (DRAW_TRAIL) { mTrail.setBounds(0, 0, right - left, bottom - top); } + + mThumbPlusArrowDrawable.setBounds(0, 0, right - left, bottom - top); + mThumbMinusArrowDrawable.setBounds(0, 0, right - left, bottom - top); } @Override @@ -227,15 +405,13 @@ public class ZoomRing extends View { mMode = MODE_IDLE; mPreviousWidgetDragX = mPreviousWidgetDragY = Integer.MIN_VALUE; mAcculumalatedTrailAngle = 0.0; - mIsThumbAngleValid = false; } public void setTapDragMode(boolean tapDragMode, int x, int y) { resetState(); mMode = tapDragMode ? MODE_TAP_DRAG : MODE_IDLE; - mIsThumbAngleValid = false; - if (tapDragMode && mCallback != null) { + if (tapDragMode) { onThumbDragStarted(getAngle(x - mCenterX, y - mCenterY)); } } @@ -244,35 +420,44 @@ public class ZoomRing extends View { switch (action) { case MotionEvent.ACTION_DOWN: - if (mPreviousDownTime + DOUBLE_TAP_DISMISS_TIMEOUT >= time) { - if (mCallback != null) { - mCallback.onZoomRingDismissed(); - } - } else { - mPreviousDownTime = time; - mPreviousDownX = x; - mPreviousDownY = y; + mCallback.onUserInteractionStarted(); + + if (time - mPreviousUpTime <= DOUBLE_TAP_DISMISS_TIMEOUT) { + mCallback.onZoomRingDismissed(true); } + + mPreviousDownX = x; + mPreviousDownY = y; resetState(); - return true; + // Fall through to code below switch (since the down is used for + // jumping to the touched tick) + break; case MotionEvent.ACTION_MOVE: + if (mMode == MODE_IGNORE_UNTIL_UP) return true; + // Fall through to code below switch break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: - if (mCallback != null) { - if (mMode == MODE_MOVE_ZOOM_RING || mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) { - mCallback.onZoomRingSetMovableHintVisible(false); - if (mMode == MODE_MOVE_ZOOM_RING) { - mCallback.onZoomRingMovingStopped(); - } - } else if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG) { - onThumbDragStopped(getAngle(x - mCenterX, y - mCenterY)); + if (mMode == MODE_MOVE_ZOOM_RING || mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) { + mCallback.onZoomRingSetMovableHintVisible(false); + if (mMode == MODE_MOVE_ZOOM_RING) { + mCallback.onZoomRingMovingStopped(); + } + } else if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG || + mMode == MODE_WAITING_FOR_DRAG_THUMB) { + onThumbDragStopped(); + + if (mMode == MODE_DRAG_THUMB) { + // Animate back to a tick + setThumbAngleAnimated(mPreviousCallbackAngle, 0); } } - mDisabler.setEnabling(true); + + mPreviousUpTime = time; + mCallback.onUserInteractionStopped(); return true; default: @@ -283,18 +468,18 @@ public class ZoomRing extends View { int localX = x - mCenterX; int localY = y - mCenterY; boolean isTouchingThumb = true; - boolean isInBounds = true; + boolean isInRingBounds = true; + int touchAngle = getAngle(localX, localY); - int radiusSquared = localX * localX + localY * localY; if (radiusSquared < mBoundInnerRadiusSquared || radiusSquared > mBoundOuterRadiusSquared) { // Out-of-bounds isTouchingThumb = false; - isInBounds = false; + isInRingBounds = false; } - int deltaThumbAndTouch = getDelta(touchAngle, mThumbAngle); + int deltaThumbAndTouch = getDelta(mThumbAngle, touchAngle); int absoluteDeltaThumbAndTouch = deltaThumbAndTouch >= 0 ? deltaThumbAndTouch : -deltaThumbAndTouch; if (isTouchingThumb && @@ -305,17 +490,68 @@ public class ZoomRing extends View { if (mMode == MODE_IDLE) { if (isTouchingThumb) { + // They grabbed the thumb mMode = MODE_DRAG_THUMB; + onThumbDragStarted(touchAngle); + + } else if (isInRingBounds) { + // They tapped somewhere else on the ring + int tickAngle = getClosestTickAngle(touchAngle); + + int deltaThumbAndTick = getDelta(mThumbAngle, tickAngle); + int boundAngle = getBoundIfExceeds(mThumbAngle, deltaThumbAndTick); + + if (mEnforceMaxAbsJump) { + // Enforcing the max jump + if (deltaThumbAndTick > MAX_ABS_JUMP_DELTA_ANGLE || + deltaThumbAndTick < -MAX_ABS_JUMP_DELTA_ANGLE) { + // Trying to jump too far, ignore this touch interaction + mMode = MODE_IGNORE_UNTIL_UP; + return true; + } + + // Make sure we only let them jump within bounds + if (boundAngle != Integer.MIN_VALUE) { + tickAngle = boundAngle; + } + } else { + // Not enforcing the max jump, but we have to make sure + // we're getting to the tapped angle by going through the + // in-bounds region + if (boundAngle != Integer.MIN_VALUE) { + // Going this direction hits a bound, let's go the opposite direction + boolean oldDirectionIsCcw = deltaThumbAndTick > 0; + deltaThumbAndTick = getDelta(mThumbAngle, tickAngle, !oldDirectionIsCcw); + boundAngle = getBoundIfExceeds(mThumbAngle, deltaThumbAndTick); + if (boundAngle != Integer.MIN_VALUE) { + Log + .d( + TAG, + "Tapped somewhere where the shortest distance goes through a bound, but then the opposite direction also went through a bound!"); + } + } + } + + mMode = MODE_WAITING_FOR_DRAG_THUMB; + mWaitingForDragThumbDownAngle = touchAngle; + boolean ccw = deltaThumbAndTick > 0; + setThumbAngleAnimated(tickAngle, 0, ccw); + + // Our thumb scrolling animation takes us from mThumbAngle to tickAngle + onThumbDragStarted(mThumbAngle); + onThumbDragged(tickAngle, true, ccw); + } else { + // They tapped somewhere else mMode = MODE_WAITING_FOR_MOVE_ZOOM_RING; + mCallback.onZoomRingSetMovableHintVisible(true); } - if (mCallback != null) { - if (mMode == MODE_DRAG_THUMB) { - onThumbDragStarted(touchAngle); - } else if (mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) { - mCallback.onZoomRingSetMovableHintVisible(true); - } + } else if (mMode == MODE_WAITING_FOR_DRAG_THUMB) { + int deltaDownAngle = getDelta(mWaitingForDragThumbDownAngle, touchAngle); + if ((deltaDownAngle < -THUMB_DRAG_SLOP || deltaDownAngle > THUMB_DRAG_SLOP) && + isDeltaInBounds(mWaitingForDragThumbDownAngle, deltaDownAngle)) { + mMode = MODE_DRAG_THUMB; } } else if (mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) { @@ -323,19 +559,14 @@ public class ZoomRing extends View { Math.abs(y - mPreviousDownY) > mTouchSlop) { /* Make sure the user has moved the slop amount before going into that mode. */ mMode = MODE_MOVE_ZOOM_RING; - - if (mCallback != null) { - mCallback.onZoomRingMovingStarted(); - } + mCallback.onZoomRingMovingStarted(); } } // Purposefully not an "else if" if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG) { - if (isInBounds) { - onThumbDragged(touchAngle, mIsThumbAngleValid ? deltaThumbAndTouch : 0); - } else { - mIsThumbAngleValid = false; + if (isInRingBounds) { + onThumbDragged(touchAngle, false, false); } } else if (mMode == MODE_MOVE_ZOOM_RING) { onZoomRingMoved(rawX, rawY); @@ -344,55 +575,219 @@ public class ZoomRing extends View { return true; } - private int getDelta(int angle1, int angle2) { - int delta = angle1 - angle2; - - // Assume this is a result of crossing over the discontinuous 0 -> 2pi - if (delta > PI_INT_MULTIPLIED || delta < -PI_INT_MULTIPLIED) { - // Bring both the radians and previous angle onto a continuous range - if (angle1 < HALF_PI_INT_MULTIPLIED) { - // Same as deltaRadians = (radians + 2PI) - previousAngle - delta += PI_INT_MULTIPLIED * 2; - } else if (angle2 < HALF_PI_INT_MULTIPLIED) { - // Same as deltaRadians = radians - (previousAngle + 2PI) - delta -= PI_INT_MULTIPLIED * 2; + private boolean isDeltaInBounds(int startAngle, int deltaAngle) { + return getBoundIfExceeds(startAngle, deltaAngle) == Integer.MIN_VALUE; + } + + private int getBoundIfExceeds(int startAngle, int deltaAngle) { + if (deltaAngle > 0) { + // Counterclockwise movement + if (mThumbCcwBound != Integer.MIN_VALUE && + getDelta(startAngle, mThumbCcwBound, true) < deltaAngle) { + return mThumbCcwBound; + } + } else if (deltaAngle < 0) { + // Clockwise movement, both of these will be negative + int deltaThumbAndBound = getDelta(startAngle, mThumbCwBound, false); + if (mThumbCwBound != Integer.MIN_VALUE && + deltaThumbAndBound > deltaAngle) { + // Tapped outside of the bound in that direction + return mThumbCwBound; } } + + return Integer.MIN_VALUE; + } + + private int getDelta(int startAngle, int endAngle, boolean useDirection, boolean ccw) { + return useDirection ? getDelta(startAngle, endAngle, ccw) : getDelta(startAngle, endAngle); + } + + /** + * Gets the smallest delta between two angles, and infers the direction + * based on the shortest path between the two angles. If going from + * startAngle to endAngle is counterclockwise, the result will be positive. + * If it is clockwise, the result will be negative. + * + * @param startAngle The start angle. + * @param endAngle The end angle. + * @return The difference in angles. + */ + private int getDelta(int startAngle, int endAngle) { + int largerAngle, smallerAngle; + if (endAngle > startAngle) { + largerAngle = endAngle; + smallerAngle = startAngle; + } else { + largerAngle = startAngle; + smallerAngle = endAngle; + } - return delta; + int delta = largerAngle - smallerAngle; + if (delta <= PI_INT_MULTIPLIED) { + // If going clockwise, negate the delta + return startAngle == largerAngle ? -delta : delta; + } else { + // The other direction is the delta we want (it includes the + // discontinuous 0-2PI angle) + delta = TWO_PI_INT_MULTIPLIED - delta; + // If going clockwise, negate the delta + return startAngle == smallerAngle ? -delta : delta; + } } + /** + * Gets the delta between two angles in the direction specified. + * + * @param startAngle The start angle. + * @param endAngle The end angle. + * @param counterClockwise The direction to take when computing the delta. + * @return The difference in angles in the given direction. + */ + private int getDelta(int startAngle, int endAngle, boolean counterClockwise) { + int delta = endAngle - startAngle; + + if (!counterClockwise && delta > 0) { + // Crossed the discontinuous 0/2PI angle, take the leftover slice of + // the pie and negate it + return -TWO_PI_INT_MULTIPLIED + delta; + } else if (counterClockwise && delta < 0) { + // Crossed the discontinuous 0/2PI angle, take the leftover slice of + // the pie (and ensure it is positive) + return TWO_PI_INT_MULTIPLIED + delta; + } else { + return delta; + } + } + private void onThumbDragStarted(int startAngle) { + setThumbArrowsVisible(false); mThumbDragStartAngle = startAngle; - mCallback.onZoomRingThumbDraggingStarted(startAngle); + mCallback.onZoomRingThumbDraggingStarted(); } - - private void onThumbDragged(int touchAngle, int deltaAngle) { - mAcculumalatedTrailAngle += Math.toDegrees(deltaAngle / (double) RADIAN_INT_MULTIPLIER); - int totalDeltaAngle = getDelta(touchAngle, mPreviousCallbackAngle); - if (totalDeltaAngle > mCallbackThreshold - || totalDeltaAngle < -mCallbackThreshold) { - if (mCallback != null) { - boolean canStillZoom = mCallback.onZoomRingThumbDragged( - totalDeltaAngle / mCallbackThreshold, - mThumbDragStartAngle, touchAngle); - mDisabler.setEnabling(canStillZoom); - - if (canStillZoom) { - // TODO: we're trying the haptics to see how it goes with - // users, so we're ignoring the settings (for now) - performHapticFeedback(HapticFeedbackConstants.ZOOM_RING_TICK, - HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING | - HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); + + private void onThumbDragged(int touchAngle, boolean useDirection, boolean ccw) { + boolean animateThumbToNewAngle = false; + + int totalDeltaAngle; + totalDeltaAngle = getDelta(mPreviousCallbackAngle, touchAngle, useDirection, ccw); + int fuzzyCallbackThreshold = (int) (mCallbackThreshold * 0.65f); + if (totalDeltaAngle >= fuzzyCallbackThreshold + || totalDeltaAngle <= -fuzzyCallbackThreshold) { + + if (!useDirection) { + // Set ccw to match the direction found by getDelta + ccw = totalDeltaAngle > 0; + } + + /* + * When the user slides the thumb through the tick that corresponds + * to a zoom bound, we don't want to abruptly stop there. Instead, + * let the user slide it to the next tick, and then animate it back + * to the original zoom bound tick. Because of this, we make sure + * the delta from the bound is more than halfway to the next tick. + * We make sure the bound is between the touch and the previous + * callback to ensure we just passed the bound. + */ + int oldTouchAngle = touchAngle; + if (ccw && mThumbCcwBound != Integer.MIN_VALUE) { + int deltaCcwBoundAndTouch = + getDelta(mThumbCcwBound, touchAngle, useDirection, true); + if (deltaCcwBoundAndTouch >= mCallbackThreshold / 2) { + // The touch has past a bound + int deltaPreviousCbAndTouch = getDelta(mPreviousCallbackAngle, + touchAngle, useDirection, true); + if (deltaPreviousCbAndTouch >= deltaCcwBoundAndTouch) { + // The bound is between the previous callback angle and the touch + touchAngle = mThumbCcwBound; + // We're moving the touch BACK to the bound, so opposite direction + ccw = false; + } + } + } else if (!ccw && mThumbCwBound != Integer.MIN_VALUE) { + // See block above for general comments + int deltaCwBoundAndTouch = + getDelta(mThumbCwBound, touchAngle, useDirection, false); + if (deltaCwBoundAndTouch <= -mCallbackThreshold / 2) { + int deltaPreviousCbAndTouch = getDelta(mPreviousCallbackAngle, + touchAngle, useDirection, false); + /* + * Both of these will be negative since we got delta in + * clockwise direction, and we want the magnitude of + * deltaPreviousCbAndTouch to be greater than the magnitude + * of deltaCwBoundAndTouch + */ + if (deltaPreviousCbAndTouch <= deltaCwBoundAndTouch) { + touchAngle = mThumbCwBound; + ccw = true; + } + } + } + if (touchAngle != oldTouchAngle) { + // We bounded the touch angle + totalDeltaAngle = getDelta(mPreviousCallbackAngle, touchAngle, useDirection, ccw); + animateThumbToNewAngle = true; + mMode = MODE_IGNORE_UNTIL_UP; + } + + + // Prevent it from jumping too far + if (mEnforceMaxAbsJump) { + if (totalDeltaAngle <= -MAX_ABS_JUMP_DELTA_ANGLE) { + totalDeltaAngle = -MAX_ABS_JUMP_DELTA_ANGLE; + animateThumbToNewAngle = true; + } else if (totalDeltaAngle >= MAX_ABS_JUMP_DELTA_ANGLE) { + totalDeltaAngle = MAX_ABS_JUMP_DELTA_ANGLE; + animateThumbToNewAngle = true; } } - // Get the closest tick and lock on there - mPreviousCallbackAngle = getClosestTickAngle(touchAngle); + /* + * We need to cover the edge case of a user grabbing the thumb, + * going into the center of the widget, and then coming out from the + * center to an angle that's slightly below the angle he's trying to + * hit. If we do int division, we'll end up with one level lower + * than the one he was going for. + */ + int deltaLevels = Math.round((float) totalDeltaAngle / mCallbackThreshold); + if (deltaLevels != 0) { + boolean canStillZoom = mCallback.onZoomRingThumbDragged( + deltaLevels, mThumbDragStartAngle, touchAngle); + + // TODO: we're trying the haptics to see how it goes with + // users, so we're ignoring the settings (for now) + performHapticFeedback(HapticFeedbackConstants.ZOOM_RING_TICK, + HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING | + HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); + + // Set the callback angle to the actual angle based on how many delta levels we gave + mPreviousCallbackAngle = getValidAngle( + mPreviousCallbackAngle + (deltaLevels * mCallbackThreshold)); + } } - setThumbAngle(touchAngle); - mIsThumbAngleValid = true; + int deltaAngle = getDelta(mThumbAngle, touchAngle, useDirection, ccw); + mAcculumalatedTrailAngle += Math.toDegrees(deltaAngle / (double) RADIAN_INT_MULTIPLIER); + + if (animateThumbToNewAngle) { + if (useDirection) { + setThumbAngleAnimated(touchAngle, 0, ccw); + } else { + setThumbAngleAnimated(touchAngle, 0); + } + } else { + setThumbAngleAuto(touchAngle, useDirection, ccw); + } + } + + private int getValidAngle(int invalidAngle) { + if (invalidAngle < 0) { + return (invalidAngle % TWO_PI_INT_MULTIPLIED) + TWO_PI_INT_MULTIPLIED; + } else if (invalidAngle >= TWO_PI_INT_MULTIPLIED) { + return invalidAngle % TWO_PI_INT_MULTIPLIED; + } else { + return invalidAngle; + } } private int getClosestTickAngle(int angle) { @@ -403,12 +798,12 @@ public class ZoomRing extends View { return smallerAngle; } else { // Closer to the bigger angle (premodding) - return (smallerAngle + mCallbackThreshold) % (PI_INT_MULTIPLIED * 2); + return (smallerAngle + mCallbackThreshold) % TWO_PI_INT_MULTIPLIED; } } - private void onThumbDragStopped(int stopAngle) { - mCallback.onZoomRingThumbDraggingStopped(stopAngle); + private void onThumbDragStopped() { + mCallback.onZoomRingThumbDraggingStopped(); } private void onZoomRingMoved(int x, int y) { @@ -416,9 +811,7 @@ public class ZoomRing extends View { int deltaX = x - mPreviousWidgetDragX; int deltaY = y - mPreviousWidgetDragY; - if (mCallback != null) { - mCallback.onZoomRingMoved(deltaX, deltaY); - } + mCallback.onZoomRingMoved(deltaX, deltaY); } mPreviousWidgetDragX = x; @@ -429,11 +822,11 @@ public class ZoomRing extends View { public void onWindowFocusChanged(boolean hasWindowFocus) { super.onWindowFocusChanged(hasWindowFocus); - if (!hasWindowFocus && mCallback != null) { - mCallback.onZoomRingDismissed(); + if (!hasWindowFocus) { + mCallback.onZoomRingDismissed(true); } } - + private int getAngle(int localX, int localY) { int radians = (int) (Math.atan2(localY, localX) * RADIAN_INT_MULTIPLIER); @@ -458,45 +851,65 @@ public class ZoomRing extends View { if (DRAW_TRAIL) { mTrail.draw(canvas); } + + // If we aren't near the bounds, draw the corresponding arrows + int callbackAngle = mPreviousCallbackAngle; + if (callbackAngle < mThumbCwBound - RADIAN_INT_ERROR || + callbackAngle > mThumbCwBound + RADIAN_INT_ERROR) { + mThumbPlusArrowDrawable.draw(canvas); + } + if (callbackAngle < mThumbCcwBound - RADIAN_INT_ERROR || + callbackAngle > mThumbCcwBound + RADIAN_INT_ERROR) { + mThumbMinusArrowDrawable.draw(canvas); + } mThumbDrawable.draw(canvas); } } - - private class Disabler implements Runnable { - private static final int DELAY = 15; - private static final float ENABLE_RATE = 1.05f; - private static final float DISABLE_RATE = 0.95f; - - private int mAlpha = 255; - private boolean mEnabling; - - public int getAlpha() { - return mAlpha; - } - - public void setEnabling(boolean enabling) { - if ((enabling && mAlpha != 255) || (!enabling && mAlpha != DISABLED_ALPHA)) { - mEnabling = enabling; - post(this); - } + + private void setThumbArrowsAngle(int angle) { + int level = -angle * 10000 / ZoomRing.TWO_PI_INT_MULTIPLIED; + mThumbPlusArrowDrawable.setLevel(level); + mThumbMinusArrowDrawable.setLevel(level); + } + + public void setThumbArrowsVisible(boolean visible) { + if (visible) { + mThumbArrowsAlpha = 255; + mThumbPlusArrowDrawable.setAlpha(255); + mThumbMinusArrowDrawable.setAlpha(255); + invalidate(); + } else if (mThumbArrowsAlpha == 255) { + // Only start fade if we're fully visible (otherwise another fade is happening already) + mThumbArrowsFadeStartTime = SystemClock.elapsedRealtime(); + onThumbArrowsFadeTick(); } + } + + private void onThumbArrowsFadeTick() { + if (mThumbArrowsAlpha <= 0) return; - public void run() { - mAlpha *= mEnabling ? ENABLE_RATE : DISABLE_RATE; - if (mAlpha < DISABLED_ALPHA) { - mAlpha = DISABLED_ALPHA; - } else if (mAlpha > 255) { - mAlpha = 255; - } else { - // Still more to go - postDelayed(this, DELAY); - } - - getBackground().setAlpha(mAlpha); - invalidate(); + mThumbArrowsAlpha = (int) + (255 - (255 * (SystemClock.elapsedRealtime() - mThumbArrowsFadeStartTime) + / THUMB_ARROWS_FADE_DURATION)); + if (mThumbArrowsAlpha < 0) mThumbArrowsAlpha = 0; + mThumbPlusArrowDrawable.setAlpha(mThumbArrowsAlpha); + mThumbMinusArrowDrawable.setAlpha(mThumbArrowsAlpha); + invalidateDrawable(mThumbPlusArrowDrawable); + invalidateDrawable(mThumbMinusArrowDrawable); + + if (!mHandler.hasMessages(MSG_THUMB_ARROWS_FADE_TICK)) { + mHandler.sendEmptyMessage(MSG_THUMB_ARROWS_FADE_TICK); } } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + + setThumbArrowsAngle(mThumbAngle); + setThumbArrowsVisible(true); + } + public interface OnZoomRingCallback { void onZoomRingSetMovableHintVisible(boolean visible); @@ -504,11 +917,17 @@ public class ZoomRing extends View { boolean onZoomRingMoved(int deltaX, int deltaY); void onZoomRingMovingStopped(); - void onZoomRingThumbDraggingStarted(int startAngle); + void onZoomRingThumbDraggingStarted(); boolean onZoomRingThumbDragged(int numLevels, int startAngle, int curAngle); - void onZoomRingThumbDraggingStopped(int endAngle); + void onZoomRingThumbDraggingStopped(); - void onZoomRingDismissed(); + void onZoomRingDismissed(boolean dismissImmediately); + + void onUserInteractionStarted(); + void onUserInteractionStopped(); } + private static void printAngle(String angleName, int angle) { + Log.d(TAG, angleName + ": " + (long) angle * 180 / PI_INT_MULTIPLIED); + } } diff --git a/core/java/android/widget/ZoomRingController.java b/core/java/android/widget/ZoomRingController.java index eb28767..31074b6 100644 --- a/core/java/android/widget/ZoomRingController.java +++ b/core/java/android/widget/ZoomRingController.java @@ -16,6 +16,8 @@ package android.widget; +import android.app.AlertDialog; +import android.app.Dialog; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -27,7 +29,6 @@ import android.graphics.Rect; import android.os.Handler; import android.os.Message; import android.os.SystemClock; -import android.os.Vibrator; import android.provider.Settings; import android.util.Log; import android.view.Gravity; @@ -35,6 +36,7 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; +import android.view.Window; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.animation.Animation; @@ -46,12 +48,16 @@ import android.view.animation.DecelerateInterpolator; /** * TODO: Docs * + * If you are using this with a custom View, please call + * {@link #setVisible(boolean) setVisible(false)} from the + * {@link View#onDetachedFromWindow}. + * * @hide */ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, View.OnTouchListener, View.OnKeyListener { - private static final int SHOW_TUTORIAL_TOAST_DELAY = 1000; + private static final int ZOOM_RING_RADIUS_INSET = 10; private static final int ZOOM_RING_RECENTERING_DURATION = 500; @@ -69,9 +75,11 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, // TODO: scale px values based on latest from ViewConfiguration private static final int SECOND_TAP_TIMEOUT = 500; private static final int ZOOM_RING_DISMISS_DELAY = SECOND_TAP_TIMEOUT / 2; - private static final int SECOND_TAP_SLOP = 70; - private static final int SECOND_TAP_MOVE_SLOP = 15; - private static final int MAX_PAN_GAP = 30; + // TODO: view config? at least scaled + private static final int MAX_PAN_GAP = 20; + private static final int MAX_INITIATE_PAN_GAP = 10; + // TODO view config + private static final int INITIATE_PAN_DELAY = 400; private static final String SETTING_NAME_SHOWN_TOAST = "shown_zoom_ring_toast"; @@ -95,6 +103,23 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, private FrameLayout mContainer; private LayoutParams mContainerLayoutParams; + /** + * The view (or null) that should receive touch events. This will get set if + * the touch down hits the container. It will be reset on the touch up. + */ + private View mTouchTargetView; + /** + * The {@link #mTouchTargetView}'s location in window, set on touch down. + */ + private int[] mTouchTargetLocationInWindow = new int[2]; + /** + * If the zoom ring is dismissed but the user is still in a touch + * interaction, we set this to true. This will ignore all touch events until + * up/cancel, and then set the owner's touch listener to null. + */ + private boolean mReleaseTouchListenerOnUp; + + /* * Tap-drag is an interaction where the user first taps and then (quickly) * does the clockwise or counter-clockwise drag. In reality, this is: (down, @@ -122,6 +147,8 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, /** Invokes panning of owner view if the zoom ring is touching an edge. */ private Panner mPanner = new Panner(); + private long mTouchingEdgeStartTime; + private boolean mPanningEnabledForThisInteraction; private ImageView mPanningArrows; private Animation mPanningArrowsEnterAnimation; @@ -162,26 +189,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, * the UI thread so it will be exceuted AFTER the layout. This is the logic. */ private Runnable mPostedVisibleInitializer; - - // TODO: need a better way to persist this value, becuase right now this - // requires the WRITE_SETTINGS perimssion which the app may not have -// private Runnable mShowTutorialToast = new Runnable() { -// public void run() { -// if (Settings.System.getInt(mContext.getContentResolver(), -// SETTING_NAME_SHOWN_TOAST, 0) == 1) { -// return; -// } -// try { -// Settings.System.putInt(mContext.getContentResolver(), SETTING_NAME_SHOWN_TOAST, 1); -// } catch (SecurityException e) { -// // The app does not have permission to clear this flag, oh well! -// } -// -// Toast.makeText(mContext, -// com.android.internal.R.string.tutorial_double_tap_to_zoom_message, -// Toast.LENGTH_LONG).show(); -// } -// }; + + /** + * Only touch from the main thread. + */ + private static Dialog sTutorialDialog; + private static long sTutorialShowTime; + private static final int TUTORIAL_MIN_DISPLAY_TIME = 2000; private IntentFilter mConfigurationChangedFilter = new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED); @@ -230,38 +244,37 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, mOwnerView = ownerView; mZoomRing = new ZoomRing(context); + mZoomRing.setId(com.android.internal.R.id.zoomControls); mZoomRing.setLayoutParams(new FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, - FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER)); + FrameLayout.LayoutParams.WRAP_CONTENT, + Gravity.CENTER)); mZoomRing.setCallback(this); createPanningArrows(); - mContainer = new FrameLayout(context); - mContainer.setMeasureAllChildren(true); - mContainer.setOnTouchListener(this); - - mContainer.addView(mZoomRing); - mContainer.addView(mPanningArrows); - mContainer.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - mContainerLayoutParams = new LayoutParams(); mContainerLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; - mContainerLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | + mContainerLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCHABLE | LayoutParams.FLAG_NOT_FOCUSABLE | - LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | LayoutParams.FLAG_LAYOUT_NO_LIMITS; + LayoutParams.FLAG_LAYOUT_NO_LIMITS; mContainerLayoutParams.height = LayoutParams.WRAP_CONTENT; mContainerLayoutParams.width = LayoutParams.WRAP_CONTENT; mContainerLayoutParams.type = LayoutParams.TYPE_APPLICATION_PANEL; - mContainerLayoutParams.format = PixelFormat.TRANSLUCENT; + mContainerLayoutParams.format = PixelFormat.TRANSPARENT; // TODO: make a new animation for this mContainerLayoutParams.windowAnimations = com.android.internal.R.style.Animation_Dialog; + + mContainer = new FrameLayout(context); + mContainer.setLayoutParams(mContainerLayoutParams); + mContainer.setMeasureAllChildren(true); + + mContainer.addView(mZoomRing); + mContainer.addView(mPanningArrows); mScroller = new Scroller(context, new DecelerateInterpolator()); mViewConfig = ViewConfiguration.get(context); - -// mHandler.postDelayed(mShowTutorialToast, SHOW_TUTORIAL_TOAST_DELAY); } private void createPanningArrows() { @@ -272,7 +285,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER)); - mPanningArrows.setVisibility(View.GONE); + mPanningArrows.setVisibility(View.INVISIBLE); mPanningArrowsEnterAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.fade_in); @@ -291,6 +304,17 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, public void setZoomCallbackThreshold(float callbackThreshold) { mZoomRing.setCallbackThreshold((int) (callbackThreshold * ZoomRing.RADIAN_INT_MULTIPLIER)); } + + /** + * Sets a drawable for the zoom ring track. + * + * @param drawable The drawable to use for the track. + * @hide Need a better way of doing this, but this one-off for browser so it + * can have its final look for the usability study + */ + public void setZoomRingTrack(int drawable) { + mZoomRing.setBackgroundResource(drawable); + } public void setCallback(OnZoomListener callback) { mCallback = callback; @@ -300,10 +324,26 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, mZoomRing.setThumbAngle((int) (angle * ZoomRing.RADIAN_INT_MULTIPLIER)); } + public void setThumbAngleAnimated(float angle) { + mZoomRing.setThumbAngleAnimated((int) (angle * ZoomRing.RADIAN_INT_MULTIPLIER), 0); + } + public void setResetThumbAutomatically(boolean resetThumbAutomatically) { mZoomRing.setResetThumbAutomatically(resetThumbAutomatically); } + public void setThumbClockwiseBound(float angle) { + mZoomRing.setThumbClockwiseBound(angle >= 0 ? + (int) (angle * ZoomRing.RADIAN_INT_MULTIPLIER) : + Integer.MIN_VALUE); + } + + public void setThumbCounterclockwiseBound(float angle) { + mZoomRing.setThumbCounterclockwiseBound(angle >= 0 ? + (int) (angle * ZoomRing.RADIAN_INT_MULTIPLIER) : + Integer.MIN_VALUE); + } + public boolean isVisible() { return mIsZoomRingVisible; } @@ -321,12 +361,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, if (mIsZoomRingVisible == visible) { return; } + mIsZoomRingVisible = visible; if (visible) { if (mContainerLayoutParams.token == null) { mContainerLayoutParams.token = mOwnerView.getWindowToken(); } - + mWindowManager.addView(mContainer, mContainerLayoutParams); if (mPostedVisibleInitializer == null) { @@ -340,6 +381,10 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, // probably can only be retrieved after it's measured, which happens // after it's added). mWindowManager.updateViewLayout(mContainer, mContainerLayoutParams); + + if (mCallback != null) { + mCallback.onVisibilityChanged(true); + } } }; } @@ -349,24 +394,49 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, // Handle configuration changes when visible mContext.registerReceiver(mConfigurationChangedReceiver, mConfigurationChangedFilter); - // Steal key events from the owner + // Steal key/touches events from the owner mOwnerView.setOnKeyListener(this); + mOwnerView.setOnTouchListener(this); + mReleaseTouchListenerOnUp = false; } else { - // Don't want to steal any more keys + // Don't want to steal any more keys/touches mOwnerView.setOnKeyListener(null); + if (mTouchTargetView != null) { + // We are still stealing the touch events for this touch + // sequence, so release the touch listener later + mReleaseTouchListenerOnUp = true; + } else { + mOwnerView.setOnTouchListener(null); + } // No longer care about configuration changes mContext.unregisterReceiver(mConfigurationChangedReceiver); mWindowManager.removeView(mContainer); - } - - mIsZoomRingVisible = visible; - if (mCallback != null) { - mCallback.onVisibilityChanged(visible); + if (mCallback != null) { + mCallback.onVisibilityChanged(false); + } } + + } + + /** + * TODO: docs + * + * Notes: + * - Touch dispatching is different. Only direct children who are clickable are eligble for touch events. + * - Please ensure you set your View to INVISIBLE not GONE when hiding it. + * + * @return + */ + public FrameLayout getContainer() { + return mContainer; + } + + public int getZoomRingId() { + return mZoomRing.getId(); } private void dismissZoomRingDelayed(int delay) { @@ -484,77 +554,8 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, mOwnerViewBounds, mTempRect); mCenteredContainerX = mTempRect.left; mCenteredContainerY = mTempRect.top; - } - // MOVE ALL THIS TO GESTURE DETECTOR -// public boolean onTouch(View v, MotionEvent event) { -// int action = event.getAction(); -// -// if (mListenForInvocation) { -// switch (mTouchMode) { -// case TOUCH_MODE_IDLE: { -// if (action == MotionEvent.ACTION_DOWN) { -// setFirstTap(event); -// } -// break; -// } -// -// case TOUCH_MODE_WAITING_FOR_SECOND_TAP: { -// switch (action) { -// case MotionEvent.ACTION_DOWN: -// if (isSecondTapWithinSlop(event)) { -// handleDoubleTapEvent(event); -// } else { -// setFirstTap(event); -// } -// break; -// -// case MotionEvent.ACTION_MOVE: -// int deltaX = (int) event.getX() - mFirstTapX; -// if (deltaX < -SECOND_TAP_MOVE_SLOP || -// deltaX > SECOND_TAP_MOVE_SLOP) { -// mTouchMode = TOUCH_MODE_IDLE; -// } else { -// int deltaY = (int) event.getY() - mFirstTapY; -// if (deltaY < -SECOND_TAP_MOVE_SLOP || -// deltaY > SECOND_TAP_MOVE_SLOP) { -// mTouchMode = TOUCH_MODE_IDLE; -// } -// } -// break; -// } -// break; -// } -// -// case TOUCH_MODE_WAITING_FOR_TAP_DRAG_MOVEMENT: -// case TOUCH_MODE_FORWARDING_FOR_TAP_DRAG: { -// handleDoubleTapEvent(event); -// break; -// } -// } -// -// if (action == MotionEvent.ACTION_CANCEL) { -// mTouchMode = TOUCH_MODE_IDLE; -// } -// } -// -// return false; -// } -// -// private void setFirstTap(MotionEvent event) { -// mFirstTapTime = event.getEventTime(); -// mFirstTapX = (int) event.getX(); -// mFirstTapY = (int) event.getY(); -// mTouchMode = TOUCH_MODE_WAITING_FOR_SECOND_TAP; -// } -// -// private boolean isSecondTapWithinSlop(MotionEvent event) { -// return mFirstTapTime + SECOND_TAP_TIMEOUT > event.getEventTime() && -// Math.abs((int) event.getX() - mFirstTapX) < SECOND_TAP_SLOP && -// Math.abs((int) event.getY() - mFirstTapY) < SECOND_TAP_SLOP; -// } - /** * Centers the point (in owner view's coordinates). */ @@ -575,16 +576,28 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, public void onZoomRingSetMovableHintVisible(boolean visible) { setPanningArrowsVisible(visible); } + + public void onUserInteractionStarted() { + mHandler.removeMessages(MSG_DISMISS_ZOOM_RING); + } + + public void onUserInteractionStopped() { + dismissZoomRingDelayed(ZOOM_CONTROLS_TIMEOUT); + } public void onZoomRingMovingStarted() { - mHandler.removeMessages(MSG_DISMISS_ZOOM_RING); mScroller.abortAnimation(); + mPanningEnabledForThisInteraction = false; + mTouchingEdgeStartTime = 0; + if (mCallback != null) { + mCallback.onBeginPan(); + } } private void setPanningArrowsVisible(boolean visible) { mPanningArrows.startAnimation(visible ? mPanningArrowsEnterAnimation : mPanningArrowsExitAnimation); - mPanningArrows.setVisibility(visible ? View.VISIBLE : View.GONE); + mPanningArrows.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); } public boolean onZoomRingMoved(int deltaX, int deltaY) { @@ -611,37 +624,73 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, mWindowManager.updateViewLayout(mContainer, lp); // Check for pan + boolean horizontalPanning = true; int leftGap = newZoomRingX - ownerBounds.left; if (leftGap < MAX_PAN_GAP) { - mPanner.setHorizontalStrength(-getStrengthFromGap(leftGap)); + if (shouldPan(leftGap)) { + mPanner.setHorizontalStrength(-getStrengthFromGap(leftGap)); + } } else { int rightGap = ownerBounds.right - (lp.x + mZoomRingWidth + zoomRingLeft); if (rightGap < MAX_PAN_GAP) { - mPanner.setHorizontalStrength(getStrengthFromGap(rightGap)); + if (shouldPan(rightGap)) { + mPanner.setHorizontalStrength(getStrengthFromGap(rightGap)); + } } else { mPanner.setHorizontalStrength(0); + horizontalPanning = false; } } int topGap = newZoomRingY - ownerBounds.top; if (topGap < MAX_PAN_GAP) { - mPanner.setVerticalStrength(-getStrengthFromGap(topGap)); + if (shouldPan(topGap)) { + mPanner.setVerticalStrength(-getStrengthFromGap(topGap)); + } } else { int bottomGap = ownerBounds.bottom - (lp.y + mZoomRingHeight + zoomRingTop); if (bottomGap < MAX_PAN_GAP) { - mPanner.setVerticalStrength(getStrengthFromGap(bottomGap)); + if (shouldPan(bottomGap)) { + mPanner.setVerticalStrength(getStrengthFromGap(bottomGap)); + } } else { mPanner.setVerticalStrength(0); + if (!horizontalPanning) { + // Neither are panning, reset any timer to start pan mode + mTouchingEdgeStartTime = 0; + } } } return true; } + private boolean shouldPan(int gap) { + if (mPanningEnabledForThisInteraction) return true; + + if (gap < MAX_INITIATE_PAN_GAP) { + long time = SystemClock.elapsedRealtime(); + if (mTouchingEdgeStartTime != 0 && + mTouchingEdgeStartTime + INITIATE_PAN_DELAY < time) { + mPanningEnabledForThisInteraction = true; + return true; + } else if (mTouchingEdgeStartTime == 0) { + mTouchingEdgeStartTime = time; + } else { + } + } else { + // Moved away from the initiate pan gap, so reset the timer + mTouchingEdgeStartTime = 0; + } + return false; + } + public void onZoomRingMovingStopped() { - dismissZoomRingDelayed(ZOOM_CONTROLS_TIMEOUT); mPanner.stop(); - setPanningArrowsVisible(false); + setPanningArrowsVisible(false); + if (mCallback != null) { + mCallback.onEndPan(); + } } private int getStrengthFromGap(int gap) { @@ -649,10 +698,9 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, (MAX_PAN_GAP - gap) * 100 / MAX_PAN_GAP; } - public void onZoomRingThumbDraggingStarted(int startAngle) { - mHandler.removeMessages(MSG_DISMISS_ZOOM_RING); + public void onZoomRingThumbDraggingStarted() { if (mCallback != null) { - mCallback.onBeginDrag((float) startAngle / ZoomRing.RADIAN_INT_MULTIPLIER); + mCallback.onBeginDrag(); } } @@ -674,25 +722,122 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, return false; } - public void onZoomRingThumbDraggingStopped(int endAngle) { - dismissZoomRingDelayed(ZOOM_CONTROLS_TIMEOUT); + public void onZoomRingThumbDraggingStopped() { if (mCallback != null) { - mCallback.onEndDrag((float) endAngle / ZoomRing.RADIAN_INT_MULTIPLIER); + mCallback.onEndDrag(); } } - public void onZoomRingDismissed() { - dismissZoomRingDelayed(ZOOM_RING_DISMISS_DELAY); + public void onZoomRingDismissed(boolean dismissImmediately) { + if (dismissImmediately) { + mHandler.removeMessages(MSG_DISMISS_ZOOM_RING); + setVisible(false); + } else { + dismissZoomRingDelayed(ZOOM_RING_DISMISS_DELAY); + } } - + + public void onRingDown(int tickAngle, int touchAngle) { + } + public boolean onTouch(View v, MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { - // If the user touches outside of the zoom ring, dismiss the zoom ring - dismissZoomRingDelayed(ZOOM_RING_DISMISS_DELAY); + if (sTutorialDialog != null && sTutorialDialog.isShowing() && + SystemClock.elapsedRealtime() - sTutorialShowTime >= TUTORIAL_MIN_DISPLAY_TIME) { + finishZoomTutorial(); + } + + int action = event.getAction(); + + if (mReleaseTouchListenerOnUp) { + // The ring was dismissed but we need to throw away all events until the up + if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { + mOwnerView.setOnTouchListener(null); + mReleaseTouchListenerOnUp = false; + } + + // Eat this event return true; } - return false; + View targetView = mTouchTargetView; + + switch (action) { + case MotionEvent.ACTION_DOWN: + targetView = mTouchTargetView = + getViewForTouch((int) event.getRawX(), (int) event.getRawY()); + if (targetView != null) { + targetView.getLocationInWindow(mTouchTargetLocationInWindow); + } + break; + + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + mTouchTargetView = null; + break; + } + + if (targetView != null) { + // The upperleft corner of the target view in raw coordinates + int targetViewRawX = mContainerLayoutParams.x + mTouchTargetLocationInWindow[0]; + int targetViewRawY = mContainerLayoutParams.y + mTouchTargetLocationInWindow[1]; + + MotionEvent containerEvent = MotionEvent.obtain(event); + // Convert the motion event into the target view's coordinates (from + // owner view's coordinates) + containerEvent.offsetLocation(mOwnerViewBounds.left - targetViewRawX, + mOwnerViewBounds.top - targetViewRawY); + boolean retValue = targetView.dispatchTouchEvent(containerEvent); + containerEvent.recycle(); + return retValue; + + } else { + if (action == MotionEvent.ACTION_DOWN) { + dismissZoomRingDelayed(ZOOM_RING_DISMISS_DELAY); + } + + return false; + } + } + + /** + * Returns the View that should receive a touch at the given coordinates. + * + * @param rawX The raw X. + * @param rawY The raw Y. + * @return The view that should receive the touches, or null if there is not one. + */ + private View getViewForTouch(int rawX, int rawY) { + // Check to see if it is touching the ring + int containerCenterX = mContainerLayoutParams.x + mContainer.getWidth() / 2; + int containerCenterY = mContainerLayoutParams.y + mContainer.getHeight() / 2; + int distanceFromCenterX = rawX - containerCenterX; + int distanceFromCenterY = rawY - containerCenterY; + int zoomRingRadius = mZoomRingWidth / 2 - ZOOM_RING_RADIUS_INSET; + if (distanceFromCenterX * distanceFromCenterX + + distanceFromCenterY * distanceFromCenterY <= + zoomRingRadius * zoomRingRadius) { + return mZoomRing; + } + + // Check to see if it is touching any other clickable View. + // Reverse order so the child drawn on top gets first dibs. + int containerCoordsX = rawX - mContainerLayoutParams.x; + int containerCoordsY = rawY - mContainerLayoutParams.y; + Rect frame = mTempRect; + for (int i = mContainer.getChildCount() - 1; i >= 0; i--) { + View child = mContainer.getChildAt(i); + if (child == mZoomRing || child.getVisibility() != View.VISIBLE || + !child.isClickable()) { + continue; + } + + child.getHitRect(frame); + if (frame.contains(containerCoordsX, containerCoordsY)) { + return child; + } + } + + return null; } /** Steals key events from the owner view. */ @@ -707,6 +852,8 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, case KeyEvent.KEYCODE_DPAD_DOWN: // Keep the zoom alive a little longer dismissZoomRingDelayed(ZOOM_CONTROLS_TIMEOUT); + // They started zooming, hide the thumb arrows + mZoomRing.setThumbArrowsVisible(false); if (mCallback != null && event.getAction() == KeyEvent.ACTION_DOWN) { mCallback.onSimpleZoom(keyCode == KeyEvent.KEYCODE_DPAD_UP); @@ -734,9 +881,14 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, ensureZoomRingIsCentered(); } + /* + * This is static so Activities can call this instead of the Views + * (Activities usually do not have a reference to the ZoomRingController + * instance.) + */ /** * Shows a "tutorial" (some text) to the user teaching her the new zoom - * invocation method. + * invocation method. Must call from the main thread. * <p> * It checks the global system setting to ensure this has not been seen * before. Furthermore, if the application does not have privilege to write @@ -757,20 +909,45 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, return; } + if (sTutorialDialog != null && sTutorialDialog.isShowing()) { + sTutorialDialog.dismiss(); + } + + sTutorialDialog = new AlertDialog.Builder(context) + .setMessage( + com.android.internal.R.string.tutorial_double_tap_to_zoom_message_short) + .setIcon(0) + .create(); + + Window window = sTutorialDialog.getWindow(); + window.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); + window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND | + WindowManager.LayoutParams.FLAG_BLUR_BEHIND); + window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | + WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); + + sTutorialDialog.show(); + sTutorialShowTime = SystemClock.elapsedRealtime(); + } + + public void finishZoomTutorial() { + if (sTutorialDialog == null) return; + + sTutorialDialog.dismiss(); + sTutorialDialog = null; + + // Record that they have seen the tutorial try { - Settings.System.putInt(cr, SETTING_NAME_SHOWN_TOAST, 1); + Settings.System.putInt(mContext.getContentResolver(), SETTING_NAME_SHOWN_TOAST, 1); } catch (SecurityException e) { /* * The app does not have permission to clear this global flag, make * sure the user does not see the message when he comes back to this * same app at least. */ + SharedPreferences sp = mContext.getSharedPreferences("_zoom", Context.MODE_PRIVATE); sp.edit().putInt(SETTING_NAME_SHOWN_TOAST, 1).commit(); } - - Toast.makeText(context, - com.android.internal.R.string.tutorial_double_tap_to_zoom_message_short, - Toast.LENGTH_LONG).show(); } private class Panner implements Runnable { @@ -861,12 +1038,14 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback, } public interface OnZoomListener { - void onBeginDrag(float startAngle); + void onBeginDrag(); boolean onDragZoom(int deltaZoomLevel, int centerX, int centerY, float startAngle, float curAngle); - void onEndDrag(float endAngle); + void onEndDrag(); void onSimpleZoom(boolean deltaZoomLevel); + void onBeginPan(); boolean onPan(int deltaX, int deltaY); + void onEndPan(); void onCenter(int x, int y); void onVisibilityChanged(boolean visible); } diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index eb232c7..b502a6c 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -19,13 +19,11 @@ package com.android.internal.app; import com.android.internal.os.BatteryStatsImpl; interface IBatteryStats { - BatteryStatsImpl getStatistics(); + byte[] getStatistics(); void noteStartWakelock(int uid, String name, int type); void noteStopWakelock(int uid, String name, int type); - void noteStartSensor(int uid, String name, int sensor); - void noteStopSensor(int uid, String name, int sensor); - void noteRequestGpsOn(int uid); - void noteRequestGpsOff(int uid); + void noteStartSensor(int uid, int sensor); + void noteStopSensor(int uid, int sensor); void noteStartGps(int uid); void noteStopGps(int uid); void noteScreenOn(); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index cbb65dc..558a122 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -31,7 +31,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; /** @@ -39,7 +38,7 @@ import java.util.Map; * battery life. All times are represented in microseconds except where indicated * otherwise. */ -public final class BatteryStatsImpl extends BatteryStats implements Parcelable { +public final class BatteryStatsImpl extends BatteryStats { private static final String TAG = "BatteryStatsImpl"; @@ -47,7 +46,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 15; + private static final int VERSION = 23; private final File mFile; private final File mBackupFile; @@ -65,8 +64,13 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { final ArrayList<Timer> mPartialTimers = new ArrayList<Timer>(); final ArrayList<Timer> mFullTimers = new ArrayList<Timer>(); final ArrayList<Timer> mWindowTimers = new ArrayList<Timer>(); - final ArrayList<Timer> mSensorTimers = new ArrayList<Timer>(); + final SparseArray<ArrayList<Timer>> mSensorTimers + = new SparseArray<ArrayList<Timer>>(); + // These are the objects that will want to do something when the device + // is unplugged from power. + final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>(); + int mStartCount; long mBatteryUptime; @@ -90,6 +94,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { * in to power. */ boolean mOnBattery; + boolean mOnBatteryInternal; long mTrackBatteryPastUptime; long mTrackBatteryUptimeStart; long mTrackBatteryPastRealtime; @@ -98,8 +103,6 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { long mUnpluggedBatteryUptime; long mUnpluggedBatteryRealtime; - HashSet<Integer> mGpsRequesters = new HashSet<Integer>(); - long mLastWriteTime = 0; // Milliseconds // For debugging @@ -107,87 +110,100 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { mFile = mBackupFile = null; } + public static interface Unpluggable { + void unplug(long batteryUptime, long batteryRealtime); + void plug(long batteryUptime, long batteryRealtime); + } + /** * State for keeping track of timing information. */ - public static final class Timer extends BatteryStats.Timer { - ArrayList<Timer> mTimerPool; + public static final class Timer extends BatteryStats.Timer implements Unpluggable { + final int mType; + final ArrayList<Timer> mTimerPool; - int mType; int mNesting; int mCount; int mLoadedCount; int mLastCount; + int mUnpluggedCount; - // Times are in microseconds for better accuracy when dividing by the lock count + // Times are in microseconds for better accuracy when dividing by the + // lock count, and are in "battery realtime" units. - long mTotalTime; // Add mUnpluggedTotalTime to get true value + long mTotalTime; long mLoadedTotalTime; long mLastTotalTime; - long mStartTime; long mUpdateTime; /** * The value of mTotalTime when unplug() was last called, initially 0. */ - long mTotalTimeAtLastUnplug; + long mUnpluggedTotalTime; - /** Constructor used for unmarshalling only. */ - Timer() {} + Timer(int type, ArrayList<Timer> timerPool, + ArrayList<Unpluggable> unpluggables, Parcel in) { + mType = type; + mTimerPool = timerPool; + mCount = in.readInt(); + mLoadedCount = in.readInt(); + mLastCount = in.readInt(); + mUnpluggedCount = in.readInt(); + mTotalTime = in.readLong(); + mLoadedTotalTime = in.readLong(); + mLastTotalTime = in.readLong(); + mUpdateTime = in.readLong(); + mUnpluggedTotalTime = in.readLong(); + unpluggables.add(this); + } - Timer(int type, ArrayList<Timer> timerPool) { + Timer(int type, ArrayList<Timer> timerPool, + ArrayList<Unpluggable> unpluggables) { mType = type; mTimerPool = timerPool; + unpluggables.add(this); } - public void writeToParcel(Parcel out) { - out.writeInt(mType); - out.writeInt(mNesting); + public void writeToParcel(Parcel out, long batteryRealtime) { out.writeInt(mCount); out.writeInt(mLoadedCount); out.writeInt(mLastCount); - out.writeLong(mTotalTime); + out.writeInt(mUnpluggedCount); + out.writeLong(computeRunTimeLocked(batteryRealtime)); out.writeLong(mLoadedTotalTime); out.writeLong(mLastTotalTime); - out.writeLong(mStartTime); out.writeLong(mUpdateTime); - out.writeLong(mTotalTimeAtLastUnplug); + out.writeLong(mUnpluggedTotalTime); } - public void readFromParcel(Parcel in) { - mType = in.readInt(); - mNesting = in.readInt(); - mCount = in.readInt(); - mLoadedCount = in.readInt(); - mLastCount = in.readInt(); - mTotalTime = in.readLong(); - mLoadedTotalTime = in.readLong(); - mLastTotalTime = in.readLong(); - mStartTime = in.readLong(); - mUpdateTime = in.readLong(); - mTotalTimeAtLastUnplug = in.readLong(); - } - - private void unplug() { - mTotalTimeAtLastUnplug += mTotalTime; - mTotalTime = 0; + public void unplug(long batteryUptime, long batteryRealtime) { + mUnpluggedTotalTime = computeRunTimeLocked(batteryRealtime); + mUnpluggedCount = mCount; } + public void plug(long batteryUptime, long batteryRealtime) { + if (mNesting > 0) { + mTotalTime = computeRunTimeLocked(batteryRealtime); + mUpdateTime = batteryRealtime; + } + } + /** * Writes a possibly null Timer to a Parcel. * * @param out the Parcel to be written to. * @param timer a Timer, or null. */ - public static void writeTimerToParcel(Parcel out, Timer timer) { + public static void writeTimerToParcel(Parcel out, Timer timer, + long batteryRealtime) { if (timer == null) { out.writeInt(0); // indicates null return; } out.writeInt(1); // indicates non-null - timer.writeToParcel(out); + timer.writeToParcel(out, batteryRealtime); } @Override @@ -197,10 +213,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { val = mLastTotalTime; } else { val = computeRunTimeLocked(now); - if (which != STATS_UNPLUGGED) { - val += mTotalTimeAtLastUnplug; - } - if ((which == STATS_CURRENT) || (which == STATS_UNPLUGGED)) { + if (which == STATS_UNPLUGGED) { + val -= mUnpluggedTotalTime; + } else if (which != STATS_TOTAL) { val -= mLoadedTotalTime; } } @@ -215,7 +230,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { val = mLastCount; } else { val = mCount; - if ((which == STATS_CURRENT) || (which == STATS_UNPLUGGED)) { + if (which == STATS_UNPLUGGED) { + val -= mUnpluggedCount; + } else if (which != STATS_TOTAL) { val -= mLoadedCount; } } @@ -223,12 +240,23 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { return val; } + public void logState() { + Log.i("foo", "mNesting=" + mNesting + " mCount=" + mCount + + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount + + " mUnpluggedCount=" + mUnpluggedCount); + Log.i("foo", "mTotalTime=" + mTotalTime + + " mLoadedTotalTime=" + mLoadedTotalTime); + Log.i("foo", "mLastTotalTime=" + mLastTotalTime + + " mUpdateTime=" + mUpdateTime); + } + void startRunningLocked(BatteryStatsImpl stats) { if (mNesting++ == 0) { - mStartTime = mUpdateTime = - stats.getBatteryUptimeLocked(SystemClock.elapsedRealtime() * 1000); - // Accumulate time to all other active counters with the current value of mCount - refreshTimersLocked(stats); + mUpdateTime = stats.getBatteryRealtimeLocked( + SystemClock.elapsedRealtime() * 1000); + // Accumulate time to all currently active timers before adding + // this new one to the pool. + refreshTimersLocked(stats, mTimerPool); // Add this timer to the active pool mTimerPool.add(this); // Increment the count @@ -242,38 +270,34 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { return; } if (--mNesting == 0) { - // Accumulate time to all active counters with the current value of mCount - refreshTimersLocked(stats); + // Accumulate time to all active counters, scaled by the total + // active in the pool, before taking this one out of the pool. + refreshTimersLocked(stats, mTimerPool); // Remove this timer from the active pool mTimerPool.remove(this); - // Decrement the count - mCount--; } } // Update the total time for all other running Timers with the same type as this Timer // due to a change in timer count - private void refreshTimersLocked(BatteryStatsImpl stats) { - for (Timer t : mTimerPool) { - t.updateTimeLocked(stats); - } - } - - /** - * Update totalTime and reset updateTime - * @param stats - */ - private void updateTimeLocked(BatteryStatsImpl stats) { - long realtime = SystemClock.elapsedRealtime() * 1000; - long heldTime = stats.getBatteryUptimeLocked(realtime) - mUpdateTime; - if (heldTime > 0) { - mTotalTime += heldTime / mCount; + private static void refreshTimersLocked(final BatteryStatsImpl stats, + final ArrayList<Timer> pool) { + final long realtime = SystemClock.elapsedRealtime() * 1000; + final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime); + final int N = pool.size(); + for (int i=N-1; i>= 0; i--) { + final Timer t = pool.get(i); + long heldTime = batteryRealtime - t.mUpdateTime; + if (heldTime > 0) { + t.mTotalTime += heldTime / N; + } + t.mUpdateTime = batteryRealtime; } - mUpdateTime = stats.getBatteryUptimeLocked(realtime); } - private long computeRunTimeLocked(long curBatteryUptime) { - return mTotalTime + (mNesting > 0 ? (curBatteryUptime - mUpdateTime) / mCount : 0); + private long computeRunTimeLocked(long curBatteryRealtime) { + return mTotalTime + (mNesting > 0 + ? (curBatteryRealtime - mUpdateTime) / mTimerPool.size() : 0); } void writeSummaryFromParcelLocked(Parcel out, long curBatteryUptime) { @@ -295,53 +319,41 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { } } - public void unplugTcpCounters() { - final int NU = mUidStats.size(); - for (int iu = 0; iu < NU; iu++) { + public void doUnplug(long batteryUptime, long batteryRealtime) { + for (int iu = mUidStats.size() - 1; iu >= 0; iu--) { Uid u = mUidStats.valueAt(iu); - u.mTcpBytesReceivedAtLastUnplug = u.getTcpBytesReceived(STATS_TOTAL); - u.mTcpBytesSentAtLastUnplug = u.getTcpBytesSent(STATS_TOTAL); + u.mStartedTcpBytesReceived = NetStat.getUidRxBytes(u.mUid); + u.mStartedTcpBytesSent = NetStat.getUidTxBytes(u.mUid); + u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived; + u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent; + } + for (int i = mUnpluggables.size() - 1; i >= 0; i--) { + mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime); } } - public void unplugTimers() { - ArrayList<Timer> timers; - - timers = mPartialTimers; - for (int i = timers.size() - 1; i >= 0; i--) { - timers.get(i).unplug(); - } - timers = mFullTimers; - for (int i = timers.size() - 1; i >= 0; i--) { - timers.get(i).unplug(); - } - timers = mWindowTimers; - for (int i = timers.size() - 1; i >= 0; i--) { - timers.get(i).unplug(); + public void doPlug(long batteryUptime, long batteryRealtime) { + for (int iu = mUidStats.size() - 1; iu >= 0; iu--) { + Uid u = mUidStats.valueAt(iu); + if (u.mStartedTcpBytesReceived >= 0) { + u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived(); + u.mStartedTcpBytesReceived = -1; + } + if (u.mStartedTcpBytesSent >= 0) { + u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent(); + u.mStartedTcpBytesSent = -1; + } } - timers = mSensorTimers; - for (int i = timers.size() - 1; i >= 0; i--) { - timers.get(i).unplug(); + for (int i = mUnpluggables.size() - 1; i >= 0; i--) { + mUnpluggables.get(i).plug(batteryUptime, batteryRealtime); } } public void noteStartGps(int uid) { - mGpsRequesters.add(uid); mUidStats.get(uid).noteStartGps(); } public void noteStopGps(int uid) { - mGpsRequesters.remove(uid); - mUidStats.get(uid).noteStopGps(); - } - - public void noteRequestGpsOn(int uid) { - mGpsRequesters.add(uid); - mUidStats.get(uid).noteStartGps(); - } - - public void noteRequestGpsOff(int uid) { - mGpsRequesters.remove(uid); mUidStats.get(uid).noteStopGps(); } @@ -349,7 +361,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { * When the device screen or battery state changes, update the appropriate "screen on time" * counter. */ - private void updateScreenOnTime(boolean screenOn) { + private void updateScreenOnTimeLocked(boolean screenOn) { if (!mScreenOn) { Log.w(TAG, "updateScreenOnTime without mScreenOn, ignored"); return; @@ -366,17 +378,17 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { } } - public void noteScreenOn() { + public void noteScreenOnLocked() { mScreenOn = true; mLastScreenOnTimeMillis = SystemClock.elapsedRealtime(); } - public void noteScreenOff() { + public void noteScreenOffLocked() { if (!mScreenOn) { Log.w(TAG, "noteScreenOff without mScreenOn, ignored"); return; } - updateScreenOnTime(false); + updateScreenOnTimeLocked(false); mScreenOn = false; } @@ -388,8 +400,11 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { return mPluggedScreenOnTimeMillis; } - @Override - public SparseArray<? extends BatteryStats.Uid> getUidStats() { + @Override public boolean getIsOnBattery() { + return mOnBattery; + } + + @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() { return mUidStats; } @@ -401,11 +416,16 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { final int mUid; long mLoadedTcpBytesReceived; long mLoadedTcpBytesSent; + long mCurrentTcpBytesReceived; + long mCurrentTcpBytesSent; long mTcpBytesReceivedAtLastUnplug; long mTcpBytesSentAtLastUnplug; - private final byte[] mBuf = new byte[16]; - + // These are not saved/restored when parcelling, since we want + // to return from the parcel with a snapshot of the state. + long mStartedTcpBytesReceived = -1; + long mStartedTcpBytesSent = -1; + /** * The statistics we have collected for this uid's wake locks. */ @@ -455,51 +475,56 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { } public long getTcpBytesReceived(int which) { - long current = NetStat.getUidRxBytes(mUid); - - if (which == STATS_CURRENT) { - return current; - } else if (which == STATS_LAST) { + if (which == STATS_LAST) { return mLoadedTcpBytesReceived; - } else if (which == STATS_UNPLUGGED) { - return current - mTcpBytesReceivedAtLastUnplug; - } else if (which == STATS_TOTAL) { - return mLoadedTcpBytesReceived + current; } else { - throw new IllegalArgumentException("which = " + which); + long current = computeCurrentTcpBytesReceived(); + if (which == STATS_UNPLUGGED) { + current -= mTcpBytesReceivedAtLastUnplug; + } else if (which == STATS_TOTAL) { + current += mLoadedTcpBytesReceived; + } + return current; } } + public long computeCurrentTcpBytesReceived() { + return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0 + ? (NetStat.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0); + } + public long getTcpBytesSent(int which) { - long current = NetStat.getUidTxBytes(mUid); - - if (which == STATS_CURRENT) { - return current; - } else if (which == STATS_LAST) { + if (which == STATS_LAST) { return mLoadedTcpBytesSent; - } else if (which == STATS_UNPLUGGED) { - return current - mTcpBytesSentAtLastUnplug; - } else if (which == STATS_TOTAL) { - return mLoadedTcpBytesSent + current; } else { - throw new IllegalArgumentException("which = " + which); + long current = computeCurrentTcpBytesSent(); + if (which == STATS_UNPLUGGED) { + current -= mTcpBytesSentAtLastUnplug; + } else if (which == STATS_TOTAL) { + current += mLoadedTcpBytesSent; + } + return current; } } - - void writeToParcelLocked(Parcel out) { + + public long computeCurrentTcpBytesSent() { + return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0 + ? (NetStat.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0); + } + + void writeToParcelLocked(Parcel out, long batteryRealtime) { out.writeInt(mWakelockStats.size()); for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) { out.writeString(wakelockEntry.getKey()); Uid.Wakelock wakelock = wakelockEntry.getValue(); - wakelock.writeToParcelLocked(out); + wakelock.writeToParcelLocked(out, batteryRealtime); } out.writeInt(mSensorStats.size()); for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) { out.writeInt(sensorEntry.getKey()); - out.writeString(sensorEntry.getValue().getName()); Uid.Sensor sensor = sensorEntry.getValue(); - sensor.writeToParcelLocked(out); + sensor.writeToParcelLocked(out, batteryRealtime); } out.writeInt(mProcessStats.size()); @@ -518,17 +543,19 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { out.writeLong(mLoadedTcpBytesReceived); out.writeLong(mLoadedTcpBytesSent); + out.writeLong(computeCurrentTcpBytesReceived()); + out.writeLong(computeCurrentTcpBytesSent()); out.writeLong(mTcpBytesReceivedAtLastUnplug); out.writeLong(mTcpBytesSentAtLastUnplug); } - void readFromParcelLocked(Parcel in) { + void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { int numWakelocks = in.readInt(); mWakelockStats.clear(); for (int j = 0; j < numWakelocks; j++) { String wakelockName = in.readString(); Uid.Wakelock wakelock = new Wakelock(); - wakelock.readFromParcelLocked(in); + wakelock.readFromParcelLocked(unpluggables, in); mWakelockStats.put(wakelockName, wakelock); } @@ -536,9 +563,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { mSensorStats.clear(); for (int k = 0; k < numSensors; k++) { int sensorNumber = in.readInt(); - String name = in.readString(); - Uid.Sensor sensor = new Sensor(name); - sensor.readFromParcelLocked(in); + Uid.Sensor sensor = new Sensor(sensorNumber); + sensor.readFromParcelLocked(mUnpluggables, in); mSensorStats.put(sensorNumber, sensor); } @@ -562,6 +588,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { mLoadedTcpBytesReceived = in.readLong(); mLoadedTcpBytesSent = in.readLong(); + mCurrentTcpBytesReceived = in.readLong(); + mCurrentTcpBytesSent = in.readLong(); mTcpBytesReceivedAtLastUnplug = in.readLong(); mTcpBytesSentAtLastUnplug = in.readLong(); } @@ -573,17 +601,17 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { /** * How long (in ms) this uid has been keeping the device partially awake. */ - Timer wakeTimePartial; + Timer mTimerPartial; /** * How long (in ms) this uid has been keeping the device fully awake. */ - Timer wakeTimeFull; + Timer mTimerFull; /** * How long (in ms) this uid has had a window keeping the device awake. */ - Timer wakeTimeWindow; + Timer mTimerWindow; /** * Reads a possibly null Timer from a Parcel. The timer is associated with the @@ -592,103 +620,85 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { * @param in the Parcel to be read from. * return a new Timer, or null. */ - private Timer readTimerFromParcel(Parcel in) { + private Timer readTimerFromParcel(int type, ArrayList<Timer> pool, + ArrayList<Unpluggable> unpluggables, Parcel in) { if (in.readInt() == 0) { return null; } - Timer timer = new Timer(); - timer.readFromParcel(in); - // Set the timer pool for the timer according to its type - switch (timer.mType) { - case WAKE_TYPE_PARTIAL: - timer.mTimerPool = mPartialTimers; - break; - case WAKE_TYPE_FULL: - timer.mTimerPool = mFullTimers; - break; - case WAKE_TYPE_WINDOW: - timer.mTimerPool = mWindowTimers; - break; - } - // If the timer is active, add it to the pool - if (timer.mNesting > 0) { - timer.mTimerPool.add(timer); - } - return timer; + return new Timer(type, pool, unpluggables, in); } - void readFromParcelLocked(Parcel in) { - wakeTimePartial = readTimerFromParcel(in); - wakeTimeFull = readTimerFromParcel(in); - wakeTimeWindow = readTimerFromParcel(in); + void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { + mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL, + mPartialTimers, unpluggables, in); + mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL, + mFullTimers, unpluggables, in); + mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW, + mWindowTimers, unpluggables, in); } - void writeToParcelLocked(Parcel out) { - Timer.writeTimerToParcel(out, wakeTimePartial); - Timer.writeTimerToParcel(out, wakeTimeFull); - Timer.writeTimerToParcel(out, wakeTimeWindow); + void writeToParcelLocked(Parcel out, long batteryRealtime) { + Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime); + Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime); + Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime); } @Override public Timer getWakeTime(int type) { switch (type) { - case WAKE_TYPE_FULL: return wakeTimeFull; - case WAKE_TYPE_PARTIAL: return wakeTimePartial; - case WAKE_TYPE_WINDOW: return wakeTimeWindow; + case WAKE_TYPE_FULL: return mTimerFull; + case WAKE_TYPE_PARTIAL: return mTimerPartial; + case WAKE_TYPE_WINDOW: return mTimerWindow; default: throw new IllegalArgumentException("type = " + type); } } } public final class Sensor extends BatteryStats.Uid.Sensor { - static final int GPS = -10000; // Treat GPS as a sensor - final String mName; - Timer sensorTime; + final int mHandle; + Timer mTimer; - public Sensor(String name) { - mName = name; + public Sensor(int handle) { + mHandle = handle; } - private Timer readTimerFromParcel(Parcel in) { + private Timer readTimerFromParcel(ArrayList<Unpluggable> unpluggables, + Parcel in) { if (in.readInt() == 0) { return null; } - Timer timer = new Timer(); - timer.readFromParcel(in); - // Set the timer pool for the timer - timer.mTimerPool = mSensorTimers; - - // If the timer is active, add it to the pool - if (timer.mNesting > 0) { - timer.mTimerPool.add(timer); + ArrayList<Timer> pool = mSensorTimers.get(mHandle); + if (pool == null) { + pool = new ArrayList<Timer>(); + mSensorTimers.put(mHandle, pool); } - return timer; + return new Timer(0, pool, unpluggables, in); } - void readFromParcelLocked(Parcel in) { - sensorTime = readTimerFromParcel(in); + void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) { + mTimer = readTimerFromParcel(unpluggables, in); } - void writeToParcelLocked(Parcel out) { - Timer.writeTimerToParcel(out, sensorTime); + void writeToParcelLocked(Parcel out, long batteryRealtime) { + Timer.writeTimerToParcel(out, mTimer, batteryRealtime); } @Override public Timer getSensorTime() { - return sensorTime; + return mTimer; } - public String getName() { - return mName; + public int getHandle() { + return mHandle; } } /** * The statistics associated with a particular process. */ - public final class Proc extends BatteryStats.Uid.Proc { + public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable { /** * Total time (in 1/100 sec) spent executing in user code. */ @@ -734,6 +744,34 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { */ int mLastStarts; + /** + * The amount of user time when last unplugged. + */ + long mUnpluggedUserTime; + + /** + * The amount of system time when last unplugged. + */ + long mUnpluggedSystemTime; + + /** + * The number of times the process has started before unplugged. + */ + int mUnpluggedStarts; + + Proc() { + mUnpluggables.add(this); + } + + public void unplug(long batteryUptime, long batteryRealtime) { + mUnpluggedUserTime = mUserTime; + mUnpluggedSystemTime = mSystemTime; + mUnpluggedStarts = mStarts; + } + + public void plug(long batteryUptime, long batteryRealtime) { + } + void writeToParcelLocked(Parcel out) { out.writeLong(mUserTime); out.writeLong(mSystemTime); @@ -744,6 +782,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { out.writeLong(mLastUserTime); out.writeLong(mLastSystemTime); out.writeInt(mLastStarts); + out.writeLong(mUnpluggedUserTime); + out.writeLong(mUnpluggedSystemTime); + out.writeInt(mUnpluggedStarts); } void readFromParcelLocked(Parcel in) { @@ -756,6 +797,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { mLastUserTime = in.readLong(); mLastSystemTime = in.readLong(); mLastStarts = in.readInt(); + mUnpluggedUserTime = in.readLong(); + mUnpluggedSystemTime = in.readLong(); + mUnpluggedStarts = in.readInt(); } public BatteryStatsImpl getBatteryStats() { @@ -780,6 +824,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { val = mUserTime; if (which == STATS_CURRENT) { val -= mLoadedUserTime; + } else if (which == STATS_UNPLUGGED) { + val -= mUnpluggedUserTime; } } return val; @@ -794,6 +840,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { val = mSystemTime; if (which == STATS_CURRENT) { val -= mLoadedSystemTime; + } else if (which == STATS_UNPLUGGED) { + val -= mUnpluggedSystemTime; } } return val; @@ -808,6 +856,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { val = mStarts; if (which == STATS_CURRENT) { val -= mLoadedStarts; + } else if (which == STATS_UNPLUGGED) { + val -= mUnpluggedStarts; } } return val; @@ -817,7 +867,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { /** * The statistics associated with a particular package. */ - public final class Pkg extends BatteryStats.Uid.Pkg { + public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable { /** * Number of times this package has done something that could wake up the * device from sleep. @@ -837,14 +887,32 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { int mLastWakeups; /** + * Number of things that could wake up the device as of the + * last run. + */ + int mUnpluggedWakeups; + + /** * The statics we have collected for this package's services. */ final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>(); + Pkg() { + mUnpluggables.add(this); + } + + public void unplug(long batteryUptime, long batteryRealtime) { + mUnpluggedWakeups = mWakeups; + } + + public void plug(long batteryUptime, long batteryRealtime) { + } + void readFromParcelLocked(Parcel in) { mWakeups = in.readInt(); mLoadedWakeups = in.readInt(); mLastWakeups = in.readInt(); + mUnpluggedWakeups = in.readInt(); int numServs = in.readInt(); mServiceStats.clear(); @@ -861,6 +929,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { out.writeInt(mWakeups); out.writeInt(mLoadedWakeups); out.writeInt(mLastWakeups); + out.writeInt(mUnpluggedWakeups); out.writeInt(mServiceStats.size()); for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) { @@ -885,6 +954,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { val = mWakeups; if (which == STATS_CURRENT) { val -= mLoadedWakeups; + } else if (which == STATS_UNPLUGGED) { + val -= mUnpluggedWakeups; } } @@ -894,9 +965,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { /** * The statistics associated with a particular service. */ - public final class Serv extends BatteryStats.Uid.Pkg.Serv { + public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable { /** - * Total time (ms) the service has been left started. + * Total time (ms in battery uptime) the service has been left started. */ long mStartTime; @@ -917,13 +988,13 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { int mStarts; /** - * Total time (ms) the service has been left launched. + * Total time (ms in battery uptime) the service has been left launched. */ long mLaunchedTime; /** * If service has been launched and not yet exited, this is - * when it was launched. + * when it was launched (ms in battery uptime). */ long mLaunchedSince; @@ -938,7 +1009,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { int mLaunches; /** - * The amount of time spent started loaded from a previous save. + * The amount of time spent started loaded from a previous save + * (ms in battery uptime). */ long mLoadedStartTime; @@ -953,7 +1025,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { int mLoadedLaunches; /** - * The amount of time spent started as of the last run. + * The amount of time spent started as of the last run (ms + * in battery uptime). */ long mLastStartTime; @@ -967,6 +1040,35 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { */ int mLastLaunches; + /** + * The amount of time spent started when last unplugged (ms + * in battery uptime). + */ + long mUnpluggedStartTime; + + /** + * The number of starts when last unplugged. + */ + int mUnpluggedStarts; + + /** + * The number of launches when last unplugged. + */ + int mUnpluggedLaunches; + + Serv() { + mUnpluggables.add(this); + } + + public void unplug(long batteryUptime, long batteryRealtime) { + mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime); + mUnpluggedStarts = mStarts; + mUnpluggedLaunches = mLaunches; + } + + public void plug(long batteryUptime, long batteryRealtime) { + } + void readFromParcelLocked(Parcel in) { mStartTime = in.readLong(); mRunningSince = in.readLong(); @@ -982,6 +1084,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { mLastStartTime = in.readLong(); mLastStarts = in.readInt(); mLastLaunches = in.readInt(); + mUnpluggedStartTime = in.readLong(); + mUnpluggedStarts = in.readInt(); + mUnpluggedLaunches = in.readInt(); } void writeToParcelLocked(Parcel out) { @@ -999,6 +1104,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { out.writeLong(mLastStartTime); out.writeInt(mLastStarts); out.writeInt(mLastLaunches); + out.writeLong(mUnpluggedStartTime); + out.writeInt(mUnpluggedStarts); + out.writeInt(mUnpluggedLaunches); } long getLaunchTimeToNowLocked(long batteryUptime) { @@ -1065,6 +1173,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { val = mLaunches; if (which == STATS_CURRENT) { val -= mLoadedLaunches; + } else if (which == STATS_UNPLUGGED) { + val -= mUnpluggedLaunches; } } @@ -1080,6 +1190,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { val = getStartTimeToNowLocked(now); if (which == STATS_CURRENT) { val -= mLoadedStartTime; + } else if (which == STATS_UNPLUGGED) { + val -= mUnpluggedStartTime; } } @@ -1095,6 +1207,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { val = mStarts; if (which == STATS_CURRENT) { val -= mLoadedStarts; + } else if (which == STATS_UNPLUGGED) { + val -= mUnpluggedStarts; } } @@ -1167,24 +1281,24 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { Timer t = null; switch (type) { case WAKE_TYPE_PARTIAL: - t = wl.wakeTimePartial; + t = wl.mTimerPartial; if (t == null) { - t = new Timer(WAKE_TYPE_PARTIAL, mPartialTimers); - wl.wakeTimePartial = t; + t = new Timer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables); + wl.mTimerPartial = t; } return t; case WAKE_TYPE_FULL: - t = wl.wakeTimeFull; + t = wl.mTimerFull; if (t == null) { - t = new Timer(WAKE_TYPE_FULL, mFullTimers); - wl.wakeTimeFull = t; + t = new Timer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables); + wl.mTimerFull = t; } return t; case WAKE_TYPE_WINDOW: - t = wl.wakeTimeWindow; + t = wl.mTimerWindow; if (t == null) { - t = new Timer(WAKE_TYPE_WINDOW, mWindowTimers); - wl.wakeTimeWindow = t; + t = new Timer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables); + wl.mTimerWindow = t; } return t; default: @@ -1192,21 +1306,26 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { } } - public Timer getSensorTimerLocked(String name, int sensor, boolean create) { - Integer sId = Integer.valueOf(sensor); - Sensor se = mSensorStats.get(sId); + public Timer getSensorTimerLocked(int sensor, boolean create) { + Sensor se = mSensorStats.get(sensor); if (se == null) { if (!create) { return null; } - se = new Sensor(name); - mSensorStats.put(sId, se); + se = new Sensor(sensor); + mSensorStats.put(sensor, se); } - Timer t = se.sensorTime; - if (t == null) { - t = new Timer(BatteryStats.SENSOR, mSensorTimers); - se.sensorTime = t; + Timer t = se.mTimer; + if (t != null) { + return t; } + ArrayList<Timer> timers = mSensorTimers.get(sensor); + if (timers == null) { + timers = new ArrayList<Timer>(); + mSensorTimers.put(sensor, timers); + } + t = new Timer(BatteryStats.SENSOR, timers, mUnpluggables); + se.mTimer = t; return t; } @@ -1224,30 +1343,30 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { } } - public void noteStartSensor(String name, int sensor) { - Timer t = getSensorTimerLocked(name, sensor, true); + public void noteStartSensor(int sensor) { + Timer t = getSensorTimerLocked(sensor, true); if (t != null) { t.startRunningLocked(BatteryStatsImpl.this); } } - public void noteStopSensor(String name, int sensor) { + public void noteStopSensor(int sensor) { // Don't create a timer if one doesn't already exist - Timer t = getSensorTimerLocked(name, sensor, false); + Timer t = getSensorTimerLocked(sensor, false); if (t != null) { t.stopRunningLocked(BatteryStatsImpl.this); } } public void noteStartGps() { - Timer t = getSensorTimerLocked("GPS", Sensor.GPS, true); + Timer t = getSensorTimerLocked(Sensor.GPS, true); if (t != null) { t.startRunningLocked(BatteryStatsImpl.this); } } public void noteStopGps() { - Timer t = getSensorTimerLocked("GPS", Sensor.GPS, false); + Timer t = getSensorTimerLocked(Sensor.GPS, false); if (t != null) { t.stopRunningLocked(BatteryStatsImpl.this); } @@ -1262,12 +1381,11 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { mFile = new File(filename); mBackupFile = new File(filename + ".bak"); mStartCount++; - mOnBattery = true; + mOnBattery = mOnBatteryInternal = false; mTrackBatteryPastUptime = 0; mTrackBatteryPastRealtime = 0; mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000; mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000; - mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart); mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart); } @@ -1290,25 +1408,25 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { synchronized(this) { if (mOnBattery != onBattery) { if (mScreenOn) { - updateScreenOnTime(true); + updateScreenOnTimeLocked(true); } + mOnBattery = mOnBatteryInternal = onBattery; + long uptime = SystemClock.uptimeMillis() * 1000; long mSecRealtime = SystemClock.elapsedRealtime(); long realtime = mSecRealtime * 1000; if (onBattery) { - mTrackBatteryUptimeStart = getBatteryUptime(uptime); - mTrackBatteryRealtimeStart = getBatteryRealtime(realtime); - unplugTcpCounters(); - unplugTimers(); - - mUnpluggedBatteryUptime = getBatteryUptime(uptime); - mUnpluggedBatteryRealtime = getBatteryRealtime(realtime); + mTrackBatteryUptimeStart = uptime; + mTrackBatteryRealtimeStart = realtime; + mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime); + mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime); + doUnplug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime); } else { mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart; mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart; + doPlug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime); } - mOnBattery = onBattery; if ((mLastWriteTime + (60 * 1000)) < mSecRealtime) { if (mFile != null) { writeLocked(); @@ -1359,7 +1477,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { case STATS_CURRENT: return uptime; case STATS_UNPLUGGED: - return uptime - mUnpluggedBatteryUptime; + return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime; } return 0; } @@ -1381,7 +1499,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { long getBatteryUptimeLocked(long curTime) { long time = mTrackBatteryPastUptime; - if (mOnBattery) { + if (mOnBatteryInternal) { time += curTime - mTrackBatteryUptimeStart; } return time; @@ -1398,7 +1516,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { long getBatteryRealtimeLocked(long curTime) { long time = mTrackBatteryPastRealtime; - if (mOnBattery) { + if (mOnBatteryInternal) { time += curTime - mTrackBatteryRealtimeStart; } return time; @@ -1554,8 +1672,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { private void readSummaryFromParcel(Parcel in) { final int version = in.readInt(); if (version != VERSION) { - Log.e("BatteryStats", "readFromParcel: version got " + version - + ", expected " + VERSION); + Log.w("BatteryStats", "readFromParcel: version got " + version + + ", expected " + VERSION + "; erasing old stats"); return; } @@ -1570,11 +1688,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { mLastRealtime = in.readLong(); mStartCount++; - if (version >= 14) { - mBatteryScreenOnTimeMillis = in.readLong(); - mPluggedScreenOnTimeMillis = in.readLong(); - mScreenOn = false; - } + mBatteryScreenOnTimeMillis = in.readLong(); + mPluggedScreenOnTimeMillis = in.readLong(); + mScreenOn = false; final int NU = in.readInt(); for (int iu = 0; iu < NU; iu++) { @@ -1596,22 +1712,16 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { } } - if (version >= 12) { - int NSE = in.readInt(); - for (int is = 0; is < NSE; is++) { - int seNumber = in.readInt(); - String seName = "<unknown>"; - if (version >= 14) { - seName = in.readString(); - } - if (in.readInt() != 0) { - u.getSensorTimerLocked(seName, seNumber, true) - .readSummaryFromParcelLocked(in); - } + int NP = in.readInt(); + for (int is = 0; is < NP; is++) { + int seNumber = in.readInt(); + if (in.readInt() != 0) { + u.getSensorTimerLocked(seNumber, true) + .readSummaryFromParcelLocked(in); } } - int NP = in.readInt(); + NP = in.readInt(); for (int ip = 0; ip < NP; ip++) { String procName = in.readString(); Uid.Proc p = u.getProcessStatsLocked(procName); @@ -1642,10 +1752,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { } } - if (version >= 14) { - u.mLoadedTcpBytesReceived = in.readLong(); - u.mLoadedTcpBytesSent = in.readLong(); - } + u.mLoadedTcpBytesReceived = in.readLong(); + u.mLoadedTcpBytesSent = in.readLong(); } } @@ -1685,24 +1793,24 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { out.writeInt(NW); if (NW > 0) { for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent - : u.mWakelockStats.entrySet()) { + : u.mWakelockStats.entrySet()) { out.writeString(ent.getKey()); Uid.Wakelock wl = ent.getValue(); - if (wl.wakeTimeFull != null) { + if (wl.mTimerFull != null) { out.writeInt(1); - wl.wakeTimeFull.writeSummaryFromParcelLocked(out, NOW); + wl.mTimerFull.writeSummaryFromParcelLocked(out, NOW); } else { out.writeInt(0); } - if (wl.wakeTimePartial != null) { + if (wl.mTimerPartial != null) { out.writeInt(1); - wl.wakeTimePartial.writeSummaryFromParcelLocked(out, NOW); + wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOW); } else { out.writeInt(0); } - if (wl.wakeTimeWindow != null) { + if (wl.mTimerWindow != null) { out.writeInt(1); - wl.wakeTimeWindow.writeSummaryFromParcelLocked(out, NOW); + wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOW); } else { out.writeInt(0); } @@ -1713,13 +1821,12 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { out.writeInt(NSE); if (NSE > 0) { for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent - : u.mSensorStats.entrySet()) { + : u.mSensorStats.entrySet()) { out.writeInt(ent.getKey()); Uid.Sensor se = ent.getValue(); - out.writeString(se.getName()); - if (se.sensorTime != null) { + if (se.mTimer != null) { out.writeInt(1); - se.sensorTime.writeSummaryFromParcelLocked(out, NOW); + se.mTimer.writeSummaryFromParcelLocked(out, NOW); } else { out.writeInt(0); } @@ -1800,6 +1907,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { mRealtimeStart = in.readLong(); mLastRealtime = in.readLong(); mOnBattery = in.readInt() != 0; + mOnBatteryInternal = false; // we are no longer really running. mTrackBatteryPastUptime = in.readLong(); mTrackBatteryUptimeStart = in.readLong(); mTrackBatteryPastRealtime = in.readLong(); @@ -1815,7 +1923,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { for (int i = 0; i < numUids; i++) { int uid = in.readInt(); Uid u = new Uid(uid); - u.readFromParcelLocked(in); + u.readFromParcelLocked(mUnpluggables, in); mUidStats.append(uid, u); } } @@ -1826,6 +1934,11 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { @SuppressWarnings("unused") void writeToParcelLocked(Parcel out, int flags) { + final long uSecUptime = SystemClock.uptimeMillis() * 1000; + final long uSecRealtime = SystemClock.elapsedRealtime() * 1000; + final long batteryUptime = getBatteryUptimeLocked(uSecUptime); + final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime); + out.writeInt(MAGIC); out.writeInt(mStartCount); out.writeLong(mBatteryUptime); @@ -1853,7 +1966,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable { out.writeInt(mUidStats.keyAt(i)); Uid uid = mUidStats.valueAt(i); - uid.writeToParcelLocked(out); + uid.writeToParcelLocked(out, batteryRealtime); } } diff --git a/core/java/com/android/internal/os/HandlerHelper.java b/core/java/com/android/internal/os/HandlerHelper.java deleted file mode 100644 index d810e6b..0000000 --- a/core/java/com/android/internal/os/HandlerHelper.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.os; - -import android.os.Handler; -import android.os.HandlerInterface; -import android.os.Message; - -/** @hide */ -public class HandlerHelper extends Handler -{ - public HandlerHelper(HandlerInterface target) - { - mTarget = target; - } - - public void handleMessage(Message msg) - { - mTarget.handleMessage(msg); - } - - private HandlerInterface mTarget; -} - diff --git a/core/java/com/android/internal/os/HandlerThread.java b/core/java/com/android/internal/os/HandlerThread.java deleted file mode 100644 index 1de6bfd..0000000 --- a/core/java/com/android/internal/os/HandlerThread.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.os; - -import android.os.Handler; -import android.os.HandlerInterface; -import android.os.Looper; - -/** - * Handy class for starting a new thread containing a Handler - * @hide - * @deprecated - */ -public class HandlerThread extends Thread -{ - Runnable mSetup; - HandlerInterface mhi; - Handler mh; - Throwable mtr; - final Object mMonitor = new Object(); - - public - HandlerThread(HandlerInterface h, Runnable setup, String name) - { - super(name); - - mhi = h; - mSetup = setup; - - synchronized (mMonitor) { - start(); - while (mh == null && mtr == null) { - try { - mMonitor.wait(); - } catch (InterruptedException ex) { - } - } - } - - if (mtr != null) { - throw new RuntimeException("exception while starting", mtr); - } - } - - @Override - public void - run() - { - synchronized(mMonitor) { - try { - Looper.prepare(); - mh = new HandlerHelper (mhi); - - if (mSetup != null) { - mSetup.run(); - mSetup = null; - } - } catch (RuntimeException exc) { - mtr = exc; - } - - mMonitor.notify(); - } - - if (mtr == null) { - Looper.loop(); - } - } - - public Handler - getHandler() - { - return mh; - } - -} - diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java index ac72a20..4f98cee 100644 --- a/core/java/com/android/internal/view/IInputConnectionWrapper.java +++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java @@ -1,7 +1,5 @@ package com.android.internal.view; -import com.android.internal.view.IInputContext; - import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -324,7 +322,7 @@ public class IInputConnectionWrapper extends IInputContext.Stub { Log.w(TAG, "showStatusIcon on inactive InputConnection"); return; } - ic.reportFullscreenMode(msg.arg1 != 1); + ic.reportFullscreenMode(msg.arg1 == 1); return; } case DO_PERFORM_PRIVATE_COMMAND: { diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java index 648d944..44cf0ed 100644 --- a/core/java/com/android/internal/widget/EditableInputConnection.java +++ b/core/java/com/android/internal/widget/EditableInputConnection.java @@ -96,4 +96,21 @@ public class EditableInputConnection extends BaseInputConnection { mTextView.onPrivateIMECommand(action, data); return true; } + + @Override + public boolean commitText(CharSequence text, int newCursorPosition) { + if (mTextView == null) { + return super.commitText(text, newCursorPosition); + } + + CharSequence errorBefore = mTextView.getError(); + boolean success = super.commitText(text, newCursorPosition); + CharSequence errorAfter = mTextView.getError(); + + if (errorAfter != null && errorBefore == errorAfter) { + mTextView.setError(null, null); + } + + return success; + } } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index ed1cd58..c8b3ad4 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -77,11 +77,10 @@ public class LockPatternUtils { public static final int MIN_PATTERN_REGISTER_FAIL = 3; private final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently"; + private final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline"; private final ContentResolver mContentResolver; - private long mLockoutDeadline = 0; - private static String sLockPatternFilename; /** @@ -270,12 +269,14 @@ public class LockPatternUtils { } /** - * Store the lockout deadline, meaning the user can't attempt his/her unlock - * pattern until the deadline has passed. Does not persist across reboots. - * @param deadline The elapsed real time in millis in future. + * Set and store the lockout deadline, meaning the user can't attempt his/her unlock + * pattern until the deadline has passed. + * @return the chosen deadline. */ - public void setLockoutAttemptDeadline(long deadline) { - mLockoutDeadline = deadline; + public long setLockoutAttemptDeadline() { + final long deadline = SystemClock.elapsedRealtime() + FAILED_ATTEMPT_TIMEOUT_MS; + setLong(LOCKOUT_ATTEMPT_DEADLINE, deadline); + return deadline; } /** @@ -284,7 +285,12 @@ public class LockPatternUtils { * enter a pattern. */ public long getLockoutAttemptDeadline() { - return (mLockoutDeadline <= SystemClock.elapsedRealtime()) ? 0 : mLockoutDeadline; + final long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L); + final long now = SystemClock.elapsedRealtime(); + if (deadline < now || deadline > (now + FAILED_ATTEMPT_TIMEOUT_MS)) { + return 0L; + } + return deadline; } /** @@ -341,5 +347,13 @@ public class LockPatternUtils { enabled ? 1 : 0); } + private long getLong(String systemSettingKey, long def) { + return android.provider.Settings.System.getLong(mContentResolver, systemSettingKey, def); + } + + private void setLong(String systemSettingKey, long value) { + android.provider.Settings.System.putLong(mContentResolver, systemSettingKey, value); + } + } diff --git a/core/java/com/android/internal/widget/TextProgressBar.java b/core/java/com/android/internal/widget/TextProgressBar.java new file mode 100644 index 0000000..d068865 --- /dev/null +++ b/core/java/com/android/internal/widget/TextProgressBar.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.widget; + +import android.content.Context; +import android.os.SystemClock; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Chronometer; +import android.widget.Chronometer.OnChronometerTickListener; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.RemoteViews.RemoteView; + +/** + * Container that links together a {@link ProgressBar} and {@link Chronometer} + * as children. It subscribes to {@link Chronometer#OnChronometerTickListener} + * and updates the {@link ProgressBar} based on a preset finishing time. + * <p> + * This widget expects to contain two children with specific ids + * {@link android.R.id.progress} and {@link android.R.id.text1}. + * <p> + * If the {@link Chronometer} {@link android.R.attr#layout_width} is + * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}, then the + * {@link android.R.attr#gravity} will be used to automatically move it with + * respect to the {@link ProgressBar} position. For example, if + * {@link android.view.Gravity#LEFT} then the {@link Chronometer} will be placed + * just ahead of the leading edge of the {@link ProgressBar} position. + */ +@RemoteView +public class TextProgressBar extends RelativeLayout implements OnChronometerTickListener { + public static final String TAG = "TextProgressBar"; + + static final int CHRONOMETER_ID = android.R.id.text1; + static final int PROGRESSBAR_ID = android.R.id.progress; + + Chronometer mChronometer = null; + ProgressBar mProgressBar = null; + + long mDurationBase = -1; + int mDuration = -1; + + boolean mChronometerFollow = false; + int mChronometerGravity = Gravity.NO_GRAVITY; + + public TextProgressBar(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public TextProgressBar(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public TextProgressBar(Context context) { + super(context); + } + + /** + * Catch any interesting children when they are added. + */ + @Override + public void addView(View child, int index, ViewGroup.LayoutParams params) { + super.addView(child, index, params); + + int childId = child.getId(); + if (childId == CHRONOMETER_ID && child instanceof Chronometer) { + mChronometer = (Chronometer) child; + mChronometer.setOnChronometerTickListener(this); + + // Check if Chronometer should move with with ProgressBar + mChronometerFollow = (params.width == ViewGroup.LayoutParams.WRAP_CONTENT); + mChronometerGravity = (mChronometer.getGravity() & Gravity.HORIZONTAL_GRAVITY_MASK); + + } else if (childId == PROGRESSBAR_ID && child instanceof ProgressBar) { + mProgressBar = (ProgressBar) child; + } + } + + /** + * Set the expected termination time of the running {@link Chronometer}. + * This value is used to adjust the {@link ProgressBar} against the elapsed + * time. + * <p> + * Call this <b>after</b> adjusting the {@link Chronometer} base, if + * necessary. + * + * @param durationBase Use the {@link SystemClock#elapsedRealtime} time + * base. + */ + public void setDurationBase(long durationBase) { + mDurationBase = durationBase; + + if (mProgressBar == null || mChronometer == null) { + throw new RuntimeException("Expecting child ProgressBar with id " + + "'android.R.id.progress' and Chronometer id 'android.R.id.text1'"); + } + + // Update the ProgressBar maximum relative to Chronometer base + mDuration = (int) (durationBase - mChronometer.getBase()); + mProgressBar.setMax(mDuration); + + } + + /** + * Callback when {@link Chronometer} changes, indicating that we should + * update the {@link ProgressBar} and change the layout if necessary. + */ + public void onChronometerTick(Chronometer chronometer) { + if (mProgressBar == null) { + throw new RuntimeException( + "Expecting child ProgressBar with id 'android.R.id.progress'"); + } + + // Stop Chronometer if we're past duration + long now = SystemClock.elapsedRealtime(); + if (now >= mDurationBase) { + mChronometer.stop(); + } + + // Update the ProgressBar status + int remaining = (int) (mDurationBase - now); + mProgressBar.setProgress(mDuration - remaining); + + // Move the Chronometer if gravity is set correctly + if (mChronometerFollow) { + RelativeLayout.LayoutParams params; + + // Calculate estimate of ProgressBar leading edge position + params = (RelativeLayout.LayoutParams) mProgressBar.getLayoutParams(); + int contentWidth = mProgressBar.getWidth() - (params.leftMargin + params.rightMargin); + int leadingEdge = ((contentWidth * mProgressBar.getProgress()) / + mProgressBar.getMax()) + params.leftMargin; + + // Calculate any adjustment based on gravity + int adjustLeft = 0; + int textWidth = mChronometer.getWidth(); + if (mChronometerGravity == Gravity.RIGHT) { + adjustLeft = -textWidth; + } else if (mChronometerGravity == Gravity.CENTER_HORIZONTAL) { + adjustLeft = -(textWidth / 2); + } + + // Limit margin to keep text inside ProgressBar bounds + leadingEdge += adjustLeft; + int rightLimit = contentWidth - params.rightMargin - textWidth; + if (leadingEdge < params.leftMargin) { + leadingEdge = params.leftMargin; + } else if (leadingEdge > rightLimit) { + leadingEdge = rightLimit; + } + + params = (RelativeLayout.LayoutParams) mChronometer.getLayoutParams(); + params.leftMargin = leadingEdge; + + // Request layout to move Chronometer + mChronometer.requestLayout(); + + } + } +} diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index 79965b9..2f1f9b8 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -51,9 +51,9 @@ struct fields_t { static fields_t fields; static Mutex sLock; +static jclass sCameraClass; struct callback_cookie { - jclass camera_class; jobject camera_ref; }; @@ -87,7 +87,7 @@ static void err_callback(status_t err, void *cookie) } LOGV("err_callback: camera_ref=%x, cookie=%x", (int)c->camera_ref, (int)cookie); - env->CallStaticVoidMethod(c->camera_class, fields.post_event, + env->CallStaticVoidMethod(sCameraClass, fields.post_event, c->camera_ref, kErrorCallback, error, 0, NULL); } @@ -115,7 +115,6 @@ static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobj jniThrowException(env, "java/lang/Exception", NULL); return; } - cookie->camera_class = (jclass)env->NewGlobalRef(clazz); // We use a weak reference so the Camera object can be garbage collected. // The reference is only used as a proxy for callbacks. @@ -157,7 +156,6 @@ static void android_hardware_Camera_release(JNIEnv *env, jobject thiz) if (cookie) { env->DeleteGlobalRef(cookie->camera_ref); - env->DeleteGlobalRef(cookie->camera_class); delete cookie; env->SetIntField(thiz, fields.listener_context, 0); } @@ -207,7 +205,7 @@ static void preview_callback(const sp<IMemory>& mem, void *cookie) obj = array; - env->CallStaticVoidMethod(c->camera_class, fields.post_event, + env->CallStaticVoidMethod(sCameraClass, fields.post_event, c->camera_ref, kPreviewCallback, arg1, arg2, obj); env->DeleteLocalRef(array); } @@ -270,13 +268,11 @@ static void autofocus_callback_impl(bool success, void *cookie) return; } callback_cookie *c = (callback_cookie *)cookie; - env->CallStaticVoidMethod(c->camera_class, fields.post_event, + env->CallStaticVoidMethod(sCameraClass, fields.post_event, c->camera_ref, kAutoFocusCallback, success, 0, NULL); } - - static void android_hardware_Camera_autoFocus(JNIEnv *env, jobject thiz) { sp<Camera> c = get_native_camera(env, thiz); @@ -301,7 +297,7 @@ static void jpeg_callback(const sp<IMemory>& mem, void *cookie) jobject obj = NULL; if (mem == NULL) { - env->CallStaticVoidMethod(c->camera_class, fields.post_event, + env->CallStaticVoidMethod(sCameraClass, fields.post_event, c->camera_ref, kJpegCallback, arg1, arg2, NULL); return; } @@ -331,7 +327,7 @@ static void jpeg_callback(const sp<IMemory>& mem, void *cookie) obj = array; - env->CallStaticVoidMethod(c->camera_class, fields.post_event, + env->CallStaticVoidMethod(sCameraClass, fields.post_event, c->camera_ref, kJpegCallback, arg1, arg2, obj); env->DeleteLocalRef(array); } @@ -344,7 +340,7 @@ static void shutter_callback_impl(void *cookie) return; } callback_cookie *c = (callback_cookie *)cookie; - env->CallStaticVoidMethod(c->camera_class, fields.post_event, + env->CallStaticVoidMethod(sCameraClass, fields.post_event, c->camera_ref, kShutterCallback, 0, 0, NULL); } @@ -357,7 +353,7 @@ static void raw_callback(const sp<IMemory>& mem __attribute__((unused)), return; } callback_cookie *c = (callback_cookie *)cookie; - env->CallStaticVoidMethod(c->camera_class, fields.post_event, + env->CallStaticVoidMethod(sCameraClass, fields.post_event, c->camera_ref, kRawCallback, 0, 0, NULL); } @@ -524,6 +520,7 @@ int register_android_hardware_Camera(JNIEnv *env) return -1; jclass clazz = env->FindClass("android/hardware/Camera"); + sCameraClass = (jclass)env->NewGlobalRef(clazz); fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V"); if (fields.post_event == NULL) { diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index 6ca821d..d9effee 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 #define LOG_TAG "AudioTrack-JNI" @@ -164,8 +164,8 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th jint streamType, jint sampleRateInHertz, jint nbChannels, jint audioFormat, jint buffSizeInBytes, jint memoryMode) { - //LOGV("sampleRate=%d, audioFormat(from Java)=%d, nbChannels=%d, buffSize=%d", - // sampleRateInHertz, audioFormat, nbChannels, buffSizeInBytes); + LOGV("sampleRate=%d, audioFormat(from Java)=%d, nbChannels=%d, buffSize=%d", + sampleRateInHertz, audioFormat, nbChannels, buffSizeInBytes); int afSampleRate; int afFrameCount; @@ -210,7 +210,20 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th LOGE("Error creating AudioTrack: unsupported audio format."); return AUDIOTRACK_ERROR_SETUP_INVALIDFORMAT; } - + + // for the moment 8bitPCM in MODE_STATIC is not supported natively in the AudioTrack C++ class + // so we declare everything as 16bitPCM, the 8->16bit conversion for MODE_STATIC will be handled + // in android_media_AudioTrack_native_write() + if ((audioFormat == javaAudioTrackFields.PCM8) + && (memoryMode == javaAudioTrackFields.MODE_STATIC)) { + LOGV("android_media_AudioTrack_native_setup(): requesting MODE_STATIC for 8bit \ + buff size of %dbytes, switching to 16bit, buff size of %dbytes", + buffSizeInBytes, 2*buffSizeInBytes); + audioFormat = javaAudioTrackFields.PCM16; + // we will need twice the memory to store the data + buffSizeInBytes *= 2; + } + // compute the frame count int bytesPerSample = audioFormat == javaAudioTrackFields.PCM16 ? 2 : 1; int format = audioFormat == javaAudioTrackFields.PCM16 ? @@ -387,13 +400,13 @@ android_media_AudioTrack_set_volume(JNIEnv *env, jobject thiz, jfloat leftVol, j // ---------------------------------------------------------------------------- static void android_media_AudioTrack_native_finalize(JNIEnv *env, jobject thiz) { - LOGV("android_media_AudioTrack_native_finalize jobject: %x\n", (int)thiz); + //LOGV("android_media_AudioTrack_native_finalize jobject: %x\n", (int)thiz); // delete the AudioTrack object AudioTrack *lpTrack = (AudioTrack *)env->GetIntField( thiz, javaAudioTrackFields.nativeTrackInJavaObj); if (lpTrack) { - LOGV("deleting lpTrack: %x\n", (int)lpTrack); + //LOGV("deleting lpTrack: %x\n", (int)lpTrack); lpTrack->stop(); delete lpTrack; } @@ -402,7 +415,7 @@ static void android_media_AudioTrack_native_finalize(JNIEnv *env, jobject thiz) AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetIntField( thiz, javaAudioTrackFields.jniData); if (pJniStorage) { - LOGV("deleting pJniStorage: %x\n", (int)pJniStorage); + //LOGV("deleting pJniStorage: %x\n", (int)pJniStorage); delete pJniStorage; } } @@ -422,7 +435,8 @@ static void android_media_AudioTrack_native_release(JNIEnv *env, jobject thiz) // ---------------------------------------------------------------------------- static jint android_media_AudioTrack_native_write(JNIEnv *env, jobject thiz, jbyteArray javaAudioData, - jint offsetInBytes, jint sizeInBytes) { + jint offsetInBytes, jint sizeInBytes, + jint javaAudioFormat) { jbyte* cAudioData = NULL; AudioTrack *lpTrack = NULL; //LOGV("android_media_AudioTrack_native_write(offset=%d, sizeInBytes=%d) called", @@ -453,8 +467,22 @@ static jint android_media_AudioTrack_native_write(JNIEnv *env, jobject thiz, if (lpTrack->sharedBuffer() == 0) { written = lpTrack->write(cAudioData + offsetInBytes, sizeInBytes); } else { - memcpy(lpTrack->sharedBuffer()->pointer(), cAudioData + offsetInBytes, sizeInBytes); - written = sizeInBytes; + if (javaAudioFormat == javaAudioTrackFields.PCM16) { + memcpy(lpTrack->sharedBuffer()->pointer(), cAudioData + offsetInBytes, sizeInBytes); + written = sizeInBytes; + } else if (javaAudioFormat == javaAudioTrackFields.PCM8) { + // cAudioData contains 8bit data we need to expand to 16bit before copying + // to the shared memory + int count = sizeInBytes; + int16_t *dst = (int16_t *)lpTrack->sharedBuffer()->pointer(); + const int8_t *src = (const int8_t *)(cAudioData + offsetInBytes); + while(count--) { + *dst++ = (int16_t)(*src++^0x80) << 8; + } + // even though we wrote 2*sizeInBytes, we only report sizeInBytes as written to hide + // the 8bit mixer restriction from the user of this function + written = sizeInBytes; + } } env->ReleasePrimitiveArrayCritical(javaAudioData, cAudioData, 0); @@ -468,10 +496,12 @@ static jint android_media_AudioTrack_native_write(JNIEnv *env, jobject thiz, // ---------------------------------------------------------------------------- static jint android_media_AudioTrack_native_write_short(JNIEnv *env, jobject thiz, jshortArray javaAudioData, - jint offsetInShorts, jint sizeInShorts) { + jint offsetInShorts, jint sizeInShorts, + jint javaAudioFormat) { return (android_media_AudioTrack_native_write(env, thiz, (jbyteArray) javaAudioData, - offsetInShorts*2, sizeInShorts*2) + offsetInShorts*2, sizeInShorts*2, + javaAudioFormat) / 2); } @@ -676,6 +706,7 @@ static jint android_media_AudioTrack_get_output_sample_rate(JNIEnv *env, jobjec // ---------------------------------------------------------------------------- // returns the minimum required size for the successful creation of a streaming AudioTrack +// returns -1 if there was an error querying the hardware. static jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env, jobject thiz, jint sampleRateInHertz, jint nbChannels, jint audioFormat) { int afSamplingRate; @@ -715,8 +746,8 @@ static JNINativeMethod gMethods[] = { (void *)android_media_AudioTrack_native_setup}, {"native_finalize", "()V", (void *)android_media_AudioTrack_native_finalize}, {"native_release", "()V", (void *)android_media_AudioTrack_native_release}, - {"native_write_byte", "([BII)I", (void *)android_media_AudioTrack_native_write}, - {"native_write_short", "([SII)I", (void *)android_media_AudioTrack_native_write_short}, + {"native_write_byte", "([BIII)I", (void *)android_media_AudioTrack_native_write}, + {"native_write_short", "([SIII)I", (void *)android_media_AudioTrack_native_write_short}, {"native_setVolume", "(FF)V", (void *)android_media_AudioTrack_set_volume}, {"native_get_native_frame_count", "()I", (void *)android_media_AudioTrack_get_native_frame_count}, diff --git a/core/jni/android_media_JetPlayer.cpp b/core/jni/android_media_JetPlayer.cpp index fe60943..e345af6 100644 --- a/core/jni/android_media_JetPlayer.cpp +++ b/core/jni/android_media_JetPlayer.cpp @@ -81,7 +81,7 @@ android_media_JetPlayer_setup(JNIEnv *env, jobject thiz, jobject weak_this, jint maxTracks, jint trackBufferSize) { //LOGV("android_media_JetPlayer_setup(): entering."); - JetPlayer* lpJet = new JetPlayer(weak_this, maxTracks, trackBufferSize); + JetPlayer* lpJet = new JetPlayer(env->NewGlobalRef(weak_this), maxTracks, trackBufferSize); EAS_RESULT result = lpJet->init(); diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index a7a0428..a6b63d8 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -117,22 +117,25 @@ static void read_mapinfo(FILE *fp, stats_t* stats) line[--len] = 0; /* ignore guard pages */ - if (len > 18 && line[18] == '-') skip = true; + if (len > 18 && line[17] == '-') skip = true; start = strtoul(line, 0, 16); - if (strstr("[heap]", line)) { + if (strstr(line, "[heap]")) { isNativeHeap = 1; - } else if (strstr("/dalvik-LinearAlloc", line)) { + } else if (strstr(line, "/dalvik-LinearAlloc")) { isDalvikHeap = 1; - } else if (strstr("/mspace/dalvik-heap", line)) { + } else if (strstr(line, "/mspace/dalvik-heap")) { isDalvikHeap = 1; - } else if (strstr("/dalvik-heap-bitmap/", line)) { + } else if (strstr(line, "/dalvik-heap-bitmap/")) { isDalvikHeap = 1; - } else if (strstr("/tmp/sqlite-heap", line)) { + } else if (strstr(line, "/tmp/sqlite-heap")) { isSqliteHeap = 1; } + //LOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap, + // isSqliteHeap, line); + while (true) { if (fgets(line, 1024, fp) == 0) { done = true; diff --git a/core/jni/android_server_BluetoothDeviceService.cpp b/core/jni/android_server_BluetoothDeviceService.cpp index 0936310..796da15 100644 --- a/core/jni/android_server_BluetoothDeviceService.cpp +++ b/core/jni/android_server_BluetoothDeviceService.cpp @@ -515,24 +515,39 @@ static jboolean cancelBondingProcessNative(JNIEnv *env, jobject object, static jboolean removeBondingNative(JNIEnv *env, jobject object, jstring address) { LOGV(__FUNCTION__); + jboolean result = JNI_FALSE; #ifdef HAVE_BLUETOOTH native_data_t *nat = get_native_data(env, object); if (nat) { const char *c_address = env->GetStringUTFChars(address, NULL); LOGV("... address = %s", c_address); + DBusError err; + dbus_error_init(&err); DBusMessage *reply = - dbus_func_args_timeout(env, nat->conn, -1, nat->adapter, - DBUS_CLASS_NAME, "RemoveBonding", - DBUS_TYPE_STRING, &c_address, - DBUS_TYPE_INVALID); - env->ReleaseStringUTFChars(address, c_address); - if (reply) { - dbus_message_unref(reply); + dbus_func_args_error(env, nat->conn, &err, nat->adapter, + DBUS_CLASS_NAME, "RemoveBonding", + DBUS_TYPE_STRING, &c_address, + DBUS_TYPE_INVALID); + if (dbus_error_is_set(&err)) { + if (dbus_error_has_name(&err, + BLUEZ_DBUS_BASE_IFC ".Error.DoesNotExist")) { + LOGW("%s: Warning: %s (%s)", __FUNCTION__, err.message, + c_address); + result = JNI_TRUE; + } else { + LOGE("%s: D-Bus error %s (%s)", __FUNCTION__, err.name, + err.message); + } + } else { + result = JNI_TRUE; } - return JNI_TRUE; + + env->ReleaseStringUTFChars(address, c_address); + dbus_error_free(&err); + if (reply) dbus_message_unref(reply); } #endif - return JNI_FALSE; + return result; } static jobjectArray listBondingsNative(JNIEnv *env, jobject object) { diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp index e5ae2ea..9100e81 100644 --- a/core/jni/android_server_BluetoothEventLoop.cpp +++ b/core/jni/android_server_BluetoothEventLoop.cpp @@ -755,17 +755,22 @@ void onCreateBondingResult(DBusMessage *msg, void *user) { // already bonded LOGV("... error = %s (%s)\n", err.name, err.message); result = BOND_RESULT_SUCCESS; + } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress")) { + // don't make the java callback + LOGV("... error = %s (%s)\n", err.name, err.message); + goto done; } else { LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message); result = BOND_RESULT_ERROR; } - dbus_error_free(&err); } env->CallVoidMethod(event_loop_nat->me, method_onCreateBondingResult, env->NewStringUTF(address), result); +done: + dbus_error_free(&err); free(user); } diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index f09bd4c..8baaa84 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -212,7 +212,9 @@ static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) dirty.top = env->GetIntField(dirtyRect, ro.t); dirty.right = env->GetIntField(dirtyRect, ro.r); dirty.bottom= env->GetIntField(dirtyRect, ro.b); - dirtyRegion.set(dirty); + if (dirty.left < dirty.right && dirty.top < dirty.bottom) { + dirtyRegion.set(dirty); + } } else { dirtyRegion.set(Rect(0x3FFF,0x3FFF)); } @@ -246,6 +248,14 @@ static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) int saveCount = nativeCanvas->save(); env->SetIntField(clazz, so.saveCount, saveCount); + if (dirtyRect) { + Rect bounds(dirtyRegion.bounds()); + env->SetIntField(dirtyRect, ro.l, bounds.left); + env->SetIntField(dirtyRect, ro.t, bounds.top); + env->SetIntField(dirtyRect, ro.r, bounds.right); + env->SetIntField(dirtyRect, ro.b, bounds.bottom); + } + return canvas; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 0e8d3fd..2c3b590 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -18,7 +18,8 @@ */ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="android" android:sharedUserId="android.uid.system"> + package="android" android:sharedUserId="android.uid.system" + android:sharedUserLabel="@string/android_system_label"> <!-- ====================================== --> <!-- Permissions for things that cost money --> @@ -946,7 +947,7 @@ <application android:process="system" android:persistent="true" android:hasCode="false" - android:label="Android System" + android:label="@string/android_system_label" android:allowClearUserData="false" android:icon="@drawable/ic_launcher_android"> <activity android:name="com.android.internal.app.ChooserActivity" diff --git a/core/res/res/drawable-land/title_bar.9.png b/core/res/res/drawable-land/title_bar.9.png Binary files differindex 63ad916..a48d967 100644 --- a/core/res/res/drawable-land/title_bar.9.png +++ b/core/res/res/drawable-land/title_bar.9.png diff --git a/core/res/res/drawable-land/title_bar_tall.png b/core/res/res/drawable-land/title_bar_tall.png Binary files differindex 670decc..16290fb 100644 --- a/core/res/res/drawable-land/title_bar_tall.png +++ b/core/res/res/drawable-land/title_bar_tall.png diff --git a/core/res/res/drawable/popup_inline_error_above.9.png b/core/res/res/drawable/popup_inline_error_above.9.png Binary files differnew file mode 100644 index 0000000..2e601d0 --- /dev/null +++ b/core/res/res/drawable/popup_inline_error_above.9.png diff --git a/core/res/res/drawable/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable/scrollbar_handle_accelerated_anim2.9.png Binary files differindex d96cb3f..85caddd 100755 --- a/core/res/res/drawable/scrollbar_handle_accelerated_anim2.9.png +++ b/core/res/res/drawable/scrollbar_handle_accelerated_anim2.9.png diff --git a/core/res/res/drawable/sym_action_call.png b/core/res/res/drawable/sym_action_call.png Binary files differindex bcd9010..a442758 100644 --- a/core/res/res/drawable/sym_action_call.png +++ b/core/res/res/drawable/sym_action_call.png diff --git a/core/res/res/drawable/sym_action_chat.png b/core/res/res/drawable/sym_action_chat.png Binary files differindex 625e0e8..9f6419e 100644 --- a/core/res/res/drawable/sym_action_chat.png +++ b/core/res/res/drawable/sym_action_chat.png diff --git a/core/res/res/drawable/sym_action_email.png b/core/res/res/drawable/sym_action_email.png Binary files differindex 5f79e92..5fea417 100644 --- a/core/res/res/drawable/sym_action_email.png +++ b/core/res/res/drawable/sym_action_email.png diff --git a/core/res/res/drawable/sym_action_map.png b/core/res/res/drawable/sym_action_map.png Binary files differdeleted file mode 100644 index b45b7a8..0000000 --- a/core/res/res/drawable/sym_action_map.png +++ /dev/null diff --git a/core/res/res/drawable/sym_action_sms.png b/core/res/res/drawable/sym_action_sms.png Binary files differdeleted file mode 100644 index 50ce0ea..0000000 --- a/core/res/res/drawable/sym_action_sms.png +++ /dev/null diff --git a/core/res/res/drawable/title_bar.9.png b/core/res/res/drawable/title_bar.9.png Binary files differindex 44c3179..482d82e 100644 --- a/core/res/res/drawable/title_bar.9.png +++ b/core/res/res/drawable/title_bar.9.png diff --git a/core/res/res/drawable/title_bar_tall.png b/core/res/res/drawable/title_bar_tall.png Binary files differindex 09f5447..cd565dc 100644 --- a/core/res/res/drawable/title_bar_tall.png +++ b/core/res/res/drawable/title_bar_tall.png diff --git a/core/res/res/drawable/zoom_ring_overview_tab.9.png b/core/res/res/drawable/zoom_ring_overview_tab.9.png Binary files differnew file mode 100644 index 0000000..4056f73 --- /dev/null +++ b/core/res/res/drawable/zoom_ring_overview_tab.9.png diff --git a/core/res/res/drawable/zoom_ring_thumb.png b/core/res/res/drawable/zoom_ring_thumb.png Binary files differindex 4cc5f6f..1002724 100644 --- a/core/res/res/drawable/zoom_ring_thumb.png +++ b/core/res/res/drawable/zoom_ring_thumb.png diff --git a/core/res/res/drawable/zoom_ring_thumb_minus_arrow.png b/core/res/res/drawable/zoom_ring_thumb_minus_arrow.png Binary files differnew file mode 100644 index 0000000..c7b87ef --- /dev/null +++ b/core/res/res/drawable/zoom_ring_thumb_minus_arrow.png diff --git a/core/res/res/drawable/zoom_ring_thumb_minus_arrow_rotatable.xml b/core/res/res/drawable/zoom_ring_thumb_minus_arrow_rotatable.xml new file mode 100644 index 0000000..f2d495b --- /dev/null +++ b/core/res/res/drawable/zoom_ring_thumb_minus_arrow_rotatable.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<rotate xmlns:android="http://schemas.android.com/apk/res/android" + android:pivotX="50%" + android:pivotY="50%" + android:fromDegrees="0" + android:toDegrees="360" + android:drawable="@drawable/zoom_ring_thumb_minus_arrow" /> diff --git a/core/res/res/drawable/zoom_ring_thumb_plus_arrow.png b/core/res/res/drawable/zoom_ring_thumb_plus_arrow.png Binary files differnew file mode 100644 index 0000000..0591d39 --- /dev/null +++ b/core/res/res/drawable/zoom_ring_thumb_plus_arrow.png diff --git a/core/res/res/drawable/zoom_ring_thumb_plus_arrow_rotatable.xml b/core/res/res/drawable/zoom_ring_thumb_plus_arrow_rotatable.xml new file mode 100644 index 0000000..b77eaa4 --- /dev/null +++ b/core/res/res/drawable/zoom_ring_thumb_plus_arrow_rotatable.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<rotate xmlns:android="http://schemas.android.com/apk/res/android" + android:pivotX="50%" + android:pivotY="50%" + android:fromDegrees="0" + android:toDegrees="360" + android:drawable="@drawable/zoom_ring_thumb_plus_arrow" /> diff --git a/core/res/res/drawable/zoom_ring_track.png b/core/res/res/drawable/zoom_ring_track.png Binary files differindex 91d91f4..60a15b7 100644 --- a/core/res/res/drawable/zoom_ring_track.png +++ b/core/res/res/drawable/zoom_ring_track.png diff --git a/core/res/res/drawable/zoom_ring_track_absolute.png b/core/res/res/drawable/zoom_ring_track_absolute.png Binary files differnew file mode 100644 index 0000000..6b38c53 --- /dev/null +++ b/core/res/res/drawable/zoom_ring_track_absolute.png diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index e0c0a64..672c4b9 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -262,10 +262,8 @@ <string name="permdesc_reboot">"Umožňuje aplikaci vynutit restartování telefonu."</string> <string name="permlab_mount_unmount_filesystems">"připojení a odpojení souborových systémů"</string> <string name="permdesc_mount_unmount_filesystems">"Umožňuje aplikaci připojit či odpojit souborové systémy ve vyměnitelných úložištích."</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> + <string name="permlab_mount_format_filesystems">"formátovat externí úložiště"</string> + <string name="permdesc_mount_format_filesystems">"Umožňuje aplikaci formátovat vyměnitelná úložiště."</string> <string name="permlab_vibrate">"ovládání vibrací"</string> <string name="permdesc_vibrate">"Umožňuje aplikaci ovládat vibrace."</string> <string name="permlab_flashlight">"ovládání kontrolky"</string> @@ -280,10 +278,8 @@ <string name="permdesc_locationUpdates">"Umožňuje povolit či zakázat aktualizace polohy prostřednictvím bezdrátového připojení. Aplikace toto nastavení obvykle nepoužívají."</string> <string name="permlab_checkinProperties">"přístup k vlastnostem Checkin"</string> <string name="permdesc_checkinProperties">"Umožňuje čtení i zápis vlastností nahraných službou Checkin. Běžné aplikace toto nastavení obvykle nevyužívají."</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> + <string name="permlab_bindGadget">"zvolit gadgety"</string> + <string name="permdesc_bindGadget">"Umožňuje aplikaci sdělit systému, které aplikace mohou použít které gadgety. Aplikace s tímto oprávněním mohou zpřístupnit osobní údaje jiným aplikacím. Není určeno pro normální aplikace."</string> <string name="permlab_modifyPhoneState">"změny stavu telefonu"</string> <string name="permdesc_modifyPhoneState">"Umožňuje aplikaci ovládat telefonní funkce zařízení. Aplikace s tímto oprávněním může přepínat sítě nebo zapnout či vypnout bezdrátové připojení telefonu bez vašeho svolení."</string> <string name="permlab_readPhoneState">"zjistit stav telefonu"</string> @@ -312,10 +308,8 @@ <string name="permdesc_writeApnSettings">"Umožňuje aplikaci změnit nastavení APN, jako je například proxy či port APN."</string> <string name="permlab_changeNetworkState">"změna připojení k síti"</string> <string name="permdesc_changeNetworkState">"Umožňuje aplikaci změnit stav připojení k síti."</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"změnit nastavení použití dat na pozadí"</string> + <string name="permdesc_changeBackgroundDataSetting">"Umožňuje aplikaci změnit nastavení použití dat na pozadí."</string> <string name="permlab_accessWifiState">"zobrazení stavu WiFi"</string> <string name="permdesc_accessWifiState">"Umožňuje aplikaci zobrazit informace o stavu připojení WiFi."</string> <string name="permlab_changeWifiState">"Změnit stav WiFi"</string> @@ -336,14 +330,10 @@ <string name="permdesc_subscribedFeedsRead">"Umožňuje aplikaci získat podrobnosti o aktuálně synchronizovaných zdrojích."</string> <string name="permlab_subscribedFeedsWrite">"zápis odebíraných zdrojů"</string> <string name="permdesc_subscribedFeedsWrite">"Umožňuje aplikaci upravit vaše aktuálně synchronizované zdroje. To může škodlivým aplikacím umožnit změnu vašich synchronizovaných zdrojů."</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"číst slovník definovaný uživatelem"</string> + <string name="permdesc_readDictionary">"Umožní aplikaci číst soukromá slova, jména a fráze, která uživatel mohl uložit do svého slovníku."</string> + <string name="permlab_writeDictionary">"zapisovat do slovníku definovaného uživatelem"</string> + <string name="permdesc_writeDictionary">"Umožní aplikaci zapisovat nová slova do uživatelského slovníku."</string> <string-array name="phoneTypes"> <item>"Domů"</item> <item>"Mobil"</item> @@ -440,12 +430,9 @@ <string name="factorytest_not_system">"Test FACTORY_TEST lze provést pouze u balíčků nainstalovaných ve složce /system/app."</string> <string name="factorytest_no_action">"Nebyl nalezen žádný balíček umožňující test FACTORY_TEST."</string> <string name="factorytest_reboot">"Restartovat"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"Stránka <xliff:g id="TITLE">%s</xliff:g> uvádí:"</string> + <string name="js_dialog_title_default">"JavaScript"</string> + <string name="js_dialog_before_unload">"Chcete opustit tuto stránku?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Vyberte OK, chcete-li pokračovat, nebo Zrušit, chcete-li na stránce zůstat."</string> <string name="save_password_label">"Potvrdit"</string> <string name="save_password_message">"Chcete, aby si prohlížeč zapamatoval toto heslo?"</string> <string name="save_password_notnow">"Nyní ne"</string> @@ -496,22 +483,38 @@ <item quantity="one">"zítra"</item> <item quantity="other">"zbývající počet dní: <xliff:g id="COUNT">%d</xliff:g>"</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"před 1 s"</item> + <item quantity="other">"před <xliff:g id="COUNT">%d</xliff:g> s"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"před 1 min."</item> + <item quantity="other">"před <xliff:g id="COUNT">%d</xliff:g> min."</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"před 1 hodinou"</item> + <item quantity="other">"před <xliff:g id="COUNT">%d</xliff:g> hod."</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"včera"</item> + <item quantity="other">"před <xliff:g id="COUNT">%d</xliff:g> dny"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"za 1 s"</item> + <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> s"</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"za 1 min."</item> + <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> min."</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"za 1 hodinu"</item> + <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> hod."</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"zítra"</item> + <item quantity="other">"zbývající počet dní: <xliff:g id="COUNT">%d</xliff:g>"</item> + </plurals> <string name="preposition_for_date">"%s"</string> <string name="preposition_for_time">"%s"</string> <string name="preposition_for_year">"v roce %s"</string> @@ -553,17 +556,15 @@ <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_month_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"poledne"</string> <string name="Noon">"Poledne"</string> <string name="midnight">"půlnoc"</string> @@ -691,8 +692,7 @@ <string name="paste">"Vložit"</string> <string name="copyUrl">"Kopírovat adresu URL"</string> <string name="inputMethod">"Metoda zadávání dat"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"Přidat „%s“ do slovníku"</string> <string name="editTextMenuTitle">"Úpravy textu"</string> <string name="low_internal_storage_view_title">"Málo paměti"</string> <string name="low_internal_storage_view_text">"V telefonu zbývá málo místa pro ukládání dat."</string> @@ -700,8 +700,7 @@ <string name="cancel">"Zrušit"</string> <string name="yes">"OK"</string> <string name="no">"Zrušit"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"Upozornění"</string> <string name="capital_on">"ZAPNUTO"</string> <string name="capital_off">"VYPNOUT"</string> <string name="whichApplication">"Dokončit akci pomocí aplikace"</string> @@ -725,8 +724,7 @@ <string name="volume_music">"Hlasitost médií"</string> <string name="volume_music_hint_playing_through_bluetooth">"Přehrávání pomocí rozhraní Bluetooth"</string> <string name="volume_call">"Hlasitost hovoru"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"Hlasitost příchozích hovorů při připojení Bluetooth"</string> <string name="volume_alarm">"Hlasitost upozornění a budíku"</string> <string name="volume_notification">"Hlasitost oznámení"</string> <string name="volume_unknown">"Hlasitost"</string> @@ -762,60 +760,35 @@ <string name="usb_storage_error_message">"Při používání vaší karty SD jako úložiště USB došlo k problému."</string> <string name="usb_storage_notification_title">"USB připojeno"</string> <string name="usb_storage_notification_message">"Vyberte, chcete-li kopírovat soubory do nebo z počítače."</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"Vypnout úložiště USB"</string> + <string name="usb_storage_stop_notification_message">"Vyberte, chcete-li vypnout úložiště USB."</string> + <string name="usb_storage_stop_title">"Vypnout úložiště USB"</string> + <string name="usb_storage_stop_message">"Před vypnutím úložiště USB se přesvědčte, zda byl hostitel USB odpojen. Úložiště USB vypnete volbou Vypnout."</string> + <string name="usb_storage_stop_button_mount">"Vypnout"</string> + <string name="usb_storage_stop_button_unmount">"Zrušit"</string> + <string name="usb_storage_stop_error_message">"Při vypínání úložiště USB došlo k problémům. Zkontrolujte, zda byl hostitel USB odpojen, a zkuste to znovu."</string> + <string name="extmedia_format_title">"Formátovat kartu SD"</string> + <string name="extmedia_format_message">"Opravdu chcete kartu SD naformátovat? Všechna data na kartě budou ztracena."</string> + <string name="extmedia_format_button_format">"Formátovat"</string> <string name="select_input_method">"Výběr metody zadávání dat"</string> <string name="fast_scroll_alphabet">"AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"kandidáti"</u></string> + <string name="ext_media_checking_notification_title">"Příprava karty SD"</string> + <string name="ext_media_checking_notification_message">"Kontrola chyb"</string> + <string name="ext_media_nofs_notification_title">"Prázdná karta SD"</string> + <string name="ext_media_nofs_notification_message">"Karta SD je prázdná nebo používá nepodporovaný systém souborů."</string> + <string name="ext_media_unmountable_notification_title">"Poškozená karta SD"</string> + <string name="ext_media_unmountable_notification_message">"Karta SD je poškozena. Pravděpodobně ji bude nutné znovu formátovat."</string> + <string name="ext_media_badremoval_notification_title">"Karta SD byla neočekávaně odebrána"</string> + <string name="ext_media_badremoval_notification_message">"Chcete-li zabránit ztrátě dat, kartu SD před odebráním odpojte."</string> + <string name="ext_media_safe_unmount_notification_title">"Kartu SD je možné bezpečně odebrat"</string> + <string name="ext_media_safe_unmount_notification_message">"Kartu SD lze nyní bezpečně vyjmout."</string> + <string name="ext_media_nomedia_notification_title">"Karta SD byla odstraněna"</string> + <string name="ext_media_nomedia_notification_message">"Karta SD byla odebrána. Chcete-li zvětšit úložiště svého zařízení, vložte kartu SD."</string> + <string name="activity_list_empty">"Nebyly nalezeny žádné odpovídající aktivity."</string> + <string name="permlab_pkgUsageStats">"aktualizovat statistiku použití součástí"</string> + <string name="permdesc_pkgUsageStats">"Umožňuje změnu shromážděných statistických údajů o použití součástí. Není určeno pro běžné aplikace."</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index d9c4174..113c226 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -262,10 +262,8 @@ <string name="permdesc_reboot">"Ermöglicht der Anwendung, einen Neustart des Telefons zu erzwingen."</string> <string name="permlab_mount_unmount_filesystems">"Dateisysteme bereitstellen oder Bereitstellung aufheben"</string> <string name="permdesc_mount_unmount_filesystems">"Ermöglicht der Anwendung, Dateisysteme für austauschbare Speicherplätze bereitzustellen oder die Bereitstellung aufzuheben."</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> + <string name="permlab_mount_format_filesystems">"Externen Speicher formatieren"</string> + <string name="permdesc_mount_format_filesystems">"Erlaubt der Anwendung, austauschbaren Speicher zu formatieren."</string> <string name="permlab_vibrate">"Vibrationsalarm steuern"</string> <string name="permdesc_vibrate">"Ermöglicht der Anwendung, den Vibrationsalarm zu steuern."</string> <string name="permlab_flashlight">"Lichtanzeige steuern"</string> @@ -280,10 +278,8 @@ <string name="permdesc_locationUpdates">"Ermöglicht die Aktivierung/Deaktivierung der Radio-Benachrichtigungen über Standort-Updates. Nicht für normale Anwendungen vorgesehen."</string> <string name="permlab_checkinProperties">"Auf Check-In-Eigenschaften zugreifen"</string> <string name="permdesc_checkinProperties">"Ermöglicht den Schreib-/Lesezugriff auf vom Check-In-Service hochgeladene Elemente. Nicht für normale Anwendungen vorgesehen."</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> + <string name="permlab_bindGadget">"Gadgets auswählen"</string> + <string name="permdesc_bindGadget">"Bei dieser Option meldet die Anwendung dem System, welche Gadgets von welcher Anwendung verwendet werden können. Mit dieser Genehmigung können Anwendungen anderen Anwendungen Zugriff auf persönliche Daten geben. Nicht für normale Anwendungen vorgesehen."</string> <string name="permlab_modifyPhoneState">"Telefonstatus ändern"</string> <string name="permdesc_modifyPhoneState">"Ermöglicht einer Anwendung, die Telefonfunktionen des Gerätes zu steuern. Eine Anwendung mit dieser Berechtigung kann unter anderem das Netzwerk wechseln oder das Radio des Telefons ein- und ausschalten, ohne Sie darüber zu informieren."</string> <string name="permlab_readPhoneState">"Telefonstatus lesen"</string> @@ -312,10 +308,8 @@ <string name="permdesc_writeApnSettings">"Ermöglicht einer Anwendung, die APN-Einstellungen wie Proxy und Port eines Zugriffspunkts zu ändern."</string> <string name="permlab_changeNetworkState">"Netzwerkkonnektivität ändern"</string> <string name="permdesc_changeNetworkState">"Ermöglicht einer Anwendung, den Status der Netzwerkkonnektivität zu ändern."</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"Einstellung zur Verwendung von Hintergrunddaten ändern"</string> + <string name="permdesc_changeBackgroundDataSetting">"Ermöglicht einer Anwendung, die Einstellung der Verwendung von Hintergrunddaten zu ändern."</string> <string name="permlab_accessWifiState">"WLAN-Status anzeigen"</string> <string name="permdesc_accessWifiState">"Ermöglicht einer Anwendung, die Informationen zum WLAN-Status einzusehen."</string> <string name="permlab_changeWifiState">"WLAN-Status ändern"</string> @@ -336,14 +330,10 @@ <string name="permdesc_subscribedFeedsRead">"Ermöglicht einer Anwendung, Details zu den zurzeit synchronisierten Feeds abzurufen."</string> <string name="permlab_subscribedFeedsWrite">"Abonnierte Feeds schreiben"</string> <string name="permdesc_subscribedFeedsWrite">"Ermöglicht einer Anwendung, Änderungen an den kürzlich synchronisierten Feeds vorzunehmen. Schädliche Anwendungen könnten so Ihre synchronisierten Feeds ändern."</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"Nutzerdefiniertes Wörterbuch lesen"</string> + <string name="permdesc_readDictionary">"Erlaubt einer Anwendung, alle privaten Wörter, Namen und Ausdrücke zu lesen, die ein Nutzer in seinem Wörterbuch gespeichert hat."</string> + <string name="permlab_writeDictionary">"in nutzerdefiniertes Wörterbuch schreiben"</string> + <string name="permdesc_writeDictionary">"Erlaubt einer Anwendung, neue Wörter in das Wörterbuch des Nutzers zu schreiben."</string> <string-array name="phoneTypes"> <item>"Privat"</item> <item>"Mobil"</item> @@ -440,12 +430,9 @@ <string name="factorytest_not_system">"Die Aktion FACTORY_TEST wird nur für unter \"/system/app\" gespeicherte Pakete unterstützt."</string> <string name="factorytest_no_action">"Es wurden kein Paket mit der Aktion FACTORY_TEST gefunden."</string> <string name="factorytest_reboot">"Neu booten"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"Die Seite auf \'<xliff:g id="TITLE">%s</xliff:g>\' sagt:"</string> + <string name="js_dialog_title_default">"JavaScript"</string> + <string name="js_dialog_before_unload">"Von dieser Seite navigieren?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Wählen Sie \"OK\", um fortzufahren, oder wählen Sie \"Abbrechen\", um auf der aktuellen Seite zu bleiben."</string> <string name="save_password_label">"Bestätigen"</string> <string name="save_password_message">"Möchten Sie, dass der Browser dieses Passwort speichert?"</string> <string name="save_password_notnow">"Nicht jetzt"</string> @@ -496,22 +483,38 @@ <item quantity="one">"morgen"</item> <item quantity="other">"in <xliff:g id="COUNT">%d</xliff:g> Tagen"</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"vor 1 Sekunde"</item> + <item quantity="other">"Vor <xliff:g id="COUNT">%d</xliff:g> Sekunden"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"vor 1 Minute"</item> + <item quantity="other">"vor <xliff:g id="COUNT">%d</xliff:g> Minuten"</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"Vor 1 Stunde"</item> + <item quantity="other">"Vor <xliff:g id="COUNT">%d</xliff:g> Stunden"</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"Gestern"</item> + <item quantity="other">"Vor <xliff:g id="COUNT">%d</xliff:g> Tagen"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"in 1 Sekunde"</item> + <item quantity="other">"in <xliff:g id="COUNT">%d</xliff:g> Sekunden"</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"in 1 Minute"</item> + <item quantity="other">"in <xliff:g id="COUNT">%d</xliff:g> Minuten"</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"in 1 Stunde"</item> + <item quantity="other">"In <xliff:g id="COUNT">%d</xliff:g> Stunden"</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"morgen"</item> + <item quantity="other">"in <xliff:g id="COUNT">%d</xliff:g> Tagen"</item> + </plurals> <string name="preposition_for_date">"am %s"</string> <string name="preposition_for_time">"am %s"</string> <string name="preposition_for_year">"in %s"</string> @@ -542,8 +545,7 @@ <string name="VideoView_error_title">"Video kann nicht wiedergegeben werden."</string> <string name="VideoView_error_text_unknown">"Dieses Video kann leider nicht abgespielt werden."</string> <string name="VideoView_error_button">"OK"</string> - <!-- no translation found for am (4885350190794996052) --> - <skip /> + <string name="am">"AM"</string> <string name="pm">".."</string> <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string> <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string> @@ -554,17 +556,15 @@ <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_month_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"Mittag"</string> <string name="Noon">"Mittag"</string> <string name="midnight">"Mitternacht"</string> @@ -692,8 +692,7 @@ <string name="paste">"Einfügen"</string> <string name="copyUrl">"URL kopieren"</string> <string name="inputMethod">"Eingabemethode"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"\"%s\" dem Wörterbuch hinzufügen"</string> <string name="editTextMenuTitle">"Text bearbeiten"</string> <string name="low_internal_storage_view_title">"Geringer Speicher"</string> <string name="low_internal_storage_view_text">"Kaum noch freier Telefonspeicher verfügbar."</string> @@ -701,8 +700,7 @@ <string name="cancel">"Abbrechen"</string> <string name="yes">"OK"</string> <string name="no">"Abbrechen"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"Achtung"</string> <string name="capital_on">"EIN"</string> <string name="capital_off">"AUS"</string> <string name="whichApplication">"Aktion beenden mit"</string> @@ -726,8 +724,7 @@ <string name="volume_music">"Medienlautstärke"</string> <string name="volume_music_hint_playing_through_bluetooth">"Wiedergabe durch Bluetooth"</string> <string name="volume_call">"Hörerlautstärke"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"Lautstärke bei eingehendem Bluetooth-Anruf"</string> <string name="volume_alarm">"Lautstärke für Alarm"</string> <string name="volume_notification">"Benachrichtigungslautstärke"</string> <string name="volume_unknown">"Lautstärke"</string> @@ -763,60 +760,35 @@ <string name="usb_storage_error_message">"Bei der Verwendung Ihrer SD-Karte als USB-Speicher ist ein Problem aufgetreten."</string> <string name="usb_storage_notification_title">"USB-Verbindung"</string> <string name="usb_storage_notification_message">"Wählen Sie die Dateien aus, die von Ihrem oder auf Ihren Computer kopiert werden sollen."</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"USB-Speicher deaktivieren"</string> + <string name="usb_storage_stop_notification_message">"Auswählen, um USB-Speicher zu deaktivieren."</string> + <string name="usb_storage_stop_title">"USB-Speicher deaktivieren"</string> + <string name="usb_storage_stop_message">"Bevor Sie den USB-Speicher deaktivieren, stellen Sie sicher, dass Sie Ihn vom USB-Host getrennt haben. Wählen Sie \"Deaktivieren\", um den USB-Speicher zu deaktivieren."</string> + <string name="usb_storage_stop_button_mount">"Ausschalten"</string> + <string name="usb_storage_stop_button_unmount">"Abbrechen"</string> + <string name="usb_storage_stop_error_message">"Wir haben beim Deaktivieren des USB-Speichers ein Problem festgestellt. Überprüfen Sie, ob Sie den USB-Host getrennt haben, und versuchen Sie es erneut."</string> + <string name="extmedia_format_title">"SD-Karte formatieren"</string> + <string name="extmedia_format_message">"Möchten Sie die SD-Karte wirklich formatieren? Alle Daten auf Ihrer Karte gehen dann verloren."</string> + <string name="extmedia_format_button_format">"Format"</string> <string name="select_input_method">"Eingabemethode auswählen"</string> <string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"Kandidaten"</u></string> + <string name="ext_media_checking_notification_title">"SD-Karte wird vorbereitet"</string> + <string name="ext_media_checking_notification_message">"Nach Fehlern wird gesucht"</string> + <string name="ext_media_nofs_notification_title">"SD-Karte leer"</string> + <string name="ext_media_nofs_notification_message">"Die SD-Karte ist leer oder verwendet ein Dateisystem, das nicht unterstützt wird."</string> + <string name="ext_media_unmountable_notification_title">"Beschädigte SD-Karte"</string> + <string name="ext_media_unmountable_notification_message">"Die SD-Karte ist beschädigt. Sie müssen Ihre Karte eventuell neu formatieren."</string> + <string name="ext_media_badremoval_notification_title">"SD-Karte unerwartet entfernt"</string> + <string name="ext_media_badremoval_notification_message">"SD-Karte vor dem Entnehmen trennen, um Datenverlust zu vermeiden."</string> + <string name="ext_media_safe_unmount_notification_title">"SD-Karte\nkann entfernt werden."</string> + <string name="ext_media_safe_unmount_notification_message">"Die SD-Karte kann jetzt entfernt werden."</string> + <string name="ext_media_nomedia_notification_title">"SD-Karte entfernt"</string> + <string name="ext_media_nomedia_notification_message">"Die SD-Karte wurde entfernt. Legen Sie eine neue SD-Karte ein, um den Speicherplatz Ihres Geräts zu erweitern."</string> + <string name="activity_list_empty">"Keine passenden Aktivitäten gefunden"</string> + <string name="permlab_pkgUsageStats">"Nutzungsstatistik der Komponente aktualisieren"</string> + <string name="permdesc_pkgUsageStats">"Ermöglicht die Änderung von gesammelten Nutzungsstatistiken der Komponente. Nicht für normale Anwendungen vorgesehen."</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index b9df983..9da879b 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -710,7 +710,7 @@ <!-- no translation found for lockscreen_glogin_invalid_input (4881057177478491580) --> <skip /> <!-- no translation found for status_bar_time_format (2168573805413119180) --> - <skip /> + <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string> <!-- no translation found for hour_minute_ampm (1850330605794978742) --> <skip /> <!-- no translation found for hour_minute_cap_ampm (1122840227537374196) --> @@ -861,34 +861,38 @@ <skip /> <!-- no translation found for pm (7206933220587555766) --> <skip /> - <!-- no translation found for numeric_date (5120078478872821100) --> + <!-- from values-de/strings.xml and removal of all the german craziyness--> <skip /> + <!-- no translation found for numeric_date (5120078478872821100) --> + <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string> <!-- no translation found for wday1_date1_time1_wday2_date2_time2 (7066878981949584861) --> - <skip /> + <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string> <!-- no translation found for wday1_date1_wday2_date2 (8671068747172261907) --> + <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string> + <!-- no translation found for numeric_date (5537215108967329745) --> <skip /> <!-- no translation found for date1_time1_date2_time2 (3645498975775629615) --> - <skip /> + <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string> <!-- no translation found for date1_date2 (377057563556488062) --> - <skip /> + <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string> <!-- no translation found for time1_time2 (3173474242109288305) --> - <skip /> + <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string> <!-- no translation found for time_wday_date (8928955562064570313) --> - <skip /> + <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <!-- no translation found for wday_date (8794741400546136975) --> - <skip /> + <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <!-- no translation found for time_date (1922644512833014496) --> - <skip /> + <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <!-- no translation found for time_wday (1422050241301754712) --> <skip /> <!-- no translation found for full_date_month_first (6011143962222283357) --> <skip /> <!-- no translation found for full_date_day_first (8621594762705478189) --> - <skip /> + <string name="full_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string> <!-- no translation found for medium_date_month_first (48990963718825728) --> <skip /> <!-- no translation found for medium_date_day_first (2898992016440387123) --> - <skip /> + <string name="medium_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string> <!-- no translation found for twelve_hour_time_format (6015557937879492156) --> <skip /> <!-- no translation found for twenty_four_hour_time_format (5176807998669709535) --> @@ -902,71 +906,73 @@ <!-- no translation found for Midnight (1260172107848123187) --> <skip /> <!-- no translation found for month_day (3356633704511426364) --> - <skip /> + <string name="month_day">"<xliff:g id="day" example="9">%-d</xliff:g> <xliff:g id="month" example="October">%B</xliff:g>"</string> <!-- no translation found for month (3017405760734206414) --> <skip /> <!-- no translation found for month_day_year (2435948225709176752) --> - <skip /> + <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string> <!-- no translation found for month_year (6228414124777343135) --> <skip /> <!-- no translation found for time_of_day (8375993139317154157) --> - <skip /> + <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string> <!-- no translation found for date_and_time (9197690194373107109) --> <skip /> <!-- no translation found for same_year_md1_md2 (9199324363135981317) --> - <skip /> + <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string> <!-- no translation found for same_year_wday1_md1_wday2_md2 (6006392413355305178) --> - <skip /> + <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string> + <!-- no translation found for date_and_time (353898423108629694) --> + <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string> <!-- no translation found for same_year_mdy1_mdy2 (1576657593937827090) --> - <skip /> + <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string> <!-- no translation found for same_year_wday1_mdy1_wday2_mdy2 (9135935796468891580) --> - <skip /> + <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string> <!-- no translation found for same_year_md1_time1_md2_time2 (2172964106375558081) --> - <skip /> + <string name="same_year_md1_time1_md2_time2">" <xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_year_wday1_md1_time1_wday2_md2_time2 (1702879534101786310) --> - <skip /> + <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_year_mdy1_time1_mdy2_time2 (2476443311723358767) --> - <skip /> + <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_year_wday1_mdy1_time1_wday2_mdy2_time2 (1564837340334069879) --> - <skip /> + <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for numeric_md1_md2 (8908376522875100300) --> - <skip /> + <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string> <!-- no translation found for numeric_wday1_md1_wday2_md2 (3239690882018292077) --> - <skip /> + <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string> <!-- no translation found for numeric_mdy1_mdy2 (8883797176939233525) --> - <skip /> + <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string> <!-- no translation found for numeric_wday1_mdy1_wday2_mdy2 (4150475769255828954) --> - <skip /> + <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string> <!-- no translation found for numeric_md1_time1_md2_time2 (3624746590607741419) --> - <skip /> + <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for numeric_wday1_md1_time1_wday2_md2_time2 (4258040955467298134) --> - <skip /> + <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for numeric_mdy1_time1_mdy2_time2 (3598215409314517987) --> - <skip /> + <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for numeric_wday1_mdy1_time1_wday2_mdy2_time2 (264076937155877259) --> - <skip /> + <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_month_md1_md2 (2393563617438036111) --> - <skip /> + <string name="same_month_md1_md2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g>"</string> <!-- no translation found for same_month_wday1_md1_wday2_md2 (1208946773794057819) --> - <skip /> + <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string> <!-- no translation found for same_month_mdy1_mdy2 (3713236637869030492) --> - <skip /> + <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g> <xliff:g id="YEAR2" example="2007">%9$s</xliff:g>"</string> <!-- no translation found for same_month_wday1_mdy1_wday2_mdy2 (389638922479870472) --> - <skip /> + <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string> <!-- no translation found for same_month_md1_time1_md2_time2 (7477075526337542685) --> - <skip /> + <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_month_wday1_md1_time1_wday2_md2_time2 (3516978303779391173) --> - <skip /> + <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_month_mdy1_time1_mdy2_time2 (7320410992514057310) --> - <skip /> + <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_month_wday1_mdy1_time1_wday2_mdy2_time2 (1332950588774239228) --> - <skip /> + <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for abbrev_month_day_year (5767271534015320250) --> - <skip /> + <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string> <!-- no translation found for abbrev_month_year (8058929633673942490) --> <skip /> <!-- no translation found for abbrev_month_day (458867920693482757) --> - <skip /> + <string name="abbrev_month_day">"<xliff:g id="day" example="31">%-d</xliff:g> <xliff:g id="month" example="Oct">%b</xliff:g>"</string> <!-- no translation found for abbrev_month (1674509986330181349) --> <skip /> <!-- no translation found for day_of_week_long_sunday (9057662850446501884) --> @@ -1112,9 +1118,9 @@ <!-- no translation found for month_shortest_december (6213739417171334040) --> <skip /> <!-- no translation found for elapsed_time_short_format_mm_ss (1294409362352514646) --> - <skip /> + <string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string> <!-- no translation found for elapsed_time_short_format_h_mm_ss (2997059666628785039) --> - <skip /> + <string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string> <!-- no translation found for selectAll (691691810023908884) --> <skip /> <!-- no translation found for cut (5845613239192595662) --> diff --git a/core/res/res/values-en-rSG/strings.xml b/core/res/res/values-en-rSG/strings.xml index b9df983..6850a5d 100644 --- a/core/res/res/values-en-rSG/strings.xml +++ b/core/res/res/values-en-rSG/strings.xml @@ -710,7 +710,7 @@ <!-- no translation found for lockscreen_glogin_invalid_input (4881057177478491580) --> <skip /> <!-- no translation found for status_bar_time_format (2168573805413119180) --> - <skip /> + <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string> <!-- no translation found for hour_minute_ampm (1850330605794978742) --> <skip /> <!-- no translation found for hour_minute_cap_ampm (1122840227537374196) --> @@ -861,34 +861,35 @@ <skip /> <!-- no translation found for pm (7206933220587555766) --> <skip /> - <!-- no translation found for numeric_date (5120078478872821100) --> - <skip /> + <!-- copied from values-de/strings.xml with the crazyness of the . removed--> <!-- no translation found for wday1_date1_time1_wday2_date2_time2 (7066878981949584861) --> - <skip /> + <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string> <!-- no translation found for wday1_date1_wday2_date2 (8671068747172261907) --> - <skip /> + <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string> + <!-- no translation found for numeric_date (5537215108967329745) --> + <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string> <!-- no translation found for date1_time1_date2_time2 (3645498975775629615) --> - <skip /> + <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string> <!-- no translation found for date1_date2 (377057563556488062) --> - <skip /> + <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string> <!-- no translation found for time1_time2 (3173474242109288305) --> - <skip /> + <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string> <!-- no translation found for time_wday_date (8928955562064570313) --> - <skip /> + <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <!-- no translation found for wday_date (8794741400546136975) --> - <skip /> + <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <!-- no translation found for time_date (1922644512833014496) --> - <skip /> + <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <!-- no translation found for time_wday (1422050241301754712) --> - <skip /> + <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> <!-- no translation found for full_date_month_first (6011143962222283357) --> <skip /> <!-- no translation found for full_date_day_first (8621594762705478189) --> - <skip /> + <string name="full_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string> <!-- no translation found for medium_date_month_first (48990963718825728) --> <skip /> <!-- no translation found for medium_date_day_first (2898992016440387123) --> - <skip /> + <string name="medium_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string> <!-- no translation found for twelve_hour_time_format (6015557937879492156) --> <skip /> <!-- no translation found for twenty_four_hour_time_format (5176807998669709535) --> @@ -902,71 +903,71 @@ <!-- no translation found for Midnight (1260172107848123187) --> <skip /> <!-- no translation found for month_day (3356633704511426364) --> - <skip /> + <string name="month_day">"<xliff:g id="day" example="9">%-d</xliff:g> <xliff:g id="month" example="October">%B</xliff:g>"</string> <!-- no translation found for month (3017405760734206414) --> <skip /> <!-- no translation found for month_day_year (2435948225709176752) --> - <skip /> + <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string> <!-- no translation found for month_year (6228414124777343135) --> <skip /> <!-- no translation found for time_of_day (8375993139317154157) --> - <skip /> + <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string> <!-- no translation found for date_and_time (9197690194373107109) --> - <skip /> + <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string> <!-- no translation found for same_year_md1_md2 (9199324363135981317) --> - <skip /> + <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string> <!-- no translation found for same_year_wday1_md1_wday2_md2 (6006392413355305178) --> - <skip /> + <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string> <!-- no translation found for same_year_mdy1_mdy2 (1576657593937827090) --> - <skip /> + <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string> <!-- no translation found for same_year_wday1_mdy1_wday2_mdy2 (9135935796468891580) --> - <skip /> + <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string> <!-- no translation found for same_year_md1_time1_md2_time2 (2172964106375558081) --> <skip /> <!-- no translation found for same_year_wday1_md1_time1_wday2_md2_time2 (1702879534101786310) --> - <skip /> + <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_year_mdy1_time1_mdy2_time2 (2476443311723358767) --> - <skip /> + <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_year_wday1_mdy1_time1_wday2_mdy2_time2 (1564837340334069879) --> - <skip /> + <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for numeric_md1_md2 (8908376522875100300) --> - <skip /> + <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string> <!-- no translation found for numeric_wday1_md1_wday2_md2 (3239690882018292077) --> - <skip /> + <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string> <!-- no translation found for numeric_mdy1_mdy2 (8883797176939233525) --> - <skip /> + <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string> <!-- no translation found for numeric_wday1_mdy1_wday2_mdy2 (4150475769255828954) --> - <skip /> + <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string> <!-- no translation found for numeric_md1_time1_md2_time2 (3624746590607741419) --> - <skip /> + <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for numeric_wday1_md1_time1_wday2_md2_time2 (4258040955467298134) --> - <skip /> + <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for numeric_mdy1_time1_mdy2_time2 (3598215409314517987) --> - <skip /> + <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for numeric_wday1_mdy1_time1_wday2_mdy2_time2 (264076937155877259) --> - <skip /> + <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_month_md1_md2 (2393563617438036111) --> - <skip /> + <string name="same_month_md1_md2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g>"</string> <!-- no translation found for same_month_wday1_md1_wday2_md2 (1208946773794057819) --> - <skip /> + <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string> <!-- no translation found for same_month_mdy1_mdy2 (3713236637869030492) --> - <skip /> + <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g> <xliff:g id="YEAR2" example="2007">%9$s</xliff:g>"</string> <!-- no translation found for same_month_wday1_mdy1_wday2_mdy2 (389638922479870472) --> - <skip /> + <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string> <!-- no translation found for same_month_md1_time1_md2_time2 (7477075526337542685) --> - <skip /> + <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_month_wday1_md1_time1_wday2_md2_time2 (3516978303779391173) --> - <skip /> + <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_month_mdy1_time1_mdy2_time2 (7320410992514057310) --> - <skip /> + <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for same_month_wday1_mdy1_time1_wday2_mdy2_time2 (1332950588774239228) --> - <skip /> + <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> <!-- no translation found for abbrev_month_day_year (5767271534015320250) --> - <skip /> + <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string> <!-- no translation found for abbrev_month_year (8058929633673942490) --> <skip /> <!-- no translation found for abbrev_month_day (458867920693482757) --> - <skip /> + <string name="abbrev_month_day">"<xliff:g id="day" example="31">%-d</xliff:g> <xliff:g id="month" example="Oct">%b</xliff:g>"</string> <!-- no translation found for abbrev_month (1674509986330181349) --> <skip /> <!-- no translation found for day_of_week_long_sunday (9057662850446501884) --> @@ -1112,9 +1113,9 @@ <!-- no translation found for month_shortest_december (6213739417171334040) --> <skip /> <!-- no translation found for elapsed_time_short_format_mm_ss (1294409362352514646) --> - <skip /> + <string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string> <!-- no translation found for elapsed_time_short_format_h_mm_ss (2997059666628785039) --> - <skip /> + <string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string> <!-- no translation found for selectAll (691691810023908884) --> <skip /> <!-- no translation found for cut (5845613239192595662) --> diff --git a/core/res/res/values-es-rES/arrays.xml b/core/res/res/values-es-rES/arrays.xml new file mode 100644 index 0000000..7f5667c --- /dev/null +++ b/core/res/res/values-es-rES/arrays.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/assets/res/any/colors.xml +** +** Copyright 2006, Google Inc. +** +** 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> + + <!-- Do not translate. --> + <integer-array name="maps_starting_lat_lng"> + <item>40413496</item> + <item>-3713379</item> + </integer-array> + <!-- Do not translate. --> + <integer-array name="maps_starting_zoom"> + <item>6</item> + </integer-array> + +</resources> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index dc17445..dc3fcd5 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -149,7 +149,7 @@ <string name="permlab_setDebugApp">"habilitar depuración de aplicación"</string> <string name="permdesc_setDebugApp">"Permite que una aplicación active la depuración de otra aplicación. Las aplicaciones malintencionadas pueden utilizar este permiso para desactivar otras aplicaciones."</string> <string name="permlab_changeConfiguration">"cambiar la configuración de la interfaz de usuario"</string> - <string name="permdesc_changeConfiguration">"Permite que una aplicación cambie la configuración actual como, por ejemplo, la configuración regional o el tamaño de fuente general."</string> + <string name="permdesc_changeConfiguration">"Permite que una aplicación cambie la configuración actual como, por ejemplo, la configuración local o el tamaño de fuente general."</string> <string name="permlab_restartPackages">"reiniciar otras aplicaciones"</string> <string name="permdesc_restartPackages">"Permite que una aplicación reinicie de forma forzosa otras aplicaciones."</string> <string name="permlab_setProcessForeground">"impedir su interrupción"</string> @@ -262,10 +262,8 @@ <string name="permdesc_reboot">"Permite que la aplicación fuerce al teléfono a reiniciarse."</string> <string name="permlab_mount_unmount_filesystems">"montar y desmontar sistemas de archivos"</string> <string name="permdesc_mount_unmount_filesystems">"Permite que las aplicaciones monten y desmonten sistemas de archivos para un almacenamiento extraíble."</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> + <string name="permlab_mount_format_filesystems">"formatear almacenamiento externo"</string> + <string name="permdesc_mount_format_filesystems">"Permite a la aplicación formatear un almacenamiento extraíble."</string> <string name="permlab_vibrate">"controlar vibración"</string> <string name="permdesc_vibrate">"Permite que la aplicación controle la función de vibración."</string> <string name="permlab_flashlight">"controlar linterna"</string> @@ -280,10 +278,8 @@ <string name="permdesc_locationUpdates">"Permite habilitar/inhabilitar las notificaciones de actualización de la ubicación de la radio. No está destinado al uso por parte de aplicaciones normales."</string> <string name="permlab_checkinProperties">"acceder a propiedades de registro"</string> <string name="permdesc_checkinProperties">"Permite el acceso de lectura/escritura a las propiedades cargadas por el servicio de registro. No está destinado al uso por parte de aplicaciones normales."</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> + <string name="permlab_bindGadget">"seleccionar gadgets"</string> + <string name="permdesc_bindGadget">"Permite a la aplicación indicar al sistema qué gadgets puede utilizar cada aplicación. Con este permiso, las aplicaciones pueden permitir a otras aplicaciones acceder a datos personales. No está destinado al uso por parte de aplicaciones normales."</string> <string name="permlab_modifyPhoneState">"modificar estado del teléfono"</string> <string name="permdesc_modifyPhoneState">"Permite que la aplicación controle las funciones de teléfono del dispositivo. Una aplicación con este permiso puede cambiar redes, activar y desactivar la radio, etc., sin necesidad de notificar al usuario."</string> <string name="permlab_readPhoneState">"leer el estado del teléfono"</string> @@ -312,10 +308,8 @@ <string name="permdesc_writeApnSettings">"Permite que una aplicación modifique los valores de configuración de un APN como, por ejemplo, el proxy y el puerto de cualquier APN."</string> <string name="permlab_changeNetworkState">"cambiar la conectividad de red"</string> <string name="permdesc_changeNetworkState">"Permite que una aplicación cambie la conectividad de red de estado."</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"cambiar configuración de uso de datos de referencia"</string> + <string name="permdesc_changeBackgroundDataSetting">"Permite a una aplicación cambiar la configuración de uso de los datos de referencia."</string> <string name="permlab_accessWifiState">"ver estado de la conectividad Wi-Fi"</string> <string name="permdesc_accessWifiState">"Permite que una aplicación vea la información sobre el estado de la conectividad Wi-Fi."</string> <string name="permlab_changeWifiState">"cambiar estado de Wi-Fi"</string> @@ -336,14 +330,10 @@ <string name="permdesc_subscribedFeedsRead">"Permite que una aplicación obtenga detalles sobre los feeds sincronizados en este momento."</string> <string name="permlab_subscribedFeedsWrite">"escribir feeds a los que está suscrito el usuario"</string> <string name="permdesc_subscribedFeedsWrite">"Permite que una aplicación modifique los feeds sincronizados actualmente. Este permiso podría provocar que una aplicación malintencionada cambie los feeds sincronizados."</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"leer diccionario definido por el usuario"</string> + <string name="permdesc_readDictionary">"Permite a una aplicación leer cualquier frase, palabra o nombre privado que el usuario haya almacenado en su diccionario."</string> + <string name="permlab_writeDictionary">"escribir en el diccionario definido por el usuario"</string> + <string name="permdesc_writeDictionary">"Permite a una aplicación escribir palabras nuevas en el diccionario del usuario."</string> <string-array name="phoneTypes"> <item>"Casa"</item> <item>"Móvil"</item> @@ -355,7 +345,7 @@ <item>"Personalizar"</item> </string-array> <string-array name="emailAddressTypes"> - <item>"Casa"</item> + <item>"Personal?????"</item> <item>"Trabajo"</item> <item>"Otra"</item> <item>"Personalizar"</item> @@ -389,12 +379,12 @@ </string-array> <string name="keyguard_password_enter_pin_code">"Introduce el código PIN"</string> <string name="keyguard_password_wrong_pin_code">"El código PIN es incorrecto."</string> - <string name="keyguard_label_text">"Para desbloquear el teléfono, pulsa \"Menú\" y, a continuación, pulsa 0."</string> + <string name="keyguard_label_text">"Para desbloquear el teléfono, pulsa MENU y, a continuación, pulsa 0."</string> <string name="emergency_call_dialog_number_for_display">"Número de emergencia"</string> <string name="lockscreen_carrier_default">"(Sin servicio)"</string> - <string name="lockscreen_screen_locked">"Pantalla bloqueada."</string> - <string name="lockscreen_instructions_when_pattern_enabled">"Pulsa \"Menú\" para desbloquear el teléfono o realizar una llamada de emergencia."</string> - <string name="lockscreen_instructions_when_pattern_disabled">"Pulsa \"Menú\" para desbloquear el teléfono."</string> + <string name="lockscreen_screen_locked">"Pantalla bloqueada"</string> + <string name="lockscreen_instructions_when_pattern_enabled">"Pulsa MENU para desbloquear el teléfono o realizar una llamada de emergencia."</string> + <string name="lockscreen_instructions_when_pattern_disabled">"Pulsa MENU para desbloquear el teléfono."</string> <string name="lockscreen_pattern_instructions">"Crear patrón para desbloquear"</string> <string name="lockscreen_emergency_call">"Llamada de emergencia"</string> <string name="lockscreen_pattern_correct">"Correcto"</string> @@ -440,12 +430,9 @@ <string name="factorytest_not_system">"La acción FACTORY_TEST sólo es compatible con los paquetes instalados en /system/app."</string> <string name="factorytest_no_action">"No se ha encontrado ningún paquete que proporcione la acción FACTORY_TEST."</string> <string name="factorytest_reboot">"Reiniciar"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"La página \"<xliff:g id="TITLE">%s</xliff:g>\" dice:"</string> + <string name="js_dialog_title_default">"JavaScript"</string> + <string name="js_dialog_before_unload">"¿Quieres salir de esta página?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Selecciona \"Aceptar\" para continuar o \"Cancelar\" para permanecer en la página actual."</string> <string name="save_password_label">"Confirmar"</string> <string name="save_password_message">"¿Deseas que el navegador recuerde esta contraseña?"</string> <string name="save_password_notnow">"Ahora no"</string> @@ -454,7 +441,7 @@ <string name="open_permission_deny">"No dispones de permiso para abrir esta página."</string> <string name="text_copied">"Texto copiado al portapapeles."</string> <string name="more_item_label">"Más"</string> - <string name="prepend_shortcut_label">"\"Menú\"+"</string> + <string name="prepend_shortcut_label">"MENU+"</string> <string name="menu_space_shortcut_label">"espacio"</string> <string name="menu_enter_shortcut_label">"intro"</string> <string name="menu_delete_shortcut_label">"suprimir"</string> @@ -496,22 +483,38 @@ <item quantity="one">"mañana"</item> <item quantity="other">"dentro de <xliff:g id="COUNT">%d</xliff:g> días"</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"hace 1 segundo"</item> + <item quantity="other">"hace <xliff:g id="COUNT">%d</xliff:g> segundos"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"hace 1 minuto"</item> + <item quantity="other">"hace <xliff:g id="COUNT">%d</xliff:g> minutos"</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"hace 1 hora"</item> + <item quantity="other">"hace <xliff:g id="COUNT">%d</xliff:g> horas"</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"ayer"</item> + <item quantity="other">"hace <xliff:g id="COUNT">%d</xliff:g> días"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"dentro de 1 segundo"</item> + <item quantity="other">"dentro de <xliff:g id="COUNT">%d</xliff:g> segundos"</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"dentro de 1 minuto"</item> + <item quantity="other">"dentro de <xliff:g id="COUNT">%d</xliff:g> minutos"</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"dentro de 1 hora"</item> + <item quantity="other">"dentro de <xliff:g id="COUNT">%d</xliff:g> horas"</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"mañana"</item> + <item quantity="other">"dentro de <xliff:g id="COUNT">%d</xliff:g> días"</item> + </plurals> <string name="preposition_for_date">"el %s"</string> <string name="preposition_for_time">"a las %s"</string> <string name="preposition_for_year">"en %s"</string> @@ -553,17 +556,15 @@ <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="MONTH">MMMM</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="full_date_day_first">"<xliff:g id="MONTH">MMMM</xliff:g>' de '<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_month_first">"<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="MONTH">MMM</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="MONTH">MMMM</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' de '<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="MONTH">MMM</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"mediodía"</string> <string name="Noon">"Mediodía"</string> <string name="midnight">"medianoche"</string> @@ -691,8 +692,7 @@ <string name="paste">"Pegar"</string> <string name="copyUrl">"Copiar URL"</string> <string name="inputMethod">"Método de introducción de texto"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"Añadir \"%s\" al diccionario"</string> <string name="editTextMenuTitle">"Editar texto"</string> <string name="low_internal_storage_view_title">"Poco espacio"</string> <string name="low_internal_storage_view_text">"Se está agotando el espacio de almacenamiento del teléfono."</string> @@ -700,8 +700,7 @@ <string name="cancel">"Cancelar"</string> <string name="yes">"Aceptar"</string> <string name="no">"Cancelar"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"Atención"</string> <string name="capital_on">"Activado"</string> <string name="capital_off">"Desconectado"</string> <string name="whichApplication">"Completar acción utilizando"</string> @@ -725,8 +724,7 @@ <string name="volume_music">"Volumen multimedia"</string> <string name="volume_music_hint_playing_through_bluetooth">"Reproduciendo a través de Bluetooth"</string> <string name="volume_call">"Volumen de la llamada"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"Volumen de la llamada de Bluetooth"</string> <string name="volume_alarm">"Volumen de alarma"</string> <string name="volume_notification">"Volumen de notificaciones"</string> <string name="volume_unknown">"Volumen"</string> @@ -762,60 +760,35 @@ <string name="usb_storage_error_message">"Se ha producido un problema al intentar utilizar la tarjeta SD para el almacenamiento USB."</string> <string name="usb_storage_notification_title">"Conectado por USB"</string> <string name="usb_storage_notification_message">"Seleccionar para copiar archivos al/desde el equipo"</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"Desactivar almacenamiento USB"</string> + <string name="usb_storage_stop_notification_message">"Selecciona esta opción para desactivar el almacenamiento USB."</string> + <string name="usb_storage_stop_title">"Desactivar almacenamiento USB"</string> + <string name="usb_storage_stop_message">"Antes de desactivar el almacenamiento USB, asegúrate de haber desmontado el host USB. Selecciona \"Desactivar\" para desactivar el almacenamiento USB."</string> + <string name="usb_storage_stop_button_mount">"Desactivar"</string> + <string name="usb_storage_stop_button_unmount">"Cancelar"</string> + <string name="usb_storage_stop_error_message">"Se ha producido un problema al desactivar el almacenamiento USB. Asegúrate de que has desmontado el host USB e inténtalo de nuevo."</string> + <string name="extmedia_format_title">"Formatear tarjeta SD"</string> + <string name="extmedia_format_message">"¿Estás seguro de que quieres formatear la tarjeta SD? Se perderán todos los datos de la tarjeta."</string> + <string name="extmedia_format_button_format">"Formato"</string> <string name="select_input_method">"Seleccionar método de introducción de texto"</string> <string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"candidatos"</u></string> + <string name="ext_media_checking_notification_title">"Preparando tarjeta SD"</string> + <string name="ext_media_checking_notification_message">"Comprobando errores"</string> + <string name="ext_media_nofs_notification_title">"Tarjeta SD vacía"</string> + <string name="ext_media_nofs_notification_message">"La tarjeta SD está vacía o utiliza un sistema de archivos incompatible."</string> + <string name="ext_media_unmountable_notification_title">"Tarjeta SD dañada"</string> + <string name="ext_media_unmountable_notification_message">"La tarjeta SD está dañada. Es posible que sea necesario volver a formatearla."</string> + <string name="ext_media_badremoval_notification_title">"La tarjeta SD se ha extraído inesperadamente."</string> + <string name="ext_media_badremoval_notification_message">"Desmonta la tarjeta SD antes de extraerla para evitar la pérdida de datos."</string> + <string name="ext_media_safe_unmount_notification_title">"Es seguro extraer la tarjeta SD."</string> + <string name="ext_media_safe_unmount_notification_message">"Ya puedes extraer la tarjeta SD de forma segura."</string> + <string name="ext_media_nomedia_notification_title">"Tarjeta SD extraída"</string> + <string name="ext_media_nomedia_notification_message">"La tarjeta SD se ha extraído. Inserta una nueva tarjeta SD para aumentar la capacidad de almacenamiento de tu dispositivo."</string> + <string name="activity_list_empty">"No se ha encontrado ninguna actividad coincidente."</string> + <string name="permlab_pkgUsageStats">"actualizar estadísticas de uso de componentes"</string> + <string name="permdesc_pkgUsageStats">"Permite la modificación de estadísticas recopiladas sobre el uso de componentes. No está destinado al uso por parte de aplicaciones normales."</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values-fr-rFR/arrays.xml b/core/res/res/values-fr-rFR/arrays.xml new file mode 100644 index 0000000..504ab0f --- /dev/null +++ b/core/res/res/values-fr-rFR/arrays.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/assets/res/any/colors.xml +** +** Copyright 2006, Google Inc. +** +** 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> + + <!-- Do not translate. --> + <integer-array name="maps_starting_lat_lng"> + <item>48850258</item> + <item>2351074</item> + </integer-array> + <!-- Do not translate. --> + <integer-array name="maps_starting_zoom"> + <item>6</item> + </integer-array> + +</resources> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 95e3052..45b8f03 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -38,7 +38,7 @@ <string name="badPin">"L\'ancien code PIN saisi est incorrect."</string> <string name="badPuk">"Le code PUK saisi est incorrect."</string> <string name="mismatchPin">"Les codes PIN saisis ne correspondent pas."</string> - <string name="invalidPin">"Saisissez un code PIN comptant 4 à 8 chiffres."</string> + <string name="invalidPin">"Le code PIN doit compter de 4 à 8 chiffres."</string> <string name="needPuk">"Votre carte SIM est verrouillée par code PUK. Saisissez le code PUK pour la déverrouiller."</string> <string name="needPuk2">"Saisissez le code PUK2 pour débloquer la carte SIM."</string> <string name="ClipMmi">"Identifiant d\'appelant entrant"</string> @@ -95,7 +95,7 @@ <string name="screen_lock">"Verrouillage de l\'écran"</string> <string name="power_off">"Éteindre"</string> <string name="shutdown_progress">"Arrêt en cours..."</string> - <string name="shutdown_confirm">"Votre téléphone va s\'éteindra."</string> + <string name="shutdown_confirm">"Votre téléphone va s\'éteindre."</string> <string name="no_recent_tasks">"Aucune application récente"</string> <string name="global_actions">"Options du téléphone"</string> <string name="global_action_lock">"Verrouillage de l\'écran"</string> @@ -109,8 +109,8 @@ <string name="permgrouplab_messages">"Vos messages"</string> <string name="permgroupdesc_messages">"Permet de lire et rédiger vos SMS, e-mails et autres messages."</string> <string name="permgrouplab_personalInfo">"Vos informations personnelles"</string> - <string name="permgroupdesc_personalInfo">"Accédez directement aux contacts et au calendrier enregistrés sur votre téléphone."</string> - <string name="permgrouplab_location">"Votre position géographique"</string> + <string name="permgroupdesc_personalInfo">"Accédez directement aux contacts et à l\'agenda enregistrés sur votre téléphone."</string> + <string name="permgrouplab_location">"Votre position"</string> <string name="permgroupdesc_location">"Suivre votre position géographique"</string> <string name="permgrouplab_network">"Communications réseau"</string> <string name="permgroupdesc_network">"Permet à des applications d\'accéder à différentes fonctionnalités du réseau."</string> @@ -213,7 +213,7 @@ <string name="permlab_diagnostic">"Lire/écrire dans les ressources appartenant aux diagnostics"</string> <string name="permdesc_diagnostic">"Permet à une application de lire et d\'éditer toute ressource appartenant au groupe de diagnostics (par exemple, les fichiers in/dev). Ceci peut affecter la stabilité et la sécurité du système. Cette fonctionnalité est UNIQUEMENT réservée aux diagnostics matériels effectués par le fabricant ou l\'opérateur."</string> <string name="permlab_changeComponentState">"Activer ou désactiver des éléments de l\'application"</string> - <string name="permdesc_changeComponentState">"Permet à une application de modifier l\'état d\'activation/désactivation d\'un élément d\'une autre application. Des applications malveillantes peuvent utiliser cette fonctionnalité pour désactiver des options importantes du téléphone. Soyez prudent en utilisant cette autorisation, car il est possible que certains éléments deviennent instables, incohérents ou inutilisables."</string> + <string name="permdesc_changeComponentState">"Permet à une application d\'envoyer une notification lors de la réception d\'un message WAP PUSH. Des applications malveillantes peuvent utiliser cette fonctionnalité pour créer de faux accusés de réception de MMS ou remplacer le contenu de toute page Web par des données malveillantes."</string> <string name="permlab_setPreferredApplications">"Définir les applications préférées"</string> <string name="permdesc_setPreferredApplications">"Permet à une application de modifier vos applications préférées. Des applications malveillantes peuvent utiliser cette fonctionnalité pour modifier discrètement les applications en cours d\'exécution, en imitant vos applications existantes afin de récupérer des données personnelles vous concernant."</string> <string name="permlab_writeSettings">"Modifier les paramètres généraux du système"</string> @@ -223,7 +223,7 @@ <string name="permlab_writeGservices">"Modifier la carte des services Google"</string> <string name="permdesc_writeGservices">"Permet à une application de modifier la carte des services Google. Les applications normales n\'utilisent pas cette fonctionnalité."</string> <string name="permlab_receiveBootCompleted">"Lancer automatiquement au démarrage"</string> - <string name="permdesc_receiveBootCompleted">"Permet à une application de se lancer dès la fin du démarrage du système. Ceci peut rallonger le temps de démarrage requis par le téléphone. L\'application étant alors constamment en cours d\'exécution, le fonctionnement général du téléphone risque d\'être ralenti."</string> + <string name="permdesc_receiveBootCompleted">"Permet à une application de se lancer dès la fin du démarrage du système. Cela peut rallonger le temps de démarrage requis par le téléphone. L\'application étant alors constamment en cours d\'exécution, le fonctionnement général du téléphone risque d\'être ralenti."</string> <string name="permlab_broadcastSticky">"Envoyer une diffusion persistante"</string> <string name="permdesc_broadcastSticky">"Permet à une application d\'envoyer des diffusions \"persistantes\", qui perdurent après la fin de la diffusion. Des applications malveillantes peuvent ainsi ralentir le téléphone ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string> <string name="permlab_readContacts">"Lire les données des contacts"</string> @@ -234,17 +234,17 @@ <string name="permdesc_writeOwnerData">"Permet à une application de modifier les données du propriétaire du téléphone enregistrées sur votre appareil. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier ces données."</string> <string name="permlab_readOwnerData">"Lire des données du propriétaire"</string> <string name="permdesc_readOwnerData">"Permet à une application de lire les données du propriétaire du téléphone enregistrées sur votre appareil. Des applications malveillantes peuvent utiliser cette fonctionnalité pour lire ces données."</string> - <string name="permlab_readCalendar">"Lire les données du calendrier"</string> - <string name="permdesc_readCalendar">"Permet à une application de lire tous les événements du calendrier enregistrés sur votre téléphone. Des applications malveillantes peuvent utiliser cette fonctionnalité pour envoyer les événements de votre calendrier à d\'autres personnes."</string> - <string name="permlab_writeCalendar">"Écrire les données du calendrier"</string> - <string name="permdesc_writeCalendar">"Permet à une application de modifier les événements du calendrier enregistrés sur votre téléphone. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier les données de votre calendrier."</string> + <string name="permlab_readCalendar">"Lire les données de l\'agenda"</string> + <string name="permdesc_readCalendar">"Permet à une application de lire tous les événements de l\'agenda enregistrés sur votre téléphone. Des applications malveillantes peuvent utiliser cette fonctionnalité pour envoyer les événements de votre agenda à d\'autres personnes."</string> + <string name="permlab_writeCalendar">"Écrire les données de l\'agenda"</string> + <string name="permdesc_writeCalendar">"Permet à une application de modifier les événements de l\'agenda enregistrés sur votre téléphone. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier les données de votre agenda."</string> <string name="permlab_accessMockLocation">"Créer des sources géographiques fictives à des fins de test"</string> <string name="permdesc_accessMockLocation">"Permet de créer des sources de position géographique fictives à des fins de test. Des applications malveillantes peuvent utiliser cette fonctionnalité pour remplacer la position géographique et/ou l\'état fournis par des sources réelles comme le GPS ou les fournisseurs d\'accès."</string> <string name="permlab_accessLocationExtraCommands">"Accéder à des commandes de fournisseur de position géographique supplémentaires"</string> <string name="permdesc_accessLocationExtraCommands">"Permet d\'accéder à des commandes de fournisseur de position géographique supplémentaires. Des applications malveillantes peuvent utiliser cette fonctionnalité pour interférer avec l\'utilisation du GPS ou d\'autres sources de positionnement géographique."</string> - <string name="permlab_accessFineLocation">"Position géographique précise (GPS)"</string> + <string name="permlab_accessFineLocation">"Position géo. OK (GPS)"</string> <string name="permdesc_accessFineLocation">"Permet d\'accéder à des sources de positionnement géographique précises comme le Global Positioning System (GPS) sur le téléphone, lorsque ces services sont disponibles. Des applications malveillantes peuvent utiliser cette fonctionnalité pour déterminer l\'endroit où vous vous trouvez et augmenter la consommation de la batterie de votre téléphone."</string> - <string name="permlab_accessCoarseLocation">"Position géographique approximative (selon le réseau)"</string> + <string name="permlab_accessCoarseLocation">"Position géo. approximative (selon le réseau)"</string> <string name="permdesc_accessCoarseLocation">"Accéder à des sources de positionnement géographique approximatif (par ex. des bases de données de réseaux mobiles) pour déterminer la position géographique du téléphone, lorsque cette option est disponible. Des applications malveillantes peuvent utiliser cette fonctionnalité pour déterminer approximativement l\'endroit où vous vous trouvez."</string> <string name="permlab_accessSurfaceFlinger">"Accéder à SurfaceFlinger"</string> <string name="permdesc_accessSurfaceFlinger">"Permet à certaines applications d\'utiliser les fonctionnalités SurfaceFlinger de bas niveau."</string> @@ -262,10 +262,8 @@ <string name="permdesc_reboot">"Permet à l\'application de forcer le redémarrage du téléphone."</string> <string name="permlab_mount_unmount_filesystems">"Monter et démonter des systèmes de fichiers"</string> <string name="permdesc_mount_unmount_filesystems">"Permet à l\'application de monter et démonter des systèmes de fichiers pour des périphériques de stockage amovibles."</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> + <string name="permlab_mount_format_filesystems">"formater le périphérique de stockage externe"</string> + <string name="permdesc_mount_format_filesystems">"Permet à l\'application de formater le périphérique de stockage amovible."</string> <string name="permlab_vibrate">"Contrôler le vibreur"</string> <string name="permdesc_vibrate">"Permet à l\'application de contrôler le vibreur."</string> <string name="permlab_flashlight">"Contrôler la lampe de poche"</string> @@ -280,10 +278,8 @@ <string name="permdesc_locationUpdates">"Permet l\'activation/la désactivation des notifications de mises à jour de la position géographique provenant de la radio. Les applications normales n\'utilisent pas cette fonctionnalité."</string> <string name="permlab_checkinProperties">"Accéder aux propriétés d\'enregistrement"</string> <string name="permdesc_checkinProperties">"Permet un accès en lecture/écriture à des propriétés envoyées par le service d\'inscription. Les applications normales n\'utilisent pas cette fonctionnalité."</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> + <string name="permlab_bindGadget">"choisir les gadgets"</string> + <string name="permdesc_bindGadget">"Permet à l\'application de signaler au système quels gadgets peuvent être utilisés pour quelle application. Cette autorisation permet aux applications de fournir l\'accès à des données personnelles à d\'autres applications. Cette option n\'est pas utilisée par les applications standard."</string> <string name="permlab_modifyPhoneState">"Modifier l\'état du téléphone"</string> <string name="permdesc_modifyPhoneState">"Permet à une application de contrôler les fonctionnalités téléphoniques de l\'appareil. Une application bénéficiant de cette autorisation peut changer de réseau, éteindre et allumer la radio du téléphone, etc., sans vous en notifier."</string> <string name="permlab_readPhoneState">"Lire l\'état du téléphone"</string> @@ -312,10 +308,8 @@ <string name="permdesc_writeApnSettings">"Permet à une application de modifier les paramètres APN (Nom des points d\'accès), comme le proxy ou le port de tout APN."</string> <string name="permlab_changeNetworkState">"Modifier la connectivité du réseau"</string> <string name="permdesc_changeNetworkState">"Permet à une application de modifier la connectivité du réseau."</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"modifier le paramètre d\'utilisation des données en arrière-plan"</string> + <string name="permdesc_changeBackgroundDataSetting">"Permet à une application de modifier le paramètre d\'utilisation des données en arrière-plan."</string> <string name="permlab_accessWifiState">"Afficher l\'état du Wi-Fi"</string> <string name="permdesc_accessWifiState">"Permet à une application d\'afficher des informations concernant l\'état du Wi-Fi."</string> <string name="permlab_changeWifiState">"Modifier l\'état du Wi-Fi"</string> @@ -336,16 +330,12 @@ <string name="permdesc_subscribedFeedsRead">"Permet à une application d\'obtenir des informations sur les flux récemment synchronisés."</string> <string name="permlab_subscribedFeedsWrite">"Écrire les flux auxquels vous êtes abonné"</string> <string name="permdesc_subscribedFeedsWrite">"Permet à une application de modifier vos flux synchronisés actuels. Cette fonctionnalité peut permettre à des applications malveillantes de modifier vos flux synchronisés."</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"lire le dictionnaire défini par l\'utilisateur"</string> + <string name="permdesc_readDictionary">"Permet à une application de lire tous les mots, noms et expressions que l\'utilisateur a pu enregistrer dans son dictionnaire personnel."</string> + <string name="permlab_writeDictionary">"enregistrer dans le dictionnaire défini par l\'utilisateur"</string> + <string name="permdesc_writeDictionary">"Permet à une application d\'enregistrer de nouveaux mots dans le dictionnaire personnel de l\'utilisateur."</string> <string-array name="phoneTypes"> - <item>"Accueil"</item> + <item>"Domicile"</item> <item>"Mobile"</item> <item>"Bureau"</item> <item>"Télécopie bureau"</item> @@ -355,19 +345,19 @@ <item>"Personnalisé"</item> </string-array> <string-array name="emailAddressTypes"> - <item>"Accueil"</item> + <item>"Domicile"</item> <item>"Bureau"</item> <item>"Autre"</item> <item>"Personnalisée"</item> </string-array> <string-array name="postalAddressTypes"> - <item>"Accueil"</item> + <item>"Domicile"</item> <item>"Bureau"</item> <item>"Autre"</item> <item>"Personnalisée"</item> </string-array> <string-array name="imAddressTypes"> - <item>"Accueil"</item> + <item>"Domicile"</item> <item>"Bureau"</item> <item>"Autre"</item> <item>"Personnalisé"</item> @@ -387,14 +377,14 @@ <item>"ICQ"</item> <item>"Jabber"</item> </string-array> - <string name="keyguard_password_enter_pin_code">"Saisir le code PIN"</string> + <string name="keyguard_password_enter_pin_code">"Saisissez le code PIN"</string> <string name="keyguard_password_wrong_pin_code">"Le code PIN est incorrect !"</string> - <string name="keyguard_label_text">"Pour débloquer le clavier, appuyez sur Menu puis sur 0."</string> + <string name="keyguard_label_text">"Pour débloquer le clavier, appuyez sur \"Menu\" puis sur 0."</string> <string name="emergency_call_dialog_number_for_display">"Numéro d\'urgence"</string> <string name="lockscreen_carrier_default">"(Aucun service)"</string> <string name="lockscreen_screen_locked">"Écran verrouillé"</string> - <string name="lockscreen_instructions_when_pattern_enabled">"Appuyez sur Menu pour débloquer le téléphone ou appeler un numéro d\'urgence"</string> - <string name="lockscreen_instructions_when_pattern_disabled">"Appuyez sur Menu pour déverrouiller le téléphone."</string> + <string name="lockscreen_instructions_when_pattern_enabled">"Appuyez sur \"Menu\" pour débloquer le téléphone ou appeler un numéro d\'urgence"</string> + <string name="lockscreen_instructions_when_pattern_disabled">"Appuyez sur \"Menu\" pour déverrouiller le téléphone."</string> <string name="lockscreen_pattern_instructions">"Dessinez un motif pour déverrouiller le téléphone"</string> <string name="lockscreen_emergency_call">"Appel d\'urgence"</string> <string name="lockscreen_pattern_correct">"Combinaison correcte !"</string> @@ -440,12 +430,9 @@ <string name="factorytest_not_system">"L\'action FACTORY_TEST est uniquement prise en charge pour les paquets de données installés dans in/system/app."</string> <string name="factorytest_no_action">"Impossible de trouver un paquet proposant l\'action FACTORY_TEST."</string> <string name="factorytest_reboot">"Redémarrer"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"La page \"<xliff:g id="TITLE">%s</xliff:g>\" affirme :"</string> + <string name="js_dialog_title_default">"JavaScript"</string> + <string name="js_dialog_before_unload">"Vous souhaitez quitter cette page ?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Sélectionnez OK pour continuer ou Annuler pour rester sur la page actuelle."</string> <string name="save_password_label">"Confirmer"</string> <string name="save_password_message">"Voulez-vous que le navigateur se souvienne de ce mot de passe ?"</string> <string name="save_password_notnow">"Pas maintenant"</string> @@ -496,22 +483,38 @@ <item quantity="one">"demain"</item> <item quantity="other">"dans <xliff:g id="COUNT">%d</xliff:g> jours"</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"il y a 1 seconde"</item> + <item quantity="other">"il y a <xliff:g id="COUNT">%d</xliff:g> secondes"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"il y a 1 minute"</item> + <item quantity="other">"il y a <xliff:g id="COUNT">%d</xliff:g> minutes"</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"il y a 1 heure"</item> + <item quantity="other">"Il y a <xliff:g id="COUNT">%d</xliff:g> heures"</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"hier"</item> + <item quantity="other">"Il y a <xliff:g id="COUNT">%d</xliff:g> jours"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"dans 1 seconde"</item> + <item quantity="other">"dans <xliff:g id="COUNT">%d</xliff:g> secondes"</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"dans 1 minute"</item> + <item quantity="other">"dans <xliff:g id="COUNT">%d</xliff:g> minutes"</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"dans 1 heure"</item> + <item quantity="other">"dans <xliff:g id="COUNT">%d</xliff:g> heures"</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"demain"</item> + <item quantity="other">"dans <xliff:g id="COUNT">%d</xliff:g> jours"</item> + </plurals> <string name="preposition_for_date">"%s"</string> <string name="preposition_for_time">"à %s"</string> <string name="preposition_for_year">"en %s"</string> @@ -553,17 +556,15 @@ <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_month_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"midi"</string> <string name="Noon">"Midi"</string> <string name="midnight">"minuit"</string> @@ -691,8 +692,7 @@ <string name="paste">"Coller"</string> <string name="copyUrl">"Copier l\'URL"</string> <string name="inputMethod">"Mode de saisie"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"Ajouter \"%s\" au dictionnaire"</string> <string name="editTextMenuTitle">"Modifier le texte"</string> <string name="low_internal_storage_view_title">"Espace disponible faible"</string> <string name="low_internal_storage_view_text">"La mémoire du téléphone commence à être pleine."</string> @@ -700,8 +700,7 @@ <string name="cancel">"Annuler"</string> <string name="yes">"OK"</string> <string name="no">"Annuler"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"Attention"</string> <string name="capital_on">"ON"</string> <string name="capital_off">"OFF"</string> <string name="whichApplication">"Terminer l\'action avec"</string> @@ -725,8 +724,7 @@ <string name="volume_music">"Volume des médias"</string> <string name="volume_music_hint_playing_through_bluetooth">"Lecture via Bluetooth"</string> <string name="volume_call">"Volume des appels entrants"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"Volume d\'appels entrants sur Bluetooth"</string> <string name="volume_alarm">"Volume de l\'alarme"</string> <string name="volume_notification">"Volume des notifications"</string> <string name="volume_unknown">"Volume"</string> @@ -762,60 +760,35 @@ <string name="usb_storage_error_message">"Un problème est survenu lors de l\'utilisation de votre carte SD en tant que périphérique de stockage USB."</string> <string name="usb_storage_notification_title">"Connecté avec un câble USB"</string> <string name="usb_storage_notification_message">"Sélectionnez cette option pour copier des fichiers vers/à partir de votre ordinateur."</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"Éteindre le périphérique de stockage USB"</string> + <string name="usb_storage_stop_notification_message">"Sélectionner pour éteindre le périphérique de stockage USB"</string> + <string name="usb_storage_stop_title">"Éteindre le périphérique de stockage USB"</string> + <string name="usb_storage_stop_message">"Avant d\'éteindre le périphérique de stockage USB, assurez-vous d\'avoir désactivé l\'hôte USB. Sélectionnez \"Éteindre\" pour éteindre le périphérique de stockage USB."</string> + <string name="usb_storage_stop_button_mount">"Éteindre"</string> + <string name="usb_storage_stop_button_unmount">"Annuler"</string> + <string name="usb_storage_stop_error_message">"Un problème est survenu lors de la mise hors tension du périphérique de stockage USB. Assurez-vous que l\'hôte USB a bien été désactivé, puis essayez à nouveau."</string> + <string name="extmedia_format_title">"Formater la carte SD"</string> + <string name="extmedia_format_message">"Voulez-vous vraiment formater la carte SD ? Toutes les données de cette carte seront perdues."</string> + <string name="extmedia_format_button_format">"Format"</string> <string name="select_input_method">"Sélectionner un mode de saisie"</string> <string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"candidats"</u></string> + <string name="ext_media_checking_notification_title">"Préparation de la carte SD"</string> + <string name="ext_media_checking_notification_message">"Recherche d\'erreurs"</string> + <string name="ext_media_nofs_notification_title">"Carte SD vide"</string> + <string name="ext_media_nofs_notification_message">"La carte SD est vide ou utilise un système de fichiers non pris en charge."</string> + <string name="ext_media_unmountable_notification_title">"Carte SD endommagée"</string> + <string name="ext_media_unmountable_notification_message">"La carte SD est endommagée. Vous devez peut-être reformater votre carte."</string> + <string name="ext_media_badremoval_notification_title">"Carte SD retirée inopinément"</string> + <string name="ext_media_badremoval_notification_message">"Désactiver la carte SD avant de la retirer pour éviter toute perte de données."</string> + <string name="ext_media_safe_unmount_notification_title">"La carte SD peut être retirée en toute sécurité"</string> + <string name="ext_media_safe_unmount_notification_message">"Vous pouvez désormais retirer la carte SD en toute sécurité."</string> + <string name="ext_media_nomedia_notification_title">"Carte SD manquante"</string> + <string name="ext_media_nomedia_notification_message">"La carte SD a été retirée. Insérez une autre carte pour augmenter la capacité de stockage de votre appareil."</string> + <string name="activity_list_empty">"Aucune activité correspondante trouvée"</string> + <string name="permlab_pkgUsageStats">"mettre à jour les données statistiques du composant"</string> + <string name="permdesc_pkgUsageStats">"Permet de modifier les données statistiques collectées du composant. Cette option n\'est pas utilisée par les applications standard."</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values-it-rIT/arrays.xml b/core/res/res/values-it-rIT/arrays.xml new file mode 100644 index 0000000..92e5260 --- /dev/null +++ b/core/res/res/values-it-rIT/arrays.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/assets/res/any/colors.xml +** +** Copyright 2006, Google Inc. +** +** 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> + + <!-- Do not translate. --> + <integer-array name="maps_starting_lat_lng"> + <item>41795888</item> + <item>12480469</item> + </integer-array> + <!-- Do not translate. --> + <integer-array name="maps_starting_zoom"> + <item>6</item> + </integer-array> + +</resources> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 2cf7b43..2ac9699 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -262,10 +262,8 @@ <string name="permdesc_reboot">"Consente all\'applicazione di imporre il riavvio del telefono."</string> <string name="permlab_mount_unmount_filesystems">"montare e smontare filesystem"</string> <string name="permdesc_mount_unmount_filesystems">"Consente montaggio e smontaggio da parte dell\'applicazione dei filesystem degli archivi rimovibili."</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> + <string name="permlab_mount_format_filesystems">"formatta archivio esterno"</string> + <string name="permdesc_mount_format_filesystems">"Consente all\'applicazione di formattare l\'archivio rimovibile."</string> <string name="permlab_vibrate">"controllare la vibrazione"</string> <string name="permdesc_vibrate">"Consente all\'applicazione di controllare la vibrazione."</string> <string name="permlab_flashlight">"controllare il flash"</string> @@ -280,10 +278,8 @@ <string name="permdesc_locationUpdates">"Consente l\'attivazione/disattivazione delle notifiche di aggiornamento della posizione. Da non usare per normali applicazioni."</string> <string name="permlab_checkinProperties">"accedere a proprietà di archiviazione"</string> <string name="permdesc_checkinProperties">"Consente l\'accesso di lettura/scrittura alle proprietà caricate dal servizio di archiviazione. Da non usare per normali applicazioni."</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> + <string name="permlab_bindGadget">"scegliere gadget"</string> + <string name="permdesc_bindGadget">"Consente all\'applicazione di indicare al sistema quali gadget possono essere utilizzati e da quale applicazione. Con questa autorizzazione, le applicazioni possono consentire ad altre applicazioni di accedere a dati personali. Da non usare per normali applicazioni."</string> <string name="permlab_modifyPhoneState">"modificare lo stato del telefono"</string> <string name="permdesc_modifyPhoneState">"Consente all\'applicazione di controllare le funzioni telefoniche del dispositivo. Un\'applicazione con questa autorizzazione può cambiare rete, accendere e spegnere il modulo radio del telefono e così via, il tutto automaticamente."</string> <string name="permlab_readPhoneState">"leggere lo stato del telefono"</string> @@ -312,10 +308,8 @@ <string name="permdesc_writeApnSettings">"Consente a un\'applicazione di modificare le impostazioni APN, come proxy e porta di qualsiasi APN."</string> <string name="permlab_changeNetworkState">"cambiare connettività di rete"</string> <string name="permdesc_changeNetworkState">"Consente a un\'applicazione di modificare lo stato di connettività di rete."</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"cambiare l\'impostazione di utilizzo dei dati in background"</string> + <string name="permdesc_changeBackgroundDataSetting">"Consente a un\'applicazione di cambiare l\'impostazione di utilizzo dei dati in background."</string> <string name="permlab_accessWifiState">"visualizzare lo stato Wi-Fi"</string> <string name="permdesc_accessWifiState">"Consente a un\'applicazione di visualizzare le informazioni relative allo stato della connessione Wi-Fi."</string> <string name="permlab_changeWifiState">"cambiare stato Wi-Fi"</string> @@ -336,14 +330,10 @@ <string name="permdesc_subscribedFeedsRead">"Consente a un\'applicazione di ottenere dettagli sui feed attualmente sincronizzati."</string> <string name="permlab_subscribedFeedsWrite">"scrivere feed sottoscritti"</string> <string name="permdesc_subscribedFeedsWrite">"Consente la modifica da parte di un\'applicazione dei feed attualmente sincronizzati. Le applicazioni dannose potrebbero essere in grado di modificare i feed sincronizzati."</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"leggi dizionario definito dall\'utente"</string> + <string name="permdesc_readDictionary">"Consente a un\'applicazione di leggere parole, nomi e frasi private che l\'utente potrebbe aver memorizzato nel dizionario utente."</string> + <string name="permlab_writeDictionary">"scrivi nel dizionario definito dall\'utente"</string> + <string name="permdesc_writeDictionary">"Consente a un\'applicazione di scrivere nuove parole nel dizionario utente."</string> <string-array name="phoneTypes"> <item>"Casa"</item> <item>"Cellulare"</item> @@ -440,12 +430,9 @@ <string name="factorytest_not_system">"L\'azione FACTORY_TEST è supportata soltanto per i pacchetti installati in /system/app."</string> <string name="factorytest_no_action">"Nessun pacchetto trovato che fornisca l\'azione FACTORY_TEST."</string> <string name="factorytest_reboot">"Riavvia"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"La pagina all\'indirizzo <xliff:g id="TITLE">%s</xliff:g> indica:"</string> + <string name="js_dialog_title_default">"JavaScript"</string> + <string name="js_dialog_before_unload">"Uscire da questa pagina?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Seleziona OK per continuare o Annulla per rimanere nella pagina corrente."</string> <string name="save_password_label">"Conferma"</string> <string name="save_password_message">"Memorizzare la password nel browser?"</string> <string name="save_password_notnow">"Non ora"</string> @@ -496,22 +483,38 @@ <item quantity="one">"domani"</item> <item quantity="other">"tra <xliff:g id="COUNT">%d</xliff:g> giorni"</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"1 sec fa"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> sec fa"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"1 min fa"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> min fa"</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"1 ora fa"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> ore fa"</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"ieri"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> giorni fa"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"tra 1 sec"</item> + <item quantity="other">"tra <xliff:g id="COUNT">%d</xliff:g> sec"</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"tra 1 min"</item> + <item quantity="other">"tra <xliff:g id="COUNT">%d</xliff:g> min"</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"tra 1 ora"</item> + <item quantity="other">"tra <xliff:g id="COUNT">%d</xliff:g> ore"</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"domani"</item> + <item quantity="other">"tra <xliff:g id="COUNT">%d</xliff:g> giorni"</item> + </plurals> <string name="preposition_for_date">"il %s"</string> <string name="preposition_for_time">"alle %s"</string> <string name="preposition_for_year">"nel %s"</string> @@ -553,17 +556,15 @@ <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"mezzogiorno"</string> <string name="Noon">"Mezzogiorno"</string> <string name="midnight">"mezzanotte"</string> @@ -691,8 +692,7 @@ <string name="paste">"Incolla"</string> <string name="copyUrl">"Copia URL"</string> <string name="inputMethod">"Metodo inserimento"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"Aggiungi \"%s\" al dizionario"</string> <string name="editTextMenuTitle">"Modifica testo"</string> <string name="low_internal_storage_view_title">"Spazio in esaurimento"</string> <string name="low_internal_storage_view_text">"Spazio di archiviazione del telefono in esaurimento."</string> @@ -700,8 +700,7 @@ <string name="cancel">"Annulla"</string> <string name="yes">"OK"</string> <string name="no">"Annulla"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"Attenzione"</string> <string name="capital_on">"ON"</string> <string name="capital_off">"OFF"</string> <string name="whichApplication">"Completa l\'azione con"</string> @@ -725,8 +724,7 @@ <string name="volume_music">"Volume media"</string> <string name="volume_music_hint_playing_through_bluetooth">"Riproduzione tramite Bluetooth"</string> <string name="volume_call">"Volume chiamate"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"Volume chiamate Bluetooth"</string> <string name="volume_alarm">"Volume allarme"</string> <string name="volume_notification">"Volume notifiche"</string> <string name="volume_unknown">"Volume"</string> @@ -762,60 +760,35 @@ <string name="usb_storage_error_message">"Problema di utilizzo della scheda SD per l\'archiviazione USB."</string> <string name="usb_storage_notification_title">"USB collegata"</string> <string name="usb_storage_notification_message">"Seleziona per copiare file sul/dal computer in uso."</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"Disattiva archivio USB"</string> + <string name="usb_storage_stop_notification_message">"Seleziona per disattivare archivio USB."</string> + <string name="usb_storage_stop_title">"Disattiva archivio USB"</string> + <string name="usb_storage_stop_message">"Prima di disattivare l\'archivio USB, verifica di aver smontato l\'host USB. A tale scopo, seleziona \"Disattiva\"."</string> + <string name="usb_storage_stop_button_mount">"Disattiva"</string> + <string name="usb_storage_stop_button_unmount">"Annulla"</string> + <string name="usb_storage_stop_error_message">"Abbiamo riscontrato un problema disattivando l\'archivio USB. Verifica di aver smontato l\'host USB e riprova."</string> + <string name="extmedia_format_title">"Formatta scheda SD"</string> + <string name="extmedia_format_message">"Formattare la scheda SD? Tutti i dati sulla scheda verranno persi."</string> + <string name="extmedia_format_button_format">"Formatta"</string> <string name="select_input_method">"Seleziona metodo di inserimento"</string> <string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"candidati"</u></string> + <string name="ext_media_checking_notification_title">"Preparazione scheda SD"</string> + <string name="ext_media_checking_notification_message">"Ricerca errori"</string> + <string name="ext_media_nofs_notification_title">"Scheda SD vuota"</string> + <string name="ext_media_nofs_notification_message">"La scheda SD è vuota o utilizza un file system non supportato."</string> + <string name="ext_media_unmountable_notification_title">"Scheda SD danneggiata"</string> + <string name="ext_media_unmountable_notification_message">"La scheda SD è danneggiata. Potrebbe essere necessario riformattarla."</string> + <string name="ext_media_badremoval_notification_title">"Rimozione imprevista della scheda SD"</string> + <string name="ext_media_badremoval_notification_message">"Smonta scheda SD prima della rimozione per evitare la perdita di dati."</string> + <string name="ext_media_safe_unmount_notification_title">"È possibile rimuovere la scheda SD"</string> + <string name="ext_media_safe_unmount_notification_message">"È ora possibile rimuovere la scheda SD in modo sicuro."</string> + <string name="ext_media_nomedia_notification_title">"Scheda SD rimossa"</string> + <string name="ext_media_nomedia_notification_message">"Scheda SD rimossa. Inserisci una nuova scheda SD per aumentare la memoria del dispositivo."</string> + <string name="activity_list_empty">"Nessuna attività corrispondente trovata"</string> + <string name="permlab_pkgUsageStats">"aggiornare le statistiche di utilizzo dei componenti"</string> + <string name="permdesc_pkgUsageStats">"Consente la modifica delle statistiche di utilizzo dei componenti raccolte. Da non usare per normali applicazioni."</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 24e3cb6..1fa3eee 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -21,10 +21,10 @@ <string name="gigabyteShort">"GB"</string> <string name="terabyteShort">"TB"</string> <string name="petabyteShort">"PB"</string> - <string name="untitled">"<無題>"</string> + <string name="untitled">"<新規>"</string> <string name="ellipsis">"..."</string> - <string name="emptyPhoneNumber">"(電話番号なし)"</string> - <string name="unknownName">"(不明)"</string> + <string name="emptyPhoneNumber">"(電話番号なし)"</string> + <string name="unknownName">"(名前)"</string> <string name="defaultVoiceMailAlphaTag">"ボイスメール"</string> <string name="defaultMsisdnAlphaTag">"MSISDN1"</string> <string name="mmiError">"接続に問題があるか、MMIコードが正しくありません。"</string> @@ -48,11 +48,11 @@ <string name="BaMmi">"発信制限"</string> <string name="PwdMmi">"パスワードの変更"</string> <string name="PinMmi">"PINの変更"</string> - <string name="CLIRDefaultOnNextCallOn">"デフォルトでは発信者番号は非通知です。次の通話でも非通知です。"</string> - <string name="CLIRDefaultOnNextCallOff">"デフォルトでは発信者番号は非通知ですが、次の通話では通知されます。"</string> - <string name="CLIRDefaultOffNextCallOn">"デフォルトでは発信者番号は通知されますが、次の通話では非通知です。"</string> - <string name="CLIRDefaultOffNextCallOff">"デフォルトでは発信者番号は通知されます。次の通話でも通知されます。"</string> - <string name="serviceNotProvisioned">"サービスは提供されません。"</string> + <string name="CLIRDefaultOnNextCallOn">"既定: 発信者番号非通知、次の発信: 非通知"</string> + <string name="CLIRDefaultOnNextCallOff">"既定: 発信者番号非通知、次の発信: 通知"</string> + <string name="CLIRDefaultOffNextCallOn">"既定: 発信者番号通知、次の発信: 非通知"</string> + <string name="CLIRDefaultOffNextCallOff">"既定: 発信者番号通知、次の発信: 通知"</string> + <string name="serviceNotProvisioned">"提供可能なサービスがありません。"</string> <string name="CLIRPermanent">"発信者番号の設定は変更できません。"</string> <string name="serviceClassVoice">"音声"</string> <string name="serviceClassData">"データ"</string> @@ -90,15 +90,15 @@ <string name="me">"自分"</string> <string name="power_dialog">"携帯電話オプション"</string> <string name="silent_mode">"マナーモード"</string> - <string name="turn_on_radio">"ワイヤレスをオン"</string> - <string name="turn_off_radio">"ワイヤレスオフ"</string> + <string name="turn_on_radio">"ワイヤレス接続をONにする"</string> + <string name="turn_off_radio">"ワイヤレス接続をOFFにする"</string> <string name="screen_lock">"画面をロック"</string> <string name="power_off">"電源オフ"</string> <string name="shutdown_progress">"シャットダウン中..."</string> <string name="shutdown_confirm">"携帯電話の電源をオフにします。"</string> <string name="no_recent_tasks">"最近使ったアプリケーションはありません。"</string> <string name="global_actions">"携帯電話オプション"</string> - <string name="global_action_lock">"画面をロック"</string> + <string name="global_action_lock">"画面ロック"</string> <string name="global_action_power_off">"電源オフ"</string> <string name="global_action_toggle_silent_mode">"マナーモード"</string> <string name="global_action_silent_mode_on_status">"音声オフ"</string> @@ -109,27 +109,27 @@ <string name="permgrouplab_messages">"送受信したメッセージ"</string> <string name="permgroupdesc_messages">"SMS、メールなどのメッセージの読み書き"</string> <string name="permgrouplab_personalInfo">"個人情報"</string> - <string name="permgroupdesc_personalInfo">"携帯電話に保存した連絡先とカレンダーに直接アクセス"</string> + <string name="permgroupdesc_personalInfo">"端末の連絡先とカレンダーに直接アクセス"</string> <string name="permgrouplab_location">"現在地"</string> - <string name="permgroupdesc_location">"現在地を監視"</string> + <string name="permgroupdesc_location">"現在地を追跡"</string> <string name="permgrouplab_network">"ネットワーク通信"</string> <string name="permgroupdesc_network">"ネットワークのさまざまな機能へのアクセスをアプリケーションに許可します。"</string> <string name="permgrouplab_accounts">"Googleアカウント"</string> <string name="permgroupdesc_accounts">"利用可能なGoogleアカウントへのアクセス"</string> <string name="permgrouplab_hardwareControls">"ハードウェアの制御"</string> <string name="permgroupdesc_hardwareControls">"携帯電話のハードウェアに直接アクセスします。"</string> - <string name="permgrouplab_phoneCalls">"電話の発信"</string> + <string name="permgrouplab_phoneCalls">"電話/通話"</string> <string name="permgroupdesc_phoneCalls">"通話の監視、記録、処理"</string> <string name="permgrouplab_systemTools">"システムツール"</string> <string name="permgroupdesc_systemTools">"システムの低レベルのアクセスと制御"</string> <string name="permgrouplab_developmentTools">"開発ツール"</string> <string name="permgroupdesc_developmentTools">"アプリケーションのデベロッパーにのみ必要な機能です。"</string> - <string name="permlab_statusBar">"ステータスバーを無効にしたり変更する"</string> - <string name="permdesc_statusBar">"ステータスバーの無効化や、システムアイコンの追加や削除をアプリケーションに許可します。"</string> + <string name="permlab_statusBar">"ステータスバーの無効化や変更"</string> + <string name="permdesc_statusBar">"ステータスバーの無効化やシステムアイコンの追加や削除をアプリケーションに許可します。"</string> <string name="permlab_expandStatusBar">"ステータスバーの拡大/縮小"</string> <string name="permdesc_expandStatusBar">"ステータスバーの拡大や縮小をアプリケーションに許可します。"</string> <string name="permlab_processOutgoingCalls">"発信の傍受"</string> - <string name="permdesc_processOutgoingCalls">"発信を処理して、ダイヤルする番号を変更することをアプリケーションに許可します。悪意のあるアプリケーションが発信を監視、転送、阻止する恐れがあります。"</string> + <string name="permdesc_processOutgoingCalls">"通話の発信とダイヤルする番号の変更とをアプリケーションに許可します。悪意のあるアプリケーションが発信を監視、転送、阻止する恐れがあります。"</string> <string name="permlab_receiveSms">"SMSの受信"</string> <string name="permdesc_receiveSms">"SMSメッセージの受信と処理をアプリケーションに許可します。悪意のあるアプリケーションがメッセージを監視したり、表示せずに削除する恐れがあります。"</string> <string name="permlab_receiveMms">"MMSの受信"</string> @@ -137,7 +137,7 @@ <string name="permlab_sendSms">"SMSメッセージの送信"</string> <string name="permdesc_sendSms">"SMSメッセージの送信をアプリケーションに許可します。悪意のあるアプリケーションが確認なしでメッセージを送信し、料金が発生する恐れがあります。"</string> <string name="permlab_readSms">"SMSやMMSの読み取り"</string> - <string name="permdesc_readSms">"携帯電話またはSIMカードに保存したSMSメッセージの読み取りをアプリケーションに許可します。悪意のあるアプリケーションが機密メッセージを読み取る恐れがあります。"</string> + <string name="permdesc_readSms">"携帯電話やSIMカードに保存したSMSメッセージの読み取りをアプリケーションに許可します。悪意のあるアプリケーションが機密メッセージを読み取る恐れがあります。"</string> <string name="permlab_writeSms">"SMSやMMSの編集"</string> <string name="permdesc_writeSms">"携帯電話やSIMカードに保存したSMSメッセージへの書き込みをアプリケーションに許可します。悪意のあるアプリケーションがメッセージを削除する恐れがあります。"</string> <string name="permlab_receiveWapPush">"WAPの受信"</string> @@ -147,9 +147,9 @@ <string name="permlab_reorderTasks">"実行中のアプリケーションの順序の変更"</string> <string name="permdesc_reorderTasks">"タスクをフォアグラウンドやバックグラウンドに移動することをアプリケーションに許可します。悪意のあるアプリケーションが優先されて、コントロールできなくなる恐れがあります。"</string> <string name="permlab_setDebugApp">"アプリケーションのデバッグを有効にする"</string> - <string name="permdesc_setDebugApp">"別のアプリケーションをデバッグモードにすることをアプリケーションに許可します。これにより悪意のあるアプリケーションが、別のアプリケーションを終了させる恐れがあります。"</string> + <string name="permdesc_setDebugApp">"別のアプリケーションをデバッグモードにすることをアプリケーションに許可します。悪意のあるアプリケーションが別のアプリケーションを終了させる恐れがあります。"</string> <string name="permlab_changeConfiguration">"UI設定の変更"</string> - <string name="permdesc_changeConfiguration">"ロケールや全体のフォントのサイズなど、現在の設定の変更をアプリケーションに許可します。"</string> + <string name="permdesc_changeConfiguration">"地域/言語やフォントのサイズなど、現在の設定の変更をアプリケーションに許可します。"</string> <string name="permlab_restartPackages">"他のアプリケーションの再起動"</string> <string name="permdesc_restartPackages">"他のアプリケーションの強制的な再起動をアプリケーションに許可します。"</string> <string name="permlab_setProcessForeground">"停止の阻止"</string> @@ -157,47 +157,47 @@ <string name="permlab_forceBack">"アプリケーションの強制終了"</string> <string name="permdesc_forceBack">"フォアグラウンドで実行されている操作を強制終了して戻ることをアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string> <string name="permlab_dump">"システムの内部状態の取得"</string> - <string name="permdesc_dump">"システムの内部状態の取得をアプリケーションに許可します。悪意のあるアプリケーションが、通常は必要のない、広範囲にわたる非公開の機密情報を取得する恐れがあります。"</string> + <string name="permdesc_dump">"システムの内部状態の取得をアプリケーションに許可します。悪意のあるアプリケーションが、通常は必要としない広範囲にわたる非公開の機密情報を取得する恐れがあります。"</string> <string name="permlab_addSystemService">"低レベルサービスの公開"</string> <string name="permdesc_addSystemService">"独自の低レベルのシステムサービスを公開することをアプリケーションに許可します。悪意のあるアプリケーションがシステムを乗っ取って、データの盗用や破壊をする恐れがあります。"</string> <string name="permlab_runSetActivityWatcher">"起動中のすべてのアプリケーションの監視と制御"</string> <string name="permdesc_runSetActivityWatcher">"システムが起動する操作の監視と制御をアプリケーションに許可します。悪意のあるアプリケーションがシステムを完全に破壊する恐れがあります。この許可は開発にのみ必要で、携帯電話の通常の使用にはまったく必要ありません。"</string> <string name="permlab_broadcastPackageRemoved">"パッケージ削除ブロードキャストの送信"</string> - <string name="permdesc_broadcastPackageRemoved">"アプリケーションパッケージの削除通知を配信することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、他の実行中のアプリケーションを強制終了する恐れがあります。"</string> + <string name="permdesc_broadcastPackageRemoved">"アプリケーションパッケージの削除の通知を配信することをアプリケーションに許可します。悪意のあるアプリケーションが他の実行中のアプリケーションを強制終了する恐れがあります。"</string> <string name="permlab_broadcastSmsReceived">"SMS受信ブロードキャストの送信"</string> - <string name="permdesc_broadcastSmsReceived">"SMSメッセージの受信通知の配信をアプリケーションに許可します。これにより悪意のあるアプリケーションが、受信SMSメッセージを偽造する恐れがあります。"</string> + <string name="permdesc_broadcastSmsReceived">"SMSメッセージの受信通知の配信をアプリケーションに許可します。悪意のあるアプリケーションが受信SMSメッセージを偽造する恐れがあります。"</string> <string name="permlab_broadcastWapPush">"WAP-PUSH受信ブロードキャストの送信"</string> - <string name="permdesc_broadcastWapPush">"WAP PUSHメッセージの受信通知を配信することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、MMS受信メッセージを偽造したり、ウェブページのコンテンツを密かに改ざんしたりする恐れがあります。"</string> + <string name="permdesc_broadcastWapPush">"WAP PUSHメッセージの受信の通知を配信することをアプリケーションに許可します。悪意のあるアプリケーションがMMS受信メッセージを偽造したり、ウェブページのコンテンツを密かに改ざんする恐れがあります。"</string> <string name="permlab_setProcessLimit">"実行中のプロセスの数を制限"</string> <string name="permdesc_setProcessLimit">"実行するプロセス数の上限の制御をアプリケーションに許可します。通常のアプリケーションにはまったく必要ありません。"</string> <string name="permlab_setAlwaysFinish">"バックグラウンドアプリケーションをすべて終了する"</string> <string name="permdesc_setAlwaysFinish">"バックグラウンドになり次第必ず操作を終了させるかどうかの制御をアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string> <string name="permlab_fotaUpdate">"システムアップデートの自動インストール"</string> - <string name="permdesc_fotaUpdate">"保留中のシステムアップデートに関する通知を受信してインストールを開始することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、許可なく更新を行ってシステムを破壊したり、更新処理を妨害する恐れがあります。"</string> - <string name="permlab_batteryStats">"バッテリ統計の変更"</string> - <string name="permdesc_batteryStats">"収集されたバッテリの統計の変更を許可します。通常のアプリケーションでは使用しません。"</string> + <string name="permdesc_fotaUpdate">"保留中のシステムアップデートに関する通知の受信とインストールの開始をアプリケーションに許可します。悪意のあるアプリケーションが許可なく更新を行ってシステムを破壊したり、更新処理を妨害する恐れがあります。"</string> + <string name="permlab_batteryStats">"電池統計情報の変国"</string> + <string name="permdesc_batteryStats">"収集した電池統計情報の変更を許可します。通常のアプリケーションでは使用しません。"</string> <string name="permlab_internalSystemWindow">"未許可のウィンドウの表示"</string> <string name="permdesc_internalSystemWindow">"内部システムのユーザーインターフェースで使用するためのウィンドウ作成を許可します。通常のアプリケーションでは使用しません。"</string> <string name="permlab_systemAlertWindow">"システムレベルの警告の表示"</string> - <string name="permdesc_systemAlertWindow">"システムの警告ウィンドウをアプリケーションで表示できるようにします。悪意のあるアプリケーションが携帯電話の画面全体を偽装する恐れがあります。"</string> - <string name="permlab_setAnimationScale">"アニメーション全般の速度の変更"</string> + <string name="permdesc_systemAlertWindow">"システムの警告ウィンドウの表示をアプリケーションに許可します。悪意のあるアプリケーションが携帯電話の画面全体を偽装する恐れがあります。"</string> + <string name="permlab_setAnimationScale">"アニメーションのプリセット速度の変更"</string> <string name="permdesc_setAnimationScale">"いつでもアニメーション全般の速度を変更する (アニメーションを速くまたは遅くする) ことをアプリケーションに許可します。"</string> <string name="permlab_manageAppTokens">"アプリケーショントークンの管理"</string> <string name="permdesc_manageAppTokens">"通常のZ-orderingを回避して、独自のトークンを作成、管理することをアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string> <string name="permlab_injectEvents">"キーを押してボタンをコントロール"</string> <string name="permdesc_injectEvents">"入力イベント (キーを押すなど) を別のアプリケーションに伝えることをアプリケーションに許可します。これにより悪意のあるアプリケーションが、携帯電話を乗っ取る恐れがあります。"</string> <string name="permlab_readInputState">"入力や操作の記録"</string> - <string name="permdesc_readInputState">"別のアプリケーションへの入力 (パスワードなど) でもキー入力を監視することをアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string> + <string name="permdesc_readInputState">"別のアプリケーションへの入力(パスワードなど)でもキー入力を監視することをアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string> <string name="permlab_bindInputMethod">"入力方法に関連付ける"</string> <string name="permdesc_bindInputMethod">"入力方法のトップレベルインターフェースに関連付けることを所有者に許可します。通常のアプリケーションにはまったく必要ありません。"</string> <string name="permlab_setOrientation">"画面の向きの変更"</string> <string name="permdesc_setOrientation">"いつでも画面の回転を変更することをアプリケーションに許可します。通常のアプリケーションにはまったく必要ありません。"</string> <string name="permlab_signalPersistentProcesses">"Linuxのシグナルをアプリケーションに送信"</string> - <string name="permdesc_signalPersistentProcesses">"すべての永続プロセスに特定の信号を送信するリクエストをアプリケーションに許可します。"</string> + <string name="permdesc_signalPersistentProcesses">"受信した電波を継続プロセスに送信することをアプリケーションに許可します。"</string> <string name="permlab_persistentActivity">"アプリケーションを常に実行する"</string> <string name="permdesc_persistentActivity">"自身を部分的に永続させて、他のアプリケーション用にはその領域をシステムに使わせないようにすることをアプリケーションに許可します。"</string> <string name="permlab_deletePackages">"アプリケーションの削除"</string> - <string name="permdesc_deletePackages">"Androidパッケージの削除をアプリケーションに許可します。これにより悪意のあるアプリケーションが、重要なアプリケーションを削除する恐れがあります。"</string> + <string name="permdesc_deletePackages">"Androidパッケージの削除をアプリケーションに許可します。悪意のあるアプリケーションが、重要なアプリケーションを削除する恐れがあります。"</string> <string name="permlab_clearAppUserData">"他のアプリケーションのデータを削除"</string> <string name="permdesc_clearAppUserData">"ユーザーデータの消去をアプリケーションに許可します。"</string> <string name="permlab_deleteCacheFiles">"他のアプリケーションのキャッシュを削除"</string> @@ -205,46 +205,46 @@ <string name="permlab_getPackageSize">"アプリケーションのメモリ容量の計測"</string> <string name="permdesc_getPackageSize">"アプリケーションのコード、データ、キャッシュのサイズを取得することを許可します。"</string> <string name="permlab_installPackages">"アプリケーションを直接インストール"</string> - <string name="permdesc_installPackages">"Androidパッケージを新たにインストールまたは更新することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、勝手に強力な権限を持つ新しいアプリケーションを追加する恐れがあります。"</string> + <string name="permdesc_installPackages">"Androidパッケージのインストール/更新をアプリケーションに許可します。悪意のあるアプリケーションが、勝手に強力な権限を持つ新しいアプリケーションを追加する恐れがあります。"</string> <string name="permlab_clearAppCache">"アプリケーションキャッシュデータの削除"</string> <string name="permdesc_clearAppCache">"アプリケーションのキャッシュディレクトリからファイルを削除して携帯電話のメモリを解放することをアプリケーションに許可します。通常、アクセスはシステムプロセスのみに制限されます。"</string> <string name="permlab_readLogs">"システムログファイルの読み取り"</string> <string name="permdesc_readLogs">"システムのさまざまなログファイルの読み取りをアプリケーションに許可します。これにより携帯電話の使用状況に関する全般情報が取得されますが、個人情報や非公開情報が含まれることはありません。"</string> <string name="permlab_diagnostic">"diagが所有するリソースの読み書き"</string> - <string name="permdesc_diagnostic">"diagグループが所有するリソース (/dev内のファイルなど) への読み書きをアプリケーションに許可します。これはシステムの安定性とセキュリティに影響する恐れがあります。メーカーまたはオペレータによるハードウェア固有の診断以外には使用しないでください。"</string> + <string name="permdesc_diagnostic">"diagグループが所有するリソース(例:/dev内のファイル)への読み書きをアプリケーションに許可します。システムの安定性とセキュリティに影響する恐れがあります。メーカー/オペレーターによるハードウェア固有の診断以外には使用しないでください。"</string> <string name="permlab_changeComponentState">"アプリケーションのコンポーネントを有効/無効にする"</string> <string name="permdesc_changeComponentState">"別アプリケーションのコンポーネントの有効/無効を変更することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、携帯電話の重要な機能を無効にする恐れがあります。アプリケーションコンポーネントが利用できない、整合性が取れない、または不安定な状態になる恐れがあるので、許可には注意が必要です。"</string> <string name="permlab_setPreferredApplications">"優先アプリケーションの設定"</string> - <string name="permdesc_setPreferredApplications">"優先アプリケーションを変更することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、実行中のアプリケーションを密かに変更し、既存のアプリケーションになりすまして、非公開データを収集する恐れがあります。"</string> - <string name="permlab_writeSettings">"システム全般の設定の変更"</string> + <string name="permdesc_setPreferredApplications">"優先アプリケーションを変更することをアプリケーションに許可します。悪意のあるアプリケーションが実行中のアプリケーションを密かに変更し、既存のアプリケーションになりすまして非公開データを収集する恐れがあります。"</string> + <string name="permlab_writeSettings">"システムの全般設定の変更"</string> <string name="permdesc_writeSettings">"システム設定データの変更をアプリケーションに許可します。悪意のあるアプリケーションがシステム設定を破壊する恐れがあります。"</string> <string name="permlab_writeSecureSettings">"システムのセキュリティ設定の変更"</string> <string name="permdesc_writeSecureSettings">"システムのセキュリティ設定の変更をアプリケーションに許可します。通常のアプリケーションでは使用しません。"</string> <string name="permlab_writeGservices">"Googleサービスの地図の変更"</string> <string name="permdesc_writeGservices">"Googleサービスマップの変更をアプリケーションに許可します。通常のアプリケーションでは使用しません。"</string> <string name="permlab_receiveBootCompleted">"起動時に自動的に開始"</string> - <string name="permdesc_receiveBootCompleted">"システムの起動直後に自動的に起動することをアプリケーションに許可します。これにより携帯電話の起動に時間がかかるようになります。また、アプリケーションが常に実行中となるため、携帯電話の全体的な動作が遅くなります。"</string> + <string name="permdesc_receiveBootCompleted">"システムの起動後に自動的に起動することをアプリケーションに許可します。携帯電話の起動に時間がかかるようになり、アプリケーションが常に実行されるために携帯電話の全体的な動作が遅くなります。"</string> <string name="permlab_broadcastSticky">"stickyブロードキャストの配信"</string> <string name="permdesc_broadcastSticky">"配信が終了してもメモリに残るようなstickyブロードキャストをアプリケーションに許可します。悪意のあるアプリケーションがメモリを使いすぎて、携帯電話の動作が遅くなったり、不安定になる恐れがあります。"</string> <string name="permlab_readContacts">"連絡先データの読み取り"</string> - <string name="permdesc_readContacts">"携帯電話に保存した連絡先 (アドレス) データをアプリケーションですべて読み取れるようにします。これにより悪意のあるアプリケーションが、そのデータを他人に送信する恐れがあります。"</string> + <string name="permdesc_readContacts">"端末に保存した連絡先(アドレス)データの読み取りをアプリケーションに許可します。悪意のあるアプリケーションがデータを他人に送信する恐れがあります。"</string> <string name="permlab_writeContacts">"連絡先データの書き込み"</string> - <string name="permdesc_writeContacts">"携帯電話に保存した連絡先 (アドレス) データの変更をアプリケーションに許可します。これにより悪意のあるアプリケーションが、連絡先データを消去や変更する恐れがあります。"</string> + <string name="permdesc_writeContacts">"端末に保存した連絡先(アドレス)データの変更をアプリケーションに許可します。悪意のあるアプリケーションが連絡先データを消去/変更する恐れがあります。"</string> <string name="permlab_writeOwnerData">"所有者データの書き込み"</string> - <string name="permdesc_writeOwnerData">"携帯電話に保存した所有者のデータの変更をアプリケーションに許可します。これにより悪意のあるアプリケーションが、所有者のデータを消去または変更する恐れがあります。"</string> + <string name="permdesc_writeOwnerData">"端末に保存した所有者のデータの変更をアプリケーションに許可します。悪意のあるアプリケーションが所有者のデータを消去/変更する恐れがあります。"</string> <string name="permlab_readOwnerData">"所有者データの読み取り"</string> - <string name="permdesc_readOwnerData">"携帯電話に保存した所有者データの読み取りをアプリケーションに許可します。これにより悪意のあるアプリケーションが、所有者データを読み取る恐れがあります。"</string> + <string name="permdesc_readOwnerData">"携帯電話に保存した所有者データの読み取りをアプリケーションに許可します。悪意のあるアプリケーションが所有者データを読み取る恐れがあります。"</string> <string name="permlab_readCalendar">"カレンダーデータの読み取り"</string> - <string name="permdesc_readCalendar">"携帯電話に保存したカレンダーのイベントをアプリケーションですべて読み取れるようにします。悪意のあるアプリケーションではこれを利用して、カレンダーのイベントを他人に送信できます。"</string> + <string name="permdesc_readCalendar">"端末に保存したカレンダーの予定の読み取りをアプリケーションに許可します。悪意のあるアプリケーションがカレンダーの予定を他人に送信する恐れがあります。"</string> <string name="permlab_writeCalendar">"カレンダーデータの書き込み"</string> - <string name="permdesc_writeCalendar">"携帯電話に保存したカレンダーイベントの変更をアプリケーションに許可します。これにより悪意のあるアプリケーションが、カレンダーデータを消去や変更する恐れがあります。"</string> + <string name="permdesc_writeCalendar">"端末に保存したカレンダーの予定の変更をアプリケーションに許可します。悪意のあるアプリケーションが、カレンダーデータを消去/変更する恐れがあります。"</string> <string name="permlab_accessMockLocation">"仮の位置情報でテスト"</string> <string name="permdesc_accessMockLocation">"テスト用に仮の位置情報源を作成します。これにより悪意のあるアプリケーションが、GPS、ネットワークプロバイダなどから返される本当の位置情報や状況を改ざんする恐れがあります。"</string> <string name="permlab_accessLocationExtraCommands">"位置情報プロバイダのその他のコマンドへのアクセス"</string> - <string name="permdesc_accessLocationExtraCommands">"位置情報プロバイダのその他のコマンドにアクセスします。これにより悪意のあるアプリケーションが、GPSなどの位置情報源の動作を妨害する恐れがあります。"</string> - <string name="permlab_accessFineLocation">"正確な (GPS) 位置"</string> - <string name="permdesc_accessFineLocation">"GPSなど、携帯電話の正確な位置情報源に、可能な場合アクセスします。これにより悪意のあるアプリケーションが、ユーザーの現在地を特定したり、バッテリの消費を増やしたりする恐れがあります。"</string> - <string name="permlab_accessCoarseLocation">"おおよその (ネットワーク情報による) 位置"</string> + <string name="permdesc_accessLocationExtraCommands">"位置情報提供元の追加コマンドにアクセスします。悪意のあるアプリケーションがGPSなどの位置提供の動作を妨害する恐れがあります。"</string> + <string name="permlab_accessFineLocation">"精細な位置情報(GPS)"</string> + <string name="permdesc_accessFineLocation">"GPSなど携帯電話の位置情報にアクセスします(可能な場合)。今いる場所が悪意のあるアプリケーションに検出されたり、バッテリーの消費が増える恐れがあります。"</string> + <string name="permlab_accessCoarseLocation">"おおよその位置情報(ネットワーク基地局)"</string> <string name="permdesc_accessCoarseLocation">"セルラーネットワークデータベースなど、携帯電話のおおよその位置を特定する情報源が利用可能な場合にアクセスします。これにより悪意のあるアプリケーションが、ユーザーのおおよその位置を特定できる恐れがあります。"</string> <string name="permlab_accessSurfaceFlinger">"SurfaceFlingerへのアクセス"</string> <string name="permdesc_accessSurfaceFlinger">"SurfaceFlingerの低レベルの機能の使用をアプリケーションに許可します。"</string> @@ -255,41 +255,37 @@ <string name="permlab_recordAudio">"録音"</string> <string name="permdesc_recordAudio">"オーディオ録音パスへのアクセスをアプリケーションに許可します。"</string> <string name="permlab_camera">"写真の撮影"</string> - <string name="permdesc_camera">"カメラで写真を撮ることをアプリケーションに許可します。これによりアプリケーションは、カメラに写る画像をいつでも収集できます。"</string> - <string name="permlab_brick">"携帯電話を永久に使用できなくする"</string> + <string name="permdesc_camera">"カメラでの写真撮影をアプリケーションに許可します。アプリケーションはカメラから画像をいつでも収集できます。"</string> + <string name="permlab_brick">"端末を永続的に無効にする"</string> <string name="permdesc_brick">"携帯電話全体を永続的に無効にすることをアプリケーションに許可します。この許可は非常に危険です。"</string> - <string name="permlab_reboot">"携帯電話の再起動"</string> - <string name="permdesc_reboot">"携帯電話の強制的な再起動をアプリケーションに許可します。"</string> + <string name="permlab_reboot">"端末の再起動"</string> + <string name="permdesc_reboot">"端末の強制的な再起動をアプリケーションに許可します。"</string> <string name="permlab_mount_unmount_filesystems">"ファイルシステムのマウントとマウント解除"</string> <string name="permdesc_mount_unmount_filesystems">"リムーバブルメモリのファイルシステムのマウントとマウント解除をアプリケーションに許可します。"</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> - <string name="permlab_vibrate">"バイブレータの制御"</string> - <string name="permdesc_vibrate">"バイブレータのコントロールをアプリケーションに許可します。"</string> + <string name="permlab_mount_format_filesystems">"外部ストレージのフォーマット"</string> + <string name="permdesc_mount_format_filesystems">"アプリケーションがリムーバブルストレージをフォーマットすることを許可します。"</string> + <string name="permlab_vibrate">"バイブレーション制御"</string> + <string name="permdesc_vibrate">"バイブレーションの制御をアプリケーションに許可します。"</string> <string name="permlab_flashlight">"ライトのコントロール"</string> <string name="permdesc_flashlight">"ライトの制御をアプリケーションに許可します。"</string> <string name="permlab_hardware_test">"ハードウェアのテスト"</string> <string name="permdesc_hardware_test">"ハードウェアのテストのためにさまざまな周辺機器を制御することをアプリケーションに許可します。"</string> - <string name="permlab_callPhone">"電話番号に直接発信"</string> - <string name="permdesc_callPhone">"電話を自動でかけることをアプリケーションに許可します。悪意のあるアプリケーションが予想外の電話をかけて、料金が発生する恐れがあります。緊急電話番号への通話は許可しません。"</string> - <string name="permlab_callPrivileged">"あらゆる電話番号に直接発信"</string> - <string name="permdesc_callPrivileged">"緊急電話を含めてあらゆる電話番号に自動発信することをアプリケーションに許可します。悪意のあるアプリケーションが緊急サービスに不要かつ不正な通話をする恐れがあります。"</string> - <string name="permlab_locationUpdates">"位置の更新通知の制御"</string> + <string name="permlab_callPhone">"電話番号発信"</string> + <string name="permdesc_callPhone">"アプリケーションが電話を自動発信することを許可します。悪意のあるアプリケーションが意図しない電話をかけて料金が発生する恐れがあります。緊急呼への発信は許可しません。"</string> + <string name="permlab_callPrivileged">"電話番号発信"</string> + <string name="permdesc_callPrivileged">"緊急呼を含めあらゆる電話番号に自動発信することをアプリケーションに許可します。悪意のあるアプリケーションが緊急サービスに不正な通報をする恐れがあります。"</string> + <string name="permlab_locationUpdates">"位置情報の更新通知"</string> <string name="permdesc_locationUpdates">"無線通信からの位置更新通知を有効/無効にすることを許可します。通常のアプリケーションでは使用しません。"</string> <string name="permlab_checkinProperties">"チェックインプロパティへのアクセス"</string> <string name="permdesc_checkinProperties">"チェックインサービスがアップロードしたプロパティへの読み書きを許可します。通常のアプリケーションでは使用しません。"</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> - <string name="permlab_modifyPhoneState">"携帯電話の状態の変更"</string> - <string name="permdesc_modifyPhoneState">"携帯端末の電話機能のコントロールをアプリケーションに許可します。この許可を受けたアプリケーションは、ネットワークの切り替え、携帯電話の無線通信のオン/オフなどを通知せずに行うことができます。"</string> - <string name="permlab_readPhoneState">"携帯電話の状態の読み取り"</string> - <string name="permdesc_readPhoneState">"携帯端末の電話機能へのアクセスをアプリケーションに許可します。これを許可されたアプリケーションは、この携帯電話の電話番号、通話中かどうか、通話相手の電話番号などを特定できます。"</string> - <string name="permlab_wakeLock">"携帯電話をスリープ状態にしない"</string> - <string name="permdesc_wakeLock">"携帯電話をスリープ状態にしないようにすることをアプリケーションに許可します。"</string> + <string name="permlab_bindGadget">"ガジェットの選択"</string> + <string name="permdesc_bindGadget">"特定のアプリケーションで使用可能なガジェットをシステムに指定することをアプリケーションに許可します。この許可を受けたアプリケーションは、他のアプリケーションに個人データへのアクセスを許可することができます。通常のアプリケーションでは使用しません。"</string> + <string name="permlab_modifyPhoneState">"端末ステータスの変更"</string> + <string name="permdesc_modifyPhoneState">"端末の電話機能のコントロールをアプリケーションに許可します。アプリケーションは、ネットワークの切り替え、携帯電話の無線通信のオン/オフなどを通知せずに行うことができます。"</string> + <string name="permlab_readPhoneState">"端末ステータスの読み取り"</string> + <string name="permdesc_readPhoneState">"端末の電話機能へのアクセスをアプリケーションに許可します。アプリケーションは、この携帯電話の電話番号、通話中かどうか、通話相手の電話番号などを特定できます。"</string> + <string name="permlab_wakeLock">"端末のスリープを無効にする"</string> + <string name="permdesc_wakeLock">"端末のスリープを無効にすることをアプリケーションに許可します。"</string> <string name="permlab_devicePower">"携帯電話の電源のオン/オフ"</string> <string name="permdesc_devicePower">"携帯電話の電源のオン/オフをアプリケーションに許可します。"</string> <string name="permlab_factoryTest">"出荷時試験モードでの実行"</string> @@ -298,82 +294,76 @@ <string name="permdesc_setWallpaper">"システムの壁紙の設定をアプリケーションに許可します。"</string> <string name="permlab_setWallpaperHints">"壁紙サイズのヒントの設定"</string> <string name="permdesc_setWallpaperHints">"システムの壁紙サイズのヒントの設定をアプリケーションに許可します。"</string> - <string name="permlab_masterClear">"システムを出荷時のデフォルトにリセット"</string> + <string name="permlab_masterClear">"システムを出荷時設定にリセット"</string> <string name="permdesc_masterClear">"データ、設定、インストールしたアプリケーションをすべて消去して、完全に出荷時の設定にシステムをリセットすることをアプリケーションに許可します。"</string> <string name="permlab_setTimeZone">"タイムゾーンの設定"</string> - <string name="permdesc_setTimeZone">"携帯電話のタイムゾーンの変更をアプリケーションに許可します。"</string> + <string name="permdesc_setTimeZone">"端末のタイムゾーンの変更をアプリケーションに許可します。"</string> <string name="permlab_getAccounts">"既知のアカウントの取得"</string> - <string name="permdesc_getAccounts">"携帯端末内にあるアカウントのリストの取得をアプリケーションに許可します。"</string> + <string name="permdesc_getAccounts">"端末内にあるアカウントのリストの取得をアプリケーションに許可します。"</string> <string name="permlab_accessNetworkState">"ネットワーク状態の表示"</string> <string name="permdesc_accessNetworkState">"すべてのネットワーク状態の表示をアプリケーションに許可します。"</string> - <string name="permlab_createNetworkSockets">"インターネットへの完全なアクセス権"</string> + <string name="permlab_createNetworkSockets">"完全なインターネットアクセス"</string> <string name="permdesc_createNetworkSockets">"ネットワークソケットの作成をアプリケーションに許可します。"</string> <string name="permlab_writeApnSettings">"アクセスポイント名設定の書き込み"</string> <string name="permdesc_writeApnSettings">"APNのプロキシやポートなどのAPN設定の変更をアプリケーションに許可します。"</string> <string name="permlab_changeNetworkState">"ネットワーク接続の変更"</string> <string name="permdesc_changeNetworkState">"ネットワークの接続状態の変更をアプリケーションに許可します。"</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"バックグラウンドデータ使用の設定の変更"</string> + <string name="permdesc_changeBackgroundDataSetting">"バックグラウンドデータ使用の設定の変更をアプリケーションに許可します。"</string> <string name="permlab_accessWifiState">"Wi-Fi状態の表示"</string> <string name="permdesc_accessWifiState">"Wi-Fi状態に関する情報の表示をアプリケーションに許可します。"</string> <string name="permlab_changeWifiState">"Wi-Fi状態の変更"</string> <string name="permdesc_changeWifiState">"Wi-Fiアクセスポイントへの接続や接続の切断、設定されたWi-Fiネットワークの変更をアプリケーションに許可します。"</string> <string name="permlab_bluetoothAdmin">"Bluetoothの管理"</string> - <string name="permdesc_bluetoothAdmin">"ローカルのBluetooth電話を設定し、リモートデバイスを検出してペアに設定することをアプリケーションに許可します。"</string> + <string name="permdesc_bluetoothAdmin">"このBluetooth端末の設定、およびリモート端末を検出してペアに設定することをアプリケーションに許可します。"</string> <string name="permlab_bluetooth">"Bluetooth接続の作成"</string> - <string name="permdesc_bluetooth">"ローカルBluetooth電話の設定を表示し、デバイスをペアとして設定して接続を承認することをアプリケーションに許可します。"</string> + <string name="permdesc_bluetooth">"このBluetooth端末の設定表示、および別の端末をペアとして設定し接続を承認することをアプリケーションに許可します。"</string> <string name="permlab_disableKeyguard">"キーロックを無効にする"</string> <string name="permdesc_disableKeyguard">"キーロックや関連するパスワードセキュリティを無効にすることをアプリケーションに許可します。正当な利用の例では、かかってきた電話を受信する際にキーロックを無効にし、通話の終了時にキーロックを有効にし直します。"</string> <string name="permlab_readSyncSettings">"同期設定の読み取り"</string> - <string name="permdesc_readSyncSettings">"連絡先の同期が有効かどうかなど、同期設定の読み取りをアプリケーションに許可します。"</string> + <string name="permdesc_readSyncSettings">"連絡先の同期の有効/無効など、同期設定の読み取りをアプリケーションに許可します。"</string> <string name="permlab_writeSyncSettings">"同期設定の書き込み"</string> - <string name="permdesc_writeSyncSettings">"連絡先の同期が有効かどうかなど、同期設定の変更をアプリケーションに許可します。"</string> + <string name="permdesc_writeSyncSettings">"連絡先の同期の有効/無効など、同期設定の変更をアプリケーションに許可します。"</string> <string name="permlab_readSyncStats">"同期統計の読み取り"</string> - <string name="permdesc_readSyncStats">"同期状態 (同期履歴など) の読み取りをアプリケーションに許可します。"</string> + <string name="permdesc_readSyncStats">"同期状態(同期履歴など)の読み取りをアプリケーションに許可します。"</string> <string name="permlab_subscribedFeedsRead">"登録したフィードの読み取り"</string> <string name="permdesc_subscribedFeedsRead">"現在同期しているフィードの詳細の取得をアプリケーションに許可します。"</string> <string name="permlab_subscribedFeedsWrite">"登録したフィードの書き込み"</string> <string name="permdesc_subscribedFeedsWrite">"現在同期しているフィードの変更をアプリケーションに許可します。悪意のあるアプリケーションが同期フィードを変更する恐れがあります。"</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"ユーザー定義辞書の読み込み"</string> + <string name="permdesc_readDictionary">"アプリケーションがユーザー辞書に登録されている個人的な語句や名前を読み込むことを許可します。"</string> + <string name="permlab_writeDictionary">"ユーザー定義辞書への書き込み"</string> + <string name="permdesc_writeDictionary">"アプリケーションがユーザー辞書に新しい語句を書き込むことを許可します。"</string> <string-array name="phoneTypes"> <item>"自宅"</item> <item>"携帯"</item> - <item>"勤務先"</item> - <item>"勤務先FAX"</item> - <item>"自宅FAX"</item> + <item>"仕事"</item> + <item>"FAX(仕事)"</item> + <item>"FAX(自宅)"</item> <item>"ポケベル"</item> <item>"その他"</item> <item>"カスタム"</item> </string-array> <string-array name="emailAddressTypes"> <item>"自宅"</item> - <item>"勤務先"</item> + <item>"仕事"</item> <item>"その他"</item> <item>"カスタム"</item> </string-array> <string-array name="postalAddressTypes"> <item>"自宅"</item> - <item>"勤務先"</item> + <item>"仕事"</item> <item>"その他"</item> <item>"カスタム"</item> </string-array> <string-array name="imAddressTypes"> <item>"自宅"</item> - <item>"勤務先"</item> + <item>"仕事"</item> <item>"その他"</item> <item>"カスタム"</item> </string-array> <string-array name="organizationTypes"> - <item>"勤務先"</item> + <item>"仕事"</item> <item>"その他"</item> <item>"カスタム"</item> </string-array> @@ -389,31 +379,31 @@ </string-array> <string name="keyguard_password_enter_pin_code">"PINコードを入力"</string> <string name="keyguard_password_wrong_pin_code">"PINコードが正しくありません。"</string> - <string name="keyguard_label_text">"ロックを解除するには、Menu、0キーの順に押します。"</string> - <string name="emergency_call_dialog_number_for_display">"緊急電話番号"</string> - <string name="lockscreen_carrier_default">"(サービスなし)"</string> - <string name="lockscreen_screen_locked">"画面がロックされています。"</string> - <string name="lockscreen_instructions_when_pattern_enabled">"Menuキーを押してロックを解除するか、緊急電話をかけます。"</string> - <string name="lockscreen_instructions_when_pattern_disabled">"ロックを解除するにはMenuキーを押します。"</string> + <string name="keyguard_label_text">"ロックを解除するにはMENU、0キーの順に押します。"</string> + <string name="emergency_call_dialog_number_for_display">"緊急呼番号"</string> + <string name="lockscreen_carrier_default">"(サービス登録なし)"</string> + <string name="lockscreen_screen_locked">"画面ロック中"</string> + <string name="lockscreen_instructions_when_pattern_enabled">"MENUキーでロック解除(または緊急呼)"</string> + <string name="lockscreen_instructions_when_pattern_disabled">"MENUキーでロック解除"</string> <string name="lockscreen_pattern_instructions">"ロックを解除するパターンを入力"</string> - <string name="lockscreen_emergency_call">"緊急電話"</string> + <string name="lockscreen_emergency_call">"緊急呼"</string> <string name="lockscreen_pattern_correct">"一致しました"</string> - <string name="lockscreen_pattern_wrong">"もう一度試してください"</string> + <string name="lockscreen_pattern_wrong">"やり直してください"</string> <string name="lockscreen_plugged_in">"充電中 (<xliff:g id="NUMBER">%d%%</xliff:g>)"</string> <string name="lockscreen_low_battery">"充電してください。"</string> - <string name="lockscreen_missing_sim_message_short">"SIMカードがありません。"</string> - <string name="lockscreen_missing_sim_message">"SIMカードが携帯電話に挿入されていません。"</string> + <string name="lockscreen_missing_sim_message_short">"SIMカードが挿入されていません"</string> + <string name="lockscreen_missing_sim_message">"SIMカードが挿入されていません"</string> <string name="lockscreen_missing_sim_instructions">"SIMカードを挿入してください。"</string> <string name="lockscreen_network_locked_message">"ネットワークがロックされました"</string> <string name="lockscreen_sim_puk_locked_message">"SIMカードはPUKでロックされています。"</string> <string name="lockscreen_sim_puk_locked_instructions">"お客様サポートにお問い合わせください。"</string> <string name="lockscreen_sim_locked_message">"SIMカードはロックされています。"</string> - <string name="lockscreen_sim_unlock_progress_dialog_message">"SIMカードのロックを解除中..."</string> + <string name="lockscreen_sim_unlock_progress_dialog_message">"SIMカードのロック解除中..."</string> <string name="lockscreen_too_many_failed_attempts_dialog_message">"ロック解除のパターンは<xliff:g id="NUMBER_0">%d</xliff:g>回とも正しく指定されていません。"\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度指定してください。"</string> <string name="lockscreen_failed_attempts_almost_glogin">"指定したパターンは<xliff:g id="NUMBER_0">%d</xliff:g>回とも正しくありません。あと<xliff:g id="NUMBER_1">%d</xliff:g>回指定に失敗すると、携帯電話のロックの解除にGoogleへのログインが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度指定してください。"</string> - <string name="lockscreen_too_many_failed_attempts_countdown">"<xliff:g id="NUMBER">%d</xliff:g>秒後にもう一度試してください。"</string> + <string name="lockscreen_too_many_failed_attempts_countdown">"<xliff:g id="NUMBER">%d</xliff:g>秒後にやり直してください。"</string> <string name="lockscreen_forgot_pattern_button_text">"パターンを忘れた場合"</string> - <string name="lockscreen_glogin_too_many_attempts">"パターンの指定回数が多すぎる"</string> + <string name="lockscreen_glogin_too_many_attempts">"パターンのエラーが多すぎます"</string> <string name="lockscreen_glogin_instructions">"ロックを解除するには、"\n"Googleアカウントでログインしてください。"</string> <string name="lockscreen_glogin_username_hint">"ユーザー名 (メール)"</string> <string name="lockscreen_glogin_password_hint">"パスワード"</string> @@ -434,27 +424,24 @@ <skip /> <string name="battery_status_charging">"充電中..."</string> <string name="battery_low_title">"充電してください"</string> - <string name="battery_low_subtitle">"バッテリの残量が少なくなっています。"</string> + <string name="battery_low_subtitle">"電池が残り少なくなっています:"</string> <string name="battery_low_percent_format">"残り<xliff:g id="NUMBER">%d%%</xliff:g>未満"</string> <string name="factorytest_failed">"出荷時試験が失敗"</string> <string name="factorytest_not_system">"FACTORY_TEST操作は、/system/appにインストールされたパッケージのみが対象です。"</string> <string name="factorytest_no_action">"FACTORY_TEST操作を行うパッケージは見つかりませんでした。"</string> <string name="factorytest_reboot">"再起動"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"ページ「<xliff:g id="TITLE">%s</xliff:g>」の記述:"</string> + <string name="js_dialog_title_default">"JavaScript"</string> + <string name="js_dialog_before_unload">"このページから移動しますか?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"続行する場合は[OK]、今のページに残る場合は[キャンセル]を選択してください。"</string> <string name="save_password_label">"確認"</string> <string name="save_password_message">"このパスワードをブラウザで保存しますか?"</string> <string name="save_password_notnow">"今は保存しない"</string> <string name="save_password_remember">"保存"</string> <string name="save_password_never">"保存しない"</string> <string name="open_permission_deny">"このページへのアクセスは許可されていません。"</string> - <string name="text_copied">"テキストがクリップボードにコピーされました。"</string> + <string name="text_copied">"テキストをクリップボードにコピーしました。"</string> <string name="more_item_label">"その他"</string> - <string name="prepend_shortcut_label">"Menu+"</string> + <string name="prepend_shortcut_label">"MENU+"</string> <string name="menu_space_shortcut_label">"Space"</string> <string name="menu_enter_shortcut_label">"Enter"</string> <string name="menu_delete_shortcut_label">"Del"</string> @@ -496,22 +483,38 @@ <item quantity="one">"明日"</item> <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>日後"</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"1秒前"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>秒前"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"1分前"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>分後"</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"1時間前"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>時間前"</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"昨日"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>日前"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"1秒後"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>秒後"</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"1分後"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>分後"</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"1時間後"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>時間後"</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"明日"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>日後"</item> + </plurals> <string name="preposition_for_date">"%s"</string> <string name="preposition_for_time">"%s"</string> <string name="preposition_for_year">"%s年"</string> @@ -527,14 +530,14 @@ <string name="weeks">"週間"</string> <string name="year">"年"</string> <string name="years">"年"</string> - <string name="sunday">"日曜"</string> - <string name="monday">"月曜"</string> - <string name="tuesday">"火曜"</string> - <string name="wednesday">"水曜"</string> - <string name="thursday">"木曜"</string> - <string name="friday">"金曜"</string> - <string name="saturday">"土曜"</string> - <string name="every_weekday">"平日の毎日 (月~金)"</string> + <string name="sunday">"日曜日"</string> + <string name="monday">"月曜日"</string> + <string name="tuesday">"火曜日"</string> + <string name="wednesday">"水曜日"</string> + <string name="thursday">"木曜日"</string> + <string name="friday">"金曜日"</string> + <string name="saturday">"土曜日"</string> + <string name="every_weekday">"平日(月~金)"</string> <string name="daily">"毎日"</string> <string name="weekly">"毎週<xliff:g id="DAY">%s</xliff:g>"</string> <string name="monthly">"毎月"</string> @@ -545,25 +548,23 @@ <string name="am">"AM"</string> <string name="pm">"PM"</string> <string name="numeric_date">"<xliff:g id="YEAR">%Y</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="DAY">%d</xliff:g>"</string> - <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%3$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g> (<xliff:g id="WEEKDAY2">%4$s</xliff:g>) <xliff:g id="TIME2">%6$s</xliff:g>"</string> - <string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="DATE2">%5$s</xliff:g> (<xliff:g id="WEEKDAY2">%4$s</xliff:g>)"</string> + <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%3$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g><xliff:g id="TIME2">%6$s</xliff:g>"</string> + <string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g>"</string> <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string> <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g>"</string> <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g>~<xliff:g id="TIME2">%2$s</xliff:g>"</string> - <string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g> (<xliff:g id="WEEKDAY">%2$s</xliff:g>) <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string> - <string name="wday_date">"<xliff:g id="DATE">%3$s</xliff:g> (<xliff:g id="WEEKDAY">%2$s</xliff:g>)"</string> + <string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g><xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string> + <string name="wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="DATE">%3$s</xliff:g>、<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>、<xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>、<xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g>、<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string> - <string name="full_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string> - <string name="medium_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string> - <string name="medium_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>'/'<xliff:g id="MONTH">MMMM</xliff:g>'/'<xliff:g id="DAY">d</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>'年'<xliff:g id="MONTH">MMMM</xliff:g>'月'<xliff:g id="DAY">d</xliff:g>'日'"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>'/'<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>'年'"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'/'<xliff:g id="MONTH">MMM</xliff:g>'/'<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"正午"</string> <string name="Noon">"正午"</string> <string name="midnight">"午前0時"</string> @@ -576,66 +577,66 @@ <!-- no translation found for month_year (9219019380312413367) --> <skip /> <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string> - <string name="date_and_time">"<xliff:g id="YEAR">%Y</xliff:g>年<xliff:g id="MONTH">%B</xliff:g><xliff:g id="DAY">%-d</xliff:g>日<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string> - <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日"</string> - <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string> - <string name="same_year_mdy1_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日"</string> - <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string> - <string name="same_year_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日<xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日<xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日<xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日<xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="date_and_time">"<xliff:g id="YEAR">%Y</xliff:g>/<xliff:g id="MONTH">%B</xliff:g>/<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string> + <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="MONTH2">%7$s</xliff:g>月<xliff:g id="DAY2">%8$s</xliff:g>日"</string> + <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string> + <string name="same_year_mdy1_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="MONTH2">%7$s</xliff:g>月<xliff:g id="DAY2">%8$s</xliff:g>日"</string> + <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string> + <string name="same_year_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日<xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>月<xliff:g id="DAY2">%8$s</xliff:g>日<xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日 <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g>月<xliff:g id="DAY2">%8$s</xliff:g>日 <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string> <string name="numeric_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string> - <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g> (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string> + <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string> <string name="numeric_mdy1_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string> - <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g> (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string> + <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string> <string name="numeric_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g> (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string> <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g> (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_month_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="DAY2">%8$s</xliff:g>日"</string> - <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string> - <string name="same_month_mdy1_mdy2">"<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="DAY2">%8$s</xliff:g>日"</string> - <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string> - <string name="same_month_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日<xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日<xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日<xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日<xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="abbrev_month_day_year">"<xliff:g id="YEAR">%Y</xliff:g>年<xliff:g id="MONTH">%b</xliff:g><xliff:g id="DAY">%-d</xliff:g>日"</string> + <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_month_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="DAY2">%8$s</xliff:g>日"</string> + <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string> + <string name="same_month_mdy1_mdy2">"<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="DAY2">%8$s</xliff:g>日"</string> + <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string> + <string name="same_month_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="abbrev_month_day_year">"<xliff:g id="YEAR">%Y</xliff:g>/<xliff:g id="MONTH">%b</xliff:g>/<xliff:g id="DAY">%-d</xliff:g>"</string> <!-- no translation found for abbrev_month_year (3856424847226891943) --> <skip /> <!-- no translation found for abbrev_month_day (5028815883653985933) --> <skip /> <!-- no translation found for abbrev_month (3131032032850777433) --> <skip /> - <string name="day_of_week_long_sunday">"日曜"</string> - <string name="day_of_week_long_monday">"月曜"</string> - <string name="day_of_week_long_tuesday">"火曜"</string> - <string name="day_of_week_long_wednesday">"水曜"</string> - <string name="day_of_week_long_thursday">"木曜"</string> - <string name="day_of_week_long_friday">"金曜"</string> - <string name="day_of_week_long_saturday">"土曜"</string> - <string name="day_of_week_medium_sunday">"日"</string> - <string name="day_of_week_medium_monday">"月"</string> - <string name="day_of_week_medium_tuesday">"火"</string> - <string name="day_of_week_medium_wednesday">"水"</string> - <string name="day_of_week_medium_thursday">"木"</string> - <string name="day_of_week_medium_friday">"金"</string> - <string name="day_of_week_medium_saturday">"土"</string> - <string name="day_of_week_short_sunday">"日"</string> - <string name="day_of_week_short_monday">"月"</string> - <string name="day_of_week_short_tuesday">"火"</string> - <string name="day_of_week_short_wednesday">"水"</string> - <string name="day_of_week_short_thursday">"木"</string> - <string name="day_of_week_short_friday">"金"</string> - <string name="day_of_week_short_saturday">"土"</string> - <string name="day_of_week_shorter_sunday">"日"</string> + <string name="day_of_week_long_sunday">"日曜日"</string> + <string name="day_of_week_long_monday">"月曜日"</string> + <string name="day_of_week_long_tuesday">"火曜日"</string> + <string name="day_of_week_long_wednesday">"水曜日"</string> + <string name="day_of_week_long_thursday">"木曜日"</string> + <string name="day_of_week_long_friday">"金曜日"</string> + <string name="day_of_week_long_saturday">"土曜日"</string> + <string name="day_of_week_medium_sunday">"(日)"</string> + <string name="day_of_week_medium_monday">"(月)"</string> + <string name="day_of_week_medium_tuesday">"(火)"</string> + <string name="day_of_week_medium_wednesday">"(水)"</string> + <string name="day_of_week_medium_thursday">"(木)"</string> + <string name="day_of_week_medium_friday">"(金)"</string> + <string name="day_of_week_medium_saturday">"(土)"</string> + <string name="day_of_week_short_sunday">"(日)"</string> + <string name="day_of_week_short_monday">"(月)"</string> + <string name="day_of_week_short_tuesday">"(火)"</string> + <string name="day_of_week_short_wednesday">"(水)"</string> + <string name="day_of_week_short_thursday">"(木)"</string> + <string name="day_of_week_short_friday">"(金)"</string> + <string name="day_of_week_short_saturday">"(土)"</string> + <string name="day_of_week_shorter_sunday">"(日)"</string> <string name="day_of_week_shorter_monday">"月"</string> - <string name="day_of_week_shorter_tuesday">"火"</string> + <string name="day_of_week_shorter_tuesday">"(火)"</string> <string name="day_of_week_shorter_wednesday">"水"</string> - <string name="day_of_week_shorter_thursday">"木"</string> + <string name="day_of_week_shorter_thursday">"(木)"</string> <string name="day_of_week_shorter_friday">"金"</string> - <string name="day_of_week_shorter_saturday">"土"</string> + <string name="day_of_week_shorter_saturday">"(土)"</string> <string name="day_of_week_shortest_sunday">"日"</string> <string name="day_of_week_shortest_monday">"月"</string> <string name="day_of_week_shortest_tuesday">"火"</string> @@ -669,7 +670,7 @@ <string name="month_medium_december">"12月"</string> <string name="month_shortest_january">"1"</string> <string name="month_shortest_february">"2"</string> - <string name="month_shortest_march">"月"</string> + <string name="month_shortest_march">"3"</string> <string name="month_shortest_april">"4"</string> <string name="month_shortest_may">"5"</string> <string name="month_shortest_june">"6"</string> @@ -691,8 +692,7 @@ <string name="paste">"貼り付け"</string> <string name="copyUrl">"URLをコピー"</string> <string name="inputMethod">"入力方法"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"辞書に「%s」を追加"</string> <string name="editTextMenuTitle">"テキストを編集"</string> <string name="low_internal_storage_view_title">"空き容量低下"</string> <string name="low_internal_storage_view_text">"携帯電話の空き容量が少なくなっています。"</string> @@ -700,44 +700,42 @@ <string name="cancel">"キャンセル"</string> <string name="yes">"OK"</string> <string name="no">"キャンセル"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"注意"</string> <string name="capital_on">"オン"</string> <string name="capital_off">"オフ"</string> <string name="whichApplication">"操作の完了に使用"</string> - <string name="alwaysUse">"この操作にデフォルトで使用します。"</string> - <string name="clearDefaultHintMsg">"ホームの[設定]>[アプリケーション]>[アプリケーションを管理]で、デフォルトをクリアします。"</string> + <string name="alwaysUse">"常にこの操作で使用する"</string> + <string name="clearDefaultHintMsg">"ホームの[設定]>[アプリケーション]>[アプリケーションの管理]でデフォルト設定をクリアします。"</string> <string name="chooseActivity">"操作の選択"</string> <string name="noApplications">"この操作を実行できるアプリケーションはありません。"</string> <string name="aerr_title">"エラー"</string> - <string name="aerr_application">"アプリケーション<xliff:g id="APPLICATION">%1$s</xliff:g> (<xliff:g id="PROCESS">%2$s</xliff:g>プロセス) が予期せず停止しました。もう一度試してください。"</string> - <string name="aerr_process">"<xliff:g id="PROCESS">%1$s</xliff:g>プロセスが予期せず停止しました。もう一度試してください。"</string> + <string name="aerr_application">"<xliff:g id="APPLICATION">%1$s</xliff:g>(<xliff:g id="PROCESS">%2$s</xliff:g>)が予期せず停止しました。やり直してください。"</string> + <string name="aerr_process">"<xliff:g id="PROCESS">%1$s</xliff:g>が予期せず停止しました。やり直してください。"</string> <string name="anr_title">"エラー"</string> - <string name="anr_activity_application">"<xliff:g id="ACTIVITY">%1$s</xliff:g>操作 (アプリケーション<xliff:g id="APPLICATION">%2$s</xliff:g>) は応答していません。"</string> - <string name="anr_activity_process">"<xliff:g id="ACTIVITY">%1$s</xliff:g>操作 (プロセス:<xliff:g id="PROCESS">%2$s</xliff:g>) は応答していません。"</string> - <string name="anr_application_process">"アプリケーション<xliff:g id="APPLICATION">%1$s</xliff:g> (<xliff:g id="PROCESS">%2$s</xliff:g>プロセス) は応答していません。"</string> - <string name="anr_process">"<xliff:g id="PROCESS">%1$s</xliff:g>プロセスは応答していません。"</string> + <string name="anr_activity_application">"<xliff:g id="ACTIVITY">%1$s</xliff:g>(<xliff:g id="APPLICATION">%2$s</xliff:g>)は応答していません。"</string> + <string name="anr_activity_process">"<xliff:g id="ACTIVITY">%1$s</xliff:g>(プロセス: <xliff:g id="PROCESS">%2$s</xliff:g>)は応答していません。"</string> + <string name="anr_application_process">"<xliff:g id="APPLICATION">%1$s</xliff:g>(<xliff:g id="PROCESS">%2$s</xliff:g>)は応答していません。"</string> + <string name="anr_process">"<xliff:g id="PROCESS">%1$s</xliff:g>は応答していません。"</string> <string name="force_close">"強制終了"</string> <string name="wait">"待機"</string> <string name="debug">"デバッグ"</string> - <string name="sendText">"テキストの操作の選択"</string> + <string name="sendText">"テキストの操作"</string> <string name="volume_ringtone">"着信音の音量"</string> <string name="volume_music">"メディアの音量"</string> <string name="volume_music_hint_playing_through_bluetooth">"Bluetooth経由で再生中です"</string> <string name="volume_call">"着信音の音量"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"Bluetooth着信音の音量"</string> <string name="volume_alarm">"アラームの音量"</string> <string name="volume_notification">"通知音の音量"</string> <string name="volume_unknown">"音量"</string> <string name="ringtone_default">"デフォルトの着信音"</string> - <string name="ringtone_default_with_actual">"デフォルトの着信音 (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <string name="ringtone_default_with_actual">"端末既定の着信音(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> <string name="ringtone_silent">"無音"</string> <string name="ringtone_picker_title">"着信音"</string> - <string name="ringtone_unknown">"不明時着信音"</string> + <string name="ringtone_unknown">"不明な着信音"</string> <plurals name="wifi_available"> - <item quantity="one">"Wi-Fiネットワークが利用可能"</item> - <item quantity="other">"Wi-Fiネットワークが利用可能"</item> + <item quantity="one">"Wi-Fiを利用できます"</item> + <item quantity="other">"Wi-Fiを利用できます"</item> </plurals> <plurals name="wifi_available_detailed"> <item quantity="one">"Wi-Fiオープンネットワークが利用できます"</item> @@ -746,12 +744,12 @@ <string name="select_character">"文字を挿入"</string> <string name="sms_control_default_app_name">"不明なアプリケーション"</string> <string name="sms_control_title">"SMSメッセージの送信中"</string> - <string name="sms_control_message">"大量のSMSメッセージが送信されます。送信するには[OK]、中止するには[キャンセル]を選択します。"</string> + <string name="sms_control_message">"大量のSMSメッセージを送信しようとしています。[OK]で送信、[キャンセル]で中止します。"</string> <string name="sms_control_yes">"OK"</string> <string name="sms_control_no">"キャンセル"</string> <string name="date_time_set">"設定"</string> - <string name="default_permission_group">"デフォルト"</string> - <string name="no_permissions">"許可は必要ありません"</string> + <string name="default_permission_group">"端末既定"</string> + <string name="no_permissions">"権限付与の必要はありません"</string> <string name="perms_hide"><b>"隠す"</b></string> <string name="perms_show_all"><b>"すべて表示"</b></string> <string name="googlewebcontenthelper_loading">"読み込み中..."</string> @@ -762,60 +760,35 @@ <string name="usb_storage_error_message">"USBメモリにSDカードを使用する際に問題が発生しました。"</string> <string name="usb_storage_notification_title">"USB接続"</string> <string name="usb_storage_notification_message">"パソコンとの間でファイルをコピーします。"</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"USBストレージをOFFにする"</string> + <string name="usb_storage_stop_notification_message">"USBストレージをOFFにする場合に選択します。"</string> + <string name="usb_storage_stop_title">"USBストレージをOFFにする"</string> + <string name="usb_storage_stop_message">"USBストレージをOFFにする前にUSBホストのマウントを解除したことを確認してください。USBストレージをOFFにするには[OFF]を選択します。"</string> + <string name="usb_storage_stop_button_mount">"OFF"</string> + <string name="usb_storage_stop_button_unmount">"キャンセル"</string> + <string name="usb_storage_stop_error_message">"USBストレージをOFFにする際に問題が発生しました。USBホストのマウントが解除されていることを確認してからもう一度お試しください。"</string> + <string name="extmedia_format_title">"SDカードをフォーマット"</string> + <string name="extmedia_format_message">"SDカードをフォーマットしてもよろしいですか?カード内のすべてのデータが失われます。"</string> + <string name="extmedia_format_button_format">"フォーマット"</string> <string name="select_input_method">"入力方法の選択"</string> <string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"候補"</u></string> + <string name="ext_media_checking_notification_title">"SDカードの準備中"</string> + <string name="ext_media_checking_notification_message">"エラーを確認中"</string> + <string name="ext_media_nofs_notification_title">"空のSDカード"</string> + <string name="ext_media_nofs_notification_message">"SDカードが空か、サポート対象外のファイルシステムを使用しています。"</string> + <string name="ext_media_unmountable_notification_title">"破損したSDカード"</string> + <string name="ext_media_unmountable_notification_message">"SDカードが破損しています。カードのフォーマットが必要な可能性があります。"</string> + <string name="ext_media_badremoval_notification_title">"SDカードが予期せず取り外されました"</string> + <string name="ext_media_badremoval_notification_message">"データの喪失を防ぐためSDカードを取り外す前にマウントを解除してください。"</string> + <string name="ext_media_safe_unmount_notification_title">"SDカードを安全に取り外しました"</string> + <string name="ext_media_safe_unmount_notification_message">"SDカードを安全に取り外せます。"</string> + <string name="ext_media_nomedia_notification_title">"SDカードが取り外されています"</string> + <string name="ext_media_nomedia_notification_message">"SDカードが取り外されました。新しいSDカードを挿入して端末のメモリを増やしてください。"</string> + <string name="activity_list_empty">"一致するアクティビティが見つかりません"</string> + <string name="permlab_pkgUsageStats">"コンポーネント使用状況に関する統計情報の更新"</string> + <string name="permdesc_pkgUsageStats">"収集されたコンポーネント使用状況に関する統計情報の変更を許可します。通常のアプリケーションでは使用しません。"</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 140f32f..311f501 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -262,10 +262,8 @@ <string name="permdesc_reboot">"응용프로그램이 전화기를 강제로 다시 부팅할 수 있습니다."</string> <string name="permlab_mount_unmount_filesystems">"파일시스템 마운트 및 마운트 해제"</string> <string name="permdesc_mount_unmount_filesystems">"응용프로그램이 이동식 저장소의 파일시스템을 마운트하고 마운트 해제할 수 있습니다."</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> + <string name="permlab_mount_format_filesystems">"외부 저장소 포맷"</string> + <string name="permdesc_mount_format_filesystems">"응용프로그램이 제거 가능한 저장소를 포맷하도록 합니다."</string> <string name="permlab_vibrate">"진동 제어"</string> <string name="permdesc_vibrate">"응용프로그램이 진동을 제어할 수 있습니다."</string> <string name="permlab_flashlight">"손전등 제어"</string> @@ -280,10 +278,8 @@ <string name="permdesc_locationUpdates">"무선의 위치 업데이트 알림을 활성화하거나 비활성화할 수 있습니다. 일반 응용프로그램에서는 사용하지 않습니다."</string> <string name="permlab_checkinProperties">"체크인 속성 액세스"</string> <string name="permdesc_checkinProperties">"체크인 서비스에서 업로드한 속성에 대한 읽기/쓰기 액세스를 허용합니다. 일반 응용프로그램에서는 사용하지 않습니다."</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> + <string name="permlab_bindGadget">"가젯 선택"</string> + <string name="permdesc_bindGadget">"어느 응용프로그램이 어느 가젯을 사용할 수 있는지 시스템에 알려 주는 권한을 본 응용프로그램에 부여합니다. 이 권한을 사용하면 응용프로그램이 개인 데이터에 대한 액세스 권한을 다른 응용프로그램에 제공할 수 있습니다. 일반 응용프로그램은 이 권한을 사용할 수 없습니다."</string> <string name="permlab_modifyPhoneState">"전화기 상태 수정"</string> <string name="permdesc_modifyPhoneState">"응용프로그램이 장치의 전화 기능을 제어할 수 있습니다. 이 권한을 갖는 응용프로그램은 사용자에게 알리지 않고 네트워크를 전환하거나, 전화 무선 기능을 켜고 끌 수 있습니다."</string> <string name="permlab_readPhoneState">"전화기 상태 읽기"</string> @@ -312,10 +308,8 @@ <string name="permdesc_writeApnSettings">"응용프로그램이 APN의 프록시 및 포트 같은 APN 설정을 수정할 수 있습니다."</string> <string name="permlab_changeNetworkState">"네트워크 연결 변경"</string> <string name="permdesc_changeNetworkState">"응용프로그램이 네트워크 연결 상태를 변경할 수 있습니다."</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"백그라운드 데이터 사용 설정 변경"</string> + <string name="permdesc_changeBackgroundDataSetting">"백그라운드 데이터 사용 설정을 변경할 수 있는 권한을 응용프로그램에 부여합니다."</string> <string name="permlab_accessWifiState">"Wi-Fi 상태 보기"</string> <string name="permdesc_accessWifiState">"응용프로그램이 Wi-Fi의 상태에 대한 정보를 볼 수 있습니다."</string> <string name="permlab_changeWifiState">"Wi-Fi 상태 변경"</string> @@ -336,14 +330,10 @@ <string name="permdesc_subscribedFeedsRead">"응용프로그램이 현재 동기화된 피드에 대한 상세정보를 가져올 수 있습니다."</string> <string name="permlab_subscribedFeedsWrite">"가입 피드 작성"</string> <string name="permdesc_subscribedFeedsWrite">"응용프로그램이 현재 동기화된 피드를 수정할 수 있습니다. 악성 응용프로그램은 이 기능을 이용하여 동기화된 피드를 변경할 수 있습니다."</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"상용자 정의 사전 읽기"</string> + <string name="permdesc_readDictionary">"응용프로그램이 사용자 사전에 보관되어 있을 수 있는 비공개 단어, 이름 및 구문을 읽도록 합니다."</string> + <string name="permlab_writeDictionary">"상용자 정의 사전에 작성"</string> + <string name="permdesc_writeDictionary">"응용프로그램이 사용자 사전에 새 단어를 입력할 수 있습니다."</string> <string-array name="phoneTypes"> <item>"집"</item> <item>"휴대전화"</item> @@ -440,12 +430,9 @@ <string name="factorytest_not_system">"FACTORY_TEST 작업은 /system/app 디렉토리에 설치된 패키지에 대해서만 지원됩니다."</string> <string name="factorytest_no_action">"FACTORY_TEST 작업을 제공하는 패키지가 없습니다."</string> <string name="factorytest_reboot">"다시 부팅"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"\'<xliff:g id="TITLE">%s</xliff:g>\' 페이지 내용:"</string> + <string name="js_dialog_title_default">"자바스크립트"</string> + <string name="js_dialog_before_unload">"다른 페이지를 탐색하시겠습니까?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"계속하려면 \'확인\'을 선택하고 현재 페이지에 그대로 있으려면 \'취소\'를 선택하세요."</string> <string name="save_password_label">"확인"</string> <string name="save_password_message">"브라우저에 이 비밀번호를 저장하시겠습니까?"</string> <string name="save_password_notnow">"나중에"</string> @@ -496,22 +483,38 @@ <item quantity="one">"내일"</item> <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>일 후"</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"1초 전"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 초 전"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"1분 전"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>분 전"</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"1시간 전"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>시간 전"</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"어제"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>일 전"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"1초 후"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 초 후"</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"1분 후"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>분 후"</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"1시간 후"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>시간 후"</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"내일"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>일 후"</item> + </plurals> <string name="preposition_for_date">"%s"</string> <string name="preposition_for_time">"%s"</string> <string name="preposition_for_year">"%s년"</string> @@ -553,17 +556,15 @@ <string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string> <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="DATE">%3$s</xliff:g>, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="DAY">d</xliff:g>"</string> - <string name="full_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="DAY">d</xliff:g>"</string> - <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="DAY">d</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="DAY">d</xliff:g>"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"정오"</string> <string name="Noon">"정오"</string> <string name="midnight">"자정"</string> @@ -691,8 +692,7 @@ <string name="paste">"붙여넣기"</string> <string name="copyUrl">"URL 복사"</string> <string name="inputMethod">"입력 방법"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"사전에 \'%s\' 추가"</string> <string name="editTextMenuTitle">"텍스트 수정"</string> <string name="low_internal_storage_view_title">"저장공간 부족"</string> <string name="low_internal_storage_view_text">"전화기 저장공간이 부족합니다."</string> @@ -700,8 +700,7 @@ <string name="cancel">"취소"</string> <string name="yes">"확인"</string> <string name="no">"취소"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"주의"</string> <string name="capital_on">"켜짐"</string> <string name="capital_off">"끄기"</string> <string name="whichApplication">"작업을 수행할 때 사용하는 권한"</string> @@ -725,8 +724,7 @@ <string name="volume_music">"미디어 볼륨"</string> <string name="volume_music_hint_playing_through_bluetooth">"Bluetooth를 통해 재생"</string> <string name="volume_call">"통화볼륨"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"Bluetooth 통화 볼륨"</string> <string name="volume_alarm">"알람 볼륨"</string> <string name="volume_notification">"알림 볼륨"</string> <string name="volume_unknown">"볼륨"</string> @@ -762,60 +760,35 @@ <string name="usb_storage_error_message">"USB 저장소에 SD 카드를 사용하는 동안 문제가 발생했습니다."</string> <string name="usb_storage_notification_title">"USB 연결됨"</string> <string name="usb_storage_notification_message">"컴퓨터에 파일을 복사하거나 컴퓨터의 파일을 복사하려면 선택합니다."</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"USB 저장소 끄기"</string> + <string name="usb_storage_stop_notification_message">"USB 저장소 끄기를 선택하세요."</string> + <string name="usb_storage_stop_title">"USB 저장소 끄기"</string> + <string name="usb_storage_stop_message">"USB 저장소를 끄기 전에 반드시 USB 호스를 마운트 해제하세요. USB 저장소를 끄려면 \'끄기\'를 선택하세요."</string> + <string name="usb_storage_stop_button_mount">"USB 저장소 끄기"</string> + <string name="usb_storage_stop_button_unmount">"취소"</string> + <string name="usb_storage_stop_error_message">"USB 저장소를 끄는 동안 Weve에 문제가 발행했습니다. USB 호스트를 마운트 해제했는지 확인한 후 다시 시도하세요."</string> + <string name="extmedia_format_title">"SD 카드 포맷"</string> + <string name="extmedia_format_message">"SD 카드를 포맷하시겠습니까? 포맷하면 카드의 모든 데이터를 잃게 됩니다."</string> + <string name="extmedia_format_button_format">"포맷"</string> <string name="select_input_method">"입력 방법 선택"</string> <string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"가능한 원인"</u></string> + <string name="ext_media_checking_notification_title">"SD 카드 준비 중"</string> + <string name="ext_media_checking_notification_message">"오류 확인 중"</string> + <string name="ext_media_nofs_notification_title">"빈 SD 카드"</string> + <string name="ext_media_nofs_notification_message">"SD 카드가 비어 있거나 지원되지 않는 파일시스템입니다."</string> + <string name="ext_media_unmountable_notification_title">"손상된 SD 카드"</string> + <string name="ext_media_unmountable_notification_message">"SD 카드가 손상되었습니다. 카드를 다시 포맷하시기 바랍니다."</string> + <string name="ext_media_badremoval_notification_title">"SD 카드가 예상치 않게 제거되었습니다."</string> + <string name="ext_media_badremoval_notification_message">"데이터 손실을 피하려면 SD 카드를 제거하기 전에 마운트 해제합니다."</string> + <string name="ext_media_safe_unmount_notification_title">"SD 카드를 안전하게 제거할 수 있습니다."</string> + <string name="ext_media_safe_unmount_notification_message">"이제 SD 카드를 안전하게 제거할 수 있습니다."</string> + <string name="ext_media_nomedia_notification_title">"SD 카드를 제거했습니다."</string> + <string name="ext_media_nomedia_notification_message">"SD가 제거되었습니다. 기기의 저장 용량을 늘리려면 새 SD 카드를 삽입하세요."</string> + <string name="activity_list_empty">"일치하는 활동이 없습니다."</string> + <string name="permlab_pkgUsageStats">"구성요소 사용 통계 업데이트"</string> + <string name="permdesc_pkgUsageStats">"수집된 구성요소 사용 통계를 수정할 수 있는 권한을 부여합니다. 일반 응용프로그램은 이 권한을 사용할 수 없습니다."</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 466f2b1..9ee553f 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -559,12 +559,12 @@ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'., \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'. \\\'\'\\\'\''<xliff:g id="MONTH">MMMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\', \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'. \\\'\'\\\'\''<xliff:g id="MONTH">MMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>'\\\'\'\\\'\':\\\'\'\\\'\''<xliff:g id="MINUTE">mm</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>'\\\'\'\\\'\':\\\'\'\\\'\''<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'., \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'. \\\'\'\\\'\''<xliff:g id="MONTH">MMMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\', \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'. \\\'\'\\\'\''<xliff:g id="MONTH">MMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>'\\\'\'\\\'\':\\\'\'\\\'\''<xliff:g id="MINUTE">mm</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>'\\\'\'\\\'\':\\\'\'\\\'\''<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"middag"</string> <string name="Noon">"Middag"</string> <string name="midnight">"midnatt"</string> @@ -789,4 +789,6 @@ <string name="activity_list_empty">"Fant ingen tilsvarende aktiviteter"</string> <string name="permlab_pkgUsageStats">"oppdater statistikk over komponentbruk"</string> <string name="permdesc_pkgUsageStats">"Tillater endring av innsamlet data om bruk av komponenter. Ikke ment for vanlige applikasjoner."</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> + <skip /> </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index a2810a1..a1446f5 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -262,10 +262,8 @@ <string name="permdesc_reboot">"Hiermee kan de toepassing de telefoon gedwongen opnieuw opstarten."</string> <string name="permlab_mount_unmount_filesystems">"bestandssystemen koppelen en ontkoppelen"</string> <string name="permdesc_mount_unmount_filesystems">"Hiermee kan de toepassing bestandssystemen koppelen en ontkoppelen voor verwisselbare opslagruimte."</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> + <string name="permlab_mount_format_filesystems">"externe opslag formatteren"</string> + <string name="permdesc_mount_format_filesystems">"Hiermee kan de toepassing de externe opslag formatteren."</string> <string name="permlab_vibrate">"trilstand beheren"</string> <string name="permdesc_vibrate">"Hiermee kan de toepassing de trilstand beheren."</string> <string name="permlab_flashlight">"zaklamp bedienen"</string> @@ -280,10 +278,8 @@ <string name="permdesc_locationUpdates">"Hiermee kunnen updatemeldingen voor locaties van de radio worden ingeschakeld/uitgeschakeld. Niet voor gebruik door normale toepassingen."</string> <string name="permlab_checkinProperties">"toegang tot checkin-eigenschappen"</string> <string name="permdesc_checkinProperties">"Hiermee wordt lees-/schrijftoegang gegeven tot eigenschappen die door de checkin-service zijn geüpload. Niet voor gebruik door normale toepassingen."</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> + <string name="permlab_bindGadget">"gadgets kiezen"</string> + <string name="permdesc_bindGadget">"Hiermee kan een toepassing het systeem melden welke gadgets door welke toepassing kunnen worden gebruikt. Met deze toestemming kunnen toepassingen andere toepassingen toegang geven tot persoonlijke gegevens. Niet voor gebruik door normale toepassingen."</string> <string name="permlab_modifyPhoneState">"telefoonstatus wijzigen"</string> <string name="permdesc_modifyPhoneState">"Hiermee kan de toepassing de telefoonfuncties van het apparaat beheren. Een toepassing met deze machtiging kan schakelen tussen netwerken, de radio van de telefoon in- of uitschakelen en dergelijke zonder dat u hiervan op de hoogte wordt gesteld."</string> <string name="permlab_readPhoneState">"telefoonstatus lezen"</string> @@ -312,10 +308,8 @@ <string name="permdesc_writeApnSettings">"Hiermee kan een toepassing de APN-instellingen, zoals proxy en poort, van elke APN wijzigen."</string> <string name="permlab_changeNetworkState">"netwerkverbinding wijzigen"</string> <string name="permdesc_changeNetworkState">"Hiermee kan een toepassing de verbindingsstatus van het netwerk wijzigen."</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"instelling voor gebruik van achtergrondgegevens van gegevens wijzigen"</string> + <string name="permdesc_changeBackgroundDataSetting">"Hiermee kan een toepassing de instelling voor gebruik van achtergrondgegevens wijzigen."</string> <string name="permlab_accessWifiState">"Wi-Fi-status bekijken"</string> <string name="permdesc_accessWifiState">"Hiermee kan een toepassing informatie over de Wi-Fi-status bekijken."</string> <string name="permlab_changeWifiState">"Wi-Fi-status wijzigen"</string> @@ -336,14 +330,10 @@ <string name="permdesc_subscribedFeedsRead">"Hiermee kan een toepassing details over de huidige gesynchroniseerde feeds achterhalen."</string> <string name="permlab_subscribedFeedsWrite">"geabonneerde feeds schrijven"</string> <string name="permdesc_subscribedFeedsWrite">"Hiermee kan een toepassing uw huidige gesynchroniseerde feeds wijzigen. Een schadelijke toepassing kan op deze manier uw gesynchroniseerde feeds wijzigen."</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"door gebruiker gedefinieerd woordenboek lezen"</string> + <string name="permdesc_readDictionary">"Hiermee kan een toepassing privéwoorden, namen en woordcombinaties lezen die de gebruiker heeft opgeslagen in het gebruikerswoordenboek."</string> + <string name="permlab_writeDictionary">"schrijven naar door gebruiker gedefinieerd woordenboek"</string> + <string name="permdesc_writeDictionary">"Hiermee kan een toepassing nieuwe woorden schrijven naar het gebruikerswoordenboek."</string> <string-array name="phoneTypes"> <item>"Thuis"</item> <item>"Mobiel"</item> @@ -440,12 +430,9 @@ <string name="factorytest_not_system">"De actie FACTORY_TEST wordt alleen ondersteund voor pakketten die zijn geïnstalleerd in /system/app."</string> <string name="factorytest_no_action">"Er is geen pakket gevonden dat de actie FACTORY_TEST levert."</string> <string name="factorytest_reboot">"Opnieuw opstarten"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"De pagina op \'<xliff:g id="TITLE">%s</xliff:g>\' zegt:"</string> + <string name="js_dialog_title_default">"JavaScript"</string> + <string name="js_dialog_before_unload">"Wilt u deze pagina verlaten?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Kies OK om door te gaan of Annuleren om op de huidige pagina te blijven."</string> <string name="save_password_label">"Bevestigen"</string> <string name="save_password_message">"Wilt u dat de browser dit wachtwoord onthoudt?"</string> <string name="save_password_notnow">"Niet nu"</string> @@ -496,22 +483,38 @@ <item quantity="one">"morgen"</item> <item quantity="other">"over <xliff:g id="COUNT">%d</xliff:g> dagen"</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"1 seconde geleden"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> seconden geleden"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"1 minuut geleden"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minuten geleden"</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"1 uur geleden"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> uur geleden"</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"gisteren"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dagen geleden"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"over 1 seconde"</item> + <item quantity="other">"over <xliff:g id="COUNT">%d</xliff:g> seconden"</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"over 1 minuut"</item> + <item quantity="other">"over <xliff:g id="COUNT">%d</xliff:g> minuten"</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"over 1 uur"</item> + <item quantity="other">"over <xliff:g id="COUNT">%d</xliff:g> uur"</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"morgen"</item> + <item quantity="other">"over <xliff:g id="COUNT">%d</xliff:g> dagen"</item> + </plurals> <string name="preposition_for_date">"op %s"</string> <string name="preposition_for_time">"om %s"</string> <string name="preposition_for_year">"in %s"</string> @@ -553,17 +556,15 @@ <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"twaalf uur \'s middags"</string> <string name="Noon">"Twaalf uur \'s middags"</string> <string name="midnight">"middernacht"</string> @@ -691,8 +692,7 @@ <string name="paste">"Plakken"</string> <string name="copyUrl">"URL kopiëren"</string> <string name="inputMethod">"Invoermethode"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"\'%s\' toevoegen aan woordenboek"</string> <string name="editTextMenuTitle">"Tekst bewerken"</string> <string name="low_internal_storage_view_title">"Weinig ruimte"</string> <string name="low_internal_storage_view_text">"Opslagruimte van telefoon raakt op."</string> @@ -700,8 +700,7 @@ <string name="cancel">"Annuleren"</string> <string name="yes">"OK"</string> <string name="no">"Annuleren"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"Let op"</string> <string name="capital_on">"AAN"</string> <string name="capital_off">"UIT"</string> <string name="whichApplication">"Actie voltooien met"</string> @@ -725,8 +724,7 @@ <string name="volume_music">"Mediavolume"</string> <string name="volume_music_hint_playing_through_bluetooth">"Afspelen via Bluetooth"</string> <string name="volume_call">"Volume inkomende oproep"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"Volume tijdens gesprek in Bluetooth-modus"</string> <string name="volume_alarm">"Alarmvolume"</string> <string name="volume_notification">"Meldingsvolume"</string> <string name="volume_unknown">"Volume"</string> @@ -762,60 +760,35 @@ <string name="usb_storage_error_message">"Er is een probleem bij het gebruik van uw SD-kaart voor USB-opslag."</string> <string name="usb_storage_notification_title">"USB-verbinding"</string> <string name="usb_storage_notification_message">"Selecteer dit om bestanden naar/van uw computer te kopiëren."</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"USB-opslag uitschakelen"</string> + <string name="usb_storage_stop_notification_message">"Selecteer dit om USB-opslag uit te schakelen."</string> + <string name="usb_storage_stop_title">"USB-opslag uitschakelen"</string> + <string name="usb_storage_stop_message">"Voordat u de USB-opslag uitschakelt, moet u de koppeling met de USB-host verbreken. Selecteer \'Uitschakelen\' om USB-opslag uit te schakelen."</string> + <string name="usb_storage_stop_button_mount">"Uitschakelen"</string> + <string name="usb_storage_stop_button_unmount">"Annuleren"</string> + <string name="usb_storage_stop_error_message">"Er is een probleem opgetreden tijdens het uitschakelen van USB-opslag. Controleer of u de USB-host heeft losgekoppeld en probeer het opnieuw."</string> + <string name="extmedia_format_title">"SD-kaart formatteren"</string> + <string name="extmedia_format_message">"Weet u zeker dat u de SD-kaart wilt formatteren? Alle gegevens op uw kaart gaan dan verloren."</string> + <string name="extmedia_format_button_format">"Formatteren"</string> <string name="select_input_method">"Invoermethode selecteren"</string> <string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"kandidaten"</u></string> + <string name="ext_media_checking_notification_title">"SD-kaart voorbereiden"</string> + <string name="ext_media_checking_notification_message">"Controleren op fouten"</string> + <string name="ext_media_nofs_notification_title">"Lege SD-kaart"</string> + <string name="ext_media_nofs_notification_message">"De SD-kaart is leeg of gebruikt een niet-ondersteund bestandssysteem."</string> + <string name="ext_media_unmountable_notification_title">"Beschadigde SD-kaart"</string> + <string name="ext_media_unmountable_notification_message">"De SD-kaart is beschadigd. U moet de kaart mogelijk opnieuw formatteren."</string> + <string name="ext_media_badremoval_notification_title">"SD-kaart onverwachts verwijderd"</string> + <string name="ext_media_badremoval_notification_message">"Ontkoppel de SD-kaart voordat u deze verwijdert om gegevensverlies te voorkomen."</string> + <string name="ext_media_safe_unmount_notification_title">"De SD-kaart kan veilig worden verwijderd"</string> + <string name="ext_media_safe_unmount_notification_message">"De SD-kaart kan nu veilig worden verwijderd."</string> + <string name="ext_media_nomedia_notification_title">"SD-kaart is verwijderd"</string> + <string name="ext_media_nomedia_notification_message">"De SD-kaart is verwijderd. Plaats een nieuwe SD-kaart om de opslagcapaciteit van uw apparaat te vergroten."</string> + <string name="activity_list_empty">"Geen overeenkomende activiteiten gevonden"</string> + <string name="permlab_pkgUsageStats">"gebruiksstatistieken van component bijwerken"</string> + <string name="permdesc_pkgUsageStats">"Hiermee kunnen verzamelde gebruiksstatistieken van een component worden gewijzigd. Niet voor gebruik door normale toepassingen."</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 12f1616..a49b824 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -262,10 +262,8 @@ <string name="permdesc_reboot">"Pozwala aplikacji na wymuszenie ponownego uruchomienia telefonu."</string> <string name="permlab_mount_unmount_filesystems">"montowanie i odmontowanie systemów plików"</string> <string name="permdesc_mount_unmount_filesystems">"Pozwala aplikacjom na podłączanie i odłączanie systemów plików w pamięciach przenośnych."</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> + <string name="permlab_mount_format_filesystems">"formatowanie pamięci zewnętrznej"</string> + <string name="permdesc_mount_format_filesystems">"Zezwala aplikacji na formatowanie wymiennych nośników."</string> <string name="permlab_vibrate">"kontrolowanie wibracji"</string> <string name="permdesc_vibrate">"Pozwala aplikacjom na kontrolowanie wibracji."</string> <string name="permlab_flashlight">"kontrolowanie latarki"</string> @@ -280,10 +278,8 @@ <string name="permdesc_locationUpdates">"Pozwala włączyć/wyłączyć powiadomienia o aktualizacji położenia przez radio. Nie wykorzystywane przez normalne aplikacje."</string> <string name="permlab_checkinProperties">"dostęp do właściwości usługi rezerwacji"</string> <string name="permdesc_checkinProperties">"Pozwala na dostęp z uprawnieniami do odczytu/zapisu do właściwości przesłanych przez usługę rezerwacji. Nie wykorzystywane przez normalne aplikacje."</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> + <string name="permlab_bindGadget">"wybieranie gadżetów"</string> + <string name="permdesc_bindGadget">"Zezwala aplikacjom na wskazywanie systemowi, które gadżety mogą być używane przez inne aplikacje. Z użyciem tego pozwolenia aplikacje mogą udzielać dostępu do danych osobistych innym aplikacjom. Nie jest ono przeznaczone dla zwykłych aplikacji."</string> <string name="permlab_modifyPhoneState">"zmiana stanu telefonu"</string> <string name="permdesc_modifyPhoneState">"Pozwala aplikacji na kontrolowanie funkcji telefonu w urządzeniu. Aplikacja z tymi uprawnieniami może przełączać sieci, włączać i wyłączać radio itp. bez informowania użytkownika."</string> <string name="permlab_readPhoneState">"czytanie stanu telefonu"</string> @@ -312,10 +308,8 @@ <string name="permdesc_writeApnSettings">"Pozwala aplikacji na zmianę ustawień APN, takich jak serwer proxy oraz port dowolnego APN."</string> <string name="permlab_changeNetworkState">"zmienianie połączeń sieci"</string> <string name="permdesc_changeNetworkState">"Pozwala aplikacji na zmianę stanu połączeń sieciowych."</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"zmienianie ustawienia używania danych w tle"</string> + <string name="permdesc_changeBackgroundDataSetting">"Zezwala aplikacji na zmianę ustawień użycia danych w tle."</string> <string name="permlab_accessWifiState">"wyświetlanie stanu Wi-Fi"</string> <string name="permdesc_accessWifiState">"Pozwala aplikacji na wyświetlanie informacji o stanie Wi-Fi."</string> <string name="permlab_changeWifiState">"zmiana stanu Wi-Fi"</string> @@ -336,14 +330,10 @@ <string name="permdesc_subscribedFeedsRead">"Pozwala aplikacjom na pobieranie informacji szczegółowych na temat obecnie zsynchronizowanych źródeł."</string> <string name="permlab_subscribedFeedsWrite">"zapisywanie subskrybowanych źródeł"</string> <string name="permdesc_subscribedFeedsWrite">"Umożliwia aplikacji zmianę obecnie zsynchronizowanych źródeł. Może to pozwolić szkodliwej aplikacji na zmianę zsynchronizowanych źródeł."</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"odczytywanie słownika zdefiniowanego przez użytkownika"</string> + <string name="permdesc_readDictionary">"Zezwala aplikacji na odczytywanie wszelkich prywatnych słów, nazw i wyrażeń zapisanych przez użytkownika w swoim słowniku."</string> + <string name="permlab_writeDictionary">"zapisywanie w słowniku zdefiniowanym przez użytkownika"</string> + <string name="permdesc_writeDictionary">"Zezwala aplikacjom na zapisywanie nowych słów w słowniku użytkownika."</string> <string-array name="phoneTypes"> <item>"Dom"</item> <item>"Komórka"</item> @@ -440,12 +430,9 @@ <string name="factorytest_not_system">"Czynność FACTORY_TEST jest obsługiwana tylko dla pakietów zainstalowanych w katalogu /system/app."</string> <string name="factorytest_no_action">"Nie znaleziono żadnego pakietu, który zapewnia działanie FACTORY_TEST."</string> <string name="factorytest_reboot">"Uruchom ponownie"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"Komunikat ze strony pod adresem „<xliff:g id="TITLE">%s</xliff:g>”:"</string> + <string name="js_dialog_title_default">"JavaScript"</string> + <string name="js_dialog_before_unload">"Czy opuścić tę stronę?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Wybierz opcję OK, aby kontynuować, lub opcję Anuluj, aby pozostać na tej stronie."</string> <string name="save_password_label">"Potwierdź"</string> <string name="save_password_message">"Czy chcesz, aby zapamiętać to hasło w przeglądarce?"</string> <string name="save_password_notnow">"Nie teraz"</string> @@ -496,22 +483,38 @@ <item quantity="one">"jutro"</item> <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> dni"</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"sekundę temu"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> sek. temu"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"minutę temu"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> min temu"</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"godzinę temu"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> godz. temu"</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"wczoraj"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dni temu"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"za sekundę"</item> + <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> sek."</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"za minutę"</item> + <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> min"</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"za godzinę"</item> + <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> godz."</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"jutro"</item> + <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> dni"</item> + </plurals> <string name="preposition_for_date">"dnia %s"</string> <string name="preposition_for_time">"o %s"</string> <string name="preposition_for_year">"w %s"</string> @@ -553,17 +556,15 @@ <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"południe"</string> <string name="Noon">"Południe"</string> <string name="midnight">"północ"</string> @@ -691,8 +692,7 @@ <string name="paste">"Wklej"</string> <string name="copyUrl">"Kopiuj adres URL"</string> <string name="inputMethod">"Metoda wejściowa"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"Dodaj „%s” do słownika"</string> <string name="editTextMenuTitle">"Edytuj tekst"</string> <string name="low_internal_storage_view_title">"Mało miejsca"</string> <string name="low_internal_storage_view_text">"Maleje ilość dostępnej pamięci telefonu."</string> @@ -700,8 +700,7 @@ <string name="cancel">"Anuluj"</string> <string name="yes">"OK"</string> <string name="no">"Anuluj"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"Uwaga"</string> <string name="capital_on">"Włącz"</string> <string name="capital_off">"Wyłącz"</string> <string name="whichApplication">"Zakończ działanie, korzystając z"</string> @@ -725,8 +724,7 @@ <string name="volume_music">"Głośność multimediów"</string> <string name="volume_music_hint_playing_through_bluetooth">"Odtwarzanie przez Bluetooth"</string> <string name="volume_call">"Głośność podczas połączenia"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"Głośność Bluetooth w czasie połączenia"</string> <string name="volume_alarm">"Głośność alarmu"</string> <string name="volume_notification">"Głośność powiadomienia"</string> <string name="volume_unknown">"Głośność"</string> @@ -762,60 +760,35 @@ <string name="usb_storage_error_message">"Wystąpił problem z wykorzystaniem karty SD dla pamięci USB."</string> <string name="usb_storage_notification_title">"Połączenie przez USB"</string> <string name="usb_storage_notification_message">"Wybierz, aby skopiować pliki do/z komputera"</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"Wyłącz nośnik USB"</string> + <string name="usb_storage_stop_notification_message">"Wybierz, aby wyłączyć nośnik USB."</string> + <string name="usb_storage_stop_title">"Wyłącz nośnik USB"</string> + <string name="usb_storage_stop_message">"Przed wyłączeniem nośnika USB upewnij się, że odłączono go od hosta USB. Wybierz „Wyłącz”, aby wyłączyć nośnik USB."</string> + <string name="usb_storage_stop_button_mount">"Wyłącz"</string> + <string name="usb_storage_stop_button_unmount">"Anuluj"</string> + <string name="usb_storage_stop_error_message">"Napotkano problem przy wyłączaniu nośnika USB. Sprawdź, czy host USB został odłączony i spróbuj ponownie."</string> + <string name="extmedia_format_title">"Formatuj kartę SD"</string> + <string name="extmedia_format_message">"Czy na pewno sformatować kartę SD? Wszystkie dane na karcie zostaną utracone."</string> + <string name="extmedia_format_button_format">"Formatuj"</string> <string name="select_input_method">"Wybierz metodę wejściową"</string> <string name="fast_scroll_alphabet">"AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"kandydaci"</u></string> + <string name="ext_media_checking_notification_title">"Przygotowywanie karty SD"</string> + <string name="ext_media_checking_notification_message">"Sprawdzanie w poszukiwaniu błędów"</string> + <string name="ext_media_nofs_notification_title">"Pusta karta SD"</string> + <string name="ext_media_nofs_notification_message">"Karta SD jest pusta lub używa nieobsługiwanego systemu plików."</string> + <string name="ext_media_unmountable_notification_title">"Uszkodzona karta SD"</string> + <string name="ext_media_unmountable_notification_message">"Karta SD jest uszkodzona. Konieczne może być przeformatowanie karty."</string> + <string name="ext_media_badremoval_notification_title">"Karta SD została nieoczekiwanie wyjęta"</string> + <string name="ext_media_badremoval_notification_message">"Odłącz kartę SD przed jej wyjęciem, aby uniknąć utraty danych."</string> + <string name="ext_media_safe_unmount_notification_title">"Można bezpiecznie usunąć kartę SD"</string> + <string name="ext_media_safe_unmount_notification_message">"Można teraz bezpiecznie usunąć kartę SD."</string> + <string name="ext_media_nomedia_notification_title">"Usunięta karta SD"</string> + <string name="ext_media_nomedia_notification_message">"Karta SD została usunięta. Włóż nową kartę SD, aby zwiększyć pamięć urządzenia."</string> + <string name="activity_list_empty">"Nie znaleziono pasujących działań"</string> + <string name="permlab_pkgUsageStats">"aktualizowanie statystyk użycia komponentu"</string> + <string name="permdesc_pkgUsageStats">"Zezwala na modyfikacje zebranych statystyk użycia komponentu. Nieprzeznaczone dla zwykłych aplikacji."</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 76a358d..612a185 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -262,10 +262,8 @@ <string name="permdesc_reboot">"Разрешает приложению принудительно перезагружать телефон."</string> <string name="permlab_mount_unmount_filesystems">"подключаться и отключаться от файловых систем"</string> <string name="permdesc_mount_unmount_filesystems">"Разрешает приложению подключаться и отключаться от файловых систем съемных устройств хранения."</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> + <string name="permlab_mount_format_filesystems">"форматировать внешний накопитель"</string> + <string name="permdesc_mount_format_filesystems">"Позволяет приложению форматировать съемный накопитель."</string> <string name="permlab_vibrate">"управлять вибрацией"</string> <string name="permdesc_vibrate">"Разрешает приложению управлять вибровызовом."</string> <string name="permlab_flashlight">"управлять фонарем"</string> @@ -280,10 +278,8 @@ <string name="permdesc_locationUpdates">"Разрешает включение/отключение уведомлений о местоположении по радиосвязи. Не используется обычными приложениями."</string> <string name="permlab_checkinProperties">"открывать свойства проверки"</string> <string name="permdesc_checkinProperties">"Разрешает доступ на чтение и запись к свойствам, загруженным службой проверки. Не используется обычными приложениями."</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> + <string name="permlab_bindGadget">"выбирать гаджеты"</string> + <string name="permdesc_bindGadget">"Позволяет приложению сообщить системе, какие приложения могут использовать какие гаджеты. Это разрешение позволяет приложениям предоставлять другим приложениям доступ к личной информации. Не предназначено для использования обычными приложениями."</string> <string name="permlab_modifyPhoneState">"изменять состояние телефона"</string> <string name="permdesc_modifyPhoneState">"Позволяет приложению управлять телефонными функциями устройства. Приложение с такими полномочиями может переключать сети, включать и выключать радиосвязь и т.д., не сообщая вам об этом."</string> <string name="permlab_readPhoneState">"считывать состояние телефона"</string> @@ -312,10 +308,8 @@ <string name="permdesc_writeApnSettings">"Разрешает приложению изменять настройки APN, например прокси и порт любого APN."</string> <string name="permlab_changeNetworkState">"изменять подключение к сети"</string> <string name="permdesc_changeNetworkState">"Позволяет приложению изменять подключение к сети."</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"изменить настройку использования фоновых данных"</string> + <string name="permdesc_changeBackgroundDataSetting">"Позволяет приложению изменять настройку использования фоновых данных."</string> <string name="permlab_accessWifiState">"просматривать состояние Wi-Fi"</string> <string name="permdesc_accessWifiState">"Разрешает приложению просматривать сведения о состоянии Wi-Fi."</string> <string name="permlab_changeWifiState">"изменять состояние Wi-Fi"</string> @@ -336,14 +330,10 @@ <string name="permdesc_subscribedFeedsRead">"Позволяет приложению получать сведения о синхронизированных фидах."</string> <string name="permlab_subscribedFeedsWrite">"записывать фиды с подпиской"</string> <string name="permdesc_subscribedFeedsWrite">"Разрешает приложению изменять ваши синхронизированные фиды. Это может позволить вредоносному ПО изменять ваши синхронизированные фиды."</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"выполнять чтение из пользовательского словаря"</string> + <string name="permdesc_readDictionary">"Позволяет приложению считывать любые слова, имена и фразы личного пользования, которые могут храниться в пользовательском словаре."</string> + <string name="permlab_writeDictionary">"записывать в пользовательский словарь"</string> + <string name="permdesc_writeDictionary">"Позволяет приложению записывать новые слова в пользовательский словарь."</string> <string-array name="phoneTypes"> <item>"Домашний"</item> <item>"Мобильный"</item> @@ -440,12 +430,9 @@ <string name="factorytest_not_system">"Действие FACTORY_TEST поддерживается только для пакетов, установленных в папке /system/app."</string> <string name="factorytest_no_action">"Пакет, предоставляющий действие FACTORY_TEST, не найден."</string> <string name="factorytest_reboot">"Перезагрузить"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"На странице по адресу \"<xliff:g id="TITLE">%s</xliff:g>\" сказано:"</string> + <string name="js_dialog_title_default">"JavaScript"</string> + <string name="js_dialog_before_unload">"Перейти с этой страницы?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Нажмите \"ОК\", чтобы продолжить, или \"Отмена\", чтобы остаться на текущей странице."</string> <string name="save_password_label">"Подтверждение"</string> <string name="save_password_message">"Сохранить этот пароль в браузере?"</string> <string name="save_password_notnow">"Не сейчас"</string> @@ -496,22 +483,38 @@ <item quantity="one">"завтра"</item> <item quantity="other">"через <xliff:g id="COUNT">%d</xliff:g> дн."</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"1 сек. назад"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> сек. назад"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"1 мин. назад"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> мин. назад"</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"1 час назад"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> ч. назад"</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"вчера"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> дн. назад"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"через 1 сек."</item> + <item quantity="other">"через <xliff:g id="COUNT">%d</xliff:g> сек."</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"через 1 мин."</item> + <item quantity="other">"через <xliff:g id="COUNT">%d</xliff:g> мин."</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"через 1 час"</item> + <item quantity="other">"через <xliff:g id="COUNT">%d</xliff:g> час."</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"завтра"</item> + <item quantity="other">"через <xliff:g id="COUNT">%d</xliff:g> дн."</item> + </plurals> <string name="preposition_for_date">"%s"</string> <string name="preposition_for_time">"в %s"</string> <string name="preposition_for_year">"в %s"</string> @@ -553,17 +556,15 @@ <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_month_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"полдень"</string> <string name="Noon">"Полдень"</string> <string name="midnight">"полночь"</string> @@ -691,8 +692,7 @@ <string name="paste">"Вставить"</string> <string name="copyUrl">"Копировать URL"</string> <string name="inputMethod">"Способ ввода"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"Добавить \"%s\" в словарь"</string> <string name="editTextMenuTitle">"Правка текста"</string> <string name="low_internal_storage_view_title">"Недостаточно места"</string> <string name="low_internal_storage_view_text">"В памяти телефона осталось мало места."</string> @@ -700,8 +700,7 @@ <string name="cancel">"Отмена"</string> <string name="yes">"ОК"</string> <string name="no">"Отмена"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"Внимание"</string> <string name="capital_on">"ВКЛ"</string> <string name="capital_off">"ВЫКЛ"</string> <string name="whichApplication">"Выполнить действие с помощью"</string> @@ -725,8 +724,7 @@ <string name="volume_music">"Громкость звука мультимедиа"</string> <string name="volume_music_hint_playing_through_bluetooth">"Воспроизводится через Bluetooth"</string> <string name="volume_call">"Громкость звонка"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"Громкость входящего вызова Bluetooth"</string> <string name="volume_alarm">"Громкость будильника"</string> <string name="volume_notification">"Громкость уведомления"</string> <string name="volume_unknown">"Громкость"</string> @@ -762,60 +760,35 @@ <string name="usb_storage_error_message">"Не удается использовать карту SD в качестве USB-хранилища."</string> <string name="usb_storage_notification_title">"Подключение через USB"</string> <string name="usb_storage_notification_message">"Выберите для копирования файлов на/с компьютера."</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"Выключить USB-накопитель"</string> + <string name="usb_storage_stop_notification_message">"Выберите, чтобы выключить USB-накопитель."</string> + <string name="usb_storage_stop_title">"Выключить USB-накопитель"</string> + <string name="usb_storage_stop_message">"Перед выключением USB-накопителя обязательно отключите USB-хост. Выберите \"Выключить\", чтобы выключить USB-накопитель."</string> + <string name="usb_storage_stop_button_mount">"Выключить"</string> + <string name="usb_storage_stop_button_unmount">"Отмена"</string> + <string name="usb_storage_stop_error_message">"При выключении USB-накопителя произошла проблема. Убедитесь, что USB-хост отключен, и повторите попытку."</string> + <string name="extmedia_format_title">"Форматировать карту SD"</string> + <string name="extmedia_format_message">"Отформатировать карту SD? Все данные, находящиеся на карте, будут уничтожены."</string> + <string name="extmedia_format_button_format">"Формат"</string> <string name="select_input_method">"Выбор способа ввода"</string> <string name="fast_scroll_alphabet">"АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"кандидаты"</u></string> + <string name="ext_media_checking_notification_title">"Подготовка карты SD"</string> + <string name="ext_media_checking_notification_message">"Поиск ошибок"</string> + <string name="ext_media_nofs_notification_title">"Пустая карта SD"</string> + <string name="ext_media_nofs_notification_message">"Карта SD пуста или использует неподдерживаемую файловую систему."</string> + <string name="ext_media_unmountable_notification_title">"Поврежденная карта SD"</string> + <string name="ext_media_unmountable_notification_message">"Карта SD повреждена. Может потребоваться переформатировать ее."</string> + <string name="ext_media_badremoval_notification_title">"Карта SD неожиданно извлечена"</string> + <string name="ext_media_badremoval_notification_message">"Перед извлечением карты SD отключите ее во избежание потери данных."</string> + <string name="ext_media_safe_unmount_notification_title">"Безопасное удаление карты SD"</string> + <string name="ext_media_safe_unmount_notification_message">"Теперь карту SD можно безопасно удалить."</string> + <string name="ext_media_nomedia_notification_title">"Карта SD удалена"</string> + <string name="ext_media_nomedia_notification_message">"Карта SD была удалена. Для увеличения емкости устройства вставьте новую карту SD."</string> + <string name="activity_list_empty">"Подходящих действий не найдено"</string> + <string name="permlab_pkgUsageStats">"обновлять статистику использования компонентов"</string> + <string name="permdesc_pkgUsageStats">"Позволяет изменять собранную статистику использования компонентов. Не предназначено для использования обычными приложениями."</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 13d4e9c..fbd58e8 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -262,10 +262,8 @@ <string name="permdesc_reboot">"允许应用程序强制手机重新引导。"</string> <string name="permlab_mount_unmount_filesystems">"装载和卸载文件系统"</string> <string name="permdesc_mount_unmount_filesystems">"允许应用程序装载和卸载文件系统以进行可移动存储。"</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> + <string name="permlab_mount_format_filesystems">"格式化外部存储设备"</string> + <string name="permdesc_mount_format_filesystems">"允许应用程序格式化可移除的存储设备。"</string> <string name="permlab_vibrate">"控制振动器"</string> <string name="permdesc_vibrate">"允许应用程序控制振动器。"</string> <string name="permlab_flashlight">"控制闪光灯"</string> @@ -280,10 +278,8 @@ <string name="permdesc_locationUpdates">"允许启用/禁用来自收音机的位置更新通知。普通应用程序不能使用此权限。"</string> <string name="permlab_checkinProperties">"访问检入属性"</string> <string name="permdesc_checkinProperties">"允许对检入服务上传的属性进行读/写访问。普通应用程序不能使用此权限。"</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> + <string name="permlab_bindGadget">"选择小工具"</string> + <string name="permdesc_bindGadget">"允许应用程序告诉系统哪些应用程序可以使用哪些小工具。应用程序可以借此授予其他应用程序访问个人数据的权限。普通应用程序不能使用此权限。"</string> <string name="permlab_modifyPhoneState">"修改手机状态"</string> <string name="permdesc_modifyPhoneState">"允许应用程序控制设备的手机功能。具有此权限的应用程序可能会切换网络,打开和关闭手机收音机以及类似操作,而不会通知您。"</string> <string name="permlab_readPhoneState">"读取手机状态"</string> @@ -312,10 +308,8 @@ <string name="permdesc_writeApnSettings">"允许应用程序修改 APN 设置,例如任何 APN 的代理和端口。"</string> <string name="permlab_changeNetworkState">"更改网络连接性"</string> <string name="permdesc_changeNetworkState">"允许应用程序更改状态网络连接性。"</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"更改背景数据使用设置"</string> + <string name="permdesc_changeBackgroundDataSetting">"允许应用程序更改背景数据使用设置。"</string> <string name="permlab_accessWifiState">"查看 Wi-Fi 状态"</string> <string name="permdesc_accessWifiState">"允许应用程序查看有关 Wi-Fi 状态的信息。"</string> <string name="permlab_changeWifiState">"更改 Wi-Fi 状态"</string> @@ -336,14 +330,10 @@ <string name="permdesc_subscribedFeedsRead">"允许应用程序获取有关当前同步的供稿的详情。"</string> <string name="permlab_subscribedFeedsWrite">"写入订阅的供稿"</string> <string name="permdesc_subscribedFeedsWrite">"允许应用程序修改您当前同步的供稿。这样恶意程序可以更改您同步的供稿。"</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"读取用户定义的词典"</string> + <string name="permdesc_readDictionary">"允许应用程序读取用户在用户词典中存储的任意私有字词、名称和短语。"</string> + <string name="permlab_writeDictionary">"写入用户定义的词典"</string> + <string name="permdesc_writeDictionary">"允许应用程序向用户词典中写入新词。"</string> <string-array name="phoneTypes"> <item>"家庭"</item> <item>"手机"</item> @@ -440,12 +430,9 @@ <string name="factorytest_not_system">"只有在 /system/app 中安装的包支持 FACTORY_TEST 操作。"</string> <string name="factorytest_no_action">"未发现支持 FACTORY_TEST 操作的包。"</string> <string name="factorytest_reboot">"重新引导"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"“<xliff:g id="TITLE">%s</xliff:g>”处的页面表明:"</string> + <string name="js_dialog_title_default">"JavaScript"</string> + <string name="js_dialog_before_unload">"是否从该页面导航至它处?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"选择“确定”继续,或选择“取消”留在当前页面。"</string> <string name="save_password_label">"确认"</string> <string name="save_password_message">"是否希望浏览器记住此密码?"</string> <string name="save_password_notnow">"暂不保存"</string> @@ -496,22 +483,38 @@ <item quantity="one">"明天"</item> <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天后"</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"1 秒前"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 秒前"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"1 分钟前"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分钟前"</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"1 小时前"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 小时前"</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"昨天"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天前"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"1 秒后"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 秒后"</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"1 分钟后"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分钟后"</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"1 小时后"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 小时后"</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"明天"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天后"</item> + </plurals> <string name="preposition_for_date">"在 %s"</string> <string name="preposition_for_time">"在 %s"</string> <string name="preposition_for_year">"%s 年内"</string> @@ -553,17 +556,15 @@ <string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string> <string name="wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="DATE">%3$s</xliff:g> <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g><xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g><xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string> - <string name="full_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string> - <string name="medium_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string> - <string name="medium_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="DAY">d</xliff:g>' 月 '<xliff:g id="MONTH">MMM</xliff:g>' 日'"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="DAY">d</xliff:g>' 月 '<xliff:g id="MONTH">MMM</xliff:g>' 日'"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"中午"</string> <string name="Noon">"中午"</string> <string name="midnight">"午夜"</string> @@ -691,8 +692,7 @@ <string name="paste">"粘贴"</string> <string name="copyUrl">"复制网址"</string> <string name="inputMethod">"输入方法"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"将“%s”添加到词典"</string> <string name="editTextMenuTitle">"编辑文本"</string> <string name="low_internal_storage_view_title">"存储空间不足"</string> <string name="low_internal_storage_view_text">"手机存储空间在减少。"</string> @@ -700,8 +700,7 @@ <string name="cancel">"取消"</string> <string name="yes">"正常"</string> <string name="no">"取消"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"注意事项"</string> <string name="capital_on">"开启"</string> <string name="capital_off">"关闭"</string> <string name="whichApplication">"使用以下内容完成操作"</string> @@ -725,8 +724,7 @@ <string name="volume_music">"媒体音量"</string> <string name="volume_music_hint_playing_through_bluetooth">"正通过蓝牙播放"</string> <string name="volume_call">"来电音量"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"使用蓝牙时的通话音量"</string> <string name="volume_alarm">"警告音量"</string> <string name="volume_notification">"通知音量"</string> <string name="volume_unknown">"音量"</string> @@ -762,60 +760,35 @@ <string name="usb_storage_error_message">"使用 SD 卡进行 USB 存储时出现问题。"</string> <string name="usb_storage_notification_title">"USB 已连接"</string> <string name="usb_storage_notification_message">"选择以将文件复制到计算机或从计算机复制文件。"</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"关闭 USB 存储设备"</string> + <string name="usb_storage_stop_notification_message">"选中以关闭 USB 存储设备。"</string> + <string name="usb_storage_stop_title">"关闭 USB 存储设备"</string> + <string name="usb_storage_stop_message">"在关闭 USB 存储设备前,请确保您已卸载了 USB 主设备。选择“关闭”关闭 USB 存储设备。"</string> + <string name="usb_storage_stop_button_mount">"关闭"</string> + <string name="usb_storage_stop_button_unmount">"取消"</string> + <string name="usb_storage_stop_error_message">"关闭 USB 存储设备时遇到问题。请检查是否卸载了 USB 主设备,然后重试。"</string> + <string name="extmedia_format_title">"格式化 SD 卡"</string> + <string name="extmedia_format_message">"您确定要格式化 SD 卡?卡上的所有数据都会丢失。"</string> + <string name="extmedia_format_button_format">"格式化"</string> <string name="select_input_method">"选择输入方法"</string> <string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"候选"</u></string> + <string name="ext_media_checking_notification_title">"正在准备 SD 卡"</string> + <string name="ext_media_checking_notification_message">"检查是否有错误"</string> + <string name="ext_media_nofs_notification_title">"空 SD 卡"</string> + <string name="ext_media_nofs_notification_message">"SD 卡为空或使用不支持的文件系统。"</string> + <string name="ext_media_unmountable_notification_title">"SD 卡受损"</string> + <string name="ext_media_unmountable_notification_message">"SD 卡受损。您可能需要重新格式化您的卡。"</string> + <string name="ext_media_badremoval_notification_title">"SD 卡被意外拔除"</string> + <string name="ext_media_badremoval_notification_message">"先卸载 SD 卡再拔除,以避免数据丢失。"</string> + <string name="ext_media_safe_unmount_notification_title">"SD 卡已安全移除"</string> + <string name="ext_media_safe_unmount_notification_message">"现在可以安全移除 SD 卡。"</string> + <string name="ext_media_nomedia_notification_title">"已移除 SD 卡"</string> + <string name="ext_media_nomedia_notification_message">"SD 卡已移除。请插入新 SD 卡来增加您的设备存储空间。"</string> + <string name="activity_list_empty">"找不到匹配的活动"</string> + <string name="permlab_pkgUsageStats">"更新组件使用情况统计"</string> + <string name="permdesc_pkgUsageStats">"允许修改收集的组件使用情况统计。普通应用程序不能使用此权限。"</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 419e8c2..18d6711 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -262,10 +262,8 @@ <string name="permdesc_reboot">"允許應用程式強制重開機。"</string> <string name="permlab_mount_unmount_filesystems">"掛載/卸載檔案系統"</string> <string name="permdesc_mount_unmount_filesystems">"允許應用程式掛載/卸載抽取式儲存設備的檔案系統。"</string> - <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) --> - <skip /> - <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) --> - <skip /> + <string name="permlab_mount_format_filesystems">"將外接式儲存裝置格式化"</string> + <string name="permdesc_mount_format_filesystems">"允許應用程式將可移除式儲存裝置格式化。"</string> <string name="permlab_vibrate">"控制震動器"</string> <string name="permdesc_vibrate">"允許應用程式控制震動器。"</string> <string name="permlab_flashlight">"控制閃光燈"</string> @@ -280,10 +278,8 @@ <string name="permdesc_locationUpdates">"允許啟用/停用無線通訊位置更新通知。一般應用程式不會使用此功能。"</string> <string name="permlab_checkinProperties">"存取登機選項"</string> <string name="permdesc_checkinProperties">"允許讀寫登機服務上傳的資料。一般應用程式不會使用此功能。"</string> - <!-- no translation found for permlab_bindGadget (2519859363977647275) --> - <skip /> - <!-- no translation found for permdesc_bindGadget (7865866514555126333) --> - <skip /> + <string name="permlab_bindGadget">"選擇小工具"</string> + <string name="permdesc_bindGadget">"允許應用程式告知系統哪些應用程式可以使用哪些小工具。擁有此權限的應用程式可以讓其他應用程式使用個人資料。一般應用程式不會使用此功能。"</string> <string name="permlab_modifyPhoneState">"修改手機狀態"</string> <string name="permdesc_modifyPhoneState">"允許應用程式控制電話功能。擁有此權限的程式可自行切換網路、開關無線通訊功能。"</string> <string name="permlab_readPhoneState">"讀取手機狀態"</string> @@ -312,10 +308,8 @@ <string name="permdesc_writeApnSettings">"允許應用程式修改 APN 設定,例如:Proxy 及 APN 的連接埠。"</string> <string name="permlab_changeNetworkState">"變更網路連線"</string> <string name="permdesc_changeNetworkState">"允許應用程式變更網路連線狀態。"</string> - <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) --> - <skip /> - <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) --> - <skip /> + <string name="permlab_changeBackgroundDataSetting">"變更背景資料使用設定"</string> + <string name="permdesc_changeBackgroundDataSetting">"允許應用程式變更背景資料使用設定。"</string> <string name="permlab_accessWifiState">"檢視 Wi-Fi 狀態"</string> <string name="permdesc_accessWifiState">"允許應用程式檢視 Wi-Fi 狀態資訊。"</string> <string name="permlab_changeWifiState">"變更 Wi-Fi 狀態"</string> @@ -336,14 +330,10 @@ <string name="permdesc_subscribedFeedsRead">"允許應用程式取得目前已同步處理的資訊提供。"</string> <string name="permlab_subscribedFeedsWrite">"寫入訂閱資訊提供"</string> <string name="permdesc_subscribedFeedsWrite">"允許應用程式修改已同步處理的資訊提供。惡意程式可使用此功能變更已同步處理的資訊提供。"</string> - <!-- no translation found for permlab_readDictionary (432535716804748781) --> - <skip /> - <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> - <skip /> - <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> - <skip /> - <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> - <skip /> + <string name="permlab_readDictionary">"讀取使用者定義的字典"</string> + <string name="permdesc_readDictionary">"允許應用程式讀取使用者儲存在使用者字典內的任何私人字詞、名稱和詞組。"</string> + <string name="permlab_writeDictionary">"寫入使用者定義的字典"</string> + <string name="permdesc_writeDictionary">"允許應用程式將新字詞寫入使用者的字典。"</string> <string-array name="phoneTypes"> <item>"首頁"</item> <item>"行動"</item> @@ -440,12 +430,9 @@ <string name="factorytest_not_system">"FACTORY_TEST 動作只支援安裝在 /system/app 裡的程式。"</string> <string name="factorytest_no_action">"找不到提供 FACTORY_TEST 的程式。"</string> <string name="factorytest_reboot">"重新開機"</string> - <!-- no translation found for js_dialog_title (8143918455087008109) --> - <skip /> - <!-- no translation found for js_dialog_title_default (6961903213729667573) --> - <skip /> - <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> - <skip /> + <string name="js_dialog_title">"「<xliff:g id="TITLE">%s</xliff:g>」的網頁指出:"</string> + <string name="js_dialog_title_default">"JavaScript"</string> + <string name="js_dialog_before_unload">"離開此頁?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n" 選取 [確定] 離開此頁;或 [取消] 留在此頁。"</string> <string name="save_password_label">"確認"</string> <string name="save_password_message">"是否記憶此密碼?"</string> <string name="save_password_notnow">"現在不要"</string> @@ -496,22 +483,38 @@ <item quantity="one">"明天"</item> <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天內"</item> </plurals> - <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) --> - <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) --> - <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) --> - <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) --> - <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) --> - <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) --> - <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) --> - <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) --> - <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) --> - <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) --> - <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) --> - <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) --> - <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) --> - <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) --> - <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) --> - <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) --> + <plurals name="abbrev_num_seconds_ago"> + <item quantity="one">"1 秒以前"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 秒以前"</item> + </plurals> + <plurals name="abbrev_num_minutes_ago"> + <item quantity="one">"1 分鐘以前"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分鐘以前"</item> + </plurals> + <plurals name="abbrev_num_hours_ago"> + <item quantity="one">"1 小時以前"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 小時以前"</item> + </plurals> + <plurals name="abbrev_num_days_ago"> + <item quantity="one">"昨天"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天以前"</item> + </plurals> + <plurals name="abbrev_in_num_seconds"> + <item quantity="one">"1 秒內"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 秒內"</item> + </plurals> + <plurals name="abbrev_in_num_minutes"> + <item quantity="one">"1 分鐘內"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分鐘內"</item> + </plurals> + <plurals name="abbrev_in_num_hours"> + <item quantity="one">"1 小時內"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 小時內"</item> + </plurals> + <plurals name="abbrev_in_num_days"> + <item quantity="one">"明天"</item> + <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天內"</item> + </plurals> <string name="preposition_for_date">"%s"</string> <string name="preposition_for_time">"%s"</string> <string name="preposition_for_year">"%s"</string> @@ -553,17 +556,15 @@ <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>,<xliff:g id="WEEKDAY">%2$s</xliff:g>,<xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>,<xliff:g id="DATE">%3$s</xliff:g>"</string> <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>,<xliff:g id="DATE">%3$s</xliff:g>"</string> - <!-- no translation found for date_time (6104442718633642836) --> - <skip /> - <!-- no translation found for relative_time (1818557177829411417) --> - <skip /> + <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>,<xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>,<xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>,<xliff:g id="WEEKDAY">%2$s</xliff:g>"</string> - <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string> - <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> - <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> + <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string> + <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string> + <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string> <string name="noon">"中午"</string> <string name="Noon">"中午"</string> <string name="midnight">"午夜"</string> @@ -691,8 +692,7 @@ <string name="paste">"貼上"</string> <string name="copyUrl">"複製網址"</string> <string name="inputMethod">"輸入法"</string> - <!-- no translation found for addToDictionary (726256909274177272) --> - <skip /> + <string name="addToDictionary">"將「%s」新增到字典"</string> <string name="editTextMenuTitle">"編輯文字"</string> <string name="low_internal_storage_view_title">"儲存空間太少"</string> <string name="low_internal_storage_view_text">"手機儲存空間即將不足。"</string> @@ -700,8 +700,7 @@ <string name="cancel">"取消"</string> <string name="yes">"確定"</string> <string name="no">"取消"</string> - <!-- no translation found for dialog_alert_title (2049658708609043103) --> - <skip /> + <string name="dialog_alert_title">"注意"</string> <string name="capital_on">"開啟"</string> <string name="capital_off">"關閉"</string> <string name="whichApplication">"選取...完成動作"</string> @@ -725,8 +724,7 @@ <string name="volume_music">"媒體音量"</string> <string name="volume_music_hint_playing_through_bluetooth">"透過藍牙播放"</string> <string name="volume_call">"來電音量"</string> - <!-- no translation found for volume_bluetooth_call (2002891926351151534) --> - <skip /> + <string name="volume_bluetooth_call">"藍牙通話音量"</string> <string name="volume_alarm">"鬧鐘音量"</string> <string name="volume_notification">"通知音量"</string> <string name="volume_unknown">"音量"</string> @@ -762,60 +760,35 @@ <string name="usb_storage_error_message">"把 SD 卡當成 USB 儲存裝置時發生問題。"</string> <string name="usb_storage_notification_title">"USB 已連接"</string> <string name="usb_storage_notification_message">"選取此項將檔案複製到電腦,或從電腦複製。"</string> - <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) --> - <skip /> - <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) --> - <skip /> - <!-- no translation found for usb_storage_stop_title (6014127947456185321) --> - <skip /> - <!-- no translation found for usb_storage_stop_message (2390958966725232848) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) --> - <skip /> - <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) --> - <skip /> - <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) --> - <skip /> - <!-- no translation found for extmedia_format_title (8663247929551095854) --> - <skip /> - <!-- no translation found for extmedia_format_message (3621369962433523619) --> - <skip /> - <!-- no translation found for extmedia_format_button_format (4131064560127478695) --> - <skip /> + <string name="usb_storage_stop_notification_title">"關閉 USB 儲存裝置"</string> + <string name="usb_storage_stop_notification_message">"選取此處關閉 USB 儲存裝置。"</string> + <string name="usb_storage_stop_title">"關閉 USB 儲存裝置"</string> + <string name="usb_storage_stop_message">"關閉 USB 儲存裝置之前,請確定先從 USB Host 卸載。選取 [關閉] 即可關閉 USB 儲存裝置。"</string> + <string name="usb_storage_stop_button_mount">"關閉"</string> + <string name="usb_storage_stop_button_unmount">"取消"</string> + <string name="usb_storage_stop_error_message">"關閉 USB 儲存裝置時發生問題。請檢查確認您是否已卸載 USB Host,然後再試一次。"</string> + <string name="extmedia_format_title">"將 SD 卡格式化"</string> + <string name="extmedia_format_message">"確定要將 SD 卡格式化嗎?該 SD 卡中的所有資料將會遺失。"</string> + <string name="extmedia_format_button_format">"格式化"</string> <string name="select_input_method">"選取輸入法"</string> <string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> - <!-- no translation found for candidates_style (4333913089637062257) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) --> - <skip /> - <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) --> - <skip /> - <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) --> - <skip /> - <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) --> - <skip /> - <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) --> - <skip /> - <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) --> - <skip /> - <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) --> - <skip /> - <!-- no translation found for activity_list_empty (4168820609403385789) --> - <skip /> - <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) --> - <skip /> - <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) --> - <skip /> + <string name="candidates_style"><u>"待選項目"</u></string> + <string name="ext_media_checking_notification_title">"正在準備 SD 卡"</string> + <string name="ext_media_checking_notification_message">"正在檢查錯誤"</string> + <string name="ext_media_nofs_notification_title">"SD 卡為空白"</string> + <string name="ext_media_nofs_notification_message">"SD 卡為空白或使用不支援的檔案系統。"</string> + <string name="ext_media_unmountable_notification_title">"SD 卡已損壞"</string> + <string name="ext_media_unmountable_notification_message">"SD 卡已損壞。您可能需要將 SD 卡重新格式化。"</string> + <string name="ext_media_badremoval_notification_title">"SD 卡未預期移除"</string> + <string name="ext_media_badremoval_notification_message">"請先卸載 SD 卡,再將其移除,以免資料遺失。"</string> + <string name="ext_media_safe_unmount_notification_title">"可安全移除 SD 卡"</string> + <string name="ext_media_safe_unmount_notification_message">"現在可以安全移除 SD 卡。"</string> + <string name="ext_media_nomedia_notification_title">"已移除 SD 卡"</string> + <string name="ext_media_nomedia_notification_message">"已移除 SD 卡。請插入新的 SD 卡來增加裝置的儲存容量。"</string> + <string name="activity_list_empty">"找不到符合的活動"</string> + <string name="permlab_pkgUsageStats">"更新元件使用統計資料"</string> + <string name="permdesc_pkgUsageStats">"允許修改收集到的元件使用統計資料。一般應用程式不會使用此功能。"</string> + <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) --> <skip /> </resources> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 593d1ff..6e6e074 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -224,15 +224,18 @@ <!-- Leave the soft input window as-is, in whatever state it last was. --> <flag name="stateUnchanged" value="1" /> - <!-- Don't display the soft input area, there is no reason to - do so on this window. --> + <!-- Make the soft input area hidden when normally appropriate + (when the user is navigating forward to your window). --> <flag name="stateHidden" value="2" /> + <!-- Always make the soft input area hidden when this window + has input focus. --> + <flag name="stateAlwaysHidden" value="3" /> <!-- Make the soft input area visible when normally appropriate (when the user is navigating forward to your window). --> - <flag name="stateVisible" value="3" /> + <flag name="stateVisible" value="4" /> <!-- Always make the soft input area visible when this window has input focus. --> - <flag name="stateAlwaysVisible" value="4" /> + <flag name="stateAlwaysVisible" value="5" /> <!-- The window resize/pan adjustment has not been specified, the system will automatically select between resize and pan diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index f717196..2ff0962 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -170,6 +170,12 @@ user ID, they must also be signed with the same signature. --> <attr name="sharedUserId" format="string" /> + <!-- Specify a label for the shared user UID of this package. This is + only used if you have also used android:sharedUserId. This must + be a reference to a string resource; it can not be an explicit + string. --> + <attr name="sharedUserLabel" format="reference" /> + <!-- Internal version code. This is the number used to determine whether one version is more recent than another: it has no other meaning than that higher numbers are more recent. You could use this number to @@ -579,6 +585,7 @@ <attr name="versionCode" /> <attr name="versionName" /> <attr name="sharedUserId" /> + <attr name="sharedUserLabel" /> </declare-styleable> <!-- The <code>application</code> tag describes application-level components diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 9175f31..e6b0ff7 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1004,6 +1004,7 @@ <public type="attr" name="hapticFeedbackEnabled" id="0x0101025e" /> <public type="attr" name="innerRadius" id="0x0101025f" /> <public type="attr" name="thickness" id="0x01010260" /> + <public type="attr" name="sharedUserLabel" id="0x01010261" /> <!-- The part of the UI shown by an {@link android.inputmethodservice.InputMethodService} that contains the diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 1174996..7adf542 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -243,6 +243,9 @@ <!-- Displayed to the user to tell them that they have started up the phone in "safe mode" --> <string name="safeMode">Safe mode</string> + <!-- Label for the Android system components when they are shown to the user. --> + <string name="android_system_label">Android System</string> + <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_costMoney">Services that cost you money</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> @@ -2265,6 +2268,3 @@ <!-- Shown in the tutorial for double tap to zoom. --> <string name="tutorial_double_tap_to_zoom_message_short">Double tap to zoom</string> </resources> - - - |