MainActivity.java
package com.example.testone;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Handler handler=new Handler();
handler.postDelayed(() -> {
startService(new Intent(getApplicationContext(), FloatCameraService.class));
finish();
},1000);
if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 2);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 2) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "请允许相机权限", Toast.LENGTH_SHORT).show();
}
}
}
}
FloatCameraService.java
package com.example.testone;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.concurrent.ExecutionException;
public class FloatCameraService extends Service implements LifecycleOwner {
private WindowManager windowManager;
private View floatView;
private LifecycleRegistry lifecycleRegistry;
private ListenableFuture<ProcessCameraProvider> mCameraProviderFuture;
private ProcessCameraProvider cameraProvider;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
lifecycleRegistry = new LifecycleRegistry(this);
lifecycleRegistry.setCurrentState(Lifecycle.State.CREATED);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("tag", "onStartCommand , " + startId);
if (floatView == null) {
initUi();
}
lifecycleRegistry.setCurrentState(Lifecycle.State.STARTED);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.d("tag1", "onDestroy");
if (floatView != null) {
windowManager.removeView(floatView);
}
lifecycleRegistry.setCurrentState(Lifecycle.State.DESTROYED);
super.onDestroy();
}
@SuppressLint("InflateParams")
private void initUi() {
DisplayMetrics metrics = getApplicationContext().getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
LayoutInflater inflater = (LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
floatView = inflater.inflate(R.layout.float_camera, null);
int layoutType;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
layoutType = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
layoutType = WindowManager.LayoutParams.TYPE_PHONE;
}
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
(int) (width * (0.4f)),
(int) (height * (0.3f)),
layoutType,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
);
layoutParams.gravity = Gravity.CENTER;
layoutParams.x = 0;
layoutParams.y = 0;
windowManager.addView(floatView, layoutParams);
floatView.setOnTouchListener(new View.OnTouchListener() {
final WindowManager.LayoutParams floatWindowLayoutUpdateParam = layoutParams;
double x;
double y;
double px;
double py;
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = floatWindowLayoutUpdateParam.x;
y = floatWindowLayoutUpdateParam.y;
px = event.getRawX();
py = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
floatWindowLayoutUpdateParam.x = (int) ((x + event.getRawX()) - px);
floatWindowLayoutUpdateParam.y = (int) ((y + event.getRawY()) - py);
windowManager.updateViewLayout(floatView, floatWindowLayoutUpdateParam);
break;
}
return false;
}
});
mCameraProviderFuture = ProcessCameraProvider.getInstance(this);
mCameraProviderFuture.addListener(() -> {
try {
cameraProvider = mCameraProviderFuture.get();
Log.d("TAG", "service获取到了cameraProvider");
bindPreview(cameraProvider, floatView.findViewById(R.id.preview_view));
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}, ContextCompat.getMainExecutor(this));
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return lifecycleRegistry;
}
private void bindPreview(ProcessCameraProvider cameraProvider, PreviewView previewView) {
if (cameraProvider == null) {
Toast.makeText(getApplicationContext(), "没获取到相机", Toast.LENGTH_SHORT).show();
return;
}
//Toast.makeText(getApplicationContext(), "相机启动", Toast.LENGTH_SHORT).show();
Preview preview = new Preview.Builder().build();
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_FRONT)
.build();
preview.setSurfaceProvider(previewView.getSurfaceProvider());
cameraProvider.bindToLifecycle(this, cameraSelector, preview);
}
}
float_camera.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.camera.view.PreviewView
android:id="@+id/preview_view"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
</FrameLayout>
别忘记增加权限…