I'm build an app that draws a circle to the screen when the user double-taps an image. I want the circle to appear at the exact x and y coordinates where the user taps the screen. RIght now, it draws the image at the top right of the screen. Do I have to implement onTouchEvent and how do I do that?
Here is the On Touch Listener: (touch is an imageview)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_display);
Intent intent = getIntent();
String path = getIntent().getStringExtra(ImageDisplayActivity.KEY_PATH);
try {
java.io.FileInputStream in = this.openFileInput(path);
bitmap = BitmapFactory.decodeStream(in);
bitmap = bitmap.copy(bitmap.getConfig(), true);
touch = (ZoomInZoomOut)findViewById(R.id.IMAGEID);
touch = arrangeImageView(touch);
touch.setImageBitmap(bitmap);
in.close();
touch.setOnTouchListener(new View.OnTouchListener() {
GestureDetector gestureDetector = new
GestureDetector(new MyGestureDetector(context));
#Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
And here is the class that is supposed to draw the circle
class MyGestureDetector extends GestureDetector.SimpleOnGestureListener {
public Context context;
public MyGestureDetector(Context con)
{
this.context=con;
}
#Override
public boolean onDoubleTap(MotionEvent event) {
Bitmap bmOverlay = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(),
bitmap.getConfig());
Canvas canvas = new Canvas(bmOverlay);
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(Color.RED);
p.setStrokeWidth(2);
p.setStyle(Paint.Style.STROKE);
canvas.drawBitmap(bitmap,new Matrix(),null);
canvas.drawCircle(event.getX(),event.getY(),
100, p);
touch.setImageBitmap(bmOverlay);
return false;
}
}
Related
I want to implement zoom function while video recording in android.But, I am not able to access Camera parameters or Camera startSmoothZoom() method in neither main activity nor surface class. If you access camera parametera in media recorder method(prepareMediaRecorder()) it will throw null pointer exception.
this activity class- in prepareMediaRecorder() method not able to access camera parameters and also not able to set startSmoothZoom(). here camera object giving null pointer exception.
public class CustomCameraPreview extends BaseActivity implements
OnClickListener, AlertPositiveListener, OrientationListener,
ActivityCompat.OnRequestPermissionsResultCallback {
RelativeLayout mLayout;
MediaRecorder mediaRecorder;
private PictureCallback mPictureCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
cameraData = data;
captureAngle = getRotation();
mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
}
catch (OutOfMemoryError e){
System.gc();
mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
}
// int rotation=getRotation();
Matrix matrix = new Matrix();
matrix.postRotate(getRotation());
/*mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(),
mBitmap.getHeight(), matrix, true);*/
mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(),
mBitmap.getHeight(), matrix, false);
if (mBitmap != null) {
mButtonRetake.setEnabled(true);
} else {
Message.displayToast(CustomCameraPreview.this,
getString(R.string.picture_not_taken));
}
mCamera.release();
mButtonCapture.setEnabled(false);
}
};
protected void onCreate(){
initiCameraForVideo();
}
private void initiCameraForVideo() {
params = mCamera.getParameters();
mButtonCapture.setBackgroundResource(R.drawable.videostart);
mShowCamera = new CameraSurfaceHolder(CustomCameraPreview.this,
mCamera);
mLayout = (RelativeLayout) findViewById(R.id.relativeLayout);
mLayout.removeAllViews();
mLayout.addView(mShowCamera);
List<Camera.Size> mSizeList_Video = null;// params.getSupportedPreviewSizes();
if (params.getSupportedVideoSizes() != null) {
mSizeList_Video = params.getSupportedVideoSizes();
} else {
// Video sizes may be null, which indicates that all the
// supported preview sizes are supported for video
// recording.
mSizeList_Video = mCamera.getParameters()
.getSupportedPreviewSizes();
}
}
#Override
public void onClick(View v) {
int viewId = v.getId();
switch (viewId) {
case R.id.button_Capture:
releaseCamera();
if (!prepareMediaRecorder()) {
Message.displayToast(
CustomCameraPreview.this,
getString(R.string.somethign_went_wrong));
} else {
mediaRecorder.start();
recording = true;
}
}
private boolean prepareMediaRecorder() \*method to setup media player to record video
{
mCamera = isCameraAvailable();
mediaRecorder = new MediaRecorder();
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
if(CamcorderProfile.hasProfile(findCameraID(), CamcorderProfile.QUALITY_480P)) {
mediaRecorder.setProfile(CamcorderProfile
.get(CamcorderProfile.QUALITY_480P));
}else{
mediaRecorder.setProfile(CamcorderProfile
.get(CamcorderProfile.QUALITY_LOW));
}
mediaRecorder.setOutputFile(getOutputVideoFile());
mediaRecorder.setMaxDuration(60000);
// mediaRecorder.setMaxFileSize(100 * 1000 * 1000);
mediaRecorder.setPreviewDisplay(mShowCamera.getHolder().getSurface());
try {
mediaRecorder.prepare();
}
}
#Override
protected void onPause() {
super.onPause();
releaseMediaRecorder();
releaseCamera();
}
private void releaseCamera() {
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
and this surface preview class-
public class CameraSurfaceHolder extends SurfaceView implements
SurfaceHolder.Callback {
private static final String TAG = "CameraSurfaceHolder";
Context mContext;
private String errorMessage = "";
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
public CameraSurfaceHolder(Context context, Camera camera) {
super(context);
mContext = context;
mCamera = camera;
mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(this);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
/*if (holder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
setCameraDisplayOrientation((Activity)mContext, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera);
// start preview with new settings
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
*/
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
} catch (Exception e) {
Logger.ex(e);
}
}
public void setCameraDisplayOrientation(Activity activity, int cameraId,
Camera camera) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
/*Display mDisplay = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = mDisplay.getDisplayId();*/
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
Camera.Parameters mParameters = camera.getParameters();
mParameters.setRotation(rotation);
camera.setDisplayOrientation(result);
camera.setParameters(mParameters);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
in above class I added some code like below and when user touch on camera preview its throwing null pointer exception in onTouchEvent() on access of camera paramters. Also tried like I set again camera object to surface in activity after configure media recorder(prepareMediaRecorder()), but zoom function working but video is not recording.
#Override
public boolean onTouchEvent(MotionEvent event) {
// Get the pointer ID
Camera.Parameters params = mCamera.getParameters();
int action = event.getAction();
if (event.getPointerCount() > 1) {
// handle multi-touch events
if (action == MotionEvent.ACTION_POINTER_DOWN) {
mDist = getFingerSpacing(event);
} else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) {
mCamera.cancelAutoFocus();
handleZoom(event, params);
}
} else {
// handle single touch events
if (action == MotionEvent.ACTION_UP) {
handleFocus(event, params);
}
}
return true;
}
private void handleZoom(MotionEvent event, Camera.Parameters params) {
int maxZoom = params.getMaxZoom();
int zoom = params.getZoom();
float newDist = getFingerSpacing(event);
if (newDist > mDist) {
//zoom in
if (zoom < maxZoom)
zoom++;
} else if (newDist < mDist) {
//zoom out
if (zoom > 0)
zoom--;
}
mDist = newDist;
params.setZoom(zoom);
mCamera.setParameters(params);
}
public void handleFocus(MotionEvent event, Camera.Parameters params) {
int pointerId = event.getPointerId(0);
int pointerIndex = event.findPointerIndex(pointerId);
// Get the pointer's current position
float x = event.getX(pointerIndex);
float y = event.getY(pointerIndex);
List<String> supportedFocusModes = params.getSupportedFocusModes();
if (supportedFocusModes != null && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
mCamera.autoFocus(new Camera.AutoFocusCallback() {
#Override
public void onAutoFocus(boolean b, Camera camera) {
// currently set to auto-focus on single touch
}
});
}
}
/** Determine the space between the first two fingers */
private float getFingerSpacing(MotionEvent event) {
// ...
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float)Math.sqrt(x * x + y * y);
}
I am creating a game and would like to read the player input for the character in the characters class. I don't know if this is good practice for game development however it seems like the logical thing to do.
I have the following code within my Player class (relevant code included) however my suspicion is that it isn't working as it isn't the primary view class or something? All help is appreciated.
Player
public class Player implements View.OnTouchListener{
private static Player instance = null;
int x, y;
boolean moveRight = false;
Bitmap sprite;
public Player (Context context){
sprite = BitmapFactory.decodeResource(context.getResources(), R.drawable.test_sprite);
x = 300;
y = 0;
}
public void Update(){
if (moveRight){
x += 3;
} else {
x -= 3;
}
}
public static Player getInstance(Context context) {
if (instance == null){
instance = new Player(context);
}
return instance;
}
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
float x = motionEvent.getX(), y = motionEvent.getY();
switch (motionEvent.getAction() & motionEvent.getActionMasked()){
case MotionEvent.ACTION_DOWN:
moveRight = true;
break;
case MotionEvent.ACTION_UP:
moveRight = false;
break;
}
return true;
}
}
GameView
public class GameView extends SurfaceView implements Runnable {
private boolean running = true;
SurfaceHolder surfaceHolder = getHolder();
SimpleTurret simpleTurret;
Player player;
private Thread thread = new Thread(this);
public GameView (Context context){
super(context);
simpleTurret = SimpleTurret.getInstance(context);
player = Player.getInstance(context);
thread.start();
}
#Override
public void run() {
while (running){
DrawCanvas();
Control();
}
}
public void DrawCanvas(){
Canvas canvas = surfaceHolder.lockCanvas();
if (surfaceHolder.getSurface().isValid()){
canvas.drawColor(Color.RED);
canvas.drawBitmap(simpleTurret.getSprite(), simpleTurret.getX(), simpleTurret.getY(), null);
canvas.drawBitmap(player.getSprite(), player.getX(), player.getY(), null);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
public void Control(){
try{
thread.sleep(17);
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
public class GameView extends SurfaceView implements Runnable, OnTouchListener {
public GameView(Context context) {
super(context);
this.setOnTouchListener(this);
}
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return false;
} ...
this.setOnTouchListener(this); line puts the OnTouchListener on the GameView class which extends the SurfaceView. So now anytime there is a touch on your SurfaceView the onTouch method would be called
You can use ImageView instead a Bitmap and set your implementation of View.OnTouchListener with the method setOnTouchListener:
ImageView sprite;
public Player (Context context){
sprite = new ImageView(context);
sprite.setBackgroundResource(R.drawable.monkey);
sprite.setOnTouchListener(this);
x = 300;
y = 0;
}
I am using open street Map tool of osmdroid
How can I create a blue dot with direction pointing base on direction bearing?
I only find out how to add marker in OSMDROID, what is the blue dot call in osmdroid?
I did this a few years ago, I don't know if Osmdroid has changed in the mean time. I was overriding overlay and its draw method, inserting my bitmap.
As I said, this is old code, check with the current API before you use it.
public class MyLocationOverlay extends Overlay implements MyLocationListener {
private static final String TAG = MyLocationOverlay.class.getSimpleName();
private BoundedMapView mapView;
private Point point = new Point();
private Bitmap myLocationMarker;
private Bitmap haloMarker;
private Location myLocation;
private Bitmap bm;
private MyLocationManager locationManager;
public MyLocationOverlay(Drawable pDefaultMarker, ResourceProxy pResourceProxy,
Context context, MapView mapView, MyLocationManager locationManager,
BitmapUtils bitmapUtils) {
super(pResourceProxy);
this.mapView = (BoundedMapView) mapView;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
myLocationMarker = bitmapUtils.rotateIcon(BitmapFactory.decodeResource(
context.getResources(), R.drawable.trackingdot, options));
haloMarker = BitmapFactory.decodeResource(context.getResources(),
R.drawable.trackingdothalo);
myLocation = locationManager.getMyLocation();
this.locationManager = locationManager;
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
/*
* draw my location
*/
if (myLocation != null) {
try {
point = mapView.getProjection().toPixels(
new GeoPoint(myLocation.getLatitude(), myLocation.getLongitude()), point);
canvas.drawBitmap(myLocationMarker, point.x - (myLocationMarker.getWidth() / 2),
point.y - (myLocationMarker.getWidth() / 2), null);
int size = (int) mapView.getProjection().metersToEquatorPixels(
myLocation.getAccuracy());
if (bm != null) {
bm.recycle();
}
if (size > 40) {
bm = Bitmap.createScaledBitmap(haloMarker, size, size, false);
canvas.drawBitmap(bm, point.x - (bm.getWidth() / 2), point.y
- (bm.getHeight() / 2), null);
}
} catch (OutOfMemoryError e) {
Log.d(TAG, e.getMessage() == null ? "OutOfMemoryError" : e.getMessage());
} catch (IllegalArgumentException e) {
Log.d(TAG, e.getMessage() == null ? "IllegalArgumentException" : e.getMessage());
}
}
}
#Override
public void onLocationChanged(Location location) {
myLocation = location;
mapView.postInvalidate();
}
#Override
public void onProviderDisabled(String provider) {
if (LocationManager.GPS_PROVIDER.equalsIgnoreCase(provider)) {
myLocation = null;
}
}
#Override
public void onProviderEnabled(String provider) {
if (LocationManager.GPS_PROVIDER.equalsIgnoreCase(provider)) {
myLocation = locationManager.getMyLocation();
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
if (LocationManager.GPS_PROVIDER.equalsIgnoreCase(provider)
&& status == LocationProvider.AVAILABLE) {
myLocation = locationManager.getMyLocation();
}
}
#Override
public void onExitEnterPark(InParkStatus inParkStatus) {
}
}
Step 1: install osmonuspack
(https://github.com/MKergall/osmbonuspack/wiki/Tutorial_0)
Step 2: download osmand and get icons from osmand;
blue arrow (map_navigation_default)
or similar to the icon above (map_location_default)
Step 3: Change DirectedLocationOverlay icon:
myLocationOverlay = new DirectedLocationOverlay(this);
first choice, Single bitmap;
// 1-Single Bitmap
Drawable d = ResourcesCompat.getDrawable(getResources(), R.drawable.direction_arrow, null);
Bitmap bitmap = ((BitmapDrawable) d).getBitmap();
or second option, Blue Arrow;
// 2-Single LayerDrawable - Blue Arrow
LayerDrawable ld = (LayerDrawable)getResources().getDrawable(R.drawable.map_navigation_default);
final int width = ld.getIntrinsicWidth();
final int height = ld.getIntrinsicHeight();
final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
ld.setBounds(0, 0, width, height);
ld.draw(new Canvas(bitmap));
or third option, similar to the icon above;
//3- Double layerdrawable
Drawable bottom = ContextCompat.getDrawable(this, R.drawable.map_location_default_view_angle);
Drawable top = ContextCompat.getDrawable(this, R.drawable.map_location_default);
final LayerDrawable ld = new LayerDrawable(new Drawable[]{bottom, top});
final int width = ld.getIntrinsicWidth();
final int height = ld.getIntrinsicHeight();
final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
ld.setBounds(0, 0, width, height);
ld.draw(new Canvas(bitmap));
change icon;
myLocationOverlay.setDirectionArrow(bitmap);
map.getOverlays().add(myLocationOverlay);
I am creating a multi-image capturing feature using custom Camera in my app.But there is a problem with the custom camera. Image captured by custom camera is not getting clear as like default camera(Camera opening with Intent)
Please help me out.I have tried the lot of suggested solutions.
CameraActivity.java
public class CameraActivity extends Activity {
private Camera mCamera;
private SharedPreferences prefs;
private String clickedMenuItem;
Button captureButton;
private LayoutInflater controlInflater = null;
private View viewControl;
private CircularImageView imgview;
private ArrayList<Bitmap> bitmapArray = new ArrayList<Bitmap>();;
private ImageView cancleimg;
private FrameLayout imgLayout;
int RESULT_IMG = 200;
int NO_IMG = 204;
FrameLayout preview;
private CameraPreview mCameraPreview;
ArrayList<CharSequence> imgarrayList = new ArrayList<CharSequence>();
Intent intent = new Intent( );
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_preview);
clickedMenuItem = Attributes.Another_Item;
if(getIntent().hasExtra(Attributes.ClickedMenuItem)){
clickedMenuItem = getIntent().getExtras().getString(Attributes.ClickedMenuItem);
}
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(this, mCamera);
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
try{
controlInflater = LayoutInflater.from(getBaseContext());
viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
}catch(Exception e)
{e.printStackTrace();}
captureButton = (Button)viewControl.findViewById(R.id.button_capture);
Button doneBtn = (Button)viewControl.findViewById(R.id.done);
imgview = (CircularImageView)viewControl.findViewById(R.id.captureimg);
cancleimg = (ImageView)viewControl.findViewById(R.id.cancleimg);
imgLayout = (FrameLayout)viewControl.findViewById(R.id.imglayout);
imgLayout.setVisibility(View.INVISIBLE);
if (isDIYUSer() && clickedMenuItem != null && !clickedMenuItem.equals(Attributes.Kagazz_Scanner)) {
captureButton.setBackgroundResource(R.drawable.cam);
}
cancleBtnClick();
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
});
doneBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
setResult(RESULT_IMG,intent);
bitmapArray = null;
finish();
}
});
}
#Override
public void onPause() {
try{
super.onPause();
releaseCamera();
}catch(Exception e)
{}// release the camera immediately on pause event
}
private void releaseCamera(){
try{
if (mCamera != null){
mCamera.stopPreview();
mCamera.setPreviewCallback(null);// stop the preview
mCamera.release();
preview.removeView(mCameraPreview);
mCamera = null;
// release the camera for other applicationsCODE_IMG
}
}
catch(Exception e)
{}
}
#Override
public void onBackPressed() {
imgarrayList.clear();
intent.putCharSequenceArrayListExtra("List",imgarrayList);
setResult(RESULT_IMG,intent);
finish();
}
void cancleImg()
{}
public void deleteTempImg(Uri uri)
{
try {
File file = new File(uri.getPath());
boolean isdeleted = file.delete();
if(file.exists()){
boolean deleted = file.getCanonicalFile().delete();
if(deleted)
{Log.d("tag", "file deleted.");}
}
if(file.exists()){
this.getApplicationContext().deleteFile(file.getName());
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onResume() {
super.onResume();
try{
if (mCamera == null)
{
mCamera = getCameraInstance();
// three new lines, creating a new CameraPreview, then adding it to the FrameLayout
mCameraPreview = new CameraPreview(this, mCamera);
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
}
}catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Helper method to access the camera returns null if it cannot get the
* camera or does not exist
*
* #return
*/
private Camera getCameraInstance() {
mCamera = null;
try {
mCamera = Camera.open();
//STEP #1: Get rotation degrees
// Camera.CameraInfo info = new Camera.CameraInfo();
// Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
// int rotation = this.getWindowManager().getDefaultDisplay().getRotation();
// int degrees = 0;
// switch (rotation) {
// case Surface.ROTATION_0: degrees = 0; break; //Natural orientation
// case Surface.ROTATION_90: degrees = 90; break; //Landscape left
// case Surface.ROTATION_180: degrees = 180; break;//Upside down
// case Surface.ROTATION_270: degrees = 270; break;//Landscape right
// }
// int rotate = (info.orientation - degrees + 360) % 360;
//STEP #2: Set the 'rotation' parameter
Camera.Parameters params = mCamera.getParameters();
// params.setRotation(rotate);
/* Set Auto focus */
List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
}
else{
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
mCamera.setParameters(params);
} catch (Exception e) {
// cannot get camera or does not exist
}
return mCamera;
}
private static File getOutputMediaFile() {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
public static Bitmap rotate(Bitmap bitmap, int degree) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
// mtx.postRotate(degree);
mtx.setRotate(degree);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
#Override
protected void onStop() {
super.onStop();
}
}
CameraPreview.java
public class CameraPreview extends SurfaceView implements
SurfaceHolder.Callback {
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
private LayoutInflater controlInflater = null;
// Constructor that obtains context and camera
#SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera) {
super(context);
this.mCamera = camera;
this.mSurfaceHolder = this.getHolder();
this.mSurfaceHolder.addCallback(this);
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
#SuppressWarnings("deprecation")
Camera.Parameters parameters = mCamera.getParameters();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
parameters.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
parameters.setRotation(90);
}
else {
// This is an undocumented although widely known feature
parameters.set("orientation", "landscape");
// For Android 2.2 and above
mCamera.setDisplayOrientation(0);
// Uncomment for Android 2.0 and above
parameters.setRotation(0);
}
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
}
}
#SuppressWarnings("deprecation")
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
try{
surfaceHolder.removeCallback(this);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}catch(Exception e)
{
if(e!=null)
e.printStackTrace();}
}
#SuppressWarnings("deprecation")
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format,
int width, int height) {
// start preview with new settings
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (Exception e) {
// intentionally left blank for a test
}
}
}
I'm working on a live wallpaper application. For the service, I'm playing a video as a wallpaper on loop using the MediaPlayer class. I would like to know if it's possible to draw over the video like it was a canvas, or at least a work around for do something like that (video playing and a drawn generated on top of it). I've been trying to make it work but no success at all after googling a lot and trying different alternatives.
The wallpaper service I'm using:
public class LiveWallpaperService extends WallpaperService {
#Override
public Engine onCreateEngine() {
ThemeList.init(getApplicationContext());
return new LiveWallpaperEngine();
}
private class LiveWallpaperEngine extends Engine {
private MediaPlayer mp;
private SurfaceHolder sh;
private Uri L, P;
public LiveWallpaperEngine() {
checkConfig();
}
public void onSurfaceCreated(SurfaceHolder holder) {
sh = new VideoHolder(holder);
}
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
}
#Override
public void onVisibilityChanged(boolean visible) {
//Check the current configuration
checkConfig();
if (visible) playTheme();
/*
Canvas canvas = null;
try {
canvas = sh.lockCanvas();
if (canvas != null) {
Log.d("DRAW", "DRAWING!");
Paint p = new Paint();
p.setColor(Color.WHITE);
p.setStrokeWidth(8.0f);
p.setTextSize(100.0f);
canvas.drawText("Testing", 150, 250, p);
} else {
Log.d("DRAW", "NOT DRAWING!");
}
} finally {
sh.unlockCanvasAndPost(canvas);
}*/
super.onVisibilityChanged(visible);
}
private void playTheme() {
//Check the current orientation and select the proper file to load
mp = orientationCheck();
//Start the video
mp.setDisplay(sh);
mp.setLooping(true);
mp.start();
}
private MediaPlayer orientationCheck() {
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
return MediaPlayer.create(getApplicationContext(), L);
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
return MediaPlayer.create(getApplicationContext(), P);
} else {
return MediaPlayer.create(getApplicationContext(), P);
}
}
private void checkConfig() {
//This code generates the L and P URIs based on the configuration set on the app
}
}
}
The commented code is one of the things I tried to do it, but it gives java.lang.IllegalArgumentException: canvas object must be the same instance that was previously returned by lockCanvas"
The VideoHolder is just a class that extends from SurfaceHolder.
If I don't try to draw anything the video just plays fine, and the commented code works if the video is not initialized.
Thanks!