סקירה כללית של קובץ המניפסט של האפליקציה

בכל פרויקט של אפליקציה חייב להיות קובץ AndroidManifest.xml, עם השם הזה בדיוק, בבסיס של קבוצת המקורות של הפרויקט. קובץ המניפסט מתאר מידע חיוני על האפליקציה לכלי ה-build של Android, למערכת ההפעלה Android ול-Google Play.

בין היתר, קובץ המניפסט נדרש כדי להצהיר על הדברים הבאים:

  • רכיבי האפליקציה, כולל כל הפעילויות, השירותים, מקלטי השידור והספקים לניהול גישה. כל רכיב צריך להגדיר מאפיינים בסיסיים, כמו השם של המחלקה שלו ב-Kotlin או ב-Java. הוא יכול גם להצהיר על יכולות, כמו אילו הגדרות אישיות של מכשירים הוא יכול לטפל בהן, ועל מסנני Intent שמתארים איך אפשר להפעיל את הרכיב. מידע נוסף על רכיבי אפליקציה מופיע בקטע הבא.
  • ההרשאות שהאפליקציה צריכה כדי לגשת לחלקים מוגנים במערכת או באפליקציות אחרות. הוא גם מצהיר על כל ההרשאות שנדרשות לאפליקציות אחרות כדי לגשת לתוכן מהאפליקציה הזו. מידע נוסף על הרשאות מופיע בקטע הבא.
  • תכונות החומרה והתוכנה שהאפליקציה דורשת, שמשפיעות על המכשירים שבהם אפשר להתקין את האפליקציה מ-Google Play. מידע נוסף על תאימות המכשיר מופיע בקטע הבא.

אם אתם משתמשים ב-Android Studio כדי לפתח את האפליקציה, קובץ המניפסט נוצר בשבילכם ורוב רכיבי המניפסט החיוניים נוספים בזמן פיתוח האפליקציה, במיוחד כשמשתמשים בתבניות קוד.

תכונות של קבצים

בקטעים הבאים מוסבר איך חלק מהמאפיינים הכי חשובים של האפליקציה באים לידי ביטוי בקובץ המניפסט.

רכיבי האפליקציה

לכל רכיב שאתם יוצרים באפליקציה, צריך להצהיר על רכיב XML תואם בקובץ המניפסט:

אם יוצרים מחלקת משנה של אחד מהרכיבים האלה בלי להצהיר עליה בקובץ המניפסט, המערכת לא יכולה להפעיל אותה.

מציינים את השם של מחלקת המשנה במאפיין name, באמצעות שם החבילה המלא. לדוגמה, כך מצהירים על מחלקת משנה של Activity:

<manifest ... >
    <application ... >
        <activity android:name="com.example.myapp.MainActivity" ... >
        </activity>
    </application>
</manifest>

עם זאת, אם התו הראשון בערך name הוא נקודה, מרחב השמות של האפליקציה, מהמאפיין namespace של הקובץ build.gradle ברמת המודול, מתווסף לשם. לדוגמה, אם מרחב השמות הוא "com.example.myapp", שם הפעילות הבא יתורגם ל-com.example.myapp.MainActivity:

<manifest ... >
    <application ... >
        <activity android:name=".MainActivity" ... >
            ...
        </activity>
    </application>
</manifest>

מידע נוסף על הגדרת שם החבילה או מרחב השמות זמין במאמר הגדרת מרחב השמות.

אם יש לכם רכיבי אפליקציה שנמצאים בחבילות משנה, כמו com.example.myapp.purchases, הערך של name צריך להוסיף את השמות החסרים של חבילות המשנה, כמו ".purchases.PayActivity", או להשתמש בשם החבילה המלא.

מסנני Intent

פעילויות, שירותים ומקלטי שידורים של אפליקציות מופעלים על ידי כוונות. Intent הוא הודעה שמוגדרת על ידי אובייקט Intent שמתאר פעולה שצריך לבצע, כולל הנתונים שעליהם צריך לבצע את הפעולה, קטגוריית הרכיב שאמור לבצע את הפעולה והוראות אחרות.

כשאפליקציה מנפיקה Intent למערכת, המערכת מאתרת רכיב של אפליקציה שיכול לטפל ב-Intent על סמך הצהרות של מסנן Intent בקובץ המניפסט של כל אפליקציה. המערכת מפעילה מופע של הרכיב התואם ומעבירה את האובייקט Intent לרכיב הזה. אם יותר מאפליקציה אחת יכולה לטפל ב-Intent, המשתמש יכול לבחור באיזו אפליקציה להשתמש.

לרכיב של אפליקציה יכולים להיות כמה מסנני Intent (שמוגדרים באמצעות הרכיב <intent-filter>), וכל אחד מהם מתאר יכולת אחרת של הרכיב הזה.

מידע נוסף זמין במסמך Intents and Intent Filters.

סמלים ותוויות

למספר רכיבים במניפסט יש מאפיינים של icon ו-label להצגת סמל קטן ותווית טקסט, בהתאמה, למשתמשים של רכיב האפליקציה התואם.

בכל מקרה, הסמל והתווית שמוגדרים ברכיב הורה הופכים לערך ברירת המחדל של icon ו-label לכל רכיבי הצאצא. לדוגמה, הסמל והתווית שמוגדרים ברכיב <application> הם הסמל והתווית שמוגדרים כברירת מחדל לכל אחד מהרכיבים של האפליקציה, כמו כל הפעילויות.

הסמל והתווית שמוגדרים ב-<intent-filter> של רכיב מוצגים למשתמש בכל פעם שהרכיב הזה מוצג כאפשרות למילוי Intent. כברירת מחדל, הסמל הזה עובר בירושה מהסמל שמוגדר לרכיב ההורה, כלומר הרכיב <activity> או <application>.

כדאי לשנות את הסמל של מסנן Intent אם הוא מספק פעולה ייחודית שרוצים לציין בצורה ברורה יותר בתיבת הדו-שיח לבחירה. מידע נוסף זמין במאמר איך מאפשרים לאפליקציות אחרות להתחיל את הפעילות.

הרשאות

אפליקציות ל-Android צריכות לבקש הרשאה כדי לגשת לנתוני משתמשים רגישים, כמו אנשי קשר ו-SMS, או לתכונות מערכת מסוימות, כמו המצלמה והגישה לאינטרנט. כל הרשאה מזוהה באמצעות תווית ייחודית. לדוגמה, באפליקציה שצריכה לשלוח הודעות SMS, צריך להוסיף את השורה הבאה למניפסט:

<manifest ... >
    <uses-permission android:name="android.permission.SEND_SMS"/>
    ...
</manifest>

החל מ-Android 6.0 (רמת API‏ 23), המשתמש יכול לאשר או לדחות חלק מההרשאות שניתנות לאפליקציה בזמן הריצה. אבל לא משנה באיזו גרסת Android האפליקציה תומכת, צריך להצהיר על כל בקשות ההרשאה באמצעות רכיב <uses-permission> במניפסט. אם ההרשאה ניתנת, האפליקציה יכולה להשתמש בתכונות המוגנות. אם לא, הניסיונות שלה לגשת לתכונות האלה ייכשלו.

האפליקציה יכולה גם להגן על הרכיבים שלה באמצעות הרשאות. היא יכולה להשתמש בכל אחת מההרשאות שמוגדרות על ידי Android, כמו שמפורט ב-android.Manifest.permission, או בהרשאה שמוצהרת באפליקציה אחרת. האפליקציה שלכם יכולה גם להגדיר הרשאות משלה. הרשאה חדשה מוצהרת באמצעות הרכיב <permission>.

מידע נוסף זמין במאמר הרשאות ב-Android.

תאימות מכשיר

בקובץ המניפסט אפשר גם להצהיר על סוגי התכונות של החומרה או התוכנה שהאפליקציה דורשת, וכך גם על סוגי המכשירים שהאפליקציה תואמת להם. חנות Google Play לא מאפשרת למשתמשים להתקין את האפליקציה במכשירים שלא מספקים את התכונות או את גרסת המערכת שהאפליקציה דורשת.

יש כמה תגי מניפסט שמגדירים לאילו מכשירים האפליקציה מתאימה. הנה כמה מהסיבות הנפוצות ביותר:

<uses-feature>

הרכיב <uses-feature> מאפשר להצהיר על תכונות החומרה והתוכנה שהאפליקציה צריכה. לדוגמה, אם האפליקציה לא יכולה לבצע פונקציונליות בסיסית במכשיר בלי חיישן מצפן, אפשר להצהיר שחיישן המצפן נדרש באמצעות תג המניפסט הבא:

<manifest ... >
    <uses-feature android:name="android.hardware.sensor.compass"
                  android:required="true" />
    ...
</manifest>

הערה: אם אתם רוצים שהאפליקציה תהיה זמינה במכשירי Chromebook, יש כמה מגבלות חשובות על תכונות חומרה ותוכנה שצריך להביא בחשבון. מידע נוסף זמין במאמר תאימות של קובץ המניפסט של האפליקציה למכשירי Chromebook.

<uses-sdk>

כל גרסה חדשה של הפלטפורמה מוסיפה לעיתים קרובות ממשקי API חדשים שלא זמינים בגרסה הקודמת. כדי לציין את הגרסה המינימלית שהאפליקציה תואמת לה, המניפסט צריך לכלול את התג <uses-sdk> ואת המאפיין minSdkVersion שלו.

עם זאת, חשוב לזכור שהמאפיינים ברכיב <uses-sdk> מוחלפים על ידי המאפיינים התואמים בקובץ build.gradle. לכן, אם אתם משתמשים ב-Android Studio, ציינו שם את הערכים של minSdkVersion ו-targetSdkVersion:

מגניב

android {
    defaultConfig {
        applicationId 'com.example.myapp'

        // Defines the minimum API level required to run the app.
        minSdkVersion 23

        // Specifies the API level used to test the app.
        targetSdkVersion 36
        ...
    }
}

Kotlin

android {
    defaultConfig {
        applicationId = "com.example.myapp"

        // Defines the minimum API level required to run the app.
        minSdkVersion(23)

        // Specifies the API level used to test the app.
        targetSdkVersion(36)
        ...
    }
}

מידע נוסף על הקובץ build.gradle זמין במאמר איך מגדירים את ה-build.

כדי ללמוד איך להצהיר על תמיכה של האפליקציה במכשירים שונים, עיינו בסקירה הכללית בנושא תאימות למכשירים.

מוסכמות לגבי קבצים

בקטע הזה מתוארים המוסכמות והכללים שבדרך כלל חלים על כל הרכיבים והמאפיינים בקובץ המניפסט.

רכיבים
רק הרכיבים <manifest> ו-<application> נדרשים. כל אחד מהם יכול להופיע רק פעם אחת. רוב הרכיבים האחרים יכולים להופיע אפס פעמים או יותר. עם זאת, חלק מהם חייבים להיות נוכחים כדי שקובץ המניפסט יהיה שימושי.

כל הערכים מוגדרים באמצעות מאפיינים, ולא כנתוני תווים בתוך רכיב.

בדרך כלל, רכיבים באותה רמה לא מסודרים לפי סדר מסוים. לדוגמה, אפשר למקם את הרכיבים <activity>,‏ <provider> ו-<service> בכל סדר. יש שני יוצאים מן הכלל:

  • רכיב <activity-alias> חייב להופיע אחרי הרכיב <activity> שהוא משמש לו ככינוי.
  • הרכיב <application> חייב להיות הרכיב האחרון בתוך הרכיב <manifest>.
מאפיינים
מבחינה טכנית, כל המאפיינים הם אופציונליים. עם זאת, צריך לציין מאפיינים רבים כדי שרכיב יוכל למלא את המטרה שלו. במאמרי העזרה מצוינים ערכי ברירת המחדל של מאפיינים שהם באמת אופציונליים.

חוץ מכמה מאפיינים של רכיב הבסיס <manifest>, כל שמות המאפיינים מתחילים בקידומת android:, כמו android:alwaysRetainTaskState. מכיוון שהקידומת היא אוניברסלית, בדרך כלל היא לא מופיעה במסמכים כשמתייחסים למאפיינים לפי השם שלהם.

ערכים מרובים
אם אפשר לציין יותר מערך אחד, הרכיב כמעט תמיד חוזר על עצמו, במקום שיופיעו כמה ערכים ברכיב אחד. לדוגמה, מסנן Intent יכול לכלול כמה פעולות:
<intent-filter ... >
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.INSERT" />
    <action android:name="android.intent.action.DELETE" />
    ...
</intent-filter>
ערכי המשאבים
לחלק מהמאפיינים יש ערכים שמוצגים למשתמשים, כמו השם של הפעילות או סמל האפליקציה. הערך של המאפיינים האלה יכול להשתנות בהתאם לשפה של המשתמש או להגדרות אחרות של המכשיר (למשל, כדי לספק גודל סמל שונה בהתאם לצפיפות הפיקסלים של המכשיר), לכן צריך להגדיר את הערכים ממשאב או מעיצוב, במקום להוסיף אותם באופן קבוע לקובץ המניפסט. הערך בפועל יכול להשתנות בהתאם למשאבים החלופיים שאתם מספקים לתצורות שונות של מכשירים.

המשאבים מיוצגים כערכים בפורמט הבא:

"@[package:]type/name"

אפשר להשמיט את השם של package אם המשאב מסופק על ידי האפליקציה (כולל אם הוא מסופק על ידי תלות בספרייה, כי משאבי הספרייה מוזגו עם המשאבים שלכם). שם החבילה החוקי היחיד האחר הוא android, כשרוצים להשתמש במשאב מה-framework של Android.

‫type הוא סוג של משאב, כמו string או drawable, ו-name הוא השם שמזהה את המשאב הספציפי. לדוגמה:

<activity android:icon="@drawable/smallPic" ... >

במאמר סקירה כללית על משאבי אפליקציה מוסבר איך מוסיפים משאבים לפרויקט.

כדי להחיל ערך שמוגדר בעיצוב, התו הראשון צריך להיות ? במקום @:

"?[package:]type/name"

ערכי מחרוזת
אם ערך המאפיין הוא מחרוזת, צריך להשתמש בלוכסנים הפוכים כפולים (\\) כדי להוסיף תווי בריחה (escape), כמו \\n לשורה חדשה או \\uxxxx לתו Unicode.

הפניה לרכיבי מניפסט

בטבלה הבאה יש קישורים למאמרי העזרה של כל הרכיבים התקינים בקובץ AndroidManifest.xml.

<action> מוסיף פעולה למסנן Intent.
<activity> מצהיר על רכיב פעילות.
<activity-alias> מצהיר על כינוי לפעילות.
<application> מצהיר על האפליקציה.
<category> מוסיף שם קטגוריה למסנן Intent.
<compatible-screens> מציין כל הגדרת מסך שהאפליקציה תואמת לה.
<data> מוסיף מפרט נתונים למסנן Intent.
<grant-uri-permission> מציין את קבוצות המשנה של נתוני האפליקציה שלספק לניהול גישה הראשי יש הרשאה לגשת אליהן.
<instrumentation> מצהירה על מחלקת Instrumentation שמאפשרת לעקוב אחרי האינטראקציה של אפליקציה עם המערכת.
<intent-filter> מציין את סוגי ה-Intent שפעילות, שירות או מקלט שידור יכולים להגיב להם.
<manifest> רכיב הבסיס של הקובץ AndroidManifest.xml.
<meta-data> צמד שם-ערך של פריט נתונים נוסף ושרירותי שאפשר לספק לרכיב ההורה.
<path-permission> מגדיר את הנתיב ואת ההרשאות הנדרשות לקבוצת משנה ספציפית של נתונים בתוך ספק לניהול גישה.
<permission> מצהירה על הרשאת אבטחה שאפשר להשתמש בה כדי להגביל את הגישה לרכיבים או לתכונות ספציפיים של האפליקציה הזו או של אפליקציות אחרות.
<permission-group> מצהירה על שם לקבוצה לוגית של הרשאות קשורות.
<permission-tree> מצהירה על שם הבסיס של עץ ההרשאות.
<provider> מצהיר על רכיב של ספק לניהול גישה.
<queries> מצהיר על קבוצת האפליקציות האחרות שהאפליקציה שלכם מתכוונת לגשת אליהן. מידע נוסף זמין במדריך בנושא סינון הרשאות הגישה לחבילות.
<receiver> מצהיר על רכיב של מקלט שידורים.
<service> מצהיר על רכיב שירות.
<supports-gl-texture> מצהיר על פורמט דחיסת טקסטורה יחיד של GL שהאפליקציה תומכת בו.
<supports-screens> מצהיר על גודלי המסכים שהאפליקציה תומכת בהם ומפעיל מצב תאימות למסכים שגדולים יותר מאלה שהאפליקציה תומכת בהם.
<uses-configuration> מציין תכונות קלט ספציפיות שהאפליקציה דורשת.
<uses-feature> מצהיר על תכונת חומרה או תוכנה אחת שבה האפליקציה משתמשת.
<uses-library> מציין ספרייה משותפת שהאפליקציה צריכה להיות מקושרת אליה.
<uses-native-library> מציין ספריית Native משותפת שסופקה על ידי הספק שהאפליקציה צריכה להיות מקושרת אליה.
<uses-permission> מציינת הרשאת מערכת שהמשתמש חייב להעניק כדי שהאפליקציה תפעל בצורה תקינה.
<uses-permission-sdk-23> מציין שהאפליקציה מבקשת הרשאה מסוימת, אבל רק אם האפליקציה מותקנת במכשיר עם Android בגרסה 6.0 (רמת API‏ 23) ומעלה.
<uses-sdk> מאפשרת לכם להגדיר את התאימות של האפליקציה לגרסה אחת או יותר של פלטפורמת Android, באמצעות מספר שלם של רמת API.

המגבלות

יש מגבלה על מספר המופעים של התגים הבאים בקובץ מניפסט:

שם התג הגבלה
<package> 1000
<meta-data> 1000
<uses-library> 1000

יש מגבלה על האורך המקסימלי של המאפיינים הבאים:

מאפיין הגבלה
name 1024
versionName 1024
host 255
mimeType 255

קובץ מניפסט לדוגמה

קובץ ה-XML שבהמשך הוא דוגמה פשוטה AndroidManifest.xml שמצהירה על שתי פעילויות באפליקציה.

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0">

    <!-- Beware that these values are overridden by the build.gradle file -->
    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="26" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!-- This name is resolved to com.example.myapp.MainActivity
             based on the namespace property in the build.gradle file -->
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".DisplayMessageActivity"
            android:parentActivityName=".MainActivity" />
    </application>
</manifest>