需求:通过手机web端,点击指定按钮能够调用Android手机内部的某个应用程序,以QQ为例。
分析:phonegap可以实现用web API调用手机的本地功能,如二维码扫描,拍照等。官网已有一些现成可用的插件实现调用本地的一些功能,但是没有相应的调用手机已安装的应用程序的功能,这就需要自行实现对应的phonegap插件。可以参考已有插件的实现方式进行开发。
方法:可以参考博文phonegap(cordova)安装配置 创建android工程,工程创建之后,进行如下步骤:
1、新增一个类OpenQQ
这个类负责打开QQ,代码如下:
/**
* @Title: OpenQQ.java
* @Package com.gzx.hello
* @Description: 定义OpenQQ类
* @author hhh
* @date 2014-4-30 上午10:02:36
* @version V1.0
*/
package com.gzx.hello;
import java.util.ArrayList;
import java.util.List;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.R.bool;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import android.widget.Toast;
/**
* @ClassName: OpenQQ
* @Description: TODO(这里用一句话描述这个类的作用)
* @author hhh
* @date 2014-4-30 上午10:02:36
*
*/
public class OpenQQ extends CordovaPlugin
{
public static final int REQUEST_CODE = 0x0ba7c0de;
public static final String PAKEAGE_NAME="com.tencent.mobileqq";
private static final String OPEN = "open";
private static final String LOG_TAG = "OpenQQ";
private PluginResult result = null;
private CallbackContext callbackContext;
/* (非 Javadoc)
* <p>Title: execute</p>
* <p>Description: </p>
* @param action
* @param args
* @param callbackContext
* @return
* @throws JSONException
* @see org.apache.cordova.CordovaPlugin#execute(java.lang.String, org.json.JSONArray, org.apache.cordova.CallbackContext)
*/
@Override
public boolean execute(String action,
JSONArray args,
CallbackContext callbackContext) throws JSONException
{
this.callbackContext = callbackContext;
if (OPEN.equals(action))
{
try
{
/* SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(target, null, content, null, null);*/
open();
result = new PluginResult(PluginResult.Status.OK);
}
catch (IllegalArgumentException ex)
{
Log.d("IllegalArgumentException", "IllegalArgumentException");
result = new PluginResult(PluginResult.Status.ERROR);
}
}
else
{
result = new PluginResult(PluginResult.Status.INVALID_ACTION);
}
return true;
}
public void open()
{
JSONObject obj = new JSONObject();
if (checkPackage(PAKEAGE_NAME))//包名存在
{
boolean isAppRunning = chekIsRunning(PAKEAGE_NAME);
if (isAppRunning)//正在运行
{
Toast.makeText(cordova.getActivity(), "QQ已打开", 0).show();
try {
obj.put("info", "QQ已打开");
} catch (JSONException e) {
Log.d(LOG_TAG, "This should never happen");
}
}
else
{
Intent intentScan = new Intent();
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
intentScan.setComponent(new ComponentName("com.tencent.mobileqq",
"com.tencent.mobileqq.activity.SplashActivity"));
intentScan.setAction(Intent.ACTION_VIEW);
Toast.makeText(cordova.getActivity(), "正打开QQ", 0).show();
try {
obj.put("info", "QQ打开成功");
} catch (JSONException e) {
Log.d(LOG_TAG, "This should never happen");
}
this.cordova.startActivityForResult((CordovaPlugin) this,
intentScan,
REQUEST_CODE);
}
}else {
Toast.makeText(cordova.getActivity(), "请安装QQ", 0).show();
try {
obj.put("info", "请安装QQ");
} catch (JSONException e) {
Log.d(LOG_TAG, "This should never happen");
}
}
this.callbackContext.success(obj);
}
/* (非 Javadoc)
* <p>Title: onActivityResult</p>
* <p>Description: </p>
* @param requestCode
* @param resultCode
* @param intent
* @see org.apache.cordova.CordovaPlugin#onActivityResult(int, int, android.content.Intent)
*/
@Override
public void onActivityResult(int requestCode,
int resultCode,
Intent intent)
{
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, intent);
callbackContext.success("activity 跳转成功了");
Toast.makeText(cordova.getActivity(), "QQ已退出", 0).show();
}
/**
*
* @Title: checkPackage
* @Description: 检测该包名所对应的应用是否存在
* @param packageName
* @return
*/
public boolean checkPackage(String packageName)
{
PackageManager packageManager = cordova.getActivity()
.getPackageManager();
if (packageName == null || "".equals(packageName)) return false;
try
{
packageManager.getApplicationInfo(packageName,
PackageManager.GET_UNINSTALLED_PACKAGES);
return true;
}
catch (Exception e)
{
return false;
// TODO: handle exception
}
}
/**
*
* @Title: chekIsRunning
* @Description: 检测包名对应的应用程序是否正在运行
* @param pakageName
* @return
*/
public boolean chekIsRunning(String pakageName)
{
boolean isAppRunning=false;
ActivityManager am = (ActivityManager) cordova.getActivity()
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> list = am.getRunningTasks(100);
for (RunningTaskInfo info : list)
{
if (info.topActivity.getPackageName().equals(pakageName)
|| info.baseActivity.getPackageName().equals(pakageName))
{
isAppRunning = true;
Log.i("Name", info.topActivity.getPackageName()
+ " info.baseActivity.getPackageName()="
+ info.baseActivity.getPackageName());
break;
}
}
return isAppRunning;
}
}
2、增加一个调用打开QQ的javascript的API
在工程目录assets/www/js下面增加一个javascript文件:openQQ.js,然后加入代码:
cordova.define('com.gzx.hello.OpenQQ', function(require, exports, module){
var exec = require("cordova/exec");
/**
* Constructor.
*
* @returns {OpenQQPllugin}
*/
function OpenQQPllugin()
{
};
/**
* Read code from scanner.
*
* @param {Function}
* successCallback This function will recieve a result object: { text :
* '12345-mock', // The code that was scanned. format :
* 'FORMAT_NAME', // Code format. cancelled : true/false, // Was
* canceled. }
* @param {Function}
* errorCallback
*/
OpenQQPllugin.prototype.openQQ = function (successCallback, errorCallback)
{
if (errorCallback == null)
{
errorCallback = function (){
};
}
if (typeof errorCallback != "function")
{
console.log("OpenQQPllugin.open failure: failure parameter not a function");
return;
}
if (typeof successCallback != "function")
{
console.log("OpenQQPllugin.open failure: success callback parameter must be a function");
return;
}
exec(successCallback, errorCallback, 'OpenQQ', 'open',[]);
};
var openQQPllugin = new OpenQQPllugin();
module.exports = openQQPllugin;
});
3、将自己的插件加入到PhoneGap的配置中
打开目录中res/xml/plugins.xml文件,在最后面加上
<feature name="OpenQQ">
<param name="android-package" value="com.gzx.hello.OpenQQ" />
</feature>
注意name要和你的插件类名一致! value是类的包名.类名。
至此,打开QQ的插件已经完成,可以测试一下,建一个index.html,如果要使用插件功能,必须要引用cordova.js和openQQ.js,代码如下:
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
<meta name="viewport"
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<!-- <link rel="stylesheet" type="text/css" href="css/index.css" /> -->
<title>Hello World</title>
<link rel="stylesheet" href="jquery.mobile-1.4.1.min.css">
<script type="text/javascript" charset="utf-8" src="jquery-1.9.1.min.js"></script>
<script src="jquery.mobile-1.4.1.min.js"></script>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8" src="openQQ.js"></script>
<script type="text/javascript">
function openQQ()
{
var openQQPllugin = cordova.require('com.gzx.hello.OpenQQ');
openQQPllugin.openQQ(function (result) {
alert(result.info);
}, function (error) {
alert(error);
},tel, content
);
}
</script>
</head>
<body>
<button οnclick="openQQ();">打开QQ</button> <br>
</body>
</html>
这只是一个简单的Demo用以熟悉phonegap的插件开发,需要加入1、实现功能的java类;2、调用java功能对应的javascript API;3、插件加入配置文件