I have been following this tutorial:
Page.
I have been getting a lot of errors.
Can you please help me by sharing the code on GitHub?
You can also post your answer on Stack Overflow.
This is my Gif
I have used this in my java file:
package com.example.background;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.SurfaceHolder;
import java.io.IOException;
public class GIFWallpaperEngine extends WallpaperService{
private final int frameDuration = 20;
private SurfaceHolder holder;
private Movie movie;
private boolean visible;
private Handler handler;
public GIFWallpaperEngine(Movie movie) {
this.movie = movie;
handler = new Handler();
}
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
this.holder = surfaceHolder;
}
private Runnable drawGIF = new Runnable() {
public void run() {
draw();
}
};
private void draw() {
if (visible) {
Canvas canvas = holder.lockCanvas();
canvas.save();
// Adjust size and position so that
// the image looks good on your screen
canvas.scale(3f, 3f);
movie.draw(canvas, -100, 0);
canvas.restore();
holder.unlockCanvasAndPost(canvas);
movie.setTime((int) (System.currentTimeMillis() % movie.duration()));
handler.removeCallbacks(drawGIF);
handler.postDelayed(drawGIF, frameDuration);
}
}
#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);
}
#Override
public Engine onCreateEngine() {
try {
Movie movie = Movie.decodeStream(
getResources().getAssets().open("wolverine.gif"));
return new Engine(movie);
}catch(IOException e){
Log.d("GIF", "Could not load asset");
return null;
}
}
}
Is there anything wrong because the override is showing an error.
It's this: Override is not required because method whatever super does.
Well, this is the solution for me GitLink
Solution to your problem when you try to run app, first click in app and in Edit Configurations
Now, in Launch Options select NOTHING:
Last step, press OK:
Finally, you can run your app. Try it!
Related
I am new to Agora.io and I am creating an android app for 1 to 1 video calling. Everything is working fine in my app - I can join/leave the channel and even see my own local image through my camera. However, in the call, only the audio is being transmitted and video is not being transmitted.
When I debug the app, I can see that the event 'onFirstRemoteVideoFrame' is not being triggered. I tried changing it to 'onFirstRemoteVideoDecoded'(which I saw in many tutorials but android studio says the method is depreciated) but it is still not working.
Also, please note that when I add the line '-keep class io.agora.**{;}' in my proguard-rules.pro file, it says that it can't find the class. So instead I am using '-keep class io.agora.{*;}'.
Below is the java code for my activity. I am using agora 3.1.3.
package com.guideu.helloagora;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import io.agora.rtc.IRtcEngineEventHandler;
import io.agora.rtc.RtcEngine;
import io.agora.rtc.video.VideoCanvas;
import io.agora.rtc.video.VideoEncoderConfiguration;
public class MainActivity extends AppCompatActivity {
private static final String TAG=MainActivity.class.getSimpleName();
private static final int PERMISSION_REQ_ID=22;
private static final String[] REQUESTED_PERMISSIONS={
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private RtcEngine mRtcEngine; // Agora engine reference
private FrameLayout mLocalContainer;
private RelativeLayout mRemoteContainer;
private SurfaceView mLocalView;
private SurfaceView mRemoteView;
private ImageView mCallBtn;
private ImageView mMuteBtn;
private ImageView mSwitchCameraBtn;
private boolean mCallEnd;
private boolean mMuted;
//Agora engine event handler
private final IRtcEngineEventHandler mRTCHandler=new IRtcEngineEventHandler() {
#Override
public void onJoinChannelSuccess(String channel, final int uid, int elapsed) {
super.onJoinChannelSuccess(channel, uid, elapsed);
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.i("agora","Join channel success, uid: " + (uid & 0xFFFFFFFFL));
}
});
}
#Override
public void onUserOffline(final int uid, int reason) {
super.onUserOffline(uid, reason);
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.i("agora","User offline, uid: " + (uid & 0xFFFFFFFFL));
removeRemoteView();
}
});
}
#Override
public void onFirstRemoteVideoFrame(final int uid, int width, int height, int elapsed) {
super.onFirstRemoteVideoFrame(uid, width, height, elapsed);
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.i("agora","First remote video decoded, uid: " + (uid & 0xFFFFFFFFL));
setupRemoteVideo(uid);
}
});
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
if(checkSelfPermission(REQUESTED_PERMISSIONS[0],PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[1],PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[2],PERMISSION_REQ_ID)){
//init engine
initEngineAndJoinChannel();
}
}
#Override
protected void onDestroy(){
super.onDestroy();
if(!mCallEnd){
leaveChannel();
}
RtcEngine.destroy();
}
private void initUI(){
mLocalContainer=findViewById(R.id.local_video_view_container);
mRemoteContainer=findViewById(R.id.remote_video_view_container);
mCallBtn=findViewById(R.id.btn_call);
mMuteBtn=findViewById(R.id.btn_mute);
mSwitchCameraBtn=findViewById(R.id.btn_switch_camera);
}
private void initEngineAndJoinChannel(){
//initialize engine
initializeEngine();
//setup video config
setupVideoConfig();
//setup local video
setupLocalVideo();
//join channel
joinChannel();
}
private void initializeEngine(){
try {
mRtcEngine = RtcEngine.create(getBaseContext(), getString(R.string.agora_app_id), mRTCHandler);
}
catch (Exception e){
Log.e(TAG,Log.getStackTraceString(e));
throw new RuntimeException("Need to check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
}
}
private void setupVideoConfig(){
mRtcEngine.enableVideo();
mRtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
VideoEncoderConfiguration.VD_640x360,
VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15,
VideoEncoderConfiguration.STANDARD_BITRATE,
VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT
));
}
private void setupLocalVideo(){
mRtcEngine.enableVideo();
mLocalView=RtcEngine.CreateRendererView(getBaseContext());
mLocalView.setZOrderMediaOverlay(true);
mLocalContainer.addView(mLocalView);
VideoCanvas localVideoCanvas=new VideoCanvas(mLocalView,VideoCanvas.RENDER_MODE_HIDDEN,0);
mRtcEngine.setupLocalVideo(localVideoCanvas);
}
private void setupRemoteVideo(int uid){
/*int count=mRemoteContainer.getChildCount();
View view=null;
for(int i=0;i<count;i++){
View v=mRemoteContainer.getChildAt(i);
if(v.getTag() instanceof Integer && ((int) v.getTag())==uid){
view=v;
}
}
if(view!=null){
return;
}*/
mRemoteView=RtcEngine.CreateRendererView(getBaseContext());
mRemoteContainer.addView(mRemoteView);
mRtcEngine.setupRemoteVideo(new VideoCanvas(mRemoteView,VideoCanvas.RENDER_MODE_HIDDEN,uid));
mRemoteView.setTag(uid);
}
private void removeRemoteView(){
if(mRemoteView!=null){
mRemoteContainer.removeView(mRemoteView);
}
mRemoteView=null;
}
private void joinChannel(){
String token=getString(R.string.agora_access_token);
if(TextUtils.isEmpty(token)){
token=null;
}
mRtcEngine.joinChannel(token,"HelloAgora","",0);
}
private void leaveChannel(){
mRtcEngine.leaveChannel();
}
public void onLocalAudioMuteClicked(View view){
mMuted=!mMuted;
mRtcEngine.muteLocalAudioStream(mMuted);
int res=mMuted?R.drawable.btn_mutecall:R.drawable.btn_unmute;
mMuteBtn.setImageResource(res);
}
public void onSwitchCameraClicked(View view){
mRtcEngine.switchCamera();
}
public void onCallClicked(View view){
if(mCallEnd){
startCall();
mCallEnd=false;
mCallBtn.setImageResource(R.drawable.btn_endcall);
}
else{
endCall();
mCallEnd=true;
mCallBtn.setImageResource(R.drawable.btn_startcall);
}
showButtons(!mCallEnd);
}
private void startCall(){
setupLocalVideo();
joinChannel();
}
private void endCall(){
removeLocalVideo();
removeRemoteView();
leaveChannel();
}
private void removeLocalVideo(){
if(mLocalView!=null){
mLocalContainer.removeView(mLocalView);
}
mLocalView=null;
}
private void showButtons(boolean show){
int visibility=show?View.VISIBLE:View.GONE;
mMuteBtn.setVisibility(visibility);
mSwitchCameraBtn.setVisibility(visibility);
}
private boolean checkSelfPermission(String permission, int requestCode){
if(ContextCompat.checkSelfPermission(this,permission)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,REQUESTED_PERMISSIONS,requestCode);
Toast.makeText(this,"No Permission",Toast.LENGTH_LONG);
return false;
}
return true;
}
}
'''
You can try "onRemoteVideoStateChanged" callback instead of "onFirstRemoteVideoFrame".
Here is the code snippet:
#Override
public void onRemoteVideoStateChanged(final int uid, int state, int reason, int elapsed) {
super.onRemoteVideoStateChanged(uid, state, reason, elapsed);
if (state == Constants.REMOTE_VIDEO_STATE_STARTING) {
runOnUiThread(new Runnable() {
#Override
public void run() {
setupRemoteVideo(uid);
}
});
}
}
I am learning preferences using LibGDX. I can run the following code sucessfully both in Windows and Android Device. The file "MyDemo" is stored in
my C: drive user directory. It is prefect. I can run the code in Android device sucessfully as well. However, I can't find the file "MyDemo". There is nothing
in Android/data/...
package com.hkprogram.mydemo;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class MyDemo implements ApplicationListener {
private SpriteBatch batch;
private BitmapFont font1;
int screenWidth, screenHeight;
public Preferences prefs;
String name;
#Override
public void create() {
batch = new SpriteBatch();
font1 = new BitmapFont();
font1.setColor(Color.BLACK);
font1.setScale(5);
screenWidth=Gdx.graphics.getWidth();
screenHeight=Gdx.graphics.getHeight();
Preferences prefs = Gdx.app.getPreferences("MyDemo");
prefs.putString("Name", "Peter");
prefs.flush();
prefs = Gdx.app.getPreferences("MyDemo");
name=prefs.getString("Name","no name stored");
System.out.println("Name="+name);
}
#Override
public void dispose() {
}
#Override
public void pause() {
}
#Override
public void render() {
Gdx.gl.glClearColor(159/255.0f,220/255.0f,235/255.0f,0xff/255.0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
font1.draw(batch, name, screenWidth/2, screenHeight/2);
batch.end();
}
#Override
public void resize(int arg0, int arg1) {
}
#Override
public void resume() {
}
}
You can get the path where you have MyDemo doing this :
File MyDemoFile = getDatabasePath("MyDemo.txt"); //choose your extension
if (MyDemoFile != null){
Log.d("Absolute path : ", MyDemoFile.getAbsolutePath());
}
I am making a "Defend the castle" style android application. The game is complete, however I just need help closing my surfaceview and starting a new activity for when the the player has lost the game.
The condition for losing the game is just a boolean variable in my GameThread class. The variable is called "lost" and is by default set to false. When the life of the castle drops below 1, lost is set to true and a sound effect plays.
Ideally, I would like to stop the currently looping sound effects and open a new activity (which is already made and working) upon lost=true.
The main activity is as follows:
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
public class MainActivity extends Activity {
Button btn_startGame;
Activity activity;
GameView mGameView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
activity = this;
setContentView(R.layout.main);
btn_startGame = (Button) findViewById(R.id.btnStartGame);
btn_startGame.setOnClickListener(new OnClickListener() {
//#Override
public void onClick(View v) {
mGameView = new GameView(activity);
setContentView(mGameView);
mGameView.mThread.doStart();
}
});
}
#Override
public boolean onTouchEvent(MotionEvent event) {
try {
mGameView.mThread.onTouch(event);
} catch(Exception e) {}
return true;
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
// ignore orientation/keyboard change
super.onConfigurationChanged(newConfig);
}
}
The surfaceview is created in this class called GameView:
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class GameView extends SurfaceView implements Callback {
Context mContext;
GameThread mThread;
public GameView(Context context) {
super(context);
this.mContext = context;
getHolder().addCallback(this);
mThread = new GameThread(getHolder(), mContext, new Handler() {
#Override
public void handleMessage(Message m) {
// Use for pushing back messages.
}
});
setFocusable(true);
}
//#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.d(this.getClass().toString(), "in SurfaceChanged()");
}
//#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d(this.getClass().toString(), "in SurfaceCreated()");
mThread.running = true;
mThread.start();
}
//#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(this.getClass().toString(), "in SurfaceDestroyed()");
boolean retry = true;
mThread.running = false;
while (retry) {
try {
mThread.join();
retry = false;
} catch (InterruptedException e) {
}
GameThread.music.stop();
GameThread.groan1.stop();
GameThread.groan2.stop();
GameThread.walk.stop();
GameThread.music.release();
GameThread.groan1.release();
GameThread.groan2.release();
GameThread.walk.release();
GameThread.shoot.release();
}
}
}
The GameThread class contains all of the drawing, the logic and all a run method (below).
#Override
public void run() {
// check if condition here
if(lost){
mContext.runOnUiThread(new Runnable() {
#Override
public void run() {
//start Activity here
Intent intent = new Intent(mContext, LoseActivity.class);
mContext.startActivity(intent);
}
});
}
else{
if (running == true) {
while (running) {
Canvas c = null;
try {
c = mHolder.lockCanvas();
if (width == 0) {
width = c.getWidth();
height = c.getHeight();
player.x = 50;
player.y = 45;
}
synchronized (mHolder) {
long now = System.currentTimeMillis();
update();
draw(c);
ifps++;
if (now > (mLastTime + 1000)) {
mLastTime = now;
fps = ifps;
ifps = 0;
}
}
} finally {
if (c != null) {
mHolder.unlockCanvasAndPost(c);
}
}
}
}
}
The activity that I want to start is called LoseActivity.class. Thank you in advance for any and all help. If anybody needs any further code/explanations, I will be more than happy to post it.
Use runOnUiThread for starting Activity from Thread as:
Change your main Activity as:
public class MainActivity extends Activity {
Button btn_startGame;
Activity activity;
GameView mGameView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
activity = this;
setContentView(R.layout.main);
btn_startGame = (Button) findViewById(R.id.btnStartGame);
btn_startGame.setOnClickListener(new OnClickListener() {
//#Override
public void onClick(View v) {
mGameView = new GameView(activity,MainActivity.this);
setContentView(mGameView);
mGameView.mThread.doStart();
}
});
}
///your code.....
Change your GameView class as:
public class GameView extends SurfaceView implements Callback {
Context mContext;
Activity contextx;
GameThread mThread;
public GameView(Context context,Activity contextx) {
super(context);
this.mContext = context;
this.contextx=contextx;
getHolder().addCallback(this);
mThread = new GameThread(getHolder(), mContext, new Handler() {
#Override
public void handleMessage(Message m) {
// Use for pushing back messages.
}
});
setFocusable(true);
}
//your code here..........
#Override
public void run() {
// check if condition here
if(lost){
contextx.runOnUiThread(new Runnable() {
#Override
public void run() {
//start Activity here
Intent intent = new Intent(contextx, LoseActivity.class);
contextx.startActivity(intent);
}
});
}
else{
//your code here.........
OK so I'm using xml to set this menu which is supported by the following java code
package starting.rt;
import java.util.List;
import java.util.Random;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class Menu extends Activity implements OnClickListener{
View.OnTouchListener gestureListener;
TextView display;
Button begin;
Button random;
Button game;
TextView counter;
Button next;
Button previous;
Button moreapps;
Button rate;
Random myRandom;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(starting.rt.R.layout.menu);
begin = (Button) findViewById(starting.rt.R.id.Begin);
random = (Button) findViewById(starting.rt.R.id.Random);
display = (TextView) findViewById(starting.rt.R.id.tvResults);
counter = (TextView) findViewById(starting.rt.R.id.tvCounter);
next = (Button) findViewById(starting.rt.R.id.Next);
previous = (Button) findViewById(starting.rt.R.id.Previous);
moreapps = (Button)findViewById(R.id.More);
rate = (Button) findViewById(R.id.rate);
game = (Button) findViewById(R.id.game);
// display.setOnTouchListener(this.gestureListener);
begin.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent openStartingPoint = new Intent("starting.rt.RelationshipTipsActivity");
startActivity(openStartingPoint);
}});
moreapps.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent goToMarket;
goToMarket = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pub:\"Wompa\""));
startActivity(goToMarket);
}});
game.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent openStartingPoint = new Intent("starting.rt.GameView");
startActivity(openStartingPoint);
}});
rate.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("market://details?id=" + getPackageName()));
startActivity(i);
}});}
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
Now what's supposed to be happening is when they click on the game which starts a new java class called GameView it crashes on clicked. Every other button works.
This is the code from GameView
package starting.rt;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GameView extends SurfaceView {
private GameLoopThread gameLoopThread;
private List<Sprite> sprites = new ArrayList<Sprite>();
private List<TempSprite> temps = new ArrayList<TempSprite>();
private long lastClick;
private Bitmap bmpBlood;
public GameView(Context context) {
super(context);
gameLoopThread = new GameLoopThread(this);
getHolder().addCallback(new SurfaceHolder.Callback() {
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
gameLoopThread.setRunning(false);
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {}
}
}
public void surfaceCreated(SurfaceHolder holder) {
createSprites();
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
bmpBlood = BitmapFactory.decodeResource(getResources(), R.drawable.blood1);
}
private void createSprites() {
sprites.add(createSprite(R.drawable.bad1));
// sprites.add(createSprite(R.drawable.bad2));
// sprites.add(createSprite(R.drawable.bad3));
// sprites.add(createSprite(R.drawable.bad4));
// sprites.add(createSprite(R.drawable.bad5));
// sprites.add(createSprite(R.drawable.bad6));
// sprites.add(createSprite(R.drawable.good1));
// sprites.add(createSprite(R.drawable.good2));
// sprites.add(createSprite(R.drawable.good3));
// sprites.add(createSprite(R.drawable.good4));
// sprites.add(createSprite(R.drawable.good5));
// sprites.add(createSprite(R.drawable.good6));
}
private Sprite createSprite(int resouce) {
Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
return new Sprite(this, bmp);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
for (int i = temps.size() - 1; i >= 0; i--) {
temps.get(i).onDraw(canvas);
}
for (Sprite sprite : sprites) {
sprite.onDraw(canvas);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (System.currentTimeMillis() - lastClick > 300) {
lastClick = System.currentTimeMillis();
float x = event.getX();
float y = event.getY();
synchronized (getHolder()) {
for (int i = sprites.size() - 1; i >= 0; i--) {
Sprite sprite = sprites.get(i);
if (sprite.isCollition(x, y)) {
sprites.remove(sprite);
temps.add(new TempSprite(temps, this, x, y, bmpBlood));
break;
}
}
}
}
return true;
}
}
The GameView calls a few other classes for things part of the game but it crashes before it can start. I think it's crashing because it's switching from xml layout to the java surfaceview. Help would be appreciated :) Thanks!
First of all, you should always post in your questions the stacktrace with the exception from the Logcat if your app crashes.
You can't start a SurfaceView directly, instead your custom SurfaceView must be embedded in an Activity like any other view in android. For example:
public class GameViewActivity extends Activity {
#Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(new GameView(this));
}
}
Where in this code would I put a thread delay, that will happen after the completion of onCreate(), which means also after the completion/showing of onDraw()? Afterwards I will be calling grid.clearPattern() which clears the pattern drawn on the canvas when grid.displayPattern() was called. So afterwards I will still need to be able to modify the canvas.
package com.patterns;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class PlayGame extends Activity implements View.OnTouchListener {
int size;
Grid grid;
PatternView patternview;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
size = getIntent().getExtras().getInt("size");
patternview = new PatternView(this);
setContentView(patternview);
Handler pauser = new Handler();
pauser.postDelayed(new Runnable() {
public void run() {
patternview.clearDraw();
}
}, 2000);
patternview.setOnTouchListener(this);
}
public class PatternView extends View {
Paint paint = new Paint();
public PatternView(Context context){
super(context);
}
protected void clearDraw() {
Log.d("debug", "clearDraw called");
grid.clearPattern();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
grid = new Grid(size, size, getWidth(), getWidth(), canvas, paint);
grid.createPattern();
grid.displayPattern();
Log.d("debug", "lines drawn");
grid.setBoard();
Log.d("debug", "board set");
}
}
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
//Log.d("debug", "screen touched");
grid.screenTouch(arg1);
grid.fillActiveRectangles();
return false;
}
}
Maybe stick the call to grid.clearPattern() into an android.os.Handler? Had a similar app-pausing problem and this did the trick for me. So stick something like this at the end of onCreate() -- the 3500 is a pause in milliseconds, choose the value that you want.
Handler pauser = new Handler();
pauser.postDelayed (new Runnable() {
public void run() {
grid.clearPattern();
}
}, 3500);
Could it be like this?
grid.createPattern();
grid.displayPattern(canvas, paint);
Thread.sleep(2000);
But it will be a pain...