Android(andengine)中的确认对话框

Posted

技术标签:

【中文标题】Android(andengine)中的确认对话框【英文标题】:Confirmation Dialog in Android (andengine) 【发布时间】:2014-08-20 07:35:34 【问题描述】:

我正在开发一个 android 应用程序,并试图弄清楚如何在按下按钮时显示一个带有确认和取消按钮的弹出确认窗口。

这是警报的创建。

final AlertDialog.Builder alertBuilder = new AlertDialog.Builder(activity);
    alertBuilder.setTitle("Your Title");
    alertBuilder.setMessage("Your Messages");
    alertBuilder.setPositiveButton("Confirm", new OnClickListener() 
        public void onClick(DialogInterface dialog, int whichButton) 
            // Do something with value!

        
    );

    alertBuilder.setNegativeButton("Cancel", new OnClickListener() 
        public void onClick(DialogInterface dialog, int whichButton) 
            // Canceled.
        
    );

这是显示的调用。

 Sprite p2 = new Sprite(goldMult, 25, 450, WIDTH, HEIGHT,
            resourceManager.spriteRegion, vbom) 

        /**
         * @see org.andengine.entity.shape.Shape#onAreaTouched(org.andengine.input.touch.TouchEvent, float, float)
         */
        @Override
        public boolean onAreaTouched(final TouchEvent sceneTouchEvent, final float touchAreaLocalX,
                final float touchAreaLocalY) 

            AlertDialog alert = alertBuilder.create(); 
            alert.show();

我遇到了这个异常: java.lang.RuntimeException:无法在未调用 Looper.prepare() 的线程内创建处理程序

我看到了一个类似问题的帖子here

但是,我对如何使用我的 onAreaClicked 事件来实现这一点感到困惑。 感谢您在高级方面的任何帮助

【问题讨论】:

我通过在我的 onAreaTouched 方法中将警报包装在一个新线程中来解决我的问题 【参考方案1】:

andengine 使用 opengl,因此您可能需要创建一个处理程序来在 opengl 线程上执行您的对话框

public Handler handler; 

然后

handler = new Handler() 
            @Override
            public void handleMessage(Message msg) 
                switch (msg.what) 
                case 0:
                AlertDialog alert = alertBuilder.create(); 
                alert.show();
                break;

;

然后使用它

handler.sendMessage(Message.obtain(handler, 0));

类似的东西

编辑:使用looper处理程序的类准备opengl

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import java.net.MalformedURLException;
import java.nio.IntBuffer;
import java.util.List;


import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;


import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.FacebookError;
import com.facebook.android.Facebook.DialogListener;

import pic.puzzle.framework.Audio;
import pic.puzzle.framework.FileIO;
import pic.puzzle.framework.Game;
import pic.puzzle.framework.Graphics;
import pic.puzzle.framework.Input;
import pic.puzzle.framework.Screen;
import pic.puzzle.picturepuzzle.GameOverScreen;
import pic.puzzle.picturepuzzle.GameOverScreenCustom;
import pic.puzzle.picturepuzzle.PicturePuzzleScreen;
import pic.puzzle.picturepuzzle.PuzzleScreen;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.net.Uri;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;

import android.view.Window;
import android.view.WindowManager;

import android.widget.Toast;


public abstract class GLGame extends Activity implements Game, Renderer 
    enum GLGameState 
        Initialized,
        Running,
        Paused,
        Finished,
        Idle
    


    GLSurfaceView glView;    
    GLGraphics glGraphics;
    Audio audio;
    Input input;
    FileIO fileIO;
    Screen screen;
    GLGameState state = GLGameState.Initialized;
    Object stateChanged = new Object();
    long startTime = System.nanoTime();
    WakeLock wakeLock;
    public static Bitmap lastscreenshot;
    public static boolean screenshot = false,finish = false;
   public static int width, height;
    public static Handler handler; 
    public static boolean share = false;
    String APP_ID = ("567944629883125");
    public Facebook fb;
    public byte[] data;
    public static int custom = 0;
    public Uri uri;
    String here;

    @SuppressLint("HandlerLeak")
    @SuppressWarnings("deprecation")
    @Override 
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                             WindowManager.LayoutParams.FLAG_FULLSCREEN);
        glView = new GLSurfaceView(this);
        glView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0);
        glView.setRenderer(this);
        setContentView(glView);
        fb = new Facebook(APP_ID);
        glGraphics = new GLGraphics(glView);
        fileIO = new AndroidFileIO(getAssets());
        audio = new AndroidAudio(this);
        input = new AndroidInput(this, glView, 1, 1);
        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLGame");
        handler = new Handler() 
            @Override
            public void handleMessage(Message msg) 
                switch (msg.what) 
                case 0:


                    if(custom == 0)
                    uri = GameOverScreen.pngUri;
                    else if(custom == 1)
                        uri = GameOverScreenCustom.pngUri;


                    if(custom == 0)
                         here = "Moves: " + GameOverScreen.moves + "   " + "Time: " + GameOverScreen.time;
                    else if(custom == 1)
                        here = "Moves: " + GameOverScreenCustom.moves + "   " + "Time: " + GameOverScreenCustom.time;

                    Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
                    shareIntent.setType("text/plain");



                    shareIntent.putExtra(android.content.Intent.EXTRA_TEXT,
                            here);
                    shareIntent.setType("image/png");
                    shareIntent.putExtra(android.content.Intent.EXTRA_STREAM,
                                    uri); //Share the image on Facebook
                    PackageManager pm = getApplicationContext().getPackageManager();
                    List<ResolveInfo> activityList = pm.queryIntentActivities(
                                        shareIntent, 0);
                    for (final ResolveInfo app : activityList) 
                        if ((app.activityInfo.name).contains("facebook")) 
                            final ActivityInfo activity = app.activityInfo;
                            final ComponentName name = new ComponentName(
                                        activity.applicationInfo.packageName,
                                        activity.name);
                            shareIntent.addCategory(Intent.CATEGORY_LAUNCHER);
                            shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
                            shareIntent.setComponent(name);
                            startActivity(shareIntent);
                            break;
                                
                            
                
            
        ;
    

    public void onResume() 
        super.onResume();
        glView.onResume();
        wakeLock.acquire();
    

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config)         
        glGraphics.setGL(gl);

        synchronized(stateChanged) 
            if(state == GLGameState.Initialized)
                screen = getStartScreen();
            state = GLGameState.Running;
            screen.resume();
            startTime = System.nanoTime();
                
    

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height)  
        GLGame.width = width;
        GLGame.height = height;
    

    @Override
    public void onDrawFrame(GL10 gl)                 
        GLGameState state = null;
        if(finish)
            finish = false;
            finish();
        
        if(share)  
            share = false;
           handler.sendMessage(Message.obtain(handler, 0));

        

        synchronized(stateChanged) 
            state = this.state;
        

        if(state == GLGameState.Running) 
            float deltaTime = (System.nanoTime()-startTime) / 1000000000.0f;
            startTime = System.nanoTime();

            screen.update(deltaTime);
            screen.present(deltaTime);
            if(screenshot)                     
                lastscreenshot = SavePixels(0,0,width,height,gl);
                lastscreenshot = Bitmap.createScaledBitmap(lastscreenshot, 320, 480, true);


                screenshot = false;
             

        

        if(state == GLGameState.Paused) 
            screen.pause();            
            synchronized(stateChanged) 
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
            
        

        if(state == GLGameState.Finished) 
            screen.pause();
            screen.dispose();
            synchronized(stateChanged) 
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
                        
        

     


    @Override 
    public void onPause()         
        synchronized(stateChanged) 
            if(isFinishing())            
                state = GLGameState.Finished;
            else
                state = GLGameState.Paused;
            while(true) 
                try 
                    stateChanged.wait();
                    break;
                 catch(InterruptedException e)          
                
            
        
        wakeLock.release();
        glView.onPause();  
        super.onPause();
     
    @Override
    public void onDestroy()
        if(lastscreenshot != null)
        lastscreenshot.recycle();
        if(PicturePuzzleScreen.pic != null)
        PicturePuzzleScreen.pic.recycle();

        if(GameOverScreen.finalbitmap != null)
        GameOverScreen.finalbitmap.recycle();
        if(GameOverScreenCustom.finalbitmap != null)
        GameOverScreenCustom.finalbitmap.recycle();
        System.gc();
        super.onDestroy();
    
    public static Bitmap SavePixels(int x, int y, int w, int h, GL10 gl)
      
         int b[]=new int[w*(y+h)];
         int bt[]=new int[w*h];
         IntBuffer ib=IntBuffer.wrap(b);
         ib.position(0);
         gl.glReadPixels(x, 0, w, y+h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);

         for(int i=0, k=0; i<h; i++, k++)
         //remember, that OpenGL bitmap is incompatible with Android bitmap
          //and so, some correction need.        
              for(int j=0; j<w; j++)
              
                   int pix=b[i*w+j];
                   int pb=(pix>>16)&0xff;
                   int pr=(pix<<16)&0x00ff0000;
                   int pix1=(pix&0xff00ff00) | pr | pb;
                   bt[(h-k-1)*w+j]=pix1;
              
         


         Bitmap sb=Bitmap.createBitmap(bt, w, h, Bitmap.Config.RGB_565);
         return sb;
    


    public GLGraphics getGLGraphics() 
        return glGraphics;
      

    @Override
    public Input getInput() 
        return input;
    

    @Override
    public FileIO getFileIO() 
        return fileIO;
    

    @Override
    public Graphics getGraphics() 
        throw new IllegalStateException("We are using OpenGL!");
    

    @Override
    public Audio getAudio() 
        return audio;
    

    @Override
    public void setScreen(Screen screen) 
        if (screen == null)
            throw new IllegalArgumentException("Screen must not be null");

        this.screen.pause();
        this.screen.dispose();
        screen.resume();
        screen.update(0);
        this.screen = screen;
    

    @Override
    public Screen getCurrentScreen() 
        return screen;
      
    @SuppressWarnings("deprecation")
    @Override
    protected void onActivityResult(int requestCode,int resultCode,Intent data)
    
        super.onActivityResult(requestCode, resultCode, data);
        fb.authorizeCallback(requestCode, resultCode, data);
    


【讨论】:

我试图这样做并得到同样的错误。 java.lang.RuntimeException:无法在未调用 Looper.prepare() 的线程内创建处理程序 生病发布整个课程,我实际上是从 onDrawFrame 方法调用它,使用布尔值来实际触发它,这就是我能为你做的一切,对不起,希望你明白【参考方案2】:

我通过将警报包装在一个新线程中找到了答案

activity.runOnUiThread(new Runnable() 
                @Override
                public void run() 

                    AlertDialog.Builder alert = new AlertDialog.Builder(activity);
                    alert.setTitle("");
                    alert.setMessage("");
                    alert.setPositiveButton("Buy", new OnClickListener() 
                        @Override
                        public void onClick(DialogInterface arg0, int arg1) 

                        
                    );
                    alert.setNegativeButton("Cancel", new OnClickListener() 
                        @Override
                        public void onClick(DialogInterface arg0, int arg1) 

                        
                    );

                    alert.show();
                
            );

【讨论】:

以上是关于Android(andengine)中的确认对话框的主要内容,如果未能解决你的问题,请参考以下文章

Android 手机卫士--确认密码对话框编写

Android Andengine 背景音乐自动复制

iOS Spritekit 和 Android Andengine 之间的物理标准化

如何在eclipse里导入android游戏引擎,例如ANGEL、ANDENGINE之类的

Android:拍摄相机图片意图删除确认对话框

在 Android 9 上绕过 android usb 主机权限确认对话框