幾年前使用Cordova 進行兩個app之間的相互調用和通信;當時也是幾經折騰,今天把它整理出來,理一下思路,也方便有一樣需求的朋友參考java
require("cordova!com.lampa.startapp-master");
這個插件下載 https://github.com/dengxiaoning/com.lampa.startapp
(申明:該插件參考https://github.com/lampaa/com.lampa.startapp本身實現了ios的參數傳遞以及 downloadApps
應用下載的功能)android
首選來看看這個插件的實現ios
<js-module src="www/startApp.js" name="startapp"> <merges target="startApp" /> </js-module>
指定了js module 的路徑和調用時的名稱target="startApp"
git
<!-- android --> <platform name="android"> <config-file target="res/xml/config.xml" parent="/*"> <feature name="startApp"> <param name="android-package" value="com.lampa.startapp.startApp"/> </feature> </config-file> <source-file src="src/android/startApp.java" target-dir="src/com/lampa/startapp" /> </platform> <platform name="ios"> <config-file target="config.xml" parent="/*"> <feature name="startApp"> <param name="ios-package" value="startApp"/> </feature> </config-file> <header-file src="src/ios/startApp.h"/> <source-file src="src/ios/startApp.m"/> </platform>
指定插件源文件路徑,根據不一樣平臺,定義插件包名、將文件寫入平臺指定的路徑下github
var exec = require('cordova/exec'); module.exports = { set: function(params, extra) { var output = [params]; if(extra != undefined) { output.push(extra); } else { output.push(null); } return { start: function(completeCallback, errorCallback) { completeCallback = completeCallback || function() {}; errorCallback = errorCallback || function() {}; exec(completeCallback, errorCallback, "startApp", "start", output); }, }, /** * extra values */ getExtras: function(completeCallback, errorCallback) { exec(completeCallback, errorCallback, "startApp", "getExtras", []); }, }
該js 實現了使用Cordova 調用android 和 ios 原生接口而後返回參數,
如:exec(completeCallback, errorCallback, "startApp", "start", output);
其中startApp
指定調用的類名
【ios是@interface startApp : CDVPlugin
,android是public class startApp extends CordovaPlugin
】;
start
指定調用該類的方法名;其餘參數就是cordova 導出的成功、錯誤回調和攜帶返回數據。web
/** * download application from market * */ public void downloadApps(JSONArray args, CallbackContext callback){ JSONObject params; try { if(args.get(0) instanceof JSONObject){ params = args.getJSONObject(0); if(params.has("application")) { Uri uri = Uri.parse("market://details?id="+params.getString("application")+""); Intent it = new Intent(Intent.ACTION_VIEW, uri); cordova.getActivity().startActivity(it); } if(params.has("downloadurl")){ cordova.getActivity().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(params.getString("downloadurl")))); } } } catch (JSONException e) { callback.error("JSONException: " + e.getMessage()); e.printStackTrace(); } catch (ActivityNotFoundException e) { callback.error("ActivityNotFoundException: " + e.getMessage()); e.printStackTrace(); } }
增長Android 根據路徑下載apk的方法
shell
- (void)getExtras:(CDVInvokedUrlCommand*)command; - (void)downloadApps:(CDVInvokedUrlCommand*)command; - (void)exitApplication:(CDVInvokedUrlCommand*)command;
增長ISO平臺下 獲取應用調用時傳入的參數,在未安裝時根據url下載應用
apache
- (void)getExtras:(CDVInvokedUrlCommand*)command{ CDVPluginResult* pluginResult = nil; // 從 url中獲取保存的參數,將其返回給Cordova NSString *userurl = [[NSUserDefaults standardUserDefaults] objectForKey:@"url"]; if(userurl == nil || userurl == NULL){ NSString *addResult = @"returnFalse"; pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:addResult]; }else{ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:userurl]; [[NSUserDefaults standardUserDefaults] setObject:nil forKey:@"url"]; } [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } -(void)downloadApps:(CDVInvokedUrlCommand*)command{ CDVPluginResult* pluginResult = nil; NSString* scheme = [command.arguments objectAtIndex:0]; if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:scheme]]; pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:(true)]; } else { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsBool:(false)]; } [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - (void)exitApplication:(CDVInvokedUrlCommand*)command { exit(0); }
首先將該ios文件導入xcode,點擊.xcodeproj後綴的文件,xcode將會自動打開,再找到 LSApplicationQueriesScheme 爲應用添加容許訪問的app的白名單。 而後添加Scheme(只有這樣另外一個app在添加白名單時才知道寫什麼)。具體操做以下圖json
|
|
|
|
同時配置ios訪問設備的一些權限,不然無權限訪問時應用會崩潰
找到 你的項目名-info.plist
文件打開,在最後一個array標籤下加入配置xcode
<!-- 相冊 --> <key>NSPhotoLibraryUsageDescription</key> <string>App須要您的贊成,才能訪問相冊</string> <!-- 相機 --> <key>NSCameraUsageDescription</key> <string>App須要您的贊成,才能訪問相機</string> <!-- 麥克風 --> <key>NSMicrophoneUsageDescription</key> <string>App須要您的贊成,才能訪問麥克風</string> <!-- 位置 --> <key>NSLocationUsageDescription</key> <string>App須要您的贊成,才能訪問位置</string> <!-- 在使用期間訪問位置 --> <key>NSLocationWhenInUseUsageDescription</key> <string>App須要您的贊成,才能在使用期間訪問位置</string> <!-- 始終訪問位置 --> <key>NSLocationAlwaysUsageDescription</key> <string>App須要您的贊成,才能始終訪問位置</string> <!-- 日曆 --> <key>NSCalendarsUsageDescription</key> <string>App須要您的贊成,才能訪問日曆</string> <!-- 提醒事項 --> <key>NSRemindersUsageDescription</key> <string>App須要您的贊成,才能訪問提醒事項</string> <!-- 運動與健身 --> <key>NSMotionUsageDescription</key> <string>App須要您的贊成,才能訪問運動與健身</string> <!-- 健康更新 --> <key>NSHealthUpdateUsageDescription</key> <string>App須要您的贊成,才能訪問健康更新 </string> <!-- 健康分享 --> <key>NSHealthShareUsageDescription</key> <string>App須要您的贊成,才能訪問健康分享</string> <!-- 藍牙 --> <key>NSBluetoothPeripheralUsageDescription</key> <string>App須要您的贊成,才能訪問藍牙</string> <!-- 媒體資料庫 --> <key>NSAppleMusicUsageDescription</key> <string>App須要您的贊成,才能訪問媒體資料庫</string>
操做截圖
|
|
本身寫的一個配置ios 相關權限和Scheme的xml
建立如上相似文件夾考入便可:
<?xml version="1.0" encoding="UTF-8"?> <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-plistconfig" version="5.3.0"> <name>開啓第三方應用</name> <description>新開啓第三方應用相關配置</description> <license>MIT</license> <keywords>cordova,sina</keywords> <!--require cordova version --> <engines> <engine name="cordova" version=">=3.5.0" /> </engines> <!-- ios --> <platform name="ios"> <!-- 容許訪問的應用的 Scheme白名單,如打包A應用;此處應寫B應用的scheme,(假如 將A定義爲 aapp B定義爲bapp 配置以下)。 反之打包的是B應用下面的配置就要反過來寫了 --> <config-file platform="ios" target="*-Info.plist" parent="LSApplicationQueriesSchemes"> <array> <string>bapp</string> </array> </config-file> <!-- 當前應用本身的 Scheme --> <config-file platform="ios" target="*-Info.plist" parent="CFBundleURLTypes"> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLSchemes</key> <array> <string>aapp</string> </array> </dict> </array> </config-file> <!-- 配置相關權限 --> <config-file platform="ios" target="*-Info.plist" parent="NSAppleMusicUsageDescription"> <string>App須要您的贊成,才能訪問媒體資料庫</string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSBluetoothPeripheralUsageDescription"> <string>App須要您的贊成,才能訪問藍牙</string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSCalendarsUsageDescription"> <string>App須要您的贊成,才能訪問日曆</string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSCameraUsageDescription"> <string>App須要您的贊成,才能訪問相機</string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSHealthShareUsageDescription"> <string>App須要您的贊成,才能訪問健康分享</string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSHealthUpdateUsageDescription"> <string>App須要您的贊成,才能訪問健康更新 </string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSLocationAlwaysUsageDescription"> <string>App須要您的贊成,才能始終訪問位置</string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSLocationUsageDescription"> <string>App須要您的贊成,才能訪問位置</string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSLocationWhenInUseUsageDescription"> <string>App須要您的贊成,才能在使用期間訪問位置</string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSMainNibFile"> <string></string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSMainNibFile~ipad"> <string></string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSMicrophoneUsageDescription"> <string>App須要您的贊成,才能訪問麥克風</string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSMotionUsageDescription"> <string>App須要您的贊成,才能訪問運動與健身</string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSPhotoLibraryUsageDescription"> <string>App須要您的贊成,才能訪問相冊</string> </config-file> <config-file platform="ios" target="*-Info.plist" parent="NSRemindersUsageDescription"> <string>App須要您的贊成,才能訪問提醒事項</string> </config-file> </platform> </plugin>
// 在該方法中新增以下代碼 - (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation{ NSString *URLString= [url absoluteString]; [[NSUserDefaults standardUserDefaults] setObject:URLString forKey:@"url"]; [[NSUserDefaults standardUserDefaults] synchronize]; }
操做截圖
A應用調用B應用的方法
invokeBapp(){ var sApp; sApp = startApp.set({// 設置應用包名----注意修改----該包名對應【被叫application】 "application" : "com.myapplication.bapp"// 替換爲你真實的包名 }, {//傳遞給B應用的參數 "username" : "lili" "userId" : "123456" }); /* * 監測應用是否安裝 */ cordova.plugins.fileOpener2.appIsInstalled(packageName, { success : function(res) { if (res.status === 0) { startApp.downloadApps({ "downloadurl":「https://192.168.1.1:8080/bapp/bapp.apk」 //替換爲你服務器真實的apk路徑 },function(success){ console.log("success"); },function(error){ alert(error); }); } else { sApp.start(function(success) { // success console.log("OK"); }, function(error) { // fail alert(error); }); } } }); }
A應用調用B應用的方法
invokeBapp(){ var sApp; var sendParams = "username:lili;userId:123456"; //傳遞給B應用的參數(ios不能傳遞json對象) var twitter = 「bapp://」; // B應用的Scheme(就是上面 第三 步配置的那個 再加上冒號和雙斜槓就ok了) sApp = startApp.set(twitter + sendParams + ""); /* 監測是否安裝應用 */ sApp.check(function(values) { sApp.start(function(success) { // success }, function(error) { // fail alert(error); }); }, function(error) { startApp.downloadApps({ "downloadurl":"itms-services:///?action=download-manifest&url=https://192.168.1.1:8080/bapp/dependence.plist" //替換爲你服務器真實的plis路徑(這裏使用的是plist進行ipa下載,若是你已經發布到AppStore那就直接寫AppStore下載路徑了) }); }
receiveAappParams(){ startApp.getExtras(function(res){ // to do something... console.log(res); }); }
因爲沒u有上傳到商店,ipa沒法在ios應用中下載,全部使用plis進行ipa映射,而後調用Safari進行下載安裝
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>items</key> <array> <dict> <key>assets</key> <array> <dict> <key>kind</key> <string>software-package</string> <key>url</key> <!-- ipa位於服務器的真實路徑 --> <string>https://192.168.1.1:8080/bapp/bapp.ipa</string> </dict> <dict> <key>kind</key> <string>full-size-image</string> <key>needs-shine</key> <true/> <key>url</key> <!-- app下載時顯示的圖標 --> <string>https://192.168.1.1:8080/bapp/icon.png</string> </dict> <dict> <key>kind</key> <string>display-image</string> <key>needs-shine</key> <true/> <key>url</key> <!-- app下載時顯示的圖標 --> <string>https://192.168.1.1:8080/bapp/icon.png</string> </dict> </array> <key>metadata</key> <dict> <key>bundle-identifier</key> <!-- app包名 --> <string>com.myapplication.bapp</string> <key>bundle-version</key> <!-- app當前版本 --> <string>1.0.0</string> <key>kind</key> <string>software</string> <key>title</key> <!-- app名稱 --> <string>客戶諮詢平臺</string> </dict> </dict> </array> </dict> </plist>
ok到這裏就結束了,寫得不對 的地方請指正,有更好的方法請分享