2011-01-20 7 views
27

私は常に画面上にあるボタンを作成しようとしています。ホームボタンがまだ機能するシステムオーバーレイを作成しますか?

  1. ボタンがクリック可能と直接プレス上でアクティブ化するべきではありません ボタンの下に 何もする必要があります。ボタンの後ろ を実行している
  2. 活動やホーム画面にはまだユーザーを意味することは、まだ ホーム 画面やアプリケーションと対話することができるはず 、動作するはずです。
  3. ソフトキー ボタンがまだ動作するはずです:

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
         WindowManager.LayoutParams.WRAP_CONTENT, 
         WindowManager.LayoutParams.WRAP_CONTENT, 
         WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 
         WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | 
         WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 
         PixelFormat.TRANSLUCENT); 
    
    :など家庭、バック 、メニュー、

次のコードは、#1、#2が、ソフトキーボタン、もはや仕事もしません

これにそれを変更すると、クリックからオーバーレイを無効が、#2、#3、ワーク:この例では最後

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, 

オーバーレイであり、w帽子は、それがクリックされます真後ろにある:

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 

がどのようにオーバーレイがクリック可能であること、それは、オーバーレイの外クリッカブル、およびすべてではありませんいただきました直接の下にホームボタンを含む作品ように、これを変更することができますか?

このすべてを実行するアプリケーション例は、スーパーマネージャです。

UPDATE:あなたができない、またはウィンドウタイプ

 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT | 
      WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
     WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | 
      WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH 

+0

最終回答を投稿したり質問を更新したりできますか?また、それを構築するために使用したアクセス許可は何ですか? – shaimagz

答えて

18
  1. :私は次のように使用するホームボタンを可能にするが、それでもない他のボタンは検出されませんでした一緒に。ランダムな他のタイプを作成します。そして、正直言って、あなたが使用しているウィンドウの種類は、実際にはアプリケーションによって使用されることは意図されていませんでした(そのため、それらに「システム」という言葉があります)。

  2. 「ソフトキーボタンが機能しなくなった」とはどういう意味ですか?それが大きな問題であれば、家の仕事を止めることはできないはずです(私はこれを行うためのコードを知りたいと思います)。他のキーは現在のキーフォーカスに配信されます。焦点を合わせたくない場合は、FLAG_NOT_FOCUSABLEを使用してください。

  3. これらのフラグのそれぞれのドキュメントは、その動作がはっきりしている必要があります。そのため、必要なフラグを選択してください。 FLAG_NOT_FOCUSABLEキーイベントを受けたくないためです。 FLAG_NOT_TOUCH_MODALあなたのウィンドウの外にあるタッチイベントをブロックしたくないためです。あなたはあなたの窓の外にあるプレスについて知りたいとは言わないので、FLAG_WATCH_OUTSIDE_TOUCHを使用する理由はありません。

+2

うわー、ありがとう!フラグ付きのtype_system_alertの使用not_focusable | not_touch_modalがこのトリックを終えました。ボタンやセレクタはクリックされたアニメーションを表示しませんが、OnClickをクリックしてOnTouchを使用して、action_downとaction_upの背景を変更することで、そのことを知りました。 – pcm2a

+2

"家の仕事を止めることはできません。"実際は@ pcm2aが正しいです。私はモトローラドローイング3でこれをテストし、上記のフラグを持つTYPE_SYSTEM_ERRORまたはTYPE_SYSTEM_ALERTウィンドウは、HOMEキーを含むキーイベントを消費する可能性があります(イベントが消費されなくても実際にはデフォルトの動作は発生しません)。これは、これがどのアプリケーションでも傍受されることのない1つの鍵であるという印象を受けていたので、これは非常に奇妙です。 – Tom

+0

@Tom Dianneがソフトキーボタンを機能させることができないと言ったとき、ユーザーがソフトキーボタンをクリックするのを防ぐことは不可能であると考えました。もちろん、ウィンドウをボタンのデフォルト動作よりも優先させることはできますが、ホームボタンを「無効にする」ことはできません(つまり、クリック不可にすることはできません)。これは、これらのボタンがシステムが所有する別のウィンドウの一部として存在するためです。 –

17

私はpcm2aが実用的なソリューションを公開していないことを知っています。

ノート:私は実際の解決策を提示していますが、そのような方法の使用はAndroidアーキテクチャの設計に関して100%正しいわけではありません。 Androidデベロッパーチームの誰かに詳細情報を尋ねることをお勧めします(私たち全員が見るためにここに回答を投稿してください)。

権限

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

サービス

package com.vidmind.test.service.video; 
import android.app.Service; 
import android.content.Intent; 
import android.graphics.PixelFormat; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnPreparedListener; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.IBinder; 
import android.os.Message; 
import android.os.Messenger; 
import android.util.Log; 
import android.view.Gravity; 
import android.view.LayoutInflater; 
import android.view.WindowManager; 
import android.widget.LinearLayout; 
import android.widget.VideoView; 

public class TestVideoService extends Service { 

    /** Command to the service to display a message */ 
    public static final int MSG_PLAY_VIDEO = 1; 
    public static final int MSG_VIDEO_LOOP_MODE = 2; 


    /** Bundle Strings */ 
    public static final String KEY_VIDEO_URL = "KEY_VIDEO_URL"; 
    public static final String KEY_VIDEO_LOOP_MODE = "KEY_VIDEO_LOOP_MODE"; 


    // Binder given to clients 
    private static final String TAG = "TestVideoService"; 
    final Messenger mMessenger = new Messenger(new IncomingHandler()); 
    private LinearLayout mOverlay; 
    private VideoView mVideoView; 
    private boolean mVideoLoop = true; 


    /** ****************** Handler implementation class ****************** **/ 

    /** 
    * Handler of incoming messages from clients. 
    */ 
    class IncomingHandler extends Handler { 
     @Override 
     public void handleMessage(Message msg) { 
      Bundle bundle; 
      switch (msg.what) { 
       case MSG_PLAY_VIDEO: 
        bundle = msg.getData(); 
        String url = bundle.getString(KEY_VIDEO_URL); 
        play(url); 
        break; 

       case MSG_VIDEO_LOOP_MODE: 
        bundle = msg.getData(); 
        boolean looping = bundle.getBoolean(KEY_VIDEO_LOOP_MODE); 
        setVideoLoop(looping); 
        break; 
       default: 
        super.handleMessage(msg); 
      } 
     } 
    } 

    /** ****************************************************************** **/ 

    @Override 
    public IBinder onBind(Intent intent) { 
     return mMessenger.getBinder(); 
    } 


    @Override 
    public void onCreate() { 
     super.onCreate(); 
     Log.d(TAG, "Service has started"); 

    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.d(TAG, "Serice destroyed"); 

     // Remove view from WindowManager 
     WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
     wm.removeView(mOverlay); 

     mOverlay = null; 
     mVideoView = null; 
    } 


    /** ****************** Private Functions ****************** **/ 

    /** 
    * Set video loop mode 
    * @param value 
    */ 
    private void setVideoLoop(boolean value) { 
     mVideoLoop = value; 
    } 

    /** 
    * Start playing the movie 
    * @param url 
    * @returns success/failure 
    */ 
    private boolean play(String url) { 
     boolean isSuccess = false; 

     if (mOverlay != null && mVideoView.isPlaying()) { 
      Log.w(TAG, "Cannot recreate video overlay"); 
      return isSuccess; 
     } 

     // Create overlay video 
     createOverlay(mOverlay != null); 
     if (!mVideoView.isPlaying()) { 
      mVideoView.setOnPreparedListener(new OnPreparedListener() { 

       @Override 
       public void onPrepared(MediaPlayer mp) { 
        mp.setLooping(mVideoLoop); 
       } 
      }); 

      mVideoView.setVideoURI(Uri.parse(url)); 
      mVideoView.requestFocus(); 
      mVideoView.start(); 
      isSuccess = true; 
     } 
     return isSuccess; 
    } 

    /** 
    * Create video overlay 
    * 
    * @param isCreated 
    */ 
    private void createOverlay(boolean isCreated) { 
     if (isCreated) return; 

     // Create System overlay video 
     WindowManager.LayoutParams params = new WindowManager.LayoutParams(
       WindowManager.LayoutParams.FILL_PARENT, 150, 
       WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, 
       WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 
         | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, 
       PixelFormat.TRANSLUCENT); 
     params.gravity = Gravity.BOTTOM; 

     LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); 
     mOverlay = (LinearLayout) inflater.inflate(R.layout.main, null); 
     mVideoView = (VideoView) mOverlay.findViewById(R.id.video_player); 

     WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); 
     wm.addView(mOverlay, params); 

    } 
} 

layout.main

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

    <VideoView 
     android:id="@+id/video_player" 
     android:layout_width="120dp" 
     android:layout_height="120dp"/> 

</LinearLayout> 

コーディングハッピー!
amir

関連する問題