首页 > 代码库 > Float Camera Service
Float Camera Service
1. MainActivity.java
package com.jean.lee.floatcamera; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Rect; import android.hardware.Camera; import android.os.Bundle; import android.util.DisplayMetrics; import android.widget.Toast; import com.jean.lee.floatcamera.service.FloatCameraService; import com.jean.lee.floatcamera.util.SecLog; @SuppressLint("NewApi") public class MainActivity extends Activity { private static final String TAG = "FloatCamera"; private static final String FLOAT_CAM_SERVICE_PREFERENCES = "pref_float_camera_service"; private static final String KEY_PREFERENCES_SERVICE_STARTED = "key_preferences_service_started"; private static final String KEY_PREFERENCES_SCREEN_HEIGHT = "key_preferences_screen_height"; private static final String KEY_PREFERENCES_CAMERA_NUMBERS = "key_preferences_camera_numbers"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SecLog.e(TAG, "onCreate"); } @Override protected void onResume() { SecLog.e(TAG, "onResume"); SharedPreferences mSharedPreferences = getSharedPreferences(FLOAT_CAM_SERVICE_PREFERENCES, Activity.MODE_PRIVATE); if(mSharedPreferences.getInt(KEY_PREFERENCES_CAMERA_NUMBERS, -2) == 0){ Toast.makeText(this, R.string.toast_no_camera, Toast.LENGTH_SHORT).show(); finish(); }else if(mSharedPreferences.getInt(KEY_PREFERENCES_CAMERA_NUMBERS, -2) == -2){ SharedPreferences.Editor editor = mSharedPreferences.edit(); editor.putInt(KEY_PREFERENCES_CAMERA_NUMBERS, Camera.getNumberOfCameras()); editor.commit(); } if(mSharedPreferences.getInt(KEY_PREFERENCES_SCREEN_HEIGHT, 0) == 0){ DisplayMetrics dm = new DisplayMetrics(); this.getWindowManager().getDefaultDisplay().getMetrics(dm); int screenHeight = dm.heightPixels; SecLog.e(TAG, "screenHeight="+screenHeight); SharedPreferences.Editor editor = mSharedPreferences.edit(); editor.putInt(KEY_PREFERENCES_SCREEN_HEIGHT, screenHeight); editor.commit(); } Intent intent = new Intent(MainActivity.this, FloatCameraService.class); SharedPreferences.Editor editor = mSharedPreferences.edit(); if(!mSharedPreferences.getBoolean(KEY_PREFERENCES_SERVICE_STARTED, false)){ SecLog.e(TAG, "call start service"); startService(intent); editor.putBoolean(KEY_PREFERENCES_SERVICE_STARTED, true); }else { SecLog.e(TAG, "call stop service"); stopService(intent); editor.putBoolean(KEY_PREFERENCES_SERVICE_STARTED, false); } editor.commit(); finish(); super.onResume(); } @Override protected void onDestroy() { SecLog.e(TAG, "onDestroy"); super.onDestroy(); } @Override protected void onPause() { SecLog.e(TAG, "onPause"); super.onPause(); } }
2. FloatCameraService.java
package com.jean.lee.floatcamera.service; import java.io.IOException; import java.lang.reflect.Field; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.PixelFormat; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Parameters; import android.os.IBinder; import android.os.Vibrator; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnLongClickListener; import android.view.View.OnTouchListener; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.LinearLayout; import android.widget.Toast; import com.jean.lee.floatcamera.R; import com.jean.lee.floatcamera.util.SecLog; @SuppressLint("NewApi") public class FloatCameraService extends Service implements SurfaceHolder.Callback{ private static final String TAG = "FloatCameraService"; private static final String FLOAT_CAM_SERVICE_PREFERENCES = "pref_float_camera_service"; private static final String KEY_PREFERENCES_CAMERA_ID = "key_preferences_camera_id"; private static final String KEY_PREFERENCES_WINDOW_X = "key_preferences_window_x"; private static final String KEY_PREFERENCES_WINDOW_Y = "key_preferences_window_y"; private static final String KEY_PREFERENCES_WINDOW_WIDTH_BACK = "key_preferences_window_width_back"; private static final String KEY_PREFERENCES_WINDOW_HEIGHT_BACK = "key_preferences_window_height_back"; private static final String KEY_PREFERENCES_WINDOW_WIDTH_FRONT = "key_preferences_window_width_front"; private static final String KEY_PREFERENCES_WINDOW_HEIGHT_FRONT = "key_preferences_window_height_front"; private static final String KEY_PREFERENCES_STATUSBAR_HEIGHT = "key_preferences_statusbar_height"; private static final String KEY_PREFERENCES_SCREEN_HEIGHT = "key_preferences_screen_height"; private static final String KEY_PREFERENCES_CAMERA_NUMBERS = "key_preferences_camera_numbers"; LinearLayout mFloatLayout; WindowManager.LayoutParams wmParams; WindowManager mWindowManager; private SurfaceView mSvPreview; private SurfaceHolder mSurfaceHolder; private Camera mCamera; private Parameters mParameters; private static final int DEFAULT_CAMERA_ID = CameraInfo.CAMERA_FACING_BACK; private static int mCameraId = DEFAULT_CAMERA_ID; private static int mCameraNumbers; private SharedPreferences mSharedPreferences; private boolean bLongPressed = false; private boolean bMultiTouchPressed = false; private static int mStatusBarHeight = 0; private static int mWindowWidth = 270; private static int mWindowHeight = 480; private static final int PREVIEW_4_3_WIDTH = 300; private static final int PREVIEW_4_3_HEIGHT = 400; private static final int PREVIEW_16_9_WIDTH = 270; private static final int PREVIEW_16_9_HEIGHT = 480; @Override public void onCreate() { SecLog.e(TAG, "onCreate"); super.onCreate(); } @Override public void onDestroy() { SecLog.e(TAG, "onDestroy"); if(mFloatLayout != null) { mWindowManager.removeView(mFloatLayout); } if(null != mCamera){ mCamera.stopPreview(); mCamera.release(); mCamera = null; } super.onDestroy(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { SecLog.e(TAG, "onStartCommand"); mSharedPreferences = getSharedPreferences(FLOAT_CAM_SERVICE_PREFERENCES, Activity.MODE_PRIVATE); LayoutInflater inflater = LayoutInflater.from(getApplication()); mFloatLayout = (LinearLayout) inflater.inflate(R.layout.float_layout, null); mSvPreview = (SurfaceView)mFloatLayout.findViewById(R.id.sv_preview); mSurfaceHolder = mSvPreview.getHolder(); mSurfaceHolder.addCallback(this); mStatusBarHeight = mSharedPreferences.getInt(KEY_PREFERENCES_STATUSBAR_HEIGHT, 0); if(0 == mStatusBarHeight){ mStatusBarHeight = getStatusBarHeight(getBaseContext()); SharedPreferences.Editor editor = mSharedPreferences.edit(); editor.putInt(KEY_PREFERENCES_STATUSBAR_HEIGHT, mStatusBarHeight); editor.commit(); } openCamera(); createFloatView(); return super.onStartCommand(intent, flags, startId); } @Override public boolean onUnbind(Intent intent) { SecLog.e(TAG, "onUnbind"); return super.onUnbind(intent); } @Override public IBinder onBind(Intent arg0) { SecLog.e(TAG, "onBind"); return null; } @SuppressLint("InflateParams") private void createFloatView() { SecLog.e(TAG, "createFloatView"); wmParams = new WindowManager.LayoutParams(); mWindowManager = (WindowManager)getApplication().getSystemService(getApplication().WINDOW_SERVICE); wmParams.type = LayoutParams.TYPE_PHONE; //设置图片格式,效果为背景透明 wmParams.format = PixelFormat.RGBA_8888; //设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作) wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE; //调整悬浮窗显示的停靠位置为左侧置顶 wmParams.gravity = Gravity.LEFT | Gravity.TOP; // 以屏幕左上角为原点,设置x、y初始值,相对于gravity wmParams.x = mSharedPreferences.getInt(KEY_PREFERENCES_WINDOW_X, 0); wmParams.y = mSharedPreferences.getInt(KEY_PREFERENCES_WINDOW_Y, 0); /* //设置悬浮窗口长宽数据 wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT; wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;*/ setOptimizeWindowSize(); // 设置悬浮窗口长宽数据 wmParams.width = mWindowWidth; wmParams.height = mWindowHeight; mWindowManager.addView(mFloatLayout, wmParams); mFloatLayout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec .makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); mFloatLayout.setOnTouchListener(new OnTouchListener(){ @Override public boolean onTouch(View arg0, MotionEvent event) { switch(event.getActionMasked()){ case MotionEvent.ACTION_DOWN: SecLog.e(TAG, "onTouch, ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: SecLog.e(TAG, "onTouch, ACTION_MOVE"); if(bLongPressed){ //getRawX是触摸位置相对于屏幕的坐标,getX是相对于按钮的坐标 wmParams.x = (int) event.getRawX() - mSvPreview.getMeasuredWidth()/2; //减25为状态栏的高度 wmParams.y = (int) event.getRawY() - mSvPreview.getMeasuredHeight()/2 - mStatusBarHeight; mWindowManager.updateViewLayout(mFloatLayout, wmParams); } break; case MotionEvent.ACTION_POINTER_DOWN: SecLog.e(TAG, "onTouch, ACTION_POINTER_DOWN"); break; case MotionEvent.ACTION_POINTER_UP: SecLog.e(TAG, "onTouch, ACTION_POINTER_UP"); break; case MotionEvent.ACTION_UP: SecLog.e(TAG, "onTouch, ACTION_UP"); if(bLongPressed){ bLongPressed = false; SharedPreferences.Editor editor = mSharedPreferences.edit(); editor.putInt(KEY_PREFERENCES_WINDOW_X, wmParams.x); editor.putInt(KEY_PREFERENCES_WINDOW_Y, wmParams.y); editor.commit(); }else{ if(mSharedPreferences.getInt(KEY_PREFERENCES_CAMERA_NUMBERS, -2) == 1){ Toast.makeText(getBaseContext(), R.string.toast_only_one_camera, Toast.LENGTH_SHORT).show(); return false; } switchCamera(); startPreview(); } break; default: SecLog.e(TAG, "onTouch,event="+event.getActionMasked()); break; } return false; } }); mFloatLayout.setOnLongClickListener(new OnLongClickListener(){ @Override public boolean onLongClick(View arg0) { SecLog.e(TAG, "onLongClick"); bLongPressed = true; Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); vibrator.vibrate(100); return false; } }); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { SecLog.e(TAG, "surfaceChanged"); } @Override public void surfaceCreated(SurfaceHolder arg0) { SecLog.e(TAG, "surfaceCreated"); startPreview(); } private void openCamera(){ SecLog.e(TAG, "openCamera"); if(null == mCamera && null != mSharedPreferences){ mCameraId = mSharedPreferences.getInt(KEY_PREFERENCES_CAMERA_ID, DEFAULT_CAMERA_ID); mCamera = Camera.open(mCameraId); mParameters = mCamera.getParameters(); } } private void switchCamera(){ SecLog.e(TAG, "switchCamera"); if(null != mCamera){ mCamera.stopPreview(); mCamera.release(); mCamera = null; } SharedPreferences.Editor editor = mSharedPreferences.edit(); mCameraId = mSharedPreferences.getInt(KEY_PREFERENCES_CAMERA_ID, DEFAULT_CAMERA_ID); if(CameraInfo.CAMERA_FACING_BACK == mCameraId){ mCameraId = CameraInfo.CAMERA_FACING_FRONT; mCamera = Camera.open(mCameraId); }else{ mCameraId = CameraInfo.CAMERA_FACING_BACK; mCamera = Camera.open(mCameraId); } editor.putInt(KEY_PREFERENCES_CAMERA_ID, mCameraId); editor.commit(); if(mCamera != null){ mParameters = mCamera.getParameters(); } } private void startPreview(){ SecLog.e(TAG, "startPreview"); if(null != mCamera){ try { mCamera.setPreviewDisplay(mSurfaceHolder); } catch (IOException e) { e.printStackTrace(); } if(null != mParameters){ SecLog.e(TAG, "preview size:"+mParameters.getPreviewSize().width+"x"+mParameters.getPreviewSize().height); } mCamera.setDisplayOrientation(90); mCamera.startPreview(); updateWindownSize(); } } @Override public void surfaceDestroyed(SurfaceHolder arg0) { SecLog.e(TAG, "surfaceDestroyed"); } public static int getStatusBarHeight(Context context){ SecLog.e(TAG, "getStatusBarHeight"); Class<?> c = null; Object obj = null; Field field = null; int x = 0, statusBarHeight = 0; try { c = Class.forName("com.android.internal.R$dimen"); obj = c.newInstance(); field = c.getField("status_bar_height"); x = Integer.parseInt(field.get(obj).toString()); statusBarHeight = context.getResources().getDimensionPixelSize(x); } catch (Exception e1) { e1.printStackTrace(); } return statusBarHeight; } public void setOptimizeWindowSize(){ SecLog.e(TAG, "setOptimizeWindowSize"); if(mCameraId == CameraInfo.CAMERA_FACING_BACK) { mWindowWidth = mSharedPreferences.getInt(KEY_PREFERENCES_WINDOW_WIDTH_BACK, 0); mWindowHeight = mSharedPreferences.getInt(KEY_PREFERENCES_WINDOW_HEIGHT_BACK, 0); }else{ mWindowWidth = mSharedPreferences.getInt(KEY_PREFERENCES_WINDOW_WIDTH_FRONT, 0); mWindowHeight = mSharedPreferences.getInt(KEY_PREFERENCES_WINDOW_HEIGHT_FRONT, 0); } if(0 == mWindowWidth || 0 == mWindowHeight) { int screenHeight = mSharedPreferences.getInt(KEY_PREFERENCES_SCREEN_HEIGHT, 0); float ratio = (float)mParameters.getPreviewSize().width/(float)mParameters.getPreviewSize().height; if(Math.abs(ratio-16.0/9.0) < 1.0E-6) {// 16/9 mWindowWidth = PREVIEW_16_9_WIDTH; mWindowHeight = PREVIEW_16_9_HEIGHT; if(screenHeight < 1000){ mWindowWidth = mWindowWidth*5/6; mWindowHeight = mWindowHeight*5/6; } }else if(Math.abs(ratio-4.0/3.0) < 1.0E-6){ mWindowWidth = PREVIEW_4_3_WIDTH; mWindowHeight = PREVIEW_4_3_HEIGHT; if(screenHeight < 1000){ mWindowWidth = mWindowWidth*4/5; mWindowHeight = mWindowHeight*4/5; } }else{ mWindowWidth = PREVIEW_4_3_WIDTH; mWindowHeight = PREVIEW_4_3_HEIGHT; } SecLog.e(TAG, "width height:"+mWindowWidth+","+mWindowHeight); SharedPreferences.Editor editor = mSharedPreferences.edit(); if(mCameraId == CameraInfo.CAMERA_FACING_BACK) { editor.putInt(KEY_PREFERENCES_WINDOW_WIDTH_BACK, mWindowWidth); editor.putInt(KEY_PREFERENCES_WINDOW_HEIGHT_BACK, mWindowHeight); }else{ editor.putInt(KEY_PREFERENCES_WINDOW_WIDTH_FRONT, mWindowWidth); editor.putInt(KEY_PREFERENCES_WINDOW_HEIGHT_FRONT, mWindowHeight); } editor.commit(); } } public void updateWindownSize(){ SecLog.e(TAG, "updateWindownSize"); setOptimizeWindowSize(); wmParams.width = mWindowWidth; wmParams.height = mWindowHeight; mWindowManager.updateViewLayout(mFloatLayout, wmParams); } }
3. Manifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jean.lee.floatcamera" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="14" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.VIBRATE" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@android:style/Theme.NoDisplay" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".service.FloatCameraService"></service> </application> </manifest>
4. float_layout.xml
<?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" > <SurfaceView android:id="@+id/sv_preview" android:visibility="visible" android:text="TestTest" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
Float Camera Service
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。