Android實現可隨意拖動的懸浮窗體
1、在Service中監聽電話狀態
package com.example.incomingcall.service;import android.app.Service; import android.content.Intent; import android.graphics.PixelFormat; import android.os.IBinder; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.Button; import android.widget.TextView; import com.example.incomingcall.R; public class ShowAddressService extends Service { private static final String TAG = ShowAddressService.class.getSimpleName(); private TelephonyManager tm; private MyPhoneListener listener; private WindowManager wm; private float x; private float y; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } // 在服務第一次被創建的時候 執行的方法 @Override public void onCreate() { super.onCreate(); Log.e(TAG, "onCreate"); wm = (WindowManager) getSystemService(WINDOW_SERVICE); tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); listener = new MyPhoneListener(); tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE); } private class MyPhoneListener extends PhoneStateListener { private View v; private String incomingNumber; // 來電號碼 private WindowManager.LayoutParams params; /** * 當手機的電話狀態發生改變的時候 調用的方法 */ @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state) { case TelephonyManager.CALL_STATE_IDLE: // 沒有通話,靜止狀態 Log.i(TAG, "CALL_STATE_IDLE"); if (v != null) { wm.removeView(v); v = null; } if (this.incomingNumber != null) { // 模仿土司 利用窗體的管理服務 把一個布局展現到界面上 v = View.inflate(getApplicationContext(), R.layout.show_marknumber, null); TextView tv = (TextView) v .findViewById(R.id.tv_mark_number); tv.setText("電話:" + this.incomingNumber); Button bt_mark_cancel = (Button) v .findViewById(R.id.bt_mark_cancel); bt_mark_cancel.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { Log.i(TAG, "onClick dismiss"); if (v != null) { wm.removeView(v); v = null; } } }); params = new LayoutParams(); params.gravity = Gravity.CENTER; params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; params.format = PixelFormat.TRANSLUCENT; params.type = WindowManager.LayoutParams.TYPE_PHONE; params.setTitle("號碼標記"); wm.addView(v, params); } break; case TelephonyManager.CALL_STATE_OFFHOOK: // 電話接通 或者掛斷 Log.i(TAG, "CALL_STATE_OFFHOOK"); if (v != null) { wm.removeView(v); v = null; } break; case TelephonyManager.CALL_STATE_RINGING: // 響鈴狀態 this.incomingNumber = incomingNumber; Log.e(TAG, "CALL_STATE_RINGING incomingNumber:" + incomingNumber); // 模仿土司 利用窗體的管理服務 把一個布局展現到界面上 v = View.inflate(getApplicationContext(), R.layout.show_address, null); TextView tv = (TextView) v.findViewById(R.id.tv_show_address); tv.setText("來電:" + incomingNumber); params = new LayoutParams(); params.gravity = Gravity.TOP | Gravity.LEFT; params.x = 0; params.y = 0; params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; params.format = PixelFormat.TRANSLUCENT; params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; params.setTitle("電話幫"); v.setOnTouchListener(new OnTouchListener() { float mTouchStartX; float mTouchStartY; @Override public boolean onTouch(View v, MotionEvent event) { // 獲取相對屏幕的坐標,即以屏幕左上角為原點 x = event.getRawX(); y = event.getRawY() - 25; // 25是系統狀態欄的高度 Log.i(TAG, "currX" + x + "====currY" + y); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 獲取相對View的坐標,即以此View左上角為原點 mTouchStartX = event.getX(); mTouchStartY = event.getY(); Log.i("startP", "startX" + mTouchStartX + "====startY" + mTouchStartY); break; case MotionEvent.ACTION_MOVE: //更新浮動窗口位置參數 params.x=(int)( x-mTouchStartX); params.y=(int) (y-mTouchStartY); wm.updateViewLayout(v, params); break; case MotionEvent.ACTION_UP: //更新浮動窗口位置參數 params.x=(int)( x-mTouchStartX); params.y=(int) (y-mTouchStartY); wm.updateViewLayout(v, params); //可以在此記錄最后一次的位置 mTouchStartX = mTouchStartY = 0; break; } return true; } }); wm.addView(v, params); break; } } } /** * 服務在被停止的時候 調用的方法 */ @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); // 停止 電話狀態的監聽. tm.listen(listener, PhoneStateListener.LISTEN_NONE); } } </pre><strong><span style="color:#3333ff;font-size:14px;">2、添加權限<pre class="brush:java; toolbar: true; auto-links: false;"> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> </pre></span></strong>來自:http://blog.csdn.net/top_code/article/details/12906171
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!