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!
Related
I have a problem with a simple android application. It has a SurfaceView with simple drawing, but activity orientation sometimes seems not to be changed after a screen rotation.
This is how an activity looks in the portrait mode:
landscape mode:
but sometimes, when I rotate the screen, an activity looks like this in the portrait mode:
MainActivity.java:
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback
{
private Thread mGameThread;
private GameApp mGameApp;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SurfaceView mainView = (SurfaceView)findViewById(R.id.mainView);
SurfaceHolder holder = mainView.getHolder();
holder.addCallback(this);
mGameApp = new GameApp(getResources(), holder);
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
mGameThread = new Thread(new Runnable()
{
#Override
public void run()
{
mGameApp.run();
}
});
mGameThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
mGameApp.setSurfaceSize(width, height);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
boolean retry = true;
mGameApp.setRunning(false);
while (retry)
{
try
{
mGameThread.join();
retry = false;
}
catch (InterruptedException e)
{
}
}
}
}
GameApp.java:
package com.example.myapplication;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.view.SurfaceHolder;
public class GameApp
{
private Resources mResources;
private SurfaceHolder mSurfaceHolder;
private int mCanvasHeight = 1;
private int mCanvasWidth = 1;
private volatile boolean mRun = false;
public GameApp(Resources resources, SurfaceHolder surfaceHolder)
{
mResources = resources;
mSurfaceHolder = surfaceHolder;
}
public void setSurfaceSize(int width, int height)
{
synchronized (mSurfaceHolder)
{
mCanvasWidth = width;
mCanvasHeight = height;
}
}
public void run()
{
setRunning(true);
while (mRun)
{
Canvas canvas = null;
try
{
canvas = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder)
{
if (mRun && canvas != null)
{
draw(canvas);
}
}
}
finally
{
if (canvas != null)
{
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
public void setRunning(boolean b)
{
mRun = b;
}
private void draw(Canvas canvas)
{
canvas.drawColor(Color.GREEN);
Drawable cellImage = mResources.getDrawable(R.drawable.cell);
final float cellWidth = mCanvasWidth / 6;
final float cellHeight = mCanvasHeight / 6;
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
float x = i * cellWidth;
float y = j * cellHeight;
cellImage.setBounds(Math.round(x), Math.round(y), Math.round(x + cellWidth), Math.round(y + cellHeight));
cellImage.draw(canvas);
}
}
}
}
Eventual answer:
The problem is that you are doing a while loop in your GameApp's thread that locks the canvas and then unlocks without any long blocking or sleep in between.
The SurfaceHolder#lockCanvas documentation states:
If null is not returned, this function internally holds a lock until the corresponding unlockCanvasAndPost(Canvas) call, preventing SurfaceView from creating, destroying, or modifying the surface while it is being drawn.
So this means that the destroy code which is run from main thread needs to run between the unlockCanvasAndPost and the next lockCanvas. But since you have no sleep or even other code in between (except for the while condintion check), the chance of this happening is very small, and - depending on the device - could practically take forever.
To fix this, put a sleep in your game app to achieve the wanted framerate,
in it's most simple from this could look like this.
class GameApp
...
while (mRun)
{
Canvas canvas = null;
try
{
canvas = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder)
{
if (mRun && canvas != null)
{
draw(canvas);
}
}
}
finally
{
if (canvas != null)
{
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
// Add some sleep time depending on how fast you want to refresh
try {
Thread.sleep(1000/60); //~60 fps
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Original answer 1: What could have helped in case of handling orientation changes
Seems like the surface is not always re-drawn on a config change.
Try overriding the onConfigurationChanged method of the activity and then triggering a re-layout of the surface
in MainActivity.java:
...
#Override
public void onConfigurationChanged(Configuration newConfig) {
// You should save (SurfaceView)findViewById(R.id.mainView) in a field for better performance, but I'm putting it here for shorter code.
SurfaceView mainView = (SurfaceView)findViewById(R.id.mainView);
mainView.invalidate();
mainView.requestLayout();
}
...
More info on these methods nicely explained here:
Usage of forceLayout(), requestLayout() and invalidate()
Original answer 2: A way to check if your threads are blocked
Another possibility is that you have a thread lock issue on your main thread.
For checking that you could change your activity like this:
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private Thread mGameThread;
private GameApp mGameApp;
private static View currMainView;
private static Thread logPosterThread = new Thread(new Runnable() {
volatile boolean mainLogDone = true;
#Override
public void run() {
Runnable mainThreadLogger = new Runnable() {
#Override
public void run() {
Log.d("THREAD_CHECK", "Main Thread is ok");
mainLogDone = true;
}
};
while (true) {
try {
int sleepTime = 1000;
Thread.sleep(sleepTime);
if (currMainView != null) {
if (mainLogDone) {
mainLogDone = false;
Log.d("THREAD_CHECK", "Main Thread doing post");
currMainView.post(mainThreadLogger);
} else {
Log.w("THREAD_CHECK", "Main Thread did not run the runnable within " + sleepTime + "ms");
mainLogDone = true;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
static {
logPosterThread.start();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final SurfaceView mainView = (SurfaceView) findViewById(R.id.mainView);
currMainView = mainView;
SurfaceHolder holder = mainView.getHolder();
holder.addCallback(this);
mGameApp = new GameApp(getResources(), holder);
}
#Override
public void onPause() {
...
And then see if those logs still get printed with 1000ms in between when the issue happens.
When you try this, you will see that actually the main thread is hanging when this happens.
I am trying to create a livewallpaper for android which uses Android 8.1's WallpaperColors API to change systemUI to dark or light depending on the livewallpaper color.
This is my LiveWallpaperAndroid.java
public class LiveWallpaperAndroid extends AndroidLiveWallpaperService {
String TAG="LiveWallpaperAndroid";
#Override
public void onCreateApplication () {
super.onCreateApplication();
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
config.numSamples=0;
config.useCompass = false;
config.useWakelock = false;
config.useAccelerometer = false;
config.getTouchEventsForLiveWallpaper = true;
ApplicationListener listener = new LiveWallpaperStarter();
initialize(listener, config);
if (Build.VERSION.SDK_INT >= 27) {
linkedEngine.notifyColorsChanged();
Log.d(TAG,"trying to notify from onCreate()");
}
}
public class MyLiveWallpaperListener extends LiveWallpaperScreen implements AndroidWallpaperListener {
public MyLiveWallpaperListener(Game game) {
super(game);
}
#Override
public void offsetChange (float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) {
}
#Override
public void previewStateChange (boolean isPreview) {
Log.i("LiveWallpaper test", "previewStateChange(isPreview:"+isPreview+")");
}
}
When I call notifyColorsChanged() from on create , this is what shows up in the logcat
W/WallpaperService: Can't notify system because wallpaper connection was not established.
I wanted my live wallpaper to trigger the dark them, so I used this
public class MyEngine extends Engine
#RequiresApi(api = Build.VERSION_CODES.O_MR1)
#Override
public WallpaperColors onComputeColors() {
return new WallpaperColors(Color.valueOf(Color.BLACK), Color.valueOf(Color.BLACK), Color.valueOf(Color.BLACK));
}
If you wanted to recalculate the color on the fly you probably have to call engine.notifyColorsChanged()
I am new in Android. I am currently developing a game and when I press the back button I realize that my activity's state is not saved so I search and I found out about Android Lifecycle. I read it and now i know how they work but the thing is I don't know how to pause and resume my activity or What code should I use because it is the auto-generated grid and my timer is CountDownTimer.
When I press the Back button this Activity is what appears.
GameModeActivity
Now i want to detect if the game is still going on .. so if I click again the game mode this is what should appear.
GamePlayActivity
The problem is The grid was back to its normal state. and when I click a button timer never runs. If possible i want to restore the player's progress (like the position of mines, the flags, and the timer itself.).
My question is ... Is there a specific code to get the whole state of activity? so that i can just pause it and when i came back it will just resume?
This is the code of timer and grid in GameEngine class:
public static GameEngine getInstance() {
if (instance == null) {
instance = new GameEngine();
}
return instance;
}
private GameEngine() {
}
public void startit() {
countdowntimer = new CountDownTimer(60000, 1000) {
TextView timer = (TextView) ((GamePlayActivity) context).findViewById(R.id.tvTimeValue);
#Override
public void onTick(long millisUntilFinished) {
timer.setText("" + millisUntilFinished / 1000);
}
#Override
public void onFinish() {
timer.setText("Times up!");
timer.setTextColor(Color.RED);
}
}.start();
}
public static void cancel() {
if (countdowntimer != null) {
countdowntimer.cancel();
countdowntimer = null;
}
}
public void createGrid(Context context) {
Log.e("GameEngine", "Creating Grid..");
this.context = context;
int[][] GeneratedGrid = Generator.generate(bombnumber, WIDTH, HEIGHT);
setGrid(context, GeneratedGrid);
}
private void setGrid(final Context context, final int[][] grid) {
for (int x = 0; x < WIDTH; x++) {
for (int y = 0; y < HEIGHT; y++) {
if (MinesweeperGrid[x][y] == null) {
MinesweeperGrid[x][y] = new Cell(context, x, y);
}
MinesweeperGrid[x][y].setValue(grid[x][y]);
MinesweeperGrid[x][y].invalidate();
}
}
}
public Cell getCellposition(int position) {
int x = position % WIDTH;
int y = position / WIDTH;
return MinesweeperGrid[x][y];
}
public Cell getCellposition(int x, int y) {
return MinesweeperGrid[x][y];
}
I call the GameEngine.getInstance().createGrid(this) class in onCreate method of GamePlayActivity
And when I press the Back button on phone it will go to the previous activity which is GameModeActivity.
i am trying to make an app that detects faces. The code below has no errors and from what i can see should be working fine. However when I run it, i get the following:
FATAL EXCEPTION: main
Process: org.bytefish.videofacedetection, PID: 12075
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.hardware.Camera.setFaceDetectionListener(android.hardware.Camera$FaceDetectionListener)'
on a null object reference
at org.bytefish.videofacedetection.
CameraActivity.surfaceCreated(CameraActivity.java:100)
at android.view.SurfaceView.updateWindow(SurfaceView.java:582)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:177)
at
android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2055)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
at
android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
at
android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at
android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
The code is below, an all caps comment shows line 100 and the error
import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Face;
import android.hardware.Camera.FaceDetectionListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.OrientationEventListener;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup.LayoutParams;
import android.widget.Toast;
import java.util.List;
public class CameraActivity extends Activity
implements SurfaceHolder.Callback {
public static final String TAG = CameraActivity.class.getSimpleName();
private Camera mCamera;
// We need the phone orientation to correctly draw the overlay:
private int mOrientation;
private int mOrientationCompensation;
private OrientationEventListener mOrientationEventListener;
// Let's keep track of the display rotation and orientation also:
private int mDisplayRotation;
private int mDisplayOrientation;
// Holds the Face Detection result:
private Camera.Face[] mFaces;
// The surface view for the camera data
private SurfaceView mView;
// Draw rectangles and other fancy stuff:
private FaceOverlayView mFaceView;
// Log all errors:
private final CameraErrorCallback mErrorCallback = new CameraErrorCallback();
/**
* Sets the faces for the overlay view, so it can be updated
* and the face overlays will be drawn again.
*/
private FaceDetectionListener faceDetectionListener = new FaceDetectionListener() {
#Override
public void onFaceDetection(Face[] faces, Camera camera) {
Log.d("onFaceDetection", "Number of Faces:" + faces.length);
// Update the view now!
mFaceView.setFaces(faces);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mView = new SurfaceView(this);
setContentView(mView);
// Now create the OverlayView:
mFaceView = new FaceOverlayView(this);
addContentView(mFaceView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// Create and Start the OrientationListener:
mOrientationEventListener = new SimpleOrientationEventListener(this);
mOrientationEventListener.enable();
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
SurfaceHolder holder = mView.getHolder();
holder.addCallback(this);
}
#Override
protected void onPause() {
mOrientationEventListener.disable();
super.onPause();
}
#Override
protected void onResume() {
mOrientationEventListener.enable();
super.onResume();
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
mCamera = Camera.open();
mCamera.setFaceDetectionListener(faceDetectionListener);
mCamera.startFaceDetection();
try {
mCamera.setPreviewDisplay(surfaceHolder);
} catch (Exception e) {
Log.e(TAG, "Could not preview the image.", e);
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
// We have no surface, return immediately:
if (surfaceHolder.getSurface() == null) {
return;
}
// Try to stop the current preview:
try {
mCamera.stopPreview();
} catch (Exception e) {
// Ignore...
}
configureCamera(width, height);
setDisplayOrientation();
setErrorCallback();
// Everything is configured! Finally start the camera preview again:
mCamera.startPreview();
}
private void setErrorCallback() {
mCamera.setErrorCallback(mErrorCallback);
}
private void setDisplayOrientation() {
// Now set the display orientation:
mDisplayRotation = Util.getDisplayRotation(CameraActivity.this);
mDisplayOrientation = Util.getDisplayOrientation(mDisplayRotation, 0);
mCamera.setDisplayOrientation(mDisplayOrientation);
if (mFaceView != null) {
mFaceView.setDisplayOrientation(mDisplayOrientation);
}
}
private void configureCamera(int width, int height) {
Camera.Parameters parameters = mCamera.getParameters();
// Set the PreviewSize and AutoFocus:
setOptimalPreviewSize(parameters, width, height);
setAutoFocus(parameters);
// And set the parameters:
mCamera.setParameters(parameters);
}
private void setOptimalPreviewSize(Camera.Parameters cameraParameters, int width, int height) {
List<Camera.Size> previewSizes = cameraParameters.getSupportedPreviewSizes();
float targetRatio = (float) width / height;
Camera.Size previewSize = Util.getOptimalPreviewSize(this, previewSizes, targetRatio);
cameraParameters.setPreviewSize(previewSize.width, previewSize.height);
}
private void setAutoFocus(Camera.Parameters cameraParameters) {
cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mCamera.setPreviewCallback(null);
mCamera.setFaceDetectionListener(null);
mCamera.setErrorCallback(null);
mCamera.release();
mCamera = null;
}
/**
* We need to react on OrientationEvents to rotate the screen and
* update the views.
*/
private class SimpleOrientationEventListener extends OrientationEventListener {
public SimpleOrientationEventListener(Context context) {
super(context, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
public void onOrientationChanged(int orientation) {
// We keep the last known orientation. So if the user first orient
// the camera then point the camera to floor or sky, we still have
// the correct orientation.
if (orientation == ORIENTATION_UNKNOWN) return;
mOrientation = Util.roundOrientation(orientation, mOrientation);
// When the screen is unlocked, display rotation may change. Always
// calculate the up-to-date orientationCompensation.
int orientationCompensation = mOrientation
+ Util.getDisplayRotation(CameraActivity.this);
if (mOrientationCompensation != orientationCompensation) {
mOrientationCompensation = orientationCompensation;
mFaceView.setOrientation(mOrientationCompensation);
}
}
}
}
When i try to open it in android studio it opens fine with no errors but dies when i try to run it.
I am new to android so any tips would be much appreciated. Thanks a ton for your help and time.
Ok, it looks like you are not getting the camera object right
this code will init the front camera properly
part1
cameraId = findFrontFacingCamera();
if (cameraId < 0) {
Toast.makeText(this, "No camera found.",
Toast.LENGTH_LONG).show();
} else {
mcamera = Camera.open(cameraId);
}
part2
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
Log.d(DEBUG_TAG, "Camera found");
cameraId = i;
break;
}
}
return cameraId;
}
please try and let me know.
I have this method to set current location pushpin on map:
private void createPushPinOnMap(Canvas canvas, MapView mapView, BOMPushpin pushpin) {
Location location = currentBestLocation;
float accuracy = location.getAccuracy();
Point pointPts = mapView.getProjection().toPixels(new GeoPoint(pushpin.getLatitude(),
pushpin.getLongtitude()),
null);
Bitmap bmp1 = BitmapFactory.decodeResource(
context.getResources(), R.drawable.pushpin);
canvas.drawBitmap(bmp1, pointPts.x-10, pointPts.y-34, null);
}
But I need to change this code, so pushpin size would be somehow equal to accuracy (Like in maps.google.com location pushpin).
Why no one told me that androids google api has class named MyLocation, which makes everything .
Here is the sample code what I use in my GTL application, with a little difference i use circle instead of pushpin. If the accuracy is changed you need to set it in the lastAccuracy. The GPSSettings.IS_SHOW_ACCURACY_MARKER is defalt true.
Here is the code
public class AccuracyOverlay extends Overlay {
private GeoPoint geoPoint;
private boolean isNeedClearCanvas = false;
private float lastAccuracy;
public void clearCanvas(Canvas canvas) {
canvas.drawColor(Color.WHITE);
}
private void drawAccuracyCircle(Canvas canvas, MapView mapView, GeoPoint geoPoint) {
// convert point to pixels
Point screenPoint = new Point();
mapView.getProjection().toPixels(geoPoint, screenPoint);
Paint circlePaint = new Paint();
circlePaint.setAntiAlias(true);
circlePaint.setStrokeWidth(2.0f);
circlePaint.setColor(0xff6666ff);
circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
circlePaint.setAlpha(64);
double lat = geoPoint.getLatitudeE6();
int radius = (int) mapView.getProjection().metersToEquatorPixels(lastAccuracy);
canvas.drawCircle(screenPoint.x, screenPoint.y, radius, circlePaint);
}
public int metersToRadius(double latitude) {
return (int) (mapView.getProjection().metersToEquatorPixels(lastAccuracy) * (1/ Math.cos(Math.toRadians(latitude))));
}
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
if (GPSSettings.IS_SHOW_ACCURACY_MARKER) {
if (!shadow && getLastLocation() != null) {
geoPoint = getLastLocation();
}
if (geoPoint != null) {
if (GPSSettings.IS_SHOW_ACCURACY_MARKER && (lastAccuracy > 0)) {
drawAccuracyCircle(canvas, mapView, geoPoint);
}
}
if (isNeedClearCanvas) {
boolean wasOn = GPSSettings.IS_SHOW_ACCURACY_MARKER;
try {
try {
if (wasOn)
GPSSettings.IS_SHOW_ACCURACY_MARKER = false;
geoPoint = null;
canvas.drawColor(Color.WHITE);
}
finally {
if (wasOn) {
GPSSettings.IS_SHOW_ACCURACY_MARKER = true;
}
}
}
finally {
isNeedClearCanvas = false;
}
}
}
}
public AccuracyOverlay() {
super();
}
public void clearMarks() {
this.isNeedClearCanvas = true;
}
public void setLastAccuracy(float lastAccuracy) {
this.lastAccuracy = lastAccuracy;
}
}