开发者社区> 技术小阿哥> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

[Android]开发摇一摇分歧表决器过程

简介:
+关注继续查看

 心血来潮,走进Android,准备开发一个摇一摇分歧表决器(PS:这个想法源自去年看的一个都市剧《约会专家》中主人公杭杭开发的分歧表决器APP)。


   简述:摇一摇分歧表决器是一款Android App,通过将传统的手头剪刀布分歧表决游戏移植到智能手机上,玩家可以通过摇动手机还获取结果,PK对家。 (汗!)

   目标:一款简单,易用的Android分歧表决App

   设备要求:加速传感器,Android系统

   涉及知识点:Android ImageView,TextView,RelativeLayout,Sensor,Vibrator,SoundPool

   

   开始动手:

1.在Eclipse中创建Android 项目

2.准备资源文件,石头,剪刀,布,和玩法示意图,AppIcon四张图片,结果提示音(mp3)

3.创建布局文件(activity_splitter.xml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <ImageView
        android:id="@+id/image_result"
        android:layout_width="match_parent"
        android:layout_height="375dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:contentDescription="@string/image_desc_msg"
        android:scaleType="fitXY"
        android:scrollbars="none"
        android:src="@drawable/rules" />
    <TextView
        android:id="@+id/text_msg"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/image_result"
        android:layout_centerVertical="true"
        android:layout_marginTop="50dp"
        android:gravity="center_horizontal"
        android:text="@string/user_method_msg"
        android:textStyle="bold" />
</RelativeLayout>

      

4.实现思路

  4.1启动App,在ImageView中展示玩法图片,TextView显示玩法说明;

  4.2玩家摇动手机,应用程序通过加速传感器获得手机加速度,当加速度达到指定范围,发送更新UI界面消息;

  4.3通过消息处理机制,更新UI界面,在ImageView中展示结果图片(石头,剪刀,布三者之一),TextView显示对应的文字说明,并伴随提示音和轻微震动。


5.开发实现

  5.1该应用极其简单,仅有一个Activity,在ApplicationManifest.xml中配置启动界面

  

1
2
3
4
5
6
7
8
9
<activity
            android:name=".SplitterActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    

  5.2应用程序使用到设备的震动,在ApplicationManifest.xml中配置权限

 

1
<uses-permission android:name="android.permission.VIBRATE" />

  

  5.3具体开发Activity

  

    需要熟悉:SensorManager,Sensor,SoundPool,Handler这几个类的使用,自己实现SensorEventListener接口方法,如下onSensorChanged,onAccuracyChanged方法。

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
public class SplitterActivity extends Activity implements SensorEventListener {
 
    private ImageView imageViewResult;
 
    private TextView textViewMsg;
 
    private int[][] result = new int[][] {
            { R.drawable.rock, R.string.rock_result_msg },
            { R.drawable.paper, R.string.paper_result_msg },
            { R.drawable.scissors, R.string.scissors_result_msg } };
 
    private SensorManager sensorManager;
 
    private Sensor sensor;
 
    private Vibrator vibrator;
 
    private SoundPool soundPool;
 
    private int streamSoundId;
 
    private static final int UPDATE_VIEW = 0x01;
 
    private Handler handler = new Handler() {
 
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == UPDATE_VIEW) {
                if (vibrator.hasVibrator()) {
                    vibrator.vibrate(new long[] { 200L, 500L }, -1);
                }
                soundPool.play(streamSoundId, 0.5F, 0.5F, 501.0F);
 
                Random random = new Random();
                int index = random.nextInt(result.length);
                imageViewResult.setImageResource(result[index][0]);
                textViewMsg.setText(result[index][1]);
            }
        }
    };
 
    public SplitterActivity() {
    }
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_splitter);
 
        imageViewResult = (ImageView) this.findViewById(R.id.image_result);
        textViewMsg = (TextView) this.findViewById(R.id.text_msg);
 
        sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
        sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        vibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
 
        soundPool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);
        streamSoundId = soundPool.load(this, R.raw.call_result, 0);
 
    }
 
    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, sensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    }
 
    @Override
    protected void onStop() {
        sensorManager.unregisterListener(this);
        if (null != vibrator) {
            vibrator.cancel();
            vibrator = null;
        }
 
        if (null != soundPool) {
            soundPool.release();
            soundPool = null;
        }
        super.onStop();
    }
 
    @Override
    public void onSensorChanged(SensorEvent event) {
 
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            float[] values = event.values;
            if (isNormalAcceler(values)) {
 
                new Thread(new Runnable() {
 
                    @Override
                    public void run() {
                        Message msg = new Message();
                        msg.what = UPDATE_VIEW;
                        handler.sendMessage(msg);
                    }
                }).start();
            }
        }
    }
 
    private boolean isNormalAcceler(float[] values) {
        int g = 15;
        return (Math.abs(values[0]) > g && Math.abs(values[1]) > g)
                || Math.abs(values[2]) > g;
    }
 
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
 
    }
 
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            BackListener backListener = new BackListener();
            new AlertDialog.Builder(this)
                    .setIcon(android.R.drawable.ic_dialog_info)
                    .setTitle(R.string.app_name)
                    .setMessage(R.string.exite_app_info)
                    .setPositiveButton(R.string.leave, backListener)
                    .setNegativeButton(R.string.without, backListener).show();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
 
    private class BackListener implements DialogInterface.OnClickListener {
 
        @Override
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                SplitterActivity.this.finish();
                break;
            case DialogInterface.BUTTON_NEGATIVE:
                break;
            default:
                break;
            }
        }
    }
}


6.效果图

  

wKioL1TEgYHShI3RAAFHZHsmsLA348.jpgwKiom1TEgKbyBhERAAE2ZudrOV8909.jpg

7.总结

  通读了Android官方开发文档之后,感觉不得要领。唯找出一个目标App,进行模仿,在此过程不断深入了解其中原理,API文档,反复回顾Android开发知识体系,久而久之就能开发自己的想要的Android应用了。

  另外就是针对某一知识点,比如:Activity,ContentProvider,View 等做示例,实验,探究;最后将四大组件,各种布局结合起来,集成各种服务实现完备应用,这样就基本掌握了Android开发。接下来就该深入探究其中机理。



本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1608042,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
安卓开发过程中的RatingBar、Handler以及GPS在大型项目中的使用【Android】
安卓开发过程中的RatingBar、Handler以及GPS在大型项目中的使用【Android】
0 0
【Android】使用Android开发应用过程中遇到ViewGroup的简单效以及aw和assets文件夹下的文件(Http协议的底层工作)
【Android】使用Android开发应用过程中遇到ViewGroup的简单效以及aw和assets文件夹下的文件(Http协议的底层工作)
0 0
转 - Android下一次OOM调试过程
线程数超限,即proc/pid/status中记录的线程数(threads项)突破/proc/sys/kernel/threads-max中规定的最大线程数。
0 0
【Android】构建安卓项目过程中的一些细节问题全记录
前言 距离安卓项目结束已经过去了好几天,之后很长一段时间我应该都不会再写和安卓有关的项目了。今天偶然翻到之前写的笔记,想了想还是决定整理出来,希望对后来要完成课设的学弟学妹们有帮助。
0 0
最详细的Android开发环境配置经验分享(包含配置过程中可能出现的问题及解决办法。繁琐的配置步骤是否是你头疼呢,详细配置步骤你值得拥有!)
最详细的Android开发环境配置经验分享(包含配置过程中可能出现的问题及解决办法。繁琐的配置步骤是否是你头疼呢,详细配置步骤你值得拥有!)
0 0
Android | 毫分缕析!说说图片加载的整个过程
Android | 毫分缕析!说说图片加载的整个过程
0 0
Android | 说说从 android:text 到 TextView 的过程(主题&样式)
Android | 说说从 android:text 到 TextView 的过程(主题&样式)
0 0
❤️Android Apk 的打包过程 ❤️ 只需两幅图
官方介绍 在分析安装过程之前,需要先了解一下 Android 项目是如何经过编译->打包生成最终的 .apk 格式的安装包。谷歌有一张官方图片来描述 apk 的打包流程,如下图所示。
0 0
🍵补齐Android技能树——从AGP构建过程到APK打包过程(下)
Android Gradle Plugin,简称 AGP,老早之前就想好好研究下Android APK的打包过程,毕竟 APK包体积优化 的前置知识之一。
0 0
🍵补齐Android技能树——从AGP构建过程到APK打包过程(中)
Android Gradle Plugin,简称 AGP,老早之前就想好好研究下Android APK的打包过程,毕竟 APK包体积优化 的前置知识之一。
0 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Android组件化实现
立即下载
蚂蚁聚宝Android秒级编译—— Freeline
立即下载
Android插件化:从入门到放弃
立即下载