تغییرات رفتار اندروید 7.0

اندروید 7.0 همراه با ویژگی ها و قابلیت های جدید، شامل انواع تغییرات رفتاری سیستم و API می شود. این سند برخی از تغییرات کلیدی را که باید درک کنید و در برنامه‌های خود در نظر بگیرید، برجسته می‌کند.

اگر قبلاً برنامه ای برای اندروید منتشر کرده اید، توجه داشته باشید که ممکن است برنامه شما تحت تأثیر این تغییرات در پلتفرم قرار گیرد.

باتری و حافظه

اندروید 7.0 شامل تغییرات رفتاری سیستم با هدف بهبود عمر باتری دستگاه ها و کاهش مصرف رم است. این تغییرات می‌تواند بر دسترسی برنامه شما به منابع سیستم و همچنین نحوه تعامل برنامه شما با سایر برنامه‌ها از طریق اهداف ضمنی خاص تأثیر بگذارد.

دوز

Doze که در Android 6.0 (سطح API 23) معرفی شد، با به تعویق انداختن CPU و فعالیت های شبکه، زمانی که کاربر دستگاهی را قطع، ثابت و با صفحه خاموش می گذارد، عمر باتری را بهبود می بخشد. Android 7.0 با اعمال زیرمجموعه‌ای از CPU و محدودیت‌های شبکه در حالی که دستگاه با صفحه خاموش وصل است، اما لزوماً ثابت نیست، برای مثال، هنگامی که یک گوشی در جیب کاربر حرکت می‌کند، پیشرفت‌های بیشتری را برای Doze به ارمغان می‌آورد.

تصویری از اینکه Doze چگونه اولین سطح از محدودیت‌های فعالیت سیستم را برای بهبود عمر باتری اعمال می‌کند

شکل 1. تصویری از نحوه اعمال اولین سطح از محدودیت های فعالیت سیستم برای بهبود عمر باتری Doze.

وقتی دستگاهی از باتری استفاده می‌کند و صفحه نمایش برای مدت معینی خاموش است، دستگاه وارد Doze می‌شود و اولین زیرمجموعه محدودیت‌ها را اعمال می‌کند: دسترسی به شبکه برنامه را قطع می‌کند، و کارها و همگام‌سازی‌ها را به تعویق می‌اندازد. اگر دستگاه پس از وارد شدن به Doze برای مدت معینی ثابت باشد، سیستم بقیه محدودیت‌های Doze را روی PowerManager.WakeLock اعمال می‌کند. هشدارهای WakeLock، AlarmManager ، GPS و اسکن‌های Wi-Fi. صرف نظر از اینکه برخی یا همه محدودیت‌های Doze اعمال می‌شوند، سیستم دستگاه را برای پنجره‌های تعمیر و نگهداری کوتاه بیدار می‌کند، که در طی آن برنامه‌ها اجازه دسترسی به شبکه را دارند و می‌توانند هر کار/همگام‌سازی معوقی را اجرا کنند.

تصویری از نحوه اعمال سطح دوم از محدودیت‌های فعالیت سیستم توسط Doze پس از ثابت ماندن دستگاه برای مدت معینی

شکل 2. تصویری از نحوه اعمال سطح دوم از محدودیت های فعالیت سیستم پس از ثابت ماندن دستگاه برای مدت معینی Doze.

توجه داشته باشید که فعال کردن صفحه نمایش یا وصل کردن آن به دستگاه از Doze خارج می شود و این محدودیت های پردازش را حذف می کند. رفتار اضافی بر توصیه‌ها و بهترین شیوه‌ها در تطبیق برنامه شما با نسخه قبلی Doze که در Android 6.0 (سطح API 23) معرفی شده است، تأثیری نمی‌گذارد، همانطور که در Optimizing for Doze و App Standby بحث شده است. همچنان باید این توصیه‌ها را دنبال کنید، مانند استفاده از Firebase Cloud Messaging (FCM) برای ارسال و دریافت پیام‌ها، و برنامه‌ریزی به‌روزرسانی‌ها را برای تطبیق با رفتار Doze اضافی شروع کنید.

Project Svelte: بهینه سازی پس زمینه

Android 7.0 سه پخش ضمنی را حذف می کند تا به بهینه سازی استفاده از حافظه و مصرف انرژی کمک کند. این تغییر ضروری است زیرا پخش‌های ضمنی اغلب برنامه‌هایی را شروع می‌کنند که برای گوش دادن به آنها در پس‌زمینه ثبت نام کرده‌اند. حذف این پخش ها می تواند به طور قابل توجهی به عملکرد دستگاه و تجربه کاربر کمک کند.

دستگاه‌های تلفن همراه تغییرات اتصال مکرری را تجربه می‌کنند، مانند هنگام جابجایی بین Wi-Fi و داده تلفن همراه. در حال حاضر، برنامه‌ها می‌توانند با ثبت یک گیرنده برای پخش ضمنی CONNECTIVITY_ACTION در مانیفست خود، تغییرات در اتصال را کنترل کنند. از آنجایی که بسیاری از برنامه‌ها برای دریافت این پخش ثبت نام می‌کنند، یک سوئیچ شبکه می‌تواند باعث شود که همه آنها بیدار شوند و پخش را به یکباره پردازش کنند.

به طور مشابه، در نسخه‌های قبلی Android، برنامه‌ها می‌توانستند برای دریافت پخش‌های ضمنی ACTION_NEW_PICTURE و ACTION_NEW_VIDEO از برنامه‌های دیگر، مانند دوربین، ثبت نام کنند. وقتی کاربر با برنامه دوربین عکس می‌گیرد، این برنامه‌ها برای پردازش پخش بیدار می‌شوند.

برای کاهش این مشکلات، Android 7.0 بهینه سازی های زیر را اعمال می کند:

  • برنامه‌هایی که Android 7.0 (سطح API 24) و بالاتر را هدف قرار می‌دهند، اگر گیرنده پخش خود را در مانیفست اعلام کنند، پخش‌های CONNECTIVITY_ACTION دریافت نمی‌کنند. اگر برنامه‌ها BroadcastReceiver خود را با Context.registerReceiver() ثبت کنند، همچنان پخش‌های CONNECTIVITY_ACTION را دریافت خواهند کرد و این زمینه همچنان معتبر است.
  • سیستم دیگر پخش ACTION_NEW_PICTURE یا ACTION_NEW_VIDEO را ارسال نمی کند. این بهینه‌سازی بر همه برنامه‌ها تأثیر می‌گذارد، نه تنها برنامه‌هایی که اندروید 7.0 را هدف قرار می‌دهند.

اگر برنامه شما از هر یک از این مقاصد استفاده می‌کند، باید وابستگی‌ها را در اسرع وقت حذف کنید تا بتوانید دستگاه‌های Android 7.0 را به درستی هدف‌گیری کنید. چارچوب Android چندین راه حل برای کاهش نیاز به این پخش های ضمنی ارائه می دهد. به عنوان مثال، JobScheduler API مکانیزمی قوی برای برنامه‌ریزی عملیات شبکه در زمانی که شرایط مشخص شده، مانند اتصال به یک شبکه بدون اندازه‌گیری برآورده می‌شود، فراهم می‌کند. حتی می توانید از JobScheduler برای واکنش به تغییرات ارائه دهندگان محتوا استفاده کنید.

برای اطلاعات بیشتر در مورد بهینه‌سازی پس‌زمینه در Android 7.0 (سطح API 24) و نحوه تطبیق برنامه خود، به بهینه‌سازی پس‌زمینه مراجعه کنید.

تغییرات مجوزها

Android 7.0 شامل تغییراتی در مجوزهایی است که ممکن است بر برنامه شما تأثیر بگذارد.

مجوز سیستم فایل تغییر می کند

به منظور بهبود امنیت فایل‌های خصوصی، دایرکتوری خصوصی برنامه‌هایی که Android نسخه ۷.۰ یا بالاتر را هدف قرار می‌دهند، دسترسی را محدود کرده است ( 0700 ). این تنظیم از نشت ابرداده فایل های خصوصی مانند اندازه یا وجود آنها جلوگیری می کند. این تغییر مجوز عوارض جانبی متعددی دارد:

  • مجوزهای فایل های خصوصی دیگر نباید توسط مالک کاهش یابد، و تلاش برای انجام این کار با استفاده از MODE_WORLD_READABLE و/یا MODE_WORLD_WRITEABLE ، یک SecurityException را ایجاد می کند.

    توجه: هنوز این محدودیت به طور کامل اجرا نشده است. برنامه ها همچنان ممکن است با استفاده از API های بومی یا File API مجوزها را در فهرست خصوصی خود تغییر دهند. با این حال، ما به شدت از کاهش مجوزهای فهرست خصوصی خودداری می کنیم.

  • عبور URIهای file:// در خارج از دامنه بسته ممکن است مسیری غیرقابل دسترسی برای گیرنده ایجاد کند. بنابراین، تلاش برای ارسال یک file:// URI باعث ایجاد یک FileUriExposedException می شود. روش توصیه شده برای به اشتراک گذاری محتوای یک فایل خصوصی استفاده از FileProvider است.
  • DownloadManager دیگر نمی تواند فایل های ذخیره شده خصوصی را با نام فایل به اشتراک بگذارد. برنامه‌های قدیمی ممکن است در هنگام دسترسی به COLUMN_LOCAL_FILENAME با یک مسیر غیرقابل دسترسی تمام شوند. برنامه‌هایی که Android نسخه 7.0 یا بالاتر را هدف قرار می‌دهند، هنگام تلاش برای دسترسی به COLUMN_LOCAL_FILENAME یک SecurityException ایجاد می‌کنند. برنامه‌های قدیمی که مکان دانلود را با استفاده از DownloadManager.Request.setDestinationInExternalFilesDir() یا DownloadManager.Request.setDestinationInExternalPublicDir() مکان دانلود را روی یک مکان عمومی تنظیم می‌کنند همچنان می‌توانند به مسیر در COLUMN_LOCAL_FILENAME دسترسی داشته باشند، اما این روش به شدت ممنوع است. راه ترجیحی برای دسترسی به فایلی که توسط DownloadManager در معرض دید قرار می‌گیرد، استفاده از ContentResolver.openFileDescriptor() است.

به اشتراک گذاری فایل ها بین برنامه ها

برای برنامه‌هایی که Android 7.0 را هدف قرار می‌دهند، چارچوب Android خط‌مشی StrictMode API را اعمال می‌کند که افشای file:// ​​URI در خارج از برنامه شما را ممنوع می‌کند. اگر یک هدف حاوی URI فایل از برنامه شما خارج شود، برنامه با یک استثنا FileUriExposedException از کار می افتد.

برای اشتراک گذاری فایل ها بین برنامه ها، باید یک content:// URI ارسال کنید و یک مجوز دسترسی موقت به URI بدهید. ساده ترین راه برای اعطای این مجوز استفاده از کلاس FileProvider است. برای اطلاعات بیشتر در مورد مجوزها و اشتراک گذاری فایل ها، به اشتراک گذاری فایل ها مراجعه کنید.

بهبود دسترسی

Android 7.0 شامل تغییراتی است که به منظور بهبود قابلیت استفاده از پلتفرم برای کاربرانی با دید ضعیف یا ضعیف طراحی شده است. این تغییرات معمولاً نیازی به تغییر کد در برنامه شما ندارند، با این حال باید این ویژگی ها را بررسی کرده و با برنامه خود آزمایش کنید تا تأثیرات احتمالی آن را بر تجربه کاربر ارزیابی کنید.

بزرگنمایی صفحه

Android 7.0 به کاربران امکان می‌دهد اندازه نمایشگر را تنظیم کنند که تمام عناصر روی صفحه را بزرگ یا کوچک می‌کند و در نتیجه دسترسی به دستگاه را برای کاربران کم‌بینا بهبود می‌بخشد. کاربران نمی توانند روی صفحه نمایش از حداقل عرض صفحه نمایش sw320dp بزرگنمایی کنند، که عرض یک Nexus 4، یک تلفن متوسط ​​معمولی است.

صفحه نمایش اندازه نمایشگر زوم نشده دستگاهی که دارای تصویر سیستم Android نسخه 7.0 است
صفحه نمایش اثر افزایش اندازه نمایشگر دستگاهی که دارای تصویر سیستم اندروید 7.0 است

شکل 3. صفحه سمت راست اثر افزایش اندازه نمایشگر دستگاهی را که دارای تصویر سیستم اندروید 7.0 است را نشان می دهد.

هنگامی که تراکم دستگاه تغییر می کند، سیستم به روش های زیر به برنامه های در حال اجرا اطلاع می دهد:

  • اگر برنامه ای سطح API 23 یا پایین تر را هدف قرار دهد، سیستم به طور خودکار تمام فرآیندهای پس زمینه خود را از بین می برد. این بدان معناست که اگر کاربر از چنین برنامه‌ای برای باز کردن صفحه تنظیمات و تغییر تنظیمات اندازه نمایشگر فاصله بگیرد، سیستم برنامه را به همان روشی که در موقعیت‌های کم حافظه انجام می‌دهد، از بین می‌برد. اگر برنامه دارای فرآیندهای پیش زمینه باشد، سیستم آن فرآیندها را از تغییر پیکربندی همانطور که در Handling Runtime Changes توضیح داده شده است مطلع می کند، درست مثل اینکه جهت دستگاه تغییر کرده است.
  • اگر برنامه‌ای Android 7.0 را هدف قرار دهد، همه فرآیندهای آن (پیش‌زمینه و پس‌زمینه) از تغییر پیکربندی همانطور که در Handling Runtime Changes توضیح داده شده مطلع می‌شوند.

اکثر برنامه ها برای پشتیبانی از این ویژگی نیازی به تغییر ندارند، مشروط بر اینکه برنامه ها از بهترین شیوه های اندروید پیروی کنند. موارد خاصی که باید بررسی شوند:

  • برنامه خود را روی دستگاهی با عرض صفحه sw320dp تست کنید و مطمئن شوید که به اندازه کافی کار می کند.
  • هنگامی که پیکربندی دستگاه تغییر می کند، هر گونه اطلاعات کش وابسته به چگالی، مانند بیت مپ های کش یا منابع بارگیری شده از شبکه را به روز کنید. هنگامی که برنامه از حالت توقف باز می‌گردد، تغییرات پیکربندی را بررسی کنید.

    توجه: اگر داده‌های وابسته به پیکربندی را در حافظه پنهان ذخیره می‌کنید، ایده خوبی است که ابرداده‌های مرتبط مانند اندازه صفحه نمایش یا تراکم پیکسلی مناسب برای آن داده را درج کنید. ذخیره این ابرداده به شما این امکان را می دهد که تصمیم بگیرید که آیا پس از تغییر پیکربندی نیاز به بازخوانی داده های حافظه پنهان دارید یا خیر.

  • از تعیین ابعاد با واحدهای px خودداری کنید، زیرا آنها با تراکم صفحه نمایش مقیاس ندارند. در عوض، ابعاد را با واحدهای پیکسل ( dp ) مستقل از چگالی مشخص کنید.

تنظیمات Vision در Setup Wizard

Android 7.0 شامل تنظیمات Vision در صفحه خوش‌آمدگویی است، جایی که کاربران می‌توانند تنظیمات دسترسی زیر را در یک دستگاه جدید تنظیم کنند: حرکت بزرگنمایی ، اندازه قلم ، اندازه نمایشگر و TalkBack . این تغییر باعث افزایش دید باگ های مربوط به تنظیمات مختلف صفحه نمایش می شود. برای ارزیابی تأثیر این ویژگی، باید برنامه های خود را با فعال بودن این تنظیمات آزمایش کنید. می‌توانید تنظیمات را در تنظیمات > دسترسی پیدا کنید.

پیوند برنامه‌های NDK به کتابخانه‌های پلتفرم

با شروع Android 7.0، این سیستم از اتصال پویا برنامه‌ها به کتابخانه‌های غیر NDK جلوگیری می‌کند، که ممکن است باعث از کار افتادن برنامه شما شود. هدف این تغییر رفتار ایجاد یک تجربه برنامه سازگار در به‌روزرسانی‌های پلتفرم و دستگاه‌های مختلف است. حتی اگر کد شما ممکن است با کتابخانه‌های خصوصی مرتبط نباشد، ممکن است یک کتابخانه استاتیک شخص ثالث در برنامه شما این کار را انجام دهد. بنابراین، همه توسعه دهندگان باید بررسی کنند که برنامه هایشان در دستگاه های دارای Android 7.0 خراب نشود. اگر برنامه شما از کد بومی استفاده می کند، باید فقط از API های عمومی NDK استفاده کنید.

سه راه وجود دارد که برنامه شما ممکن است سعی کند به APIهای پلتفرم خصوصی دسترسی پیدا کند:

  • برنامه شما مستقیماً به کتابخانه های پلتفرم خصوصی دسترسی دارد. باید برنامه خود را به‌روزرسانی کنید تا نسخه‌ای از آن کتابخانه‌ها را شامل شود یا از APIهای عمومی NDK استفاده کنید.
  • برنامه شما از یک کتابخانه شخص ثالث استفاده می کند که به کتابخانه های پلت فرم خصوصی دسترسی دارد. حتی اگر مطمئن هستید که برنامه شما مستقیماً به کتابخانه های خصوصی دسترسی ندارد، همچنان باید برنامه خود را برای این سناریو آزمایش کنید.
  • برنامه شما به کتابخانه ای ارجاع می دهد که در APK آن موجود نیست. به عنوان مثال، اگر سعی کنید از نسخه OpenSSL خود استفاده کنید اما فراموش کرده باشید آن را با APK برنامه خود همراه کنید، ممکن است این اتفاق بیفتد. این برنامه ممکن است به طور معمول در نسخه‌های پلتفرم Android که شامل libcrypto.so است اجرا شود. با این حال، برنامه ممکن است در نسخه‌های بعدی اندروید که شامل این کتابخانه نمی‌شوند (مانند Android 6.0 و بالاتر) از کار بیفتد. برای رفع این مشکل، مطمئن شوید که همه کتابخانه‌های غیر NDK خود را با APK خود بسته‌بندی کرده‌اید.

برنامه‌ها نباید از کتابخانه‌های بومی که در NDK گنجانده نشده‌اند استفاده کنند زیرا ممکن است بین نسخه‌های مختلف Android تغییر یا حذف شوند. تغییر از OpenSSL به BoringSSL نمونه ای از چنین تغییری است. همچنین، از آنجایی که هیچ الزامات سازگاری برای کتابخانه‌های پلتفرم موجود در NDK وجود ندارد، دستگاه‌های مختلف ممکن است سطوح مختلفی از سازگاری را ارائه دهند.

به منظور کاهش تأثیری که این محدودیت ممکن است بر برنامه‌های منتشر شده در حال حاضر داشته باشد، مجموعه‌ای از کتابخانه‌ها که کاربرد قابل توجهی دارند - مانند libandroid_runtime.so ، libcutils.so ، libcrypto.so و libssl.so - به طور موقت در Android 7.0 در دسترس هستند. (سطح API 24) برای برنامه هایی که سطح API 23 یا پایین تر را هدف قرار می دهند. اگر برنامه شما یکی از این کتابخانه ها را بارگیری کند، logcat یک هشدار ایجاد می کند و یک نان تست روی دستگاه مورد نظر ظاهر می شود تا به شما اطلاع دهد. اگر این هشدارها را مشاهده کردید، باید برنامه خود را به‌روزرسانی کنید تا یا نسخه‌ای از آن کتابخانه‌ها را شامل شود یا فقط از APIهای عمومی NDK استفاده کنید. نسخه‌های بعدی پلتفرم اندروید ممکن است استفاده از کتابخانه‌های خصوصی را به کلی محدود کند و باعث از کار افتادن برنامه شما شود.

همه برنامه ها هنگام فراخوانی یک API که نه عمومی است و نه به طور موقت در دسترس است، خطای زمان اجرا ایجاد می کنند. نتیجه این است که System.loadLibrary و dlopen(3) هر دو NULL را برمی‌گردانند و ممکن است باعث از کار افتادن برنامه شما شوند. باید کد برنامه خود را بررسی کنید تا استفاده از APIهای پلتفرم خصوصی را حذف کنید و برنامه های خود را با استفاده از دستگاه یا شبیه ساز دارای Android 7.0 (سطح API 24) به طور کامل آزمایش کنید. اگر مطمئن نیستید که آیا برنامه شما از کتابخانه های خصوصی استفاده می کند، می توانید logcat را بررسی کنید تا خطای زمان اجرا را شناسایی کنید.

جدول زیر رفتاری را که باید از یک برنامه بسته به استفاده از کتابخانه‌های بومی خصوصی و سطح API هدف آن ( android:targetSdkVersion ) انتظار داشته باشید را توصیف می‌کند.

کتابخانه ها سطح API را هدف قرار دهید دسترسی در زمان اجرا از طریق لینکر پویا رفتار Android 7.0 (سطح API 24). رفتار پلتفرم اندروید آینده
عمومی NDK هر قابل دسترس همانطور که انتظار می رود کار می کند همانطور که انتظار می رود کار می کند
خصوصی (کتابخانه های خصوصی با دسترسی موقت) 23 یا کمتر به طور موقت در دسترس است همانطور که انتظار می رود کار می کند، اما شما یک هشدار logcat دریافت می کنید. خطای زمان اجرا
خصوصی (کتابخانه های خصوصی با دسترسی موقت) 24 یا بالاتر محدود شده است خطای زمان اجرا خطای زمان اجرا
خصوصی (سایر) هر محدود شده است خطای زمان اجرا خطای زمان اجرا

بررسی کنید که آیا برنامه شما از کتابخانه های خصوصی استفاده می کند

برای کمک به شناسایی مشکلات بارگیری کتابخانه های خصوصی، logcat ممکن است یک هشدار یا خطای زمان اجرا ایجاد کند. به عنوان مثال، اگر برنامه شما سطح API 23 یا پایین‌تر را هدف قرار می‌دهد و سعی می‌کند به یک کتابخانه خصوصی در دستگاهی که Android نسخه 7.0 دارد دسترسی پیدا کند، ممکن است هشداری مشابه موارد زیر مشاهده کنید:

03-21 17:07:51.502 31234 31234 W linker  : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120

این اخطارهای logcat به شما می‌گویند کدام کتابخانه سعی می‌کند به یک API پلتفرم خصوصی دسترسی پیدا کند، اما باعث از کار افتادن برنامه شما نمی‌شود. اگر برنامه سطح API 24 یا بالاتر را هدف قرار دهد، logcat خطای زمان اجرا زیر را ایجاد می کند و ممکن است برنامه شما از کار بیفتد:

java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"
("/system/lib/libcutils.so") needed or dlopened by
"/system/lib/libnativeloader.so" is not accessible for the namespace
"classloader-namespace"
  at java.lang.Runtime.loadLibrary0(Runtime.java:977)
  at java.lang.System.loadLibrary(System.java:1602)

همچنین اگر برنامه شما از کتابخانه های شخص ثالثی استفاده می کند که به صورت پویا به API های پلت فرم خصوصی پیوند می زنند، ممکن است این خروجی های logcat را ببینید. ابزار readelf در Android 7.0DK به شما این امکان را می‌دهد که با اجرای دستور زیر، فهرستی از تمام کتابخانه‌های مشترک پیوند شده پویا از یک فایل .so را ایجاد کنید:

aarch64-linux-android-readelf -dW libMyLibrary.so

برنامه خود را به روز کنید

در اینجا چند مرحله وجود دارد که می‌توانید برای رفع این نوع خطاها انجام دهید و مطمئن شوید که برنامه شما در به‌روزرسانی‌های آینده پلتفرم خراب نمی‌شود:

  • اگر برنامه شما از کتابخانه‌های پلتفرم خصوصی استفاده می‌کند، باید آن را به‌روزرسانی کنید تا نسخه‌ای از آن کتابخانه‌ها را شامل شود یا از APIهای عمومی NDK استفاده کنید.
  • اگر برنامه شما از کتابخانه شخص ثالثی استفاده می کند که به نمادهای خصوصی دسترسی دارد، برای به روز رسانی کتابخانه با نویسنده کتابخانه تماس بگیرید.
  • مطمئن شوید که تمام کتابخانه های غیر NDK خود را با APK خود بسته بندی کرده اید.
  • از توابع استاندارد JNI به جای getJavaVM و getJNIEnv از libandroid_runtime.so استفاده کنید:
    AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h>
    AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or
    JavaVM::AttachCurrentThread from <jni.h>.
    
  • از __system_property_get به جای نماد خصوصی_ property_get از libcutils.so استفاده کنید. برای انجام این کار، از __system_property_get با موارد زیر استفاده کنید:
    #include <sys/system_properties.h>
    

    توجه: در دسترس بودن و محتوای ویژگی های سیستم از طریق CTS آزمایش نمی شود. راه حل بهتر این است که به طور کامل از این ویژگی ها استفاده نکنید.

  • از یک نسخه محلی نماد SSL_ctrl از libcrypto.so استفاده کنید. برای مثال، باید libcyrpto.a به صورت ایستا در فایل .so خود پیوند دهید، یا یک نسخه پیوند شده پویا از libcrypto.so را از BoringSSL/OpenSSL اضافه کنید و آن را در APK خود بسته بندی کنید.

اندروید برای کار

Android 7.0 شامل تغییراتی برای برنامه‌هایی است که Android for Work را هدف قرار می‌دهند، از جمله تغییرات در نصب گواهی، بازنشانی رمز عبور، مدیریت کاربر ثانویه، و دسترسی به شناسه‌های دستگاه. اگر در حال ساختن برنامه برای محیط‌های Android for Work هستید، باید این تغییرات را بررسی کرده و برنامه خود را بر اساس آن اصلاح کنید.

  • قبل از اینکه DPC بتواند آن را تنظیم کند، باید نصب کننده گواهی تفویض شده را نصب کنید. برای برنامه‌های نمایه و مالک دستگاه که Android 7.0 (سطح API 24) را هدف قرار می‌دهند، باید نصب‌کننده گواهی واگذار شده را قبل از اینکه کنترل‌کننده خط‌مشی دستگاه (DPC) DevicePolicyManager.setCertInstallerPackage() را فراخوانی کند نصب کنید. اگر نصب کننده قبلاً نصب نشده باشد، سیستم یک IllegalArgumentException را پرتاب می کند.
  • محدودیت‌های بازنشانی گذرواژه برای مدیران دستگاه اکنون برای مالکان نمایه اعمال می‌شود. مدیران دستگاه دیگر نمی‌توانند از DevicePolicyManager.resetPassword() برای پاک کردن گذرواژه‌ها یا تغییر گذرواژه‌هایی که قبلاً تنظیم شده‌اند استفاده کنند. سرپرست‌های دستگاه همچنان می‌توانند رمز عبور تعیین کنند، اما فقط زمانی که دستگاه رمز عبور، پین یا الگوی نداشته باشد.
  • صاحبان دستگاه و نمایه می‌توانند حساب‌ها را مدیریت کنند، حتی اگر محدودیت‌هایی تعیین شده باشد. صاحبان دستگاه و مالکان نمایه می‌توانند با APIهای مدیریت حساب تماس بگیرند، حتی اگر محدودیت‌های کاربر DISALLOW_MODIFY_ACCOUNTS وجود داشته باشد.
  • صاحبان دستگاه می توانند کاربران ثانویه را راحت تر مدیریت کنند. وقتی دستگاهی در حالت مالک دستگاه اجرا می‌شود، محدودیت DISALLOW_ADD_USER به‌طور خودکار تنظیم می‌شود. این از ایجاد کاربران ثانویه مدیریت نشده توسط کاربران جلوگیری می کند. علاوه بر این، متدهای CreateUser() و createAndInitializeUser() منسوخ شده اند. متد جدید DevicePolicyManager.createAndManageUser() جایگزین آنها می شود.
  • صاحبان دستگاه می توانند به شناسه های دستگاه دسترسی داشته باشند. صاحب دستگاه می‌تواند با استفاده از DevicePolicyManager.getWifiMacAddress() به آدرس مک Wi-Fi یک دستگاه دسترسی داشته باشد. اگر Wi-Fi هرگز در دستگاه فعال نشده باشد، این روش مقدار null را برمی‌گرداند.
  • تنظیم حالت کار دسترسی به برنامه های کاری را کنترل می کند. وقتی حالت کار خاموش است، راه‌انداز سیستم نشان می‌دهد که برنامه‌های کاری با خاکستری کردن آن‌ها در دسترس نیستند. فعال کردن حالت کار دوباره رفتار عادی را بازیابی می کند.
  • هنگام نصب یک فایل PKCS #12 حاوی یک زنجیره گواهی مشتری و کلید خصوصی مربوطه از تنظیمات UI، گواهی CA در زنجیره دیگر در فضای ذخیره اطلاعات مورد اعتماد نصب نمی شود. هنگامی که برنامه‌ها تلاش می‌کنند زنجیره گواهی مشتری را بعداً بازیابی کنند، این روی نتیجه KeyChain.getCertificateChain() تأثیری نمی‌گذارد. در صورت نیاز، گواهی CA باید به طور جداگانه از طریق تنظیمات UI، با یک قالب رمزگذاری شده با DER تحت پسوند فایل crt. یا cer. در فضای ذخیره اطلاعات معتبر نصب شود.
  • با شروع اندروید 7.0، ثبت نام اثر انگشت و فضای ذخیره سازی برای هر کاربر مدیریت می شود. اگر Device Policy Client (DPC) مالک نمایه، سطح API 23 (یا پایین‌تر) را در دستگاهی با Android 7.0 (سطح API 24) هدف قرار دهد، کاربر همچنان می‌تواند اثر انگشت را روی دستگاه تنظیم کند، اما برنامه‌های کاربردی نمی‌توانند به اثر انگشت دستگاه دسترسی داشته باشند. وقتی DPC سطح API 24 و بالاتر را هدف قرار می دهد، کاربر می تواند با رفتن به تنظیمات > امنیت > امنیت نمایه کاری ، اثر انگشت را به طور خاص برای نمایه کاری تنظیم کند.
  • یک وضعیت رمزگذاری جدید ENCRYPTION_STATUS_ACTIVE_PER_USER توسط DevicePolicyManager.getStorageEncryptionStatus() برگردانده می شود تا نشان دهد که رمزگذاری فعال است و کلید رمزگذاری به کاربر گره خورده است. وضعیت جدید تنها در صورتی برگردانده می شود که DPC سطح API 24 و بالاتر را هدف قرار دهد. برای برنامه‌هایی که سطوح API قبلی را هدف قرار می‌دهند، ENCRYPTION_STATUS_ACTIVE برگردانده می‌شود، حتی اگر کلید رمزگذاری مختص کاربر یا نمایه باشد.
  • در Android 7.0، اگر دستگاه دارای نمایه کاری با چالش کاری جداگانه نصب شده باشد، چندین روش که معمولاً کل دستگاه را تحت تأثیر قرار می دهند، رفتار متفاوتی دارند. این روش‌ها به‌جای تأثیرگذاری بر کل دستگاه، فقط برای نمایه کاری اعمال می‌شوند. (فهرست کامل این روش ها در اسناد DevicePolicyManager.getParentProfileInstance() است.) برای مثال، DevicePolicyManager.lockNow() فقط نمایه کاری را قفل می کند، به جای قفل کردن کل دستگاه. برای هر یک از این روش‌ها، می‌توانید با فراخوانی روش در نمونه والد DevicePolicyManager ، رفتار قدیمی را دریافت کنید. می‌توانید با فراخوانی DevicePolicyManager.getParentProfileInstance() این والد را دریافت کنید. به عنوان مثال، اگر متد lockNow() نمونه والد را فراخوانی کنید، کل دستگاه قفل می شود.

یادداشت ها حفظ

Android 7.0 اشکالی را که در آن قابل مشاهده بودن حاشیه نویسی ها نادیده گرفته می شد، برطرف می کند. این مشکل زمان اجرا را فعال کرد تا به حاشیه نویسی هایی که نباید می توانست دسترسی داشته باشد. این یادداشت ها شامل موارد زیر بود:

  • VISIBILITY_BUILD : در نظر گرفته شده است که فقط در زمان ساخت قابل مشاهده باشد.
  • VISIBILITY_SYSTEM : در نظر گرفته شده است که در زمان اجرا قابل مشاهده باشد، اما فقط برای سیستم اصلی.

اگر برنامه شما به این رفتار متکی است، لطفاً یک خط مشی حفظ را به حاشیه نویسی اضافه کنید که باید در زمان اجرا در دسترس باشد. این کار را با استفاده از @Retention(RetentionPolicy.RUNTIME) انجام می دهید.

تغییرات پیکربندی پیش فرض TLS/SSL

Android 7.0 تغییرات زیر را در پیکربندی پیش‌فرض TLS/SSL مورد استفاده برنامه‌ها برای HTTPS و سایر ترافیک TLS/SSL ایجاد می‌کند:

  • مجموعه‌های رمز RC4 اکنون غیرفعال شده‌اند.
  • مجموعه‌های رمز CHACHA20-POLY1305 اکنون فعال هستند.

غیرفعال شدن RC4 به طور پیش‌فرض ممکن است منجر به قطع شدن اتصال HTTPS یا TLS/SSL شود، زمانی که سرور با مجموعه‌های رمزنگاری مدرن مذاکره نمی‌کند. راه حل ترجیحی بهبود پیکربندی سرور برای فعال کردن مجموعه‌ها و پروتکل‌های رمز قوی‌تر و مدرن‌تر است. در حالت ایده‌آل، TLSv1.2 و AES-GCM باید فعال باشند، و مجموعه‌های رمز محرمانه پیشرو (ECDHE) باید فعال و ترجیح داده شوند.

یک جایگزین این است که برنامه را تغییر دهید تا از یک SSLSocketFactory سفارشی برای برقراری ارتباط با سرور استفاده کنید. کارخانه باید به گونه‌ای طراحی شود که نمونه‌های SSLSocket را ایجاد کند که علاوه بر مجموعه‌های رمز پیش‌فرض، برخی از مجموعه‌های رمز مورد نیاز سرور را فعال کنند.

توجه: این تغییرات مربوط به WebView نیست.

برنامه هایی که اندروید 7.0 را هدف قرار می دهند

این تغییرات رفتاری منحصراً برای برنامه‌هایی اعمال می‌شود که Android 7.0 (سطح API 24) یا بالاتر را هدف قرار می‌دهند. برنامه‌هایی که با Android 7.0 کامپایل می‌شوند، یا targetSdkVersion روی Android 7.0 یا بالاتر تنظیم می‌کنند، باید برنامه‌های خود را تغییر دهند تا از این رفتارها به درستی پشتیبانی کنند، در صورتی که برای برنامه قابل اجرا باشد.

تغییرات سریال سازی

Android 7.0 (سطح API 24) اشکالی را در محاسبه سریالVersionUID پیش‌فرض رفع کرد که با مشخصات مطابقت نداشت.

کلاس‌هایی که Serializable پیاده‌سازی می‌کنند و فیلد serialVersionUID صریح را مشخص نمی‌کنند، می‌توانند تغییری در serialVersionUID پیش‌فرض خود ببینند که باعث می‌شود هنگام تلاش برای سریال‌زدایی نمونه‌هایی از کلاس که در نسخه‌های قبلی سریال‌سازی شده‌اند یا توسط برنامه‌ای که هدفش سریال‌سازی شده‌اند، استثنا ایجاد شود. نسخه قبلی پیام خطا چیزی شبیه به این خواهد بود:

local class incompatible: stream classdesc serialVersionUID = 1234, local class serialVersionUID = 4567

رفع این مشکلات مستلزم افزودن یک فیلد serialVersionUID به هر کلاس آسیب‌دیده با مقدار stream classdesc serialVersionUID از پیام خطا است، مثلاً در این مورد 1234 . این تغییر به همه توصیه‌های عملی خوب برای نوشتن کد سریال‌سازی پایبند است و روی همه نسخه‌های اندروید کار خواهد کرد.

اشکال خاصی که رفع شد مربوط به وجود روش های اولیه استاتیک، یعنی <clinit> بود. با توجه به مشخصات، وجود یا عدم وجود یک روش اولیه استاتیک در کلاس، سریالVersionUID پیش‌فرض محاسبه‌شده برای آن کلاس را تحت تأثیر قرار می‌دهد. قبل از رفع اشکال، اگر کلاسی نداشته باشد، محاسبات کلاس فوق را برای یک راه‌انداز اولیه استاتیک بررسی می‌کند.

برای روشن‌تر شدن، این تغییر بر برنامه‌هایی که سطوح API 23 یا پایین‌تر را هدف می‌گیرند، کلاس‌هایی که دارای یک قسمت serialVersionUID هستند یا کلاس‌هایی که دارای روش اولیه‌ای استاتیک هستند، تأثیر نمی‌گذارد.

سایر نکات مهم

  • هنگامی که یک برنامه در Android 7.0 اجرا می شود، اما سطح API پایین تری را هدف قرار می دهد و کاربر اندازه نمایشگر را تغییر می دهد، روند برنامه از بین می رود. برنامه باید بتواند به خوبی این سناریو را مدیریت کند. در غیر این صورت، زمانی که کاربر آن را از Recents بازیابی می کند، از کار می افتد.

    باید برنامه خود را آزمایش کنید تا مطمئن شوید که این رفتار رخ نمی دهد. شما می توانید این کار را با ایجاد یک خرابی یکسان در هنگام کشتن دستی برنامه از طریق DDMS انجام دهید.

    برنامه‌هایی که Android 7.0 (سطح API 24) و بالاتر را هدف قرار می‌دهند، به‌طور خودکار با تغییرات چگالی از بین نمی‌روند. با این حال، ممکن است هنوز به تغییرات پیکربندی ضعیف پاسخ دهند.

  • برنامه‌های اندروید 7.0 باید بتوانند تغییرات پیکربندی را به‌خوبی مدیریت کنند و نباید در شروع‌های بعدی خراب شوند. می‌توانید رفتار برنامه را با تغییر اندازه قلم ( تنظیم > نمایش > اندازه قلم )، و سپس بازیابی برنامه از Recents تأیید کنید.
  • به دلیل وجود اشکال در نسخه‌های قبلی اندروید، سیستم نوشتن در سوکت TCP در رشته اصلی را به‌عنوان نقض حالت سخت پرچم‌گذاری نکرد. اندروید 7.0 این باگ را برطرف می کند. برنامه‌هایی که این رفتار را نشان می‌دهند اکنون یک android.os.NetworkOnMainThreadException می‌اندازند. به طور کلی، انجام عملیات شبکه بر روی رشته اصلی ایده بدی است زیرا این عملیات معمولا تاخیر بالایی دارند که باعث ANR و jank می شود.
  • خانواده روش‌های Debug.startMethodTracing() اکنون به‌جای ذخیره‌سازی در سطح بالای کارت SD، خروجی‌ها را به‌طور پیش‌فرض در دایرکتوری مخصوص بسته شما در فضای ذخیره‌سازی مشترک ذخیره می‌کنند. این بدان معناست که برنامه‌ها دیگر نیازی به درخواست مجوز WRITE_EXTERNAL_STORAGE برای استفاده از این APIها ندارند.
  • بسیاری از APIهای پلتفرم اکنون شروع به بررسی برای بارهای بزرگ ارسال شده در تراکنش‌های Binder کرده‌اند، و سیستم اکنون TransactionTooLargeExceptions به‌جای ثبت یا سرکوب بی‌صدا به عنوان RuntimeExceptions بازگردانی می‌کند. یکی از مثال‌های رایج، ذخیره داده‌های بیش از حد در Activity.onSaveInstanceState() است که باعث می‌شود ActivityThread.StopInfo زمانی که برنامه شما Android 7.0 را هدف قرار می‌دهد RuntimeException ایجاد کند.
  • اگر یک برنامه وظایف Runnable را در یک View پست کند، و View به پنجره متصل نباشد، سیستم وظیفه Runnable را با View در صف قرار می دهد. کار Runnable تا زمانی که View به یک پنجره متصل نشود اجرا نمی شود. این رفتار باگ های زیر را برطرف می کند:
    • اگر برنامه‌ای از رشته‌ای غیر از رشته رابط کاربری پنجره مورد نظر به View پست شود، در نتیجه Runnable ممکن است در رشته اشتباهی اجرا شود.
    • اگر وظیفه Runnable از یک رشته به غیر از یک رشته حلقه پست شده باشد، برنامه می تواند وظیفه Runnable را آشکار کند.
  • اگر برنامه‌ای در Android 7.0 با مجوز DELETE_PACKAGES سعی کند بسته‌ای را حذف کند، اما برنامه دیگری آن بسته را نصب کرده باشد، سیستم به تأیید کاربر نیاز دارد. در این سناریو، برنامه‌ها هنگام فراخوانی PackageInstaller.uninstall() باید از STATUS_PENDING_USER_ACTION به عنوان وضعیت بازگشت انتظار داشته باشند.
  • ارائه دهنده JCA به نام Crypto منسوخ شده است، زیرا تنها الگوریتم آن، SHA1PRNG، از نظر رمزنگاری ضعیف است. برنامه‌ها دیگر نمی‌توانند از SHA1PRNG برای استخراج (ناامن) کلیدها استفاده کنند، زیرا این ارائه‌دهنده دیگر در دسترس نیست. برای اطلاعات بیشتر، به پست وبلاگ ارائه دهنده امنیت "Crypto" منسوخ شده در Android N مراجعه کنید.
،

اندروید 7.0 همراه با ویژگی ها و قابلیت های جدید، شامل انواع تغییرات رفتاری سیستم و API می شود. این سند برخی از تغییرات کلیدی را که باید درک کنید و در برنامه‌های خود در نظر بگیرید، برجسته می‌کند.

اگر قبلاً برنامه ای برای اندروید منتشر کرده اید، توجه داشته باشید که ممکن است برنامه شما تحت تأثیر این تغییرات در پلتفرم قرار گیرد.

باتری و حافظه

اندروید 7.0 شامل تغییرات رفتاری سیستم با هدف بهبود عمر باتری دستگاه ها و کاهش مصرف رم است. این تغییرات می‌تواند بر دسترسی برنامه شما به منابع سیستم و همچنین نحوه تعامل برنامه شما با سایر برنامه‌ها از طریق اهداف ضمنی خاص تأثیر بگذارد.

دوز

Doze که در Android 6.0 (سطح API 23) معرفی شد، با به تعویق انداختن CPU و فعالیت های شبکه، زمانی که کاربر دستگاهی را قطع، ثابت و با صفحه خاموش می گذارد، عمر باتری را بهبود می بخشد. Android 7.0 با اعمال زیرمجموعه‌ای از CPU و محدودیت‌های شبکه در حالی که دستگاه با صفحه خاموش وصل است، اما لزوماً ثابت نیست، برای مثال، هنگامی که یک گوشی در جیب کاربر حرکت می‌کند، پیشرفت‌های بیشتری را برای Doze به ارمغان می‌آورد.

تصویری از اینکه Doze چگونه اولین سطح از محدودیت‌های فعالیت سیستم را برای بهبود عمر باتری اعمال می‌کند

شکل 1. تصویری از نحوه اعمال اولین سطح از محدودیت های فعالیت سیستم برای بهبود عمر باتری Doze.

وقتی دستگاهی از باتری استفاده می‌کند و صفحه نمایش برای مدت معینی خاموش است، دستگاه وارد Doze می‌شود و اولین زیرمجموعه محدودیت‌ها را اعمال می‌کند: دسترسی به شبکه برنامه را قطع می‌کند، و کارها و همگام‌سازی‌ها را به تعویق می‌اندازد. اگر دستگاه پس از وارد شدن به Doze برای مدت معینی ثابت باشد، سیستم بقیه محدودیت‌های Doze را روی PowerManager.WakeLock اعمال می‌کند. هشدارهای WakeLock، AlarmManager ، GPS و اسکن‌های Wi-Fi. صرف نظر از اینکه برخی یا همه محدودیت‌های Doze اعمال می‌شوند، سیستم دستگاه را برای پنجره‌های تعمیر و نگهداری کوتاه بیدار می‌کند، که در طی آن برنامه‌ها اجازه دسترسی به شبکه را دارند و می‌توانند هر کار/همگام‌سازی معوقی را اجرا کنند.

تصویری از نحوه اعمال سطح دوم از محدودیت‌های فعالیت سیستم توسط Doze پس از ثابت ماندن دستگاه برای مدت معینی

شکل 2. تصویری از نحوه اعمال سطح دوم از محدودیت های فعالیت سیستم پس از ثابت ماندن دستگاه برای مدت معینی Doze.

توجه داشته باشید که فعال کردن صفحه نمایش یا وصل کردن آن به دستگاه از Doze خارج می شود و این محدودیت های پردازش را حذف می کند. رفتار اضافی بر توصیه‌ها و بهترین شیوه‌ها در تطبیق برنامه شما با نسخه قبلی Doze که در Android 6.0 (سطح API 23) معرفی شده است، تأثیری نمی‌گذارد، همانطور که در Optimizing for Doze و App Standby بحث شده است. همچنان باید این توصیه‌ها را دنبال کنید، مانند استفاده از Firebase Cloud Messaging (FCM) برای ارسال و دریافت پیام‌ها، و برنامه‌ریزی به‌روزرسانی‌ها را برای تطبیق با رفتار Doze اضافی شروع کنید.

Project Svelte: بهینه سازی پس زمینه

Android 7.0 سه پخش ضمنی را حذف می کند تا به بهینه سازی استفاده از حافظه و مصرف انرژی کمک کند. این تغییر ضروری است زیرا پخش‌های ضمنی اغلب برنامه‌هایی را شروع می‌کنند که برای گوش دادن به آنها در پس‌زمینه ثبت نام کرده‌اند. حذف این پخش ها می تواند به طور قابل توجهی به عملکرد دستگاه و تجربه کاربر کمک کند.

دستگاه‌های تلفن همراه تغییرات اتصال مکرری را تجربه می‌کنند، مانند هنگام جابجایی بین Wi-Fi و داده تلفن همراه. در حال حاضر، برنامه‌ها می‌توانند با ثبت یک گیرنده برای پخش ضمنی CONNECTIVITY_ACTION در مانیفست خود، تغییرات در اتصال را کنترل کنند. از آنجایی که بسیاری از برنامه‌ها برای دریافت این پخش ثبت نام می‌کنند، یک سوئیچ شبکه می‌تواند باعث شود که همه آنها بیدار شوند و پخش را به یکباره پردازش کنند.

به طور مشابه، در نسخه‌های قبلی Android، برنامه‌ها می‌توانستند برای دریافت پخش‌های ضمنی ACTION_NEW_PICTURE و ACTION_NEW_VIDEO از برنامه‌های دیگر، مانند دوربین، ثبت نام کنند. وقتی کاربر با برنامه دوربین عکس می‌گیرد، این برنامه‌ها برای پردازش پخش بیدار می‌شوند.

برای کاهش این مشکلات، Android 7.0 بهینه سازی های زیر را اعمال می کند:

  • برنامه‌هایی که Android 7.0 (سطح API 24) و بالاتر را هدف قرار می‌دهند، اگر گیرنده پخش خود را در مانیفست اعلام کنند، پخش‌های CONNECTIVITY_ACTION دریافت نمی‌کنند. اگر برنامه‌ها BroadcastReceiver خود را با Context.registerReceiver() ثبت کنند، همچنان پخش‌های CONNECTIVITY_ACTION را دریافت خواهند کرد و این زمینه همچنان معتبر است.
  • سیستم دیگر پخش ACTION_NEW_PICTURE یا ACTION_NEW_VIDEO را ارسال نمی کند. این بهینه‌سازی بر همه برنامه‌ها تأثیر می‌گذارد، نه تنها برنامه‌هایی که اندروید 7.0 را هدف قرار می‌دهند.

اگر برنامه شما از هر یک از این مقاصد استفاده می‌کند، باید وابستگی‌ها را در اسرع وقت حذف کنید تا بتوانید دستگاه‌های Android 7.0 را به درستی هدف‌گیری کنید. Framework Android چندین راه حل برای کاهش نیاز به این پخش های ضمنی ارائه می دهد. به عنوان مثال ، API JobScheduler یک مکانیسم قوی برای برنامه ریزی عملیات شبکه در هنگام شرایط مشخص مانند اتصال به یک شبکه بدون ترمیم فراهم می کند. حتی می توانید از JobScheduler برای واکنش به تغییرات در ارائه دهندگان محتوا استفاده کنید.

برای کسب اطلاعات بیشتر در مورد بهینه سازی پس زمینه در Android 7.0 (API سطح 24) و نحوه تطبیق برنامه خود ، به بهینه سازی های پس زمینه مراجعه کنید.

تغییر مجوزها

Android 7.0 شامل تغییراتی در مجوزهایی است که ممکن است روی برنامه شما تأثیر بگذارد.

تغییر اجازه سیستم پرونده

به منظور بهبود امنیت پرونده های خصوصی ، فهرست خصوصی برنامه هایی که Android 7.0 یا بالاتر را هدف قرار می دهند ، دسترسی محدود شده است ( 0700 ). این تنظیم از نشت ابرداده پرونده های خصوصی مانند اندازه یا وجود آنها جلوگیری می کند. این تغییر مجوز دارای چندین عوارض جانبی است:

  • مجوزهای پرونده پرونده های خصوصی دیگر نباید توسط مالک آرام شود و تلاش برای انجام این کار با استفاده از MODE_WORLD_READABLE و/یا MODE_WORLD_WRITEABLE ، باعث ایجاد SecurityException می شود.

    توجه: از این پس ، این محدودیت به طور کامل اجرا نشده است. برنامه ها هنوز هم ممکن است مجوزها را با استفاده از API های بومی یا API File به فهرست خصوصی خود تغییر دهند. با این حال ، ما به شدت از آرامش مجوزها به فهرست خصوصی دلسرد می شویم.

  • عبور از file:// URIS در خارج از دامنه بسته ممکن است گیرنده را با یک مسیر غیرقابل دسترسی ترک کند. بنابراین ، تلاش برای تصویب یک file:// URI باعث می شود FileUriExposedException باشد. روش پیشنهادی برای به اشتراک گذاشتن محتوای یک فایل خصوصی استفاده از FileProvider است.
  • DownloadManager دیگر نمی تواند پرونده های ذخیره شده خصوصی را توسط نام پرونده به اشتراک بگذارد. برنامه های میراث ممکن است هنگام دسترسی به COLUMN_LOCAL_FILENAME با یک مسیر غیرقابل دسترسی به پایان برسد. برنامه هایی که Android 7.0 یا بالاتر را هدف قرار می دهند ، هنگام تلاش برای دسترسی به COLUMN_LOCAL_FILENAME ، SecurityException ایجاد می کنند. برنامه های Legacy که مکان بارگیری را با استفاده از DownloadManager.Request.setDestinationInExternalFilesDir() یا DownloadManager.Request.setDestinationInExternalPublicDir() تنظیم می کند ، هنوز هم می تواند به مسیر COLUMN_LOCAL_FILENAME دسترسی پیدا کند ، اما این روش به شدت دلسرد می شود. روش ترجیحی برای دسترسی به پرونده ای که توسط DownloadManager در معرض آن قرار دارد ، استفاده از ContentResolver.openFileDescriptor() است.

به اشتراک گذاری پرونده ها بین برنامه ها

برای برنامه هایی که Android 7.0 را هدف قرار می دهند ، Android Framework خط مشی API StrictMode را که ممنوعیت قرار گرفتن در معرض file:// URIS خارج از برنامه شما را اجرا می کند. اگر قصد حاوی پرونده URI برنامه شما را ترک کند ، برنامه با استثناء FileUriExposedException از کار خود خارج می شود.

برای به اشتراک گذاشتن پرونده ها بین برنامه ها ، باید یک content:// URI و اجازه دسترسی موقتی را به URI اعطا کنید. ساده ترین راه برای اعطای این مجوز با استفاده از کلاس FileProvider است. برای اطلاعات بیشتر در مورد مجوزها و به اشتراک گذاری پرونده ها ، به اشتراک گذاری پرونده ها مراجعه کنید.

پیشرفت های دسترسی

Android 7.0 شامل تغییراتی در نظر گرفته شده برای بهبود قابلیت استفاده از پلتفرم برای کاربران با دید کم یا کمبود است. این تغییرات به طور کلی نیازی به تغییر کد در برنامه شما ندارند ، اما شما باید این ویژگی ها را مرور کرده و آنها را با برنامه خود آزمایش کنید تا تأثیرات احتمالی را به تجربه کاربر ارزیابی کنید.

بزرگنمایی

Android 7.0 کاربران را قادر می سازد اندازه نمایشگر را تنظیم کنند که همه عناصر موجود در صفحه را بزرگ می کند یا کوچک می کند ، در نتیجه دسترسی به دستگاه برای کاربران با دید کم را بهبود می بخشد. کاربران نمی توانند صفحه نمایش را از حداقل عرض صفحه نمایش SW320DP ، که عرض یک Nexus 4 ، یک تلفن متوسط ​​متوسط ​​است ، بزرگنمایی کنید.

صفحه نمایش نشان داده شده اندازه نمایشگر دستگاه در حال اجرا یک تصویر سیستم Android 7.0
صفحه نمایش تأثیر افزایش اندازه نمایشگر دستگاهی که یک تصویر سیستم Android 7.0 دارد

شکل 3. صفحه در سمت راست تأثیر افزایش اندازه صفحه نمایش دستگاهی که یک تصویر سیستم Android 7.0 را اجرا می کند ، نشان می دهد.

هنگامی که تراکم دستگاه تغییر می کند ، سیستم به روش های زیر برنامه های در حال اجرا را اعلام می کند:

  • اگر یک برنامه API سطح 23 یا پایین را هدف قرار دهد ، سیستم به طور خودکار تمام فرایندهای پس زمینه خود را از بین می برد. این بدان معناست که اگر کاربر برای باز کردن صفحه تنظیمات از چنین برنامه ای دور شود و تنظیم اندازه نمایش را تغییر دهد ، سیستم برنامه را به همان روشی که در یک وضعیت کم حافظه قرار می گیرد ، می کشد. اگر برنامه دارای فرآیندهای پیش زمینه باشد ، سیستم به آن فرآیندهای تغییر پیکربندی همانطور که در رسیدگی به تغییرات زمان اجرا شده است ، اطلاع می دهد ، دقیقاً مثل اینکه جهت گیری دستگاه تغییر کرده است.
  • اگر یک برنامه Android 7.0 را هدف قرار دهد ، تمام فرآیندهای آن (پیش زمینه و پس زمینه) از تغییر پیکربندی آگاه می شوند ، همانطور که در رسیدگی به تغییرات زمان اجرا شده است.

بیشتر برنامه ها نیازی به ایجاد تغییراتی برای پشتیبانی از این ویژگی ندارند ، به شرط برنامه ها از بهترین روشهای اندروید پیروی می کنند. موارد خاص برای بررسی:

  • برنامه خود را بر روی دستگاه با عرض صفحه sw320dp تست کنید و مطمئن باشید که به اندازه کافی انجام می شود.
  • هنگامی که پیکربندی دستگاه تغییر می کند ، هرگونه اطلاعات ذخیره شده وابسته به چگالی ، مانند مپ های ذخیره شده یا منابع بارگذاری شده از شبکه را به روز کنید. هنگام از سرگیری برنامه از حالت مکث ، تغییرات پیکربندی را بررسی کنید.

    توجه: اگر داده های وابسته به پیکربندی را ذخیره می کنید ، ایده خوبی است که ابرداده مربوطه مانند اندازه صفحه مناسب یا تراکم پیکسل را برای آن داده ها درج کنید. صرفه جویی در این ابرداده به شما امکان می دهد تصمیم بگیرید که آیا پس از تغییر پیکربندی ، باید داده های ذخیره شده را تازه کنید.

  • از مشخص کردن ابعاد با واحدهای PX خودداری کنید ، زیرا آنها با چگالی صفحه مقیاس نمی شوند. در عوض ، ابعاد را با واحدهای پیکسل مستقل از چگالی ( dp ) مشخص کنید.

تنظیمات دید در جادوگر راه اندازی

Android 7.0 شامل تنظیمات بینایی در صفحه Welcome است ، جایی که کاربران می توانند تنظیمات دسترسی زیر را بر روی یک دستگاه جدید تنظیم کنند: ژست بزرگنمایی ، اندازه فونت ، اندازه نمایش و گفتگوی . این تغییر باعث افزایش دید اشکالات مربوط به تنظیمات مختلف صفحه می شود. برای ارزیابی تأثیر این ویژگی ، باید برنامه های خود را با این تنظیمات فعال کنید. می توانید تنظیمات را در زیر تنظیمات> دسترسی پیدا کنید.

برنامه های NDK که به کتابخانه های پلتفرم پیوند دارند

با شروع در Android 7.0 ، این سیستم مانع از پیوند برنامه ها به صورت پویا در برابر کتابخانه های غیر NDK می شود ، که ممکن است باعث خراب شدن برنامه شما شود. این تغییر در رفتار با هدف ایجاد یک تجربه برنامه مداوم در سراسر به روزرسانی های پلتفرم و دستگاه های مختلف انجام می شود. حتی اگر کد شما ممکن است با کتابخانه های خصوصی پیوند برقرار نکند ، ممکن است که یک کتابخانه استاتیک شخص ثالث در برنامه شما این کار را انجام دهد. بنابراین ، همه توسعه دهندگان باید اطمینان حاصل کنند که برنامه های آنها در دستگاه هایی که Android 7.0 را اجرا می کنند خراب نمی شوند. اگر برنامه شما از کد بومی استفاده می کند ، فقط باید از API های عمومی NDK استفاده کنید.

سه روش وجود دارد که برنامه شما در تلاش برای دسترسی به API های پلت فرم خصوصی است:

  • برنامه شما به طور مستقیم به کتابخانه های پلت فرم خصوصی دسترسی پیدا می کند. شما باید برنامه خود را به روز کنید تا نسخه خود را از آن کتابخانه ها درج کنید یا از API های عمومی NDK استفاده کنید.
  • برنامه شما از یک کتابخانه شخص ثالث استفاده می کند که به کتابخانه های پلت فرم خصوصی دسترسی پیدا می کند. حتی اگر مطمئن باشید که برنامه شما به طور مستقیم به کتابخانه های خصوصی دسترسی ندارد ، باز هم باید برنامه خود را برای این سناریو آزمایش کنید.
  • برنامه شما به کتابخانه ای اشاره می کند که در APK آن گنجانده نشده است. به عنوان مثال ، اگر سعی کردید از نسخه خود OpenSSL استفاده کنید ، این اتفاق می افتد اما فراموش کرده اید که آن را با APK برنامه خود جمع کنید. این برنامه ممکن است به طور عادی بر روی نسخه های سیستم عامل Android که شامل libcrypto.so است اجرا شود. با این حال ، این برنامه می تواند در نسخه های بعدی Android که شامل این کتابخانه نمی شود (مانند Android 6.0 و بعد) خراب شود. برای رفع این مشکل ، اطمینان حاصل کنید که تمام کتابخانه های غیر NDK خود را با APK خود جمع کرده اید.

برنامه ها نباید از کتابخانه های بومی استفاده کنند که در NDK گنجانده نشده اند زیرا ممکن است بین نسخه های مختلف Android تغییر یا حذف شوند. سوئیچ از OpenSSL به BoringsSL نمونه ای از چنین تغییری است. همچنین ، از آنجا که هیچ الزامات سازگاری برای کتابخانه های پلت فرم وجود ندارد که در NDK گنجانده نشده باشد ، دستگاه های مختلف ممکن است سطوح مختلف سازگاری را ارائه دهند.

به منظور کاهش تأثیر این محدودیت در برنامه های منتشر شده در حال حاضر ، مجموعه ای از کتابخانه ها که استفاده قابل توجهی را مشاهده می کنند - از جمله libandroid_runtime.so ، libcutils.so ، libcrypto.so و libssl.so - موقتاً در Android 7.0 قابل دسترسی است (API سطح 24) برای برنامه هایی که API سطح 23 یا پایین را هدف قرار می دهند. اگر برنامه شما یکی از این کتابخانه ها را بارگیری کند ، LogCat یک هشدار ایجاد می کند و یک نان تست در دستگاه هدف ظاهر می شود تا به شما اطلاع دهد. اگر این هشدارها را مشاهده می کنید ، باید برنامه خود را به روز کنید تا نسخه خود را از آن کتابخانه ها درج کنید یا فقط از API های عمومی NDK استفاده کنید. انتشار آینده پلت فرم Android ممکن است استفاده از کتابخانه های خصوصی را به طور کلی محدود کند و باعث خراب شدن برنامه شما شود.

همه برنامه ها هنگام تماس با API که نه عمومی است و نه به طور موقت در دسترس است ، خطای زمان اجرا ایجاد می کنند. نتیجه این است که System.loadLibrary و dlopen(3) هر دو NULL می کنند و ممکن است باعث خراب شدن برنامه شما شود. برای حذف استفاده از API های پلت فرم خصوصی باید کد برنامه خود را مرور کنید و برنامه های خود را با استفاده از دستگاه یا شبیه ساز در حال اجرا Android 7.0 (API سطح 24) به طور کامل آزمایش کنید. اگر مطمئن نیستید که برنامه شما از کتابخانه های خصوصی استفاده می کند ، می توانید LogCat را برای شناسایی خطای زمان اجرا بررسی کنید .

در جدول زیر رفتاری که باید انتظار داشته باشید از یک برنامه بسته به استفاده از کتابخانه های بومی خصوصی و سطح API هدف آن ( android:targetSdkVersion ) مشاهده کنید.

کتابخانه ها سطح API هدف دسترسی به زمان اجرا از طریق پیوند دهنده پویا رفتار Android 7.0 (API سطح 24) رفتار آینده پلتفرم اندرویدی
NDK عمومی هر قابل دسترس همانطور که انتظار می رود کار می کند همانطور که انتظار می رود کار می کند
خصوصی (کتابخانه های خصوصی به طور موقت در دسترس) 23 یا پایین موقتاً در دسترس همانطور که انتظار می رفت کار می کند ، اما شما یک هشدار logcat دریافت می کنید. خطای زمان اجرا
خصوصی (کتابخانه های خصوصی به طور موقت در دسترس) 24 یا بالاتر محدود شده است خطای زمان اجرا خطای زمان اجرا
خصوصی (سایر) هر محدود شده است خطای زمان اجرا خطای زمان اجرا

بررسی کنید که آیا برنامه شما از کتابخانه های خصوصی استفاده می کند

برای کمک به شما در شناسایی مسائل بارگیری کتابخانه های خصوصی ، LogCat ممکن است خطای هشدار دهنده یا زمان اجرا ایجاد کند. به عنوان مثال ، اگر برنامه شما API سطح 23 یا پایین را هدف قرار دهد ، و سعی می کند به یک کتابخانه خصوصی در دستگاهی که Android 7.0 را اجرا می کند ، دسترسی پیدا کند ، ممکن است هشدار مشابه موارد زیر را ببینید:

03-21 17:07:51.502 31234 31234 W linker  : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120

این هشدارهای LogCat به شما می گوید کدام کتابخانه در تلاش است به یک API پلت فرم خصوصی دسترسی پیدا کند ، اما باعث خراب شدن برنامه شما نمی شود. اگر برنامه API سطح 24 یا بالاتر را هدف قرار دهد ، LogCat خطای زمان زیر را ایجاد می کند و برنامه شما ممکن است خراب شود:

java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"
("/system/lib/libcutils.so") needed or dlopened by
"/system/lib/libnativeloader.so" is not accessible for the namespace
"classloader-namespace"
  at java.lang.Runtime.loadLibrary0(Runtime.java:977)
  at java.lang.System.loadLibrary(System.java:1602)

همچنین اگر برنامه شما از کتابخانه های شخص ثالث استفاده می کند که به طور پویا به API های پلت فرم خصوصی پیوند می دهند ، ممکن است این خروجی های LogCat را مشاهده کنید. ابزار خواندن در Android 7.0DK به شما امکان می دهد با اجرای دستور زیر لیستی از کلیه کتابخانه های مشترک به صورت پویا مرتبط از یک پرونده .so را تهیه کنید:

aarch64-linux-android-readelf -dW libMyLibrary.so

برنامه خود را به روز کنید

در اینجا برخی از اقدامات برای رفع این نوع خطاها وجود دارد و اطمینان حاصل کنید که برنامه شما در به روزرسانی های پلت فرم آینده خراب نمی شود:

  • اگر برنامه شما از کتابخانه های پلتفرم خصوصی استفاده می کند ، باید آن را به روز کنید تا نسخه خود را از آن کتابخانه ها درج کنید یا از API های عمومی NDK استفاده کنید.
  • اگر برنامه شما از یک کتابخانه شخص ثالث که به نمادهای خصوصی دسترسی پیدا می کند ، استفاده می کند ، برای به روزرسانی کتابخانه با نویسنده کتابخانه تماس بگیرید.
  • اطمینان حاصل کنید که تمام کتابخانه های غیر NDK خود را با APK خود بسته بندی کرده اید.
  • از توابع استاندارد JNI به جای getJavaVM و getJNIEnv از libandroid_runtime.so استفاده کنید:
    AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h>
    AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or
    JavaVM::AttachCurrentThread from <jni.h>.
    
  • به جای نماد property_get از libcutils.so از __system_property_get استفاده کنید. برای انجام این کار ، از __system_property_get با موارد زیر استفاده کنید:
    #include <sys/system_properties.h>
    

    توجه: در دسترس بودن و محتوای خصوصیات سیستم از طریق CTS آزمایش نمی شود. رفع بهتر این است که از استفاده از این خواص در کل جلوگیری شود.

  • از یک نسخه محلی از نماد SSL_ctrl از libcrypto.so استفاده کنید. به عنوان مثال ، شما باید libcyrpto.a در پرونده .so خود پیوند دهید ، یا یک نسخه پویا مرتبط از libcrypto.so از BoringsSL/OpenSSL را درج کنید و آن را در APK خود بسته بندی کنید.

اندروید برای کار

Android 7.0 شامل تغییراتی در برنامه هایی است که Android را برای کار هدف قرار می دهد ، از جمله تغییر در نصب گواهی ، تنظیم مجدد رمز عبور ، مدیریت ثانویه کاربر و دسترسی به شناسه های دستگاه. اگر در حال ساخت برنامه هایی برای Android برای محیط های کاری هستید ، باید این تغییرات را مرور کرده و برنامه خود را مطابق با آن اصلاح کنید.

  • قبل از اینکه DPC بتواند آن را تنظیم کند ، باید یک نصب کننده گواهینامه را نصب کنید. برای هر دو برنامه مشخصات و صاحب دستگاه که Android 7.0 (API سطح 24) را هدف قرار می دهند ، باید قبل از تماس با کنترل کننده خط مشی دستگاه (DPC) با DevicePolicyManager.setCertInstallerPackage() نصب کننده گواهینامه ارائه شده را نصب کنید. اگر نصب کننده قبلاً نصب نشده باشد ، سیستم یک IllegalArgumentException را پرتاب می کند.
  • تنظیم مجدد رمز عبور برای مدیر دستگاه اکنون برای صاحبان پروفایل اعمال می شود. مدیر دستگاه دیگر نمی تواند از DevicePolicyManager.resetPassword() برای پاک کردن رمزهای عبور یا تغییر مواردی که قبلاً تنظیم شده اند استفاده کنند. مدیر دستگاه هنوز هم می تواند رمز عبور را تنظیم کند ، اما فقط در صورت عدم وجود دستگاه رمز ، پین یا الگوی.
  • صاحبان دستگاه و پروفایل حتی اگر محدودیت ها تنظیم شوند می توانند حساب ها را مدیریت کنند. صاحبان دستگاه و صاحبان پروفایل می توانند با API های مدیریت حساب تماس بگیرند حتی اگر محدودیت های کاربری DISALLOW_MODIFY_ACCOUNTS وجود داشته باشد.
  • صاحبان دستگاه می توانند کاربران ثانویه را راحت تر مدیریت کنند. هنگامی که یک دستگاه در حالت صاحب دستگاه کار می کند ، محدودیت DISALLOW_ADD_USER به طور خودکار تنظیم می شود. این امر باعث می شود کاربران از ایجاد کاربران ثانویه بدون کنترل استفاده کنند. علاوه بر این ، روشهای CreateUser() و createAndInitializeUser() کاهش می یابد. روش جدید DevicePolicyManager.createAndManageUser() جایگزین آنها می شود.
  • صاحبان دستگاه می توانند به شناسه های دستگاه دسترسی پیدا کنند. یک صاحب دستگاه می تواند با استفاده از DevicePolicyManager.getWifiMacAddress() به آدرس MAC Wi-Fi یک دستگاه دسترسی پیدا کند. اگر Wi-Fi هرگز در دستگاه فعال نشده باشد ، این روش مقدار null را برمی گرداند.
  • تنظیم حالت کار دسترسی به برنامه های کاری را کنترل می کند. هنگامی که حالت کار خاموش است ، پرتاب سیستم نشان می دهد که برنامه های کاری با خاکستری کردن آنها در دسترس نیستند. فعال کردن حالت کار دوباره رفتار عادی را بازیابی می کند.
  • هنگام نصب پرونده PKCS #12 حاوی زنجیره گواهی مشتری و کلید خصوصی مربوطه از تنظیمات UI ، گواهی CA در زنجیره دیگر در ذخیره اعتبار معتبر نصب نمی شود. این امر بر نتیجه KeyChain.getCertificateChain() تأثیر نمی گذارد که برنامه ها بعداً سعی در بازیابی زنجیره گواهی مشتری دارند. در صورت لزوم ، گواهی CA باید از طریق تنظیمات UI به طور جداگانه ، با یک قالب رمزگذاری شده تحت یک پسوند پرونده .crt یا .cer ، به ذخیره اعتبار معتبر قابل اعتماد نصب شود.
  • با شروع در Android 7.0 ، ثبت نام اثر انگشت و ذخیره سازی برای هر کاربر مدیریت می شود. اگر مشتری خط مشی دستگاه صاحب پروفایل (DPC) API سطح 23 (یا پایین) را بر روی دستگاهی که Android 7.0 (API سطح 24) را اجرا می کند ، هدف قرار می دهد ، کاربر هنوز قادر به تنظیم اثر انگشت روی دستگاه است ، اما برنامه های کار نمی توانند به اثر انگشت دستگاه دسترسی پیدا کنند. هنگامی که DPC API سطح 24 و بالاتر را هدف قرار می دهد ، کاربر می تواند با مراجعه به تنظیمات> امنیت> امنیت پروفایل کار ، اثر انگشت را به طور خاص برای مشخصات کار تنظیم کند.
  • یک وضعیت رمزگذاری جدید ENCRYPTION_STATUS_ACTIVE_PER_USER توسط DevicePolicyManager.getStorageEncryptionStatus() بازگردانده می شود ، تا نشان دهد که رمزگذاری فعال است و کلید رمزگذاری به کاربر گره خورده است. وضعیت جدید فقط در صورتی بازگردانده می شود که DPC سطح 24 و بالاتر API را هدف قرار دهد. برای برنامه هایی که سطح API قبلی را هدف قرار می دهند ، ENCRYPTION_STATUS_ACTIVE بازگردانده می شود ، حتی اگر کلید رمزگذاری مختص کاربر یا نمایه باشد.
  • در Android 7.0 ، روش های مختلفی که معمولاً بر کل دستگاه تأثیر می گذارد ، اگر دستگاه دارای مشخصات کار با یک چالش کار جداگانه باشد ، متفاوت رفتار می کنند. این روشها به جای تأثیرگذاری بر کل دستگاه ، فقط در پروفایل کار اعمال می شود. (لیست کامل این روشها در DevicePolicyManager.getParentProfileInstance() مستندات است.) به عنوان مثال ، DevicePolicyManager.lockNow() به جای قفل کردن کل دستگاه ، مشخصات کار را قفل می کند. برای هر یک از این روشها ، می توانید با فراخوانی روش در نمونه والدین از DevicePolicyManager رفتار قدیمی را بدست آورید. شما می توانید این والدین را با تماس با DevicePolicyManager.getParentProfileInstance() دریافت کنید. به عنوان مثال ، اگر با روش lockNow() نمونه والدین تماس بگیرید ، کل دستگاه قفل شده است.

حفظ حاشیه نویسی

Android 7.0 اشکالی را برطرف می کند که در آن دیدگاه حاشیه نویسی نادیده گرفته می شود. این مسئله باعث می شود تا زمان اجرا به حاشیه نویسی که نباید قادر به آن باشد دسترسی پیدا کند. این حاشیه نویسی ها شامل:

  • VISIBILITY_BUILD : در نظر گرفته شده فقط در زمان ساخت قابل مشاهده است.
  • VISIBILITY_SYSTEM : در نظر گرفته شده است که در زمان اجرا قابل مشاهده است ، اما فقط به سیستم زیرین.

اگر برنامه شما به این رفتار اعتماد کرده است ، لطفاً یک خط مشی نگهداری را به حاشیه نویسی اضافه کنید که باید در زمان اجرا در دسترس باشد. شما این کار را با استفاده از @Retention(RetentionPolicy.RUNTIME) انجام می دهید.

تنظیمات پیش فرض TLS/SSL تغییر می کند

Android 7.0 تغییرات زیر را در پیکربندی پیش فرض TLS/SSL استفاده شده توسط برنامه های HTTPS و سایر ترافیک TLS/SSL ایجاد می کند:

  • سوئیت های رمزنگاری RC4 اکنون غیرفعال هستند.
  • سوئیت های رمزگذاری Chacha20-Poly1305 اکنون فعال شده اند.

RC4 که به طور پیش فرض غیرفعال می شوند ممکن است منجر به شکستگی در اتصال HTTPS یا TLS/SSL شود که سرور در مورد مجموعه های رمزنگاری مدرن مذاکره نکند. اصلاح ارجح بهبود پیکربندی سرور برای فعال کردن سوئیت ها و پروتکل های رمزنگاری قوی تر و مدرن تر است. در حالت ایده آل ، TLSV1.2 و AES-GCM باید فعال شوند و سوئیت های رمزگذاری رادسی رو به جلو (ECDHE) باید فعال و ترجیح داده شوند.

یک گزینه جایگزین برای اصلاح برنامه برای استفاده از SSLSocketFactory سفارشی برای برقراری ارتباط با سرور است. این کارخانه باید برای ایجاد نمونه های SSLSocket طراحی شود که برخی از مجموعه های رمزنگاری مورد نیاز سرور علاوه بر سوئیت های رمزنگاری پیش فرض نیز وجود دارد.

توجه: این تغییرات مربوط به WebView نیست.

برنامه هایی که Android 7.0 را هدف قرار می دهند

این تغییرات رفتاری منحصراً در مورد برنامه هایی که Android 7.0 (API سطح 24) یا بالاتر را هدف قرار می دهند ، اعمال می شود. برنامه هایی که در برابر Android 7.0 کامپایل می شوند ، یا targetSdkVersion به Android 7.0 یا بالاتر تنظیم می کنند ، باید برنامه های خود را برای پشتیبانی از این رفتارها به درستی ، در صورت لزوم در برنامه ، اصلاح کنند.

تغییر سریال سازی

Android 7.0 (API سطح 24) در محاسبه سریال پیش فرض سریال VersionUID که در آن با مشخصات مطابقت ندارد ، یک اشکال را برطرف کرد.

کلاس هایی که Serializable اجرا هستند و یک قسمت serialVersionUID صریح را مشخص نمی کنند ، می توانند تغییر در سریال پیش فرض خود را مشاهده کنند که باعث می شود یک استثنا در هنگام تلاش برای ناامیدی کردن نمونه هایی از کلاس که بر روی نسخه قبلی سریال شده اند یا توسط یک برنامه هدفمند هدف قرار گرفته اند ، پرتاب شود. نسخه قبلی پیام خطا چیزی شبیه به این خواهد بود:

local class incompatible: stream classdesc serialVersionUID = 1234, local class serialVersionUID = 4567

رفع این موارد نیاز به اضافه کردن یک قسمت serialVersionUID به هر کلاس تحت تأثیر با مقدار stream classdesc serialVersionUID از پیام خطا دارد ، به عنوان مثال 1234 در این مورد. این تغییر به کلیه توصیه های تمرین خوب برای نوشتن کد سریال سازی می پردازد و روی همه نسخه های Android کار خواهد کرد.

اشکال خاص که برطرف شد مربوط به وجود روشهای اولیه استاتیک ، یعنی <clinit> بود. با توجه به مشخصات ، حضور یا عدم وجود یک روش اولیه استاتیک در کلاس بر سریال پیش فرض محاسبه شده برای آن کلاس تأثیر می گذارد. قبل از رفع اشکال ، محاسبه نیز در صورت عدم داشتن یک کلاس ، کلاس فوق العاده را برای یک استاتیک استاتیک بررسی می کند.

برای روشن شدن ، این تغییر بر برنامه هایی که سطح API 23 یا پایین تر را هدف قرار می دهند ، کلاس هایی که دارای یک زمینه serialVersionUID یا کلاس هایی هستند که دارای یک روش اولیه ساز استاتیک هستند ، تأثیر نمی گذارد.

سایر نکات مهم

  • هنگامی که یک برنامه در Android 7.0 در حال اجرا است ، اما سطح API پایین تر را هدف قرار می دهد و کاربر اندازه نمایش را تغییر می دهد ، روند برنامه کشته می شود. این برنامه باید بتواند با لطف و داوری این سناریو را اداره کند. در غیر این صورت ، هنگامی که کاربر آن را از قله ها بازیابی می کند ، خراب می شود.

    شما باید برنامه خود را آزمایش کنید تا اطمینان حاصل شود که این رفتار رخ نمی دهد. شما می توانید با ایجاد یک تصادف یکسان هنگام کشتن برنامه به صورت دستی از طریق DDMS ، این کار را انجام دهید.

    برنامه هایی که Android 7.0 (API سطح 24) و بالاتر را هدف قرار می دهند ، به طور خودکار بر روی تغییرات چگالی کشته نمی شوند. با این حال ، آنها هنوز هم ممکن است به تغییرات پیکربندی پاسخ دهند.

  • برنامه های موجود در Android 7.0 باید بتوانند تغییرات پیکربندی را با لطف انجام دهند و نباید در شروع های بعدی خراب شوند. می توانید با تغییر اندازه قلم ( تنظیم > نمایش > اندازه قلم ) رفتار برنامه را تأیید کنید و سپس بازیابی برنامه از Recents.
  • به دلیل اشکال در نسخه های قبلی اندروید ، سیستم به عنوان نقض حالت سخت ، به یک سوکت TCP روی موضوع اصلی نمی نویسد. Android 7.0 این اشکال را برطرف می کند. برنامه هایی که این رفتار را به نمایش می گذارند اکنون یک android.os.NetworkOnMainThreadException را پرتاب می کنند. به طور کلی ، انجام عملیات شبکه بر روی موضوع اصلی ایده بدی است زیرا این عملیات معمولاً دارای تأخیر بالایی است که باعث ANR و JANK می شود.
  • Debug.startMethodTracing() خانواده روشها اکنون به جای اینکه در سطح بالای کارت SD باشد ، به طور پیش فرض برای ذخیره خروجی در فهرست اختصاصی بسته بندی شما در ذخیره سازی مشترک است. این بدان معناست که برنامه ها دیگر نیازی به درخواست مجوز WRITE_EXTERNAL_STORAGE برای استفاده از این API ها ندارند.
  • بسیاری از API های پلتفرم اکنون شروع به بررسی بارهای بزرگ ارسال شده در معاملات Binder کرده اند ، و این سیستم اکنون به جای اینکه ساکت ورود یا سرکوب آنها را انجام دهد ، TransactionTooLargeExceptions به عنوان RuntimeExceptions بازیابی می کند. یک مثال متداول ، ذخیره کردن داده های بیش از حد در Activity.onSaveInstanceState() ، که باعث می شود ActivityThread.StopInfo وقتی برنامه شما Android 7.0 را هدف قرار می دهد ، یک RuntimeException پرتاب کند.
  • اگر یک برنامه وظایف Runnable را به یک View ارسال کند و View به یک پنجره وصل نشود ، سیستم با View کار Runnable را صف می کند. کار Runnable تا زمانی که View به یک پنجره وصل نشود ، اجرا نمی شود. این رفتار اشکالات زیر را برطرف می کند:
    • اگر برنامه ارسال شده از یک View به غیر از موضوع UI پنجره در نظر گرفته شده ، Runnable ممکن است در نتیجه روی موضوع اشتباه اجرا شود.
    • اگر کار Runnable از یک موضوع غیر از موضوع Looper ارسال شود ، برنامه می تواند وظیفه Runnable را در معرض دید قرار دهد.
  • اگر یک برنامه در Android 7.0 با اجازه DELETE_PACKAGES سعی کند یک بسته را حذف کند ، اما یک برنامه متفاوت آن بسته را نصب کرده بود ، سیستم نیاز به تأیید کاربر دارد. در این سناریو ، برنامه ها باید هنگام استفاده از PackageInstaller.uninstall() STATUS_PENDING_USER_ACTION به عنوان وضعیت بازگشت انتظار داشته باشند.
  • ارائه دهنده JCA به نام Crypto مستهلک می شود ، زیرا تنها الگوریتم آن ، SHA1PRNG ، از نظر رمزنگاری ضعیف است. برنامه ها دیگر نمی توانند از کلیدهای مشتق شده از sha1prng استفاده کنند ، زیرا این ارائه دهنده دیگر در دسترس نیست. برای اطلاعات بیشتر ، به ارائه دهنده امنیت "Crypto" در پست وبلاگ که در Android N است ، مراجعه کنید.