2010-09-13 14 views

回答

7

解決方案:

@Override 
public boolean dispatchKeyEvent(KeyEvent event) { 
    if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) { 
     Intent i = new Intent(this, ActivitySetupMenu.class); 
     startActivity(i); 
     return true; 
    } 

    return super.dispatchKeyEvent(event); 
} 
+1

不工作:(我 – 2011-04-19 11:59:14

+5

請分享完整的代碼 – 2011-04-20 05:24:14

+2

這個作品外核層y當它是一個長按 – Sjk 2013-06-24 09:09:18

1

您可以覆蓋Activity類中的public boolean onKeyDown(int keyCode, KeyEvent event)public boolean onKeyUp(int keyCode, KeyEvent event)函數,並測試keyCode是否等於KeyEvent.KEYCODE_POWER

我還沒有測試過這個,但是我會假設系統把它當作Home的關鍵,因爲你不能阻止系統接收到關鍵事件,你只能觀察到它發生了。要測試這一點,請嘗試從上述函數返回True並查看是否捕獲了關鍵事件。

4

在你的活動添加:

public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) { 
     // do what you want with the power button 
     return true; 
    } 
    return super.onKeyDown(keyCode, event); 
} 

雖然......這種按鍵都弄好了特殊的......不知道是否可以給問題給你。

0

,你必須使用這樣的:

BroadcastReceiver screenoff = new BroadcastReceiver() { 

public static final String Screenoff = "android.intent.action.SCREEN_OFF"; 

@Override 
public void onReceive(Context context, Intent intent) { 
     if (!intent.getAction().equals(Screenoff)) return; 
     //put code to handle power press here 
     return; 

}}; 
+2

這是行不通的?我很確定屏幕仍然會熄滅。 – Pandalover 2011-09-19 13:17:20

37

現有的答案並不完全回答這個問題,並留下了足夠的細節,他們將沒有更多的調查工作。我將分享我學會解決這個問題。

首先,你需要下列權限添加到您的清單文件:

<uses-permission android:name="android.permission.PREVENT_POWER_KEY" /> 

要處理的短按和長按添加以下覆蓋到你的活動類:

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_POWER) { 
     // Do something here... 
     event.startTracking(); // Needed to track long presses 
     return true; 
    } 
    return super.onKeyDown(keyCode, event); 
} 

@Override 
public boolean onKeyLongPress(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_POWER) { 
     // Do something here... 
     return true; 
    } 
    return super.onKeyLongPress(keyCode, event); 
} 

注意:是值得注意的是onKeyDown()將在onKeyLongPress之前觸發多次,因此您可能需要在onKeyUp()或其他邏輯上觸發,以防止在用戶真正關閉時執行一系列onKeyDown()調用。

我認爲接下來的部分僅適用於Cyanogenmod。如果 PREVENT_POWER_KEY 常量未定義,那麼你不應該需要它。

要開始攔截,你需要從你的活動設置下列標誌的電源鍵:

getWindow().addFlags(WindowManager.LayoutParams.PREVENT_POWER_KEY); 

要停止攔截電源鍵(允許標準功能):

getWindow().clearFlags(WindowManager.LayoutParams.PREVENT_POWER_KEY); 

你可以如果您願意,可以在程序中反覆切換兩種模式。

+4

是否可以在所有API版本中使用?我嘗試API 8和15,在LayoutParams中沒有PREVENT_POWER_KEY參數。你可能會在這裏看到這個參數的價值嗎? – Koger 2012-09-04 15:06:26

+1

WindowManager.LayoutParams.PREVENT_POWER_KEY的值是0x80000000但是它看起來像是一個隱藏的值,或者只針對Cyanogenmod(如果這是真的會令人不安)。我這樣做的項目是API 10,但是我修改了sdk以暴露隱藏的API,並且我在Cyanogenmod 7上運行了它。 – 2012-09-22 00:20:57

+3

onKeyDown僅在發生長按事件時才起作用,實際上onKeyLongPress永遠不會被Power按鈕觸發至少在摩托羅拉Droid X2上。 – JPM 2012-11-27 15:31:35

3

如這裏https://stackoverflow.com/a/15828592/1065357

@Override 
public void onWindowFocusChanged(boolean hasFocus) { 
    super.onWindowFocusChanged(hasFocus); 
    if(!hasFocus) { 
     Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 
     sendBroadcast(closeDialog); 
    } 
} 
2

提到共享監聽電源鍵長按的方法。工程與API 23+權限:

  1. 問計系統權限draw overlay(這是不是一個正常的或脆弱的權限)。這不是用戶許可,所以你應該真的知道,你在做什麼,通過詢問它。

    public class MainActivity extends AppCompatActivity { 
    
        public final static int REQUEST_CODE = 10101; 
    
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState); 
         setContentView(R.layout.activity_main); 
         if (checkDrawOverlayPermission()) { 
          startService(new Intent(this, PowerButtonService.class)); 
         } 
        } 
    
        public boolean checkDrawOverlayPermission() { 
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 
          return true; 
         } 
         if (!Settings.canDrawOverlays(this)) { 
          /** if not construct intent to request permission */ 
          Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, 
           Uri.parse("package:" + getPackageName())); 
         /** request permission via start activity for result */ 
          startActivityForResult(intent, REQUEST_CODE); 
          return false; 
         } else { 
          return true; 
         } 
        } 
    
        @Override 
        @TargetApi(Build.VERSION_CODES.M) 
        protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
         if (requestCode == REQUEST_CODE) { 
          if (Settings.canDrawOverlays(this)) { 
           startService(new Intent(this, PowerButtonService.class)); 
          } 
         } 
        } 
    } 
    
  2. 啓動服務,並增加了WindowManager

  3. 特別景緻等待內部ViewonCloseSystemDialogs方法的動作。

    public class PowerButtonService extends Service { 
    
        public PowerButtonService() { 
    
        } 
    
        @Override 
        public void onCreate() { 
         super.onCreate(); 
         LinearLayout mLinear = new LinearLayout(getApplicationContext()) { 
    
          //home or recent button 
          public void onCloseSystemDialogs(String reason) { 
           if ("globalactions".equals(reason)) { 
            Log.i("Key", "Long press on power button"); 
           } else if ("homekey".equals(reason)) { 
            //home key pressed 
           } else if ("recentapss".equals(reason)) { 
            // recent apps button clicked 
           } 
          } 
    
          @Override 
          public boolean dispatchKeyEvent(KeyEvent event) { 
           if (event.getKeyCode() == KeyEvent.KEYCODE_BACK 
            || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP 
            || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN 
            || event.getKeyCode() == KeyEvent.KEYCODE_CAMERA 
            || event.getKeyCode() == KeyEvent.KEYCODE_POWER) { 
            Log.i("Key", "keycode " + event.getKeyCode()); 
           } 
           return super.dispatchKeyEvent(event); 
          } 
         }; 
    
         mLinear.setFocusable(true); 
    
         View mView = LayoutInflater.from(this).inflate(R.layout.service_layout, mLinear); 
         WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
    
         //params 
         WindowManager.LayoutParams params = new WindowManager.LayoutParams(
          100, 
          100, 
          WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 
          WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 
            | WindowManager.LayoutParams.FLAG_FULLSCREEN 
            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 
            | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, 
          PixelFormat.TRANSLUCENT); 
         params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL; 
         wm.addView(mView, params); 
        } 
    
        @Override 
        public IBinder onBind(Intent intent) { 
         return null; 
        } 
    } 
    

清單:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
      package="powerbuttonpress"> 

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     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> 

     <service 
      android:name=".PowerButtonService" 
      android:enabled="true" 
      android:exported="true"> 
     </service> 

    </application> 

</manifest> 

service_layout:。

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

</LinearLayout> 
+1

太棒了!謝謝。 這裏的一個問題是軟鍵盤無法打開:( – Zohar 2016-08-31 09:16:22

+0

@R。Zagórski嗨,但這不會打印任何信息 – Abhishek 2016-10-06 08:32:56

+0

如果有人遇到軟鍵盤沒有顯示的問題,可以在窗口管理器參數中添加'WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE'來修復它 – 2017-08-17 18:06:55

相關問題