পূর্ববর্তী রিলিজগুলোর মতোই, অ্যান্ড্রয়েড ১৫-এ এমন কিছু আচরণগত পরিবর্তন রয়েছে যা আপনার অ্যাপকে প্রভাবিত করতে পারে। নিম্নলিখিত আচরণগত পরিবর্তনগুলো শুধুমাত্র সেইসব অ্যাপের জন্য প্রযোজ্য যেগুলো অ্যান্ড্রয়েড ১৫ বা তার উচ্চতর সংস্করণকে টার্গেট করছে। যদি আপনার অ্যাপটি অ্যান্ড্রয়েড ১৫ বা তার উচ্চতর সংস্করণকে টার্গেট করে থাকে, তবে প্রযোজ্য ক্ষেত্রে এই আচরণগুলোকে সঠিকভাবে সমর্থন করার জন্য আপনার অ্যাপটি পরিবর্তন করা উচিত।
আপনার অ্যাপের targetSdkVersion নির্বিশেষে Android 15-এ চালিত সমস্ত অ্যাপকে প্রভাবিত করে এমন আচরণগত পরিবর্তনের তালিকাটিও পর্যালোচনা করতে ভুলবেন না।
মূল কার্যকারিতা
অ্যান্ড্রয়েড ১৫ অ্যান্ড্রয়েড সিস্টেমের বিভিন্ন মূল সক্ষমতাকে পরিবর্তন বা প্রসারিত করে।
ফোরগ্রাউন্ড পরিষেবাগুলিতে পরিবর্তন
我们将对 Android 15 中的前台服务进行以下更改。
数据同步前台服务超时行为
Android 15 Android 15 (API স্তর 35) বা উচ্চতরকে লক্ষ্য করে এমন অ্যাপগুলির জন্য dataSync একটি নতুন টাইমআউট আচরণ প্রবর্তন করে৷ এই আচরণটি নতুন mediaProcessing ফোরগ্রাউন্ড পরিষেবা প্রকারের ক্ষেত্রেও প্রযোজ্য।
সিস্টেমটি একটি অ্যাপের dataSync পরিষেবাগুলিকে 24-ঘন্টা সময়ের মধ্যে মোট 6 ঘন্টা চালানোর অনুমতি দেয়, তারপরে সিস্টেমটি চলমান পরিষেবাটির Service.onTimeout(int, int) পদ্ধতিতে কল করে (Android 15 এ চালু করা হয়েছে)৷ এই সময়ে, পরিষেবাটিতে Service.stopSelf() কল করার জন্য কয়েক সেকেন্ড সময় আছে। যখন Service.onTimeout() কল করা হয়, তখন পরিষেবাটিকে আর অগ্রভাগের পরিষেবা হিসাবে বিবেচনা করা হয় না। যদি পরিষেবাটি Service.stopSelf() কল না করে, তবে সিস্টেমটি একটি অভ্যন্তরীণ ব্যতিক্রম নিক্ষেপ করে৷ ব্যতিক্রমটি নিম্নলিখিত বার্তার সাথে লগক্যাটে লগ ইন করা হয়েছে:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"
এই আচরণ পরিবর্তনের সমস্যাগুলি এড়াতে, আপনি নিম্নলিখিতগুলির মধ্যে এক বা একাধিক করতে পারেন:
- আপনার পরিষেবাকে নতুন
Service.onTimeout(int, int)পদ্ধতি প্রয়োগ করতে দিন। আপনার অ্যাপ কলব্যাক গ্রহণ করলে, কয়েক সেকেন্ডের মধ্যেstopSelf()কল করতে ভুলবেন না। (যদি আপনি এখনই অ্যাপটি বন্ধ না করেন তবে সিস্টেমটি একটি ব্যর্থতা তৈরি করে।) - নিশ্চিত করুন যে আপনার অ্যাপের
dataSyncপরিষেবাগুলি যে কোনও 24-ঘণ্টার সময়ের মধ্যে মোট 6 ঘন্টার বেশি চলবে না (যদি না ব্যবহারকারী অ্যাপটির সাথে ইন্টারঅ্যাক্ট করে, টাইমার রিসেট করে)। - শুধুমাত্র
dataSyncফোরগ্রাউন্ড পরিষেবাগুলি সরাসরি ব্যবহারকারীর ইন্টারঅ্যাকশনের ফলে শুরু করুন; যেহেতু পরিষেবাটি শুরু হওয়ার সময় আপনার অ্যাপটি ফোরগ্রাউন্ডে থাকে, তাই অ্যাপটি ব্যাকগ্রাউন্ডে যাওয়ার পরে আপনার পরিষেবার পুরো ছয় ঘন্টা থাকে। - একটি
dataSyncফোরগ্রাউন্ড পরিষেবা ব্যবহার করার পরিবর্তে, একটি বিকল্প API ব্যবহার করুন৷
যদি আপনার অ্যাপের dataSync ফোরগ্রাউন্ড পরিষেবাগুলি গত 24-এর মধ্যে 6 ঘন্টা ধরে চলে থাকে, তবে ব্যবহারকারী আপনার অ্যাপটিকে ফোরগ্রাউন্ডে না আনলে আপনি অন্য dataSync ফোরগ্রাউন্ড পরিষেবা শুরু করতে পারবেন না (যা টাইমার রিসেট করে)। আপনি যদি অন্য একটি dataSync ফোরগ্রাউন্ড পরিষেবা শুরু করার চেষ্টা করেন, তাহলে সিস্টেমটি "ফোরগ্রাউন্ড সার্ভিস টাইপ ডেটাসিঙ্কের জন্য সময়সীমা ইতিমধ্যেই শেষ" এর মতো একটি ত্রুটি বার্তা সহ ForegroundServiceStartNotAllowedException ছুড়ে দেয়৷
টেস্টিং
আপনার অ্যাপের আচরণ পরীক্ষা করার জন্য, আপনি ডেটা সিঙ্ক টাইমআউট সক্ষম করতে পারেন এমনকি যদি আপনার অ্যাপ অ্যান্ড্রয়েড 15 টার্গেট না করে (যতক্ষণ অ্যাপটি একটি Android 15 ডিভাইসে চলছে)। টাইমআউট সক্ষম করতে, নিম্নলিখিত adb কমান্ডটি চালান:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
আপনি টাইমআউট পিরিয়ড সামঞ্জস্য করতে পারেন, সীমা পৌঁছে গেলে আপনার অ্যাপ কীভাবে আচরণ করে তা পরীক্ষা করা সহজ করতে। একটি নতুন টাইমআউট পিরিয়ড সেট করতে, নিম্নলিখিত adb কমান্ডটি চালান:
adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds
新的媒体处理前台服务类型
Android 15 引入了一种新的前台服务类型 mediaProcessing。此服务类型适用于转码媒体文件等操作。例如,媒体应用可能会下载音频文件,并需要先将其转换为其他格式,然后才能播放。您可以使用 mediaProcessing 前台服务,确保即使应用在后台运行时转换也会继续。
系统允许应用的 mediaProcessing 服务在 24 小时内总共运行 6 小时,之后系统会调用正在运行的服务的 Service.onTimeout(int, int) 方法(在 Android 15 中引入)。此时,服务有几秒钟的时间来调用 Service.stopSelf()。如果服务未调用 Service.stopSelf(),系统会抛出内部异常。系统会在 Logcat 中记录此异常,并显示以下消息:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"
为避免出现此异常,您可以执行以下任一操作:
- 让您的服务实现新的
Service.onTimeout(int, int)方法。当您的应用收到回调时,请务必在几秒钟内调用stopSelf()。(如果您未立即停止应用,系统会生成失败情况。) - 确保应用的
mediaProcessing服务在任何 24 小时内总运行时间不超过 6 小时(除非用户与应用互动,重置计时器)。 - 仅在有直接用户互动时启动
mediaProcessing前台服务;由于服务启动时应用位于前台,因此您的服务在应用进入后台后有完整的 6 小时时间。 - 请改用 替代 API(例如 WorkManager),而不是使用
mediaProcessing前台服务。
如果您的应用的 mediaProcessing 前台服务在过去 24 小时内运行了 6 小时,则您无法启动其他 mediaProcessing 前台服务,除非用户将您的应用切换到前台(这会重置计时器)。如果您尝试启动另一个 mediaProcessing 前台服务,系统会抛出 ForegroundServiceStartNotAllowedException,并显示类似于“前台服务类型 mediaProcessing 的时间限制已用尽”的错误消息。
如需详细了解 mediaProcessing 服务类型,请参阅 Android 15 前台服务类型变更:媒体处理。
测试
如需测试应用的行为,您可以启用媒体处理超时,即使您的应用并非以 Android 15 为目标平台也是如此(前提是应用在 Android 15 设备上运行)。如需启用超时,请运行以下 adb 命令:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
您还可以调整超时期限,以便更轻松地测试应用在达到上限时的行为方式。如需设置新的超时期限,请运行以下 adb 命令:
adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds
对启动前台服务的 BOOT_COMPLETED 广播接收器的限制
在启动 BOOT_COMPLETED 广播接收器方面存在新限制
前台服务。BOOT_COMPLETED 接收器不能启动
以下类型的前台服务:
dataSynccameramediaPlaybackphoneCallmediaProjectionmicrophone(自 Android 14 起,microphone就受到此限制)
如果 BOOT_COMPLETED 接收器尝试启动任何上述类型的前台
服务,系统会抛出 ForegroundServiceStartNotAllowedException。
测试
如需测试应用的行为,您可以启用这些新限制,即使您的应用并未以 Android 15 为目标平台(只要应用在 Android 15 设备上运行)也是如此。运行以下 adb 命令:
adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name
如需在不重启设备的情况下发送 BOOT_COMPLETED 广播,请运行以下 adb 命令:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name
在应用拥有 SYSTEM_ALERT_WINDOW 权限时启动前台服务的限制
以前,如果应用拥有 SYSTEM_ALERT_WINDOW 权限,即使应用当前在后台运行,也可以启动前台服务(如免于后台启动限制中所述)。
如果应用以 Android 15 为目标平台,则此豁免范围现在更窄。现在,应用需要具有 SYSTEM_ALERT_WINDOW 权限,并且还需要有一个可见的叠加窗口。也就是说,应用需要先启动 TYPE_APPLICATION_OVERLAY 窗口,并且该窗口需要处于可见状态,然后您才能启动前台服务。
如果您的应用尝试从后台启动前台服务,但不符合这些新要求(并且没有其他豁免情况),系统会抛出 ForegroundServiceStartNotAllowedException。
如果您的应用声明了 SYSTEM_ALERT_WINDOW 权限并从后台启动前台服务,则可能会受到此变更的影响。如果您的应用获得了 ForegroundServiceStartNotAllowedException,请检查应用的操作顺序,并确保应用在尝试从后台启动前台服务之前已具有有效的叠加层窗口。您可以通过调用 View.getWindowVisibility() 检查叠加层窗口当前是否可见,也可以替换 View.onWindowVisibilityChanged(),以便在可见性发生变化时收到通知。
测试
如需测试应用的行为,您可以启用这些新限制,即使您的应用并未以 Android 15 为目标平台(只要应用在 Android 15 设备上运行)也是如此。如需针对从后台启动前台服务启用这些新限制,请运行以下 adb 命令:
adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name
অ্যাপগুলো কখন ডু নট ডিস্টার্ব মোডের গ্লোবাল স্টেট পরিবর্তন করতে পারবে, সেই নিয়মে পরিবর্তন আনা হয়েছে।
যে অ্যাপগুলি Android 15 (API লেভেল 35) এবং উচ্চতরকে টার্গেট করে তারা আর কোনও ডিভাইসে গ্লোবাল স্টেট বা Do Not Disturb (DND) এর নীতি পরিবর্তন করতে পারে না (হয় ব্যবহারকারী সেটিংস পরিবর্তন করে বা DND মোড বন্ধ করে)। পরিবর্তে, অ্যাপগুলিকে অবশ্যই একটি AutomaticZenRule অবদান রাখতে হবে, যা সিস্টেমটি বিদ্যমান সর্বাধিক-নিষেধমূলক-নীতি-জয় স্কিমের সাথে একটি বৈশ্বিক নীতিতে একত্রিত করে। বিদ্যমান API-এ কল যা পূর্বে গ্লোবাল স্টেটকে প্রভাবিত করেছিল ( setInterruptionFilter , setNotificationPolicy ) এর ফলে একটি অন্তর্নিহিত AutomaticZenRule তৈরি বা আপডেট হয়, যা সেই API কলগুলির কল-চক্রের উপর নির্ভর করে টগল করা এবং বন্ধ করা হয়।
মনে রাখবেন যে এই পরিবর্তনটি শুধুমাত্র পর্যবেক্ষণযোগ্য আচরণকে প্রভাবিত করে যদি অ্যাপটি setInterruptionFilter(INTERRUPTION_FILTER_ALL) কল করে এবং আশা করে যে কলটি একটি AutomaticZenRule নিষ্ক্রিয় করবে যা আগে তাদের মালিকদের দ্বারা সক্রিয় করা হয়েছিল৷
OpenJDK API পরিবর্তন
সর্বশেষ OpenJDK LTS রিলিজের ফিচারগুলোর সাথে সামঞ্জস্য রাখতে Android 15, Android-এর কোর লাইব্রেরিগুলোকে নতুন করে সাজানোর কাজ চালিয়ে যাচ্ছে।
এই পরিবর্তনগুলোর কিছু কিছু অ্যান্ড্রয়েড ১৫ (এপিআই লেভেল ৩৫) টার্গেট করা অ্যাপগুলোর সামঞ্জস্যতাকে প্রভাবিত করতে পারে:
স্ট্রিং ফরম্যাটিং এপিআই-তে পরিবর্তন : নিম্নলিখিত
String.format()এবংFormatter.format()এপিআই ব্যবহার করার সময় আর্গুমেন্ট index, flags, width, এবং precision-এর ভ্যালিডেশন এখন আরও কঠোর করা হয়েছে:-
String.format(String, Object[]) -
String.format(Locale, String, Object[]) -
Formatter.format(String, Object[]) -
Formatter.format(Locale, String, Object[])
উদাহরণস্বরূপ, যখন আর্গুমেন্ট ইনডেক্স 0 ব্যবহার করা হয় (ফরম্যাট স্ট্রিং-এ
%0), তখন নিম্নলিখিত এক্সেপশনটি থ্রো করা হয়:IllegalFormatArgumentIndexException: Illegal format argument index = 0এক্ষেত্রে, ফরম্যাট স্ট্রিং-এ আর্গুমেন্ট ইনডেক্স ১ (
%1) ব্যবহার করে সমস্যাটি সমাধান করা যেতে পারে।-
Arrays.asList(...).toArray()এর কম্পোনেন্ট টাইপের পরিবর্তন :Arrays.asList(...).toArray()ব্যবহার করার ফলে, তৈরি হওয়া অ্যারের কম্পোনেন্ট টাইপ এখন একটিObjectহয় — যা মূল অ্যারের এলিমেন্টগুলোর টাইপ নয়। তাই নিচের কোডটি একটিClassCastExceptionথ্রো করে:String[] elements = (String[]) Arrays.asList("one", "two").toArray();এই ক্ষেত্রে, ফলাফল অ্যারেতে কম্পোনেন্ট টাইপ হিসেবে
Stringবজায় রাখতে, আপনি এর পরিবর্তেCollection.toArray(Object[])ব্যবহার করতে পারেন:String[] elements = Arrays.asList("two", "one").toArray(new String[0]);ভাষা কোড পরিচালনায় পরিবর্তন : লোকেল এপিআই (
LocaleAPI) ব্যবহার করার সময়, হিব্রু, ইদ্দিশ এবং ইন্দোনেশীয় ভাষার কোডগুলিকে আর তাদের অপ্রচলিত রূপে (হিব্রু:iw, ইদ্দিশ:ji, এবং ইন্দোনেশীয়:in) রূপান্তর করা হয় না। এই লোকেলগুলির কোনো একটির জন্য ভাষা কোড নির্দিষ্ট করার সময়, এর পরিবর্তে ISO 639-1 থেকে কোডগুলি ব্যবহার করুন (হিব্রু:he, ইদ্দিশ:yi, এবং ইন্দোনেশীয়:id)।র্যান্ডম ইন্ট সিকোয়েন্সে পরিবর্তন : https://bugs.openjdk.org/browse/JDK-8301574- এ করা পরিবর্তনগুলো অনুসরণ করে, নিম্নলিখিত
Random.ints()মেথডগুলো এখনRandom.nextInt()মেথডগুলোর থেকে ভিন্ন একটি সংখ্যার সিকোয়েন্স রিটার্ন করে:সাধারণত, এই পরিবর্তনের ফলে অ্যাপে কোনো সমস্যা হওয়ার কথা নয়, কিন্তু আপনার কোডের এমনটা আশা করা উচিত নয় যে
Random.ints()মেথড থেকে তৈরি হওয়া সিকোয়েন্সটিRandom.nextInt()এর সাথে মিলবে।
আপনার অ্যাপের বিল্ড কনফিগারেশনে compileSdk আপডেট করে Android 15 (API লেভেল 35) ব্যবহার করার পর, নতুন SequencedCollection API আপনার অ্যাপের কম্প্যাটিবিলিটিকে প্রভাবিত করতে পারে।
kotlin-stdlibএMutableList.removeFirst()এবংMutableList.removeLast()এক্সটেনশন ফাংশনগুলির সাথে সংঘর্ষ।জাভার
Listটাইপটি কোটলিনেরMutableListটাইপের সাথে ম্যাপ করা হয়েছে। যেহেতু Android 15 (API লেভেল 35)-এList.removeFirst()এবংList.removeLast()API-গুলো চালু করা হয়েছে, তাই কোটলিন কম্পাইলার ফাংশন কলগুলোকে, যেমনlist.removeFirst(),kotlin-stdlibএর এক্সটেনশন ফাংশনগুলোর পরিবর্তে নতুনListAPI-গুলোতে স্ট্যাটিক্যালি রিজলভ করে।যদি কোনো অ্যাপকে
compileSdk35এবংminSdk34বা তার কম মানে সেট করে পুনরায় কম্পাইল করা হয়, এবং তারপর অ্যাপটি অ্যান্ড্রয়েড ১৪ বা তার নিচের সংস্করণে চালানো হয়, তাহলে একটি রানটাইম এরর দেখা দেয়:java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;অ্যান্ড্রয়েড গ্রেডল প্লাগইনে বিদ্যমান
NewApiলিন্ট অপশনটি এই নতুন এপিআই ব্যবহারগুলো ধরতে পারে।./gradlew lintMainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi] list.removeFirst()রানটাইম এক্সেপশন এবং লিন্ট এরর ঠিক করার জন্য, কোটলিনে
removeFirst()এবংremoveLast()ফাংশন কলগুলোকে যথাক্রমেremoveAt(0)এবংremoveAt(list.lastIndex)দিয়ে প্রতিস্থাপন করা যায়। আপনি যদি অ্যান্ড্রয়েড স্টুডিও লেডিবাগ | 2024.1.3 বা তার উচ্চতর সংস্করণ ব্যবহার করেন, তবে এটি এই এররগুলোর জন্য একটি কুইক ফিক্স অপশনও প্রদান করে।যদি লিন্ট অপশনটি নিষ্ক্রিয় করা হয়ে থাকে, তাহলে
@SuppressLint("NewApi")এবংlintOptions { disable 'NewApi' }সরিয়ে ফেলার কথা বিবেচনা করুন।জাভাতে অন্যান্য পদ্ধতির সাথে সংঘর্ষ
বিদ্যমান টাইপগুলোতে, যেমন
ListএবংDeque, নতুন মেথড যোগ করা হয়েছে। এই নতুন মেথডগুলো অন্যান্য ইন্টারফেস এবং ক্লাসের একই নাম ও আর্গুমেন্ট টাইপের মেথডগুলোর সাথে সামঞ্জস্যপূর্ণ নাও হতে পারে। অসামঞ্জস্যতার কারণে মেথড সিগনেচারের সংঘর্ষের ক্ষেত্রে,javacকম্পাইলার একটি বিল্ড-টাইম এরর আউটপুট করে। উদাহরণস্বরূপ:উদাহরণ ত্রুটি ১:
javac MyList.javaMyList.java:135: error: removeLast() in MyList cannot implement removeLast() in List public void removeLast() { ^ return type void is not compatible with Object where E is a type-variable: E extends Object declared in interface Listউদাহরণ ত্রুটি ২:
javac MyList.javaMyList.java:7: error: types Deque<Object> and List<Object> are incompatible; public class MyList implements List<Object>, Deque<Object> { both define reversed(), but with unrelated return types 1 errorউদাহরণ ত্রুটি ৩:
javac MyList.javaMyList.java:43: error: types List<E#1> and MyInterface<E#2> are incompatible; public static class MyList implements List<Object>, MyInterface<Object> { class MyList inherits unrelated defaults for getFirst() from types List and MyInterface where E#1,E#2 are type-variables: E#1 extends Object declared in interface List E#2 extends Object declared in interface MyInterface 1 errorএই বিল্ড ত্রুটিগুলি সমাধান করার জন্য, এই ইন্টারফেসগুলি বাস্তবায়নকারী ক্লাসটিকে একটি সামঞ্জস্যপূর্ণ রিটার্ন টাইপ দিয়ে মেথডটি ওভাররাইড করতে হবে। উদাহরণস্বরূপ:
@Override public Object getFirst() { return List.super.getFirst(); }
নিরাপত্তা
অ্যান্ড্রয়েড ১৫-এ এমন কিছু পরিবর্তন আনা হয়েছে যা সিস্টেমের নিরাপত্তা বাড়িয়ে অ্যাপ এবং ব্যবহারকারীদের ক্ষতিকর অ্যাপ থেকে সুরক্ষিত রাখতে সাহায্য করে।
সীমাবদ্ধ TLS সংস্করণ
Android 15 限制了对 TLS 版本 1.0 和 1.1 的使用。这些版本之前已在 Android 中被弃用,但现在不允许面向 Android 15 的应用使用。
সুরক্ষিত পটভূমি কার্যকলাপ চালু হয়
Android 15 做出了一些变更,可防止恶意后台应用将其他应用置于前台、提升自身权限并滥用用户互动,从而保护用户免受恶意应用的侵害,并让用户更好地控制自己的设备。自 Android 10(API 级别 29)起,后台 activity 启动受到限制。
其他更改
- 将
PendingIntent创建者更改为默认阻止后台活动启动。这有助于防止应用意外创建可能被恶意行为者滥用的PendingIntent。 - 除非
PendingIntent发送方允许,否则请勿将应用转至前台。此变更旨在防止恶意应用滥用在后台启动 activity 的功能。默认情况下,除非创建者允许后台 activity 启动权限或发送者具有后台 activity 启动权限,否则不允许应用将任务堆栈带到前台。 - 控制任务堆栈的顶层 activity 如何完成其任务。如果顶部 activity 完成了一项任务,Android 将返回到上次处于活跃状态的任务。此外,如果非顶部 activity 完成其任务,Android 会返回到主屏幕;它不会阻止此非顶部 activity 完成。
- 防止从其他应用启动任意 activity 进入您自己的任务。此变更可防止恶意应用通过创建看似来自其他应用的 activity 来对用户进行钓鱼式攻击。
- 阻止将非可见窗口纳入后台 activity 启动的考虑范围。这有助于防止恶意应用滥用后台活动启动来向用户显示不必要或恶意的内容。
নিরাপদ উদ্দেশ্য
Android 15 针对 intent 引入了 StrictMode。
如需查看有关 Intent 使用违规行为的详细日志,请使用以下方法:
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() .detectUnsafeIntentLaunch() .build() ) }
Java
public void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() .detectUnsafeIntentLaunch() .build()); }
ব্যবহারকারীর অভিজ্ঞতা এবং সিস্টেম UI
অ্যান্ড্রয়েড ১৫-এ এমন কিছু পরিবর্তন আনা হয়েছে, যার উদ্দেশ্য হলো আরও সামঞ্জস্যপূর্ণ ও স্বজ্ঞামূলক ব্যবহারকারীর অভিজ্ঞতা তৈরি করা।
জানালার ভেতরের পরিবর্তন
Android 15 中与窗口内边距相关的两项变更:默认强制执行边到边,此外还有配置变更,例如系统栏的默认配置。
全面实施政策
অ্যান্ড্রয়েড ১৫ চালিত ডিভাইসগুলিতে অ্যাপগুলি ডিফল্টরূপে এজ-টু-এজ হয়, যদি অ্যাপটি অ্যান্ড্রয়েড ১৫ (এপিআই লেভেল ৩৫) টার্গেট করে তৈরি করা হয়।

এটি একটি ব্রেকিং চেঞ্জ যা আপনার অ্যাপের UI-কে নেতিবাচকভাবে প্রভাবিত করতে পারে। এই পরিবর্তনগুলো UI-এর নিম্নলিখিত অংশগুলোকে প্রভাবিত করবে:
- অঙ্গভঙ্গি হ্যান্ডেল নেভিগেশন বার
- ডিফল্টরূপে স্বচ্ছ।
- বটম অফসেট নিষ্ক্রিয় থাকায়, ইনসেট প্রয়োগ না করা হলে কন্টেন্ট সিস্টেম নেভিগেশন বারের পিছনে প্রদর্শিত হয়।
-
setNavigationBarColorএবংR.attr#navigationBarColorঅপ্রচলিত এবং জেসচার নেভিগেশনকে প্রভাবিত করে না। -
setNavigationBarContrastEnforcedএবংR.attr#navigationBarContrastEnforcedজেসচার নেভিগেশনের উপর কোনো প্রভাব ফেলে না।
- ৩-বোতাম নেভিগেশন
- ডিফল্টরূপে অস্বচ্ছতা ৮০% এ সেট করা থাকে এবং এর রঙ উইন্ডোর ব্যাকগ্রাউন্ডের সাথে মিলে যেতে পারে।
- বটম অফসেট নিষ্ক্রিয় করা হয়েছে, তাই ইনসেট প্রয়োগ না করা হলে কন্টেন্ট সিস্টেম নেভিগেশন বারের পিছনে প্রদর্শিত হয়।
- ডিফল্টরূপে
setNavigationBarColorএবংR.attr#navigationBarColorউইন্ডোর ব্যাকগ্রাউন্ডের সাথে মেলানোর জন্য সেট করা থাকে। এই ডিফল্টটি প্রয়োগ হওয়ার জন্য উইন্ডোর ব্যাকগ্রাউন্ড অবশ্যই একটি কালার ড্রয়েবল হতে হবে। এই API-টি এখন আর ব্যবহৃত হয় না, কিন্তু এটি এখনও ৩-বাটন নেভিগেশনকে প্রভাবিত করে। -
setNavigationBarContrastEnforcedএবংR.attr#navigationBarContrastEnforcedডিফল্টরূপে true থাকে, যা ৩-বাটন নেভিগেশন জুড়ে একটি ৮০% অস্বচ্ছ ব্যাকগ্রাউন্ড যোগ করে।
- স্ট্যাটাস বার
- ডিফল্টরূপে স্বচ্ছ।
- টপ অফসেট নিষ্ক্রিয় করা আছে, তাই ইনসেট প্রয়োগ না করা হলে কন্টেন্ট স্ট্যাটাস বারের পিছনে প্রদর্শিত হয়।
-
setStatusBarColorএবংR.attr#statusBarColorঅপ্রচলিত হয়ে গেছে এবং Android 15-এ এগুলোর কোনো প্রভাব নেই। -
setStatusBarContrastEnforcedএবংR.attr#statusBarContrastEnforcedঅপ্রচলিত হলেও Android 15-এ এখনও এগুলোর প্রভাব রয়েছে।
- ডিসপ্লে কাটআউট
- নন-ফ্লোটিং উইন্ডোগুলোর
layoutInDisplayCutoutModeঅবশ্যইLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYSহতে হবে।SHORT_EDGES,NEVER, এবংDEFAULTALWAYSহিসেবে গণ্য করা হয়, যাতে ব্যবহারকারীরা ডিসপ্লে কাটআউটের কারণে সৃষ্ট কালো বার দেখতে না পান এবং উইন্ডোটি প্রান্ত থেকে প্রান্ত পর্যন্ত দেখা যায়।
- নন-ফ্লোটিং উইন্ডোগুলোর
নিম্নলিখিত উদাহরণটি অ্যান্ড্রয়েড ১৫ (এপিআই লেভেল ৩৫) টার্গেট করার আগে ও পরে এবং ইনসেট প্রয়োগ করার আগে ও পরের একটি অ্যাপ দেখাচ্ছে। এই উদাহরণটি সম্পূর্ণ নয়, অ্যান্ড্রয়েড অটোতে এটি ভিন্নভাবে প্রদর্শিত হতে পারে।



আপনার অ্যাপটি ইতিমধ্যে এজ-টু-এজ কিনা তা পরীক্ষা করতে হবে।
আপনার অ্যাপটি যদি ইতিমধ্যেই এজ-টু-এজ হয় এবং ইনসেট প্রয়োগ করে, তবে নিম্নলিখিত পরিস্থিতিগুলো ছাড়া আপনি মূলত অপ্রভাবিত থাকবেন। তবে, আপনি প্রভাবিত হচ্ছেন না বলে মনে করলেও, আমরা আপনাকে আপনার অ্যাপটি পরীক্ষা করার পরামর্শ দিচ্ছি।
- আপনার একটি নন-ফ্লোটিং উইন্ডো আছে, যেমন একটি
ActivityযাLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYSএর পরিবর্তেSHORT_EDGES,NEVERবাDEFAULTব্যবহার করে। যদি আপনার অ্যাপ চালু হওয়ার সময় ক্র্যাশ করে, তবে এর কারণ আপনার স্প্ল্যাশস্ক্রিন হতে পারে। আপনি হয় কোর স্প্ল্যাশস্ক্রিন ডিপেন্ডেন্সিটি 1.2.0-alpha01 বা তার পরবর্তী সংস্করণে আপগ্রেড করতে পারেন অথবাwindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.alwaysসেট করতে পারেন। - কম ব্যবহৃত কিছু স্ক্রিনের UI আড়াল হয়ে থাকতে পারে। যাচাই করুন যে এই কম ব্যবহৃত স্ক্রিনগুলিতে UI আড়াল হয়ে নেই। কম ব্যবহৃত স্ক্রিনগুলির মধ্যে রয়েছে:
- অনবোর্ডিং বা সাইন-ইন স্ক্রিন
- সেটিংস পৃষ্ঠাগুলি
আপনার অ্যাপটি যদি আগে থেকেই এজ-টু-এজ না হয়ে থাকে, তাহলে কী পরীক্ষা করতে হবে।
আপনার অ্যাপটি যদি ইতিমধ্যে এজ-টু-এজ না হয়ে থাকে, তাহলে সম্ভবত আপনি এর দ্বারা প্রভাবিত হবেন। যেসব অ্যাপ ইতিমধ্যে এজ-টু-এজ, সেগুলোর জন্য প্রযোজ্য পরিস্থিতিগুলোর পাশাপাশি আপনার নিম্নলিখিত বিষয়গুলো বিবেচনা করা উচিত:
- আপনার অ্যাপে যদি কম্পোজে Material 3 কম্পোনেন্ট (
androidx.compose.material3) ব্যবহৃত হয়, যেমনTopAppBar,BottomAppBar, এবংNavigationBar, তাহলে এই কম্পোনেন্টগুলো সম্ভবত প্রভাবিত হবে না , কারণ এগুলো স্বয়ংক্রিয়ভাবে ইনসেট পরিচালনা করে। - আপনার অ্যাপ যদি কম্পোজে ম্যাটেরিয়াল ২ কম্পোনেন্ট (
androidx.compose.material) ব্যবহার করে, তবে এই কম্পোনেন্টগুলো স্বয়ংক্রিয়ভাবে ইনসেটগুলো পরিচালনা করে না। তবে, আপনি ইনসেটগুলো অ্যাক্সেস করতে এবং ম্যানুয়ালি প্রয়োগ করতে পারেন। androidx.compose.material 1.6.0 এবং এর পরবর্তী সংস্করণগুলোতে,BottomAppBar,TopAppBar,BottomNavigation, এবংNavigationRailজন্য ইনসেটগুলো ম্যানুয়ালি প্রয়োগ করতেwindowInsetsপ্যারামিটারটি ব্যবহার করুন। একইভাবে,Scaffoldজন্যcontentWindowInsetsপ্যারামিটারটি ব্যবহার করুন। - আপনার অ্যাপে যদি ভিউ এবং ম্যাটেরিয়াল কম্পোনেন্ট (
com.google.android.material) ব্যবহৃত হয়, তাহলেBottomNavigationView,BottomAppBar,NavigationRailViewবাNavigationViewএর মতো বেশিরভাগ ভিউ-ভিত্তিক ম্যাটেরিয়াল কম্পোনেন্ট ইনসেট (inset) পরিচালনা করতে পারে এবং এর জন্য কোনো অতিরিক্ত কাজের প্রয়োজন হয় না। তবে,AppBarLayoutব্যবহার করলে আপনাকেandroid:fitsSystemWindows="true"যোগ করতে হবে। - কাস্টম কম্পোজেবলের জন্য, ইনসেটগুলো প্যাডিং হিসেবে ম্যানুয়ালি প্রয়োগ করুন। যদি আপনার কন্টেন্ট কোনো
Scaffoldমধ্যে থাকে, তাহলে আপনিScaffoldপ্যাডিং ভ্যালু ব্যবহার করে ইনসেটগুলো ব্যবহার করতে পারেন। অন্যথায়,WindowInsets) যেকোনো একটি ব্যবহার করে প্যাডিং প্রয়োগ করুন। - আপনার অ্যাপে যদি ভিউ এবং
BottomSheet,SideSheetবা কাস্টম কন্টেইনার ব্যবহার করা হয়, তাহলেViewCompat.setOnApplyWindowInsetsListenerব্যবহার করে প্যাডিং প্রয়োগ করুন।RecyclerViewএর ক্ষেত্রে, এই লিসেনারটি ব্যবহার করে প্যাডিং প্রয়োগ করুন এবং সাথেclipToPadding="false"যোগ করুন।
আপনার অ্যাপে কাস্টম ব্যাকগ্রাউন্ড সুরক্ষা থাকা আবশ্যক কিনা তা পরীক্ষা করতে হবে।
যদি আপনার অ্যাপকে ৩-বাটন নেভিগেশন বা স্ট্যাটাস বারের জন্য কাস্টম ব্যাকগ্রাউন্ড সুরক্ষা দিতেই হয়, তবে ৩-বাটন নেভিগেশন বারের উচ্চতা পাওয়ার জন্য WindowInsets.Type#tappableElement() অথবা WindowInsets.Type#statusBars ব্যবহার করে সিস্টেম বারের পিছনে একটি কম্পোজেবল বা ভিউ স্থাপন করা উচিত।
অতিরিক্ত প্রান্ত থেকে প্রান্ত পর্যন্ত সম্পদ
ইনসেট প্রয়োগের ক্ষেত্রে অতিরিক্ত বিবেচনার জন্য ‘ এজ টু এজ ভিউ’ এবং ‘এজ টু এজ কম্পোজ’ গাইডগুলো দেখুন।
অপ্রচলিত এপিআই
নিম্নলিখিত API-গুলি অপ্রচলিত কিন্তু নিষ্ক্রিয় করা হয়নি:
-
R.attr#enforceStatusBarContrast -
R.attr#navigationBarColor(৩টি বাটন নেভিগেশনের জন্য, ৮০% আলফা সহ) -
Window#isStatusBarContrastEnforced -
Window#setNavigationBarColor(৩টি বাটন নেভিগেশনের জন্য, ৮০% আলফা সহ) -
Window#setStatusBarContrastEnforced
নিম্নলিখিত API-গুলি অপ্রচলিত এবং নিষ্ক্রিয় করা হয়েছে:
-
R.attr#navigationBarColor(জেসচার নেভিগেশনের জন্য) -
R.attr#navigationBarDividerColor -
R.attr#statusBarColor -
Window#setDecorFitsSystemWindows -
Window#getNavigationBarColor -
Window#getNavigationBarDividerColor -
Window#getStatusBarColor -
Window#setNavigationBarColor(জেসচার নেভিগেশনের জন্য) -
Window#setNavigationBarDividerColor -
Window#setStatusBarColor
稳定配置
如果您的应用以 Android 15(API 级别 35)或更高版本为目标平台,Configuration 不再排除系统栏。如果您在 Configuration 类中使用屏幕尺寸进行布局计算,则应根据需要将其替换为更好的替代方案,例如适当的 ViewGroup、WindowInsets 或 WindowMetricsCalculator。
Configuration 自 API 1 起可用。它通常从 Activity.onConfigurationChanged 获取。它提供窗口密度、屏幕方向和尺寸等信息。从 Configuration 返回的窗口尺寸的一个重要特征是,它之前排除了系统栏。
配置尺寸通常用于资源选择,例如 /res/layout-h500dp,这仍然是一个有效的用例。但是,我们一直不建议将其用于布局计算。如果您这样做,现在应该停止。您应该根据自己的用例,将 Configuration 的使用替换为更合适的内容。
如果您使用它来计算布局,请使用适当的 ViewGroup,例如 CoordinatorLayout 或 ConstraintLayout。如果您使用它来确定系统导航栏的高度,请使用 WindowInsets。如果您想知道应用窗口的当前尺寸,请使用 computeCurrentWindowMetrics。
以下列表介绍了受此更改影响的字段:
Configuration.screenWidthDp和screenHeightDp尺寸不再 排除系统栏。Configuration.smallestScreenWidthDp间接受到screenWidthDp和screenHeightDp更改的影响。Configuration.orientation间接受到接近正方形的设备上screenWidthDp和screenHeightDp更改的影响。Display.getSize(Point)间接受到Configuration更改的影响。此方法已从 API 级别 30 开始被弃用。- 自 API 级别 33 起,
Display.getMetrics()的运作方式已是如此。
elegantTextHeight অ্যাট্রিবিউটের ডিফল্ট মান true থাকে।
অ্যান্ড্রয়েড 15 (API স্তর 35) লক্ষ্য করা অ্যাপগুলির জন্য, elegantTextHeight TextView বৈশিষ্ট্যটি ডিফল্টরূপে true হয়ে যায়, ডিফল্টরূপে ব্যবহৃত কমপ্যাক্ট ফন্টটিকে এমন কিছু স্ক্রিপ্টের সাথে প্রতিস্থাপন করে যেখানে বড় উল্লম্ব মেট্রিক্স রয়েছে যা অনেক বেশি পাঠযোগ্য। বিন্যাস ভাঙা প্রতিরোধ করার জন্য কমপ্যাক্ট ফন্ট চালু করা হয়েছিল; অ্যান্ড্রয়েড 13 (এপিআই লেভেল 33) fallbackLineSpacing অ্যাট্রিবিউট ব্যবহার করে টেক্সট লেআউটকে উল্লম্ব উচ্চতা প্রসারিত করার অনুমতি দিয়ে এই ধরনের অনেক ভাঙন প্রতিরোধ করে।
অ্যান্ড্রয়েড 15-এ, কমপ্যাক্ট ফন্টটি এখনও সিস্টেমে রয়ে গেছে, তাই আপনার অ্যাপটি আগের মতো একই আচরণ পেতে elegantTextHeight false সেট করতে পারে, তবে এটি আসন্ন রিলিজে সমর্থিত হওয়ার সম্ভাবনা কম। সুতরাং, যদি আপনার অ্যাপ নিম্নলিখিত স্ক্রিপ্টগুলিকে সমর্থন করে: আরবি, লাও, মায়ানমার, তামিল, গুজরাটি, কন্নড়, মালয়ালম, ওড়িয়া, তেলুগু বা থাই, তাহলে আপনার অ্যাপটি true elegantTextHeight সেট করে পরীক্ষা করুন।

elegantTextHeight আচরণ। 
elegantTextHeight আচরণ।জটিল অক্ষরের আকারের জন্য TextView-এর প্রস্থ পরিবর্তিত হয়
在以前的 Android 版本中,某些具有复杂形状的手写字体或语言可能会在上一个或下一个字符的区域绘制字母。在某些情况下,此类字母会在开头或结尾处被剪裁。从 Android 15 开始,TextView 会分配宽度,以便为此类字母绘制足够的空间,并允许应用请求向左额外添加内边距以防止剪裁。
由于此更改会影响 TextView 确定宽度的方式,因此如果应用以 Android 15(API 级别 35)或更高版本为目标平台,TextView 会默认分配更多宽度。您可以通过对 TextView 调用 setUseBoundsForWidth API 来启用或停用此行为。
由于添加左内边距可能会导致现有布局未对齐,因此默认情况下不会添加内边距,即使以 Android 15 或更高版本为目标平台的应用也是如此。不过,您可以通过调用 setShiftDrawingOffsetForStartOverhang 添加额外的内边距以防止剪裁。
以下示例展示了这些更改如何改进某些字体和语言的文本布局。
<TextView android:fontFamily="cursive" android:text="java" />
<TextView android:fontFamily="cursive" android:text="java" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
<TextView android:text="คอมพิวเตอร์" />
<TextView android:text="คอมพิวเตอร์" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
EditText-এর জন্য লোকাল-সচেতন ডিফল্ট লাইন উচ্চতা
অ্যান্ড্রয়েডের পূর্ববর্তী সংস্করণগুলিতে, বর্তমান লোকেলের সাথে মেলে ফন্টের লাইনের উচ্চতা মেটাতে পাঠ্য বিন্যাস পাঠ্যের উচ্চতাকে প্রসারিত করে। উদাহরণস্বরূপ, যদি বিষয়বস্তু জাপানি ভাষায় হয়, কারণ জাপানি ফন্টের লাইনের উচ্চতা একটি ল্যাটিন ফন্টের চেয়ে সামান্য বড়, পাঠ্যের উচ্চতা কিছুটা বড় হয়ে গেছে। যাইহোক, লাইনের উচ্চতায় এই পার্থক্য থাকা সত্ত্বেও, EditText উপাদানটি অভিন্ন আকারের ছিল, লোকেল ব্যবহার করা নির্বিশেষে, নিম্নলিখিত ছবিতে চিত্রিত হয়েছে:

EditText উপাদানের প্রতিনিধিত্বকারী তিনটি বাক্স যা ইংরেজি (en), জাপানি (ja), এবং বার্মিজ (my) থেকে পাঠ্য ধারণ করতে পারে। EditText এর উচ্চতা একই, যদিও এই ভাষাগুলির একে অপরের থেকে আলাদা লাইন উচ্চতা রয়েছে। Android 15 (API লেভেল 35) লক্ষ্য করা অ্যাপগুলির জন্য, একটি ন্যূনতম লাইন উচ্চতা এখন EditText এর জন্য নির্দিষ্ট লোকেলের রেফারেন্স ফন্টের সাথে মেলে, যা নিম্নলিখিত ছবিতে দেখানো হয়েছে:

EditText উপাদানের প্রতিনিধিত্বকারী তিনটি বাক্স যা ইংরেজি (en), জাপানি (ja), এবং বার্মিজ (my) থেকে পাঠ্য ধারণ করতে পারে। EditText এর উচ্চতায় এখন এই ভাষার ফন্টগুলির জন্য ডিফল্ট লাইনের উচ্চতা মিটমাট করার জন্য স্থান রয়েছে। প্রয়োজনে, আপনার অ্যাপ useLocalePreferredLineHeightForMinimum অ্যাট্রিবিউটটি false নির্দিষ্ট করে পূর্ববর্তী আচরণ পুনরুদ্ধার করতে পারে এবং আপনার অ্যাপটি Kotlin এবং Java এ setMinimumFontMetrics API ব্যবহার করে কাস্টম ন্যূনতম উল্লম্ব মেট্রিক্স সেট করতে পারে।
ক্যামেরা এবং মিডিয়া
অ্যান্ড্রয়েড ১৫ বা তার উচ্চতর সংস্করণকে লক্ষ্য করে তৈরি অ্যাপগুলোর ক্যামেরা এবং মিডিয়ার আচরণে অ্যান্ড্রয়েড ১৫ নিম্নলিখিত পরিবর্তনগুলো এনেছে।
অডিও ফোকাস অনুরোধ করার উপর বিধিনিষেধ
以 Android 15(API 级别 35)为目标平台的应用必须是顶部应用或正在运行前台服务,才能请求音频焦点。如果应用在未满足上述任一要求的情况下尝试请求焦点,调用将返回 AUDIOFOCUS_REQUEST_FAILED。
如需详细了解音频焦点,请参阅管理音频焦点。
আপডেট করা নন-এসডিকে বিধিনিষেধ
অ্যান্ড্রয়েড ডেভেলপারদের সাথে সহযোগিতা এবং সর্বশেষ অভ্যন্তরীণ পরীক্ষার উপর ভিত্তি করে অ্যান্ড্রয়েড ১৫-এ সীমাবদ্ধ নন-এসডিকে ইন্টারফেসের হালনাগাদ তালিকা অন্তর্ভুক্ত করা হয়েছে। যখনই সম্ভব, আমরা নন-এসডিকে ইন্টারফেস সীমাবদ্ধ করার আগে নিশ্চিত করি যে সেগুলোর পাবলিক বিকল্প উপলব্ধ আছে।
আপনার অ্যাপটি যদি অ্যান্ড্রয়েড ১৫-কে টার্গেট না করে, তবে এই পরিবর্তনগুলোর কিছু হয়তো আপনাকে তাৎক্ষণিকভাবে প্রভাবিত করবে না। তবে, আপনার অ্যাপের টার্গেট এপিআই লেভেলের উপর নির্ভর করে কিছু নন-এসডিকে ইন্টারফেস অ্যাক্সেস করা সম্ভব হলেও, যেকোনো নন-এসডিকে মেথড বা ফিল্ড ব্যবহার করলে আপনার অ্যাপটি ভেঙে যাওয়ার ঝুঁকি সবসময়ই অনেক বেশি থাকে।
আপনার অ্যাপ নন-এসডিকে ইন্টারফেস ব্যবহার করে কিনা, সে বিষয়ে আপনি অনিশ্চিত থাকলে, তা জানার জন্য আপনার অ্যাপটি পরীক্ষা করে দেখতে পারেন। যদি আপনার অ্যাপ নন-এসডিকে ইন্টারফেসের উপর নির্ভরশীল হয়, তবে আপনার এসডিকে বিকল্পগুলিতে স্থানান্তরের পরিকল্পনা শুরু করা উচিত। তা সত্ত্বেও, আমরা বুঝি যে কিছু অ্যাপের ক্ষেত্রে নন-এসডিকে ইন্টারফেস ব্যবহারের যৌক্তিক কারণ থাকে। যদি আপনি আপনার অ্যাপের কোনো ফিচারের জন্য নন-এসডিকে ইন্টারফেস ব্যবহারের কোনো বিকল্প খুঁজে না পান, তবে আপনার একটি নতুন পাবলিক এপিআই-এর জন্য অনুরোধ করা উচিত।
অ্যান্ড্রয়েডের এই প্রকাশের পরিবর্তনগুলি সম্পর্কে আরও জানতে, Android 15-এ নন-SDK ইন্টারফেস সীমাবদ্ধতার আপডেটগুলি দেখুন। সাধারণত নন-SDK ইন্টারফেস সম্পর্কে আরও জানতে, নন-SDK ইন্টারফেসের উপর সীমাবদ্ধতা দেখুন।