diff options
Diffstat (limited to 'core')
87 files changed, 6078 insertions, 3308 deletions
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index 3a11cb3..8af5fa4 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -16,20 +16,27 @@ package android.accounts; +import android.Manifest; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.RegisteredServicesCache; -import android.content.pm.PackageInfo; -import android.content.pm.ApplicationInfo; import android.content.pm.RegisteredServicesCacheListener; import android.database.Cursor; import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; @@ -37,17 +44,13 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SystemClock; -import android.os.Binder; import android.os.SystemProperties; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.util.Pair; -import android.app.PendingIntent; -import android.app.NotificationManager; -import android.app.Notification; -import android.Manifest; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -58,8 +61,9 @@ import java.util.HashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import com.android.internal.telephony.TelephonyIntents; import com.android.internal.R; +import com.android.internal.telephony.ITelephony; +import com.android.internal.telephony.TelephonyIntents; /** * A system service that provides account, password, and authtoken management for all @@ -90,11 +94,8 @@ public class AccountManagerService // Messages that can be sent on mHandler private static final int MESSAGE_TIMED_OUT = 3; - private static final int MESSAGE_CONNECTED = 7; - private static final int MESSAGE_DISCONNECTED = 8; private final AccountAuthenticatorCache mAuthenticatorCache; - private final AuthenticatorBindHelper mBindHelper; private final DatabaseHelper mOpenHelper; private final SimWatcher mSimWatcher; @@ -220,8 +221,6 @@ public class AccountManagerService mAuthenticatorCache = new AccountAuthenticatorCache(mContext); mAuthenticatorCache.setListener(this); - mBindHelper = new AuthenticatorBindHelper(mContext, mAuthenticatorCache, mMessageHandler, - MESSAGE_CONNECTED, MESSAGE_DISCONNECTED); mSimWatcher = new SimWatcher(mContext); sThis.set(this); @@ -1068,7 +1067,7 @@ public class AccountManagerService } private abstract class Session extends IAccountAuthenticatorResponse.Stub - implements AuthenticatorBindHelper.Callback, IBinder.DeathRecipient { + implements IBinder.DeathRecipient, ServiceConnection { IAccountManagerResponse mResponse; final String mAccountType; final boolean mExpectActivityLaunch; @@ -1150,7 +1149,7 @@ public class AccountManagerService if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "initiating bind to authenticator type " + mAccountType); } - if (!mBindHelper.bind(mAccountType, this)) { + if (!bindToAuthenticator(mAccountType)) { Log.d(TAG, "bind attempt failed for " + toDebugString()); onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "bind failure"); } @@ -1159,7 +1158,7 @@ public class AccountManagerService private void unbind() { if (mAuthenticator != null) { mAuthenticator = null; - mBindHelper.unbind(this); + mContext.unbindService(this); } } @@ -1172,7 +1171,7 @@ public class AccountManagerService mMessageHandler.removeMessages(MESSAGE_TIMED_OUT, this); } - public void onConnected(IBinder service) { + public void onServiceConnected(ComponentName name, IBinder service) { mAuthenticator = IAccountAuthenticator.Stub.asInterface(service); try { run(); @@ -1182,9 +1181,7 @@ public class AccountManagerService } } - public abstract void run() throws RemoteException; - - public void onDisconnected() { + public void onServiceDisconnected(ComponentName name) { mAuthenticator = null; IAccountManagerResponse response = getResponseAndClose(); if (response != null) { @@ -1193,6 +1190,8 @@ public class AccountManagerService } } + public abstract void run() throws RemoteException; + public void onTimedOut() { IAccountManagerResponse response = getResponseAndClose(); if (response != null) { @@ -1262,6 +1261,39 @@ public class AccountManagerService } } } + + /** + * find the component name for the authenticator and initiate a bind + * if no authenticator or the bind fails then return false, otherwise return true + */ + private boolean bindToAuthenticator(String authenticatorType) { + AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo = + mAuthenticatorCache.getServiceInfo( + AuthenticatorDescription.newKey(authenticatorType)); + if (authenticatorInfo == null) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "there is no authenticator for " + authenticatorType + + ", bailing out"); + } + return false; + } + + Intent intent = new Intent(); + intent.setAction(AccountManager.ACTION_AUTHENTICATOR_INTENT); + intent.setComponent(authenticatorInfo.componentName); + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "performing bindService to " + authenticatorInfo.componentName); + } + if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE)) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "bindService to " + authenticatorInfo.componentName + " failed"); + } + return false; + } + + + return true; + } } private class MessageHandler extends Handler { @@ -1270,9 +1302,6 @@ public class AccountManagerService } public void handleMessage(Message msg) { - if (mBindHelper.handleMessage(msg)) { - return; - } switch (msg.what) { case MESSAGE_TIMED_OUT: Session session = (Session)msg.obj; @@ -1412,16 +1441,58 @@ public class AccountManagerService */ @Override public void onReceive(Context context, Intent intent) { - // Check IMSI on every update; nothing happens if the IMSI is missing or unchanged. - String imsi = ((TelephonyManager) context.getSystemService( - Context.TELEPHONY_SERVICE)).getSubscriberId(); + // Check IMSI on every update; nothing happens if the IMSI + // is missing or unchanged. + TelephonyManager telephonyManager = + (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + if (telephonyManager == null) { + Log.w(TAG, "failed to get TelephonyManager"); + return; + } + String imsi = telephonyManager.getSubscriberId(); + + // If the subscriber ID is an empty string, don't do anything. if (TextUtils.isEmpty(imsi)) return; + // If the current IMSI matches what's stored, don't do anything. String storedImsi = getMetaValue("imsi"); - if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "current IMSI=" + imsi + "; stored IMSI=" + storedImsi); } + if (imsi.equals(storedImsi)) return; + + // If a CDMA phone is unprovisioned, getSubscriberId() + // will return a different value, but we *don't* erase the + // passwords. We only erase them if it has a different + // subscriber ID once it's provisioned. + if (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { + IBinder service = ServiceManager.checkService(Context.TELEPHONY_SERVICE); + if (service == null) { + Log.w(TAG, "call to checkService(TELEPHONY_SERVICE) failed"); + return; + } + ITelephony telephony = ITelephony.Stub.asInterface(service); + if (telephony == null) { + Log.w(TAG, "failed to get ITelephony interface"); + return; + } + boolean needsProvisioning; + try { + needsProvisioning = telephony.getCdmaNeedsProvisioning(); + } catch (RemoteException e) { + Log.w(TAG, "exception while checking provisioning", e); + // default to NOT wiping out the passwords + needsProvisioning = true; + } + if (needsProvisioning) { + // if the phone needs re-provisioning, don't do anything. + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "current IMSI=" + imsi + " (needs provisioning); stored IMSI=" + + storedImsi); + } + return; + } + } if (!imsi.equals(storedImsi) && !TextUtils.isEmpty(storedImsi)) { Log.w(TAG, "wiping all passwords and authtokens because IMSI changed (" @@ -1567,13 +1638,14 @@ public class AccountManagerService private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) { final boolean fromAuthenticator = hasAuthenticatorUid(account.type, callerUid); final boolean hasExplicitGrants = hasExplicitlyGrantedPermission(account, authTokenType); + final boolean inSystemImage = inSystemImage(callerUid); if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid " + callerUid + ", account " + account + ": is authenticator? " + fromAuthenticator + ", has explicit permission? " + hasExplicitGrants); } - return fromAuthenticator || hasExplicitGrants || inSystemImage(callerUid); + return fromAuthenticator || hasExplicitGrants || inSystemImage; } private boolean hasAuthenticatorUid(String accountType, int callingUid) { diff --git a/core/java/android/accounts/AuthenticatorBindHelper.java b/core/java/android/accounts/AuthenticatorBindHelper.java deleted file mode 100644 index 2ca1f0e..0000000 --- a/core/java/android/accounts/AuthenticatorBindHelper.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.accounts; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.Handler; -import android.os.IBinder; -import android.os.Message; -import android.util.Log; - -import java.util.ArrayList; -import java.util.Map; - -import com.google.android.collect.Lists; -import com.google.android.collect.Maps; - -/** - * A helper object that simplifies binding to Account Authenticators. It uses the - * {@link AccountAuthenticatorCache} to find the component name of the authenticators, - * allowing the user to bind by account name. It also allows multiple, simultaneous binds - * to the same authenticator, with each bind call guaranteed to return either - * {@link Callback#onConnected} or {@link Callback#onDisconnected} if the bind() call - * itself succeeds, even if the authenticator is already bound internally. - * @hide - */ -public class AuthenticatorBindHelper { - private static final String TAG = "Accounts"; - private final Handler mHandler; - private final Context mContext; - private final int mMessageWhatConnected; - private final int mMessageWhatDisconnected; - private final Map<String, MyServiceConnection> mServiceConnections = Maps.newHashMap(); - private final Map<String, ArrayList<Callback>> mServiceUsers = Maps.newHashMap(); - private final AccountAuthenticatorCache mAuthenticatorCache; - - public AuthenticatorBindHelper(Context context, - AccountAuthenticatorCache authenticatorCache, Handler handler, - int messageWhatConnected, int messageWhatDisconnected) { - mContext = context; - mHandler = handler; - mAuthenticatorCache = authenticatorCache; - mMessageWhatConnected = messageWhatConnected; - mMessageWhatDisconnected = messageWhatDisconnected; - } - - public interface Callback { - void onConnected(IBinder service); - void onDisconnected(); - } - - public boolean bind(String authenticatorType, Callback callback) { - // if the authenticator is connecting or connected then return true - synchronized (mServiceConnections) { - if (mServiceConnections.containsKey(authenticatorType)) { - MyServiceConnection connection = mServiceConnections.get(authenticatorType); - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "service connection already exists for " + authenticatorType); - } - mServiceUsers.get(authenticatorType).add(callback); - if (connection.mService != null) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "the service is connected, scheduling a connected message for " - + authenticatorType); - } - connection.scheduleCallbackConnectedMessage(callback); - } else { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "the service is *not* connected, waiting for for " - + authenticatorType); - } - } - return true; - } - - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "there is no service connection for " + authenticatorType); - } - - // otherwise find the component name for the authenticator and initiate a bind - // if no authenticator or the bind fails then return false, otherwise return true - AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo = - mAuthenticatorCache.getServiceInfo( - AuthenticatorDescription.newKey(authenticatorType)); - if (authenticatorInfo == null) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "there is no authenticator for " + authenticatorType - + ", bailing out"); - } - return false; - } - - MyServiceConnection connection = new MyServiceConnection(authenticatorType); - - Intent intent = new Intent(); - intent.setAction("android.accounts.AccountAuthenticator"); - intent.setComponent(authenticatorInfo.componentName); - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "performing bindService to " + authenticatorInfo.componentName); - } - if (!mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE)) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "bindService to " + authenticatorInfo.componentName + " failed"); - } - return false; - } - - mServiceConnections.put(authenticatorType, connection); - mServiceUsers.put(authenticatorType, Lists.newArrayList(callback)); - return true; - } - } - - public void unbind(Callback callbackToUnbind) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "unbinding callback " + callbackToUnbind); - } - synchronized (mServiceConnections) { - for (Map.Entry<String, ArrayList<Callback>> entry : mServiceUsers.entrySet()) { - final String authenticatorType = entry.getKey(); - final ArrayList<Callback> serviceUsers = entry.getValue(); - for (Callback callback : serviceUsers) { - if (callback == callbackToUnbind) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "found callback in service" + authenticatorType); - } - serviceUsers.remove(callbackToUnbind); - if (serviceUsers.isEmpty()) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "there are no more callbacks for service " - + authenticatorType + ", unbinding service"); - } - unbindFromServiceLocked(authenticatorType); - } else { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "leaving service " + authenticatorType - + " around since there are still callbacks using it"); - } - } - return; - } - } - } - Log.e(TAG, "did not find callback " + callbackToUnbind + " in any of the services"); - } - } - - /** - * You must synchronized on mServiceConnections before calling this - */ - private void unbindFromServiceLocked(String authenticatorType) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "unbindService from " + authenticatorType); - } - mContext.unbindService(mServiceConnections.get(authenticatorType)); - mServiceUsers.remove(authenticatorType); - mServiceConnections.remove(authenticatorType); - } - - private class ConnectedMessagePayload { - public final IBinder mService; - public final Callback mCallback; - public ConnectedMessagePayload(IBinder service, Callback callback) { - mService = service; - mCallback = callback; - } - } - - private class MyServiceConnection implements ServiceConnection { - private final String mAuthenticatorType; - private IBinder mService = null; - - public MyServiceConnection(String authenticatorType) { - mAuthenticatorType = authenticatorType; - } - - public void onServiceConnected(ComponentName name, IBinder service) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "onServiceConnected for account type " + mAuthenticatorType); - } - // post a message for each service user to tell them that the service is connected - synchronized (mServiceConnections) { - mService = service; - for (Callback callback : mServiceUsers.get(mAuthenticatorType)) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "the service became connected, scheduling a connected " - + "message for " + mAuthenticatorType); - } - scheduleCallbackConnectedMessage(callback); - } - } - } - - private void scheduleCallbackConnectedMessage(Callback callback) { - final ConnectedMessagePayload payload = - new ConnectedMessagePayload(mService, callback); - mHandler.obtainMessage(mMessageWhatConnected, payload).sendToTarget(); - } - - public void onServiceDisconnected(ComponentName name) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "onServiceDisconnected for account type " + mAuthenticatorType); - } - // post a message for each service user to tell them that the service is disconnected, - // and unbind from the service. - synchronized (mServiceConnections) { - final ArrayList<Callback> callbackList = mServiceUsers.get(mAuthenticatorType); - if (callbackList != null) { - for (Callback callback : callbackList) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "the service became disconnected, scheduling a " - + "disconnected message for " - + mAuthenticatorType); - } - mHandler.obtainMessage(mMessageWhatDisconnected, callback).sendToTarget(); - } - unbindFromServiceLocked(mAuthenticatorType); - } - } - } - } - - boolean handleMessage(Message message) { - if (message.what == mMessageWhatConnected) { - ConnectedMessagePayload payload = (ConnectedMessagePayload)message.obj; - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "notifying callback " + payload.mCallback + " that it is connected"); - } - payload.mCallback.onConnected(payload.mService); - return true; - } else if (message.what == mMessageWhatDisconnected) { - Callback callback = (Callback)message.obj; - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "notifying callback " + callback + " that it is disconnected"); - } - callback.onDisconnected(); - return true; - } else { - return false; - } - } -} diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java index e3ed2e9..f4b7258 100644 --- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java +++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java @@ -18,14 +18,16 @@ package android.accounts; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; -import android.widget.ArrayAdapter; -import android.widget.ListView; +import android.widget.LinearLayout; +import android.widget.ImageView; import android.view.View; import android.view.LayoutInflater; -import android.view.ViewGroup; +import android.view.Window; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.text.TextUtils; +import android.graphics.drawable.Drawable; import com.android.internal.R; /** @@ -43,62 +45,68 @@ public class GrantCredentialsPermissionActivity extends Activity implements View private String mAuthTokenType; private int mUid; private Bundle mResultBundle = null; + protected LayoutInflater mInflater; protected void onCreate(Bundle savedInstanceState) { + requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); - getWindow().setContentView(R.layout.grant_credentials_permission); - mAccount = getIntent().getExtras().getParcelable(EXTRAS_ACCOUNT); - mAuthTokenType = getIntent().getExtras().getString(EXTRAS_AUTH_TOKEN_TYPE); - mUid = getIntent().getExtras().getInt(EXTRAS_REQUESTING_UID); - final String accountTypeLabel = - getIntent().getExtras().getString(EXTRAS_ACCOUNT_TYPE_LABEL); - final String[] packages = getIntent().getExtras().getStringArray(EXTRAS_PACKAGES); + setContentView(R.layout.grant_credentials_permission); - findViewById(R.id.allow).setOnClickListener(this); - findViewById(R.id.deny).setOnClickListener(this); + mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - TextView messageView = (TextView) getWindow().findViewById(R.id.message); - String authTokenLabel = getIntent().getExtras().getString(EXTRAS_AUTH_TOKEN_LABEL); - if (authTokenLabel.length() == 0) { - CharSequence grantCredentialsPermissionFormat = getResources().getText( - R.string.grant_credentials_permission_message_desc); - messageView.setText(String.format(grantCredentialsPermissionFormat.toString(), - mAccount.name, accountTypeLabel)); - } else { - CharSequence grantCredentialsPermissionFormat = getResources().getText( - R.string.grant_credentials_permission_message_with_authtokenlabel_desc); - messageView.setText(String.format(grantCredentialsPermissionFormat.toString(), - authTokenLabel, mAccount.name, accountTypeLabel)); - } + final Bundle extras = getIntent().getExtras(); + mAccount = extras.getParcelable(EXTRAS_ACCOUNT); + mAuthTokenType = extras.getString(EXTRAS_AUTH_TOKEN_TYPE); + mUid = extras.getInt(EXTRAS_REQUESTING_UID); + final String accountTypeLabel = extras.getString(EXTRAS_ACCOUNT_TYPE_LABEL); + final String[] packages = extras.getStringArray(EXTRAS_PACKAGES); + final String authTokenLabel = extras.getString(EXTRAS_AUTH_TOKEN_LABEL); + + findViewById(R.id.allow_button).setOnClickListener(this); + findViewById(R.id.deny_button).setOnClickListener(this); + + LinearLayout packagesListView = (LinearLayout) findViewById(R.id.packages_list); - String[] packageLabels = new String[packages.length]; final PackageManager pm = getPackageManager(); - for (int i = 0; i < packages.length; i++) { + for (String pkg : packages) { + String packageLabel; try { - packageLabels[i] = - pm.getApplicationLabel(pm.getApplicationInfo(packages[i], 0)).toString(); + packageLabel = pm.getApplicationLabel(pm.getApplicationInfo(pkg, 0)).toString(); } catch (PackageManager.NameNotFoundException e) { - packageLabels[i] = packages[i]; + packageLabel = pkg; } + packagesListView.addView(newPackageView(packageLabel)); + } + + ((TextView) findViewById(R.id.account_name)).setText(mAccount.name); + ((TextView) findViewById(R.id.account_type)).setText(accountTypeLabel); + TextView authTokenTypeView = (TextView) findViewById(R.id.authtoken_type); + if (TextUtils.isEmpty(authTokenLabel)) { + authTokenTypeView.setVisibility(View.GONE); + } else { + authTokenTypeView.setText(authTokenLabel); } - ((ListView) findViewById(R.id.packages_list)).setAdapter( - new PackagesArrayAdapter(this, packageLabels)); + } + + private View newPackageView(String packageLabel) { + View view = mInflater.inflate(R.layout.permissions_package_list_item, null); + ((TextView) view.findViewById(R.id.package_label)).setText(packageLabel); + return view; } public void onClick(View v) { + final AccountManagerService accountManagerService = AccountManagerService.getSingleton(); switch (v.getId()) { - case R.id.allow: - AccountManagerService.getSingleton().grantAppPermission(mAccount, mAuthTokenType, - mUid); + case R.id.allow_button: + accountManagerService.grantAppPermission(mAccount, mAuthTokenType, mUid); Intent result = new Intent(); result.putExtra("retry", true); setResult(RESULT_OK, result); setAccountAuthenticatorResult(result.getExtras()); break; - case R.id.deny: - AccountManagerService.getSingleton().revokeAppPermission(mAccount, mAuthTokenType, - mUid); + case R.id.deny_button: + accountManagerService.revokeAppPermission(mAccount, mAuthTokenType, mUid); setResult(RESULT_CANCELED); break; } @@ -110,63 +118,20 @@ public class GrantCredentialsPermissionActivity extends Activity implements View } /** - * Sends the result or a Constants.ERROR_CODE_CANCELED error if a result isn't present. + * Sends the result or a {@link AccountManager#ERROR_CODE_CANCELED} error if a + * result isn't present. */ public void finish() { Intent intent = getIntent(); - AccountAuthenticatorResponse accountAuthenticatorResponse = - intent.getParcelableExtra(EXTRAS_RESPONSE); - if (accountAuthenticatorResponse != null) { + AccountAuthenticatorResponse response = intent.getParcelableExtra(EXTRAS_RESPONSE); + if (response != null) { // send the result bundle back if set, otherwise send an error. if (mResultBundle != null) { - accountAuthenticatorResponse.onResult(mResultBundle); + response.onResult(mResultBundle); } else { - accountAuthenticatorResponse.onError(AccountManager.ERROR_CODE_CANCELED, "canceled"); + response.onError(AccountManager.ERROR_CODE_CANCELED, "canceled"); } } super.finish(); } - - private static class PackagesArrayAdapter extends ArrayAdapter<String> { - protected LayoutInflater mInflater; - private static final int mResource = R.layout.simple_list_item_1; - - public PackagesArrayAdapter(Context context, String[] items) { - super(context, mResource, items); - mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - } - - static class ViewHolder { - TextView label; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - // A ViewHolder keeps references to children views to avoid unneccessary calls - // to findViewById() on each row. - ViewHolder holder; - - // When convertView is not null, we can reuse it directly, there is no need - // to reinflate it. We only inflate a new View when the convertView supplied - // by ListView is null. - if (convertView == null) { - convertView = mInflater.inflate(mResource, null); - - // Creates a ViewHolder and store references to the two children views - // we want to bind data to. - holder = new ViewHolder(); - holder.label = (TextView) convertView.findViewById(R.id.text1); - - convertView.setTag(holder); - } else { - // Get the ViewHolder back to get fast access to the TextView - // and the ImageView. - holder = (ViewHolder) convertView.getTag(); - } - - holder.label.setText(getItem(position)); - - return convertView; - } - } } diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index ff48583..5b34ef9 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -46,7 +46,7 @@ import java.util.UUID; */ public final class BluetoothAdapter { private static final String TAG = "BluetoothAdapter"; - private static final boolean DBG = false; + private static final boolean DBG = true; //STOPSHIP: Remove excess logging /** * Sentinel error value for this class. Guaranteed to not equal any other diff --git a/core/java/android/content/AbstractSyncableContentProvider.java b/core/java/android/content/AbstractSyncableContentProvider.java index eba8715..9866862 100644 --- a/core/java/android/content/AbstractSyncableContentProvider.java +++ b/core/java/android/content/AbstractSyncableContentProvider.java @@ -747,4 +747,8 @@ public abstract class AbstractSyncableContentProvider extends SyncableContentPro public void writeSyncDataBytes(Account account, byte[] data) { mSyncState.writeSyncDataBytes(mOpenHelper.getWritableDatabase(), account, data); } + + protected ContentProvider getSyncStateProvider() { + return mSyncState.asContentProvider(); + } } diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java index fb6091a..0db6155 100644 --- a/core/java/android/content/AbstractThreadedSyncAdapter.java +++ b/core/java/android/content/AbstractThreadedSyncAdapter.java @@ -21,6 +21,7 @@ import android.os.Bundle; import android.os.Process; import android.os.NetStat; import android.os.IBinder; +import android.os.RemoteException; import android.util.EventLog; import java.util.concurrent.atomic.AtomicInteger; @@ -117,6 +118,12 @@ public abstract class AbstractThreadedSyncAdapter { } } } + + public void initialize(Account account, String authority) throws RemoteException { + Bundle extras = new Bundle(); + extras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true); + startSync(null, authority, account, extras); + } } /** diff --git a/core/java/android/content/ISyncAdapter.aidl b/core/java/android/content/ISyncAdapter.aidl index 4660527..dd9d14e 100644 --- a/core/java/android/content/ISyncAdapter.aidl +++ b/core/java/android/content/ISyncAdapter.aidl @@ -44,4 +44,12 @@ oneway interface ISyncAdapter { * @param syncContext the ISyncContext that was passed to {@link #startSync} */ void cancelSync(ISyncContext syncContext); + + /** + * Initialize the SyncAdapter for this account and authority. + * + * @param account the account that should be synced + * @param authority the authority that should be synced + */ + void initialize(in Account account, String authority); } diff --git a/core/java/android/content/SyncAdapter.java b/core/java/android/content/SyncAdapter.java index 88dc332..af1634e 100644 --- a/core/java/android/content/SyncAdapter.java +++ b/core/java/android/content/SyncAdapter.java @@ -38,6 +38,12 @@ public abstract class SyncAdapter { public void cancelSync(ISyncContext syncContext) throws RemoteException { SyncAdapter.this.cancelSync(); } + + public void initialize(Account account, String authority) throws RemoteException { + Bundle extras = new Bundle(); + extras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true); + startSync(null, authority, account, extras); + } } Transport mTransport = new Transport(); diff --git a/core/java/android/content/SyncContext.java b/core/java/android/content/SyncContext.java index 587586d..cc914c0 100644 --- a/core/java/android/content/SyncContext.java +++ b/core/java/android/content/SyncContext.java @@ -56,7 +56,9 @@ public class SyncContext { if (now < mLastHeartbeatSendTime + HEARTBEAT_SEND_INTERVAL_IN_MS) return; try { mLastHeartbeatSendTime = now; - mSyncContext.sendHeartbeat(); + if (mSyncContext != null) { + mSyncContext.sendHeartbeat(); + } } catch (RemoteException e) { // this should never happen } @@ -64,13 +66,15 @@ public class SyncContext { public void onFinished(SyncResult result) { try { - mSyncContext.onFinished(result); + if (mSyncContext != null) { + mSyncContext.onFinished(result); + } } catch (RemoteException e) { // this should never happen } } public IBinder getSyncContextBinder() { - return mSyncContext.asBinder(); + return (mSyncContext == null) ? null : mSyncContext.asBinder(); } } diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 9757ef6..8a529e9 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -544,6 +544,46 @@ class SyncManager implements OnAccountsUpdateListener { return (activeSyncContext != null) ? activeSyncContext.mSyncOperation.account : null; } + private void initializeSyncAdapter(Account account, String authority) { + SyncAdapterType syncAdapterType = SyncAdapterType.newKey(authority, account.type); + RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo = + mSyncAdapters.getServiceInfo(syncAdapterType); + if (syncAdapterInfo == null) { + Log.w(TAG, "can't find a sync adapter for " + syncAdapterType); + return; + } + + Intent intent = new Intent(); + intent.setAction("android.content.SyncAdapter"); + intent.setComponent(syncAdapterInfo.componentName); + mContext.bindService(intent, new InitializerServiceConnection(account, authority), + Context.BIND_AUTO_CREATE); + } + + private class InitializerServiceConnection implements ServiceConnection { + private final Account mAccount; + private final String mAuthority; + + public InitializerServiceConnection(Account account, String authority) { + mAccount = account; + mAuthority = authority; + } + + public void onServiceConnected(ComponentName name, IBinder service) { + try { + ISyncAdapter.Stub.asInterface(service).initialize(mAccount, mAuthority); + } catch (RemoteException e) { + // doesn't matter, we will retry again later + } finally { + mContext.unbindService(this); + } + } + + public void onServiceDisconnected(ComponentName name) { + mContext.unbindService(this); + } + } + /** * Returns whether or not sync is enabled. Sync can be enabled by * setting the system property "ro.config.sync" to the value "yes". @@ -686,36 +726,34 @@ class SyncManager implements OnAccountsUpdateListener { continue; } - // make this an initialization sync if the isSyncable state is unknown - Bundle extrasCopy = extras; - long delayCopy = delay; + // initialize the SyncAdapter if the isSyncable state is unknown if (isSyncable < 0) { - extrasCopy = new Bundle(extras); - extrasCopy.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true); - delayCopy = -1; // expedite this - } else { - final boolean syncAutomatically = masterSyncAutomatically - && mSyncStorageEngine.getSyncAutomatically(account, authority); - boolean syncAllowed = - manualSync || (backgroundDataUsageAllowed && syncAutomatically); - if (!syncAllowed) { - if (isLoggable) { - Log.d(TAG, "scheduleSync: sync of " + account + ", " + authority - + " is not allowed, dropping request"); - } - continue; + initializeSyncAdapter(account, authority); + continue; + } + + final boolean syncAutomatically = masterSyncAutomatically + && mSyncStorageEngine.getSyncAutomatically(account, authority); + boolean syncAllowed = + manualSync || (backgroundDataUsageAllowed && syncAutomatically); + if (!syncAllowed) { + if (isLoggable) { + Log.d(TAG, "scheduleSync: sync of " + account + ", " + authority + + " is not allowed, dropping request"); } + continue; } + if (isLoggable) { Log.v(TAG, "scheduleSync:" - + " delay " + delayCopy + + " delay " + delay + ", source " + source + ", account " + account + ", authority " + authority - + ", extras " + extrasCopy); + + ", extras " + extras); } scheduleSyncOperation( - new SyncOperation(account, source, authority, extrasCopy, delayCopy)); + new SyncOperation(account, source, authority, extras, delay)); } } } diff --git a/core/java/android/net/http/Connection.java b/core/java/android/net/http/Connection.java index 2d39e39..b8e17da 100644 --- a/core/java/android/net/http/Connection.java +++ b/core/java/android/net/http/Connection.java @@ -94,7 +94,6 @@ abstract class Connection { */ private static final String HTTP_CONNECTION = "http.connection"; - RequestQueue.ConnectionManager mConnectionManager; RequestFeeder mRequestFeeder; /** @@ -104,11 +103,9 @@ abstract class Connection { private byte[] mBuf; protected Connection(Context context, HttpHost host, - RequestQueue.ConnectionManager connectionManager, RequestFeeder requestFeeder) { mContext = context; mHost = host; - mConnectionManager = connectionManager; mRequestFeeder = requestFeeder; mCanPersist = false; @@ -124,18 +121,15 @@ abstract class Connection { * necessary */ static Connection getConnection( - Context context, HttpHost host, - RequestQueue.ConnectionManager connectionManager, + Context context, HttpHost host, HttpHost proxy, RequestFeeder requestFeeder) { if (host.getSchemeName().equals("http")) { - return new HttpConnection(context, host, connectionManager, - requestFeeder); + return new HttpConnection(context, host, requestFeeder); } // Otherwise, default to https - return new HttpsConnection(context, host, connectionManager, - requestFeeder); + return new HttpsConnection(context, host, proxy, requestFeeder); } /** @@ -338,7 +332,7 @@ abstract class Connection { mRequestFeeder.requeueRequest(tReq); empty = false; } - if (empty) empty = mRequestFeeder.haveRequest(mHost); + if (empty) empty = !mRequestFeeder.haveRequest(mHost); } return empty; } diff --git a/core/java/android/net/http/ConnectionThread.java b/core/java/android/net/http/ConnectionThread.java index 0b30e58..32191d2 100644 --- a/core/java/android/net/http/ConnectionThread.java +++ b/core/java/android/net/http/ConnectionThread.java @@ -108,24 +108,11 @@ class ConnectionThread extends Thread { if (HttpLog.LOGV) HttpLog.v("ConnectionThread: new request " + request.mHost + " " + request ); - HttpHost proxy = mConnectionManager.getProxyHost(); - - HttpHost host; - if (false) { - // Allow https proxy - host = proxy == null ? request.mHost : proxy; - } else { - // Disallow https proxy -- tmob proxy server - // serves a request loop for https reqs - host = (proxy == null || - request.mHost.getSchemeName().equals("https")) ? - request.mHost : proxy; - } - mConnection = mConnectionManager.getConnection(mContext, host); + mConnection = mConnectionManager.getConnection(mContext, + request.mHost); mConnection.processRequests(request); if (mConnection.getCanPersist()) { - if (!mConnectionManager.recycleConnection(host, - mConnection)) { + if (!mConnectionManager.recycleConnection(mConnection)) { mConnection.closeConnection(); } } else { diff --git a/core/java/android/net/http/HttpConnection.java b/core/java/android/net/http/HttpConnection.java index 8b12d0b..6df86bf 100644 --- a/core/java/android/net/http/HttpConnection.java +++ b/core/java/android/net/http/HttpConnection.java @@ -35,9 +35,8 @@ import org.apache.http.params.HttpConnectionParams; class HttpConnection extends Connection { HttpConnection(Context context, HttpHost host, - RequestQueue.ConnectionManager connectionManager, RequestFeeder requestFeeder) { - super(context, host, connectionManager, requestFeeder); + super(context, host, requestFeeder); } /** diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java index 8a69d0d..f735f3d 100644 --- a/core/java/android/net/http/HttpsConnection.java +++ b/core/java/android/net/http/HttpsConnection.java @@ -131,13 +131,16 @@ public class HttpsConnection extends Connection { */ private boolean mAborted = false; + // Used when connecting through a proxy. + private HttpHost mProxyHost; + /** * Contructor for a https connection. */ - HttpsConnection(Context context, HttpHost host, - RequestQueue.ConnectionManager connectionManager, + HttpsConnection(Context context, HttpHost host, HttpHost proxy, RequestFeeder requestFeeder) { - super(context, host, connectionManager, requestFeeder); + super(context, host, requestFeeder); + mProxyHost = proxy; } /** @@ -159,8 +162,7 @@ public class HttpsConnection extends Connection { AndroidHttpClientConnection openConnection(Request req) throws IOException { SSLSocket sslSock = null; - HttpHost proxyHost = mConnectionManager.getProxyHost(); - if (proxyHost != null) { + if (mProxyHost != null) { // If we have a proxy set, we first send a CONNECT request // to the proxy; if the proxy returns 200 OK, we negotiate // a secure connection to the target server via the proxy. @@ -172,7 +174,7 @@ public class HttpsConnection extends Connection { Socket proxySock = null; try { proxySock = new Socket - (proxyHost.getHostName(), proxyHost.getPort()); + (mProxyHost.getHostName(), mProxyHost.getPort()); proxySock.setSoTimeout(60 * 1000); diff --git a/core/java/android/net/http/RequestHandle.java b/core/java/android/net/http/RequestHandle.java index 190ae7a..77cd544 100644 --- a/core/java/android/net/http/RequestHandle.java +++ b/core/java/android/net/http/RequestHandle.java @@ -42,15 +42,13 @@ public class RequestHandle { private WebAddress mUri; private String mMethod; private Map<String, String> mHeaders; - private RequestQueue mRequestQueue; - private Request mRequest; - private InputStream mBodyProvider; private int mBodyLength; - private int mRedirectCount = 0; + // Used only with synchronous requests. + private Connection mConnection; private final static String AUTHORIZATION_HEADER = "Authorization"; private final static String PROXY_AUTHORIZATION_HEADER = "Proxy-Authorization"; @@ -81,6 +79,19 @@ public class RequestHandle { } /** + * Creates a new request session with a given Connection. This connection + * is used during a synchronous load to handle this request. + */ + public RequestHandle(RequestQueue requestQueue, String url, WebAddress uri, + String method, Map<String, String> headers, + InputStream bodyProvider, int bodyLength, Request request, + Connection conn) { + this(requestQueue, url, uri, method, headers, bodyProvider, bodyLength, + request); + mConnection = conn; + } + + /** * Cancels this request */ public void cancel() { @@ -262,6 +273,12 @@ public class RequestHandle { mRequest.waitUntilComplete(); } + public void processRequest() { + if (mConnection != null) { + mConnection.processRequests(mRequest); + } + } + /** * @return Digest-scheme authentication response. */ diff --git a/core/java/android/net/http/RequestQueue.java b/core/java/android/net/http/RequestQueue.java index 875caa0..84b6487 100644 --- a/core/java/android/net/http/RequestQueue.java +++ b/core/java/android/net/http/RequestQueue.java @@ -171,16 +171,17 @@ public class RequestQueue implements RequestFeeder { } public Connection getConnection(Context context, HttpHost host) { + host = RequestQueue.this.determineHost(host); Connection con = mIdleCache.getConnection(host); if (con == null) { mTotalConnection++; - con = Connection.getConnection( - mContext, host, this, RequestQueue.this); + con = Connection.getConnection(mContext, host, mProxyHost, + RequestQueue.this); } return con; } - public boolean recycleConnection(HttpHost host, Connection connection) { - return mIdleCache.cacheConnection(host, connection); + public boolean recycleConnection(Connection connection) { + return mIdleCache.cacheConnection(connection.getHost(), connection); } } @@ -342,6 +343,66 @@ public class RequestQueue implements RequestFeeder { req); } + private static class SyncFeeder implements RequestFeeder { + // This is used in the case where the request fails and needs to be + // requeued into the RequestFeeder. + private Request mRequest; + SyncFeeder() { + } + public Request getRequest() { + Request r = mRequest; + mRequest = null; + return r; + } + public Request getRequest(HttpHost host) { + return getRequest(); + } + public boolean haveRequest(HttpHost host) { + return mRequest != null; + } + public void requeueRequest(Request r) { + mRequest = r; + } + } + + public RequestHandle queueSynchronousRequest(String url, WebAddress uri, + String method, Map<String, String> headers, + EventHandler eventHandler, InputStream bodyProvider, + int bodyLength) { + if (HttpLog.LOGV) { + HttpLog.v("RequestQueue.dispatchSynchronousRequest " + uri); + } + + HttpHost host = new HttpHost(uri.mHost, uri.mPort, uri.mScheme); + + Request req = new Request(method, host, mProxyHost, uri.mPath, + bodyProvider, bodyLength, eventHandler, headers); + + // Open a new connection that uses our special RequestFeeder + // implementation. + host = determineHost(host); + Connection conn = Connection.getConnection(mContext, host, mProxyHost, + new SyncFeeder()); + + // TODO: I would like to process the request here but LoadListener + // needs a RequestHandle to process some messages. + return new RequestHandle(this, url, uri, method, headers, bodyProvider, + bodyLength, req, conn); + + } + + // Chooses between the proxy and the request's host. + private HttpHost determineHost(HttpHost host) { + // There used to be a comment in ConnectionThread about t-mob's proxy + // being really bad about https. But, HttpsConnection actually looks + // for a proxy and connects through it anyway. I think that this check + // is still valid because if a site is https, we will use + // HttpsConnection rather than HttpConnection if the proxy address is + // not secure. + return (mProxyHost == null || "https".equals(host.getSchemeName())) + ? host : mProxyHost; + } + /** * @return true iff there are any non-active requests pending */ @@ -478,6 +539,6 @@ public class RequestQueue implements RequestFeeder { interface ConnectionManager { HttpHost getProxyHost(); Connection getConnection(Context context, HttpHost host); - boolean recycleConnection(HttpHost host, Connection connection); + boolean recycleConnection(Connection connection); } } diff --git a/core/java/android/os/DropBoxEntry.aidl b/core/java/android/os/DropBoxEntry.aidl new file mode 100644 index 0000000..225eee1 --- /dev/null +++ b/core/java/android/os/DropBoxEntry.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +parcelable DropBoxEntry; diff --git a/core/java/android/os/DropBoxEntry.java b/core/java/android/os/DropBoxEntry.java new file mode 100644 index 0000000..e3816a8 --- /dev/null +++ b/core/java/android/os/DropBoxEntry.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.util.zip.GZIPInputStream; + +/** + * A single entry retrieved from an {@link IDropBox} implementation. + * This may include a reference to a stream, so you must call + * {@link #close()} when you are done using it. + * + * {@pending} + */ +public class DropBoxEntry implements Parcelable { + private final String mTag; + private final long mTimeMillis; + + private final String mText; + private final ParcelFileDescriptor mFileDescriptor; + private final int mFlags; + + /** Flag value: Entry's content was deleted to save space. */ + public static final int IS_EMPTY = 1; + + /** Flag value: Content is human-readable UTF-8 text (possibly compressed). */ + public static final int IS_TEXT = 2; + + /** Flag value: Content can been decompressed with {@link GZIPOutputStream}. */ + public static final int IS_GZIPPED = 4; + + /** Create a new DropBoxEntry with the specified contents. */ + public DropBoxEntry(String tag, long timeMillis, String text) { + if (tag == null || text == null) throw new NullPointerException(); + mTag = tag; + mTimeMillis = timeMillis; + mText = text; + mFileDescriptor = null; + mFlags = IS_TEXT; + } + + /** Create a new DropBoxEntry with the specified contents. */ + public DropBoxEntry(String tag, long millis, File data, int flags) throws IOException { + if (tag == null) throw new NullPointerException(); + if (((flags & IS_EMPTY) != 0) != (data == null)) throw new IllegalArgumentException(); + + mTag = tag; + mTimeMillis = millis; + mText = null; + mFlags = flags; + mFileDescriptor = data == null ? null : + ParcelFileDescriptor.open(data, ParcelFileDescriptor.MODE_READ_ONLY); + } + + /** Internal constructor for CREATOR.createFromParcel(). */ + private DropBoxEntry(String tag, long millis, Object value, int flags) { + if (tag == null) throw new NullPointerException(); + if (((flags & IS_EMPTY) != 0) != (value == null)) throw new IllegalArgumentException(); + + mTag = tag; + mTimeMillis = millis; + mFlags = flags; + + if (value == null) { + mText = null; + mFileDescriptor = null; + } else if (value instanceof String) { + if ((flags & IS_TEXT) == 0) throw new IllegalArgumentException(); + mText = (String) value; + mFileDescriptor = null; + } else if (value instanceof ParcelFileDescriptor) { + mText = null; + mFileDescriptor = (ParcelFileDescriptor) value; + } else { + throw new IllegalArgumentException(); + } + } + + /** Close the input stream associated with this entry. */ + public synchronized void close() { + try { if (mFileDescriptor != null) mFileDescriptor.close(); } catch (IOException e) { } + } + + /** @return the tag originally attached to the entry. */ + public String getTag() { return mTag; } + + /** @return time when the entry was originally created. */ + public long getTimeMillis() { return mTimeMillis; } + + /** @return flags describing the content returned by @{link #getInputStream()}. */ + public int getFlags() { return mFlags & ~IS_GZIPPED; } // getInputStream() decompresses. + + /** + * @param maxLength of string to return (will truncate at this length). + * @return the uncompressed text contents of the entry, null if the entry is not text. + */ + public String getText(int maxLength) { + if (mText != null) return mText.substring(0, Math.min(maxLength, mText.length())); + if ((mFlags & IS_TEXT) == 0) return null; + + try { + InputStream stream = getInputStream(); + if (stream == null) return null; + char[] buf = new char[maxLength]; + InputStreamReader reader = new InputStreamReader(stream); + return new String(buf, 0, Math.max(0, reader.read(buf))); + } catch (IOException e) { + return null; + } + } + + /** @return the uncompressed contents of the entry, or null if the contents were lost */ + public InputStream getInputStream() throws IOException { + if (mText != null) return new ByteArrayInputStream(mText.getBytes("UTF8")); + if (mFileDescriptor == null) return null; + InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(mFileDescriptor); + return (mFlags & IS_GZIPPED) != 0 ? new GZIPInputStream(is) : is; + } + + public static final Parcelable.Creator<DropBoxEntry> CREATOR = new Parcelable.Creator() { + public DropBoxEntry[] newArray(int size) { return new DropBoxEntry[size]; } + public DropBoxEntry createFromParcel(Parcel in) { + return new DropBoxEntry( + in.readString(), in.readLong(), in.readValue(null), in.readInt()); + } + }; + + public int describeContents() { + return mFileDescriptor != null ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0; + } + + public void writeToParcel(Parcel out, int flags) { + out.writeString(mTag); + out.writeLong(mTimeMillis); + if (mFileDescriptor != null) { + out.writeValue(mFileDescriptor); + } else { + out.writeValue(mText); + } + out.writeInt(mFlags); + } +} diff --git a/core/java/android/os/IDropBox.aidl b/core/java/android/os/IDropBox.aidl new file mode 100644 index 0000000..26294b6 --- /dev/null +++ b/core/java/android/os/IDropBox.aidl @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import android.os.DropBoxEntry; +import android.os.ParcelFileDescriptor; + +/** + * Enqueues chunks of data (from various sources -- application crashes, kernel + * log records, etc.). The queue is size bounded and will drop old data if the + * enqueued data exceeds the maximum size. + * + * <p>This interface is implemented by a system service you can access: + * + * <pre>IDropBox.Stub.asInterface(ServiceManager.getService("dropbox"));</pre> + * + * <p>Other system services and debugging tools may scan the drop box to upload + * entries for processing. + * + * {@pending} + */ +interface IDropBox { + /** + * Stores human-readable text. The data may be discarded eventually (or even + * immediately) if space is limited, or ignored entirely if the tag has been + * blocked (see {@link #isTagEnabled}). + * + * @param tag describing the type of entry being stored + * @param data value to store + */ + void addText(String tag, String data); + + /** + * Stores binary data. The data may be ignored or discarded as with + * {@link #addText}. + * + * @param tag describing the type of entry being stored + * @param data value to store + * @param flags describing the data, defined in {@link DropBoxEntry} + */ + void addData(String tag, in byte[] data, int flags); + + /** + * Stores data read from a file descriptor. The data may be ignored or + * discarded as with {@link #addText}. You must close your + * ParcelFileDescriptor object after calling this method! + * + * @param tag describing the type of entry being stored + * @param data file descriptor to read from + * @param flags describing the data, defined in {@link DropBoxEntry} + */ + void addFile(String tag, in ParcelFileDescriptor data, int flags); + + /** + * Checks any blacklists (set in system settings) to see whether a certain + * tag is allowed. Entries with disabled tags will be dropped immediately, + * so you can save the work of actually constructing and sending the data. + * + * @param tag that would be used in {@link #addText} or {@link #addFile} + * @return whether events with that tag would be accepted + */ + boolean isTagEnabled(String tag); + + /** + * Gets the next entry from the drop box *after* the specified time. + * Requires android.permission.READ_LOGS. You must always call + * {@link DropBoxEntry#close()} on the return value! + * + * @param tag of entry to look for, null for all tags + * @param millis time of the last entry seen + * @return the next entry, or null if there are no more entries + */ + DropBoxEntry getNextEntry(String tag, long millis); + + // TODO: It may be useful to have some sort of notification mechanism + // when data is added to the dropbox, for demand-driven readers -- + // for now readers need to poll the dropbox to find new data. +} diff --git a/core/java/android/pim/vcard/Constants.java b/core/java/android/pim/vcard/Constants.java index ca41ce5..a1c7e10 100644 --- a/core/java/android/pim/vcard/Constants.java +++ b/core/java/android/pim/vcard/Constants.java @@ -16,16 +16,47 @@ package android.pim.vcard; /** - * Constants used in both composer and parser. + * Constants used in both exporter and importer code. */ /* package */ class Constants { - public static final String ATTR_TYPE = "TYPE"; - public static final String VERSION_V21 = "2.1"; public static final String VERSION_V30 = "3.0"; + + // The property names valid both in vCard 2.1 and 3.0. + public static final String PROPERTY_BEGIN = "BEGIN"; + public static final String PROPERTY_VERSION = "VERSION"; + public static final String PROPERTY_N = "N"; + public static final String PROPERTY_FN = "FN"; + public static final String PROPERTY_ADR = "ADR"; + public static final String PROPERTY_EMAIL = "EMAIL"; + public static final String PROPERTY_NOTE = "NOTE"; + public static final String PROPERTY_ORG = "ORG"; + public static final String PROPERTY_SOUND = "SOUND"; // Not fully supported. + public static final String PROPERTY_TEL = "TEL"; + public static final String PROPERTY_TITLE = "TITLE"; + public static final String PROPERTY_ROLE = "ROLE"; + public static final String PROPERTY_PHOTO = "PHOTO"; + public static final String PROPERTY_LOGO = "LOGO"; + public static final String PROPERTY_URL = "URL"; + public static final String PROPERTY_BDAY = "BDAY"; // Birthday + public static final String PROPERTY_END = "END"; + + // Valid property names not supported (not appropriately handled) by our vCard importer now. + public static final String PROPERTY_REV = "REV"; + public static final String PROPERTY_AGENT = "AGENT"; + + // Available in vCard 3.0. Shoud not use when composing vCard 2.1 file. + public static final String PROPERTY_NAME = "NAME"; + public static final String PROPERTY_NICKNAME = "NICKNAME"; + public static final String PROPERTY_SORT_STRING = "SORT-STRING"; - // Properties both the current (as of 2009-08-17) ContactsStruct and de-fact vCard extensions + // De-fact property values expressing phonetic names. + public static final String PROPERTY_X_PHONETIC_FIRST_NAME = "X-PHONETIC-FIRST-NAME"; + public static final String PROPERTY_X_PHONETIC_MIDDLE_NAME = "X-PHONETIC-MIDDLE-NAME"; + public static final String PROPERTY_X_PHONETIC_LAST_NAME = "X-PHONETIC-LAST-NAME"; + + // Properties both ContactsStruct in Eclair and de-fact vCard extensions // shown in http://en.wikipedia.org/wiki/VCard support are defined here. public static final String PROPERTY_X_AIM = "X-AIM"; public static final String PROPERTY_X_MSN = "X-MSN"; @@ -34,12 +65,26 @@ package android.pim.vcard; public static final String PROPERTY_X_JABBER = "X-JABBER"; public static final String PROPERTY_X_GOOGLE_TALK = "X-GOOGLE-TALK"; public static final String PROPERTY_X_SKYPE_USERNAME = "X-SKYPE-USERNAME"; + // Properties only ContactsStruct has. We alse use this. + public static final String PROPERTY_X_QQ = "X-QQ"; + public static final String PROPERTY_X_NETMEETING = "X-NETMEETING"; + // Phone number for Skype, available as usual phone. public static final String PROPERTY_X_SKYPE_PSTNNUMBER = "X-SKYPE-PSTNNUMBER"; - // Some device emits this "X-" attribute, which is specifically invalid but should be - // always properly accepted, and emitted in some special case (for that device/application). - public static final String PROPERTY_X_GOOGLE_TALK_WITH_SPACE = "X-GOOGLE TALK"; - + + // Properties for DoCoMo vCard. + public static final String PROPERTY_X_CLASS = "X-CLASS"; + public static final String PROPERTY_X_REDUCTION = "X-REDUCTION"; + public static final String PROPERTY_X_NO = "X-NO"; + public static final String PROPERTY_X_DCM_HMN_MODE = "X-DCM-HMN-MODE"; + + // For some historical reason, we often use the term "ATTR"/"attribute" especially toward + // what is called "param" in both vCard specs, while vCard, while vCard importer side uses + // "param". + // + // TODO: Confusing. Fix it. + public static final String ATTR_TYPE = "TYPE"; + // How more than one TYPE fields are expressed is different between vCard 2.1 and vCard 3.0 // // e.g. @@ -59,12 +104,19 @@ package android.pim.vcard; public static final String ATTR_TYPE_VOICE = "VOICE"; public static final String ATTR_TYPE_INTERNET = "INTERNET"; + // Abbreviation of "prefered" according to vCard 2.1 specification. + // We interpret this value as "primary" property during import/export. + // + // Note: Both vCard specs does anything about the requirement about this attribute, + // but there may be some vCard importer which will get confused with more than + // one "PREF"s in one property name, while Android accepts them. public static final String ATTR_TYPE_PREF = "PREF"; // Phone types valid in vCard and known to ContactsContract, but not so common. public static final String ATTR_TYPE_CAR = "CAR"; public static final String ATTR_TYPE_ISDN = "ISDN"; public static final String ATTR_TYPE_PAGER = "PAGER"; + public static final String ATTR_TYPE_TLX = "TLX"; // Telex // Phone types existing in vCard 2.1 but not known to ContactsContract. // TODO: should make parser make these TYPE_CUSTOM. @@ -73,22 +125,39 @@ package android.pim.vcard; public static final String ATTR_TYPE_BBS = "BBS"; public static final String ATTR_TYPE_VIDEO = "VIDEO"; - // Phone types existing in the current Contacts structure but not valid in vCard (at least 2.1) - // These types are encoded to "X-" attributes when composing vCard for now. - // Parser passes these even if "X-" is added to the attribute. - public static final String ATTR_TYPE_PHONE_EXTRA_OTHER = "OTHER"; - public static final String ATTR_TYPE_PHONE_EXTRA_CALLBACK = "CALLBACK"; - // TODO: may be "TYPE=COMPANY,PREF", not "COMPANY-MAIN". - public static final String ATTR_TYPE_PHONE_EXTRA_COMPANY_MAIN = "COMPANY-MAIN"; - public static final String ATTR_TYPE_PHONE_EXTRA_RADIO = "RADIO"; - public static final String ATTR_TYPE_PHONE_EXTRA_TELEX = "TELEX"; - public static final String ATTR_TYPE_PHONE_EXTRA_TTY_TDD = "TTY-TDD"; - public static final String ATTR_TYPE_PHONE_EXTRA_ASSISTANT = "ASSISTANT"; + // Attribute for Phones, which are not formally valid in vCard (at least 2.1). + // These types are basically encoded to "X-" attributes when composing vCard. + // Parser passes these when "X-" is added to the attribute or not. + public static final String ATTR_PHONE_EXTRA_TYPE_CALLBACK = "CALLBACK"; + public static final String ATTR_PHONE_EXTRA_TYPE_RADIO = "RADIO"; + public static final String ATTR_PHONE_EXTRA_TYPE_TTY_TDD = "TTY-TDD"; + public static final String ATTR_PHONE_EXTRA_TYPE_ASSISTANT = "ASSISTANT"; + // vCard composer translates this type to "WORK" + "PREF". Just for parsing. + public static final String ATTR_PHONE_EXTRA_TYPE_COMPANY_MAIN = "COMPANY-MAIN"; + // vCard composer translates this type to "VOICE" Just for parsing. + public static final String ATTR_PHONE_EXTRA_TYPE_OTHER = "OTHER"; + + // Attribute for addresses. + public static final String ATTR_ADR_TYPE_PARCEL = "PARCEL"; + public static final String ATTR_ADR_TYPE_DOM = "DOM"; + public static final String ATTR_ADR_TYPE_INTL = "INTL"; + + // Attribute types not officially valid but used in some vCard exporter. + // Do not use in composer side. + public static final String ATTR_EXTRA_TYPE_COMPANY = "COMPANY"; // DoCoMo specific attribute. Used with "SOUND" property, which is alternate of SORT-STRING in // vCard 3.0. public static final String ATTR_TYPE_X_IRMC_N = "X-IRMC-N"; + public interface ImportOnly { + public static final String PROPERTY_X_NICKNAME = "X-NICKNAME"; + // Some device emits this "X-" attribute for expressing Google Talk, + // which is specifically invalid but should be always properly accepted, and emitted + // in some special case (for that device/application). + public static final String PROPERTY_X_GOOGLE_TALK_WITH_SPACE = "X-GOOGLE TALK"; + } + private Constants() { } }
\ No newline at end of file diff --git a/core/java/android/pim/vcard/ContactStruct.java b/core/java/android/pim/vcard/ContactStruct.java index 36e5e23..eb9c48a 100644 --- a/core/java/android/pim/vcard/ContactStruct.java +++ b/core/java/android/pim/vcard/ContactStruct.java @@ -38,6 +38,7 @@ import android.provider.ContactsContract.CommonDataKinds.StructuredName; import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.provider.ContactsContract.CommonDataKinds.Website; import android.telephony.PhoneNumberUtils; +import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.util.Log; @@ -46,7 +47,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -55,11 +55,11 @@ import java.util.Map; */ public class ContactStruct { private static final String LOG_TAG = "vcard.ContactStruct"; - + // Key: the name shown in VCard. e.g. "X-AIM", "X-ICQ" // Value: the result of {@link Contacts.ContactMethods#encodePredefinedImProtocol} private static final Map<String, Integer> sImMap = new HashMap<String, Integer>(); - + static { sImMap.put(Constants.PROPERTY_X_AIM, Im.PROTOCOL_AIM); sImMap.put(Constants.PROPERTY_X_MSN, Im.PROTOCOL_MSN); @@ -68,12 +68,10 @@ public class ContactStruct { sImMap.put(Constants.PROPERTY_X_JABBER, Im.PROTOCOL_JABBER); sImMap.put(Constants.PROPERTY_X_SKYPE_USERNAME, Im.PROTOCOL_SKYPE); sImMap.put(Constants.PROPERTY_X_GOOGLE_TALK, Im.PROTOCOL_GOOGLE_TALK); - sImMap.put(Constants.PROPERTY_X_GOOGLE_TALK_WITH_SPACE, Im.PROTOCOL_GOOGLE_TALK); + sImMap.put(Constants.ImportOnly.PROPERTY_X_GOOGLE_TALK_WITH_SPACE, + Im.PROTOCOL_GOOGLE_TALK); } - /** - * @hide only for testing - */ static public class PhoneData { public final int type; public final String data; @@ -90,7 +88,7 @@ public class ContactStruct { @Override public boolean equals(Object obj) { - if (obj instanceof PhoneData) { + if (!(obj instanceof PhoneData)) { return false; } PhoneData phoneData = (PhoneData)obj; @@ -125,7 +123,7 @@ public class ContactStruct { @Override public boolean equals(Object obj) { - if (obj instanceof EmailData) { + if (!(obj instanceof EmailData)) { return false; } EmailData emailData = (EmailData)obj; @@ -202,7 +200,7 @@ public class ContactStruct { @Override public boolean equals(Object obj) { - if (obj instanceof PostalData) { + if (!(obj instanceof PostalData)) { return false; } PostalData postalData = (PostalData)obj; @@ -251,87 +249,117 @@ public class ContactStruct { } } - /** - * @hide only for testing. - */ static public class OrganizationData { public final int type; - public final String companyName; - // can be changed in some VCard format. - public String positionName; + // non-final is Intended: we may change the values since this info is separated into + // two parts in vCard: "ORG" + "TITLE". + public String companyName; + public String departmentName; + public String titleName; // isPrimary is changable only when there's no appropriate one existing in // the original VCard. public boolean isPrimary; - public OrganizationData(int type, String companyName, String positionName, + public OrganizationData(int type, + String companyName, + String departmentName, + String titleName, boolean isPrimary) { this.type = type; this.companyName = companyName; - this.positionName = positionName; + this.departmentName = departmentName; + this.titleName = titleName; this.isPrimary = isPrimary; } @Override public boolean equals(Object obj) { - if (obj instanceof OrganizationData) { + if (!(obj instanceof OrganizationData)) { return false; } OrganizationData organization = (OrganizationData)obj; - return (type == organization.type && companyName.equals(organization.companyName) && - positionName.equals(organization.positionName) && + return (type == organization.type && + TextUtils.equals(companyName, organization.companyName) && + TextUtils.equals(departmentName, organization.departmentName) && + TextUtils.equals(titleName, organization.titleName) && isPrimary == organization.isPrimary); } - + @Override public String toString() { - return String.format("type: %d, company: %s, position: %s, isPrimary: %s", - type, companyName, positionName, isPrimary); + return String.format( + "type: %d, company: %s, department: %s, title: %s, isPrimary: %s", + type, companyName, departmentName, titleName, isPrimary); } } static public class ImData { + public final int protocol; + public final String customProtocol; public final int type; public final String data; - public final String label; public final boolean isPrimary; - // TODO: ContactsConstant#PROTOCOL, ContactsConstant#CUSTOM_PROTOCOL should be used? - public ImData(int type, String data, String label, boolean isPrimary) { + public ImData(int protocol, String customProtocol, int type, + String data, boolean isPrimary) { + this.protocol = protocol; + this.customProtocol = customProtocol; this.type = type; this.data = data; - this.label = label; this.isPrimary = isPrimary; } @Override public boolean equals(Object obj) { - if (obj instanceof ImData) { + if (!(obj instanceof ImData)) { return false; } ImData imData = (ImData)obj; - return (type == imData.type && data.equals(imData.data) && - label.equals(imData.label) && isPrimary == imData.isPrimary); + return (type == imData.type && protocol == imData.protocol + && (customProtocol != null ? customProtocol.equals(imData.customProtocol) : + (imData.customProtocol == null)) + && (data != null ? data.equals(imData.data) : (imData.data == null)) + && isPrimary == imData.isPrimary); } @Override public String toString() { - return String.format("type: %d, data: %s, label: %s, isPrimary: %s", - type, data, label, isPrimary); + return String.format( + "type: %d, protocol: %d, custom_protcol: %s, data: %s, isPrimary: %s", + type, protocol, customProtocol, data, isPrimary); } } - /** - * @hide only for testing. - */ static public class PhotoData { public static final String FORMAT_FLASH = "SWF"; public final int type; public final String formatName; // used when type is not defined in ContactsContract. public final byte[] photoBytes; + public final boolean isPrimary; - public PhotoData(int type, String formatName, byte[] photoBytes) { + public PhotoData(int type, String formatName, byte[] photoBytes, boolean isPrimary) { this.type = type; this.formatName = formatName; this.photoBytes = photoBytes; + this.isPrimary = isPrimary; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof PhotoData)) { + return false; + } + PhotoData photoData = (PhotoData)obj; + return (type == photoData.type && + (formatName == null ? (photoData.formatName == null) : + formatName.equals(photoData.formatName)) && + (Arrays.equals(photoBytes, photoData.photoBytes)) && + (isPrimary == photoData.isPrimary)); + } + + @Override + public String toString() { + return String.format("type: %d, format: %s: size: %d, isPrimary: %s", + type, formatName, photoBytes.length, isPrimary); } } @@ -342,10 +370,6 @@ public class ContactStruct { private List<String> mPropertyValueList = new ArrayList<String>(); private byte[] mPropertyBytes; - public Property() { - clear(); - } - public void setPropertyName(final String propertyName) { mPropertyName = propertyName; } @@ -385,6 +409,7 @@ public class ContactStruct { mPropertyName = null; mParameterMap.clear(); mPropertyValueList.clear(); + mPropertyBytes = null; } } @@ -421,17 +446,8 @@ public class ContactStruct { private final int mVCardType; private final Account mAccount; - // Each Column of four properties has ISPRIMARY field - // (See android.provider.Contacts) - // If false even after the parsing loop, we choose the first entry as a "primary" - // entry. - private boolean mPrefIsSet_Address; - private boolean mPrefIsSet_Phone; - private boolean mPrefIsSet_Email; - private boolean mPrefIsSet_Organization; - public ContactStruct() { - this(VCardConfig.VCARD_TYPE_V21_GENERIC); + this(VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8); } public ContactStruct(int vcardType) { @@ -444,186 +460,6 @@ public class ContactStruct { } /** - * @hide only for testing. - */ - public ContactStruct(String givenName, - String familyName, - String middleName, - String prefix, - String suffix, - String phoneticGivenName, - String pheneticFamilyName, - String phoneticMiddleName, - List<byte[]> photoBytesList, - List<String> notes, - List<PhoneData> phoneList, - List<EmailData> emailList, - List<PostalData> postalList, - List<OrganizationData> organizationList, - List<PhotoData> photoList, - List<String> websiteList) { - this(VCardConfig.VCARD_TYPE_DEFAULT); - mGivenName = givenName; - mFamilyName = familyName; - mPrefix = prefix; - mSuffix = suffix; - mPhoneticGivenName = givenName; - mPhoneticFamilyName = familyName; - mPhoneticMiddleName = middleName; - mEmailList = emailList; - mPostalList = postalList; - mOrganizationList = organizationList; - mPhotoList = photoList; - mWebsiteList = websiteList; - } - - // All getter methods should be used carefully, since they may change - // in the future as of 2009-09-24, on which I cannot be sure this structure - // is completely consolidated. - // When we are sure we will no longer change them, we'll be happy to - // make it complete public (withouth @hide tag) - // - // Also note that these getter methods should be used only after - // all properties being pushed into this object. If not, incorrect - // value will "be stored in the local cache and" be returned to you. - - /** - * @hide - */ - public String getFamilyName() { - return mFamilyName; - } - - /** - * @hide - */ - public String getGivenName() { - return mGivenName; - } - - /** - * @hide - */ - public String getMiddleName() { - return mMiddleName; - } - - /** - * @hide - */ - public String getPrefix() { - return mPrefix; - } - - /** - * @hide - */ - public String getSuffix() { - return mSuffix; - } - - /** - * @hide - */ - public String getFullName() { - return mFullName; - } - - /** - * @hide - */ - public String getPhoneticFamilyName() { - return mPhoneticFamilyName; - } - - /** - * @hide - */ - public String getPhoneticGivenName() { - return mPhoneticGivenName; - } - - /** - * @hide - */ - public String getPhoneticMiddleName() { - return mPhoneticMiddleName; - } - - /** - * @hide - */ - public String getPhoneticFullName() { - return mPhoneticFullName; - } - - /** - * @hide - */ - public final List<String> getNickNameList() { - return mNickNameList; - } - - /** - * @hide - */ - public String getDisplayName() { - if (mDisplayName == null) { - constructDisplayName(); - } - return mDisplayName; - } - - /** - * @hide - */ - public String getBirthday() { - return mBirthday; - } - - /** - * @hide - */ - public final List<PhotoData> getPhotoList() { - return mPhotoList; - } - - /** - * @hide - */ - public final List<String> getNotes() { - return mNoteList; - } - - /** - * @hide - */ - public final List<PhoneData> getPhoneList() { - return mPhoneList; - } - - /** - * @hide - */ - public final List<EmailData> getEmailList() { - return mEmailList; - } - - /** - * @hide - */ - public final List<PostalData> getPostalList() { - return mPostalList; - } - - /** - * @hide - */ - public final List<OrganizationData> getOrganizationList() { - return mOrganizationList; - } - - /** * Add a phone info to phoneList. * @param data phone number * @param type type col of content://contacts/phones @@ -643,10 +479,24 @@ public class ContactStruct { } } - PhoneData phoneData = new PhoneData(type, - PhoneNumberUtils.formatNumber(builder.toString()), - label, isPrimary); - + final String formattedPhoneNumber; + { + final String rawPhoneNumber = builder.toString(); + if (VCardConfig.isJapaneseDevice(mVCardType)) { + // As of 2009-10-07, there's no formatNumber() which accepts + // the second argument and returns String directly. + final SpannableStringBuilder tmpBuilder = + new SpannableStringBuilder(rawPhoneNumber); + PhoneNumberUtils.formatNumber(tmpBuilder, PhoneNumberUtils.FORMAT_JAPAN); + formattedPhoneNumber = tmpBuilder.toString(); + } else { + // There's no information available on vCard side. Depend on the default + // behavior, which may cause problem in the future when the additional format + // rule is supported (e.g. PhoneNumberUtils.FORMAT_KLINGON) + formattedPhoneNumber = PhoneNumberUtils.formatNumber(rawPhoneNumber); + } + } + PhoneData phoneData = new PhoneData(type, formattedPhoneNumber, label, isPrimary); mPhoneList.add(phoneData); } @@ -666,24 +516,122 @@ public class ContactStruct { private void addPostal(int type, List<String> propValueList, String label, boolean isPrimary){ if (mPostalList == null) { - mPostalList = new ArrayList<PostalData>(); + mPostalList = new ArrayList<PostalData>(0); } mPostalList.add(new PostalData(type, propValueList, label, isPrimary)); } - private void addOrganization(int type, final String companyName, - final String positionName, boolean isPrimary) { + /** + * Should be called via {@link #handleOrgValue(int, List, boolean)} or + * {@link #handleTitleValue(String)}. + */ + private void addNewOrganization(int type, final String companyName, + final String departmentName, + final String titleName, boolean isPrimary) { if (mOrganizationList == null) { mOrganizationList = new ArrayList<OrganizationData>(); } - mOrganizationList.add(new OrganizationData(type, companyName, positionName, isPrimary)); + mOrganizationList.add(new OrganizationData(type, companyName, + departmentName, titleName, isPrimary)); } + + private static final List<String> sEmptyList = new ArrayList<String>(0); - private void addIm(int type, String data, String label, boolean isPrimary) { + /** + * Set "ORG" related values to the appropriate data. If there's more than one + * OrganizationData objects, this input data are attached to the last one which does not + * have valid values (not including empty but only null). If there's no + * OrganizationData object, a new OrganizationData is created, whose title is set to null. + */ + private void handleOrgValue(final int type, List<String> orgList, boolean isPrimary) { + if (orgList == null) { + orgList = sEmptyList; + } + final String companyName; + final String departmentName; + final int size = orgList.size(); + switch (size) { + case 0: { + companyName = ""; + departmentName = null; + break; + } + case 1: { + companyName = orgList.get(0); + departmentName = null; + break; + } + default: { // More than 1. + companyName = orgList.get(0); + // We're not sure which is the correct string for department. + // In order to keep all the data, concatinate the rest of elements. + StringBuilder builder = new StringBuilder(); + for (int i = 1; i < size; i++) { + if (i > 1) { + builder.append(' '); + } + builder.append(orgList.get(i)); + } + departmentName = builder.toString(); + } + } + if (mOrganizationList == null) { + // Create new first organization entry, with "null" title which may be + // added via handleTitleValue(). + addNewOrganization(type, companyName, departmentName, null, isPrimary); + return; + } + for (OrganizationData organizationData : mOrganizationList) { + // Not use TextUtils.isEmpty() since ORG was set but the elements might be empty. + // e.g. "ORG;PREF:;" -> Both companyName and departmentName become empty but not null. + if (organizationData.companyName == null && + organizationData.departmentName == null) { + // Probably the "TITLE" property comes before the "ORG" property via + // handleTitleLine(). + organizationData.companyName = companyName; + organizationData.departmentName = departmentName; + organizationData.isPrimary = isPrimary; + return; + } + } + // No OrganizatioData is available. Create another one, with "null" title, which may be + // added via handleTitleValue(). + addNewOrganization(type, companyName, departmentName, null, isPrimary); + } + + private final static int DEFAULT_ORGANIZATION_TYPE = Organization.TYPE_WORK; + + /** + * Set "title" value to the appropriate data. If there's more than one + * OrganizationData objects, this input is attached to the last one which does not + * have valid title value (not including empty but only null). If there's no + * OrganizationData object, a new OrganizationData is created, whose company name is + * set to null. + */ + private void handleTitleValue(final String title) { + if (mOrganizationList == null) { + // Create new first organization entry, with "null" other info, which may be + // added via handleOrgValue(). + addNewOrganization(DEFAULT_ORGANIZATION_TYPE, null, null, title, false); + return; + } + for (OrganizationData organizationData : mOrganizationList) { + if (organizationData.titleName == null) { + organizationData.titleName = title; + return; + } + } + // No Organization is available. Create another one, with "null" other info, which may be + // added via handleOrgValue(). + addNewOrganization(DEFAULT_ORGANIZATION_TYPE, null, null, title, false); + } + + private void addIm(int protocol, String customProtocol, int type, + String propValue, boolean isPrimary) { if (mImList == null) { mImList = new ArrayList<ImData>(); } - mImList.add(new ImData(type, data, label, isPrimary)); + mImList.add(new ImData(protocol, customProtocol, type, propValue, isPrimary)); } private void addNote(final String note) { @@ -693,43 +641,14 @@ public class ContactStruct { mNoteList.add(note); } - private void addPhotoBytes(String formatName, byte[] photoBytes) { + private void addPhotoBytes(String formatName, byte[] photoBytes, boolean isPrimary) { if (mPhotoList == null) { mPhotoList = new ArrayList<PhotoData>(1); } - final PhotoData photoData = new PhotoData(0, null, photoBytes); + final PhotoData photoData = new PhotoData(0, null, photoBytes, isPrimary); mPhotoList.add(photoData); } - /** - * Set "position" value to the appropriate data. If there's more than one - * OrganizationData objects, the value is set to the last one. If there's no - * OrganizationData object, a new OrganizationData is created, whose company name is - * empty. - * - * TODO: incomplete logic. fix this: - * - * e.g. This assumes ORG comes earlier, but TITLE may come earlier like this, though we do not - * know how to handle it in general cases... - * ---- - * TITLE:Software Engineer - * ORG:Google - * ---- - */ - private void setPosition(String positionValue) { - if (mOrganizationList == null) { - mOrganizationList = new ArrayList<OrganizationData>(); - } - int size = mOrganizationList.size(); - if (size == 0) { - addOrganization(ContactsContract.CommonDataKinds.Organization.TYPE_OTHER, - "", null, false); - size = 1; - } - OrganizationData lastData = mOrganizationList.get(size - 1); - lastData.positionName = positionValue; - } - @SuppressWarnings("fallthrough") private void handleNProperty(List<String> elems) { // Family, Given, Middle, Prefix, Suffix. (1 - 5) @@ -755,7 +674,7 @@ public class ContactStruct { mFamilyName = elems.get(0); } } - + /** * Some Japanese mobile phones use this field for phonetic name, * since vCard 2.1 does not have "SORT-STRING" type. @@ -796,28 +715,36 @@ public class ContactStruct { } final String propValue = listToString(propValueList).trim(); - if (propName.equals("VERSION")) { + if (propName.equals(Constants.PROPERTY_VERSION)) { // vCard version. Ignore this. - } else if (propName.equals("FN")) { + } else if (propName.equals(Constants.PROPERTY_FN)) { mFullName = propValue; - } else if (propName.equals("NAME") && mFullName == null) { + } else if (propName.equals(Constants.PROPERTY_NAME) && mFullName == null) { // Only in vCard 3.0. Use this if FN, which must exist in vCard 3.0 but may not // actually exist in the real vCard data, does not exist. mFullName = propValue; - } else if (propName.equals("N")) { + } else if (propName.equals(Constants.PROPERTY_N)) { handleNProperty(propValueList); - } else if (propName.equals("SORT-STRING")) { + } else if (propName.equals(Constants.PROPERTY_NICKNAME)) { mPhoneticFullName = propValue; - } else if (propName.equals("NICKNAME") || propName.equals("X-NICKNAME")) { + } else if (propName.equals(Constants.PROPERTY_NICKNAME) || + propName.equals(Constants.ImportOnly.PROPERTY_X_NICKNAME)) { addNickName(propValue); - } else if (propName.equals("SOUND")) { + } else if (propName.equals(Constants.PROPERTY_SOUND)) { Collection<String> typeCollection = paramMap.get(Constants.ATTR_TYPE); if (typeCollection != null && typeCollection.contains(Constants.ATTR_TYPE_X_IRMC_N)) { - handlePhoneticNameFromSound(propValueList); + // As of 2009-10-08, Parser side does not split a property value into separated + // values using ';' (in other words, propValueList.size() == 1), + // which is correct behavior from the view of vCard 2.1. + // But we want it to be separated, so do the separation here. + final List<String> phoneticNameList = + VCardUtils.constructListFromValue(propValue, + VCardConfig.isV30(mVCardType)); + handlePhoneticNameFromSound(phoneticNameList); } else { // Ignore this field since Android cannot understand what it is. } - } else if (propName.equals("ADR")) { + } else if (propName.equals(Constants.PROPERTY_ADR)) { boolean valuesAreAllEmpty = true; for (String value : propValueList) { if (value.length() > 0) { @@ -836,23 +763,21 @@ public class ContactStruct { if (typeCollection != null) { for (String typeString : typeCollection) { typeString = typeString.toUpperCase(); - if (typeString.equals(Constants.ATTR_TYPE_PREF) && !mPrefIsSet_Address) { - // Only first "PREF" is considered. - mPrefIsSet_Address = true; + if (typeString.equals(Constants.ATTR_TYPE_PREF)) { isPrimary = true; } else if (typeString.equals(Constants.ATTR_TYPE_HOME)) { type = StructuredPostal.TYPE_HOME; label = ""; } else if (typeString.equals(Constants.ATTR_TYPE_WORK) || - typeString.equalsIgnoreCase("COMPANY")) { + typeString.equalsIgnoreCase(Constants.ATTR_EXTRA_TYPE_COMPANY)) { // "COMPANY" seems emitted by Windows Mobile, which is not // specifically supported by vCard 2.1. We assume this is same // as "WORK". type = StructuredPostal.TYPE_WORK; label = ""; - } else if (typeString.equals("PARCEL") || - typeString.equals("DOM") || - typeString.equals("INTL")) { + } else if (typeString.equals(Constants.ATTR_ADR_TYPE_PARCEL) || + typeString.equals(Constants.ATTR_ADR_TYPE_DOM) || + typeString.equals(Constants.ATTR_ADR_TYPE_INTL)) { // We do not have any appropriate way to store this information. } else { if (typeString.startsWith("X-") && type < 0) { @@ -871,7 +796,7 @@ public class ContactStruct { } addPostal(type, propValueList, label, isPrimary); - } else if (propName.equals("EMAIL")) { + } else if (propName.equals(Constants.PROPERTY_EMAIL)) { int type = -1; String label = null; boolean isPrimary = false; @@ -879,9 +804,7 @@ public class ContactStruct { if (typeCollection != null) { for (String typeString : typeCollection) { typeString = typeString.toUpperCase(); - if (typeString.equals(Constants.ATTR_TYPE_PREF) && !mPrefIsSet_Email) { - // Only first "PREF" is considered. - mPrefIsSet_Email = true; + if (typeString.equals(Constants.ATTR_TYPE_PREF)) { isPrimary = true; } else if (typeString.equals(Constants.ATTR_TYPE_HOME)) { type = Email.TYPE_HOME; @@ -905,50 +828,47 @@ public class ContactStruct { type = Email.TYPE_OTHER; } addEmail(type, propValue, label, isPrimary); - } else if (propName.equals("ORG")) { + } else if (propName.equals(Constants.PROPERTY_ORG)) { // vCard specification does not specify other types. - int type = Organization.TYPE_WORK; + final int type = Organization.TYPE_WORK; boolean isPrimary = false; - Collection<String> typeCollection = paramMap.get(Constants.ATTR_TYPE); if (typeCollection != null) { for (String typeString : typeCollection) { - if (typeString.equals(Constants.ATTR_TYPE_PREF) && !mPrefIsSet_Organization) { - // vCard specification officially does not have PREF in ORG. - // This is just for safety. - mPrefIsSet_Organization = true; + if (typeString.equals(Constants.ATTR_TYPE_PREF)) { isPrimary = true; } } } - - StringBuilder builder = new StringBuilder(); - for (Iterator<String> iter = propValueList.iterator(); iter.hasNext();) { - builder.append(iter.next()); - if (iter.hasNext()) { - builder.append(' '); - } - } - addOrganization(type, builder.toString(), "", isPrimary); - } else if (propName.equals("TITLE")) { - setPosition(propValue); - } else if (propName.equals("ROLE")) { - setPosition(propValue); - } else if (propName.equals("PHOTO") || propName.equals("LOGO")) { - String formatName = null; - Collection<String> typeCollection = paramMap.get("TYPE"); - if (typeCollection != null) { - formatName = typeCollection.iterator().next(); - } + handleOrgValue(type, propValueList, isPrimary); + } else if (propName.equals(Constants.PROPERTY_TITLE)) { + handleTitleValue(propValue); + } else if (propName.equals(Constants.PROPERTY_ROLE)) { + // This conflicts with TITLE. Ignore for now... + // handleTitleValue(propValue); + } else if (propName.equals(Constants.PROPERTY_PHOTO) || + propName.equals(Constants.PROPERTY_LOGO)) { Collection<String> paramMapValue = paramMap.get("VALUE"); if (paramMapValue != null && paramMapValue.contains("URL")) { // Currently we do not have appropriate example for testing this case. } else { - addPhotoBytes(formatName, propBytes); + final Collection<String> typeCollection = paramMap.get("TYPE"); + String formatName = null; + boolean isPrimary = false; + if (typeCollection != null) { + for (String typeValue : typeCollection) { + if (Constants.ATTR_TYPE_PREF.equals(typeValue)) { + isPrimary = true; + } else if (formatName == null){ + formatName = typeValue; + } + } + } + addPhotoBytes(formatName, propBytes, isPrimary); } - } else if (propName.equals("TEL")) { - Collection<String> typeCollection = paramMap.get(Constants.ATTR_TYPE); - Object typeObject = VCardUtils.getPhoneTypeFromStrings(typeCollection); + } else if (propName.equals(Constants.PROPERTY_TEL)) { + final Collection<String> typeCollection = paramMap.get(Constants.ATTR_TYPE); + final Object typeObject = VCardUtils.getPhoneTypeFromStrings(typeCollection); final int type; final String label; if (typeObject instanceof Integer) { @@ -960,9 +880,7 @@ public class ContactStruct { } final boolean isPrimary; - if (!mPrefIsSet_Phone && typeCollection != null && - typeCollection.contains(Constants.ATTR_TYPE_PREF)) { - mPrefIsSet_Phone = true; + if (typeCollection != null && typeCollection.contains(Constants.ATTR_TYPE_PREF)) { isPrimary = true; } else { isPrimary = false; @@ -975,47 +893,48 @@ public class ContactStruct { int type = Phone.TYPE_OTHER; final String label = null; final boolean isPrimary; - if (!mPrefIsSet_Phone && typeCollection != null && - typeCollection.contains(Constants.ATTR_TYPE_PREF)) { - mPrefIsSet_Phone = true; + if (typeCollection != null && typeCollection.contains(Constants.ATTR_TYPE_PREF)) { isPrimary = true; } else { isPrimary = false; } addPhone(type, propValue, label, isPrimary); - } else if (sImMap.containsKey(propName)){ - int type = sImMap.get(propName); + } else if (sImMap.containsKey(propName)) { + final int protocol = sImMap.get(propName); boolean isPrimary = false; + int type = -1; final Collection<String> typeCollection = paramMap.get(Constants.ATTR_TYPE); if (typeCollection != null) { for (String typeString : typeCollection) { if (typeString.equals(Constants.ATTR_TYPE_PREF)) { isPrimary = true; - } else if (typeString.equalsIgnoreCase(Constants.ATTR_TYPE_HOME)) { - type = Phone.TYPE_HOME; - } else if (typeString.equalsIgnoreCase(Constants.ATTR_TYPE_WORK)) { - type = Phone.TYPE_WORK; + } else if (type < 0) { + if (typeString.equalsIgnoreCase(Constants.ATTR_TYPE_HOME)) { + type = Im.TYPE_HOME; + } else if (typeString.equalsIgnoreCase(Constants.ATTR_TYPE_WORK)) { + type = Im.TYPE_WORK; + } } } } if (type < 0) { type = Phone.TYPE_HOME; } - addIm(type, propValue, null, isPrimary); - } else if (propName.equals("NOTE")) { + addIm(protocol, null, type, propValue, isPrimary); + } else if (propName.equals(Constants.PROPERTY_NOTE)) { addNote(propValue); - } else if (propName.equals("URL")) { + } else if (propName.equals(Constants.PROPERTY_URL)) { if (mWebsiteList == null) { mWebsiteList = new ArrayList<String>(1); } mWebsiteList.add(propValue); - } else if (propName.equals("X-PHONETIC-FIRST-NAME")) { + } else if (propName.equals(Constants.PROPERTY_X_PHONETIC_FIRST_NAME)) { mPhoneticGivenName = propValue; - } else if (propName.equals("X-PHONETIC-MIDDLE-NAME")) { + } else if (propName.equals(Constants.PROPERTY_X_PHONETIC_MIDDLE_NAME)) { mPhoneticMiddleName = propValue; - } else if (propName.equals("X-PHONETIC-LAST-NAME")) { + } else if (propName.equals(Constants.PROPERTY_X_PHONETIC_LAST_NAME)) { mPhoneticFamilyName = propValue; - } else if (propName.equals("BDAY")) { + } else if (propName.equals(Constants.PROPERTY_BDAY)) { mBirthday = propValue; /*} else if (propName.equals("REV")) { // Revision of this VCard entry. I think we can ignore this. @@ -1048,7 +967,10 @@ public class ContactStruct { * Construct the display name. The constructed data must not be null. */ private void constructDisplayName() { - if (!(TextUtils.isEmpty(mFamilyName) && TextUtils.isEmpty(mGivenName))) { + // FullName (created via "FN" or "NAME" field) is prefered. + if (!TextUtils.isEmpty(mFullName)) { + mDisplayName = mFullName; + } else if (!(TextUtils.isEmpty(mFamilyName) && TextUtils.isEmpty(mGivenName))) { StringBuilder builder = new StringBuilder(); List<String> nameList; switch (VCardConfig.getNameOrderType(mVCardType)) { @@ -1079,8 +1001,6 @@ public class ContactStruct { } } mDisplayName = builder.toString(); - } else if (!TextUtils.isEmpty(mFullName)) { - mDisplayName = mFullName; } else if (!(TextUtils.isEmpty(mPhoneticFamilyName) && TextUtils.isEmpty(mPhoneticGivenName))) { mDisplayName = VCardUtils.constructNameFromElements(mVCardType, @@ -1103,25 +1023,10 @@ public class ContactStruct { */ public void consolidateFields() { constructDisplayName(); - + if (mPhoneticFullName != null) { mPhoneticFullName = mPhoneticFullName.trim(); } - - // If there is no "PREF", we choose the first entries as primary. - if (!mPrefIsSet_Phone && mPhoneList != null && mPhoneList.size() > 0) { - mPhoneList.get(0).isPrimary = true; - } - - if (!mPrefIsSet_Address && mPostalList != null && mPostalList.size() > 0) { - mPostalList.get(0).isPrimary = true; - } - if (!mPrefIsSet_Email && mEmailList != null && mEmailList.size() > 0) { - mEmailList.get(0).isPrimary = true; - } - if (!mPrefIsSet_Organization && mOrganizationList != null && mOrganizationList.size() > 0) { - mOrganizationList.get(0).isPrimary = true; - } } // From GoogleSource.java in Contacts app. @@ -1181,22 +1086,16 @@ public class ContactStruct { } if (mNickNameList != null && mNickNameList.size() > 0) { - boolean first = true; for (String nickName : mNickNameList) { builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); builder.withValueBackReference(Nickname.RAW_CONTACT_ID, 0); builder.withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE); - builder.withValue(Nickname.TYPE, Nickname.TYPE_DEFAULT); builder.withValue(Nickname.NAME, nickName); - if (first) { - builder.withValue(Data.IS_PRIMARY, 1); - first = false; - } operationList.add(builder.build()); } } - + if (mPhoneList != null) { for (PhoneData phoneData : mPhoneList) { builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); @@ -1209,30 +1108,34 @@ public class ContactStruct { } builder.withValue(Phone.NUMBER, phoneData.data); if (phoneData.isPrimary) { - builder.withValue(Data.IS_PRIMARY, 1); + builder.withValue(Phone.IS_PRIMARY, 1); } operationList.add(builder.build()); } } - + if (mOrganizationList != null) { - boolean first = true; for (OrganizationData organizationData : mOrganizationList) { builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); builder.withValueBackReference(Organization.RAW_CONTACT_ID, 0); builder.withValue(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE); - - // Currently, we do not use TYPE_CUSTOM. builder.withValue(Organization.TYPE, organizationData.type); - builder.withValue(Organization.COMPANY, organizationData.companyName); - builder.withValue(Organization.TITLE, organizationData.positionName); - if (first) { - builder.withValue(Data.IS_PRIMARY, 1); + if (organizationData.companyName != null) { + builder.withValue(Organization.COMPANY, organizationData.companyName); + } + if (organizationData.departmentName != null) { + builder.withValue(Organization.DEPARTMENT, organizationData.departmentName); + } + if (organizationData.titleName != null) { + builder.withValue(Organization.TITLE, organizationData.titleName); + } + if (organizationData.isPrimary) { + builder.withValue(Organization.IS_PRIMARY, 1); } operationList.add(builder.build()); } } - + if (mEmailList != null) { for (EmailData emailData : mEmailList) { builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); @@ -1265,12 +1168,11 @@ public class ContactStruct { builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); builder.withValueBackReference(Im.RAW_CONTACT_ID, 0); builder.withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE); - builder.withValue(Im.TYPE, imData.type); - if (imData.type == Im.TYPE_CUSTOM) { - builder.withValue(Im.LABEL, imData.label); + builder.withValue(Im.PROTOCOL, imData.protocol); + if (imData.protocol == Im.PROTOCOL_CUSTOM) { + builder.withValue(Im.CUSTOM_PROTOCOL, imData.customProtocol); } - builder.withValue(Im.DATA, imData.data); if (imData.isPrimary) { builder.withValue(Data.IS_PRIMARY, 1); } @@ -1282,22 +1184,19 @@ public class ContactStruct { builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); builder.withValueBackReference(Note.RAW_CONTACT_ID, 0); builder.withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE); - builder.withValue(Note.NOTE, note); operationList.add(builder.build()); } } - + if (mPhotoList != null) { - boolean first = true; for (PhotoData photoData : mPhotoList) { builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); builder.withValueBackReference(Photo.RAW_CONTACT_ID, 0); builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE); builder.withValue(Photo.PHOTO, photoData.photoBytes); - if (first) { - builder.withValue(Data.IS_PRIMARY, 1); - first = false; + if (photoData.isPrimary) { + builder.withValue(Photo.IS_PRIMARY, 1); } operationList.add(builder.build()); } @@ -1310,12 +1209,12 @@ public class ContactStruct { builder.withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE); builder.withValue(Website.URL, website); // There's no information about the type of URL in vCard. - // We use TYPE_HOME for safety. - builder.withValue(Website.TYPE, Website.TYPE_HOME); + // We use TYPE_HOMEPAGE for safety. + builder.withValue(Website.TYPE, Website.TYPE_HOMEPAGE); operationList.add(builder.build()); } } - + if (!TextUtils.isEmpty(mBirthday)) { builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); builder.withValueBackReference(Event.RAW_CONTACT_ID, 0); @@ -1364,4 +1263,99 @@ public class ContactStruct { return ""; } } + + // All getter methods should be used carefully, since they may change + // in the future as of 2009-10-05, on which I cannot be sure this structure + // is completely consolidated. + // + // Also note that these getter methods should be used only after + // all properties being pushed into this object. If not, incorrect + // value will "be stored in the local cache and" be returned to you. + + public String getFamilyName() { + return mFamilyName; + } + + public String getGivenName() { + return mGivenName; + } + + public String getMiddleName() { + return mMiddleName; + } + + public String getPrefix() { + return mPrefix; + } + + public String getSuffix() { + return mSuffix; + } + + public String getFullName() { + return mFullName; + } + + public String getPhoneticFamilyName() { + return mPhoneticFamilyName; + } + + public String getPhoneticGivenName() { + return mPhoneticGivenName; + } + + public String getPhoneticMiddleName() { + return mPhoneticMiddleName; + } + + public String getPhoneticFullName() { + return mPhoneticFullName; + } + + public final List<String> getNickNameList() { + return mNickNameList; + } + + public String getBirthday() { + return mBirthday; + } + + public final List<String> getNotes() { + return mNoteList; + } + + public final List<PhoneData> getPhoneList() { + return mPhoneList; + } + + public final List<EmailData> getEmailList() { + return mEmailList; + } + + public final List<PostalData> getPostalList() { + return mPostalList; + } + + public final List<OrganizationData> getOrganizationList() { + return mOrganizationList; + } + + public final List<ImData> getImList() { + return mImList; + } + + public final List<PhotoData> getPhotoList() { + return mPhotoList; + } + + public final List<String> getWebsiteList() { + return mWebsiteList; + } + + public String getDisplayName() { + if (mDisplayName == null) { + constructDisplayName(); + } + return mDisplayName; + } } diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java index c4711f8..8eabd4b 100644 --- a/core/java/android/pim/vcard/VCardComposer.java +++ b/core/java/android/pim/vcard/VCardComposer.java @@ -72,19 +72,38 @@ import java.util.Set; * Usually, this class should be used like this. * </p> * - * <pre class="prettyprint"> VCardComposer composer = null; try { composer = new - * VCardComposer(context); composer.addHandler(composer.new - * HandlerForOutputStream(outputStream)); if (!composer.init()) { // Do - * something handling the situation. return; } while (!composer.isAfterLast()) { - * if (mCanceled) { // Assume a user may cancel this operation during the - * export. return; } if (!composer.createOneEntry()) { // Do something handling - * the error situation. return; } } } finally { if (composer != null) { - * composer.terminate(); } } </pre> + * <pre class="prettyprint">VCardComposer composer = null; + * try { + * composer = new VCardComposer(context); + * composer.addHandler( + * composer.new HandlerForOutputStream(outputStream)); + * if (!composer.init()) { + * // Do something handling the situation. + * return; + * } + * while (!composer.isAfterLast()) { + * if (mCanceled) { + * // Assume a user may cancel this operation during the export. + * return; + * } + * if (!composer.createOneEntry()) { + * // Do something handling the error situation. + * return; + * } + * } + * } finally { + * if (composer != null) { + * composer.terminate(); + * } + * } </pre> */ public class VCardComposer { private static final String LOG_TAG = "vcard.VCardComposer"; - private static final String DEFAULT_EMAIL_TYPE = Constants.ATTR_TYPE_INTERNET; + // TODO: Should be configurable? + public static final int DEFAULT_PHONE_TYPE = Phone.TYPE_HOME; + public static final int DEFAULT_POSTAL_TYPE = StructuredPostal.TYPE_HOME; + public static final int DEFAULT_EMAIL_TYPE = Email.TYPE_OTHER; public static final String FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO = "Failed to get database information"; @@ -95,28 +114,83 @@ public class VCardComposer { public static final String FAILURE_REASON_NOT_INITIALIZED = "The vCard composer object is not correctly initialized"; + /** Should be visible only from developers... (no need to translate, hopefully) */ + public static final String FAILURE_REASON_UNSUPPORTED_URI = + "The Uri vCard composer received is not supported by the composer."; + public static final String NO_ERROR = "No error"; + public static final String VCARD_TYPE_STRING_DOCOMO = "docomo"; + + // Property for call log entry + private static final String VCARD_PROPERTY_X_TIMESTAMP = "X-IRMC-CALL-DATETIME"; + private static final String VCARD_PROPERTY_CALLTYPE_INCOMING = "INCOMING"; + private static final String VCARD_PROPERTY_CALLTYPE_OUTGOING = "OUTGOING"; + private static final String VCARD_PROPERTY_CALLTYPE_MISSED = "MISSED"; + + private static final String VCARD_DATA_VCARD = "VCARD"; + private static final String VCARD_DATA_PUBLIC = "PUBLIC"; + + private static final String VCARD_ATTR_SEPARATOR = ";"; + private static final String VCARD_COL_SEPARATOR = "\r\n"; + private static final String VCARD_DATA_SEPARATOR = ":"; + private static final String VCARD_ITEM_SEPARATOR = ";"; + private static final String VCARD_WS = " "; + private static final String VCARD_ATTR_EQUAL = "="; + + private static final String VCARD_ATTR_ENCODING_QP = "ENCODING=QUOTED-PRINTABLE"; + + private static final String VCARD_ATTR_ENCODING_BASE64_V21 = "ENCODING=BASE64"; + private static final String VCARD_ATTR_ENCODING_BASE64_V30 = "ENCODING=b"; + + private static final String SHIFT_JIS = "SHIFT_JIS"; + + /** + * Special URI for testing. + */ + public static final String VCARD_TEST_AUTHORITY = "com.android.unit_tests.vcard"; + public static final Uri VCARD_TEST_AUTHORITY_URI = + Uri.parse("content://" + VCARD_TEST_AUTHORITY); + public static final Uri CONTACTS_TEST_CONTENT_URI = + Uri.withAppendedPath(VCARD_TEST_AUTHORITY_URI, "contacts"); + private static final Uri sDataRequestUri; + private static final Map<Integer, String> sImMap; + + /** + * See the comment in {@link VCardConfig#FLAG_REFRAIN_QP_TO_PRIMARY_PROPERTIES}. + */ + private static final Set<String> sPrimaryPropertyNameSet; static { Uri.Builder builder = RawContacts.CONTENT_URI.buildUpon(); builder.appendQueryParameter(Data.FOR_EXPORT_ONLY, "1"); sDataRequestUri = builder.build(); + sImMap = new HashMap<Integer, String>(); + sImMap.put(Im.PROTOCOL_AIM, Constants.PROPERTY_X_AIM); + sImMap.put(Im.PROTOCOL_MSN, Constants.PROPERTY_X_MSN); + sImMap.put(Im.PROTOCOL_YAHOO, Constants.PROPERTY_X_YAHOO); + sImMap.put(Im.PROTOCOL_ICQ, Constants.PROPERTY_X_ICQ); + sImMap.put(Im.PROTOCOL_JABBER, Constants.PROPERTY_X_JABBER); + sImMap.put(Im.PROTOCOL_SKYPE, Constants.PROPERTY_X_SKYPE_USERNAME); + // Google talk is a special case. + + // TODO: incomplete. Implement properly + sPrimaryPropertyNameSet = new HashSet<String>(); + sPrimaryPropertyNameSet.add(Constants.PROPERTY_N); + sPrimaryPropertyNameSet.add(Constants.PROPERTY_FN); + sPrimaryPropertyNameSet.add(Constants.PROPERTY_SOUND); } public static interface OneEntryHandler { public boolean onInit(Context context); - public boolean onEntryCreated(String vcard); - public void onTerminate(); } /** * <p> - * An useful example handler, which emits VCard String to outputstream one - * by one. + * An useful example handler, which emits VCard String to outputstream one by one. * </p> * <p> * The input OutputStream object is closed() on {{@link #onTerminate()}. @@ -211,65 +285,6 @@ public class VCardComposer { } } - public static final String VCARD_TYPE_STRING_DOCOMO = "docomo"; - - private static final String VCARD_PROPERTY_ADR = "ADR"; - private static final String VCARD_PROPERTY_BEGIN = "BEGIN"; - private static final String VCARD_PROPERTY_EMAIL = "EMAIL"; - private static final String VCARD_PROPERTY_END = "END"; - private static final String VCARD_PROPERTY_NAME = "N"; - private static final String VCARD_PROPERTY_FULL_NAME = "FN"; - private static final String VCARD_PROPERTY_NOTE = "NOTE"; - private static final String VCARD_PROPERTY_ORG = "ORG"; - private static final String VCARD_PROPERTY_SOUND = "SOUND"; - private static final String VCARD_PROPERTY_SORT_STRING = "SORT-STRING"; - private static final String VCARD_PROPERTY_NICKNAME = "NICKNAME"; - private static final String VCARD_PROPERTY_TEL = "TEL"; - private static final String VCARD_PROPERTY_TITLE = "TITLE"; - private static final String VCARD_PROPERTY_PHOTO = "PHOTO"; - private static final String VCARD_PROPERTY_VERSION = "VERSION"; - private static final String VCARD_PROPERTY_URL = "URL"; - private static final String VCARD_PROPERTY_BIRTHDAY = "BDAY"; - - private static final String VCARD_PROPERTY_X_PHONETIC_FIRST_NAME = "X-PHONETIC-FIRST-NAME"; - private static final String VCARD_PROPERTY_X_PHONETIC_MIDDLE_NAME = "X-PHONETIC-MIDDLE-NAME"; - private static final String VCARD_PROPERTY_X_PHONETIC_LAST_NAME = "X-PHONETIC-LAST-NAME"; - - // Android specific properties - // TODO: ues extra MIME-TYPE instead of adding this kind of inflexible fields - private static final String VCARD_PROPERTY_X_NICKNAME = "X-NICKNAME"; - - // Property for call log entry - private static final String VCARD_PROPERTY_X_TIMESTAMP = "X-IRMC-CALL-DATETIME"; - private static final String VCARD_PROPERTY_CALLTYPE_INCOMING = "INCOMING"; - private static final String VCARD_PROPERTY_CALLTYPE_OUTGOING = "OUTGOING"; - private static final String VCARD_PROPERTY_CALLTYPE_MISSED = "MISSED"; - - // Properties for DoCoMo vCard. - private static final String VCARD_PROPERTY_X_CLASS = "X-CLASS"; - private static final String VCARD_PROPERTY_X_REDUCTION = "X-REDUCTION"; - private static final String VCARD_PROPERTY_X_NO = "X-NO"; - private static final String VCARD_PROPERTY_X_DCM_HMN_MODE = "X-DCM-HMN-MODE"; - - private static final String VCARD_DATA_VCARD = "VCARD"; - private static final String VCARD_DATA_PUBLIC = "PUBLIC"; - - private static final String VCARD_ATTR_SEPARATOR = ";"; - private static final String VCARD_COL_SEPARATOR = "\r\n"; - private static final String VCARD_DATA_SEPARATOR = ":"; - private static final String VCARD_ITEM_SEPARATOR = ";"; - private static final String VCARD_WS = " "; - private static final String VCARD_ATTR_EQUAL = "="; - - // Type strings are now in VCardConstants.java. - - private static final String VCARD_ATTR_ENCODING_QP = "ENCODING=QUOTED-PRINTABLE"; - - private static final String VCARD_ATTR_ENCODING_BASE64_V21 = "ENCODING=BASE64"; - private static final String VCARD_ATTR_ENCODING_BASE64_V30 = "ENCODING=b"; - - private static final String SHIFT_JIS = "SHIFT_JIS"; - private final Context mContext; private final int mVCardType; private final boolean mCareHandlerErrors; @@ -286,7 +301,9 @@ public class VCardComposer { private final boolean mUsesDefactProperty; private final boolean mUsesUtf8; private final boolean mUsesShiftJis; - private final boolean mUsesQPToPrimaryProperties; + private final boolean mAppendTypeParamName; + private final boolean mRefrainsQPToPrimaryProperties; + private final boolean mNeedsToConvertPhoneticString; private Cursor mCursor; private int mIdColumn; @@ -298,20 +315,7 @@ public class VCardComposer { private String mErrorReason = NO_ERROR; - private static final Map<Integer, String> sImMap; - - static { - sImMap = new HashMap<Integer, String>(); - sImMap.put(Im.PROTOCOL_AIM, Constants.PROPERTY_X_AIM); - sImMap.put(Im.PROTOCOL_MSN, Constants.PROPERTY_X_MSN); - sImMap.put(Im.PROTOCOL_YAHOO, Constants.PROPERTY_X_YAHOO); - sImMap.put(Im.PROTOCOL_ICQ, Constants.PROPERTY_X_ICQ); - sImMap.put(Im.PROTOCOL_JABBER, Constants.PROPERTY_X_JABBER); - sImMap.put(Im.PROTOCOL_SKYPE, Constants.PROPERTY_X_SKYPE_USERNAME); - // Google talk is a special case. - } - - private boolean mIsCallLogComposer = false; + private boolean mIsCallLogComposer; private static final String[] sContactsProjection = new String[] { Contacts._ID, @@ -332,30 +336,24 @@ public class VCardComposer { private static final String FLAG_TIMEZONE_UTC = "Z"; public VCardComposer(Context context) { - this(context, VCardConfig.VCARD_TYPE_DEFAULT, true, false); + this(context, VCardConfig.VCARD_TYPE_DEFAULT, true); } - public VCardComposer(Context context, String vcardTypeStr, - boolean careHandlerErrors) { - this(context, VCardConfig.getVCardTypeFromString(vcardTypeStr), - careHandlerErrors, false); + public VCardComposer(Context context, int vcardType) { + this(context, vcardType, true); } - public VCardComposer(Context context, int vcardType, boolean careHandlerErrors) { - this(context, vcardType, careHandlerErrors, false); + public VCardComposer(Context context, String vcardTypeStr, boolean careHandlerErrors) { + this(context, VCardConfig.getVCardTypeFromString(vcardTypeStr), careHandlerErrors); } /** * Construct for supporting call log entry vCard composing. - * - * @param isCallLogComposer true if this composer is for creating Call Log vCard. */ - public VCardComposer(Context context, int vcardType, boolean careHandlerErrors, - boolean isCallLogComposer) { + public VCardComposer(Context context, int vcardType, boolean careHandlerErrors) { mContext = context; mVCardType = vcardType; mCareHandlerErrors = careHandlerErrors; - mIsCallLogComposer = isCallLogComposer; mContentResolver = context.getContentResolver(); mIsV30 = VCardConfig.isV30(vcardType); @@ -370,7 +368,9 @@ public class VCardComposer { mUsesDefactProperty = VCardConfig.usesDefactProperty(vcardType); mUsesUtf8 = VCardConfig.usesUtf8(vcardType); mUsesShiftJis = VCardConfig.usesShiftJis(vcardType); - mUsesQPToPrimaryProperties = VCardConfig.usesQPToPrimaryProperties(vcardType); + mRefrainsQPToPrimaryProperties = VCardConfig.refrainsQPToPrimaryProperties(vcardType); + mAppendTypeParamName = VCardConfig.appendTypeParamName(vcardType); + mNeedsToConvertPhoneticString = VCardConfig.needsToConvertPhoneticString(vcardType); mHandlerList = new ArrayList<OneEntryHandler>(); if (mIsDoCoMo) { @@ -389,50 +389,32 @@ public class VCardComposer { } /** - * This static function is to compose vCard for phone own number - */ - public String composeVCardForPhoneOwnNumber(int phonetype, String phoneName, - String phoneNumber, boolean vcardVer21) { - final StringBuilder builder = new StringBuilder(); - appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD); - if (!vcardVer21) { - appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V30); - } else { - appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V21); - } - - boolean needCharset = false; - if (!(VCardUtils.containsOnlyPrintableAscii(phoneName))) { - needCharset = true; - } - // TODO: QP should be used? Using mUsesQPToPrimaryProperties should help. - appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, phoneName, needCharset, false); - appendVCardLine(builder, VCARD_PROPERTY_NAME, phoneName, needCharset, false); - - String label = Integer.toString(phonetype); - appendVCardTelephoneLine(builder, phonetype, label, phoneNumber); - - appendVCardLine(builder, VCARD_PROPERTY_END, VCARD_DATA_VCARD); - - return builder.toString(); - } - - /** * Must call before {{@link #init()}. */ public void addHandler(OneEntryHandler handler) { mHandlerList.add(handler); } + /** + * @return Returns true when initialization is successful and all the other + * methods are available. Returns false otherwise. + */ public boolean init() { return init(null, null); } + public boolean init(final String selection, final String[] selectionArgs) { + return init(Contacts.CONTENT_URI, selection, selectionArgs, null); + } + /** - * @return Returns true when initialization is successful and all the other - * methods are available. Returns false otherwise. + * Note that this is unstable interface, may be deleted in the future. */ - public boolean init(final String selection, final String[] selectionArgs) { + public boolean init(final Uri contentUri, final String selection, + final String[] selectionArgs, final String sortOrder) { + if (contentUri == null) { + return false; + } if (mCareHandlerErrors) { List<OneEntryHandler> finishedList = new ArrayList<OneEntryHandler>( mHandlerList.size()); @@ -451,13 +433,19 @@ public class VCardComposer { } } - if (mIsCallLogComposer) { - mCursor = mContentResolver.query(CallLog.Calls.CONTENT_URI, sCallLogProjection, - selection, selectionArgs, null); + final String[] projection; + if (CallLog.Calls.CONTENT_URI.equals(contentUri)) { + projection = sCallLogProjection; + mIsCallLogComposer = true; + } else if (Contacts.CONTENT_URI.equals(contentUri) || + CONTACTS_TEST_CONTENT_URI.equals(contentUri)) { + projection = sContactsProjection; } else { - mCursor = mContentResolver.query(Contacts.CONTENT_URI, sContactsProjection, - selection, selectionArgs, null); + mErrorReason = FAILURE_REASON_UNSUPPORTED_URI; + return false; } + mCursor = mContentResolver.query( + contentUri, projection, selection, selectionArgs, sortOrder); if (mCursor == null) { mErrorReason = FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO; @@ -534,89 +522,6 @@ public class VCardComposer { return true; } - /** - * Format according to RFC 2445 DATETIME type. - * The format is: ("%Y%m%dT%H%M%SZ"). - */ - private final String toRfc2455Format(final long millSecs) { - Time startDate = new Time(); - startDate.set(millSecs); - String date = startDate.format2445(); - return date + FLAG_TIMEZONE_UTC; - } - - /** - * Try to append the property line for a call history time stamp field if possible. - * Do nothing if the call log type gotton from the database is invalid. - */ - private void tryAppendCallHistoryTimeStampField(final StringBuilder builder) { - // Extension for call history as defined in - // in the Specification for Ic Mobile Communcation - ver 1.1, - // Oct 2000. This is used to send the details of the call - // history - missed, incoming, outgoing along with date and time - // to the requesting device (For example, transferring phone book - // when connected over bluetooth) - // - // e.g. "X-IRMC-CALL-DATETIME;MISSED:20050320T100000Z" - final int callLogType = mCursor.getInt(CALL_TYPE_COLUMN_INDEX); - final String callLogTypeStr; - switch (callLogType) { - case Calls.INCOMING_TYPE: { - callLogTypeStr = VCARD_PROPERTY_CALLTYPE_INCOMING; - break; - } - case Calls.OUTGOING_TYPE: { - callLogTypeStr = VCARD_PROPERTY_CALLTYPE_OUTGOING; - break; - } - case Calls.MISSED_TYPE: { - callLogTypeStr = VCARD_PROPERTY_CALLTYPE_MISSED; - break; - } - default: { - Log.w(LOG_TAG, "Call log type not correct."); - return; - } - } - - final long dateAsLong = mCursor.getLong(DATE_COLUMN_INDEX); - builder.append(VCARD_PROPERTY_X_TIMESTAMP); - builder.append(VCARD_ATTR_SEPARATOR); - appendTypeAttribute(builder, callLogTypeStr); - builder.append(VCARD_DATA_SEPARATOR); - builder.append(toRfc2455Format(dateAsLong)); - builder.append(VCARD_COL_SEPARATOR); - } - - private String createOneCallLogEntryInternal() { - final StringBuilder builder = new StringBuilder(); - appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD); - if (mIsV30) { - appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V30); - } else { - appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V21); - } - String name = mCursor.getString(CALLER_NAME_COLUMN_INDEX); - if (TextUtils.isEmpty(name)) { - name = mCursor.getString(NUMBER_COLUMN_INDEX); - } - final boolean needCharset = !(VCardUtils.containsOnlyPrintableAscii(name)); - // TODO: QP should be used? Using mUsesQPToPrimaryProperties should help. - appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, name, needCharset, false); - appendVCardLine(builder, VCARD_PROPERTY_NAME, name, needCharset, false); - - String number = mCursor.getString(NUMBER_COLUMN_INDEX); - int type = mCursor.getInt(CALLER_NUMBERTYPE_COLUMN_INDEX); - String label = mCursor.getString(CALLER_NUMBERLABEL_COLUMN_INDEX); - if (TextUtils.isEmpty(label)) { - label = Integer.toString(type); - } - appendVCardTelephoneLine(builder, type, label, number); - tryAppendCallHistoryTimeStampField(builder); - appendVCardLine(builder, VCARD_PROPERTY_END, VCARD_DATA_VCARD); - return builder.toString(); - } - private String createOneEntryInternal(final String contactId) { final Map<String, List<ContentValues>> contentValuesListMap = new HashMap<String, List<ContentValues>>(); @@ -633,8 +538,7 @@ public class VCardComposer { dataExists = entityIterator.hasNext(); while (entityIterator.hasNext()) { Entity entity = entityIterator.next(); - for (NamedContentValues namedContentValues : entity - .getSubValues()) { + for (NamedContentValues namedContentValues : entity.getSubValues()) { ContentValues contentValues = namedContentValues.values; String key = contentValues.getAsString(Data.MIMETYPE); if (key != null) { @@ -663,11 +567,11 @@ public class VCardComposer { } final StringBuilder builder = new StringBuilder(); - appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD); + appendVCardLine(builder, Constants.PROPERTY_BEGIN, VCARD_DATA_VCARD); if (mIsV30) { - appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V30); + appendVCardLine(builder, Constants.PROPERTY_VERSION, Constants.VERSION_V30); } else { - appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V21); + appendVCardLine(builder, Constants.PROPERTY_VERSION, Constants.VERSION_V21); } appendStructuredNames(builder, contentValuesListMap); @@ -681,16 +585,16 @@ public class VCardComposer { appendOrganizations(builder, contentValuesListMap); appendPhotos(builder, contentValuesListMap); appendNotes(builder, contentValuesListMap); - // TODO: GroupMembership + // TODO: GroupMembership, Relation, Event other than birthday. if (mIsDoCoMo) { - appendVCardLine(builder, VCARD_PROPERTY_X_CLASS, VCARD_DATA_PUBLIC); - appendVCardLine(builder, VCARD_PROPERTY_X_REDUCTION, ""); - appendVCardLine(builder, VCARD_PROPERTY_X_NO, ""); - appendVCardLine(builder, VCARD_PROPERTY_X_DCM_HMN_MODE, ""); + appendVCardLine(builder, Constants.PROPERTY_X_CLASS, VCARD_DATA_PUBLIC); + appendVCardLine(builder, Constants.PROPERTY_X_REDUCTION, ""); + appendVCardLine(builder, Constants.PROPERTY_X_NO, ""); + appendVCardLine(builder, Constants.PROPERTY_X_DCM_HMN_MODE, ""); } - appendVCardLine(builder, VCARD_PROPERTY_END, VCARD_DATA_VCARD); + appendVCardLine(builder, Constants.PROPERTY_END, VCARD_DATA_VCARD); return builder.toString(); } @@ -748,11 +652,11 @@ public class VCardComposer { if (contentValuesList != null && contentValuesList.size() > 0) { appendStructuredNamesInternal(builder, contentValuesList); } else if (mIsDoCoMo) { - appendVCardLine(builder, VCARD_PROPERTY_NAME, ""); + appendVCardLine(builder, Constants.PROPERTY_N, ""); } else if (mIsV30) { // vCard 3.0 requires "N" and "FN" properties. - appendVCardLine(builder, VCARD_PROPERTY_NAME, ""); - appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, ""); + appendVCardLine(builder, Constants.PROPERTY_N, ""); + appendVCardLine(builder, Constants.PROPERTY_FN, ""); } } @@ -762,21 +666,38 @@ public class VCardComposer { // may get confused with multiple "N", "FN", etc. properties, though it is valid in // vCard spec. ContentValues primaryContentValues = null; + ContentValues subprimaryContentValues = null; for (ContentValues contentValues : contentValuesList) { + if (contentValues == null){ + continue; + } Integer isSuperPrimary = contentValues.getAsInteger(StructuredName.IS_SUPER_PRIMARY); - if (isSuperPrimary != null && isSuperPrimary != 0) { + if (isSuperPrimary != null && isSuperPrimary > 0) { // We choose "super primary" ContentValues. primaryContentValues = contentValues; break; - } else if (primaryContentValues == null && contentValues != null) { - // We choose the first ContentValues if "super primary" ContentValues does not exist. - primaryContentValues = contentValues; + } else if (primaryContentValues == null) { + // We choose the first "primary" ContentValues + // if "super primary" ContentValues does not exist. + Integer primary = contentValues.getAsInteger(StructuredName.IS_PRIMARY); + if (primary != null && primary > 0) { + primaryContentValues = contentValues; + // Do not break, since there may be ContentValues with "super primary" + // afterword. + } else if (subprimaryContentValues == null) { + subprimaryContentValues = contentValues; + } } } if (primaryContentValues == null) { - Log.e(LOG_TAG, "All ContentValues given from database is empty."); - primaryContentValues = new ContentValues(); + if (subprimaryContentValues != null) { + // We choose the first ContentValues if any "primary" ContentValues does not exist. + primaryContentValues = subprimaryContentValues; + } else { + Log.e(LOG_TAG, "All ContentValues given from database is empty."); + primaryContentValues = new ContentValues(); + } } final String familyName = primaryContentValues @@ -800,7 +721,7 @@ public class VCardComposer { final String encodedSuffix; final boolean reallyUseQuotedPrintableToName = - (mUsesQPToPrimaryProperties && + (!mRefrainsQPToPrimaryProperties && !(VCardUtils.containsOnlyNonCrLfPrintableAscii(familyName) && VCardUtils.containsOnlyNonCrLfPrintableAscii(givenName) && VCardUtils.containsOnlyNonCrLfPrintableAscii(middleName) && @@ -821,10 +742,9 @@ public class VCardComposer { encodedSuffix = escapeCharacters(suffix); } - // N property. This order is specified by vCard spec and does not depend on countries. - builder.append(VCARD_PROPERTY_NAME); + builder.append(Constants.PROPERTY_N); if (shouldAppendCharsetAttribute(Arrays.asList( - familyName, givenName, middleName, prefix, suffix))) { + encodedFamily, encodedGiven, encodedMiddle, encodedPrefix, encodedSuffix))) { builder.append(VCARD_ATTR_SEPARATOR); builder.append(mVCardAttributeCharset); } @@ -845,20 +765,26 @@ public class VCardComposer { builder.append(encodedSuffix); builder.append(VCARD_COL_SEPARATOR); - final String fullname = VCardUtils.constructNameFromElements( + final String formattedName; + if (!TextUtils.isEmpty(displayName)) { + formattedName = displayName; + } else { + formattedName = VCardUtils.constructNameFromElements( VCardConfig.getNameOrderType(mVCardType), encodedFamily, encodedMiddle, encodedGiven, encodedPrefix, encodedSuffix); + } + final boolean reallyUseQuotedPrintableToFullname = - mUsesQPToPrimaryProperties && - !VCardUtils.containsOnlyNonCrLfPrintableAscii(fullname); + !mRefrainsQPToPrimaryProperties && + !VCardUtils.containsOnlyNonCrLfPrintableAscii(formattedName); final String encodedFullname = reallyUseQuotedPrintableToFullname ? - encodeQuotedPrintable(fullname) : - escapeCharacters(fullname); + encodeQuotedPrintable(formattedName) : + escapeCharacters(formattedName); // FN property - builder.append(VCARD_PROPERTY_FULL_NAME); + builder.append(Constants.PROPERTY_FN); if (shouldAppendCharsetAttribute(encodedFullname)) { builder.append(VCARD_ATTR_SEPARATOR); builder.append(mVCardAttributeCharset); @@ -872,14 +798,14 @@ public class VCardComposer { builder.append(VCARD_COL_SEPARATOR); } else if (!TextUtils.isEmpty(displayName)) { final boolean reallyUseQuotedPrintableToDisplayName = - (mUsesQPToPrimaryProperties && + (!mRefrainsQPToPrimaryProperties && !VCardUtils.containsOnlyNonCrLfPrintableAscii(displayName)); final String encodedDisplayName = reallyUseQuotedPrintableToDisplayName ? encodeQuotedPrintable(displayName) : escapeCharacters(displayName); - builder.append(VCARD_PROPERTY_NAME); + builder.append(Constants.PROPERTY_N); if (shouldAppendCharsetAttribute(encodedDisplayName)) { builder.append(VCARD_ATTR_SEPARATOR); builder.append(mVCardAttributeCharset); @@ -895,38 +821,54 @@ public class VCardComposer { builder.append(VCARD_ITEM_SEPARATOR); builder.append(VCARD_ITEM_SEPARATOR); builder.append(VCARD_COL_SEPARATOR); - } else if (mIsDoCoMo) { - appendVCardLine(builder, VCARD_PROPERTY_NAME, ""); + if (mIsV30) { + builder.append(Constants.PROPERTY_FN); + // TODO: Not allowed formally... + if (shouldAppendCharsetAttribute(encodedDisplayName)) { + builder.append(VCARD_ATTR_SEPARATOR); + builder.append(mVCardAttributeCharset); + } + builder.append(VCARD_DATA_SEPARATOR); + builder.append(encodedDisplayName); + builder.append(VCARD_COL_SEPARATOR); + } } else if (mIsV30) { - appendVCardLine(builder, VCARD_PROPERTY_NAME, ""); - appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, ""); + // vCard 3.0 specification requires these fields. + appendVCardLine(builder, Constants.PROPERTY_N, ""); + appendVCardLine(builder, Constants.PROPERTY_FN, ""); + } else if (mIsDoCoMo) { + appendVCardLine(builder, Constants.PROPERTY_N, ""); } - String phoneticFamilyName = primaryContentValues - .getAsString(StructuredName.PHONETIC_FAMILY_NAME); - String phoneticMiddleName = primaryContentValues - .getAsString(StructuredName.PHONETIC_MIDDLE_NAME); - String phoneticGivenName = primaryContentValues - .getAsString(StructuredName.PHONETIC_GIVEN_NAME); - if (!(TextUtils.isEmpty(phoneticFamilyName) - && TextUtils.isEmpty(phoneticMiddleName) && - TextUtils.isEmpty(phoneticGivenName))) { // if not empty - if (mIsJapaneseMobilePhone) { - phoneticFamilyName = VCardUtils - .toHalfWidthString(phoneticFamilyName); - phoneticMiddleName = VCardUtils - .toHalfWidthString(phoneticMiddleName); - phoneticGivenName = VCardUtils - .toHalfWidthString(phoneticGivenName); + final String phoneticFamilyName; + final String phoneticMiddleName; + final String phoneticGivenName; + { + String tmpPhoneticFamilyName = + primaryContentValues.getAsString(StructuredName.PHONETIC_FAMILY_NAME); + String tmpPhoneticMiddleName = + primaryContentValues.getAsString(StructuredName.PHONETIC_MIDDLE_NAME); + String tmpPhoneticGivenName = + primaryContentValues.getAsString(StructuredName.PHONETIC_GIVEN_NAME); + if (mNeedsToConvertPhoneticString) { + phoneticFamilyName = VCardUtils.toHalfWidthString(tmpPhoneticFamilyName); + phoneticMiddleName = VCardUtils.toHalfWidthString(tmpPhoneticMiddleName); + phoneticGivenName = VCardUtils.toHalfWidthString(tmpPhoneticGivenName); + } else { + phoneticFamilyName = tmpPhoneticFamilyName; + phoneticMiddleName = tmpPhoneticMiddleName; + phoneticGivenName = tmpPhoneticGivenName; } + } + if (!(TextUtils.isEmpty(phoneticFamilyName) + && TextUtils.isEmpty(phoneticMiddleName) + && TextUtils.isEmpty(phoneticGivenName))) { if (mIsV30) { final String sortString = VCardUtils .constructNameFromElements(mVCardType, - phoneticFamilyName, - phoneticMiddleName, - phoneticGivenName); - builder.append(VCARD_PROPERTY_SORT_STRING); + phoneticFamilyName, phoneticMiddleName, phoneticGivenName); + builder.append(Constants.PROPERTY_SORT_STRING); // Do not need to care about QP, since vCard 3.0 does not allow it. final String encodedSortString = escapeCharacters(sortString); @@ -937,25 +879,26 @@ public class VCardComposer { builder.append(VCARD_DATA_SEPARATOR); builder.append(encodedSortString); builder.append(VCARD_COL_SEPARATOR); - } else { + } else if (mIsJapaneseMobilePhone) { // Note: There is no appropriate property for expressing // phonetic name in vCard 2.1, while there is in // vCard 3.0 (SORT-STRING). - // We chose to use DoCoMo's way since it is supported by + // We chose to use DoCoMo's way when the device is Japanese one + // since it is supported by // a lot of Japanese mobile phones. This is "X-" property, so // any parser hopefully would not get confused with this. - builder.append(VCARD_PROPERTY_SOUND); + builder.append(Constants.PROPERTY_SOUND); builder.append(VCARD_ATTR_SEPARATOR); builder.append(Constants.ATTR_TYPE_X_IRMC_N); boolean reallyUseQuotedPrintable = - (mUsesQPToPrimaryProperties && - !(VCardUtils.containsOnlyNonCrLfPrintableAscii( - phoneticFamilyName) && - VCardUtils.containsOnlyNonCrLfPrintableAscii( - phoneticMiddleName) && - VCardUtils.containsOnlyNonCrLfPrintableAscii( - phoneticGivenName))); + (!mRefrainsQPToPrimaryProperties + && !(VCardUtils.containsOnlyNonCrLfPrintableAscii( + phoneticFamilyName) + && VCardUtils.containsOnlyNonCrLfPrintableAscii( + phoneticMiddleName) + && VCardUtils.containsOnlyNonCrLfPrintableAscii( + phoneticGivenName))); final String encodedPhoneticFamilyName; final String encodedPhoneticMiddleName; @@ -987,7 +930,7 @@ public class VCardComposer { builder.append(VCARD_COL_SEPARATOR); } } else if (mIsDoCoMo) { - builder.append(VCARD_PROPERTY_SOUND); + builder.append(Constants.PROPERTY_SOUND); builder.append(VCARD_ATTR_SEPARATOR); builder.append(Constants.ATTR_TYPE_X_IRMC_N); builder.append(VCARD_DATA_SEPARATOR); @@ -1001,15 +944,14 @@ public class VCardComposer { if (mUsesDefactProperty) { if (!TextUtils.isEmpty(phoneticGivenName)) { final boolean reallyUseQuotedPrintable = - (mUsesQPToPrimaryProperties && - !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticGivenName)); + !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticGivenName); final String encodedPhoneticGivenName; if (reallyUseQuotedPrintable) { encodedPhoneticGivenName = encodeQuotedPrintable(phoneticGivenName); } else { encodedPhoneticGivenName = escapeCharacters(phoneticGivenName); } - builder.append(VCARD_PROPERTY_X_PHONETIC_FIRST_NAME); + builder.append(Constants.PROPERTY_X_PHONETIC_FIRST_NAME); if (shouldAppendCharsetAttribute(encodedPhoneticGivenName)) { builder.append(VCARD_ATTR_SEPARATOR); builder.append(mVCardAttributeCharset); @@ -1024,15 +966,14 @@ public class VCardComposer { } if (!TextUtils.isEmpty(phoneticMiddleName)) { final boolean reallyUseQuotedPrintable = - (mUsesQPToPrimaryProperties && - !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticMiddleName)); + !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticMiddleName); final String encodedPhoneticMiddleName; if (reallyUseQuotedPrintable) { encodedPhoneticMiddleName = encodeQuotedPrintable(phoneticMiddleName); } else { encodedPhoneticMiddleName = escapeCharacters(phoneticMiddleName); } - builder.append(VCARD_PROPERTY_X_PHONETIC_MIDDLE_NAME); + builder.append(Constants.PROPERTY_X_PHONETIC_MIDDLE_NAME); if (shouldAppendCharsetAttribute(encodedPhoneticMiddleName)) { builder.append(VCARD_ATTR_SEPARATOR); builder.append(mVCardAttributeCharset); @@ -1047,15 +988,14 @@ public class VCardComposer { } if (!TextUtils.isEmpty(phoneticFamilyName)) { final boolean reallyUseQuotedPrintable = - (mUsesQPToPrimaryProperties && - !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticFamilyName)); + !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticFamilyName); final String encodedPhoneticFamilyName; if (reallyUseQuotedPrintable) { encodedPhoneticFamilyName = encodeQuotedPrintable(phoneticFamilyName); } else { encodedPhoneticFamilyName = escapeCharacters(phoneticFamilyName); } - builder.append(VCARD_PROPERTY_X_PHONETIC_LAST_NAME); + builder.append(Constants.PROPERTY_X_PHONETIC_LAST_NAME); if (shouldAppendCharsetAttribute(encodedPhoneticFamilyName)) { builder.append(VCARD_ATTR_SEPARATOR); builder.append(mVCardAttributeCharset); @@ -1075,46 +1015,48 @@ public class VCardComposer { final Map<String, List<ContentValues>> contentValuesListMap) { final List<ContentValues> contentValuesList = contentValuesListMap .get(Nickname.CONTENT_ITEM_TYPE); - if (contentValuesList != null) { - final String propertyNickname; - if (mIsV30) { - propertyNickname = VCARD_PROPERTY_NICKNAME; - } else if (mUsesAndroidProperty) { - propertyNickname = VCARD_PROPERTY_X_NICKNAME; - } else { - // There's no way to add this field. - return; - } + if (contentValuesList == null) { + return; + } - for (ContentValues contentValues : contentValuesList) { - final String nickname = contentValues.getAsString(Nickname.NAME); - if (TextUtils.isEmpty(nickname)) { - continue; - } + final String propertyNickname; + if (mIsV30) { + propertyNickname = Constants.PROPERTY_NICKNAME; + /*} else if (mUsesAndroidProperty) { + propertyNickname = VCARD_PROPERTY_X_NICKNAME;*/ + } else { + // There's no way to add this field. + return; + } - final String encodedNickname; - final boolean reallyUseQuotedPrintable = - (mUsesQuotedPrintable && - !VCardUtils.containsOnlyNonCrLfPrintableAscii(nickname)); - if (reallyUseQuotedPrintable) { - encodedNickname = encodeQuotedPrintable(nickname); - } else { - encodedNickname = escapeCharacters(nickname); - } + for (ContentValues contentValues : contentValuesList) { + final String nickname = contentValues.getAsString(Nickname.NAME); + if (TextUtils.isEmpty(nickname)) { + continue; + } - builder.append(propertyNickname); - if (shouldAppendCharsetAttribute(propertyNickname)) { - builder.append(VCARD_ATTR_SEPARATOR); - builder.append(mVCardAttributeCharset); - } - if (reallyUseQuotedPrintable) { - builder.append(VCARD_ATTR_SEPARATOR); - builder.append(VCARD_ATTR_ENCODING_QP); - } - builder.append(VCARD_DATA_SEPARATOR); - builder.append(encodedNickname); - builder.append(VCARD_COL_SEPARATOR); + final String encodedNickname; + final boolean reallyUseQuotedPrintable = + (mUsesQuotedPrintable && + !VCardUtils.containsOnlyNonCrLfPrintableAscii(nickname)); + if (reallyUseQuotedPrintable) { + encodedNickname = encodeQuotedPrintable(nickname); + } else { + encodedNickname = escapeCharacters(nickname); + } + + builder.append(propertyNickname); + if (shouldAppendCharsetAttribute(propertyNickname)) { + builder.append(VCARD_ATTR_SEPARATOR); + builder.append(mVCardAttributeCharset); } + if (reallyUseQuotedPrintable) { + builder.append(VCARD_ATTR_SEPARATOR); + builder.append(VCARD_ATTR_ENCODING_QP); + } + builder.append(VCARD_DATA_SEPARATOR); + builder.append(encodedNickname); + builder.append(VCARD_COL_SEPARATOR); } } @@ -1128,6 +1070,9 @@ public class VCardComposer { for (ContentValues contentValues : contentValuesList) { final Integer typeAsObject = contentValues.getAsInteger(Phone.TYPE); final String label = contentValues.getAsString(Phone.LABEL); + final Integer isPrimaryAsInteger = contentValues.getAsInteger(Phone.IS_PRIMARY); + final boolean isPrimary = (isPrimaryAsInteger != null ? + (isPrimaryAsInteger > 0) : false); String phoneNumber = contentValues.getAsString(Phone.NUMBER); if (phoneNumber != null) { phoneNumber = phoneNumber.trim(); @@ -1136,18 +1081,18 @@ public class VCardComposer { continue; } phoneLineExists = true; - int type = (typeAsObject != null ? typeAsObject : Phone.TYPE_HOME); + int type = (typeAsObject != null ? typeAsObject : DEFAULT_PHONE_TYPE); // TODO: Premature, since this allows two phone numbers which are // same from the view of phone number format (e.g. "100" v.s. "1-0-0") if (!phoneSet.contains(phoneNumber)) { phoneSet.add(phoneNumber); - appendVCardTelephoneLine(builder, type, label, phoneNumber); + appendVCardTelephoneLine(builder, type, label, phoneNumber, isPrimary); } } } if (!phoneLineExists && mIsDoCoMo) { - appendVCardTelephoneLine(builder, Phone.TYPE_HOME, "", ""); + appendVCardTelephoneLine(builder, Phone.TYPE_HOME, "", "", false); } } @@ -1155,14 +1100,11 @@ public class VCardComposer { final Map<String, List<ContentValues>> contentValuesListMap) { final List<ContentValues> contentValuesList = contentValuesListMap .get(Email.CONTENT_ITEM_TYPE); + boolean emailAddressExists = false; if (contentValuesList != null) { - Set<String> addressSet = new HashSet<String>(); + final Set<String> addressSet = new HashSet<String>(); for (ContentValues contentValues : contentValuesList) { - Integer typeAsObject = contentValues.getAsInteger(Email.TYPE); - final int type = (typeAsObject != null ? - typeAsObject : Email.TYPE_OTHER); - final String label = contentValues.getAsString(Email.LABEL); String emailAddress = contentValues.getAsString(Email.DATA); if (emailAddress != null) { emailAddress = emailAddress.trim(); @@ -1170,16 +1112,23 @@ public class VCardComposer { if (TextUtils.isEmpty(emailAddress)) { continue; } + Integer typeAsObject = contentValues.getAsInteger(Email.TYPE); + final int type = (typeAsObject != null ? + typeAsObject : DEFAULT_EMAIL_TYPE); + final String label = contentValues.getAsString(Email.LABEL); + Integer isPrimaryAsInteger = contentValues.getAsInteger(Email.IS_PRIMARY); + final boolean isPrimary = (isPrimaryAsInteger != null ? + (isPrimaryAsInteger > 0) : false); emailAddressExists = true; if (!addressSet.contains(emailAddress)) { addressSet.add(emailAddress); - appendVCardEmailLine(builder, type, label, emailAddress); + appendVCardEmailLine(builder, type, label, emailAddress, isPrimary); } } } if (!emailAddressExists && mIsDoCoMo) { - appendVCardEmailLine(builder, Email.TYPE_HOME, "", ""); + appendVCardEmailLine(builder, Email.TYPE_HOME, "", "", false); } } @@ -1194,7 +1143,7 @@ public class VCardComposer { appendPostalsForGeneric(builder, contentValuesList); } } else if (mIsDoCoMo) { - builder.append(VCARD_PROPERTY_ADR); + builder.append(Constants.PROPERTY_ADR); builder.append(VCARD_ATTR_SEPARATOR); builder.append(Constants.ATTR_TYPE_HOME); builder.append(VCARD_DATA_SEPARATOR); @@ -1236,7 +1185,10 @@ public class VCardComposer { final Integer type = contentValues.getAsInteger(StructuredPostal.TYPE); final String label = contentValues.getAsString(StructuredPostal.LABEL); if (type == preferedType) { - appendVCardPostalLine(builder, type, label, contentValues); + // Note: Not sure why we need to emit "empty" line even when actual + // data does not exist. There may be some reason or may not. + // We keep safer side since the previous implementation did so. + appendVCardPostalLine(builder, type, label, contentValues, true, true); return true; } } @@ -1246,11 +1198,18 @@ public class VCardComposer { private void appendPostalsForGeneric(final StringBuilder builder, final List<ContentValues> contentValuesList) { for (ContentValues contentValues : contentValuesList) { - final Integer type = contentValues.getAsInteger(StructuredPostal.TYPE); - final String label = contentValues.getAsString(StructuredPostal.LABEL); - if (type != null) { - appendVCardPostalLine(builder, type, label, contentValues); + if (contentValues == null) { + continue; } + final Integer typeAsObject = contentValues.getAsInteger(StructuredPostal.TYPE); + final int type = (typeAsObject != null ? + typeAsObject : DEFAULT_POSTAL_TYPE); + final String label = contentValues.getAsString(StructuredPostal.LABEL); + final Integer isPrimaryAsInteger = + contentValues.getAsInteger(StructuredPostal.IS_PRIMARY); + final boolean isPrimary = (isPrimaryAsInteger != null ? + (isPrimaryAsInteger > 0) : false); + appendVCardPostalLine(builder, type, label, contentValues, isPrimary, false); } } @@ -1258,24 +1217,63 @@ public class VCardComposer { final Map<String, List<ContentValues>> contentValuesListMap) { final List<ContentValues> contentValuesList = contentValuesListMap .get(Im.CONTENT_ITEM_TYPE); - if (contentValuesList != null) { - for (ContentValues contentValues : contentValuesList) { - Integer protocol = contentValues.getAsInteger(Im.PROTOCOL); - String data = contentValues.getAsString(Im.DATA); - if (data != null) { - data = data.trim(); - } - if (TextUtils.isEmpty(data)) { - continue; - } - - if (protocol != null && protocol == Im.PROTOCOL_GOOGLE_TALK) { - if (VCardConfig.usesAndroidSpecificProperty(mVCardType)) { - appendVCardLine(builder, Constants.PROPERTY_X_GOOGLE_TALK, data); + if (contentValuesList == null) { + return; + } + for (ContentValues contentValues : contentValuesList) { + final Integer protocolAsObject = contentValues.getAsInteger(Im.PROTOCOL); + if (protocolAsObject == null) { + continue; + } + final String propertyName = VCardUtils.getPropertyNameForIm(protocolAsObject); + if (propertyName == null) { + continue; + } + String data = contentValues.getAsString(Im.DATA); + if (data != null) { + data = data.trim(); + } + if (TextUtils.isEmpty(data)) { + continue; + } + final String typeAsString; + { + final Integer typeAsInteger = contentValues.getAsInteger(Im.TYPE); + switch (typeAsInteger != null ? typeAsInteger : Im.TYPE_OTHER) { + case Im.TYPE_HOME: { + typeAsString = Constants.ATTR_TYPE_HOME; + break; + } + case Im.TYPE_WORK: { + typeAsString = Constants.ATTR_TYPE_WORK; + break; + } + case Im.TYPE_CUSTOM: { + final String label = contentValues.getAsString(Im.LABEL); + typeAsString = (label != null ? "X-" + label : null); + break; + } + case Im.TYPE_OTHER: // Ignore + default: { + typeAsString = null; + break; } - // TODO: add "X-GOOGLE TALK" case... } } + + List<String> attributeList = new ArrayList<String>(); + if (!TextUtils.isEmpty(typeAsString)) { + attributeList.add(typeAsString); + } + final Integer isPrimaryAsInteger = contentValues.getAsInteger(Im.IS_PRIMARY); + final boolean isPrimary = (isPrimaryAsInteger != null ? + (isPrimaryAsInteger > 0) : false); + if (isPrimary) { + attributeList.add(Constants.ATTR_TYPE_PREF); + } + + appendVCardLineWithCharsetAndQPDetection( + builder, propertyName, attributeList, data); } } @@ -1283,39 +1281,83 @@ public class VCardComposer { final Map<String, List<ContentValues>> contentValuesListMap) { final List<ContentValues> contentValuesList = contentValuesListMap .get(Website.CONTENT_ITEM_TYPE); - if (contentValuesList != null) { - for (ContentValues contentValues : contentValuesList) { - String website = contentValues.getAsString(Website.URL); - if (website != null) { - website = website.trim(); - } - if (!TextUtils.isEmpty(website)) { - appendVCardLine(builder, VCARD_PROPERTY_URL, website); - } + if (contentValuesList == null) { + return; + } + for (ContentValues contentValues : contentValuesList) { + String website = contentValues.getAsString(Website.URL); + if (website != null) { + website = website.trim(); + } + // Note: vCard 3.0 does not allow any attribute addition toward "URL" + // property, while there's no document in vCard 2.1. + // + // TODO: Should we allow adding it when appropriate? + // (Actually, we drop some data. Using "group.X-URL-TYPE" or something + // may help) + if (!TextUtils.isEmpty(website)) { + appendVCardLine(builder, Constants.PROPERTY_URL, website); } } } + /** + * Theoretically, there must be only one birthday for each vCard entry. + * Also, we are afraid of some importer's parse error during its import. + * We emit only one birthday entry even when there are more than one. + */ private void appendBirthday(final StringBuilder builder, final Map<String, List<ContentValues>> contentValuesListMap) { - final List<ContentValues> contentValuesList = contentValuesListMap - .get(Event.CONTENT_ITEM_TYPE); - if (contentValuesList != null && contentValuesList.size() > 0) { - Integer eventType = contentValuesList.get(0).getAsInteger(Event.TYPE); - if (eventType == null || !eventType.equals(Event.TYPE_BIRTHDAY)) { - return; + final List<ContentValues> contentValuesList = + contentValuesListMap.get(Event.CONTENT_ITEM_TYPE); + if (contentValuesList == null) { + return; + } + String primaryBirthday = null; + String secondaryBirthday = null; + for (ContentValues contentValues : contentValuesList) { + if (contentValues == null) { + continue; } - // Theoretically, there must be only one birthday for each vCard data and - // we are afraid of some parse error occuring in some devices, so - // we emit only one birthday entry for now. - String birthday = contentValuesList.get(0).getAsString(Event.START_DATE); - if (birthday != null) { - birthday = birthday.trim(); + final Integer eventType = contentValues.getAsInteger(Event.TYPE); + if (eventType == null || !eventType.equals(Event.TYPE_BIRTHDAY)) { + continue; + } + final String birthdayCandidate = contentValues.getAsString(Event.START_DATE); + if (birthdayCandidate == null) { + continue; + } + final Integer isSuperPrimaryAsInteger = + contentValues.getAsInteger(Event.IS_SUPER_PRIMARY); + final boolean isSuperPrimary = (isSuperPrimaryAsInteger != null ? + (isSuperPrimaryAsInteger > 0) : false); + if (isSuperPrimary) { + // "super primary" birthday should the prefered one. + primaryBirthday = birthdayCandidate; + break; } - if (!TextUtils.isEmpty(birthday)) { - appendVCardLine(builder, VCARD_PROPERTY_BIRTHDAY, birthday); + final Integer isPrimaryAsInteger = + contentValues.getAsInteger(Event.IS_PRIMARY); + final boolean isPrimary = (isPrimaryAsInteger != null ? + (isPrimaryAsInteger > 0) : false); + if (isPrimary) { + // We don't break here since "super primary" birthday may exist later. + primaryBirthday = birthdayCandidate; + } else if (secondaryBirthday == null) { + // First entry is set to the "secondary" candidate. + secondaryBirthday = birthdayCandidate; } } + + final String birthday; + if (primaryBirthday != null) { + birthday = primaryBirthday.trim(); + } else if (secondaryBirthday != null){ + birthday = secondaryBirthday.trim(); + } else { + return; + } + appendVCardLineWithCharsetAndQPDetection(builder, Constants.PROPERTY_BDAY, birthday); } private void appendOrganizations(final StringBuilder builder, @@ -1324,25 +1366,37 @@ public class VCardComposer { .get(Organization.CONTENT_ITEM_TYPE); if (contentValuesList != null) { for (ContentValues contentValues : contentValuesList) { - String company = contentValues - .getAsString(Organization.COMPANY); + String company = contentValues.getAsString(Organization.COMPANY); if (company != null) { company = company.trim(); } - String title = contentValues - .getAsString(Organization.TITLE); + String department = contentValues.getAsString(Organization.DEPARTMENT); + if (department != null) { + department = department.trim(); + } + String title = contentValues.getAsString(Organization.TITLE); if (title != null) { title = title.trim(); } + StringBuilder orgBuilder = new StringBuilder(); if (!TextUtils.isEmpty(company)) { - appendVCardLine(builder, VCARD_PROPERTY_ORG, company, - !VCardUtils.containsOnlyPrintableAscii(company), - (mUsesQuotedPrintable && - !VCardUtils.containsOnlyNonCrLfPrintableAscii(company))); + orgBuilder.append(company); } + if (!TextUtils.isEmpty(department)) { + if (orgBuilder.length() > 0) { + orgBuilder.append(';'); + } + orgBuilder.append(department); + } + final String orgline = orgBuilder.toString(); + appendVCardLine(builder, Constants.PROPERTY_ORG, orgline, + !VCardUtils.containsOnlyPrintableAscii(orgline), + (mUsesQuotedPrintable && + !VCardUtils.containsOnlyNonCrLfPrintableAscii(orgline))); + if (!TextUtils.isEmpty(title)) { - appendVCardLine(builder, VCARD_PROPERTY_TITLE, title, + appendVCardLine(builder, Constants.PROPERTY_TITLE, title, !VCardUtils.containsOnlyPrintableAscii(title), (mUsesQuotedPrintable && !VCardUtils.containsOnlyNonCrLfPrintableAscii(title))); @@ -1369,11 +1423,9 @@ public class VCardComposer { photoType = "GIF"; } else if (data.length >= 4 && data[0] == (byte) 0x89 && data[1] == 'P' && data[2] == 'N' && data[3] == 'G') { - // Note: vCard 2.1 officially does not support PNG, but we - // may have it - // and using X- word like "X-PNG" may not let importers know - // it is - // PNG. So we use the String "PNG" as is... + // Note: vCard 2.1 officially does not support PNG, but we may + // have it and using X- word like "X-PNG" may not let importers + // know it is PNG. So we use the String "PNG" as is... photoType = "PNG"; } else if (data.length >= 2 && data[0] == (byte) 0xff && data[1] == (byte) 0xd8) { @@ -1420,7 +1472,7 @@ public class VCardComposer { final boolean reallyUseQuotedPrintable = (mUsesQuotedPrintable && !VCardUtils.containsOnlyNonCrLfPrintableAscii(noteStr)); - appendVCardLine(builder, VCARD_PROPERTY_NOTE, noteStr, + appendVCardLine(builder, Constants.PROPERTY_NOTE, noteStr, shouldAppendCharsetInfo, reallyUseQuotedPrintable); } else { for (ContentValues contentValues : contentValuesList) { @@ -1431,7 +1483,7 @@ public class VCardComposer { final boolean reallyUseQuotedPrintable = (mUsesQuotedPrintable && !VCardUtils.containsOnlyNonCrLfPrintableAscii(noteStr)); - appendVCardLine(builder, VCARD_PROPERTY_NOTE, noteStr, + appendVCardLine(builder, Constants.PROPERTY_NOTE, noteStr, shouldAppendCharsetInfo, reallyUseQuotedPrintable); } } @@ -1454,7 +1506,7 @@ public class VCardComposer { final StringBuilder tmpBuilder = new StringBuilder(); final int length = unescaped.length(); for (int i = 0; i < length; i++) { - char ch = unescaped.charAt(i); + final char ch = unescaped.charAt(i); switch (ch) { case ';': { tmpBuilder.append('\\'); @@ -1465,7 +1517,7 @@ public class VCardComposer { if (i + 1 < length) { char nextChar = unescaped.charAt(i); if (nextChar == '\n') { - continue; + break; } else { // fall through } @@ -1517,7 +1569,7 @@ public class VCardComposer { private void appendVCardPhotoLine(final StringBuilder builder, final String encodedData, final String photoType) { StringBuilder tmpBuilder = new StringBuilder(); - tmpBuilder.append(VCARD_PROPERTY_PHOTO); + tmpBuilder.append(Constants.PROPERTY_PHOTO); tmpBuilder.append(VCARD_ATTR_SEPARATOR); if (mIsV30) { tmpBuilder.append(VCARD_ATTR_ENCODING_BASE64_V30); @@ -1547,59 +1599,126 @@ public class VCardComposer { builder.append(VCARD_COL_SEPARATOR); } - private void appendVCardPostalLine(final StringBuilder builder, - final Integer typeAsObject, final String label, - final ContentValues contentValues) { - builder.append(VCARD_PROPERTY_ADR); - builder.append(VCARD_ATTR_SEPARATOR); + private class PostalStruct { + final boolean reallyUseQuotedPrintable; + final boolean appendCharset; + final String addressData; + public PostalStruct(final boolean reallyUseQuotedPrintable, + final boolean appendCharset, final String addressData) { + this.reallyUseQuotedPrintable = reallyUseQuotedPrintable; + this.appendCharset = appendCharset; + this.addressData = addressData; + } + } - // Note: Not sure why we need to emit "empty" line even when actual data does not exist. - // There may be some reason or may not be any. We keep safer side. - // TODO: investigate this. - boolean dataExists = false; + /** + * @return null when there's no information available to construct the data. + */ + private PostalStruct tryConstructPostalStruct(ContentValues contentValues) { + boolean reallyUseQuotedPrintable = false; + boolean appendCharset = false; + + boolean dataArrayExists = false; String[] dataArray = VCardUtils.getVCardPostalElements(contentValues); - boolean actuallyUseQuotedPrintable = false; - boolean shouldAppendCharset = false; for (String data : dataArray) { if (!TextUtils.isEmpty(data)) { - dataExists = true; - if (!shouldAppendCharset && !VCardUtils.containsOnlyPrintableAscii(data)) { - shouldAppendCharset = true; + dataArrayExists = true; + if (!appendCharset && !VCardUtils.containsOnlyPrintableAscii(data)) { + appendCharset = true; } if (mUsesQuotedPrintable && !VCardUtils.containsOnlyNonCrLfPrintableAscii(data)) { - actuallyUseQuotedPrintable = true; + reallyUseQuotedPrintable = true; break; } } } - int length = dataArray.length; - for (int i = 0; i < length; i++) { - String data = dataArray[i]; - if (!TextUtils.isEmpty(data)) { - if (actuallyUseQuotedPrintable) { - dataArray[i] = encodeQuotedPrintable(data); + if (dataArrayExists) { + StringBuffer addressBuffer = new StringBuffer(); + boolean first = true; + for (String data : dataArray) { + if (first) { + first = false; } else { - dataArray[i] = escapeCharacters(data); + addressBuffer.append(VCARD_ITEM_SEPARATOR); + } + if (!TextUtils.isEmpty(data)) { + if (reallyUseQuotedPrintable) { + addressBuffer.append(encodeQuotedPrintable(data)); + } else { + addressBuffer.append(escapeCharacters(data)); + } } } + return new PostalStruct(reallyUseQuotedPrintable, appendCharset, + addressBuffer.toString()); } - final int typeAsPrimitive; - if (typeAsObject == null) { - typeAsPrimitive = StructuredPostal.TYPE_OTHER; - } else { - typeAsPrimitive = typeAsObject; + String formattedAddress = + contentValues.getAsString(StructuredPostal.FORMATTED_ADDRESS); + if (!TextUtils.isEmpty(formattedAddress)) { + reallyUseQuotedPrintable = + !VCardUtils.containsOnlyPrintableAscii(formattedAddress); + appendCharset = + !VCardUtils.containsOnlyNonCrLfPrintableAscii(formattedAddress); + if (reallyUseQuotedPrintable) { + formattedAddress = encodeQuotedPrintable(formattedAddress); + } else { + formattedAddress = escapeCharacters(formattedAddress); + } + // We use the second value ("Extended Address"). + // + // adr-value = 0*6(text-value ";") text-value + // ; PO Box, Extended Address, Street, Locality, Region, Postal + // ; Code, Country Name + StringBuffer addressBuffer = new StringBuffer(); + addressBuffer.append(VCARD_ITEM_SEPARATOR); + addressBuffer.append(formattedAddress); + addressBuffer.append(VCARD_ITEM_SEPARATOR); + addressBuffer.append(VCARD_ITEM_SEPARATOR); + addressBuffer.append(VCARD_ITEM_SEPARATOR); + addressBuffer.append(VCARD_ITEM_SEPARATOR); + addressBuffer.append(VCARD_ITEM_SEPARATOR); + return new PostalStruct( + reallyUseQuotedPrintable, appendCharset, addressBuffer.toString()); + } + return null; // There's no data available. + } + + private void appendVCardPostalLine(final StringBuilder builder, + final int type, final String label, final ContentValues contentValues, + final boolean isPrimary, final boolean emitLineEveryTime) { + final boolean reallyUseQuotedPrintable; + final boolean appendCharset; + final String addressData; + { + PostalStruct postalStruct = tryConstructPostalStruct(contentValues); + if (postalStruct == null) { + if (emitLineEveryTime) { + reallyUseQuotedPrintable = false; + appendCharset = false; + addressData = ""; + } else { + return; + } + } else { + reallyUseQuotedPrintable = postalStruct.reallyUseQuotedPrintable; + appendCharset = postalStruct.appendCharset; + addressData = postalStruct.addressData; + } } - String typeAsString = null; - switch (typeAsPrimitive) { + List<String> attributeList = new ArrayList<String>(); + if (isPrimary) { + attributeList.add(Constants.ATTR_TYPE_PREF); + } + switch (type) { case StructuredPostal.TYPE_HOME: { - typeAsString = Constants.ATTR_TYPE_HOME; + attributeList.add(Constants.ATTR_TYPE_HOME); break; } case StructuredPostal.TYPE_WORK: { - typeAsString = Constants.ATTR_TYPE_WORK; + attributeList.add(Constants.ATTR_TYPE_WORK); break; } case StructuredPostal.TYPE_CUSTOM: { @@ -1609,9 +1728,7 @@ public class VCardComposer { // ("IANA-token" in the vCard 3.0 is unclear...) // Just for safety, we add "X-" at the beggining of each label. // Also checks the label obeys with vCard 3.0 spec. - builder.append("X-"); - builder.append(label); - builder.append(VCARD_DATA_SEPARATOR); + attributeList.add("X-" + label); } break; } @@ -1619,82 +1736,56 @@ public class VCardComposer { break; } default: { - Log.e(LOG_TAG, "Unknown StructuredPostal type: " + typeAsPrimitive); + Log.e(LOG_TAG, "Unknown StructuredPostal type: " + type); break; } } - // Attribute(s). + // Actual data construction starts from here. + // TODO: add a new version of appendVCardLine() for this purpose. + builder.append(Constants.PROPERTY_ADR); + builder.append(VCARD_ATTR_SEPARATOR); + + // Attributes { boolean shouldAppendAttrSeparator = false; - if (typeAsString != null) { - appendTypeAttribute(builder, typeAsString); + if (!attributeList.isEmpty()) { + appendTypeAttributes(builder, attributeList); shouldAppendAttrSeparator = true; } - if (dataExists) { - if (shouldAppendCharset) { - // Strictly, vCard 3.0 does not allow exporters to emit charset information, - // but we will add it since the information should be useful for importers, - // - // Assume no parser does not emit error with this attribute in vCard 3.0. - if (shouldAppendAttrSeparator) { - builder.append(VCARD_ATTR_SEPARATOR); - } - builder.append(mVCardAttributeCharset); - shouldAppendAttrSeparator = true; + if (appendCharset) { + // Strictly, vCard 3.0 does not allow exporters to emit charset information, + // but we will add it since the information should be useful for importers, + // + // Assume no parser does not emit error with this attribute in vCard 3.0. + if (shouldAppendAttrSeparator) { + builder.append(VCARD_ATTR_SEPARATOR); } + builder.append(mVCardAttributeCharset); + shouldAppendAttrSeparator = true; + } - if (actuallyUseQuotedPrintable) { - if (shouldAppendAttrSeparator) { - builder.append(VCARD_ATTR_SEPARATOR); - } - builder.append(VCARD_ATTR_ENCODING_QP); - shouldAppendAttrSeparator = true; + if (reallyUseQuotedPrintable) { + if (shouldAppendAttrSeparator) { + builder.append(VCARD_ATTR_SEPARATOR); } + builder.append(VCARD_ATTR_ENCODING_QP); + shouldAppendAttrSeparator = true; } } - // Property values. - builder.append(VCARD_DATA_SEPARATOR); - if (dataExists) { - // The elements in dataArray are already encoded to quoted printable - // if needed. - // See above. - // - // TODO: in vCard 3.0, one line may become too huge. Fix this. - builder.append(dataArray[0]); - builder.append(VCARD_ITEM_SEPARATOR); - builder.append(dataArray[1]); - builder.append(VCARD_ITEM_SEPARATOR); - builder.append(dataArray[2]); - builder.append(VCARD_ITEM_SEPARATOR); - builder.append(dataArray[3]); - builder.append(VCARD_ITEM_SEPARATOR); - builder.append(dataArray[4]); - builder.append(VCARD_ITEM_SEPARATOR); - builder.append(dataArray[5]); - builder.append(VCARD_ITEM_SEPARATOR); - builder.append(dataArray[6]); - } + builder.append(addressData); builder.append(VCARD_COL_SEPARATOR); } private void appendVCardEmailLine(final StringBuilder builder, - final Integer typeAsObject, final String label, final String data) { - builder.append(VCARD_PROPERTY_EMAIL); - - final int typeAsPrimitive; - if (typeAsObject == null) { - typeAsPrimitive = Email.TYPE_OTHER; - } else { - typeAsPrimitive = typeAsObject; - } - + final int type, final String label, + final String rawData, final boolean isPrimary) { final String typeAsString; - switch (typeAsPrimitive) { + switch (type) { case Email.TYPE_CUSTOM: { // For backward compatibility. // Detail: Until Donut, there isn't TYPE_MOBILE for email while there is now. @@ -1706,7 +1797,7 @@ public class VCardComposer { && VCardUtils.containsOnlyAlphaDigitHyphen(label)) { typeAsString = "X-" + label; } else { - typeAsString = DEFAULT_EMAIL_TYPE; + typeAsString = null; } break; } @@ -1719,7 +1810,7 @@ public class VCardComposer { break; } case Email.TYPE_OTHER: { - typeAsString = DEFAULT_EMAIL_TYPE; + typeAsString = null; break; } case Email.TYPE_MOBILE: { @@ -1727,23 +1818,28 @@ public class VCardComposer { break; } default: { - Log.e(LOG_TAG, "Unknown Email type: " + typeAsPrimitive); - typeAsString = DEFAULT_EMAIL_TYPE; + Log.e(LOG_TAG, "Unknown Email type: " + type); + typeAsString = null; break; } } - builder.append(VCARD_ATTR_SEPARATOR); - appendTypeAttribute(builder, typeAsString); - builder.append(VCARD_DATA_SEPARATOR); - builder.append(data); - builder.append(VCARD_COL_SEPARATOR); + final List<String> attributeList = new ArrayList<String>(); + if (isPrimary) { + attributeList.add(Constants.ATTR_TYPE_PREF); + } + if (!TextUtils.isEmpty(typeAsString)) { + attributeList.add(typeAsString); + } + + appendVCardLineWithCharsetAndQPDetection(builder, Constants.PROPERTY_EMAIL, + attributeList, rawData); } private void appendVCardTelephoneLine(final StringBuilder builder, final Integer typeAsObject, final String label, - String encodedData) { - builder.append(VCARD_PROPERTY_TEL); + final String encodedData, boolean isPrimary) { + builder.append(Constants.PROPERTY_TEL); builder.append(VCARD_ATTR_SEPARATOR); final int typeAsPrimitive; @@ -1753,53 +1849,102 @@ public class VCardComposer { typeAsPrimitive = typeAsObject; } + ArrayList<String> attributeList = new ArrayList<String>(); switch (typeAsPrimitive) { case Phone.TYPE_HOME: - appendTypeAttributes(builder, Arrays.asList( - Constants.ATTR_TYPE_HOME, Constants.ATTR_TYPE_VOICE)); + attributeList.addAll( + Arrays.asList(Constants.ATTR_TYPE_HOME, Constants.ATTR_TYPE_VOICE)); break; case Phone.TYPE_WORK: - appendTypeAttributes(builder, Arrays.asList( - Constants.ATTR_TYPE_WORK, Constants.ATTR_TYPE_VOICE)); + attributeList.addAll( + Arrays.asList(Constants.ATTR_TYPE_WORK, Constants.ATTR_TYPE_VOICE)); break; case Phone.TYPE_FAX_HOME: - appendTypeAttributes(builder, Arrays.asList( - Constants.ATTR_TYPE_HOME, Constants.ATTR_TYPE_FAX)); + attributeList.addAll( + Arrays.asList(Constants.ATTR_TYPE_HOME, Constants.ATTR_TYPE_FAX)); break; case Phone.TYPE_FAX_WORK: - appendTypeAttributes(builder, Arrays.asList( - Constants.ATTR_TYPE_WORK, Constants.ATTR_TYPE_FAX)); + attributeList.addAll( + Arrays.asList(Constants.ATTR_TYPE_WORK, Constants.ATTR_TYPE_FAX)); break; case Phone.TYPE_MOBILE: - builder.append(Constants.ATTR_TYPE_CELL); + attributeList.add(Constants.ATTR_TYPE_CELL); break; case Phone.TYPE_PAGER: if (mIsDoCoMo) { // Not sure about the reason, but previous implementation had // used "VOICE" instead of "PAGER" - // Also, refrain from using appendType() so that "TYPE=" is never be appended. - builder.append(Constants.ATTR_TYPE_VOICE); + attributeList.add(Constants.ATTR_TYPE_VOICE); } else { - appendTypeAttribute(builder, Constants.ATTR_TYPE_PAGER); + attributeList.add(Constants.ATTR_TYPE_PAGER); } break; case Phone.TYPE_OTHER: - appendTypeAttribute(builder, Constants.ATTR_TYPE_VOICE); + attributeList.add(Constants.ATTR_TYPE_VOICE); + break; + case Phone.TYPE_CAR: + attributeList.add(Constants.ATTR_TYPE_CAR); + break; + case Phone.TYPE_COMPANY_MAIN: + // There's no relevant field in vCard (at least 2.1). + attributeList.add(Constants.ATTR_TYPE_WORK); + isPrimary = true; + break; + case Phone.TYPE_ISDN: + attributeList.add(Constants.ATTR_TYPE_ISDN); + break; + case Phone.TYPE_MAIN: + isPrimary = true; + break; + case Phone.TYPE_OTHER_FAX: + attributeList.add(Constants.ATTR_TYPE_FAX); + break; + case Phone.TYPE_TELEX: + attributeList.add(Constants.ATTR_TYPE_TLX); + break; + case Phone.TYPE_WORK_MOBILE: + attributeList.addAll( + Arrays.asList(Constants.ATTR_TYPE_WORK, Constants.ATTR_TYPE_CELL)); + break; + case Phone.TYPE_WORK_PAGER: + attributeList.add(Constants.ATTR_TYPE_WORK); + // See above. + if (mIsDoCoMo) { + attributeList.add(Constants.ATTR_TYPE_VOICE); + } else { + attributeList.add(Constants.ATTR_TYPE_PAGER); + } + break; + case Phone.TYPE_MMS: + attributeList.add(Constants.ATTR_TYPE_MSG); break; case Phone.TYPE_CUSTOM: if (mUsesAndroidProperty && !TextUtils.isEmpty(label) && VCardUtils.containsOnlyAlphaDigitHyphen(label)) { - appendTypeAttribute(builder, "X-" + label); + // Note: Strictly, vCard 2.1 does not allow "X-" attribute without + // "TYPE=" string. + attributeList.add("X-" + label); } else { // Just ignore the custom type. - appendTypeAttribute(builder, Constants.ATTR_TYPE_VOICE); + attributeList.add(Constants.ATTR_TYPE_VOICE); } break; + case Phone.TYPE_RADIO: + case Phone.TYPE_TTY_TDD: default: - appendUncommonPhoneType(builder, typeAsPrimitive); break; } + if (isPrimary) { + attributeList.add(Constants.ATTR_TYPE_PREF); + } + + if (attributeList.isEmpty()) { + appendUncommonPhoneType(builder, typeAsPrimitive); + } else { + appendTypeAttributes(builder, attributeList); + } + builder.append(VCARD_DATA_SEPARATOR); builder.append(encodedData); builder.append(VCARD_COL_SEPARATOR); @@ -1823,15 +1968,43 @@ public class VCardComposer { } } + private void appendVCardLineWithCharsetAndQPDetection(final StringBuilder builder, + final String propertyName, final String rawData) { + appendVCardLineWithCharsetAndQPDetection(builder, propertyName, null, rawData); + } + + private void appendVCardLineWithCharsetAndQPDetection(final StringBuilder builder, + final String propertyName, + final List<String> attributeList, final String rawData) { + final boolean needCharset = + (mUsesQuotedPrintable && !VCardUtils.containsOnlyPrintableAscii(rawData)); + final boolean reallyUseQuotedPrintable = + !VCardUtils.containsOnlyNonCrLfPrintableAscii(rawData); + appendVCardLine(builder, propertyName, attributeList, + rawData, needCharset, reallyUseQuotedPrintable); + } + private void appendVCardLine(final StringBuilder builder, final String propertyName, final String rawData) { appendVCardLine(builder, propertyName, rawData, false, false); } private void appendVCardLine(final StringBuilder builder, - final String field, final String rawData, final boolean needCharset, + final String propertyName, final String rawData, final boolean needCharset, + boolean needQuotedPrintable) { + appendVCardLine(builder, propertyName, null, rawData, needCharset, needQuotedPrintable); + } + + private void appendVCardLine(final StringBuilder builder, + final String propertyName, + final List<String> attributeList, + final String rawData, final boolean needCharset, boolean needQuotedPrintable) { - builder.append(field); + builder.append(propertyName); + if (attributeList != null && attributeList.size() > 0) { + builder.append(VCARD_ATTR_SEPARATOR); + appendTypeAttributes(builder, attributeList); + } if (needCharset) { builder.append(VCARD_ATTR_SEPARATOR); builder.append(mVCardAttributeCharset); @@ -1853,6 +2026,9 @@ public class VCardComposer { builder.append(VCARD_COL_SEPARATOR); } + /** + * VCARD_ATTR_SEPARATOR must be appended before this method being called. + */ private void appendTypeAttributes(final StringBuilder builder, final List<String> types) { // We may have to make this comma separated form like "TYPE=DOM,WORK" in the future, @@ -1868,9 +2044,15 @@ public class VCardComposer { } } + /** + * VCARD_ATTR_SEPARATOR must be appended before this method being called. + */ private void appendTypeAttribute(final StringBuilder builder, final String type) { + // Refrain from using appendType() so that "TYPE=" is not be appended when the + // device is DoCoMo's (just for safety). + // // Note: In vCard 3.0, Type strings also can be like this: "TYPE=HOME,PREF" - if (mIsV30) { + if ((mIsV30 || mAppendTypeParamName) && !mIsDoCoMo) { builder.append(Constants.ATTR_TYPE).append(VCARD_ATTR_EQUAL); } builder.append(type); @@ -1961,4 +2143,116 @@ public class VCardComposer { return tmpBuilder.toString(); } + + //// The methods bellow are for call log history //// + + /** + * This static function is to compose vCard for phone own number + */ + public String composeVCardForPhoneOwnNumber(int phonetype, String phoneName, + String phoneNumber, boolean vcardVer21) { + final StringBuilder builder = new StringBuilder(); + appendVCardLine(builder, Constants.PROPERTY_BEGIN, VCARD_DATA_VCARD); + if (!vcardVer21) { + appendVCardLine(builder, Constants.PROPERTY_VERSION, Constants.VERSION_V30); + } else { + appendVCardLine(builder, Constants.PROPERTY_VERSION, Constants.VERSION_V21); + } + + boolean needCharset = false; + if (!(VCardUtils.containsOnlyPrintableAscii(phoneName))) { + needCharset = true; + } + appendVCardLine(builder, Constants.PROPERTY_FN, phoneName, needCharset, false); + appendVCardLine(builder, Constants.PROPERTY_N, phoneName, needCharset, false); + + String label = Integer.toString(phonetype); + appendVCardTelephoneLine(builder, phonetype, label, phoneNumber, false); + + appendVCardLine(builder, Constants.PROPERTY_END, VCARD_DATA_VCARD); + + return builder.toString(); + } + + /** + * Format according to RFC 2445 DATETIME type. + * The format is: ("%Y%m%dT%H%M%SZ"). + */ + private final String toRfc2455Format(final long millSecs) { + Time startDate = new Time(); + startDate.set(millSecs); + String date = startDate.format2445(); + return date + FLAG_TIMEZONE_UTC; + } + + /** + * Try to append the property line for a call history time stamp field if possible. + * Do nothing if the call log type gotton from the database is invalid. + */ + private void tryAppendCallHistoryTimeStampField(final StringBuilder builder) { + // Extension for call history as defined in + // in the Specification for Ic Mobile Communcation - ver 1.1, + // Oct 2000. This is used to send the details of the call + // history - missed, incoming, outgoing along with date and time + // to the requesting device (For example, transferring phone book + // when connected over bluetooth) + // + // e.g. "X-IRMC-CALL-DATETIME;MISSED:20050320T100000Z" + final int callLogType = mCursor.getInt(CALL_TYPE_COLUMN_INDEX); + final String callLogTypeStr; + switch (callLogType) { + case Calls.INCOMING_TYPE: { + callLogTypeStr = VCARD_PROPERTY_CALLTYPE_INCOMING; + break; + } + case Calls.OUTGOING_TYPE: { + callLogTypeStr = VCARD_PROPERTY_CALLTYPE_OUTGOING; + break; + } + case Calls.MISSED_TYPE: { + callLogTypeStr = VCARD_PROPERTY_CALLTYPE_MISSED; + break; + } + default: { + Log.w(LOG_TAG, "Call log type not correct."); + return; + } + } + + final long dateAsLong = mCursor.getLong(DATE_COLUMN_INDEX); + builder.append(VCARD_PROPERTY_X_TIMESTAMP); + builder.append(VCARD_ATTR_SEPARATOR); + appendTypeAttribute(builder, callLogTypeStr); + builder.append(VCARD_DATA_SEPARATOR); + builder.append(toRfc2455Format(dateAsLong)); + builder.append(VCARD_COL_SEPARATOR); + } + + private String createOneCallLogEntryInternal() { + final StringBuilder builder = new StringBuilder(); + appendVCardLine(builder, Constants.PROPERTY_BEGIN, VCARD_DATA_VCARD); + if (mIsV30) { + appendVCardLine(builder, Constants.PROPERTY_VERSION, Constants.VERSION_V30); + } else { + appendVCardLine(builder, Constants.PROPERTY_VERSION, Constants.VERSION_V21); + } + String name = mCursor.getString(CALLER_NAME_COLUMN_INDEX); + if (TextUtils.isEmpty(name)) { + name = mCursor.getString(NUMBER_COLUMN_INDEX); + } + final boolean needCharset = !(VCardUtils.containsOnlyPrintableAscii(name)); + appendVCardLine(builder, Constants.PROPERTY_FN, name, needCharset, false); + appendVCardLine(builder, Constants.PROPERTY_N, name, needCharset, false); + + String number = mCursor.getString(NUMBER_COLUMN_INDEX); + int type = mCursor.getInt(CALLER_NUMBERTYPE_COLUMN_INDEX); + String label = mCursor.getString(CALLER_NUMBERLABEL_COLUMN_INDEX); + if (TextUtils.isEmpty(label)) { + label = Integer.toString(type); + } + appendVCardTelephoneLine(builder, type, label, number, false); + tryAppendCallHistoryTimeStampField(builder); + appendVCardLine(builder, Constants.PROPERTY_END, VCARD_DATA_VCARD); + return builder.toString(); + } } diff --git a/core/java/android/pim/vcard/VCardConfig.java b/core/java/android/pim/vcard/VCardConfig.java index 68cd0df..9581c74 100644 --- a/core/java/android/pim/vcard/VCardConfig.java +++ b/core/java/android/pim/vcard/VCardConfig.java @@ -15,14 +15,20 @@ */ package android.pim.vcard; +import android.util.Log; + import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; /** * The class representing VCard related configurations. Useful static methods are not in this class * but in VCardUtils. */ public class VCardConfig { + private static final String LOG_TAG = "vcard.VCardConfig"; + // TODO: may be better to make the instance of this available and stop using static methods and // one integer. @@ -41,8 +47,8 @@ public class VCardConfig { // TODO: make the other codes use this flag public static final boolean IGNORE_CASE_EXCEPT_VALUE = true; - private static final int FLAG_V21 = 0; - private static final int FLAG_V30 = 1; + public static final int FLAG_V21 = 0; + public static final int FLAG_V30 = 1; // 0x2 is reserved for the future use ... @@ -95,96 +101,187 @@ public class VCardConfig { private static final int FLAG_DOCOMO = 0x20000000; /** - * The flag indicating the vCard composer use Quoted-Printable toward even "primary" types. - * In this context, "primary" types means "N", "FN", etc. which are usually "not" encoded - * into Quoted-Printable format in external exporters. - * This flag is useful when some target importer does not accept "primary" property values - * without Quoted-Printable encoding. + * <P> + * The flag indicating the vCard composer does "NOT" use Quoted-Printable toward "primary" + * properties even though it is required by vCard 2.1 (QP is prohibited in vCard 3.0). + * </P> + * <P> + * We actually cannot define what is the "primary" property. Note that this is NOT defined + * in vCard specification either. Also be aware that it is NOT related to "primary" notion + * used in {@link android.provider.ContactsContract}. + * This notion is just for vCard composition in Android. + * </P> + * <P> + * We added this Android-specific notion since some (incomplete) vCard exporters for vCard 2.1 + * do NOT use Quoted-Printable encoding toward some properties like "N", "FN", etc. even when + * their values contain non-ascii or/and CR/LF, while they use the encoding in the other + * properties like "ADR", "ORG", etc. + * <P> + * We are afraid of the case where some vCard importer also forget handling QP presuming QP is + * not used in such fields. + * </P> + * <P> + * This flag is useful when some target importer you are going to focus on does not accept + * such "primary" property values with Quoted-Printable encoding. + * </P> + * <P> + * Again, we should not use this flag at all for complying vCard 2.1 spec. + * </P> + * <P> + * We will change the behavior around this flag in the future, after understanding the other + * real vCard cases around this problem. Please use this flag with extreme caution even when + * needed. + * </P> + * <P> + * In vCard 3.0, Quoted-Printable is explicitly "prohibitted", so we don't need to care this + * kind of problem (hopefully). + * </P> + */ + public static final int FLAG_REFRAIN_QP_TO_PRIMARY_PROPERTIES = 0x10000000; + + /** + * <P> + * The flag indicating that phonetic name related fields must be converted to + * appropriate form. Note that "appropriate" is not defined in any vCard specification. + * This is Android-specific. + * </P> + * <P> + * One typical (and currently sole) example where we need this flag is the time when + * we need to emit Japanese phonetic names into vCard entries. The property values + * should be encoded into half-width katakana when the target importer is Japanese mobile + * phones', which are probably not able to parse full-width hiragana/katakana for + * historical reasons, while the vCard importers embedded to softwares for PC should be + * able to parse them as we expect. + * </P> + */ + public static final int FLAG_CONVERT_PHONETIC_NAME_STRINGS = 0x0800000; + + /** + * <P> + * The flag indicating the vCard composer "for 2.1" emits "TYPE=" string every time + * possible. The default behavior does not emit it and is valid, while adding "TYPE=" + * is also valid. In vCrad 3.0, this flag is unnecessary, since "TYPE=" is MUST in + * vCard 3.0 specification. + * + * If you are targeting to some importer which cannot accept type attributes (params) + * without "TYPE=" string (which should be rare though), please use this flag. * - * @hide Temporaly made public. We don't strictly define "primary", so we may change the - * behavior around this flag in the future. Do not use this flag without any reason. + * XXX: Really rare? + * + * e.g. int vcardType = (VCARD_TYPE_V21_GENERIC | FLAG_APPEND_TYPE_PARAM); */ - public static final int FLAG_USE_QP_TO_PRIMARY_PROPERTIES = 0x10000000; - - // VCard types + public static final int FLAG_APPEND_TYPE_PARAM = 0x04000000; + + //// The followings are VCard types available from importer/exporter. //// /** + * <P> * General vCard format with the version 2.1. Uses UTF-8 for the charset. - * When composing a vCard entry, the US convension will be used. - * + * When composing a vCard entry, the US convension will be used toward formatting + * some values + * </P> + * <P> * e.g. The order of the display name would be "Prefix Given Middle Family Suffix", - * while in Japan, it should be "Prefix Family Middle Given Suffix". + * while it should be "Prefix Family Middle Given Suffix" in Japan. + * </P> */ - public static final int VCARD_TYPE_V21_GENERIC = + public static final int VCARD_TYPE_V21_GENERIC_UTF8 = (FLAG_V21 | NAME_ORDER_DEFAULT | FLAG_CHARSET_UTF8 | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); - /* package */ static String VCARD_TYPE_V21_GENERIC_STR = "v21_generic"; + /* package */ static String VCARD_TYPE_V21_GENERIC_UTF8_STR = "v21_generic"; /** + * <P> * General vCard format with the version 3.0. Uses UTF-8 for the charset. - * - * Note that this type is not fully implemented, so probably some bugs remain both in - * parsing and composing. - * - * TODO: implement this type correctly. + * </P> + * <P> + * Not ready yet. Use with caution when you use this. + * </P> */ - public static final int VCARD_TYPE_V30_GENERIC = + public static final int VCARD_TYPE_V30_GENERIC_UTF8 = (FLAG_V30 | NAME_ORDER_DEFAULT | FLAG_CHARSET_UTF8 | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); - /* package */ static final String VCARD_TYPE_V30_GENERIC_STR = "v30_generic"; + /* package */ static final String VCARD_TYPE_V30_GENERIC_UTF8_STR = "v30_generic"; /** - * General vCard format with the version 2.1 with some Europe convension. Uses Utf-8. + * <P> + * General vCard format for the vCard 2.1 with some Europe convension. Uses Utf-8. * Currently, only name order is considered ("Prefix Middle Given Family Suffix") + * </P> */ - public static final int VCARD_TYPE_V21_EUROPE = + public static final int VCARD_TYPE_V21_EUROPE_UTF8 = (FLAG_V21 | NAME_ORDER_EUROPE | FLAG_CHARSET_UTF8 | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); - /* package */ static final String VCARD_TYPE_V21_EUROPE_STR = "v21_europe"; + /* package */ static final String VCARD_TYPE_V21_EUROPE_UTF8_STR = "v21_europe"; /** + * <P> * General vCard format with the version 3.0 with some Europe convension. Uses UTF-8 + * </P> + * <P> + * Not ready yet. Use with caution when you use this. + * </P> */ - public static final int VCARD_TYPE_V30_EUROPE = + public static final int VCARD_TYPE_V30_EUROPE_UTF8 = (FLAG_V30 | NAME_ORDER_EUROPE | FLAG_CHARSET_UTF8 | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); /* package */ static final String VCARD_TYPE_V30_EUROPE_STR = "v30_europe"; - - /** - * vCard 2.1 format for miscellaneous Japanese devices. Shift_Jis is used for - * parsing/composing the vCard data. - */ - public static final int VCARD_TYPE_V21_JAPANESE = - (FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS | - FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); - /* package */ static final String VCARD_TYPE_V21_JAPANESE_STR = "v21_japanese"; - /** - * vCard 2.1 format for miscellaneous Japanese devices, using UTF-8 as default charset. + * <P> + * The vCard 2.1 format for miscellaneous Japanese devices, using UTF-8 as default charset. + * </P> + * <P> + * Not ready yet. Use with caution when you use this. + * </P> */ public static final int VCARD_TYPE_V21_JAPANESE_UTF8 = (FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_UTF8 | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); /* package */ static final String VCARD_TYPE_V21_JAPANESE_UTF8_STR = "v21_japanese_utf8"; + + /** + * <P> + * vCard 2.1 format for miscellaneous Japanese devices. Shift_Jis is used for + * parsing/composing the vCard data. + * </P> + * <P> + * Not ready yet. Use with caution when you use this. + * </P> + */ + public static final int VCARD_TYPE_V21_JAPANESE_SJIS = + (FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS | + FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); + + /* package */ static final String VCARD_TYPE_V21_JAPANESE_SJIS_STR = "v21_japanese_sjis"; /** + * <P> * vCard format for miscellaneous Japanese devices, using Shift_Jis for * parsing/composing the vCard data. + * </P> + * <P> + * Not ready yet. Use with caution when you use this. + * </P> */ - public static final int VCARD_TYPE_V30_JAPANESE = + public static final int VCARD_TYPE_V30_JAPANESE_SJIS = (FLAG_V30 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); - /* package */ static final String VCARD_TYPE_V30_JAPANESE_STR = "v30_japanese"; + /* package */ static final String VCARD_TYPE_V30_JAPANESE_SJIS_STR = "v30_japanese_sjis"; /** - * vCard 3.0 format for miscellaneous Japanese devices, using UTF-8 as default charset. + * <P> + * The vCard 3.0 format for miscellaneous Japanese devices, using UTF-8 as default charset. + * </P> + * <P> + * Not ready yet. Use with caution when you use this. + * </P> */ public static final int VCARD_TYPE_V30_JAPANESE_UTF8 = (FLAG_V30 | NAME_ORDER_JAPANESE | FLAG_CHARSET_UTF8 | @@ -193,38 +290,72 @@ public class VCardConfig { /* package */ static final String VCARD_TYPE_V30_JAPANESE_UTF8_STR = "v30_japanese_utf8"; /** - * VCard format used in DoCoMo, which is one of Japanese mobile phone careers. - * Base version is vCard 2.1, but the data has several DoCoMo-specific convensions. - * No Android-specific property nor defact property is included. + * <P> + * The vCard 2.1 based format which (partially) considers the convention in Japanese + * mobile phones, where phonetic names are translated to half-width katakana if + * possible, etc. + * </P> + * <P> + * Not ready yet. Use with caution when you use this. + * </P> + */ + public static final int VCARD_TYPE_V21_JAPANESE_MOBILE = + (FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS | + FLAG_CONVERT_PHONETIC_NAME_STRINGS | + FLAG_REFRAIN_QP_TO_PRIMARY_PROPERTIES); + + public static final String VCARD_TYPE_V21_JAPANESE_MOBILE_STR = "v21_japanese_mobile"; + + /** + * <P> + * VCard format used in DoCoMo, which is one of Japanese mobile phone careers. + * </p> + * <P> + * Base version is vCard 2.1, but the data has several DoCoMo-specific convensions. + * No Android-specific property nor defact property is included. The "Primary" properties + * are NOT encoded to Quoted-Printable. + * </P> */ public static final int VCARD_TYPE_DOCOMO = - (FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS | FLAG_DOCOMO); + (VCARD_TYPE_V21_JAPANESE_MOBILE | FLAG_DOCOMO); private static final String VCARD_TYPE_DOCOMO_STR = "docomo"; - public static int VCARD_TYPE_DEFAULT = VCARD_TYPE_V21_GENERIC; + public static int VCARD_TYPE_DEFAULT = VCARD_TYPE_V21_GENERIC_UTF8; - private static final Map<String, Integer> VCARD_TYPES_MAP; + private static final Map<String, Integer> sVCardTypeMap; + private static final Set<Integer> sJapaneseMobileTypeSet; static { - VCARD_TYPES_MAP = new HashMap<String, Integer>(); - VCARD_TYPES_MAP.put(VCARD_TYPE_V21_GENERIC_STR, VCARD_TYPE_V21_GENERIC); - VCARD_TYPES_MAP.put(VCARD_TYPE_V30_GENERIC_STR, VCARD_TYPE_V30_GENERIC); - VCARD_TYPES_MAP.put(VCARD_TYPE_V21_EUROPE_STR, VCARD_TYPE_V21_EUROPE); - VCARD_TYPES_MAP.put(VCARD_TYPE_V30_EUROPE_STR, VCARD_TYPE_V30_EUROPE); - VCARD_TYPES_MAP.put(VCARD_TYPE_V21_JAPANESE_STR, VCARD_TYPE_V21_JAPANESE); - VCARD_TYPES_MAP.put(VCARD_TYPE_V21_JAPANESE_UTF8_STR, VCARD_TYPE_V21_JAPANESE_UTF8); - VCARD_TYPES_MAP.put(VCARD_TYPE_V30_JAPANESE_STR, VCARD_TYPE_V30_JAPANESE); - VCARD_TYPES_MAP.put(VCARD_TYPE_V30_JAPANESE_UTF8_STR, VCARD_TYPE_V30_JAPANESE_UTF8); - VCARD_TYPES_MAP.put(VCARD_TYPE_DOCOMO_STR, VCARD_TYPE_DOCOMO); + sVCardTypeMap = new HashMap<String, Integer>(); + sVCardTypeMap.put(VCARD_TYPE_V21_GENERIC_UTF8_STR, VCARD_TYPE_V21_GENERIC_UTF8); + sVCardTypeMap.put(VCARD_TYPE_V30_GENERIC_UTF8_STR, VCARD_TYPE_V30_GENERIC_UTF8); + sVCardTypeMap.put(VCARD_TYPE_V21_EUROPE_UTF8_STR, VCARD_TYPE_V21_EUROPE_UTF8); + sVCardTypeMap.put(VCARD_TYPE_V30_EUROPE_STR, VCARD_TYPE_V30_EUROPE_UTF8); + sVCardTypeMap.put(VCARD_TYPE_V21_JAPANESE_SJIS_STR, VCARD_TYPE_V21_JAPANESE_SJIS); + sVCardTypeMap.put(VCARD_TYPE_V21_JAPANESE_UTF8_STR, VCARD_TYPE_V21_JAPANESE_UTF8); + sVCardTypeMap.put(VCARD_TYPE_V30_JAPANESE_SJIS_STR, VCARD_TYPE_V30_JAPANESE_SJIS); + sVCardTypeMap.put(VCARD_TYPE_V30_JAPANESE_UTF8_STR, VCARD_TYPE_V30_JAPANESE_UTF8); + sVCardTypeMap.put(VCARD_TYPE_V21_JAPANESE_MOBILE_STR, VCARD_TYPE_V21_JAPANESE_MOBILE); + sVCardTypeMap.put(VCARD_TYPE_DOCOMO_STR, VCARD_TYPE_DOCOMO); + + sJapaneseMobileTypeSet = new HashSet<Integer>(); + sJapaneseMobileTypeSet.add(VCARD_TYPE_V21_JAPANESE_SJIS); + sJapaneseMobileTypeSet.add(VCARD_TYPE_V21_JAPANESE_UTF8); + sJapaneseMobileTypeSet.add(VCARD_TYPE_V21_JAPANESE_SJIS); + sJapaneseMobileTypeSet.add(VCARD_TYPE_V30_JAPANESE_SJIS); + sJapaneseMobileTypeSet.add(VCARD_TYPE_V30_JAPANESE_UTF8); + sJapaneseMobileTypeSet.add(VCARD_TYPE_V21_JAPANESE_MOBILE); + sJapaneseMobileTypeSet.add(VCARD_TYPE_DOCOMO); } public static int getVCardTypeFromString(String vcardTypeString) { String loweredKey = vcardTypeString.toLowerCase(); - if (VCARD_TYPES_MAP.containsKey(loweredKey)) { - return VCARD_TYPES_MAP.get(loweredKey); + if (sVCardTypeMap.containsKey(loweredKey)) { + return sVCardTypeMap.get(loweredKey); } else { // XXX: should return the value indicating the input is invalid? + Log.e(LOG_TAG, "Unknown vCard type String: \"" + vcardTypeString + "\""); return VCARD_TYPE_DEFAULT; } } @@ -237,22 +368,6 @@ public class VCardConfig { return !isV30(vcardType); } - public static boolean isDoCoMo(int vcardType) { - return ((vcardType & FLAG_DOCOMO) != 0); - } - - /** - * @return true if the device is Japanese and some Japanese convension is - * applied to creating "formatted" something like FORMATTED_ADDRESS. - */ - public static boolean isJapaneseDevice(int vcardType) { - return ((vcardType == VCARD_TYPE_V21_JAPANESE) || - (vcardType == VCARD_TYPE_V21_JAPANESE_UTF8) || - (vcardType == VCARD_TYPE_V30_JAPANESE) || - (vcardType == VCARD_TYPE_V30_JAPANESE_UTF8) || - (vcardType == VCARD_TYPE_DOCOMO)); - } - public static boolean usesUtf8(int vcardType) { return ((vcardType & FLAG_CHARSET_UTF8) != 0); } @@ -261,17 +376,6 @@ public class VCardConfig { return ((vcardType & FLAG_CHARSET_SHIFT_JIS) != 0); } - /** - * @return true when Japanese phonetic string must be converted to a string - * containing only half-width katakana. This method exists since Japanese mobile - * phones usually use only half-width katakana for expressing phonetic names and - * some devices are not ready for parsing other phonetic strings like hiragana and - * full-width katakana. - */ - public static boolean needsToConvertPhoneticString(int vcardType) { - return (vcardType == VCARD_TYPE_DOCOMO); - } - public static int getNameOrderType(int vcardType) { return vcardType & NAME_ORDER_MASK; } @@ -284,20 +388,37 @@ public class VCardConfig { return ((vcardType & FLAG_USE_DEFACT_PROPERTY) != 0); } - public static boolean onlyOneNoteFieldIsAvailable(int vcardType) { - return vcardType == VCARD_TYPE_DOCOMO; - } - public static boolean showPerformanceLog() { return (VCardConfig.LOG_LEVEL & VCardConfig.LOG_LEVEL_PERFORMANCE_MEASUREMENT) != 0; } + public static boolean refrainsQPToPrimaryProperties(int vcardType) { + return (!usesQuotedPrintable(vcardType) || + ((vcardType & FLAG_REFRAIN_QP_TO_PRIMARY_PROPERTIES) != 0)); + } + + public static boolean appendTypeParamName(int vcardType) { + return (isV30(vcardType) || ((vcardType & FLAG_APPEND_TYPE_PARAM) != 0)); + } + /** - * @hide + * @return true if the device is Japanese and some Japanese convension is + * applied to creating "formatted" something like FORMATTED_ADDRESS. */ - public static boolean usesQPToPrimaryProperties(int vcardType) { - return (usesQuotedPrintable(vcardType) && - ((vcardType & FLAG_USE_QP_TO_PRIMARY_PROPERTIES) != 0)); + public static boolean isJapaneseDevice(int vcardType) { + return sJapaneseMobileTypeSet.contains(vcardType); + } + + public static boolean needsToConvertPhoneticString(int vcardType) { + return ((vcardType & FLAG_CONVERT_PHONETIC_NAME_STRINGS) != 0); + } + + public static boolean onlyOneNoteFieldIsAvailable(int vcardType) { + return vcardType == VCARD_TYPE_DOCOMO; + } + + public static boolean isDoCoMo(int vcardType) { + return ((vcardType & FLAG_DOCOMO) != 0); } private VCardConfig() { diff --git a/core/java/android/pim/vcard/VCardDataBuilder.java b/core/java/android/pim/vcard/VCardDataBuilder.java index d2026d0..76ad482 100644 --- a/core/java/android/pim/vcard/VCardDataBuilder.java +++ b/core/java/android/pim/vcard/VCardDataBuilder.java @@ -69,7 +69,7 @@ public class VCardDataBuilder implements VCardBuilder { private List<EntryHandler> mEntryHandlers = new ArrayList<EntryHandler>(); public VCardDataBuilder() { - this(null, null, false, VCardConfig.VCARD_TYPE_V21_GENERIC, null); + this(null, null, false, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8, null); } /** @@ -86,7 +86,7 @@ public class VCardDataBuilder implements VCardBuilder { boolean strictLineBreakParsing, int vcardType, Account account) { this(null, charset, strictLineBreakParsing, vcardType, account); } - + /** * @hide */ @@ -127,6 +127,18 @@ public class VCardDataBuilder implements VCardBuilder { } /** + * Called when the parse failed between startRecord() and endRecord(). + * Currently it happens only when the vCard format is 3.0. + * (VCardVersionException is thrown by VCardParser_V21 and this object is reused by + * VCardParser_V30. At that time, startRecord() is called twice before endRecord() is called.) + * TODO: Should this be in VCardBuilder interface? + */ + public void clear() { + mCurrentContactStruct = null; + mCurrentProperty = new ContactStruct.Property(); + } + + /** * Assume that VCard is not nested. In other words, this code does not accept */ public void startRecord(String type) { diff --git a/core/java/android/pim/vcard/VCardParser_V21.java b/core/java/android/pim/vcard/VCardParser_V21.java index 974fca8..b3ff8fa 100644 --- a/core/java/android/pim/vcard/VCardParser_V21.java +++ b/core/java/android/pim/vcard/VCardParser_V21.java @@ -144,10 +144,14 @@ public class VCardParser_V21 extends VCardParser { } } - protected String getVersion() { - return "2.1"; + protected int getVersion() { + return VCardConfig.FLAG_V21; } - + + protected String getVersionString() { + return Constants.VERSION_V21; + } + /** * @return true when the propertyName is a valid property name. */ @@ -356,7 +360,7 @@ public class VCardParser_V21 extends VCardParser { * / [groups "."] "ADR" [params] ":" addressparts CRLF * / [groups "."] "ORG" [params] ":" orgparts CRLF * / [groups "."] "N" [params] ":" nameparts CRLF - * / [groups "."] "AGENT" [params] ":" vcard CRLF + * / [groups "."] "AGENT" [params] ":" vcard CRLF */ protected boolean parseItem() throws IOException, VCardException { mEncoding = sDefaultEncoding; @@ -392,9 +396,10 @@ public class VCardParser_V21 extends VCardParser { } else { throw new VCardException("Unknown BEGIN type: " + propertyValue); } - } else if (propertyName.equals("VERSION") && !propertyValue.equals(getVersion())) { + } else if (propertyName.equals("VERSION") && + !propertyValue.equals(getVersionString())) { throw new VCardVersionException("Incompatible version: " + - propertyValue + " != " + getVersion()); + propertyValue + " != " + getVersionString()); } start = System.currentTimeMillis(); handlePropertyValue(propertyName, propertyValue); @@ -520,11 +525,19 @@ public class VCardParser_V21 extends VCardParser { throw new VCardException("Unknown type \"" + paramName + "\""); } } else { - handleType(strArray[0]); + handleParamWithoutName(strArray[0]); } } /** + * vCard 3.0 parser may throw VCardException. + */ + @SuppressWarnings("unused") + protected void handleParamWithoutName(final String paramValue) throws VCardException { + handleType(paramValue); + } + + /** * ptypeval = knowntype / "X-" word */ protected void handleType(String ptypeval) { @@ -761,32 +774,11 @@ public class VCardParser_V21 extends VCardParser { } if (mBuilder != null) { - StringBuilder builder = new StringBuilder(); - ArrayList<String> list = new ArrayList<String>(); - int length = propertyValue.length(); - for (int i = 0; i < length; i++) { - char ch = propertyValue.charAt(i); - if (ch == '\\' && i < length - 1) { - char nextCh = propertyValue.charAt(i + 1); - String unescapedString = maybeUnescapeCharacter(nextCh); - if (unescapedString != null) { - builder.append(unescapedString); - i++; - } else { - builder.append(ch); - } - } else if (ch == ';') { - list.add(builder.toString()); - builder = new StringBuilder(); - } else { - builder.append(ch); - } - } - list.add(builder.toString()); - mBuilder.propertyValues(list); + mBuilder.propertyValues(VCardUtils.constructListFromValue( + propertyValue, (getVersion() == VCardConfig.FLAG_V30))); } } - + /** * vCard 2.1 specifies AGENT allows one vcard entry. It is not encoded at all. * @@ -819,12 +811,16 @@ public class VCardParser_V21 extends VCardParser { protected String maybeUnescapeText(String text) { return text; } - + /** * Returns unescaped String if the character should be unescaped. Return null otherwise. * e.g. In vCard 2.1, "\;" should be unescaped into ";" while "\x" should not be. */ protected String maybeUnescapeCharacter(char ch) { + return unescapeCharacter(ch); + } + + public static String unescapeCharacter(char ch) { // Original vCard 2.1 specification does not allow transformation // "\:" -> ":", "\," -> ",", and "\\" -> "\", but previous implementation of // this class allowed them, so keep it as is. @@ -844,6 +840,9 @@ public class VCardParser_V21 extends VCardParser { @Override public boolean parse(InputStream is, String charset, VCardBuilder builder) throws IOException, VCardException { + if (charset == null) { + charset = VCardConfig.DEFAULT_CHARSET; + } final InputStreamReader tmpReader = new InputStreamReader(is, charset); if (VCardConfig.showPerformanceLog()) { mReader = new CustomBufferedReader(tmpReader); diff --git a/core/java/android/pim/vcard/VCardParser_V30.java b/core/java/android/pim/vcard/VCardParser_V30.java index 384649a..86e7625 100644 --- a/core/java/android/pim/vcard/VCardParser_V30.java +++ b/core/java/android/pim/vcard/VCardParser_V30.java @@ -46,14 +46,42 @@ public class VCardParser_V30 extends VCardParser_V21 { private static final HashSet<String> acceptablePropsWithoutParam = new HashSet<String>(); private String mPreviousLine; - + private boolean mEmittedAgentWarning = false; - + + /** + * True when the caller wants the parser to be strict about the input. + * Currently this is only for testing. + */ + private final boolean mStrictParsing; + + public VCardParser_V30() { + super(); + mStrictParsing = false; + } + + /** + * @param strictParsing when true, this object throws VCardException when the vcard is not + * valid from the view of vCard 3.0 specification (defined in RFC 2426). Note that this class + * is not fully yet for being used with this flag and may not notice invalid line(s). + * + * @hide currently only for testing! + */ + public VCardParser_V30(boolean strictParsing) { + super(); + mStrictParsing = strictParsing; + } + + @Override + protected int getVersion() { + return VCardConfig.FLAG_V30; + } + @Override - protected String getVersion() { + protected String getVersionString() { return Constants.VERSION_V30; } - + @Override protected boolean isValidPropertyName(String propertyName) { if (!(sAcceptablePropsWithParam.contains(propertyName) || @@ -199,7 +227,16 @@ public class VCardParser_V30 extends VCardParser_V21 { // TODO: fix this. super.handleAnyParam(paramName, paramValue); } - + + @Override + protected void handleParamWithoutName(final String paramValue) throws VCardException { + if (mStrictParsing) { + throw new VCardException("Parameter without name is not acceptable in vCard 3.0"); + } else { + super.handleParamWithoutName(paramValue); + } + } + /** * vCard 3.0 defines * @@ -284,6 +321,10 @@ public class VCardParser_V30 extends VCardParser_V21 { */ @Override protected String maybeUnescapeText(String text) { + return unescapeText(text); + } + + public static String unescapeText(String text) { StringBuilder builder = new StringBuilder(); int length = text.length(); for (int i = 0; i < length; i++) { @@ -299,15 +340,19 @@ public class VCardParser_V30 extends VCardParser_V21 { builder.append(ch); } } - return builder.toString(); + return builder.toString(); } @Override protected String maybeUnescapeCharacter(char ch) { + return unescapeCharacter(ch); + } + + public static String unescapeCharacter(char ch) { if (ch == 'n' || ch == 'N') { return "\n"; } else { return String.valueOf(ch); - } + } } } diff --git a/core/java/android/pim/vcard/VCardUtils.java b/core/java/android/pim/vcard/VCardUtils.java index 4f50103..376327c 100644 --- a/core/java/android/pim/vcard/VCardUtils.java +++ b/core/java/android/pim/vcard/VCardUtils.java @@ -18,13 +18,16 @@ package android.pim.vcard; import android.content.ContentProviderOperation; import android.content.ContentValues; import android.provider.ContactsContract.Data; +import android.provider.ContactsContract.CommonDataKinds.Im; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.text.TextUtils; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -41,44 +44,56 @@ public class VCardUtils { // vCard and current (as of 2009-08-07) Contacts structure. private static final Map<Integer, String> sKnownPhoneTypesMap_ItoS; private static final Set<String> sPhoneTypesSetUnknownToContacts; - - private static final Map<String, Integer> sKnownPhoneTypesMap_StoI; - + + private static final Map<String, Integer> sKnownPhoneTypeMap_StoI; + + private static final Map<Integer, String> sKnownImPropNameMap_ItoS; + static { sKnownPhoneTypesMap_ItoS = new HashMap<Integer, String>(); - sKnownPhoneTypesMap_StoI = new HashMap<String, Integer>(); + sKnownPhoneTypeMap_StoI = new HashMap<String, Integer>(); sKnownPhoneTypesMap_ItoS.put(Phone.TYPE_CAR, Constants.ATTR_TYPE_CAR); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_CAR, Phone.TYPE_CAR); + sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_CAR, Phone.TYPE_CAR); sKnownPhoneTypesMap_ItoS.put(Phone.TYPE_PAGER, Constants.ATTR_TYPE_PAGER); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_PAGER, Phone.TYPE_PAGER); + sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_PAGER, Phone.TYPE_PAGER); sKnownPhoneTypesMap_ItoS.put(Phone.TYPE_ISDN, Constants.ATTR_TYPE_ISDN); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_ISDN, Phone.TYPE_ISDN); + sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_ISDN, Phone.TYPE_ISDN); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_HOME, Phone.TYPE_HOME); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_WORK, Phone.TYPE_WORK); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_CELL, Phone.TYPE_MOBILE); + sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_HOME, Phone.TYPE_HOME); + sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_WORK, Phone.TYPE_WORK); + sKnownPhoneTypeMap_StoI.put(Constants.ATTR_TYPE_CELL, Phone.TYPE_MOBILE); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_PHONE_EXTRA_OTHER, Phone.TYPE_OTHER); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_PHONE_EXTRA_CALLBACK, Phone.TYPE_CALLBACK); - sKnownPhoneTypesMap_StoI.put( - Constants.ATTR_TYPE_PHONE_EXTRA_COMPANY_MAIN, Phone.TYPE_COMPANY_MAIN); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_PHONE_EXTRA_RADIO, Phone.TYPE_RADIO); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_PHONE_EXTRA_TELEX, Phone.TYPE_TELEX); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_PHONE_EXTRA_TTY_TDD, Phone.TYPE_TTY_TDD); - sKnownPhoneTypesMap_StoI.put(Constants.ATTR_TYPE_PHONE_EXTRA_ASSISTANT, Phone.TYPE_ASSISTANT); + sKnownPhoneTypeMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_OTHER, Phone.TYPE_OTHER); + sKnownPhoneTypeMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_CALLBACK, Phone.TYPE_CALLBACK); + sKnownPhoneTypeMap_StoI.put( + Constants.ATTR_PHONE_EXTRA_TYPE_COMPANY_MAIN, Phone.TYPE_COMPANY_MAIN); + sKnownPhoneTypeMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_RADIO, Phone.TYPE_RADIO); + sKnownPhoneTypeMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_TTY_TDD, Phone.TYPE_TTY_TDD); + sKnownPhoneTypeMap_StoI.put(Constants.ATTR_PHONE_EXTRA_TYPE_ASSISTANT, + Phone.TYPE_ASSISTANT); sPhoneTypesSetUnknownToContacts = new HashSet<String>(); sPhoneTypesSetUnknownToContacts.add(Constants.ATTR_TYPE_MODEM); - sPhoneTypesSetUnknownToContacts.add(Constants.ATTR_TYPE_MSG); sPhoneTypesSetUnknownToContacts.add(Constants.ATTR_TYPE_BBS); sPhoneTypesSetUnknownToContacts.add(Constants.ATTR_TYPE_VIDEO); + + sKnownImPropNameMap_ItoS = new HashMap<Integer, String>(); + sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_AIM, Constants.PROPERTY_X_AIM); + sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_MSN, Constants.PROPERTY_X_MSN); + sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_YAHOO, Constants.PROPERTY_X_YAHOO); + sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_SKYPE, Constants.PROPERTY_X_SKYPE_USERNAME); + sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_GOOGLE_TALK, Constants.PROPERTY_X_GOOGLE_TALK); + sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_ICQ, Constants.PROPERTY_X_ICQ); + sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_JABBER, Constants.PROPERTY_X_JABBER); + sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_QQ, Constants.PROPERTY_X_QQ); + sKnownImPropNameMap_ItoS.put(Im.PROTOCOL_NETMEETING, Constants.PROPERTY_X_NETMEETING); } - + public static String getPhoneAttributeString(Integer type) { return sKnownPhoneTypesMap_ItoS.get(type); } - + /** * Returns Interger when the given types can be parsed as known type. Returns String object * when not, which should be set to label. @@ -100,7 +115,7 @@ public class VCardUtils { if (typeString.startsWith("X-") && type < 0) { typeString = typeString.substring(2); } - Integer tmp = sKnownPhoneTypesMap_StoI.get(typeString); + Integer tmp = sKnownPhoneTypeMap_StoI.get(typeString); if (tmp != null) { type = tmp; } else if (type < 0) { @@ -133,7 +148,11 @@ public class VCardUtils { return type; } } - + + public static String getPropertyNameForIm(int protocol) { + return sKnownImPropNameMap_ItoS.get(protocol); + } + public static boolean isValidPhoneAttribute(String phoneAttribute, int vcardType) { // TODO: check the following. // - it may violate vCard spec @@ -187,7 +206,10 @@ public class VCardUtils { } builder.withValue(StructuredPostal.POBOX, postalData.pobox); - // Extended address is dropped since there's no relevant entry in ContactsContract. + // TODO: Japanese phone seems to use this field for expressing all the address including + // region, city, etc. Not sure we're ok to store them into NEIGHBORHOOD, while it would be + // better than dropping them all. + builder.withValue(StructuredPostal.NEIGHBORHOOD, postalData.extendedAddress); builder.withValue(StructuredPostal.STREET, postalData.street); builder.withValue(StructuredPostal.CITY, postalData.localty); builder.withValue(StructuredPostal.REGION, postalData.region); @@ -200,12 +222,12 @@ public class VCardUtils { builder.withValue(Data.IS_PRIMARY, 1); } } - + /** * Returns String[] containing address information based on vCard spec * (PO Box, Extended Address, Street, Locality, Region, Postal Code, Country Name). * All String objects are non-null ("" is used when the relevant data is empty). - * + * * Note that the data structure of ContactsContract is different from that defined in vCard. * So some conversion may be performed in this method. See also * {{@link #insertStructuredPostalDataUsingContactsStruct(int, @@ -213,13 +235,20 @@ public class VCardUtils { * android.pim.vcard.ContactStruct.PostalData)} */ public static String[] getVCardPostalElements(ContentValues contentValues) { + // adr-value = 0*6(text-value ";") text-value + // ; PO Box, Extended Address, Street, Locality, Region, Postal + // ; Code, Country Name String[] dataArray = new String[7]; dataArray[0] = contentValues.getAsString(StructuredPostal.POBOX); if (dataArray[0] == null) { dataArray[0] = ""; } - // Extended addr. There's no relevant data in ContactsContract. - dataArray[1] = ""; + // We keep all the data in StructuredPostal, presuming NEIGHBORHOOD is + // similar to "Extended Address". + dataArray[1] = contentValues.getAsString(StructuredPostal.NEIGHBORHOOD); + if (dataArray[1] == null) { + dataArray[1] = ""; + } dataArray[2] = contentValues.getAsString(StructuredPostal.STREET); if (dataArray[2] == null) { dataArray[2] = ""; @@ -282,7 +311,36 @@ public class VCardUtils { } return builder.toString(); } - + + public static List<String> constructListFromValue(final String value, + final boolean isV30) { + final List<String> list = new ArrayList<String>(); + StringBuilder builder = new StringBuilder(); + int length = value.length(); + for (int i = 0; i < length; i++) { + char ch = value.charAt(i); + if (ch == '\\' && i < length - 1) { + char nextCh = value.charAt(i + 1); + final String unescapedString = + (isV30 ? VCardParser_V30.unescapeCharacter(nextCh) : + VCardParser_V21.unescapeCharacter(nextCh)); + if (unescapedString != null) { + builder.append(unescapedString); + i++; + } else { + builder.append(ch); + } + } else if (ch == ';') { + list.add(builder.toString()); + builder = new StringBuilder(); + } else { + builder.append(ch); + } + } + list.add(builder.toString()); + return list; + } + public static boolean containsOnlyPrintableAscii(String str) { if (TextUtils.isEmpty(str)) { return true; diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index 08a2a9f..197d976 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -188,17 +188,7 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis mContext = context; TypedArray a = context.obtainStyledAttributes(attrs, - com.android.internal.R.styleable.Preference); - if (a.hasValue(com.android.internal.R.styleable.Preference_layout) || - a.hasValue(com.android.internal.R.styleable.Preference_widgetLayout)) { - // This preference has a custom layout defined (not one taken from - // the default style) - mHasSpecifiedLayout = true; - } - a.recycle(); - - a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Preference, - defStyle, 0); + com.android.internal.R.styleable.Preference, defStyle, 0); for (int i = a.getIndexCount(); i >= 0; i--) { int attr = a.getIndex(i); switch (attr) { @@ -252,6 +242,11 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis } } a.recycle(); + + if (!getClass().getName().startsWith("android.preference")) { + // For subclasses not in this package, assume the worst and don't cache views + mHasSpecifiedLayout = true; + } } /** @@ -332,11 +327,11 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis * @see #setWidgetLayoutResource(int) */ public void setLayoutResource(int layoutResId) { - - if (!mHasSpecifiedLayout) { + if (layoutResId != mLayoutResId) { + // Layout changed mHasSpecifiedLayout = true; } - + mLayoutResId = layoutResId; } @@ -360,6 +355,10 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis * @see #setLayoutResource(int) */ public void setWidgetLayoutResource(int widgetLayoutResId) { + if (widgetLayoutResId != mWidgetLayoutResId) { + // Layout changed + mHasSpecifiedLayout = true; + } mWidgetLayoutResId = widgetLayoutResId; } diff --git a/core/java/android/preference/PreferenceGroupAdapter.java b/core/java/android/preference/PreferenceGroupAdapter.java index 14c0054..a908ecd 100644 --- a/core/java/android/preference/PreferenceGroupAdapter.java +++ b/core/java/android/preference/PreferenceGroupAdapter.java @@ -69,7 +69,9 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn * count once--when the adapter is being set). We will not recycle views for * Preference subclasses seen after the count has been returned. */ - private List<String> mPreferenceClassNames; + private ArrayList<PreferenceLayout> mPreferenceLayouts; + + private PreferenceLayout mTempPreferenceLayout = new PreferenceLayout(); /** * Blocks the mPreferenceClassNames from being changed anymore. @@ -86,14 +88,37 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn } }; + private static class PreferenceLayout implements Comparable<PreferenceLayout> { + private int resId; + private int widgetResId; + private String name; + + public int compareTo(PreferenceLayout other) { + int compareNames = name.compareTo(other.name); + if (compareNames == 0) { + if (resId == other.resId) { + if (widgetResId == other.widgetResId) { + return 0; + } else { + return widgetResId - other.widgetResId; + } + } else { + return resId - other.resId; + } + } else { + return compareNames; + } + } + } + public PreferenceGroupAdapter(PreferenceGroup preferenceGroup) { mPreferenceGroup = preferenceGroup; // If this group gets or loses any children, let us know mPreferenceGroup.setOnPreferenceChangeInternalListener(this); - + mPreferenceList = new ArrayList<Preference>(); - mPreferenceClassNames = new ArrayList<String>(); - + mPreferenceLayouts = new ArrayList<PreferenceLayout>(); + syncMyPreferences(); } @@ -102,7 +127,7 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn if (mIsSyncing) { return; } - + mIsSyncing = true; } @@ -128,7 +153,7 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn preferences.add(preference); - if (!mHasReturnedViewTypeCount) { + if (!mHasReturnedViewTypeCount && !preference.hasSpecifiedLayout()) { addPreferenceClassName(preference); } @@ -143,15 +168,28 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn } } + /** + * Creates a string that includes the preference name, layout id and widget layout id. + * If a particular preference type uses 2 different resources, they will be treated as + * different view types. + */ + private PreferenceLayout createPreferenceLayout(Preference preference, PreferenceLayout in) { + PreferenceLayout pl = in != null? in : new PreferenceLayout(); + pl.name = preference.getClass().getName(); + pl.resId = preference.getLayoutResource(); + pl.widgetResId = preference.getWidgetLayoutResource(); + return pl; + } + private void addPreferenceClassName(Preference preference) { - final String name = preference.getClass().getName(); - int insertPos = Collections.binarySearch(mPreferenceClassNames, name); - + final PreferenceLayout pl = createPreferenceLayout(preference, null); + int insertPos = Collections.binarySearch(mPreferenceLayouts, pl); + // Only insert if it doesn't exist (when it is negative). if (insertPos < 0) { // Convert to insert index insertPos = insertPos * -1 - 1; - mPreferenceClassNames.add(insertPos, name); + mPreferenceLayouts.add(insertPos, pl); } } @@ -171,19 +209,15 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn public View getView(int position, View convertView, ViewGroup parent) { final Preference preference = this.getItem(position); - - if (preference.hasSpecifiedLayout()) { - // If the preference had specified a layout (as opposed to the - // default), don't use convert views. + // Build a PreferenceLayout to compare with known ones that are cacheable. + mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout); + + // If it's not one of the cached ones, set the convertView to null so that + // the layout gets re-created by the Preference. + if (Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout) < 0) { convertView = null; - } else { - // TODO: better way of doing this - final String name = preference.getClass().getName(); - if (Collections.binarySearch(mPreferenceClassNames, name) < 0) { - convertView = null; - } } - + return preference.getView(convertView, parent); } @@ -225,8 +259,9 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn return IGNORE_ITEM_VIEW_TYPE; } - final String name = preference.getClass().getName(); - int viewType = Collections.binarySearch(mPreferenceClassNames, name); + mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout); + + int viewType = Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout); if (viewType < 0) { // This is a class that was seen after we returned the count, so // don't recycle it. @@ -242,7 +277,7 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn mHasReturnedViewTypeCount = true; } - return Math.max(1, mPreferenceClassNames.size()); + return Math.max(1, mPreferenceLayouts.size()); } } diff --git a/core/java/android/provider/Calendar.java b/core/java/android/provider/Calendar.java index f046cef..faa63af 100644 --- a/core/java/android/provider/Calendar.java +++ b/core/java/android/provider/Calendar.java @@ -514,6 +514,12 @@ public final class Calendar { * <P>Type: String</P> */ public static final String OWNER_ACCOUNT = "ownerAccount"; + + /** + * Whether the row has been deleted. A deleted row should be ignored. + * <P>Type: INTEGER (boolean)</P> + */ + public static final String DELETED = "deleted"; } /** diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 062080d..cd71682 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -238,6 +238,7 @@ public final class MediaStore { private static final int FULL_SCREEN_KIND = 2; private static final int MICRO_KIND = 3; private static final String[] PROJECTION = new String[] {_ID, MediaColumns.DATA}; + static final int DEFAULT_GROUP_ID = 0; /** * This method cancels the thumbnail request so clients waiting for getThumbnail will be @@ -246,11 +247,14 @@ public final class MediaStore { * * @param cr ContentResolver * @param origId original image or video id. use -1 to cancel all requests. + * @param groupId the same groupId used in getThumbnail * @param baseUri the base URI of requested thumbnails */ - static void cancelThumbnailRequest(ContentResolver cr, long origId, Uri baseUri) { + static void cancelThumbnailRequest(ContentResolver cr, long origId, Uri baseUri, + long groupId) { Uri cancelUri = baseUri.buildUpon().appendQueryParameter("cancel", "1") - .appendQueryParameter("orig_id", String.valueOf(origId)).build(); + .appendQueryParameter("orig_id", String.valueOf(origId)) + .appendQueryParameter("group_id", String.valueOf(groupId)).build(); Cursor c = null; try { c = cr.query(cancelUri, PROJECTION, null, null, null); @@ -271,9 +275,10 @@ public final class MediaStore { * @param kind could be MINI_KIND or MICRO_KIND * @param options this is only used for MINI_KIND when decoding the Bitmap * @param baseUri the base URI of requested thumbnails + * @param groupId the id of group to which this request belongs * @return Bitmap bitmap of specified thumbnail kind */ - static Bitmap getThumbnail(ContentResolver cr, long origId, int kind, + static Bitmap getThumbnail(ContentResolver cr, long origId, long groupId, int kind, BitmapFactory.Options options, Uri baseUri, boolean isVideo) { Bitmap bitmap = null; String filePath = null; @@ -297,7 +302,8 @@ public final class MediaStore { Cursor c = null; try { Uri blockingUri = baseUri.buildUpon().appendQueryParameter("blocking", "1") - .appendQueryParameter("orig_id", String.valueOf(origId)).build(); + .appendQueryParameter("orig_id", String.valueOf(origId)) + .appendQueryParameter("group_id", String.valueOf(groupId)).build(); c = cr.query(blockingUri, PROJECTION, null, null, null); // This happens when original image/video doesn't exist. if (c == null) return null; @@ -354,7 +360,7 @@ public final class MediaStore { } if (isVideo) { bitmap = ThumbnailUtil.createVideoThumbnail(filePath); - if (kind == MICRO_KIND) { + if (kind == MICRO_KIND && bitmap != null) { bitmap = ThumbnailUtil.extractMiniThumb(bitmap, ThumbnailUtil.MINI_THUMB_TARGET_SIZE, ThumbnailUtil.MINI_THUMB_TARGET_SIZE, @@ -669,7 +675,8 @@ public final class MediaStore { * @param origId original image id */ public static void cancelThumbnailRequest(ContentResolver cr, long origId) { - InternalThumbnails.cancelThumbnailRequest(cr, origId, EXTERNAL_CONTENT_URI); + InternalThumbnails.cancelThumbnailRequest(cr, origId, EXTERNAL_CONTENT_URI, + InternalThumbnails.DEFAULT_GROUP_ID); } /** @@ -685,7 +692,39 @@ public final class MediaStore { */ public static Bitmap getThumbnail(ContentResolver cr, long origId, int kind, BitmapFactory.Options options) { - return InternalThumbnails.getThumbnail(cr, origId, kind, options, + return InternalThumbnails.getThumbnail(cr, origId, + InternalThumbnails.DEFAULT_GROUP_ID, kind, options, + EXTERNAL_CONTENT_URI, false); + } + + /** + * This method cancels the thumbnail request so clients waiting for getThumbnail will be + * interrupted and return immediately. Only the original process which made the getThumbnail + * requests can cancel their own requests. + * + * @param cr ContentResolver + * @param origId original image id + * @param groupId the same groupId used in getThumbnail. + */ + public static void cancelThumbnailRequest(ContentResolver cr, long origId, long groupId) { + InternalThumbnails.cancelThumbnailRequest(cr, origId, EXTERNAL_CONTENT_URI, groupId); + } + + /** + * This method checks if the thumbnails of the specified image (origId) has been created. + * It will be blocked until the thumbnails are generated. + * + * @param cr ContentResolver used to dispatch queries to MediaProvider. + * @param origId Original image id associated with thumbnail of interest. + * @param groupId the id of group to which this request belongs + * @param kind The type of thumbnail to fetch. Should be either MINI_KIND or MICRO_KIND. + * @param options this is only used for MINI_KIND when decoding the Bitmap + * @return A Bitmap instance. It could be null if the original image + * associated with origId doesn't exist or memory is not enough. + */ + public static Bitmap getThumbnail(ContentResolver cr, long origId, long groupId, + int kind, BitmapFactory.Options options) { + return InternalThumbnails.getThumbnail(cr, origId, groupId, kind, options, EXTERNAL_CONTENT_URI, false); } @@ -1598,7 +1637,26 @@ public final class MediaStore { * @param origId original video id */ public static void cancelThumbnailRequest(ContentResolver cr, long origId) { - InternalThumbnails.cancelThumbnailRequest(cr, origId, EXTERNAL_CONTENT_URI); + InternalThumbnails.cancelThumbnailRequest(cr, origId, EXTERNAL_CONTENT_URI, + InternalThumbnails.DEFAULT_GROUP_ID); + } + + /** + * This method checks if the thumbnails of the specified image (origId) has been created. + * It will be blocked until the thumbnails are generated. + * + * @param cr ContentResolver used to dispatch queries to MediaProvider. + * @param origId Original image id associated with thumbnail of interest. + * @param kind The type of thumbnail to fetch. Should be either MINI_KIND or MICRO_KIND. + * @param options this is only used for MINI_KIND when decoding the Bitmap + * @return A Bitmap instance. It could be null if the original image + * associated with origId doesn't exist or memory is not enough. + */ + public static Bitmap getThumbnail(ContentResolver cr, long origId, int kind, + BitmapFactory.Options options) { + return InternalThumbnails.getThumbnail(cr, origId, + InternalThumbnails.DEFAULT_GROUP_ID, kind, options, + EXTERNAL_CONTENT_URI, true); } /** @@ -1607,18 +1665,32 @@ public final class MediaStore { * * @param cr ContentResolver used to dispatch queries to MediaProvider. * @param origId Original image id associated with thumbnail of interest. + * @param groupId the id of group to which this request belongs * @param kind The type of thumbnail to fetch. Should be either MINI_KIND or MICRO_KIND * @param options this is only used for MINI_KIND when decoding the Bitmap * @return A Bitmap instance. It could be null if the original image associated with * origId doesn't exist or memory is not enough. */ - public static Bitmap getThumbnail(ContentResolver cr, long origId, int kind, - BitmapFactory.Options options) { - return InternalThumbnails.getThumbnail(cr, origId, kind, options, + public static Bitmap getThumbnail(ContentResolver cr, long origId, long groupId, + int kind, BitmapFactory.Options options) { + return InternalThumbnails.getThumbnail(cr, origId, groupId, kind, options, EXTERNAL_CONTENT_URI, true); } /** + * This method cancels the thumbnail request so clients waiting for getThumbnail will be + * interrupted and return immediately. Only the original process which made the getThumbnail + * requests can cancel their own requests. + * + * @param cr ContentResolver + * @param origId original video id + * @param groupId the same groupId used in getThumbnail. + */ + public static void cancelThumbnailRequest(ContentResolver cr, long origId, long groupId) { + InternalThumbnails.cancelThumbnailRequest(cr, origId, EXTERNAL_CONTENT_URI, groupId); + } + + /** * Get the content:// style URI for the image media table on the * given volume. * diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index cb3dc16..456181c 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3110,6 +3110,13 @@ public final class Settings { = "google_login_generic_auth_service"; /** + * Duration in milliseconds after setup at which market does not reconcile applications + * which are installed during restore. + */ + public static final String VENDING_RESTORE_WINDOW_MS = "vending_restore_window_ms"; + + + /** * Frequency in milliseconds at which we should sync the locally installed Vending Machine * content with the server. */ @@ -3623,7 +3630,6 @@ public final class Settings { */ public static final String SEARCH_PER_SOURCE_CONCURRENT_QUERY_LIMIT = "search_per_source_concurrent_query_limit"; - /** * Flag for allowing ActivityManagerService to send ACTION_APP_ERROR intents * on application crashes and ANRs. If this is disabled, the crash/ANR dialog @@ -3638,6 +3644,32 @@ public final class Settings { public static final String LAST_KMSG_KB = "last_kmsg_kb"; /** + * Maximum age of entries kept by {@link android.os.IDropBox}. + */ + public static final String DROPBOX_AGE_SECONDS = + "dropbox_age_seconds"; + /** + * Maximum amount of disk space used by {@link android.os.IDropBox} no matter what. + */ + public static final String DROPBOX_QUOTA_KB = + "dropbox_quota_kb"; + /** + * Percent of free disk (excluding reserve) which {@link android.os.IDropBox} will use. + */ + public static final String DROPBOX_QUOTA_PERCENT = + "dropbox_quota_percent"; + /** + * Percent of total disk which {@link android.os.IDropBox} will never dip into. + */ + public static final String DROPBOX_RESERVE_PERCENT = + "dropbox_reserve_percent"; + /** + * Prefix for per-tag dropbox disable/enable settings. + */ + public static final String DROPBOX_TAG_PREFIX = + "dropbox:"; + + /** * @deprecated * @hide */ diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java index 67b30a9..0db29a4 100644 --- a/core/java/android/server/BluetoothService.java +++ b/core/java/android/server/BluetoothService.java @@ -61,7 +61,7 @@ import java.util.Map; public class BluetoothService extends IBluetooth.Stub { private static final String TAG = "BluetoothService"; - private static final boolean DBG = false; + private static final boolean DBG = true; private int mNativeData; private BluetoothEventLoop mEventLoop; diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index a92800d..afc6864 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -294,7 +294,12 @@ public abstract class Layout { lbaseline, lbottom, buf, start, end, par, this); - left += margin.getLeadingMargin(par); + boolean useMargin = par; + if (margin instanceof LeadingMarginSpan.LeadingMarginSpan2) { + int count = ((LeadingMarginSpan.LeadingMarginSpan2)margin).getLeadingMarginLineCount(); + useMargin = count > i; + } + left += margin.getLeadingMargin(useMargin); } } } @@ -1293,7 +1298,13 @@ public abstract class Layout { LeadingMarginSpan.class); for (int i = 0; i < spans.length; i++) { - left += spans[i].getLeadingMargin(par); + boolean margin = par; + LeadingMarginSpan span = spans[i]; + if (span instanceof LeadingMarginSpan.LeadingMarginSpan2) { + int count = ((LeadingMarginSpan.LeadingMarginSpan2)span).getLeadingMarginLineCount(); + margin = count >= line; + } + left += span.getLeadingMargin(margin); } } } diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index f0a5ffd..fbf1261 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -161,6 +161,7 @@ extends Layout else end++; + int firstWidthLineCount = 1; int firstwidth = outerwidth; int restwidth = outerwidth; @@ -171,8 +172,12 @@ extends Layout sp = spanned.getSpans(start, end, LeadingMarginSpan.class); for (int i = 0; i < sp.length; i++) { + LeadingMarginSpan lms = sp[i]; firstwidth -= sp[i].getLeadingMargin(true); restwidth -= sp[i].getLeadingMargin(false); + if (lms instanceof LeadingMarginSpan.LeadingMarginSpan2) { + firstWidthLineCount = ((LeadingMarginSpan.LeadingMarginSpan2)lms).getLeadingMarginLineCount(); + } } chooseht = spanned.getSpans(start, end, LineHeightSpan.class); @@ -750,7 +755,9 @@ extends Layout fitascent = fitdescent = fittop = fitbottom = 0; okascent = okdescent = oktop = okbottom = 0; - width = restwidth; + if (--firstWidthLineCount <= 0) { + width = restwidth; + } } } } diff --git a/core/java/android/text/style/LeadingMarginSpan.java b/core/java/android/text/style/LeadingMarginSpan.java index 8e212e3..cb55329 100644 --- a/core/java/android/text/style/LeadingMarginSpan.java +++ b/core/java/android/text/style/LeadingMarginSpan.java @@ -33,6 +33,11 @@ extends ParagraphStyle CharSequence text, int start, int end, boolean first, Layout layout); + + public interface LeadingMarginSpan2 extends LeadingMarginSpan, WrapTogetherSpan { + public int getLeadingMarginLineCount(); + }; + public static class Standard implements LeadingMarginSpan, ParcelableSpan { private final int mFirst, mRest; diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index f4593f5..e4f2b63 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -68,6 +68,7 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachInfo.Callbacks { private static final String TAG = "ViewRoot"; private static final boolean DBG = false; + private static final boolean SHOW_FPS = false; @SuppressWarnings({"ConstantConditionalExpression"}) private static final boolean LOCAL_LOGV = false ? Config.LOGD : Config.LOGV; /** @noinspection PointlessBooleanExpression*/ @@ -1244,7 +1245,7 @@ public final class ViewRoot extends Handler implements ViewParent, mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); checkEglErrors(); - if (Config.DEBUG && ViewDebug.showFps) { + if (SHOW_FPS || Config.DEBUG && ViewDebug.showFps) { int now = (int)SystemClock.elapsedRealtime(); if (sDrawTime != 0) { nativeShowFPS(canvas, now - sDrawTime); @@ -1356,7 +1357,7 @@ public final class ViewRoot extends Handler implements ViewParent, mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING); } - if (Config.DEBUG && ViewDebug.showFps) { + if (SHOW_FPS || Config.DEBUG && ViewDebug.showFps) { int now = (int)SystemClock.elapsedRealtime(); if (sDrawTime != 0) { nativeShowFPS(canvas, now - sDrawTime); diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index 9456ae1..d1db35e 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -19,17 +19,21 @@ package android.webkit; import android.app.ActivityManager; import android.content.Context; import android.content.res.AssetManager; +import android.database.Cursor; import android.graphics.Bitmap; import android.net.ParseException; +import android.net.Uri; import android.net.WebAddress; import android.net.http.SslCertificate; import android.os.Handler; import android.os.Message; +import android.provider.OpenableColumns; import android.util.Log; import android.util.TypedValue; import junit.framework.Assert; +import java.io.InputStream; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; @@ -463,6 +467,63 @@ class BrowserFrame extends Handler { } /** + * Called by JNI. Given a URI, find the associated file and return its size + * @param uri A String representing the URI of the desired file. + * @return int The size of the given file. + */ + private int getFileSize(String uri) { + int size = 0; + Cursor cursor = mContext.getContentResolver().query(Uri.parse(uri), + new String[] { OpenableColumns.SIZE }, + null, + null, + null); + if (cursor != null) { + try { + if (cursor.moveToNext()) { + size = cursor.getInt(0); + } + } finally { + cursor.close(); + } + } + return size; + } + + /** + * Called by JNI. Given a URI, a buffer, and an offset into the buffer, + * copy the resource into buffer. + * @param uri A String representing the URI of the desired file. + * @param buffer The byte array to copy the data into. + * @param offset The offet into buffer to place the data. + * @param expectSize The size that the buffer has allocated for this file. + * @return int The size of the given file, or zero if it fails. + */ + private int getFile(String uri, byte[] buffer, int offset, + int expectedSize) { + int size = 0; + try { + InputStream stream = mContext.getContentResolver() + .openInputStream(Uri.parse(uri)); + size = stream.available(); + if (size <= expectedSize && buffer != null + && buffer.length - offset >= size) { + stream.read(buffer, offset, size); + } else { + size = 0; + } + stream.close(); + } catch (java.io.FileNotFoundException e) { + Log.e(LOGTAG, "FileNotFoundException:" + e); + size = 0; + } catch (java.io.IOException e2) { + Log.e(LOGTAG, "IOException: " + e2); + size = 0; + } + return size; + } + + /** * Start loading a resource. * @param loaderHandle The native ResourceLoader that is the target of the * data. diff --git a/core/java/android/webkit/ByteArrayBuilder.java b/core/java/android/webkit/ByteArrayBuilder.java index 145411c..334526b 100644 --- a/core/java/android/webkit/ByteArrayBuilder.java +++ b/core/java/android/webkit/ByteArrayBuilder.java @@ -16,6 +16,8 @@ package android.webkit; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; import java.util.LinkedList; import java.util.ListIterator; @@ -23,47 +25,37 @@ import java.util.ListIterator; them back out. It does not optimize for returning the result in a single array, though this is supported in the API. It is fastest if the retrieval can be done via iterating through chunks. - - Things to add: - - consider dynamically increasing our min_capacity, - as we see mTotalSize increase */ class ByteArrayBuilder { private static final int DEFAULT_CAPACITY = 8192; - private LinkedList<Chunk> mChunks; - - /** free pool */ - private LinkedList<Chunk> mPool; + // Global pool of chunks to be used by other ByteArrayBuilders. + private static final LinkedList<SoftReference<Chunk>> sPool = + new LinkedList<SoftReference<Chunk>>(); + // Reference queue for processing gc'd entries. + private static final ReferenceQueue<Chunk> sQueue = + new ReferenceQueue<Chunk>(); - private int mMinCapacity; + private LinkedList<Chunk> mChunks; public ByteArrayBuilder() { - init(0); - } - - public ByteArrayBuilder(int minCapacity) { - init(minCapacity); - } - - private void init(int minCapacity) { mChunks = new LinkedList<Chunk>(); - mPool = new LinkedList<Chunk>(); - - if (minCapacity <= 0) { - minCapacity = DEFAULT_CAPACITY; - } - mMinCapacity = minCapacity; - } - - public void append(byte[] array) { - append(array, 0, array.length); } public synchronized void append(byte[] array, int offset, int length) { while (length > 0) { - Chunk c = appendChunk(length); + Chunk c = null; + if (mChunks.isEmpty()) { + c = obtainChunk(length); + mChunks.addLast(c); + } else { + c = mChunks.getLast(); + if (c.mLength == c.mArray.length) { + c = obtainChunk(length); + mChunks.addLast(c); + } + } int amount = Math.min(length, c.mArray.length - c.mLength); System.arraycopy(array, offset, c.mArray, c.mLength, amount); c.mLength += amount; @@ -75,7 +67,7 @@ class ByteArrayBuilder { /** * The fastest way to retrieve the data is to iterate through the * chunks. This returns the first chunk. Note: this pulls the - * chunk out of the queue. The caller must call releaseChunk() to + * chunk out of the queue. The caller must call Chunk.release() to * dispose of it. */ public synchronized Chunk getFirstChunk() { @@ -83,23 +75,11 @@ class ByteArrayBuilder { return mChunks.removeFirst(); } - /** - * recycles chunk - */ - public synchronized void releaseChunk(Chunk c) { - c.mLength = 0; - mPool.addLast(c); - } - - public boolean isEmpty() { + public synchronized boolean isEmpty() { return mChunks.isEmpty(); } - public int size() { - return mChunks.size(); - } - - public int getByteSize() { + public synchronized int getByteSize() { int total = 0; ListIterator<Chunk> it = mChunks.listIterator(0); while (it.hasNext()) { @@ -112,37 +92,40 @@ class ByteArrayBuilder { public synchronized void clear() { Chunk c = getFirstChunk(); while (c != null) { - releaseChunk(c); + c.release(); c = getFirstChunk(); } } - private Chunk appendChunk(int length) { - if (length < mMinCapacity) { - length = mMinCapacity; - } - - Chunk c; - if (mChunks.isEmpty()) { - c = obtainChunk(length); - } else { - c = mChunks.getLast(); - if (c.mLength == c.mArray.length) { - c = obtainChunk(length); + // Must be called with lock held on sPool. + private void processPoolLocked() { + while (true) { + SoftReference<Chunk> entry = (SoftReference<Chunk>) sQueue.poll(); + if (entry == null) { + break; } + sPool.remove(entry); } - return c; } private Chunk obtainChunk(int length) { - Chunk c; - if (mPool.isEmpty()) { - c = new Chunk(length); - } else { - c = mPool.removeFirst(); + // Correct a small length. + if (length < DEFAULT_CAPACITY) { + length = DEFAULT_CAPACITY; + } + synchronized (sPool) { + // Process any queued references and remove them from the pool. + processPoolLocked(); + if (!sPool.isEmpty()) { + Chunk c = sPool.removeFirst().get(); + // The first item may have been queued after processPoolLocked + // so check for null. + if (c != null) { + return c; + } + } + return new Chunk(length); } - mChunks.addLast(c); - return c; } public static class Chunk { @@ -153,5 +136,19 @@ class ByteArrayBuilder { mArray = new byte[length]; mLength = 0; } + + /** + * Release the chunk and make it available for reuse. + */ + public void release() { + mLength = 0; + synchronized (sPool) { + // Add the chunk back to the pool as a SoftReference so it can + // be gc'd if needed. + sPool.offer(new SoftReference<Chunk>(this, sQueue)); + sPool.notifyAll(); + } + } + } } diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java index 8d55247..f9dec7f 100644 --- a/core/java/android/webkit/CallbackProxy.java +++ b/core/java/android/webkit/CallbackProxy.java @@ -107,6 +107,7 @@ class CallbackProxy extends Handler { private static final int GEOLOCATION_PERMISSIONS_HIDE_PROMPT = 131; private static final int RECEIVED_TOUCH_ICON_URL = 132; private static final int GET_VISITED_HISTORY = 133; + private static final int OPEN_FILE_CHOOSER = 134; // Message triggered by the client to resume execution private static final int NOTIFY = 200; @@ -149,6 +150,16 @@ class CallbackProxy extends Handler { } /** + * Get the WebViewClient. + * @return the current WebViewClient instance. + * + *@hide pending API council approval. + */ + public WebViewClient getWebViewClient() { + return mWebViewClient; + } + + /** * Set the WebChromeClient. * @param client An implementation of WebChromeClient. */ @@ -662,6 +673,12 @@ class CallbackProxy extends Handler { mWebChromeClient.getVisitedHistory((ValueCallback<String[]>)msg.obj); } break; + + case OPEN_FILE_CHOOSER: + if (mWebChromeClient != null) { + mWebChromeClient.openFileChooser((UploadFile) msg.obj); + } + break; } } @@ -1348,4 +1365,40 @@ class CallbackProxy extends Handler { msg.obj = callback; sendMessage(msg); } + + private class UploadFile implements ValueCallback<Uri> { + private Uri mValue; + public void onReceiveValue(Uri value) { + mValue = value; + synchronized (CallbackProxy.this) { + CallbackProxy.this.notify(); + } + } + public Uri getResult() { + return mValue; + } + } + + /** + * Called by WebViewCore to open a file chooser. + */ + /* package */ Uri openFileChooser() { + if (mWebChromeClient == null) { + return null; + } + Message myMessage = obtainMessage(OPEN_FILE_CHOOSER); + UploadFile uploadFile = new UploadFile(); + myMessage.obj = uploadFile; + synchronized (this) { + sendMessage(myMessage); + try { + wait(); + } catch (InterruptedException e) { + Log.e(LOGTAG, + "Caught exception while waiting for openFileChooser"); + Log.e(LOGTAG, Log.getStackTraceString(e)); + } + } + return uploadFile.getResult(); + } } diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java index b7a9065..3e0be1c 100644 --- a/core/java/android/webkit/HTML5VideoViewProxy.java +++ b/core/java/android/webkit/HTML5VideoViewProxy.java @@ -199,6 +199,8 @@ class HTML5VideoViewProxy extends Handler public void playbackEnded() { Message msg = Message.obtain(mWebCoreHandler, ENDED); mWebCoreHandler.sendMessage(msg); + // also send a message to ourselves to return to the WebView + sendMessage(obtainMessage(ENDED)); } // Handler for the messages from WebCore thread to the UI thread. @@ -224,6 +226,7 @@ class HTML5VideoViewProxy extends Handler VideoPlayer.pause(this); break; } + case ENDED: case ERROR: { WebChromeClient client = mWebView.getWebChromeClient(); if (client != null) { diff --git a/core/java/android/webkit/HttpDateTime.java b/core/java/android/webkit/HttpDateTime.java index 2f46f2b..042953c 100644 --- a/core/java/android/webkit/HttpDateTime.java +++ b/core/java/android/webkit/HttpDateTime.java @@ -50,13 +50,15 @@ public final class HttpDateTime { * Wdy Mon DD HH:MM:SS YYYY GMT * * HH can be H if the first digit is zero. + * + * Mon can be the full name of the month. */ private static final String HTTP_DATE_RFC_REGEXP = - "([0-9]{1,2})[- ]([A-Za-z]{3,3})[- ]([0-9]{2,4})[ ]" + "([0-9]{1,2})[- ]([A-Za-z]{3,9})[- ]([0-9]{2,4})[ ]" + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])"; private static final String HTTP_DATE_ANSIC_REGEXP = - "[ ]([A-Za-z]{3,3})[ ]+([0-9]{1,2})[ ]" + "[ ]([A-Za-z]{3,9})[ ]+([0-9]{1,2})[ ]" + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])[ ]([0-9]{2,4})"; /** diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java index 4c17f99..5c0ce3c 100644 --- a/core/java/android/webkit/LoadListener.java +++ b/core/java/android/webkit/LoadListener.java @@ -78,7 +78,7 @@ class LoadListener extends Handler implements EventHandler { private static int sNativeLoaderCount; - private final ByteArrayBuilder mDataBuilder = new ByteArrayBuilder(8192); + private final ByteArrayBuilder mDataBuilder = new ByteArrayBuilder(); private String mUrl; private WebAddress mUri; @@ -522,17 +522,18 @@ class LoadListener extends Handler implements EventHandler { * IMPORTANT: as this is called from network thread, can't call native * directly * XXX: Unlike the other network thread methods, this method can do the - * work of decoding the data and appending it to the data builder because - * mDataBuilder is a thread-safe structure. + * work of decoding the data and appending it to the data builder. */ public void data(byte[] data, int length) { if (DebugFlags.LOAD_LISTENER) { Log.v(LOGTAG, "LoadListener.data(): url: " + url()); } - // Synchronize on mData because commitLoad may write mData to WebCore - // and we don't want to replace mData or mDataLength at the same time - // as a write. + // The reason isEmpty() and append() need to synchronized together is + // because it is possible for getFirstChunk() to be called multiple + // times between isEmpty() and append(). This could cause commitLoad() + // to finish before processing the newly appended data and no message + // will be sent. boolean sendMessage = false; synchronized (mDataBuilder) { sendMessage = mDataBuilder.isEmpty(); @@ -1009,28 +1010,34 @@ class LoadListener extends Handler implements EventHandler { if (mIsMainPageLoader) { String type = sCertificateTypeMap.get(mMimeType); if (type != null) { - // In the case of downloading certificate, we will save it to - // the KeyStore and stop the current loading so that it will not - // generate a new history page - byte[] cert = new byte[mDataBuilder.getByteSize()]; - int offset = 0; - while (true) { - ByteArrayBuilder.Chunk c = mDataBuilder.getFirstChunk(); - if (c == null) break; - - if (c.mLength != 0) { - System.arraycopy(c.mArray, 0, cert, offset, c.mLength); - offset += c.mLength; + // This must be synchronized so that no more data can be added + // after getByteSize returns. + synchronized (mDataBuilder) { + // In the case of downloading certificate, we will save it + // to the KeyStore and stop the current loading so that it + // will not generate a new history page + byte[] cert = new byte[mDataBuilder.getByteSize()]; + int offset = 0; + while (true) { + ByteArrayBuilder.Chunk c = mDataBuilder.getFirstChunk(); + if (c == null) break; + + if (c.mLength != 0) { + System.arraycopy(c.mArray, 0, cert, offset, c.mLength); + offset += c.mLength; + } + c.release(); } - mDataBuilder.releaseChunk(c); + CertTool.addCertificate(mContext, type, cert); + mBrowserFrame.stopLoading(); + return; } - CertTool.addCertificate(mContext, type, cert); - mBrowserFrame.stopLoading(); - return; } } - // Give the data to WebKit now + // Give the data to WebKit now. We don't have to synchronize on + // mDataBuilder here because pulling each chunk removes it from the + // internal list so it cannot be modified. PerfChecker checker = new PerfChecker(); ByteArrayBuilder.Chunk c; while (true) { @@ -1047,7 +1054,7 @@ class LoadListener extends Handler implements EventHandler { } nativeAddData(c.mArray, c.mLength); } - mDataBuilder.releaseChunk(c); + c.release(); checker.responseAlert("res nativeAddData"); } } @@ -1210,8 +1217,17 @@ class LoadListener extends Handler implements EventHandler { // mRequestHandle can be null when the request was satisfied // by the cache, and the cache returned a redirect if (mRequestHandle != null) { - mRequestHandle.setupRedirect(mUrl, mStatusCode, - mRequestHeaders); + try { + mRequestHandle.setupRedirect(mUrl, mStatusCode, + mRequestHeaders); + } catch(RuntimeException e) { + Log.e(LOGTAG, e.getMessage()); + // Signal a bad url error if we could not load the + // redirection. + handleError(EventHandler.ERROR_BAD_URL, + mContext.getString(R.string.httpErrorBadUrl)); + return; + } } else { // If the original request came from the cache, there is no // RequestHandle, we have to create a new one through diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java index fffba1b..84a8a3c 100644 --- a/core/java/android/webkit/MimeTypeMap.java +++ b/core/java/android/webkit/MimeTypeMap.java @@ -431,6 +431,8 @@ public class MimeTypeMap { sMimeTypeMap.loadEntry("text/calendar", "icz"); sMimeTypeMap.loadEntry("text/comma-separated-values", "csv"); sMimeTypeMap.loadEntry("text/css", "css"); + sMimeTypeMap.loadEntry("text/html", "htm"); + sMimeTypeMap.loadEntry("text/html", "html"); sMimeTypeMap.loadEntry("text/h323", "323"); sMimeTypeMap.loadEntry("text/iuls", "uls"); sMimeTypeMap.loadEntry("text/mathml", "mml"); @@ -481,6 +483,7 @@ public class MimeTypeMap { sMimeTypeMap.loadEntry("video/dv", "dif"); sMimeTypeMap.loadEntry("video/dv", "dv"); sMimeTypeMap.loadEntry("video/fli", "fli"); + sMimeTypeMap.loadEntry("video/m4v", "m4v"); sMimeTypeMap.loadEntry("video/mpeg", "mpeg"); sMimeTypeMap.loadEntry("video/mpeg", "mpg"); sMimeTypeMap.loadEntry("video/mpeg", "mpe"); diff --git a/core/java/android/webkit/Network.java b/core/java/android/webkit/Network.java index af0cb1e..b53e404 100644 --- a/core/java/android/webkit/Network.java +++ b/core/java/android/webkit/Network.java @@ -180,20 +180,24 @@ class Network { } RequestQueue q = mRequestQueue; + RequestHandle handle = null; if (loader.isSynchronous()) { - q = new RequestQueue(loader.getContext(), 1); - } - - RequestHandle handle = q.queueRequest( - url, loader.getWebAddress(), method, headers, loader, - bodyProvider, bodyLength); - loader.attachRequestHandle(handle); - - if (loader.isSynchronous()) { - handle.waitUntilComplete(); + handle = q.queueSynchronousRequest(url, loader.getWebAddress(), + method, headers, loader, bodyProvider, bodyLength); + loader.attachRequestHandle(handle); + handle.processRequest(); loader.loadSynchronousMessages(); - q.shutdown(); + } else { + handle = q.queueRequest(url, loader.getWebAddress(), method, + headers, loader, bodyProvider, bodyLength); + // FIXME: Although this is probably a rare condition, normal network + // requests are processed in a separate thread. This means that it + // is possible to process part of the request before setting the + // request handle on the loader. We should probably refactor this to + // ensure the handle is attached before processing begins. + loader.attachRequestHandle(handle); } + return true; } diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java index 232ed36..211e5e4 100644 --- a/core/java/android/webkit/URLUtil.java +++ b/core/java/android/webkit/URLUtil.java @@ -367,19 +367,23 @@ public final class URLUtil { /** Regex used to parse content-disposition headers */ private static final Pattern CONTENT_DISPOSITION_PATTERN = - Pattern.compile("attachment;\\s*filename\\s*=\\s*\"([^\"]*)\""); + Pattern.compile("attachment;\\s*filename\\s*=\\s*(\"?)([^\"]*)\\1\\s*$", + Pattern.CASE_INSENSITIVE); /* * Parse the Content-Disposition HTTP Header. The format of the header * is defined here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html * This header provides a filename for content that is going to be * downloaded to the file system. We only support the attachment type. + * Note that RFC 2616 specifies the filename value must be double-quoted. + * Unfortunately some servers do not quote the value so to maintain + * consistent behaviour with other browsers, we allow unquoted values too. */ static String parseContentDisposition(String contentDisposition) { try { Matcher m = CONTENT_DISPOSITION_PATTERN.matcher(contentDisposition); if (m.find()) { - return m.group(1); + return m.group(2); } } catch (IllegalStateException ex) { // This function is defined as returning null when it can't parse the header diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java index 7f5b862..ae4f7c2 100644 --- a/core/java/android/webkit/WebChromeClient.java +++ b/core/java/android/webkit/WebChromeClient.java @@ -17,6 +17,7 @@ package android.webkit; import android.graphics.Bitmap; +import android.net.Uri; import android.os.Message; import android.view.View; @@ -302,4 +303,13 @@ public class WebChromeClient { public void getVisitedHistory(ValueCallback<String[]> callback) { } + /** + * Tell the client to open a file chooser. + * @param uploadFile A ValueCallback to set the URI of the file to upload. + * onReceiveValue must be called to wake up the thread. + * @hide + */ + public void openFileChooser(ValueCallback<Uri> uploadFile) { + uploadFile.onReceiveValue(null); + } } diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index 4fedec9..79d8c03 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -1007,7 +1007,8 @@ public class WebSettings { * should never be null. */ public synchronized void setGeolocationDatabasePath(String databasePath) { - if (databasePath != null && !databasePath.equals(mDatabasePath)) { + if (databasePath != null + && !databasePath.equals(mGeolocationDatabasePath)) { mGeolocationDatabasePath = databasePath; postSync(); } diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java index e0d41c2..71b1f9f 100644 --- a/core/java/android/webkit/WebTextView.java +++ b/core/java/android/webkit/WebTextView.java @@ -84,13 +84,24 @@ import java.util.ArrayList; // True if the most recent drag event has caused either the TextView to // scroll or the web page to scroll. Gets reset after a touch down. private boolean mScrolled; - // Gets set to true when the the IME jumps to the next textfield. When this - // happens, the next time the user hits a key it is okay for the focus - // pointer to not match the WebTextView's node pointer + // Gets set to true any time the WebTextView has focus, but the navigation + // cache does not yet know that the focus has been changed. This happens + // if the user presses "Next", if the user moves the cursor to a textfield + // and starts typing or clicks the trackball/center key, and when the user + // touches a textfield. boolean mOkayForFocusNotToMatch; // Whether or not a selection change was generated from webkit. If it was, // we do not need to pass the selection back to webkit. private boolean mFromWebKit; + // Whether or not a selection change was generated from the WebTextView + // gaining focus. If it is, we do not want to pass it to webkit. This + // selection comes from the MovementMethod, but we behave differently. If + // WebTextView gained focus from a touch, webkit will determine the + // selection. + private boolean mFromFocusChange; + // Whether or not a selection change was generated from setInputType. We + // do not want to pass this change to webkit. + private boolean mFromSetInputType; private boolean mGotTouchDown; private boolean mInSetTextAndKeepSelection; // Array to store the final character added in onTextChanged, so that its @@ -136,20 +147,23 @@ import java.util.ArrayList; isArrowKey = true; break; } - if (!isArrowKey && !mOkayForFocusNotToMatch - && mWebView.nativeFocusNodePointer() != mNodePointer) { - mWebView.nativeClearCursor(); - // Do not call remove() here, which hides the soft keyboard. If - // the soft keyboard is being displayed, the user will still want - // it there. - mWebView.removeView(this); - mWebView.requestFocus(); - return mWebView.dispatchKeyEvent(event); - } - // After a jump to next textfield and the first key press, the cursor - // and focus will once again match, so reset this value. - mOkayForFocusNotToMatch = false; + if (down) { + if (mOkayForFocusNotToMatch) { + if (mWebView.nativeFocusNodePointer() == mNodePointer) { + mOkayForFocusNotToMatch = false; + } + } else if (mWebView.nativeFocusNodePointer() != mNodePointer + && !isArrowKey) { + mWebView.nativeClearCursor(); + // Do not call remove() here, which hides the soft keyboard. If + // the soft keyboard is being displayed, the user will still want + // it there. + mWebView.removeView(this); + mWebView.requestFocus(); + return mWebView.dispatchKeyEvent(event); + } + } Spannable text = (Spannable) getText(); int oldLength = text.length(); // Normally the delete key's dom events are sent via onTextChanged. @@ -185,7 +199,7 @@ import java.util.ArrayList; } // Center key should be passed to a potential onClick if (!down) { - mWebView.shortPressOnTextField(); + mWebView.centerKeyPressOnTextField(); } // Pass to super to handle longpress. return super.dispatchKeyEvent(event); @@ -303,15 +317,19 @@ import java.util.ArrayList; public void onEditorAction(int actionCode) { switch (actionCode) { case EditorInfo.IME_ACTION_NEXT: + // Since the cursor will no longer be in the same place as the + // focus, set the focus controller back to inactive + mWebView.setFocusControllerInactive(); mWebView.nativeMoveCursorToNextTextInput(); + mOkayForFocusNotToMatch = true; + // Pass the click to set the focus to the textfield which will now + // have the cursor. + mWebView.centerKeyPressOnTextField(); // Preemptively rebuild the WebTextView, so that the action will // be set properly. mWebView.rebuildWebTextView(); - // Since the cursor will no longer be in the same place as the - // focus, set the focus controller back to inactive - mWebView.setFocusControllerInactive(); + setDefaultSelection(); mWebView.invalidate(); - mOkayForFocusNotToMatch = true; break; case EditorInfo.IME_ACTION_DONE: super.onEditorAction(actionCode); @@ -331,6 +349,14 @@ import java.util.ArrayList; } @Override + protected void onFocusChanged(boolean focused, int direction, + Rect previouslyFocusedRect) { + mFromFocusChange = true; + super.onFocusChanged(focused, direction, previouslyFocusedRect); + mFromFocusChange = false; + } + + @Override protected void onSelectionChanged(int selStart, int selEnd) { // This code is copied from TextView.onDraw(). That code does not get // executed, however, because the WebTextView does not draw, allowing @@ -342,7 +368,8 @@ import java.util.ArrayList; int candEnd = EditableInputConnection.getComposingSpanEnd(sp); imm.updateSelection(this, selStart, selEnd, candStart, candEnd); } - if (!mFromWebKit && mWebView != null) { + if (!mFromWebKit && !mFromFocusChange && !mFromSetInputType + && mWebView != null) { if (DebugFlags.WEB_TEXT_VIEW) { Log.v(LOGTAG, "onSelectionChanged selStart=" + selStart + " selEnd=" + selEnd); @@ -591,6 +618,17 @@ import java.util.ArrayList; } /** + * Sets the selection when the user clicks on a textfield or textarea with + * the trackball or center key, or starts typing into it without clicking on + * it. + */ + /* package */ void setDefaultSelection() { + Spannable text = (Spannable) getText(); + int selection = mSingle ? text.length() : 0; + Selection. setSelection(text, selection, selection); + } + + /** * Determine whether to use the system-wide password disguising method, * or to use none. * @param inPassword True if the textfield is a password field. @@ -660,6 +698,13 @@ import java.util.ArrayList; setTextColor(Color.BLACK); } + @Override + public void setInputType(int type) { + mFromSetInputType = true; + super.setInputType(type); + mFromSetInputType = false; + } + /* package */ void setMaxLength(int maxLength) { mMaxLength = maxLength; if (-1 == maxLength) { @@ -761,32 +806,6 @@ import java.util.ArrayList; } /** - * Set the text for this WebTextView, and set the selection to (start, end) - * @param text Text to go into this WebTextView. - * @param start Beginning of the selection. - * @param end End of the selection. - */ - /* package */ void setText(CharSequence text, int start, int end) { - mPreChange = text.toString(); - setText(text); - Spannable span = (Spannable) getText(); - int length = span.length(); - if (end > length) { - end = length; - } - if (start < 0) { - start = 0; - } else if (start > length) { - start = length; - } - if (DebugFlags.WEB_TEXT_VIEW) { - Log.v(LOGTAG, "setText start=" + start - + " end=" + end); - } - Selection.setSelection(span, start, end); - } - - /** * Set the text to the new string, but use the old selection, making sure * to keep it within the new string. * @param text The new text to place in the textfield. diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index fe91229..304c927 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -64,7 +64,9 @@ import android.widget.AbsoluteLayout; import android.widget.Adapter; import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.CheckedTextView; import android.widget.FrameLayout; +import android.widget.LinearLayout; import android.widget.ListView; import android.widget.Scroller; import android.widget.Toast; @@ -82,6 +84,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import junit.framework.Assert; + /** * <p>A View that displays web pages. This class is the basis upon which you * can roll your own web browser or simply display some online content within your Activity. @@ -390,6 +394,8 @@ public class WebView extends AbsoluteLayout private static final int LONG_PRESS_TIMEOUT = 1000; // needed to avoid flinging after a pause of no movement private static final int MIN_FLING_TIME = 250; + // draw unfiltered after drag is held without movement + private static final int MOTIONLESS_TIME = 100; // The time that the Zoom Controls are visible before fading away private static final long ZOOM_CONTROLS_TIMEOUT = ViewConfiguration.getZoomControlsTimeout(); @@ -427,6 +433,10 @@ public class WebView extends AbsoluteLayout private Scroller mScroller; private boolean mWrapContent; + private static final int MOTIONLESS_FALSE = 0; + private static final int MOTIONLESS_PENDING = 1; + private static final int MOTIONLESS_TRUE = 2; + private int mHeldMotionless; /** * Private message ids @@ -438,6 +448,8 @@ public class WebView extends AbsoluteLayout private static final int RELEASE_SINGLE_TAP = 5; private static final int REQUEST_FORM_DATA = 6; private static final int RESUME_WEBCORE_UPDATE = 7; + private static final int DRAG_HELD_MOTIONLESS = 8; + private static final int AWAKEN_SCROLL_BARS = 9; //! arg1=x, arg2=y static final int SCROLL_TO_MSG_ID = 10; @@ -468,9 +480,9 @@ public class WebView extends AbsoluteLayout "SWITCH_TO_LONGPRESS", // = 4; "RELEASE_SINGLE_TAP", // = 5; "REQUEST_FORM_DATA", // = 6; - "SWITCH_TO_CLICK", // = 7; - "RESUME_WEBCORE_UPDATE", // = 8; - "9", + "RESUME_WEBCORE_UPDATE", // = 7; + "DRAG_HELD_MOTIONLESS", // = 8; + "AWAKEN_SCROLL_BARS", // = 9; "SCROLL_TO_MSG_ID", // = 10; "SCROLL_BY_MSG_ID", // = 11; "SPAWN_SCROLL_TO_MSG_ID", // = 12; @@ -535,11 +547,10 @@ public class WebView extends AbsoluteLayout private boolean mUserScroll = false; private int mSnapScrollMode = SNAP_NONE; - private static final int SNAP_NONE = 1; - private static final int SNAP_X = 2; - private static final int SNAP_Y = 3; - private static final int SNAP_X_LOCK = 4; - private static final int SNAP_Y_LOCK = 5; + private static final int SNAP_NONE = 0; + private static final int SNAP_LOCK = 1; // not a separate state + private static final int SNAP_X = 2; // may be combined with SNAP_LOCK + private static final int SNAP_Y = 4; // may be combined with SNAP_LOCK private boolean mSnapPositive; // Used to match key downs and key ups @@ -1713,6 +1724,7 @@ public class WebView extends AbsoluteLayout * as the data member with "url" as key. The result can be null. */ public void requestImageRef(Message msg) { + if (0 == mNativeClass) return; // client isn't initialized int contentX = viewToContentX((int) mLastTouchX + mScrollX); int contentY = viewToContentY((int) mLastTouchY + mScrollY); String ref = nativeImageURI(contentX, contentY); @@ -2331,6 +2343,7 @@ public class WebView extends AbsoluteLayout * @param forward Direction to search. */ public void findNext(boolean forward) { + if (0 == mNativeClass) return; // client isn't initialized nativeFindNext(forward); } @@ -2341,6 +2354,7 @@ public class WebView extends AbsoluteLayout * that were found. */ public int findAll(String find) { + if (0 == mNativeClass) return 0; // client isn't initialized if (mFindIsUp == false) { recordNewContentSize(mContentWidth, mContentHeight + mFindHeight, false); @@ -2605,12 +2619,12 @@ public class WebView extends AbsoluteLayout if (mHeightCanMeasure) { if (getMeasuredHeight() != contentToViewDimension(mContentHeight) - && updateLayout) { + || updateLayout) { requestLayout(); } } else if (mWidthCanMeasure) { if (getMeasuredWidth() != contentToViewDimension(mContentWidth) - && updateLayout) { + || updateLayout) { requestLayout(); } } else { @@ -2630,6 +2644,16 @@ public class WebView extends AbsoluteLayout } /** + * Gets the WebViewClient + * @return the current WebViewClient instance. + * + *@hide pending API council approval. + */ + public WebViewClient getWebViewClient() { + return mCallbackProxy.getWebViewClient(); + } + + /** * Register the interface to be used when content can not be handled by * the rendering engine, and should be downloaded instead. This will replace * the current handler. @@ -2810,10 +2834,7 @@ public class WebView extends AbsoluteLayout public boolean performLongClick() { if (mNativeClass != 0 && nativeCursorIsTextInput()) { // Send the click so that the textfield is in focus - // FIXME: When we start respecting changes to the native textfield's - // selection, need to make sure that this does not change it. - mWebViewCore.sendMessage(EventHub.CLICK, nativeCursorFramePointer(), - nativeCursorNodePointer()); + centerKeyPressOnTextField(); rebuildWebTextView(); } if (inEditingMode()) { @@ -2836,6 +2857,21 @@ public class WebView extends AbsoluteLayout */ private boolean mNeedToAdjustWebTextView; + private boolean didUpdateTextViewBounds(boolean allowIntersect) { + Rect contentBounds = nativeFocusCandidateNodeBounds(); + Rect vBox = contentToViewRect(contentBounds); + Rect visibleRect = new Rect(); + calcOurVisibleRect(visibleRect); + if (allowIntersect ? Rect.intersects(visibleRect, vBox) : + visibleRect.contains(vBox)) { + mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), + vBox.height()); + return true; + } else { + return false; + } + } + private void drawCoreAndCursorRing(Canvas canvas, int color, boolean drawCursorRing) { if (mDrawHistory) { @@ -2845,8 +2881,22 @@ public class WebView extends AbsoluteLayout } boolean animateZoom = mZoomScale != 0; - boolean animateScroll = !mScroller.isFinished() - || mVelocityTracker != null; + boolean animateScroll = (!mScroller.isFinished() + || mVelocityTracker != null) + && (mTouchMode != TOUCH_DRAG_MODE || + mHeldMotionless != MOTIONLESS_TRUE); + if (mTouchMode == TOUCH_DRAG_MODE) { + if (mHeldMotionless == MOTIONLESS_PENDING) { + mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS); + mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS); + mHeldMotionless = MOTIONLESS_FALSE; + } + if (mHeldMotionless == MOTIONLESS_FALSE) { + mPrivateHandler.sendMessageDelayed(mPrivateHandler + .obtainMessage(DRAG_HELD_MOTIONLESS), MOTIONLESS_TIME); + mHeldMotionless = MOTIONLESS_PENDING; + } + } if (animateZoom) { float zoomScale; int interval = (int) (SystemClock.uptimeMillis() - mZoomStart); @@ -2863,19 +2913,13 @@ public class WebView extends AbsoluteLayout invalidate(); if (mNeedToAdjustWebTextView) { mNeedToAdjustWebTextView = false; - Rect contentBounds = nativeFocusCandidateNodeBounds(); - Rect vBox = contentToViewRect(contentBounds); - Rect visibleRect = new Rect(); - calcOurVisibleRect(visibleRect); - if (visibleRect.contains(vBox)) { - // As a result of the zoom, the textfield is now on - // screen. Place the WebTextView in its new place, - // accounting for our new scroll/zoom values. + // As a result of the zoom, the textfield is now on + // screen. Place the WebTextView in its new place, + // accounting for our new scroll/zoom values. + if (didUpdateTextViewBounds(false)) { mWebTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, contentToViewDimension( nativeFocusCandidateTextSize())); - mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), - vBox.height()); // If it is a password field, start drawing the // WebTextView once again. if (nativeFocusCandidateIsPassword()) { @@ -2927,11 +2971,12 @@ public class WebView extends AbsoluteLayout if (mNativeClass == 0) return; if (mShiftIsPressed && !animateZoom) { - if (mTouchSelection) { + if (mTouchSelection || mExtendSelection) { nativeDrawSelectionRegion(canvas); - } else { - nativeDrawSelection(canvas, mInvActualScale, getTitleHeight(), - mSelectX, mSelectY, mExtendSelection); + } + if (!mTouchSelection) { + nativeDrawSelectionPointer(canvas, mInvActualScale, mSelectX, + mSelectY - getTitleHeight(), mExtendSelection); } } else if (drawCursorRing) { if (mTouchMode == TOUCH_SHORTPRESS_START_MODE) { @@ -2951,6 +2996,10 @@ public class WebView extends AbsoluteLayout if (mFindIsUp && !animateScroll) { nativeDrawMatches(canvas); } + if (mFocusSizeChanged) { + mFocusSizeChanged = false; + didUpdateTextViewBounds(true); + } } // draw history @@ -3046,6 +3095,16 @@ public class WebView extends AbsoluteLayout imm.hideSoftInputFromWindow(this.getWindowToken(), 0); } + /** + * Only for calling from JNI. Allows a click on an unfocused textfield to + * put the textfield in focus. + */ + private void setOkayNotToMatch() { + if (inEditingMode()) { + mWebTextView.mOkayForFocusNotToMatch = true; + } + } + /* * This method checks the current focus and cursor and potentially rebuilds * mWebTextView to have the appropriate properties, such as password, @@ -3101,6 +3160,7 @@ public class WebView extends AbsoluteLayout && nativeTextGeneration() == mTextGeneration) { mWebTextView.setTextAndKeepSelection(text); } else { + // FIXME: Determine whether this is necessary. Selection.setSelection(spannable, start, end); } } else { @@ -3133,34 +3193,12 @@ public class WebView extends AbsoluteLayout mWebTextView.setSingleLine(isTextField); mWebTextView.setInPassword(nativeFocusCandidateIsPassword()); if (null == text) { - mWebTextView.setText("", 0, 0); if (DebugFlags.WEB_VIEW) { Log.v(LOGTAG, "rebuildWebTextView null == text"); } - } else { - // Change to true to enable the old style behavior, where - // entering a textfield/textarea always set the selection to the - // whole field. This was desirable for the case where the user - // intends to scroll past the field using the trackball. - // However, it causes a problem when replying to emails - the - // user expects the cursor to be at the beginning of the - // textarea. Testing out a new behavior, where textfields set - // selection at the end, and textareas at the beginning. - if (false) { - mWebTextView.setText(text, 0, text.length()); - } else if (isTextField) { - int length = text.length(); - mWebTextView.setText(text, length, length); - if (DebugFlags.WEB_VIEW) { - Log.v(LOGTAG, "rebuildWebTextView length=" + length); - } - } else { - mWebTextView.setText(text, 0, 0); - if (DebugFlags.WEB_VIEW) { - Log.v(LOGTAG, "rebuildWebTextView !isTextField"); - } - } + text = ""; } + mWebTextView.setTextAndKeepSelection(text); mWebTextView.requestFocus(); } } @@ -3227,23 +3265,22 @@ public class WebView extends AbsoluteLayout if (mShiftIsPressed == false && nativeCursorWantsKeyEvents() == false && (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT || keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT)) { - mExtendSelection = false; - mShiftIsPressed = true; - if (nativeHasCursorNode()) { - Rect rect = nativeCursorNodeBounds(); - mSelectX = contentToViewX(rect.left); - mSelectY = contentToViewY(rect.top); - } else { - mSelectX = mScrollX + (int) mLastTouchX; - mSelectY = mScrollY + (int) mLastTouchY; - } - nativeHideCursor(); - } + setUpSelectXY(); + } if (keyCode >= KeyEvent.KEYCODE_DPAD_UP && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) { // always handle the navigation keys in the UI thread switchOutDrawHistory(); + if (mShiftIsPressed) { + int xRate = keyCode == KeyEvent.KEYCODE_DPAD_LEFT + ? -1 : keyCode == KeyEvent.KEYCODE_DPAD_RIGHT ? 1 : 0; + int yRate = keyCode == KeyEvent.KEYCODE_DPAD_UP ? + -1 : keyCode == KeyEvent.KEYCODE_DPAD_DOWN ? 1 : 0; + int multiplier = event.getRepeatCount() + 1; + moveSelection(xRate * multiplier, yRate * multiplier); + return true; + } if (navHandledKey(keyCode, 1, false, event.getEventTime(), false)) { playSoundEffect(keyCodeToSoundsEffect(keyCode)); return true; @@ -3255,6 +3292,9 @@ public class WebView extends AbsoluteLayout if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { switchOutDrawHistory(); if (event.getRepeatCount() == 0) { + if (mShiftIsPressed) { + return true; // discard press if copy in progress + } mGotCenterDown = true; mPrivateHandler.sendMessageDelayed(mPrivateHandler .obtainMessage(LONG_PRESS_CENTER), LONG_PRESS_TIMEOUT); @@ -3304,10 +3344,7 @@ public class WebView extends AbsoluteLayout } } - if (nativeCursorIsPlugin()) { - nativeUpdatePluginReceivesEvents(); - invalidate(); - } else if (nativeCursorIsTextInput()) { + if (nativeCursorIsTextInput()) { // This message will put the node in focus, for the DOM's notion // of focus, and make the focuscontroller active mWebViewCore.sendMessage(EventHub.CLICK, nativeCursorFramePointer(), @@ -3316,13 +3353,17 @@ public class WebView extends AbsoluteLayout // our view system's notion of focus rebuildWebTextView(); // Now we need to pass the event to it - return mWebTextView.onKeyDown(keyCode, event); + if (inEditingMode()) { + mWebTextView.setDefaultSelection(); + mWebTextView.mOkayForFocusNotToMatch = true; + return mWebTextView.dispatchKeyEvent(event); + } } else if (nativeHasFocusNode()) { // In this case, the cursor is not on a text input, but the focus // might be. Check it, and if so, hand over to the WebTextView. rebuildWebTextView(); if (inEditingMode()) { - return mWebTextView.onKeyDown(keyCode, event); + return mWebTextView.dispatchKeyEvent(event); } } @@ -3387,7 +3428,13 @@ public class WebView extends AbsoluteLayout mGotCenterDown = false; if (mShiftIsPressed) { - return false; + if (mExtendSelection) { + commitCopy(); + } else { + mExtendSelection = true; + invalidate(); // draw the i-beam instead of the arrow + } + return true; // discard press if copy in progress } // perform the single click @@ -3397,21 +3444,23 @@ public class WebView extends AbsoluteLayout if (!nativeCursorIntersects(visibleRect)) { return false; } - nativeSetFollowedLink(true); - nativeUpdatePluginReceivesEvents(); WebViewCore.CursorData data = cursorData(); mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE, data); playSoundEffect(SoundEffectConstants.CLICK); - boolean isTextInput = nativeCursorIsTextInput(); - if (isTextInput || !mCallbackProxy.uiOverrideUrlLoading( - nativeCursorText())) { + if (nativeCursorIsTextInput()) { + rebuildWebTextView(); + centerKeyPressOnTextField(); + if (inEditingMode()) { + mWebTextView.setDefaultSelection(); + mWebTextView.mOkayForFocusNotToMatch = true; + } + return true; + } + nativeSetFollowedLink(true); + if (!mCallbackProxy.uiOverrideUrlLoading(nativeCursorText())) { mWebViewCore.sendMessage(EventHub.CLICK, data.mFrame, nativeCursorNodePointer()); } - if (isTextInput) { - rebuildWebTextView(); - displaySoftKeyboard(true); - } return true; } @@ -3427,13 +3476,29 @@ public class WebView extends AbsoluteLayout return false; } + private void setUpSelectXY() { + mExtendSelection = false; + mShiftIsPressed = true; + if (nativeHasCursorNode()) { + Rect rect = nativeCursorNodeBounds(); + mSelectX = contentToViewX(rect.left); + mSelectY = contentToViewY(rect.top); + } else if (mLastTouchY > getVisibleTitleHeight()) { + mSelectX = mScrollX + (int) mLastTouchX; + mSelectY = mScrollY + (int) mLastTouchY; + } else { + mSelectX = mScrollX + getViewWidth() / 2; + mSelectY = mScrollY + getViewHeightWithTitle() / 2; + } + nativeHideCursor(); + } + /** * @hide */ public void emulateShiftHeld() { - mExtendSelection = false; - mShiftIsPressed = true; - nativeHideCursor(); + if (0 == mNativeClass) return; // client isn't initialized + setUpSelectXY(); } private boolean commitCopy() { @@ -3451,6 +3516,7 @@ public class WebView extends AbsoluteLayout mExtendSelection = false; } mShiftIsPressed = false; + invalidate(); // remove selection region and pointer if (mTouchMode == TOUCH_SELECT_MODE) { mTouchMode = TOUCH_INIT_MODE; } @@ -3594,6 +3660,24 @@ public class WebView extends AbsoluteLayout super.onFocusChanged(focused, direction, previouslyFocusedRect); } + /** + * @hide + */ + @Override + protected boolean setFrame(int left, int top, int right, int bottom) { + boolean changed = super.setFrame(left, top, right, bottom); + if (!changed && mHeightCanMeasure) { + // When mHeightCanMeasure is true, we will set mLastHeightSent to 0 + // in WebViewCore after we get the first layout. We do call + // requestLayout() when we get contentSizeChanged(). But the View + // system won't call onSizeChanged if the dimension is not changed. + // In this case, we need to call sendViewSizeZoom() explicitly to + // notify the WebKit about the new dimensions. + sendViewSizeZoom(); + } + return changed; + } + @Override protected void onSizeChanged(int w, int h, int ow, int oh) { super.onSizeChanged(w, h, ow, oh); @@ -3702,8 +3786,10 @@ public class WebView extends AbsoluteLayout mLastSentTouchTime = eventTime; } - int deltaX = (int) (mLastTouchX - x); - int deltaY = (int) (mLastTouchY - y); + float fDeltaX = mLastTouchX - x; + float fDeltaY = mLastTouchY - y; + int deltaX = (int) fDeltaX; + int deltaY = (int) fDeltaY; switch (action) { case MotionEvent.ACTION_DOWN: { @@ -3725,6 +3811,7 @@ public class WebView extends AbsoluteLayout nativeMoveSelection(viewToContentX(mSelectX), viewToContentY(mSelectY), false); mTouchSelection = mExtendSelection = true; + invalidate(); // draw the i-beam instead of the arrow } else if (mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) { mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP); if (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare) { @@ -3829,12 +3916,21 @@ public class WebView extends AbsoluteLayout // do pan int newScrollX = pinLocX(mScrollX + deltaX); - deltaX = newScrollX - mScrollX; + int newDeltaX = newScrollX - mScrollX; + if (deltaX != newDeltaX) { + deltaX = newDeltaX; + fDeltaX = (float) newDeltaX; + } int newScrollY = pinLocY(mScrollY + deltaY); - deltaY = newScrollY - mScrollY; + int newDeltaY = newScrollY - mScrollY; + if (deltaY != newDeltaY) { + deltaY = newDeltaY; + fDeltaY = (float) newDeltaY; + } boolean done = false; - if (deltaX == 0 && deltaY == 0) { - done = true; + boolean keepScrollBarsVisible = false; + if (Math.abs(fDeltaX) < 1.0f && Math.abs(fDeltaY) < 1.0f) { + keepScrollBarsVisible = done = true; } else { if (mSnapScrollMode == SNAP_X || mSnapScrollMode == SNAP_Y) { int ax = Math.abs(deltaX); @@ -3846,56 +3942,47 @@ public class WebView extends AbsoluteLayout mSnapScrollMode = SNAP_NONE; } // reverse direction means lock in the snap mode - if ((ax > MAX_SLOPE_FOR_DIAG * ay) && - ((mSnapPositive && - deltaX < -mMinLockSnapReverseDistance) - || (!mSnapPositive && - deltaX > mMinLockSnapReverseDistance))) { - mSnapScrollMode = SNAP_X_LOCK; + if (ax > MAX_SLOPE_FOR_DIAG * ay && + (mSnapPositive + ? deltaX < -mMinLockSnapReverseDistance + : deltaX > mMinLockSnapReverseDistance)) { + mSnapScrollMode |= SNAP_LOCK; } } else { // radical change means getting out of snap mode - if ((ax > MAX_SLOPE_FOR_DIAG * ay) + if (ax > MAX_SLOPE_FOR_DIAG * ay && ax > MIN_BREAK_SNAP_CROSS_DISTANCE) { mSnapScrollMode = SNAP_NONE; } // reverse direction means lock in the snap mode - if ((ay > MAX_SLOPE_FOR_DIAG * ax) && - ((mSnapPositive && - deltaY < -mMinLockSnapReverseDistance) - || (!mSnapPositive && - deltaY > mMinLockSnapReverseDistance))) { - mSnapScrollMode = SNAP_Y_LOCK; + if (ay > MAX_SLOPE_FOR_DIAG * ax && + (mSnapPositive + ? deltaY < -mMinLockSnapReverseDistance + : deltaY > mMinLockSnapReverseDistance)) { + mSnapScrollMode |= SNAP_LOCK; } } } - - if (mSnapScrollMode == SNAP_X - || mSnapScrollMode == SNAP_X_LOCK) { - if (deltaX == 0) { - // keep the scrollbar on the screen even there is no - // scroll - awakenScrollBars(ViewConfiguration - .getScrollDefaultDelay(), false); + if (mSnapScrollMode != SNAP_NONE) { + if ((mSnapScrollMode & SNAP_X) == SNAP_X) { + deltaY = 0; } else { - scrollBy(deltaX, 0); + deltaX = 0; } - mLastTouchX = x; - } else if (mSnapScrollMode == SNAP_Y - || mSnapScrollMode == SNAP_Y_LOCK) { - if (deltaY == 0) { - // keep the scrollbar on the screen even there is no - // scroll - awakenScrollBars(ViewConfiguration - .getScrollDefaultDelay(), false); - } else { - scrollBy(0, deltaY); + } + if ((deltaX | deltaY) != 0) { + scrollBy(deltaX, deltaY); + if (deltaX != 0) { + mLastTouchX = x; + } + if (deltaY != 0) { + mLastTouchY = y; } - mLastTouchY = y; + mHeldMotionless = MOTIONLESS_FALSE; } else { - scrollBy(deltaX, deltaY); - mLastTouchX = x; - mLastTouchY = y; + // keep the scrollbar on the screen even there is no + // scroll + keepScrollBarsVisible = true; } mLastTouchTime = eventTime; mUserScroll = true; @@ -3914,13 +4001,17 @@ public class WebView extends AbsoluteLayout } } - if (done) { + if (keepScrollBarsVisible) { + if (mHeldMotionless != MOTIONLESS_TRUE) { + mHeldMotionless = MOTIONLESS_TRUE; + invalidate(); + } // keep the scrollbar on the screen even there is no scroll awakenScrollBars(ViewConfiguration.getScrollDefaultDelay(), false); // return false to indicate that we can't pan out of the // view space - return false; + return !done; } break; } @@ -3973,6 +4064,9 @@ public class WebView extends AbsoluteLayout break; } case TOUCH_DRAG_MODE: + mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS); + mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS); + mHeldMotionless = MOTIONLESS_TRUE; // redraw in high-quality, as we're done dragging invalidate(); // if the user waits a while w/o moving before the @@ -4012,6 +4106,9 @@ public class WebView extends AbsoluteLayout } mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS); mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); + mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS); + mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS); + mHeldMotionless = MOTIONLESS_TRUE; mTouchMode = TOUCH_DONE_MODE; nativeHideCursor(); break; @@ -4038,6 +4135,7 @@ public class WebView extends AbsoluteLayout private static final int SELECT_CURSOR_OFFSET = 16; private int mSelectX = 0; private int mSelectY = 0; + private boolean mFocusSizeChanged = false; private boolean mShiftIsPressed = false; private boolean mTrackballDown = false; private long mTrackballUpTime = 0; @@ -4096,6 +4194,7 @@ public class WebView extends AbsoluteLayout commitCopy(); } else { mExtendSelection = true; + invalidate(); // draw the i-beam instead of the arrow } return true; // discard press if copy in progress } @@ -4143,8 +4242,8 @@ public class WebView extends AbsoluteLayout return; int width = getViewWidth(); int height = getViewHeight(); - mSelectX += scaleTrackballX(xRate, width); - mSelectY += scaleTrackballY(yRate, height); + mSelectX += xRate; + mSelectY += yRate; int maxX = width + mScrollX; int maxY = height + mScrollY; mSelectX = Math.min(maxX, Math.max(mScrollX - SELECT_CURSOR_OFFSET @@ -4226,8 +4325,11 @@ public class WebView extends AbsoluteLayout } float xRate = mTrackballRemainsX * 1000 / elapsed; float yRate = mTrackballRemainsY * 1000 / elapsed; + int viewWidth = getViewWidth(); + int viewHeight = getViewHeight(); if (mShiftIsPressed) { - moveSelection(xRate, yRate); + moveSelection(scaleTrackballX(xRate, viewWidth), + scaleTrackballY(yRate, viewHeight)); mTrackballRemainsX = mTrackballRemainsY = 0; return; } @@ -4241,8 +4343,8 @@ public class WebView extends AbsoluteLayout + " mTrackballRemainsX=" + mTrackballRemainsX + " mTrackballRemainsY=" + mTrackballRemainsY); } - int width = mContentWidth - getViewWidth(); - int height = mContentHeight - getViewHeight(); + int width = mContentWidth - viewWidth; + int height = mContentHeight - viewHeight; if (width < 0) width = 0; if (height < 0) height = 0; ax = Math.abs(mTrackballRemainsX * TRACKBALL_MULTIPLIER); @@ -4317,7 +4419,7 @@ public class WebView extends AbsoluteLayout int vy = (int) mVelocityTracker.getYVelocity(); if (mSnapScrollMode != SNAP_NONE) { - if (mSnapScrollMode == SNAP_X || mSnapScrollMode == SNAP_X_LOCK) { + if ((mSnapScrollMode & SNAP_X) == SNAP_X) { vy = 0; } else { vx = 0; @@ -4597,21 +4699,21 @@ public class WebView extends AbsoluteLayout } int x = viewToContentX((int) event.getX() + mWebTextView.getLeft()); int y = viewToContentY((int) event.getY() + mWebTextView.getTop()); - // In case the soft keyboard has been dismissed, bring it back up. - InputMethodManager.getInstance(getContext()).showSoftInput(mWebTextView, - 0); if (nativeFocusNodePointer() != nativeCursorNodePointer()) { nativeMotionUp(x, y, mNavSlop); } nativeTextInputMotionUp(x, y); } - /*package*/ void shortPressOnTextField() { - if (inEditingMode()) { - View v = mWebTextView; - int x = viewToContentX((v.getLeft() + v.getRight()) >> 1); - int y = viewToContentY((v.getTop() + v.getBottom()) >> 1); - nativeTextInputMotionUp(x, y); + /** + * Called when pressing the center key or trackball on a textfield. + */ + /*package*/ void centerKeyPressOnTextField() { + mWebViewCore.sendMessage(EventHub.CLICK, nativeCursorFramePointer(), + nativeCursorNodePointer()); + // Need to show the soft keyboard if it's not readonly. + if (!nativeCursorIsReadOnly()) { + displaySoftKeyboard(true); } } @@ -4681,15 +4783,6 @@ public class WebView extends AbsoluteLayout mCallbackProxy.uiOverrideUrlLoading(url); } - // called by JNI - private void sendPluginState(int state) { - WebViewCore.PluginStateData psd = new WebViewCore.PluginStateData(); - psd.mFrame = nativeCursorFramePointer(); - psd.mNode = nativeCursorNodePointer(); - psd.mState = state; - mWebViewCore.sendMessage(EventHub.PLUGIN_STATE, psd); - } - @Override public boolean requestFocus(int direction, Rect previouslyFocusedRect) { boolean result = false; @@ -4838,14 +4931,6 @@ public class WebView extends AbsoluteLayout } /* package */ void passToJavaScript(String currentText, KeyEvent event) { - if (nativeCursorWantsKeyEvents() && !nativeCursorMatchesFocus()) { - mWebViewCore.sendMessage(EventHub.CLICK); - if (mWebTextView.mOkayForFocusNotToMatch) { - int select = nativeFocusCandidateIsTextField() ? - nativeFocusCandidateMaxLength() : 0; - setSelection(select, select); - } - } WebViewCore.JSKeyData arg = new WebViewCore.JSKeyData(); arg.mEvent = event; arg.mCurrentText = currentText; @@ -4876,9 +4961,10 @@ public class WebView extends AbsoluteLayout class PrivateHandler extends Handler { @Override public void handleMessage(Message msg) { - if (DebugFlags.WEB_VIEW) { + // exclude INVAL_RECT_MSG_ID since it is frequently output + if (DebugFlags.WEB_VIEW && msg.what != INVAL_RECT_MSG_ID) { Log.v(LOGTAG, msg.what < REMEMBER_PASSWORD || msg.what - > INVAL_RECT_MSG_ID ? Integer.toString(msg.what) + > REQUEST_KEYBOARD ? Integer.toString(msg.what) : HandlerDebugString[msg.what - REMEMBER_PASSWORD]); } if (mWebViewCore == null) { @@ -5040,6 +5126,9 @@ public class WebView extends AbsoluteLayout / mZoomOverviewWidth, false); } } + if (draw.mFocusSizeChanged && inEditingMode()) { + mFocusSizeChanged = true; + } break; } case WEBCORE_INITIALIZED_MSG_ID: @@ -5080,9 +5169,7 @@ public class WebView extends AbsoluteLayout } break; case MOVE_OUT_OF_PLUGIN: - if (nativePluginEatsNavKey()) { - navHandledKey(msg.arg1, 1, false, 0, true); - } + navHandledKey(msg.arg1, 1, false, 0, true); break; case UPDATE_TEXT_ENTRY_MSG_ID: // this is sent after finishing resize in WebViewCore. Make @@ -5166,9 +5253,29 @@ public class WebView extends AbsoluteLayout hideSoftKeyboard(); } else { displaySoftKeyboard(false); + if (DebugFlags.WEB_VIEW) { + Log.v(LOGTAG, "REQUEST_KEYBOARD" + + " focusCandidateIsPlugin=" + + nativeFocusCandidateIsPlugin()); + } } break; + case DRAG_HELD_MOTIONLESS: + mHeldMotionless = MOTIONLESS_TRUE; + invalidate(); + // fall through to keep scrollbars awake + + case AWAKEN_SCROLL_BARS: + if (mTouchMode == TOUCH_DRAG_MODE + && mHeldMotionless == MOTIONLESS_TRUE) { + awakenScrollBars(ViewConfiguration + .getScrollDefaultDelay(), false); + mPrivateHandler.sendMessageDelayed(mPrivateHandler + .obtainMessage(AWAKEN_SCROLL_BARS), + ViewConfiguration.getScrollDefaultDelay()); + } + break; default: super.handleMessage(msg); break; @@ -5192,8 +5299,16 @@ public class WebView extends AbsoluteLayout // Need these to provide stable ids to my ArrayAdapter, // which normally does not have stable ids. (Bug 1250098) private class Container extends Object { + /** + * Possible values for mEnabled. Keep in sync with OptionStatus in + * WebViewCore.cpp + */ + final static int OPTGROUP = -1; + final static int OPTION_DISABLED = 0; + final static int OPTION_ENABLED = 1; + String mString; - boolean mEnabled; + int mEnabled; int mId; public String toString() { @@ -5214,6 +5329,54 @@ public class WebView extends AbsoluteLayout } @Override + public View getView(int position, View convertView, + ViewGroup parent) { + // Always pass in null so that we will get a new CheckedTextView + // Otherwise, an item which was previously used as an <optgroup> + // element (i.e. has no check), could get used as an <option> + // element, which needs a checkbox/radio, but it would not have + // one. + convertView = super.getView(position, null, parent); + Container c = item(position); + if (c != null && Container.OPTION_ENABLED != c.mEnabled) { + // ListView does not draw dividers between disabled and + // enabled elements. Use a LinearLayout to provide dividers + LinearLayout layout = new LinearLayout(mContext); + layout.setOrientation(LinearLayout.VERTICAL); + if (position > 0) { + View dividerTop = new View(mContext); + dividerTop.setBackgroundResource( + android.R.drawable.divider_horizontal_bright); + layout.addView(dividerTop); + } + + if (Container.OPTGROUP == c.mEnabled) { + // Currently select_dialog_multichoice and + // select_dialog_singlechoice are CheckedTextViews. If + // that changes, the class cast will no longer be valid. + Assert.assertTrue( + convertView instanceof CheckedTextView); + ((CheckedTextView) convertView).setCheckMarkDrawable( + null); + } else { + // c.mEnabled == Container.OPTION_DISABLED + // Draw the disabled element in a disabled state. + convertView.setEnabled(false); + } + + layout.addView(convertView); + if (position < getCount() - 1) { + View dividerBottom = new View(mContext); + dividerBottom.setBackgroundResource( + android.R.drawable.divider_horizontal_bright); + layout.addView(dividerBottom); + } + return layout; + } + return convertView; + } + + @Override public boolean hasStableIds() { // AdapterView's onChanged method uses this to determine whether // to restore the old state. Return false so that the old (out @@ -5248,12 +5411,11 @@ public class WebView extends AbsoluteLayout if (item == null) { return false; } - return item.mEnabled; + return Container.OPTION_ENABLED == item.mEnabled; } } - private InvokeListBox(String[] array, - boolean[] enabled, int[] selected) { + private InvokeListBox(String[] array, int[] enabled, int[] selected) { mMultiple = true; mSelectedArray = selected; @@ -5267,8 +5429,7 @@ public class WebView extends AbsoluteLayout } } - private InvokeListBox(String[] array, boolean[] enabled, int - selection) { + private InvokeListBox(String[] array, int[] enabled, int selection) { mSelection = selection; mMultiple = false; @@ -5399,10 +5560,11 @@ public class WebView extends AbsoluteLayout * Request a dropdown menu for a listbox with multiple selection. * * @param array Labels for the listbox. - * @param enabledArray Which positions are enabled. + * @param enabledArray State for each element in the list. See static + * integers in Container class. * @param selectedArray Which positions are initally selected. */ - void requestListBox(String[] array, boolean[]enabledArray, int[] + void requestListBox(String[] array, int[] enabledArray, int[] selectedArray) { mPrivateHandler.post( new InvokeListBox(array, enabledArray, selectedArray)); @@ -5413,10 +5575,11 @@ public class WebView extends AbsoluteLayout * <select> element. * * @param array Labels for the listbox. - * @param enabledArray Which positions are enabled. + * @param enabledArray State for each element in the list. See static + * integers in Container class. * @param selection Which position is initally selected. */ - void requestListBox(String[] array, boolean[]enabledArray, int selection) { + void requestListBox(String[] array, int[] enabledArray, int selection) { mPrivateHandler.post( new InvokeListBox(array, enabledArray, selection)); } @@ -5500,7 +5663,7 @@ public class WebView extends AbsoluteLayout if (mNativeClass == 0) { return false; } - if (ignorePlugin == false && nativePluginEatsNavKey()) { + if (ignorePlugin == false && nativeFocusIsPlugin()) { KeyEvent event = new KeyEvent(time, time, KeyEvent.ACTION_DOWN , keyCode, count, (mShiftIsPressed ? KeyEvent.META_SHIFT_ON : 0) | (false ? KeyEvent.META_ALT_ON : 0) // FIXME @@ -5575,6 +5738,17 @@ public class WebView extends AbsoluteLayout } /** + * Draw the HTML page into the specified canvas. This call ignores any + * view-specific zoom, scroll offset, or other changes. It does not draw + * any view-specific chrome, such as progress or URL bars. + * + * @hide only needs to be accessible to Browser and testing + */ + public void drawPage(Canvas canvas) { + mWebViewCore.drawContentPicture(canvas, 0, false, false); + } + + /** * Update our cache with updatedText. * @param updatedText The new text to put in our cache. */ @@ -5592,7 +5766,7 @@ public class WebView extends AbsoluteLayout /* package */ native boolean nativeCursorMatchesFocus(); private native boolean nativeCursorIntersects(Rect visibleRect); private native boolean nativeCursorIsAnchor(); - private native boolean nativeCursorIsPlugin(); + private native boolean nativeCursorIsReadOnly(); private native boolean nativeCursorIsTextInput(); private native Point nativeCursorPosition(); private native String nativeCursorText(); @@ -5605,13 +5779,15 @@ public class WebView extends AbsoluteLayout private native void nativeDestroy(); private native void nativeDrawCursorRing(Canvas content); private native void nativeDrawMatches(Canvas canvas); - private native void nativeDrawSelection(Canvas content, float scale, - int offset, int x, int y, boolean extendSelection); + private native void nativeDrawSelectionPointer(Canvas content, + float scale, int x, int y, boolean extendSelection); private native void nativeDrawSelectionRegion(Canvas content); private native void nativeDumpDisplayTree(String urlOrNull); private native int nativeFindAll(String findLower, String findUpper); private native void nativeFindNext(boolean forward); + private native int nativeFocusCandidateFramePointer(); private native boolean nativeFocusCandidateIsPassword(); + private native boolean nativeFocusCandidateIsPlugin(); private native boolean nativeFocusCandidateIsRtlText(); private native boolean nativeFocusCandidateIsTextField(); private native boolean nativeFocusCandidateIsTextInput(); @@ -5621,6 +5797,7 @@ public class WebView extends AbsoluteLayout /* package */ native int nativeFocusCandidatePointer(); private native String nativeFocusCandidateText(); private native int nativeFocusCandidateTextSize(); + private native boolean nativeFocusIsPlugin(); /* package */ native int nativeFocusNodePointer(); private native Rect nativeGetCursorRingBounds(); private native Region nativeGetSelection(); @@ -5638,7 +5815,6 @@ public class WebView extends AbsoluteLayout private native int nativeMoveGeneration(); private native void nativeMoveSelection(int x, int y, boolean extendSelection); - private native boolean nativePluginEatsNavKey(); // 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 focused, @@ -5660,7 +5836,6 @@ public class WebView extends AbsoluteLayout // we always want to pass in our generation number. private native void nativeUpdateCachedTextfield(String updatedText, int generation); - private native void nativeUpdatePluginReceivesEvents(); // return NO_LEFTEDGE means failure. private static final int NO_LEFTEDGE = -1; private native int nativeGetBlockLeftEdge(int x, int y, float scale); diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 86685fb..6505ee2 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -18,6 +18,7 @@ package android.webkit; import android.content.Context; import android.content.Intent; +import android.database.Cursor; import android.graphics.Canvas; import android.graphics.DrawFilter; import android.graphics.Paint; @@ -26,11 +27,13 @@ import android.graphics.Picture; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; +import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Process; import android.provider.Browser; +import android.provider.OpenableColumns; import android.util.Log; import android.util.SparseBooleanArray; import android.view.KeyEvent; @@ -273,6 +276,39 @@ final class WebViewCore { mCallbackProxy.onJsAlert(url, message); } + + /** + * Called by JNI. Open a file chooser to upload a file. + * @return String version of the URI plus the name of the file. + * FIXME: Just return the URI here, and in FileSystem::pathGetFileName, call + * into Java to get the filename. + */ + private String openFileChooser() { + Uri uri = mCallbackProxy.openFileChooser(); + if (uri == null) return ""; + // Find out the name, and append it to the URI. + // Webkit will treat the name as the filename, and + // the URI as the path. The URI will be used + // in BrowserFrame to get the actual data. + Cursor cursor = mContext.getContentResolver().query( + uri, + new String[] { OpenableColumns.DISPLAY_NAME }, + null, + null, + null); + String name = ""; + if (cursor != null) { + try { + if (cursor.moveToNext()) { + name = cursor.getString(0); + } + } finally { + cursor.close(); + } + } + return uri.toString() + "/" + name; + } + /** * Notify the browser that the origin has exceeded it's database quota. * @param url The URL that caused the overflow. @@ -422,6 +458,8 @@ final class WebViewCore { */ private native boolean nativeRecordContent(Region invalRegion, Point wh); + private native boolean nativeFocusBoundsChanged(); + /** * Splits slow parts of the picture set. Called from the webkit * thread after nativeDrawContent returns true. @@ -522,8 +560,6 @@ final class WebViewCore { */ private native void nativeSetNewStorageLimit(long limit); - private native void nativeUpdatePluginState(int framePtr, int nodePtr, int state); - /** * Provide WebCore with a Geolocation permission state for the specified * origin. @@ -678,12 +714,6 @@ final class WebViewCore { int mY; } - static class PluginStateData { - int mFrame; - int mNode; - int mState; - } - static class GeolocationPermissionsData { String mOrigin; boolean mAllow; @@ -720,7 +750,7 @@ final class WebViewCore { "SINGLE_LISTBOX_CHOICE", // = 124; "MESSAGE_RELAY", // = 125; "SET_BACKGROUND_COLOR", // = 126; - "PLUGIN_STATE", // = 127; + "127", // = 127 "SAVE_DOCUMENT_STATE", // = 128; "GET_SELECTION", // = 129; "WEBKIT_DRAW", // = 130; @@ -771,7 +801,6 @@ final class WebViewCore { static final int SINGLE_LISTBOX_CHOICE = 124; static final int MESSAGE_RELAY = 125; static final int SET_BACKGROUND_COLOR = 126; - static final int PLUGIN_STATE = 127; // plugin notifications static final int SAVE_DOCUMENT_STATE = 128; static final int GET_SELECTION = 129; static final int WEBKIT_DRAW = 130; @@ -1031,11 +1060,6 @@ final class WebViewCore { nativeFreeMemory(); break; - case PLUGIN_STATE: - PluginStateData psd = (PluginStateData) msg.obj; - nativeUpdatePluginState(psd.mFrame, psd.mNode, psd.mState); - break; - case SET_NETWORK_STATE: if (BrowserFrame.sJavaBridge == null) { throw new IllegalStateException("No WebView " + @@ -1593,6 +1617,7 @@ final class WebViewCore { int mMinPrefWidth; RestoreState mRestoreState; // only non-null if it is for the first // picture set after the first layout + boolean mFocusSizeChanged; } private void webkitDraw() { @@ -1607,6 +1632,7 @@ final class WebViewCore { if (mWebView != null) { // Send the native view size that was used during the most recent // layout. + draw.mFocusSizeChanged = nativeFocusBoundsChanged(); draw.mViewPoint = new Point(mCurrentViewWidth, mCurrentViewHeight); if (mSettings.getUseWideViewPort()) { draw.mMinPrefWidth = Math.max( @@ -1643,8 +1669,9 @@ final class WebViewCore { final DrawFilter mZoomFilter = new PaintFlagsDrawFilter(ZOOM_BITS, Paint.LINEAR_TEXT_FLAG); - final DrawFilter mScrollFilter = - new PaintFlagsDrawFilter(SCROLL_BITS, 0); + final DrawFilter mScrollFilter = null; + // If we need to trade more speed for less quality on slower devices + // use this: new PaintFlagsDrawFilter(SCROLL_BITS, 0); /* package */ void drawContentPicture(Canvas canvas, int color, boolean animatingZoom, @@ -2101,7 +2128,7 @@ final class WebViewCore { private native void nativeSetGlobalBounds(int x, int y, int w, int h); // called by JNI - private void requestListBox(String[] array, boolean[] enabledArray, + private void requestListBox(String[] array, int[] enabledArray, int[] selectedArray) { if (mWebView != null) { mWebView.requestListBox(array, enabledArray, selectedArray); @@ -2109,7 +2136,7 @@ final class WebViewCore { } // called by JNI - private void requestListBox(String[] array, boolean[] enabledArray, + private void requestListBox(String[] array, int[] enabledArray, int selection) { if (mWebView != null) { mWebView.requestListBox(array, enabledArray, selection); @@ -2175,6 +2202,11 @@ final class WebViewCore { return view; } + private void updateSurface(ViewManager.ChildView childView, int x, int y, + int width, int height) { + childView.attachView(x, y, width, height); + } + private void destroySurface(ViewManager.ChildView childView) { childView.removeView(); } diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java index 6e10811..110e4f8 100644 --- a/core/java/android/webkit/WebViewDatabase.java +++ b/core/java/android/webkit/WebViewDatabase.java @@ -27,6 +27,7 @@ import android.content.Context; import android.database.Cursor; import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteStatement; import android.util.Log; import android.webkit.CookieManager.Cookie; @@ -174,7 +175,16 @@ public class WebViewDatabase { public static synchronized WebViewDatabase getInstance(Context context) { if (mInstance == null) { mInstance = new WebViewDatabase(); - mDatabase = context.openOrCreateDatabase(DATABASE_FILE, 0, null); + try { + mDatabase = context + .openOrCreateDatabase(DATABASE_FILE, 0, null); + } catch (SQLiteException e) { + // try again by deleting the old db and create a new one + if (context.deleteDatabase(DATABASE_FILE)) { + mDatabase = context.openOrCreateDatabase(DATABASE_FILE, 0, + null); + } + } // mDatabase should not be null, // the only case is RequestAPI test has problem to create db @@ -194,8 +204,16 @@ public class WebViewDatabase { mDatabase.setLockingEnabled(false); } - mCacheDatabase = context.openOrCreateDatabase(CACHE_DATABASE_FILE, - 0, null); + try { + mCacheDatabase = context.openOrCreateDatabase( + CACHE_DATABASE_FILE, 0, null); + } catch (SQLiteException e) { + // try again by deleting the old db and create a new one + if (context.deleteDatabase(CACHE_DATABASE_FILE)) { + mCacheDatabase = context.openOrCreateDatabase( + CACHE_DATABASE_FILE, 0, null); + } + } // mCacheDatabase should not be null, // the only case is RequestAPI test has problem to create db diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 165794a..5991ad4 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -3560,6 +3560,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te // into the scrap heap int viewType = lp.viewType; if (!shouldRecycleViewType(viewType)) { + removeDetachedView(scrap, false); return; } diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java index fd590ed..aa9062b 100644 --- a/core/java/android/widget/CheckedTextView.java +++ b/core/java/android/widget/CheckedTextView.java @@ -117,11 +117,11 @@ public class CheckedTextView extends TextView implements Checkable { * @param d The Drawable to use for the checkmark. */ public void setCheckMarkDrawable(Drawable d) { + if (mCheckMarkDrawable != null) { + mCheckMarkDrawable.setCallback(null); + unscheduleDrawable(mCheckMarkDrawable); + } if (d != null) { - if (mCheckMarkDrawable != null) { - mCheckMarkDrawable.setCallback(null); - unscheduleDrawable(mCheckMarkDrawable); - } d.setCallback(this); d.setVisible(getVisibility() == VISIBLE, false); d.setState(CHECKED_STATE_SET); @@ -130,10 +130,10 @@ public class CheckedTextView extends TextView implements Checkable { mCheckMarkWidth = d.getIntrinsicWidth(); mPaddingRight = mCheckMarkWidth + mBasePaddingRight; d.setState(getDrawableState()); - mCheckMarkDrawable = d; } else { mPaddingRight = mBasePaddingRight; } + mCheckMarkDrawable = d; requestLayout(); } diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java index 8019f14..07c3e4b 100644 --- a/core/java/android/widget/QuickContactBadge.java +++ b/core/java/android/widget/QuickContactBadge.java @@ -25,9 +25,9 @@ import android.database.Cursor; import android.graphics.drawable.Drawable; import android.net.Uri; import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.QuickContact; import android.provider.ContactsContract.Intents; import android.provider.ContactsContract.PhoneLookup; +import android.provider.ContactsContract.QuickContact; import android.provider.ContactsContract.RawContacts; import android.provider.ContactsContract.CommonDataKinds.Email; import android.util.AttributeSet; @@ -55,21 +55,28 @@ public class QuickContactBadge extends ImageView implements OnClickListener { static final private int TOKEN_PHONE_LOOKUP = 1; static final private int TOKEN_EMAIL_LOOKUP_AND_TRIGGER = 2; static final private int TOKEN_PHONE_LOOKUP_AND_TRIGGER = 3; + static final private int TOKEN_CONTACT_LOOKUP_AND_TRIGGER = 4; static final String[] EMAIL_LOOKUP_PROJECTION = new String[] { RawContacts.CONTACT_ID, Contacts.LOOKUP_KEY, }; - static int EMAIL_ID_COLUMN_INDEX = 0; - static int EMAIL_LOOKUP_STRING_COLUMN_INDEX = 1; + static final int EMAIL_ID_COLUMN_INDEX = 0; + static final int EMAIL_LOOKUP_STRING_COLUMN_INDEX = 1; static final String[] PHONE_LOOKUP_PROJECTION = new String[] { PhoneLookup._ID, PhoneLookup.LOOKUP_KEY, }; - static int PHONE_ID_COLUMN_INDEX = 0; - static int PHONE_LOOKUP_STRING_COLUMN_INDEX = 1; + static final int PHONE_ID_COLUMN_INDEX = 0; + static final int PHONE_LOOKUP_STRING_COLUMN_INDEX = 1; + static final String[] CONTACT_LOOKUP_PROJECTION = new String[] { + Contacts._ID, + Contacts.LOOKUP_KEY, + }; + static final int CONTACT_ID_COLUMN_INDEX = 0; + static final int CONTACT_LOOKUPKEY_COLUMN_INDEX = 1; public QuickContactBadge(Context context) { @@ -181,9 +188,9 @@ public class QuickContactBadge extends ImageView implements OnClickListener { public void onClick(View v) { if (mContactUri != null) { - final ContentResolver resolver = getContext().getContentResolver(); - final Uri lookupUri = Contacts.getLookupUri(resolver, mContactUri); - trigger(lookupUri); + mQueryHandler.startQuery(TOKEN_CONTACT_LOOKUP_AND_TRIGGER, null, + mContactUri, + CONTACT_LOOKUP_PROJECTION, null, null, null); } else if (mContactEmail != null) { mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, mContactEmail, Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)), @@ -249,6 +256,17 @@ public class QuickContactBadge extends ImageView implements OnClickListener { lookupUri = Contacts.getLookupUri(contactId, lookupKey); } } + + case TOKEN_CONTACT_LOOKUP_AND_TRIGGER: { + if (cursor != null && cursor.moveToFirst()) { + long contactId = cursor.getLong(CONTACT_ID_COLUMN_INDEX); + String lookupKey = cursor.getString(CONTACT_LOOKUPKEY_COLUMN_INDEX); + lookupUri = Contacts.getLookupUri(contactId, lookupKey); + trigger = true; + } + + break; + } } } finally { if (cursor != null) { diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index bf3d26e..3ed995b 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -5198,7 +5198,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mDesiredHeightAtMeasure = desired; if (heightMode == MeasureSpec.AT_MOST) { - height = Math.min(desired, height); + height = Math.min(desired, heightSize); } } diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp index 38f3fda..46000c9 100644 --- a/core/jni/android_net_wifi_Wifi.cpp +++ b/core/jni/android_net_wifi_Wifi.cpp @@ -20,6 +20,7 @@ #include <utils/misc.h> #include <android_runtime/AndroidRuntime.h> #include <utils/Log.h> +#include <utils/String16.h> #include "wifi.h" @@ -92,7 +93,8 @@ static jstring doStringCommand(JNIEnv *env, const char *cmd) if (doCommand(cmd, reply, sizeof(reply)) != 0) { return env->NewStringUTF(NULL); } else { - return env->NewStringUTF(reply); + String16 str((char *)reply); + return env->NewString((const jchar *)str.string(), str.size()); } } diff --git a/core/res/assets/images/combobox-disabled.png b/core/res/assets/images/combobox-disabled.png Binary files differindex 42fc0c5..fe220e4 100644 --- a/core/res/assets/images/combobox-disabled.png +++ b/core/res/assets/images/combobox-disabled.png diff --git a/core/res/assets/images/combobox-noHighlight.png b/core/res/assets/images/combobox-noHighlight.png Binary files differindex 838dc65..abcdf72 100644 --- a/core/res/assets/images/combobox-noHighlight.png +++ b/core/res/assets/images/combobox-noHighlight.png diff --git a/core/res/assets/webkit/youtube.html b/core/res/assets/webkit/youtube.html index 2aaaa15..45d9c5e 100644 --- a/core/res/assets/webkit/youtube.html +++ b/core/res/assets/webkit/youtube.html @@ -30,14 +30,8 @@ </head> <body> <div id="bg"> - <table height="100%" width="100%" border="0" cellpadding="0" - cellspacing="0"> - <tr> - <td valign="middle"> - <img src="http://img.youtube.com/vi/VIDEO_ID/0.jpg" width="100%"/> - </td> - </tr> - </table> + <img src="http://img.youtube.com/vi/VIDEO_ID/0.jpg" + style="width:100%; height:100%"/> </div> <div id="main"> <table height="100%" width="100%"> diff --git a/core/res/res/layout/alert_dialog.xml b/core/res/res/layout/alert_dialog.xml index cf2de05..40e3f42 100644 --- a/core/res/res/layout/alert_dialog.xml +++ b/core/res/res/layout/alert_dialog.xml @@ -50,11 +50,11 @@ android:paddingTop="6dip" android:paddingRight="10dip" android:src="@drawable/ic_dialog_info" /> - <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle" + <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle" style="?android:attr/textAppearanceLarge" android:singleLine="true" android:ellipsize="end" - android:layout_width="fill_parent" + android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> <ImageView android:id="@+id/titleDivider" @@ -63,9 +63,7 @@ android:visibility="gone" android:scaleType="fitXY" android:gravity="fill_horizontal" - android:src="@android:drawable/dialog_divider_horizontal_light" - android:layout_marginLeft="10dip" - android:layout_marginRight="10dip"/> + android:src="@android:drawable/divider_horizontal_dark" /> <!-- If the client uses a customTitle, it will be added here. --> </LinearLayout> @@ -88,7 +86,7 @@ android:padding="5dip" /> </ScrollView> </LinearLayout> - + <FrameLayout android:id="@+id/customPanel" android:layout_width="fill_parent" android:layout_height="wrap_content" @@ -99,13 +97,13 @@ android:paddingTop="5dip" android:paddingBottom="5dip" /> </FrameLayout> - + <LinearLayout android:id="@+id/buttonPanel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:minHeight="54dip" - android:orientation="vertical" > - <LinearLayout + android:orientation="vertical" > + <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" diff --git a/core/res/res/layout/grant_credentials_permission.xml b/core/res/res/layout/grant_credentials_permission.xml index fe1c22e..84b6623 100644 --- a/core/res/res/layout/grant_credentials_permission.xml +++ b/core/res/res/layout/grant_credentials_permission.xml @@ -1,41 +1,163 @@ <?xml version="1.0" encoding="utf-8"?> <!-- -/* -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ +/** + * Copyright (c) 2008, 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. + */ --> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> + android:layout_height="fill_parent"> + + <!-- The header --> <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:id="@+id/message" /> - <Button android:id="@+id/allow" + android:id="@+id/header_text" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="@string/allow" /> + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="@color/white" + android:textStyle="bold" + android:text="@string/grant_permissions_header_text" + android:shadowColor="@color/shadow" + android:shadowRadius="2" + android:singleLine="true" + android:background="@drawable/title_bar_medium" + android:gravity="left|center_vertical" + android:paddingLeft="19dip" + android:ellipsize="marquee" /> - <Button android:id="@+id/deny" + <!-- The list of packages that correspond to the requesting UID + and the account/authtokenType that is being requested --> + <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="@string/deny" /> + android:fillViewport="true" + android:layout_weight="1" + android:gravity="top|center_horizontal" + android:foreground="@drawable/title_bar_shadow"> + + <LinearLayout + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:paddingTop="14dip" + android:orientation="vertical"> + + <TextView + android:id="@+id/grant_credentials_permission_message_header" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/grant_credentials_permission_message_header" + android:textAppearance="?android:attr/textAppearanceMedium" + android:paddingLeft="19dip" + android:paddingBottom="12dip" /> + + <LinearLayout + android:id="@+id/packages_list" + android:orientation="vertical" + android:paddingLeft="16dip" + android:paddingRight="12dip" + android:layout_width="fill_parent" + android:layout_height="wrap_content" /> + + <RelativeLayout + android:paddingLeft="16dip" + android:paddingRight="12dip" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + + <ImageView + android:id="@+id/permission_icon" + android:layout_width="30dip" + android:layout_height="30dip" + android:src="@drawable/ic_bullet_key_permission" + android:layout_alignParentLeft="true" + android:scaleType="fitCenter" /> + + <TextView + android:id="@+id/account_type" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="@color/perms_dangerous_perm_color" + android:textStyle="bold" + android:paddingLeft="6dip" + android:layout_toRightOf="@id/permission_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> - <ListView android:id="@+id/packages_list" - android:layout_width="fill_parent" android:layout_height="fill_parent"/> + <TextView + android:id="@+id/account_name" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="@color/perms_dangerous_perm_color" + android:layout_marginTop="-4dip" + android:paddingBottom="8dip" + android:paddingLeft="6dip" + android:layout_below="@id/account_type" + android:layout_toRightOf="@id/permission_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + <TextView + android:id="@+id/authtoken_type" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="@color/perms_dangerous_perm_color" + android:textStyle="bold" + android:layout_marginTop="-4dip" + android:paddingBottom="8dip" + android:paddingLeft="6dip" + android:layout_below="@id/account_name" + android:layout_toRightOf="@id/permission_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + </RelativeLayout> + + <TextView + android:id="@+id/grant_credentials_permission_message_footer" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/grant_credentials_permission_message_footer" + android:textAppearance="?android:attr/textAppearanceMedium" + android:paddingLeft="19dip" + android:paddingBottom="12dip" /> + </LinearLayout> + </ScrollView> + + <!-- The buttons to allow or deny --> + <LinearLayout + android:id="@+id/buttons" + android:layout_width="fill_parent" + android:layout_height="52dip" + android:background="@drawable/bottom_bar" + android:paddingTop="4dip" + android:paddingLeft="2dip" + android:paddingRight="2dip"> + + <Button + android:id="@+id/allow_button" + android:text="@string/allow" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="2" /> + + <Button + android:id="@+id/deny_button" + android:text="@string/deny" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="2" /> + + </LinearLayout> </LinearLayout> + diff --git a/core/res/res/layout/permissions_account_and_authtokentype.xml b/core/res/res/layout/permissions_account_and_authtokentype.xml new file mode 100644 index 0000000..4494a2c --- /dev/null +++ b/core/res/res/layout/permissions_account_and_authtokentype.xml @@ -0,0 +1,67 @@ +<?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. +--> + +<!-- + Defines the layout of an account and authtoken type permission item. + Contains an icon, the account type and name and the authtoken type. +--> + +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + + <ImageView + android:id="@+id/permission_icon" + android:layout_width="30dip" + android:layout_height="30dip" + android:drawable="@drawable/ic_bullet_key_permission" + android:layout_alignParentLeft="true" + android:scaleType="fitCenter" /> + + + <TextView + android:id="@+id/account_type" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textStyle="bold" + android:paddingLeft="6dip" + android:layout_toRightOf="@id/permission_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <TextView + android:id="@+id/account_name" + android:textAppearance="?android:attr/textAppearanceSmall" + android:layout_marginTop="-4dip" + android:paddingBottom="8dip" + android:paddingLeft="6dip" + android:layout_below="@id/account_type" + android:layout_toRightOf="@id/permission_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <TextView + android:id="@+id/authtoken_type" + android:textAppearance="?android:attr/textAppearanceSmall" + android:layout_marginTop="-4dip" + android:paddingBottom="8dip" + android:paddingLeft="6dip" + android:layout_below="@id/account_name" + android:layout_toRightOf="@id/permission_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + +</RelativeLayout> diff --git a/core/res/res/layout/permissions_package_list_item.xml b/core/res/res/layout/permissions_package_list_item.xml new file mode 100644 index 0000000..1bffe51 --- /dev/null +++ b/core/res/res/layout/permissions_package_list_item.xml @@ -0,0 +1,45 @@ +<?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. +--> + +<!-- + Defines the layout of a single package item. + Contains a bullet point icon and the name of the package. +--> + +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + + <ImageView + android:id="@+id/package_icon" + android:layout_width="30dip" + android:layout_height="30dip" + android:layout_alignParentLeft="true" + android:src="@drawable/ic_text_dot" + android:scaleType="fitCenter" /> + + + <TextView + android:id="@+id/package_label" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textStyle="bold" + android:paddingLeft="6dip" + android:layout_toRightOf="@id/package_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + +</RelativeLayout> diff --git a/core/res/res/layout/screen_title_icons.xml b/core/res/res/layout/screen_title_icons.xml index 4d7a6c8..5415909 100644 --- a/core/res/res/layout/screen_title_icons.xml +++ b/core/res/res/layout/screen_title_icons.xml @@ -66,22 +66,25 @@ This is the basic layout for a screen, with all of its features enabled. android:layout_toLeftOf="@id/progress_circular" android:layout_toRightOf="@android:id/left_icon" > - <!-- 2dip between the icon and the title text, if icon is present. --> - <ImageView android:id="@android:id/right_icon" - android:visibility="gone" - android:layout_width="16dip" - android:layout_height="16dip" - android:layout_gravity="center_vertical" - android:scaleType="fitCenter" - android:layout_marginRight="2dip" /> <TextView android:id="@android:id/title" style="?android:attr/windowTitleStyle" - android:layout_width="fill_parent" + android:layout_width="0dip" android:layout_height="fill_parent" + android:layout_weight="1" android:background="@null" android:fadingEdge="horizontal" android:scrollHorizontally="true" android:gravity="center_vertical" + android:layout_marginRight="2dip" + /> + <!-- 2dip between the icon and the title text, if icon is present. --> + <ImageView android:id="@android:id/right_icon" + android:visibility="gone" + android:layout_width="16dip" + android:layout_height="16dip" + android:layout_weight="0" + android:layout_gravity="center_vertical" + android:scaleType="fitCenter" /> </LinearLayout> </RelativeLayout> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index f93fb01..67fac9f 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"K souboru nelze získat přístup."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Požadovaný soubor nebyl nalezen."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Je zpracováváno příliš mnoho požadavků. Opakujte akci později."</string> - <string name="notification_title" msgid="1259940370369187045">"Chyba přihlášení k účtu <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Synchronizace"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchronizace"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Příliš mnoho smazaných položek služby <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Sleduje vaši fyzickou polohu"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Síťová komunikace"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Umožňuje aplikacím získat přístup k různým funkcím sítě."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Vaše účty"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Přístup k dostupným účtům."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Řízení hardwaru"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Přímý přístup k hardwaru telefonu."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Telefonní hovory"</string> @@ -316,7 +319,7 @@ <string name="permlab_callPrivileged" msgid="4198349211108497879">"přímé volání na libovolná telefonní čísla"</string> <string name="permdesc_callPrivileged" msgid="244405067160028452">"Umožňuje aplikaci bez vašeho zásahu vytočit jakékoli telefonní číslo, včetně čísel tísňového volání. Škodlivé aplikace mohou provádět zbytečná a nezákonná volání na tísňové linky."</string> <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"přímo spustit nastavení telefonu CDMA"</string> - <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Umožňuje aplikaci zahájit poskytování CDMA. Škodlivé aplikace mohou poskytování CDMA zahájit samovolně."</string> + <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Umožňuje aplikaci zahájit zřizování CDMA. Škodlivé aplikace mohou zřizování CDMA zahájit samovolně."</string> <string name="permlab_locationUpdates" msgid="7785408253364335740">"ovládání oznámení o aktualizaci polohy"</string> <string name="permdesc_locationUpdates" msgid="2300018303720930256">"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" msgid="7855259461268734914">"přístup k vlastnostem Checkin"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Vlastní"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Domů"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobil"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Práce"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Pracovní fax"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Domácí fax"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Pager"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Jiné"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Zpětné volání"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Auto"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Firma (hlavní)"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Hlavní"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Jiný fax"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Radiotelefon"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"Telefon pro sluchově postižené (TTY/TDD)"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Pracovní mobil"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Pracovní pager"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Asistent"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Narozeniny"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Výročí"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Událost"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Vlastní"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Domů"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Práce"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Jiné"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Vlastní"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Domů"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Práce"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Jiné"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Vlastní"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Domů"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Práce"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Jiné"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Vlastní"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Práce"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Jiné"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Vlastní"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"pomocí <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> pomocí <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Zadejte kód PIN"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Nesprávný kód PIN"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Chcete-li telefon odemknout, stiskněte Menu a poté 0."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Zkuste to prosím znovu"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Nabíjení (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Nabito."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Připojte dobíjecí zařízení."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Není vložena SIM karta."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"V telefonu není žádná karta SIM."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Nabíjení..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Prosím připojte dobíjecí zařízení"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Baterie je vybitá:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"Zbývá <xliff:g id="NUMBER">%d%%</xliff:g> nebo méně."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Využití baterie"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Test továrního nastavení se nezdařil"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"Test FACTORY_TEST lze provést pouze u balíčků nainstalovaných ve složce /system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"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" msgid="6860261758665825069">"Potvrdit"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Tip: Dvojitým klepnutím můžete zobrazení přiblížit nebo oddálit."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"čtení historie a záložek Prohlížeče"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Umožňuje aplikaci číst všechny navštívené adresy URL a záložky Prohlížeče."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"zápis do historie a záložek Prohlížeče"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"Opravdu chcete kartu SD naformátovat? Všechna data na kartě budou ztracena."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formátovat"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes rozhraní USB připojeno"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Vyberte, chcete-li zakázat ladění USB."</string> - <string name="select_input_method" msgid="6865512749462072765">"Výběr metody zadávání dat"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Vytvořit kontakt"\n"pro <xliff:g id="NUMBER">%s</xliff:g>."</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"Zaškrtnuto"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"Nezaškrtnuto"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Uvedené aplikace od <xliff:g id="APPLICATION">%2$s</xliff:g> požadují oprávnění přistupovat k přihlašovacím údajům účtu <xliff:g id="ACCOUNT">%1$s</xliff:g>. Chcete toto oprávnění udělit? Pokud je udělíte, vaše odpověď se uloží a tato výzva se již nebude zobrazovat."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Uvedené aplikace požadují od <xliff:g id="APPLICATION">%3$s</xliff:g> oprávnění přistupovat k přihlašovacím údajům (typ: <xliff:g id="TYPE">%1$s</xliff:g>) účtu <xliff:g id="ACCOUNT">%2$s</xliff:g>. Chcete toto oprávnění udělit? Pokud je udělíte, vaše odpověď se uloží a tato výzva se již nebude zobrazovat."</string> <string name="allow" msgid="7225948811296386551">"Povolit"</string> <string name="deny" msgid="2081879885755434506">"Odepřít"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Požadováno oprávnění"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Požadováno oprávnění"\n"pro účet <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Metoda zadávání dat"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Synchronizace"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Usnadnění"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Změnit tapetu"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Protokol PPTP (Point-to-Point Tunneling Protocol)"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Protokol L2TP (Layer 2 Tunneling Protocol)"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"Síť VPN L2TP/IPSec s předsdíleným klíčem"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"Síť VPN L2TP/IPSec s certifikátem"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index fa89fea..7b37709 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Der kunne ikke oprettes adgang til filen."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Den anmodede fil blev ikke fundet."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Der behandles for mange anmodninger. Prøv igen senere."</string> - <string name="notification_title" msgid="1259940370369187045">"Loginfejl for <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Synkroniser"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synkroniser"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"For mange <xliff:g id="CONTENT_TYPE">%s</xliff:g> sletninger"</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Overvåg din fysiske placering"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Netværkskommunikation"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Tillader programmer at få adgang til forskellige netværksfunktioner."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Dine konti"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Få adgang til de tilgængelige konti."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Hardwarekontroller"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Direkte adgang til hardware på håndsættet."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Telefonopkald"</string> @@ -212,7 +215,7 @@ <string name="permlab_backup" msgid="470013022865453920">"kontroller sikkerhedskopiering af system, og gendan"</string> <string name="permdesc_backup" msgid="4837493065154256525">"Tillader et program at kontrollere systemets sikkerhedskopierings- og gendannelsesmekanisme. Ikke til brug til normale programmer."</string> <string name="permlab_backup_data" msgid="4057625941707926463">"Sikkerhedskopier og gendan programmets data"</string> - <string name="permdesc_backup_data" msgid="8274426305151227766">"Tillader et program at deltage i systemets sikkerhedskopierings- og gendannelsesmekanisme."</string> + <string name="permdesc_backup_data" msgid="8274426305151227766">"Tillader et program at kontrollere systemets sikkerhedskopierings- og gendannelsesmekanisme."</string> <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"vis uautoriserede vinduer"</string> <string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"Tillader oprettelse af vinduer, der er beregnet til at blive brugt af den interne systembrugergrænseflade. Ikke til brug for normale programmer."</string> <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"vis underretninger på systemniveau"</string> @@ -316,7 +319,7 @@ <string name="permlab_callPrivileged" msgid="4198349211108497879">"ring direkte op til alle telefonnumre"</string> <string name="permdesc_callPrivileged" msgid="244405067160028452">"Tillader programmet at ringe til alle telefonnumre inklusive nødnumre uden din indgriben. Ondsindede programmer kan eventuelt foretage unødvendige og ulovlige opkald til nødtjenester."</string> <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"start CDMA-telefonopsætning direkte"</string> - <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Tillader, at programmet starter CDMA-levering. Ondsindede programmer kan starte unødvendig CDMA-levering"</string> + <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Tillader, at programmet starter CDMA-levering. Onsindede programmer kan starte unødvendig CDMA-levering"</string> <string name="permlab_locationUpdates" msgid="7785408253364335740">"kontroller meddelelser om placeringsopdatering"</string> <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Tillader aktivering/deaktivering af placeringsdata fra radioen. Ikke til brug til normale programmer."</string> <string name="permlab_checkinProperties" msgid="7855259461268734914">"egenskaber for adgangskontrol"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Tilpasset"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Start"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobil"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Arbejde"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Arbejdsfax"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Hjemmefax"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Personsøger"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Andre"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Tilbagekald"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Bil"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Virksomhed (hovednummer)"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Hoved"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Andre faxmeddelelser"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Arbejdsmobiltelefon"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Personsøger"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistent"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Fødselsdato"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Årsdag"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Begivenhed"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Tilpasset"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Start"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Arbejde"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Andre"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Tilpasset"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Start"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Arbejde"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Andre"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Tilpasset"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Start"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Arbejde"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Andre"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Tilpasset"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Arbejde"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Andre"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Tilpasset"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"via <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> via <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Indtast PIN-kode"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Forkert PIN-kode!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Tryk på Menu og dernæst på 0 for at låse op."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Beklager! Prøv igen"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Oplader (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Opladt."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Tilslut din oplader."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Der er ikke noget SIM-kort."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Der er ikke noget SIM-kort i telefonen."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Oplader ..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Forbind oplader"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Batteriet er ved at blive tomt:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"<xliff:g id="NUMBER">%d%%</xliff:g> eller mindre tilbage."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Batteriforbrug"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Fabrikstest mislykkedes"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"Handlingen FACTORY_TEST understøttes kun af pakker installeret i /system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"Javascript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"Naviger væk fra denne side?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n" Vælg OK for at fortsætte eller Annuller for at blive på den aktuelle side."</string> <string name="save_password_label" msgid="6860261758665825069">"Bekræft"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Tip: Dobbeltklik for at zoome ind eller ud."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"læs browserens oversigt og bogmærker"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Tillader programmet at læse alle de webadresser, browseren har besøgt, og alle browserens bogmærker."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"skriv browserens oversigt og bogmærker"</string> @@ -623,7 +681,7 @@ <item quantity="one" msgid="2178576254385739855">"i morgen"</item> <item quantity="other" msgid="2973062968038355991">"om <xliff:g id="COUNT">%d</xliff:g> dage"</item> </plurals> - <string name="preposition_for_date" msgid="9093949757757445117">"den <xliff:g id="DATE">%s</xliff:g>"</string> + <string name="preposition_for_date" msgid="9093949757757445117">"til <xliff:g id="DATE">%s</xliff:g>"</string> <string name="preposition_for_time" msgid="5506831244263083793">"kl. <xliff:g id="TIME">%s</xliff:g>"</string> <string name="preposition_for_year" msgid="5040395640711867177">"i <xliff:g id="YEAR">%s</xliff:g>"</string> <string name="day" msgid="8144195776058119424">"dag"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"Er du sikker på, du ønsker at formatere SD-kortet? Alle data på kortet mistes."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formater"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning forbundet"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string> - <string name="select_input_method" msgid="6865512749462072765">"Vælg indtastningsmetode"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Opret kontakt"\n"ved hjælp af <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"kontrolleret"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"ikke kontrolleret"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"De nævnte programmer beder om tilladelse til at få adgang til loginoplysningerne til kontoen <xliff:g id="ACCOUNT">%1$s</xliff:g> fra <xliff:g id="APPLICATION">%2$s</xliff:g>. Ønsker du at give denne tilladelse? Hvis ja, så huskes dit svar, og du vil ikke blive spurgt om det igen."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"De nævnte programmer beder om tilladelse til at få adgang til <xliff:g id="TYPE">%1$s</xliff:g>-loginoplysningerne til kontoen <xliff:g id="ACCOUNT">%2$s</xliff:g> fra <xliff:g id="APPLICATION">%3$s</xliff:g>. Vil du give denne tilladelse? Hvis ja, så huskes dit svar, og du vil ikke blive spurgt om det igen."</string> <string name="allow" msgid="7225948811296386551">"Tillad"</string> <string name="deny" msgid="2081879885755434506">"Afvis"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Der er anmodet om tilladelse"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Der er anmodet om tilladelse"\n"til kontoen <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Inputmetode"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Synkroniser"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Tilgængelighed"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapet"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Skift tapet"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Point-to-Point Tunneling Protocol"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Layer 2 Tunneling Protocol"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"L2TP/IPSec VPN baseret på forhåndsdelt nøglekodning"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"Certifikatbaseret L2TP/IPSec VPN"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index ebf3b66..af68303 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Auf die Datei konnte nicht zugegriffen werden."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Die angeforderte Datei wurde nicht gefunden."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Es werden zurzeit zu viele Anfragen verarbeitet. Versuchen Sie es später erneut."</string> - <string name="notification_title" msgid="1259940370369187045">"Fehler bei Anmeldung für <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Synchronisieren"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchronisieren"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Zu viele <xliff:g id="CONTENT_TYPE">%s</xliff:g> gelöscht."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Ihren physischen Standort überwachen"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Netzwerkkommunikation"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Ermöglicht Anwendungen den Zugriff auf verschiedene Netzwerkfunktionen."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Ihre Konten"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Zugriff auf verfügbare Konten"</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Hardware-Steuerelemente"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Direkter Zugriff auf Hardware über Headset"</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Anrufe"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Benutzerdefiniert"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Privat"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobil"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Arbeit"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Fax (Beruflich)"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Fax (privat)"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Pager"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Andere"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Rückruf"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Auto"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Firma (Hauptnummer)"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Hauptnummer"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Weitere Faxnummer"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY/TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Handy (geschäftlich)"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Pager (beruflich)"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Zweite Nummer"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Geburtstag"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Jahrestag"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Termin"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Benutzerdefiniert"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Privat"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Beruflich"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Andere"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Benutzerdefiniert"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Privat"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Beruflich"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Andere"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Benutzerdefiniert"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Privat"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Beruflich"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Andere"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Benutzerdefiniert"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Beruflich"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Andere"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Benutzerdefiniert"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"über <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> über <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"PIN-Code eingeben"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Falscher PIN-Code!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Drücken Sie zum Entsperren die Menütaste und dann auf \"0\"."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Tut uns leid. Versuchen Sie es noch einmal."</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Wird geladen (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Aufgeladen"</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Bitte Ladegerät anschließen"</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Keine SIM-Karte."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Keine SIM-Karte im Telefon."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Wird aufgeladen..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Ladegerät anschließen"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Akku ist fast leer."</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"<xliff:g id="NUMBER">%d%%</xliff:g> oder weniger verbleiben."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Akkuverbrauch"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Werkstest fehlgeschlagen"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"Die Aktion FACTORY_TEST wird nur für unter \"/system/app\" gespeicherte Pakete unterstützt."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"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" msgid="6860261758665825069">"Bestätigen"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Tipp: Zum Heranzoomen und Vergrößern zweimal tippen"</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"Browserverlauf und Lesezeichen lesen"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Ermöglicht der Anwendung, alle URLs, die mit dem Browser besucht wurden, sowie alle Lesezeichen des Browsers zu lesen."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"Browserverlauf und Lesezeichen schreiben"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"Möchten Sie die SD-Karte wirklich formatieren? Alle Daten auf Ihrer Karte gehen dann verloren."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging verbunden"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Zum Deaktivieren des USB-Debugging auswählen"</string> - <string name="select_input_method" msgid="6865512749462072765">"Eingabemethode auswählen"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"Kandidaten"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Neuer Kontakt"\n"mit <xliff:g id="NUMBER">%s</xliff:g> erstellen"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"aktiviert"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"nicht aktiviert"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Die aufgelisteten Anwendungen fordern eine Berechtigung zum Zugriff auf die Anmeldeinformationen für das Konto <xliff:g id="ACCOUNT">%1$s</xliff:g> von <xliff:g id="APPLICATION">%2$s</xliff:g> an. Möchten Sie diese Berechtigung erteilen? Wenn ja, wird Ihre Antwort gespeichert und Sie erhalten keine erneute Aufforderung."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Die aufgelisteten Anwendungen fordern eine Berechtigung zum Zugriff auf die <xliff:g id="TYPE">%1$s</xliff:g>-Anmeldeinformationen für das Konto <xliff:g id="APPLICATION">%3$s</xliff:g> von <xliff:g id="ACCOUNT">%2$s</xliff:g> an. Möchten Sie diese Berechtigung erteilen? Wenn ja, wird Ihre Antwort gespeichert und Sie erhalten keine erneute Aufforderung."</string> <string name="allow" msgid="7225948811296386551">"Zulassen"</string> <string name="deny" msgid="2081879885755434506">"Ablehnen"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Berechtigung angefordert"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Berechtigung erforderlich"\n"für Konto <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Eingabemethode"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Synchronisieren"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Eingabehilfen"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Hintergrund"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Hintergrundbild ändern"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Point-to-Point-Tunneling-Protokoll"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Layer-2-Tunneling-Protokoll"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"L2TP/IPSec-VPN mit vorinstalliertem Schlüssel"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"Zertifikat mit vorinstalliertem Schlüssel"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 062658d..a4ec8c1 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Η πρόσβαση στο αρχείο δεν ήταν δυνατή."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Το αρχείο που ζητήθηκε δεν βρέθηκε."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Πραγματοποιείται επεξεργασία πάρα πολλών αιτημάτων. Προσπαθήστε ξανά αργότερα."</string> - <string name="notification_title" msgid="1259940370369187045">"Σφάλμα σύνδεσης για <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Συγχρονισμός"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Συγχρονισμός"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Πάρα πολλές <xliff:g id="CONTENT_TYPE">%s</xliff:g> διαγραφές."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Παρακολούθηση της φυσικής τοποθεσίας σας"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Επικοινωνία δικτύου"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Επιτρέπει σε εφαρμογές να αποκτήσουν πρόσβαση σε διάφορες λειτουργίες δικτύου."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Οι λογαριασμοί σας"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Πρόσβαση στους διαθέσιμους λογαριασμούς."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Στοιχεία ελέγχου υλικού"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Άμεση πρόσβαση στο υλικό της συσκευής τηλεφώνου."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Τηλεφωνικές κλήσεις"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Προσαρμοσμένο"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Οικία"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Κινητό"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Εργασία"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Φαξ εργασίας"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Φαξ οικίας"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Βομβητής"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Άλλο"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Επανάκληση"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Αυτοκίνητο"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Κύρια εταιρική γραμμή"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Κύριος"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Άλλο fax"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Πομπός"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Τέλεξ"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"Τηλέφωνο TTY/TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Κινητό τηλέφωνο εργασίας"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Βομβητής εργασίας"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Βοηθός"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Γενέθλια"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Επέτειος"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Συμβάν"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Προσαρμοσμένο"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Οικία"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Εργασία"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Άλλο"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Κινητό"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Προσαρμοσμένο"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Οικία"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Εργασία"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Άλλο"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Προσαρμοσμένο"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Οικία"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Εργασία"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Άλλο"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Προσαρμοσμένο"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Εργασία"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Άλλο"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Προσαρμοσμένο"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"μέσω <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> μέσω <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Πληκτρολογήστε τον κωδικό αριθμό PIN"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Εσφαλμένος κωδικός αριθμός PIN!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Για ξεκλείδωμα, πατήστε το πλήκτρο Menu και, στη συνέχεια, το πλήκτρο 0."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Προσπαθήστε αργότερα"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Φόρτιση (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Φορτίστηκε."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Συνδέστε τον φορτιστή."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Δεν υπάρχει κάρτα SIM."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Δεν υπάρχει κάρτα SIM στο τηλέφωνο."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Φόρτιση..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Συνδέστε τον φορτιστή"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Η στάθμη της μπαταρίας είναι χαμηλή:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"Απομένει <xliff:g id="NUMBER">%d%%</xliff:g> ή λιγότερο."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Χρήση μπαταρίας"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Η εργοστασιακή δοκιμή απέτυχε"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"Η ενέργεια FACTORY_TEST υποστηρίζεται μόνο για πακέτα που είναι εγκατεστημένα στον κατάλογο /system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"Απομάκρυνση από αυτή τη σελίδα;"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Επιλέξτε OK για συνέχεια, ή Ακύρωση για παραμονή στην τρέχουσα σελίδα."</string> <string name="save_password_label" msgid="6860261758665825069">"Επιβεβαίωση"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Συμβουλή: διπλό άγγιγμα για μεγέθυνση και σμίκρυνση."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ανάγνωση ιστορικού και σελιδοδεικτών προγράμματος περιήγησης"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Επιτρέπει στην εφαρμογή την ανάγνωση όλων των διευθύνσεων URL που το πρόγραμμα περιήγησης έχει επισκεφθεί και όλων των σελιδοδεικτών του προγράμματος περιήγησης."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"εγγραφή ιστορικού και σελιδοδεικτών προγράμματος περιήγησης"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"Είστε βέβαιοι ότι θέλετε να διαμορφώσετε την κάρτα SD; Όλα τα δεδομένα στην κάρτα σας θα χαθούν."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Διαμόρφωση"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string> - <string name="select_input_method" msgid="6865512749462072765">"Επιλογή μεθόδου εισόδου"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"υποψήφιοι"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Δημιουργία επαφής"\n"με τη χρήση του <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"επιλεγμένο"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"δεν ελέγχθηκε"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Οι εφαρμογές που παραθέτονται στη λίστα ζητούν άδεια για να αποκτήσουν πρόσβαση στα διαπιστευτήρια σύνδεσης για τον λογαριασμό <xliff:g id="ACCOUNT">%1$s</xliff:g> από <xliff:g id="APPLICATION">%2$s</xliff:g>. Θα αποδεχτείτε το αίτημα; Εάν το αποδεχτείτε, η απάντησή σας θα αποθηκευτεί και δεν θα ερωτηθείτε ξανά."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Οι εφαρμογές που παραθέτονται στη λίστα ζητούν άδεια για να αποκτήσουν πρόσβαση στα διαπιστευτήρια σύνδεσης <xliff:g id="TYPE">%1$s</xliff:g> για τον λογαριασμό <xliff:g id="ACCOUNT">%2$s</xliff:g> από <xliff:g id="APPLICATION">%3$s</xliff:g>. Θα αποδεχτείτε το αίτημα; Εάν το αποδεχτείτε, η απάντησή σας θα αποθηκευτεί και δεν θα ερωτηθείτε ξανά."</string> <string name="allow" msgid="7225948811296386551">"Να επιτρέπεται"</string> <string name="deny" msgid="2081879885755434506">"Άρνηση"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Απαιτείται άδεια"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Ζητήθηκε άδεια"\n"για τον λογαριασμό <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Μέθοδος εισόδου"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Συγχρονισμός"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Προσβασιμότητα"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Ταπετσαρία"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Αλλαγή ταπετσαρίας"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Πρωτόκολλο Point-to-Point Tunneling Protocol (PPTP)"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Πρωτόκολλο Layer 2 Tunneling Protocol (L2TP)"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"Κλειδί pre-shared βάσει L2TP/IPSec VPN"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"Πιστοποιητικό βάσει L2TP/IPSec VPN"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 88f16a9..025ae60 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -777,8 +777,6 @@ <string name="create_contact_using" msgid="4947405226788104538">"Crear contacto "\n"con <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"verificado"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"no verificado"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Las aplicaciones enumeradas requieren permiso para acceder a las credenciales de inicio de sesión para la cuenta <xliff:g id="ACCOUNT">%1$s</xliff:g> desde <xliff:g id="APPLICATION">%2$s</xliff:g> ¿Deseas otorgar este permiso? Si es así, el sistema recordará tu respuesta y no volverá a solicitarla."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Las aplicaciones enumeradas requieren permiso para acceder a las <xliff:g id="TYPE">%1$s</xliff:g> credenciales de inicio de sesión para la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g> desde <xliff:g id="APPLICATION">%3$s</xliff:g>.¿Deseas otorgar este permiso? Si es así, el sistema recordará tu respuesta y no volverá a solicitarla."</string> <string name="allow" msgid="7225948811296386551">"Permitir"</string> <string name="deny" msgid="2081879885755434506">"Denegar"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Permiso solicitado"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 2757978..ebe1bb0 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"No se ha podido acceder al archivo."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"No se ha encontrado el archivo solicitado."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Se están procesando demasiadas solicitudes. Vuelve a intentarlo más tarde."</string> - <string name="notification_title" msgid="1259940370369187045">"Error de acceso a la cuenta <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Sincronización"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronización"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Demasiadas eliminaciones de <xliff:g id="CONTENT_TYPE">%s</xliff:g>"</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Controlar su ubicación física"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Comunicación de red"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Permite que las aplicaciones accedan a distintas funciones de red."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Tus cuentas"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Acceder a las cuentas disponibles"</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Controles de hardware"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Acceso directo al hardware del móvil"</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Llamadas de teléfono"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Personalizado"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Casa"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Móvil"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Trabajo"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Fax del trabajo"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Fax de casa"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Buscapersonas"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Otro"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Devolución de llamada"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Coche"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Teléfono principal de la empresa"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"RDSI"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Principal"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Otro fax"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Télex"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Móvil del trabajo"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Buscapersonas del trabajo"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Asistente"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Cumpleaños"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Aniversario"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Evento"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Personalizado"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Casa"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Trabajo"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Otro"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Móvil"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Personalizada"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Casa"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Trabajo"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Otro"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Personalizada"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Casa"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Trabajo"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Otro"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Personalizada"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo!"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Trabajo"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Otra"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Personalizada"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"a través de <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> a través de <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Introduce el código PIN"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"El código PIN es incorrecto."</string> <string name="keyguard_label_text" msgid="861796461028298424">"Para desbloquear el teléfono, pulsa la tecla de menú y, a continuación, pulsa 0."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Inténtalo de nuevo"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Cargando (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Cargado"</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Conecta el cargador"</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Falta la tarjeta SIM"</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"No se ha insertado ninguna tarjeta SIM en el teléfono."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Cargando..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Conecta el cargador"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Se está agotando la batería:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"<xliff:g id="NUMBER">%d%%</xliff:g> o menos disponible"</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Uso de la batería"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Fallo en la prueba de fábrica"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"La acción FACTORY_TEST sólo es compatible con los paquetes instalados en /system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"¿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" msgid="6860261758665825069">"Confirmar"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Sugerencia: toca dos veces para ampliar o reducir."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"leer información de marcadores y del historial del navegador"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Permite que la aplicación lea todas las URL que ha visitado el navegador y todos sus marcadores."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"escribir en marcadores y en el historial del navegador"</string> @@ -624,7 +682,7 @@ <item quantity="other" msgid="2973062968038355991">"dentro de <xliff:g id="COUNT">%d</xliff:g> días"</item> </plurals> <string name="preposition_for_date" msgid="9093949757757445117">"el <xliff:g id="DATE">%s</xliff:g>"</string> - <string name="preposition_for_time" msgid="5506831244263083793">"a la(s) <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="preposition_for_time" msgid="5506831244263083793">"a las <xliff:g id="TIME">%s</xliff:g>"</string> <string name="preposition_for_year" msgid="5040395640711867177">"en <xliff:g id="YEAR">%s</xliff:g>"</string> <string name="day" msgid="8144195776058119424">"día"</string> <string name="days" msgid="4774547661021344602">"días"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"¿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" msgid="4131064560127478695">"Formato"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Dispositivo de depuración USB conectado"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string> - <string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de introducción de texto"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Crear un contacto"\n"a partir de <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"seleccionado"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"no seleccionado"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Las aplicaciones de la lista están solicitando permiso para acceder a las credenciales de acceso de la cuenta <xliff:g id="ACCOUNT">%1$s</xliff:g> desde <xliff:g id="APPLICATION">%2$s</xliff:g>. ¿Deseas conceder este permiso? En tal caso, se recordará tu respuesta y no se te volverá a preguntar."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Las aplicaciones de la lista están solicitando permiso para acceder a las credenciales de acceso (<xliff:g id="TYPE">%1$s</xliff:g>) de la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g> desde <xliff:g id="APPLICATION">%3$s</xliff:g>. ¿Deseas conceder este permiso? En tal caso, se recordará tu respuesta y no se te volverá a preguntar."</string> <string name="allow" msgid="7225948811296386551">"Permitir"</string> <string name="deny" msgid="2081879885755434506">"Denegar"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Permiso solicitado"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Permiso solicitado"\n"para la cuenta <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Método de introducción de texto"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Sincronización"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Accesibilidad"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fondo de pantalla"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambiar fondo de pantalla"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Protocolo de túnel punto a punto"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Protocolo de túnel de nivel 2"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"Red privada virtual L2TP/IPSec basada en clave compartida previamente"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"Red privada virtual L2TP/IPSec basada en certificado"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 7a07a7c..5647063 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Impossible d\'accéder au fichier."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Le fichier demandé est introuvable."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Trop de requêtes sont en cours de traitement. Veuillez réessayer ultérieurement."</string> - <string name="notification_title" msgid="1259940370369187045">"Erreur de connexion au compte <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Synchroniser"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchronisation"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Trop de contenus supprimés (<xliff:g id="CONTENT_TYPE">%s</xliff:g>)."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Suivre votre position géographique"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Communications réseau"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Permet à des applications d\'accéder à différentes fonctionnalités du réseau."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Vos comptes"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Accéder aux comptes disponibles"</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Commandes du matériel"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Permet d\'accéder directement au matériel de l\'appareil."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Appels"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Personnalisé"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Domicile"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobile"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Bureau"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Télécopie bureau"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Télécopie domicile"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Téléavertisseur"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Autre"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Rappel"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Voiture"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Société (principal)"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"RNIS"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Principal"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Autre télécopie"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Télex"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY/TTD (malentendants)"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mobile (professionnel)"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Téléavertisseur (professionnel)"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistant"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Anniversaire"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Fête"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Événement"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Personnalisé"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Domicile"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Bureau"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Autre"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Mobile"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Personnalisée"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Domicile"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Bureau"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Autre"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Personnalisée"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Domicile"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Bureau"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Autre"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Personnalisée"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Bureau"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Autre"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Personnalisée"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"via <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> via <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Saisissez le code PIN"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Le code PIN est incorrect !"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Pour débloquer le clavier, appuyez sur \"Menu\" puis sur 0."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Désolé. Merci de réessayer."</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Chargement (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Chargé"</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Branchez votre chargeur."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Aucune carte SIM n\'a été trouvée."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Aucune carte SIM n\'est insérée dans le téléphone."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Chargement..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Branchez le chargeur"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Le niveau de la batterie est bas :"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"Maximum <xliff:g id="NUMBER">%d%%</xliff:g> restants."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Utilisation de la batterie"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Échec du test usine"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"L\'action FACTORY_TEST est uniquement prise en charge pour les paquets de données installés dans in/system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"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" msgid="6860261758665825069">"Confirmer"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Conseil : Appuyez deux fois pour effectuer un zoom avant ou arrière."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"lire l\'historique et les favoris du navigateur"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Autorise l\'application à lire toutes les URL auxquelles le navigateur a accédé et tous ses favoris."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"écrire dans l\'historique et les favoris du navigateur"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"Voulez-vous vraiment formater la carte SD ? Toutes les données de cette carte seront perdues."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string> - <string name="select_input_method" msgid="6865512749462072765">"Sélectionner un mode de saisie"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Ajouter un contact"\n"en utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"sélectionné"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"non sélectionné"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Les applications répertoriées demandent l\'autorisation d\'accéder aux informations d\'identification du compte <xliff:g id="ACCOUNT">%1$s</xliff:g> depuis <xliff:g id="APPLICATION">%2$s</xliff:g>. Souhaitez-vous accorder cette autorisation ? Si vous acceptez, votre choix sera enregistré et cette question ne vous sera plus posée."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Les applications répertoriées demandent l\'autorisation d\'accéder aux informations d\'identification des <xliff:g id="TYPE">%1$s</xliff:g> associés au compte <xliff:g id="ACCOUNT">%2$s</xliff:g> depuis <xliff:g id="APPLICATION">%3$s</xliff:g>. Souhaitez-vous accorder cette autorisation ? Si vous acceptez, votre choix sera enregistré et cette question ne vous sera plus posée."</string> <string name="allow" msgid="7225948811296386551">"Autoriser"</string> <string name="deny" msgid="2081879885755434506">"Refuser"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Autorisation demandée"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Autorisation demandée"\n"pour le compte <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Mode de saisie"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Synchronisation"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilité"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fond d\'écran"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Changer de fond d\'écran"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Protocole de tunnelisation point-à-point"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Protocole de tunnelisation de niveau 2"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"Clé pré-partagée basée sur L2TP/IPSec VPN"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"Certificat basé sur L2TP/IPSec VPN"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 8d2aefa..f0647e7 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Impossibile accedere al file."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Impossibile trovare il file richiesto."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Troppe richieste in fase di elaborazione. Riprova più tardi."</string> - <string name="notification_title" msgid="1259940370369187045">"Errore di accesso per <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Sinc"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronizzazione"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Troppe eliminazioni di <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Monitorare la posizione fisica dell\'utente"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Comunicazione di rete"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Consentono l\'accesso delle applicazioni a varie funzionalità di rete."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"I tuoi account"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Accedere agli account disponibili."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Controlli hardware"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Accedere direttamente all\'hardware del ricevitore."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Telefonate"</string> @@ -316,7 +319,7 @@ <string name="permlab_callPrivileged" msgid="4198349211108497879">"chiamata diretta di tutti i n. telefono"</string> <string name="permdesc_callPrivileged" msgid="244405067160028452">"Consente all\'applicazione di chiamare qualsiasi numero, compresi quelli di emergenza, automaticamente. Le applicazioni dannose potrebbero effettuare chiamate non necessarie e illegali a servizi di emergenza."</string> <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"avviare direttamente la configurazione del telefono CDMA"</string> - <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Consente all\'applicazione di avviare il servizio di provisioning CDMA. Le applicazioni dannose potrebbero avviare il servizio di provisioning CDMA quando non è necessario"</string> + <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Consente all\'applicazione di avviare il servizio di CDMA provisioning. Le applicazioni dannose potrebbero avviare il servizio di CDMA provisioning quando non è necessario"</string> <string name="permlab_locationUpdates" msgid="7785408253364335740">"controllo notifiche aggiornamento posizione"</string> <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Consente l\'attivazione/disattivazione delle notifiche di aggiornamento della posizione dal segnale cellulare. Da non usare per normali applicazioni."</string> <string name="permlab_checkinProperties" msgid="7855259461268734914">"accesso a proprietà di archiviazione"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Personalizzato"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Casa"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Cellulare"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Ufficio"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Fax ufficio"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Fax casa"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Cercapersone"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Altro"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Callback"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Automobile"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Azienda, principale"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Principale"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Altro fax"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Segnale cellulare"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Cellulare ufficio"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Cercapersone ufficio"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistente"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Compleanno"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Anniversario"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Evento"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Personalizzato"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Casa"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Ufficio"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Altro"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Cellulare"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Personalizzato"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Casa"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Ufficio"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Altro"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Personalizzato"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Casa"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Ufficio"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Altro"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Personalizzato"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Ufficio"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Altro"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Personalizzato"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"tramite <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> tramite <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Inserisci il PIN"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Codice PIN errato."</string> <string name="keyguard_label_text" msgid="861796461028298424">"Per sbloccare, premi Menu, poi 0."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Riprova"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"In carica (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Carico."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Collegare il caricabatterie."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Nessuna SIM presente."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Nessuna SIM presente nel telefono."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"In carica..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Collegare il caricabatterie"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Batteria quasi scarica:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"<xliff:g id="NUMBER">%d%%</xliff:g> rimanente o meno."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Utilizzo batteria"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Test di fabbrica non riuscito"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"L\'azione FACTORY_TEST è supportata soltanto per i pacchetti installati in /system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"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" msgid="6860261758665825069">"Conferma"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Suggerimento. Tocca due volte per aumentare/ridurre lo zoom."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"lettura cronologia e segnalibri del browser"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Consente all\'applicazione di leggere tutti gli URL visitati e tutti i segnalibri del browser."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"creazione cronologia e segnalibri del browser"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"Formattare la scheda SD? Tutti i dati sulla scheda verranno persi."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatta"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Seleziona per disattivare il debug USB."</string> - <string name="select_input_method" msgid="6865512749462072765">"Seleziona metodo di inserimento"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidati"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Crea contatto"\n"utilizzando <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"selezionato"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"non selezionato"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Le applicazioni elencate richiedono l\'autorizzazione per accedere alle credenziali di accesso per l\'account <xliff:g id="ACCOUNT">%1$s</xliff:g> da <xliff:g id="APPLICATION">%2$s</xliff:g>. Concedere questa autorizzazione? In tal caso la tua risposta verrà memorizzata e questa domanda non ti verrà più posta."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Le applicazioni elencate richiedono l\'autorizzazione per accedere alle credenziali di accesso <xliff:g id="TYPE">%1$s</xliff:g> per l\'account <xliff:g id="ACCOUNT">%2$s</xliff:g> da <xliff:g id="APPLICATION">%3$s</xliff:g>. Concedere questa autorizzazione? In tal caso la tua risposta verrà memorizzata e questa domanda non ti verrà più posta."</string> <string name="allow" msgid="7225948811296386551">"Consenti"</string> <string name="deny" msgid="2081879885755434506">"Nega"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Autorizzazione richiesta"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Autorizzazione richiesta"\n"per l\'account <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Metodo inserimento"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Sinc"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Accesso facilitato"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Sfondo"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambia sfondo"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Protocollo di tunneling Point-to-Point"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Protocollo di tunneling livello 2"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"VPN L2TP/IPSec basata su chiave precondivisa"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"VPN L2TP/IPSec basata su certificato"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 8c3836c..9517af5 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"ファイルにアクセスできませんでした。"</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"要求されたファイルが見つかりませんでした。"</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"処理中のリクエストが多すぎます。しばらくしてからもう一度試してください。"</string> - <string name="notification_title" msgid="1259940370369187045">"ログインエラー: <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"同期"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"同期"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"<xliff:g id="CONTENT_TYPE">%s</xliff:g>での削除が多すぎます。"</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"現在地を追跡"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"ネットワーク通信"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"ネットワークのさまざまな機能へのアクセスをアプリケーションに許可します。"</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"アカウント"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"利用可能なアカウントにアクセスします。"</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"ハードウェアの制御"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"携帯電話のハードウェアに直接アクセスします。"</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"電話/通話"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"カスタム"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"自宅"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"携帯"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"勤務先"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"FAX(勤務先)"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"FAX(自宅)"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"ポケベル"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"その他"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"コールバック"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"クルマ"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"会社代表番号"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"メイン"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"FAX(その他)"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"無線"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"テレックス"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"携帯電話(勤務先)"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"ポケベル(勤務先)"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"アシスタント"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"誕生日"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"記念日"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"予定"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"カスタム"</string> - <string name="emailTypeHome" msgid="449227236140433919">"自宅"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"勤務先"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"その他"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"携帯"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"カスタム"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"自宅"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"勤務先"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"その他"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"カスタム"</string> - <string name="imTypeHome" msgid="6241181032954263892">"自宅"</string> - <string name="imTypeWork" msgid="1371489290242433090">"勤務先"</string> - <string name="imTypeOther" msgid="5377007495735915478">"その他"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"カスタム"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Googleトーク"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"勤務先"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"その他"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"カスタム"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"<xliff:g id="SOURCE">%1$s</xliff:g>経由"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g>、更新元: <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"PINコードを入力"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"PINコードが正しくありません。"</string> <string name="keyguard_label_text" msgid="861796461028298424">"MENU、0キーでロック解除"</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"やり直してください"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"充電中(<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"充電完了。"</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"充電してください。"</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"SIMカードが挿入されていません"</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"SIMカードが挿入されていません"</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"充電中..."</string> <string name="battery_low_title" msgid="7923774589611311406">"充電してください"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"電池が残り少なくなっています:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"残り<xliff:g id="NUMBER">%d%%</xliff:g>未満です。"</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"電池使用量"</string> <string name="factorytest_failed" msgid="5410270329114212041">"出荷時試験が失敗"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST操作は、/system/appにインストールされたパッケージのみが対象です。"</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"このページから移動しますか?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"移動する場合は[OK]、今のページに残る場合は[キャンセル]を選択してください。"</string> <string name="save_password_label" msgid="6860261758665825069">"確認"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"ヒント: ダブルタップで拡大/縮小できます。"</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ブラウザの履歴とブックマークを読み取る"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"ブラウザでアクセスしたすべてのURLおよびブラウザのすべてのブックマークの読み取りをアプリケーションに許可します。"</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"ブラウザの履歴とブックマークを書き込む"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"SDカードをフォーマットしてもよろしいですか?カード内のすべてのデータが失われます。"</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"フォーマット"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string> - <string name="select_input_method" msgid="6865512749462072765">"入力方法の選択"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"候補"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g>を使って"\n"連絡先を新規登録"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"オン"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"オフ"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"リストされているアプリケーションが、アカウント<xliff:g id="ACCOUNT">%1$s</xliff:g>のログイン認証情報に<xliff:g id="APPLICATION">%2$s</xliff:g>からアクセスする権限をリクエストしています。この権限を許可しますか?許可すると、入力が記録され、次回以降はこのメッセージが表示されなくなります。"</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"リストされているアプリケーションが、アカウント<xliff:g id="ACCOUNT">%2$s</xliff:g>の<xliff:g id="TYPE">%1$s</xliff:g>ログイン認証情報に<xliff:g id="APPLICATION">%3$s</xliff:g>からアクセスする権限をリクエストしています。この権限を許可しますか?許可すると、入力は記録され、次回以降はこのメッセージが表示されなくなります。"</string> <string name="allow" msgid="7225948811296386551">"許可"</string> <string name="deny" msgid="2081879885755434506">"拒否"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"リクエスト済み権限"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"次のアカウントにアクセスする権限が"\n"リクエストされました:<xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"入力方法"</string> <string name="sync_binding_label" msgid="3687969138375092423">"同期"</string> - <string name="accessibility_binding_label" msgid="4148120742096474641">"ユーザー補助"</string> + <string name="accessibility_binding_label" msgid="4148120742096474641">"アクセシビリティ"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"壁紙"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"壁紙を変更"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"ポイントツーポイントトンネリングプロトコル"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"レイヤー2トンネリングプロトコル"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"L2TP/IPSec VPNベースの事前共有鍵"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"L2TP/IPSec VPNベースの証明書"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 840fa99..0ef3824 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"파일에 액세스할 수 없습니다."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"요청한 파일을 찾을 수 없습니다."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"처리 중인 요청이 너무 많습니다. 잠시 후에 다시 시도해 주세요."</string> - <string name="notification_title" msgid="1259940370369187045">"<xliff:g id="ACCOUNT">%1$s</xliff:g>에 로그인 오류 발생"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"동기화"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"동기화"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"<xliff:g id="CONTENT_TYPE">%s</xliff:g> 삭제가 너무 많습니다."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"실제 위치 모니터링"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"네트워크 통신"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"응용프로그램이 다양한 네트워크 기능에 액세스할 수 있도록 합니다."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"계정"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"사용 가능한 계정에 액세스합니다."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"하드웨어 제어"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"휴대전화의 하드웨어에 직접 액세스합니다."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"전화 통화"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"맞춤설정"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"집"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"휴대전화"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"직장"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"직장 팩스"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"집(팩스)"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"호출기"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"기타"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"콜백"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"카폰"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"회사 기본전화"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"기본"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"기타 팩스"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"무선통신"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"텔렉스"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"직장 휴대전화"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"직장 호출기"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"비서"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"생일"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"기념일"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"일정"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"맞춤설정"</string> - <string name="emailTypeHome" msgid="449227236140433919">"집"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"직장"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"기타"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"모바일"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"맞춤설정"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"집"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"직장"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"기타"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"맞춤설정"</string> - <string name="imTypeHome" msgid="6241181032954263892">"집"</string> - <string name="imTypeWork" msgid="1371489290242433090">"직장"</string> - <string name="imTypeOther" msgid="5377007495735915478">"기타"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"맞춤설정"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google 토크"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"직장"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"기타"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"맞춤설정"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"<xliff:g id="SOURCE">%1$s</xliff:g>을(를) 통해"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g>(<xliff:g id="SOURCE">%2$s</xliff:g> 사용)"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"PIN 코드 입력"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"PIN 코드가 잘못되었습니다."</string> <string name="keyguard_label_text" msgid="861796461028298424">"잠금해제하려면 메뉴를 누른 다음 0을 누릅니다."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"죄송합니다. 다시 시도하세요."</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"충전 중(<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"충전되었습니다."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"충전기를 연결하세요."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"SIM 카드가 없습니다."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"휴대전화에 SIM 카드가 없습니다."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"충전 중..."</string> <string name="battery_low_title" msgid="7923774589611311406">"충전기를 연결하세요."</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"배터리 전원이 부족합니다."</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"잔여 배터리가 <xliff:g id="NUMBER">%d%%</xliff:g> 이하입니다."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"배터리 사용"</string> <string name="factorytest_failed" msgid="5410270329114212041">"출고 테스트 불합격"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST 작업은 /system/app 디렉토리에 설치된 패키지에 대해서만 지원됩니다."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"자바스크립트"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"다른 페이지를 탐색하시겠습니까?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"계속하려면 \'확인\'을 선택하고 현재 페이지에 그대로 있으려면 \'취소\'를 선택하세요."</string> <string name="save_password_label" msgid="6860261758665825069">"확인"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"도움말: 축소/확대하려면 두 번 누릅니다."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"브라우저의 기록 및 북마크 읽기"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"응용프로그램이 브라우저로 방문한 모든 URL과 브라우저의 모든 북마크를 읽도록 허용합니다."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"브라우저의 기록 및 북마크 쓰기"</string> @@ -740,13 +798,15 @@ <string name="usb_storage_stop_message" msgid="2390958966725232848">"USB 저장소를 끄기 전에 반드시 USB 호스트에서 마운트 해제하세요. USB 저장소를 끄려면 \'끄기\'를 선택하세요."</string> <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"USB 저장소 끄기"</string> <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"취소"</string> - <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"USB 저장소를 끄는 동안 문제가 발생했습니다. USB 호스트와 연결을 해제했는지 확인한 다음 다시 시도하세요."</string> + <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"USB 저장소를 끄는 동안 문제가 발생했습니다. USB 호스트를 마운트 해제했는지 확인한 다음 다시 시도하세요."</string> <string name="extmedia_format_title" msgid="8663247929551095854">"SD 카드 포맷"</string> <string name="extmedia_format_message" msgid="3621369962433523619">"SD 카드를 포맷하시겠습니까? 포맷하면 카드의 모든 데이터를 잃게 됩니다."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"포맷"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string> - <string name="select_input_method" msgid="6865512749462072765">"입력 방법 선택"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"가능한 원인"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"전화번호부에"\n"<xliff:g id="NUMBER">%s</xliff:g> 추가"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"선택함"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"선택 안함"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"나열된 응용프로그램이 <xliff:g id="APPLICATION">%2$s</xliff:g>에서 <xliff:g id="ACCOUNT">%1$s</xliff:g> 계정의 로그인 자격증명에 액세스할 수 있는 권한을 요청 중입니다. 권한을 부여하시겠습니까? 권한을 부여하면 응답 내용이 저장되며 메시지가 다시 표시되지 않습니다."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"나열된 응용프로그램이 <xliff:g id="APPLICATION">%3$s</xliff:g>에서 <xliff:g id="ACCOUNT">%2$s</xliff:g> 계정의 <xliff:g id="TYPE">%1$s</xliff:g> 로그인 자격증명에 액세스할 수 있는 권한을 요청 중입니다. 권한을 부여하시겠습니까? 권한을 부여하면 응답 내용이 저장되며 메시지가 다시 표시되지 않습니다."</string> <string name="allow" msgid="7225948811296386551">"허용"</string> <string name="deny" msgid="2081879885755434506">"거부"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"권한 요청"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"<xliff:g id="ACCOUNT">%s</xliff:g> 계정에 대해"\n"권한 요청"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"입력 방법"</string> <string name="sync_binding_label" msgid="3687969138375092423">"동기화"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"접근성"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"배경화면"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"배경화면 변경"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"PPTP(Point-to-Point Tunneling Protocol)"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"L2TP(Layer 2 Tunneling Protocol)"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"사전 공유 키 기반 L2TP/IPSec VPN"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"인증서 기반 L2TP/IPSec VPN"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index ef90da7..aa15ad1 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Kunne ikke åpne filen."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Fant ikke den forespurte filen."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"For mange forespørsler blir behandlet. Prøv igjen senere."</string> - <string name="notification_title" msgid="1259940370369187045">"Påloggingsfeil for <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Synkronisering"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synkronisering"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"For mange slettinger av <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Overvåking av telefonens fysiske plassering"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Nettverkstilgang"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Gir applikasjoner tilgang til diverse nettverksfunksjoner."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Dine kontoer"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Gi tilgang til de tilgjengelige kontoene."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Maskinvarekontroll"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Direkte tilgang til maskinvaren på telefonen."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Telefonsamtaler"</string> @@ -210,7 +213,7 @@ <string name="permlab_batteryStats" msgid="7863923071360031652">"endre batteristatistikk"</string> <string name="permdesc_batteryStats" msgid="5847319823772230560">"Lar applikasjonen endre på innsamlet batteristatistikk. Ikke ment for vanlige applikasjoner."</string> <string name="permlab_backup" msgid="470013022865453920">"kontrollere backup og gjenoppretting"</string> - <string name="permdesc_backup" msgid="4837493065154256525">"Gir programmet tillatelse til å kontrollere systemets mekanismer for sikkerhetskopiering og·gjenoppretting. Ikke beregnet på vanlige programmer."</string> + <string name="permdesc_backup" msgid="4837493065154256525">"Gir programmet tillatelse til å kontrollere systemets mekanismer for sikkerhetskopiering gjenoppretting. Ikke beregnet på vanlige programmer."</string> <string name="permlab_backup_data" msgid="4057625941707926463">"sikkerhetskopier og gjenopprett programmets data"</string> <string name="permdesc_backup_data" msgid="8274426305151227766">"Gir programmet tillatelse til å ta del i systemets mekanismer for sikkerhetskopiering og gjenoppretting."</string> <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"vis uautoriserte vinduer"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Tilpasset"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Privat"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobil"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Arbeid"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Send faks (arbeid)"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Send faks (privat)"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Personsøker"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Annen"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Tilbakeringing"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Bil"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Firma (sentralbord)"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Hoved"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Annen faks"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Teleks"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY/TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mobil (arbeid)"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Personsøker (arbeid)"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistent"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Fødselsdag"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Merkedag"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Aktivitet"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Tilpasset"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Privat"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Arbeid"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Annen"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Tilpasset"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Privat"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Arbeid"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Annen"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Tilpasset"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Privat"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Arbeid"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Annen"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Tilpasset"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Arbeid"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Annen"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Tilpasset"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"via <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> via <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Skriv inn PIN-kode:"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Gal PIN-kode!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"For å låse opp, trykk på menyknappen og deretter 0."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Beklager, prøv igjen:"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Lader (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Fullt ladet"</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Koble til en batterilader."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Mangler SIM-kort."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Ikke noe SIM-kort i telefonen."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Lader…"</string> <string name="battery_low_title" msgid="7923774589611311406">"Koble til en lader"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Batteriet er nesten tomt:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"<xliff:g id="NUMBER">%d%%</xliff:g> eller mindre gjenstår."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Batteribruk"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Factory test failed"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"Naviger bort fra denne siden?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Velg OK for å fortsette, eller Avbryt for å forbli på denne siden."</string> <string name="save_password_label" msgid="6860261758665825069">"Bekreft"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Tips: trykk to ganger for å zoome inn og ut."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"lese nettleserens logg og bokmerker"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Lar applikasjonen lese alle adresser nettleseren har besøkt, og alle nettleserens bokmerker."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"skrive til nettleserens logg og bokmerker"</string> @@ -740,13 +798,15 @@ <string name="usb_storage_stop_message" msgid="2390958966725232848">"Før du slår av USB-lagring, sjekk at du har avmontert enheten i USB-verten. Velg «slå av» for å slå av USB-lagring."</string> <string name="usb_storage_stop_button_mount" msgid="1181858854166273345">"Slå av"</string> <string name="usb_storage_stop_button_unmount" msgid="3774611918660582898">"Avbryt"</string> - <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Det har oppstått et problem ved deaktiveringen av USB-lagring. Kontroller at du har frakoblet USB-verten, og prøv igjen."</string> + <string name="usb_storage_stop_error_message" msgid="3746037090369246731">"Det har oppstått et problem ved deaktiveringen av USB-lagring. Kontroller at du har demontert USB-verten, og prøv igjen."</string> <string name="extmedia_format_title" msgid="8663247929551095854">"Formatere minnekort"</string> <string name="extmedia_format_message" msgid="3621369962433523619">"Er du sikker på at du ønsker å formatere minnekortet? Alle data på kortet vil gå tapt."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-debugging tilkoblet"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Velg for å deaktivere USB-feilsøking"</string> - <string name="select_input_method" msgid="6865512749462072765">"Velg inndatametode"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string> <string name="candidates_style" msgid="4333913089637062257">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Lag kontakt"\n"med nummeret <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"valgt"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"ikke valgt"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"De·oppførte·programmene ber om tilgangstillatelse til påloggingsopplysningene for konto <xliff:g id="ACCOUNT">%1$s</xliff:g> fra <xliff:g id="APPLICATION">%2$s</xliff:g>. Vil du gi denne tillatelsen? I·så·fall·lagres·svaret,·og·du·blir·ikke·spurt·flere·ganger."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"De·oppførte·programmene ber om tilgangstillatelse til <xliff:g id="TYPE">%1$s</xliff:g>-påloggingsopplysningene for konto <xliff:g id="ACCOUNT">%2$s</xliff:g> fra <xliff:g id="APPLICATION">%3$s</xliff:g>. Vil du gi denne tillatelsen? I·så·fall·lagres·svaret,·og·du·blir·ikke·spurt·flere·ganger."</string> <string name="allow" msgid="7225948811296386551">"Tillat"</string> <string name="deny" msgid="2081879885755434506">"Avslå"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Tillatelse forespurt"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Tillatelse forespurt"\n"for konto <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Inndatametode"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Synkronisering"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Tilgjengelighet"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Bakgrunnsbilde"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Endre bakgrunnsbilde"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"PPTP·(point-to-point·tunneling·protocol)"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Tunnelprotokoll for lag 2"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"Forhåndsdelt nøkkelbasert L2TP/IPSec VPN"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"Sertifikatbasert L2TP/IPSec VPN"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index f419284..c299ef8 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Het bestand kan niet worden geopend."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Het opgevraagde bestand is niet gevonden."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Er worden te veel aanvragen verwerkt. Probeer het later opnieuw."</string> - <string name="notification_title" msgid="1259940370369187045">"Fout bij aanmelding voor \'<xliff:g id="ACCOUNT">%1$s</xliff:g>\'"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Synchroniseren"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchroniseren"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Te veel verwijderen voor <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string> @@ -434,61 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Aangepast"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Thuis"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobiel"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Werk"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Fax werk"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Fax thuis"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Pager"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Overig"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Terugbelnummer"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Auto"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Hoofdkantoor"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Algemeen"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Andere fax"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"Teksttelefoon"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mobiel werk"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Pager werk"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistent"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> <!-- no translation found for eventTypeBirthday (2813379844211390740) --> <skip /> <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> <skip /> <!-- no translation found for eventTypeOther (5834288791948564594) --> <skip /> - <string name="emailTypeCustom" msgid="8525960257804213846">"Aangepast"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Thuis"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Werk"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Overig"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Mobiel"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Aangepast"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Thuis"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Werk"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Overig"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Aangepast"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Thuis"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Werk"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Overig"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Aangepast"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Werk"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Overig"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Aangepast"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"via <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> via <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"PIN-code invoeren"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Onjuiste PIN-code!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Druk op \'Menu\' en vervolgens op 0 om te ontgrendelen."</string> @@ -503,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Probeer het opnieuw"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Opladen (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Opgeladen."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Sluit de oplader aan."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Geen SIM-kaart."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Geen SIM-kaart in telefoon."</string> @@ -535,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Opladen..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Sluit de oplader aan"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"De accu raakt op:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"<xliff:g id="NUMBER">%d%%</xliff:g> of minder resterend."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Accugebruik"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Fabriekstest mislukt"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"De actie FACTORY_TEST wordt alleen ondersteund voor pakketten die zijn geïnstalleerd in /system/app."</string> @@ -545,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"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" msgid="6860261758665825069">"Bevestigen"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Tip: tik tweemaal om in of uit te zoomen."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"browsergeschiedenis en bladwijzers lezen"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Hiermee kan een toepassing de URL\'s lezen die u via de browser heeft bezocht, evenals alle bladwijzers van de browser."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"browsergeschiedenis en bladwijzers schrijven"</string> @@ -669,7 +722,7 @@ <string name="paste" msgid="5629880836805036433">"Plakken"</string> <string name="copyUrl" msgid="2538211579596067402">"URL kopiëren"</string> <string name="inputMethod" msgid="1653630062304567879">"Invoermethode"</string> - <string name="addToDictionary" msgid="8793624991686948709">"\'<xliff:g id="WORD">%s</xliff:g>\' toevoegen aan woordenboek"</string> + <string name="addToDictionary" msgid="8793624991686948709">"\' <xliff:g id="WORD">%s</xliff:g>\' toevoegen aan woordenboek"</string> <string name="editTextMenuTitle" msgid="1672989176958581452">"Tekst bewerken"</string> <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Weinig ruimte"</string> <string name="low_internal_storage_view_text" msgid="635106544616378836">"Opslagruimte van telefoon raakt op."</string> @@ -750,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"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" msgid="4131064560127478695">"Formatteren"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Selecteer deze optie om USB-foutopsporing uit te schakelen."</string> - <string name="select_input_method" msgid="6865512749462072765">"Invoermethode selecteren"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaten"</u></string> @@ -782,12 +837,11 @@ <string name="create_contact_using" msgid="4947405226788104538">"Contact maken"\n"met <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"aangevinkt"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"niet aangevinkt"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"De weergegeven toepassingen vragen toestemming voor toegang tot de aanmeldingsgegevens voor account \'<xliff:g id="ACCOUNT">%1$s</xliff:g>\' van <xliff:g id="APPLICATION">%2$s</xliff:g>. Wilt u deze toestemming verlenen? Als u dit wilt doen, wordt uw antwoord onthouden en wordt dit niet opnieuw gevraagd."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"De weergegeven toepassingen vragen toestemming voor toegang tot de aanmeldingsgegevens voor <xliff:g id="TYPE">%1$s</xliff:g> van het account \'<xliff:g id="ACCOUNT">%2$s</xliff:g>\' van <xliff:g id="APPLICATION">%3$s</xliff:g>. Wilt u deze toestemming verlenen? Als u dit wilt doen, wordt uw antwoord onthouden en wordt dit niet opnieuw gevraagd."</string> <string name="allow" msgid="7225948811296386551">"Toestaan"</string> <string name="deny" msgid="2081879885755434506">"Weigeren"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Toestemming gevraagd"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Toestemming gevraagd"\n"voor account \'<xliff:g id="ACCOUNT">%s</xliff:g>\'"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Invoermethode"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Synchroniseren"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Toegankelijkheid"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 388a9e7..f53bd4c 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Nie można uzyskać dostępu do pliku."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Nie znaleziono żądanego pliku."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Zbyt wiele żądań jest przetwarzanych. Spróbuj ponownie później."</string> - <string name="notification_title" msgid="1259940370369187045">"Błąd logowania na konto <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Synchronizacja"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchronizuj"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Zbyt wiele usuwanych <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Monitorowanie fizycznej lokalizacji"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Połączenia sieciowe"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Pozwól aplikacjom na dostęp do różnych funkcji sieci."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Twoje konta"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Dostęp do udostępnionych kont."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Sterowanie sprzętowe"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Bezpośredni dostęp do elementów sprzętowych telefonu."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Połączenia telefoniczne"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Niestandardowy"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Domowy"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Komórkowy"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Służbowy"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Faks służbowy"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Faks domowy"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Pager"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Inny"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Połączenie zwrotne"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Samochód"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Firmowy główny"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Główny"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Inny faks"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Teleks"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Służbowy komórkowy"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Pager służbowy"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Asystent"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"Wiadomość MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Urodziny"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Rocznica"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Wydarzenie"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Niestandardowy"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Domowy"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Służbowy"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Inny"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Komórkowy"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Niestandardowy"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Domowy"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Służbowy"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Inny"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Niestandardowy"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Domowy"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Służbowy"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Inny"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Niestandardowy"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Służbowy"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Inny"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Niestandardowy"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"przez <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> za pośrednictwem: <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Wprowadź kod PIN"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Błędny kod PIN!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Aby odblokować, naciśnij Menu, a następnie 0."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Niestety, spróbuj ponownie"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Ładowanie (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Naładowany."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Podłącz ładowarkę."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Brak karty SIM."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Brak karty SIM w telefonie."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Ładowanie..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Podłącz ładowarkę"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Bateria się rozładowuje:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"Pozostało: <xliff:g id="NUMBER">%d%%</xliff:g> lub mniej."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Użycie baterii"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Nieudany test fabryczny"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"Czynność FACTORY_TEST jest obsługiwana tylko dla pakietów zainstalowanych w katalogu /system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"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" msgid="6860261758665825069">"Potwierdź"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Wskazówka: dotknij dwukrotnie, aby powiększyć lub pomniejszyć."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"odczyt historii i zakładek przeglądarki"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Umożliwia aplikacji odczyt wszystkich adresów URL odwiedzonych przez przeglądarkę, a także wszystkich zakładek przeglądarki."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"zapis historii i zakładek przeglądarki"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"Czy na pewno sformatować kartę SD? Wszystkie dane na karcie zostaną utracone."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatuj"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string> - <string name="select_input_method" msgid="6865512749462072765">"Wybierz metodę wprowadzania"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandydaci"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Utwórz kontakt"\n"dla numeru <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"zaznaczone"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"niezaznaczone"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Wymienione aplikacje żądają pozwolenia na dostęp do danych logowania dla konta <xliff:g id="ACCOUNT">%1$s</xliff:g> powiązanego z aplikacją <xliff:g id="APPLICATION">%2$s</xliff:g>. Czy chcesz udzielić takiego pozwolenia? Jeśli tak, odpowiedź zostanie zapamiętana i to pytanie nie będzie już wyświetlane."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Wymienione aplikacje żądają pozwolenia na dostęp do danych logowania dotyczących funkcji <xliff:g id="TYPE">%1$s</xliff:g> dla konta <xliff:g id="ACCOUNT">%2$s</xliff:g> powiązanego z aplikacją <xliff:g id="APPLICATION">%3$s</xliff:g>. Czy chcesz udzielić takiego pozwolenia? Jeśli tak, odpowiedź zostanie zapamiętana i to pytanie nie będzie już wyświetlane."</string> <string name="allow" msgid="7225948811296386551">"Zezwól"</string> <string name="deny" msgid="2081879885755434506">"Odmów"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Żądane pozwolenie"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Prośba o pozwolenie"\n"dotyczące konta <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Metoda wprowadzania"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Synchronizacja"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Ułatwienia dostępu"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Zmień tapetę"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Protokół PPTP"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Protokół L2TP"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"Sieć VPN L2TP/IPSec z kluczem PSK"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"Sieć VPN L2TP/IPSec z certyfikatem"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index b2edaae..891e7ce 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Não foi possível aceder ao ficheiro."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Não foi possível localizar o ficheiro pedido."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Existem demasiados pedidos em processamento. Tente novamente mais tarde."</string> - <string name="notification_title" msgid="1259940370369187045">"Erro de início de sessão para <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Sincronização"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronização"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Demasiadas eliminações de <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Monitorizar a sua localização física"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Comunicação de rede"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Permite o acesso de aplicações a várias funcionalidades de rede."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"As suas contas"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Aceda às contas disponíveis."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Controlos de hardware"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Aceda directamente ao hardware no telefone."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Chamadas"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Personalizado"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Residência"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Telemóvel"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Emprego"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Fax do emprego"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Fax da residência"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Pager"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Outro"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Rechamada"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Automóvel"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Telefone principal da empresa"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"RDIS"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Principal"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Outro fax"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Rádio"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Telemóvel do emprego"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Pager do trabalho"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistente"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Data de nascimento"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Aniversário"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Evento"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Personalizado"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Residência"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Emprego"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Outro"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Telemóvel"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Personalizado"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Residência"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Emprego"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Outro"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Personalizado"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Residência"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Emprego"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Outro"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Personalizado"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Emprego"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Outro"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Personalizado"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"através do <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> através de <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Introduzir código PIN"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Código PIN incorrecto!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Para desbloquear, prima Menu e, em seguida, 0."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Lamentamos, tente novamente"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"A carregar (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Carregado."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Ligue o carregador."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Nenhum cartão SIM."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Nenhum cartão SIM no telefone."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"A carregar..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Ligue o carregador"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"A bateria está a ficar fraca:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"Restam <xliff:g id="NUMBER">%d%%</xliff:g> ou menos."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Utilização da bateria"</string> <string name="factorytest_failed" msgid="5410270329114212041">"O teste de fábrica falhou"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"A acção FACTORY_TEST apenas é suportada para pacotes instalados em /system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"Navegar para outra página?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Seleccione OK para continuar ou Cancelar para permanecer na página actual."</string> <string name="save_password_label" msgid="6860261758665825069">"Confirmar"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Sugestão: toque duas vezes para aumentar ou diminuir o zoom."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ler histórico e marcadores do browser"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Permite que a aplicação leia todos os URLs visitados pelo browser e todos os marcadores do browser."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"gravar histórico e marcadores do browser"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"Tem a certeza de que pretende formatar o cartão SD? Perder-se-ão todos os dados no cartão."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatar"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccione para desactivar depuração USB."</string> - <string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de entrada"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Criar contacto"\n"utilizando <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"verificado"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"não verificado"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"As aplicações listadas estão a pedir autorização para aceder às credenciais de início de sessão da conta <xliff:g id="ACCOUNT">%1$s</xliff:g> a partir de <xliff:g id="APPLICATION">%2$s</xliff:g>. Pretende conceder esta autorização? Em caso afirmativo, a sua resposta será memorizada e não terá de responder a esta questão novamente."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"As aplicações listadas estão a pedir autorização para aceder às credenciais de início de sessão <xliff:g id="TYPE">%1$s</xliff:g> para a conta <xliff:g id="ACCOUNT">%2$s</xliff:g> a partir de <xliff:g id="APPLICATION">%3$s</xliff:g>. Pretende conceder esta autorização? Em caso afirmativo, a sua resposta será memorizada e não terá de responder a esta questão novamente."</string> <string name="allow" msgid="7225948811296386551">"Permitir"</string> <string name="deny" msgid="2081879885755434506">"Recusar"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Autorização Solicitada"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Autorização solicitada"\n"para a conta <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Método de entrada"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Sincronização"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Acessibilidade"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Imagem de fundo"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Alterar imagem de fundo"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Protocolo de túnel ponto a ponto (PPTP)"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Protocolo de túnel de camada 2 (L2TP)"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"VPN L2TP/IPSec baseada em chave pré- partilhada"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"VPN L2TP/IPSec baseada em certificado"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 725053c..265fb62 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Não foi possível acessar o arquivo."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"O arquivo solicitado não foi encontrado."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Há muitas solicitações sendo processadas. Tente novamente mais tarde."</string> - <string name="notification_title" msgid="1259940370369187045">"Erro de login para <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Sincronizar"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronizar"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Muitas exclusões de <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Monitora o seu local físico."</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Comunicação da rede"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Permite que os aplicativos acessem diversos recursos de rede."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Suas contas"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Acessar as contas disponíveis."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Controles de hardware"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Acessa o hardware diretamente no aparelho."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Chamadas telefônicas"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Personalizado"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Página inicial"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Celular"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Comercial"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Fax comercial"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Fax residencial"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Pager"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Outros"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Retorno de chamada"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Carro"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Empresa (principal)"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Principal"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Outro fax"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Rádio"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Celular comercial"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Pager comercial"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistente"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Aniversário"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Data comemorativa"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Evento"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Personalizado"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Página inicial"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Comercial"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Outros"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Celular"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Personalizado"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Página inicial"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Comercial"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Outros"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Personalizado"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Página inicial"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Comercial"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Outros"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Personalizado"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Comercial"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Outros"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Personalizado"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"por meio de <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> via <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Digite o código PIN"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Código PIN incorreto!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Para desbloquear, pressione Menu e, em seguida, 0."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Tente novamente"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Carregando (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Carregado."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Conecte o seu carregador."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Sem cartão SIM."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Não há um cartão SIM no telefone."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Carregando..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Conecte o carregador"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"A bateria está ficando baixa:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"<xliff:g id="NUMBER">%d%%</xliff:g> ou menos restante(s)."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Uso da bateria"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Falha no teste de fábrica"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"A ação FACTORY_TEST é suportada apenas para pacotes instalados em /system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"Deseja sair desta página?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Selecione OK para continuar ou Cancelar para permanecer na página atual."</string> <string name="save_password_label" msgid="6860261758665825069">"Confirmar"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Dica: toque duas vezes para aumentar e diminuir o zoom."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ler histórico e favoritos do Navegador"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Permite que o aplicativo leia todos os URLs visitados pelo Navegador e todos os favoritos do Navegador."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"gravar histórico e favoritos do Navegador"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"Tem certeza de que deseja formatar o cartão SD? Todos os dados no seu cartão serão perdidos."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatar"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string> - <string name="select_input_method" msgid="6865512749462072765">"Selecionar método de entrada"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Criar contato "\n"usando <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"selecionado"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"não selecionado"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Os aplicativos listados estão solicitando autorização para acessar as credenciais de login para a conta <xliff:g id="ACCOUNT">%1$s</xliff:g> do <xliff:g id="APPLICATION">%2$s</xliff:g>. Deseja conceder essa autorização? Em caso afirmativo, sua resposta será lembrada e essa pergunta não será feita novamente."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Os aplicativos listados estão solicitando autorização para acessar as credenciais de login <xliff:g id="TYPE">%1$s</xliff:g> para a conta <xliff:g id="ACCOUNT">%2$s</xliff:g> do <xliff:g id="APPLICATION">%3$s</xliff:g>. Deseja conceder essa autorização? Em caso afirmativo, sua resposta será lembrada e essa pergunta não será feita novamente."</string> <string name="allow" msgid="7225948811296386551">"Permitir"</string> <string name="deny" msgid="2081879885755434506">"Negar"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Autorização solicitada"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Solicitada a permissão"\n"para a conta <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Método de entrada"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Sincronizar"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Acessibilidade"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Papel de parede"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Alterar papel de parede"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Protocolo de encapsulamento ponto a ponto"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Protocolo de encapsulamento de camada 2"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"VPN L2TP/IPSec com base em chave pré-compartilhada"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"VPN L2TP/IPSec com base em certificado"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 1e1500b..373c45e 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Не удается получить доступ к файлу."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Не удалось найти указанные файлы."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Обрабатывается слишком много запросов. Повторите попытку позднее."</string> - <string name="notification_title" msgid="1259940370369187045">"Ошибка входа (<xliff:g id="ACCOUNT">%1$s</xliff:g>)"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Синхр."</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Синхр."</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Слишком много удалений <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Отслеживание физического местоположения"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Сетевой обмен данными"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Позволяет приложениям получать доступ к различным сетевым функциям."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Ваши аккаунты"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Доступ к имеющимся аккаунтам."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Элементы управления аппаратным обеспечением"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Прямой доступ к аппаратному обеспечению телефона."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Телефонные вызовы"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Особый"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Дом"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Моб."</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Раб."</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Раб. факс"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Дом. факс"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Пейджер"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Другой"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Обр. вызов"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"В авто"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Раб., осн."</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Основной"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Доп. факс"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Радио"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Телекс"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"Телетайп"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Раб. моб."</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Рабочий пейджер"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Секретарь"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"День рождения"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Юбилей"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Мероприятие"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Особый"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Дом"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Раб."</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Другой"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Моб."</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Особый"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Дом"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Раб."</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Другой"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Особый"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Дом"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Раб."</string> - <string name="imTypeOther" msgid="5377007495735915478">"Другой"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Особый"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Раб."</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Другой"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Особый"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"с помощью <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> с помощью <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Введите PIN-код"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Неверный PIN-код!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Для разблокировки нажмите \"Меню\", а затем 0."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Повторите попытку"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Идет зарядка (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Заряжена."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Подключите зарядное устройство."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Нет SIM-карты."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"SIM-карта не установлена."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Идет зарядка..."</string> <string name="battery_low_title" msgid="7923774589611311406">"Подключите зарядное устройство"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Батарея разряжена:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"Осталось <xliff:g id="NUMBER">%d%%</xliff:g> или меньше."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Расход заряда батареи"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Не удалось провести стандартный тест"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"Действие FACTORY_TEST поддерживается только для пакетов, установленных в /system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"Перейти с этой страницы?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Нажмите \"ОК\", чтобы продолжить, или \"Отмена\", чтобы остаться на текущей странице."</string> <string name="save_password_label" msgid="6860261758665825069">"Подтвердите"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Совет: нажмите дважды, чтобы увеличить и уменьшить масштаб."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"считывать историю и закладки браузера"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Разрешает приложению считывать все URL, посещенные браузером, и все его закладки."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"записывать историю и закладки браузера"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"Отформатировать карту SD? Все данные, находящиеся на карте, будут уничтожены."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Формат"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка USB подключена"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку USB."</string> - <string name="select_input_method" msgid="6865512749462072765">"Выберите способ ввода"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"варианты"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Создать контакт"\n"с номером <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"отмечено"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"не проверено"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Перечисленные приложения запрашивают разрешение на доступ к регистрационном данным аккаунта <xliff:g id="ACCOUNT">%1$s</xliff:g> из <xliff:g id="APPLICATION">%2$s</xliff:g>. Разрешить доступ? Если да, ответ будет сохранен и это сообщение больше не будет выводиться."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Перечисленные приложения запрашивают разрешение на доступ к регистрационном данным <xliff:g id="TYPE">%1$s</xliff:g> аккаунта <xliff:g id="ACCOUNT">%2$s</xliff:g> из <xliff:g id="APPLICATION">%3$s</xliff:g>. Разрешить доступ? Если да, ответ будет сохранен и это сообщение больше не будет выводиться."</string> <string name="allow" msgid="7225948811296386551">"Разрешить"</string> <string name="deny" msgid="2081879885755434506">"Отклонить"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Разрешение запрошено"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Требуется разрешение"\n"для аккаунта <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Способ ввода"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Синхр."</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Специальные возможности"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Фоновый рисунок"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Изменить фоновый рисунок"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Протокол PPTP"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Протокол L2TP"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"L2TP/IPSec VPN (на основе предв. общ. ключа)"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"L2TP/IPSec VPN (на основе сертификата)"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 823ba22..db77ee1 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Det gick inte att komma åt filen."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Den begärda filen hittades inte."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"För många begäranden bearbetas. Försök igen senare."</string> - <string name="notification_title" msgid="1259940370369187045">"Inloggningsfel för <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Synkronisera"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synkronisera"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"För många <xliff:g id="CONTENT_TYPE">%s</xliff:g>-borttagningar."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Övervaka din fysiska plats"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Nätverkskommunikation"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Tillåt att program kommer åt olika nätverksfunktioner."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Dina konton"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Få åtkomst till tillgängliga konton."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Kontroller för maskinvara"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Direkt åtkomst till maskinvara på handenheten."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Telefonsamtal"</string> @@ -316,7 +319,7 @@ <string name="permlab_callPrivileged" msgid="4198349211108497879">"ringa telefonnummer direkt"</string> <string name="permdesc_callPrivileged" msgid="244405067160028452">"Tillåter att programmet ringer ett telefonnummer, inklusive nödnummer, utan att du behöver göra något. Skadliga program kan ringa onödiga och olagliga samtal till räddningtjänsten."</string> <string name="permlab_performCdmaProvisioning" msgid="5604848095315421425">"starta CDMA-telefoninställningar direkt"</string> - <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Tillåter att programmet startar CDMA-anslutning. Skadliga program kan starta CDMA-anslutningar i onödan."</string> + <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Tillåter att programmet startar CDMA-anslutning. Skadliga program kan skada CDMA-anslutningar i onödan."</string> <string name="permlab_locationUpdates" msgid="7785408253364335740">"styra meddelanden för platsuppdatering"</string> <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Tillåter aktivering och inaktivering av avisering om platsuppdatering i radion. Används inte av vanliga program."</string> <string name="permlab_checkinProperties" msgid="7855259461268734914">"få åtkomst till incheckningsegenskaper"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Anpassad"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Hem"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobil"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"Arbete"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Arbetsfax"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Hemfax"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Personsökare"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Övrigt"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Återuppringning"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Bil"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Nummer till företag"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Telefonnummer"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Annat faxnummer"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mobiltelefon, arbetet"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"Personsökare, arbetet"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistent"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Födelsedag"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Högtidsdag"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Händelse"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Anpassad"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Hem"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"Arbete"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Övrigt"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Anpassad"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Hem"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"Arbete"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Övrigt"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Anpassad"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Hem"</string> - <string name="imTypeWork" msgid="1371489290242433090">"Arbete"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Övrigt"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Anpassad"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"Arbete"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Övrigt"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Anpassad"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"via <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g> via <xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Ange PIN-kod"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Fel PIN-kod!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Tryck på Meny och sedan på 0 om du vill låsa upp."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Försök igen"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Laddar (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Laddad."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Anslut din laddare."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Inget SIM-kort."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Inget SIM-kort i telefonen."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Laddar…"</string> <string name="battery_low_title" msgid="7923774589611311406">"Anslut laddaren"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Batteriet håller på att ta slut:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"<xliff:g id="NUMBER">%d%%</xliff:g> eller mindre kvar."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Batteriförbrukning"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Det gick fel vid fabrikstestet"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"Åtgärden FACTORY_TEST stöds endast för paket som har installerats i /system/app."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"Vill du lämna den här den här sidan?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Tryck på OK om du vill fortsätta eller på Avbryt om du vill vara kvar på den aktuella sidan."</string> <string name="save_password_label" msgid="6860261758665825069">"Bekräfta"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"Tips! Dubbelklicka om du vill zooma in eller ut."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"läsa webbläsarhistorik och bokmärken"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Tillåter att program läser alla webbadresser som webbläsaren har öppnat och alla webbläsarens bokmärken."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"skriva webbläsarhistorik och bokmärken"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"Vill du formatera SD-kortet? Alla data på ditt kort kommer att gå förlorade."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"Välj att inaktivera USB-felsökning."</string> - <string name="select_input_method" msgid="6865512749462072765">"Välj indatametod"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"Skapa kontakt"\n"med <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"markerad"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"inte markerad"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Programmen begär åtkomst till inloggningsuppgifterna för kontot <xliff:g id="ACCOUNT">%1$s</xliff:g> från <xliff:g id="APPLICATION">%2$s</xliff:g>. Vill du bevilja behörighet? Om du gör det kommer vi ihåg det och du blir inte tillfrågad igen."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Programmen begär åtkomst till inloggningsuppgifterna <xliff:g id="TYPE">%1$s</xliff:g> för kontot <xliff:g id="ACCOUNT">%2$s</xliff:g> från <xliff:g id="APPLICATION">%3$s</xliff:g>. Vill du bevilja behörighet? Om du gör det kommer vi ihåg det och du blir inte tillfrågad igen."</string> <string name="allow" msgid="7225948811296386551">"Tillåt"</string> <string name="deny" msgid="2081879885755434506">"Neka"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Begärd behörighet"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Behörighet krävs"\n"för kontot <xliff:g id="ACCOUNT">%s</xliff:g>"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Indatametod"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Synkronisera"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Tillgänglighet"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Bakgrund"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Ändra bakgrund"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Point-to-Point Tunneling Protocol"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Layer 2 Tunneling Protocol"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"I förväg delad L2TP/IPSec VPN-nyckel"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"Certifikatsbaserad L2TP/IPSec VPN"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index f95fc0a..503ad7d 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"Dosyaya erişilemedi."</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"İstenen dosya bulunamadı."</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Çok fazla sayıda istek işleniyor. Daha sonra yeniden deneyin."</string> - <string name="notification_title" msgid="1259940370369187045">"<xliff:g id="ACCOUNT">%1$s</xliff:g> hesabı için oturum açma hatası"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"Senk."</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Senk."</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Çok fazla <xliff:g id="CONTENT_TYPE">%s</xliff:g> silme var."</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"Fiziksel konumunuzu izleyin"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"Ağ iletişimi"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"Uygulamaların çeşitli ağ özelliklerine erişmesine izin verir."</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"Hesaplarınız"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Kullanılabilir hesaplara erişin."</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Donanım denetimleri"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Telefon donanımına doğrudan erişim."</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Telefon çağrıları"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"Özel"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Ev"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobil"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"İş"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"İş Faksı"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Ev Faksı"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"Çağrı cihazı"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"Diğer"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"Geri Arama"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"Araç"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Şirket Merkezi"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"Ana"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Diğer Faks"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"Telsiz"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Teleks"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"İş Yeri Cep Telefonu"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"İş Yeri Çağrı Cihazı"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"Yardımcı"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"Doğum günü"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"Yıldönümü"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"Etkinlik"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"Özel"</string> - <string name="emailTypeHome" msgid="449227236140433919">"Ev"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"İş"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"Diğer"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"Özel"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Ev"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"İş"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"Diğer"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"Özel"</string> - <string name="imTypeHome" msgid="6241181032954263892">"Ev"</string> - <string name="imTypeWork" msgid="1371489290242433090">"İş"</string> - <string name="imTypeOther" msgid="5377007495735915478">"Diğer"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"Özel"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"İş"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"Diğer"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"Özel"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"<xliff:g id="SOURCE">%1$s</xliff:g> aracılığıyla"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="SOURCE">%2$s</xliff:g> ile <xliff:g id="DATE">%1$s</xliff:g> tarihinde"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"PIN kodunu gir"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Yanlış PIN kodu!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"Kilidi açmak için önce Menü\'ye, sonra 0\'a basın."</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"Üzgünüz, lütfen yeniden deneyin"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"Şarj oluyor (<xliff:g id="PERCENT">%%</xliff:g><xliff:g id="NUMBER">%d</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"Şarj oldu."</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Şarj cihazınızı bağlayın."</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"SIM kart yok."</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"Telefonda SIM kart yok."</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"Şarj oluyor…"</string> <string name="battery_low_title" msgid="7923774589611311406">"Lütfen şarj cihazını takın"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"Pil tükeniyor:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"<xliff:g id="NUMBER">%d%%</xliff:g> veya daha az kaldı."</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"Pil kullanımı"</string> <string name="factorytest_failed" msgid="5410270329114212041">"Fabrika testi yapılamadı"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST işlemi yalnızca /system/app dizinine yüklenmiş paketler için desteklenir."</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"Bu sayfadan ayrılıyor musunuz?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Devam etmek için Tamam\'ı, sayfada kalmak için İptal\'i tıklatın."</string> <string name="save_password_label" msgid="6860261758665825069">"Onayla"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"İpucu: Yakınlaştırmak ve uzaklaştırmak için iki kez hafifçe vurun."</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"Tarayıcı geçmişini ve favorileri oku"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Uygulamaya Tarayıcının ziyaret etmiş olduğu tüm URL\'leri ve Tarayıcının tüm favorilerini okuma izni verir."</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"Tarayıcı geçmişini ve favorileri yaz"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"SD kartı biçimlendirmek istediğinizden emin misiniz? Kartınızdaki tüm veriler yok olacak."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Biçimlendir"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için tıklayın."</string> - <string name="select_input_method" msgid="6865512749462072765">"Giriş yöntemini seç"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g>"\n" ile kişi oluştur"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"seçildi"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"seçilmedi"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"Listelenen uygulamalar, <xliff:g id="APPLICATION">%2$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%1$s</xliff:g> hesabı için giriş bilgilerine erişim izni istiyor. Bu izni vermek istiyor musunuz? İstiyorsanız yanıtınız kaydedilecek ve tekrar sorulmayacaktır."</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"Listelenen uygulamalar, <xliff:g id="APPLICATION">%3$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%2$s</xliff:g> hesabı için <xliff:g id="TYPE">%1$s</xliff:g> girişi bilgilerine erişim izni istiyor. Bu izni vermek istiyor musunuz? İstiyorsanız yanıtınız kaydedilecek ve tekrar sorulmayacaktır."</string> <string name="allow" msgid="7225948811296386551">"İzin Ver"</string> <string name="deny" msgid="2081879885755434506">"Reddet"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"İzin İstendi"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"<xliff:g id="ACCOUNT">%s</xliff:g> hesabı için"\n"İzin İstendi"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"Giriş yöntemi"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Senkronizasyon"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Erişebilirlik"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Duvar Kağıdı"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Duvar kağıdını değiştir"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"Noktadan Noktaya Tünel Protokolü Kuralları"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"Katman 2 Tünel Protokolü"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"L2TP/IPSec VPN temelli önceden paylaşılmış anahtar"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"L2TP/IPSec VPN temelli sertifika"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index ab5554b..474fffc 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"无法访问该文件。"</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"找不到请求的文件。"</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"正在处理的请求太多,请稍后重试。"</string> - <string name="notification_title" msgid="1259940370369187045">"<xliff:g id="ACCOUNT">%1$s</xliff:g> 发生登录错误"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"同步"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"同步"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"太多<xliff:g id="CONTENT_TYPE">%s</xliff:g>删除项。"</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"监视您的物理位置"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"网络通信"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"允许应用程序访问各种网络功能。"</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"您的帐户"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"访问可用的帐户。"</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"硬件控制"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"直接访问手机上的硬件。"</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"手机通话"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"自定义"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"住宅"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"手机"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"单位"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"单位传真"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"住宅传真"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"寻呼机"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"其他"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"回拨号码"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"车载电话"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"公司总机"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"总机"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"其他传真"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"无线装置"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"电报"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"单位手机"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"单位寻呼机"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"助理"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"彩信"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"生日"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"周年纪念"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"活动"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"自定义"</string> - <string name="emailTypeHome" msgid="449227236140433919">"住宅"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"单位"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"其他"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"手机"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"自定义"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"住宅"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"单位"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"其他"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"自定义"</string> - <string name="imTypeHome" msgid="6241181032954263892">"住宅"</string> - <string name="imTypeWork" msgid="1371489290242433090">"单位"</string> - <string name="imTypeOther" msgid="5377007495735915478">"其他"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"自定义"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"雅虎"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> - <string name="orgTypeWork" msgid="29268870505363872">"公司"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"其他"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"自定义"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"通过 <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"时间:<xliff:g id="DATE">%1$s</xliff:g>,方式:<xliff:g id="SOURCE">%2$s</xliff:g>"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"输入 PIN 码"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"PIN 码不正确!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"要解锁,请先按 MENU 再按 0。"</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"很抱歉,请重试"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"正在充电 (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"已充满。"</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"连接您的充电器。"</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"没有 SIM 卡"</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"手机中无 SIM 卡"</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"正在充电..."</string> <string name="battery_low_title" msgid="7923774589611311406">"请连接充电器"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"电量在减少:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"电量剩余 <xliff:g id="NUMBER">%d%%</xliff:g> 或更少。"</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"电量使用情况"</string> <string name="factorytest_failed" msgid="5410270329114212041">"出厂测试失败"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"只有 /system/app 中安装的包支持 FACTORY_TEST 操作。"</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"是否从该页面导航至它处?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"选择“确定”继续,或选择“取消”留在当前页面。"</string> <string name="save_password_label" msgid="6860261758665825069">"确认"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"提示:点按两次可放大和缩小。"</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"读取浏览器的历史记录和书签"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"允许应用程序读取用浏览器访问过的所有网址,以及浏览器的所有书签。"</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"写入浏览器的历史记录和书签"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"您确定要格式化 SD 卡?卡上的所有数据都会丢失。"</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"格式化"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接 USB 调试"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"选择停用 USB 调试。"</string> - <string name="select_input_method" msgid="6865512749462072765">"选择输入法"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"候选"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"创建电话号码为"\n"<xliff:g id="NUMBER">%s</xliff:g> 的联系人"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"已选中"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"未选中"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"所列应用程序正在请求相应的权限,以便从<xliff:g id="APPLICATION">%2$s</xliff:g>访问 <xliff:g id="ACCOUNT">%1$s</xliff:g> 帐户的登录凭据。是否要授予这种权限?如果授予,系统会记住您所做的选择,且不再提示。"</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"所列应用程序正在请求相应的权限,以便从<xliff:g id="APPLICATION">%3$s</xliff:g>访问 <xliff:g id="ACCOUNT">%2$s</xliff:g> 帐户的<xliff:g id="TYPE">%1$s</xliff:g>登录凭据。是否要授予这种权限?如果授予,系统会记住您所做的选择,且不再提示。"</string> <string name="allow" msgid="7225948811296386551">"允许"</string> <string name="deny" msgid="2081879885755434506">"拒绝"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"已请求权限"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"已为帐户<xliff:g id="ACCOUNT">%s</xliff:g>"\n"请求了权限"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"输入法"</string> <string name="sync_binding_label" msgid="3687969138375092423">"同步"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"辅助功能"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"壁纸"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"更改壁纸"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"点对点隧道协议"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"第 2 层隧道协议"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"基于预共享密钥的 L2TP/IPSec VPN"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"基于证书的 L2TP/IPSec VPN"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index da02fe7..3542536 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -111,7 +111,8 @@ <string name="httpErrorFile" msgid="8250549644091165175">"無法存取此檔案。"</string> <string name="httpErrorFileNotFound" msgid="5588380756326017105">"找不到要求的檔案。"</string> <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"太多執行要求。請稍後再試一次。"</string> - <string name="notification_title" msgid="1259940370369187045">"<xliff:g id="ACCOUNT">%1$s</xliff:g>登入錯誤"</string> + <!-- no translation found for notification_title (1259940370369187045) --> + <skip /> <string name="contentServiceSync" msgid="8353523060269335667">"同步處理"</string> <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"同步處理"</string> <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"同時刪除太多 <xliff:g id="CONTENT_TYPE">%s</xliff:g>。"</string> @@ -147,8 +148,10 @@ <string name="permgroupdesc_location" msgid="2430258821648348660">"監視實際位置"</string> <string name="permgrouplab_network" msgid="5808983377727109831">"網路通訊"</string> <string name="permgroupdesc_network" msgid="5035763698958415998">"允許應用程式存取多項網路功能。"</string> - <string name="permgrouplab_accounts" msgid="3359646291125325519">"您的帳戶"</string> - <string name="permgroupdesc_accounts" msgid="4948732641827091312">"存取可用帳戶。"</string> + <!-- no translation found for permgrouplab_accounts (3359646291125325519) --> + <skip /> + <!-- no translation found for permgroupdesc_accounts (4948732641827091312) --> + <skip /> <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"硬體控制"</string> <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"在免持設備上直接存取硬體。"</string> <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"撥打電話"</string> @@ -432,58 +435,110 @@ <item msgid="2506857312718630823">"ICQ"</item> <item msgid="1648797903785279353">"Jabber"</item> </string-array> - <string name="phoneTypeCustom" msgid="1644738059053355820">"自訂"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"住家"</string> - <string name="phoneTypeMobile" msgid="6501463557754751037">"行動裝置"</string> - <string name="phoneTypeWork" msgid="8863939667059911633">"公司"</string> - <string name="phoneTypeFaxWork" msgid="3517792160008890912">"公司傳真"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"住家傳真"</string> - <string name="phoneTypePager" msgid="7582359955394921732">"呼叫器"</string> - <string name="phoneTypeOther" msgid="1544425847868765990">"其他"</string> - <string name="phoneTypeCallback" msgid="2712175203065678206">"回撥電話"</string> - <string name="phoneTypeCar" msgid="8738360689616716982">"汽車電話"</string> - <string name="phoneTypeCompanyMain" msgid="540434356461478916">"公司代表號"</string> - <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> - <string name="phoneTypeMain" msgid="6766137010628326916">"代表號"</string> - <string name="phoneTypeOtherFax" msgid="8587657145072446565">"其他傳真"</string> - <string name="phoneTypeRadio" msgid="4093738079908667513">"無線電"</string> - <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string> - <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY/TDD"</string> - <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"公司行動電話"</string> - <string name="phoneTypeWorkPager" msgid="649938731231157056">"公司呼叫器"</string> - <string name="phoneTypeAssistant" msgid="5596772636128562884">"助理"</string> - <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> - <string name="eventTypeBirthday" msgid="2813379844211390740">"生日"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"週年紀念日"</string> - <string name="eventTypeOther" msgid="5834288791948564594">"活動"</string> - <string name="emailTypeCustom" msgid="8525960257804213846">"自訂"</string> - <string name="emailTypeHome" msgid="449227236140433919">"住家"</string> - <string name="emailTypeWork" msgid="3548058059601149973">"公司"</string> - <string name="emailTypeOther" msgid="2923008695272639549">"其他"</string> - <string name="emailTypeMobile" msgid="119919005321166205">"行動裝置"</string> - <string name="postalTypeCustom" msgid="8903206903060479902">"自訂"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"住家"</string> - <string name="postalTypeWork" msgid="5268172772387694495">"公司"</string> - <string name="postalTypeOther" msgid="2726111966623584341">"其他"</string> - <string name="imTypeCustom" msgid="2074028755527826046">"自訂"</string> - <string name="imTypeHome" msgid="6241181032954263892">"住家"</string> - <string name="imTypeWork" msgid="1371489290242433090">"公司"</string> - <string name="imTypeOther" msgid="5377007495735915478">"其他"</string> - <string name="imProtocolCustom" msgid="6919453836618749992">"自訂"</string> - <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> - <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> - <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> - <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> - <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> - <string name="imProtocolGoogleTalk" msgid="3808393979157698766">"Google Talk"</string> - <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> - <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> - <string name="imProtocolNetMeeting" msgid="8287625655986827971">"網路會議"</string> - <string name="orgTypeWork" msgid="29268870505363872">"公司"</string> - <string name="orgTypeOther" msgid="3951781131570124082">"其他"</string> - <string name="orgTypeCustom" msgid="225523415372088322">"自訂"</string> - <string name="contact_status_update_attribution" msgid="5112589886094402795">"透過 <xliff:g id="SOURCE">%1$s</xliff:g>"</string> - <string name="contact_status_update_attribution_with_date" msgid="5945386376369979909">"<xliff:g id="DATE">%1$s</xliff:g>透過「<xliff:g id="SOURCE">%2$s</xliff:g>」"</string> + <!-- no translation found for phoneTypeCustom (1644738059053355820) --> + <skip /> + <!-- no translation found for phoneTypeHome (2570923463033985887) --> + <skip /> + <!-- no translation found for phoneTypeMobile (6501463557754751037) --> + <skip /> + <!-- no translation found for phoneTypeWork (8863939667059911633) --> + <skip /> + <!-- no translation found for phoneTypeFaxWork (3517792160008890912) --> + <skip /> + <!-- no translation found for phoneTypeFaxHome (2067265972322971467) --> + <skip /> + <!-- no translation found for phoneTypePager (7582359955394921732) --> + <skip /> + <!-- no translation found for phoneTypeOther (1544425847868765990) --> + <skip /> + <!-- no translation found for phoneTypeCallback (2712175203065678206) --> + <skip /> + <!-- no translation found for phoneTypeCar (8738360689616716982) --> + <skip /> + <!-- no translation found for phoneTypeCompanyMain (540434356461478916) --> + <skip /> + <!-- no translation found for phoneTypeIsdn (8022453193171370337) --> + <skip /> + <!-- no translation found for phoneTypeMain (6766137010628326916) --> + <skip /> + <!-- no translation found for phoneTypeOtherFax (8587657145072446565) --> + <skip /> + <!-- no translation found for phoneTypeRadio (4093738079908667513) --> + <skip /> + <!-- no translation found for phoneTypeTelex (3367879952476250512) --> + <skip /> + <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) --> + <skip /> + <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) --> + <skip /> + <!-- no translation found for phoneTypeWorkPager (649938731231157056) --> + <skip /> + <!-- no translation found for phoneTypeAssistant (5596772636128562884) --> + <skip /> + <!-- no translation found for phoneTypeMms (7254492275502768992) --> + <skip /> + <!-- no translation found for eventTypeBirthday (2813379844211390740) --> + <skip /> + <!-- no translation found for eventTypeAnniversary (3876779744518284000) --> + <skip /> + <!-- no translation found for eventTypeOther (5834288791948564594) --> + <skip /> + <!-- no translation found for emailTypeCustom (8525960257804213846) --> + <skip /> + <!-- no translation found for emailTypeHome (449227236140433919) --> + <skip /> + <!-- no translation found for emailTypeWork (3548058059601149973) --> + <skip /> + <!-- no translation found for emailTypeOther (2923008695272639549) --> + <skip /> + <!-- no translation found for emailTypeMobile (119919005321166205) --> + <skip /> + <!-- no translation found for postalTypeCustom (8903206903060479902) --> + <skip /> + <!-- no translation found for postalTypeHome (8165756977184483097) --> + <skip /> + <!-- no translation found for postalTypeWork (5268172772387694495) --> + <skip /> + <!-- no translation found for postalTypeOther (2726111966623584341) --> + <skip /> + <!-- no translation found for imTypeCustom (2074028755527826046) --> + <skip /> + <!-- no translation found for imTypeHome (6241181032954263892) --> + <skip /> + <!-- no translation found for imTypeWork (1371489290242433090) --> + <skip /> + <!-- no translation found for imTypeOther (5377007495735915478) --> + <skip /> + <!-- no translation found for imProtocolCustom (6919453836618749992) --> + <skip /> + <!-- no translation found for imProtocolAim (7050360612368383417) --> + <skip /> + <!-- no translation found for imProtocolMsn (144556545420769442) --> + <skip /> + <!-- no translation found for imProtocolYahoo (8271439408469021273) --> + <skip /> + <!-- no translation found for imProtocolSkype (9019296744622832951) --> + <skip /> + <!-- no translation found for imProtocolQq (8887484379494111884) --> + <skip /> + <!-- no translation found for imProtocolGoogleTalk (3808393979157698766) --> + <skip /> + <!-- no translation found for imProtocolIcq (1574870433606517315) --> + <skip /> + <!-- no translation found for imProtocolJabber (2279917630875771722) --> + <skip /> + <!-- no translation found for imProtocolNetMeeting (8287625655986827971) --> + <skip /> + <!-- no translation found for orgTypeWork (29268870505363872) --> + <skip /> + <!-- no translation found for orgTypeOther (3951781131570124082) --> + <skip /> + <!-- no translation found for orgTypeCustom (225523415372088322) --> + <skip /> + <!-- no translation found for contact_status_update_attribution (5112589886094402795) --> + <skip /> + <!-- no translation found for contact_status_update_attribution_with_date (5945386376369979909) --> + <skip /> <string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"輸入 PIN 碼"</string> <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"PIN 碼錯誤!"</string> <string name="keyguard_label_text" msgid="861796461028298424">"如要解鎖,請按 Menu 鍵,然後按 0。"</string> @@ -498,7 +553,8 @@ <string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"很抱歉,請再試一次"</string> <string name="lockscreen_plugged_in" msgid="613343852842944435">"正在充電 (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string> <string name="lockscreen_charged" msgid="4938930459620989972">"充電完成。"</string> - <string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> + <!-- no translation found for lockscreen_battery_short (3617549178603354656) --> + <skip /> <string name="lockscreen_low_battery" msgid="1482873981919249740">"請連接充電器。"</string> <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"沒有 SIM 卡。"</string> <string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"手機未插入 SIM 卡。"</string> @@ -530,7 +586,8 @@ <string name="battery_status_charging" msgid="756617993998772213">"充電中"</string> <string name="battery_low_title" msgid="7923774589611311406">"請連接充電器"</string> <string name="battery_low_subtitle" msgid="7388781709819722764">"電池電量即將不足:"</string> - <string name="battery_low_percent_format" msgid="696154104579022959">"還剩 <xliff:g id="NUMBER">%d%%</xliff:g> 以下。"</string> + <!-- no translation found for battery_low_percent_format (696154104579022959) --> + <skip /> <string name="battery_low_why" msgid="7279169609518386372">"電池使用狀況"</string> <string name="factorytest_failed" msgid="5410270329114212041">"出廠測試失敗"</string> <string name="factorytest_not_system" msgid="4435201656767276723">"只有安裝在 /system/app 裡的程式才能支援 FACTORY_TEST 操作。"</string> @@ -540,7 +597,8 @@ <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload" msgid="1901675448179653089">"離開此頁?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n" 選取 [確定] 離開此頁;或 [取消] 留在此頁。"</string> <string name="save_password_label" msgid="6860261758665825069">"確認"</string> - <string name="double_tap_toast" msgid="1068216937244567247">"提示:輕按兩下可放大縮小。"</string> + <!-- no translation found for double_tap_toast (1068216937244567247) --> + <skip /> <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"讀取瀏覽器的記錄與書籤"</string> <string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"允許應用程式讀取瀏覽器曾經造訪過的所有網址,以及瀏覽器的所有書籤。"</string> <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"寫入瀏覽器的記錄與書籤"</string> @@ -745,8 +803,10 @@ <string name="extmedia_format_message" msgid="3621369962433523619">"確定要將 SD 卡格式化嗎?該 SD 卡中的所有資料將會遺失。"</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"格式化"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 偵錯模式已啟用"</string> - <string name="adb_active_notification_message" msgid="8470296818270110396">"選取以停用 USB 偵錯。"</string> - <string name="select_input_method" msgid="6865512749462072765">"選取輸入方式"</string> + <!-- no translation found for adb_active_notification_message (8470296818270110396) --> + <skip /> + <!-- no translation found for select_input_method (6865512749462072765) --> + <skip /> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string> @@ -777,19 +837,22 @@ <string name="create_contact_using" msgid="4947405226788104538">"建立手機號碼為 <xliff:g id="NUMBER">%s</xliff:g>"\n"的聯絡人"</string> <string name="accessibility_compound_button_selected" msgid="5612776946036285686">"已勾選"</string> <string name="accessibility_compound_button_unselected" msgid="8864512895673924091">"未勾選"</string> - <string name="grant_credentials_permission_message_desc" msgid="6883276587034335667">"這些應用程式要求存取「<xliff:g id="APPLICATION">%2$s</xliff:g>」的 <xliff:g id="ACCOUNT">%1$s</xliff:g> 帳戶登入認證的權限,您要授予此權限嗎?如果確定授予,系統會記住您的選擇,不會再次詢問您。"</string> - <string name="grant_credentials_permission_message_with_authtokenlabel_desc" msgid="3159007601893584687">"這些應用程式要求存取「<xliff:g id="APPLICATION">%3$s</xliff:g>」的 <xliff:g id="ACCOUNT">%2$s</xliff:g> 帳戶「<xliff:g id="TYPE">%1$s</xliff:g>」登入認證的權限,您要授予此權限嗎?如果確定授予,系統會記住您的選擇,不會再次詢問您。"</string> <string name="allow" msgid="7225948811296386551">"允許"</string> <string name="deny" msgid="2081879885755434506">"拒絕"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"已要求權限"</string> - <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"帳戶 <xliff:g id="ACCOUNT">%s</xliff:g> 的"\n"權限要求"</string> + <!-- no translation found for permission_request_notification_with_subtitle (4325409589686688000) --> + <skip /> <string name="input_method_binding_label" msgid="1283557179944992649">"輸入方式"</string> <string name="sync_binding_label" msgid="3687969138375092423">"同步處理"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"協助工具"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"桌布"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"變更桌布"</string> - <string name="pptp_vpn_description" msgid="2688045385181439401">"點對點通道通訊協定"</string> - <string name="l2tp_vpn_description" msgid="3750692169378923304">"第二層通道通訊協定"</string> - <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"採用預先共用金鑰的 L2TP/IPSec VPN"</string> - <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"採用憑證的 L2TP/IPSec VPN"</string> + <!-- no translation found for pptp_vpn_description (2688045385181439401) --> + <skip /> + <!-- no translation found for l2tp_vpn_description (3750692169378923304) --> + <skip /> + <!-- no translation found for l2tp_ipsec_psk_vpn_description (3945043564008303239) --> + <skip /> + <!-- no translation found for l2tp_ipsec_crt_vpn_description (5382714073103653577) --> + <skip /> </resources> diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index 5d3069b..a506c9a 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -78,6 +78,7 @@ <!-- For security permissions --> <color name="perms_dangerous_grp_color">#dd6826</color> <color name="perms_dangerous_perm_color">#dd6826</color> + <color name="shadow">#cc222222</color> <!-- For search-related UIs --> <color name="search_url_text_normal">#7fa87f</color> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index de30fe7..83a6dc5 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2067,16 +2067,9 @@ <!-- Title for the unselected state of a CompoundButton. --> <string name="accessibility_compound_button_unselected">not checked</string> - <string name="grant_credentials_permission_message_desc">The - listed applications are requesting permission to access the login credentials for account <xliff:g id="account" example="foo@gmail.com">%1$s</xliff:g> from - <xliff:g id="application" example="Google Apps">%2$s</xliff:g>. Do you wish to grant this permission? If so, your answer will be remembered and you will not be prompted - again.</string> - - <string name="grant_credentials_permission_message_with_authtokenlabel_desc">The - listed applications are requesting permission to access the <xliff:g id="type" example="Contacts">%1$s</xliff:g> login credentials for account <xliff:g id="account" example="foo@gmail.com">%2$s</xliff:g> from - <xliff:g id="application" example="Google Apps">%3$s</xliff:g>. Do you wish to grant this permission? If so, your answer will be remembered and you will not be prompted - again.</string> - + <string name="grant_credentials_permission_message_header">The following one or more applications request permission to access your account, now and in the future.</string> + <string name="grant_credentials_permission_message_footer">Do you want to allow this request?</string> + <string name="grant_permissions_header_text">Access Request</string> <string name="allow">Allow</string> <string name="deny">Deny</string> <string name="permission_request_notification_title">Permission Requested</string> @@ -2100,4 +2093,6 @@ <string name="l2tp_vpn_description">Layer 2 Tunneling Protocol</string> <string name="l2tp_ipsec_psk_vpn_description">Pre-shared key based L2TP/IPSec VPN</string> <string name="l2tp_ipsec_crt_vpn_description">Certificate based L2TP/IPSec VPN</string> + <!-- Label for button in a WebView that will open a chooser to choose a file to upload --> + <string name="upload_file">Choose file</string> </resources> |
