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
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.
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(); }
}
}
}
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
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
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