NO END FOR LEARNING

Writing blog if you feel tired | 学海无涯 苦写博客

Cordova探索之旅系列(三)

| Comments

自从3.0之后,Cordova默认是关闭所有关于设备原生特性功能的,所以我们要通过添加插件来启动原生特性。

这里以Accelerometer(加速度感应器)为例,来学习如何使用设备原生特性。

1.添加插件

首先,需要在工程目录下,通过CLI命令添加插件。

1
cordova plugin add org.apache.cordova.device-motion

通过ls命令,可以查看当前项目下,已经安装的插件。

1
cordova plugin ls

2.在config.xml文件中配置该特性

路径:res/xml/config.xml

1
2
3
<feature name="Accelerometer">
  <param name="android-package" value="org.apache.cordova.devicemotion.AccelListener" />
</feature>

完整配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.example.hello.HelloWorld" version="0.0.1"
xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>HelloCordova</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <access origin="*" />
    <feature name="Accelerometer">
        <param name="android-package" value="org.apache.cordova.devicemotion.AccelListener" />
    </feature>
</widget>

某些插件还需要在Android的AndroidManifest.xml中添加uses-permission

例如:

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

当然,这里不需要!

3.API

1
navigator.accelerometer.getCurrentAcceleration(onSuccess, onError)

onSuccess和onError是对应的回调函数

4.完整例子

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
<!DOCTYPE html>
<html>
  <head>
    <title>Acceleration Example</title>
    <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
    <script type="text/javascript" charset="utf-8">

    document.addEventListener("deviceready", onDeviceReady, false);

    function onDeviceReady() {

    }

    function getCurrrentAcceleration() {
        navigator.accelerometer.getCurrentAcceleration(onSuccess, onError);
    }

    function onSuccess(acceleration) {
        alert('Acceleration X: ' + acceleration.x + '\n' +
              'Acceleration Y: ' + acceleration.y + '\n' +
              'Acceleration Z: ' + acceleration.z + '\n' +
              'Timestamp: '      + acceleration.timestamp + '\n');
    }

    function onError() {
        alert('onError!');
    }
    </script>
  </head>
  <body>
    <button onClick="getCurrrentAcceleration()">click</button>
  </body>
</html>

如果用Android的原生API,用Java代码来实现相同功能呢,如下:

Activity

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
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
import me.zeph.shakeshake.R;
import me.zeph.shakeshake.fragment.FireMissilesDialogFragment;

import static android.hardware.Sensor.TYPE_ACCELEROMETER;
import static android.hardware.SensorManager.SENSOR_DELAY_NORMAL;

public class MyActivity extends Activity {

    private SensorManager sensorManager;
    private Sensor sensor;
    private AccelerometerListener listener;
    private String text;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        initSensor();
    }

    private void initSensor() {
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        sensor = sensorManager.getDefaultSensor(TYPE_ACCELEROMETER);
        listener = new AccelerometerListener();
        sensorManager.registerListener(listener, sensor, SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onStop() {
        super.onStop();
        sensorManager.unregisterListener(listener);
    }

    public void sendMessage(View view) {
        FireMissilesDialogFragment fireMissilesDialogFragment = new FireMissilesDialogFragment(text);
        fireMissilesDialogFragment.show(getFragmentManager(), "some tag");
    }

    class AccelerometerListener implements SensorEventListener {

        @Override
        public void onSensorChanged(SensorEvent event) {
            text = "Acceleration X: \n" + event.values[0] + "\n" +
                    "Acceleration Y: \n" + event.values[1] + "\n" +
                    "Acceleration Z: \n" + event.values[2] + "\n" +
                    "Timestamp: \n" + event.timestamp + "\n";
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int i) {

        }

    }

}

Dialog

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
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import me.zeph.shakeshake.R;

public class FireMissilesDialogFragment extends DialogFragment {
    private String text;

    public FireMissilesDialogFragment(String text) {
        this.text = text;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder
                .setTitle(R.string.dialog_accelerometer)
                .setMessage(text)
                .setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                    }
                });
        return builder.create();
    }
}

main.xml

1
2
3
4
5
6
7
8
9
10
11
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
        >
    <Button android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/click"
            android:onClick="sendMessage"
            />
</LinearLayout>

Cordova探索之旅系列(二)

| Comments

在Cordova中有一个很重要的概念:插件

插件会提供访问Cordova核心API的接口。

插件是一些附加的代码,它能够提供访问原生组件的接口。一般情况下,你都需要添加一些插件以启动Cordova设备级别的特性。

插件由官方和社区提供,可以在plugins.cordova.io上找到,当然还可以在命令行中去搜索插件。

从3.0之后,Cordova将所有设备的API都作为插件,并默认设置为是不启动的。

那么,如何添加插件呢?两种方式。

第一种是使用CLI命令行。

第二种是使用更低级别的命令行Plugman。

两个的区别在于,Plugman只能一次添加一个平台的插件,而CLI命令行会添加所有平台的插件。所以如果你只在单个平台上工作,使用Plugman就显得更合理。

使用CLI命令行添加插件:

1.添加插件

1
cordova plugin add org.apache.cordova.camera

2.删除插件

1
cordova plugin rm org.apache.cordova.camera

3.查看当前已有插件

1
cordova plugin ls

4.根据关键字搜索插件

1
cordova plugin search bar code

5.社区中会提供很多插件,但是如果它没有注册到registry.cordova.io,你可以通过仓库地址添加

1
cordova plugin add https://github.com/apache/cordova-plugin-console.git

使用plugman添加插件:

首先你需要安装plugman

1
npm install -g plugman

1.添加一个插件

1
plugman --platform <ios|amazon-fireos|android|blackberry10|wp7|wp8> --project <directory> --plugin <name|url|path> [--plugins_dir <directory>] [--www <directory>] [--variable <name>=<value> [--variable <name>=<value> ...]]

通过plugman命令行将一个插件加到一个Cordova工程中。你至少要指定平台信息、Cordova项目位置。

name:插件的目录名称。它必须是存在于plugins_dirpath路径下或者在Cordova中有注册。

url:以”http://“或者”git://”开头的url,指向一个合法的git可克隆仓库,仓库中应该包含一个plugin.xml的文件,仓库中的内容可以被拷贝到plugins_dir路径下。

path:一个指向包含合法插件(包含plugin.xml文件)目录的路径。该路径下的内容可以被拷贝到plugins_dir。 其他参数:

plugin_dir:默认是指向/cordova/plugins,当然也可以是任何包含每一个已获取插件的子目录。

www:默认指向项目的www目录,但是也可以指向Cordova项目的应用web asserts目录。

variable:允许在安装时指定某些变量,对于某些插件需要API key或者其他用户定义参数是有必要的。

下面是添加电池状态插件的安装命令行

1
plugman -d --platform android --project myProject –plugin org.apache.cordova.battery-status

-d或者—debug参数,会帮助你打印出内部调试信息,帮助你跟踪具体信息。

2.删除一个插件

1
plugman --uninstall --platform <ios|amazon-fireos|android|blackberry10|wp7|wp8> --project <directory> --plugin <id> [--www <directory>] [--plugins_dir <directory>]