LightBlog

jeudi 7 octobre 2021

Advanced Android Development: Elevate app permissions using Shizuku

There are a lot of reasons the permissions normally granted to your app might not be enough. Maybe you’re like me and enjoy creating hacky apps that abuse the Android API. Some of the APIs I use are locked behind special permissions. Sometimes only the shell user (ADB) or system can access them. There’s a solution though — Shizuku.

Shizuku allows you to call system APIs almost directly, and entirely in Java or Kotlin. This guide will show you how to implement and use Shizuku.

What is Shizuku?

Before we go about using Shizuku, it might be helpful to know what exactly it is. If you’re familiar with Magisk, then Shizuku is similar. But instead of managing root access, it manages shell access.

Shizuku runs its own process with shell-level permissions. How the user activates that process depends on their device, Android version, and choice. Shizuku can be activated through ADB, through on-device wireless ADB (on Android 11 and later), or through root access. Apps implementing Shizuku can then request permission to use that process to perform elevated operations.

Shizuku (Free, Google Play) →

Why Shizuku?

While shell-level access to the system doesn’t let you do as much as root, it still gives you more access than a normal app would. On top of that, the way Shizuku works lets you use the Android APIs almost like normal. You don’t have to rely on shell commands (although you can if you want to).

If your app needs special permissions that can only be granted through ADB (or with root), Shizuku and Android 11 make a great pairing. You can just use Shizuku to grant special permissions fully on-device.

Even with devices that aren’t on Android 11, Shizuku can be useful. The app provides instructions and scripts for users so you don’t have to.

Integration

Adding Shizuku to your app isn’t the simplest, but it’s not hard, either. Unfortunately, the developer documentation isn’t exactly complete, but this article has you covered. Here’s how to integrate Shizuku into your app.

Dependencies

The first step is to add the Shizuku dependencies. In your module-level build.gradle, add the following to the dependencies block.

def shizuku_version = '11.0.3'

implementation "dev.rikka.shizuku:api:$shizuku_version"
implementation "dev.rikka.shizuku:provider:$shizuku_version"

Make sure to update the version if needed. 11.0.3 is the latest at the time of writing.

Provider

In order for Shizuku to work, you need to add a provider block to your app’s manifest. Open AndroidManifest.xml and add the following inside the application block.

<provider
    android:name="rikka.shizuku.ShizukuProvider"
    android:authorities="${applicationId}.shizuku"
    android:multiprocess="false"
    android:enabled="true"
    android:exported="true"
    android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />

Permission

For authorization, Shizuku uses a runtime permission. We’ll get into granting that permission in a bit. For now, add it to AndroidManifest.xml inside the manifest block.

Now that all of that is added, the basic integration is done. Let Gradle do a project sync, and continue on to Usage.


Usage

Checking Availability

Before going into how to use Shizuku, let’s talk about making sure it’s actually available to use.

Before checking to see if the permission is granted, and before making API calls through Shizuku, you can make sure those checks and calls will succeed with the following method:

Shizuku.pingBinder()

If Shizuku is installed and running, this will return true. Otherwise, it will return false.

Granting Permission

Since Shizuku uses a runtime permission, it has to be granted to your app before you can do anything with shell access. There are also two API versions in circulation, with different ways of granting it. This section will show you how to handle both.

Checking

Before you request the permission, the best thing to do is to check if you already have it. If you do, you can continue with whatever you need to do. Otherwise, you’ll need to request it before continuing.

To check if you have permission to use Shizuku, you can use the following. This code is assuming you’re running it inside an Activity.

Kotlin:

val isGranted = if (Shizuku.isPreV11() || Shizuku.getVersion() < 11) {
    checkSelfPermission(ShizukuProvider.PERMISSION) == PackageManager.PERMISSION_GRANTED
} else {
    Shizuku.checkSelfPermission() = PackageManager.PERMISSION_GRANTED
}

Java:

boolean isGranted;
if (Shizuku.isPreV11() || Shizuku.getVersion() < 11) {
    isGranted = checkSelfPermission(ShizukuProvider.PERMISSION) == PackageManager.PERMISSION_GRANTED;
} else {
    isGranted = Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED;
}

Requesting

If you need to request permission to use Shizuku, here’s how.

The SHIZUKU_CODE variable used below should be an integer with a steady value (static variable).

Kotlin:

if (Shizuku.isPreV11() || Shizuku.getVersion() < 11) {
    requestPermissions(arrayOf(ShizukuProvider.PERMISSION), SHIZUKU_CODE)
} else {
    Shizuku.requestPermission(SHIZUKU_CODE)
}

Java:

if (Shizuku.isPreV11() || Shizuku.getVersion() < 11) {
    requestPermissions(new String[] { ShizukuProvider.PERMISSION }, SHIZUKU_CODE);
} else {
    Shizuku.requestPermissions(SHIZUKU_CODE);
}

To listen for the result, you’ll need to override Activity’s onRequestPermissionsResult() method. You’ll also need to implement Shizuku.OnRequestPermissionResultListener. The example I’m going to show assumes your Activity implements that interface, but you can implement it in a variable if you want.

Kotlin:

class ExampleActivity : AppCompatActivity, Shizuku.OnRequestPermissionResultListener {
    ...

    override void onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        permissions.forEachIndexed { index, permission ->
            if (permission == ShizukuProvider.PERMISSION) {
                onRequestPermissionResult(requestCode, grantResults[index])
            }
       }
    }

    override void onRequestPermissionResult(requestCode: Int, grantResult: Int) {
        val isGranted = grantResult == PackageManager.PERMISSION_GRANTED
        //Do stuff based on the result.

    }
}

Java:

public class ExampleActivity extends AppCompatActivity implements Shizuku.OnRequestPermissionResultListener {
    ...

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        for (int i = 0; i < permissions.length; i++) {
            String permission = permissions[i];
            int result = grantResults[i];

            if (permission.equals(ShizukuProvider.PERMISSION) {
                onRequestPermissionResult(requestCode, result);
            }
        }
    }

    @Override
    public void onRequestPermissionResult(int requestCode, int grantResult) {
        boolean isGranted = grantResult == PackageManager.PERMISSION_GRANTED;
        //Do stuff based on the result.
    }
}

Using APIs

Now that Shizuku is set up and permissions are granted, you can start actually calling APIs using Shizuku. The process here is a little different than you might be used to. Instead of calling getSystemService() and casting to something like WindowManager, you’ll have to use the internal APIs for these instead (e.g., IWindowManager).

Shizuku includes a bypass for Android’s hidden API blacklist, so you won’t need to worry about that when using it. If you’re curious how to bypass that yourself though, check out my previous tutorial.

Here’s a quick example (using reflection) showing you how you can get an instance of IPackageManager and use it to grant an app a runtime permission.

Kotlin:

val iPmClass = Class.forName("android.content.pm.IPackageManager")
val iPmStub = Class.forName("android.content.pm.IPackageManager\$Stub")
val asInterfaceMethod = iPmStub.getMethod("asInterface", IBinder::class.java)
val grantRuntimePermissionMethod = iPmClass.getMethod("grantRuntimePermission", String::class.java /* package name */, String::class.java /* permission name */, Int::class.java /* user ID */)

val iPmInstance = asInterfaceMethod.invoke(null, ShizukuBinderWrapper(SystemServiceHelper.getSystemService("package")))

grantRuntimePermissionMethod.invoke(iPmInstance, "com.zacharee1.systemuituner", android.Manifest.permission.WRITE_SECURE_SETTINGS, 0)

Java:

Class<?> iPmClass = Class.forName("android.content.pm.IPackageManager");
Class<?> iPmStub = Class.forName("android.content.pm.IPackageManager$Stub");
Method asInterfaceMethod = iPmStub.getMethod("asInterface", IBinder.class);
Method grantRuntimePermissionMethod = iPmClass.getMethod("grantRuntimePermission", String.class, String.class, int.class);

val iPmInstance = asInterfaceMethod.invoke(null, new ShizukuBinderWrapper(SystemServiceHelper.getSystemService("package")));

grantRuntimePermissionMethod.invoke(iPmInstance, "com.zacharee1.systemuituner", android.Manifest.permission.WRITE_SECURE_SETTINGS, 0);

The process for other APIs is similar. Get the references to the class and its Stub sub-class. Get the reference to the asInterface method for the Stub class. Get the references to the methods you want from the class itself. Then, invoke the asInterface method reference you have, replacing "package" above with whatever service you need. That instance can then be passed for method invocations.

Pro-tip: you can avoid using reflection altogether if you install a modified SDK. Check out anggrayudi’s GitHub repository for the modified SDKs and installation instructions. With this installed, the above code (in Kotlin) becomes a whole lot simpler.

val iPm = IPackageManager.Stub.asInterface(ShizukuBinderWrapper(SystemServiceHelper.getService("package"))))
iPm.grantRuntimePermission("com.zacharee1.systemuituner", android.Manifest.permission.WRITE_SECURE_SETTINGS, 0)

Any AIDL-based APIs can be used with this method from anywhere in your app, as long as Shizuku is running and your app has permission.

User Service

While the Binder method covers most use-cases, there may be times where you need an API that doesn’t have a direct Binder interface. In that case, you can use the User Service feature in Shizuku.

This method works similarly to a normal Service in Android. You “start” it, communicate by binding to it with a ServiceConnection, and run your logic in the service class. The difference is you aren’t using Android’s Service, and anything inside the service runs with ADB permissions.

Now there are some limitations. The User Service runs in a completely separate process and user, so you can’t interact with the rest of your app except through your own AIDL callbacks and Binders. Since it’s also not running in a proper app process, some things like binding Android Services may not work properly.

This also requires Shizuku version 10 or later. While most sources for the app have version 11 currently, you should still include a version check, which will be included in the example.

Defining an AIDL

To get started, you’ll need to create a new AIDL file. You can do this in Android Studio by right-clicking anything in the Android file-view, hovering over the “New” option, and choosing the “AIDL” option. Enter the name of the file (e.g., “IUserService”), and Android Studio will create a template file for you.

If you aren’t familiar with how AIDLs work, be sure to check out Google’s documentation.

Remove the template methods from the AIDL and then add a destroy() method with the proper ID for Shizuku. This will be called when Shizuku is killing the User Service, and should be used to clean up any references or ongoing logic you have.

Example AIDL:

package tk.zwander.shizukudemo;

interface IUserService {
    void destroy() = 16777114;

    void grantPermission(String packageName, String permission, int userId) = 1; //You can specify your own method IDs in the AIDL. Check out the documentation for more details on this.
}

Implementing the AIDL

The next thing to do is actually implement the AIDL.

Java:

public class UserService extends IUserService.Stub {
    //Make sure to include an empty constructor.
    public UserService() {
    }

    @Override
    public void destroy() {
        //Shizuku wants the service to be killed. Clean up and then exit.
        System.exit(0);
    }

    @Override
    public void grantPermission(String packageName, String permission, int userId) {
        //No need to use ShizukuBinderWrapper.
        IPackageManager.Stub.asInterface(SystemServiceHelper.getService("package")).grantRuntimePermission(packageName, permission, userId);
    }
}

Kotlin:

class UserService : IUserService.Stub {
    //Include an empty constructor.
    constructor() {
    }

    override fun destroy() {
        //Shizuku wants the service to be killed. Clean up and exit.
        System.exit(0)
    }

    override fun grantPermission(packageName: String, permission: String, userId: Int) {
        //No need for ShizukuBinderWrapper.
        IPackageManager.Stub.asInterface(SystemServiceHelper.getService("package")).grantRuntimePermission(packageName, permission, userId)
    }
}

The above examples assume you have the Android Hidden API SDK installed.

Setting up the Service Connection

Now that the User Service is defined and implemented, it’s time to get it set up for use. The first thing you should do is define a ServiceConnection where you want to communicate with it (e.g., from the main Activity in your app).

Java:

private IUserService binder = null;

private final ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder binder) {
        if (binder != null && binder.pingBinder()) {
            binder = IUserService.Stub.asInterface(binder);
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        binder = null;
    }
}

Kotlin:

private var binder: IUserService? = null

private val connection = object : ServiceConnection {
    override fun onServiceConnected(componentName: ComponentName, binder: IBinder?) {
        if (binder != null && binder.pingBinder()) {
            binder = IUserService.Stub.asInterface(binder)
        }
    }

    override fun onServiceDisconnected(componentName: ComponentName) {
        binder = null;
    }
}

The binder variable is what you’ll be using to communicate with the User Service from your app. To check if it’s available for use, just check that it’s not null and that pingBinder() returns true, just like in the code example above.

Creating the User Service arguments

Before you can control the User Service, you’ll need to define some arguments for Shizuku to use when starting and stopping it. These include things like actually telling Shizuku the class name of the service, specifying the process suffix, whether or not it’s debuggable, and what version it is.

Java:

private final Shizuku.UserServiceArgs serviceArgs = new Shizuku.UserServiceArgs(
    new ComponentName(BuildConfig.APPLICATION_ID, UserService.class.getName()))
        .processNameSuffix("user_service")
        .debuggable(BuildConfig.DEBUG)
        .version(BuildConfig.VERSION_CODE);

Kotlin:

private val serviceArgs = Shizuku.UserServiceArgs(
    ComponentName(BuildConfig.APPLICATION_ID, UserService.class::java.getName()))
        .processNameSuffix("user_service")
        .debuggable(BuildCOnfig.DEBUG)
        .version(BuildConfig.VERSION_CODE)

Starting, Stopping, and Binding the User Service

The start and bind actions and the stop and unbind actions are unified in Shizuku. There aren’t separate start and bind methods or stop and unbind methods.

Here’s how to start and bind the User Service.

Java:

if (Shizuku.getVersion >= 10) {
    //This only works on Shizuku 10 or later.
    Shizuku.bindUserService(serviceArgs, connection);
} else {
    //Tell the user to upgrade Shizuku.
}

Kotlin:

if (Shizuku.getVersion() >= 10) {
    //This only works on Shizuku 10 or later.
    Shizuku.bindUserService(serviceArgs, connection)
} else {
    //Tell the user to upgrade Shizuku.
}

Here’s how to stop and unbind the User Service.

Java:

if  (Shizuku.getVersion >= 10) {
    Shizuku.unbindUserService(serviceArgs, connection, true);
}

Kotlin:

if (Shizuku.getVersion >= 10) {
    Shizuku.unbindUserService(serviceArgs, connection, true)
}

Invoking the User Service

Once the User Service is started, you can start using it. Simply check whether the binder variable is non-null and pingable, and then make your method call.

Java:

if (binder != null && binder.pingBinder()) {
    binder.grantPermission("com.zacharee1.systemuituner", android.Manifest.permission.WRITE_SECURE_SETTINGS, 0);
}

Kotlin:

if (binder?.pingBinder() == true) {
    binder?.grantPermission("com.zacharee1.systemuituner", android.Manifest.permission.WRITE_SECURE_SETTINGS, 0)
}

Conclusion

If you followed through all of that, you should now have a working Shizuku integration. Just remember to tell your users to install Shizuku, and to properly check that Shizuku is available before trying to use it.

The post Advanced Android Development: Elevate app permissions using Shizuku appeared first on xda-developers.



from xda-developers https://ift.tt/3uQa3eZ
via IFTTT

YouTube might be planning on improving its podcast experience

Although Google already has a dedicated app for podcasts, the company is reportedly planning on improving the podcast experience on YouTube. The company has posted an opening for an executive who would oversee its podcasting business.

Although many users already use YouTube to listen to podcasts, it isn’t one of the platform’s core offerings. However, Google allegedly wants to change that. According to a YouTube spokesperson (via Bloomberg), the company is currently on the lookout for an executive to “be in charge of organizing and managing the millions of podcasts that already exist on the site.” This news comes just a few weeks after YouTube launched its first-ever official podcast called “The Upload: The Rise of the Creator Economy.”

Currently, many creators use YouTube as a supplementary platform to share their podcasts. They either publish the podcast as a reaction video or as an audio file with generic cover art. While listeners can easily tune in to such uploads on YouTube or YouTube Music across all platforms, the service doesn’t offer any podcast-specific features to improve the listening experience. However, the company might address that in the future.

Since Google already offers a dedicated app for podcasts, though, it isn’t clear to what extent it wants to improve YouTube’s podcast experience. However, we won’t be surprised if Google eventually kills off Google Podcasts and integrates all of its features into YouTube. It’s worth noting that if the company is indeed planning such a transition, it’s likely way out into the future, as it’s actively updating the Google Podcasts app with new features and design changes.

Do you listen to podcasts on YouTube? Would you like to see more podcast-specific features on the service or would you rather use Google Podcasts? Share your thoughts in the comments section below.

The post YouTube might be planning on improving its podcast experience appeared first on xda-developers.



from xda-developers https://ift.tt/3Fu5xYO
via IFTTT

AMD processors are slower on Windows 11, but a fix is coming

Windows 11 began rolling out this week after just over three months of public testing with Windows Insiders. While the operating system launched with a few known issues, it seems that one may have slipped by undetected. AMD has confirmed that its processors are being negatively affected by the Windows 11 upgrade, resulting in reduced performance in certain situations. Thankfully, resolutions are already on the way.

AMD points out two distinct problems with its processors and Windows 11. The first has to do with the latency of the L3 cache on its processors, which may be as much as three times higher on Windows 11. This will particularly affect performance in apps that may depend on the access time to the memory subsystem, including some fast-paced esports titles. AMD says the performance may be as high as 15% in very specific games, but generally the performance impact ranges between 3% and 5%.

For this one, AMD says a fix is coming as Windows 11 update later this month, presumably with next week’s Patch Tuesday updates. This will be the first cumulative update for Windows 11 since its general availability, so we should see plenty of bug fixes roll out alongside this one.

The other issue has to do with the “preferred core” feature in UEFI systems not scheduling tasks for the fastest core available in a given scenario. This could affect the performance of applications that rely mostly on a single or a few cores, since multi-threaded tasks would use all of the available cores anyway. As such, the performance impact may be more significant in processors with high core and thread counts, specifically those with a 65W TDP or higher. AMD doesn’t explicitly say how big the performance impact may be.

Regardless, a fix is also in the works for this problem. AMD says it will arrive via a “software update”, not a Windows update, so it may come in the form of a new driver release for Windows 11. This fix, too, is expected sometime this month.

Windows 11 is rolling out gradually, and it’s likely many users haven’t upgraded yet, so this shouldn’t be a huge issue. It’s not unheard of for problems to arise after major new updates like this, and at least a fix is coming relatively quickly. We’ve also heard of an issue with Virtualization-Based Security potentially affecting gaming performance, which is currently being investigated by Microsoft. If you haven’t yet, read your Windows 11 review to see why we recommend the upgrade to anyone using Windows 10.

The post AMD processors are slower on Windows 11, but a fix is coming appeared first on xda-developers.



from xda-developers https://ift.tt/3iGZupJ
via IFTTT

Apple App Store will require apps to provide an account deletion option starting next year

Apple is well known for how strictly it enforces App Store policies. Whenever a developer breaks one of them, their app gets rejected until they abide by Apple’s rules. The latest policy issued from Cupertino is, unsurprisingly, data-focused. Starting next year, Apple will force developers to include an account deletion option in their apps, assuming users can create a new account through said apps.

As per a report from The Verge, Apple shared a new announcement yesterday on its Developer website. It states:

The updates to App Store Review Guideline 5.1.1 last June provided users with greater control over their personal data, stating that all apps that allow for account creation must also allow users to initiate deletion of their account from within the app. This requirement applies to all app submissions starting January 31, 2022. We encourage you to review any laws that may require you to maintain certain types of data, and to make sure your app clearly explains what data your app collects, how it collects that data, all uses of that data, your data retention/deletion policies, and more as described in the guideline. Examples of this type of data include electronic health records, and sales and warranty records. Please also confirm that the app privacy information on your product page is accurate.

So starting January 31 of the upcoming year, developers will no longer be able to submit new apps or updates to existing ones if they don’t meet the new policy criteria.

This change is a welcome one, as it will help users feel more at peace. It might even encourage them to try new apps since they will no longer have to worry about endless website redirects to delete their accounts from a service.

What do you think of this new policy? Will it encourage you to try more apps? Let us know in the comments section below.

The post Apple App Store will require apps to provide an account deletion option starting next year appeared first on xda-developers.



from xda-developers https://ift.tt/2YuYQEs
via IFTTT

The Moto G Pure is a new budget phone with an outdated design

After launching the Moto G50 5G towards the end of August, Motorola is now back with another G series device. The latest addition to the lineup is an affordable phone called the Moto G Pure, and it features budget hardware and an outdated design. Read on to learn more about Motorola’s latest budget offering.

Moto G Pure: Specifications

Specification Moto G Pure
Build
  • IP52 water-resistance
Dimensions & Weight
  • 167.36 x 75.63 x 8.75mm
  • 188g
Display
  • 6.5-inch HD+ LCD
  • 1600 x 720p
SoC MediaTek Helio G25
RAM & Storage
  • 3GB RAM
  • 32GB storage
  • Expandable up to 512GB
Battery & Charging
  • 4,000mAh
  • 10W charging support
Security Rear-mounted fingerprint reader
Rear Camera(s)
  • Primary: 13MP f/2.2
  • Depth sensor: 2MP f/2.4
Front Camera(s) 5MP f/2.4
Port(s)
  • USB Type-C
  • 3.5mm headphone jack
Audio
  • Single bottom-firing speaker
  • Dual-mic
Connectivity
  • 4G LTE
  • 802.11 a/b/g/n/ac dual-band Wi-Fi
  • Bluetooth 5.0
  • GPS, A-GPS, LTEPP, SUPL, GLONASS, Galileo
Software Android 11
Color(s) Deep Indigo

As you can see in the attached images, the new Moto G Pure looks nothing like the other Moto G series devices launched this year. It features the same design as Motorola devices from last year, with a pill-shaped camera module and a textured back panel. Over on the front, it features huge bezels around the display and a teardrop-style notch at the top for the selfie cameras.

Moto G Pure front Moto G Pure back

As you’d expect from looking at its design, the Moto G Pure isn’t a powerhouse of a device. It features a 6.5-inch HD+ display backed by a MediaTek Helio G25 chip, 3GB RAM, and 32GB storage. The device has a dual-camera setup on the back, featuring a 13MP primary sensor and a 2MP depth sensor, and a single 5MP selfie shooter on the front.

Thankfully, it does have a substantially large 4,000mAh battery, which, combined with the budget-centric hardware, should deliver excellent battery life. However, charging up the device won’t be that good of an experience, as it only supports 10W wired charging. For connectivity, the Moto G Pure features a USB Type-C port, a 3.5mm headphone jack, 4G LTE support, dual-band Wi-Fi, and Bluetooth 5.0.

Other noteworthy features include IP52 certification, a rear-mounted fingerprint scanner, a single bottom-firing speaker, and dual microphones. The Moto G Pure runs Android 11 out of the box.

Pricing & Availability

The Moto G Pure will be available for pre-order in the US starting October 14. Motorola will offer the device in a single Deep Indigo color variant. The phone will retail for $159.99 on Best Buy, Walmart, B&H Photo, Amaazon.com, and Motorola’s website. It will also be available through Verizon on the same date. T-Mobile and Metro will offer the device in the coming months.

    Moto G Pure
    The Moto G Pure is a budget-friendly device featuring the MediaTek Helio G25 SoC, a 6.5-inch HD+ display, and an outdated design.

Motorola says that the Moto G Pure will go on sale in Canada in the coming months, but it hasn’t shared a definite timeline for the same.

The post The Moto G Pure is a new budget phone with an outdated design appeared first on xda-developers.



from xda-developers https://ift.tt/3muDDDb
via IFTTT

iPhone 13 Mini Review: The best small phone ever made

Last month’s Apple event taught us one simple thing: small is undoubtedly mighty and the iPad Mini 6, iPhone 13 Mini, and iPhone 13 Pro all follow the same model of offering the same key experience as their bigger counterparts, in a smaller more compact form factor.

XDA Recommended Product in 2020 Award Badge
The iPhone 13 Pro is undoubtedly the best iPhone you can buy right now, offering the same features as the iPhone 13 Pro Max in a smaller form factor. Normally, this would be at the expense of battery life, but as we discovered in our iPhone 13 Pro review, the bigger battery in the iPhone 13 Pro this year results in a battery life that’s close to the iPhone 12 Pro Max from last year. The result means you can buy the smaller iPhone and save a little money – which could be used to upgrade to the 256GB variant and get the ProRes video at 4k – without compromising on a specific feature or overall longevity.

The iPhone 13 Mini follows the same philosophy as the iPhone 13 Pro: it offers all the features detailed in our iPhone 13 review, but in a much more compact form factor. After spending two weeks with the Mini, I’ll tell you that it’s the best iPhone right now if you don’t need the Pro specs, and it has certainly changed my feelings towards the iPhone 13 Pro. It’s also proven to be good enough for my usage over the past two weeks, good enough that I’m likely keeping the iPhone 13 Mini as my main iPhone going forward, not the iPhone 13 Pro.

    Apple iPhone 13 mini
    The iPhone 13 mini is the best small phone ever made, and sets the standard that all compact phones must follow. Despite the better features of the iPhone 13 Pro, the size of the iPhone 13 mini means its become my go-to iPhone to grab. It’s the best small Pro phone for all users and most people won’t need the features of the iPhone 13 Pro either.

iPhone 13 Mini: The benchmark for compact flagships

It’s still seriously shocking to me that so few companies cater to the small phone market, especially on the flagship end. Look around at the best phones right now, and there’s only one phone that properly ticks the boxes of being a flagship and yet being compact: the iPhone 13 Mini. That’s not because others haven’t tried; Sony’s Compact phones followed the same model. But most companies who build something smaller compromise on the overall experience, without reducing the price as much.

If you’re looking for a compact phone, Apple does it best

If you’re looking for a compact phone, most companies approach it one specific way: not only will you pay close to flagship pricing for a compact phone, you’ll also be forced to pay for a stripped-down experience. It’s almost as if you’re being penalized for wanting a smaller phone. It’s almost like performance and power cannot co-exist with a small form factor, and we know that that is not entirely true.

Apple, however, takes a very different approach. Knowing that many users of devices like the iPhone 8 or older are used to screens around the 5.5-inch mark or smaller, and may not want to go for a larger screen, it creates two phones that satisfy the compact one-handed form factor: the iPhone 13 Mini and the iPhone SE 2. The latter is basically a carbon copy of the old iPhone 6 with updated internals, while the iPhone 13 Mini is effectively an iPhone SE Pro and offers an upgraded compact experience at a higher price.

Yes, the Mini does still have a 60Hz display — but it is the same as the regular-sized iPhone of this generation, and you’d need to bump up to the Pros to get the 120Hz refresh rate. And because of the nature of iOS and its animations, the difference in experience between 60Hz and 120Hz on an iPhone is not as pronounced as it would be on Android. And yes, there is no fifth core on the A15 Bionic’s GPU; but four cores continue to be overkill anyway. And yes, there is no telephoto or macro capabilities, but these do appear to be limited to the space within the device for more cameras and larger camera setups. Yes, all of these are indeed limitations, but they are limitations on the more overkill territory. You still get a proper flagship experience with the iPhone 13 Mini — just not that of an overkill flagship.

The only real compromises on the iPhone 13 Mini are thanks to physics

The reason the iPhone 13 Mini is easily the best small phone ever made comes down to Apple’s approach. As mentioned, instead of taking an Android manufacturer’s approach of stripping the experience back, the iPhone 13 Mini is basically the same as the iPhone 13, just in a smaller form factor. The smaller body size means a smaller screen size and a physically smaller battery, resulting in slightly lower battery life, but these are all thanks to physics.

Beyond the comparison, the iPhone 13 Mini continues to offer the boxy, flat sides design language Apple has introduced across all of its devices. The flat railing around the iPhone 13 Mini is crafted out of aluminum and it has a matte finish. It’s got a 60Hz OLED screen interrupted by a notch. The front side is covered by what Apple calls “Ceramic Shield” technology. Around the back, we have a slightly glossy glass back with a dual-camera system consisting of a 12MP main (wide) lens and a 12MP ultra-wide lens. Both rear cameras’ sensors are new and larger than the iPhone 12 Mini’s sensors. The battery is larger than that of the 12 Mini, and we’ll have more to talk about it in the next section.

The overall iPhone 13 Mini experience is really impressive, though. I’ve got the iPhone 13 Pro, iPhone 13, and iPhone 13 Mini here and I almost always pick up the iPhone 13 Mini first. It’s the perfect size to be ergonomically friendly for one-handed use, and it’s designed to offer a flagship experience with few compromises along the way.

iPhone 13 Mini Battery: Bigger, better, and more impressive

Much like the rest of the iPhone 13 series, the 13 Mini offers a bigger battery size that results in better battery life. The actual battery life will vary according to your usage, the ambient lighting conditions (which affect the brightness of the display), and your cell signal. The latter is a point to note – like any phone, a bad cell signal will result in poor battery life.

The iPhone 13 Mini battery finally lasts all-day

During an average day of usage, the iPhone 13 Mini is capable of lasting 14-16 hours on a full charge with around 5-6 hours of screen time. This is my first experience with Apple’s mini form factor, but my colleague Sumukh used the iPhone 12 Mini for a year and recently upgraded to the iPhone 13 Mini. He has found that – much like the rest of the iPhone 13 series – the battery on the iPhone 13 Mini lasts about 2 hours longer than the iPhone 12 Mini.

It’s hard for me to judge the iPhone 13 Mini battery life without knowing how it compares to the competition, which is basically last year’s iPhone 12 Mini and the iPhone SE. I used the revamped iPhone SE last year, and the iPhone 13 Mini battery life is definitely better than that. It’s also better than some other phones I’ve used recently including the Galaxy Z Flip 3, and quite comparable to last year’s iPhone 12 which I used extensively.

All this to say – I’m not the target market but the iPhone 13 Mini battery life is good enough for me to consider using it as a daily device despite being a power user, which means it’s more than good enough for most users. As always, your specific mileage with the battery life will vary.

The iPhone 13 Mini is actually the iPhone SE Pro

When Apple unveiled the iPhone SE last year, I fell in love. During the early part of the pandemic especially, where we were all stuck at home next to a charger, things like the smaller battery and the single-camera were less of a problem. Yet, this love affair didn’t last long and within two months, I was back on my iPhone 11 Pro. What I really wanted at the time, was a Pro version of the SE, and this is where the iPhone 13 Mini (and iPhone 12 mini before it) comes in.

If you like the iPhone SE but want a more up-to-date flagship experience, the iPhone 13 Mini is designed for you. It has all the same hallmarks of a great compact phone, except it also adds in all the upgrades you’d want from a Pro version of the SE. Aside from the additional camera lens, 120Hz refresh rate, and a few other tweaks, it also offers most of the iPhone 13 Pro experience in the more compact form factor. Nowhere is this more apparent than the camera.

iPhone 13 Mini Camera: Everything that most users need

The iPhone 13 camera is pretty much good enough for most people, and the iPhone 13 Mini camera is exactly the same. I’ve been fairly impressed by the regular and wide-angle cameras, and the latter also supports the same macro mode features found on the rest of the iPhone 13 series. In particular, images captured on the main camera come out really sharp even in questionable light.

When you’re taking photos outside, they are sharp, well-produced, and good enough for most people.

The only area that will leave you disappointed is the lack of zoom capabilities – Apple bills any zoom as the jump from the ultra-wide-angle to the top zoom capabilities, so while the iPhone 13 mini technically offers 2x zoom, the reality is it’s not a zoom lens. Telephoto is still exclusive to the Pro range, despite rival Android devices in this price point having a triple camera set up, so this represents an area for improvement in the future.

What is great is that the iPhone 13 mini still comes with all of the other camera features found in the Pro – aside from the ProRes that is – including the cinematic video modes. The iPhone is known for being one of the best smartphones for video recording and the entire iPhone 13 series delivers on this trend. We go much more in-depth with the iPhone 13 camera, so do check out our full iPhone 13 review!

Every Android OEM needs to make an iPhone 13 Mini competitor

The iPhone 13 Mini is also unique in that if you’re looking for a small phone and don’t care about which platform it runs on – and honestly, for most people, even if you do have strong feelings about the platform – there’s no other device like it. If you want something compact yet flagship with a screen measuring under 5.5-inches, there are no other real options out there for you to consider. Other options have their own drawbacks, one of the biggest ones being availability: you can’t buy a small flagship as easily as you can buy the iPhone 13 Mini, and OEMs are even more restricted on their marketing budgets to be heavily advertising the small phone. Customer ignorance thus spells doom for the category.

For this reason, every Android manufacturer needs to make an iPhone 13 Mini competitor. Each one needs to follow the same model of offering the flagship experience with as few cutbacks as possible, make it widely available and ensure that they can’t overcharge for it. Sony used to make Compact phones and ended up charging about the same as the flagship iPhone for them, which isn’t going to spur adoption.

In reality, the two companies that seem capable of producing a viable iPhone 13 mini competitor are Samsung and OnePlus. I’ve ruled out Google from this list because it’s highly unlikely they’ll produce a phone that doesn’t have major compromises, and while I’ve included OnePlus, it’s also fairly unlikely that OnePlus will create those devices, although maybe being under the Oppo banner will help.

Which leaves Samsung. I believe it’s time for Samsung to create 4 versions of the Galaxy S22 next year, and basically follow Apple’s lead. Create a small flagship Android phone that is effectively the iPhone 13 mini of the Android world and they’ll have some sales, even though the iPhone 12 Mini counted for just 5% of all the iPhone 12 sales worldwide. It’s a small market, but with phone sizes every increasing, it gains importance.

Forget the Pro, the iPhone 13 Mini is my favorite iPhone this year

Should you buy the iPhone 13 Mini? For most users, it’s absolutely worth buying and you will love it. If you want or need a bigger screen, the iPhone 13 is the one to buy, but I would then spend $200 extra to buy the iPhone 13 Pro and get all the extras that come along. The iPhone 13 Mini is the iPhone that’s good enough for most users and most importantly – for me, at least – it delivers enough of the iPhone 13 Pro experience to be a recommended purchase at a much lower price.

There’s a lot it doesn’t do that its more illustrious siblings do, including having the 120Hz adaptive refresh rate, ProRes camera, telephoto zoom lens, and an arguably better finish. But crucially, it does come with the outstanding A15 Bionic CPU that will beat any other smartphone processor, even though the iPhone 13 Mini and iPhone 13 have one less core than the Pro models. It also has 5G, an outstanding display, and two excellent cameras.

For most people, that’s going to be enough. A lot of people bought the iPhone 12 last year, but very few bought the iPhone 12 Mini. Hopefully, enough people give the iPhone 13 Mini a chance – which certainly seems to be the case based on the general availability of the mini – that Apple won’t kill it next year. Right now, the latest leaks of the iPhone 14 series suggest there won’t be a mini model so if this is the last year that Apple offers the mini, at least it’s going out on the top form.

    Apple iPhone 13 mini
    The iPhone 13 mini is the best small phone ever made, and sets the standard that all compact phones must follow. Despite the better features of the iPhone 13 Pro, the size of the iPhone 13 mini means its become my go-to iPhone to grab. It’s the best small Pro phone for all users and most people won’t need the features of the iPhone 13 Pro either.

The post iPhone 13 Mini Review: The best small phone ever made appeared first on xda-developers.



from xda-developers https://ift.tt/3lg7HD8
via IFTTT

And so it begins: Payment platform shares timeline for alternative in-app purchase system on iOS

The Apple vs. Epic Games saga has been going on for over a year now. It first started when Epic Games, the company known for Fortnite, implemented its own in-app purchase (IAP) system on iOS last year. In response, Apple removed the game from the App Store and then terminated Epic’s developer account. Back in September, a year later, a court ruled in Epic’s favor and gave Apple 90 days to allow alternative in-app purchase systems on iOS. It appears like some platforms are already preparing for this change.

As per a MacRumors report, Paddle — a payment platform founded in 2012, has shared a timeline for its own alternative IAP system. App developers will be able to take advantage of it down the road. That is assuming Apple allows developers to implement and use their own payment systems in iOS apps. The website already allows developers to join the waitlist and express their interest in the platform. They’re planning to launch it on December 7th, three months after the recent court ruling.

Paddle’s selling point is its lower commission fee, compared to that of Apple, in addition to other perks. Apple currently charges developers 15-30% of payments made in the App Store or through their IAP system. Paddle is aiming for a 10% fee for purchases under $10 and a 5% + $0.5 fee for ones over $10. If Apple goes ahead and allows alternative payment systems, then Paddle’s rates put the Cupertino giant at a significant disadvantage.

Paddle using customer data access as a pro against apple

It’s worth mentioning that some users, including me, would rather pay extra to use Apple’s IAP system instead of having our payment info stored on too many websites. Paddle advertises access to customer data, including email addresses, as a pro for businesses. But, in reality, it’s a major disadvantage to users who care about their privacy. Having user emails exposed to other companies will worsen the spam issue.

It’s yet to be seen whether Apple will allow alternative payment methods later this year or not. If they do, Paddle’s timeline could open the flood gates and start a domino effect that changes how users buy digital goods, particularly on Apple devices. However, Florian Mueller, a seasoned antitrust expert, told iMore that app developers that implement the Paddle payment API would see their apps rejected from the App Store. He explained:

There’s, unfortunately, an urban legend making the rounds about the injunction, but it irresponsibly ignores the detailed judgment as well as the legal principle that a defendant violates an injunction only by taking an unreasonably restrictive view. The injunction is merely meant to enable app developers to tell customers that, for example, they could make the same in-app purchase at a lower cost if they play the same game on a Samsung phone and download the app there via the Galaxy Store.

However, after iMore posted Mueller’s statement, Paddle reached out to Stephen Warwick, informing him that they believe their system will be permissible following the court ruling.

We will find out what Apple changes in its policies regarding third-party IAP systems on the App Store later this year.

What do you think of Paddle’s move? Are you willing to have your data shared with other businesses for a lower IAP fee? Let us know in the comments section below.

The post And so it begins: Payment platform shares timeline for alternative in-app purchase system on iOS appeared first on xda-developers.



from xda-developers https://ift.tt/3Bpb8gn
via IFTTT