安卓手机摇一摇功能的实现

春节期间,摇一摇抢红包很好的推广了微信摇一摇功能。
现在我们来实现一个摇一摇抢优惠券的功能。

需求概述

用户登录之后才能参加活动。
进入活动之后,每人每天有三次摇一摇机会。
根据服务器返回的中奖结果显示不同的对话框。
大概如图:
摇一摇对话框

界面实现

我们根据设计给出的资源,先把活动涉及到的几个界面给画出来。
主界面:
主界面
tips:
tips
dialog:
dialog

功能实现

核心功能其实很简单,就是根据传感器返回的数据来判断用户是否在摇手机,然后根据相应的情况进行处理。
还要加上一个摇一摇的动画。

传感器的使用

注册传感器:

private SensorManager sensor;
sensor = (SensorManager) this.getSystemService(Service.SENSOR_SERVICE);
sensor.registerListener(shakelistener,  
                        sensor.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),  
                        SensorManager.SENSOR_DELAY_NORMAL);

sensor.unregisterListener(shakelistener);//解除监听

监听器:

    public class ShakeListenerUtils implements SensorEventListener
    {
        public ShakeListenerUtils()
        {
            super();
        }

        @SuppressLint("ShowToast")
        @Override
        public void onSensorChanged(SensorEvent event)
        {
            int sensorType = event.sensor.getType();

            if (sensorType == Sensor.TYPE_ACCELEROMETER)
            {

                //values[0]:X轴,values[1]:Y轴,values[2]:Z轴  
                float[] values = event.values;

                /*正常情况下,任意轴数值最大就在9.8~10之间,只有在突然摇动手机 
                  的时候,瞬时加速度才会突然增大或减少。监听任一轴的加速度大于19即可
                */

                if ((Math.abs(values[0]) > 15 || Math.abs(values[1]) > 15 || Math
                        .abs(values[2]) > 15))
                {
                    startAnim ();

                }
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy)
        {
            //当传感器精度改变时回调该方法,Do nothing. 
        }

    }

添加动画和震动

自定义动画:
        public void startAnim () {   //定义摇一摇动画动画  
            AnimationSet animup = new AnimationSet(true);  
            CustomerAnimation customerAnimation=new CustomerAnimation();
            customerAnimation.setDuration(1000);
            customerAnimation.setAnimationListener(this);
            animup.addAnimation(customerAnimation);

            handImageView.startAnimation(animup);  

        }

    class CustomerAnimation extends Animation {
          private int mWaveTimes=5;//摇摆次数
          private int mWaveRange=50;//摇摆幅度
          public CustomerAnimation(){
          }
          public CustomerAnimation(int waveTimes,int waveRange){
            mWaveTimes = waveTimes;
            mWaveRange = waveRange;
          }

          @Override
          protected void applyTransformation(float interpolatedTime,
              Transformation t) {
            //运用周期性函数,实现左右摇摆
            t.getMatrix().setTranslate((int)(Math.sin(interpolatedTime*Math.PI*mWaveTimes)*mWaveRange),0);
          }
        }
添加震动

震动我们就加在动画开始的部分吧。
让活动继承
AnimationListener
接口,然后分别实现

onAnimationStart
onAnimationEnd
onAnimationRepeat

于是我们只要这样做就行了:

    @Override
    public void onAnimationStart(Animation animation) {
        // TODO Auto-generated method stub
        vibrator.vibrate(200);
//      系统提示音
//      Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);  
//        Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);  
//        r.play(); 
    }

震动两秒,一行代码就够了。
对了别忘了注册vibrator:

private Vibrator vibrator;
vibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);

其实我们也可以在这个发出个声音,我直接调用了系统的提示音,去掉注释就能用了。

添加dialog

在动画结束的时候,我们弹出对话框。
并且根据情况设置不同的文字。

初始化dialog
    private AlertDialog alertDialog;
    private Builder builder;
        builder=new Builder(ShakeActivity.this);
        alertDialog=new Builder(this).create();
重写onAnimationEnd()
    @Override
    public void onAnimationEnd(Animation animation) {
        // TODO Auto-generated method stub

        alertDialog.setCancelable(false);
        alertDialog.setCanceledOnTouchOutside(false);
        alertDialog.show();
        Window window=alertDialog.getWindow();
        window.setContentView(R.layout.dialog_view);

        shake_pop_face=(ImageView) window.findViewById(R.id.shake_pop_face1);
        dialog_textView=(TextView) window.findViewById(R.id.dialog_textView);

        dialog_button=(Button) window.findViewById(R.id.dialog_button);
        dialog_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                alertDialog.dismiss();
                sensor.registerListener(shakelistener,  
                        sensor.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),  
                        SensorManager.SENSOR_DELAY_NORMAL);
            }
        });
        sensor.unregisterListener(shakelistener);

        ArrayList<String> failure1=new ArrayList<String>();
        failure1.add("不信邪?再来一次");
        failure1.add("慢点“我晕”,再试一次");
        failure1.add("换一只手,试一试");
        failure1.add("别气馁,好运还在后头");
        failure1.add("死了都要摇,再来一次");
        failure1.add("摇劲不够,再猛烈一些");

        ArrayList<String> failure2=new ArrayList<String>();
        failure2.add("哭了,小编你个坑货!明天再来吧");
        failure2.add("多做好事积攒RP,明天再来吧!");
        failure2.add("再摇,再努力!明天继续");
        failure2.add("至少还有明天~~");
        failure2.add("生命不息,摇奖不止");

        ArrayList<String> success=new ArrayList<String>();
        success.add("摇劲足矣,5元给您!快去“我的优惠券”查看吧");
        success.add("运气来了,挡也挡不住!5元给您!");
        success.add("哟,恭喜得5元“票”子,快去“我的优惠券”查看");

        //中奖的情况
        if (shakeCounts>0&&checkBoxWin.isChecked()) {
            shakeCounts--;
            shakeTimesTextView.setText("今天您还可以摇"+shakeCounts+"次");
            if (isWon) {
                //已经中过奖了,但是次数未用完
                dialog_textView.setText("亲,留点机会给别人吧!");
                dialog_button.setText("知道了");
                shake_pop_face.setImageResource(R.drawable.shake_pop_face5);
            } else {
                isWon=true;
                dialog_textView.setText(success.get(
                        (int) ((Math.random()*100)%success.size())
                        ));
            }
            return;
        }

        //没中奖的情况
        if (shakeCounts>0&&!checkBoxWin.isChecked()) {
            shakeCounts--;
            shakeTimesTextView.setText("今天您还可以摇"+shakeCounts+"次");
            if (shakeCounts==0) {
                //三次全没中
                dialog_textView.setText(failure2.get(
                        (int) ((Math.random()*100)%failure2.size())
                        ));
                dialog_button.setText("明天再来吧");
                shake_pop_face.setImageResource(R.drawable.shake_pop_face3);
            } else {
                dialog_textView.setText(failure1.get(
                            (int) ((Math.random()*100)%failure1.size())
                            ));
                dialog_button.setText("再来一次");
                shake_pop_face.setImageResource(R.drawable.shake_pop_face2);
            }
            return;
        }

        //次数用完
        if (shakeCounts<=0){
            dialog_textView.setText("亲,每天只有三次机会哦~");
            dialog_button.setText("知道了");
            shake_pop_face.setImageResource(R.drawable.shake_pop_face4);
            return;
        }
    }

dialog出现之后,执行了这个:
sensor.unregisterListener(shakelistener);
这样是为了防止用户在已经出现dialog的情况下继续摇,使得dialog重叠。
然后在点击了dialog中的button之后再重新注册,确保只能摇出一个dialog。
防止用户不点击button,于是使用了

alertDialog.setCancelable(false);
alertDialog.setCanceledOnTouchOutside(false);

至此,离线版的摇一摇功能基本实现。

完成效果图:

摇一摇

代码地址:

https://code.csdn.net/u012591761/shake

实际运用

现在完成的这玩意只能自个儿摇着玩,怎么放到实际运用中呢?

根据接口发送请求

确定好业务逻辑,我要发送的数据和公共服务返回数据格式之后,开始吧!
实体类:

public class ResponseSpecialEasyBean extends BaseResponseBean {
    private SpecialDetail detail;

    public class SpecialDetail{
            private String actionsCount;//每天每人已经参加的活动次数
            private String sumCount;//每天每人总次数
            private String skakeCount;//中奖次数
}
}

执行类:

public class MySpecialUtil extends JsonParseBaseUtil{

    private Context context;
    private Handler handler;
    private ResponseSpecialBean responseSpecialBean;
    private ResponseSpecialEasyBean responseSpecialEasyBean;

    public MySpecialUtil(Context context, Handler handler) {
        super();
        this.context = context;
        this.handler = handler;
    }

    public void getMemberShakeActions() {
        // TODO Auto-generated method stub
        new Thread() {
            public void run() {
                handler.sendEmptyMessage(HandlerCASE.MSG_DIALOG_SHOW);
                    try {
                        JSONObject object1 = new JSONObject();
                        JSONObject reqStr = new JSONObject();

                        object1.put("orderSourceId", Constant.orderSourceId);
                        object1.put("userId", Constant.userId);
                        object1.put("orderChannel", Constant.orderChannel);
                        object1.put("mobilePhoneModel", android.os.Build.MODEL);

                        reqStr.put("cmd", "getMemberShakeActions");
                        reqStr.put("params", object1);
                        String request = formatJson(reqStr.toString());

                        String response = "";
                        try {
                            response = NetManager.getInstance(context)
                                    .dopostAsString(Constant.BASE_TEST_URL,
                                            request);
                            Log.i("shake", response);
                        } catch (Exception e) {
                            // TODO: handle exception
                            handler.sendEmptyMessage(HandlerCASE.MSG_NET_ERROR);
                            handler.sendEmptyMessage(HandlerCASE.MSG_DIALOG_CANL);
                            return;
                        }

                        setResponseSpecialEasyBean(getGson().fromJson(response,
                                ResponseSpecialEasyBean.class));

                        handler.sendEmptyMessage(HandlerCASE.MSG_DONE);
                        handler.sendEmptyMessage(HandlerCASE.MSG_DIALOG_CANL);
                    } catch (Exception e) {
                        // TODO: handle exception
                        handler.sendEmptyMessage(HandlerCASE.MSG_FAIL);
                        handler.sendEmptyMessage(HandlerCASE.MSG_DIALOG_CANL);
                    }
            };
        }.start();
    }

启了一个线程向接口发送请求,并将返回的数据封装到实体类中。

设置handle

    Handler handler=new Handler(){
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case HandlerCASE.MSG_DIALOG_SHOW:
                showLoadingDialog(false);
                break;
            case HandlerCASE.MSG_DIALOG_CANL:
                cancelLoadingDialog(false);
                break;
            case HandlerCASE.MSG_NET_ERROR:
                tip(Constant.responseExceptionError);
                break;
            case HandlerCASE.MSG_FAIL:
                tip(Constant.responseError);
                break;
            case HandlerCASE.MSG_DONE:
                ResponseSpecialEasyBean responseSpecialEasyBean=mySpecialUtil.getResponseSpecialEasyBean();
                actionsCount=Integer.parseInt(responseSpecialEasyBean.getSpecialDetail().getActionsCount());
                shakeCount=Integer.parseInt(responseSpecialEasyBean.getSpecialDetail().getSkakeCount());
                sumCount=Integer.parseInt(responseSpecialEasyBean.getSpecialDetail().getSumCount());
                shakeTimesTextView.setText("今天您还可以摇"+(sumCount-actionsCount)+"次");
//              showShakeDialog();
                break;
            case HandlerCASE.MSG_DONE_SECOND:
                ResponseSpecialBean responseSpecialBean=mySpecialUtil.getResponseSpecialBean();
                responseSpecialBean.getSpecialDetail();
                actionsCount=Integer.parseInt(responseSpecialBean.getSpecialDetail().getCountDetail().getActionsCount());
                shakeCount=Integer.parseInt(responseSpecialBean.getSpecialDetail().getCountDetail().getSkakeCount());
                sumCount=Integer.parseInt(responseSpecialBean.getSpecialDetail().getCountDetail().getSumCount());
                bonus=responseSpecialBean.getSpecialDetail().getBonus();
                shakeTimesTextView.setText("今天您还可以摇"+(sumCount-actionsCount<0?0:sumCount-actionsCount)+"次");
                showShakeDialog();
                break;
                }
        }
    };

重构代码

将原来onAnimationEnd()中的代码提取出来,叫做showShakeDialog()
重写onAnimationEnd()

    @Override
    public void onAnimationEnd(Animation animation) {
    mySpecialUtil.getMemberActions();
    }

动画结束的时候发送请求,然后根据返回结果弹出相应的对话框。
至此,功能全部实现了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值