Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
Ask Question
I'm trying to execute the following command :
Process process = Runtime.getRuntime().exec("adb shell dpm set-device-owner com.example.package/.DeviceAdmin", null,null);
and have gotten the following Exception
W/System.err:java.io.IOException: Cannot run program "adb": error=13, Permission denied
W/System.err: at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
W/System.err: at java.lang.Runtime.exec(Runtime.java:692)
W/System.err: at java.lang.Runtime.exec(Runtime.java:525)
I'm trying to set my device as the owner by programmatically executing "adb shell dpm set-device-owner com.example.package/.DeviceAdmin".
I've been referring to the following SO links however I cant seem to get out this error.
https://stackoverflow.com/a/27909315/5521089
https://stackoverflow.com/a/44164984/5521089
NOTE: I've tried running the command w/o the adb shell prefix, however it was returning null and not applying any changes.
The following code executes my command.
try {
StringBuffer output = new StringBuffer();
Process process = Runtime.getRuntime().exec("dpm set-device-owner com.example.package/.DeviceAdmin", null,null);
process.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "n");
Log.d("OUTPUT = ", output.toString());
} catch (Exception e) {
Log.e("LOGINACTIVITY ", "device owner not set");
Log.e("LOGINACTIVITY ", e.toString());
e.printStackTrace();
Below is my DeviceAdminReceiver subclass
public class DeviceAdmin extends DeviceAdminReceiver {
public ComponentName getComponentName(Context context){
return new ComponentName(context.getApplicationContext(), DeviceAdmin.class);
void showToast(Context context, String msg) {
String status = msg;
Toast.makeText(context, status, Toast.LENGTH_SHORT).show();
@Override
public void onEnabled(Context context, Intent intent) {
showToast(context, "Enabled");
@Override
public void onDisabled(Context context, Intent intent) {
showToast(context,"Disabled");
My Manifest registering my receiver
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<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=".DeviceAdmin"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/policies"/>
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
</intent-filter>
</receiver>
</application>
Checked settings and device has no accounts(It's an android device without any google play services and is not rooted.). The app has a minSdkVersion of 21/targetSdkVersion of 27.
Ultimately, I wish to set device as owner(without NFC) for the sole purpose of pinning the screen without asking user permission.(it's a POS application). How can I execute the command so that I can set the device as owner without any exceptions?
The short answer is: Your app cannot run ADB commands. It would be a huge security hole for Android to allow this.
If you want to set your device as Device admin programmatically, take a look at the example on the documentation
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mDeviceAdminSample);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, getString(R.string.add_admin_extra_app_text));
startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
–
–
–
a) Device provisioning
After you unbox a device you tap it with a specially prepared NFC tag. An app specified by instructions stored on the NFC tag is now set as the device owner.
b) ADB
You can use the command mentioned in the question as long as these conditions are met:
There is no device owner set
There are no accounts registered on the device
The dpm set-device-owner
command can only be run from shell that's been opened by the user (i.e. ADB from a dev machine). It doesn't work with a shell opened by Runtime.exec()
. And, obviously, even if you could ADB from the device to itself, it would fall under the same restrictions.
Source:
https://github.com/aosp-mirror/platform_frameworks_base/blob/2d82493ded10d88cb44e84b90a1b485d3a895d75/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java#L7172
https://github.com/aosp-mirror/platform_frameworks_base/blob/2d82493ded10d88cb44e84b90a1b485d3a895d75/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java#L12184
Ultimately, I wish to set device as owner(without NFC) for the sole purpose of pinning the screen without asking user permission
You could use hidden system API (android.app.StatusBarManager
) to hide the status bar and navigation buttons yourself and have your app signed with the platform signature by the device manufacturer. You'll need the signature for the android.permission.STATUS_BAR
permission.
–
–