I am developing an App which will capture photo from front camera when user will enter wrong password. I have done some part like capture the event of incorrect password and capturing image. But My code captures a black image.
I have done so research on it, and found that it is not possible to capture image without preview or without user interaction because of privacy reasons. But there are some Intruder Selfie apps available in the market which does that. then how do they do it?
Here's my Admin.java :-
public class Admin extends DeviceAdminReceiver {
public static int pass_failed_count = 0;
Context conn;
private Camera camera; // camera object
// private TextView TimeLeft; // time left field
File mediaFile;
private static final String IMAGE_DIRECTORY_NAME = "Captured_Images";
int numberOfCameras;
// private TextView cameras;
void showToast(Context context, CharSequence msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
@Override
public void onEnabled(Context context, Intent intent) {
showToast(context, "Device Administrator: Activated");
}
@Override
public CharSequence onDisableRequested(Context context, Intent intent) {
return "This is an optional message to warn the user about disabling.";
}
@Override
public void onDisabled(Context context, Intent intent) {
showToast(context, "Device Administrator: Deactivated");
}
public Admin(Context con) {
this.conn = con;
}
public Admin() {
}
@Override
public void onPasswordFailed(Context context, Intent intent) {
pass_failed_count++;
showToast(context, "Sample Device Admin: pw failed");
Vibrator v = (Vibrator)context.getSystemService(context.VIBRATOR_SERVICE);
// Vibrate for 2 seconds
v.vibrate(2000);
Intent i = new Intent(conn, CameraView.class);
conn.startActivity(i);
/* if (mHiddenCameraFragment != null) { //Remove fragment from container if present
getSupportFragmentManager()
.beginTransaction()
.remove(mHiddenCameraFragment)
.commit();
mHiddenCameraFragment = null;
}
startService(new Intent(context, DemoCamService.class));*/
}
@Override
public void onPasswordSucceeded(Context context, Intent intent) {
showToast(context, "Welcome Device Owner");
}
}
Here is the service I want to call onPasswordFailed :-
public class DemoCamService extends HiddenCameraService {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
if (HiddenCameraUtils.canOverDrawOtherApps(this)) {
CameraConfig cameraConfig = new CameraConfig()
.getBuilder(this)
.setCameraFacing(CameraFacing.FRONT_FACING_CAMERA)
.setCameraResolution(CameraResolution.MEDIUM_RESOLUTION)
.setImageFormat(CameraImageFormat.FORMAT_JPEG)
.build();
startCamera(cameraConfig);
new android.os.Handler().postDelayed(new Runnable() {
@Override
public void run() {
takePicture();
}
}, 2000);
} else {
//Open settings to grant permission for "Draw other apps".
HiddenCameraUtils.openDrawOverPermissionSetting(this);
}
} else {
//TODO Ask your parent activity for providing runtime permission
Toast.makeText(this, "Camera permission not available", Toast.LENGTH_SHORT).show();
}
return START_NOT_STICKY;
}
@Override
public void onImageCapture(@NonNull File imageFile) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
//Do something with the bitmap
saveImage(bitmap,"service");
Log.d("Image capture", imageFile.length() + "");
stopSelf();
}
private void saveImage(Bitmap finalBitmap, String image_name) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root);
myDir.mkdirs();
String fname = "Image-" + image_name+ ".jpg";
File file = new File(myDir, fname);
if (file.exists()) file.delete();
Log.i("LOAD", root + fname);
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onCameraError(@CameraError.CameraErrorCodes int errorCode) {
switch (errorCode) {
case CameraError.ERROR_CAMERA_OPEN_FAILED:
//Camera open failed. Probably because another application
//is using the camera
Toast.makeText(this, "Cannot open camera.", Toast.LENGTH_LONG).show();
break;
case CameraError.ERROR_IMAGE_WRITE_FAILED:
//Image write failed. Please check if you have provided WRITE_EXTERNAL_STORAGE permission
Toast.makeText(this, "Cannot write image captured by camera.", Toast.LENGTH_LONG).show();
break;
case CameraError.ERROR_CAMERA_PERMISSION_NOT_AVAILABLE:
//camera permission is not available
//Ask for the camera permission before initializing it.
Toast.makeText(this, "Camera permission not available.", Toast.LENGTH_LONG).show();
break;
case CameraError.ERROR_DOES_NOT_HAVE_OVERDRAW_PERMISSION:
//Display information dialog to the user with steps to grant "Draw over other app"
//permission for the app.
HiddenCameraUtils.openDrawOverPermissionSetting(this);
break;
case CameraError.ERROR_DOES_NOT_HAVE_FRONT_CAMERA:
Toast.makeText(this, "Your device does not have front camera.", Toast.LENGTH_LONG).show();
break;
}
stopSelf();
}
}
CameraView activity :-
By Using this activity and some extra classes I am able to click photos. I am also able to click photos by clicking on service button. but both of the time device is in unlocked state. I want to do this when device is locked and user enters wrong password.
public class CameraView extends AppCompatActivity
{
//a variable to store a reference to the Image View at the main.xml file
// private ImageView iv_image;
//a variable to store a reference to the Surface View at the main.xml file
private SurfaceView sv;
//a bitmap to display the captured image
private Bitmap bmp;
//Camera variables
//a surface holder
private SurfaceHolder sHolder;
//a variable to control the camera
private Camera mCamera;
//the camera parameters
private Camera.Parameters parameters;
private HiddenCameraFragment mHiddenCameraFragment;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_view);
if (mHiddenCameraFragment != null) { //Remove fragment from container if present
getSupportFragmentManager()
.beginTransaction()
.remove(mHiddenCameraFragment)
.commit();
mHiddenCameraFragment = null;
}
startService(new Intent(CameraView.this, DemoCamService.class));
findViewById(R.id.btn_using_activity).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mHiddenCameraFragment != null) { //Remove fragment from container if present
getSupportFragmentManager()
.beginTransaction()
.remove(mHiddenCameraFragment)
.commit();
mHiddenCameraFragment = null;
}
startActivity(new Intent(CameraView.this, DemoCamActivity.class));
}
});
findViewById(R.id.btn_using_service).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mHiddenCameraFragment != null) { //Remove fragment from container if present
getSupportFragmentManager()
.beginTransaction()
.remove(mHiddenCameraFragment)
.commit();
mHiddenCameraFragment = null;
}
startService(new Intent(CameraView.this, DemoCamService.class));
}
});
findViewById(R.id.btn_using_fragment).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mHiddenCameraFragment = new DemoCamFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, mHiddenCameraFragment)
.commit();
}
});
}
@Override
public void onBackPressed() {
if (mHiddenCameraFragment != null) { //Remove fragment from container if present
getSupportFragmentManager()
.beginTransaction()
.remove(mHiddenCameraFragment)
.commit();
mHiddenCameraFragment = null;
}else { //Kill the activity
super.onBackPressed();
}
}
}
So, How to call a Activity or Service from OnPasswordFailed in DeviceAdminReceiver?