11

Chcę zaimplementować funkcję przechwytywania obrazu za pomocą przedniego aparatu, gdy ktoś spróbuje odblokować moje urządzenie i wprowadzić nieprawidłowe hasło 3 razy. Sprawdziłem, czy jest to możliwe w systemie Android, a niektóre aplikacje są również dostępne w usłudze Market.Przechwyć obraz, gdy urządzenie jest zablokowane hasłem

Zrobiłem trochę pracy, aby to osiągnąć, ale otrzymuję czarny obraz. Oto kod:

Rejestracja z administratorem urządzenia, aby uzyskać transmisję za nieprawidłowe hasło próba:

public class DeviceAdminSample extends DeviceAdminReceiver { 

static Context ctx; 

static SharedPreferences getSamplePreferences(Context context) { 

    ctx = context; 

    return context.getSharedPreferences(
      DeviceAdminReceiver.class.getName(), 0); 
} 

@Override 
public void onPasswordFailed(Context context, Intent intent) { 
    super.onPasswordFailed(context, intent); 

    System.out.println("Password Attempt is Failed..."); 

    Intent i = new Intent(context, CameraView.class); 
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    context.startActivity(i); 

} 

} 

Camera klasy, aby przechwycić obraz i zapisać go na karcie SD:

public class CameraView extends Activity implements SurfaceHolder.Callback, 
    OnClickListener { 
private static final String TAG = "CameraTest"; 
Camera mCamera; 
boolean mPreviewRunning = false; 

public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    Log.e(TAG, "onCreate"); 

    setContentView(R.layout.cameraview); 

    mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera); 

    // mSurfaceView.setOnClickListener(this); 

    mSurfaceHolder = mSurfaceView.getHolder(); 
    mSurfaceHolder.addCallback(this); 

    mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    mSurfaceHolder.setKeepScreenOn(true); 

    // mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

} 

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState) { 
    super.onRestoreInstanceState(savedInstanceState); 
} 

protected void onResume() { 
    Log.e(TAG, "onResume"); 
    super.onResume(); 
} 

protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
} 

protected void onStop() { 
    Log.e(TAG, "onStop"); 
    super.onStop(); 
} 

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    Log.e(TAG, "surfaceChanged"); 

    // XXX stopPreview() will crash if preview is not running 
    if (mPreviewRunning) { 
     mCamera.stopPreview(); 
    } 

    Camera.Parameters p = mCamera.getParameters(); 

    mCamera.setParameters(p); 

    mCamera.startPreview(); 
    mPreviewRunning = true; 
    mCamera.takePicture(null, null, mPictureCallback); 


} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    Log.e(TAG, "surfaceDestroyed"); 
    // mCamera.stopPreview(); 
    // mPreviewRunning = false; 
    // mCamera.release(); 

    stopCamera(); 
} 

private SurfaceView mSurfaceView; 
private SurfaceHolder mSurfaceHolder; 

public void onClick(View v) { 
    mCamera.takePicture(null, mPictureCallback, mPictureCallback); 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    Log.e(TAG, "surfaceCreated"); 

    int i = findFrontFacingCamera(); 

    if (i > 0); 
    while (true) { 
     try { 
      this.mCamera = Camera.open(i); 
      try { 
       this.mCamera.setPreviewDisplay(holder); 
       return; 
      } catch (IOException localIOException2) { 
       stopCamera(); 
       return; 
      } 
     } catch (RuntimeException localRuntimeException) { 
      localRuntimeException.printStackTrace(); 
      if (this.mCamera == null) 
       continue; 
      stopCamera(); 
      this.mCamera = Camera.open(i); 
      try { 
       this.mCamera.setPreviewDisplay(holder); 
       Log.d("HiddenEye Plus", "Camera open RE"); 
       return; 
      } catch (IOException localIOException1) { 
       stopCamera(); 
       localIOException1.printStackTrace(); 
       return; 
      } 

     } catch (Exception localException) { 
      if (this.mCamera != null) 
       stopCamera(); 
      localException.printStackTrace(); 
      return; 
     } 
    } 
} 

private void stopCamera() { 
    if (this.mCamera != null) { 
     /*this.mCamera.stopPreview(); 
     this.mCamera.release(); 
     this.mCamera = null;*/ 
     this.mPreviewRunning = false; 
    } 
} 

private int findFrontFacingCamera() { 
    int i = Camera.getNumberOfCameras(); 
    for (int j = 0;; j++) { 
     if (j >= i) 
      return -1; 
     Camera.CameraInfo localCameraInfo = new Camera.CameraInfo(); 
     Camera.getCameraInfo(j, localCameraInfo); 
     if (localCameraInfo.facing == 1) 
      return j; 
    } 
} 

Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { 

    public void onPictureTaken(byte[] data, Camera camera) { 
     if (data != null) { 
      // Intent mIntent = new Intent(); 
      // mIntent.putExtra("image",imageData); 

      mCamera.stopPreview(); 
      mPreviewRunning = false; 
      mCamera.release(); 

      try { 
       BitmapFactory.Options opts = new BitmapFactory.Options(); 
       Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, 
         data.length, opts); 
       bitmap = Bitmap.createScaledBitmap(bitmap, 300, 300, false); 
       int width = bitmap.getWidth(); 
       int height = bitmap.getHeight(); 
       int newWidth = 300; 
       int newHeight = 300; 

       // calculate the scale - in this case = 0.4f 
       float scaleWidth = ((float) newWidth)/width; 
       float scaleHeight = ((float) newHeight)/height; 

       // createa matrix for the manipulation 
       Matrix matrix = new Matrix(); 
       // resize the bit map 
       matrix.postScale(scaleWidth, scaleHeight); 
       // rotate the Bitmap 
       matrix.postRotate(-90); 
       Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, 
         width, height, matrix, true); 

       ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 
       resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 40, 
         bytes); 

       // you can create a new file name "test.jpg" in sdcard 
       // folder. 
       File f = new File(Environment.getExternalStorageDirectory() 
         + File.separator + "test.jpg"); 

       System.out.println("File F : " + f); 

       f.createNewFile(); 
       // write the bytes in file 
       FileOutputStream fo = new FileOutputStream(f); 
       fo.write(bytes.toByteArray()); 

       // remember close de FileOutput 
       fo.close(); 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      // StoreByteImage(mContext, imageData, 50,"ImageName"); 
      // setResult(FOTO_MODE, mIntent); 
      setResult(585); 
      finish(); 
     } 
    } 
}; 
} 
+0

Czy testowałeś kod po odblokowaniu telefonu? –

+0

Tak, jestem w stanie przechwycić obraz z tym kodem, gdy telefon jest odblokowany ... –

+0

@KrishnakantDalal: Czy sprawdziłeś dziennik konsoli Androida. Czy są jakieś komunikaty o błędach? –

Odpowiedz

6

Przetestowałem Twój kod i otrzymałem prawidłowy obraz, więc myślę, że Twój kod aparatu działa dobrze.

Możesz sprawdzić mój kod here. Skopiowałem klasę CameraView z twojej. Część administracyjna urządzenia pobrałem od https://github.com/marakana/DevicePolicyDemo Zdjęcie zostanie wykonane, gdy pierwsza próba zakończy się niepowodzeniem.

Wątpię, że może to być jakiś problem ze sprzętem. Nie jestem pewien, czy widziałeś Taking picture from camera without preview.

Druga odpowiedź wspomina, że ​​sfałszowanie podglądu przy użyciu atrapy SurfaceView nie działa na wszystkich urządzeniach z systemem Android. Zobacz jego blog. Wykonał test na różnych telefonach. Możesz wypróbować mój projekt i jeśli to nie zadziała w Twoim telefonie. Tak może być. (Inne odpowiedzi również mogą ci się przydać).

Próbowałem mojego kodu na Galaxy S3 z CM10.

Mam nadzieję, że to pomoże.

Edit1: Testowany na HTC One, HTC One X, Sony Experia. Działa w porządku.

Edycja2: pracował na Galaxy Note.

+0

Wielkie dzięki ... To naprawdę pomocne. Najpierw testowałem to na Samsung Nexusie, ale później testuję to na wielu innych urządzeniach i pracuję nad wszystkim poza tym jednym Samsung Nexus. Testuję aplikację na LG Nexus, Samsung Galaxy Tab 7 'i 10', Samsung SII i Samsung SII. Wielkie dzięki jeszcze raz drodzy .... –

+0

Serdecznie zapraszamy. – pt2121

+0

Proszę, wyświadcz mi przysługę, jeśli przetestujesz ten kod również w innym urządzeniu, aktualizuj tutaj, aby mieć pewność, że moja aplikacja obsługuje numery urządzeń. –

0

jestem nie wiem, czy to zadziała na innych urządzeniach, ale jeśli to zrobi, może dać wgląd w to, co się dzieje.

W Camera.Parameters dostępna jest funkcja zapisywania obrazu surowego bayera bezpośrednio na karcie SD. Ten obraz ma miejsce przed utworzeniem pliku .jpeg, więc jeśli system operacyjny wygasza obraz, obraz ten może nie zostać wykonany.

Camera.Parameters parameters=camera.getParameters(); 
    parameters.set("rawsave-mode", "1"); 
    parameters.set("rawfname", "/mnt/sdcard2/test5.raw"); 
    camera.setParameters(parameters); 

Jeśli funkcja ta działa na urządzeniu, należy być w stanie określić, czy obraz jest podejmowane i wymazane lub jeżeli nie są brane w ogóle.

Jeśli obraz nieprzetworzony działa, dość łatwo jest przekonwertować łącznik na obraz RGB lub obraz w skali szarości.

Drugim obszarem, który chciałbym obejrzeć, jest informacja o logcat i porównanie dzienników między odblokowanym kontekstem kodu i zablokowanym kontekstem kodu. Jeśli wystąpił problem z zabezpieczeniami, powinien on zostać odzwierciedlony w kodzie logowania.