tag:blogger.com,1999:blog-67557096430449471792024-03-08T15:05:05.166-08:00Android Developers BlogAn Open Handset Alliance Project.Ian Lakehttp://www.blogger.com/profile/17415160793077313560noreply@blogger.comBlogger1632125tag:blogger.com,1999:blog-6755709643044947179.post-37322927052228567182024-03-08T01:00:00.000-08:002024-03-08T01:00:00.128-08:00Better, faster, stronger time zone updates on Android<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9JvUThxwLTM03JTYkygOtTnzlsM6PwlsfpEHPLOp-LuGv4XwVAR4UUBSgDXazrj482_FDb10KiBARaZJZa36pPnMpitYYl8AABqq8pAPxEVNSQZs1G-hkyBxp25fSll_ZxrNCt1HZioP2kwJX-adozbdZ8dkUoML7KLhJB8bUy1QNI6yE2GzGsqtqQ6A/s1600/social-Better,-faster,-stronger-timezone-updates-on-Android.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9JvUThxwLTM03JTYkygOtTnzlsM6PwlsfpEHPLOp-LuGv4XwVAR4UUBSgDXazrj482_FDb10KiBARaZJZa36pPnMpitYYl8AABqq8pAPxEVNSQZs1G-hkyBxp25fSll_ZxrNCt1HZioP2kwJX-adozbdZ8dkUoML7KLhJB8bUy1QNI6yE2GzGsqtqQ6A/s1600/social-Better,-faster,-stronger-timezone-updates-on-Android.png" style="display: none;" />
<em>Posted by Almaz Mingaleev – Software Engineer and Masha Khokhlova – Technical Program Manager</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu_XZWUxUGTyu6vmO0ul45K8wOtANb_tMiy3yZGUcNrFydI7sAgJ8FneIcrHYqhm8I5MRNpHjIKIy-53GoJi4F4_-shBDcfqP6XQy3w5TC6PL9pNXA2iPV-It4q32PzaN68xmOyQrnbE4BeBp60vubra0PQIX6EB8oCiXsLl53tcsAwyfICzYxqTggZQw/s1600/header-Better,faster,-stronger-timezone-updates-on-Android.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu_XZWUxUGTyu6vmO0ul45K8wOtANb_tMiy3yZGUcNrFydI7sAgJ8FneIcrHYqhm8I5MRNpHjIKIy-53GoJi4F4_-shBDcfqP6XQy3w5TC6PL9pNXA2iPV-It4q32PzaN68xmOyQrnbE4BeBp60vubra0PQIX6EB8oCiXsLl53tcsAwyfICzYxqTggZQw/s1600/header-Better,faster,-stronger-timezone-updates-on-Android.png" /></a>
<p>It's that time of year again when many of us move our clocks! Oh wait, your Android devices did it automatically, didn’t they? For Android users living in many countries, this may not be surprising. For example, the US, EU and UK governments haven't changed their time legislation in a while<sup>*</sup>, so users wake up every morning to see the correct time.</p>
<p>But, what happens when time laws change? If you look globally, governments can and do change their time laws, sometimes every year, and Android devices have to keep up to support our global user base.
</p>
<p>To implement a region’s time legislation, Android devices have to follow a set of encoded rules. What are these rules? Let’s start with why rules are needed in the first place. Clearly, 7am in Los Angeles and 7am in London are not the same time. Moreover, if you are in London and want to know the time in Los Angeles, you have to know how many hours to subtract, and this is not fixed throughout the year<sup>**</sup>. So to tell local time (time your watches should show) it is convenient to have a reference clock that everybody on the planet agrees on. This clock is named <a href="https://en.wikipedia.org/wiki/Coordinated_Universal_Timehttps://en.wikipedia.org/wiki/Coordinated_Universal_Time" target="_blank">UTC</a>, coordinated universal time. Local time in London during winter matches UTC, during summer it is calculated by adding one hour to UTC, usually referred to as UTC+1. For Los Angeles local time during summer is UTC-8 (8 hours behind, UTC offset is -8 hours) and during winter it is UTC-7 correspondingly. When a region changes from one offset to another, we call that a “transition”. Combination of these offsets and rules when a transition happens (such as “last Sunday of March” or “first Sunday on or after 8th March”) defines a time zone. For some countries, the time zone rules can be very simple and primarily determined by their chosen UTC offset: “no transitions, we don’t move our clocks forwards and backwards”.</p>
<p>Governments can decide to change the UTC offset for regions, introduce new time zone regions, or alter the day that daylight saving transitions occur. When governments do this, the time zone rules on every Android device needs to be updated, otherwise the Android device will continue to follow the old rules, which can lead to an incorrect local time being shown to users in the affected areas.</p>
<p>Android is not alone in needing to keep track of this information. Fortunately, there is a database supported by IANA (<a href="https://www.iana.org/time-zones" target="_blank">Internet Assigned Numbers Authority</a>) and maintained by a small group of volunteers known as the TZDB (Time Zone Database) which is used as a basis for local timekeeping on most modern operating systems. The TZDB contains most of the information that Android needs.</p>
<p>There is no schedule, but typically the TZDB releases a new update 4-5 times a year. The Android team wants to release updates that affect its devices as soon as possible.</p>
<p>How do these changes reach your devices?</p>
<ul>
<div style="text-align: left;">1.<span> </span>Government signs a law / decree.</div><div style="text-align: left;"><br /></div>
<div style="text-align: left;">2.<span> </span>Someone lets IANA know about these changes</div><div style="text-align: left;"><br /></div>
<div style="text-align: left;">3.<span> </span>Depending on how much lead time was given and changes announced by other countries IANA publishes a new TZDB release.</div><div style="text-align: left;"><br /></div>
<div style="text-align: left;">4.<span> </span>The Android team incorporates the TZDB release (along with a small amount additional information we obtain from related projects and derive ourselves) into our codebase.</div><div style="text-align: left;"><br /></div>
<div style="text-align: left;">5.<span> </span>We roll-out these updates to your devices. How the roll-out happens depends on the type and age of the Android device.</div><div style="text-align: left;"><br /></div>
<ul><ul><div>a.<span> </span>Many mobile Android devices are covered by Google’s Project <a href="https://source.android.com/docs/core/ota/modular-system" target="_blank">Mainline</a>, which means that Google sends updates to devices directly.</div><div><br /></div></ul></ul>
<ul><ul><div>b.<span> </span>Some devices are handled by the device’s manufacturer who takes the Android team’s source code updates and releases them to devices themselves according to their own update schedule.</div></ul></ul></ul>
<p>As you can see, there are quite a few steps. Applying, testing and releasing an update can take weeks. And it is not just Android and other computer operating systems like it who need to take action. There are usually telecoms, banks, airlines and software companies that have to make adjustments to their own systems and time tables. Citizens of a country need to be made aware of changes so they know what to expect, especially if they are using older devices that might not receive necessary updates. And it all takes time and can cause problems for countless people if it isn’t handled well. The amount of disruption caused by a change is usually determined by the clarity of the legislation and notice period that governments provide. The TZDB volunteers are good at spotting changes, but it helps if the governments notify IANA directly, especially when it’s not clear the exact regions or existing laws affected. Unfortunately, many of the recent time zone changes were given with about a month or less notice time. Android has a set of <a href="https://source.android.com/docs/core/connect/time/time-zone-policy-recommendations" target="_blank">recommendations</a> for how much notice to provide. Other operating systems have similar recommendations.</p>
<p>Android is constantly evolving. One of such improvements, Project Mainline, <a href="https://android-developers.googleblog.com/2019/05/fresher-os-with-projects-treble-and-mainline.html" target="_blank">introduced</a> in Android 10, has made a big difference in how we update important parts of the Android operating system. It allows us to deliver select AOSP components directly through Google Play, making updates faster than a full OTA update and reducing duplication of efforts done by each OEM.</p>
<p>From the beginning, time zone rules were a component in Mainline, called <a href="https://source.android.com/docs/core/ota/modular-system/timezone" target="_blank">Time Zone Data or tzdata module</a>. This integration allowed us to react more quickly to government-mandated time zone changes than before. However until 2023 tzdata updates were still bundled with other Mainline changes, sometimes leading to testing complexities and slower deployment.</p>
<p>In 2023, we made further investments in Mainline's infrastructure and decoupled the tzdata module from the other components. With this isolation, we gained the ability to respond rapidly to time zone legislation changes — often releasing updates to Android users outside of the established release cadence. Additionally, this change means time zone updates can reach a far greater number of Android devices, ensuring you as Android users always see the correct time.</p>
<p>So while your Android phone may not be able to restore that lost hour of sleep, you can rest assured that it will show the accurate time, thanks to volunteers and the Android team.</p>
<p>Curious about the ever-changing world of time zones? Explore the <a href="https://data.iana.org/time-zones/tz-link.html" target="_blank">IANA Time Zone Database</a> and learn more about how <a href="https://source.android.com/docs/core/connect/time" target="_blank">time and time zones are managed</a> on Android.</p><br />
<p><small><em><sup>*</sup>In 2018-2019 there were changes in Alaska. This is a blogpost, not a technical documentation!</em></small></p>
<p><small><em><sup>**</sup>Because the US and UK apply their daylight saving changes at different local times and on different days of the year.</em></small></p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-63478232187311920122024-03-07T14:00:00.000-08:002024-03-07T14:00:00.236-08:00Introducing the Fused Orientation Provider API: Consistent device orientation for all<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivlmOIXvZ0LXZ7s7UJSt2VDp1CTLp0uzvJE-6x3OFM7RD56fK17QakAcXpCpPYwf7uGvps_vafNFohnc4Lo0XQXmzNY7XpiEyhltnMz6mR3cgg8EjZmSBv-rYiPaw3AxwbpCY5SsVD7_G1kzo6ZxZVq6dtszshGnp1Bd1X-EmWDg5Wy1NYPrKd7p7tN6I/s1600/social-Introducing-the-Fused-Orientation-Provider-API--Consistent-device-orientation-for-all-.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivlmOIXvZ0LXZ7s7UJSt2VDp1CTLp0uzvJE-6x3OFM7RD56fK17QakAcXpCpPYwf7uGvps_vafNFohnc4Lo0XQXmzNY7XpiEyhltnMz6mR3cgg8EjZmSBv-rYiPaw3AxwbpCY5SsVD7_G1kzo6ZxZVq6dtszshGnp1Bd1X-EmWDg5Wy1NYPrKd7p7tN6I/s1600/social-Introducing-the-Fused-Orientation-Provider-API--Consistent-device-orientation-for-all-.png" style="display: none;" />
<em>Posted by Geoffrey Boullanger – Senior Software Engineer, Shandor Dektor – Sensors Algorithms Engineer, Martin Frassl and Benjamin Joseph – Technical Leads and Managers</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp8dFtNlqMsgK3ffDx0qB8ZflPr8veMx-8cyMDDW7rk453Sn7KLo-j63a5s22_hgKl5K9lnhFnxq1YVMYg7TFaLy7-WsobcOlAvoy3mtFpn34H-GuurME8i_A-HS4gNgjzcb1BeGcMyBO0UXeoG5m8ahfWjwv07qSoWsG3sdt-Fw2mXbv7ZHGXtWuzNEc/s1600/header-Introducing-the-Fused-Orientation-Provider-API--Consistent-device-orientation-for-all-.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp8dFtNlqMsgK3ffDx0qB8ZflPr8veMx-8cyMDDW7rk453Sn7KLo-j63a5s22_hgKl5K9lnhFnxq1YVMYg7TFaLy7-WsobcOlAvoy3mtFpn34H-GuurME8i_A-HS4gNgjzcb1BeGcMyBO0UXeoG5m8ahfWjwv07qSoWsG3sdt-Fw2mXbv7ZHGXtWuzNEc/s1600/header-Introducing-the-Fused-Orientation-Provider-API--Consistent-device-orientation-for-all-.png" /></a>
<p>Device orientation, or attitude, is used as an input signal for many use cases: virtual or augmented reality, gesture detection, or compass and navigation – any time the app needs the orientation of a device in relation to its surroundings. We’ve heard from developers that orientation is challenging to get right, with frequent user complaints when orientation is incorrect. A maps app should show the correct direction to walk towards when a user is navigating to an exciting restaurant in a foreign city!</p>
<p>The Fused Orientation Provider (FOP) is a new API in Google Play services that provides quality and consistent device orientation by fusing signals from accelerometer, gyroscope and magnetometer.</p>
<p>Although currently the Android Rotation Vector already provides device orientation (and will continue to do so), the new FOP provides more consistent behavior and high performance across devices. We designed the FOP API to be similar to the Rotation Vector to make the transition as easy as possible for developers.</p>
<p>In particular, the Fused Orientation Provider</p>
<ul style="text-align: left;"><ul>
<li>Provides a unified implementation across devices: an API in Google Play services means that there is no implementation variance across different manufacturers. Algorithm updates can be rolled out quickly and independent of Android platform updates;</li></ul></ul><ul style="text-align: left;"><ul>
<li>Directly incorporates local magnetic declination, if available;</li></ul></ul><ul style="text-align: left;"><ul>
<li>Compensates for lower quality sensors and OEM implementations (e.g., gyro bias, sensor timing).</li>
</ul></ul>
<p>In certain cases, the FOP returns values piped through from the AOSP Rotation Vector, adapted to incorporate magnetic declination.</p>
<h3>How to use the FOP API</h3>
<p>Device orientation updates can be requested by creating and sending a DeviceOrientationRequest object, which defines some specifics of the request like the update period.</p>
<p>The FOP then outputs a stream of the device’s orientation estimates as quaternions. The orientation is referenced to <b>geographic</b> north. In cases where the local magnetic declination is not known (e.g., location is not available), the orientation will be relative to <b>magnetic</b> north.</p>
<p>In addition, the FOP provides the device’s heading and accuracy, which are derived from the orientation estimate. This is the same heading that is shown in Google Maps, which uses the FOP as well. We recently added changes to better cope with magnetic disturbances, to improve the reliability of the cone for Google Maps and FOP clients.</p>
<p>The update rate can be set by requesting a specific update period. The FOP does not guarantee a minimum or maximum update rate. For example, the update rate can be faster than requested if another app has a faster parallel request, or it can be slower as requested if the device doesn’t support the high rate.</p>
<p>For full specification of the API, please consult the API documentation:</p>
<ul><ul>
<li>Register for updates: <a href="https://developers.google.com/android/reference/com/google/android/gms/location/FusedOrientationProviderClient#public-abstract-taskvoid-requestorientationupdates-deviceorientationrequest-request,-executor-executor,-deviceorientationlistener-listener" target="_blank"><span style="font-family: courier;">requestOrientationUpdates(...)</span></a> </li>
<li>Data is returned as <a href="https://developers.google.com/android/reference/com/google/android/gms/location/DeviceOrientation" target="_blank"><span style="font-family: courier;">DeviceOrientation</span></a> </li>
</ul></ul>
<h3>Example usage (Kotlin)</h3>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="font-family: courier;"><span style="color: green; font-weight: bold;">package</span> <span style="color: blue; font-weight: bold;">...</span>
import android.content.Context
import com.google.android.gms.location.DeviceOrientation
import com.google.android.gms.location.DeviceOrientationListener
import com.google.android.gms.location.DeviceOrientationRequest
import com.google.android.gms.location.FusedOrientationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.common.flogger.FluentLogger
import java.util.concurrent.Executors
<span style="color: green; font-weight: bold;">class</span> <span style="color: blue;">Example</span>(context: Context) {
<span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">val</span> logger: FluentLogger = FluentLogger.forEnclosingClass()
<span style="color: #408080; font-style: italic;">// Get the FOP API client</span>
<span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">val</span> fusedOrientationProviderClient: FusedOrientationProviderClient =
LocationServices.getFusedOrientationProviderClient(context)
<span style="color: #408080; font-style: italic;">// Create an FOP listener</span>
<span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">val</span> listener: DeviceOrientationListener =
DeviceOrientationListener { orientation: DeviceOrientation ->
<span style="color: #408080; font-style: italic;">// Use the orientation object returned by the FOP, e.g.</span>
logger.atFinest().log(<span style="color: #ba2121;">"Device Orientation: %s deg"</span>, orientation.headingDegrees)
}
<span style="color: green; font-weight: bold;">fun</span> <span style="color: blue;">start</span>() {
<span style="color: #408080; font-style: italic;">// Create an FOP request</span>
<span style="color: green; font-weight: bold;">val</span> request =
DeviceOrientationRequest.Builder(DeviceOrientationRequest.OUTPUT_PERIOD_DEFAULT).build()
<span style="color: #408080; font-style: italic;">// Create (or re-use) an Executor or Looper, e.g.</span>
<span style="color: green; font-weight: bold;">val</span> executor = Executors.newSingleThreadExecutor()
<span style="color: #408080; font-style: italic;">// Register the request and listener</span>
fusedOrientationProviderClient
.requestOrientationUpdates(request, executor, listener)
.addOnSuccessListener { logger.atInfo().log(<span style="color: #ba2121;">"FOP: Registration Success"</span>) }
.addOnFailureListener { e: Exception? ->
logger.atSevere().withCause(e).log(<span style="color: #ba2121;">"FOP: Registration Failure"</span>)
}
}
<span style="color: green; font-weight: bold;">fun</span> <span style="color: blue;">stop</span>() {
<span style="color: #408080; font-style: italic;">// Unregister the listener</span>
fusedOrientationProviderClient.removeOrientationUpdates(listener)
}
}</span>
</pre></div>
<h3>Technical background</h3>
<p>The Android ecosystem has a wide variety of system implementations for sensors. Devices should meet the criteria in the <a href="https://source.android.com/docs/compatibility/cdd" target="_blank">Android compatibility definition document (CDD)</a> and must have an accelerometer, gyroscope, and magnetometer available to use the fused orientation provider. It is preferable that the device vendor implements the high fidelity sensor portion of the CDD.</p>
<p>Even though Android devices adhere to the Android CDD, recommended sensor specifications are not tight enough to fully prevent orientation inaccuracies. Examples of this include magnetometer interference from internal sources, and delayed, inaccurate or nonuniform sensor sampling. Furthermore, the environment around the device usually includes materials that distort the geomagnetic field, and user behavior can vary widely. To deal with this, the FOP performs a number of tasks in order to provide a robust and accurate orientation:</p>
<ol><ul>
<li>Synchronize sensors running on different clocks and delays;</li>
<li>Compensate for the hard iron offset (magnetometer bias);</li>
<li>Fuse accelerometer, gyroscope, and magnetometer measurements to determine the orientation of the device in the world;</li>
<li>Compensate for gyro drift (gyro bias) while moving;</li>
<li>Produce a realistic estimate of the compass heading accuracy.</li>
</ul></ol>
<p>We have validated our algorithms on comprehensive test data to provide a high quality result on a wide variety of devices.</p>
<h3>Availability and limitations</h3>
<p>The Fused Orientation Provider is available on all devices running Google Play services on Android 5 (Lollipop) and above. Developers need to add the dependency <span style="color: #0d904f; font-family: Courier;">play-services-location:21.2.0</span> (or above) to access the new API.</p>
<p><b>Permissions</b></p>
<p>No permissions are required to use the FOP API. The output rate is limited to 200Hz on devices running API level 31 (Android S) or higher, unless the <span style="color: #0d904f; font-family: Courier;">android.permissions.HIGH_SAMPLING_RATE_SENSORS</span> permission was added to your Manifest.xml.</p>
<p><b>Power consideration</b></p>
<p>Always request the longest update period (lowest frequency) that is sufficient for your use case. While more frequent FOP updates can be required for high precision tasks (for example Augmented Reality), it comes with a power cost. If you do not know which update period to use, we recommend starting with <span style="color: #0d904f; font-family: Courier;">DeviceOrientationRequest::OUTPUT_PERIOD_DEFAULT</span> as it fits most client needs.</p>
<p><b>Foreground behavior</b></p>
<p>FOP updates are only available to apps running in the foreground.</p><br />
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;">Copyright <span style="color: #666666;">2023</span> Google LLC<span style="color: #666666;">.</span>
SPDX<span style="color: #666666;">-</span>License<span style="color: #666666;">-</span>Identifier<span style="color: #666666;">:</span> Apache<span style="color: #666666;">-2.0</span>
</pre></div>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-55904471988359365272024-03-07T10:00:00.000-08:002024-03-07T12:52:38.965-08:00#TheAndroidShow: the latest from MWC, Gemini Nano, Android 15 and more! <meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzCfvtscYp-s6T4XFATx4pLgXixHBYITpSFBtZOFlWhbMT-x_Qf8EN_rGmlp_2Da68eufEQGt5yiRDFbq3YovBKZqVRS70Q9KegA1TzDJPAFwWdlcKIxQJPR6fxL0Hx3SPN6oqnVrZEq_WlMFqXBcp2khwgtvo7spv2y-9WhF38fBrwan4PPorToZ-W4g/s1600/Image_20240306_143230.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzCfvtscYp-s6T4XFATx4pLgXixHBYITpSFBtZOFlWhbMT-x_Qf8EN_rGmlp_2Da68eufEQGt5yiRDFbq3YovBKZqVRS70Q9KegA1TzDJPAFwWdlcKIxQJPR6fxL0Hx3SPN6oqnVrZEq_WlMFqXBcp2khwgtvo7spv2y-9WhF38fBrwan4PPorToZ-W4g/s1600/Image_20240306_143230.png" style="display: none;" />
<em>Posted by Anirudh Dewani, Director of Android Developer Relations</em>
<p><br /></p><p>Last week, Android device makers released a slew of new devices, and today we’re unpacking what that means for developers, as well as the latest in Gemini Nano, Android 15, Jetpack Compose and more, in another episode of our quarterly show, <a href="https://d.android.com/events/show" target="_blank">#TheAndroidShow</a>:</p>
<iframe allowfullscreen="" class="BLOG_video_class" height="415" src="https://www.youtube.com/embed/pou4o1X1DI4" width="100%" youtube-src-id="pou4o1X1DI4"></iframe>
<h2>The lastest wearables and foldables – get building!</h2>
<p>Android device makers unveiled their latest wearables and foldables last week at Mobile World Congress, and we were on the ground in Barcelona taking a look at those new devices and how you can get started building on top of them. A few of our favorites:</p>
<ul style="text-align: left;"><ul>
<li><b>OnePlus Watch 2</b>, powered with the latest version of Wear OS (<a href="https://android-developers.googleblog.com/2023/10/wear-os-4-is-now-stable-and-available-on-google-pixel-watch-2.html" target="_blank">Wear OS 4</a>). This device capitalizes on the updates we’ve made to the <a href="https://wearos.google.com/" target="_blank">Wear OS by Google</a> user experience, specifically improving power and performance, <a href="https://android-developers.googleblog.com/2024/02/wear-os-hybrid-interface-boosting-power-and-performance.html" target="_blank">you can read more here.</a></li></ul></ul>
<ul style="text-align: left;"><ul><li><b>Xiaomi Watch 2</b>,the <a href="https://www.mi.com/global/product/xiaomi-watch-2/" target="_blank">latest smart watch</a> from the Xiaomi team. This device is powered by Wear OS by Google and provides upgraded camera, fitness, and sleep experiences to allow users to get the most from their device.</li></ul></ul>
<ul style="text-align: left;"><ul><li><b>PORSCHE DESIGN HONOR Magic V2 RSR</b>, the world’s <a href="https://www.hihonor.com/global/phones/honor-magic-v2-rsr-porsche-design/" target="_blank">thinnest inward foldable smartphone</a>. This is the latest foldable for Android and was designed with the user experience at the forefront, including human-centric eye comfort technology.</li>
</ul></ul>
<p>Compose is an amazing way to build apps for your users across form factors. <a href="https://developer.android.com/training/wearables/compose" target="_blank">Compose for Wear OS</a> and the upcoming <a href="https://medium.com/androiddevelopers/new-apis-for-adaptive-layouts-in-jetpack-compose-f27cace48bcd" target="_blank">adaptive layouts</a> for large screens help devs bring their apps to life with less code, powerful tools, and intuitive APIs. Check out the <a href="https://d.android.com/wear/gallery" target="_blank">Wear OS</a> and <a href="https://developer.android.com/large-screens/gallery" target="_blank">Large Screen galleries</a>, where you can find UX inspiration and design guidance tailored to your type of app.</p><br />
<iframe allowfullscreen="" class="BLOG_video_class" height="415" src="https://www.youtube.com/embed/BcGfpspxX2E" width="100%" youtube-src-id="BcGfpspxX2E"></iframe><br />
<p><br /></p>
<h2 style="text-align: left;"><span style="font-size: x-large;">Behind the scenes, with Gemini Nano and AICore</span></h2>
<p>With all of the excitement around generative AI, it could be daunting to know where to start. So in today’s show, we’re taking you behind the scenes with <a href="https://android-developers.googleblog.com/2023/12/a-new-foundation-for-ai-on-android.html" target="_blank">Gemini Nano</a>, Google’s most efficient model built for on-device tasks, and <a href="http://d.android.com/ml/aicore" target="_blank">AICore</a>, Android’s system service for on-device foundation models. And we’re spotlighting how the team that builds the Recorder app used Gemini Nano to help summarize users’ voice memos on-device and with privacy in mind. And here’s the best part: the team built the feature in a short time with only a small number of engineers.</p><br />
<iframe allowfullscreen="" class="BLOG_video_class" height="415" src="https://www.youtube.com/embed/hHIMUgTuoXE" width="100%" youtube-src-id="hHIMUgTuoXE"></iframe><br />
<p><br /></p>
<h2 style="text-align: left;"><span style="font-size: x-large;">Now in Android</span></h2>
<p>We celebrated the 100th episode of Now in Android, covering the latest developer news, including:</p>
<ul style="text-align: left;"><ul>
<li><a href="http://android-developers.googleblog.com/2024/02/first-developer-preview-android15.html" target="_blank"><b>The Android 15 developer preview</b></a>, which includes updates to <a href="https://developer.android.com/design-for-safety/privacy-sandbox" target="_blank">Privacy Sandbox</a> and <a href="https://developer.android.com/health-and-fitness/guides/health-connect" target="_blank">Health Connect</a>, <a href="https://developer.android.com/reference/android/security/FileIntegrityManager" target="_blank">new file integrity protection APIs</a>, <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics" target="_blank">enhanced camera controls</a>, <a href="https://developer.android.com/reference/android/media/midi/MidiUmpDeviceService" target="_blank">virtual MIDI 2.0 devices</a>, an expanded <a href="https://developer.android.com/games/optimize/adpf" target="_blank">Android Dynamic Performance Framework</a>, and more.</li></ul></ul><ul style="text-align: left;"><ul>
<li><a href="http://android-developers.googleblog.com/2024/02/android-studio-iguana-is-stable.html" target="_blank"><b>Android Studio Iguana</b></a>🦎which is now in stable and includes <a href="https://developer.android.com/studio/releases#compose-ui-check" target="_blank">Compose UI Check</a>, <a href="https://developer.android.com/studio/releases#compose-progressive-rendering" target="_blank">Progressive rendering in Compose Previews</a>, <a href="https://developer.android.com/studio/releases#aqi-vcs" target="_blank">Version Control System support in App Quality Insights</a>, <a href="https://developer.android.com/studio/releases#baseline-profiles-module-wizard" target="_blank">built-in support to create Baseline Profiles</a>, the <a href="https://developer.android.com/studio/releases#espresso-device-api" target="_blank">Espresso device API</a>, and more.</li></ul></ul><ul style="text-align: left;"><ul><li><b><a href="http://android-developers.googleblog.com/2024/02/cloud-photos-now-available-in-android-photo-picker.html" target="_blank">Cloud photos</a></b>, now available in the Android photo picker.</li></ul></ul><ul style="text-align: left;"><ul><li><b><a href="https://developers.google.com/ml-kit/vision/doc-scanner" target="_blank">ML Kit Document Scanner API</a></b>, enabling you to easily integrate advanced document scanning capabilities in your apps.</li></ul></ul><ul style="text-align: left;"><ul><li><a href="http://android-developers.googleblog.com/2024/02/wear-os-hybrid-interface-boosting-power-and-performance.html" target="_blank">Wear OS Hybrid Interface</a>, <a href="https://medium.com/androiddevelopers/jetpack-compose-strong-skipping-mode-explained-cbdb2aa4b900?source=rss----95b274b437c2---4" target="_blank">Scrolling/Skipping/Shapes</a> in Compose, <a href="https://adbackstage.libsyn.com/episode-204-fanotations" target="_blank">Lint</a>, and more!</li>
</ul></ul><br />
<iframe allowfullscreen="" class="BLOG_video_class" height="415" src="https://www.youtube.com/embed/tiNXsmbcKgA" width="100%" youtube-src-id="tiNXsmbcKgA"></iframe><br />
<p><br /></p>
<p>And that’s a wrap on another episode of our quarterly show, #TheAndroidShow. But the conversation continues on YouTube, X and LinkedIn: tell us your favorite part, or what you’d like us to dive into next time on our quarterly episode. And before we sign off, you can watch the full playlist, with the latest in Android developer news, <a href="https://youtu.be/pou4o1X1DI4?list=PLWz5rJ2EKKc_sAwvxL-DjrIMOKT9NOh30" target="_blank">here</a>. </p>Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-3434848949545910772024-03-06T09:30:00.000-08:002024-03-06T09:39:27.838-08:00Designing your account deletion experience with users in mind<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhljLTe4e3m2lCTVHZukvwtt3N5A34tfp3uQ9kITH8m5EM-9FI-7752LR4HofGCVBUzc9aaTXmUEC_xrKJnNW1R4pzx9YCZMFxWDxF64PWv8Zg6Yai3XKNlDvRv_PjR8QE8gikqfChslevvcNF8SzPET1WNH-_thMq-svIuGSTQ5t_KrFoE-SUWok28Xhc/s1600/social-Account-Deletion-Case-Study-Blog.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhljLTe4e3m2lCTVHZukvwtt3N5A34tfp3uQ9kITH8m5EM-9FI-7752LR4HofGCVBUzc9aaTXmUEC_xrKJnNW1R4pzx9YCZMFxWDxF64PWv8Zg6Yai3XKNlDvRv_PjR8QE8gikqfChslevvcNF8SzPET1WNH-_thMq-svIuGSTQ5t_KrFoE-SUWok28Xhc/s1600/social-Account-Deletion-Case-Study-Blog.png" style="display: none;" />
<em>Posted by Tatiana van Maaren – Global T&S Partnerships Lead, Privacy & Security, May Smith - Product Manager, and Anita Issagholyan – Policy Lead</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg50WdOqNNKoMWD6WVzyUPnglOMkEDYqfzeToYuq8rKeYkm3AiqvYYgBC_gZbSKLImlxK8qyvp8tr5mMeK5Cfih1k6_uSTOmwXAczn8YkKzHWhAF8SVbkiv2m45JVHG2rDzIinPrGoyV7ujVT9Gze4sde0wVa_2-B8TvdCzPs3RRjKL5anNqxgJxRF5BcY/s1600/Play-Account-Deletion-Case-Study-Blog.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg50WdOqNNKoMWD6WVzyUPnglOMkEDYqfzeToYuq8rKeYkm3AiqvYYgBC_gZbSKLImlxK8qyvp8tr5mMeK5Cfih1k6_uSTOmwXAczn8YkKzHWhAF8SVbkiv2m45JVHG2rDzIinPrGoyV7ujVT9Gze4sde0wVa_2-B8TvdCzPs3RRjKL5anNqxgJxRF5BcY/s1600/Play-Account-Deletion-Case-Study-Blog.png" /></a>
<p>With millions of developers relying on our platform, Google Play is committed to keeping our ecosystem safe for everyone. That’s why, in addition to our ongoing investments in app privacy and security, we also continuously update our policies to respond to new challenges and user expectations.</p>
<p>For example, we recently introduced a <a href="https://android-developers.googleblog.com/2023/04/giving-people-more-control-over-their-data.html" target="_blank">new account deletion policy</a> with required disclosures within the Data Safety section on the Play Store. Deleting an account should be as easy as creating one, so the new policy requires developers to provide information and web resources that help users to manage their data and understand an app's deletion practices. </p>
<p>To help you build trust and design a user-friendly experience that helps meet our policy requirements, consider these <b>5 best practices</b> when implementing your account deletion solution.</p>
<h3>1. Make it seamless</h3>
<p>Users prefer a simple and straightforward account deletion flow. Although users know that more steps may follow (such as authentication) navigating multiple screens before the deletion page can be a significant barrier and create negative feelings for the user. Consider providing your account deletion option on an account settings page or place a prominent button on the home screen. Design the flow with discoverability in mind by taking the user directly to the deletion process.</p>
<h3>2. Allow automatic deletion</h3>
<p>Users feel that if they can create an account without talking to a customer service agent, they should be able to delete their account online, too. If automation is not on your roadmap just yet, consider a step-by-step deletion request form or a dedicated page to connect users with customer support.</p>
<h3>3. Offer guidance and explain potential implications</h3>
<p>Users delete their accounts for various reasons, some of which may be better resolved another way. Early in your deletion flow, point your users toward a Help Center article that explains how your deletion process works in simple terms, including any potential consequences. For example, make it clear if your users will need to pause their payment method before deleting the account, or download any account data they want to keep. Helping your users understand the process in advance can prevent accidental deletions. For those who do change their minds, consider offering a way to recover their accounts within a reasonable timeframe. </p>
<p>Here’s an example of how Play Store Developer, Canva, has designed the in-app deletion flow to explain potential consequences of account deletion:</p>
<image><div style="text-align: center;"><img alt="user journey on the Canva app in three panels" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSmgP5HlDbudibZxpVZwLrzDcBnt2rg_ITmTLc2t_OFMIDPyLBzQJxeBfmyyp_nk1OL0Yd-pkQKiPFUqH0WyUbcDloblVhUOv6HcW-I0iNeTOghSLQjcQnVyqEFBEpXjqT5zDcIJUFnrcAEyh_-8Y2HxwW3sRCsP4glQPy03pBG40xhwC6G9qOClzmugk/s1600/Account-Deletion-Google-Play-inline%20%281%29.png" width="100%" /></div><imgcaption><center><em>User journey on the Canva app </em></center></imgcaption></image>
<blockquote><span style="font-size: large;"><i>“User data privacy has always been important for us. We’ve always been intentional about our approach in optimizing the Canva app so our users can have more transparency and control over their data. We’re welcoming these new requirements from the Play store as we know this new flow will elevate users’ trust in our app and benefit our business in the long term.” </i></span><b>- Will Currie, Software Engineer, Canva</b></blockquote>
<h3>4. Confirm account deletion </h3>
<p>Sometimes users misunderstand whether the account itself or just data collected by the app was deleted in the deletion process. Users often think that the data your app stored in the cloud will automatically be deleted at the same time as account deletion. Since it may take time to remove account data from internal company systems or comply with data retention requirements in different regions, transparency about the process can help you maintain trust in your brand and make it more likely for users to return in the future.</p>
<p>Here’s SYBO Games, has designed their web deletion in-app deletion flow:</p>
<image><div style="text-align: center;"><img alt="user journey on the Sybo Games web resource in four panels" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi59KSA_oGI24P30Um9abe7fLhiYoTWKn5q8oJ2lDsKScf30Jq6GyC_ZAWCfCAYfwiGRD4jdN4n5KCCXFH7L-zdCY7efdN96HhsuTmOFvQNUw5l75QoLBa43i_LPo5ph1-W64y3fTSKRXFMLIy8TeFWa-pY-qjpX-0j9Tg0mroJcxc56ZFAmRjH06kvKCE/s1600/Account-Deletion-Google-Play-inline-2.png" width="100%" /></div><imgcaption><center><em>User journey on the SYBO Games web resource
</em></center></imgcaption></image>
<blockquote><span style="font-size: large;"><i>“We are always striving to ensure that our games provide a fun user experience, built on a solid data protection foundation. When we learned about the new account deletion update on Google Play, we thought this was a great step forward to ensure that the entire developer ecosystem optimizes for user safety. We encourage developers to carve out time to embrace these improvements and prioritize regular privacy check-ins.” </i></span><b>- Elizabeth Ann Schweitzer, Games Compliance Manager, SYBO Games</b></blockquote>
<h3>5. Don’t forget user engagement</h3>
<p>This is a great opportunity to connect with your users at a critical moment. Make sure users who have uninstalled your app can easily remove their accounts through a web resource without needing to reinstall the app. You can also invite them to complete a survey or provide feedback on their decision.</p>
<p>Protecting users' data is essential for building trust and loyalty. By updating the Data Safety section on Google Play and continuing to optimize user experience for account deletion, you can strengthen trust in your company while striving for the highest level of user data protection.</p><br />
<p>Thank you for your continued collaboration and feedback in developing this data transparency feature and in helping make Google Play safe for all.</p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-84035581321299341682024-03-05T09:00:00.000-08:002024-03-06T19:04:58.709-08:00Introducing a new Text-To-Speech engine on Wear OS <meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz59FlzcTBW59NOVhyLb_vZd-ePuN6w-TMUiMvxaZDiofpQHayKQn8sPLmP-bmuj5-6kPS7wHUOTqpzOTwoRqBRO1zdnLE3EuqPaH97Cw0ezGgLFKIbX0dzXfI4xx0bPa8XLl6FyvhYKs3XKBowHEz2ambpEB1H5UypEtPrn-dXMXkGlJEKu7NdjMV/s1600/Android%20-%20Policy%20Updates-%20Improving%20Wear%20App%20Quality-social.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz59FlzcTBW59NOVhyLb_vZd-ePuN6w-TMUiMvxaZDiofpQHayKQn8sPLmP-bmuj5-6kPS7wHUOTqpzOTwoRqBRO1zdnLE3EuqPaH97Cw0ezGgLFKIbX0dzXfI4xx0bPa8XLl6FyvhYKs3XKBowHEz2ambpEB1H5UypEtPrn-dXMXkGlJEKu7NdjMV/s1600/Android%20-%20Policy%20Updates-%20Improving%20Wear%20App%20Quality-social.png" style="display: none;" />
<em>Posted by Ouiam Koubaa – Product Manager and Yingzhe Li – Software Engineer</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVviCwvyzix33x3GBKtuFuXHOivMjeQP5FrEX8df4khO7Y6KSKwdAqBIRmac1eN5T9EIMbwATiUxqjjnOoMZow-T458ZZadL0fpwy901_pNLayQ-wLUAm8w0W2OyNZk_6KAYPwHOLqKcu9bLnpoc8K-3RIQvNeRV11iSzBSL2U20bRnb89EXghEHBs/s1600/Android%20-%20Policy%20Updates-%20Improving%20Wear%20App%20Quality-header.png"><img border="0" data-original-height="800" data-original-width="1058" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVviCwvyzix33x3GBKtuFuXHOivMjeQP5FrEX8df4khO7Y6KSKwdAqBIRmac1eN5T9EIMbwATiUxqjjnOoMZow-T458ZZadL0fpwy901_pNLayQ-wLUAm8w0W2OyNZk_6KAYPwHOLqKcu9bLnpoc8K-3RIQvNeRV11iSzBSL2U20bRnb89EXghEHBs/s1600/Android%20-%20Policy%20Updates-%20Improving%20Wear%20App%20Quality-header.png" /></a>
<p>Today, we’re excited to announce the release of a new Text-To-Speech (TTS) engine that is performant and reliable. Text-to-speech turns text into natural-sounding speech across more than 50 languages powered by Google’s machine learning (ML) technology. The new text-to-speech engine on Wear OS uses smaller and more efficient prosody ML models to bring faster synthesis on Wear OS devices.</p>
<p>Use cases for Wear OS’s text-to-speech can range from accessibility services, coaching cues for exercise apps, navigation cues, and reading aloud incoming alerts through the watch speaker or Bluetooth connected headphones. The engine is meant for brief interactions, so it shouldn’t be used for reading aloud a long article, or a long summary of a podcast.</p>
<h3>How to use Wear OS’s TTS</h3>
<p>Text-to-speech has long been supported on Android. Wear OS’s new TTS has been tuned to be performant and reliable on low-memory devices. All the Android APIs are still the same, so developers use the same process to integrate it into a Wear OS app, for example, <span style="font-family: Courier;"><a href="https://developer.android.com/reference/android/speech/tts/TextToSpeech#speak%28java.lang.CharSequence,%20int,%20android.os.Bundle,%20java.lang.String%29" target="_blank">TextToSpeech#speak</a></span> can be used to speak specific text. This is available on devices that run Wear OS 4 or higher.</p>
<p>When the user interacts with the Wear OS TTS for the first time following a device boot, the synthesis engine is ready in about 10 seconds. For special cases where developers want the watch to speak <i><u>immediately</u></i> after opening an app or launching an experience, the following code can be used to pre-warm the TTS engine before any synthesis requests come in.</p>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;">private fun initTtsEngine() {
<span style="color: #666666;">//</span> Callback when TextToSpeech connection is set up
val callback <span style="color: #666666;">=</span> TextToSpeech<span style="color: #666666;">.</span>OnInitListener { status <span style="color: #666666;">-></span>
<span style="color: green;">if</span> (status <span style="color: #666666;">==</span> TextToSpeech<span style="color: #666666;">.</span>SUCCESS) {
<span style="color: blue;">Log</span><span style="color: #666666;">.</span>i(TAG, <span style="color: #ba2121;">"tts Client Initialized successfully"</span>)
<span style="color: #666666;">//</span> Get default TTS locale
val defaultVoice <span style="color: #666666;">=</span> tts<span style="color: #666666;">.</span>voice
<span style="color: green;">if</span> (defaultVoice <span style="color: #666666;">==</span> null) {
<span style="color: blue;">Log</span><span style="color: #666666;">.</span>w(TAG, <span style="color: #ba2121;">"defaultVoice == null"</span>)
<span style="color: green;">return</span><span style="color: #19177c;">@OnInitListener</span>
}
<span style="color: #666666;">//</span> Set TTS engine <span style="color: green;">to</span> use default locale
tts<span style="color: #666666;">.</span>language <span style="color: #666666;">=</span> defaultVoice<span style="color: #666666;">.</span>locale
try {
<span style="color: #666666;">//</span> Create a temporary file <span style="color: green;">to</span> synthesize sample text
val tempFile <span style="color: #666666;">=</span>
File<span style="color: #666666;">.</span>createTempFile(<span style="color: #ba2121;">"tmpsynthesize"</span>, null, applicationContext<span style="color: #666666;">.</span>cacheDir)
<span style="color: #666666;">//</span> Synthesize sample text <span style="color: green;">to</span> our file
tts<span style="color: #666666;">.</span>synthesizeToFile(
<span style="color: #666666;">/*</span> text<span style="color: #666666;">=</span> <span style="color: #666666;">*/</span> <span style="color: #ba2121;">"1 2 3"</span>, <span style="color: #666666;">//</span> Some sample text
<span style="color: #666666;">/*</span> params<span style="color: #666666;">=</span> <span style="color: #666666;">*/</span> null, <span style="color: #666666;">//</span> No params necessary <span style="color: green;">for</span> a sample request
<span style="color: #666666;">/*</span> file<span style="color: #666666;">=</span> <span style="color: #666666;">*/</span> tempFile,
<span style="color: #666666;">/*</span> utteranceId<span style="color: #666666;">=</span> <span style="color: #666666;">*/</span> <span style="color: #ba2121;">"sampletext"</span>
)
<span style="color: #666666;">//</span> <span style="color: green;">And</span> clean up the file
tempFile<span style="color: #666666;">.</span>deleteOnExit()
} catch (e<span style="color: #666666;">:</span> Exception) {
<span style="color: blue;">Log</span><span style="color: #666666;">.</span>e(TAG, <span style="color: #ba2121;">"Unhandled exception: "</span>, e)
}
}
}
tts <span style="color: #666666;">=</span> TextToSpeech(applicationContext, callback)
}
</pre></div>
<p>When you are done using TTS, you can release the engine by calling <span style="color: #0d904f; font-family: Courier;">tts.shutdown()</span> in your activity’s <span style="color: #0d904f; font-family: Courier;">onDestroy()</span> method. This command should also be used when closing an app that TTS is used for.</p>
<h3>Languages and Locales</h3>
<p>By default, Wear OS TTS includes 7 pre-loaded languages in the system image: English, Spanish, French, Italian, German, Japanese, and Mandarin Chinese. OEMs may choose to preload a different set of languages. You can check what languages are available by using <span style="font-family: Courier;"><a href="https://developer.android.com/reference/android/speech/tts/TextToSpeech#getAvailableLanguages%28%29" target="_blank">TextToSpeech#getAvailableLanguages()</a></span>. During watch setup, if the user selects a system language that is not a pre-loaded voice file, the watch automatically downloads the corresponding voice file the first time the user connects to Wi-Fi while charging their watch. </p>
<p>There are limited cases where the speech output may differ from the user’s system language. For example, in a scenario where a safety app uses TTS to call emergency responders, developers might want to synthesize speech in the language of the locale the user is in, not in the language the user has their watch set to. To synthesize text in a different language from system settings, use <span style="font-family: Courier;"><a href="https://developer.android.com/reference/android/speech/tts/TextToSpeech#setLanguage%28java.util.Locale%29" target="_blank">TextToSpeech#setLanguage(java.util.Locale)</a></span></p>
<h3>Conclusion</h3>
<p>Your Wear OS apps now have the power to talk, either directly <a href="https://developer.android.com/training/wearables/apps/audio" target="_blank">from the watch’s speakers or through Bluetooth</a> connected headphones. Learn more about <a href="https://developer.android.com/reference/android/speech/tts/TextToSpeech" target="_blank">using TTS</a>.</p>
<p>We look forward to seeing how you use Text-to-speech engine to create more helpful and engaging experiences for your users on Wear OS!</p><p><br /></p>
<div style="background: #f8f8f8; overflow:auto;width:auto;border:0;"><pre style="margin: 0; line-height: 125%">Copyright <span style="color: #666666">2023</span> Google LLC<span style="color: #666666">.</span>
SPDX<span style="color: #666666">-</span>License<span style="color: #666666">-</span>Identifier<span style="color: #666666">:</span> Apache<span style="color: #666666">-2.0</span>
</pre></div>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-53972714390922417822024-03-04T14:00:00.000-08:002024-03-04T14:00:00.121-08:00Embracing Android 14: Meta's Early Adoption Empowered Enhanced User Experience<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW5n06FoVE-2EYCtpdVDhyphenhyphenTnQY6uxTLFwcX4ulmQ6OmzdgLDu500sWA8CPjM36tDpjiSCFJDsQ4fslD8InyzLPi4Tsin0zintvb4cfZbtK7WMb3BV9qXenxgSXsemkZwYkUCGOCanhUbJWMfErr-meqQ5Oo7eae1H4KC_cSh5XRngvHG3Hk6LDM0z4zOg/s1600/AndroidDev_MetaRelease__V4.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW5n06FoVE-2EYCtpdVDhyphenhyphenTnQY6uxTLFwcX4ulmQ6OmzdgLDu500sWA8CPjM36tDpjiSCFJDsQ4fslD8InyzLPi4Tsin0zintvb4cfZbtK7WMb3BV9qXenxgSXsemkZwYkUCGOCanhUbJWMfErr-meqQ5Oo7eae1H4KC_cSh5XRngvHG3Hk6LDM0z4zOg/s1600/AndroidDev_MetaRelease__V4.png" style="display: none;" />
<em>Posted by Terence Zhang – Developer Relations Engineer, Google; in partnership with Tina Ho - Partner Engineering, TPM and Kun Wang – Partner Engineering, Partner Engineer</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW5n06FoVE-2EYCtpdVDhyphenhyphenTnQY6uxTLFwcX4ulmQ6OmzdgLDu500sWA8CPjM36tDpjiSCFJDsQ4fslD8InyzLPi4Tsin0zintvb4cfZbtK7WMb3BV9qXenxgSXsemkZwYkUCGOCanhUbJWMfErr-meqQ5Oo7eae1H4KC_cSh5XRngvHG3Hk6LDM0z4zOg/s1600/AndroidDev_MetaRelease__V4.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW5n06FoVE-2EYCtpdVDhyphenhyphenTnQY6uxTLFwcX4ulmQ6OmzdgLDu500sWA8CPjM36tDpjiSCFJDsQ4fslD8InyzLPi4Tsin0zintvb4cfZbtK7WMb3BV9qXenxgSXsemkZwYkUCGOCanhUbJWMfErr-meqQ5Oo7eae1H4KC_cSh5XRngvHG3Hk6LDM0z4zOg/s1600/AndroidDev_MetaRelease__V4.png" /></a>
<p>With the first <a href="https://android-developers.googleblog.com/2024/02/first-developer-preview-android15.html" target="_blank">Developer Preview of Android 15</a> now released, another new Android release that brings new features and under-the-hood improvements for billions of users worldwide will be coming shortly. As Android developers, you are key players in this evolution; by staying on top of the <a href="https://support.google.com/googleplay/android-developer/answer/11926878" target="_blank">targetSDK upgrade cycle</a>, you are making sure that your users have the best possible experience.</p>
<p>The way Meta, the parent company of Instagram, Facebook, WhatsApp, and Messenger, approached Android 14 provides a blueprint for both developer success and user satisfaction. <b>Meta improved their velocity towards targetSDK adoption by 4x</b>, and so to understand more about how they built this, we spoke to the team at Meta, with an eye towards insights that all developers could build into their testing programs.</p>
<h3>Meta’s journey on A14: A blueprint for faster adoption</h3>
<p>When Android 11 launched, some of Meta’s apps experienced challenges with existing features, such as Chat Heads, and with new requirements, like scoped storage integration. Fixing these issues was complicated by slow developer tooling adoption and a decentralized app strategy. This experience motivated Meta to create an internal Android OS Readiness Program which focuses on prioritizing early and thorough testing throughout the Android release window and accelerating their apps’ targetSDK adoption.</p>
<p>The program officially launched last year. By compiling apps against each Android 14 beta and conducting thorough automated and smoke tests to proactively identify potential issues, Meta was able to seamlessly adopt new Android 14 features, like Foreground Service types <a href="https://issuetracker.google.com/" target="_blank">and send timely feedback and bug reports to the Android team</a>, contributing to improvements in the OS.</p>
<p>Meta also accelerated their targetSDK adoption for Android 14—updating Messenger, Facebook, and Instagram within one to two months of the AOSP release, compared to seven to nine months for Android 12 (<b>an increase of velocity of more than 4x!</b>). Meta’s newly created readiness program unlocked this achievement by working across each app to adopt latest Android changes while still maintaining compatibility. For example, by automating and simplifying their SDK release process, Meta was able to cut rollout time from three weeks to under three hours, enhancing cooperation between individual app teams by providing immediate access to the latest SDKs and allowing for rapid testing of new OS features. The centralized approach also meant Threads adopted Android 14 support quickly despite the fast-growing new app being supported by a minimal team. </p>
<h3>Reaping the rewards: The impact on users</h3>
<p>Meta's early targetSDK adoption strategy delivers significant benefits for users as well. Here's how:</p>
<ul style="text-align: left;"><ul>
<li><b>Improved reliability and compatibility:</b> Early adoption of Android previews and betas prevented surprises near the OS launch, guaranteeing a smooth day-one experience for users upgrading to the latest Android version. For example, with partial media permissions, Meta's extensive experimentation with permission flows ensured “users felt informed about the change and in control over their privacy settings,” while maximizing the app's media-sharing functionality.</li></ul></ul><br /><ul style="text-align: left;"><ul>
<li><b>Robust experimentation with new release features:</b> Early Android release adoption gave Meta ample time to collaborate across privacy, design, and content strategy teams, enabling them to thoughtfully integrate the new Android features that come with every release. This enhanced the collaboration on other features, allowing Meta to roll out <a href="https://source.android.com/docs/core/camera/ultra-hdr" target="_blank">Ultra HDR</a> image experience on Instagram within 3 months of platform release in an “Android first” manner is a great example of this, delighting users with brighter and richer colors with a higher dynamic range in their Instagram posts and stories.</li>
</ul></ul>
<image><div style="text-align: center;"><img alt="Meta's adoption of Ultra HDR in Android 14 brings brighter colors and dynamic range to Instagram posts and stories." border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYrW_yI6CcPjUcSgGaaDZ_784bCOcnub8cMzP48Wtj3MpT4n97ylqg67oyE_hNJh-buxbXstd8Q7HWPoNv_bF6eCor0_hpfeCAnlENTik0MRc8WhT44c9FtYcGu63PK01gSdxbBQ21CeeDm_ndcsmENgl66U6OftpGg0cuOePeZSaaCUd2XUeBKrcA15E/s1600/image2.png" width="100%" /></div><imgcaption><center><em>Meta's adoption of Ultra HDR in Android 14 brings brighter colors and dynamic range to Instagram posts and stories.</em></center></imgcaption></image><br />
<h3>Embrace the latest Android versions</h3>
<p>Meta's journey highlights the compelling reasons for Android developers to adopt a similar forward-thinking mindset in working with the Android betas:</p>
<ul style="text-align: left;"><ul>
<li><b>Test your apps early:</b> Anticipate Android OS changes, ensuring your apps are prepared for the latest target SDK as soon as they become available to create a seamless transition for users who update to the newest Android version. </li></ul></ul><br /><ul style="text-align: left;"><ul>
<li><b>Utilize latest tools to optimize user experience:</b> Test your apps thoroughly against each beta to identify and address any potential issues. Check the Android Studio Upgrade Assistant to highlight major breaking changes in each targetSDKVersion, and integrate the <a href="https://developer.android.com/about/versions/14/reference/compat-framework-changes" target="_blank">compatibility framework</a> tool into your testing process to help uncover potential app issues in the new OS version. </li></ul></ul><br /><ul style="text-align: left;"><ul>
<li><b>Collaborate with Google:</b> Provide your valuable feedback and bug reports using the <a href="https://issuetracker.google.com/" target="_blank">Google issue tracker</a> to contribute directly to the improvement of the Android ecosystem.</li>
</ul></ul>
<p>We encourage you to take full advantage of the Android Developer Previews & Betas program, starting with the newly-released <a href="https://android-developers.googleblog.com/2024/02/first-developer-preview-android15.html" target="_blank">Android 15 Developer Preview 1</a>. </p>
<h3>The team behind the success</h3>
<p>A big thank you to the entire Meta team for their collaboration in Android 14 and in writing this blog! We’d especially like to recognize the following folks from Meta for their outstanding contributions in establishing a culture of early adoption:</p>
<ul><ul>
<li>Tushar Varshney - Partner Engineering, Partner Engineer</li>
<li>Allen Bae - Partner Engineering, EM</li>
<li>Abel Del Pino - Facebook, SWE</li>
<li>Matias Hanco - Facebook, SWE</li>
<li>Summer Kitahara - Instagram, SWE</li>
<li>Tom Rozanski - Messenger, SWE</li>
<li>Ashish Gupta - WhatsApp, SWE</li>
<li>Daniel Hill - Mobile Infra, SWE</li>
<li>Jason Tang - Facebook, SWE</li>
<li>Jane Li - Meta Quest, SWE</li>
</ul></ul>Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-34580134393999721362024-02-29T10:30:00.000-08:002024-02-29T10:42:40.238-08:00Android Studio Iguana is stable<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMLW97x07fxQ0CLacNwpF1EkzVmEqrWeOIGWk1c8lkQ19okJMVRcjLDCOzacz4wkJG3gMS4Ot-m1qoDIzfQbhTH-dGtq5jkkv8QGLUc2uvAvfCSSaJWxg7zLrRL5NndmJ6-g1hwiH4PcFJPZqMnID3atks9uKYBzVq7GkQODb8co9XZIEQf06xApzqYX4/s1600/Android-Studio-Iguana-SOCIAL.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMLW97x07fxQ0CLacNwpF1EkzVmEqrWeOIGWk1c8lkQ19okJMVRcjLDCOzacz4wkJG3gMS4Ot-m1qoDIzfQbhTH-dGtq5jkkv8QGLUc2uvAvfCSSaJWxg7zLrRL5NndmJ6-g1hwiH4PcFJPZqMnID3atks9uKYBzVq7GkQODb8co9XZIEQf06xApzqYX4/s1600/Android-Studio-Iguana-SOCIAL.png" style="display: none;" />
<em>Posted by Neville Sicard-Gregory – Senior Product Manager, Android Studio</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMLW97x07fxQ0CLacNwpF1EkzVmEqrWeOIGWk1c8lkQ19okJMVRcjLDCOzacz4wkJG3gMS4Ot-m1qoDIzfQbhTH-dGtq5jkkv8QGLUc2uvAvfCSSaJWxg7zLrRL5NndmJ6-g1hwiH4PcFJPZqMnID3atks9uKYBzVq7GkQODb8co9XZIEQf06xApzqYX4/s1600/Android-Studio-Iguana-SOCIAL.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMLW97x07fxQ0CLacNwpF1EkzVmEqrWeOIGWk1c8lkQ19okJMVRcjLDCOzacz4wkJG3gMS4Ot-m1qoDIzfQbhTH-dGtq5jkkv8QGLUc2uvAvfCSSaJWxg7zLrRL5NndmJ6-g1hwiH4PcFJPZqMnID3atks9uKYBzVq7GkQODb8co9XZIEQf06xApzqYX4/s1600/Android-Studio-Iguana-SOCIAL.png" /></a>
<p>Today we are launching <a href="https://developer.android.com/studio" target="_blank">Android Studio Iguana</a> 🦎 in the stable release channel to make it easier for you to create high quality apps. With features like Version Control System support in App Quality Insights, to the new built-in support to create Baseline Profiles for Jetpack Compose apps, this version should enhance your development workflow as you optimize your app. Download the latest version today!</p>
<p>Check out the list of new features in Android Studio Iguana below, organized by key developer flows.</p>
<h3>Debugging</h3>
<h4 id="Version-control-system-integration-App-Quality-Insights"><span style="font-size: large">Version control system integration in App Quality Insights</span></h4>
<p>When your release build is several commits behind your local source code, line numbers in <a href="https://firebase.google.com/docs/crashlytics/get-started?platform=android" target="_blank">Firebase Crashlytics</a> crash reports can easily go stale, making it more difficult to accurately navigate from crash to code when using <a href="https://developer.android.com/studio/debug/app-quality-insights" target="_blank">App Quality Insights</a>. If you’re using git for your version control, there’s now a solution to this problem.</p>
<p>When you build your app using Android Gradle Plugin 8.3 or later and the latest version of the Crashlytics SDK, AGP includes git commit information as part of the build artifact that is published to the Play Store. When a crash occurs, Crashlytics attaches the git information to the report, and Android Studio Iguana uses this information to compare your local checkout with the exact code that caused the crash from your git history.</p>
<p>After you build your app using Android Gradle Plugin 8.3 or higher with the latest Crashlytics SDK, and publish it, new crash reports in the App Quality Insights window let you either navigate to the line of code in your current git checkout or view a diff report between the current checkout and the version of your app codebase that generated the crash report. <a href="https://developer.android.com/studio/releases#aqi-vcs" target="_blank">Learn more</a>.</p>
<image><div style="text-align: center;"><img id="imgFull" alt="app quality insights with version control system integration in Android Studio" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT1p7b4amrON_4eHtUegzZFUToeflQ6pDVsjzU5qrhsUXmyKY6cFAoZ1v3fJh1VtFmkyycF-XQOuB8RHsWZ8XXdGum-RfBTPmb_V97eXq9g2Y0m4p-fRrzpAXhZkkyLMi7d22wMK1-jkx98HN33w67rOpS-3eLFMAp3y6CYUXkny-9ONJP258OVGs0ySc/s1600/image6.png" width="100%"/></div><imgcaption><center><em>App Quality Insights with Version Control System Integration</em></center></imgcaption></image><br/>
<h4 id="View-Crashlytics-crash-variants-App-Quality-Insights"><span style="font-size: large">View Crashlytics crash variants in App Quality Insights</span></h4>
<image><div style="text-align: center;"><img id="imgFull" alt="app quality insights in Android Studio" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjopsyasNaKzqq9VwK_tGzpfW2Zj-UTpXEysJl3VIhKUBoaNPBwQfpQEWDwF02lhN3A-njmKWHiM9KHtHxr-ngv7WTFnhYkGEX0oCTZj1_PYQzr5bN1Dkn7VQAXWveDOZ0LorwSE79wuzHlY91o_q3lDO3OBEExHvZO1Jpbusqk3ChcCfSEC5-jp9VVXk0/s1600/image11.png" width="100%"/></div><imgcaption><center><em>Crash variants in App Quality Insights</em></center></imgcaption></image><br/>
<p>Today, when you select a Crashlytics issue in App Quality Insights, you see aggregated data from events that share identical points of failure in your code, but may have different root causes. To aid in your analysis of the root causes of a crash, Crashlytics now groups events that share very similar stack traces as issue variants. You can now view events in each variant of a crash report in App Quality Insights by selecting a variant from the dropdown. Alternatively, you can view aggregate information for all variants by selecting <b>All</b>.</p>
<h3>Design</h3>
<h4 id="Jetpack-Compose-UI-Check"><span style="font-size: large">Jetpack Compose UI Check</span></h4>
<p>To help developers build adaptive and accessible UI in Jetpack Compose, Iguana introduces a new UI Check mode in Compose Preview. This feature works similarly to <a href="https://developer.android.com/studio/releases/past-releases/as-electric-eel-release-notes#visual-linting" target="_blank">visual linting</a> and <a href="https://developer.android.com/guide/topics/ui/accessibility/testing#accessibility-scanner" target="_blank">accessibility checks integrations</a> for views. Activate Compose UI check mode to automatically audit your Compose UI and check for adaptive and accessibility issues across different screen sizes, such as text that's stretched on large screens or low color contrast. The mode highlights issues found in different preview configurations and lists them in the problems panel.</p>
<p>Try it out by clicking the UI Check icon in Compose Preview.</p>
<image><div style="text-align: center;"><img id="imgFull" alt="UI Check entry point in Compose Preview" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZmxUObWjCdKU1b_k7SM2GF3ctMOKgkM0DaR7iTAXNEJ1XB1La6M0XjY4FA3JpsWbmP075mUu4T1Vi9FK-4R9qO0_bMJ-KgqCCJ0of0cIBMxQ7uIijHST492HcwXdCP5advPejWe9iqMwohuaf6XW178dwOW8J0H0v-RmejVM5trelOXUso3fHWkYJoBs/s1600/image8.png" width="100%"/></div><imgcaption><center><em>UI Check entry point in Compose Preview</em></center></imgcaption></image><br/>
<image><div style="text-align: center;"><img id="imgFull" alt="UI Check results of Reply App in Compose Preview" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoU9ZlgRQ_ayGBAYuQHc5on9Q1DHesdlJc08h2IgZI8RXrrvliPYiXFk939FP7N1Bmc52qnjnOrl_RhG-GuQOmhiWNdxT4kP0JnhYU1pdwDg_rj8YTtWpCU62fQ_DuGGlProqTD7DGMxzs7VDcb2_7BD9iQQtCG6dhyphenhyphenY_yjmmH18_JGio_7S0CoQeKx3c/s1600/image3.png" width="100%"/></div><imgcaption><center><em>UI Check results of Reply App in Compose Preview</em></center></imgcaption></image><br/>
<h4><span style="font-size: large">Progressive rendering for Compose Preview</span></h4>
<p>Compose Previews in Android Studio Iguana now implement progressive rendering, allowing you to iterate on your designs with less loading time. This feature automatically lowers the detail of out-of-view previews to boost performance, meaning you can scroll through even the most complex layouts without lag.</p>
<image><div style="text-align: center;"><img id="imgFull" alt="moving image showing progressive rendering in Compose" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizA6oSmA5LLc5m2C2jxrzZwKUxk3EFAx3dzA15MPYtVwDRq5XFCqdGO0hgMi-EEHgdLCriPxflcVD4GcpHaV8bf_vQGAra4K0vb8QhBLr10br08O7NEUWP_EPu9at6oMCMx-HGTvQJfk9yChhCb8rYh2fylbnLHvRIymFI0B5dz_eFPTbt1tW3ZWuCIVw/s1600/image7.gif" width="100%"/></div><imgcaption><center><em>Progressive Rendering in Compose
</em></center></imgcaption></image><br/>
<h3>Develop</h3>
<h4><span style="font-size: large">Intellij Platform Update</span></h4>
<p>Android Studio Iguana includes the IntelliJ 2023.2 platform release, which has many new features such as support for GitLab, text search in Search Everywhere, color customization updates to the new UI and a host of new improvements. <a href="https://www.jetbrains.com/idea/whatsnew/2023-2/" target="_blank">Learn more</a>.</p>
<h3>Testing</h3>
<h4 id="Baseline-Profiles-module-wizard"><span style="font-size: large">Baseline Profiles module wizard</span></h4>
<p>Many times when you run an Android app for the first time on a device, the app can appear to have a slow start time because the operating system has to run just-in-time compilation. To improve this situation, you can create <a href="https://developer.android.com/topic/performance/baselineprofiles/overview" target="_blank">Baseline Profiles</a> that help Android improve aspects like app start-up time, scrolling, and navigation speed in your apps. We are simplifying the process of setting up a Baseline Profile by offering a new <b>Baseline Profile Generator</b> template in the new module wizard (<b>File > New > New Module</b>). This template configures your project to support Baseline Profiles and employs the latest Baseline Profiles Gradle plugin, which simplifies setup by automating required tasks with a single Gradle command.</p>
<image><div style="text-align: center;"><img id="imgFull" alt="Baseline Profile module wizard - Create New Module" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyKl8DkBdJgx4pL2FmWQCDe3tA95kmPYjyckhjetXmKUovCHj1865RvDhmtZ69h4D_lHkn9ivNvRv72z_TM0uZpoN3_lgmU0znQvH9PIEuOsBv84LOrDyrS-ZkiT1vL6-gOQsUzmsdJcz_n7XzUQ7aZZNiLQSCCAHjL5CtyGsE00GLX2xSYMAeMN0mFyQ/s1600/image1.png" width="100%"/></div><imgcaption><center><em>Baseline Profile Generator</em></center></imgcaption></image><br/>
<p>Furthermore, the template creates a run configuration that enables you to generate a Baseline Profile with a single click from the "Select Run/Debug Configuration" dropdown list.</p>
<image><div style="text-align: center;"><img id="imgFull" alt="Generate Baseline Profile drop-down menu" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEtil4Dxz-J9int-_rjsa3fPhBUWWVG3SSJFg_U7cUFuyidiKB1xwB3osGNS_r9ETRfrsR1uMZbRuC3epK5SFNO7lQZxTw8e59lbWosmaWSoFZgFVyp5o4Zyjid0Iy3ZlsDE-YiR6WZEMKe6joQDnerPSgiiVInbRo8zpLt1HsPfjElX8xvdx_PmWbFgI/s1600/image9.png" width="100%"/></div><imgcaption><center><em>Generate Baseline Profile drop-down menu</em></center></imgcaption></image><br/>
<h4 id="Espresso-Device-API"><span style="font-size: large">Test against configuration changes with the Espresso Device API</span></h4>
<image><div style="text-align: center;"><img id="imgFull" alt="Synchronous testing of window size changes using Espresso Device API" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz1i3rsJk6RwVmTP7T74LJjvZhn_bSiRcq6FO-KqIn87-oSwAVT98bf3mVDA2M8pFLCfgA6pd1qKoD-DuDmdZ8ysrE9CjB38xJ6j_wouW_Ea1QmsVxBtkBQHxgMtadci1B9B7h-UqY1kuXFRQHfGG7imIyjDommwzYhT1FHlVxel_f869cOhomhYxIP64/s1600/image10.png" width="100%"/></div><imgcaption><center><em>Synchronous testing of window size changes using Espresso Device API</em></center></imgcaption></image><br/>
<p>Catch layout problems early and ensure your app delivers a seamless user experience across devices and orientations. The <a href="https://github.com/android/testing-samples/tree/main/ui/espresso/EspressoDeviceSample" target="_blank">Espresso Device API</a> simulates how your app reacts to configuration changes—such as screen rotation, device folding/unfolding, or window size changes—in a synchronous way on virtual devices. These APIs help you rigorously test and preemptively fix issues that frustrate users so you build more reliable Android apps with confidence. These APIs are built on top of new gRPC endpoints introduced in Android Emulator 34.2, which enables secure bidirectional data streaming and precise sensor simulation.</p>
<h4 id="Pixel-8-Pixel-8-Pro-devices-in-Android-Emulator-(34.2)"><span style="font-size: large">Pixel 8 and Pixel 8 Pro devices in Android Emulator (34.2)</span></h4>
<p>Test your app on the latest Google Pixel device configurations with the updated Android Virtual Device definitions in Android Studio. With Android Studio Iguana and the latest Android Emulator (34.2+), access the Pixel Fold, Pixel Tablet, Pixel 7a, Pixel 8, and Pixel 8 Pro. Validating your app on these virtual devices is a convenient way to ensure that your app reacts correctly to a variety of screen sizes and device types.</p>
<image><div style="text-align: center;"><img id="imgFull" alt="New Pixel Android Virtual Devices in the Android Emulator" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSAlg0gBem1FyQlMUdsAhO1FRqUikc6ylXGFWuy-w90PzwkkrY7AoTTRi__scQQuWAVZX07N0X2AeCFzjfE9OKe92YEXMyqVn-mFLAbT4FQCMmpnc5otcQzZWn4D6pVOH5wmf5_q9l0R9yK7ifJZhleaVFDp5bnofCergyxRiY4AhzB4rq1H6n_S7vuT0/s1600/image5.png" width="100%"/></div><imgcaption><center><em>New Pixel Android Virtual Devices in the Android Emulator. </em></center></imgcaption></image><br/>
<h3>Build</h3>
<h4 id="Support-Gradle-Version-Catalogs"><span style="font-size: large">Support for Gradle Version Catalogs</span></h4>
<p>Android Studio Iguana streamlines dependency management with its enhanced support for TOML-based Gradle Version Catalogs. You'll benefit from:</p>
<ul><ul>
<li><b>Centralized dependency management:</b> Keep all your project's dependencies organized in a single file for easier editing and updating.</li>
<li><b>Time-saving features:</b> Enjoy seamless code completion, smart navigation within your code, and the ability to quickly edit project dependencies through the convenient Project Structure dialog.</li>
<li><b>Increased efficiency:</b> Say goodbye to scattered dependencies and manual version updates. Version catalogs give you a more manageable, efficient development workflow.</li>
</ul></ul>
<p>New projects will automatically use version catalogs for dependency management. If you have an existing project, consider making the switch to benefit from these workflow improvements. To learn how to update to Gradle version catalogs, see <a href="https://developer.android.com/studio/build/migrate-to-catalogs" target="_blank">Migrate your build to version catalogs</a>.</p>
<h4 id="policy-issues"><span style="font-size: large">Additional SDK insights: policy issues</span></h4>
<p>Android Studio Iguana now proactively alerts you to potential Google Play policy violations through integration with the <a href="https://developer.android.com/distribute/sdk-index" target="_blank">Google Play SDK Index</a>. Easily see Play policy issues right in your build files and Project Structure Dialog. This streamlines compliance, helping you avoid unexpected publishing delays or rejections on the Google Play Store.</p>
<image><div style="text-align: center;"><img id="imgFull" alt="Android Studio's project structure dialog showing a warning from the Google Play SDK Index" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2-PFVbEYLFKYj8SSlJThmWnjpbVrhZbWucwaoArGPvOo2S7ljD0Ggddg90ZlXPNyCCWdEHYCoNjb24K3cwT7tb1rygEqGDgJ9D8TL6KZ63Jw0wR7qbslgMLBBHlhGfvHnnXnX5sf8H_F9kmSQji7VaGtI8cq6P-RJ7MbEDTzC9y7LdYTuNtJjEegmF1E/s1600/image4.png" width="100%"/></div><imgcaption><center><em>A warning from the Google Play SDK Index in Android Studio’s Project Structure dialog</em></center></imgcaption></image><br/>
<h4><span style="font-size: large">Android Studio compileSdk version support</span></h4>
<p>Using Android Studio to develop a project that has an unsupported <a href="https://developer.android.com/build#android_sdk_settings" target="_blank">compileSdk version</a> can lead to unexpected errors because older versions of Android Studio may not handle the new Android SDK correctly. To avoid these issues, Android Studio Iguana now explicitly warns you if your project’s intended compileSdk is for a newer version that it does not officially support. If available, it also suggests moving to a version of Android Studio that supports the compileSdk used by your project. Keep in mind that <a href="https://developer.android.com/studio/releases#android_gradle_plugin_and_android_studio_compatibility" target="_blank">upgrading Android Studio might also require that you upgrade AGP</a>.</p>
<h3><b>Summary</b></h3>
<p>To recap, <a href="https://developer.android.com/studio" target="_blank">Android Studio Iguana</a> 🦎includes the following enhancements and features:</p>
<p><b>Debugging</b></p>
<ul><ul>
<li><a href="#Version-control-system-integration-App-Quality-Insights">Version control in App Quality Insights</a></li>
<li><a href="#View-Crashlytics-crash-variants-App-Quality-Insights">View Crashlytics in App Quality Insights</a></li>
</ul></ul>
<p><b>Design</b></p>
<ul><ul>
<li><a href="#Jetpack-Compose-UI-Check">Jetpack Compose UI Check</a></li>
<li>Progressive rendering for Compose Preview</li>
</ul></ul>
<p><b>Develop</b></p>
<ul><ul>
<li>Intellij platform update</li>
</ul></ul>
<p><b>Testing</b></p>
<ul><ul>
<li><a href="#Baseline-Profiles-module-wizard">Baseline Profiles wizard</a></li>
<li><a href="#Espresso-Device-API">Espresso Device API</a></li>
<li><a href="#Pixel-8-Pixel-8-Pro-devices-in-Android-Emulator-(34.2)">The latest Android Virtual Devices</a></li>
</ul></ul>
<p><b>Build</b></p>
<ul><ul>
<li><a href="#Support-Gradle-Version-Catalogs">Support for Gradle Version Catalogs</a></li>
<li><a href="#policy-issues">Policy issue warnings in Google Play SDK Index</a></li>
<li>CompileSDK version support</li>
</ul></ul>
<h3>Download Android Studio Today</h3>
<p>Download <a href="https://developer.android.com/studio" target="_blank">Android Studio Iguana</a> 🦎 today and take advantage of the latest features to streamline your workflow and help you make better apps. Your feedback is essential – <a href="https://developer.android.com/studio/known-issues" target="_blank">check known issues</a>, <a href="https://developer.android.com/studio/report-bugs" target="_blank">report bugs</a>, <a href="https://developer.android.com/studio/report-bugs" target="_blank">suggest improvements</a>, and be part of our vibrant community on <a href="https://www.linkedin.com/showcase/androiddev/posts/?feedView=all" target="_blank">LinkedIn</a> <a href="https://medium.com/androiddevelopers" target="_blank">Medium</a>, <a href="https://www.youtube.com/c/AndroidDevelopers/videos" target="_blank">YouTube</a>, or <a href="https://twitter.com/androidstudio" target="_blank">X (formerly known as Twitter)</a>. Let's build the future of Android apps together! </p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-46419232978888649912024-02-26T10:00:00.000-08:002024-03-05T10:02:17.643-08:00New goodies from Android, Wearables at Mobile World Congress + tune in to a new episode of #TheAndroidShow next week! <meta name="twitter:image" content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI0RiyyrPaaVPxXBOu8d8y9wAUWn_45S30v6PSfecI6OKJNKDWdm6gsiLK_14cxBUXhlnk67rK358EWhqvVABQqRVcjKo6iYmP9uPeNBAC3pdSQlMkNoit8dpmSxiymkqleXSeWNqB_q0upzqPX-waFeELV1B7JlaWGXvHqnEUfKaV-QxfGfvS8lIwjNQ/s1600/TAS-Social-Q1-AD.png">
<img style="display:none" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI0RiyyrPaaVPxXBOu8d8y9wAUWn_45S30v6PSfecI6OKJNKDWdm6gsiLK_14cxBUXhlnk67rK358EWhqvVABQqRVcjKo6iYmP9uPeNBAC3pdSQlMkNoit8dpmSxiymkqleXSeWNqB_q0upzqPX-waFeELV1B7JlaWGXvHqnEUfKaV-QxfGfvS8lIwjNQ/s1600/TAS-Social-Q1-AD.png">
<em>Posted by Anirudh Dewani, Director of Android Developer Relations</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPcej6RGlKIMCO01jywpjhx06BwCX4H99IxkpeZ-kOYOky0wayXs55BenCgg51d03jwUNyWIa3LqfHqfzZew9kj7o4o8x0QilXkmvOVILoz9V8EpMg0Tw1diGmgmIfNS3nAyTtNpjWEHQqToRo2qWHpaQvPVX4yhEz_kzARdB-F-YglL3jIeAgtDTjBY8/s1600/image%20%285%29.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPcej6RGlKIMCO01jywpjhx06BwCX4H99IxkpeZ-kOYOky0wayXs55BenCgg51d03jwUNyWIa3LqfHqfzZew9kj7o4o8x0QilXkmvOVILoz9V8EpMg0Tw1diGmgmIfNS3nAyTtNpjWEHQqToRo2qWHpaQvPVX4yhEz_kzARdB-F-YglL3jIeAgtDTjBY8/s1600/image%20%285%29.png" /></a>
<p>Earlier today, at Mobile World Congress (MWC), an annual conference showcasing the latest in mobile, Android and our partners unveiled a range of new goodies, including new wearables, foldables, as well as a number of new features for Android users. Keep reading below to see how you, as developers, can take advantage of these new features and devices that are being released. And in just over a week, on Thursday March 7 at 10AM PT, we’ll be kicking off another episode of #TheAndroidShow, our quarterly live show on YouTube and on <a href="http://developer.android.com/events/show" target="_blank">developer.android.com</a>, where we’ll dive more into these topics.</p>
<iframe class="BLOG_video_class" allowfullscreen="" youtube-src-id="3D4k2z8Wmw0" width="100%" height="413" src="https://www.youtube.com/embed/3D4k2z8Wmw0"></iframe><br/>
<h3>Meet the new watch from OnePlus and how we’re boosting power with the Wear OS hybrid interface</h3>
<p>Wearables are on display across MWC this week, and one of our favorites is OnePlus Watch 2, powered with the latest version of Wear OS (<a href="https://android-developers.googleblog.com/2023/10/wear-os-4-is-now-stable-and-available-on-google-pixel-watch-2.html" target="_blank">Wear OS 4</a>). As part of our ongoing work to improve the <a href="https://wearos.google.com/" target="_blank">Wear OS by Google</a> user experience, we’ve made fundamental changes to the platform and substantially expanded the capabilities of the Wear OS hybrid interface that improve two key areas: power and performance. As a developer, you can leverage existing Wear OS APIs to get underneath optimizations without any added effort – no code changes required! <a href="https://android-developers.googleblog.com/2024/02/wear-os-hybrid-interface-boosting-power-and-performance.html " target="_blank">You can read more about the updates here.</a> </p>
<image><div style="text-align: center;"><img alt="Images of three people wearing the OnePlus Watch 2" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY2MRgmDxsZC8Tni50uvlDqwljNbb4WyRSEHDbE4PsY_-0BL-P0W49r7v6TMX8gH39BxcjRaPNr2ZdYhbHF9vkopYBMLPE2BSmr_Nq2bC60P3hRkiNeZMgbZSyazYw5vUXprwD3sJQswKcsqzLTXv-HK-F6o-Bax9qNYmE5mNUPNLqw774no8nK4r7X7U/s1600/Oneplus_social.png" width="100%" /></div></image><br />
<h3>A few new features for Android users</h3>
<p>Google released 9 new features Android users can take advantage of across Google apps, you can <a href="https://blog.google/products/android/new-android-features-february-2024" target="_blank">read more about those features here</a>. For developers, we wanted to highlight a few ways you can take advantage of this news across experiences you build into your apps:</p>
<ul style="text-align: left;"><ul>
<li><b>More places for users to see their Health Connect data, now in the Fitbit app:</b> With permission from your users, <a href="https://developer.android.com/health-and-fitness/guides/health-connect" target="_blank">Health Connect</a> is a central way to connect and sync their favorite health and fitness apps, see all their data in one place, and stay in control of their privacy. By setting up Health Connect in the Fitbit mobile app for Android, users will have an overview of their health and fitness data from across their apps in one place. You can <a href="https://android-developers.googleblog.com/2023/08/health-connect-brings-together-peloton-oura-lifesum-for-deeper-health-and-fitness-insights.html" target="_blank">join developers like Peloton, ŌURA, and Lifesum</a> who are using Health Connect to provide their users with deeper health and fitness insights, <a href="https://developer.android.com/health-and-fitness/guides/health-connect" target="_blank">get started now</a>!</li></ul></ul><ul style="text-align: left;"><ul>
<li><b>Add Stylus support, like Google Docs did: </b> With Google Docs markups, you can <a href="https://www.android.com/new-features-on-android/?feature=google-docs-markups&utm_source=blog&utm_medium=owned&utm_campaign=y24q1spotlight/#gms-filter" target="_blank">add handwritten annotations to Docs</a> from your Android phone or tablet using just your finger or stylus. Google Docs took advantage of stylus support; <a href="https://developer.android.com/guide/topics/large-screens/support-advanced-stylus-features" target="_blank"> you can learn more about adding support for Stylus here</a>.</li></ul></ul><ul style="text-align: left;"><ul>
<li><b>Use Tiles for Wear OS, like Google Maps did:</b> With <a href="https://www.android.com/new-features-on-android/?feature=transit-directions-on-google-maps-for-wear-os&utm_source=blog&utm_medium=owned&utm_campaign=y24q1spotlight/#gms-filter" target="_blank">public transit directions on Google Maps for Wear OS</a>, you can leave your phone in your pocket and glance at your wrist to make sure you catch your bus, train or ferry. Users can see these public transit directions through Google Maps use of <a href="https://developer.android.com/design/ui/wear/guides/surfaces/tiles" target="_blank">Tiles</a> which provide quick access to the information and actions users need to get things done. <a href="https://developer.android.com/training/wearables/tiles" target="_blank">You can learn more about building a Tile for your app here</a>.</li>
</ul></ul>
<image><div style="text-align: center;"><img alt="Image that reads 'New updates on Android' with pictures of a smart watch, laptop, and Android Auto" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY6auQvdiAc77ulf-KnhpPWzh43OHJp9xTds7BPw8HWrf_SrGOCJ_45AAV8ABdQzgD4ooHD4z7XT41DTaXivXAAO9MDHmjuIvDnfW5UoQ48_gRaJMtd6SB1uzEzqdmVRrsavcmH1Asot1ob9EgqKXtLbRMxIf5axHi5AIQofNgTc5pv9QLmdzNCuPPvZM/s1600/image2.jpg" width="100%" /></div></image>
<h2><span style="font-size: x-large;">A new episode of #TheAndroidShow, live on March 7 at 10AM PT. Send us your #AskAndroid questions now! </span></h2>
<p>You can join us on March 7 at 10AM PT for a new episode of <b>#TheAndroidShow.</b> In this quarterly show, we’ll unpack the latest Android foldables and large screens for you to get building on, plus a behind-the-scenes on Gemini Nano and AICore.</p>
<p>We’ll have a live #AskAndroid Q&A with the team about building Android; you can ask us about building excellent apps across devices, Android 15, Compose, Gemini and more, using #AskAndroid on X or on YouTube. Our experts are ready to answer your questions live!</p>
<p><b>#TheAndroidShow: March 7 at 10AM PT</b>, broadcast live on YouTube and <a href="https://developer.android.com/events/show" target="_blank">d.android.com/events/show</a>!</p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-85599338749754680152024-02-26T07:00:00.000-08:002024-02-26T07:46:20.443-08:00Wear OS hybrid interface: Boosting power and performance<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmm4lj8twpvPFOe835BVS8ODXRQe300l72XMYE-oW50Ce79FGpaa9UHCtGcnhi_GZcsUCsVrbsy2mp3uVV5GPH7BRATgh-t4ZnmkG_PVICWha2ilkXy5k0O256wwlEby3PDLB-u6qKB3nyV6rtXurwlfUQqvKyQaotUso_E-Z15ql3xcuJml625jwR6PA/s1600/WearOS-OnePlus-AD-Social.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmm4lj8twpvPFOe835BVS8ODXRQe300l72XMYE-oW50Ce79FGpaa9UHCtGcnhi_GZcsUCsVrbsy2mp3uVV5GPH7BRATgh-t4ZnmkG_PVICWha2ilkXy5k0O256wwlEby3PDLB-u6qKB3nyV6rtXurwlfUQqvKyQaotUso_E-Z15ql3xcuJml625jwR6PA/s1600/WearOS-OnePlus-AD-Social.png" style="display: none;" />
<em>Posted by <a href="https://twitter.com/kseniiaS" target="_blank">Kseniia Shumelchyk</a>, Android Developer Relations Engineer</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOORsnGuE8R2oK8MeCeUegCvo3kCWraitp4mtBuyoXY9Y33cuHBJiF0JEBpipOSPLBsfyvtxC8rFdV-pxsQwX00xmE3jszlI68QLgauapkYOt_4wZdotYsITlgTehohAawtmuSOadMsnDHtv8b7fHcqADtmqo21_j0rCuih20mNd6srIEq_tKa3mTEY0I/s1600/Oneplus_blogheader.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOORsnGuE8R2oK8MeCeUegCvo3kCWraitp4mtBuyoXY9Y33cuHBJiF0JEBpipOSPLBsfyvtxC8rFdV-pxsQwX00xmE3jszlI68QLgauapkYOt_4wZdotYsITlgTehohAawtmuSOadMsnDHtv8b7fHcqADtmqo21_j0rCuih20mNd6srIEq_tKa3mTEY0I/s1600/Oneplus_blogheader.png" /></a>
<p>In collaboration with our hardware partners, we’ve continued to prioritize the <a href="https://wearos.google.com/" target="_blank">Wear OS</a> by Google user experience. As such, we’ve made fundamental design changes to the platform and substantially expanded the capabilities of the Wear OS hybrid interface that improve two key areas: power and performance.</p>
<p>With <a href="https://www.prnewswire.com/news-releases/introducing-oneplus-watch-2-a-dual-engine-flagship-smartwatch-powered-with-wear-os-by-google-302070328.html#:~:text=DALLAS%2C%20Feb.%2026%2C%202024,%E2%84%A2%20%28Wear%20OS%204%29" target="_blank">OnePlus Watch 2</a>, powered with the latest version of Wear OS (<a href="https://android-developers.googleblog.com/2023/10/wear-os-4-is-now-stable-and-available-on-google-pixel-watch-2.html" target="_blank">Wear OS 4</a>), the dual-chipset architecture works with our hybrid interface to get both chips to work better in tandem. This enables even more use cases to benefit from dramatically extended battery life of up to 100 hours of regular use with all functionalities accessible in Smart Mode.</p>
<p>Together, we’ve created a premium smartwatch experience that doesn’t compromise the advanced feature set or battery life. In this post, we’ll share how you can benefit from these changes when building experiences for Wear OS.</p>
<h2><span style="font-size: x-large;">On the edge of innovation: redesigned smartwatch architecture</span></h2>
<p>Wear OS smartwatches have a dual-chipset architecture inclusive of a powerful application processor (AP) and ultra low-power co-processor microcontroller unit (MCU). The architecture has a powerful AP capable of handling complex operations en-masse, and is seamlessly coupled with a low power MCU.</p>
<p>The Wear OS hybrid interface enables intelligent switching between the MCU or the AP, allowing the AP to be suspended when not needed to preserve battery life. It helps, for instance, achieve more power-efficient experiences, like sensor data processing on the MCU while the AP is asleep. At the same time, the hybrid interface provides a seamless transition between these states, keeping a rich and premium user experience without jarring transitions between power modes.</p>
<image><div style="text-align: center;"><img alt="ALT TEXT" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSSIa-_v9BKX-IzB2JLfd6Bz8CL3cQDm2ka_DXn8DPR92iM463UzNbpgWaVno3FJwPildLcdvFM83cAyCBjxRmhtM48nWFv7XzDPQFi5rFhfZCoJOM-pxxcTQ6VcXKy1VIR8kig880mWHhQtiPYQ6kKgY90Hkgg2eQ6Zrk3xKOMYPI_i0vCbxglUVx3LU/s1600/image2.gif" width="100%" /></div></image><br />
<h3 style="text-align: left;"><span style="font-size: large;">Connectivity and notification experience</span></h3>
<p>To enhance connectivity-reliant interactions like notifications and phone calls, OnePlus utilized platform capabilities with the notification API in the hybrid interface, enabling the MCU to process regular notification experiences and reduce the need to activate the AP.</p>
<p>For example, <a href="https://developer.android.com/training/wearables/notifications" target="_blank">bridged notifications</a> will be delivered to the watch without waking up the high-performance AP. Users can read and dismiss these notifications while the watch is still powered by the MCU. The MCU can also handle wearable-specific actions in notifications, such as quick replies or remote actions.</p>
<h2><span style="font-size: x-large;">What this means for development</span></h2>
<p>You can leverage existing Wear OS APIs to get these optimizations without any added effort – no code changes required!</p>
<h3 style="text-align: left;"><span style="font-size: large;">Notifications</span></h3>
<p>The notification hybrid interface enables seamless transitions between power modes to work with the Wear OS notification stack. You get the best notification performance by using the <a href="https://developer.android.com/training/wearables/notifications?_gl=1*9dlcvi*_up*MQ..*_ga*NjY5MzY0MTMzLjE3MDc3ODEwMzU.*_ga_6HH9YJMN9M*MTcwNzc4MTAzNC4xLjAuMTcwNzc4MTAzNC4wLjAuMA..#add-wearable-features" target="_blank">Notification API</a>.</p>
<h3 style="text-align: left;"><span style="font-size: large;">Health & Fitness experiences</span></h3>
<p>The Wear OS hybrid interface also elevates the fitness experience with more precise workout tracking, automatic sports recognition and smarter health data monitoring. All of these can be offered to users without compromising battery life.</p>
<p>Starting with Wear OS 3, developers use <a href="https://developer.android.com/health-and-fitness/guides/health-services" target="_blank">Health Services on Wear OS</a> to gain access to sensor data. The health hybrid interface works under the hood to enable power optimizations by batching sensor data on the MCU and periodically updating developer apps through the Health Services API on the AP.</p>
<h3 style="text-align: left;"><span style="font-size: large;">Watch Faces</span></h3>
<p>With Wear OS 4, we launched the <a href="https://android-developers.googleblog.com/2023/05/introducing-watch-face-format-for-wear-os.html" target="_blank">Watch Face Format</a>, a declarative XML format to create customizable and power-efficient watch faces.</p>
<p>The platform has created capabilities to implement Watch Face Format rendering on the MCU, so using the new format helps future-proof certain watch faces to take advantage of emerging optimizations in future devices for better battery usage.</p>
<p>Check out the <a href="https://developer.android.com/training/wearables/wff" target="_blank">watch face format</a> documentation and <a href="https://developer.android.com/design/ui/wear/guides/surfaces/watch-faces" target="_blank">design guidelines</a> for Wear OS watch faces.</p>
<h2><span style="font-size: x-large;">Expand your reach with Wear OS</span></h2>
<p>With the additions to the Wear OS smartwatch ecosystem and expanded device capabilities, it's an ideal time to build experiences for smartwatches that can reach more users and benefit your business.</p>
<p>To begin developing apps for Wear OS, try our <a href="https://developer.android.com/codelabs/compose-for-wear-os" target="_blank">Compose for Wear OS codelab</a>, and check out the <a href="http://d.android.com/wear" target="_blank">documentation</a> and <a href="https://github.com/android/wear-os-samples" target="_blank">samples</a>.</p>
<p>Read more about <a href="https://android-developers.googleblog.com/2023/10/wear-os-4-is-now-stable-and-available-on-google-pixel-watch-2.html" target="_blank">developer updates in Wear OS 4</a>, and how you can get your apps ready for the latest Wear OS watches.</p>
<p>We can’t wait to see what experiences you’ll build!</p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-61763421981278234772024-02-22T09:00:00.000-08:002024-02-22T09:00:00.129-08:00Easily add document scanning capability to your app with ML Kit Document Scanner API<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9szIo2TBAryM51OQHMHjvoJRkwMs2Pa3NXmFxmZrWGdLC2c83LgSXwlf2MypoXN2IBz_3SOS-HQQqKDRAWYfWDmHeNyGl5KUaFkkJeEpKLA2NIX8Vtvrt7pnUdfDDTg6ZmOLfmhQKIldp9v96yadQnUa2r8fZUS6N2t9zPCPJNZteai33hPjUKq6z23k/s1600/a_new_foundtion_editorial-social.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9szIo2TBAryM51OQHMHjvoJRkwMs2Pa3NXmFxmZrWGdLC2c83LgSXwlf2MypoXN2IBz_3SOS-HQQqKDRAWYfWDmHeNyGl5KUaFkkJeEpKLA2NIX8Vtvrt7pnUdfDDTg6ZmOLfmhQKIldp9v96yadQnUa2r8fZUS6N2t9zPCPJNZteai33hPjUKq6z23k/s1600/a_new_foundtion_editorial-social.png" style="display: none;" />
<em>Posted by Thomas Ezan – Sr. Developer Relations Engineer; Chengji Yan, Penny Li – ML Kit Engineers; David Miro Llopis – Product Manager</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm1t-9xVtRVMAjnjo5Ji5Mpx9qcqcJgdeeEOpfOB4AtYrktrF6MhoMMC8VlPKhNxF0mT-D3GA8Ja8ig0KiYnV6bZRInjHxJbkbM1sOinK5SqmJGqeWWHUxYkJ-oB8iorE9-X4MVJUaYMTEn-FycA27R4eFcA2HaUKABbP5zJbWSnCNWPVQzJZkQAqBqeI/s1600/a_new_foundtion_editorial_header.png"><img border="0" data-original-height="800" data-original-width="1058" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm1t-9xVtRVMAjnjo5Ji5Mpx9qcqcJgdeeEOpfOB4AtYrktrF6MhoMMC8VlPKhNxF0mT-D3GA8Ja8ig0KiYnV6bZRInjHxJbkbM1sOinK5SqmJGqeWWHUxYkJ-oB8iorE9-X4MVJUaYMTEn-FycA27R4eFcA2HaUKABbP5zJbWSnCNWPVQzJZkQAqBqeI/s1600/a_new_foundtion_editorial_header.png" /></a>
<p>We are excited to announce the launch of the <a href="https://developers.google.com/ml-kit/vision/doc-scanner" target="_blank">ML Kit Document Scanner API</a>. This new API makes it easy to add advanced document scanning capabilities with a high-quality and consistent user interface to your Android app. The ML Kit Document Scanner API enables your users to quickly and easily digitize paper documents.</p>
<p>Like the other ML Kit APIs, the ML Kit Document Scanner API enables you to seamlessly integrate features powered by Machine Learning (ML) without any ML knowledge.</p>
<image><div style="text-align: center;"><img alt="ml kit document scanner illustration" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3HKj8jUfxGqQIjF_4IdTi5FHiFqJ0Lh-SZmVLV62K08SunYqiT13hozvG4x6Rkf2gF8IhMdp7a6ZzGUT_iObDSJzVXkuIbAD_PD9Yb2uBCnqWPQE6VNEj7wpqHkzCeVW7jN4fNi0spo3Tx0EV2V-rxlC_5GrlegWEzIeGEDq024Dir8LPCia8s4vctnE/s1600/image4.png" width="100%" /></div></image>
<h3>Why Document Scanner SDK?</h3>
<p>Despite the digital revolution, paper documents and printouts are still present in our everyday life. Some of our most important documents are still physical (identity documents, receipts, etc.).</p>
<p>The ML Kit Document Scanner API offers a number of benefits, including:</p>
<ul><ul>
<li>A high-quality and consistent user interface for digitizing physical documents.</li>
<li>Accurate document detection with precise corner and edge detection for a seamless scanning experience and optimal scanning results.</li>
<li>Flexible functionality allows users to crop scanned documents, apply filters, remove fingers, remove stains and other blemishes and send digitized files in PDF and JPEG formats back to your app.</li>
<li>On-device processing helps preserve privacy.</li>
<li>A complete solution eliminating the need for camera permission.</li>
</ul></ul>
<p>The ML Kit Document Scanner API is already used by Google Drive Android application and the Google Pixel Camera.</p>
<image><div style="text-align: center;"><img alt="moving image showing ML Kit Document scanner API in action in
Google Drive" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtQtiEsIs_LrwPwkt6LoySSeA9sEjbBraOfzsFlLEBi1OdCyeR7JJjH42KtkiaawCdBpAXEG_BgokdO4kE2iptk9TCgpC5ld8FURaEjqpu32tlROVDZbjRtgK3biAsSnrobbvAGJSJ2bJYH8h9uj6Y-zx1aJPRI8-fIaKv5Cgaco3Q5JBdZAGbcIL6ztY/s1600/docscan_demo.gif" width="50%" /></div><imgcaption><center><em>ML Kit Document scanner API in action in
Google Drive</em></center></imgcaption></image>
<h3>Get started</h3>
<p>The ML Kit Document Scanner API requires Android API level 21 or above. The models, scanning logic, and UI flow are dynamically downloaded via Google Play services so the ML Kit Document Scanner API has a minimal impact on your app size.</p>
<p>To integrate it in your app, start by configuring the scanner options and getting a scanner client:</p>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="font-family: courier;">val options <span style="color: #666666;">=</span> GmsDocumentScannerOptions<span style="color: #666666;">.</span>Builder()
<span style="color: #666666;">.</span>setGalleryImportAllowed(false)
<span style="color: #666666;">.</span>setPageLimit(<span style="color: #666666;">2</span>)
<span style="color: #666666;">.</span>setResultFormats(RESULT_FORMAT_JPEG, RESULT_FORMAT_PDF)
<span style="color: #666666;">.</span>setScannerMode(SCANNER_MODE_FULL)
<span style="color: #666666;">.</span>build()
val scanner <span style="color: #666666;">=</span> GmsDocumentScanning<span style="color: #666666;">.</span>getClient(options)</span>
</pre></div>
<p>Then register an <span style="color: #0d904f; font-family: Courier;">ActivityResultCallback</span> to receive the scanning results:</p>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="font-family: courier;">val scannerLauncher <span>=</span> registerForActivityResult(StartIntentSenderForResult()) {
result <span>-></span> {
<span>if</span> (result<span>.</span>resultCode <span>==</span> RESULT_OK) {
val result <span>=</span>
GmsDocumentScanningResult<span>.</span>fromActivityResultIntent(result<span>.</span>data)
result<span>.</span>getPages()<span>?.</span>let { pages <span>-></span>
<span>for</span> (page in pages) {
val imageUri <span>=</span> page<span>.</span>getImageUri()
}
}
result<span>.</span>getPdf()<span>?.</span>let { pdf <span>-></span>
val pdfUri <span>=</span> pdf<span>.</span>getUri()
val pageCount <span>=</span> pdf<span>.</span>getPageCount()
}
}
}
}</span>
</pre></div>
<p>Finally launch the document scanner activity:</p>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="font-family: courier;">scanner<span>.</span>getStartScanIntent(activity)
<span>.</span>addOnSuccessListener { intentSender <span>-></span>
scannescannerrLauncher<span>.</span>launch(IntentSenderRequest<span>.</span>Builder(intentSender)<span>.</span>build())
}
<span>.</span>addOnFailureListener { <span>...</span> }
</span></pre></div>
<p>To get started with the ML Kit Document Scanner API, visit the <a href="https://developers.google.com/ml-kit/vision/doc-scanner" target="_blank">documentation</a>. We can’t wait to see what you’ll build with it!</p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-91329093376189409252024-02-16T11:00:00.000-08:002024-02-16T11:01:28.289-08:00The First Developer Preview of Android 15<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDDCgXcu5EI9w514aJNVe4C1CciGCHkKn8lWUyaa_TK-HspfRAKoKvDAiMTbGZ-Y406y9W5sn4y-SEyGFiwbNlS7EScaVTMgSOVhuq2kUBwoaMX0KqdYSIdGRHfI7zpi7nm5ciPZVlS2cdTOb_xEeWVma4KVdGt2T2DmvkNFTIuWqFpgx8Fe5maN9TCPI/s1600/Android-15-DP1-Social%20%281%29.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDDCgXcu5EI9w514aJNVe4C1CciGCHkKn8lWUyaa_TK-HspfRAKoKvDAiMTbGZ-Y406y9W5sn4y-SEyGFiwbNlS7EScaVTMgSOVhuq2kUBwoaMX0KqdYSIdGRHfI7zpi7nm5ciPZVlS2cdTOb_xEeWVma4KVdGt2T2DmvkNFTIuWqFpgx8Fe5maN9TCPI/s1600/Android-15-DP1-Social%20%281%29.png" style="display: none;" />
<em> Posted by <a href="https://twitter.com/davey_burke" target="_blank">Dave Burke</a>, VP of Engineering </em>
<div class="separator" style="border: 0px; clear: both; float: right; padding: 0px; width: 45%;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX98TKIsaJF7D4wnq7YBOuMjtYH-6D5Kgm7m7VbRek7cQIGN7TNVtJMDIbSiEG5KgcGyGpgGxEOz7u9v-WhQASrQrjvCQF8-RQ7PsZpA6djqK7RA7mXrnt6aYiac8voLef_mhP-s_TucPVEP1vvmUBjspmjA2RdrbvIqVwYXQJZ1fwPyamJIxXTrgMVmg/s1600/image1.png" style="display: block; padding: 1em 0px; text-align: center;"><img alt="Android 14 logo" border="0" data-original-height="512" data-original-width="512" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgX98TKIsaJF7D4wnq7YBOuMjtYH-6D5Kgm7m7VbRek7cQIGN7TNVtJMDIbSiEG5KgcGyGpgGxEOz7u9v-WhQASrQrjvCQF8-RQ7PsZpA6djqK7RA7mXrnt6aYiac8voLef_mhP-s_TucPVEP1vvmUBjspmjA2RdrbvIqVwYXQJZ1fwPyamJIxXTrgMVmg/s1600/image1.png" width="320" /></a></div>
<p>We're releasing the first Developer Preview of Android 15 today so you, our developers, can collaborate with us to build a better Android.</p>
<p>Android 15 continues our work to build a platform that helps improve your productivity while giving you new capabilities to produce superior media experiences, minimize battery impact, maximize smooth app performance, and protect user privacy and security all on the most diverse lineup of devices out there.</p>
<p>Android enables your apps to take advantage of premium device hardware, including high-end camera capabilities, powerful GPUs, dazzling displays, and AI processing. The demand for large-screen devices, including tablets, foldables and flippables, continues to grow, offering an opportunity to reach high-value users. Also, Android is committed to providing tooling and libraries to help your apps take advantage of the latest advances in AI.</p>
<p>Your feedback on the Android 15 Developer Preview and QPR beta program plays a key role in helping Android continuously improve. The <a href="https://developer.android.com/about/versions/15" target="_blank">Android 15 developer site</a> has more information about the preview, including downloads for Pixel and detailed documentation about changes. This preview is just the beginning, and we’ll have lots more to share as we move through the release cycle. Thank you in advance for your help in making Android a platform that works for everyone.</p>
<h3><span style="font-size: x-large;">Protecting user privacy and security</span></h3>
<p>Android is constantly working to create solutions that maximize user privacy and security.</p>
<h3><span style="font-size: large;">Privacy Sandbox on Android</span></h3>
<p>Android 15 brings Android AD Services up to extension level 10, incorporating the latest version of the <a href="https://developer.android.com/design-for-safety/privacy-sandbox" target="_blank">Privacy Sandbox on Android</a>, part of our work to develop new technologies that improve user privacy and enable effective, personalized advertising experiences for mobile apps. Our <a href="https://developer.android.com/design-for-safety/privacy-sandbox/program-overview" target="_blank">website has more</a> about the Privacy Sandbox on Android developer preview and beta programs to help you get started.</p>
<h3><span style="font-size: large;">Health Connect</span></h3>
<p>Android 15 integrates Android 14 extensions 10 around <a href="https://developer.android.com/health-and-fitness/guides/health-connect/develop/get-started" target="_blank">Health Connect by Android</a>, a secure and centralized platform to manage and share app-collected health and fitness data. This update adds support for new data types across <a href="https://developer.android.com/reference/android/health/connect/datatypes/StepsCadenceRecord#STEPS_CADENCE_RATE_AVG" target="_blank">fitness</a>, <a href="https://developer.android.com/reference/android/health/connect/datatypes/NutritionRecord#TRANS_FAT_TOTAL" target="_blank">nutrition</a>, and more.</p>
<h3><span style="font-size: large;">File integrity</span></h3>
<p>Android 15's <span style="font-family: Courier;"><a href="https://developer.android.com/reference/android/security/FileIntegrityManager" target="_blank">FileIntegrityManager</a></span> includes new APIs that tap into the power of the <a href="https://docs.kernel.org/filesystems/fsverity.html" target="_blank">fs-verity</a> feature in the Linux kernel. With fs-verity, files can be <a href="https://developer.android.com/reference/android/security/FileIntegrityManager#setupFsVerity%28java.io.File%29" target="_blank">protected by custom cryptographic signatures</a>, helping you <a href="https://developer.android.com/reference/android/security/FileIntegrityManager#getFsVerityDigest%28java.io.File%29" target="_blank">ensure they haven't been tampered with or corrupted</a>. This leads to enhanced security, protecting against potential malware or unauthorized file modifications that could compromise your app's functionality or data.</p>
<h3><span style="font-size: large;">Partial screen sharing</span></h3>
<p>Android 15 supports partial screen sharing so users can share or record just an app window rather than the entire device screen. This feature, enabled first in Android 14 QPR2, includes <span style="font-family: Courier;"><a href="https://developer.android.com/about/versions/14/features/partial-screen-sharing#media_projection_callbacks" target="_blank"> MediaProjection</span> callbacks</a> that allow your app to customize the partial screen sharing experience. Note that <a href="https://developer.android.com/about/versions/14/behavior-changes-14#media-projection-consent" target="_blank">user consent is now required</a> for each <span style="font-family: Courier;"><a href="https://developer.android.com/reference/android/media/projection/MediaProjection" target="_blank">MediaProjection</a></span> capture session.</p>
<h3><span style="font-size: x-large;">Supporting creators</span></h3>
<p>Android continues its work to give you access to tools and hardware to support creators to bring their vision to life on Android.</p>
<h3><span style="font-size: large;">In-app Camera Controls</span></h3>
<p>Android 15 adds new extensions for more control over the camera hardware and its algorithms on supported devices:</p>
<ul><ul>
<li><b>Low light enhancements</b> that give developers control to <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE" target="_blank">boost the brightness of the camera preview.</a></li></ul><ul>
<li><b>Advanced flash strength adjustments</b> enabling precise control of flash intensity in both <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL" target="_blank">SINGLE</a> and <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics#FLASH_TORCH_STRENGTH_DEFAULT_LEVEL" target="_blank">TORCH</a> modes while capturing images.</li>
</ul></ul>
<h3><span style="font-size: large;">Virtual MIDI 2.0 Devices</span></h3>
<p>Android 13 added support for connecting to <a href="https://developer.android.com/reference/android/media/midi/package-summary" target="_blank">MIDI 2.0 devices via USB</a>, which communicate using Universal MIDI Packets (UMP). Android 15 extends <a href="https://developer.android.com/reference/android/media/midi/MidiUmpDeviceService" target="_blank">UMP support to virtual MIDI apps</a>, enabling composition apps to control synthesizer apps as a virtual MIDI 2.0 device just like they would with an USB MIDI 2.0 device.</p>
<h3><span style="font-size: x-large;">Performance and quality</span></h3>
<p>Android continues its focus on helping you improve the quality of your apps. Much of this focus is around tooling and libraries, including <a href="https://developer.android.com/jetpack/compose" target="_blank">Jetpack Compose</a>, <a href="https://developer.android.com/studio" target="_blank">Android Studio</a>, and more.</p>
<h3><span style="font-size: large;">Dynamic Performance</span></h3>
<p>Android 15 continues our investment in the <a href="https://developer.android.com/games/optimize/adpf" target="_blank">Android Dynamic Performance Framework (ADPF)</a>, a set of APIs that allow games and performance intensive apps to interact more directly with power and thermal systems of Android devices. On supported devices, Android 15 will add new ADPF capabilities:</p>
<ul><ul>
<li><b>A <a href="https://developer.android.com/reference/android/os/PerformanceHintManager.Session#setPreferPowerEfficiency%28boolean%29" target="_blank">power-efficiency mode</a></b> for hint sessions to indicate that their associated threads should prefer power saving over performance, great for long-running background workloads.</li></ul><ul>
<li><b>GPU and CPU work durations</b> can both be <a href="https://developer.android.com/reference/android/os/PerformanceHintManager.Session#reportActualWorkDuration%28android.os.WorkDuration%29" target="_blank">reported</a> in hint sessions, allowing the system to adjust CPU and GPU frequencies together to best meet workload demands.</li></ul><ul>
<li><b><a href="https://developer.android.com/reference/android/os/PowerManager#getThermalHeadroomThresholds%28%29" target="_blank">Thermal headroom thresholds</a></b> to interpret possible thermal throttling status based on headroom prediction.</li>
</ul></ul>
<p>To learn more about how to use ADPF in your apps and games, <a href="https://developer.android.com/games/optimize/adpf" target="_blank">head over to the documentation</a>.</p>
<h3><span style="font-size: x-large;">Developer Productivity</span></h3>
<p>Android 15 continues to add OpenJDK APIs, including quality-of-life improvements around <a href="https://developer.android.com/reference/java/nio/ByteBuffer#get%28int,%20byte[]%29" target="_blank">NIO buffers</a>, <a href="https://developer.android.com/reference/java/util/stream/DoubleStream.DoubleMapMultiConsumer" target="_blank">streams</a>, <a href="https://developer.android.com/reference/javax/security/auth/x500/X500PrivateCredential" target="_blank">security</a>, and more. These APIs are updated on <a href="https://android-developers.googleblog.com/2023/11/the-secret-to-androids-improved-memory-latest-android-runtime-update.html" target="_blank">over a billion devices running Android 12+ through Google Play System updates</a>, so you can target the latest programming features.</p>
<h3><span style="font-size: x-large;">App compatibility</span></h3>
<image><div style="text-align: center;"><img alt="Image of Android 15 Development timeline, indicating we are on time with Developer Previews in February" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjorrv3MG899Rr4AvPI0rRj3UrXpg_O2qDcKpCXekB11JGPO5hDJgqUvvy9aZ10eusam_4cNx8zzRb8rfCv1pRsgkSWH1yFuUTr-G97i8u4SrsBey8KzWdeJi1lUpXSq7x52hoApa2GNCnSfFjeMN4eEwFasWb1IaO8rAZFJYqY9mcC7uj1b4ncp1EQzyY/s1600/image2.png" width="100%" /></div></image><br />
<p>To give you more time to plan for app compatibility work, we’re letting you know our Platform Stability milestone well in advance.</p>
<p>At this milestone, we’ll deliver final SDK/NDK APIs and also final internal APIs and app-facing system behaviors. We’re expecting to reach Platform Stability in June 2024, and from that time you’ll have several months before the official release to do your final testing. The release timeline details are <a href="https://developer.android.com/about/versions/15/overview#timeline" target="_blank">here</a>.</p>
<h2><span style="font-size: x-large;">Get started with Android 15</span></h2>
<p>The Developer Preview has everything you need to try the Android 15 features, test your apps, and give us feedback. You can get started today by <a href="https://developer.android.com/about/versions/15/get#pixel_flash_install" target="_blank">flashing a system image</a> onto a Pixel 6, 7, or 8 series device, along with the Pixel Fold and Pixel Tablet. If you don’t have a Pixel device, you can <a href="https://developer.android.com/about/versions/15/get#on_emulator" target="_blank">use the 64-bit system images with the Android Emulator</a> in Android Studio.</p>
<p>For the best development experience with Android 15, we recommend that you use the <a href="https://developer.android.com/studio/preview" target="_blank">latest preview of Android Studio Jellyfish</a> (or more recent Jellyfish+ versions). Once you’re set up, here are some of the things you should do:</p>
<ul><ul>
<li>Try the new features and APIs – your feedback is critical during the early part of the developer preview. Report issues in our tracker on the <a href="https://developer.android.com/about/versions/15/feedback" target="_blank">feedback page</a>.</li></ul><ul>
<li>Test your current app for compatibility – learn whether your app is affected by changes in Android 15; install your app onto a device or emulator running Android 15 and extensively test it.</li>
</ul></ul>
<p>We’ll update the preview system images and SDK regularly throughout the Android 15 release cycle. This initial preview release is for developers only and not intended for daily or consumer use, so we're making it available by manual download only. Once you’ve manually installed a preview build, you’ll automatically get future updates over-the-air for all later previews and Betas. Read more <a href="https://developer.android.com/about/versions/15/overview#pixel" target="_blank">here</a>.</p>
<p>If you intend to move from the <a href="https://developer.android.com/about/versions/14/get-qpr" target="_blank">Android 14 QPR Beta program</a> to the Android 15 Developer Preview program and don't want to have to wipe your device, we recommend that you move to Developer Preview 1 now. Otherwise you may run into time periods where the Android 14 Beta will have a more recent build date which will prevent you from going directly to the Android 15 Developer Preview without doing a data wipe.</p>
<p>As we reach our Beta releases, we'll be inviting consumers to try Android 15 as well, and we'll open up enrollment for the Android Beta program at that time. For now, please note that the Android Beta program is not yet available for Android 15.</p>
<p>For complete information, visit the <a href="https://developer.android.com/about/versions/15" target="_blank">Android 15 developer site</a>.</p><br />
<p><small><em>Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.</em></small></p>Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-48368964551405940232024-02-14T09:00:00.000-08:002024-02-14T09:03:32.236-08:00#WeArePlay | How two sea turtle enthusiasts are revolutionizing marine conservation<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu218W2RyLDMAvOEcTDjLxA2tjNEFk6822pJCEX1uklhlS4xpUn4A5pQbmDLsnUgOC_Vfzy1stegKYeBgy0jdWOCimNm_I9eTkUg1l5lJRk0ASIaaZxda23M1MU6HvxT5yLhxzdzNMCRU3j457Tn6g7RLBLWs7sAvwCa3u0ytAAt_WUpmpGRM-HCmzGjA/s1600/%23WeArePlay%20Social%20.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu218W2RyLDMAvOEcTDjLxA2tjNEFk6822pJCEX1uklhlS4xpUn4A5pQbmDLsnUgOC_Vfzy1stegKYeBgy0jdWOCimNm_I9eTkUg1l5lJRk0ASIaaZxda23M1MU6HvxT5yLhxzdzNMCRU3j457Tn6g7RLBLWs7sAvwCa3u0ytAAt_WUpmpGRM-HCmzGjA/s1600/%23WeArePlay%20Social%20.png" style="display: none;" />
<em>Posted by Leticia Lago – Developer Marketing</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfkoyiV0Ohxbe89HXqSsLkj4WD8ADd5AmwhHRv4MyMdbrm11cE1wn-SnjSYjsmWupfwZDt6FhaV_-kWQJ1AdObLCTglDqkO1V_Uo6z7S14NpYbQyWzxaDNOMK3fEa2_k25zNk-kQIkDI21X8YjGyoKu-Nnuptx1YYyd6nXmIxC4bPJQl0iHBj2dMD2nI4/s1600/%23WeArePlay%20Banner.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfkoyiV0Ohxbe89HXqSsLkj4WD8ADd5AmwhHRv4MyMdbrm11cE1wn-SnjSYjsmWupfwZDt6FhaV_-kWQJ1AdObLCTglDqkO1V_Uo6z7S14NpYbQyWzxaDNOMK3fEa2_k25zNk-kQIkDI21X8YjGyoKu-Nnuptx1YYyd6nXmIxC4bPJQl0iHBj2dMD2nI4/s1600/%23WeArePlay%20Banner.png" /></a>
<a name='more'></a><p></p>
<iframe class="BLOG_video_class" allowfullscreen="" youtube-src-id="CfzhLOiczDQ" width="100%" height="400" src="https://www.youtube.com/embed/CfzhLOiczDQ"></iframe>
<p>When environmental science student Caitlin returned home from a trip monitoring sea turtles in Western Australia, she was inspired to create a conservation tool that could improve tracking of the species. She connected with a French developer and fellow marine life enthusiast Nicolas to design their app <a href="https://play.google.com/store/apps/details?id=fr.altplusun.we_spot_turtles&hl=en&gl=US" target="_blank">We Spot Turtles!</a>, allowing anyone to support tracking efforts by uploading pictures of them spotted in the wild.</p>
<p>Caitlin and Nicolas shared their journey in our latest film for <a href="https://play.google.com/console/about/weareplay/" target="_blank">#WeArePlay</a>, which showcases the amazing stories behind apps and games on Google Play. We caught up with the pair to find out more about their passion and how they are making strides towards advancing sea turtle conservation. </p>
<h4><span style="font-size: large;">Tell us about how you both got interested in sea turtle conservation?</span></h4>
<p><b>Caitlin:</b> A few years ago, I did a sea turtle monitoring program for the Department of Biodiversity, Conservation and Attractions in Western Australia. It was probably one of the most magical experiences of my life. After that, I decided I only really wanted to work with sea turtles.</p>
<p><b>Nicolas:</b> In 2010, in French Polynesia, I volunteered with a sea turtle protection project. I was moved by the experience, and when I came back to France, I knew I wanted to use my tech background to create something inspired by the trip.</p>
<h4><span style="font-size: large;">How did these experiences lead you to create We Spot Turtles!?</span></h4>
<p><b>Caitlin:</b> There are seven species of sea turtle, and all are critically endangered. Or rather there’s not enough data on them to inform an accurate endangerment status. This means the needs of the species are going unmet and sea turtles are silently going extinct. Our inspiration is essentially to better track sea turtles so that conservation can be improved. </p>
<p><b>Nicolas:</b> When I returned to France after monitoring sea turtles, I knew I wanted to make an app inspired by my experience. However, I had put the project on hold for a while. Then, when a friend sent me Caitlin’s social media post looking for a developer for a sea turtle conservation app, it re-ignited my inspiration, and we teamed up to make it together.</p>
<image><div style="text-align: center;"><img id="imgFull" alt="close up image of a turtle resting in a reef underwater" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3dDXPA6FttMfzWiVw9cIXMWzS-Nzd_NWfDLUnjnShQV9rSVRnp1sJIaboQNG7z_nWrNfWjFrfu3KotnVb549sKwmH7m3adi873ADr11snns0Hg8Ew72jwTpLPuG2WNbgEMH0l62-sBXK0soMmUgtrak5EEyDRwCKrI79rSqHCvHVCqb5RXGog0aoi2XY/s1600/image3.png" width="100%"/></div></image>
<h4><span style="font-size: large;">What does We Spot Turtles! do?</span></h4>
<p><b>Caitlin:</b> Essentially, members of the public upload images of sea turtles they spot – and even get to name them. Then, the app automatically geolocates, giving us a date and timestamp of when and where the sea turtle was located. This allows us to track turtles and improve our conservation efforts.</p>
<h4><span style="font-size: large;">How do you use artificial intelligence in the app?</span></h4>
<p><b>Caitlin:</b> The advancements in AI in recent years have given us the opportunity to make a bigger impact than we would have been able to otherwise. The machine learning model that Nicolas created uses the facial scale and pigmentations of the turtles to not only identify its species, but also to give that sea turtle a unique code for tracking purposes. Then, if it is photographed by someone else in the future, we can see on the app where it's been spotted before.</p>
<h4><span style="font-size: large;">How has Google Play supported your journey?</span></h4>
<p><b>Caitlin:</b> Launching our app on Google Play has allowed us to reach a global audience. We now have communities in Exmouth in Western Australia, Manly Beach in Sydney, and have 6 countries in total using our app already. Without Google Play, we wouldn't have the ability to connect on such a global scale.</p>
<p><b>Nicolas:</b> I’m a mobile application developer and I use Google’s Flutter framework. I knew Google Play was a good place to release our title as it easily allows us to work on the platform. As a result, we’ve been able to make the app great.</p>
<image><div style="text-align: center;"><img id="imgFull" alt="Photo pf Caitlin and Nicolas on the bach in Australia at sunset. Both are kneeling in the sand. Caitlin is using her phone to identify something in the distance, and gesturing to Nicolas who is looking in the same direction" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4oAr8typ6jmDgb9oFV6f0AwCnp6vItKolavM-MGc-8nZCgaajFILzRDzMmN1OZNrTXUTxzwiGwKI8padd_Zl-HcGq-BaYm6EH8br4zSvH9hufBq0eHcOzSid_F6Qv3WiMTGZwzbx_pqdJCotyFGCWUmS0f4MJ4pg4iAxgODF3_DkVfakEprPwSnsTHqw/s1600/unnamed%20%2812%29.jpg" width="100%"/></div></image>
<h4><span style="font-size: large;">What do you hope to achieve with We Spot Turtles!?</span></h4>
<p><b>Caitlin:</b> We Spot Turtles! puts data collection in the hands of the people. It’s giving everyone the opportunity to make an impact in sea turtle conservation. Because of this, we believe that we can massively alter and redefine conservation efforts and enhance people’s engagement with the natural world.</p>
<h4><span style="font-size: large;">What are your plans for the future?</span></h4>
<p><b>Caitlin:</b> Nicolas and I have some big plans. We want to branch out into other species. We'd love to do whale sharks, birds, and red pandas. Ultimately, we want to achieve our goal of improving the conservation of various species and animals around the world. </p><br/>
<p>Discover other inspiring app and game founders featured in <a href="https://play.google.com/console/about/weareplay/" target="_blank">#WeArePlay</a>.</p>
<br /><br />
<p></p><center>
How useful did you find this blog post?
</center><p></p>
<p></p><center>
<a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=1%E2%98%85+%E2%80%93+Not+at+all&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=2%E2%98%85+%E2%80%93+Not+very&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=3%E2%98%85+%E2%80%93+Somewhat&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=4%E2%98%85+%E2%80%93+Very&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=5%E2%98%85+%E2%80%93+Extremely&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a>
</center><p></p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxnvf5XzyebGljqgi8J7by9XsvaL5WWLNamSyTg4w_c0kPHjY1B1no1FQsdSfUHUwNw0UuYfXuo6i7K6VpdyV2-K8ms4VFmZA438ujm6qwtZMt5rJfMGymhQ_iCX2Z8h0MuJo7gXUQ4Hb-hjKYK1isibMZZxCyX_vo3kGoP5tieK2PI2ZhYdGh4gsqhwA/s260/lockup_ic_Google_Play_H_260x53px_clr.png" style="display: block; padding: 1em 0px; text-align: center;"><img alt="" border="0" data-original-height="53" data-original-width="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxnvf5XzyebGljqgi8J7by9XsvaL5WWLNamSyTg4w_c0kPHjY1B1no1FQsdSfUHUwNw0UuYfXuo6i7K6VpdyV2-K8ms4VFmZA438ujm6qwtZMt5rJfMGymhQ_iCX2Z8h0MuJo7gXUQ4Hb-hjKYK1isibMZZxCyX_vo3kGoP5tieK2PI2ZhYdGh4gsqhwA/s200/lockup_ic_Google_Play_H_260x53px_clr.png" width="200" /></a></div>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-49593643734321722312024-02-13T09:00:00.000-08:002024-02-13T09:00:00.128-08:00Cloud photos now available in the Android photo picker<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBQ5LxLRpc0YSVGD1WcneUtl1bT-ieccmHkAh0rKAxWgRnm_8iUeDqpOXhJaESAuskzqGO8Z8fxMbqO1WezffgdJEPKPCBpKtCnta07ISgTq0pZ_dHEyZTNY30w8K6gs3Oa1Ep9iYW7SbpGS0w1pdlQDfie9n5HTh8EiswgcbDPOWWK_eJ15IAd9H2-4c/s1600/social-Cloud-photos-now-available-in-the-Android-photo-picker.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBQ5LxLRpc0YSVGD1WcneUtl1bT-ieccmHkAh0rKAxWgRnm_8iUeDqpOXhJaESAuskzqGO8Z8fxMbqO1WezffgdJEPKPCBpKtCnta07ISgTq0pZ_dHEyZTNY30w8K6gs3Oa1Ep9iYW7SbpGS0w1pdlQDfie9n5HTh8EiswgcbDPOWWK_eJ15IAd9H2-4c/s1600/social-Cloud-photos-now-available-in-the-Android-photo-picker.png" style="display: none;" />
<em>Posted by Roxanna Aliabadi Walker – Product Manager</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2qtvzDbbpQYf6oabNpfi_xV8ruIeWVieC4DPGUjuhHDgIi_nXKtzLqIIskpCGHDrWJsf9fMzkjOJwmPKlYg-Xxe6CimjzeLtlQ-VH6six6aTp7Dkw2EsYPil6iyHZ2uZSuD_sbhTBVogXn55dwkoFmfce6a-w4lsXQ4O6Twbaj2kOyEebL2o4m3mh3Z4/s1600/header-Cloud-photos-now-available-in-the-Android-photo-picker.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2qtvzDbbpQYf6oabNpfi_xV8ruIeWVieC4DPGUjuhHDgIi_nXKtzLqIIskpCGHDrWJsf9fMzkjOJwmPKlYg-Xxe6CimjzeLtlQ-VH6six6aTp7Dkw2EsYPil6iyHZ2uZSuD_sbhTBVogXn55dwkoFmfce6a-w4lsXQ4O6Twbaj2kOyEebL2o4m3mh3Z4/s1600/header-Cloud-photos-now-available-in-the-Android-photo-picker.png" /></a>
<h2>Available now with Google Photos</h2>
<p>Our photo picker has always been the gateway to your local media library, providing a secure, date-sorted interface for users to grant apps access to selected images and videos. But now, we're taking it a step further by integrating cloud photos from your chosen cloud media app directly into the photo picker experience.</p>
<image><div style="text-align: center;"><img alt="Moving image of the photo picker access" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGHAB8sdmGvT9ly9YMYMQdE9xVHKrgu_CeZMBIlWAIlUbyzapQmhc2xPT1uRxH1El2UoYWXTM3goBjLbHz4dPOphia_UJnWd3cogWRW7QALorWnIS5Oymdc7tTktlfi1pdP4eFjPbUxhaKabuWvYFmIo4rW2J-2zORBt4hnkoGAGHtxQGVx45DbJjd0BU/s1600/image2.gif" width="40%" /></div></image>
<h3>Unifying your media library</h3>
<p>Backed-up photos, also known as "cloud photos," will now be merged with your local ones in the photo picker, eliminating the need to switch between apps. Additionally, any albums you've created in your cloud storage app will be readily accessible within the photo picker's albums tab. If your cloud media provider has a concept of “favorites,” they will be showcased prominently within the albums tab of the photo picker for easy access. This feature is currently rolling out with the February <a href="https://support.google.com/product-documentation/answer/11462338" target="_blank">Google System Update</a> to devices running Android 12 and above.</p>
<h3>Available now with Google Photos, but open to all</h3>
<p>Google Photos is already supporting this new feature, and our APIs are open to any cloud media app that qualifies for our <a href="https://developer.android.com/guide/topics/providers/cloud-media-provider#eligibility" target="_blank">pilot program</a>. Our goal is to make accessing your lifetime of memories effortless, regardless of the app you prefer.</p>
<p>The Android photo picker will attempt to auto-select a cloud media app for you, but you can change or remove your selected cloud media app at any time from photo picker settings.</p>
<image><div style="text-align: center;"><img alt="Image of Cloud media settings in photo picker settings" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXyy2UZb-JKDSR0Whhi7fImAYHaAxTtnqA1gGfWCESzZ8WJsH-7X_Yd0fsg965WSrnb612yIA2eIsvapfmEg7aBUM2j8HbLGfyGjr_KN-TTij08WuXdLsCN7ewZW6G5i-5QyhKl7nRuGhSVSV8a7r310j3YiuKjyCcKNA4AfxzheJCHZPjDUl_ByXsgoY/s1600/image1.png" width="40%" /></div></image>
<h3>Migrate today for an enhanced, frictionless experience</h3>
<p>The Android photo picker substantially reduces friction by not requiring any runtime permissions. If you switch from using a custom photo picker to the Android photo picker, you can offer this enhanced experience with cloud photos to your users, as well as reduce or entirely eliminate the overhead involved with acquiring and managing access to photos on the device. (Note that apps without a need for persistent and/or broad scale access to photos - for example - to set a profile picture, must adopt the Android photo picker in lieu of any sensitive file permissions to adhere to <a href="https://support.google.com/googleplay/android-developer/answer/14115180?hl=en" target="_blank">Google Play policy</a>).</p>
<p>The photo picker has been backported to Android 4.4 to make it easy to migrate without needing to worry about device compatibility. Access to cloud content will only be available for users running Android 12 and higher, but developers do not need to consider this when implementing the photo picker into their apps. To use the photo picker in your app, update the ActivityX dependency to version 1.7.x or above and add the following code snippet:</p>
<!--HTML generated using hilite.me--><div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #666666; font-family: courier;"><span>//</span> Registers a photo picker activity launcher in single<span>-</span><span>select</span> mode<span>.</span>
val pickMedia <span>=</span> registerForActivityResult(PickVisualMedia()) { uri <span>-></span>
<span>//</span> Callback is invoked after the user selects a media item <span>or</span> closes the
<span>//</span> photo picker<span>.</span>
<span>if</span> (uri <span>!=</span> null) {
<span>Log</span><span>.</span>d(<span>"PhotoPicker"</span>, <span>"Selected URI: $uri"</span>)
} <span>else</span> {
<span>Log</span><span>.</span>d(<span>"PhotoPicker"</span>, <span>"No media selected"</span>)
}
}
<span>//</span> Launch the photo picker <span>and</span> let the user choose images <span>and</span> videos<span>.</span>
pickMedia<span>.</span>launch(PickVisualMediaRequest(PickVisualMedia<span>.</span>ImageAndVideo))
<span>//</span> Launch the photo picker <span>and</span> let the user choose only images<span>.</span>
pickMedia<span>.</span>launch(PickVisualMediaRequest(PickVisualMedia<span>.</span>ImageOnly))
<span>//</span> Launch the photo picker <span>and</span> let the user choose only videos<span>.</span>
pickMedia<span>.</span>launch(PickVisualMediaRequest(PickVisualMedia<span>.</span>VideoOnly))</span>
</pre></div>
<p>More customization options are listed in our <a href="https://developer.android.com/training/data-storage/shared/photopicker" target="_blank">developer documentation</a>. </p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-82214668467633621872024-01-29T12:00:00.000-08:002024-01-29T12:02:09.602-08:00Prompt users to update to your latest app version<meta name="twitter:image" content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwi55LqdnkRzHbxQ1vXKgXV6wAKcoL_Hu-WmkBhYJMDokuy9ii9kOv3NBeh6138uzbCBhNumHiAfs2bPdqBdd0XXEgkNxo0vzUbmDX5V-k0oCxgBYffsqcPvlYVLFjiHVdfb_PBnwHbdOYhy9t35X6FuOCQ3xvEeXarHBI9we_pqkdakp8ccje5Wh5n4E/s1600/SOCIAL-Prompt-users-on-the-outdated-versions-to-update.png">
<img style="display:none" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwi55LqdnkRzHbxQ1vXKgXV6wAKcoL_Hu-WmkBhYJMDokuy9ii9kOv3NBeh6138uzbCBhNumHiAfs2bPdqBdd0XXEgkNxo0vzUbmDX5V-k0oCxgBYffsqcPvlYVLFjiHVdfb_PBnwHbdOYhy9t35X6FuOCQ3xvEeXarHBI9we_pqkdakp8ccje5Wh5n4E/s1600/SOCIAL-Prompt-users-on-the-outdated-versions-to-update.png">
<em>Posted by Lidia Gaymond – Product Manager, Google Play</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVf1xFfP7lv0klpYSL7CyQ7KvpPFIWmRSwS2JHzzeLy43LkVZp82t1EpFkbLcTQMcPNOpxtWv8ntPTglOpjnutQ4Sn8nUzgMbiRBZMBKlHGIte6DjxAg_oP2PWrbTQ1dd-YXSgvRcrlm1gpDWU7Dju5Yc8ecMCIdvFr11gnd5AMO4nDQ3EKFUouM3z-vs/s1600/HEADER-Prompt-users-on-the-outdated-versions-to-update.png" imageanchor="1" ><img style="100%" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVf1xFfP7lv0klpYSL7CyQ7KvpPFIWmRSwS2JHzzeLy43LkVZp82t1EpFkbLcTQMcPNOpxtWv8ntPTglOpjnutQ4Sn8nUzgMbiRBZMBKlHGIte6DjxAg_oP2PWrbTQ1dd-YXSgvRcrlm1gpDWU7Dju5Yc8ecMCIdvFr11gnd5AMO4nDQ3EKFUouM3z-vs/s1600/HEADER-Prompt-users-on-the-outdated-versions-to-update.png" data-original-width="100%" data-original-height="800" /></a>
<p>For years, Google Play has helped users enjoy the latest versions of your app through auto-updates or in-app updates. While most users update their apps this way, some may still be stuck on outdated, unsupported or broken versions of your app.</p>
<p>Today, we are introducing <a href="https://support.google.com/googleplay/android-developer/answer/13812041?hl=en" target="_blank">a new tool that will prompt these users to update</a>, bringing them closer to the app experience you intended to deliver.</p>
<p>Play recovery tools allow you to prompt users running specific versions of your app to update every time they restart the app.</p>
<image><div style="text-align: center;"><img id="imgFull" alt="Image of side by side mobile device screens showing how the prompt to update may look to users" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGEW0NLEbNjbJmx__iwYKDa1DFnLdhb4d85qEO3p0qzYUmagntSE-lyRLK4PXmlZ0w08dIPhj1oU6_nWC_X7ZOGHnNt0S1QB_YhUD4AaCZZvDQ9Oa3wOef6U4EWgj8YWiEsjMgNoqs7kvY3QFDUAY5eg9wB6RBgHBox7oIKFhqRuuk7Ifv9HtP0MEg5Ms/s1600/image1.png" width="80%"/></div></image><imgcaption><center><em><b>Note:</b> Images are examples and subject to change</em></center></imgcaption><br/>
<p>To use this new feature, log into <a href="http://play.google.com/console" target="_blank">Google Play Console</a> and head to your Releases or to the App Bundle Explorer page, where you can select the app versions where you want to deliver the prompts. Alternatively, the feature is also available via the <a href="https://developers.google.com/android-publisher/api-ref/rest/v3/apprecovery/create" target="_blank">Play Developer API</a>, and will soon be extended to allow you to target multiple app versions at once. Please note that the version you want to deploy the prompt to needs to be built as an <a href="https://developer.android.com/guide/app-bundle" target="_blank">app bundle</a>.</p>
<p>You can then narrow your targeting criteria by country or Android version (if required), with no prior integration necessary.</p>
<p>Currently, over 50% of users are responding to the prompts, enabling more users to get the best experience of your apps.</p>
<p>After prompting users to update, you can use Play Console's recovery tools to edit your update configuration, view its progress, or cancel the recovery action altogether. Learn more about the feature <a href="https://support.google.com/googleplay/android-developer/answer/13812041?hl=en" target="_blank">here</a> and start using it today!</p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-26353791551200167592024-01-24T10:00:00.000-08:002024-01-24T14:04:34.886-08:00What’s new in the Jetpack Compose January ’24 release<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-sgaGzqJRAKlh8sK-7EWuecz5XrF8xLEt8iO9WKIFtWU2A8ExBX8L2cfdMDVwUOLEksbK1CZEH6XxXYUCKSE_LMK2T_M3VgViAQNzmgImLwjzQmeN4X9YqBqzsAV_IaiGedzOvySLGAmob66cCd5udbIV44-Py9GTHlZbJlFOD4QhY3pmjypddw8_5Jo/s1600/Social%20-%20Android%20-%20Jetpack%20Compose%20January%20%E2%80%9924.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-sgaGzqJRAKlh8sK-7EWuecz5XrF8xLEt8iO9WKIFtWU2A8ExBX8L2cfdMDVwUOLEksbK1CZEH6XxXYUCKSE_LMK2T_M3VgViAQNzmgImLwjzQmeN4X9YqBqzsAV_IaiGedzOvySLGAmob66cCd5udbIV44-Py9GTHlZbJlFOD4QhY3pmjypddw8_5Jo/s1600/Social%20-%20Android%20-%20Jetpack%20Compose%20January%20%E2%80%9924.png" style="display: none;" />
<em>Posted by <a href="https://twitter.com/bentrengrove" target="_blank">Ben Trengrove</a>, Android Developer Relations Engineer</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsWOsYH-CFQ6aJ5erNZvo0gEXZx1pMDDT9HoKtam9wBAfMC5ZPxt1DYn_VSjqAN1PMMNnVwueLDXV_v4ByjN1rjvDHeRyuJn95up0tFNuCIzbENjbvqbOVz3I1Iy7aVTzlOLtSAnADNutrwrTrzAcDOU-aadSvd15QXbjapcJpQF-_p-jKc13NMuqHBzQ/s1600/Header%20-%20Android%20-%20Jetpack%20Compose%20January%20%E2%80%9924.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsWOsYH-CFQ6aJ5erNZvo0gEXZx1pMDDT9HoKtam9wBAfMC5ZPxt1DYn_VSjqAN1PMMNnVwueLDXV_v4ByjN1rjvDHeRyuJn95up0tFNuCIzbENjbvqbOVz3I1Iy7aVTzlOLtSAnADNutrwrTrzAcDOU-aadSvd15QXbjapcJpQF-_p-jKc13NMuqHBzQ/s1600/Header%20-%20Android%20-%20Jetpack%20Compose%20January%20%E2%80%9924.png" /></a>
<p>Today, as part of the <a href="https://developer.android.com/jetpack/androidx/releases/compose" target="_blank">Compose January ‘24 Bill of Materials</a>, we’re releasing version 1.6 of <a href="https://d.android.com/compose" target="_blank">Jetpack Compose</a>, Android's modern, native UI toolkit that is <a href="https://developer.android.com/jetpack/compose#apps-built-with-compose" target="_blank">used by apps</a> such as <a href="https://android-developers.googleblog.com/2023/10/meta-built-threads-in-only-5-months-using-jetpack-compose.html" target="_blank">Threads</a>, <a href="https://www.youtube.com/watch?v=Hb5vWCwPmfE&list=PLWz5rJ2EKKc9ECua7vzYbowdn-0L8WwHL&index=9" target="_blank">Reddit</a>, and <a href="https://www.youtube.com/watch?v=quY2B_6shy0" target="_blank">Dropbox</a>. This release largely focuses on performance improvements, as we continue to migrate modifiers and improve the efficiency of major parts of our API.</p>
<p>To use today’s release, upgrade your Compose BOM version to <span style="font-family: courier;">2024.01.00</span></p>
<div align="left" dir="ltr" style="margin-left: 0pt;"><table style="border-collapse: collapse; border: none;"><colgroup></colgroup><tbody><tr style="height: 0pt;"><td style="background-color: #f0f0f0; border-bottom: solid #e0e0e0 1pt; border-color: rgb(224, 224, 224); border-left: solid #e0e0e0 1pt; border-right: solid #e0e0e0 1pt; border-style: solid; border-top: solid #e0e0e0 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: courier;"><span style="background-color: transparent; color: #0d904f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">implementation platform('androidx.compose:compose-bom:2024.01.00')</span><br /></span></p></td></tr></tbody></table></div>
<h3>Performance</h3>
<p>Performance continues to be our top priority, and this release of Compose has major performance improvements across the board. We are seeing an additional <b>~20% improvement in scroll performance</b> and ~12% improvement to startup time in our benchmarks, and this is on top of the improvements from the <a href="https://android-developers.googleblog.com/2023/08/whats-new-in-jetpack-compose-august-23-release.html" target="_blank">August ‘23</a> release. As with that release, most apps will see these benefits just by upgrading to the latest version, with no other code changes needed.</p>
<p>The improvement to scroll performance and startup time comes from our continued focus on memory allocations and lazy initialization, to ensure the framework is only doing work when it has to. These improvements can be seen across all APIs in Compose, especially in text, clickable, Lazy lists, and graphics APIs, including vectors, and were made possible in part by the Modifier.Node refactor work that has been ongoing for multiple releases.</p>
<p>There is also <a href="https://developer.android.com/jetpack/compose/custom-modifiers" target="_blank">new guidance</a> for you to create your own custom modifiers with Modifier.Node.</p>
<h4><span style="font-size: large;">Configuring the stability of external classes</span></h4>
<p>Compose compiler 1.5.5 introduces a new compiler option to provide a configuration file for what your app considers <a href="https://developer.android.com/jetpack/compose/performance/stability" target="_blank">stable</a>. This option allows you to mark any class as stable, including your own modules, external library classes, and standard library classes, without having to modify these modules or wrap them in a stable wrapper class. Note that the standard stability contract applies; this is just another convenient method to let the Compose compiler know what your app should consider stable. For more information on how to use stability configuration, see our <a href="https://developer.android.com/jetpack/compose/performance/stability/fix#configuration-file" target="_blank">documentation</a>.</p>
<h4><span style="font-size: large;">Generated code performance</span></h4>
<p>The code generated by the Compose compiler plugin has also been improved. Small tweaks in this code can lead to large performance improvements due to the fact the code is generated in every composable function. The Compose compiler tracks Compose state objects to know which composables to recompose when there is a change of value; however, many state values are only read once, and some state values are never read at all but still change frequently! This update allows the compiler to skip the tracking when it is not needed.</p>
<p>Compose compiler 1.5.6 also <a href="https://developer.android.com/jetpack/androidx/releases/compose-compiler#1.5.6" target="_blank">enables “intrinsic remember”</a> by default. This mode transforms <span style="color: #0d904f; font-family: courier;">remember</span> at compile time to take into account information we already have about any parameters of a composable that are used as a key to <span style="color: #0d904f; font-family: courier;">remember</span>. This speeds up the calculation of determining if a remembered expression needs reevaluating, but also means if you place a breakpoint inside the <span style="color: #0d904f; font-family: courier;">remember</span> function during debugging, it may no longer be called, as the compiler has removed the usage of <span style="color: #0d904f; font-family: courier;">remember</span> and replaced it with different code.</p>
<h4><span style="font-size: large;">Composables not being skipped</span></h4>
<p>We are also investing in making the code you write more performant, automatically. We want to optimize for the code you intuitively write, removing the need to dive deep into Compose internals to understand why your composable is recomposing when it shouldn’t.</p>
<p>This release of Compose adds support for an experimental mode we are calling “<b>strong skipping mode</b>”. Strong skipping mode relaxes some of the rules about which changes can skip recomposition, moving the balance towards what developers expect. With strong skipping mode enabled, composables with unstable parameters can also skip recomposition if the same instances of objects are passed in to its parameters. Additionally, strong skipping mode automatically remembers lambdas in composition that capture unstable values, in addition to the current default behavior of remembering lambdas with only stable captures. Strong skipping mode is currently experimental and disabled by default as we do not consider it ready for production usage yet. We are evaluating its effects before aiming to turn it on by default in Compose 1.7. See our <a href="https://android.googlesource.com/platform/frameworks/support/+/androidx-main/compose/compiler/design/strong-skipping.md" target="_blank">guidance</a> to experiment with strong skipping mode and help us find any issues.</p>
<h3>Text</h3>
<h4><span style="font-size: large;">Changes to default font padding</span></h4>
<p>This release now makes the <span style="color: #0d904f; font-family: courier;">includeFontPadding</span> setting <span style="color: #0d904f; font-family: courier;">false</span> by default. <span style="color: #0d904f; font-family: courier;">includeFontPadding</span> is a legacy property that adds extra padding based on font metrics at the top of the first line and bottom of the last line of a text. Making this setting default to false brings the default text layout more in line with common design tools, making it easier to match the design specifications generated. Upon upgrading to the January ‘24 release, you may see small changes in your text layout and screenshot tests. For more information about this setting, see the <a href="https://medium.com/androiddevelopers/fixing-font-padding-in-compose-text-768cd232425b" target="_blank">Fixing Font Padding in Compose Text</a> blog post and the <a href="https://developer.android.com/jetpack/compose/text/style-paragraph#adjust-line-height" target="_blank">developer documentation</a>.</p>
<image><div style="text-align: center;"><img alt="Line height with includeFontPadding as false on the left and true on the right." border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZSSRPeWAUnFmGd8-4PwVHiFDrMpsp-EPRYlyIxYP2gIdyLuWAKkaXpAO2vle-m4EQrxEKyxNHGYkYzs4kW9_qP4dd1OXL1I7yWHpEyfOQoKyJLw7V7tre-vRpCHLpGYhyphenhyphenw9mX3HvnV768ZRAj52IeOnqQGaXlB9Az-k7lfGNtep0dBbDPm5pH27h8s3U/s1600/image3.png" width="100%" /></div></image>
<h4><span style="font-size: large;">Support for nonlinear font scaling</span></h4>
<p>The January ‘24 release uses nonlinear font scaling for better text readability and accessibility. Nonlinear font scaling prevents large text elements on screen from scaling too large by applying a nonlinear scaling curve. This scaling strategy means that large text doesn't scale at the same rate as smaller text.</p>
<h3>Drag and drop</h3>
<p>Compose Foundation <a href="https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.6.0-alpha07" target="_blank">adds support</a> for platform-level drag and drop, which allows for content to be dragged between apps on a device running in multi-window mode. The API is 100% compatible with the View APIs, which means a drag and drop started from a View can be dragged into Compose and vice versa. To use this API, see the <a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/DragAndDropSamples.kt" target="_blank">code sample</a>.</p>
<image><div style="text-align: center;"><img alt="Moving image illustrating drag and drop feature" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL3AMqnass7Xa2N5suD7FFZsJdrVN56_SptvqprYimpN4HQqSVWsXn5uPbRKky6BpSFYJn8YigLUjwClrUMWn0gldUvwh2xki2lvcpLN5KnZ7GadfyiCQPst7UxrNmHiB_l0qAEYEmcQjiOnqX-g_pTcyJaTT78DRmFxI4ICZSoawT8gJbNCJY5HIffoQ/s1600/image2.gif" width="100%" /></div></image>
<h3>Additional features</h3>
<p>Other features landed in this release include:</p>
<ul><ul>
<li>Support for <span style="color: #0d904f; font-family: courier;">LookaheadScope</span> in Lazy lists.</li>
<li><a href="https://issuetracker.google.com/187188981" target="_blank">Fixed</a> composables that have been deactivated but kept alive for reuse in a Lazy list not being filtered by default from semantics trees.</li>
<li><a href="https://developer.android.com/jetpack/androidx/releases/compose-animation#1.6.0-beta01" target="_blank">Spline-based keyframes</a> in animations.</li>
<li><a href="https://issuetracker.google.com/180639271" target="_blank">Added support</a> for selection by mouse, including text.</li>
</ul></ul>
<h3>Get started!</h3>
<p>We’re grateful for all of the bug reports and feature requests submitted to our <a href="http://goo.gle/compose-feedback" target="_blank">issue tracker</a> — they help us to improve Compose and build the APIs you need. Continue providing your feedback, and help us make Compose better! </p>
<p>Wondering what’s next? Check out our <a href="https://developer.android.com/jetpack/androidx/compose-roadmap" target="_blank">roadmap</a> to see the features we’re currently thinking about and working on. We can’t wait to see what you build next!</p>
<p>Happy composing!</p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-72885755327256404752024-01-18T09:00:00.000-08:002024-01-18T09:00:00.125-08:00How This Indie Game Studio Launched Their First Game on Google Play<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQgdLnO1ea7UeWUKUw-67Fb62VLKJtTtKapVjZ8-RA2juJcXKue1tkXIMQRUvthaM8MZDXnYM61JWDuTTM_U8fQHYo8c-qZ8fMkySbWlog5Jr5RT7BleGsmcJrCjnWl6A3s5W9gmXzqxC-7yCVtDkJwl7VYLVPDP7s_BA_XE9hZ1MDVEZ74uhzjK3eh-4/s1600/social-indie-games-developer---Googlr-play-publishing-journey.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQgdLnO1ea7UeWUKUw-67Fb62VLKJtTtKapVjZ8-RA2juJcXKue1tkXIMQRUvthaM8MZDXnYM61JWDuTTM_U8fQHYo8c-qZ8fMkySbWlog5Jr5RT7BleGsmcJrCjnWl6A3s5W9gmXzqxC-7yCVtDkJwl7VYLVPDP7s_BA_XE9hZ1MDVEZ74uhzjK3eh-4/s1600/social-indie-games-developer---Googlr-play-publishing-journey.png" style="display: none;" />
<em>Posted by Scarlett Asuncion – Product Marketing Manager</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBobSCqMHyxUze5gWymiOTBMzXE3Micq3HyGSQy04Grk-Af-QImn3m2MDPDlxj51NBr16De8tTyrULgrqRJwERkglfAOs9ai3I9joDruJW8m9BSgp5CTbI_byJq1l6ir9PBDQxj_BdYZ9ZCdhllb18e76M9ahvo4h5mK-OXxR89EULSunN7qfSb3KS_RE/s1600/HEADER-Google-Play-indie-games-developer---Googlr-play-publishing-journey.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBobSCqMHyxUze5gWymiOTBMzXE3Micq3HyGSQy04Grk-Af-QImn3m2MDPDlxj51NBr16De8tTyrULgrqRJwERkglfAOs9ai3I9joDruJW8m9BSgp5CTbI_byJq1l6ir9PBDQxj_BdYZ9ZCdhllb18e76M9ahvo4h5mK-OXxR89EULSunN7qfSb3KS_RE/s1600/HEADER-Google-Play-indie-games-developer---Googlr-play-publishing-journey.png" /></a>
<p>Indie game developers Geoffrey Mugford and Samuli Pietikainen first connected online through their shared passion for game design, before joining forces to create their own studio No Devs. Looking for ways to grow as a team, they entered the <a href="https://itch.io/jam/quick-play-2022" target="_blank">Quickplay Game Jam</a> hosted by <a href="https://www.latinxingaming.com/" target="_blank">Latinx in Gaming</a> in partnership with Google Play. The 6-week competition, open to anyone globally, challenged participants to generate a game idea around the theme of ‘tradition’. The duo became one of 4 winners to receive a share of $80,000 to bring their game jam concept to life and launch it on Google Play.</p>
<p>Their winning game idea, <a href="https://play.google.com/store/apps/details?id=com.NoDevs.Pilkki&pcampaignid=web_share" target="_blank">Pilkki</a>, has just launched in early access. It offers players a captivating claymation ice fishing adventure set in a serene atmosphere that celebrates Finnish culture. Intrigued by the game’s origins and unique gameplay, we chatted with one-half of No Devs, Geoffrey. He shares how his multicultural heritage and Samuli’s Finnish background inspired their game design, the lessons they’ve learned so far and their studio’s future plans.</p>
<image><div style="text-align: center;"><img alt="Headshots of Geoffrey Mugford (left)and Samuli Pietikainen (right), smiling" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOLTqM4qppAinXfynQrPqcV-6T3Nh6ADMGxJPr0ZbGZeoe0kV-Ly9vURc8QMLUKdvupqxr-jwx9C-Qvb0jANf1ZLA3t57KzpWhC5KDhCLol5qrL8-ERN0-N1vcLvqzj-ezoY0_1DSYjwaUrxvtUbX4NrpqYnFHyps6S-BKGdcGzFNcoXiv4ZGBwMGGtBU/s1600/Inline-Google-Play-Pilkki.png" width="100%" /></div><imgcaption><center><em>Geoffrey Mugford (left); Samuli Pietikainen (right)</em></center></imgcaption></image>
<h4><span style="font-size: large;">Tell us about your journey as a team and why you entered the Quickplay Game Jam.</span></h4>
<p>We started making games together in May 2022. We talked about it for a year, but hadn’t taken the plunge, so a game jam was the perfect way of kickstarting our creative partnership. Our first game jam was a success so we decided to take it further and look for more game jam opportunities. As indie developers, balancing personal projects with financial stability is tough. Winning a prize in a game jam offers a chance to prototype an idea and potentially secure early funding for it. This game jam offered that opportunity whilst also promoting cultural diversity. Because of Samuli’s background, we were keen to make a game that embodies the Finnish mindset.</p>
<h4><span style="font-size: large;">What inspired the creation of Pilkki and how did you shape the game to offer a unique cultural experience like ice fishing?</span></h4>
<p>At first, we struggled with the game jam’s theme of 'tradition.' We were initially keen to make a traditional 'Day of the Dead' inspired game, but realized it didn't resonate enough with us after a couple of attempts, so we shifted gears. Coming from a multicultural background, we thought about blending cultures rather than a focus on one. We considered creating new traditions using deck builder or city-builder formats but found them too ambitious given the timeframe. We eventually turned our focus to Finland and its quirky traditions. Some of them, like eukonkanto (wife-carrying races) and tinanvalanta (tin melting in a sauna ladle) caught our attention, but we ultimately settled on ice fishing - a simple, unique and very Finnish activity that could suit mobile gaming. The challenge was innovating on it - we reimagined it as a physics-driven puzzle game where the player would control the hook as a pendulum, and that's how Pilkki came to be.</p>
<image><div style="text-align: center;"><img alt="side by side photos of Pilkki gameplay" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif086hvJyRx0RYc-Uqm2_3XJCt484ubmaclQC5ZSjHXHBOUuHFQGV46cMnCq3FJiUH-x7B-bC-lavnQVr0R6h6cHWFi0qb9r2ADcGjKvEiv3cwarzR9HsP0DkQo-TftAQqQXrSdOu35mT6YbEEsra395vMVGF0OwWkEbh51zr-lE9h1A0R9Q59OFIbya8/s1600/Inline-Google-Play-Pilkki-2.png" width="100%" /></div><imgcaption><center><em>Gameplay of Pilkki</em></center></imgcaption></image>
<h4><span style="font-size: large;">Can you highlight some of the learnings and adjustments you made along the way?</span></h4>
<p>We only had 6 weeks to make the game, and had already spent 2 of them brainstorming. When we settled on our game idea, we had to be very careful with scope and, sometimes, make quick decisions without the opportunity for play-testing. Some of these decisions ended up being super fun for the players - others, not so much. Luckily we had a clear division of responsibilities - I was on game design and programming, Samuli on art, audio and game feel - so we could work smoothly in parallel and meet milestones efficiently.</p>
<p>The win condition was a challenging aspect to figure out during development. We wanted a calm and reflective experience, similar to a real-life analogue, so we avoided score systems and timers. With time running out to complete the game, we were unable to explore alternative options. As a result, our game jam entry ended up being a race against time to catch as many fish as possible. After the game jam ended, we revisited this and turned towards a more tranquil atmosphere, where the progression was driven by puzzles rather than scores.</p>
<h4><span style="font-size: large;">How did the funding from the Quickplay Game Jam in partnership with Google Play contribute to the development of Pilkki beyond its initial prototype stage?</span></h4>
<p>Pilkki is much larger in scope than anything we've attempted before. Without funding, we would have likely left it in its prototype stage without exploring the concept further. The Quickplay Game Jam allowed us to recognize the potential in the idea, and dedicate ourselves to turning it into the relaxing fishing experience it has become.</p>
<p>With the funding, we were able to dedicate 3 months full-time to the design and development of Pilkki. We were able to take a step back and really put some thought into how we would build a game that would continue growing post-release. On top of that, Samuli experimented with multiple styles and multi-media art - this is how he developed the beautiful claymation visuals that have become our unique selling point.</p>
<h4><span style="font-size: large;">Are you excited about your future as a new indie game studio?</span></h4>
<p>Yes, for sure! We love creating fun and innovative experiences for people, and we have both been dreaming about working on our own games full time. It's a long road ahead, but we're excited to keep the momentum. For now, we’re actively working on Pilkki and aiming to release a major game update in 2024. We're eager to see the reaction from our players.</p>
<p>Having our game on Google Play gives us access to new markets worldwide. We can't wait to see how the game grows and attracts new players, and how it introduces them to our quirky take on Finnish culture.</p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-49244253561260943882024-01-17T09:00:00.000-08:002024-01-17T09:00:00.134-08:00#WeArePlay | Learn how a childhood experience with an earthquake shaped Álvaro's entrepreneurial journey<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu218W2RyLDMAvOEcTDjLxA2tjNEFk6822pJCEX1uklhlS4xpUn4A5pQbmDLsnUgOC_Vfzy1stegKYeBgy0jdWOCimNm_I9eTkUg1l5lJRk0ASIaaZxda23M1MU6HvxT5yLhxzdzNMCRU3j457Tn6g7RLBLWs7sAvwCa3u0ytAAt_WUpmpGRM-HCmzGjA/s1600/%23WeArePlay%20Social%20.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu218W2RyLDMAvOEcTDjLxA2tjNEFk6822pJCEX1uklhlS4xpUn4A5pQbmDLsnUgOC_Vfzy1stegKYeBgy0jdWOCimNm_I9eTkUg1l5lJRk0ASIaaZxda23M1MU6HvxT5yLhxzdzNMCRU3j457Tn6g7RLBLWs7sAvwCa3u0ytAAt_WUpmpGRM-HCmzGjA/s1600/%23WeArePlay%20Social%20.png" style="display: none;" />
<em>Posted by Leticia Lago – Developer Marketing</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfkoyiV0Ohxbe89HXqSsLkj4WD8ADd5AmwhHRv4MyMdbrm11cE1wn-SnjSYjsmWupfwZDt6FhaV_-kWQJ1AdObLCTglDqkO1V_Uo6z7S14NpYbQyWzxaDNOMK3fEa2_k25zNk-kQIkDI21X8YjGyoKu-Nnuptx1YYyd6nXmIxC4bPJQl0iHBj2dMD2nI4/s1600/%23WeArePlay%20Banner.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfkoyiV0Ohxbe89HXqSsLkj4WD8ADd5AmwhHRv4MyMdbrm11cE1wn-SnjSYjsmWupfwZDt6FhaV_-kWQJ1AdObLCTglDqkO1V_Uo6z7S14NpYbQyWzxaDNOMK3fEa2_k25zNk-kQIkDI21X8YjGyoKu-Nnuptx1YYyd6nXmIxC4bPJQl0iHBj2dMD2nI4/s1600/%23WeArePlay%20Banner.png" /></a>
<iframe class="BLOG_video_class" allowfullscreen="" youtube-src-id="HNzCCiUzryo" width="100%" height="400" src="https://www.youtube.com/embed/HNzCCiUzryo"></iframe>
<p>Being trapped inside a house following a major earthquake as a child motivated Álvaro to research and improve the outcomes of destructive, large-scale quakes in Mexico. Using <a href="https://skyalert.mx" target="_blank">SkyAlert</a> technology, sensors detect and report warnings of incoming earthquakes, giving people valuable time to prepare and get to safety.</p>
<p>Álvaro shared his story in our latest film for <a href="https://play.google.com/console/about/weareplay/" target="_blank">#WeArePlay</a>, which spotlights the founders and creatives behind inspiring apps and games on Google Play. We caught up with him to find out his motivations for <a href="https://play.google.com/store/apps/details?id=com.disappster.skyalert" target="_blank">SkyAlert</a>, the impact the app’s had and what his future plans are.</p>
<h4><span style="font-size: large;">What was the inspiration behind SkyAlert?</span></h4>
<p>Being in Colima near the epicenter of a massive earthquake as a kid had a huge impact on me. I remember feeling powerless to nature and very vulnerable watching everything falling apart around me. I was struck by how quick and smart you had to be to get to a safe place in time. I remember hugging my family once it was over and looking towards the sea to watch out for an impending tsunami – which fortunately didn’t hit my region badly. It was at this moment that I became determined to find out what had caused this catastrophe and what could be done to prevent it being so destructive another time.</p>
<p>Through my research, I learned that Mexico sits on five tectonic plates and, as a result, it is particularly prone to earthquakes. In fact, there've been seven major quakes in the last seven years, with hundreds losing their lives. Reducing the threat of earthquakes is my number one goal and the motivation behind <a href="https://play.google.com/store/apps/details?id=com.disappster.skyalert" target="_blank">SkyAlert</a>. The technology we’ve developed can detect the warning signs of an earthquake early on, deliver alerts to vulnerable people and hopefully save lives.</p>
<h4><span style="font-size: large;">How does SkyAlert work exactly?</span></h4>
<p><a href="https://play.google.com/store/apps/details?id=com.disappster.skyalert" target="_blank">SkyAlert</a> collects data from a network of sensors and translates that information into alerts. People can put their zip code in order to filter updates for their locality. We’re constantly investing in getting the most reliable and fast technology available so we can make the service as timely and effective as possible.</p>
<h4><span style="font-size: large;">Did you always imagine you’d be an entrepreneur?</span></h4>
<p>Since I was a kid I knew I wanted to be an entrepreneur. This was inspired by my grandfather who ran a large candy company with factories all over Mexico. However, what I really wanted, beyond just running my own company, was to have a positive social impact and change lives for the better: a feat I feel proud to have achieved with <a href="https://play.google.com/store/apps/details?id=com.disappster.skyalert" target="_blank">SkyAlert</a>.</p>
<h4><span style="font-size: large;">How is Google Play helping your app to grow?</span></h4>
<p>Being on Google Play helps us to reach the maximum number of people. We’ve achieved some amazing numbers in the last 10 years through Google Play, with over 7 million downloads. With 35% of our income coming from Google Play, this reach has helped us invest in new technologies and sensors.</p>
<p>We also often receive advice from Google Play and they invite us to meetings to tell us how to do better and how to make the most of the platform. Google Play is a close partner that we feel really takes care of us.</p>
<h4><span style="font-size: large;">What impact has SkyAlert had on the people of Mexico?</span></h4>
<p>The biggest advantage of <a href="https://play.google.com/store/apps/details?id=com.disappster.skyalert" target="_blank">SkyAlert</a> is that it can help them prepare for an earthquake. In 2017, we were able to notify people of a massive quake 12 seconds before it hit Mexico City. At least with those few seconds, many were able to get themselves to a safe place. Similarly, with a large earthquake in Oaxaca, we were able to give a warning of over a minute, allowing teachers to get students in schools away from infrastructure – saving kids’ lives.</p>
<p>Also, many find having <a href="https://play.google.com/store/apps/details?id=com.disappster.skyalert" target="_blank">SkyAlert</a> on their phone gives them peace of mind, knowing they’ll have some warning before an earthquake strikes. This can be very reassuring. </p>
<h4><span style="font-size: large;">What does the future look like for SkyAlert?</span></h4>
<p>We’re working hard to expand our services into new risk areas like flooding, storms and wildfires. The hope is to become a global company that can deliver alerts on a variety of natural phenomena in countries around the world. </p>
<p>Read more about Álvaro and other inspiring app and game founders featured in <a href="https://play.google.com/console/about/weareplay/" target="_blank">#WeArePlay</a>.</p>
<br /><br />
<p></p><center>
How useful did you find this blog post?
</center><p></p>
<p></p><center>
<a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=1%E2%98%85+%E2%80%93+Not+at+all&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=2%E2%98%85+%E2%80%93+Not+very&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=3%E2%98%85+%E2%80%93+Somewhat&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=4%E2%98%85+%E2%80%93+Very&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=5%E2%98%85+%E2%80%93+Extremely&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a>
</center><p></p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxnvf5XzyebGljqgi8J7by9XsvaL5WWLNamSyTg4w_c0kPHjY1B1no1FQsdSfUHUwNw0UuYfXuo6i7K6VpdyV2-K8ms4VFmZA438ujm6qwtZMt5rJfMGymhQ_iCX2Z8h0MuJo7gXUQ4Hb-hjKYK1isibMZZxCyX_vo3kGoP5tieK2PI2ZhYdGh4gsqhwA/s260/lockup_ic_Google_Play_H_260x53px_clr.png" style="display: block; padding: 1em 0px; text-align: center;"><img alt="" border="0" data-original-height="53" data-original-width="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxnvf5XzyebGljqgi8J7by9XsvaL5WWLNamSyTg4w_c0kPHjY1B1no1FQsdSfUHUwNw0UuYfXuo6i7K6VpdyV2-K8ms4VFmZA438ujm6qwtZMt5rJfMGymhQ_iCX2Z8h0MuJo7gXUQ4Hb-hjKYK1isibMZZxCyX_vo3kGoP5tieK2PI2ZhYdGh4gsqhwA/s200/lockup_ic_Google_Play_H_260x53px_clr.png" width="200" /></a></div>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-1152473655995073082024-01-11T17:00:00.000-08:002024-01-11T17:00:00.124-08:00A New Approach to Real-Money Games on Google Play<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLf1-r4ZnSclRc-JuUie1CBHw6giBnM4TIfh4mT5KsnIOvDEAI1ILqydxgNszVn3RDQn8VlrLyp1lfvAVhvURhu0pOi7g0kf9ifI9t41JJpMWZVu47bSIVWf1JWPWXPJ-6GuRfOJN8iOsyYZvsBWYAwFROUtNkaXpW95W55OLpCdWzU78qo1xABl3hD18/s1600/Social-Play-Announcement-General%20%282%29.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLf1-r4ZnSclRc-JuUie1CBHw6giBnM4TIfh4mT5KsnIOvDEAI1ILqydxgNszVn3RDQn8VlrLyp1lfvAVhvURhu0pOi7g0kf9ifI9t41JJpMWZVu47bSIVWf1JWPWXPJ-6GuRfOJN8iOsyYZvsBWYAwFROUtNkaXpW95W55OLpCdWzU78qo1xABl3hD18/s1600/Social-Play-Announcement-General%20%282%29.png" style="display: none;" />
<em>Posted by Karan Gambhir – Director, Global Trust and Safety Partnerships</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhs86DFslHGkdSuhxn0J3H9RVP0I4DWQJYit16DC4VN6n4dXig_QkDd1DXBWjGr-rKXV4LYMv1CVvH8msovXapex8IIz-jiec4brLmIodQGhe8ZVW8ULwDihAQxHXJeVHEDgaOFHXs5Al6wfb7hRDHJz1VQ801V4MqDAs9OSWf0nyN-vNKSThdhHWFIBMY/s1600/Banner-Google-Play-Announcement-General.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhs86DFslHGkdSuhxn0J3H9RVP0I4DWQJYit16DC4VN6n4dXig_QkDd1DXBWjGr-rKXV4LYMv1CVvH8msovXapex8IIz-jiec4brLmIodQGhe8ZVW8ULwDihAQxHXJeVHEDgaOFHXs5Al6wfb7hRDHJz1VQ801V4MqDAs9OSWf0nyN-vNKSThdhHWFIBMY/s1600/Banner-Google-Play-Announcement-General.png" /></a>
<p>As a platform, we strive to help developers responsibly build new businesses and reach wider audiences across a variety of content types and genres. In response to strong demand, in 2021 we began onboarding a wider range of real-money gaming (RMG) apps in markets with pre-existing licensing frameworks. Since then, this app category has continued to flourish with developers creating new RMG experiences for mobile.</p>
<p>To ensure Google Play keeps up with the pace of developer innovation, while promoting user safety, we’ve since conducted several pilot programs to determine how to support more RMG operators and game types. For example, many developers in India were eager to bring RMG apps to more Android users, so we launched a pilot program, starting with Rummy and Daily Fantasy Sports (DFS), to understand the best way to support their businesses.</p>
<p><b>Based on the learnings from the pilots and positive feedback from users and developers, Google Play will begin supporting more RMG apps this year, including game types and operators not covered by an existing licensing framework.</b> We’ll launch this expanded RMG support in June to developers for their users in India, Mexico, and Brazil, and plan to expand to users in more countries in the future.</p>
<p>We’re pleased that this new approach will provide new business opportunities to developers globally while continuing to prioritize user safety. It also enables developers currently participating in RMG pilots in India and Mexico to continue offering their apps on Play.</p>
<ul><ul>
<li><b>India pilot:</b> For developers in the Google Play <a href="https://support.google.com/googleplay/android-developer/answer/12491011" target="_blank">Pilot Program</a> for distributing DFS and Rummy apps to users in India, we are extending the grace period for pilot apps to remain on Google Play until June 30, 2024 when the new policy will take effect. After that time, developers can distribute RMG apps on Google Play to users in India, beyond DFS and Rummy, in compliance with local laws and our updated policy.</li>
<li><b>Mexico pilot:</b> For developers in the Google Play <a href="https://support.google.com/googleplay/android-developer/contact/dfsmxform?sjid=12080808016043775302-NC" target="_blank">Pilot Program</a> for DFS in Mexico, the pilot will end as scheduled on June 30, 2024, at which point developers can distribute RMG apps on Google Play to users in Mexico, beyond DFS, in compliance with local laws and our updated policy.</li>
</ul></ul>
<p>Google Play’s existing developer policies supporting user safety, such as requiring age-gating to limit RMG experiences to adults and requiring developers use geo-gating to offer RMG apps only where legal, remain unchanged and we’ll continue to strengthen them. In addition, Google Play will continue other key user safety and transparency <a href="https://android-developers.googleblog.com/2023/11/ensuring-high-quality-apps-on-google-play.html" target="_blank">efforts</a> such as our expanded developer verification mechanisms.</p>
<p>With this policy update, we will also be evolving our service fee model for RMG to reflect the value Google Play provides and to help sustain the Android and Play ecosystems. We are working closely with developers to ensure our new approach reflects the unique economics and various developer earning models of this industry. We will have more to share in the coming months on our new policy and future expansion plans.</p>
<p>For developers already involved in the real-money gaming space, or those looking to expand their involvement, we hope this helps you prepare for the upcoming policy change. As Google Play evolves our support of RMG around the world, we look forward to helping you continue to delight users, grow your businesses, and launch new game types in a safe way.</p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-89945293010122815112024-01-09T10:00:00.000-08:002024-01-10T11:10:18.138-08:00What's new with Google Cast?<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwRh6XkG-2_miLGjyCAc8GqPaN2dMcur3bO2IOeu5x2v-MGWdSw2cjhZ_04gasYpveRvqS-2OagiNyGXhfE62dH2Rmd4JhYyS1fjVhh9E9FYD0zFIaQc6wciuapt7uebdR3JhexSB9vEfa7qQZ8CXPiu-YExk5w31hBwdhOalwaE6uu3QAoHxb3-wxzTA/s1600/Social-whats-new-in-google-cast.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwRh6XkG-2_miLGjyCAc8GqPaN2dMcur3bO2IOeu5x2v-MGWdSw2cjhZ_04gasYpveRvqS-2OagiNyGXhfE62dH2Rmd4JhYyS1fjVhh9E9FYD0zFIaQc6wciuapt7uebdR3JhexSB9vEfa7qQZ8CXPiu-YExk5w31hBwdhOalwaE6uu3QAoHxb3-wxzTA/s1600/Social-whats-new-in-google-cast.png" style="display: none;" />
<em>Posted by Meher Vurimi, Product Manager</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht1ZL_b5ZKMRcqW5FdyCiSnnwQyJ1LNTNuTb6sxx3hyphenhyphenHiNcBbyFEJvwq3iyKmR5cyrqozHnUp5u2TXMg2KZfyPfaXQdK0HOE6nHgSgh3ixuUWfY6WbtTf0o1jkIdQcjlAviO-k8VbRoSFGERxPQ6UkNcrI5Km_l9zjz2m6LqeT0NNok_9IL9Ba2n4L3Pw/s1600/Banner-whats-new-in-google-cast-AD.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEht1ZL_b5ZKMRcqW5FdyCiSnnwQyJ1LNTNuTb6sxx3hyphenhyphenHiNcBbyFEJvwq3iyKmR5cyrqozHnUp5u2TXMg2KZfyPfaXQdK0HOE6nHgSgh3ixuUWfY6WbtTf0o1jkIdQcjlAviO-k8VbRoSFGERxPQ6UkNcrI5Km_l9zjz2m6LqeT0NNok_9IL9Ba2n4L3Pw/s1600/Banner-whats-new-in-google-cast-AD.png" /></a>
<p>Since we launched Google Cast in 2013, we've been working to bring casting capabilities to more apps and devices. We have come a long way. Now, users can cast to many new devices, like TVs, speakers, smart displays, and even the latest Pixel Tablet. We are very excited to launch new features that make it more seamless to cast on Android. </p>
<h3>Output Switcher</h3>
<image><div style="text-align: center;"><img alt="Moving image of output switcher showing various device categories" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlykTzAkbIgbFIzmyGda33mYBUFHP7kbLitqjTJk2zMaTfQ_-wGw84Ez9gw1VBdYDCCbmE6m-JpQHIV4axhd8AueGMltcR9NNz3n21rCIHDiCg59OI86sQD4GnqzmFlB6EQ3MO5C7F9rIx6rcRZFm3I33_glWVeGMy-16mwFttn3jPxYlTIsNS9f0VZig/s1600/image4.gif" width="35%" /></div><imgcaption><center><em>Figure 1: Output Switcher showing various device categories</em></center></imgcaption></image><br />
<p>Android makes moving media between various devices– including phones to TVs, tablets, speakers, and smart displays–easy with Output Switcher. Output Switcher is easily accessible from the Android System UI and aims to allow cross-device transfer and control in one place for different technical protocols. With Output Switcher 2.0 on Android U, you can also see improved volume control, device categories, and support for devices with custom protocols.</p>
<p>More information can be found in the <a href="https://developers.google.com/cast/docs/android_sender/output_switcher" target="_blank">Google Cast developer guide</a> and <a href="https://developer.android.com/reference/androidx/mediarouter/media/MediaRouter#setRouteListingPreference%28androidx.mediarouter.media.RouteListingPreference%29" target="_blank">Media router</a>.</p>
<p></p><ul><ul><li>Enable Output Switcher in AndroidManifest.xml</li></ul></ul>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><application>
...
<receiver
android:name=<span style="color: #ba2121;">"androidx.mediarouter.media.MediaTransferReceiver"</span>
android:exported=<span style="color: #ba2121;">"true"</span>>
</receiver>
...
</application>
</pre></div>
<p></p><ul><ul><li>Update SessionManagerListener for background casting</li></ul></ul>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: green;">class</span> <span style="color: blue;">MyService</span> : Service() {
<span style="color: green;">private</span> <span style="color: green;">var</span> castContext: CastContext? = <span style="color: green;">null</span>
<span style="color: green;">protected</span> <span style="color: green;">fun</span> <span style="color: blue;">onCreate</span>() {
castContext = CastContext.getSharedInstance(<span style="color: green;">this</span>)
castContext
.getSessionManager()
.addSessionManagerListener(sessionManagerListener,
<span style="color: #2b00fe;">CastSession</span>::<span style="color: #0d904f;">class</span>.java)
}
<span style="color: green;">protected</span> <span style="color: green;">fun</span> <span style="color: blue;">onDestroy</span>() {
<span style="color: green;">if</span> (castContext != <span style="color: green;">null</span>) {
castContext
.getSessionManager()
.removeSessionManagerListener(sessionManagerListener,
<span style="color: #2b00fe;">CastSession</span>::<span style="color: #0d904f;">class</span>.java)
}
}
}
</pre></div>
<p></p><ul><ul><li>Support Remote-to-Local playback</li></ul></ul>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: green; font-weight: bold;">class</span> <span style="color: blue; font-weight: bold;">MySessionTransferCallback</span> : SessionTransferCallback() {
<span style="color: green; font-weight: bold;">fun</span> <span style="color: blue;">onTransferring</span>(@SessionTransferCallback.TransferType transferType:
Int) {
<span style="color: #408080; font-style: italic;">// Perform necessary steps prior to onTransferred</span>
}
<span style="color: green; font-weight: bold;">fun</span> <span style="color: blue;">onTransferred</span>(@SessionTransferCallback.TransferType transferType:
Int,
sessionState: SessionState?) {
<span style="color: green; font-weight: bold;">if</span> (transferType == SessionTransferCallback.TRANSFER_TYPE_FROM_REMOTE_TO_LOCAL) {
<span style="color: #408080; font-style: italic;">// Remote stream is transferred to the local device.</span>
<span style="color: #408080; font-style: italic;">// Retrieve information from the SessionState to continue playback on the local player.</span>
}
}
<span style="color: green; font-weight: bold;">fun</span> <span style="color: blue;">onTransferFailed</span>(@SessionTransferCallback.TransferType transferType:
Int,
@SessionTransferCallback.TransferFailedReason
transferFailedReason: Int) {
<span style="color: #408080; font-style: italic;">// Handle transfer failure.</span>
}
}
</pre></div><br />
<h3>Cast to devices nearby</h3>
<image><div style="text-align: center;"><img alt="Moving image showing bringing an Android phone close to the docked Pixel Tablet to transfer media" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFkz0dXUIS9SXy04iLnpj_GEeHCNIptIDacpbhW9slU34L04I1S4zjWWYaifRlXwnR5ya1NK2KjZkoqyaBHNrwY0j_o4o4EkxciNZNJ1aL2WqKEQVxHXAxTW54J8RI904aYMG5nuijUfnz1k6D9M-F3ui_o7y5oz86b_ZKSEuw-xR8OjRY79CntpSjrC8/s1600/CasttoNearbyDevices.gif" width="80%" /></div><imgcaption><center><em>Figure 2: Bring your Android phone close to the docked Pixel Tablet to transfer media</em></center></imgcaption></image><br /><p>It will soon be possible to cast to devices nearby in a whole new way when you have a Pixel Pro phone and a docked Pixel Tablet. Users can transfer ongoing music from their Pixel Pro phone to a docked Pixel Tablet just by bringing the phone closer to the docked tablet. Similarly, they can transfer the music to their phone from a docked Pixel Tablet just by holding the phone closer to the tablet. This feature needs Output Switcher integration as a prerequisite.</p>
<h3>Cast from short-form video apps</h3>
<image><div style="text-align: center;"><img alt="Moving image showing enabling and disabling autoplay for short-form content" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwFG9F-t2Uz6E1szpq7Bc9a86ZmzcQ_g4x277N_Q1m5XIZBVNsUPPczrNzjPiEmIT1fIsBQGR9MYg4-LScLUoRtaixRoD_NQllCF3dtlo5bJlo5hU_-8PXdj6q-Cd8zQzTJGHpzJYBMvJmQW7GE3STtuvM442DQoaUv6Jk5Pd60IvpXPCiCF5a97eAkTk/s1600/image3.gif" width="100%" /></div><imgcaption><center><em>Figure 3: Enabling and disabling autoplay for short-form content (autoplay is enabled by default)</em></center></imgcaption></image><br />
<p>Short-form content is extremely popular and growing in use. Google Cast can make it easy for users to watch their favorite short-form content on TVs or other cast-enabled devices. Now, you can easily extend Google Cast support into your apps. These are the guidelines we put together to provide a great user experience to your users.</p>
<p><i>cast from your phone</i></p>
<p>Ensure that the Google Cast icon is prominently displayed on every screen with playable content on the top right corner. Users automatically understand they can cast media to a TV just by seeing the Cast icon.</p>
<p><i>cast with autoplay</i></p>
<p>Users will also have an option to disable autoplay to cast a specific video. When autoplay is enabled, playback automatically transitions to the next video without any user intervention.</p>
<h3>Persistent Cast icon</h3>
<image><div style="text-align: center;"><img alt="Moving image showing cast icon and error message for users to troubleshoot if no devices are found" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_w2G8Fr6VwpET2k8xQ4W84CQXD7FxRz5NDwvxIXakaIVzpggl-MuWeACWAey0ysqe3CAFZ-R_TEjA-Sok7X_HrIL6MXI7NV6iS_RH4DqaBNwsIEcPDdeYpD2dM2xcyWw4gDVtqj6-Ruke82N_v-EXmQCOUN5ZDpQ5Cx3NpGeR3PY2Lf2qKIopJdfp8qE/s1600/image6.gif" width="35%" /></div><imgcaption><center><em>Figure 4: Cast icon is shown even if the sender device is not connected to Wi-Fi, showcasing an error message for users to troubleshoot if no devices are found.</em></center></imgcaption></image><br />
<p>We've heard feedback that when users don't see the cast icon, they assume their Chromecast built-in devices haven't been discovered. To improve user experience and discovery, we have introduced the “Persistent cast icon”. With this support, users will see the cast icon whenever they need and can receive better help and guidance on why they don’t see a specific device. In addition, we've updated when device discovery starts. More information can be found in the <a href="https://developers.devsite.corp.google.com/cast/docs/android_sender/integrate#configure_device_discovery" target="_blank">Google Cast Developer Guide</a>.</p>
<h3>Shaka Player</h3>
<p>For any Web Receiver applications streaming HLS content, we recommend looking into migrating to Shaka Player for playback. The current player (MPL) will no longer adopt feature updates. As a result, the Web Receiver SDK has increased support for HLS playback using Shaka Player on the device targets and has introduced an opt-in flag to enable it. Refer to the <a href="https://developers.google.com/cast/docs/web_receiver/shaka_migration" target="_blank">Shaka Player migration guide</a> hosted on the DevSite for more information and implementation details.</p>
<p>To opt-in to use Shaka Player for HLS content use the following snippet in your Google Cast Receiver application:</p>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: green; font-weight: bold;">const</span> context <span style="color: #666666;">=</span> cast.framework.CastReceiverContext.getInstance();
<span style="color: green; font-weight: bold;">const</span> castReceiverOptions <span style="color: #666666;">=</span> <span style="color: green; font-weight: bold;">new</span> cast.framework.CastReceiverOptions();
castReceiverOptions.useShakaForHls <span style="color: #666666;">=</span> <span style="color: green; font-weight: bold;">true</span>;
context.start(castReceiverOptions);
</pre></div><br />
<h3>Cast to new devices </h3>
<image><div style="text-align: center;"><img alt="Moving image showing the experience of casting to an LG TV as a first time user" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNyewY_cDu4GeiqKwX3hKMcjxAY5ODHyiu4JaehGs0uo8B8_TpePJF3oKhdWlXsPBqwdiK8WQ5-H9LyPT8GbfZoGDK3HO_tWCQK57v45BVnj98oZSAFOXFffJ6JEPn5xrBgftpLFB1hNz4-BWoKpiSnhvffec6gewO4uRsutti2N0-nf6fkXS82BpnTfE/s1600/image2.gif" width="100%" /></div><imgcaption><center><em>Figure 5: Casting to LG TVs for a first time user</em></center></imgcaption></image><br />
<p>We have been continuously working with various OEMs to bring Chromecast built-in to new devices. Last year, we launched Chromecast built-in to new speakers, while also introducing the receiver support on docked Pixel Tablets. </p>
<p>As always, Google TVs come with Chromecast built-in, including the new Hisense ULED and ULED X Series, latest TCL Q Class models, and new TCL QM7 line. In fact, there are now over 220 million monthly active Google TV and other Android TV OS devices, and we’re just getting started. More devices are launching with Chromecast built-in, like the 2024 LG TV series. </p>Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-55808328072942141092023-12-19T11:00:00.000-08:002023-12-19T11:00:00.134-08:00Thank you for creating excellent apps, across devices in 2023!<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Yvyg6NZR7nXnc5g0jLvol0YBUyl_9xKGDxjM9fBmAmx2zg28HT2_JAqCqoRTCJM419rEMh_ZJrCKn0JSBtZ88Hey1D0aAeSfHX871X0AAB4i2OiPzBoLwOd4EVyefByBfFlH8LOHZXZblmo7lPhWUQ08fQ3uR8K4n9kk_CKbn5Uc0bF9idVlglNCfhA/s1600/Social-Android-EOY-Thank-YOU.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Yvyg6NZR7nXnc5g0jLvol0YBUyl_9xKGDxjM9fBmAmx2zg28HT2_JAqCqoRTCJM419rEMh_ZJrCKn0JSBtZ88Hey1D0aAeSfHX871X0AAB4i2OiPzBoLwOd4EVyefByBfFlH8LOHZXZblmo7lPhWUQ08fQ3uR8K4n9kk_CKbn5Uc0bF9idVlglNCfhA/s1600/Social-Android-EOY-Thank-YOU.png" style="display: none;" />
<em>Posted by Anirudh Dewani, Director of Android Developer Relations</em><br />
<iframe allowfullscreen="" class="BLOG_video_class" height="400" src="https://www.youtube.com/embed/yXiRLGwbi1M" width="100%" youtube-src-id="yXiRLGwbi1M"></iframe>
<p style="text-align: left;">Hello Android Developers,
</p><p style="text-align: left;">As we approach the end of 2023, I wanted to take a moment to reflect on all that we've accomplished together as a community, and send a huge *thank you* for all of your work! </p>
<p>It's been an incredible year for Android, with many new features and improvements released as part of the platform as well as many new delightful app experiences crafted and delivered by you, all for the benefit of our users across the world. Here are just a few of the highlights:</p>
<ul><ul>
<li>The release of feature packed and highly performant <a href="https://android-developers.googleblog.com/2023/10/android-14-is-live-in-aosp.html" target="_blank">Android 14</a>, our most ambitious release to date.</li>
<li>The incredible <a href="https://android-developers.googleblog.com/2023/06/the-new-pixel-fold-pixel-tablet-are-here-optimizing-for-large-screens.html" target="_blank">momentum on large screens</a> and <a href="https://android-developers.googleblog.com/2023/06/multi-device-at-google-io.html" target="_blank">Wear OS</a>, fueled by hardware innovations of device makers and by the great app experiences you build for users</li>
<li>The <a href="https://android-developers.googleblog.com/2023/05/whats-new-in-jetpack-compose.html" target="_blank">growth of Compose</a>, from being a mobile developer toolkit to Compose Everywhere, helping you build excellent apps for mobile, tablets, wear and TV,</li>
<li>And the growth of the entire Android Developer community around the world, and the millions of amazing apps you build for users!</li>
</ul></ul>
<p>I'm so proud of everything we've achieved together this year!</p>
<p>Your hard work and dedication continue to make Android the best mobile platform in the world, and I want to thank you for being a part of this community. Your contributions are invaluable, and I'm grateful for your continued support.</p>
<p>Thanks again for all that you do, and we can’t wait to see what you build next year!</p>
<div style="text-align: left;">Best,</div>
<div style="text-align: left;"><i>Anirudh Dewani</i></div>
<div style="text-align: left;">Director, Android Developer Relations</div><br />
<image><img alt="Thank You for building excellent apps across devices! 0 PELOTO zoom SAMSUNG happyHolidays (year: Int = 2023)" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF3BJ41B5jGr_pTfTedlj8ZSaXlvrxuSU1dhuZ-jscZENVV7AtxzbOFGQ8_jBjOgIfF34gIMiQkO8RGWYe3r6gt_UAjz5-H3Zex83FNk8gKSQzqAhk7geKxI7gRlVRO7iMQkzaX5PmCvScr5p8H39LBXEg1-ijA0tWxNX2sqpfz6ByTCA_9hsfHwzobnY/s1600/Social-Android-EOY-Thank-YOU.png" style="text-align: center;" width="auto" /></image>Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-56374260534720705832023-12-18T14:00:00.000-08:002023-12-18T14:01:39.525-08:00Increase your app’s availability across device types<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0mQvASMlgKp0V9-V7d-D1uIC5j1aSzEBxwsAxr1nxEyaCBYM53s2qTJ9PiS1cJ6V1ZikicN_ptQQJjwDdoWVKNzdpLzCJxJ0NQoQ5UxVRYV924yj2sXDV_obr9ajYa8nHQTTRSK2N-iNBfYRj2c_T1507KUjsZLeJkJTxMLOHH3GJ77xX0mKOEq_QJ54/s1600/social-Remove-unnecessary-required-features%20%281%29.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0mQvASMlgKp0V9-V7d-D1uIC5j1aSzEBxwsAxr1nxEyaCBYM53s2qTJ9PiS1cJ6V1ZikicN_ptQQJjwDdoWVKNzdpLzCJxJ0NQoQ5UxVRYV924yj2sXDV_obr9ajYa8nHQTTRSK2N-iNBfYRj2c_T1507KUjsZLeJkJTxMLOHH3GJ77xX0mKOEq_QJ54/s1600/social-Remove-unnecessary-required-features%20%281%29.png" style="display: none;" />
<em>Posted by Alex Vanyo – Developer Relations Engineer</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuGXY_G5N4CDN2OcJC4IWqYwKpQgbWmgOPGgNe5oZdfRT-hZkaBGn2TKpCbcNiS2BkWRFFoO-opsO5_fdcsotKYLBsxJzBOBXrEpUWpAH4qNLDYVBGI2T_w2lH4dWyqeMKnXAYwJHyR4a2G1GTQ0Nc9Ft_Yr21KXCyKwC-5u-hxBYbaKcj-s_ic2sdq-4/s1600/header-Remove-unnecessary-required-features%20%281%29.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuGXY_G5N4CDN2OcJC4IWqYwKpQgbWmgOPGgNe5oZdfRT-hZkaBGn2TKpCbcNiS2BkWRFFoO-opsO5_fdcsotKYLBsxJzBOBXrEpUWpAH4qNLDYVBGI2T_w2lH4dWyqeMKnXAYwJHyR4a2G1GTQ0Nc9Ft_Yr21KXCyKwC-5u-hxBYbaKcj-s_ic2sdq-4/s1600/header-Remove-unnecessary-required-features%20%281%29.png" /></a>
<h2><span style="font-size: large;"><b>TL;DR:</b></span><span style="font-size: large;"><i> Remove unnecessary feature requirements that prevent users from downloading your app on devices that don’t support the features. Automate tracking feature requirements and maximize app availability with badging!</i></span></h2><p></p>
<h2><span style="font-size: x-large;">Required features reduce app availability</span></h2>
<p><span style="font-family: Courier;"> <a href="https://developer.android.com/guide/topics/manifest/uses-feature-element" target="_blank"><uses-feature></a></span> is an app manifest element that specifies whether your app depends on a <a href="https://developer.android.com/guide/topics/manifest/uses-feature-element#features-reference" target="_blank">hardware or software feature</a>. By default, <span style="color: #0d904f; font-family: Courier;"><uses-feature></span> specifies that a feature is required. To indicate that the feature is optional, you must add the <span style="color: #0d904f; font-family: Courier;">android:required="false"</span> attribute.</p>
<p>Google Play <a href="https://developer.android.com/guide/topics/manifest/uses-feature-element#market-feature-filtering" target="_blank">filters</a> which apps are available to download based on required features. If the user’s device doesn’t support some hardware or software feature, then an app that requires that feature won’t be available for the user to download.</p>
<p><span style="font-family: Courier;"><a href="https://developer.android.com/guide/topics/manifest/uses-permission-element" target="_blank"><uses-permission></a></span>, another app manifest element, complicates things by implicitly requiring features for permissions such as <span style="color: #0d904f; font-family: Courier;">CAMERA</span> or <span style="color: #0d904f; font-family: Courier;">BLUETOOTH</span> (see <a href="https://developer.android.com/guide/topics/manifest/uses-feature-element#permissions" target="_blank">Permissions that imply feature requirements</a>). The initial declared orientations for your activities can also <a href="https://developer.android.com/guide/topics/manifest/uses-feature-element#screen-hw-features" target="_blank">implicitly require</a> hardware features.</p>
<p>The system determines implicitly required features after merging all modules and dependencies, so it may not be clear to you which features your app ultimately requires. You might not even be aware when the list of required features has changed. For example, integrating a new dependency into your app might introduce a new required feature. Or the integration might request additional permissions, and the permissions could introduce new, implicitly required features.</p>
<p>This behavior has been around for a while, but Android has changed a lot over the years. Android apps now run on phones, foldables, tablets, laptops, cars, TVs and watches, and these devices are more varied than ever. Some devices don’t have telephony services, some don’t have touchscreens, some don’t have cameras.</p>
<p>Expectations based on permissions have also changed. With runtime permissions, a <span style="font-family: Courier;"><a href="https://developer.android.com/guide/topics/manifest/uses-permission-element" target="_blank"><uses-permission></a></span> declaration in the manifest no longer guarantees that your app will be granted that permission. Users can choose to deny access to hardware in favor of other ways to interact with the app. For example, instead of giving an app permission to access the device’s location, a user may prefer to always search for a particular location instead.</p>
<p>Banking apps shouldn’t require the device to have an autofocusing camera for check scanning. They shouldn’t specify that the camera must be a front or rear camera or that the device has a camera at all! It should be enough to allow the user to upload a picture of a check from another source.</p>
<p>Apps should support keyboard navigation and mouse input for accessibility and usability reasons, so strictly requiring a hardware touchscreen should not be necessary.</p>
<p>Apps should support both landscape and portrait orientations, so they shouldn’t require that the screen could be landscape-oriented or could be portrait-oriented. For example, screens built in to cars may be in a fixed landscape orientation. Even if the app supports both landscape and portrait, the app could be unnecessarily requiring that the device supports being used in portrait, which would exclude those cars.</p>
<h2><span style="font-size: x-large;">Determine your app’s required features</span></h2>
<p>You can use <span style="font-family: Courier;"><a href="https://developer.android.com/tools/aapt2" target="_blank">aapt2</a></span> to <a href="https://developer.android.com/guide/topics/manifest/uses-feature-element#testing" target="_blank">output information</a> about your APK, including the explicitly and implicitly required features. The logic matches how the Play Store filters app availability.</p>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #0d904f; font-family: courier;">aapt2 dump badging <path_to_.apk></span></pre></div>
<p>In the Play Console, you can also check which devices are being excluded from accessing your app.</p>
<h2><span style="font-size: x-large;">Increase app availability by making features optional</span></h2>
<p>Most apps should not strictly require hardware and software features. There are few guarantees that the user will allow using that feature in the first place, and users expect to be able to use all parts of your app in the way they see fit. To increase your app’s availability across form factors:</p>
<ul><ul>
<li>Provide alternatives in case the feature is not available, ensuring your app doesn’t need the feature to function.</li>
<li>Add <span style="color: #0d904f; font-family: Courier;">android:required="false"</span> to existing <span style="font-family: Courier;"><a href="https://developer.android.com/guide/topics/manifest/uses-feature-element" target="_blank"><uses-feature></a></span> tags to mark the feature as not required (or remove the tag entirely if the app no longer uses a feature).</li>
<li>Add the <span style="color: #0d904f; font-family: Courier;"><uses-feature></span> tag with <span style="color: #0d904f; font-family: Courier;">android:required="false"</span> for implicitly required feature due to declaring <a href="https://developer.android.com/guide/topics/manifest/uses-feature-element#permissions" target="_blank">permissions that imply feature requirements</a>.</li>
</ul></ul>
<h2><span style="font-size: x-large;">Prevent regressions with CI and badging</span></h2>
<p>To guard against regressions caused by inadvertently adding a new feature requirement that reduces device availability, automate the task of determining your app’s features as part of your build system. By storing the badging output of the <span style="color: #0d904f; font-family: Courier;">aapt2</span> tool in a text file and checking the file into version control, you can track all declared permissions and explicitly and implicitly required features from your final universal apk. This includes all features and permissions included by transitive dependencies, in addition to your own.</p>
<p>You can automate badging as part of your continuous integration setup by setting up three Gradle tasks for each variant of your app you want to validate. Using release as an example, create these three tasks:</p>
<ul><ul>
<li><span style="color: #0d904f; font-family: Courier;">generateReleaseBadging</span> – Generates the badging file from the universal APK using the <span style="color: #0d904f; font-family: Courier;">aapt2</span> executable. The output of this task (the badging information) is used for the following two tasks.</li>
<li><span style="color: #0d904f; font-family: Courier;">updateReleaseBadging</span> – Copies the generated badging file into the main project directory. The file is checked into source control as a <i>golden</i> badging file.</li>
<li><span style="color: #0d904f; font-family: Courier;">checkReleaseBadging</span> – Validates the generated badging file against the golden badging file.</li>
</ul></ul>
<p>CI should run <span style="color: #0d904f; font-family: Courier;">checkReleaseBadging</span> to verify that the checked-in golden badging file still matches the generated badging file for the current code. If code changes or dependency updates have caused the badging file to change in any way, CI fails.</p>
<image><div style="text-align: center;"><img alt="Screen grab of failing CI due to adding a new permission and required feature without updating the badging file." border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5gEmbKrLOZt8WPIz8W14trqUnJHSV_OGxOrbnxZT3hjwfsLzjumUXUr3TmIIPc7R9LUKWkMI-0dLvpr9Twv5oSQuSVD3I1A3cg2tk8LZVrxEUeGIiJdspr37IdZmjAg503XXO49x9EcoFrnwRw8p-FhUAFMYsxbjRJS1ZvkG-A2iWM-0j0_3iPs4HYec/s1600/image2.png" style="margins: auto; width: auto;" /></div><imgcaption><center><em>Failing CI due to adding a new permission and required feature without updating the badging file.</em></center></imgcaption></image><br />
<p>When changes are intentional, run <span style="color: #0d904f; font-family: Courier;">updateReleaseBadging</span> to update the golden badging file and recheck it into source control. Then, this change will surface in code review to be validated by reviewers that the badging changes are expected.</p>
<image><div style="text-align: center;"><img alt="Screen grab showing updated golden badging file for review with additional permission and implied required feature." border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmh5GYFVBnxMNGc1KanoawkqJjUn7Sgy6CNO0WoVhFU2PF0kAp78EeC7tBZrGJ2yLj_uaMLVdvxOo9nY0qSmaUTjQQRy3kIsHaC8BL1MoUdU65YaskKhz8Jgb3O-iUQaQ5lWaQDrS_MW8QHOSkS0byHTGJyveF-4ceLxIWViYIti0rQQPK09QQs1itxMg/s1600/image1.png" style="margins: auto; width: auto;" /></div><imgcaption><center><em>Updated golden badging file for review with additional permission and implied required feature.</em></center></imgcaption></image><br />
<p>CI-automated badging guards against changes inadvertently causing a new feature to be required, which would reduce availability of the app.</p>
<p>For a complete working example of a CI system verifying the badging file, check out the setup in the <a href="https://github.com/android/nowinandroid" target="_blank">Now in Android</a> app.</p>
<h2><span style="font-size: x-large;">Keep features optional</span></h2>
<p>Android devices are continually becoming more varied, with users expecting a great experience from your Android app regardless of the type of device they’re using. While some software or hardware features might be essential to your app’s function, in many cases they should not be strictly required, needlessly preventing some users from downloading your app.</p>
<p>Use the <a href="https://developer.android.com/guide/topics/manifest/uses-feature-element#testing" target="_blank">badging</a> output from <span style="color: #0d904f; font-family: Courier;">aapt2</span> to check which features your app requires, and use the Play Console to verify which devices the requirements are preventing from downloading your app. You can automatically check your app’s badging in CI and catch regressions.</p>
<p><b>Bottom line:</b> If you don’t absolutely need a feature for your entire app to function, make the feature optional to ensure your app’s availability to the greatest number of devices and users.</p>
<p>Learn more by checking out our <a href="https://developer.android.com/guide/topics/manifest/uses-feature-element" target="_blank">developer guide</a>.</p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-20259772544572786052023-12-18T10:00:00.000-08:002023-12-18T10:00:00.133-08:00#WeArePlay | Meet Steven from Indonesia. More stories from around the world.<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu218W2RyLDMAvOEcTDjLxA2tjNEFk6822pJCEX1uklhlS4xpUn4A5pQbmDLsnUgOC_Vfzy1stegKYeBgy0jdWOCimNm_I9eTkUg1l5lJRk0ASIaaZxda23M1MU6HvxT5yLhxzdzNMCRU3j457Tn6g7RLBLWs7sAvwCa3u0ytAAt_WUpmpGRM-HCmzGjA/s1600/%23WeArePlay%20Social%20.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu218W2RyLDMAvOEcTDjLxA2tjNEFk6822pJCEX1uklhlS4xpUn4A5pQbmDLsnUgOC_Vfzy1stegKYeBgy0jdWOCimNm_I9eTkUg1l5lJRk0ASIaaZxda23M1MU6HvxT5yLhxzdzNMCRU3j457Tn6g7RLBLWs7sAvwCa3u0ytAAt_WUpmpGRM-HCmzGjA/s1600/%23WeArePlay%20Social%20.png" style="display: none;" />
<em>Posted by Leticia Lago, Developer Marketing</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfkoyiV0Ohxbe89HXqSsLkj4WD8ADd5AmwhHRv4MyMdbrm11cE1wn-SnjSYjsmWupfwZDt6FhaV_-kWQJ1AdObLCTglDqkO1V_Uo6z7S14NpYbQyWzxaDNOMK3fEa2_k25zNk-kQIkDI21X8YjGyoKu-Nnuptx1YYyd6nXmIxC4bPJQl0iHBj2dMD2nI4/s1600/%23WeArePlay%20Banner.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfkoyiV0Ohxbe89HXqSsLkj4WD8ADd5AmwhHRv4MyMdbrm11cE1wn-SnjSYjsmWupfwZDt6FhaV_-kWQJ1AdObLCTglDqkO1V_Uo6z7S14NpYbQyWzxaDNOMK3fEa2_k25zNk-kQIkDI21X8YjGyoKu-Nnuptx1YYyd6nXmIxC4bPJQl0iHBj2dMD2nI4/s1600/%23WeArePlay%20Banner.png" /></a>
<p>As we bid farewell to 2023, we're excited to unveil our last #WeArePlay blog post of the year. From Lisbon to Dubai, let’s meet the creators behind the game-changing apps supporting communities, bringing innovation and joy to people.</p><br />
<iframe allowfullscreen="" class="BLOG_video_class" height="400" src="https://www.youtube.com/embed/zVcGo35uBAY" width="100%" youtube-src-id="zVcGo35uBAY"></iframe>
<div style="text-align: left;"><br /></div><div style="text-align: left;">We’re starting off in Indonesia, where Steven remembers his pocket money quickly running out while traveling around rural areas of Indonesia with his parents. Struck by how much more expensive food items were in the villages compared to Jakarta, he was inspired to create Super, providing more affordable goods outside the capital. The app allows shop owners to buy items stored locally and supply them to their communities at lower prices. It's helped boost the hyperlocal supply chain and raise living standards for rural populations. Steven is keen to point out that “it’s not just about entrepreneurship”, but “social impact”. He hopes to take Super even further and improve economic distribution across the whole of rural Indonesia. </div><div style="text-align: left;"><br /></div><br />
<image><div style="text-align: center;"><a href="https://play.google.com/console/about/weareplay/" target="_blank"><img alt="ALT TEXT" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhenhKheBAFRNWHIYNrxsqyZlRRCh-YTViEGDYoHvQNUaGunCxGMRR7xWqn3zjGUM54zLGBpnfcdOZm9t5HVfTuRynSfttbqT_kisqAk1kZrPGadL6pOUa40pZYRyrgBVbeL4K6IH-RbQl9D1Bg4g_hBe62WFRwD9ASP5xBzzGW45liUWx7CVqZEKA5HYc/s1600/image47.png" width="55%" /></a></div></image>
<div style="text-align: left;"><br /></div><div style="text-align: left;">Next, we’re crossing the Java Sea to Singapore, where twin brothers – and marathon runners – Jeromy and Kenny decided to turn their passion for self-care into a journaling app. On <a href="https://play.google.com/store/apps/details?id=com.journey.app" target="_blank">Journey</a>, people can log their daily thoughts and work towards their mental health and self-improvement goals using prompts. With the guidance of coaches, they can practice gratitude, record their ambitions, and learn about mindfulness and building self-confidence. “People tell us it helps them find time to invest in themselves and dedicate space to self-care”, says Jeromy. In the future, the pair want to bring in additional coaches to support even more people to achieve their wellness goals.</div><div style="text-align: left;"><br /></div><br />
<image><div style="text-align: center;"><a href="https://play.google.com/console/about/weareplay/" target="_blank"><img alt="ALT TEXT" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyJFlOcuEyI8ehjVyys-32I-KmNKXDcf0D4H5EgcKuPv2V7iiw0N5btFVgwNr5rdMLakpWe4Gs6FZYsXYEXJ0nt2a32M4Twakyos7wvDW1D0Qfmy-fKUCpNqW-7J6XC7knT2dy74SzcmHPqmEZApSWEp5E8_PJ9ulcFYSOHkKHG3bCHgAJBFIggCX3gu8/s1600/image1.png" width="55%" /></a></div></image>
<div style="text-align: left;"><br /></div><div style="text-align: left;">Now we’re landing in the Middle East where former kindergarten friends Chris and Rene decided to use their experience being expats in Dubai to create a platform for connecting disparate communities across the city. On <a href="https://play.google.com/store/apps/details?id=com.hayi.android" target="_blank">Hayi</a> <a href="https://play.google.com/store/apps/details?id=com.hayi.android" target="_blank">حي</a>, locals can share information with their neighbors, find help within the community and connect with those living nearby. “Community is at the heart of everything we do and our goal is to have a positive effect”, says Chris. They’re currently working on creating groups for art and sport enthusiasts to encourage residents to bond over their interests. The pair are also dedicated to sustainability and plan on launching environmental projects, such as wide-scale city clean-ups.</div><div style="text-align: left;"><br /></div><br />
<image><div style="text-align: center;"><a href="https://play.google.com/console/about/weareplay/" target="_blank"><img alt="ALT TEXT" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUX5sn6HOVRpanNqNBW9blGszdtk4jUvj-wyLbejDn1PGWnw6g6umv4u31PKc_kFx3dvT-UDU9tVD0heU3VyUu0vwHOIdtPdQK9QOk3ZIxZT4MUhB57HGjM9i3SGeKYA2K8Zi8xaLu2jaREQS38dgYDDs24HT-5RXn00i5JfgYm7mLMCGxbAjuptz98a8/s1600/image10.jpg" width="55%" /></a></div></image>
<div style="text-align: left;"><br /></div><div style="text-align: left;">And finally, we’re off to Europe where Lisbon-based university chums Rita, João and Martim saw unexpected success. Initially, the trio created a recipe-sharing platform, SaveCook. When they launched its accompaniment, <a href="https://play.google.com/store/apps/details?id=com.savecook.save.wallet&pli=1" target="_blank">Super Save</a>, however, which compared prices of recipe ingredients across different supermarkets, it exploded in popularity. With rising inflation, people were hugely thankful to the founders “for providing a major service” at such a crucial time. Next, they’re working on a barcode scanner that tells shoppers where they can buy cheaper versions of products “to help people save as much as they can.”</div><p>Discover more founder stories from across the globe in the <a href="https://play.google.com/console/about/weareplay/" target="_blank">#WeArePlay</a> collection.</p>
<br /><br />
<p></p><center>
How useful did you find this blog post?
</center><p></p>
<p></p><center>
<a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=1%E2%98%85+%E2%80%93+Not+at+all&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=2%E2%98%85+%E2%80%93+Not+very&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=3%E2%98%85+%E2%80%93+Somewhat&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=4%E2%98%85+%E2%80%93+Very&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a> <a href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=5%E2%98%85+%E2%80%93+Extremely&entry.2056663615&entry.646747778=changeme-mm/yy" target="_blank">★</a>
</center><p></p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxnvf5XzyebGljqgi8J7by9XsvaL5WWLNamSyTg4w_c0kPHjY1B1no1FQsdSfUHUwNw0UuYfXuo6i7K6VpdyV2-K8ms4VFmZA438ujm6qwtZMt5rJfMGymhQ_iCX2Z8h0MuJo7gXUQ4Hb-hjKYK1isibMZZxCyX_vo3kGoP5tieK2PI2ZhYdGh4gsqhwA/s260/lockup_ic_Google_Play_H_260x53px_clr.png" style="display: block; padding: 1em 0px; text-align: center;"><img alt="" border="0" data-original-height="53" data-original-width="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxnvf5XzyebGljqgi8J7by9XsvaL5WWLNamSyTg4w_c0kPHjY1B1no1FQsdSfUHUwNw0UuYfXuo6i7K6VpdyV2-K8ms4VFmZA438ujm6qwtZMt5rJfMGymhQ_iCX2Z8h0MuJo7gXUQ4Hb-hjKYK1isibMZZxCyX_vo3kGoP5tieK2PI2ZhYdGh4gsqhwA/s200/lockup_ic_Google_Play_H_260x53px_clr.png" width="200" /></a></div>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-87124150428519990852023-12-13T07:00:00.000-08:002023-12-14T16:19:55.480-08:00Leverage Gemini in your Android apps<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWT4aMu5vc9bH7bcswv8GlJ5Df1hsGQlTgCIPHsU35fjjFHxS8Zj_yQBc9FZhfP4dtNO9uBAMSWoVm4n-VYpJjs-L1-rkOiAClpUJnUDxuh-6KGINCM07Z5AthyphenhyphenXRrQpEtoTFaBjEFs0c0R8QOfu1kKiJgHUkGCKr336joSXqZhMecvGejI9G-9Dgf7ZI/s1600/Social-Gemini-Android.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWT4aMu5vc9bH7bcswv8GlJ5Df1hsGQlTgCIPHsU35fjjFHxS8Zj_yQBc9FZhfP4dtNO9uBAMSWoVm4n-VYpJjs-L1-rkOiAClpUJnUDxuh-6KGINCM07Z5AthyphenhyphenXRrQpEtoTFaBjEFs0c0R8QOfu1kKiJgHUkGCKr336joSXqZhMecvGejI9G-9Dgf7ZI/s1600/Social-Gemini-Android.png" style="display: none;" />
<em>Posted by Dave Burke, VP of Engineering</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpMUkef4JqgRnGpbAD9Rmf-mN2fG3kBcfymsPyj7bNZV3U-a5cIzsstZoIyKxcL1rbOmHg_TRsrzlzXdtgVegN8795ovwjF_Q_qFkt7WGg0dmVI4ggRx3b5V0ToHpFbR1EgJ0qiAHd27OacIN3FVfo18ksfcZjggzQZm4T86AGC9vFHjX60rSNFkGI2KA/s1600/Droid%20and%20phone%20Gemini%20-%20blog%20hero@2x.png"><img border="0" data-original-height="800" data-original-width="1058" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpMUkef4JqgRnGpbAD9Rmf-mN2fG3kBcfymsPyj7bNZV3U-a5cIzsstZoIyKxcL1rbOmHg_TRsrzlzXdtgVegN8795ovwjF_Q_qFkt7WGg0dmVI4ggRx3b5V0ToHpFbR1EgJ0qiAHd27OacIN3FVfo18ksfcZjggzQZm4T86AGC9vFHjX60rSNFkGI2KA/s1600/Droid%20and%20phone%20Gemini%20-%20blog%20hero@2x.png" /></a>
<p>Last week we unveiled our most capable foundation model, <a href="https://blog.google/technology/ai/google-gemini-ai/" target="_blank">Gemini</a>. Gemini is multimodal – it can accept both text and image inputs. We introduced a way for Android developers to leverage our smallest model <a href="https://goo.gle/ai-android-blog" target="_blank">Gemini Nano</a>, on-device. This is available on select devices through <a href="http://d.android.com/ml/aicore" target="_blank">AICore</a>, a system service that handles model management, runtimes, safety features and more, simplifying the work for developers. And today, we're introducing new ways for Android developers to access the <b>Gemini Pro</b> model – which runs off-device, in Google's data centers.</p>
<h3>App development with Gemini Pro</h3>
<p>Gemini Pro is accessible via the <a href="https://ai.google.dev/?utm_source=android&utm_medium=referral&utm_campaign=blog&utm_content=" target="_blank">Gemini API</a>, and it’s our best model for scaling across a wide range of text and image reasoning tasks. To simplify integrating Gemini Pro, you can use the <a href="http://ai.google.dev/tutorials/android_quickstart/?utm_source=android&utm_medium=referral&utm_campaign=blog&utm_content=" target="_blank">Google AI SDK</a>, a client SDK for Android. This SDK enables direct integration from Android apps and removes the need for developers to build and manage their own backend infrastructure, reducing development costs and improving velocity.</p>
<p><a href="https://makersuite.google.com/app/prompts/new_freeform/?utm_source=android&utm_medium=referral&utm_campaign=blog&utm_content=" target="_blank">Google AI Studio</a> provides a streamlined way for developers to integrate the Gemini Pro model, craft prompts, create API keys, and effortlessly transform ideas into AI apps. Once you have developed your prompt in Google AI Studio, you can simply click on the “Get code” action to generate a Kotlin code snippet, and start integrating Gemini today using the Google AI SDK for Android.</p>
<image><div style="text-align: center;"><img alt="Generate Kotlin code for the Gemini API in Google AI Studio" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGPWhQo7q9ZYKdn9K2q8SxKEf45upjjZ985sHMk_adY9d5885-yJewNlRbXLJq4gin5q0g0ZFXFIT4yHlyLZDnT_pc1jF0rEo63nEvzZw4XJEQFOFo3bFdDfs43girlgujn7sbXx9SscLsARheFK2ZWYU3kT22HoXI2uNGLN6S8fMObuBfhxUWR6S2woM/s1600/image5.png" style="margins: auto; width: auto;" /></div><imgcaption><center><em>Generate Kotlin code for the Gemini API in Google AI Studio</em></center></imgcaption></image>
<p>We are also making it easier for developers to use the Gemini API directly in the <a href="https://developer.android.com/studio/preview" target="_blank">latest preview version of Android Studio</a>. We’re introducing a <a href="https://developer.android.com/studio/preview/gemini-template" target="_blank">new project template</a> for developers to get started with the Google AI SDK for Android right away. You’ll benefit from Android Studio’s enhanced code completion and lint checkers, helping with API keys and security.</p>
<image><div style="text-align: center;"><img alt="New Project template for AI in Android Studio" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6qb8s_gJxz7FdBXiYWO84Y2q0AoTcIVOVRW3jr4AIE44rPAwLItIgguRBebdlUY4bXbc8E2sd4C5zbjY8VVHChVdcqtW-BrSsQuu3wb4VIwZK65ENVR41nnRN6BXlnLkWJneaTF26WTl8tngdK5-LdWzLMi-6KY_4qUJ3VLGzTzIfosbl4L9TPLaYPbw/s1600/image3.png" style="margins: auto; width: auto;" /></div><imgcaption><center><em>New Project template for AI in Android Studio</em></center></imgcaption></image>
<p>To leverage the new template in Android Studio, start a new project through <b>File > New > New Project</b> and pick the Gemini API starter template. This template provides a pre-configured project with the necessary code to use the Gemini API. After choosing a project name and location, you will be prompted to <a href="https://makersuite.google.com/app/apikey/?utm_source=android&utm_medium=referral&utm_campaign=blog&utm_content=" target="_blank">generate an API key</a> in Google AI Studio, and asked to enter it in Android Studio. Android Studio will automatically set up the project for you with the Gemini API connection, simplifying your workflow.</p>
<p>Alternatively, you can import the <a href="https://github.com/google/generative-ai-android/tree/main/generativeai-android-sample" target="_blank">generative AI code sample</a> and set it up in Android Studio through <b>File > New > Import Sample</b>, and searching for "Generative AI Sample".</p>
<image><div style="text-align: center;"><img alt="Generative AI sample app" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicoc7spUl6SToRG8IaCisdz8ZgagobEY7o9OW08CKuIGT4Oyo-dJ-2NMAONm2NfZMYUMExBOzt-pNJnM7kXY1Ot03JGseezAnkIWqOGeg0P1HGJMKbYjmFDl2w5PusedwZJcVZeMMASqw6_A74mOcYwaXGq6dfKi2t2mVGm9W2HfvBqjOJMnoZxgSuQpQ/s1600/image5.png" style="margins: auto; width: auto;" /></div><imgcaption><center><em>Generative AI sample app</em></center></imgcaption></image>
<div style="text-align: left;"><br /></div><p>Get started building AI-powered features and Android apps using <a href="http://ai.google.dev/tutorials/android_quickstart?utm_source=android&utm_medium=referral&utm_campaign=blog&utm_content=" target="_blank">Gemini Pro.</a></p><p></p><p></p>Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-56038915814620508542023-12-12T14:00:00.000-08:002023-12-12T14:00:32.107-08:00Faster Rust Toolchains for Android<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH2si5MBUire5oM0viqDat7PxpCNjKYb024GQre7I7E_-Ygnq6beqCwyUKxVren0GCp7mJVoYbExdRp4TRbWPezF4mVYOcsx1fL-_YK-yihZQdRvjFQCkJbxXlpBIRIDYJv4E7S7Av05VgNXwbxENcq7twVznzVFX32kFj36ttJbOkHEBZOK7c-IvrHiA/s1600/SOCIAL-Faster-Rust-Toolchains-for-Android.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH2si5MBUire5oM0viqDat7PxpCNjKYb024GQre7I7E_-Ygnq6beqCwyUKxVren0GCp7mJVoYbExdRp4TRbWPezF4mVYOcsx1fL-_YK-yihZQdRvjFQCkJbxXlpBIRIDYJv4E7S7Av05VgNXwbxENcq7twVznzVFX32kFj36ttJbOkHEBZOK7c-IvrHiA/s1600/SOCIAL-Faster-Rust-Toolchains-for-Android.png" style="display: none;" />
<em>Posted by Chris Wailes - Senior Software Engineer</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQhFvt_tTP6IPlMJpWe3pgseugZXIH7X4kQdrkdlkrnG2u3EuKAWrlRcXu1BQGZQVv9h9Np21rTH1HoIbElqXg55ilSnkAAT0TO9PaL11Z5s_qMFHhEL65vKzw2tQQ-JHG59ZvPFytngF1dbI-SO-joEfaTWAET7T3YbvjR5jsz23VsqhEVfDyA_IfJWs/s1600/HEADER-Faster-Rust-Toolchains-for-Android.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQhFvt_tTP6IPlMJpWe3pgseugZXIH7X4kQdrkdlkrnG2u3EuKAWrlRcXu1BQGZQVv9h9Np21rTH1HoIbElqXg55ilSnkAAT0TO9PaL11Z5s_qMFHhEL65vKzw2tQQ-JHG59ZvPFytngF1dbI-SO-joEfaTWAET7T3YbvjR5jsz23VsqhEVfDyA_IfJWs/s1600/HEADER-Faster-Rust-Toolchains-for-Android.png" /></a>
<p>The performance, safety, and developer productivity provided by Rust has led to rapid <a href="https://security.googleblog.com/2023/09/scaling-rust-adoption-through-training.html" target="_blank">adoption</a> in the <a href="https://security.googleblog.com/2022/12/memory-safe-languages-in-android-13.html" target="_blank">Android Platform</a>. Since <a href="https://opensource.googleblog.com/2023/06/rust-fact-vs-fiction-5-insights-from-googles-rust-journey-2022.html" target="_blank">slower build times are a concern</a> when using Rust, particularly within a massive project like Android, we've worked to ship the fastest version of the Rust toolchain that we can. To do this we leverage multiple forms of profiling and optimization, as well as tuning C/C++, linker, and Rust flags. Much of what I’m about to describe is similar to the build process for the official releases of the Rust toolchain, but tailored for the specific needs of the Android codebase. I hope that this post will be generally informative and, if you are a maintainer of a Rust toolchain, may make your life easier.</p>
<h3>Android’s Compilers</h3>
<p>While Android is certainly not unique in its need for a performant cross-compiling toolchain this fact, combined with the large number of daily Android build invocations, means that we must carefully balance tradeoffs between the time it takes to build a toolchain, the toolchain’s size, and the produced compiler’s performance.</p>
<h3>Our Build Process</h3>
<p>To be clear, the optimizations listed below are also present in the versions of <span style="color: #0d904f; font-family: Courier;">rustc</span> that are obtained using <span style="color: #0d904f; font-family: Courier;">rustup</span>. What differentiates the Android toolchain from the official releases, besides the provenance, are the cross-compilation targets available and the codebase used for profiling. All performance numbers listed below are the time it takes to build the Rust components of an Android image and may not be reflective of the speedup when compiling other codebases with our toolchain.</p>
<h3>Codegen Units (CGU1)</h3>
<p>When Rust compiles a crate it will break it into some number of code generation units. Each independent chunk of code is generated and optimized concurrently and then later re-combined. This approach allows LLVM to process each code generation unit separately and improves compile time but can reduce the performance of the generated code. Some of this performance can be recovered via the use of Link Time Optimization (LTO), but this isn’t guaranteed to achieve the same performance as if the crate were compiled in a single codegen unit.</p>
<p><b>To expose as many opportunities for optimization as possible and ensure reproducible builds we add the <span style="color: #0d904f; font-family: Courier;">-C codegen-units=1</span> option to the <span style="color: #0d904f; font-family: Courier;">RUSTFLAGS</span> environment variable. This reduces the size of the toolchain by ~5.5% while increasing performance by ~1.8%.</b></p>
<p>Be aware that setting this option will slow down the time it takes to build the toolchain by ~2x (measured on our workstations).</p>
<h3>GC Sections</h3>
<p>Many projects, including the Rust toolchain, have functions, classes, or even entire namespaces that are not needed in certain contexts. The safest and easiest option is to leave these code objects in the final product. This will increase code size and may decrease performance (due to caching and layout issues), but it should never produce a miscompiled or mislinked binary.</p>
<p>It is possible, however, <b>to ask the linker to remove code objects that aren’t transitively referenced from the <span style="color: #0d904f; font-family: Courier;">main()</span>function using the <span style="color: #0d904f; font-family: Courier;">--gc-sections</span> linker argument</b>. The linker can only operate on a section-basis, so, if any object in a section is referenced, the entire section must be retained. <b>This is why it is also common to pass the <span style="color: #0d904f; font-family: Courier;">-ffunction-sections</span> and <span style="color: #0d904f; font-family: Courier;">-fdata-sections</span> options to the compiler or code generation backend.</b> This will ensure that each code object is given an independent section, thus allowing the linker’s garbage collection pass to collect objects individually.</p>
<p>This is one of the first optimizations we implemented and, at the time, it produced significant size savings (on the order of 100s of MiBs). However, most of these gains have been subsumed by those made from setting <span style="color: #0d904f; font-family: Courier;">-C codegen-units=1</span> when they are used in combination and there is now no difference between the two produced toolchains in size or performance. However, due to the extra overhead, we do not always use CGU1 when building the toolchain. When testing for correctness the final speed of the compiler is less important and, as such, we allow the toolchain to be built with the default number of codegen units. In these situations we still run section GC during linking as it yields some performance and size benefits at a very low cost.</p>
<h3>Link-Time Optimization (LTO)</h3>
<p>A compiler can only optimize the functions and data it can see. Building a library or executable from independent object files or libraries can speed up compilation but at the cost of optimizations that depend on information that’s only available when the final binary is assembled. Link-Time Optimization gives the compiler another opportunity to analyze and modify the binary during linking.</p>
<p><b>For the Android Rust toolchain we perform <a href="https://blog.llvm.org/2016/06/thinlto-scalable-and-incremental-lto.html" target="_blank">thin LTO</a></b> on both the C++ code in LLVM and the Rust code that makes up the Rust compiler and tools. Because the IR emitted by our <span style="color: #0d904f; font-family: Courier;">clang</span> might be a different version than the IR emitted by <span style="color: #0d904f; font-family: Courier;">rustc</span> we can’t perform cross-language LTO or statically link against <span style="color: #0d904f; font-family: Courier;">libLLVM</span>. The performance gains from using an LTO optimized shared library are greater than those from using a non-LTO optimized static library however, so we’ve opted to use shared linking.</p>
<p>Using CGU1, GC sections, and LTO produces a speedup of ~7.7% and size improvement of ~5.4% over the baseline. This works out to a speedup of ~6% over the previous stage in the pipeline due solely to LTO.</p>
<h3>Profile-Guided Optimization (PGO)</h3>
<p>Command line arguments, environment variables, and the contents of files can all influence how a program executes. Some blocks of code might be used frequently while other branches and functions may only be used when an error occurs. By profiling an application as it executes we can collect data on how often these code blocks are executed. This data can then be used to guide optimizations when recompiling the program.</p>
<p>We use instrumented binaries to collect profiles from both building the Rust toolchain itself and from building the Rust components of Android images for <span style="color: #0d904f; font-family: Courier;">x86_64</span>, <span style="color: #0d904f; font-family: Courier;">aarch64</span>, and <span style="color: #0d904f; font-family: Courier;">riscv64</span>. <b>These four profiles are then combined and the toolchain is recompiled with profile-guided optimizations.</b> </p>
<p>As a result, the toolchain achieves a ~19.8% speedup and 5.3% reduction in size over the baseline compiler. This is a 13.2% speedup over the previous stage in the compiler.</p>
<h3>BOLT: Binary Optimization and Layout Tool</h3>
<p>Even with LTO enabled the linker is still in control of the layout of the final binary. Because it isn’t being guided by any profiling information the linker might accidentally place a function that is frequently called (hot) next to a function that is rarely called (cold). When the hot function is later called all functions on the same memory page will be loaded. The cold functions are now taking up space that could be allocated to other hot functions, thus forcing the additional pages that do contain these functions to be loaded.</p>
<p><a href="https://github.com/llvm/llvm-project/tree/main/bolt" target="_blank">BOLT</a> mitigates this problem by using an additional set of layout-focused profiling information to re-organize functions and data. For the purposes of speeding up <span style="color: #0d904f; font-family: Courier;">rustc</span> we profiled <span style="color: #0d904f; font-family: Courier;">libLLVM</span>, <span style="color: #0d904f; font-family: Courier;">libstd</span>, and <span style="color: #0d904f; font-family: Courier;">librustc_driver</span>, which are the compiler’s main dependencies. These libraries are then BOLT optimized using the following options:</p>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 2px;"><span style="font-family: courier;"><span style="color: #0d904f;">--peepholes=all</span>
<span style="color: #0d904f;">--data=<path-to-profile></span>
<span style="color: #0d904f;">--reorder-blocks=ext-tsp</span>
<span style="color: #0d904f;">–-reorder-functions=hfsort</span>
<span style="color: #0d904f;">--split-functions</span>
<span style="color: #0d904f;">--split-all-cold</span>
<span style="color: #0d904f;">--split-eh</span>
<span style="color: #0d904f;">--dyno-stats</span></span></pre></div>
<p>Any additional libraries matching <span style="color: #0d904f; font-family: Courier;">lib/*.so</span> are optimized without profiles using only <span style="color: #0d904f; font-family: Courier;">--peepholes=all</span>.</p>
<p>Applying BOLT to our toolchain produces a speedup over the baseline compiler of ~24.7% at a size increase of ~10.9%. This is a speedup of ~6.1% over the PGOed compiler without BOLT.</p>
<p>If you are interested in using BOLT in your own project/build I offer these two bits of advice: 1) you’ll need to emit additional relocation information into your binaries using the <span style="color: #0d904f; font-family: Courier;">-Wl</span>,<span style="color: #0d904f; font-family: Courier;">--emit-relocs</span> linker argument and 2) use the same input library when invoking BOLT to produce the instrumented and the optimized versions.</p>
<h3>Conclusion</h3>
<image><div style="text-align: center;"><img alt="Graph of normalized size and duration comparison between Toolchain size and Android Rust build time" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiloqDWWxNBXttLNQjVrKX4mrvn4AzrsM4UE1KY5VwFfXcEBVQGTQf6fK-a7ZyzlmC33SgdUJv3ABJIeEIFbojQzakXCI86fPZE_TpkIbpdw_HXD0DwQ3KQIl_lJrmObtZnVz1Vl2hEIqWZ6PqjrBwlUVftB-fyWZbVhp-DU4yAy_6kRe-_m2sJfQHgTQs/s16000/image1.png" style="margins: auto; width: auto;" /></div></image><br />
<div align="center" dir="ltr" style="margin-left: 0pt;">
<table style="border-collapse: collapse; border: none; margin-right: calc(11%); table-layout: fixed; width: 100%;">
<tbody>
<tr style="height: 0pt;">
<td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><b>Optimizations
</b><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"></p></td><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><b>Speedup vs Baseline
</b></td>
</tr>
<tr style="height: 0pt;">
<td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">
Monolithic
</td>
<td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">
1.8%
</td>
</tr>
<tr style="height: 0pt;">
<td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">Mono + GC Sections
<p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"></p></td><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">1.9%
</td>
</tr>
<tr style="height: 0pt;">
<td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">
Mono + GC + LTO
</td>
<td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">
7.7%
</td>
</tr>
<tr style="height: 0pt;">
<td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">
Mono + GC + LTO + PGO
</td>
<td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">
19.8%
</td>
</tr>
<tr style="height: 0pt;">
<td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;">Mono + GC + LTO + PGO + BOLT</p>
</td>
<td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">
24.7%
</td>
</tr>
</tbody>
</table>
</div>
<p>By compiling as a single code generation unit, garbage collecting our data objects, performing both link-time and profile-guided optimizations, and leveraging the BOLT tool we were able to speed up the time it takes to compile the Rust components of Android by 24.8%. For every 50k Android builds per day run in our CI infrastructure we save ~10K hours of serial execution.</p>
<p>Our industry is not one to stand still and there will surely be another tool and another set of profiles in need of collecting in the near future. Until then we’ll continue making incremental improvements in search of additional performance. Happy coding!</p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0tag:blogger.com,1999:blog-6755709643044947179.post-53161707076605167802023-12-07T08:00:00.000-08:002023-12-07T08:00:00.138-08:00KSP2 Preview: Kotlin K2 and Standalone Source Generator<meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZN8ICjCu1JRBCumZD-9CK6dV9Gq4fAkEe2lpsTao7njxZ64zVsBoWZc-UID_okfol4yS-AkKb2TPF0PT-7NvLw19xi9yoDRXSN0YfDZZuRbujrkpmVmB5u890diZPx0slqcAPeLxlK2oe1UAkY2IMdbD-NEwdHNHvyy_KPcrdBGuQ8Y4t6gALR69zyII/s1600/editorial-Ksp2-Preview-Kotlin-K2-social.png" name="twitter:image"></meta>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZN8ICjCu1JRBCumZD-9CK6dV9Gq4fAkEe2lpsTao7njxZ64zVsBoWZc-UID_okfol4yS-AkKb2TPF0PT-7NvLw19xi9yoDRXSN0YfDZZuRbujrkpmVmB5u890diZPx0slqcAPeLxlK2oe1UAkY2IMdbD-NEwdHNHvyy_KPcrdBGuQ8Y4t6gALR69zyII/s1600/editorial-Ksp2-Preview-Kotlin-K2-social.png" style="display: none;" />
<em>Posted by Ting-Yuan Huang – Software Engineer, and Jiaxiang Chen – Software Engineer
</em>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgciES-nL42T_uDeCEbNwdhYjKVh5FB9t8S-QJL8tr9eQu4h89A9fflFVFwEisju1Ii2g9YnRiHxgBoHNVzRFX_1W9pLqe2JP7vYYB0KmXeLt6LdQNa7IhwUvC_UXqEpKdOht_jG4yLQeVahycd8g_Zw2rxp6ccjFT97borB2Ivorh9yrHxhKZI9aqyLsw/s1600/Ksp2-Preview-Kotlin-K2-Banner.png"><img border="0" data-original-height="800" data-original-width="100%" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgciES-nL42T_uDeCEbNwdhYjKVh5FB9t8S-QJL8tr9eQu4h89A9fflFVFwEisju1Ii2g9YnRiHxgBoHNVzRFX_1W9pLqe2JP7vYYB0KmXeLt6LdQNa7IhwUvC_UXqEpKdOht_jG4yLQeVahycd8g_Zw2rxp6ccjFT97borB2Ivorh9yrHxhKZI9aqyLsw/s1600/Ksp2-Preview-Kotlin-K2-Banner.png" /></a>
<p>The Kotlin Symbol Processing (KSP) tool provides a high-level API for doing meta-programming in Kotlin. Many tools have been built on KSP, enabling Kotlin code to be generated at compile time. For example, Jetpack Room uses KSP to generate code for accessing the database, based on an interface provided by the developer, like:</p>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;">@Dao
<span style="color: green; font-weight: bold;">interface</span> UserDao {
@Query(<span style="color: #ba2121;">"SELECT * FROM user"</span>)
<span style="color: green; font-weight: bold;">fun</span> <span style="color: blue;">getAll</span>(): List<User>
}
</pre></div>
<p>KSP provides the API to the Kotlin code so that Room in this case can generate the actual implementation of that interface. While KSP has become a core foundation for meta-programing in Kotlin, its current implementation has some gaps which we are aiming to resolve with a new KSP2 architecture. This blog details those architectural changes and the impact for plugins built on KSP.</p>
<p>In addition, KSP2 has preview support for:</p>
<ul><ul>
<li>The new Kotlin compiler (code-named K2)</li>
<li>A new standalone source generator that provides more flexibility and features than the current Kotlin compiler plugin</li>
</ul></ul>
<p>After getting feedback on the new architecture and continuing to address gaps we will work towards releasing KSP 2.0 where these changes will be the default.</p>
<h3>Enabling the KSP2 Preview</h3>
<p>The new preview changes can be enabled in KSP 1.0.14 or newer using a flag in <span style="color: #0d904f; font-family: courier;">gradle.properties</span>:</p>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;">ksp.useKSP2=<span style="color: green; font-weight: bold;">true</span>
</pre></div>
<p>Note: You might need to enlarge the heap size of the Gradle daemon now that KSP and processors run in the Gradle daemon instead of the Kotlin compiler’s daemon (which has larger default heap size), e.g. <span style="color: #0d904f; font-family: courier;">org.gradle.jvmargs=-Xmx4096M -XX:MaxMetaspaceSize=1024m</span></p>
<h3>KSP2 and K2</h3>
<p>Internally KSP2 uses the Beta Kotlin K2 compiler (which will be the default compiler in Kotlin 2.0). You can use KSP2 before switching your Kotlin compiler to K2 (via the <span style="color: #0d904f; font-family: courier;">languageVersion</span> setting) but if you want to use K2 for compiling your code, check out: <a href="https://android-developers.googleblog.com/2023/07/try-k2-compiler-in-your-android-projects.html" target="_blank">Try the K2 compiler in your Android projects</a>.</p>
<h3>Standalone Source Generator</h3>
<p>KSP1 is implemented as a Kotlin 1.x compiler plugin. Running KSP requires running the compiler and specifying KSP and its plugin options. In Gradle, KSP’s tasks are customized compilation tasks, which dispatch real work to <span style="color: #0d904f; font-family: courier;">KotlinCompileDaemon</span> by default. This makes debugging and testing somewhat difficult, because <span style="color: #0d904f; font-family: courier;">KotlinCompileDaemon</span> runs in its own process, outside of Gradle.</p>
<p>In KSP2, the implementation can be thought of as a library with a main entry point. Build systems and tools can call KSP with this entry point, without setting up the compiler. This makes it very easy to call KSP programmatically and is very useful especially for debugging and testing. With KSP2 you can set breakpoints in KSP processors without having to perform any other / irregular setup tasks to enable debugging.</p>
<p>Everything becomes much easier because KSP2 now controls its lifecycle and can be called as a standalone program or programmatically, like:</p>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: green; font-weight: bold;">val</span> kspConfig = KSPJvmConfig.Builder().apply {
<span style="color: #408080; font-style: italic;">// All configurations happen here.</span>
}.build()
<span style="color: green; font-weight: bold;">val</span> exitCode = KotlinSymbolProcessing(kspConfig, listOfProcessors, kspLoggerImpl).execute()
</pre></div>
<h3>KSP2 API Behavior Changes</h3>
<p>With the new implementation, it is also a great opportunity to introduce some refinements in the API behavior so that developers building on KSP will be more productive, have better debuggability and error recovery. For example, when resolving <span style="color: #0d904f; font-family: courier;">Map</span><span style="color: #0d904f; font-family: courier;"><</span><span style="color: #0d904f; font-family: courier;">String,</span> <span style="color: #0d904f; font-family: courier;">NonExistentType</span><span style="color: #0d904f; font-family: courier;">></span>, KSP1 simply returns an error type. In KSP2, <span style="color: #0d904f; font-family: courier;">Map</span><span style="color: #0d904f; font-family: courier;"><</span><span style="color: #0d904f; font-family: courier;">String,</span> <span style="color: #0d904f; font-family: courier;">ErrorType</span><span style="color: #0d904f; font-family: courier;">></span> will be returned instead. Here is a list of the current API behavior changes we plan on making in KSP2:</p>
<ul><ol>
<li>Resolve implicit type from function call: <span style="color: #0d904f; font-family: courier;">val error = mutableMapOf</span><span style="color: #0d904f; font-family: courier;"><</span><span style="color: #0d904f; font-family: courier;">String, NonExistType>()</span>
<div><span style="color: #ffa400;"><b>KSP1:</b></span> The whole type will be an error type due to failed type resolution</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> It will successfully resolve the container type, and for the non-existent type in the type argument, it will correctly report errors on the specific type argument.</div></li><p></p>
<li>Unbounded type parameter
<div><span style="color: #ffa400;"><b>KSP1:</b></span> No bounds</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> An upper bound of <span style="color: #0d904f; font-family: courier;">Any?</span> is always inserted for consistency</div></li><p></p>
<li>Resolving references to type aliases in function types and annotations
<div><span style="color: #ffa400;"><b>KSP1:</b></span> Expanded to the underlying, non-alias type</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> Not expanded, like uses in other places.</div></li><p></p>
<li>Fully qualified names
<div><span style="color: #ffa400;"><b>KSP1:</b></span> Constructors have FQN if the constructor is from source, but not if the constructor is from a library.</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> Constructors do not have FQN</div></li><p></p>
<li>Type arguments of inner types
<div><span style="color: #ffa400;"><b>KSP1:</b></span> Inner types has arguments from outer types</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> Inner types has no arguments from outer types</div></li><p></p>
<li>Type arguments of star projections
<div><span style="color: #ffa400;"><b>KSP1:</b></span> Star projections have type arguments that are expanded to the effective variances according to the declaration sites.</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> No expansion. Star projections have <span style="color: #0d904f; font-family: courier;">null</span>s in their type arguments.</div></li><p></p>
<li>Variance of Java Array
<div><span style="color: #ffa400;"><b>KSP1:</b></span> Java Array has a invariant upper bound</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> Java Array has a covariant upper bound</div></li><p></p>
<li>Enum entries
<div><span style="color: #ffa400;"><b>KSP1:</b></span> An enum entry has its own subtype with a supertype of the enum class (incorrect behavior from language point of view)</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> An enum entry's type is the type of the enclosing enum class</div></li><p></p>
<li>Multi-override scenario
<div><p></p></div>
<div>For example</div>
<div style="background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: green; font-weight: bold;">interface</span> GrandBaseInterface1 {
<span style="color: green; font-weight: bold;">fun</span> <span style="color: blue;">foo</span>(): Unit
}
<span style="color: green; font-weight: bold;">interface</span> GrandBaseInterface2 {
<span style="color: green; font-weight: bold;">fun</span> <span style="color: blue;">foo</span>(): Unit
}
<span style="color: green; font-weight: bold;">interface</span> BaseInterface1 : GrandBaseInterface1 {
}
<span style="color: green; font-weight: bold;">interface</span> BaseInterface2 : GrandBaseInterface2 {
}
<span style="color: green; font-weight: bold;">class</span> <span style="color: blue; font-weight: bold;">OverrideOrder1</span> : BaseInterface1, GrandBaseInterface2 {
<span style="color: green; font-weight: bold;">override</span> <span style="color: green; font-weight: bold;">fun</span> <span style="color: blue;">foo</span>() = TODO()
}
<span style="color: green; font-weight: bold;">class</span> <span style="color: blue; font-weight: bold;">OverrideOrder2</span> : BaseInterface2, GrandBaseInterface1 {
<span style="color: green; font-weight: bold;">override</span> <span style="color: green; font-weight: bold;">fun</span> <span style="color: blue;">foo</span>() = TODO()
}
</pre></div>
<div><b><br /></b></div><div><span style="color: #ffa400;"><b>KSP1:</b></span></div>
<div>Find overridden symbols in BFS order, first super type found on direct super type list that contains overridden symbol is returned
For the example, KSP will say <span style="color: #0d904f; font-family: courier;">OverrideOrder1.foo()</span> overrides <span style="color: #0d904f; font-family: courier;">GrandBaseInterface2.foo()</span> and <span style="color: #0d904f; font-family: courier;">OverrideOrder2.foo()</span> overrides <span style="color: #0d904f; font-family: courier;">GrandBaseInterface1.foo()</span>
<div><span style="color: #4285f4;"><b>KSP2:</b></span></div>
<div>DFS order, first super type found overridden symbols (with recursive super type look up) in direct super type list is returned.</div>
<div>For the example, KSP will say <span style="color: #0d904f; font-family: courier;">OverrideOrder1.foo()</span> overrides <span style="color: #0d904f; font-family: courier;">GrandBaseInterface1.foo()</span> and <span style="color: #0d904f; font-family: courier;">OverrideOrder2.foo()</span> overrides <span style="color: #0d904f; font-family: courier;">GrandBaseInterface2.foo()</span></div></div></li>
<li>Java modifier
<div><span style="color: #ffa400;"><b>KSP1:</b></span> Transient/volatile fields are final by default</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> Transient/volatile fields are open by default</div></li><p></p>
<li>Type annotations
<div><span style="color: #ffa400;"><b>KSP1:</b></span> Type annotations on a type argument is only reflected on the type argument symbol</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> Type annotations on a type argument now present in the resolved type as well</div></li><p></p>
<li><span style="color: #0d904f; font-family: courier;">vararg</span> parameters
<div><span style="color: #ffa400;"><b>KSP1:</b></span> Considered an Array type</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> Not considered an <span style="color: #0d904f; font-family: courier;">Array</span> type</div></li><p></p>
<li>Synthesized members of Enums
<div><span style="color: #ffa400;"><b>KSP1:</b></span> <span style="color: #0d904f; font-family: courier;">values</span> and <span style="color: #0d904f; font-family: courier;">valueOf</span> are missing if the enum is defined in Kotlin sources</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> <span style="color: #0d904f; font-family: courier;">values</span> and <span style="color: #0d904f; font-family: courier;">valueOf</span> are always present</div></li><p></p>
<li>Synthesized members of data classes
<div><span style="color: #ffa400;"><b>KSP1:</b></span> <span style="color: #0d904f; font-family: courier;">componentN</span> and <span style="color: #0d904f; font-family: courier;">copy</span> are missing if the data class is defined in Kotlin sources</div>
<div><span style="color: #4285f4;"><b>KSP2:</b></span> <span style="color: #0d904f; font-family: courier;">componentN</span> and <span style="color: #0d904f; font-family: courier;">copy</span> are always present</div></li><p></p>
</ol></ul>
<h3>New Multiplatform Processing Scheme</h3>
<p>When it comes to the processing scheme, i.e. what sources are processed when, the principle of KSP is to be consistent with the build's existing compilation scheme. In other words, what the compiler sees is what processors see, plus the source code that is generated by processors.</p>
<div align="center" dir="ltr" style="margin-left: 0pt;">
<table style="border-collapse: collapse; border: none;">
<thead>
<tr style="height: 0pt;">
<th scope="col" style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">
<span style="font-weight: normal;">What processors see</span>
</th>
<th scope="col" style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><span style="font-weight: normal;">Kotlin compiler see
</span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"></p></th></tr></thead>
<tbody><tr style="height: 23.7979pt;"><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">ClassA.kt, UtilB.kt, InterfaceC.kt ... </td>
<td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;">ClassA.kt, UtilB.kt, InterfaceC.kt ... + GeneratedFromA.kt, ...</td>
</tr>
</tbody>
</table>
</div>
<p>In KSP1's current compilation scheme, common / shared source sets are processed and compiled multiple times, with each target. For example, <span style="color: #0d904f; font-family: courier;">commonMain</span> is processed and compiled 3 times in the following project layout. Being able to process all the sources from dependencies is convenient with one exception: Processors don’t see the sources generated from <span style="color: #0d904f; font-family: courier;">commonMain</span> when processing <span style="color: #0d904f; font-family: courier;">jvmMain</span> and <span style="color: #0d904f; font-family: courier;">jsMain</span>. Everything must be re-processed and that can be inefficient.</p>
<image><div style="text-align: center;"><img alt="Flow diagram illustrating sources generated from jvmMain and jsMain processing to commonMain" border="0" id="imgCaption" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw35G_18k1-mq1xccgFm3Ibp3qEcYk5Yx7HGBYdz-bRMhlsZ919E-7Xk0t8iYAf3dbnjOylYY-YJbFv_64xeYN6UIyKy9mCvKiK5OexUtn6wqY3WDvyIW0JknxVNnuUHC1NxSioSVpTyG_AkaidpFD6IKTD7zGNp_hhCAQdHZ8yPKvcxMgI5_93I-gfjs/s1600/Ksp2-Preview-Kotlin-Chart.png" width="75%" /></div></image><br />
<div align="center">
<table style="border-collapse: collapse; border: none; margin-right: calc(0%); width: 100%;">
<tbody>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 41.4768%;">
<p><span style="font-size: 11pt;">tasks</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 29.8571%;">
<p><span style="font-size: 11pt;">inputs</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 28.4867%;">
<p><span style="font-size: 11pt;">outputs</span></p>
</td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 41.4768%;">
<p><span style="font-size: 11pt;">kspKotlinCommonMainMetadata</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 29.8571%;">
<p><span style="font-size: 11pt;">commonMain</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 28.4867%;">
<p><span style="font-size: 11pt;">generatedCommon</span></p>
</td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 41.4768%;">
<p><span style="font-size: 11pt;">kspKotlinJvm</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 29.8571%;">
<p><span style="font-size: 11pt;">commonMain, jvmMain</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 28.4867%;">
<p><span style="font-size: 11pt;">generatedCommonJvm</span></p>
</td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 41.4768%;">
<p><span style="font-size: 11pt;">kspKotlinJs</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 29.8571%;">
<p><span style="font-size: 11pt;">commonMain, jsMain</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 28.4867%;">
<p><span style="font-size: 11pt;">generatedCommonJs</span></p>
</td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 41.4768%;">
<p><span style="font-size: 11pt;">compileKotlinCommonMainMetadata</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 29.8571%;">
<p><span style="font-size: 11pt;">commonaMain, generatedCommon</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 28.4867%;">
<p><span style="font-size: 11pt;">common.klib</span></p>
</td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 41.4768%;">
<p><span style="font-size: 11pt;">compileKotlinJvm</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 29.8571%;">
<p><span style="font-size: 11pt;">commonMain, jvmMain, generatedCommonJvm</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 28.4867%;">
<p><span style="font-size: 11pt;">app.jar</span></p>
</td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 41.4768%;">
<p><span style="font-size: 11pt;">compileKotlinJs</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 29.8571%;">
<p><span style="font-size: 11pt;">commonMain, jsMain, generatedCommonJs</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 28.4867%;">
<p><span style="font-size: 11pt;">main.js</span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p>In KSP2, we plan to add an experimental mode that tries to align to <a href="https://youtrack.jetbrains.com/issue/KT-61506/Multiplatform-Separate-common-resolution-in-K2" target="_blank">how source sets are compiled in K2</a> better. All sources can be processed only once with the available new processing scheme:</p>
<div align="center">
<table style="border-collapse: collapse; border: none;">
<tbody>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 34%;">
<p><span style="font-size: 9.5pt;">tasks</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 22%;">
<p><span style="font-size: 9.5pt;">inputs</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 19%;">
<p><span style="font-size: 9.5pt;">outputs</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 25%;">
<p><span style="font-size: 9.5pt;">Resolvable but not available in </span></p><p><span style="color: #188038; font-family: courier; font-size: 10pt;">getAllFiles</span><span style="font-size: 10pt;"> / </span></p><p><span style="color: #188038; font-family: courier; font-size: 10pt;">getSymbolsWithAnnotation</span></p>
</td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 34%;">
<p><span style="font-size: 9.5pt;">kspKotlinCommonMainMetadata</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 22%;">
<p><span style="font-size: 9.5pt;">commonMain</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 20%;">
<p><span style="font-size: 9.5pt;">generatedCommon</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 24%;"><br /></td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 34%;">
<p><span style="font-size: 9.5pt;">kspKotlinJvm</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 22%;">
<p><span style="font-size: 9.5pt;">jvmMain</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 20%;">
<p><span style="font-size: 9.5pt;">generatedJvm</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 24%;">
<p><span style="font-size: 9.5pt;">commonMain, generatedCommon</span></p>
</td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 34%;">
<p><span style="font-size: 9.5pt;">kspKotlinJs</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 22%;">
<p><span style="font-size: 9.5pt;">jsMain</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 20%;">
<p><span style="font-size: 9.5pt;">generatedJs</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 24%;">
<p><span style="font-size: 9.5pt;">commonaMain, generatedCommon</span></p>
</td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 34%;">
<p><span style="font-size: 9.5pt;">compileKotlinCommonMainMetadata</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 22%;">
<p><span style="font-size: 9.5pt;">commonaMain, generatedCommon</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 20%;">
<p><span style="font-size: 9.5pt;">common.klib</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 24%;"><br /></td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 34%;">
<p><span style="font-size: 9.5pt;">compileKotlinJvm</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 22%;">
<p><span style="font-size: 9.5pt;">commonMain, jvmMain, generatedCommon, generatedJvm</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 20%;">
<p><span style="font-size: 9.5pt;">app.jar</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 24%;"><br /></td>
</tr>
<tr>
<td style="border: 1pt solid rgb(0, 0, 0); width: 34%;">
<p><span style="font-size: 9.5pt;">compileKotlinJs</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 22%;">
<p><span style="font-size: 9.5pt;">commonMain, jsMain, generatedCommon, generatedJs</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 20%;">
<p><span style="font-size: 9.5pt;">main.js</span></p>
</td>
<td style="border: 1pt solid rgb(0, 0, 0); width: 24%;"><br /></td>
</tr>
</tbody>
</table>
</div>
<p>Please note that Kotlin 2.0 is still in beta and the compilation model is subject to change. Please let us know how this works for you and give us <a href="https://github.com/google/ksp/issues" target="_blank">feedback</a>.</p>
<h3>KSP2 Preview Feedback</h3>
<p>KSP2 is in preview but there is still more <a href="https://github.com/google/ksp/milestone/24" target="_blank">work to be done</a> before a stable release. We hope these new features will ultimately help you be more productive when using KSP! Please provide us with your <a href="https://github.com/google/ksp/issues" target="_blank">feedback</a> so we can make these improvements awesome as they progress towards being stable.</p>
Android Developershttp://www.blogger.com/profile/08588467489110681140noreply@blogger.com0