4

I'm currently using an Activity to use the camera and torch in ICS and Above , I use a SurfaceView, now my question is how to use the same code in a Service, how do I create a SurfaceView and use the camera ?

Thanks .

matt freake
  • 4,877
  • 4
  • 27
  • 56
Chalom.E
  • 617
  • 5
  • 20

3 Answers3

0

You should use a TextureSurface instead of a SurfaceView (available from API 11). Have a look at this question.

Community
  • 1
  • 1
JonasVautherin
  • 7,297
  • 6
  • 49
  • 95
0

You want creat a surfaceview in service and use the view to the Camera.The source code is Here https://github.com/renhongtao/FloatCameraWindow

1.Create Surface view in a service example. This solution is help understand how to create a view in a service.

Use the class called WindowManager and the parameters object called LayoutParams. Pay attention to params.type, it may be failed in different SDK version.

in AndroidManifest.xml

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

create a new service son class

public class TopWindowService extends Service
{
private static WindowManager wm;
private static WindowManager.LayoutParams params;
private Button btn_floatView;

@Override
public void onCreate()
{
    super.onCreate();          
    createFloatView();
}

 private void createFloatView()
{

    btn_floatView = new Button(getApplicationContext());
    btn_floatView.setText("Hello");
    wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
    params = new WindowManager.LayoutParams();      
    params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
    //in different sdk this type should change 
    params.format = PixelFormat.RGBA_8888; // 
    params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
            | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

    // set float view size
    params.width = 100;
    params.height = 100;

    // set touch listen action
    btn_floatView.setOnTouchListener(new OnTouchListener()
    {
        int lastX, lastY;
        int paramX, paramY;

        public boolean onTouch(View v, MotionEvent event)
        {
            switch (event.getAction())
            {
                case MotionEvent.ACTION_DOWN:
                    lastX = (int) event.getRawX();
                    lastY = (int) event.getRawY();
                    paramX = params.x;
                    paramY = params.y;
                    break;
                case MotionEvent.ACTION_MOVE:
                    int dx = (int) event.getRawX() - lastX;
                    int dy = (int) event.getRawY() - lastY;
                    params.x = paramX + dx;
                    params.y = paramY + dy;

                    wm.updateViewLayout(btn_floatView, params);
                    break;
            }
            return true;
        }
    });

    wm.addView(btn_floatView, params);
    isAdded = true;
}

2.set the surface created from service to the camera example . This part have too many source code .The main idea is use class LayoutInflater to load a xml file.Then findViewById get the surface which the camera need. As show in example 1. use WindowManager add the view(in xml).

2.1 prepare a xml include a surface view,name is cmera_layout

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/camera_window_layout"
    android:layout_width="100dip"
    android:layout_height="100dip"
    android:background="@drawable/ic_launcher_background"
    >       
<SurfaceView
    android:id="@+id/camera_surface"
    android:layout_width="80dip"
    android:layout_height="80dip"
    android:layout_gravity="center" />
</LinearLayout>

2.2 create a view class

public class FloatWindowCamera extends LinearLayout {
protected  SurfaceView mCameraView; 
public static int viewWidth;
public static int viewHeight;
 private static int statusBarHeight;
private WindowManager mWindowManager;
private WindowManager.LayoutParams mParams;
private float xInScreen;
private float yInScreen;
private float xDownInScreen;
private float yDownInScreen;    
private float xInView;
private float yInView;

public FloatWindowCamera(Context context) {
    super(context);
/************************Main idea here**************************/
    mWindowManager = context.getSystemService(Context.WINDOW_SERVICE);
    LayoutInflater.from(context).inflate(R.layout.cmera_layout, this);
    View view = findViewById(R.id.camera_surface);
    viewWidth = view.getLayoutParams().width;
    viewHeight = view.getLayoutParams().height;
    mCameraView = (SurfaceView) view;
/****************************************************/

}

public SurfaceView getCameraView(){
    return mCameraView;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:           
        xInView = event.getX();
        yInView = event.getY();
        xDownInScreen = event.getRawX();
        yDownInScreen = event.getRawY() - getStatusBarHeight();
        xInScreen = event.getRawX();
        yInScreen = event.getRawY() - getStatusBarHeight();
        break;
    case MotionEvent.ACTION_MOVE:
        xInScreen = event.getRawX();
        yInScreen = event.getRawY() - getStatusBarHeight();         
        updateViewPosition();
        break;      
    default:
        break;
    }
    return true;
}   
public void setParams(WindowManager.LayoutParams params) {
    mParams = params;
}


private void updateViewPosition() {
    mParams.x = (int) (xInScreen - xInView);
    mParams.y = (int) (yInScreen - yInView);
    mWindowManager.updateViewLayout(this, mParams);
}

private int getStatusBarHeight() {
    if (statusBarHeight == 0) {
        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object o = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = (Integer) field.get(o);
            statusBarHeight = getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return statusBarHeight;


}

}

2.3 Create the surface view then give out the object.

We use the same class name of TopFloatWindowService

    public class TopWindowService extends Service
        {
...

    @Override
        public void onCreate()
        {

            super.onCreate();           
/********************add the view in WindowManager**************/

            mView = createCameraWindow(getApplicationContext()).getCameraView();

            //**now you can use this mView to the camera**  then startpreview       


        }

public static FloatWindowCamera createCameraWindow(Context context) {
            WindowManager windowManager = context.getSystemService(Context.WINDOW_SERVICE);
            int screenWidth = windowManager.getDefaultDisplay().getWidth();
            int screenHeight = windowManager.getDefaultDisplay().getHeight();
            if (mCameraWindow == null) {
                mCameraWindow = new FloatWindowCamera(context);
                if (mCameraWindowParams == null) {
                    mCameraWindowParams = new LayoutParams();
                    mCameraWindowParams.type = LayoutParams.TYPE_TOAST ;
                    mCameraWindowParams.format = PixelFormat.RGBA_8888;
                    mCameraWindowParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
                            | LayoutParams.FLAG_NOT_FOCUSABLE;
                    mCameraWindowParams.gravity = Gravity.LEFT | Gravity.TOP;
                    mCameraWindowParams.width = FloatWindowCamera.viewWidth;
                    mCameraWindowParams.height = FloatWindowCamera.viewHeight;
                    mCameraWindowParams.x = screenWidth;
                    mCameraWindowParams.y = screenHeight / 2;
                }
                mCameraWindow.setParams(mCameraWindowParams);
//here add the view to show 
                windowManager.addView(mCameraWindow, mCameraWindowParams);
                Log.e("FLOAT","create small success");
            }
            return mCameraWindow;
        }

The code is too many, hope can help some one.

-1

Service is not the place to use such elements. You won't be able to do that.

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
  • are you sure i cant use something like SurfaceView SView = SurfaceView(this); ? how Torch Application keep the Light On , like Widget ? beacause this is for my Widget i have an Activity actual wich start when you turn the Light On – Chalom.E Aug 31 '12 at 10:20
  • 1
    any help im still on this problem ? – Chalom.E Sep 05 '12 at 10:45