I have the following Live Wallpaper:
public class GLWallpaperVideoDemo extends GLWallpaperService {
public static final String folder = "video";
public static final String TAG = "GLWVD";
public static String videoName="VIDEOWALL.avi";
//video variables
public int videoWidth,videoHeight;
public boolean videoWideScreen=false;
VideoRenderer renderer = null;
public GLWallpaperVideoDemo() {
super();
Log.e(TAG,"constructor()");
}
#Override
public void onCreate() {
Log.e(TAG,"onCreate()");
super.onCreate();
//transfer video to sdcard
Log.d(TAG,"transferring video asset to sdcard");
copyVideoToCard();
Log.d(TAG,"transferred");
//if videoName == blankVideo, then don't load anything
//TODO
NativeCalls.initVideo();
Log.d(TAG,"Opening video");
NativeCalls.loadVideo("file:/"+"sdcard/"
+GLWallpaperVideoDemo.videoName);
//set video dimensions (now that we opened the video)
videoWidth = NativeCalls.getVideoWidth();
videoHeight = NativeCalls.getVideoHeight();
videoWideScreen = ( videoWidth > videoHeight ) ? true : false;
}
private VideoEngine mEngine=null;
#Override
public Engine onCreateEngine() {
Log.e(TAG,"onCreateEngine()");
mEngine = new VideoEngine();
return mEngine;
}
class VideoEngine extends GLEngine {
VideoEngine() {
super();
Log.e(TAG,"VideoEngine VideoEngine()");
if(renderer==null)renderer = new VideoRenderer(GLWallpaperVideoDemo.this,
this);
setRenderer(renderer);
//setRenderMode(RENDERMODE_WHEN_DIRTY);
setRenderMode(RENDERMODE_CONTINUOUSLY);
}
VideoRenderer getRenderer() { return renderer; }
}
}
And this is the renderer:
public class VideoRenderer implements GLWallpaperService.Renderer {
static private String TAG="Renderer>>>>>>>>>>>>";
static boolean runOnce = false;
//MediaPlayer mediaPlayer = MediaPlayer.create(MyApp.getContext(), R.raw.gunfireusedforboardstage);
//screen variables
int screenWidth=50,screenHeight=50;
int drawWidth, drawHeight; //dimensions of fit-to-screen video
int paddingX, paddingY; //padding for fit-to-screen-video
//texture variables
int powWidth,powHeight;
//pointers
GLWallpaperVideoDemo mParent;
GLWallpaperVideoDemo.VideoEngine mParentEngine;
//lock
static public Object lock = new Object();
//fps
long fpsTime;
public int framecount;
public VideoRenderer() {
super();
Log.e(TAG,"Constructor()");
}
public VideoRenderer(GLWallpaperVideoDemo p,
GLWallpaperVideoDemo.VideoEngine e) {
super();
mParent = p;
mParentEngine = e;
Log.e(TAG,"constructor()");
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Log.e(TAG, "onSurfaceCreated()");
}
void process(int width, int height) {
setScreenDimensions( width, height );
Log.d(TAG,"Killing texture");
NativeCalls.closeOpenGL();
setTextureDimensions( screenWidth, screenHeight );
setFitToScreenDimensions( mParent.videoWidth,
mParent.videoHeight );
if ( !runOnce ) {
Log.e(TAG,"Preparing frame");
NativeCalls.prepareStorageFrame();
}
NativeCalls.initOpenGL();
runOnce = true;
}
//This gets called whenever you preview the wallpaper or set the
//wallpaper
public void onSurfaceChanged(GL10 gl, int width, int height) {
Log.e(TAG,"onSurfaceChanged()");
synchronized(lock) {
process(width, height);
}
}
public void onDrawFrame(GL10 gl) {
synchronized(lock) {
//Log.d(TAG,"Drawing ....");
NativeCalls.getFrame(); // from video
NativeCalls.drawFrame(); // using openGL
if(framecount>300)framecount=0;
framecount++;
//Log.e("framecount",Integer.toString(framecount));
if(framecount==117 || framecount==124 ||framecount==137 ||framecount==145||framecount==159||framecount==167)
{new Thread(new Runnable() {
public void run() {
MediaPlayer mp= MediaPlayer.create(MyApp.getContext(), R.raw.gunfireusedforboardstage);
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
};
});
}
}).start();}
if (MyDebug.showFPS) {
final float fpsRate;
fpsRate = 1000f/((float) (SystemClock.uptimeMillis()
- fpsTime) );
fpsTime = SystemClock.uptimeMillis();
Log.d(TAG,
TAG+"drawFrame(): fps: "
+String.valueOf(fpsRate)
);
}
}
}
Now you see the variable framecount inside the renderer?
It gets reinitialized every time open the settings of the Wallpaper !!!
The result is that the renderer continues its work, but framecount is set again to 0,
the consequence is that the frames are not in sync with the MediaPlayer anymore.
SOLVED:
I made the variable static :-)
Related
I'm programming a pacman, the game is drawed in a SurfaceView, but I have problem to pause it and getting the atributes while it's running (no when I set them)
For example, I set a Semaphore that should be referenced in the Activity and in the Game view, and it is set it correct, but when the thread of the game view is running, and try to release the semaphore it indicates a NullPointerException.
On the other hand, when I try to pause the game, the game used to keep running in the background, and now when I resume it don't run
I'm sure the problem is with the references in memory, when I set and atribute as static i can access from both (view and surfaceview are the same object). I don't know why this happen.
Brief resume: An AppCompatActivity (which is PlayActivity) has a SurfaView (which is GameView), and this SurfaceView has the GameManager(which has all the things of the pacman in a moment). The references when the AppCompatActivity try to get something of the SurfaceView (for example the gameManager) are lost in execution.
Here the code
PlayActivity
public class PlayActivity extends AppCompatActivity {
private TextView playerNickname;
private TextView scoreTv;
private TextView maxScore;
private SurfaceView gameSurfaceView;
private GameView gameView;
private static Semaphore CHANGE_LIFES_MUTEX=new Semaphore(0,true);
private static Semaphore CHANGE_SCORE_MUTEX=new Semaphore(0,true);
private static Semaphore CHANGE_DIRECTION_MUTEX=new Semaphore(0,true);
private Thread changeScoreThread, changeDirectionThread;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Modified code
setContentView(R.layout.activity_game);
//we get text view that we will use
playerNickname=(TextView) this.findViewById(R.id.tv_player);
scoreTv=(TextView) this.findViewById(R.id.tv_current_score);
maxScore=(TextView) this.findViewById(R.id.tv_current_max_score);
gameSurfaceView= (GameView) this.findViewById(R.id.game_view);
//set text view initial values
playerNickname.setText(getIntent().getExtras().getString("playerNickname"));
scoreTv.setText("0");
maxScore.setText("To modify");
this.gameView=new GameView(gameSurfaceView.getContext());
this.gameView.setSemaphores(CHANGE_SCORE_MUTEX,CHANGE_DIRECTION_MUTEX);
this.gameSurfaceView.getHolder().addCallback(this.gameView);
}
protected void onResume(){
super.onResume();
this.gameView.resume();
this.initChangerThreads();
}
public void updateScoreTv(int score){
this.scoreTv.setText(""+score);
}
protected void onPause(){
super.onPause();
this.gameView.pause();
//in order to stop the threads
CHANGE_SCORE_MUTEX.release();
CHANGE_DIRECTION_MUTEX.release();
}
public void onLose(int score){
//We try to save the score, if there is a previous register we write only if this score
//is better that the one before
DBManager manager;
long raw;
Score scoreToSave;
manager=new DBManager(this);
scoreToSave=new Score(this.playerNickname.toString(), score);
if(manager.saveScore(scoreToSave)==-1){
//if i couldn't save the score
if(manager.updateScore(scoreToSave)!=-1){
//if my new score is better than the one previous
}else{
//if my new score is worse or equal than the one previous
}
}
}
private void initChangerThreads() {
this.changeScoreThread = new Thread(new Runnable() {
public void run() {
while (gameView.isDrawing()) {
//Log.i("Score ",""+gameManager.getScore());
try {
CHANGE_SCORE_MUTEX.acquire();
runOnUiThread(new Runnable() {
#Override
public void run() {
updateScoreTv(gameView.getGameManager().getScore());
}
});
}catch (Exception e){}
}
Log.i("Score Thread","ended");
}
});
this.changeScoreThread.start();
}
}
GameView
public class GameView extends SurfaceView implements Runnable, SurfaceHolder.Callback, GestureDetector.OnGestureListener {
private static final float SWIPE_THRESHOLD = 2;
private static final float SWIPE_VELOCITY = 2;
private static boolean CAN_DRAW = false;
private boolean GHOST_INICIALIZED=false;
private GestureDetector gestureDetector;
private GameManager gameManager;
private Thread thread; //game thread
private SurfaceHolder holder;
private int blockSize; // Ancho de la pantalla, ancho del bloque
private static int movementFluencyLevel=8; //this movement should be a multiple of the blocksize and multiple of 4, if note the pacman will pass walls
private int totalFrame = 4; // Cantidad total de animation frames por direccion
private int currentArrowFrame = 0; // animation frame de arrow actual
private long frameTicker; // tiempo desde que el ultimo frame fue dibujado
//----------------------------------------------------------------------------------------------
//Constructors
public GameView(Context context) {
super(context);
this.constructorHelper(context);
}
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
this.constructorHelper(context);
}
public GameView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.constructorHelper(context);
}
private void constructorHelper(Context context) {
this.gestureDetector = new GestureDetector(this);
setFocusable(true);
this.holder = getHolder();
this.holder.addCallback(this);
this.frameTicker = (long) (1000.0f / totalFrame);
this.gameManager=new GameManager();
int screenWidth=getResources().getDisplayMetrics().widthPixels;
this.blockSize = ((((screenWidth/this.gameManager.getGameMap().getMapWidth())/movementFluencyLevel)*movementFluencyLevel)/4)*4;
this.holder.setFixedSize(blockSize*this.gameManager.getGameMap().getMapWidth(),blockSize*this.gameManager.getGameMap().getMapHeight());
this.gameManager.getGameMap().loadBonusBitmaps(this.getBlockSize(),this.getResources(),this.getContext().getPackageName());
this.gameManager.setPacman(new Pacman("pacman","",this.movementFluencyLevel,this.gameManager.getGameMap().getPacmanSpawnPosition(),this.blockSize,this.getResources(),this.getContext().getPackageName()));
Ghost.loadCommonBitmaps(this.blockSize,this.getResources(),this.getContext().getPackageName());
}
//----------------------------------------------------------------------------------------------
//Getters and setters
public int getBlockSize() {
return blockSize;
}
public GameManager getGameManager() {
return gameManager;
}
public boolean isDrawing(){
return CAN_DRAW;
}
//----------------------------------------------------------------------------------------------
private synchronized void initGhost(){
if(!GHOST_INICIALIZED){
GHOST_INICIALIZED=true;
this.gameManager.initGhosts(this.blockSize,this.getResources(),this.getContext().getPackageName(),movementFluencyLevel);
}
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void run() {
long gameTime;
Canvas canvas;
while (!holder.getSurface().isValid()) {
}
this.initGhost();
this.setFocusable(true);
while (CAN_DRAW) {
gameTime=System.currentTimeMillis();
if(gameTime > frameTicker + (totalFrame * 15)){
canvas = holder.lockCanvas();
if(canvas!=null){
if(this.updateFrame(gameTime,canvas)){
try {
Thread.sleep(3000);
}catch (Exception e){}
}
holder.unlockCanvasAndPost(canvas);
if(this.gameManager.checkWinLevel()){
CAN_DRAW=false;
this.gameManager.cancelThreads();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
//animation
Log.i("Game","You win");
}else if(!this.gameManager.getPacman().hasLifes()){
//we lost
CAN_DRAW=false;
this.gameManager.cancelThreads();
//animation
Log.i("Game","You lose");
}
}
}
}
}
// Method to capture touchEvents
#Override
public boolean onTouchEvent(MotionEvent event) {
//To swipe
//https://www.youtube.com/watch?v=32rSs4tE-mc
this.gestureDetector.onTouchEvent(event);
super.onTouchEvent(event);
return true;
}
//Chequea si se deberia actualizar el frame actual basado en el
// tiempo que a transcurrido asi la animacion
//no se ve muy rapida y mala
#RequiresApi(api = Build.VERSION_CODES.N)
private boolean updateFrame(long gameTime, Canvas canvas) {
Pacman pacman;
Ghost[] ghosts;
boolean pacmanIsDeath;
pacman=this.gameManager.getPacman();
ghosts=this.gameManager.getGhosts();
// Si el tiempo suficiente a transcurrido, pasar al siguiente frame
frameTicker = gameTime;
canvas.drawColor(Color.BLACK);
this.gameManager.getGameMap().draw(canvas, Color.BLUE,this.blockSize,this.gameManager.getLevel());
this.gameManager.moveGhosts(canvas,this.blockSize);
pacmanIsDeath=pacman.move(this.gameManager,canvas);
if(!pacmanIsDeath){
// incrementar el frame
pacman.changeFrame();
for(int i=0; i<ghosts.length;i++){
ghosts[i].changeFrame();
}
currentArrowFrame++;
currentArrowFrame%=7;
}else{
pacman.setNextDirection(' ');
for(int i=0; i<ghosts.length;i++){
ghosts[i].respawn();
}
}
return pacmanIsDeath;
}
public int getScore(){
return this.getGameManager().getScore();
}
public void setSemaphores(Semaphore changeScoreSemaphore, Semaphore changeDirectionSemaphore){
this.gameManager.setChangeScoreSemaphore(changeScoreSemaphore);
this.gameManager.getPacman().setChangeDirectionSemaphore(changeDirectionSemaphore);
Log.i("Semaphore", "setted");
}
//----------------------------------------------------------------------------------------------
//Callback methods
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void surfaceCreated(SurfaceHolder holder) {
CAN_DRAW = true;
this.thread= new Thread(this);
this.thread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i("Surface","destroyed");
}
//----------------------------------------------------------------------------------------------
public void resume() {
CAN_DRAW = true;
thread = new Thread(this);
thread.start();
}
public void pause() {
CAN_DRAW = false;
while (true) {
try {
thread.join();
} catch (InterruptedException e) {
// retry
}
break;
}
this.thread=null;
}
#Override
public boolean onDown(MotionEvent e) {
return false;
}
#Override
public void onShowPress(MotionEvent e) {
}
#Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
#Override
public void onLongPress(MotionEvent e) {
}
#Override
public boolean onFling(MotionEvent downEvent, MotionEvent moveEvent, float velocityX, float velocityY) {
//To swipe
//https://www.youtube.com/watch?v=32rSs4tE-mc
boolean result;
float diffX, diffY;
Pacman pacman;
Log.i("Fling", "detected");
result=false;
diffX = moveEvent.getX() - downEvent.getX();
diffY = moveEvent.getY() - downEvent.getY();
pacman=this.gameManager.getPacman();
if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY){
if (Math.abs(diffX) > Math.abs(diffY)) {
if (diffX > 0) {
//right
pacman.setNextDirection('r');
} else {
//left
pacman.setNextDirection('l');
}
}else{
if (diffY > 0) {
//down
pacman.setNextDirection('d');
} else {
//up
pacman.setNextDirection('u');
}
}
result=true;
}
return result;
}
}
GameManager
public class GameManager {
private static final int TOTAL_LEVELS=256;
private static int SCORE=0;
private GameMap gameMap;
private int level,bonusResetTime;//,score;
private CountDownScareGhosts scareCountDown;
private Pacman pacman;
private Ghost[] ghosts;
private boolean fruitHasBeenInTheLevel;
private static Semaphore CHANGE_SCORE_MUTEX;
public GameManager(){
this.fruitHasBeenInTheLevel=false;
//this.score=0;
this.gameMap=new GameMap();
this.gameMap.loadMap1();
this.level=1;
this.ghosts=new Ghost[4];
this.bonusResetTime = 5000;
this.scareCountDown=null;
}
public void setChangeScoreSemaphore(Semaphore changeScoreSemaphore) {
CHANGE_SCORE_MUTEX = changeScoreSemaphore;
//if(this.changeScoreSemaphore==null){
// Log.i("Change Score Semaphore","I'm null");
//}else{
// Log.i("Change Score Semaphore","I'm not null");
//}
}
public void addScore(int s){
//this.score+=s;
SCORE+=s;
CHANGE_SCORE_MUTEX.release();
/*if(this.changeScoreSemaphore==null){
Log.i("Change Score Semaphore","I'm null");
}else{
Log.i("Change Score Semaphore","I'm not null");
}*/
//this.changeScoreSemaphore.release();
}
public int getScore() {
return SCORE;
//return this.score;
}
public int getLevel() {
return this.level;
}
public GameMap getGameMap() {
return this.gameMap;
}
public Ghost[] getGhosts(){
return this.ghosts;
}
public Pacman getPacman(){
return this.pacman;
}
public void setPacman(Pacman pacman){
this.pacman=pacman;
}
public void eatPallet(int posXMap, int posYMap){
SCORE+=10;
CHANGE_SCORE_MUTEX.release();
//this.score+=10;
Log.i("Score GM", ""+SCORE);
//Log.i("Score GM", ""+this.score);
this.gameMap.getMap()[posYMap][posXMap]=0;
//this.changeScoreSemaphore.release();
//if(this.changeScoreSemaphore==null){
// Log.i("Change Score Semaphore","I'm null");
//}else{
// Log.i("Change Score Semaphore","I'm not null");
//}
}
public void eatBonus(int posXMap,int posYMap){
SCORE+=500;
CHANGE_SCORE_MUTEX.release();
//this.score+=500;
//Log.i("Score", Double.toString(this.score).substring(0,Double.toString(this.score).indexOf('.')));
this.gameMap.getMap()[posYMap][posXMap]=0;
//this.changeScoreSemaphore.release();
}
public void eatSuperPallet(int posXMap,int posYMap){
SCORE+=50;
CHANGE_SCORE_MUTEX.release();
//this.score+=50;
this.gameMap.getMap()[posYMap][posXMap]=0;
//Si hay un timer andando lo cancelo y ejecuto otro
if (this.scareCountDown != null){
this.scareCountDown.cancel();
}
this.scareCountDown = new CountDownScareGhosts(this.ghosts,this.gameMap.getMap());
this.scareCountDown.start();
//this.changeScoreSemaphore.release();
}
public void tryCreateBonus(){
//only if pacman has eaten 20 pallets we should allow the fruit appear
if(!this.fruitHasBeenInTheLevel && this.gameMap.getEatenPallets()>=20){
//to not allow the fruit be again in the level
this.fruitHasBeenInTheLevel=true;
new CountdownBonusThread(this.gameMap,this.bonusResetTime).start();
}
}
#RequiresApi(api = Build.VERSION_CODES.N)
public void moveGhosts(Canvas canvas,int blocksize) {
for (int i = 0; i < ghosts.length; i++) {
ghosts[i].move(this.gameMap.getMap(),this.pacman);
ghosts[i].draw(canvas);
}
}
public synchronized void initGhosts(int blocksize, Resources res, String packageName,int movementFluency) {
int[][]spawnPositions,cornersPositions, notUpDownPositions,defaultTargets;
defaultTargets=this.gameMap.getDefaultGhostTarget();
notUpDownPositions=this.gameMap.getNotUpDownDecisionPositions();
spawnPositions=this.gameMap.getGhostsSpawnPositions();
cornersPositions=this.gameMap.getGhostsScatterTarget();
//start position
// 5 blinky spawn [13, 11]
// 6 pinky spawn [15,11]
// 7 inky spawn [13,16]
// 8 clyde spawn [15,16]
this.ghosts=new Ghost[4];
ghosts[0] = new Ghost("blinky",spawnPositions[0], cornersPositions[0] ,new BehaviorChaseAgressive(notUpDownPositions,movementFluency,defaultTargets[0]),movementFluency,notUpDownPositions,'l',defaultTargets[0],blocksize,res,packageName);
ghosts[1] = new Ghost("pinky",spawnPositions[1],cornersPositions[1],new BehaviorChaseAmbush(notUpDownPositions,movementFluency,defaultTargets[1]),movementFluency,notUpDownPositions,'r',defaultTargets[1],blocksize,res,packageName);
ghosts[2] = new Ghost("inky",spawnPositions[2],cornersPositions[2],new BehaviorChasePatrol(notUpDownPositions,this.ghosts[0],movementFluency,defaultTargets[0]),movementFluency,notUpDownPositions,'l',defaultTargets[0],blocksize,res,packageName);
ghosts[3] = new Ghost("clyde",spawnPositions[3],cornersPositions[3],new BehaviorChaseRandom(notUpDownPositions,cornersPositions[3],movementFluency,defaultTargets[1]),movementFluency,notUpDownPositions,'r',defaultTargets[1],blocksize,res,packageName);
try{
Thread.sleep(200);
}catch(Exception e){}
for (int i=0;i<ghosts.length;i++){
ghosts[i].onLevelStart(1);
}
}
public boolean checkWinLevel() {
//player win the level if he has eaten all the pallet
return this.gameMap.countPallets()==0;
}
public void onResume(){
for (int i=0 ; i<this.ghosts.length;i++){
this.ghosts[i].cancelBehavoirThread();
}
if(this.scareCountDown!=null && !this.scareCountDown.hasEnded()){
this.scareCountDown.start();
}
}
public void onPause(){
for (int i=0 ; i<this.ghosts.length;i++){
this.ghosts[i].cancelBehavoirThread();
}
if(this.scareCountDown!=null && !this.scareCountDown.hasEnded()){
this.scareCountDown=this.scareCountDown.onPause();
}
}
public void cancelThreads(){
for (int i=0 ; i<this.ghosts.length;i++){
this.ghosts[i].cancelBehavoirThread();
}
if(this.scareCountDown!=null){
this.scareCountDown.cancel();
}
}
}
I want to to add the media controller on VLC player android integration but i didn't find any option to do that i am sharing the code -
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.otherformat);
load = (ProgressBar) this.findViewById(R.id.load);
intent = getIntent();
load.setVisibility(View.VISIBLE);
handler = new Handler();
mFilePath ="http://mm2.pcslab.com/mm/7h800.mp4";
Log.e(TAG, "Playing: " + mFilePath);
mSurface = (SurfaceView) findViewById(R.id.surface);
holder = mSurface.getHolder();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setSize(mVideoWidth, mVideoHeight);
}
#Override
protected void onResume() {
super.onResume();
createPlayer(mFilePath);
}
#Override
protected void onPause() {
super.onPause();
releasePlayer();
}
#Override
protected void onDestroy() {
super.onDestroy();
releasePlayer();
}
/**
* Used to set size for SurfaceView
*
* #param width
* #param height
*/
private void setSize(int width, int height) {
mVideoWidth = width;
mVideoHeight = height;
if (mVideoWidth * mVideoHeight <= 1)
return;
if (holder == null || mSurface == null)
return;
int w = getWindow().getDecorView().getWidth();
int h = getWindow().getDecorView().getHeight();
boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
if (w > h && isPortrait || w < h && !isPortrait) {
int i = w;
w = h;
h = i;
}
float videoAR = (float) mVideoWidth / (float) mVideoHeight;
float screenAR = (float) w / (float) h;
if (screenAR < videoAR)
h = (int) (w / videoAR);
else
w = (int) (h * videoAR);
holder.setFixedSize(mVideoWidth, mVideoHeight);
ViewGroup.LayoutParams lp = mSurface.getLayoutParams();
lp.width = w;
lp.height = h;
mSurface.setLayoutParams(lp);
mSurface.invalidate();
}
/**
* Creates MediaPlayer and plays video
*
* #param media
*/
private void createPlayer(String media) {
releasePlayer();
try {
if (media.length() > 0) {
Toast toast = Toast.makeText(this, media, Toast.LENGTH_LONG);
toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0,
0);
//toast.show();
}
// Create LibVLC
// TODO: make this more robust, and sync with audio demo
ArrayList<String> options = new ArrayList<String>();
//options.add("--subsdec-encoding <encoding>");
options.add("--aout=opensles");
options.add("--audio-time-stretch"); // time stretching
options.add("-vvv"); // verbosity
libvlc = new LibVLC(this, options);
holder.setKeepScreenOn(true);
// Creating media player
mMediaPlayer = new MediaPlayer(libvlc);
mMediaPlayer.setEventListener(mPlayerListener);
mMediaPlayer.setVideoTrackEnabled(true);
// Seting up video output
final IVLCVout vout = mMediaPlayer.getVLCVout();
vout.setVideoView(mSurface);
//vout.setSubtitlesView(mSurfaceSubtitles);
vout.addCallback(this);
vout.attachViews();
Media m = new Media(libvlc, Uri.parse(media));
mMediaPlayer.setMedia(m);
mMediaPlayer.play();
////////////////////////////////////////////////
/* //mController = new MediaController(this);
mController = (MediaController)findViewById(R.id.mediaController);
mController.setVisibility(View.VISIBLE);
mController.setAnchorView(mSurface);
mController.show(0);*/
/*mController = new MediaController(this);
mController.setAnchorView(mSurface);
handler.post(new Runnable() {
public void run() {
mController.show();
}
});*/
} catch (Exception e) {
Log.e("Err", e.getMessage()+"");
Toast.makeText(this, "Error in creating player!"+e.getMessage(), Toast
.LENGTH_LONG).show();
}
}
private void releasePlayer() {
if (libvlc == null)
return;
mMediaPlayer.stop();
final IVLCVout vout = mMediaPlayer.getVLCVout();
vout.removeCallback(this);
vout.detachViews();
holder = null;
libvlc.release();
libvlc = null;
mVideoWidth = 0;
mVideoHeight = 0;
}
/**
* Registering callbacks
*/
private MediaPlayer.EventListener mPlayerListener = new MyPlayerListener(this);
#Override
public void onNewLayout(IVLCVout vout, int width, int height, int visibleWidth, int visibleHeight, int sarNum, int sarDen) {
if (width * height == 0)
return;
// store video size
mVideoWidth = width;
mVideoHeight = height;
setSize(mVideoWidth, mVideoHeight);
}
#Override
public void onSurfacesCreated(IVLCVout vout) {
}
#Override
public void onSurfacesDestroyed(IVLCVout vout) {
}
#Override
public void onHardwareAccelerationError(IVLCVout vlcVout) {
Log.e(TAG, "Error with hardware acceleration");
this.releasePlayer();
Toast.makeText(this, "Error with hardware acceleration", Toast.LENGTH_LONG).show();
}
private static class MyPlayerListener implements MediaPlayer.EventListener {
private WeakReference<OtherFormat> mOwner;
public MyPlayerListener(OtherFormat owner) {
mOwner = new WeakReference<OtherFormat>(owner);
}
#Override
public void onEvent(MediaPlayer.Event event) {
OtherFormat player = mOwner.get();
switch (event.type) {
case MediaPlayer.Event.EndReached:
Log.d(TAG, "MediaPlayerEndReached");
player.releasePlayer();
break;
case MediaPlayer.Event.Playing:
load.setVisibility(View.GONE);
break;
case MediaPlayer.Event.Paused:
case MediaPlayer.Event.Buffering:
float percent = event.getBuffering(); /* from 0.0f to 100f */
Log.e("Percent><><",""+percent);
break;
case MediaPlayer.Event.Stopped:
default:
break;
}
}
}}
XML for this activity -
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<SurfaceView
android:id="#+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" />
<ProgressBar
android:id="#+id/load"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="visible"
android:layout_gravity="center"
/>
<MediaController
android:id="#+id/mediaController"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
</MediaController>
</FrameLayout>
By this code mediacontrollers not showing please help me how to show media controllers for pause, play and seekbar for video position in surfaceview of vlc media player.
I had the same issue and have found a solution.
Sure, it's too late for answer, but maybe I will save some time to someone.
To add default media control you need to implement it in following way
remove MediaController from layout and add some container for media control to to your activity (it will be added programmatically).
<FrameLayout
android:id="#+id/video_surface_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:foregroundGravity="clip_horizontal|clip_vertical"
tools:ignore="true">
<SurfaceView
android:id="#+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" />
</FrameLayout>
add controller init to onStart activity or to onCreate
import android.widget.MediaController;
private MediaController controller;
#Override
protected void onStart() {
super.onStart();
....
controller = new MediaController(this);
controller.setMediaPlayer(findViewByid(R.id.video_surface_frame));
controller.setAnchorView(mVideoSurfaceFrame);
mVideoSurfaceFrame.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
controller.show(10000);
}
});
}
to define playerInterface, you need to implement the MediaController.MediaPlayerControl interface like this
private MediaController.MediaPlayerControl playerInterface = new MediaController.MediaPlayerControl() {
public int getBufferPercentage() {
return 0;
}
public int getCurrentPosition() {
float pos = mLibVlc.getPosition();
return (int)(pos * getDuration());
}
public int getDuration() {
return (int)mLibVlc.getLength();
}
public boolean isPlaying() {
return mLibVlc.isPlaying();
}
public void pause() {
mLibVlc.pause();
}
public void seekTo(int pos) {
mLibVlc.setPosition((float)pos / getDuration());
}
public void start() {
mLibVlc.play();
}
public boolean canPause() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canSeekForward() {
return true;
}
#Override
public int getAudioSessionId() {
return 0;
}
};
launch your app and tap on video. You will see default media control and it will hide in 10 sec
Good luck!
Link to VideoLan sample on github:
https://code.videolan.org/videolan/vlc-android/blob/f3db2e4a33bf96c03056874322fb5b9304f92259/vlc-android/src/vlc/android/VLC.java
public class Show_Array extends AppCompatActivity implements IVLCVout.Callback {
private TextView container_extension;
private String stream_typee,stream_idd,container_extensionn ;
private String SAMPLE_URL = "";
public int mHeight;
public int mWidth;
private SurfaceView mVideoSurface = null;
private FrameLayout sdk;
private IVLCVout vlcVout;
private LibVLC mLibVlc = null;
private MediaPlayer mMediaPlayer = null;
private int flag = 0;
private ImageButton Resize;
private Media media;
private ArrayList<String> args;
private SurfaceHolder mSurfaceHolderVideo;
private MediaController controller;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.show__array);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//Referances
Resize = findViewById(R.id.Resize);
mVideoSurface = findViewById(R.id.video_surface);
stream_typee = getIntent().getExtras().getString("stream_type");
stream_idd = getIntent().getExtras().getString("stream_id");
container_extensionn = getIntent().getExtras().getString("container_extension");
args = new ArrayList<>();
args.add("-vvv");
mLibVlc = new LibVLC(this, args);
mMediaPlayer = new MediaPlayer(mLibVlc);
vlcVout = mMediaPlayer.getVLCVout();
sdk = findViewById(R.id.sdk);
Resize_video();
setup_url();
controller = new MediaController(this);
controller.setMediaPlayer(playerInterface);
controller.setAnchorView(mVideoSurface);
mVideoSurface.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
controller.show(10000);
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
mMediaPlayer.release();
mLibVlc.release();
}
void Resize_video()
{
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
mHeight = displayMetrics.heightPixels;
mWidth = displayMetrics.widthPixels;
Resize.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
flag+=1;
int width = 1000;
int height = 560;
if(flag%2!=0) {
LinearLayout.LayoutParams myImageLayout = new LinearLayout.LayoutParams(width, height);
myImageLayout.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
sdk.setLayoutParams(myImageLayout);
vlcVout.setWindowSize(width,height);
}
else
{
LinearLayout.LayoutParams myImageLayout = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
myImageLayout.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
sdk.setLayoutParams(myImageLayout);
vlcVout.setWindowSize(mWidth,mHeight);
}
}
});
}
void setup_url()
{
//TextView
container_extension = findViewById(R.id.URL);
if (stream_typee.equals("live"))
{
SAMPLE_URL = "http://uautv.ru:2095/"+stream_typee+"/webserver/6tE#BzW73#sX/"+stream_idd+".ts";
container_extension.setText( SAMPLE_URL);
}else
{
SAMPLE_URL = "http://uautv.ru:2095/"+stream_typee+"/webserver/6tE#BzW73#sX/"+stream_idd+"."+container_extensionn;
container_extension.setText( SAMPLE_URL);
}
}
#Override
protected void onStart() {
super.onStart();
vlcVout.setWindowSize(mWidth,mHeight);
vlcVout.setVideoView(mVideoSurface);
vlcVout.attachViews();
mMediaPlayer.getVLCVout().addCallback(this);
if(!SAMPLE_URL.isEmpty()) {
media = new Media(mLibVlc, Uri.parse(SAMPLE_URL));
mMediaPlayer.setMedia(media);
media.release();
mMediaPlayer.play();
}else
{
Toast.makeText(getApplicationContext(),"URL EMPTY",Toast.LENGTH_LONG).show();
}
}
#Override
protected void onStop() {
super.onStop();
mMediaPlayer.stop();
mMediaPlayer.getVLCVout().detachViews();
mMediaPlayer.getVLCVout().removeCallback(this);
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
#Override
public void onNewLayout(IVLCVout vlcVout, int width, int height, int visibleWidth, int visibleHeight, int sarNum, int sarDen)
{ }
#Override
public void onSurfacesCreated(IVLCVout vlcVout) {
}
#Override
public void onSurfacesDestroyed(IVLCVout vlcVout) {
}
private MediaController.MediaPlayerControl playerInterface = new MediaController.MediaPlayerControl() {
public int getBufferPercentage() {
return 0;
}
public int getCurrentPosition() {
float pos = mMediaPlayer.getPosition();
return (int)(pos * getDuration());
}
public int getDuration() {
return (int)mMediaPlayer.getLength();
}
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
public void pause() {
mMediaPlayer.pause();
}
public void seekTo(int pos) {
mMediaPlayer.setPosition((float)pos / getDuration());
}
public void start() {
mMediaPlayer.play();
}
public boolean canPause() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canSeekForward() {
return true;
}
#Override
public int getAudioSessionId() {
return 0;
}
};
}
I am using the WallpaperService class to set a live wallpaper on the device.
I want to implement security on the system screen (to prevent screenshot or recording) where the 'Set Wallpaper' button shows up by the android system.
So far, I have found one method of SurfaceView class - surfaceview.setSecure(boolean value)
But, I am not able to get the instance of the SurfaceView inside my class.
Please suggest some workaround to get the instance of this class.
My Code-
public class LiveWallpaperService extends WallpaperService {
private int mDeviceWidth, mDeviceHeight;
private int mAnimationWidth, mAnimationHeight;
#Override
public Engine onCreateEngine() {
Movie movie = null;
// Some Code here
return new GIFWallpaperEngine(movie);
}
private class GIFWallpaperEngine extends Engine {
private final int frameDuration = 24;
private SurfaceHolder holder;
private final Movie movie;
private boolean visible;
private final Handler handler;
private final Runnable drawGIF = new Runnable() {
public void run() {
draw();
}
};
public SurfaceView getSurfaceView(){
// How to find the SurfaceView object here?
}
GIFWallpaperEngine(Movie movie) {
this.movie = movie;
handler = new Handler();
}
#Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
this.holder = surfaceHolder;
}
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
mDeviceWidth = width;
mDeviceHeight = height;
}
private void draw() {
if (movie != null) {
try {
if (visible) {
Canvas canvas = holder.lockCanvas();
canvas.save();
final float scaleFactorX = mDeviceWidth / (mAnimationWidth * 1.f); //608 is image width
final float scaleFactorY = mDeviceHeight / (mAnimationHeight * 1.f);
// Adjust size and position to fit animation on the screen
canvas.scale(scaleFactorX, scaleFactorY); // w,h Size of displaying Item
movie.draw(canvas, 0, 0); // position on x,y
canvas.restore();
holder.unlockCanvasAndPost(canvas);
movie.setTime((int) (System.currentTimeMillis() % movie.duration()));
handler.removeCallbacks(drawGIF);
handler.postDelayed(drawGIF, frameDuration);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
#Override
public void onVisibilityChanged(boolean visible) {
this.visible = visible;
if (visible) {
handler.post(drawGIF);
} else {
handler.removeCallbacks(drawGIF);
}
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(drawGIF);
}
}
}
I am new to Android development and currently I am implementing Live wallpaper application.So, My question is How I can change live wallpaper when new live wallpaper is selected from the application.currently I am setting only one live wallpaper from my application but issue is that when I am selecting wallpaper from my application to set as wallpaper it is not change and display previously selected wallpaper.And when i am restarting my device then it will display.I am using Glide library to display Gif image.
Here this my WallpaperService class
public class GifPaperService extends WallpaperService {
static final String TAG = "gifService";
static final Handler gifHandler = new Handler();
int position;
boolean visible;
ImageAdapter img = new ImageAdapter();
Integer[] mThumb = img.mThumbIds;
#Override
public void onCreate() {
super.onCreate();
Log.v("Helllo", "...");
}
#Override
public Engine onCreateEngine() {
try {
return new GifEngine();
} catch (IOException e) {
Log.w(TAG, "Error creating engine", e);
stopSelf();
return null;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v("Hello..", ".....");
return super.onStartCommand(intent, flags, startId);
}
class GifEngine extends Engine {
private final Movie gif;
private final int duration;
private final Runnable runnable;
float scaleX;
float scaleY;
int when;
long start;
GifEngine() throws IOException {
MyPreferenceActivity myPref = new MyPreferenceActivity(getApplicationContext());
Log.i("Imageis... ", "Position.." + myPref.getGifImage());
position = myPref.getGifImage();
InputStream is = getResources().openRawResource(mThumb[position]);
Log.i("Imageposition...", "...." + mThumb[position]);
if (is == null) {
throw new IOException("Unable to open whoa.gif");
}
try {
gif = Movie.decodeStream(is);
duration = gif.duration();
} finally {
is.close();
}
when = -1;
runnable = new Runnable() {
#Override
public void run() {
animateGif();
}
};
}
#Override
public void onDestroy() {
super.onDestroy();
gifHandler.removeCallbacks(runnable);
}
#Override
public void onVisibilityChanged(boolean visible) {
super.onVisibilityChanged(visible);
if (visible) {
animateGif();
} else {
gifHandler.removeCallbacks(runnable);
}
}
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
scaleX = width / (1f * gif.width());
scaleY = height / (1f * gif.height());
animateGif();
}
#Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xOffsetStep, float yOffsetStep,
int xPixelOffset, int yPixelOffset) {
super.onOffsetsChanged(
xOffset, yOffset,
xOffsetStep, yOffsetStep,
xPixelOffset, yPixelOffset);
animateGif();
}
void animateGif() {
tick();
SurfaceHolder surfaceHolder = getSurfaceHolder();
Canvas canvas = null;
try {
canvas = surfaceHolder.lockCanvas();
if (canvas != null) {
gifCanvas(canvas);
}
} finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
gifHandler.removeCallbacks(runnable);
if (isVisible()) {
gifHandler.postDelayed(runnable, 1000L / 25L);
}
}
void tick() {
if (when == -1L) {
when = 0;
start = SystemClock.uptimeMillis();
} else {
long diff = SystemClock.uptimeMillis() - start;
when = (int) (diff % duration);
}
}
void gifCanvas(Canvas canvas) {
canvas.save();
canvas.scale(scaleX, scaleY);
gif.setTime(when);
gif.draw(canvas, 0, 0);
canvas.restore();
}
#Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
stopSelf();
gifHandler.removeCallbacks(runnable);
}
}
}
Activity class for setting wallpaper
setWallpaper.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT > 15) {
Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, new ComponentName(mContext, GifPaperService.class));
startActivity(intent);
}
}
});
ImageAdapter:
public class ImageAdapter extends BaseAdapter {
static WallpaperInfo info;
private Context mContext;
public ImageAdapter() {
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return mThumbIds[position];
}
public long getItemId(int position) {
return 0;
}
public ImageAdapter(Context c) {
mContext = c;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null){
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(3, 3, 3, 3);
imageView.setMaxHeight(300);
imageView.setMaxWidth(300);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyPreferenceActivity myPref = new MyPreferenceActivity(mContext);
myPref.setGifImage(position);
Intent intent = new Intent(mContext, FullScreenImage.class);
intent.putExtra("imageID", mThumbIds[position]);
/*intent.putExtra(EXTRA_LIVE_WALLPAPER_INTENT, intent);
intent.putExtra(EXTRA_LIVE_WALLPAPER_SETTINGS, info.getSettingsActivity());
intent.putExtra(EXTRA_LIVE_WALLPAPER_PACKAGE, info.getPackageName());*/
mContext.startActivity(intent);
}
});
Animation anim = AnimationUtils.loadAnimation(mContext.getApplicationContext(), R.anim.fly);
imageView.setAnimation(anim);
anim.start();
}
else{
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
public Integer[] mThumbIds = {
R.drawable.gpp1, R.drawable.gpp2,
R.drawable.gpp3,R.drawable.gpp4,
R.drawable.gpp5,R.drawable.gpp6,
R.drawable.gpp7,R.mipmap.h8,
R.mipmap.h9,R.mipmap.h10,
R.mipmap.h11,R.drawable.gp3,
R.drawable.gp2,R.drawable.gp,
R.drawable.onehalloween
};
}
If anyone know what is the problem.Tell me.
Thank in advance
For destroying previous wallpaper and setting new wallpaper,You have to Clear previous wallpaper like this,
In Your setWallpaper button click event use this code,
setWallpaper.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT > 16) {
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.clear();
} catch (IOException e) {
e.printStackTrace();
}
Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, new ComponentName(mContext, GifPaperService.class));
Log.i("Intent....", "...." + intent);
startActivity(intent);
}
}
});
This is works for me...
In my android app i have activity containing a surfaceview. I want to start the surfaceview thread when the surfaceview/activity is visible to user. I have tried starting the thread in OnSurfaceCreated. That works but on some mobiles(samsung) The activity takes many seconds to become visible.The screen turns black when i resume activity. So i googled and found that when a view becomes visible onFocusChanged is called. I tried implementing OnFocusChanged in surfaceview but it is never called. below is my surfaceview class.
public class ImageSurface extends SurfaceView implements SurfaceHolder.Callback {
private DrawThread drawThread;
private SurfaceHolder sHolder;
private ImageHolder imageHolder;
Bitmap mybit;
Bitmap orgiBitmap;// ;)
int message;
Context context;
private String valMagField;
public ImageSurface(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
SurfaceHolder holder = getHolder();
holder.addCallback(this);
setFocusable(true);
clearFocus();
drawThread = new DrawThread(context);
}
public void setImageHolder(ImageHolder imageHolder){
this.imageHolder = imageHolder;
}
public void setBitmap(String filePath){
}
public void resume(){
drawThread.resumeThread();
}
#Override
public void onFocusChanged(boolean focus,int direction,Rect rect){
super.onFocusChanged(focus, direction, rect);
Log.d("in focus changed","onfocuschanged"+System.currentTimeMillis());
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
drawThread.setSurfaceSize(width, height);
resume();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
long startTime, stopTime;
startTime = System.currentTimeMillis();
sHolder = holder;
drawThread.setRunning(true);
if(drawThread.getState()==Thread.State.NEW){
drawThread.start();
}
if(drawThread.getState()==Thread.State.TERMINATED){
drawThread = new DrawThread(context);
drawThread.setRunning(true);
drawThread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
drawThread.pauseThread();
}
class DrawThread extends Thread{
int value=0;
private Boolean drun;
int valSize =30;
Context context;
private int sHeight , sWidth;
int lastmessage;
boolean threadPaused= false;
public DrawThread(Context context){
drun = false;
this.context = context;
}
public void pauseThread(){
synchronized(this){
threadPaused = true;
this.notify();
}
}
public void resumeThread(){
synchronized(this){
threadPaused = false;
this.notify();
}
}
public void setRunning(Boolean run){
drun = run;
}
public boolean isRunning(){
return drun;
}
public void setSurfaceSize(int width , int height){
sWidth = width;
sHeight = height;
}
#Override
public void run(){
while(drun){
Canvas c = null;
//Log.d("yes","thread is running");
try{
synchronized(this){
if(threadPaused)
try {
this.wait();
} catch (InterruptedException e) {
Log.d("in wait of surface view thread","error"+e.toString());
}
}
c = sHolder.lockCanvas(null);
synchronized(sHolder){
updateCanvas(c);
}
}finally {
if(c!=null){
sHolder.unlockCanvasAndPost(c);
}
}
}
}
private void updateCanvas(Canvas canvas){
try{
if(imageHolder.dispBit!= null){
int x=(sWidth-imageHolder.dispBit.getWidth())/2,y=(sHeight-imageHolder.dispBit.getHeight())/2;
imageHolder.applyEffects();
if(canvas!=null)
canvas.drawBitmap(imageHolder.dispBit, x,y,null);
}
else if(imageHolder!=null)
imageHolder.setDisplaySize(sWidth, sHeight);
}catch(Exception e){
e.printStackTrace();
}
}
}
}