package com.letv.watchball.service;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import com.letv.watchball.R;
import com.letv.watchball.bean.Game;
import com.letv.watchball.utils.LetvConfiguration;
import com.letv.watchball.utils.LetvConstant;
import com.letv.watchball.utils.LetvUtil;
import com.letv.watchball.utils.LogInfo;
import com.letv.watchball.utils.TextUtil;
import com.letv.watchball.utils.UIs;
import com.letv.watchball.view.PipPlayerView;
/**
* 隐藏/显示底部控制条的调用逻辑也在这个类中
*
* @author
*/
public class PipService extends Service {
public static final int NOTIFICATION_ID = 109001;
private static final Class<?>[] mSetForegroundSignature = new Class[] { boolean.class };
private static final Class<?>[] mStartForegroundSignature = new Class[] {
int.class, Notification.class };
private static final Class<?>[] mStopForegroundSignature = new Class[] { boolean.class };
private WindowManager wm = null;
private WindowManager.LayoutParams wmParams = null;
private PipPlayerView view;
private float mTouchStartX;
private float mTouchStartY;
private float x;
private float y;
private int state;
private float StartX;
private float StartY;
private int delaytime = 1000;
/**
* 小窗的高度
*/
int mHeight = 0;
private NotificationManager mNM;
private Method mSetForeground;
private Method mStartForeground;
private Method mStopForeground;
private Object[] mSetForegroundArgs = new Object[1];
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];
public static void launch(Context context, Bundle bundle) {
Intent intent = new Intent(context, PipService.class);
intent.putExtra(LetvConstant.Intent.Bundle.PLAY, bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(intent);
}
void invokeMethod(Method method, Object[] args) {
try {
method.invoke(this, args);
} catch (InvocationTargetException e) {
// Should not happen.
} catch (IllegalAccessException e) {
// Should not happen.
}
}
/**
* This is a wrapper around the new startForeground method, using the older
* APIs if it is not available.
*/
void startForegroundCompat(int id, Notification notification) {
// If we have the new startForeground API, then use it.
if (mStartForeground != null) {
mStartForegroundArgs[0] = Integer.valueOf(id);
mStartForegroundArgs[1] = notification;
invokeMethod(mStartForeground, mStartForegroundArgs);
return;
}
// Fall back on the old API.
mSetForegroundArgs[0] = Boolean.TRUE;
invokeMethod(mSetForeground, mSetForegroundArgs);
mNM.notify(id, notification);
}
/**
* This is a wrapper around the new stopForeground method, using the older
* APIs if it is not available.
*/
void stopForegroundCompat(int id) {
// If we have the new stopForeground API, then use it.
if (mStopForeground != null) {
mStopForegroundArgs[0] = Boolean.TRUE;
invokeMethod(mStopForeground, mStopForegroundArgs);
return;
}
// Fall back on the old API. Note to cancel BEFORE changing the
// foreground state, since we could be killed at that point.
mNM.cancel(id);
mSetForegroundArgs[0] = Boolean.FALSE;
invokeMethod(mSetForeground, mSetForegroundArgs);
}
@Override
public void onCreate() {
super.onCreate();
// 初始化艾瑞统计
// IRMonitor.getInstance(this).Init(LetvConstant.MAPPTRACKERKEY,
// LetvUtil.generateDeviceId(this), LetvConfiguration.isDebug());
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
try {
mStartForeground = getClass().getMethod("startForeground",
mStartForegroundSignature);
mStopForeground = getClass().getMethod("stopForeground",
mStopForegroundSignature);
adjustPermission();
return;
} catch (NoSuchMethodException e) {
// Running on an older platform.
mStartForeground = mStopForeground = null;
}
try {
mSetForeground = getClass().getMethod("setForeground",
mSetForegroundSignature);
adjustPermission();
} catch (NoSuchMethodException e) {
throw new IllegalStateException(
"OS doesn't have Service.startForeground OR Service.setForeground!");
}
}
/**
* 提升服务权限
*/
private void adjustPermission() {
// Notification notification = new Notification();
// notification.tickerText = "画中画正在运行。";
// notification.icon = R.drawable.icon;
//
// startForegroundCompat(NOTIFICATION_ID, notification);
Notification notification = new Notification(R.drawable.notify_icon,
TextUtil.getString(R.string.pipservice_title),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, PipService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.setLatestEventInfo(this,
TextUtil.getString(R.string.pipservice_title),
TextUtil.getString(R.string.pipservice_msg), pendingIntent);
startForegroundCompat(NOTIFICATION_ID, notification);
}
private void createView() {
view = new PipPlayerView(this);
// 获取WindowManager
wm = (WindowManager) getApplicationContext().getSystemService("window");
// 设置LayoutParams(全局变量)相关参数
if (null == wmParams) {
wmParams = new WindowManager.LayoutParams();
wmParams.type = 2002;
wmParams.flags |= 8;
wmParams.alpha = 1.0f;
wmParams.gravity = Gravity.LEFT | Gravity.BOTTOM; // 调整悬浮窗口至左下角
// 以屏幕左上角为原点,设置x、y初始值
wmParams.x = 0;
wmParams.y = 0;
// 设置悬浮窗口长宽数据
int width = LetvUtil.getDisplayWidth(getApplicationContext());
int height = 29 * width / 48;
mHeight = height;
wmParams.width = width;
wmParams.height = height;
wmParams.format = 1;
}
wm.addView(view, wmParams);
view.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// 获取相对屏幕的坐标,即以屏幕左上角为原点
x = event.getRawX();
y = event.getRawY() - 25;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
state = MotionEvent.ACTION_DOWN;
StartX = x;
StartY = y;
// 获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.getX();
mTouchStartY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
state = MotionEvent.ACTION_MOVE;
if (wannMove()) {
updateViewPosition();
}
break;
case MotionEvent.ACTION_UP:
state = MotionEvent.ACTION_UP;
if (!showControl()) {
updateViewPosition();
}
mTouchStartX = mTouchStartY = 0;
break;
}
return false;
}
});
}
/**
* 有效移动长度大于15时执行控件移动
*/
public static int MOVE_LENGTH = 15;
public boolean wannMove() {
if (Math.abs(x - StartX) < MOVE_LENGTH
&& Math.abs(y - StartY) < MOVE_LENGTH) {
return false;
}
return true;
}
/**
* 显示控制条
*
* @return
*/
public boolean showControl() {
if (Math.abs(x - StartX) < MOVE_LENGTH
&& Math.abs(y - StartY) < MOVE_LENGTH) {
if (null == view || null == view.getPlayController()
|| null == view.getPlayController().getMediaController()) {
return true;
}
if (view.getPlayController().getMediaController().isShowing()) {
view.getPlayController().getMediaController().hide();
} else {
view.getPlayController().getMediaController().show();
}
return true;
}
return false;
}
private void updateViewPosition() {
// 更新浮动窗口位置参数
wmParams.x = (int) (x - mTouchStartX);
wmParams.y = (int) (UIs.getScreenHeight() - (y - mTouchStartY) - mHeight);
wm.updateViewLayout(view, wmParams);
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
if (null == intent) {
stopSelf();
return;
}
if (null != wm && null != view) {
try {
view.finish();
wm.removeView(view);
} catch (Exception e) {
LogInfo.log("zlb", "PipService_onStart_wm.removeView-error = "
+ e.toString());
}
view = null;
}
createView();
Bundle bundle = intent.getBundleExtra(LetvConstant.Intent.Bundle.PLAY);
view.launch(bundle);
}
@Override
public void onDestroy() {
super.onDestroy();
if (null != wm && null != view) {
view.finish();
wm.removeView(view);
}
stopForegroundCompat(NOTIFICATION_ID);
System.exit(0);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public static Game game = null;
}