PhoneGap实践(Native Api调用 + 自定义Plugin(BarcodePlugin))
前一篇分析了PhoneGap的原理,这一篇将以一个实例来说一下如何用PhoneGap调用Native Api,以及自定义Plugin来调用PhoneGap Native Api中没有的功能(Barcode扫描)。
环境:Android2.2
第三方库:PhoneGap、zxing、jqueryMobile
功能:
1)在js中调用PhoneGap提供的NativeApi,navigator.contacts.find列表显示手机联系人信息。
2)由于PhoneGap的NativeApi中没有提供二维码的扫描功能,我们自定义BarcodePlugin,来实现在js中调用扫描二维码。
先上图:
查询手机联系人的关键代码:
1 var options = new ContactFindOptions();
2 options.filter = "李";
3 options.multiple = true;
4 var fields = ["displayName", "phoneNumbers", "emails"];
5 navigator.contacts.find(fields, onSuccess, onError, options);
2 options.filter = "李";
3 options.multiple = true;
4 var fields = ["displayName", "phoneNumbers", "emails"];
5 navigator.contacts.find(fields, onSuccess, onError, options);
其中,fields表示需要查询的联系人字段,onSuccess/onError是回调(因为这个调用是异步的),options是过滤条件,如果不传表示查询所有联系人。
自定义Plugin代码:
BarcodePlugin.java
1 public class BarcodePlugin extends Plugin
2 {
3 private final int CODE_REQ_BARCODE = 1;
4 private final int WHAT_BARCODE_SCAN = 1;
5 private String text;
6 private Object synObj = new Object();
7
8 private Handler handler = new Handler()
9 {
10 public void handleMessage(Message msg)
11 {
12 if(msg == null)
13 {
14 return;
15 }
16 switch (msg.what)
17 {
18 case WHAT_BARCODE_SCAN:
19 Intent intent = new Intent(ctx.getContext(), BarcodeActivity.class);
20 ctx.startActivityForResult(BarcodePlugin.this, intent, CODE_REQ_BARCODE);
21 break;
22 }
23 };
24 };
25
26 public PluginResult execute(String action, JSONArray args, String callbackId)
27 {
28 text = "";
29 handler.sendEmptyMessage(WHAT_BARCODE_SCAN);
30
31 sleep();
32
33 return new PluginResult(PluginResult.Status.OK, text);
34 }
35
36 public void onActivityResult(int requestCode, int resultCode, Intent intent)
37 {
38 if(requestCode == CODE_REQ_BARCODE)
39 {
40 if(resultCode == Activity.RESULT_OK)
41 {
42 text = intent.getExtras().getString("text");
43 }
44 weakup();
45 }
46 else
47 {
48 super.onActivityResult(requestCode, resultCode, intent);
49 }
50 }
51
52 private void sleep()
53 {
54 try
55 {
56 synchronized(synObj)
57 {
58 synObj.wait();
59 }
60 }
61 catch (InterruptedException e)
62 {
63 e.printStackTrace();
64 }
65 }
66
67 private void weakup()
68 {
69 synchronized(synObj)
70 {
71 synObj.notify();
72 }
73 }
74 }
2 {
3 private final int CODE_REQ_BARCODE = 1;
4 private final int WHAT_BARCODE_SCAN = 1;
5 private String text;
6 private Object synObj = new Object();
7
8 private Handler handler = new Handler()
9 {
10 public void handleMessage(Message msg)
11 {
12 if(msg == null)
13 {
14 return;
15 }
16 switch (msg.what)
17 {
18 case WHAT_BARCODE_SCAN:
19 Intent intent = new Intent(ctx.getContext(), BarcodeActivity.class);
20 ctx.startActivityForResult(BarcodePlugin.this, intent, CODE_REQ_BARCODE);
21 break;
22 }
23 };
24 };
25
26 public PluginResult execute(String action, JSONArray args, String callbackId)
27 {
28 text = "";
29 handler.sendEmptyMessage(WHAT_BARCODE_SCAN);
30
31 sleep();
32
33 return new PluginResult(PluginResult.Status.OK, text);
34 }
35
36 public void onActivityResult(int requestCode, int resultCode, Intent intent)
37 {
38 if(requestCode == CODE_REQ_BARCODE)
39 {
40 if(resultCode == Activity.RESULT_OK)
41 {
42 text = intent.getExtras().getString("text");
43 }
44 weakup();
45 }
46 else
47 {
48 super.onActivityResult(requestCode, resultCode, intent);
49 }
50 }
51
52 private void sleep()
53 {
54 try
55 {
56 synchronized(synObj)
57 {
58 synObj.wait();
59 }
60 }
61 catch (InterruptedException e)
62 {
63 e.printStackTrace();
64 }
65 }
66
67 private void weakup()
68 {
69 synchronized(synObj)
70 {
71 synObj.notify();
72 }
73 }
74 }
需要注意:execute()线程不是UI线程,不能执行UI操作(启动BarcodeActivity),这里交由handler来启动barcode扫描,然后execute线程睡眠,当扫描结束时,execute线程被唤醒,然后把扫描结果写到客户端。
感兴趣的朋友可以在这里下载代码