【问题标题】:Simulating power button press to display switch off dialog box模拟电源按钮按下以显示关机对话框
【发布时间】:2012-07-05 11:38:40
【问题描述】:

我正在尝试调用按下电源按钮时出现的关闭对话框。但我想从 android 应用程序或 Junit 测试用例中完成这项任务。在这种情况下,我将选择最可行的方法。我一直在尝试这样做,但未能成功。我正在尝试使用以下五种方法:

第一种方法:

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));

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

第二种方法:

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();
        }
    }

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

第三种方法:

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

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

第四种方法:

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());

}

第五种方法:

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();
                }

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

但它们都不适合我。第五个方法是调用 ShutdownThread 类的 shutdown() 方法。但它给了我以下错误:

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)

其他方法不会引发任何错误。我需要帮助来完成这项任务,尽管我必须调用本机方法来完成这项任务,但无论如何我都会这样做,但我必须显示关闭 UI。

谢谢

阿什瓦尼

【问题讨论】:

  • 嘿应用程序没有关闭,它不再说“正在关闭...”。我使用了第 5 种方法,并且是一个系统应用程序.. 如何进行?

标签: android android-ndk android-source


【解决方案1】:

第六种方法:

$ adb shell input keyevent 26

有效!

方法七:

如果你想要长按

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

您的设备可能使用与/dev/input/event5不同的输入设备

第八种方法

这种方法更聪明一点,根据 API 级别使用sendeventinput keyevent

#! /usr/bin/env python

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

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

这里的优点是这是一种通用方法,也可以用于发送其他密钥。 AdbClientadb 的python 实现,与AndroidViewClient/culebra 一起分发。

【讨论】:

  • 它可以工作,但问题是我想长按电源按钮。我如何使用 ADB Shell 发送它
  • 怎么样,我已经在 adb shell 上测试了这段代码,但是当我试图通过我的应用程序执行它时,我什么也没尝试 { Runtime.getRuntime().exec("adb shell sendevent /dev /输入/事件0 1 116 0"); Runtime.getRuntime().exec("adb shell sendevent /dev/input/event0 1 116 1"); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }
  • 字符串行;进程 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("发送事件 /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);我使用上面的代码来执行任务,但它不工作。
  • 第五种方法对我有用...当我将应用程序作为系统应用程序签名时
  • 第七种方法需要为果冻豆更新,因为在 Android 4 中电源按钮的 ID 为 116。
【解决方案2】:

其他方法

adb shell 输入keyevent --longpress KEYCODE_POWER

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 2020-04-12
    • 2011-07-14
    • 2013-12-23
    • 1970-01-01
    • 2016-04-21
    相关资源
    最近更新 更多