[转载]andorid里的手势电话学习(上)

[转载]andorid里的手势电话学习(上) – 落尘祥 – 博客园.

自己在学习手势Gesture绘制的时候突然想画一个爱心实现一键拨号给honey的应用,先在安卓巴士找了个手势电话案例结合Android samples里的Gesture Builder改写了个画爱心拨通号码的应用,先把我在安卓巴士上看到的案例复制过来:

 

学习一下Android中的手势文件。手势相关的类有
1.GestureOverlayView,这个是手势绘制区,既布局中的一个控件,用于接收用户绘制的手势、监听绘制区的改变、清除当前手势等等。
2.GestureLibrary 这个算是手势文件的一个库,里面存放着当前保存过的手势资源,可以用这个类进行手势资源的存储和读取。
3.Gesture,手势实例,无论是读取手势,还是要保存当前的手势,都是Gesture对象。
4.Prediction 识别率。主要用于在根据当前手势查询手势库中是否有匹配手势时需要用到。
下面根据程序来详细讲解一下如何应用这几个类。

 

本主要功能是根据手势判别来拨打电话。可以保存手势,查看现在保存的手势,如果程序第一次运行,便在指定路径下建立手势文件。

 

因为要保存手势文件和打电话,所以首先在程序清单中添加权限
AndroidManifest.xml代码片段:

 

1 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2         <uses-permission android:name="android.permission.CALL_PHONE"/>

 

程序用到的布局文件有4个,一个是主Activity用到的xml布局。就是第一张图的布局文件:
main.xml代码:

 

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3  android:layout_width="fill_parent"
 4  android:layout_height="fill_parent"
 5  android:orientation="vertical" >
 6 
 7     <TextView
 8 android:layout_width="fill_parent"
 9  android:layout_height="wrap_content"
10  android:text="@string/hello" />
11 
12     <android.gesture.GestureOverlayView
13 android:id="@+id/gestures"
14  android:layout_width="fill_parent"
15  android:layout_height="fill_parent"
16  android:layout_weight="1"
17  android:gestureStrokeType="multiple" >
18     </android.gesture.GestureOverlayView>
19 
20 <LinearLayout android:layout_width="fill_parent"
21  android:layout_height="wrap_content"
22  android:gravity="center_horizontal">
23         <Button
24 android:id="@+id/btnAdd"
25  android:layout_width="wrap_content"
26  android:layout_height="wrap_content"
27  android:text=" 添加手势 " />
28           <Button
29 android:id="@+id/btnSelect"
30  android:layout_width="wrap_content"
31  android:layout_height="wrap_content"
32  android:text="查看已有手势" />
33 </LinearLayout>
34 
35 </LinearLayout>

 

以及添加手势资源时用的布局文件:
addgesture.xml

 

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3  android:layout_width="fill_parent"
 4  android:layout_height="fill_parent"
 5  android:orientation="vertical" 
 6  android:gravity="center_horizontal">
 7 
 8     <LinearLayout
 9 android:layout_width="fill_parent"
10  android:layout_height="wrap_content" >
11 
12         <TextView
13 android:layout_width="wrap_content"
14  android:layout_height="wrap_content"
15  android:text="手机号码:" 
16  android:inputType="number"/>
17 
18         <EditText
19 android:id="@+id/txtNum"
20  android:layout_width="match_parent"
21  android:layout_height="wrap_content" />
22     </LinearLayout>
23 
24     <android.gesture.GestureOverlayView
25 android:id="@+id/gestureAdd"
26  android:layout_width="fill_parent"
27  android:layout_height="fill_parent"
28  android:layout_weight="1"
29  android:gestureStrokeType="multiple" >
30     </android.gesture.GestureOverlayView>
31 
32     <Button
33 android:id="@+id/btnOK"
34  android:layout_width="wrap_content"
35  android:layout_height="wrap_content"
36  android:text=" 确定 " />
37 
38 </LinearLayout>

 

剩下2个是gridView的布局文件和点击查看所有手势的布局文件:

 

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="wrap_content"
 4     android:layout_height="wrap_content"
 5     android:orientation="vertical"  android:gravity="center">
 6     <ImageView android:id="@+id/itemIcon"    android:layout_width="wrap_content"
 7         android:layout_height="wrap_content"        />
 8     <TextView android:id="@+id/itemText" android:layout_width="wrap_content"
 9         android:layout_height="wrap_content"     android:textColor="#fff"/>
10 
11 </LinearLayout>

 

 

 

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3  android:layout_width="match_parent"
 4  android:layout_height="match_parent"
 5  android:orientation="vertical" >
 6 
 7     <GridView
 8 android:id="@+id/gvTop"
 9  android:layout_width="fill_parent"
10  android:layout_height="fill_parent"
11  android:gravity="center"
12  android:numColumns="auto_fit" 
13  android:scrollbars="none">
14     </GridView>
15 
16 </LinearLayout>

 

在主activity GestureLearnActivity中,要判断第一次加载时是否有手势文件,如果没有则创建一个手势文件,并监听手势绘制区的改变,当绘制完成时与手势库中的手势进行比较。
GestureLearnActivity代码片段

 

 1 /**
 2  * 初始化
 3 */
 4         public void init() {
 5                 // 获得布局中的组件
 6                 btnAdd = (Button) findViewById(R.id.btnAdd);
 7                 btnAdd.setOnClickListener(this);
 8                 btnSelect = (Button) findViewById(R.id.btnSelect);
 9                 btnSelect.setOnClickListener(this);
10                 gesture = (GestureOverlayView) findViewById(R.id.gestures);
11                 // 手势文件的加载路径
12                 String path = "/sdcard/gestures";
13                 // 加载手势文件
14                 library = GestureLibraries.fromFile(path);
15                 if (library.load()) {
16                         
17                         gesture.addOnGesturePerformedListener(this);
18                 } else {
19                         Toast.makeText(GestureLearnActivity.this, "无手势文件",
20                                         Toast.LENGTH_LONG).show();
21                         
22                         File file = new File(path);
23                         try {
24                                 //创建手势文件
25                                 file.createNewFile();
26                         } catch (Exception e) {
27                                 e.printStackTrace();
28                         }
29                 }
30         }
31 // 这个接口里处理匹配的手势
32 public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
33         ArrayList<Prediction> predictions = library.recognize(gesture);
34         if (predictions.size() > 0) {
35                 // 获得识别率
36                 Prediction predict = predictions.get(0);
37                 // 如果识别率大于1,则说明找到匹配手势
38                 if (predict.score > 1.0) {
39                         //调用打电话activity
40                         Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"
41                                         + predict.name));
42                         //不打电话,只进入打电话界面
43 //Intent phone=new Intent("com.android.phone.action.TOUCH_DIALER");
44                         startActivity(intent);
45                         }
46                 }
47 
48         }

 

剩下的就是查看手势文件了,这里我用到的是GridView控件来布局,将手势库中的文件都读取出来,由于是练习程序,所以没做复杂的操作,只是显示已经保存的手势文件。这里用到Gesture 的实例对象,通过这个对象将手势文件转换成位图来显示。
ListGestures.java代码片段

 

 1 public void load() {
 2                 String path = "/sdcard/gestures";
 3                 // 加载手势文件
 4                 library = GestureLibraries.fromFile(path);
 5 
 6                 if (library.load()) {
 7                         int index = library.getGestureEntries().size();
 8                         pics = new Bitmap[index];
 9                         gesName=new String[index];
10                         int i = 0;
11                         //获得所有手势文件,返回的是存储key的set集合
12                         for (String name : library.getGestureEntries()) {
13                                 // 因为在手势仓库中,支持一个name对应多个手势文件,
14 // 所以会返回一个list,在这里我们取list里的第一个
15                                 ArrayList<Gesture> geess = library.getGestures(name);
16                                 Gesture gg = geess.get(0);
17                                 //将手势文件转成位图
18                                 Bitmap bmp = gg.toBitmap(100, 100, 12, Color.BLUE);
19                                 pics[i] = bmp;//保存位图
20                                 gesName[i]=name;//保存当前的手势名称。
21                                 i++;
22                         }
23                 }
24         }

 

最后的gridView的适配器代码就不多说了。直接上源码

 

 1 public class GridAdapter extends BaseAdapter {
 2         // 每个gridItem显示的值
 3         private Context mContext;
 4         private LayoutInflater mInflater;
 5 
 6         public GridAdapter(Context context) {
 7                 mContext = context;
 8                 mInflater = (LayoutInflater) context
 9                                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
10 
11         }
12 
13         public int getCount() {
14                 // 返回适配器中数据的数量
15                 return ListGestures.pics.length;
16         }
17 
18         public Object getItem(int position) {
19                 // 用不到
20                 return null;
21         }
22 
23         public long getItemId(int position) {
24                 // 用不到
25                 return 0;
26         }
27 
28         // 此方法的convertView是在grid_item里定义的组件。这里是一个ImageView和TextView
29         public View getView(int position, View convertView, ViewGroup parent) {
30                 if (convertView == null) {
31                         convertView = mInflater.inflate(R.layout.grid_item, null);
32                 }
33                 ImageView icon = (ImageView) convertView.findViewById(R.id.itemIcon);
34                 TextView text = (TextView) convertView.findViewById(R.id.itemText);
35                 icon.setImageBitmap(ListGestures.pics[position]);
36                 text.setText(ListGestures.gesName[position]);
37                 return convertView;// 返回已经改变过的convertView,节省系统资源
38         }
39 
40 }

 

OK,这些就是实现这个程序的主要代码,程序在运行后,会根据当前的绘制手势匹配库中的手势,如果匹配成功,就会调用打电话的activity。后 面附上源代码,感兴趣的可以下载了以后去运行并查看完整的代码,记得是在真机上运行哦。因为我直接访问的SD卡,模拟器上运行可能会出错。下一得晚上将自 己的再挂出来。

完整代码我已放网盘:http://dl.dbank.com/c000mayxox

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏