需求:通过手机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 onclick="openQQ();">打开QQ</button> <br> </body> </html>