0

Could anybody tell me how can I get to display an image with the sound ... I want to display an image for a few seconds just as the sound is played ... I am new to this and cant figure out. I can individually get the image or the sound but not both combined.

enter code here

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;

public class GunBlood extends Activity implements OnClickListener,
    OnLongClickListener {
Disp d;
SoundPool sp, sp2;
float y = 0, x = 0;
int ex = 0, sg = 0, f = 0;
Bitmap blood;
Canvas canvas;
View v;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    d = new Disp(this);
    v= new View(this);
    setContentView(d);
    d.setOnClickListener(this);
    d.setOnLongClickListener(this);
    blood = BitmapFactory.decodeResource(getResources(), R.drawable.blood);
    sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
    ex = sp.load(this, R.raw.gun, 1);
    sp2 = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
    sg = sp2.load(this, R.raw.sgun, 1);
}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    if (ex != 0) {
        if (f == 0)
            sp.play(ex, 1, 1, 0, 0, 1);
        f = 0;
    }
    x = v.getX();
    y = v.getY();
    }

@Override
public boolean onLongClick(View v) {
    // TODO Auto-generated method stub
    if (sg != 0)
        sp2.play(ex, 1, 1, 0, 0, 1);
    f = 1;
    return false;
}

public class Disp extends View {

    public Disp(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);

        if (x != 0 && y != 0) {
            canvas.drawBitmap(blood, (blood.getWidth() / 2),
                    (blood.getHeight() / 2), null);
        }

        invalidate();
    }
}
}

1 Answers1

0

I asked a similar question here about how to make an ImageView invisible and then visible, which may be able to apply.

You could use this to execute a block of code after a certain amount of time:

blood.setVisibility(View.VISIBLE); //make the image invisible
blood.postDelayed(new Runnable() {
    @Override
    public void run() {
         blood.setVisibility(View.INVISIBLE); //make the image visible
    }
}, 3000); //the 3000 is the amount of milliseconds until the code executes, so 3 seconds. 

sp.play(ex, 1, 1, 0, 0, 1);
sp.postDelayed(new Runnable() {
    @Override
    public void run() {
      if (sg != 0)
        sp.stop()//I have no idea if this is the right code, I'm not very familiar with SoundPool
        f = 1;
      }
}, 3000);

I am not sure if the two postDelayed methods will run at the same time, or one will delay the other, although I think they will run at the same time.

You could also use an animation for the image, and the postDelayed for the sound. The animation aspect is VERY well described by Xyresic in his answer of my question, the link is below.

The question I asked is at Pause Between Making ImageView Invisible and Visible Android

If I have something wrong here or this can be improved, let me know. I am also still a beginner and am still learning. I would gladly take the corrections.

Hope this helps!

EDIT


use:
android:Clickable="true"
android:onClick="methodYouWantCalled"

In your XML file for your button or whatever object, it will go to that method in the class file which has that XML file as its layout. Just be sure that the method is

public static void methodYouWantCalled(View view){
//code here
}

It needs to have View view in the parameters and it needs to be public.

Hope this works for you!

EDIT


So, your next two problems are that the image always shows up at the top of the screen, and there is a significant delay while the picture loads.

  1. If the image is always displaying in the top-left corner, then you can either move the image in your layout, or switch layouts. I am assuming you are using the Android SDK in eclipse. What you can do, is go to your XML file, and press 'Graphical Layout'. There, you can drag the image to where you want it. I believe that editing the placement of objects is easier in XML, and is less likely to have any bugs. If dragging the image around the screen to where you want it does not work, or it messes up your placement of other things, here are some things you can try.

    • Edit the placement in the actual XML code.

If you go into the XML code for your ImageView, you should see a line that says: android:layout_marginLeft="something"

if you replace the 'something' with a value such as 200dp (density pixels, the same for each device) you can move it to wherever you want. You can do this with marginLeft, marginRight, marginBottom and marginTop. If you play around with the density pixels, you should be able to get it in the right place. Here's an example.

XML

<!--Up here is all the basic stuff like the id. I am just making up these values -->
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_marginLeft="200dp"
android:layout_marginBottom="600dp"
android:Clickable="true"
android:onClick="methodToBeCalled"

The first 4 lines size and place your object. Using the height and margins and so on, you should be able to place it where you want.

  • Change Layouts

If you have a lot of things on the screen, you can change to a relative layout and have them be placed corresponding to one another. So say you had a TextView with the id of myTextView at the top left. You can then, using the relative layout, position your picture to the right of that using:

android:layout_toRightOf="myTextView"

This will only work, however, if you have many items on your screen.

2) I am not sure about your image taking a while to load, but I can give it a shot.

There are a few possible reasons.

  • It is a large file, and needs time to process (unlikely for a single picture)

  • The app is doing multiple things at once, and is using up all the phone's RAM (unlikely, since this sounds like a relatively simple app)

  • Something is preventing it from running right away (e.g., a Thread.sleep(); command.)

There are solutions to all of them, with a varying degree of difficulty.

For the first possible problem, you could control load times by pre-loading your resources during the splash activity, or in a loading screen before the activity. There is a nice tutorial on it here.

For the second possible problem, you would need to minimize what is being processed, to give more RAM to the main task. I have almost no experience with this, so I can't really help you there. HOWEVER, this is EXTREMELY unlikely, seeing as how phones have so much processing power.

For the final possible problem, you just need to make sure that you don't have anything like that in the app. I shy away from them because I really don't like working with threads. You could try to use a postDelayed instead.

Hope it works! Comment if you come by any more problems.

EDIT


I have found some other Stack Overflow posts about this, namely Android - setting X,Y of image programmatically and android sdk set imageview x y coordinates. The only problem is that I am not sure if the AbsouluteLayout is still just depreciated, or gone. Either way it should be replaced when it is fully removed, and you can use the replacement. I believe it is still just depreciated, so we should be able to use it. I like your idea of getting the x and y and using those, and we can still do that. Check out those posts, along with Android setX() and setY() behaving weird, and you should be ready to go. If you use the margin method (in the java code), you should be able to create a simple algorithm to calculate the margin size based on your given coordinates.

Hope that works too!

Community
  • 1
  • 1
  • I have set blood to the imageview now instead of a bitmap. And I have setcontentview to the new xml file containing the imageview. Now the issue is that I cannot use the onclicklisteners as they need the setcontent view to be with v. – Bhargav Mehta May 20 '14 at 07:58
  • CASE 1 : So if I setcontentView to the xml file with the imageview I can see the image but cannot play the sound through the onclicklisteners. Case 2: if I setcontentView to the view, I can play the sound but I cannot put any reference to imageview or the app crashes. – Bhargav Mehta May 20 '14 at 08:08
  • Instead of using the onclick listeners, use android:onClick="methodName" in your XML file, so when the button is clicked it will call the method methodName. Put all the code you want execute in there. Just make sure methodName is public. – SplatFace Development May 20 '14 at 10:45
  • I added an update to my original answer with more information – SplatFace Development May 20 '14 at 10:50
  • Yes, It did Kind of work ... thanks :) But I have two more related issue if u can help. ISSUE 1 : The Image is always displayed in the top left corner of the screen bur i want it to be displayed at the point of touch. I was going to use the following code x = v.getX(); y = v.getY(); blood.setX(x); blood.setY(y); But this does not work with the custom method. Any other way I can get it at the preferred spot. – Bhargav Mehta May 20 '14 at 15:14
  • ISSUE 2: This is more of a question. The image appears and disappears in 2 secs(I set it to 2), however sometimes it takes time to load. It is not a very high res pic. Any solutions ?? – Bhargav Mehta May 20 '14 at 15:19
  • For your first question, you can try to move it around (if you are using eclipse) in the gui to where you want it. You can also try to switch layouts and see if that helps. I can give you more info once i get to my computer later today (I am on my phone now) – SplatFace Development May 20 '14 at 19:13
  • For your second question, you can try to use the resource folder and load your resources before your app starts (during splash screen). Again, I can help you more when I get to my computer later today, as I am using my phone now – SplatFace Development May 20 '14 at 19:15
  • I wil be updating my answer now. – SplatFace Development May 20 '14 at 22:34
  • Thanks again for the solutions ... I understood the xml concept, however by doing that, the image will be still at a fixed location. What I want is to display it at a location where I have clicked or touched, which may not be fixed. I want to select the location of image dynamically instead of a fixed location, So for that i retrieved the co-ordinates X and Y using v.getX and v.getY in the method and tried to position the image to those co-ordinates by using setX and setY on the imageview. But this does not work. – Bhargav Mehta May 21 '14 at 07:50
  • I updated my post, giving you more information about how to place the image where you want. Also, don't forget to accept the answer so that people know that it worked for your original question. It also gives us both some reputation. Thanks! Hope my edit helps! – SplatFace Development May 21 '14 at 10:42