A problem about SurfaceView regarding game animation - java

I'm creating an animation and this animation must work using a moving object (my object class).
My problem is that when I pause the app the animation starts all over again after I resumed my app . . .
I will use this animation for my 2D game... and here's the code:
The Object Class:
private boolean enabled;
private final Paint paint = new Paint();
public Object() {
stylePaint(paint);
}
public abstract void draw(Canvas var1);
public Paint getPaint() {
return paint;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean bl) {
enabled = bl;
}
public abstract void stylePaint(Paint var1);
The Class that I used which extends my Object Class:
private Point pos;
private Bitmap bitmap;
private Context context;
private int height, width, visibility;
private static int vheight, vwidth;
private static View view;
public static final int
VISIBLE = 255,
INVISIBLE = 0;
public static final int
dirAll = -5,
dirX = -1,
dirY = -2,
ndirAll = -6,
ndirX = -3,
ndirY = -4;
private int speed;
public Actor(int x, int y) {
pos = new Point(x, y);
if(getSyncedView() != null) context = getSyncedView().getContext();
}
public Actor(int x, int y, int w, int h) {
this(x, y);
setDimensions(w, h);
}
public int getWidth() {
return width;
}
public static void syncView(View v) {
view = v;
vheight = v.getHeight();
vwidth = v.getWidth();
}
public static View getSyncedView() {
return view;
}
public void setPadding(int x, int y) {
setDimensions(getX() + x, getY() + y);
}
public void setGravity(Gravity where) { // Gravity is an enum
if(view != null) {
final int
n = vwidth - width,
n2 = vheight - height,
n3 = n / 2,
n4 = n2 / 2;
switch (where) {
case CENTER: {
setGravity(Gravity.CENTER_HORIZONTAL);
setGravity(Gravity.CENTER_VERTICAL);
break;
}
case CENTER_HORIZONTAL: {
setX(n3);
break;
}
case CENTER_VERTICAL: {
setY(n4);
break;
}
case LEFT: {
setX(0);
break;
}
case RIGHT: {
setX(n);
break;
}
case TOP: {
setY(0);
break;
}
case BOTTOM: {
setY(n2);
break;
}
default: {
break;
}
}
}
}
public int getHeight() {
return height;
}
public void setDimensions(int w, int h) {
width = w;
height = h;
}
public Point getPoint() {
return pos;
}
public Rect getRect() {
Rect rect = new Rect();
getRectF().round(rect);
return rect;
}
public RectF getRectF() {
return new RectF(getX(), getY(), getX() + width, getY() + height);
}
public void setPos(int x, int y) {
pos = new Point(x, y);
}
public void setVisibility(int visible) {
getPaint().setAlpha(visible);
}
public int getVisibility() {
return visibility;
}
public void alignTo(PositionedObject target, Gravity where) {
//Aligning this to target
if(view != null) {
int n = target.getX(),
n2 = (target.getWidth() - getWidth()) / 2,
n3 = (target.getWidth() + getWidth()) / 2,
n4 = target.getY(),
n5 = (target.getHeight() - getHeight()) / 2,
n6 = (target.getHeight() + getHeight()) / 2;
switch (where) {
case CENTER: {
setX(n + n2);
setY(n4 + n5);
break;
}
case BOTTOM: {
setX(n + n2);
setY(n4 + n5 + n6);
break;
}
case TOP: {
setX(n + n2);
setY(n4 + n5 - n6);
break;
}
case LEFT: {
setX(n + n2 - n3);
setY(n4 + n5);
break;
}
case RIGHT: {
setX(n + n2 + n3);
setY(n4 + n5);
break;
}
default: break;
}
}
}
public int getX() {
return pos.x;
}
public void setX(int x) {
pos.x = x;
}
public int getY() {
return pos.y;
}
public void setY(int y) {
pos.y = y;
}
public boolean intersect(MovingObject mo) {
return getRect().intersect(mo.getRect());
public int getSpeed() {
return speed;
}
public void move(int where) {
if (isEnabled()) {
switch (where) {
case dirX: {
getPoint().x = getPoint().x + getSpeed();
break;
}
case ndirX: {
getPoint().x = getPoint().x - getSpeed();
break;
}
case dirY: {
getPoint().y = getPoint().y + getSpeed();
break;
}
case ndirY: {
getPoint().y = getPoint().y - getSpeed();
break;
}
case dirAll: {
move(dirX);
move(dirY);
break;
}
case ndirAll: {
move(ndirX);
move(ndirY);
break;
}
}
}
}
public void setSpeed(int sp) {
speed = sp;
}
#Override
public void draw(Canvas canvas) {
canvas.drawBitmap(getBitmap(), getX(), getY(), getPaint());
}
#Override
public void stylePaint(Paint p) {
}
public void setBitmap(Bitmap bm) {
bitmap = bm;
}
public Bitmap getBitmap() {
return bitmap;
}
Bitmap a(Bitmap bm) {
setBitmap(bm);
setDimensions(bm.getWidth(), bm.getHeight());
return getBitmap();
}
public Bitmap createFromAsset(String path) {
try {
return a(BitmapFactory.decodeStream(context.getAssets().open(path)));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public Bitmap createFromRes(int drawable) {
return a(BitmapFactory.decodeResource(context.getResources(), drawable));
}
My SurfaceView:
public SharedPreferences pref;
public SharedPreferences.Editor editor;
private final Paint paint = new Paint();
private BaseThread thread;
private Thread thread2;
private int panelColor;
public Actor cmd, actor, actor2; // The class that extends my object class.
public AbstractPanel(Context context) {
super(context);
init(context);
}
public AbstractPanel(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
void init(Context context) {
SurfaceHolder holder = getHolder();
thread = new BaseThread(holder);
pref = context.getSharedPreferences("Scene", Context.MODE_PRIVATE);
editor = pref.edit();
holder.addCallback(this);
panelColor = Color.BLACK;
}
protected BaseThread getLoop() {
return thread;
}
protected Paint getPaint() {
return paint;
}
#Override
public boolean onKeyDown(int var1, KeyEvent var2) {
return true;
}
public void onStart() {
PositionedObject.syncView(this);
cmd = new Actor(0, 0);
actor = new Actor(0, 0);
actor2 = new Actor(0, 0);
cmd.createFromAsset("cmd.png");
actor.createFromAsset("grandGL.png");
actor2.createFromAsset("presents.png");
actor.setGravity(Gravity.CENTER);
actor2.alignTo(actor, Gravity.BOTTOM);
actor.setVisibility(Actor.INVISIBLE);
actor2.setVisibility(Actor.INVISIBLE);
cmd.setSpeed(1);
cmd.setEnabled(true);
}
public void onTimer() {}
public boolean onTouchEvent(MotionEvent motionEvent) {
return true;
}
public void redrawCanvas(Canvas canvas) {
actor.draw(canvas);
actor2.draw(canvas);
cmd.draw(canvas);
cmd.move(Actor.dirX);
switch (cmd.getX()) {
default : break;
case 25: {
actor.setVisibility(30);
break;
}
case 26: {
actor.setVisibility(60);
break;
}
case 27: {
actor.setVisibility(90);
break;
}
case 28: {
actor.setVisibility(120);
break;
}
case 29: {
actor.setVisibility(150);
break;
}
case 30: {
actor.setVisibility(180);
break;
}
case 31: {
actor.setVisibility(210);
break;
}
case 32: {
actor.setVisibility(240);
break;
}
case 35: {
actor.setVisibility(Actor.VISIBLE);
break;
}
case 60: {
actor2.setVisibility(Actor.VISIBLE);
break;
}
case 130: {
actor.setVisibility(210);
actor2.setVisibility(210);
break;
}
case 132: {
actor.setVisibility(190);
actor2.setVisibility(190);
break;
}
case 134: {
actor.setVisibility(160);
actor2.setVisibility(160);
break;
}
case 136: {
actor.setVisibility(130);
actor2.setVisibility(130);
break;
}
case 138: {
actor.setVisibility(100);
actor2.setVisibility(100);
break;
}
case 140: {
actor.setVisibility(60);
actor2.setVisibility(60);
break;
}
case 142: {
actor.setVisibility(30);
actor2.setVisibility(30);
break;
}
case 146: {
actor.setVisibility(Actor.INVISIBLE);
actor2.setVisibility(Actor.INVISIBLE);
break;
}
}
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
canvas.drawColor(panelColor);
redrawCanvas(canvas);
}
public void setPanelColor(int n) {
panelColor = n;
}
public void startGameLoop() {
thread.setRunning(true);
}
public void stopGameLoop() {
thread.setRunning(false);
}
public void surfaceChanged(SurfaceHolder hol, int n, int w, int h) {
}
public void surfaceCreated(SurfaceHolder holder) {
thread2 = new Thread(thread);
thread2.setPriority(1);
startGameLoop();
thread2.start();
onStart();
}
public void surfaceDestroyed(SurfaceHolder holder) {
stopGameLoop();
}
public class BaseThread implements Runnable {
private SurfaceHolder surHol;
private boolean running;
public BaseThread(SurfaceHolder holder) {
surHol = holder;
}
public void delay(long l) {
try {
Thread.sleep(l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean run) {
synchronized (this) {
running = run;
}
}
#Override
public void run() {
synchronized (surHol) {
delay(800L);
while (isRunning()) {
Canvas canvas = null;
try {
canvas = surHol.lockCanvas();
synchronized (canvas) {
onTimer();
draw(canvas);
}
} catch (Exception e) {
} finally {
if (canvas != null) {
surHol.unlockCanvasAndPost(canvas);
delay(36L);
}
}
}
}
}
I also need simplifications for my codes . . . Thanks in advance for the help . . .
I only accept codes using SurfaceView because this is for my game . . .
SOLVED
Here' s the final code and it's free to copy . . .
I've found out that some onStart() methods must be at the constructor since onStart() method is always called after resuming so I created an onCreate() method to put some codes of onStart() . . .
For LCPanel that extends AbstractPanel that extends SurfaceView:
Actor
cmd,
actor,
actor2;
public LCPanel(Context context) {
super(context);
}
#Override
public boolean onKeyDown(int n, KeyEvent keyEvent) {
return true;
}
#Override
public void onCreate() {
cmd = new Actor(0, 0);
actor = new Actor(0, 0);
actor2 = new Actor(0, 0);
cmd.createFromAsset("cmd.png");
actor.createFromAsset("grandGL.png");
actor2.createFromAsset("presents.png");
}
#Override
public void onStart() {
actor.setGravity(Gravity.CENTER);
actor2.alignTo(actor, Gravity.BOTTOM);
actor.setVisibility(Actor.INVISIBLE);
actor2.setVisibility(Actor.INVISIBLE);
cmd.setSpeed(1);
cmd.setEnabled(true);
}
#Override
public boolean onTouchEvent(MotionEvent motionEvent) {
return true;
}
/* package */ final int a (int n, int n2) {
return (30 * (n - n2)) > 255 ? 255 : 30 * (n - n2); // alpha animator
}
#Override
public void onDraw(Canvas canvas) {
int n = cmd.getX();
actor.draw(canvas);
actor2.draw(canvas);
cmd.draw(canvas);
cmd.move(Actor.dirX);
if (n >= 25 && n <= 38) actor.setVisibility(a(n, 25));
if(n >= 38 && n <= 145) {
actor.setVisibility(Actor.VISIBLE);
if (n >= 74) actor2.setVisibility(Actor.VISIBLE);
}
if (n >= 145 && n <= 162) {
int n3 = 255 - a(n, 145);
actor.setVisibility(n3);
actor2.setVisibility(n3);
actor.shrink();
}
if (n >= 163) {
canvas.drawColor(Color.WHITE);
actor2.draw(canvas);
actor2.createFromAsset("loadin.png");
actor2.setGravity(Gravity.CENTER);
actor2.setVisibility(Actor.VISIBLE);
}
}
Edit some existing AbstractPanel methods:
public AbstractPanel(Context context) {
super(context);
init(context);
}
public AbstractPanel(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
void init(Context context) {
pref = context.getSharedPreferences("Scene", Context.MODE_PRIVATE);
editor = pref.edit();
getHolder().addCallback(this);
Actor.syncView(this);
onCreate();
}
public abstract void onStart();
public abstract void onCreate();
public abstract void onDraw(Canvas canvas);
Edit the thread inside the AbstractClass:
public class BaseThread extends Thread {
private SurfaceHolder surHol;
private boolean running;
public BaseThread(SurfaceHolder holder) {
super();
surHol = holder;
}
public void delay(long l) {
try { sleep(l); } catch (InterruptedException e) {}
}
public void setRunning(boolean run) {
running = run;
}
#Override
public synchronized void run() {
delay(800L);
onStart();
while (true) {
if (!running) break;
Canvas canvas = null;
try {
canvas = surHol.lockCanvas();
synchronized (canvas) {
draw(canvas);
}
} catch (Exception e) {
} finally {
if (canvas != null) {
surHol.unlockCanvasAndPost(canvas);
delay(36L);
}
}
}
}
And done, problem solved..! The animation must work properly as expected . . .

Related

How to auto play first video in recyclerview in ExoPlayer

I have a problem in my code. I want to autoplay first video from recyclerview in ExoPlayer, The player is working good on scroll but the first video does not play automatically
public class VideoPlayerRecyclerView extends RecyclerView {
private static final String TAG = "VideoPlayerRecyclerView";
private enum VolumeState {ON, OFF};
// ui
private ImageView thumbnail, volumeControl;
private ProgressBar progressBar;
private View viewHolderParent;
private FrameLayout frameLayout;
private PlayerView videoSurfaceView;
private SimpleExoPlayer videoPlayer;
// vars
private ArrayList<Status_Bakend> mediaObjects = new ArrayList<>();
private int videoSurfaceDefaultHeight = 0;
private int screenDefaultHeight = 0;
private Context context;
private int playPosition = -1;
private boolean isVideoViewAdded;
private RequestManager requestManager;
// controlling playback state
private VolumeState volumeState;
public VideoPlayerRecyclerView(#NonNull Context context) {
super(context);
init(context);
}
public VideoPlayerRecyclerView(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(final Context context){
this.context = context.getApplicationContext();
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point point = new Point();
display.getSize(point);
videoSurfaceDefaultHeight = point.x;
screenDefaultHeight = point.y;
videoSurfaceView = new PlayerView(this.context);
videoSurfaceView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_ZOOM);
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector =
new DefaultTrackSelector(videoTrackSelectionFactory);
// 2. Create the player
videoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector);
// Bind the player to the view.
videoSurfaceView.setUseController(false);
videoSurfaceView.setPlayer(videoPlayer);
setVolumeControl(VolumeState.ON);
playVideo(true);
videoPlayer.setPlayWhenReady(true);
addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
Log.d(TAG, "onScrollStateChanged: called.");
if(thumbnail != null){ // show the old thumbnail
thumbnail.setVisibility(VISIBLE);
}
// There's a special case when the end of the list has been reached.
// Need to handle that with this bit of logic
if(!recyclerView.canScrollVertically(1)){
playVideo(true);
}
else{
playVideo(false);
}
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
addOnChildAttachStateChangeListener(new OnChildAttachStateChangeListener() {
#Override
public void onChildViewAttachedToWindow(View view) {
}
#Override
public void onChildViewDetachedFromWindow(View view) {
if (viewHolderParent != null && viewHolderParent.equals(view)) {
resetVideoView();
}
}
});
videoPlayer.addListener(new Player.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, #Nullable Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_BUFFERING:
Log.e(TAG, "onPlayerStateChanged: Buffering video.");
if (progressBar != null) {
progressBar.setVisibility(VISIBLE);
}
break;
case Player.STATE_ENDED:
Log.d(TAG, "onPlayerStateChanged: Video ended.");
videoPlayer.seekTo(0);
break;
case Player.STATE_IDLE:
break;
case Player.STATE_READY:
Log.e(TAG, "onPlayerStateChanged: Ready to play.");
if (progressBar != null) {
progressBar.setVisibility(GONE);
}
if(!isVideoViewAdded){
addVideoView();
}
break;
default:
break;
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
});
}
public void playVideo(boolean isEndOfList) {
int targetPosition;
if(!isEndOfList){
int startPosition = ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
int endPosition = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
// if there is more than 2 list-items on the screen, set the difference to be 1
if (endPosition - startPosition > 1) {
endPosition = startPosition + 1;
}
// something is wrong. return.
if (startPosition < 0 || endPosition < 0) {
return;
}
// if there is more than 1 list-item on the screen
if (startPosition != endPosition) {
int startPositionVideoHeight = getVisibleVideoSurfaceHeight(startPosition);
int endPositionVideoHeight = getVisibleVideoSurfaceHeight(endPosition);
targetPosition = startPositionVideoHeight > endPositionVideoHeight ? startPosition : endPosition;
}
else {
targetPosition = startPosition;
}
}
else{
targetPosition = mediaObjects.size() - 1;
}
Toast.makeText(context, "playVideo: target position: " + targetPosition, Toast.LENGTH_SHORT).show();
// video is already playing so return
if (targetPosition == playPosition) {
return;
}
// set the position of the list-item that is to be played
playPosition = targetPosition;
if (videoSurfaceView == null) {
return;
}
// remove any old surface views from previously playing videos
videoSurfaceView.setVisibility(INVISIBLE);
removeVideoView(videoSurfaceView);
int currentPosition = targetPosition - ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
View child = getChildAt(currentPosition);
if (child == null) {
return;
}
VideoPlayerViewHolder holder = (VideoPlayerViewHolder) child.getTag();
if (holder == null) {
playPosition = -1;
return;
}
thumbnail = holder.thumbnail;
progressBar = holder.progressBar;
volumeControl = holder.volumeControl;
viewHolderParent = holder.itemView;
requestManager = holder.requestManager;
frameLayout = holder.itemView.findViewById(R.id.media_container);
videoSurfaceView.setPlayer(videoPlayer);
videoPlayer.addVideoListener(new VideoListener() {
#Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
frameLayout.getLayoutParams().height = (height * 2);
}
#Override
public void onRenderedFirstFrame() {
}
});
viewHolderParent.setOnClickListener(videoViewClickListener);
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(
context, Util.getUserAgent(context, "RecyclerView VideoPlayer"));
String mediaUrl = mediaObjects.get(targetPosition).getStatus_link();
if (mediaUrl != null) {
MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(mediaUrl));
videoPlayer.prepare(videoSource);
videoPlayer.setPlayWhenReady(true);
}
}
private OnClickListener videoViewClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
toggleVolume();
}
};
/**
* Returns the visible region of the video surface on the screen.
* if some are cut off, it will return less than the #videoSurfaceDefaultHeight
* #param playPosition
* #return
*/
private int getVisibleVideoSurfaceHeight(int playPosition) {
int at = playPosition - ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
Log.d(TAG, "getVisibleVideoSurfaceHeight: at: " + at);
View child = getChildAt(at);
if (child == null) {
return 0;
}
int[] location = new int[2];
child.getLocationInWindow(location);
if (location[1] < 0) {
return location[1] + videoSurfaceDefaultHeight;
} else {
return screenDefaultHeight - location[1];
}
}
// Remove the old player
private void removeVideoView(PlayerView videoView) {
ViewGroup parent = (ViewGroup) videoView.getParent();
if (parent == null) {
return;
}
int index = parent.indexOfChild(videoView);
if (index >= 0) {
parent.removeViewAt(index);
isVideoViewAdded = false;
viewHolderParent.setOnClickListener(null);
}
}
private void addVideoView(){
frameLayout.addView(videoSurfaceView);
isVideoViewAdded = true;
videoSurfaceView.requestFocus();
videoSurfaceView.setVisibility(VISIBLE);
videoSurfaceView.setAlpha(1);
}
private void resetVideoView(){
if(isVideoViewAdded){
removeVideoView(videoSurfaceView);
playPosition = -1;
videoSurfaceView.setVisibility(INVISIBLE);
}
}
public void releasePlayer() {
if (videoPlayer != null) {
videoPlayer.release();
videoPlayer = null;
}
viewHolderParent = null;
}
private void toggleVolume() {
if (videoPlayer != null) {
if (volumeState == VolumeState.OFF) {
Log.d(TAG, "togglePlaybackState: enabling volume.");
setVolumeControl(VolumeState.ON);
} else if(volumeState == VolumeState.ON) {
Log.d(TAG, "togglePlaybackState: disabling volume.");
setVolumeControl(VolumeState.OFF);
}
}
}
private void setVolumeControl(VolumeState state){
volumeState = state;
if(state == VolumeState.OFF){
videoPlayer.setVolume(0f);
animateVolumeControl();
}
else if(state == VolumeState.ON){
videoPlayer.setVolume(1f);
animateVolumeControl();
}
}
private void animateVolumeControl(){
if(volumeControl != null){
volumeControl.bringToFront();
if(volumeState == VolumeState.OFF){
requestManager.load(R.drawable.ic_favorite_border_black_24dp)
.into(volumeControl);
}
else if(volumeState == VolumeState.ON){
requestManager.load(R.drawable.ic_favorite_border_black_24dp)
.into(volumeControl);
}
volumeControl.animate().cancel();
volumeControl.setAlpha(1f);
volumeControl.animate()
.alpha(0f)
.setDuration(600).setStartDelay(1000);
}
}
public void setMediaObjects(ArrayList<Status_Bakend> mediaObjects){
this.mediaObjects = mediaObjects;
}
}
This is my code on recyclerview scroll working fine on scroll but I want to autoplay my first video in recyclerview without scrolling.
Just add this line after setAdapter to the recycler view.
recyclerView.smoothScrollBy(0, -1);
OR
recyclerView.smoothScrollBy(0, 1);
This will solve your problem.
You only need to make the first video play using postDelayed().
I think the reason is that the views of the RecyclerView items are all drawn on the layout and the video play process are duplicated.

Xamarin Visual Studio Constructing instances of generic types from Java is not supported

I would appreciate some help with this current problem. I think I understand the cause of the issue, however I have no idea how to fix it. I have two custom views, one implements a ViewGroup and the other just a View.
CameraSourcePreview and GraphicOverlay
However they are both generic to T where T : GraphicOverlay<\T>.Graphic
In BarcodeFragmentActivity. Line 64.
SetContentView(Resource.Layout.Barcode_Capture)
Throws the following error.
System.NotSupportedException: Constructing instances of generic types from Java is not supported, as the type parameters cannot be determined. occurred
Im not sure how to create a full stack trace, as I am using my phone as the test device. Program wont run on an emulator.
Code on Github: https://github.com/StormMaster12/StockApp.
Thought it would be easier to see it on there, than copy all of my code in.
Edit Code Throwing Error.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Content.PM;
using Android.Gms.Vision.Barcodes;
using Android.Gms.Common.Apis;
using Android.Gms.Common;
using Android.Gms.Vision;
using Android.Hardware;
using Android.Support.V4.View;
using Android.Support.V4.App;
using Android.Support.V7.App;
using Android.Support.Design.Widget;
using StockApp.UI;
using Android.Util;
namespace StockApp.BarcodeReader
{
[Activity(Label = "Barcode Fragment Activity")]
class BarcodeFragmentActivity : AppCompatActivity
{
private static string tag = "Barcode-Reader";
private static int RC_HANDLE_GMS = 9001;
private static int RC_HANDLE_CAMERA_PERM = 2;
public static string AutoFocus = "AutoFocus";
public static string UseFlash = "UseFlash";
public static string BarcodeObject = "Barcode";
private CameraSourcePreview<BarcodeGraphic> mPreview;
private Android.Gms.Vision.CameraSource mCameraSource;
private GraphicOverlay<BarcodeGraphic> mGraphicOverlay;
private ScaleGestureDetector scaleGestureDetector;
private GestureDetector getsureDetector;
private View layout;
private static BarcodeFragmentActivity thisInstance;
public override View OnCreateView(View parent, string name, Context context, IAttributeSet attrs)
{
return base.OnCreateView(parent, name, context, attrs);
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
thisInstance = this;
SetContentView(Resource.Layout.Barcode_Capture);
//LayoutInflater inflater = LayoutInflater.From(this);
//ViewGroup viewGroup = (ViewGroup)FindViewById(Resource.Id.preview);
//View child = inflater.Inflate(Resource.Layout.layout1, viewGroup, true);
mPreview = (CameraSourcePreview<BarcodeGraphic>)FindViewById(Resource.Id.preview);
mGraphicOverlay = (GraphicOverlay<BarcodeGraphic>)FindViewById(Resource.Id.graphicOverlay);
bool autoFocus = Intent.GetBooleanExtra(AutoFocus, false);
bool useFlash = Intent.GetBooleanExtra(UseFlash, false);
int rc = (int) ActivityCompat.CheckSelfPermission(this, Manifest.Permission.Camera);
if (rc == (int) Permission.Granted)
{
createCameraSource(autoFocus, useFlash);
}
else
{
requestCameraPermission();
}
getsureDetector = new GestureDetector(this, new CaptureGestureListener());
}
private void requestCameraPermission()
{
string[] permissions = new string[] { Manifest.Permission.CallPhone };
if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.Camera))
{
Snackbar.Make(layout, "Require Camera Permions To Read Barcodes", Snackbar.LengthIndefinite)
.SetAction("Ok", new Action<View> (delegate(View obj)
{
ActivityCompat.RequestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM);
}
)).Show();
}
else
{
ActivityCompat.RequestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM);
}
//Activity thisActivity = this;
//View.IOnClickListener listener = new View.IOnClickListener;
}
public override bool OnTouchEvent(MotionEvent e)
{
bool b = scaleGestureDetector.OnTouchEvent(e);
bool c = getsureDetector.OnTouchEvent(e);
return b || c || base.OnTouchEvent(e);
}
private void createCameraSource(bool autoFocus, bool useFlash)
{
Context context = ApplicationContext;
BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).Build();
BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(mGraphicOverlay);
barcodeDetector.SetProcessor(
new MultiProcessor.Builder(barcodeFactory).Build());
if (!barcodeDetector.IsOperational)
{
IntentFilter lowstorageFilter = new IntentFilter(Intent.ActionDeviceStorageLow);
bool hasLowStorage = RegisterReceiver(null, lowstorageFilter) != null;
if (hasLowStorage)
{
Toast.MakeText(this, "Low Storage Error", ToastLength.Long);
}
}
Android.Gms.Vision.CameraSource.Builder builder = new Android.Gms.Vision.CameraSource.Builder(base.ApplicationContext, barcodeDetector)
.SetFacing(Android.Gms.Vision.CameraFacing.Back)
.SetRequestedPreviewSize(1600, 1024)
.SetRequestedFps(15.0f)
.SetAutoFocusEnabled(true);
mCameraSource = builder.Build();
}
private void startCameraSource()
{
int code = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(ApplicationContext);
if(code != ConnectionResult.Success)
{
Dialog dig = GoogleApiAvailability.Instance.GetErrorDialog(this, code, RC_HANDLE_GMS);
dig.Show();
}
if (mCameraSource != null)
{
try
{
mPreview.start(mCameraSource, mGraphicOverlay);
}
catch (InvalidOperationException)
{
mCameraSource.Release();
mCameraSource = null;
}
}
}
private bool OnTap(float rawX, float rawY)
{
int[] location = new int[2];
mGraphicOverlay.GetLocationOnScreen(location);
float x = (rawX - location[0]);
float y = (rawY - location[1]);
Barcode best = null;
float bestDistance = float.MaxValue;
foreach (BarcodeGraphic graphic in mGraphicOverlay.getGraphics())
{
Barcode barcode = graphic.GetBarcode();
if(barcode.BoundingBox.Contains((int)x,(int)y))
{
best = barcode;
break;
}
float dx = x - barcode.BoundingBox.CenterX();
float dy = y - barcode.BoundingBox.CenterY();
float distance = (dx * dx) + (dy * dy);
if ( distance > bestDistance)
{
best = barcode;
bestDistance = distance;
}
if (best != null)
{
Intent data = new Intent();
data.PutExtra(BarcodeObject, best);
SetResult(CommonStatusCodes.Success, data);
Finish();
return true;
}
}
return false;
}
protected override void OnResume()
{
base.OnResume();
startCameraSource();
}
protected override void OnPause()
{
base.OnPause();
if (mPreview != null)
{
mPreview.stop();
}
}
protected override void OnDestroy()
{
base.OnDestroy();
if(mPreview != null)
{
mPreview.release();
}
}
private class CaptureGestureListener : GestureDetector.SimpleOnGestureListener
{
public override bool OnSingleTapConfirmed(MotionEvent e)
{
return thisInstance.OnTap(e.RawX, e.RawY) || base.OnSingleTapConfirmed(e);
}
}
private class ScaleListener : ScaleGestureDetector.IOnScaleGestureListener
{
public IntPtr Handle => throw new NotImplementedException();
public void Dispose()
{
throw new NotImplementedException();
}
public bool OnScale(ScaleGestureDetector detector)
{
return false;
}
public bool OnScaleBegin(ScaleGestureDetector detector)
{
return true;
}
public void OnScaleEnd(ScaleGestureDetector detector)
{
}
}
}
}
Code that is being called.
CameraSourcePreview
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Gms.Vision;
using Android.Util;
using Android.Support.Annotation;
using Android.Gms.Common.Images;
using Android.Content.Res;
using Android.Graphics;
namespace StockApp.UI
{
[Register("stockapp.stockapp.ui.CameraSourcePreview")]
class CameraSourcePreview<T> : ViewGroup where T : GraphicOverlay<T>.Graphic
{
private static string TAG = "CameraSourcePreview";
private Context mContext;
private SurfaceView mSurfaceView;
public bool mStartRequested;
private bool mSurfaceAvaialbe;
private Android.Gms.Vision.CameraSource mCameraSource;
private GraphicOverlay<T> mOverlay;
private static CameraSourcePreview<T> Instance { get; set; }
public CameraSourcePreview(Context context, IAttributeSet attrs) : base(context,attrs)
{
mContext = context;
mStartRequested = false;
mSurfaceAvaialbe = false;
SurfaceCallback instance = new SurfaceCallback();
mSurfaceView = new SurfaceView(context);
mSurfaceView.Holder.AddCallback(instance);
AddView(mSurfaceView);
}
public void start(Android.Gms.Vision.CameraSource cameraSource)
{
if (cameraSource == null)
{
stop();
}
mCameraSource = cameraSource;
if(mCameraSource != null)
{
mStartRequested = true;
startIfReady();
}
}
public void start(Android.Gms.Vision.CameraSource cameraSource, GraphicOverlay<T> graphicOverlay)
{
mOverlay = graphicOverlay;
start(cameraSource);
}
public void stop()
{
if(mCameraSource != null)
{
mCameraSource.Stop();
}
}
public void release()
{
if(mCameraSource != null)
{
mCameraSource.Release();
mCameraSource = null;
}
}
private bool isPortaitMode()
{
int orientation = (int)mContext.Resources.Configuration.Orientation;
if (orientation == (int)Android.Content.Res.Orientation.Landscape)
{
return false;
}
else if (orientation == (int)Android.Content.Res.Orientation.Portrait)
{
return true;
}
return false;
}
private void startIfReady()
{
if (mStartRequested && mSurfaceAvaialbe)
{
mCameraSource.Start(mSurfaceView.Holder);
if (mOverlay != null)
{
Android.Gms.Common.Images.Size size = mCameraSource.PreviewSize;
int min = Math.Min(size.Width, size.Height);
int max = Math.Max(size.Width, size.Width);
if(isPortaitMode())
{
mOverlay.setCameraInfo(min, max, (int)mCameraSource.CameraFacing);
}
else
{
mOverlay.setCameraInfo(max, min, (int)mCameraSource.CameraFacing);
}
mOverlay.Clear();
}
mStartRequested = false;
}
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
int intWidth = 320;
int intHeight = 240;
if(mCameraSource != null)
{
Android.Gms.Common.Images.Size size = mCameraSource.PreviewSize;
if(size != null)
{
intWidth = size.Width;
intHeight = size.Height;
}
}
if(isPortaitMode())
{
int tmp = intWidth;
intHeight = intWidth;
intWidth = tmp;
}
int layoutWidth = l - r;
int layoutHeight = t - b;
int childWidth = layoutWidth;
int childHeight = (int)(((float)layoutWidth / (float) intHeight)*intWidth);
if (childHeight > layoutWidth)
{
childHeight = layoutHeight;
childWidth = (int)(((float)layoutHeight / (float)intHeight) * intWidth);
}
for (int i =0 ; i < ChildCount; i++ )
{
GetChildAt(i).Layout(0, 0, childWidth, childHeight);
}
try
{
startIfReady();
}
catch (Exception e)
{
Log.Debug("Something went wrong", e.ToString());
}
}
private class SurfaceCallback : ISurfaceHolderCallback
{
public IntPtr Handle => throw new NotImplementedException();
public void Dispose()
{
}
public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
{
}
public void SurfaceCreated(ISurfaceHolder holder)
{
Instance.mSurfaceAvaialbe = true;
try
{
Instance.startIfReady();
}
catch (Exception e)
{
Log.Debug("Something went wrong",e.ToString());
}
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
Instance.mSurfaceAvaialbe = false;
}
}
}
}
GraphicOverlay
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Gms.Vision;
using Android.Util;
using Android.Graphics;
using Java.Util;
namespace StockApp.UI
{
[Register("stockapp.stockapp.ui.GraphicOverlay")]
class GraphicOverlay<T> : View where T: GraphicOverlay<T>.Graphic
{
public T tT ;
private Object mLock = new object();
private int mPreviewWidth { get; set; }
private float mWidthScaleFactor { get; set; } = 1.0f;
private int mPreviewHeight;
private float mHeightScaleFactor { get; set; } = 1.0f;
private int mFacing { get; set; } = (int)CameraFacing.Back;
private HashSet<T> mGraphics = new HashSet<T>();
public GraphicOverlay(Context context, IAttributeSet attrs)
: base(context, attrs)
{
}
public void Clear()
{
lock(mLock)
{
mGraphics.Clear();
}
}
public void Add(T graphic)
{
lock(mLock)
{
mGraphics.Add(graphic);
}
PostInvalidate();
}
public void Remove(T graphic)
{
lock(mLock)
{
mGraphics.Remove(graphic);
}
PostInvalidate();
}
public List<T> getGraphics()
{
lock(mLock)
{
return mGraphics.ToList();
}
}
public void setCameraInfo(int previewWidth, int previewHeight, int facing)
{
lock(mLock)
{
mPreviewHeight = previewHeight;
mPreviewWidth = previewWidth;
mFacing = facing;
}
PostInvalidate();
}
protected void onDraw(Canvas canvas)
{
base.OnDraw(canvas);
lock(mLock)
{
if(mPreviewWidth !=0 && mPreviewHeight !=0)
{
mWidthScaleFactor = (float)canvas.Width / (float)mPreviewWidth;
mHeightScaleFactor = (float)canvas.Height / (float)mPreviewHeight;
}
foreach (Graphic graphic in mGraphics)
{
graphic.Draw(canvas);
}
}
}
public abstract class Graphic
{
private GraphicOverlay<T> mOverlay;
public Graphic(GraphicOverlay<T> overlay)
{
mOverlay = overlay;
}
public abstract void Draw(Canvas canvas);
public float scaleX(float horizontal) { return horizontal * mOverlay.mWidthScaleFactor; }
public float scaleY(float vertical) { return vertical * mOverlay.mHeightScaleFactor; }
public float translateX(float x)
{
float scale = scaleX(x);
if(mOverlay.mFacing == (int)CameraFacing.Front)
{
return mOverlay.Width - scale;
}
else
{
return scale;
}
}
public float translateY(float y) { return scaleY(y); }
public void postInvalidate() { mOverlay.PostInvalidate(); }
}
}
}

Android set on drag listener is showing error

I am developing an android app using drag and drop. And also I am using an a broadcast receiver for screen on. When I am using setOnDragListener It shows an error:
java.lang.RuntimeException: Error receiving broadcast Intent { act=init view flg=0x10 } in com.app.lockscreenlibrary.LockBroadcastReceiver#f22ed7d
Can anybody please help me solve the issue? Here is my code:
ActivityView.java
public class ActivityView extends FrameLayout {
public LinearLayout drop;
TextView text,sucess;
int total , failure = 0;
ImageView viewDrop;
private GestureDetector gestureDetector;
private Context mContext;
Button btnUnlock;
Button btn1;
private int CLICK_ACTION_THRESHHOLD = 200;
private float startX;
private float startY;
public ActivityView(Context context) {
this(context, null);
}
public ActivityView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ActivityView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(final Context context) {
mContext = context;
View view = inflate(context,R.layout.activity_view,null);
gestureDetector = new GestureDetector(context, new SingleTapConfirm());
drop = (LinearLayout)findViewById(R.id.bottomlinear);
sucess = (TextView)findViewById(R.id.Sucess);
drop.setOnDragListener();
drop.setOnDragListener(new View.OnDragListener() {
#Override
public boolean onDrag(View v, DragEvent event) {
//return false;
final int action = event.getAction();
switch(action) {
case DragEvent.ACTION_DRAG_STARTED:
break;
case DragEvent.ACTION_DRAG_EXITED:
break;
case DragEvent.ACTION_DRAG_ENTERED:
break;
case DragEvent.ACTION_DROP:{
failure = failure+1;
return(true);
}
case DragEvent.ACTION_DRAG_ENDED:{
total = total +1;
int suc = total - failure;
sucess.setText("Sucessful Drops :"+suc);
text.setText("Total Drops: "+total);
return(true);
}
default:
break;
}
return true;
}
});
btnUnlock = (Button) view.findViewById(R.id.unlock);
btnUnlock.setOnClickListener(new OnClickListener() {
#Override public void onClick(View v) {
LockHelper.getLockLayer().unlock();
}
});
btn01 = (Button) view.findViewById(R.id.btn0);
btn1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("LockView", "onTouch");
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
break;
case MotionEvent.ACTION_UP:
float endX = event.getX();
float endY = event.getY();
if (isAClick(startX, endX, startY, endY)) {
Log.d("LockView", "clicked");
} else {
}
break;
}
v.getParent().requestDisallowInterceptTouchEvent(true); //specific to my project
return false;
}
});
addView(view);
}
}
}
private class SingleTapConfirm extends GestureDetector.SimpleOnGestureListener {
#Override
public boolean onSingleTapUp(MotionEvent event) {
Log.d("LockView", "clicked1");
return true;
}
}
private boolean isAClick(float startX, float endX, float startY, float endY) {
float differenceX = Math.abs(startX - endX);
float differenceY = Math.abs(startY - endY);
if (differenceX > CLICK_ACTION_THRESHHOLD/* =5 */ || differenceY > CLICK_ACTION_THRESHHOLD) {
return false;
}
return true;
}
}
LockBroadcastReceiver.java
final public class LockBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = LockBroadcastReceiver.class.getSimpleName();
private volatile boolean bInterruptSupervisor = false;
private ScheduledThreadPoolExecutor mExecutor;
private FutureRunnable mSupervisorRunnable;
private static final int SCHEDULE_TASK_NUMBER = 3;
private PhoneStateChange mPhoneStateChangeCallback;
public void assignPhoneStateChangeCallback(PhoneStateChange phoneStateChangeCallback) {
mPhoneStateChangeCallback = phoneStateChangeCallback;
}
#Override public void onReceive(Context context, Intent intent) {
String mAction = intent.getAction();
//DU.sd("broadcast -----The Intent Action is: ", "" + mAction);
switch (mAction) {
case LockHelper.INIT_VIEW_FILTER:
LockHelper.INSTANCE.initLockViewInBackground(context);
break;
case Intent.ACTION_SCREEN_ON:
refreshBatteryInfo();
bringLockViewBackTopIfNot();
break;
case CoreIntent.ACTION_SCREEN_LOCKER_UNLOCK:
shutdownScheduleExecutor();
break;
case LockHelper.START_SUPERVISE:
bInterruptSupervisor = false;
supervise(context.getApplicationContext());
break;
case LockHelper.STOP_SUPERVISE:
bInterruptSupervisor = true;
break;
case LockHelper.SHOW_SCREEN_LOCKER:
//DU.sd("broadcast", "locker received");
case Intent.ACTION_SCREEN_OFF:
LockHelper.INSTANCE.initialize(context);
LockHelper.INSTANCE.getLockLayer().lock();
bInterruptSupervisor = true;
break;
case Intent.ACTION_POWER_CONNECTED:
//LockHelper.INSTANCE.getLockView().batteryChargingAnim();
break;
case Intent.ACTION_POWER_DISCONNECTED:
//LockHelper.INSTANCE.getLockView().batteryChargingAnim();
break;
case Intent.ACTION_SHUTDOWN:
break;
case "android.intent.action.PHONE_STATE":
TelephonyManager tm =
(TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
switch (tm.getCallState()) {
case TelephonyManager.CALL_STATE_RINGING:
mPhoneStateChangeCallback.ringing();
Log.i(TAG, "RINGING :" + intent.getStringExtra("incoming_number"));
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
mPhoneStateChangeCallback.offHook();
//DU.sd(TAG, "off hook");
break;
case TelephonyManager.CALL_STATE_IDLE:
mPhoneStateChangeCallback.idle();
Log.i(TAG, "incoming IDLE");
break;
}
break;
default:
break;
}
}
abstract class FutureRunnable implements Runnable {
private Future<?> future;
public Future<?> getFuture() {
return future;
}
public void setFuture(Future<?> future) {
this.future = future;
}
}
public void supervise(final Context context) {
//DU.sd("service", "supervise");
initScheduleExecutor();
if (mSupervisorRunnable == null) {
mSupervisorRunnable = new FutureRunnable() {
public void run() {
if (bInterruptSupervisor) getFuture().cancel(true);
boolean cameraRunning = false;
Camera _camera = null;
try {
_camera = Camera.open();
cameraRunning = _camera == null;
} catch (Exception e) {
// fail to open camera, secure to ignore exception
//DU.sd("camera exception on supervise");
cameraRunning = true;
} finally {
if (_camera != null) {
_camera.release();
getFuture().cancel(true);
context.sendBroadcast(new Intent(LockHelper.SHOW_SCREEN_LOCKER));
}
}
if (!cameraRunning) context.sendBroadcast(new Intent(LockHelper.SHOW_SCREEN_LOCKER));
}
};
}
Future<?> future =
mExecutor.scheduleAtFixedRate(mSupervisorRunnable, 2000, 500, TimeUnit.MILLISECONDS);
mSupervisorRunnable.setFuture(future);
}
private void bringLockViewBackTopIfNot() {
initScheduleExecutor();
mExecutor.scheduleAtFixedRate(new Runnable() {
#Override public void run() {
LockHelper.INSTANCE.getLockLayer().requestFullScreen();
}
}, 1000, 1000, TimeUnit.MILLISECONDS);
}
private void refreshBatteryInfo() {
initScheduleExecutor();
mExecutor.scheduleAtFixedRate(new Runnable() {
#Override public void run() {
//LockHelper.INSTANCE.getLockView().refreshBattery();
}
}, 2, 2, TimeUnit.MINUTES);
}
private void initScheduleExecutor() {
if (mExecutor == null) {
synchronized (this) {
if (mExecutor == null) mExecutor = new ScheduledThreadPoolExecutor(SCHEDULE_TASK_NUMBER);
}
}
}
public synchronized void shutdownScheduleExecutor() {
if (mExecutor == null) return;
mExecutor.shutdown();
mExecutor = null;
}
}
LockHelper.java
public enum LockHelper implements SwipeEvent {
INSTANCE;
private static Context mContext;
private final int UNLOCK = 830;
private final int UNLOCK_WITH_PASSWORD = 831;
private final int SWITCH_TO_GUEST = 345;
public static final String INIT_VIEW_FILTER = "init view";
public static final String START_SUPERVISE = "start supervise";
public static final String STOP_SUPERVISE = "stop supervise";
public static final String SHOW_SCREEN_LOCKER = "show screen locker";
private static LockView mLockView;
private static LockLayer mLockLayer;
public void initialize(Context context) {
initContextViewAndLayer(context);
loadLockView(context);
}
/**
* #throws NullPointerException if not init
*/
public static LockView getLockView() {
if (mLockView == null)
throw new NullPointerException("init first");
return mLockView;
}
/**
* #throws NullPointerException if not init
*/
public static LockLayer getLockLayer() {
if (mLockLayer == null)
throw new NullPointerException("init first");
return mLockLayer;
}
/**
* #throws NullPointerException if context == null
*/
public void initLockViewInBackground(final Context context) {
if (context == null)
throw new NullPointerException("context == null, assign first");
if (mLockView == null || mLockLayer == null)
initContextViewAndLayer(context);
}
public void initContextViewAndLayer(Context context) {
if (mContext == null)
synchronized (this) {
if (mContext == null)
mContext = context;
}
//init layout view
if (mLockView == null)
synchronized (this) {
if (mLockView == null)
mLockView = new LockView(context);
}
//init lock layer
if (mLockLayer == null)
synchronized (this) {
if (mLockLayer == null)
mLockLayer = LockLayer.getInstance(context, mLockView);
}
}
private volatile boolean mIsInitialized = false;
public void loadLockView(Context context) {
mLockView.showLockHome();
if( !mIsInitialized){
//mLockView.assignSwipeEvent(this);
//
//mLockView.assignDirectionOperator(new SwipeWithAnimListener.DirectionOperator() {
// #Override
// public void up() {
// }
//
// #Override
// public void down() {
//
// }
//
// #Override
// public void left() {
// if(!mLockView.leftSlidable()) return;
//
// mHandler.sendEmptyMessage(UNLOCK);
// }
//
// #Override
// public void right() {
// if(!mLockView.rightSlidable()) return;
//
// mHandler.sendEmptyMessage(UNLOCK);
// }
//});
// mLockView.assignPinCodeRuler(new PinCodeView.UnlockInterface() {
// #Override
// public void onUnlock(String password) {
//
// Message msg = new Message();
// msg.what = UNLOCK_WITH_PASSWORD;
// msg.obj = password;
// mHandler.sendMessage(msg);
// }
//
// #Override
// public void onBack() {
// mLockView.switchBackToCenterFromBottom();
// }
// });
mIsInitialized = true;
}
mLockLayer.lock();
showLockLayer();
}
private Handler mHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UNLOCK:
//DU.sd("handler", "unlock");
unlock();
break;
case UNLOCK_WITH_PASSWORD:
if (!(msg.obj instanceof String)) break;
String password = (String) msg.obj;
switchUserIfExistOrAlertUser(password);
break;
default:
break;
}
}
};
private void unlock() {
mLockLayer.unlock();
//mLockView.stopShimmer();
mContext.sendBroadcast(new Intent(LockHelper.STOP_SUPERVISE));
mContext.sendBroadcast(new Intent(CoreIntent.ACTION_SCREEN_LOCKER_UNLOCK));
}
private void switchUserIfExistOrAlertUser(String password) {
if (TextUtils.isEmpty(password)) {
wrong();
return;
}
if (!password.equals("1234")) {
wrong();
return;
}
unlockScreenAndResetPinCode();
}
private void unlockScreenAndResetPinCode() {
unlock();
// mLockView.resetPinCodeView();
}
private void wrong() {
}
public static final String INTENT_KEY_WITH_SECURE = "with_secure";
#Override
public <S, T> void onSwipe(S s, T t) {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
LockHelper.INSTANCE.getLockLayer().removeLockView();
}
}, 1000);
//triggerCameraWithSecure(mContext, !(t instanceof Boolean) || (Boolean) t);
}
private void triggerCameraWithSecure(Context context, boolean withSecure) {
//if (!CameraHelper.hasCameraHardware(context)) return;
//
//try {
// CameraHelper.cameraStrategy(context, withSecure);
//} catch (Exception e) {
// // may cannot open
// e.printStackTrace();
// showLockLayer();
//}
//
//context.sendBroadcast(new Intent(LockHelper.START_SUPERVISE));
}
private void showLockLayer() {
mLockView.showLockHome();
mLockLayer.bringBackLockView();
}
public void vibrate(long milliseconds) {
if (mContext == null) return;
Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
// Vibrate for 500 milliseconds
v.vibrate(milliseconds == 0 ? 500 : milliseconds);
}
}
There is no problem with the boradcast receiver per se. You have a clear exception in your code
java.lang.ClassCastException: com.happiness.lockscreenlibrary.LockScreenService cannot be cast to android.view.View$OnDragListener at
You are trying to cast an incompatible class type to another. I could not see that part of code in what you pasted here. So, please try to figure that out. Basically the code you are executing on receiving the broadcast has a bug, nothing with the receiver as such

Android surfaceview freezes

I want to create animation on surfaceview.
Here is a surfaceview:
public class AnimationSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private AnimationWorker animationWorker;
private GestureDetectorCompat mGestureDetector;
private OverScroller mScroller;
private Cursor mCursor;
private int pIndexA, pIndexB;
private int dir;
private float posX=0;
public AnimationSurfaceView(Context context, Cursor cursor) {
super(context);
getHolder().addCallback(this);
mCursor = cursor;
mGestureDetector = new GestureDetectorCompat(context, mGestureListener);
mScroller = new OverScroller(context);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
animationWorker = new AnimationWorker(getHolder(), getContext(), null);
animationWorker.setRunning(true);
animationWorker.run();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
animationWorker.setRunning(false);
animationWorker.postTask(null);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
Log.e("sfsfsfdf", "Работает1!!!!!!!!!!!!!!!!!!!");
boolean retVal = mGestureDetector.onTouchEvent(event);
return retVal || super.onTouchEvent(event);
}
#Override
public void computeScroll() {
super.computeScroll();
if(mCursor != null){
int i1 = Math.max(0,Math.min(mCursor.getCount()-1, (int)Math.floor(posX/720f)));
int i2 = Math.max(0,Math.min(mCursor.getCount()-1, (int)Math.ceil(posX/720f)));
if(i1 != pIndexA){
dir = i1-pIndexA;
pIndexA = i1;
pIndexB = i2;
}
}
}
private void updateWorker(){
animationWorker.postTask(new AnimationTask(posX, dir));
AnimationWorker.syncObj.notifyAll();
}
private final GestureDetector.SimpleOnGestureListener mGestureListener
= new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onDown(MotionEvent e) {
mScroller.forceFinished(true);
animationWorker.cancelTaskQueue();
return true;
}
#Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
posX += -distanceX;
updateWorker();
return true;
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
velocityX = - velocityX;
fling(velocityX);
return true;
}
private void fling(float velocity){
mScroller.forceFinished(true);
mScroller.fling((int) posX, 0, (int) -velocity, 0, 0, 720 * (mCursor != null ? mCursor.getCount() : 1), 0, 0);
updateWorker();
}
};
Here is an worker:
public class AnimationWorker extends Thread {
private static final String LOG_TAG = AnimationWorker.class.getSimpleName();
public static final Object syncObj = new Object();
private boolean runFlag = false;
private SurfaceHolder surfaceHolder;
private Context context;
private BlockingQueue<AnimationTask> queue;
private Cursor mCursor;
private AnimationImageCacheHelper animationImageCacheHelper;
private final String ASSET_SUFFIX = "assets://";
private final String FILE_SUFFIX = "file://";
Rect clipRect;
Rect bitmapRect;
Paint paint;
Pair<Bitmap, Bitmap> bitmaps;
int mLeftIndex;
int mRightIndex;
private final Float TRACK_LENTH = 720f;
private final Float MAX_ALPHA = 255f;
public AnimationWorker(
SurfaceHolder surfaceHolder,
Context context,
Cursor cursor){
super();
this.surfaceHolder = surfaceHolder;
this.animationImageCacheHelper = new AnimationImageCacheHelper();
bitmapRect = new Rect();
paint = new Paint();
clipRect = new Rect();
queue = new LinkedBlockingDeque<AnimationTask>();
}
public void setRunning(boolean run){
runFlag = run;
}
public void postTask(AnimationTask task){
try {
queue.put(task);
}catch (Exception e){
//do nothing
}
}
public void cancelTaskQueue(){
queue.clear();
}
#Override
public void run() {
while(runFlag){
Log.e(LOG_TAG, "running");
try {
AnimationTask task = queue.remove();
if(task != null) {
processTask(task);
}
}catch(Exception e){
try {
synchronized (syncObj) {
syncObj.wait();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
Log.e(LOG_TAG, "exception");
e.printStackTrace();
}
}
}
private void processTask(AnimationTask task){
int leftIndex = Math.max(0,Math.min(mCursor.getCount()-1, (int)Math.floor(task.currentPosition/TRACK_LENTH.intValue())));
int rightIndex = Math.max(0,Math.min(mCursor.getCount()-1, (int)Math.ceil(task.currentPosition/TRACK_LENTH.intValue())));
if(mLeftIndex != leftIndex || mRightIndex != rightIndex){
bitmaps = getBitmaps(leftIndex, rightIndex, task.direction);
}
float alpha = (MAX_ALPHA / TRACK_LENTH * task.currentPosition) % MAX_ALPHA;
draw(bitmaps.first, bitmaps.second, alpha);
}
private Pair<Bitmap, Bitmap> getBitmaps(int leftIndex, int rightIndex, int direction){
final Bitmap foregroundBitmap;
final Bitmap backgroundBitmap;
final Pair<Bitmap, Bitmap> result;
if(direction == 1) {
//right on top
if(mCursor.moveToPosition(leftIndex)){
String backgroundImageUrl = mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
backgroundBitmap = loadImage(backgroundImageUrl);
}else{
backgroundBitmap = null;
}
if (mCursor.moveToPosition(rightIndex)){
String foregroundImageUrl = mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
foregroundBitmap = loadImage(foregroundImageUrl);
}else{
foregroundBitmap = null;
}
} else {
//left on top
if(mCursor.moveToPosition(rightIndex)){
String backgroundImageUrl = mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
backgroundBitmap = loadImage(backgroundImageUrl);
}else{
backgroundBitmap = null;
}
if (mCursor.moveToPosition(leftIndex)){
String foregroundImageUrl = mCursor.getString(mCursor.getColumnIndex(PhotoContract.PhotoEntry.COLUMN_PHOTO_URL));
foregroundBitmap = loadImage(foregroundImageUrl);
}else{
foregroundBitmap = null;
}
}
result = new Pair<Bitmap, Bitmap>(foregroundBitmap, backgroundBitmap);
return result;
}
private Bitmap loadImage(String uri){
if(animationImageCacheHelper.isImageContains(uri)){
return animationImageCacheHelper.getBitmap(uri);
}
if (uri.startsWith(ASSET_SUFFIX)) {
Bitmap bitmap = ImageLoader.getInstance().loadImageSync(uri);
animationImageCacheHelper.put(uri, bitmap);
return bitmap;
} else {
Bitmap bitmap = ImageLoader.getInstance().loadImageSync("file://" + uri);
animationImageCacheHelper.put(uri, bitmap);
return bitmap;
}
}
private void draw(Bitmap foreground, Bitmap background, float alpha){
Canvas canvas;
canvas = null;
try {
canvas = surfaceHolder.lockCanvas(null);
canvas.getClipBounds(clipRect);
synchronized (surfaceHolder) {
//draw background
paint.setAlpha(255);
bitmapRect.set(0, 0, background.getWidth(), background.getHeight());
canvas.drawBitmap(background, bitmapRect, clipRect, paint);
//draw foreground
paint.setAlpha((int)alpha);
bitmapRect.set(0, 0, foreground.getWidth(), foreground.getHeight());
canvas.drawBitmap(foreground, bitmapRect, clipRect, paint);
}
}finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
I'm listening onTouch events and add task(current position and direction) for worker. Worker must getting task from queue and draw current state.
In my version nothing happens. Surfaceview freeezes and I need pull battery from my device to unlock it.
*Note: I'm tried use queue.take() - but I get same result

What is wrong with my Game Thread?

I have been trying for a while to implement a Game Thread to utilise a loop to implement logic. I posted a question here not long ago, I hope no one minds the follow up.
I have managed to scrape together this code from my research:
public class GameView extends SurfaceView implements SurfaceHolder.Callback
{
class GameThread extends Thread
{
//states
public static final int STATE_LOSE = 1;
public static final int STATE_PAUSE = 2;
public static final int STATE_READY = 3;
public static final int STATE_RUNNING = 4;
private Paint m_paint;
//canvas dimensions
private int m_canvasWidth;
private int m_canvasHeight;
private long m_lastTime;
private boolean m_run = false;
private int m_mode;
public ImageView ship;
RelativeLayout.LayoutParams shipParams;
// Handle to the surface manager
private SurfaceHolder m_surfaceHolder;
public GameThread(SurfaceHolder surfaceHolder, Context context, Handler handler)
{
m_surfaceHolder = surfaceHolder;
}
//Initialise the game
public void doStart()
{
synchronized (m_surfaceHolder)
{
resetGame();
m_lastTime = System.currentTimeMillis() + 100;
setState(STATE_RUNNING);
ship = (ImageView) findViewById(R.id.imageView1);
shipParams = (RelativeLayout.LayoutParams)ship.getLayoutParams();
}
}
public void pause()
{
synchronized (m_surfaceHolder)
{
if (m_mode == STATE_RUNNING)
setState(STATE_PAUSE);
}
}
#Override
public void run()
{
while (m_run)
{
Canvas c = null;
try
{
c = m_surfaceHolder.lockCanvas(null);
synchronized (m_surfaceHolder)
{
if (m_mode == STATE_RUNNING)
{
updateGame();
}
doDraw(c);
}
}
catch(Exception e){}
finally
{
if (c != null)
{
m_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
public void setRunning(boolean b)
{
m_run = b;
}
public void setState(int mode)
{
synchronized (m_surfaceHolder)
{
setState(mode, null);
}
}
public void setState(int mode, CharSequence message)
{
synchronized (m_surfaceHolder)
{
m_mode = mode;
}
}
public void setPlayers(boolean onePlayer)
{
}
public void setSurfaceSize(int width, int height)
{
synchronized (m_surfaceHolder)
{
m_canvasWidth = width;
m_canvasHeight = height;
}
}
public void unpause()
{
synchronized (m_surfaceHolder)
{
m_lastTime = System.currentTimeMillis() + 100;
}
setState(STATE_RUNNING);
}
private void doDraw(Canvas canvas)
{
canvas.drawARGB(255, 0, 0, 0);
}
private void updateGame()
{
long now = System.currentTimeMillis();
if (m_lastTime > now)
return;
double elapsed = (now - m_lastTime) / 1000.0;
m_lastTime = now;
System.out.print("HELLO WORLD");
shipParams.topMargin++;
ship.setLayoutParams(shipParams);
}
private boolean collided(Rect rectangle)
{
return false;
}
public boolean foundWinner()
{
return false;
}
public void resetGame()
{
}
public void handleInput(MotionEvent event)
{
}
}
private Context m_context;
private GameThread m_thread;
private Handler m_handler;
public GameView(Context context, AttributeSet attrs)
{
super(context, attrs);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
m_handler = new Handler() {
#Override
public void handleMessage(Message m) {
Bundle b = m.getData();
MotionEvent e = b.getParcelable("event");
m_thread.handleInput(e);
}
};
m_thread = new GameThread(holder, context, m_handler);
setFocusable(true);
};
public GameThread getThread()
{
return m_thread;
}
#Override
public void onWindowFocusChanged(boolean hasWindowFocus)
{
if (!hasWindowFocus)
m_thread.pause();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
m_thread.setSurfaceSize(width, height);
}
public void surfaceCreated(SurfaceHolder holder)
{
if(m_thread.getState() == State.TERMINATED)
{
m_thread = new GameThread(getHolder(), m_context, m_handler);
m_thread.setRunning(true);
m_thread.start();
m_thread.doStart();
}
else
{
m_thread.setRunning(true);
m_thread.start();
}
}
public void surfaceDestroyed(SurfaceHolder holder)
{
boolean retry = true;
m_thread.setRunning(false);
while (retry)
{
try
{
m_thread.join();
retry = false;
}
catch (InterruptedException e)
{
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
return true;
}
}
I am fairly certain that my issue lies here and it is merely a logical one. Everything does seem fine to me, however and I am in need of assistance.
I have attempted to draw an image at line 47 and defined a movement to take place in the update method at line 153. I also have placed a print line for extra debug, but the line doesn't show.
I am stumped.
Any help would be great, thanks.
Here are my other codes, if neccessary:
MainActivity.java
GameSetup.java
game_setup.xml
edit: I should note that I'm not getting any kind of errors within the code, it merely doesn't respond
You are initializing m_run as false,then in the while cycle in the run() method you must have set to true. Change it to true and the thread will work normally.
set m_run to true in your doStart() procedure

Categories

Resources