Reputation: 51
I have created a device owner app but I am having trouble installing it on a real device. I'm using the QR Code method given here.
The text I am using to create my QR Code is
{
"android.app.extra.PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME":
"com.example.killapplication/com.example.killapplication.DevAdminReceiver",
"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM":
"JdySYN-hMYsxWKagMxbk5q8Giu4lCCsUpQayMMKpwK0",
"android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION":
"https://drive.google.com/u/0/uc?id=13O35_iCUcHVqNcuOvnRM5-sc8G586Xgf&export=download",
"android.app.extra.PROVISIONING_TIME_ZONE":
"America/Los_Angeles",
"android.app.extra.PROVISIONING_SKIP_ENCRYPTION": false,
"android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE": {
}
}
I generate my apk from Android studio by doing this: Build -> Generate Signed Apk-> Create a new keystore -> Ok -> Next-> Select "Release"-> Build. Then I create the package checksum using
cat /mnt/c/Users/Antarpuneet/app-release.apk | openssl dgst -binary -sha256 | openssl base64 | tr '+/' '-_' | tr -d '='
After doing a factory reset, tapping 6 times on the welcome screen opens a QR reader app, I scan the code and then It takes me to the WIFI connection screen, I successfully connect to the Internet. It says Setting up device.. but returns with the Error Can't setup device- Couldn't install the admin app. This is my DevAdminReceiver Class :-
package com.example.killapplication
import android.app.admin.DeviceAdminReceiver
import android.content.ComponentName
import android.content.ContentValues.TAG
import android.content.Context
import android.content.Intent
import android.util.Log
import android.widget.Toast
class DevAdminReceiver: DeviceAdminReceiver() {
override fun onEnabled(context: Context?, intent: Intent?) {
super.onEnabled(context, intent)
Log.d(TAG, "Device Owner Enabled")
Toast.makeText(context, "Device Owner Enabled", Toast.LENGTH_SHORT).show();
}
companion object {
fun getComponentName(context: Context): ComponentName {
return ComponentName(context.applicationContext, DevAdminReceiver::class.java)
}
}
}
My Main Activity:-
package com.example.killapplication
import android.Manifest
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
class MainActivity : AppCompatActivity() {
var button: Button? = null
private lateinit var mAdminComponentName: ComponentName
fun onClick(view: View?) {
mAdminComponentName = DevAdminReceiver.getComponentName(this)
val devicePolicyManager = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
if (devicePolicyManager.isDeviceOwnerApp("com.example.killapplication")) {
Toast.makeText(this, "YES", Toast.LENGTH_SHORT).show()
Log.i("Status", "Yes")
} else {
Toast.makeText(this, "NO", Toast.LENGTH_SHORT).show()
Log.i("Status", "No")
}
//devicePolicyManager.reboot( mAdminComponentName)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
At the moment, the app doesn't do much and only gives a toast Yes or No depending on whether the device owner privilege has been granted to the app or not.
My Manifest file:-
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.killapplication">
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.RESTART_PACKAGES" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<permission android:name="android.permission.REBOOT"/>
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<application
android:allowBackup="true"
android:sharedUserId="android.uid.system"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:testOnly="true">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".DevAdminReceiver"
android:label="@string/app_name"
android:permission="android.permission.BIND_DEVICE_ADMIN" >
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/device_admin" />
</receiver>
</application>
</manifest>
device_admin.xml :-
<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
<uses-policies>
<limit-password />
<watch-login />
<reset-password />
<force-lock />
<wipe-data />
<expire-password />
<encrypted-storage />
<disable-camera />
<disable-keyguard-features />
</uses-policies>
</device-admin>
What I have already tried:
adb shell dpm set-device-owner com.example.killapplication/.DevAdminReceiver
It successfully sets the app as a Device owner.
3.Used : android.app.extra.PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM instead of android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM , It returns the same error.
I am trying to install it on a device with Android Version 9.
UPDATE: I figured out that "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION" doesn't accept google drive links(or Long links) and my app wasn't even being downloaded. So, I have now hosted my app on a free file hosting website and now it's being downloaded(I can confirm from that website)..Also, there is no problem with the checksum because I tried giving it the wrong ones and it returned with a checksum error. Now, My app is being downloaded but while installing, it says Blocked by Play Protect and when I tap on Install Anyway, it returns with the old error: Can't set up device - Couldn't install the admin app
Upvotes: 3
Views: 5386
Reputation: 51
After a lot of factory resets, I was able to solve my problem. First of all, make sure that the link you provide in your QR code to this attribute "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION"
should not be a google drive link. For testing, you can host your app on a file hosting free website that gives you a short link.
After doing this, my app was downloaded successfully but still failed to install. I figured out the issue and it was the android:testOnly="true" attribute in my Manifest. I set it to false and it worked properly. Strange though, because all the blogs I read which helped me create this device owner app specifically asked this attribute to be true.
Upvotes: 2