andorid里的手势电话学习(下)
说好的昨晚把自己写的代码挂出来,最后还是有事没时间挂,其实我的代码也是参考GestureBuilder和上篇的那个手势电话写的,功能差不多,只是我是通过画图查询得到名字再访问通讯录,先上下图
color.xml,string.xml很简单
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 <drawable name="darkgray">#808080</drawable> 4 <drawable name="white">#FFFFFF</drawable> 5 <drawable name="blue">#0000FF</drawable> 6 </resources>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">画一颗心,打电话给HONEY!</string> <string name="app_name">HONEY</string> <string name="button_done">添加</string> <string name="button_cancel">重置</string> <string name="load_failed">加载失败!</string> <string name="save_success">添加成功!</string> <string name="save_failed">添加失败!</string> <string name="title">Name:</string> <string name="button_cancer">Cancer</string> <string name="gestures_error_loading">Could not load %s. Make sure you have storage available.</string> <string name="button_add">Add gesture</string> <string name="button_reload">Reload</string> <string name="error_missing_name">You must enter a name</string> <string name="rename_action">OK</string> <string name="cancel_action">Cancel</string> <string name="gestures_loading">Loading gestures...</string> <string name="gestures_empty">No gestures</string> <string name="gestures_activity">Gestures</string> <string name="gestures_rename">Rename</string> <string name="gestures_delete">Delete</string> <string name="gestures_delete_success">Gesture deleted</string> <string name="gestures_rename_title">Rename gesture</string> <string name="gestures_rename_label">Gesture name</string> </resources>
布局文件就不上了,都差不多。把我写的java挂出来吧
1 package shi.desture.dome.android; 2 3 4 import java.io.File; 5 import java.util.ArrayList; 6 import java.util.Timer; 7 import java.util.TimerTask; 8 9 import android.app.Activity; 10 import android.content.ContentResolver; 11 import android.content.Context; 12 import android.content.Intent; 13 import android.database.Cursor; 14 import android.gesture.Gesture; 15 import android.gesture.GestureLibraries; 16 import android.gesture.GestureLibrary; 17 import android.gesture.GestureOverlayView; 18 import android.gesture.Prediction; 19 import android.gesture.GestureOverlayView.OnGesturePerformedListener; 20 import android.net.Uri; 21 import android.os.Bundle; 22 import android.os.Environment; 23 import android.provider.ContactsContract; 24 import android.view.KeyEvent; 25 import android.view.View; 26 import android.widget.Button; 27 import android.widget.Toast; 28 29 30 public class shi extends Activity 31 { 32 private GestureLibrary gesLib; 33 private GestureOverlayView gesOverlay; 34 private String gesPath; 35 private Button button01; 36 private Button button02; 37 38 /** Called when the activity is first created. */ 39 @Override 40 public void onCreate(Bundle savedInstanceState) 41 { 42 super.onCreate(savedInstanceState); 43 /* 加载main.xml Layout */ 44 setContentView(R.layout.main); 45 button01 = (Button)this.findViewById(R.id.btnAdd); 46 button02 = (Button)this.findViewById(R.id.btnSelect); 47 button01.setOnClickListener(new Button.OnClickListener() 48 { 49 @Override 50 public void onClick(View v) 51 { 52 Intent intent=new Intent(shi.this,CreateGestureActivity.class); 53 startActivity(intent); 54 shi.this.finish(); 55 //切换activity动画 56 overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_in_left); 57 } 58 }); 59 button02.setOnClickListener(new Button.OnClickListener() 60 { 61 @Override 62 public void onClick(View v) 63 { 64 Intent intent=new Intent(shi.this,ListGestures.class); 65 startActivity(intent); 66 shi.this.finish(); 67 //overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_in_left); 68 } 69 }); 70 71 72 /* 查看SDCard是否存在 */ 73 if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) 74 { 75 /* SD卡不存在,显示Toast信息 */ 76 Toast.makeText(shi.this,"SD卡不存在!程序无法运行", 77 Toast.LENGTH_LONG).show(); 78 finish(); 79 } 80 81 /* 取得GestureLibrary的文件路径 */ 82 gesPath = new File 83 ( 84 Environment.getExternalStorageDirectory(),"gestures" 85 ).getAbsolutePath(); 86 87 File file = new File(gesPath); 88 if(!file.exists()) 89 { 90 /* gestures文件不存在,显示Toast信息 */ 91 Toast.makeText(shi.this,"gestures文件不存在!程序无法运行", 92 Toast.LENGTH_LONG).show(); 93 finish(); 94 } 95 96 /* 初始化GestureLibrary */ 97 gesLib = GestureLibraries.fromFile(gesPath); 98 if (!gesLib.load()) 99 { 100 /* 读取失败,显示Toast信息 */ 101 Toast.makeText(shi.this,"gestures文件读取失败!程序无法运行", 102 Toast.LENGTH_LONG).show(); 103 finish(); 104 } 105 /* GestureOverlayView初始化 */ 106 gesOverlay = (GestureOverlayView) findViewById(R.id.myGestures1); 107 gesOverlay.addOnGesturePerformedListener(new MyListener(this)); 108 } 109 110 /* 告定义OnGesturePerformedListener */ 111 public class MyListener implements OnGesturePerformedListener 112 { 113 private Context context; 114 115 public MyListener(Context context) 116 { 117 this.context = context; 118 } 119 120 @Override 121 public void onGesturePerformed(GestureOverlayView overlay, 122 Gesture gesture) 123 { 124 /* 手势比对 */ 125 ArrayList<Prediction> predictions = gesLib.recognize(gesture); 126 if (predictions.size() > 0) 127 { 128 /* 取最接近的手势 */ 129 Prediction prediction = predictions.get(0); 130 /* 取得预测值吹少己于1.0 */ 131 if (prediction.score > 1.0) 132 { 133 /* 从通信录中取得联系人电话 */ 134 String phone=getContactPeople(prediction.name); 135 /* 拨打电话给联系人 */ 136 if(phone!="") 137 { 138 Intent intent=new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+phone)); 139 startActivity(intent); 140 } 141 else 142 { 143 /* 比对不到,显示Toast */ 144 Toast.makeText(this.context,"phone number not found!", 145 Toast.LENGTH_SHORT).show(); 146 } 147 } 148 else 149 { 150 /* 比对不到,显示Toast */ 151 Toast.makeText(this.context,"gesture no match!", 152 Toast.LENGTH_SHORT).show(); 153 } 154 } 155 else 156 { 157 /* 比对不到,显示Toast */ 158 Toast.makeText(this.context,"gesture no match!", 159 Toast.LENGTH_SHORT).show(); 160 } 161 } 162 } 163 164 /* 以联系人名称搜索通信录中联系人的电话的method */ 165 private String getContactPeople(String name) 166 { 167 String result=""; 168 ContentResolver contentResolver = 169 shi.this.getContentResolver(); 170 Cursor cursor = null; 171 172 /* 要搜索的字段名称 */ 173 String[] projection = new String[] 174 { ContactsContract.CommonDataKinds.Phone.NUMBER }; 175 176 /* 以联系人的名字去找该联系人的电话 */ 177 cursor = contentResolver.query( 178 ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, 179 ContactsContract.Contacts.DISPLAY_NAME + "=?", new String[] 180 { name }, ""); 181 182 if (cursor.getCount() != 0) 183 { 184 cursor.moveToFirst(); 185 /* 取得联系人电话 */ 186 result = cursor.getString(0); 187 } 188 return result; 189 } 190 private static Boolean isExit = false;// 标志是否按下返回键 191 // 自定义计时任务,这里在2秒之后如果没有按下按钮,则将标志回复成原值。 192 class task extends TimerTask{ 193 @Override 194 public void run() { 195 isExit = false; 196 } 197 } 198 199 @Override 200 public boolean onKeyDown(int keyCode, KeyEvent event) { 201 if (keyCode == KeyEvent.KEYCODE_BACK) { 202 if (isExit == false) { 203 isExit = true; 204 Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_LONG).show(); 205 task tt=new task(); 206 Timer tExit = new Timer(); 207 tExit.schedule(tt, 3000); 208 } else { 209 finish(); 210 overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); 211 System.exit(0); 212 } 213 214 } 215 216 return false; 217 218 } 219 220 }
1 package shi.desture.dome.android; 2 import java.io.File; 3 import java.util.ArrayList; 4 import java.util.Set; 5 import java.util.TimerTask; 6 7 import android.app.Activity; 8 import android.content.Intent; 9 import android.gesture.Gesture; 10 import android.gesture.GestureLibraries; 11 import android.gesture.GestureLibrary; 12 import android.gesture.GestureOverlayView; 13 import android.os.Bundle; 14 import android.os.Environment; 15 import android.view.KeyEvent; 16 import android.view.MotionEvent; 17 import android.view.View; 18 import android.widget.Button; 19 import android.widget.EditText; 20 import android.widget.Toast; 21 22 public class CreateGestureActivity extends Activity 23 { 24 private Gesture ges; 25 private GestureLibrary lib; 26 private GestureOverlayView overlay; 27 private Button button01,button02; 28 private EditText et; 29 private String gesPath; 30 31 /** Called when the activity is first created. */ 32 @Override 33 public void onCreate(Bundle savedInstanceState) 34 { 35 super.onCreate(savedInstanceState); 36 /* 加载main.xml Layout */ 37 setContentView(R.layout.create_gesture); 38 39 /* 查看SDCard是否存在 */ 40 if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) 41 { 42 /* SD卡不存在,显示Toast信息 */ 43 Toast.makeText(CreateGestureActivity.this,"SD卡不存在!程序无法运行", 44 Toast.LENGTH_LONG).show(); 45 finish(); 46 } 47 /* 以findViewById()取得对象 */ 48 et = (EditText)this.findViewById(R.id.myEditText1); 49 button01 = (Button)this.findViewById(R.id.myButton1); 50 button02 = (Button)this.findViewById(R.id.myButton2); 51 overlay = (GestureOverlayView) findViewById(R.id.myGestures1); 52 53 /* 取得GestureLibrary的文件路径 */ 54 gesPath = new File 55 ( 56 Environment.getExternalStorageDirectory(),"gestures" 57 ).getAbsolutePath(); 58 59 /* 设置EditText的OnKeyListener */ 60 et.setOnKeyListener(new EditText.OnKeyListener(){ 61 @Override 62 public boolean onKey(View v, int keyCode, KeyEvent event) 63 { 64 /* 名称与手写都已设置时将新增的Button enable */ 65 if(ges!=null&&et.getText().length()!=0) 66 { 67 button01.setEnabled(true); 68 } 69 else 70 { 71 button01.setEnabled(false); 72 } 73 return false; 74 } 75 }); 76 77 /* 设定Overlay的OnGestureListener */ 78 overlay.addOnGestureListener(new GestureOverlayView.OnGestureListener() 79 { 80 @Override 81 public void onGesture(GestureOverlayView overlay,MotionEvent event) 82 { 83 } 84 /* 开始画手势时将新增的Button disable,并清除Gesture */ 85 @Override 86 public void onGestureStarted(GestureOverlayView overlay,MotionEvent event) 87 { 88 button01.setEnabled(false); 89 ges = null; 90 } 91 /* 手势画完时判断名称与手写是否完整建立 */ 92 @Override 93 public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) 94 { 95 ges = overlay.getGesture(); 96 if (ges!=null&&et.getText().length()!=0) 97 { 98 button01.setEnabled(true); 99 } 100 } 101 @Override 102 public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) 103 { 104 } 105 }); 106 107 /* 设定button01的OnClickListener */ 108 button01.setOnClickListener(new Button.OnClickListener() 109 { 110 @Override 111 public void onClick(View v) 112 { 113 String gesName=et.getText().toString(); 114 try 115 { 116 File file = new File(gesPath); 117 lib = GestureLibraries.fromFile(gesPath); 118 119 if(!file.exists()) 120 { 121 /* 文件不存在就直接写入 */ 122 lib.addGesture(gesName,ges); 123 if(lib.save()) 124 { 125 /* 将设定画面数据清除 */ 126 et.setText(""); 127 button01.setEnabled(false); 128 overlay.clear(true); 129 /* 保存成功,显示Toast信息 */ 130 Toast.makeText(CreateGestureActivity.this,getString(R.string.save_success)+":"+gesPath, 131 Toast.LENGTH_LONG).show(); 132 } 133 else 134 { 135 /* 保存失败,显示Toast信息 */ 136 Toast.makeText(CreateGestureActivity.this, getString(R.string.save_failed)+":"+gesPath, 137 Toast.LENGTH_LONG).show(); 138 } 139 } 140 else 141 { 142 /* 文件存在时因读取保存的Gesture */ 143 if (!lib.load()) 144 { 145 /* Library读取失败,显示Toast讯息 */ 146 Toast.makeText(CreateGestureActivity.this, getString(R.string.load_failed)+":"+gesPath, 147 Toast.LENGTH_LONG).show(); 148 } 149 else 150 { 151 /* 如果Library中存在相同名称,则因将其移除再写入 */ 152 Set<String> en=lib.getGestureEntries(); 153 if(en.contains(gesName)) 154 { 155 ArrayList<Gesture> al=lib.getGestures(gesName); 156 for(int i=0;i<al.size();i++){ 157 lib.removeGesture(gesName,al.get(i)); 158 } 159 } 160 lib.addGesture(gesName,ges); 161 if(lib.save()) 162 { 163 /* 将设定画面数据清除 */ 164 et.setText(""); 165 button01.setEnabled(false); 166 overlay.clear(true); 167 /* 保存成功,显示Toast信息 */ 168 Toast.makeText(CreateGestureActivity.this,getString(R.string.save_success)+":"+gesPath, 169 Toast.LENGTH_LONG).show(); 170 } 171 else 172 { 173 /* 保存失败,显示Toast信息 */ 174 Toast.makeText(CreateGestureActivity.this, getString(R.string.save_failed)+":"+gesPath, 175 Toast.LENGTH_LONG).show(); 176 } 177 } 178 } 179 } 180 catch(Exception e) 181 { 182 e.printStackTrace(); 183 } 184 } 185 }); 186 /* 设置button02的OnClickListener */ 187 button02.setOnClickListener(new Button.OnClickListener() 188 { 189 @Override 190 public void onClick(View v) 191 { 192 et.setText(""); 193 button01.setEnabled(false); 194 overlay.clear(true); 195 } 196 }); 197 } 198 private static Boolean isExit = false;// 标志是否按下返回键 199 // 自定义计时任务,这里在2秒之后如果没有按下按钮,则将标志回复成原值。 200 class task extends TimerTask{ 201 @Override 202 public void run() { 203 isExit = false; 204 } 205 } 206 207 @Override 208 public boolean onKeyDown(int keyCode, KeyEvent event) { 209 if (keyCode == KeyEvent.KEYCODE_BACK) { 210 211 Intent intent=new Intent(CreateGestureActivity.this,shi.class); 212 startActivity(intent); 213 CreateGestureActivity.this.finish(); 214 215 } 216 217 return false; 218 219 } 220 }
1 package shi.desture.dome.android; 2 3 import java.util.ArrayList; 4 import java.util.TimerTask; 5 6 import android.app.Activity; 7 import android.content.Intent; 8 import android.gesture.Gesture; 9 import android.gesture.GestureLibraries; 10 import android.gesture.GestureLibrary; 11 import android.graphics.Bitmap; 12 import android.graphics.Color; 13 import android.os.Bundle; 14 import android.view.ContextMenu; 15 import android.view.ContextMenu.ContextMenuInfo; 16 import android.view.KeyEvent; 17 import android.view.MenuItem; 18 import android.view.View; 19 import android.widget.AdapterView; 20 import android.widget.AdapterView.AdapterContextMenuInfo; 21 import android.widget.GridView; 22 23 public class ListGestures extends Activity { 24 private GestureLibrary library; 25 public static String[] gesName; 26 public static Bitmap[] pics; 27 28 @Override 29 protected void onCreate(Bundle savedInstanceState) { 30 // TODO Auto-generated method stub 31 super.onCreate(savedInstanceState); 32 setContentView(R.layout.allgesture); 33 load(); 34 GridAdapter adapter = new GridAdapter(this); 35 GridView grv = (GridView) findViewById(R.id.gvTop); 36 grv.setAdapter(adapter); 37 38 } 39 40 public void load() { 41 String path = "/sdcard/gestures"; 42 // 加载手势文件 43 library = GestureLibraries.fromFile(path); 44 45 if (library.load()) { 46 int index = library.getGestureEntries().size(); 47 pics = new Bitmap[index]; 48 gesName=new String[index]; 49 int i = 0; 50 //获得所有手势文件,返回的是存储key的set集合 51 for (String name : library.getGestureEntries()) { 52 // 因为在手势仓库中,支持一个name对应多个手势文件, 53 // 所以会返回一个list,在这里我们取list里的第一个 54 ArrayList<Gesture> geess = library.getGestures(name); 55 Gesture gg = geess.get(0); 56 //将手势文件转成位图 57 Bitmap bmp = gg.toBitmap(100, 100, 12, Color.BLUE); 58 pics[i] = bmp;//保存位图 59 gesName[i]=name;//保存当前的手势名称。 60 i++; 61 } 62 } 63 } 64 65 private static Boolean isExit = false;// 标志是否按下返回键 66 // 自定义计时任务,这里在2秒之后如果没有按下按钮,则将标志回复成原值。 67 class task extends TimerTask{ 68 @Override 69 public void run() { 70 isExit = false; 71 } 72 } 73 74 @Override 75 public boolean onKeyDown(int keyCode, KeyEvent event) { 76 if (keyCode == KeyEvent.KEYCODE_BACK) { 77 78 Intent intent=new Intent(ListGestures.this,shi.class); 79 startActivity(intent); 80 ListGestures.this.finish(); 81 overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_in_left); 82 83 } 84 85 return false; 86 87 } 88 }
1 package shi.desture.dome.android; 2 3 import android.content.Context; 4 import android.gesture.GestureLibrary; 5 import android.view.LayoutInflater; 6 import android.view.View; 7 import android.view.ViewGroup; 8 import android.widget.BaseAdapter; 9 import android.widget.ImageView; 10 import android.widget.TextView; 11 12 public class GridAdapter extends BaseAdapter { 13 // 每个gridItem显示的值 14 private Context mContext; 15 private LayoutInflater mInflater; 16 17 public GridAdapter(Context context) { 18 mContext = context; 19 mInflater = (LayoutInflater) context 20 .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 21 22 } 23 24 public int getCount() { 25 // 返回适配器中数据的数量 26 return ListGestures.pics.length; 27 } 28 29 public Object getItem(int position) { 30 // 用不到 31 return null; 32 } 33 34 public long getItemId(int position) { 35 // 用不到 36 return 0; 37 } 38 39 // 此方法的convertView是在grid_item里定义的组件。这里是一个ImageView和TextView 40 public View getView(int position, View convertView, ViewGroup parent) { 41 if (convertView == null) { 42 convertView = mInflater.inflate(R.layout.grid_item, null); 43 } 44 ImageView icon = (ImageView) convertView.findViewById(R.id.itemIcon); 45 TextView text = (TextView) convertView.findViewById(R.id.itemText); 46 icon.setImageBitmap(ListGestures.pics[position]); 47 text.setText(ListGestures.gesName[position]); 48 return convertView;// 返回已经改变过的convertView,节省系统资源 49 } 50 51 }
其实都差不多我就一菜鸟接触着玩玩,而且我为了简单,删除和重命名这一块还是没做,等有时间再搞吧,下面是完整代码网盘:http://dl.dbank.com/c00aqi59pu