我正在尝试向Android屏幕对脸距离测量https://github.com/philiiiiiipp/Android-Screen-to-Face-Distance-Measurement添加一些功能 例如使其在前景或背景下工作,当人脸离屏幕太近时,会弹出通知。现在,该应用程序可以在前台运行,并可以在通知中更新距离测量值。 但是,一旦按下主屏幕按钮以最小化该应用程序,距离测量值就会在该通知中停止更新。
我尝试过前台和后台。当我最小化应用程序时,该应用程序仍无法在后台或前景中工作。
MainActivity.java
public class MainActivity extends Activity implements MessageListener{
public static final String CAM_SIZE_WIDTH = "intent_cam_size_width";
public static final String CAM_SIZE_HEIGHT = "intent_cam_size_height";
public static final String AVG_NUM = "intent_avg_num";
public static final String PROBANT_NAME = "intent_probant_name";
private NotificationManagerCompat notificationManager;
private CameraSurfaceView _mySurfaceView;
Camera _cam;
private final static DecimalFormat _decimalFormater = new DecimalFormat(
"0.0");
private float _currentDevicePosition;
private int _cameraHeight;
private int _cameraWidth;
private int _avgNum;
//new added
private static final String TAG = "MainActivity";
TextView _currentDistanceView;
Button _calibrateButton;
//for floating
public static final int SYSTEM_ALERT_WINDOW_PERMISSION = 7;
Button button ;
/**
* Abusing the media controls to create a remote control
*/
// ComponentName _headSetButtonReceiver;
// AudioManager _audioManager;
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.measurement_activity);
//for notification
notificationManager = NotificationManagerCompat.from(this);
_mySurfaceView = (CameraSurfaceView) findViewById(R.id.surface_camera);
RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(
(int) (0.95 * this.getResources().getDisplayMetrics().widthPixels),
(int) (0.6 * this.getResources().getDisplayMetrics().heightPixels));
layout.setMargins(0, (int) (0.05 * this.getResources()
.getDisplayMetrics().heightPixels), 0, 0);
_mySurfaceView.setLayoutParams(layout);
_currentDistanceView = (TextView) findViewById(R.id.currentDistance);
_calibrateButton = (Button) findViewById(R.id.calibrateButton);
}
@Override
protected void onResume() {
super.onResume();
MessageHUB.get().registerListener(this);
// _audioManager.registerMediaButtonEventReceiver(_headSetButtonReceiver);
// 1 for front cam. No front cam ? Not my fault!
_cam = Camera.open(1);
Camera.Parameters param = _cam.getParameters();
// Find the best suitable camera picture size for your device. Competent
// research has shown that a smaller size gets better results up to a
// certain point.
// http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=6825217&url=http%3A%2F%2Fieeexplore.ieee.org%2Fiel7%2F6816619%2F6825201%2F06825217.pdf%3Farnumber%3D6825217
List<Size> pSize = param.getSupportedPictureSizes();
double deviceRatio = (double) this.getResources().getDisplayMetrics().widthPixels
/ (double) this.getResources().getDisplayMetrics().heightPixels;
Size bestSize = pSize.get(0);
double bestRation = (double) bestSize.width / (double) bestSize.height;
for (Size size : pSize) {
double sizeRatio = (double) size.width / (double) size.height;
if (Math.abs(deviceRatio - bestRation) > Math.abs(deviceRatio
- sizeRatio)) {
bestSize = size;
bestRation = sizeRatio;
}
}
_cameraHeight = bestSize.height;
_cameraWidth = bestSize.width;
Log.d("PInfo", _cameraWidth + " x " + _cameraHeight);
param.setPreviewSize(_cameraWidth, _cameraHeight);
_cam.setParameters(param);
_mySurfaceView.setCamera(_cam);
}
@Override
protected void onPause() {
super.onPause();
MessageHUB.get().unregisterListener(this);
// _audioManager
// .unregisterMediaButtonEventReceiver(_headSetButtonReceiver);
resetCam();
}
/**
* Sets the current eye distance to the calibration point.
*
* @param v
*/
public void pressedCalibrate(final View v) {
if (!_mySurfaceView.isCalibrated()) {
_calibrateButton.setBackgroundResource(R.drawable.yellow_button);
_mySurfaceView.calibrate();
}
}
public void pressedReset(final View v) {
if (_mySurfaceView.isCalibrated()) {
_calibrateButton.setBackgroundResource(R.drawable.red_button);
_mySurfaceView.reset();
}
}
public void onShowMiddlePoint(final View view) {
// Is the toggle on?
boolean on = ((Switch) view).isChecked();
_mySurfaceView.showMiddleEye(on);
}
public void onShowEyePoints(final View view) {
// Is the toggle on?
boolean on = ((Switch) view).isChecked();
_mySurfaceView.showEyePoints(on);
}
/**
* Update the UI values.
*
* @param eyeDist
* @param frameTime
*/
void updateUI(final MeasurementStepMessage message) {
_currentDistanceView.setText(_decimalFormater.format(message
.getDistToFace()) + " cm");
float fontRatio = message.getDistToFace() / 29.7f;
_currentDistanceView.setTextSize(fontRatio * 20);
//Foreground Services
//String input = editTextInput.getText().toString();
float number = message.getDistToFace();
String input = Float.toString(number);
Intent serviceIntent = new Intent(this, ExampleService.class);
serviceIntent.putExtra("inputExtra",input);
ContextCompat.startForegroundService(this, serviceIntent);
//my new code added here(working)
if(message.getDistToFace()<25)
{
Notification notification = new NotificationCompat.Builder(this, CHANNEL_1_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("ALERT")
.setContentText("You are too near to the screen!")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 })
.build();
notificationManager.notify(3, notification);
}
}
private void resetCam() {
_mySurfaceView.reset();
_cam.stopPreview();
_cam.setPreviewCallback(null);
_cam.release();
}
@Override
public void onMessage(final int messageID, final Object message) {
switch (messageID) {
case MessageHUB.MEASUREMENT_STEP:
updateUI((MeasurementStepMessage) message);
break;
case MessageHUB.DONE_CALIBRATION:
_calibrateButton.setBackgroundResource(R.drawable.green_button);
break;
default:
break;
}
}
ExampleService.java
public class ExampleService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Example Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
//do heavy work on a background thread
//stopSelf();
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}