Secure Text Entry هو وضع إدخال نص في Android حيث يتم عرض الأحرف المدخلة بشكل مخفي (نقاط أو نجوم) بدلاً من الأحرف الفعلية. يُستخدم هذا الوضع لحقول كلمات المرور وأرقام PIN ورموز CVV والمعلومات السرية الأخرى. لا يحمي Secure Text Entry البيانات من الاعتراض البصري فحسب، بل يمنع أيضًا التسرب من خلال لقطات الشاشة وتسجيلات الشاشة وميزات التصحيح التلقائي. وفقًا لـ Android Security Best Practices (2026)، فإن الإدخال المخفي هو متطلب إلزامي للتطبيقات التي تتعامل مع بيانات مصادقة المستخدمين.
الخلاصة
Secure Text Entry (إدخال النص المحمي) هي ميزة في Android تستبدل عرض كل حرف مدخل بحرف إخفاء، عادةً نقطة (•) أو نجمة (*). يمنع ذلك قراءة كلمة المرور من فوق الكتف (shoulder surfing) ويخفي البيانات المدخلة عن الأعين المتطفلة. تُعرف هذه الميزة أيضًا باسم إخفاء كلمة المرور وهي ممارسة قياسية في التطبيقات المحمولة.
على عكس iOS، حيث يكون Secure Text Entry إعدادًا منفصلاً لـ UITextField، في Android يتم تفعيل هذه الميزة عبر السمة inputType مع اختلاف PASSWORD. عندما يتلقى EditText inputType="textPassword"، يقوم تلقائيًا بتطبيق PasswordTransformationMethod — وهي الفئة المسؤولة عن استبدال الأحرف. عند إدخال كل حرف جديد، يقوم EditText باستبداله فورًا بحرف إخفاء عبر آلية واجهة TransformationMethod.
وفقًا لـ Android Source Code (AOSP, 2026)، يستخدم تنفيذ PasswordTransformationMethod فئة TextPaint لرسم أحرف الإخفاء. حجم حرف الإخفاء يتطابق مع حجم خط الحقل، مما يمنع تسرب المعلومات من خلال طول الكلمة — جميع الأحرف تبدو متطابقة في العرض. هذا مهم للحماية من الهجمات القائمة على تحليل طول البيانات المدخلة.
<!-- Basic Secure Text Entry example -->
@+id/etPassword
android:layout_width="match_parent"
android:hint="Enter password"
android:inputType="textPassword"
android:maxLength="64"
android:importantForAutofill="yes" />
آلية Secure Text Entry في Android تعتمد على واجهة TransformationMethod، المعرفة في حزمة android.text.method. PasswordTransformationMethod هي تطبيق مدمج يتجاوز طريقة getTransformation()، ويعيد تسلسل أحرف مستبدل للعرض. النص الأصلي في Editable يبقى دون تغيير — فقط تمثيله البصري يتغير.
عندما يدخل المستخدم حرفًا، يستدعي EditText dispatchEvent ويمرر الحرف إلى InputConnection، الذي يضيفه إلى Editable. ثم يستدعي EditText طريقة getTransformation() لـ TransformationMethod الحالي، الذي يأخذ CharSequence الأصلي ويعيد SpannableString بأحرف الإخفاء. يتم عرض SpannableString على الشاشة بدلاً من النص الأصلي. الميزة الأساسية هي أن التحويل نفسه لا يغير محتوى Editable، لذلك استدعاء getText().toString() يعيد النص الفعلي المدخل.
وفقًا لـ Android Developers Reference (2026)، يضيف PasswordTransformationMethod MetricAffectingSpan لكل حرف، والذي يستبدل الرسم البياني بنقطة. لا تؤثر هذه الامتدادات على طول النص، لذلك يتم الحفاظ على المؤشر وموضع الإدخال بشكل صحيح حتى مع العرض المخفي. يوجد أيضًا VisiblePasswordTransformationMethod، الذي يعرض آخر حرف مدخل لفترة قصيرة (مماثل لـ iOS).
// PasswordTransformationMethod - built-in masking
editText.transformationMethod = PasswordTransformationMethod.getInstance()
// VisiblePasswordTransformationMethod - shows last char
editText.transformationMethod = VisiblePasswordTransformationMethod.getInstance()
تبديل الرؤية (password visibility toggle) هي ميزة تسمح للمستخدم بإظهار كلمة المرور المدخلة مؤقتًا للتحقق منها قبل إرسال النموذج. في Android، يتم تنفيذ هذه الميزة عبر TextInputLayout مع السمة app:endIconMode="password_toggle". عند النقر على أيقونة العين، يتحول الحقل بين textPassword و textVisiblePassword.
تنفيذ password_toggle في TextInputLayout يغير تلقائيًا inputType لـ EditText الداخلي ويحرك الأيقونة (عين مفتوحة/مغلقة). من المهم تذكر أنه أثناء هذا التبديل قد يتم إعادة تعيين موضع المؤشر، لذلك يقوم TextInputLayout بحفظ واستعادة الموضع بعد تغيير الوضع. أيضًا، عند التبديل إلى كلمة مرور مرئية، لا يتم تفعيل التصحيح التلقائي والاقتراحات — يتم استخدام TYPE_TEXT_VARIATION_VISIBLE_PASSWORD، وليس النص العادي.
وفقًا لـ Material Design Guidelines (2025)، يجب أن تكون أيقونة إظهار كلمة المرور مرئية دائمًا، وليس فقط عندما يكون الحقل في التركيز. يجب أن يكون المستخدم قادرًا على التحقق من كلمة المرور في أي لحظة. لا يجب أن تخفي الأيقونة كلمة المرور تلقائيًا بعد وقت معين — فقط بناءً على إجراء المستخدم.
<!-- TextInputLayout with password toggle -->
@+id/tilPassword
android:layout_width="match_parent"
app:endIconMode="password_toggle"
app:passwordToggleTint="@color/primary">
@+id/etPassword
android:inputType="textPassword"
android:hint="Password" />
</com.google.android.material.textfield.TextInputLayout>
الإعداد البرمجي لـ Secure Text Entry في Kotlin يتم عن طريق تعيين inputType أو عبر setTransformationMethod(). كلا النهجين يؤديان إلى نفس النتيجة لكن يختلفان في التفاصيل. تعيين inputType يهيئ أيضًا التصحيح التلقائي والاقتراحات، بينما setTransformationMethod يؤثر فقط على عرض الأحرف.
// Programmatic password visibility toggle
fun togglePasswordVisibility(til: TextInputLayout) {
val editText = til.editText ?: return
val currentType = editText.inputType
val isPassword = (currentType and
InputType.TYPE_TEXT_VARIATION_PASSWORD) != 0
if (isPassword) {
editText.inputType = InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
} else {
editText.inputType = InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_VARIATION_PASSWORD
}
// Restore cursor position
val cursorPos = editText.selectionStart
editText.setSelection(maxOf(0, cursorPos))
}
// Custom masking — shows only last 4 chars
class PartialPasswordTransformation : TransformationMethod {
override fun getTransformation(source: CharSequence?,
view: View?): CharSequence {
val text = source?.toString() ?: ""
if (text.length <= 4) return text
val dots = "\u2022".repeat(text.length - 4)
return dots + text.substring(text.length - 4)
}
override fun onFocusChanged(view: View?,
sourceText: CharSequence?,
focused: Boolean,
direction: Int,
previouslyFocusedRect: android.graphics.Rect?) {}
}
Secure Text Entry يوفر حماية على مستويات متعددة. الإخفاء البصري يمنع قراءة كلمة المرور من فوق الكتف (shoulder surfing) — الطريقة الأكثر شيوعًا لسرقة كلمات المرور في الأماكن العامة. تعطيل التصحيح التلقائي يمنع حفظ كلمة المرور في قاموس المستخدم، مما يزيل التسرب من خلال الإدخال التنبؤي. الحماية من لقطات الشاشة (إذا تم تمكين FLAG_SECURE) تمنع التطبيقات الأخرى من التقاط محتوى الحقل.
ومع ذلك، Secure Text Entry ليس حماية كاملة. الهجمات من خلال اعتراض الإدخال (keylogging) على مستوى النظام يمكنها الحصول على الأحرف الفعلية من InputConnection. التطبيقات الخبيثة مع خدمات إمكانية الوصول يمكنها قراءة محتوى EditText حتى إذا كانت الأحرف مخفية على الشاشة. أيضًا، اعتراض SSL أثناء نقل البيانات إلى الخادم يمكن أن يكشف كلمة المرور إذا لم يتم استخدام HTTPS مع التحقق المناسب من الشهادة.
وفقًا لـ OWASP Mobile Security Testing Guide (2025)، للحماية القصوى لكلمات المرور في Android يُوصى بـ: استخدام inputType="textPassword" + تعطيل autofill للحقول الحرجة؛ عدم تخزين كلمة المرور مؤقتًا في الذاكرة لفترة أطول من اللازم؛ مسح حقل كلمة المرور عند تصغير التطبيق (onPause/onStop)؛ استخدام الإخفاء حتى أثناء العرض المؤقت لكلمة المرور.
| مستوى الحماية | Secure Text Entry | إجراءات إضافية |
|---|---|---|
| الاعتراض البصري | إخفاء الأحرف | المصادقة البيومترية، تجنب shoulder surfing |
| لقطات الشاشة | جزئي (يعتمد على التنفيذ) | FLAG_SECURE على Window |
| تسجيل المفاتيح | لا يحمي | استخدام IME مع إدخال آمن |
| التصحيح التلقائي/القاموس | معطل | معطل افتراضيًا لكلمة المرور |
| اعتراض الشبكة | لا يحمي | HTTPS مع تثبيت الشهادة |
يجب على مطوري Android اتباع العديد من الممارسات الرئيسية عند العمل مع الإدخال المخفي. أولاً، استخدم دائمًا TextInputLayout مع endIconMode="password_toggle" لحقول كلمة المرور — هذا هو المعيار الحديث لـ Material Design. ثانيًا، لا تعطل القدرة على إظهار كلمة المرور — يجب أن يتمكن المستخدم من التحقق مما أدخله، خاصة على الأجهزة المحمولة ذات لوحات المفاتيح الصغيرة.
Secure Text Entry يتطلب أيضًا تكوينًا مناسبًا للتعبئة التلقائية. لحقول كلمة المرور، حدد دائمًا autofillHints="password" أو autofillHints="newPassword" حتى تتمكن مديري كلمات المرور من تعبئة البيانات وحفظها بشكل صحيح. لحقل تأكيد كلمة المرور الجديدة، استخدم autofillHints="newPassword" حتى لا يقترح النظام تعبئته بكلمة المرور المحفوظة الحالية.
// Full password field with autofill and cleanup
class SecurePasswordField {
private fun setupPasswordField(til: TextInputLayout) {
val editText = til.editText ?: return
editText.inputType = InputType.TYPE_CLASS_TEXT or
InputType.TYPE_TEXT_VARIATION_PASSWORD
editText.setAutofillHints(View.AUTOFILL_HINT_PASSWORD>)
editText.importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_YES
}
fun clearOnPause(editText: EditText) {
editText.text?.clear()
}
}
الأسئلة الشائعة
textPassword يخفي جميع الأحرف المدخلة ويعطل التصحيح التلقائي. textVisiblePassword أيضًا يعطل التصحيح التلقائي لكنه يعرض الأحرف بشكل واضح. يُستخدم textVisiblePassword عند تبديل رؤية كلمة المرور — إنه ليس نصًا عاديًا، حيث تظل التصحيح التلقائي والاقتراحات معطلة للأمان.
نعم، قم بإنشاء فئة مخصصة تنفذ واجهة TransformationMethod. تجاوز طريقة getTransformation() التي تعيد CharSequence مع حرف الاستبدال المطلوب. قم بتعيينها عبر editText.transformationMethod = CustomPasswordTransformation(). تذكر أن الحرف يجب أن يكون أحادي العرض للأمان.
على الأجهزة المحمولة ذات الشاشات الصغيرة ولوحات المفاتيح اللمسية، احتمال الخطأ عند إدخال كلمة المرور أعلى بكثير من سطح المكتب. القدرة على التحقق من كلمة المرور المدخلة تقلل من أخطاء الإدخال وتقلل من عدد طلبات إعادة تعيين كلمة المرور، مما يحسن تجربة المستخدم ويقلل عبء الدعم.
قم بتعيين العلم FLAG_SECURE على نافذة Activity أو Dialog: window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE). يمنع ذلك لقطات الشاشة وتسجيل الشاشة للنافذة بأكملها. لكن لاحظ أن هذا سيعطل أيضًا لقطات الشاشة للمحتوى العادي، مما قد يكون غير مرغوب فيه.
بدءًا من Android 8.0 (API 26)، يكتشف إطار Autofill تلقائيًا حقول كلمة المرور عن طريق inputType. للتشغيل الصحيح، قم بتعيين importantForAutofill="yes" وحدد autofillHints ("password", "newPassword", "emailAddress"). يستخدم Gboard ومديري كلمات المرور هذه السمات لاقتراح كلمات المرور المحفوظة.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.