I'm writing a xamarin app for android that uses the device admin api to implement a "kiosk mode". To do this I've implemented a subclass of DeviceAdminReceiver and and set that component as a device administrator via the adb command " dpm set-device-owner ". I am able to do this successfully.
However, after I've made the application a device administrator I'm unable to remove the application without doing a factory wipe which is making debugging a real pita. The dpm command help output says that you can use the remove_active_admin subcommand to remove a device admin if android:testOnly is declared in the app manifest. I attempted to do this via the Application attribute in e.g.
[Application(Debuggable = true, TestOnly = true )]
public class MyApp: Application
{
}
However the TestOnly propery is not available on the application attribute in xamarin.
My questions are ...
Below are screenshots from the Settings -> Security -> Device Administrator menu.
Thanks!
Many thanks to SushiHangover for the answer. I wanted to add that if you set this flag in your manifest, the apk will no longer install properly when you debug the project. Instead you'll have to use the adb pm command to install the package. I made the following scripts to simplify installing / removing the apk. Side note the dpm command fails for me if the root namespace starts with a capital letter.
To install
adb push com.bla.myproject.apk /sdcard/app.apk
adb shell pm install -t /sdcard/app.apk
adb shell dpm set-device-owner com.bla.myproject/com.bla.myproject.AdminRx
To remove
adb shell dpm remove-active-admin com.bla.myproject/com.bla.myproject.AdminRx
adb shell pm uninstall com.bla.myproject
Just edit and add it manually to the existing manifest in the Properties
folders of your project:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.sushihangover.Android_BottomBar">
<uses-sdk android:minSdkVersion="16" />
<application android:testOnly="true" android:label="@string/app_name" android:theme="@android:style/Theme.Holo.Light.DarkActionBar">
</application>
</manifest>
Along with your ApplicationAtrributes
:
#if DEBUG
[Application(Debuggable = true, AllowBackup = false, Icon = "@mipmap/icon_debug")]
#else
[Application(Debuggable = false, AllowBackup = true, Icon = "@mipmap/icon")]
#endif
public class App : Application
{
~~~
They will both get merged together during the build process and become:
~~~
<application android:testOnly="true" android:label="@string/app_name" android:theme="@android:style/Theme.Holo.Light.DarkActionBar" android:allowBackup="false" android:debuggable="true" android:icon="@mipmap/icon_debug" android:name="md59b195add2a2dc8f3ae98a691cd945df5.App">
~~~
</application>
~~~