23

I am trying to invoke the switch off dialog box that appears when we press power button. But i want to accomplish this task from an android application or a Junit test case. I will choose the most feasible approach in this case. I have been trying to do this but was not able to succeed. I am trying to use the following five approaches:

First approach:

long eventTime = SystemClock.uptimeMillis(); boolean
                  dispateched = launcherButtonWInst.dispatchKeyEvent(new
                  KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN,
                  KeyEvent.KEYCODE_POWER, 0, 0, 0, 0, 0) );
                  Log.i(LOG_TAG,String.valueOf(dispateched)); boolean
                  dispateched2=launcherButtonWInst.dispatchKeyEvent(new
                  KeyEvent(eventTime+2000, eventTime+2000, KeyEvent.ACTION_UP,
                  KeyEvent.KEYCODE_POWER, 0, 0, 0, 0, 0) );
                  Log.i(LOG_TAG,String.valueOf(dispateched2));

=======================================================

Second apporach:

private void generateKeys() {
        // Obtain the WindowManager system service interface
        IBinder wmbinder = ServiceManager.getService("window");
        Log.d(LOG_TAG, "WindowManager: " + wmbinder);
        IWindowManager wm = IWindowManager.Stub.asInterface(wmbinder);
        keyUpDown(wm, KeyEvent.KEYCODE_POWER);
    }

    private void keyUpDown(IWindowManager wm, int keycode) {
        try {
            Log.d(LOG_TAG, "keyDown: " + keycode);
            wm.injectKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keycode), true);
            Log.d(LOG_TAG, "keyUp: " + keycode);
            wm.injectKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keycode), true);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            Log.e("ERROR!!!!!", e.toString());
            e.printStackTrace();
        }
    }

============================================================

Third approach:

Instrumentation inst = new Instrumentation();
        inst.sendKeyDownUpSync(KeyEvent.KEYCODE_POWER);

======================================================

Fourth approach:

try {
                         long now =SystemClock.uptimeMillis();
                         KeyEvent down = new KeyEvent(now, now,
                         KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_POWER, 0);

                         Log.d( LOG_TAG,down.toString() );
                         KeyEvent up = new KeyEvent(now+2000, now+2000,
                         KeyEvent.ACTION_UP, KeyEvent.KEYCODE_POWER, 0);
                         Log.d( LOG_TAG,up.toString() );
                         (IWindowManager.Stub.asInterface(ServiceManager.getService("window"))).injectKeyEvent(down,
                         true);
                         try {
                         Thread.sleep(2000);
                         } catch (InterruptedException e) {
                         // TODO Auto-generated catch block
                         e.printStackTrace();
                         }
                         (IWindowManager.Stub.asInterface(ServiceManager.getService("window"))).injectKeyEvent(up,
                         true);
                         } catch (RemoteException e) {
                         Log.d("LOGTAG",
                         "SendKeyEvent exception:"+e.getMessage());

}

Fifth approach:

try {
                    Context mContext = getBaseContext();
                    Dialog dialog=new Dialog(mContext);
                    dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
                    ShutdownThread.shutdown(mContext, true);

                } catch (Exception e) {
                    Log.e("ERROR!!!", e.toString());
                    e.printStackTrace();
                }

===================================================================

But none of them is working for me. The fifth approach is invoking shutdown() method of ShutdownThread class. But it gives me following error:

07-05 10:18:21.489: W/System.err(709): android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@4104d798 -- permission denied for this window type
07-05 10:18:21.499: W/System.err(709):     at android.view.ViewRootImpl.setView(ViewRootImpl.java:537)
07-05 10:18:21.499: W/System.err(709):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:301)
07-05 10:18:21.499: W/System.err(709):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
07-05 10:18:21.499: W/System.err(709):     at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
07-05 10:18:21.499: W/System.err(709):     at android.app.Dialog.show(Dialog.java:278)
07-05 10:18:21.499: W/System.err(709):     at com.android.internal.app.ShutdownThread.shutdown(ShutdownThread.java:124)
07-05 10:18:21.499: W/System.err(709):     at aexp.keygen.KeyGen$1.onClick(KeyGen.java:47)
07-05 10:18:21.499: W/System.err(709):     at android.view.View.performClick(View.java:3511)
07-05 10:18:21.499: W/System.err(709):     at android.view.View$PerformClick.run(View.java:14105)
07-05 10:18:21.509: W/System.err(709):     at android.os.Handler.handleCallback(Handler.java:605)
07-05 10:18:21.509: W/System.err(709):     at android.os.Handler.dispatchMessage(Handler.java:92)
07-05 10:18:21.509: W/System.err(709):     at android.os.Looper.loop(Looper.java:137)
07-05 10:18:21.509: W/System.err(709):     at android.app.ActivityThread.main(ActivityThread.java:4424)
07-05 10:18:21.509: W/System.err(709):     at java.lang.reflect.Method.invokeNative(Native Method)
07-05 10:18:21.509: W/System.err(709):     at java.lang.reflect.Method.invoke(Method.java:511)
07-05 10:18:21.509: W/System.err(709):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
07-05 10:18:21.509: W/System.err(709):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
07-05 10:18:21.509: W/System.err(709):     at dalvik.system.NativeStart.main(Native Method)

Other approaches do not throw any error. I need help to accomplish this task, which ever way it takes even though I have to invoke native methods to accomplish I will do that, but I have to display the switch off UI.

Thanks

Ashwani

Bruce
  • 7,094
  • 1
  • 25
  • 42
Ashwani Kumar
  • 834
  • 3
  • 16
  • 30
  • Hey app doesn't shut down, it stops saying "shutting down...". I used 5th method and is a system app.. how to proceed ? – Charan Pai Aug 28 '13 at 08:58

2 Answers2

31

Sixth approach:

$ adb shell input keyevent 26

works!

Seventh approach:

If you want the long press

$ adb shell <<!
> sendevent /dev/input/event5 1 107 1
> sleep 1
> sendevent /dev/input/event5 1 107 0
> exit
> !

You device may use a different input device than /dev/input/event5

Eighth approach

This approach is a bit more clever and uses sendevent or input keyevent depending on API level.

#! /usr/bin/env python

from com.dtmilano.android.adb.adbclient import *

AdbClient(serialno='your-serial-number-here').longPress('POWER')

The advantage here is that this is a generic approach and can be used to send other keys too. AdbClient is a python implementation of adb and is distributed with AndroidViewClient/culebra.

Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134
  • it works but the problem is i want to perform a long click of the power button. How do i send that using ADB Shell – Ashwani Kumar Jul 05 '12 at 05:08
  • How about this i had tested this code on adb shell its working but when i tried to execute it through my application i got nothing try { Runtime.getRuntime().exec("adb shell sendevent /dev/input/event0 1 116 0"); Runtime.getRuntime().exec("adb shell sendevent /dev/input/event0 1 116 1"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } – Ashwani Kumar Jul 05 '12 at 06:38
  • String line; Process p = Runtime.getRuntime().exec("su -c sendevent /dev/input/event0 1 107 0\n"); DataOutputStream d = new DataOutputStream(p.getOutputStream()); BufferedReader input = new BufferedReader(new InputStreamReader(p.getErrorStream())); BufferedReader input2 = new BufferedReader(new InputStreamReader(p.getInputStream())); d.writeBytes("sendevent /dev/input/event0 1 107 1 \n"); while ((line = input.readLine()) != null) { Log.i("PROCESSSTAT", line); } while ((line = input.readLine()) != null) { Log.i("PROCESSSTAT", line); } I used above code to perform the task but its not working. – Ashwani Kumar Jul 06 '12 at 06:58
  • 1
    Fifth approach worked for me... when i signed the application as system application – Ashwani Kumar Jul 06 '12 at 07:39
  • @dtmilano How do you figure out which input device is being used by a particular phone? – Karthik Balakrishnan Jul 07 '13 at 09:42
  • 2
    The seventh approach needs to be updated for Jelly Bean as the ID for Power Button is 116 in Android 4. – Samveen Sep 21 '13 at 09:51
  • @AshwaniKumar: how to sign application as system application? – Mehul Joisar Feb 25 '14 at 07:07
  • @Mehul Joisar: https://groups.google.com/forum/#!msg/android-devphone-updating/sSNXXY-yWLg/4yw4kmBTytwJ – Ashwani Kumar Feb 26 '14 at 08:52
  • for the android 4, the Seventh approach: $ sendevent /dev/input/event6 1 116 1 $ sendevent /dev/input/event6 0 0 0 $ sendevent /dev/input/event6 1 116 0 $ sendevent /dev/input/event6 0 0 0 – user175257 May 14 '23 at 14:40
5

Other Approach

adb shell input keyevent --longpress KEYCODE_POWER

ajay
  • 477
  • 6
  • 14