AndroidManifest.xml یک فایل پیکربندی اجباری برای هر برنامه Android است که اجزاء، مجوزها و ابردادههای آن را توصیف میکند. سیستم Android این فایل را در هنگام نصب و راهاندازی هر برنامه میخواند. طبق Android Developers, 2025، بدون مانیفست صحیح، برنامه روی دستگاه نصب نمیشود. AndroidManifest.xml Activity، Service، BroadcastReceiver و ContentProvider را برای سیستم عامل ثبت میکند.
نکات اصلی
AndroidManifest.xml یک فایل پیکربندی اصلی در قالب XML است که هر پروژه Android باید در دایرکتوری app/src/main داشته باشد. سیستم Android آن را قبل از اجرای هر کد برنامه — در مرحله تجزیه APK هنگام نصب — تحلیل میکند. اگر در مانیفست خطای نحوی وجود داشته باشد یا اعلامیه اجباری گم شده باشد، نصب با پیام خطا متوقف میشود.
فایل حاوی اعلامیه کامل برنامه است: فهرست همه اجزاء (Activity, Service, BroadcastReceiver, ContentProvider)، مجوزهای درخواستی، حداقل نسخه SDK، الزامات سختافزاری و پیکربندی تمها و سبکها. هر جزئی که میتواند توسط سیستم یا سایر برنامهها فراخوانی شود، باید به صراحت در مانیفست اعلام شود. این یک الزام امنیتی است: بدون اعلام صریح، جزء برای فراخوانی در دسترس نیست.
بدون مانیفست به درستی پیکربندی شده، برنامه نمیتواند از طریق Google Play یا نصب جانبی نصب شود. سیستم مانیفست را در مرحله تجزیه APK بررسی میکند و در صورت خطا، نصب را رد میکند. Google Play همچنین مانیفست را برای پیکربندیهای ناامن اسکن میکند: برای exported=true در جزئی بدون intent-filter اخطار داده میشود و در صورت نبود مجوزهای اجباری برای targetSdk 34+ انتشار مسدود میشود. بنابراین درک ساختار مانیفست یک مهارت اجباری برای توسعهدهنده Android است.
هر جزء برنامه Android باید به صراحت در مانیفست ثبت شود. این یک الزام اجباری پلتفرم برای هر چهار نوع جزء است. بدون ثبت، جزء نمیتواند توسط سیستم ایجاد شود و تلاش برای راهاندازی آن منجر به استثنای ActivityNotFoundException یا مشابه میشود. اجزاء داخل تگ application به ترتیبی که بر عملکردشان تأثیر نمیگذارد ثبت میشوند.
تگ activity صفحه برنامه را ثبت میکند. ویژگی exported تعیین میکند که آیا سایر برنامهها میتوانند این Activity را راهاندازی کنند. از Android 12 به بعد، نبود exported در حضور intent-filter باعث خطای کامپایل میشود — این یک الزام امنیتی است. نقطه ورود از طریق intent-filter با action MAIN و category LAUNCHER تنظیم میشود. هر Activity باید دارای android:name یکتا مطابق با نام کامل یا نسبی کلاس باشد.
<activity
android:name=".MainActivity"
android:exported="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
تگ service سرویس پسزمینه را تعریف میکند. از Android 8 به بعد، سرویسهای پسزمینه محدودیتهای شدیدی دارند: foreground service نیاز به اعلان اجباری با آیکون قابل مشاهده برای کاربر دارد و bound service فقط در صورت وجود کلاینت متصل زنده میماند. سرویسهایی که در پسزمینه بدون اعلان کار میکنند، چند دقیقه پس از انتقال برنامه به حالت پسزمینه به طور خودکار توسط سیستم خاتمه مییابند. برای وظایف طولانیمدت به جای Service از WorkManager استفاده کنید.
<service
android:name=".SyncService"
android:exported="false"
android:foregroundServiceType="dataSync" />
تگ receiver دریافتکننده پیامهای پخشی سیستم یا سفارشی را اعلام میکند. از Android 8 به بعد، بیشتر پخشهای ضمنی به دریافتکنندگانی که به صورت ایستا در مانیفست اعلام شدهاند تحویل داده نمیشوند. در عوض توصیه میشود دریافتکنندگان به صورت پویا از طریق Context.registerReceiver در کد ثبت شوند. استثنا برخی پخشهای سیستمی مانند BOOT_COMPLETED هستند که همچنان نیاز به ثبت ایستا در مانیفست دارند.
<receiver
android:name=".ConnectivityReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
هر مجوز خطرناک در Android نیاز به اعلام در مانیفست از طریق تگ uses-permission دارد. از Android 6 به بعد، مجوزهای خطرناک در زمان اجرا از طریق دیالوگ با کاربر درخواست میشوند، اما اعلام در مانیفست همچنان اجباری است. بدون آن، متد requestPermissions استثنای SecurityException را پرتاب میکند. مجوزهای سطح عادی مانند INTERNET و ACCESS_NETWORK_STATE به طور خودکار هنگام نصب اعطا میشوند.
| مجوز | کاربرد |
|---|---|
| CAMERA | دسترسی به دوربین دستگاه برای عکس و فیلم |
| ACCESS_FINE_LOCATION | موقعیت دقیق از طریق GPS و شبکه |
| RECORD_AUDIO | ضبط صدا از میکروفون دستگاه |
| READ_CONTACTS | خواندن مخاطبین از دفترچه تلفن |
| POST_NOTIFICATIONS | ارسال اعلانها در Android 13+ |
تگ uses-permission-sdk-23 مجوزهایی را مشخص میکند که فقط در Android 6.0+ لازم هستند. این به حفظ سازگاری با نسخههای قدیمی بدون درخواست مجوزهای ناموجود کمک میکند. مثلاً POST_NOTIFICATIONS فقط در Android 13+ در دسترس است، بنابراین باید از طریق uses-permission-sdk-33 مشخص شود تا در دستگاههای قدیمیتر خطای مجوز ناشناخته رخ ندهد. ویژگی maxSdkVersion در uses-permission امکان لغو خودکار مجوزهای غیرضروری هنگام بهروزرسانی برنامه در نسخههای جدید Android را فراهم میکند.
مجوزهای سطح عادی (INTERNET, ACCESS_NETWORK_STATE) هنگام نصب به طور خودکار اعطا میشوند و نیاز به درخواست زمان اجرا ندارند. آنها نیز از طریق uses-permission اعلام میشوند اما در دیالوگ به کاربر نشان داده نمیشوند. برای کنترل دسترسی به اجزای برنامه از سایر برنامهها از مکانیزم permission-protected components استفاده میشود: میتوان مجوز سفارشی در سطح Activity یا Service تعیین کرد که هنگام فراخوانی جزء از خارج توسط سیستم بررسی میشود. این سطح امنیت اضافی برای ارتباط بین فرآیندی فراهم میکند.
تگ intent-filter در مانیفست اعلام میکند که جزء کدام intentهای ضمنی را میتواند پردازش کند. این مکانیزمی است که از طریق آن Android اقدامات سیستمی یا سفارشی را به برنامه مرتبط میکند. Intent filter از سه عنصر تشکیل شده است: action (اقدام)، category (دسته) و data (داده). هر سه میتوانند برای توصیف دقیق این که جزء کدام intentها را باید دریافت کند ترکیب شوند. سیستم بر اساس خاصترین فیلتر، جزء مناسب را انتخاب میکند.
<activity android:name=".DeepLinkActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="itsectr.com"
android:pathPrefix="/app" />
</intent-filter>
</activity>
ویژگی autoVerify تأیید Android App Links را فعال میکند: سیستم برای تأیید مالکیت دامنه با سرور ارتباط برقرار میکند. بدون تأیید، لینکهای عمیق از طریق دیالوگ انتخاب استاندارد کار میکنند که در آن کاربر انتخاب میکند لینک با کدام برنامه باز شود. پس از تأیید موفق، لینکها مستقیماً در برنامه بدون دیالوگ باز میشوند. Google Search Console نیز از autoVerify برای نمایهسازی deep linkها و نمایش آنها در نتایج جستجو استفاده میکند.
فیلترهای با action.VIEW و دستههای DEFAULT و BROWSABLE لینکهای مرورگر، ایمیل و سایر برنامهها را پردازش میکنند. این مکانیزم اصلی پیادهسازی لینکهای عمیق در Android است. برای پشتیبانی از طرحهای URL سفارشی مانند myapp://، کافی است scheme بدون host مشخص شود. با این حال Google استفاده از لینکهای عمیق HTTPS را به جای طرحهای سفارشی توصیه میکند زیرا امنتر هستند و نیاز به مجوزهای اضافی ندارند. طرحهای سفارشی میتوانند توسط هر برنامهای که همان طرح را ثبت کرده است رهگیری شوند.
تگ ریشه manifest شامل ویژگیهای بسته، نسخه و SDK است. تگ application تنظیمات سراسری را ذخیره میکند: تم، آیکون، برچسب و پرچمهای اشکالزدایی. ویژگیهای manifest نسخهبندی را در سطح بسته تعیین میکنند و ویژگیهای application ظاهر و رفتار کلی برنامه را مشخص میکنند. مقادیر میتوانند ارجاع به منابع از طریق نحو @ یا رشتههای تحتاللفظی باشند.
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itsectr.myapp"
<uses-sdk
android:minSdkVersion="24"
android:targetSdkVersion="34" />
<application
android:label="MyApp"
android:icon="@mipmap/ic_launcher"
android:theme="@style/Theme.MyApp"
android:supportsRtl="true"
android:allowBackup="true">
<!-- اجزای برنامه -->
</application>
</manifest>
تگ meta-data در داخل application امکان ذخیره جفتهای کلید-مقدار دلخواه را فراهم میکند. این برای پیکربندی کتابخانههای شخص ثالث مناسب است: کلیدهای API، آدرسهای endpoint و پرچمهای عملکرد. دادههای meta-data از طریق PackageManager.getApplicationInfo().metaData در زمان اجرا در دسترس هستند. مثلاً Firebase و Google Maps از meta-data برای انتقال کلیدهای دسترسی بدون کدنویسی سخت در کد منبع استفاده میکنند. کلیدها در مانیفست تعیین میشوند و میتوانند برای انواع مختلف ساخت متفاوت باشند.
ویژگی android:extractNativeLibs استخراج کتابخانههای بومی از APK را کنترل میکند. برای برنامههای با targetSdk 34+ این ویژگی باید به صراحت مشخص شود، در غیر این صورت ساخت ممکن است با خطای INSTALL_FAILED_INVALID_APK شکست بخورد. اگر extractNativeLibs=false باشد، کتابخانههای بومی بدون استخراج در داخل APK باقی میمانند که اندازه برنامه نصب شده را کاهش میدهد اما زمان بارگذاری کتابخانهها را افزایش میدهد. برای بیشتر برنامههای مدرن، extractNativeLibs=false برای کاهش فضای اشغال شده روی دیسک کاربر توصیه میشود.
ویژگی android:networkSecurityConfig امکان تعیین فایل پیکربندی امنیت شبکه را فراهم میکند. این به ویژه برای برنامههای با targetSdk 28+ مهم است، جایی که ترافیک HTTP به طور پیشفرض مسدود شده است. فایل پیکربندی گواهیهای مورد اعتماد، دامنههای اتصالات HTTP و قوانین pinning گواهی را تعیین میکند. این جایگزین ویژگی منسوخ شده android:usesCleartextTraffic میشود و مکانیزم انعطافپذیرتری برای مدیریت امنیت اتصالات در سطح سیستم عامل فراهم میکند.
ویژگی android:largeHeap اندازه heap افزایش یافته را برای برنامه درخواست میکند. به طور پیشفرض Android به هر برنامه حافظه محدودی اختصاص میدهد که به دستگاه و نسخه سیستم عامل بستگی دارد. اگر برنامه با تصاویر سنگین، ویدئو یا مجموعه دادههای بزرگ کار میکند، largeHeap میتواند از OutOfMemoryError جلوگیری کند. با این حال سوءاستفاده از این ویژگی مضر است: برنامه با مصرف حافظه بالا در کمبود منابع سریعتر توسط سیستم خاتمه مییابد. largeHeap را فقط پس از پروفایلسازی و تأیید ضرورت استفاده کنید.
سؤالات متداول
از Android 12 به بعد، نبود ویژگی exported در حضور intent-filter باعث خطای کامپایل میشود. سیستم نیاز به مشخص کردن صریح دید هر جزء با intent-filter دارد — این یک اقدام امنیتی برای جلوگیری از باز شدن تصادفی اجزاء توسط سایر برنامهها است. برای Activity بدون intent-filter، exported به طور پیشفرض false است.
بله، اما در launcher چند آیکون برنامه نمایش داده میشود. هر Activity با MAIN/LAUNCHER به یک نقطه ورود جداگانه تبدیل میشود. این برای ایجاد میانبر به بخشهای مختلف برنامه استفاده میشود، مثلاً برای رفتن مستقیم به تنظیمات یا ایجاد یک رکورد جدید. هر آیکون Activity مربوطه را مستقیماً باز میکند.
Android مانیفستهای کتابخانهها را با مانیفست اصلی برنامه ادغام میکند. در صورت تضاد ویژگیها، از tools:replace یا tools:node="merge" برای حل استفاده میشود. این مکانیزم خودکار است: هنگام افزودن کتابخانه از طریق Gradle، مانیفست آن با اصلی ادغام میشود. برای لغو یا جایگزینی ویژگی از کتابخانه، از tools:node="remove" یا tools:replace="attributeName" استفاده کنید.
دلایل معمول: مجوز در مانیفست از طریق uses-permission اعلام نشده است، از مجوز سطح عادی استفاده میشود (نیاز به درخواست زمان اجرا ندارد)، کاربر "دیگر نپرس" را انتخاب کرده و مجوز برای همیشه رد شده است، یا targetSdkVersion کمتر از 23 است، جایی که مجوزها هنگام نصب درخواست میشوند. برای تشخیص، مانیفست و لاگها را از طریق adb logcat بررسی کنید.
ویژگی android:debuggable اشکالزدایی برنامه را از طریق ADB فعال میکند. برای ساختهای انتشار در Google Play باید false باشد. اگر debuggable=true در ساخت انتشار باشد، مهاجم میتواند از طریق ADB به برنامه متصل شود، دادهها را بخواند و کد دلخواه اجرا کند. Google Play به طور خودکار انتشار ساختهای با debuggable=true را مسدود میکند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید