首页 > 代码库 > 浏览器端javascript调用手机终端本地功能实现02-功能点汇总

浏览器端javascript调用手机终端本地功能实现02-功能点汇总

  上篇博文已经说明,本篇直接进入主题。本篇大致说明总体功能以及代码用途,下篇将功能点逐一详细说明。

  功能点包括:

  1.   拍照相关接口(camera)

功能函数名称

作用

备注

invokeCamera()

调用摄像头拍照

 

requestAlbum()

调用相册功能

 

requestAlbumMulti()

相册多选

 

requestAlbumMultiUpload()

相册多选完后上传

 

  2.  录音相关接口(media)

功能函数名称

作用

备注

startRecord()

录制音频

 

stopRecord()

停止录制

 

playRecord()

播放录制完成的音频

 

stopPlay()

停止播放录制完成的音频

 

upload()

上传音频文件

 

  3.  二维码、条形码扫码(scan)

功能函数名称

作用

备注

scan()

扫描条码

 

  4.  其他接口

功能函数名称

作用

备注

saveLoginInfo ()

保存登陆信息

app需要web浏览器网页数据时

  PS:后续会根据需要增加其他功能

  调用摄像拍照,上传语音文件等功能,最终要上传到服务器。所以请先搭建好服务器,这里我是自己搭建了PHP服务器。接收请求参数file,类型为文件,服务器部分您可以自己实现,不在本博文内容范围内。后期为便于大家测试之用,应该会将接口公布在外网。

  将分3部分说明,贴出部分代码,后续文章同样遵循此步骤。

  1.JS文件部分

  • android部分采用系统addJavascriptInterface添加js接口的方式实现
  • ios部分采用拦截特定的请求实现
  • 核心js函数(之后的js调用都用到此函数)

  

 1 /** 2  *@description Web js communications with mobile terminal local function 3  *@author yanrongxiang 4  *@date 2014-7-17 5  */ 6 function controllerCenter(type,cmd,params){ 7     if(navigator.userAgent.toLowerCase().indexOf(‘iphone‘)>0){ 8         document.location="http://QM_APP_WEBVIEW_ENGINE:"+cmd+":"+params; 9     }else if(navigator.userAgent.indexOf(‘Android‘)>0){10         eval(‘javascript:QM_APP_WEBVIEW_ENGINE_‘+type+‘.‘+cmd+‘("‘+params+‘")‘);11     }else{12         alert("Can‘t use this feature");13     }14 }

使用javascript调用摄像头及相册部分

  

 1 //Access to the camera function 2 var $camera={ 3     "invokeCamera":function(params){ 4         controllerCenter(‘camera‘,‘invoke_camera‘,params); 5     }, 6     "requestAlbum":function(params){ 7         controllerCenter(‘camera‘,‘request_albums‘,params); 8     }, 9     "requestAlbumMulti":function(params){10         controllerCenter(‘camera‘,‘request_albums_multi‘,params);11     },12     "requestAlbumMultiUpload":function(params){13         controllerCenter(‘camera‘,‘request_albums_multi_upload‘,params);14     }15 }

使用javascript调用录音,播放部分

 1 //Access to the media function 2 var $media={ 3     "startRecord":function(params){ 4         controllerCenter(‘media‘,‘start_record‘,params); 5     }, 6     "stopRecord":function(params){ 7         controllerCenter(‘media‘,‘stop_record‘,params); 8     }, 9     "playRecord":function(params){10         controllerCenter(‘media‘,‘play_record‘,params);11     },12     "stopPlay":function(params){13         controllerCenter(‘media‘,‘stop_play‘,params);14     },15     "upload":function(params){16         controllerCenter(‘media‘,‘upload_to_server‘,params);17     }18 }

使用javascript调用二维码,条形码扫描部分

1 var $scanbar={2     "scan":function(params){3         controllerCenter(‘scan‘,‘scan_bar‘,params);4     }5 }

 

    

  2.android端实现

  说明:以下为android应用启动展现的第一个activity,在此activity里面放入Webview控件,请求服务器html页面

  

  1 package com.qimeng.activity;  2   3 import java.io.File;  4 import java.io.FileNotFoundException;  5 import java.io.FileOutputStream;  6 import java.io.IOException;  7 import java.util.ArrayList;  8 import java.util.List;  9  10 import android.annotation.SuppressLint; 11 import android.app.AlertDialog; 12 import android.app.Notification; 13 import android.content.ContentResolver; 14 import android.content.DialogInterface; 15 import android.content.DialogInterface.OnKeyListener; 16 import android.content.res.Resources; 17 import android.content.Intent; 18 import android.graphics.Bitmap; 19 import android.graphics.BitmapFactory; 20 import android.net.Uri; 21 import android.os.Bundle; 22 import android.os.Environment; 23 import android.os.Handler; 24 import android.util.Log; 25 import android.view.KeyEvent; 26 import android.view.View; 27 import android.view.View.OnClickListener; 28 import android.webkit.JsResult; 29 import android.webkit.WebChromeClient; 30 import android.webkit.WebSettings; 31 import android.webkit.WebView; 32 import android.widget.Button; 33 import android.widget.EditText; 34 import android.widget.TextView; 35 import android.widget.Toast; 36  37 import com.baidu.android.pushservice.BasicPushNotificationBuilder; 38 import com.baidu.android.pushservice.CustomPushNotificationBuilder; 39 import com.baidu.android.pushservice.PushConstants; 40 import com.baidu.android.pushservice.PushManager; 41 import com.qimeng.R; 42 import com.qimeng.api.JSInterfaceAPI; 43 import com.qimeng.common.BaseActivity; 44 import com.qimeng.common.IBaseActivity; 45 import com.qimeng.workman.common.imgsupload.util.Bimp; 46 import com.qimeng.workman.common.imgsupload.util.FileUtils; 47  48 /** 49  *  50  */ 51 @SuppressLint("SetJavaScriptEnabled") public class IndexActivity extends BaseActivity implements IBaseActivity { 52     private String[] paramJS; 53     EditText tv_url; 54     public WebView webView; 55     private Handler myHandler; 56     JSInterfaceAPI jsApi = new JSInterfaceAPI(); 57     private static final int REQUEST_CODE_UPLOAD = 300; 58     public static final int REQUEST_CODE_MULTI_UPLOAD = 3001; 59     public static final int REQUEST_CODE_MEDIA_UPLOAD = 3002; 60     private JSInterfaceCamera jsInterfaceCamera; 61     private JSInterfaceMedia jsInterfaceMedia; 62     private JSInterfaceSetting jsInterfaceSetting; 63     private JSInterfaceScanbar jsInterfaceScanbar; 64     public int currentUploadNums=0; 65     @Override 66     protected void onCreate(Bundle savedInstanceState) { 67         super.onCreate(savedInstanceState); 68         setContentView(R.layout.activity_index); 69         myHandler=new Handler(); 70         webView=(WebView)this.findViewById(R.id.webview); 71         webView.getSettings().setJavaScriptEnabled(true); 72         //webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); 73         //webView.getSettings().setAllowFileAccess(true);// 设置允许访问文件数据 74         //webView.getSettings().setSupportZoom(true); 75         //webView.getSettings().setBuiltInZoomControls(true); 76         //webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); 77         //webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 78         //webView.getSettings().setDomStorageEnabled(true); 79         //webView.getSettings().setDatabaseEnabled(true); 80         //webView.getSettings().setLoadsImagesAutomatically(true); 81         tv_url=(EditText)findViewById(R.id.tv_url); 82         Button btn=(Button)findViewById(R.id.btn_ok); 83         tv_url.setText("http://10.1.2.123/webview/"); 84         btn.setOnClickListener(new OnClickListener() { 85             @Override 86             public void onClick(View arg0) { 87                 webView.loadUrl(tv_url.getText().toString()); 88             } 89         }); 90          91         webView.setWebChromeClient(new WebChromeClient(){ 92             @Override 93             public boolean onJsAlert(WebView view, String url, String message, 94                     JsResult result) { 95                 AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext()); 96                 builder.setTitle("提示").setMessage(message).setPositiveButton("确定", null); 97                 // 不需要绑定按键事件   98                 // 屏蔽keycode等于84之类的按键 99                 builder.setOnKeyListener(new OnKeyListener() {100                     public boolean onKey(DialogInterface dialog, int keyCode,KeyEvent event) {  101                         Log.v("onJsAlert", "keyCode==" + keyCode + "event="+ event);  102                         return true;  103                     }104                 });105                 // 禁止响应按back键的事件  106                 builder.setCancelable(false);  107                 AlertDialog dialog = builder.create();  108                 dialog.show();  109                 result.confirm();// 因为没有绑定事件,需要强行confirm,否则页面会变黑显示不了内容。  110                 return true; 111             }112         });113         jsInterfaceCamera=new JSInterfaceCamera(this, myHandler);114         jsInterfaceMedia=new JSInterfaceMedia(this, myHandler);115         jsInterfaceSetting=new JSInterfaceSetting(this, myHandler);116         jsInterfaceScanbar=new JSInterfaceScanbar(this, myHandler);117         //添加js与本地代码通讯接口118         webView.addJavascriptInterface(jsInterfaceCamera, "QM_APP_WEBVIEW_ENGINE_camera");119         webView.addJavascriptInterface(jsInterfaceMedia, "QM_APP_WEBVIEW_ENGINE_media");120         webView.addJavascriptInterface(jsInterfaceSetting, "QM_APP_WEBVIEW_ENGINE_setting");121         webView.addJavascriptInterface(jsInterfaceScanbar, "QM_APP_WEBVIEW_ENGINE_scan");122         //集成百度推送123         PushManager.startWork(this, PushConstants.LOGIN_TYPE_API_KEY, "SQgonTuwWx3cQc2wPxYimgCQ");124         Resources resource = this.getResources();125         String pkgName = this.getPackageName();126         CustomPushNotificationBuilder cBuilder = new CustomPushNotificationBuilder(127                 getApplicationContext(), resource.getIdentifier(128                         "notification_custom_builder", "layout", pkgName),129                 resource.getIdentifier("notification_icon", "id", pkgName),130                 resource.getIdentifier("notification_title", "id", pkgName),131                 resource.getIdentifier("notification_text", "id", pkgName));132         cBuilder.setNotificationFlags(Notification.FLAG_AUTO_CANCEL);133         cBuilder.setNotificationDefaults(Notification.DEFAULT_SOUND134                 | Notification.DEFAULT_VIBRATE);135         //cBuilder.setStatusbarIcon(this.getApplicationInfo().icon);136         cBuilder.setLayoutDrawable(resource.getIdentifier("simple_notification_icon", "drawable", pkgName));137         PushManager.setNotificationBuilder(this, 1, cBuilder);138     }139 140     public void refresh(final Object... param) {141         super.refresh(param);142         int flag = ((Integer) param[0]).intValue();// 获取第一个参数143         switch (flag) {144         case 10001:145             break;146         case REQUEST_CODE_UPLOAD:147             webView.post(new Runnable() {148                 @Override149                 public void run() {150                     webView.loadUrl("javascript:"+paramJS[1]+"(\""+(paramJS.length>=2?param[1].toString():"Can‘t get the callback, confirm your parameters correctly")+"\")");151                 }152             });153             break;154         case REQUEST_CODE_MULTI_UPLOAD:155             currentUploadNums++;156             webView.post(new Runnable() {157                 @Override158                 public void run() {159                     webView.loadUrl("javascript:"+paramJS[1]+"(\""+(paramJS.length>=2?param[1].toString():"Can‘t get the callback, confirm your parameters correctly")+"\","+Bimp.drr.size()+","+currentUploadNums+")");160                     if(currentUploadNums<Bimp.drr.size()){161                         File f=new File(Bimp.drr.get(currentUploadNums).toString());162                         jsApi.uploadPhoto((paramJS[0].indexOf("http:")==0?"":"http://")+paramJS[0], f, IndexActivity.this, IndexActivity.REQUEST_CODE_MULTI_UPLOAD);163                     }164                 }165             });166             break;167         case REQUEST_CODE_MEDIA_UPLOAD:168             webView.post(new Runnable() {169                 @Override170                 public void run() {171                     jsInterfaceMedia.isRecorded=0;172                     webView.loadUrl("javascript:"+paramJS[1]+"(\""+(paramJS.length>=2?param[1].toString():"Can‘t get the callback, confirm your parameters correctly")+"\")");173                 }174             });175             break;176         }177     }178 179     public void initListener() {180         super.initListener();181     }182 183     public void initView() {184         super.initView();185     }186     private Bitmap bmp;187     protected void onActivityResult(int requestCode, int resultCode, final Intent data) {  188         super.onActivityResult(requestCode, resultCode, data);189             if(requestCode==jsInterfaceScanbar.SELECT_SCANER){190                 if(resultCode == 1){191                     Bundle bundle = data.getExtras();192                     Log.e("##############JFKDJFDKJFKDFJ############", "{\"Result\":\""+bundle.getString("Result")+",\"Format\":\""+bundle.getString("Format")+"\"}");193                     webView.loadUrl("javascript:"+paramJS[0]+"({\"Result\":\""+bundle.getString("Result")+"\",\"Format\":\""+bundle.getString("Format")+"\"})");194                 }195             }else{196                 if(resultCode == RESULT_OK){197                     upload_carmare_photo(data);198                 }199             }200     }201     protected void onRestart() {202         super.onRestart();203         if(Bimp.drr.size()>0){204 //            如果为相册多选回到主界面时205             StringBuffer sb=new StringBuffer();206             //List<String> list = new ArrayList<String>();207             sb.append("[");208             for (int i = 0; i < Bimp.drr.size(); i++) {209                 //String Str = Bimp.drr.get(i).substring( 210                 //        Bimp.drr.get(i).lastIndexOf("/") + 1,211                 //        Bimp.drr.get(i).lastIndexOf("."));212                 //list.add(FileUtils.SDPATH+Str+".JPEG");213                 sb.append("{\"path\":\""+Bimp.drr.get(i).toString()+"\"}");214                 if(i<Bimp.drr.size()-1){215                     sb.append(",");216                 }217             }218             sb.append("]");219             final String sbStr=sb.toString();220             //调用网页函数221             if(paramJS.length>2){222                 webView.post(new Runnable() {223                     @Override224                     public void run() {225                         webView.loadUrl("javascript:"+paramJS[2]+"("+sbStr+")");226                     }227                 });228             }else{229                 webView.loadUrl("javascript:"+paramJS[2]+"(\"Can‘t get the callback, confirm your parameters correctly\")");230             }231         }232     }233     public String[] getParamJS() {234         return paramJS;235     }236 237     public void setParamJS(String[] paramJS) {238         this.paramJS = paramJS;239     }240     241     public void     upload_carmare_photo(final Intent data){242         Thread thread=new Thread(){243             @Override244             public void run() {245                 super.run();246                 //选择图片  247                 Uri uri = data.getData();   248                 ContentResolver cr = IndexActivity.this.getContentResolver();   249                 try {  250                     if(bmp != null)//如果不释放的话,不断取图片,将会内存不够  251                         bmp.recycle();  252                     bmp = BitmapFactory.decodeStream(cr.openInputStream(uri));  253                 } catch (FileNotFoundException e) {  254                     // TODO Auto-generated catch block  255                     e.printStackTrace();  256                 }  257                 System.out.println("the bmp toString: " + bmp);258                 File fileDir = new File(Environment.getExternalStorageDirectory() + "/Myimage");259                 if (!fileDir.exists()) {260                     fileDir.mkdirs();// 创建文件夹261                 }262                    File file = new File(Environment.getExternalStorageDirectory()263                     + "/Myimage/", String.valueOf(System.currentTimeMillis())264                     + ".png");265                    FileOutputStream fos;266                 try {267                     fos = new FileOutputStream(file);268                        bmp.compress(Bitmap.CompressFormat.JPEG, 50, fos);269                        fos.flush();270                        fos.close();271                 } catch (FileNotFoundException e) {272                     // TODO Auto-generated catch block273                     e.printStackTrace();274                 } catch (IOException e) {275                     // TODO Auto-generated catch block276                     e.printStackTrace();277                 }278                 if(bmp!=null){279                     jsApi.uploadPhoto((paramJS[0].indexOf("http:")==0?"":"http://")+paramJS[0], file, IndexActivity.this, REQUEST_CODE_UPLOAD);280                 }281             }282             283         };284         thread.start();285     }286 }

 

  3.IOS端实现

  说明:以下为IOS应用启动展现的第一个ViewController,在此视图控制器里面放入UIWebview控件,请求服务器html页面

  1 //  2 //  QMViewController.m  3 //  QMWebView  4 //  5 //  Created by Qimeng Tech on 14-7-15.  6 //  Copyright (c) 2014年 Qimeng Tech. All rights reserved.  7 //  8   9 #import "QMViewController.h" 10 #import "QMUtil.h" 11 #import "SecurityUtil.h" 12 #import "JSONKit.h" 13 #import "FileUtil.h" 14 #import "Toast+UIView.h" 15 #import "MLAudioRecorder.h" 16 #import "AmrRecordWriter.h" 17 #import <AVFoundation/AVFoundation.h> 18 #import "MLAudioMeterObserver.h" 19  20 @interface QMViewController () 21 @property (nonatomic, strong) MLAudioRecorder *recorder; 22 @property (nonatomic, strong) AmrRecordWriter *amrWriter; 23  24 @property (nonatomic, strong) AVAudioPlayer *player; 25  26 @property (nonatomic, copy) NSString *filePath; 27 @property (weak, nonatomic) IBOutlet UIButton *recordButton; 28 @property (nonatomic, strong) MLAudioMeterObserver *meterObserver; 29 @property (nonatomic,strong) NSTimer *timerStopRecord; 30 @property (nonatomic,assign) int timerStopNum; 31 @end 32  33 @implementation QMViewController 34 @synthesize currentParams,webView; 35 @synthesize currentUploadPhotoNum,selectMultiUploadPhotoUrls; 36 - (void)viewDidLoad 37 { 38     [super viewDidLoad]; 39     self.title=@"启梦浏览器"; 40     if( ([[[UIDevice currentDevice] systemVersion] doubleValue]>=7.0)) { 41         self.edgesForExtendedLayout = UIRectEdgeNone; 42         self.extendedLayoutIncludesOpaqueBars = NO; 43         self.modalPresentationCapturesStatusBarAppearance = NO; 44     } 45     self.webView=[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, UI_SCREEN_WIDTH, UI_SCREEN_HEIGHT-20-44)]; 46     self.webView.delegate=self; 47     [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://10.1.2.123/webview/"]]]; 48     [self.view addSubview:self.webView]; 49      50     self.selectMultiUploadPhotoUrls=[[NSMutableArray alloc] init]; 51     // Do any additional setup after loading the view, typically from a nib. 52 } 53 #pragma mark -- 54 #pragma mark UIWebViewDelegate 55 /** 56  *截获特殊请求url,完成js与本地交互 57  */ 58 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { 59      60     NSString *requestString = [[request URL] absoluteString]; 61     NSArray *components = [requestString componentsSeparatedByString:@":"]; 62     NSRange range=[[components objectAtIndex:1] rangeOfString:@"QM_APP_WEBVIEW_ENGINE"]; 63     if ([components count] > 3 && range.location == 2 && range.length == 21) { 64         NSString *cmd=(NSString *)[components objectAtIndex:2]; 65         //上传参数1、请求地址;2、成功回调函数;3、失败回调函数 66         NSArray *params=[[components objectAtIndex:3] componentsSeparatedByString:@","]; 67         //请求相册列表 68         self.currentParams=params; 69         if([cmd isEqualToString:JS_CMD_NAME_ALBUM]){ 70             [QMUtil LocalPhotos:self delegate:self]; 71         //调用摄像头 72         }else if ([cmd isEqualToString:JS_CMD_NAME_CAMERA]){ 73             [QMUtil takeCamera:self delegate:self]; 74         //请求相册列表-多选 75         }else if([cmd isEqualToString:JS_CMD_NAME_request_albums_multi]){ 76             [FileUtil cleaerImgAreaDirectory]; 77             [FileUtil createImgAreaUploadDirectory]; 78             [self.selectMultiUploadPhotoUrls removeAllObjects]; 79             self.currentUploadPhotoNum=0; 80             [QMUtil LocalPhotosSelectMulti:self delegate:self]; 81         }else if([cmd isEqualToString:JS_CMD_NAME_request_albums_multi_upload]){ 82             if (self.selectMultiUploadPhotoUrls.count>0) { 83                 [NetWorkUtil uploadFile:[NSString stringWithFormat:@"http://%@",[self.currentParams objectAtIndex:0]] localFilePath:[self.selectMultiUploadPhotoUrls objectAtIndex:0] uploadDelegate:self params:nil code:@"upload_photos_multi"]; 84             }else{ 85                 [self.view makeToast:@"没有选择上传图片,无法上传" duration:2.0 position:@"center"]; 86             } 87         //录制音频 88         }else if([cmd isEqualToString:@"start_record"]){ 89             if(self.amrWriter==nil){ 90                 [self initRecorder]; 91             } 92             if (self.recorder.isRecording) { 93                 //取消录音 94                 [self.view makeToast:@"正在录音中,请先停止" duration:2.0 position:@"center"]; 95             }else{ 96                 //开始录音 97                 [self.recorder startRecording]; 98                 self.meterObserver.audioQueue = self.recorder->_audioQueue; 99                 //防止用户不停止,录音会一直继续下去100                 self.timerStopNum=0;101                 self.timerStopRecord=[NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(timerFired:) userInfo:nil repeats:NO];102             }103         }else if([cmd isEqualToString:@"stop_record"]){104             if(self.amrWriter==nil){105                 [self initRecorder];106             }107             if (self.recorder.isRecording) {108                 //取消录音109                 [self.recorder stopRecording];110                 if(self.timerStopRecord!=nil){111                     [self.timerStopRecord invalidate];112                     self.timerStopRecord=nil;113                 }114             }else{115                 [self.view makeToast:@"还没开始录音" duration:2.0 position:@"center"];116             }117         }else if([cmd isEqualToString:@"play_record"]){118             if(self.player==nil){119                 self.player = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:self.filePath] error:nil];120             }121             NSLog(@"%@",self.filePath);122             if([self.player isPlaying]){123                 [self.view makeToast:@"正在播放中,请先停止" duration:2.0 position:@"center"];124             }else{125                 [self.player play];126             }127         }else if([cmd isEqualToString:@"stop_play"]){128             if(self.player==nil){129                 self.player = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:self.filePath] error:nil];130             }131             NSLog(@"%@",self.filePath);132             if([self.player isPlaying]){133                 [self.player stop];134             }135         }else if([cmd isEqualToString:@"upload_to_server"]){136             if(!self.filePath){137                 [self.view makeToast:@"请先录制音频" duration:2.0 position:@"center"];138                 return NO;139             }140             [NetWorkUtil uploadFile:[NSString stringWithFormat:@"http://%@",[self.currentParams objectAtIndex:0]] localFilePath:self.filePath uploadDelegate:self params:nil code:@"upload_media"];141         }else if([cmd isEqualToString:@"save_login_info"]){142             NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];143             if ([self.currentParams count]>=3) {144                 [defaults setObject:[self.currentParams objectAtIndex:0] forKey:@"uid"];145             }else{146                 [self.view makeToast:@"请设置正确的参数" duration:2.0 position:@"center"];147             }148             [defaults synchronize];149             //发送推送的userid到服务器150             //[NetWorkUtil uploadFile:[NSString stringWithFormat:@"http://%@",[self.currentParams objectAtIndex:0]] localFilePath:self.filePath uploadDelegate:self params:nil code:@"upload_media"];151         }else if ([cmd isEqualToString:@"scan_bar"]){152             if (TARGET_IPHONE_SIMULATOR) {153                 ZBarReaderViewController *controller=[[ZBarReaderViewController alloc] initWithNibName:nil bundle:nil];154                 [self presentModalViewController:controller animated:YES];155             }156         }157         return NO;158     }159     return YES;160 }161 -(void) timerFired:(id)sender{162     self.timerStopNum++;163     if(self.timerStopNum==5){164         if (self.recorder&&self.recorder.isRecording){165             [self.recorder stopRecording];166             NSLog(@"时间到,已自动停止录音");167             [self.timerStopRecord invalidate];168             self.timerStopRecord=nil;169         }170     }171 }172 #pragma make QBImagePickerControllerDelegate delegate173 #pragma make UIImagePickerControllerDelegate174 //当选择一张图片后进入这里175 -(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary *)info176 {177     //系统自带的相册单选178     if ([picker isKindOfClass:[UIImagePickerController class]]) {179         NSString *type = [info objectForKey:UIImagePickerControllerMediaType];180         //当选择的类型是图片181         if ([type isEqualToString:@"public.image"]){182             //关闭相册界面183             [picker dismissViewControllerAnimated:YES completion:^{}];184             //先把图片转成NSData185             UIImage* image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];186             NSData *data;187             //if (UIImagePNGRepresentation(image) == nil){188                 data = http://www.mamicode.com/UIImageJPEGRepresentation(image, 0.5);189             //}190             //else{191             //    data = http://www.mamicode.com/UIImagePNGRepresentation(image);>192             //}193             //图片保存的路径194             //这里将图片放在沙盒的documents文件夹中195             NSString * DocumentsPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];196             //文件管理器197             NSFileManager *fileManager = [NSFileManager defaultManager];198             //把刚刚图片转换的data对象拷贝至沙盒中 并保存为image.png199             [fileManager createDirectoryAtPath:DocumentsPath withIntermediateDirectories:YES attributes:nil error:nil];200             NSString *path=[DocumentsPath stringByAppendingString:@"/image.png"];201             [fileManager createFileAtPath:path contents:data attributes:nil];202             //得到选择后沙盒中图片的完整路径203             //NSString *filePath = [[NSString alloc]initWithFormat:@"%@%@",DocumentsPath,  @"/image.png"];204 205             //创建一个选择后图片的小图标放在下方206             //类似微薄选择图后的效果207             UIImageView *smallimage = [[UIImageView alloc] initWithFrame:CGRectMake(50, 120, 40, 40)];208             smallimage.image = image;209         210             //上传图片211             [NetWorkUtil uploadFile:[NSString stringWithFormat:@"http://%@",[self.currentParams objectAtIndex:0]] localFilePath:path uploadDelegate:self params:nil code:@"upload_photo"];212             //操作完后回调网页js213             //[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(‘nihao‘)",[picker.userParam objectAtIndex:1]]];214         ;215             //加在视图中216             //[self.view addSubview:smallimage];217         }218     }else{219         //自定义的相册多选220         NSArray *mediaInfoArray = (NSArray *)info;221         NSLog(@"Selected %d photos and mediaInfoArray==%@", mediaInfoArray.count,mediaInfoArray);222         NSString *resultJson=@"[";223         for (int i=0;i<mediaInfoArray.count; i++) {224             NSDictionary *mediaInfo = [mediaInfoArray objectAtIndex:i];225             UIImage *image= [mediaInfo objectForKey:@"UIImagePickerControllerOriginalImage"];226             NSString *fileUrl=[NSString stringWithFormat:@"%@/local_%d.jpg",[FileUtil getImgAreaUploadDirecoty],i];227             image=[QMUtil makeThumbnailFromImage:image scale:0.5];228             [UIImageJPEGRepresentation(image, 0.5) writeToFile:fileUrl atomically:YES];229             //image=[UIUtil makeThumbnailFromImage:image scale:0.7];230             //[UIImagePNGRepresentation(image) writeToFile:fileUrl atomically:YES];231             resultJson=[resultJson stringByAppendingString:[NSString stringWithFormat:@"{\"path\":\"%@\"}",fileUrl]];232             [self.selectMultiUploadPhotoUrls addObject:fileUrl];233             if (i<mediaInfoArray.count-1) {234                 resultJson=[resultJson stringByAppendingString:@","];235             }236         }237         resultJson=[resultJson stringByAppendingString:@"]"];238         [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(%@)",[self.currentParams objectAtIndex:2],resultJson]];239         [self dismissViewControllerAnimated:YES completion:NULL];240     }241     242 }243 - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker244 {245     NSLog(@"您取消了选择图片");246     [picker dismissViewControllerAnimated:YES completion:^{}];247     [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(‘‘)",[self.currentParams objectAtIndex:2]]];248 }249 - (void)didReceiveMemoryWarning250 {251     [super didReceiveMemoryWarning];252     // Dispose of any resources that can be recreated.253 }254 -(void) uploadDelegate:(NSString *)response code:(NSString *)code error:(NSError *)error{255     if ([response rangeOfString:@"http://"].length==7) {256         if ([@"upload_photo" isEqualToString:code]) {257             [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(‘%@‘)",[self.currentParams objectAtIndex:1],response]];258         }else if([@"upload_photos_multi" isEqualToString:code]) {259             self.currentUploadPhotoNum++;260             [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(‘%@‘,%d,%d)",[self.currentParams objectAtIndex:1],response,self.selectMultiUploadPhotoUrls.count,self.currentUploadPhotoNum]];261             if (self.currentUploadPhotoNum<self.selectMultiUploadPhotoUrls.count) {262                 //继续上传263                 [NetWorkUtil uploadFile:[NSString stringWithFormat:@"http://%@",[self.currentParams objectAtIndex:0]] localFilePath:[self.selectMultiUploadPhotoUrls objectAtIndex:self.currentUploadPhotoNum] uploadDelegate:self params:nil code:@"upload_photos_multi"];264             }265         }else if ([@"upload_media" isEqualToString:code]) {266             [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(‘%@‘)",[self.currentParams objectAtIndex:1],response]];267         }268 269     }else{270         [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(‘%@‘)",[self.currentParams objectAtIndex:2],response]];271     }272 }273 274 -(void) initRecorder{275     NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];276     AmrRecordWriter *amrWriter = [[AmrRecordWriter alloc]init];277     amrWriter.filePath = [path stringByAppendingPathComponent:@"record.amr"];278     amrWriter.maxSecondCount = 60;279     amrWriter.maxFileSize = 1024*256;280     amrWriter.cafFilePath = [path stringByAppendingPathComponent:@"recordAmr.caf"];281     self.amrWriter = amrWriter;282     283     284     MLAudioMeterObserver *meterObserver = [[MLAudioMeterObserver alloc]init];285     meterObserver.actionBlock = ^(NSArray *levelMeterStates,MLAudioMeterObserver *meterObserver){286         NSLog(@"volume:%f",[MLAudioMeterObserver volumeForLevelMeterStates:levelMeterStates]);287     };288     meterObserver.errorBlock = ^(NSError *error,MLAudioMeterObserver *meterObserver){289         [[[UIAlertView alloc]initWithTitle:@"错误" message:error.userInfo[NSLocalizedDescriptionKey] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"知道了", nil]show];290     };291     self.meterObserver = meterObserver;292     MLAudioRecorder *recorder = [[MLAudioRecorder alloc]init];293     __weak __typeof(self)weakSelf = self;294     recorder.receiveStoppedBlock = ^{295         [weakSelf.recordButton setTitle:@"Record" forState:UIControlStateNormal];296         weakSelf.meterObserver.audioQueue = nil;297     };298     recorder.receiveErrorBlock = ^(NSError *error){299         [weakSelf.recordButton setTitle:@"Record" forState:UIControlStateNormal];300         weakSelf.meterObserver.audioQueue = nil;301         302         [[[UIAlertView alloc]initWithTitle:@"错误" message:error.userInfo[NSLocalizedDescriptionKey] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"知道了", nil]show];303     };304     recorder.bufferDurationSeconds = 0.04;305     recorder.fileWriterDelegate = amrWriter;306     self.filePath  = amrWriter.cafFilePath; //因为能直接播放是的caf文件,所以给予caf文件地址307     self.recorder = recorder;308 }309 @end310 311 @interface UIWebView (JavaScriptAlert)312 313 - (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(CGRect *)frame;314 315 @end316 317 @implementation UIWebView (JavaScriptAlert)318 319 - (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(CGRect *)frame {320     321     322     UIAlertView* customAlert = [[UIAlertView alloc] initWithTitle:@"提示信息" message:message delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];323     324     [customAlert show];325     326 }327 @end