phonegap(cordova)android ios的QQ 微博 人人第三方登录

2014-11-28 奇Yu 移动应用

这是phonegap plugin,用来做第三方平台登录的,目前有qq、微博、人人三个平台

qq登录

首先要在qq互联,创建移动应用,获取appId神马的

然后搭建环境,ios环境搭建看这里android的在这里

环境配好了,Next,就是写代码了,直接把.java.m .h文件copy到工程里,然后把www/plugins下的qqLogin.js拷贝到对应的www/plugins目录下

还有一步,在工程的cordova_plugins.jsconfig.xml里增加对应plugin的说明

ios版

<feature name="QQLogin">
    <param name="ios-package" value="QQLogin" />
</feature>

android版

<feature name="QQLogin">
    <param name="android-package" value="com.example.cordova.qqLogin.QQLogin" />
</feature>

注意,android版value对应的是QQLogin.java这个文件所在的路径

最后在对应的js里写上登录按钮的点击事件,比如

$('#qq-login').click(function() {
    qqLogin.ssoLogin(function(res) { alert('uid:'+res.uid+' token:'+res.token);
    }, function() { alert('授权失败');
    });

});

另外,ios的AppDelegate.mopenURL里要加上如下所示代码,当然还要import对应的.h文件:

// this happens while we are running ( in the background, or from within our own app ) // only valid if Filpped-Info.plist specifies a protocol to handle - (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation
{ if (!url) { return NO;
    } // calls into javascript global function 'handleOpenURL' NSString* jsString = [NSString stringWithFormat:@"handleOpenURL(\"%@\");", url];
    [self.viewController.webView stringByEvaluatingJavaScriptFromString:jsString]; // all plugins will get the notification, and their handlers will be called [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]]; // weiboLogin WeiboLogin *weiboPlugin = [self.viewController.pluginObjects objectForKey:@"WeiboLogin"];
    [WeiboSDK handleOpenURL:url delegate:weiboPlugin]; // renrenLogin RenrenLogin *renrenPlugin = [self.viewController.pluginObjects objectForKey:@"RenrenLogin"];
    [RennClient handleOpenURL:url];
    [TencentOAuth HandleOpenURL:url ];
    QQLogin *qqPlugin = [self.viewController.pluginObjects objectForKey:@"QQLogin"];

    [QQApiInterface handleOpenURL:url delegate:qqPlugin]; return YES;
}

微博登录

和qq基本一致,微博的文档po主放在doc目录下了

人人登录

人人文档在这里,ios版android

步骤和前面的一致

git地址

https://github.com/jessiehan/phonegap-social-sso

原作者地址

http://zjuhpp.com/phonegap-di-san-fang-ping-tai-deng-lu-di-plugin.html



标签: phonegap cordova android

评论(0) 浏览(6440)

phonegap(cordova)android插件开发技巧

2014-11-28 奇Yu 移动应用

这里说的是 3.0之后的。

因为3.0之后的版本插件和主程序是分开的,插件需要单独安装

网络上有很多插件的相关文章,我感觉讲的比较繁琐,所以重新整理一篇。


首先需要了解插件包的 文件结构


test 
│  plugin.xml 
│ 
├─src 
│  └─android 
│          Easemob.java 
│ 
└─www 
       easemob.js



一.先看plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
    id="com.imqiyu.cordova.easemob"
    version="0.0.1">
    <name>环信聊天</name>
    <description>easemob.com的聊天 封装的cordova插件</description>
    <author>qiyu</author>
    <license>Apache 2.0 License</license>
    <engines>
        <engine name="cordova" version=">=3.0.0" />
    </engines>
    
    <!--js-module指向的就是我们刚才所写的js文件的路径,src指向www/easemob.js,name属性自己定义,share代表我们在客户端调用的时候的实例名。--> <js-module src="www/easemob.js" name="easemob"> <clobbers target="easemob" />
    </js-module>
    
    <!-- android -->  
    <platform name="android">    
        <source-file src="src/android/Easemob.java" target-dir="src/com/imqiyu/cordova/easemob" /> 
        
        <config-file target="res/xml/config.xml" parent="/*">  
            <feature name="Easemob" >  
                <param name="android-package" value="com.imqiyu.cordova.easemob.Easemob"/>  
            </feature>  
        </config-file>  
    
    </platform>  
</plugin>


如果直接在上面写注释容易出错,简单的写在这里
最上面的 id 需要唯一,name,描述,作者自己看着写,engines的版本需要大于3.0,这样就是因为3.0后的版本后之前的是分界线,如果你开发的插件是在3.X后特有的版本才有的,需要指定到能调的动你插件的版本。
<js-module src="www/easemob.js" name="easemob">
        <clobbers target="easemob" />
</js-module>

这段是JS 的描述。JS的路径,jS的调用名称,
platform是每个平台的描述
source-file 是文件在插件包内的路径 target-dir 安装到android后的路径,甚至可以理解成包名
 <param name="android-package" value="com.imqiyu.cordova.easemob.Easemob"/>  
这里是value是只插件中java文件的路径。注意他包含了 报名 和文件名 如果你还需要其它的配置
比如 activity和权限可以这样写他们都在platform的下级
     <config-file  target="AndroidManifest.xml" parent="/*">       
		<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
     </config-file>
	 <config-file  target="AndroidManifest.xml" parent="application">
       <activity
		  android:name="cn.sharesdk.framework.ShareSDKUIShell"
		  android:theme="@android:style/Theme.Translucent.NoTitleBar"
		  android:configChanges="keyboardHidden|orientation|screenSize"
		  android:screenOrientation="portrait"
		  android:windowSoftInputMode="stateHidden|adjustResize" >
		   <intent-filter>
				<data android:scheme="tencent100371282" />
				<action android:name="android.intent.action.VIEW" />
				<category android:name="android.intent.category.BROWSABLE" />
				<category android:name="android.intent.category.DEFAULT" />
			</intent-filter>
		</activity>		
     </config-file> 

二. easemob.js文件

var cordova = require('cordova');
var Easemob =function(){};

Easemob.prototype.login = function(success,error,str) {
    cordova.exec(success,error,'Easemob','login',str);
};
var easemob = new Easemob();
module.exports = easemob;


主要看 cordova.exec()


  1.        一共5个参数 
  2.        第一个 :成功回调 
  3.        第二个 :失败回调 
  4.        第三个 :将要调用的类,等下JAVA文件里面的类名称 
  5.        第四个 :调用的方法名(一个类里可能有多个方法 靠这个参数区分) 
  6.        第五个 :传递的参数  以数组的格式 


这里可以看到我把他们写在一个函数里面 在前端页面调研那个的时候可以直接使用

easemob.login(function(){},function(){}},"[]");

如果是有多个可以这样写


var cordova = require('cordova');
var Easemob =function(){};

Easemob.prototype.login = function(success,error,str) {
    cordova.exec(success,error,'Easemob','login',str);
};
Easemob.prototype.logout = function(success,error,str) {
    cordova.exec(success,error,'Easemob','logout',str);
};
Easemob.prototype.chat = function(success,error,str) {
    cordova.exec(success,error,'Easemob','chat',str);
};

var easemob = new Easemob();
module.exports = easemob;


我这里写了三个调用。前台调用的时候可以直接使用easemob.login();easemoblogout;easemob.chat();三个方法调用

三.Easemob.java 文件

package com.imqiyu.cordova.easemob;
//此处的包名要和 XML里面的包名一样
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import android.content.Context;

//这里的类名 就是 XML里面android-package的只 包名+类名
//这里的类名 就是JS cordova.exec()的第三个参数
public class Easemob extends CordovaPlugin {	
	//这里的String action就是JS cordova.exec()的第四个参数 要执行什么动作
	@Override
	public boolean execute(String action, JSONArray args,
			CallbackContext callbackContext) throws JSONException {
		//这里的args n就是JS cordova.exec()的第五个参数 以JSON格式得到,一定要安顺序
		final String	user=args.getString(0);
		final String	psword=args.getString(1);	  
		  if (action.equals("login")) {
				   
				if(user=="admin" && paword=="123456"){
					   callbackContext.success("成功登录");  
				}
			  }else if(action.equals("logout")){
				  
			
				  
			  }else if(action.equals("chat")){
				 
			  }

		return super.execute(action, args, callbackContext);
	}

	
	
}

至此一个插件算是开发完成了

插件的安装 cordova plugin add 你的本地路径 或者是GIT路径

然后前台调用

easemob.login(function(s){alert(s);},function(){}},['admin','123456']);



如果你想要更新界面需要使用 UI线程,

	 if (action.equals("login")) {
				   
				   cordova.getActivity().runOnUiThread(new Runnable() {
		                public void run() {		                	
							//需要更新页面的操作
		                }
		            });
			  }else if(action.equals("logout")){				  
	
				  
			  }else if(action.equals("chat")){
			
			  }

如果你需要得到内容上下文可以使用

Context context = this.cordova.getActivity().getApplicationContext(); 

如果你需要返回一个集合 可以使用

callbackContext.sendPluginResult(new PluginResult(status,aa));

标签: phonegap cordova 插件开发 android

评论(0) 浏览(5303)

android List异步获取网络图片之聊天列表

2014-11-20 奇Yu 移动应用

安卓获取网络图片可以参考

http://blog.csdn.net/wangjinyu501/article/details/8219317

我现在要的需求和这篇博客所讲的有一点点的不同

他这里获取的列表每张图片都不一样。

而我要获取的是 有些列表的图片是相同的

聊天列表.png

像我这张图片一样是一个聊天的列表

左侧和右侧的几张图片 是重合的。

如果还用上面博客的代码,

就会出现

第一个线程 去请求  头像,当第一个请求还没有返回的时候,

第二个,第三个,第四个,线程也会去请求相同的头像图片资源,


现在解决的方法。

在线程去请求之前,先判断 内存内有没有这个图片资源

没有了 就将现在要去请求的 放到一个集合里面。

如果集合里已经存在这个网址了。

就直接返回

没有存在就往下继续执行 ,去网络请求这个图片,

等待图片请求回来了。

循环刚才的集合,设置每个ImageView控件的图片


ImageLoader.java


package com.imqiyu.aochen;
import java.io.BufferedReader;
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.InputStreamReader;
import java.io.OutputStream; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.util.ArrayList;
import java.util.Collections; 
import java.util.Map; 
import java.util.WeakHashMap; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import com.easemob.chatuidemo.R;
import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.util.Log;
import android.widget.ImageView; 
import com.imqiyu.aochen.Utils;  
public class ImageLoader {
  
    MemoryCache memoryCache=new MemoryCache(); 
    FileCache fileCache; 
    ExecutorService executorService;
    
    final  Map<String,ArrayList<ImageView>> imageViews=Collections.synchronizedMap(new WeakHashMap<String,ArrayList<ImageView>>()); 
    private void ViewList(String url,ImageView iv){
    	ArrayList<ImageView> temp;
    		//先取出数组里
    		 temp=imageViews.get(url);
    		 if(temp==null){
    			 ArrayList<ImageView> imList=new ArrayList<ImageView>();  
    			 imList.add(iv);
    			 imageViews.put(url, imList); 
    			 Log.d("img",url+"需要新建一个集合");
    		 }else{
    			 temp.add(iv);
    			 Log.d("img",url+"直接累加的集合");
    			 imageViews.put(url, temp); 
    		 }        
    
    	
    
    }
  
    public ImageLoader(Context context){ 
        fileCache=new FileCache(context); 
        executorService=Executors.newFixedThreadPool(5); 
    } 

  
    final int stub_id = R.drawable.default_avatar; 
    public void DisplayImage(String url, ImageView imageView) 
    {    
        Bitmap bitmap=memoryCache.get(url); 
        if(bitmap!=null){  
        	Log.d("img",url+"读取的是缓存");
            imageView.setImageBitmap(bitmap); 
        } else
        {  
        	Log.d("img",url+"读取的是URL");
        	ArrayList<ImageView> temp;        	
    		//先取出数组里
    		 temp=imageViews.get(url);
        	//然后往里面添加
        	if(temp != null){
        		Log.d("img",url+"已经存在集合了 直接返回即可");
        		ViewList(url,imageView); 
        	
        	}else{
        		Log.d("img",url+"不存在与集合,需要重新获取");
        		ViewList(url,imageView); 
                queuePhoto(url);                 
        	}
        	imageView.setImageResource(stub_id); 
        	
        } 
    } 

  
    private void queuePhoto(String url) 
    {     	
        PhotoToLoad p=new PhotoToLoad(url); 
        executorService.submit(new PhotosLoader(p)); 
    } 
    
 
  
    private Bitmap getBitmap(String url) 
    { 
        File f=fileCache.getFile(url); 
  
        //从sd卡 因为是头像他会换的不适合长期保存
       Bitmap b = decodeFile(f); 
        if(b!=null) 
            return b; 
  
        //从网络
        try {         
            Bitmap bitmap=null; 
            URL imageUrl = new URL(url); 
            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection(); 
            conn.setConnectTimeout(30000); 
            conn.setReadTimeout(30000); 
            conn.setInstanceFollowRedirects(true); 
            InputStream is=conn.getInputStream(); 
            OutputStream os = new FileOutputStream(f); 
            Utils.CopyStream(is, os);            
            os.close();          
            bitmap = decodeFile(f);         
            return bitmap; 
        } catch (Exception ex){         	
           ex.printStackTrace(); 
           return null; 
        } 
    } 
  
    //解码图像用来减少内存消耗
    private Bitmap decodeFile(File f){ 
        try { 
            //解码图像大小
            BitmapFactory.Options o = new BitmapFactory.Options(); 
            o.inJustDecodeBounds = true; 
            BitmapFactory.decodeStream(new FileInputStream(f),null,o); 
  
            //找到正确的刻度值,它应该是2的幂。
            final int REQUIRED_SIZE=70; 
            int width_tmp=o.outWidth, height_tmp=o.outHeight; 
            int scale=1; 
            while(true){ 
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) 
                    break; 
                width_tmp/=2; 
                height_tmp/=2; 
                scale*=2; 
            } 
  
            BitmapFactory.Options o2 = new BitmapFactory.Options(); 
            o2.inSampleSize=scale; 
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
        } catch (FileNotFoundException e) {} 
        Log.d("getimg","解码出错了");
        return null; 
    } 
  
   // /任务队列
    private class PhotoToLoad 
    { 
        public String url;   
        public PhotoToLoad(String u){ 
            url=u; 
          
        } 
    } 
    

    class PhotosLoader implements Runnable { 
        PhotoToLoad photoToLoad;        
        PhotosLoader(PhotoToLoad photoToLoad){ 
            this.photoToLoad=photoToLoad; 
        } 
  
        @Override
        public void run() { 
            Bitmap bmp=getBitmap(photoToLoad.url);             
            memoryCache.put(photoToLoad.url, bmp);
        
            BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad); 
            Activity a=(Activity)imageViews.get(photoToLoad.url).get(0).getContext(); 
            a.runOnUiThread(bd); 
        } 
    } 
   
  
    boolean imageViewReused(PhotoToLoad photoToLoad){ 
        ArrayList<ImageView> tag=imageViews.get(photoToLoad.url); 
        if(tag==null || !tag.get(0).equals(photoToLoad.url)) 
            return true; 
        return false; 
    } 

  
    //用于显示位图在UI线程
    class BitmapDisplayer implements Runnable 
    { 
        Bitmap bitmap; 
        PhotoToLoad photoToLoad; 
        public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;} 
        public void run() 
        { 
        	Log.d("img","url="+photoToLoad.url);
        	ArrayList<ImageView> ivList=imageViews.get(photoToLoad.url);
        	int size=ivList.size(); 
        	Log.d("img","需要循环设置图片的次数"+size);
        	for(int i=0;i<size;i++){
        		if(bitmap!=null){
                	Log.d("img","设置图片成功");
                	ivList.get(i).setImageBitmap(bitmap); 
                }
                else{
                	Log.d("img","设置图片失败");                 
                    ivList.get(i).setImageResource(stub_id);                	
                    
                }
        	}
        	//都设置成功了就删除把。
        	imageViews.remove(photoToLoad.url);
            
        } 
    } 
  
    public void clearCache() { 
        memoryCache.clear(); 
        fileCache.clear(); 
    } 
   

  
} 

附上其它几个文件的代码

FileCache.java


package com.imqiyu.aochen;

import java.io.File;

import android.content.Context;

public class FileCache {
    
    private File cacheDir;
    
    public FileCache(Context context){
        //找一个用来缓存图片的路径
        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
            cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
        else
            cacheDir=context.getCacheDir();
        if(!cacheDir.exists())
            cacheDir.mkdirs();
    }
    
    public File getFile(String url){
        
        String filename=String.valueOf(url.hashCode());       
        File f = new File(cacheDir, filename);
        return f;
        
    }
    
    public void clear(){
        File[] files=cacheDir.listFiles();
        if(files==null)
            return;
        for(File f:files)
            f.delete();
    }

}

MemoryCache.java

package com.imqiyu.aochen;

import java.lang.ref.SoftReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import android.graphics.Bitmap;

public class MemoryCache {
    private Map<String, SoftReference<Bitmap>> cache=Collections.synchronizedMap(new HashMap<String, SoftReference<Bitmap>>());//软引用
    
    public Bitmap get(String id){
        if(!cache.containsKey(id))
            return null;
        SoftReference<Bitmap> ref=cache.get(id);
        return ref.get();
    }
    
    public void put(String id, Bitmap bitmap){
        cache.put(id, new SoftReference<Bitmap>(bitmap));
    }

    public void clear() {
        cache.clear();
    }
}

Utils.java

package com.imqiyu.aochen;
import java.io.InputStream;
import java.io.OutputStream;


public class Utils {
    public static void CopyStream(InputStream is, OutputStream os)
    {
        final int buffer_size=1024;
        try
        {
            byte[] bytes=new byte[buffer_size];
            for(;;)
            {
              int count=is.read(bytes, 0, buffer_size);
              if(count==-1)
                  break;
              os.write(bytes, 0, count);              
            }  
            is.close();
            os.close();
                     	
       
      /*     int len=0;
            byte[] buffer = new byte[buffer_size];
            while((len = is.read(buffer)) != -1){
                os.write(buffer, 0, len);
            }
            os.close();
            is.close();  */
            
            
        }
        catch(Exception ex){}
    }
    

}

标签: android

评论(0) 浏览(2612)

android 5分钟集成环信及时聊天DEMO

2014-11-17 奇Yu 移动应用

第一步

首先将环节的UIDEMO 导入到eclipse IDE内

然后新建一个自己想项目

QQ截图20141117155132.png


第二步 将DEMO 变成library



右击 demo 选择Properties

QQ截图20141117155638.png

以次选择 android  勾选is libray 然后选择apply  OK


第三步 复制架包覆盖DEMO的架包

复制自己项目里的 android架包 覆盖DEMO里面的

QQ截图20141117161732.png


第四步 修改 DEMO里面和自己有冲突的布局文件

因为这里是是演示 所以只有 activity_main.xml 这个布局是重名的

修复错误

修改冲突的布局文件.png


第5步

在project.properties文件内添加 manifestmerger.enabled=true 

QQ图片20141117163330.jpg


第六步修改  <application 标签的 android:name值 

android:name="com.easemob.chatuidemo.DemoApplication"

QQ截图20141117164048.png


第七步 在自己的项目引入 library


然后在自己的项目内 点击右键选择Properties

QQ截图20141117160054.png

选择android ->add ->chatdemoui ->ok ->apply->ok


这时候 DEMO应用里面应该会报错

case expressions must be constant expressions

很简单 在报错的 鼠标放到switch 上 安ctrl + 1 让他变成 if esle就可以了

case expressions must be constant expressions.pngQQ截图20141117164252.png


此时基本都可以了 

然后在自己的 项目内 新建一个按钮 监听按钮 点击了打开 DEMO的登录页面


    but=(Button) findViewById(R.id.button1);
        but.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent= new Intent(MainActivity.this,com.easemob.chatuidemo.activity.LoginActivity.class); 
startActivity(intent);
}
});

然后运行下看看 ,是不是已经集成了


Screenshot_2014-11-17-17-26-38.pngScreenshot_2014-11-17-17-26-49.pngScreenshot_2014-11-17-17-27-10.png



补充一点 自己的 环信应用标识(AppKey): 可以直接在 DEMO里面修改成自己的就可以了





标签: android

评论(2) 浏览(7765)

谷歌翻译API 返回JSON,JSONP 格式,支持超长文本

2014-11-16 奇Yu WEB开发

最近需要用到多语言翻译,国内的有道翻译不错。但是他们只提供 中英相互翻译,中文对其他语言的翻译,功能比较少,

所以考虑到使用谷歌翻译,

谷歌翻译已经关闭了API 所以只能先用PHP的CURL 处理过后在返回,

网上有人提供了 这样的接口,但是他没有提供JSONP格式的,如果你需要还得再再你的PHP文件内CURL下他的PHP文件,然后他的PHP文件再去UCRL谷歌的API,速度肯定是慢的,然后我这边也安他们说的用CURL 直接可以返回JSONP 格式的数据,

这样可以大大提高速度,


  提交地址:
    http://fanyi.imqiyu.com/fanyi.php
    
    url参数
    from 需要翻译的文本语言码 
    to 要翻译成什么样的语言
    content 需要翻译的内容
    type  采取什么样的类型提交,服务器会根据这个TYPE去获取 content的内容 $_get['content'] 或者  $_post['content']
    callback  jsonp的回调名

json的返回格式
{"source":"\u4f60\u597d","result":"Hello","code":"0000"}
完整的JSONP 访问连接
http://fanyi.imqiyu.com/fanyi.php?from=auto&amp;to=en&amp;type=get&amp;content=%E4%BD%A0%E5%A5%BD&amp;callback=fanyi
jsonp的返回格式
fanyi({"source":"\u4f60\u597d","result":"Hello","code":"0000"});
如果返回的code 是0000说明是正确的返回,如果不是四个0 就是有错误
source 是原来的语言
result 是翻译后的语言


其他的可以参考 http://fanyi.imqiyu.com/


各国语言CODE

 <li><a href="javascript:;"value=sq>阿尔巴尼亚语</a></li>
                        <li><a href="javascript:;"value=ar>阿拉伯语</a></li>
                        <li><a href="javascript:;"value=az>阿塞拜疆语</a></li>
                        <li><a href="javascript:;"value=ga>爱尔兰语</a></li>
                        <li><a href="javascript:;"value=et>爱沙尼亚语</a></li>
                        <li><a href="javascript:;"value=eu>巴斯克语</a></li>
                        <li><a href="javascript:;"value=be>白俄罗斯语</a></li>
                        <li><a href="javascript:;"value=bg>保加利亚语</a></li>
                        <li><a href="javascript:;"value=is>冰岛语</a></li>
                        <li><a href="javascript:;"value=pl>波兰语</a></li>
                        <li><a href="javascript:;"value=bs>波斯尼亚语</a></li>
                        <li><a href="javascript:;"value=fa>波斯语</a></li>
                        <li><a href="javascript:;"value=af>布尔语(南非荷兰语)</a></li>
                        <li><a href="javascript:;"value=da>丹麦语</a></li>
                        <li><a href="javascript:;"value=de>德语</a></li>
                        <li><a href="javascript:;"value=ru>俄语</a></li>
                        <li><a href="javascript:;"value=fr>法语</a></li>
                        <li><a href="javascript:;"value=tl>菲律宾语</a></li>
                        <li><a href="javascript:;"value=fi>芬兰语</a></li>
                        <li><a href="javascript:;"value=km>高棉语</a></li>
                        <li><a href="javascript:;"value=ka>格鲁吉亚语</a></li>
                        <li><a href="javascript:;"value=gu>古吉拉特语</a></li>
                        <li><a href="javascript:;"value=ht>海地克里奥尔语</a></li>
                        <li><a href="javascript:;"value=ko>韩语</a></li>
                        <li><a href="javascript:;"value=ha>豪萨语</a></li>
                        <li><a href="javascript:;"value=nl>荷兰语</a></li>
                        <li><a href="javascript:;"value=gl>加利西亚语</a></li>
                        <li><a href="javascript:;"value=ca>加泰罗尼亚语</a></li>
                        <li><a href="javascript:;"value=cs>捷克语</a></li>
                        <li><a href="javascript:;"value=kn>卡纳达语</a></li>
                        <li><a href="javascript:;"value=hr>克罗地亚语</a></li>
                        <li><a href="javascript:;"value=la>拉丁语</a></li>
                        <li><a href="javascript:;"value=lv>拉脱维亚语</a></li>
                        <li><a href="javascript:;"value=lo>老挝语</a></li>
                        <li><a href="javascript:;"value=lt>立陶宛语</a></li>
                        <li><a href="javascript:;"value=ro>罗马尼亚语</a></li>
                        <li><a href="javascript:;"value=mt>马耳他语</a></li>
                        <li><a href="javascript:;"value=mr>马拉地语</a></li>
                        <li><a href="javascript:;"value=ms>马来语</a></li>
                        <li><a href="javascript:;"value=mk>马其顿语</a></li>
                        <li><a href="javascript:;"value=mi>毛利语</a></li>
                        <li><a href="javascript:;"value=mn>蒙古语</a></li>
                        <li><a href="javascript:;"value=bn>孟加拉语</a></li>
                        <li><a href="javascript:;"value=hmn>苗语</a></li>
                        <li><a href="javascript:;"value=zu>南非祖鲁语</a></li>
                        <li><a href="javascript:;"value=ne>尼泊尔语</a></li>
                        <li><a href="javascript:;"value=no>挪威语</a></li>
                        <li><a href="javascript:;"value=pa>旁遮普语</a></li>
                        <li><a href="javascript:;"value=pt>葡萄牙语</a></li>
                        <li><a href="javascript:;"value=ja>日语</a></li>
                        <li><a href="javascript:;"value=sv>瑞典语</a></li>
                        <li><a href="javascript:;"value=sr>塞尔维亚语</a></li>
                        <li><a href="javascript:;"value=eo>世界语</a></li>
                        <li><a href="javascript:;"value=sk>斯洛伐克语</a></li>
                        <li><a href="javascript:;"value=sl>斯洛文尼亚语</a></li>
                        <li><a href="javascript:;"value=sw>斯瓦希里语</a></li>
                        <li><a href="javascript:;"value=ceb>宿务语</a></li>
                        <li><a href="javascript:;"value=so>索马里语</a></li>
                        <li><a href="javascript:;"value=te>泰卢固语</a></li>
                        <li><a href="javascript:;"value=ta>泰米尔语</a></li>
                        <li><a href="javascript:;"value=th>泰语</a></li>
                        <li><a href="javascript:;"value=tr>土耳其语</a></li>
                        <li><a href="javascript:;"value=cy>威尔士语</a></li>
                        <li><a href="javascript:;"value=ur>乌尔都语</a></li>
                        <li><a href="javascript:;"value=uk>乌克兰语</a></li>
                        <li><a href="javascript:;"value=iw>希伯来语</a></li>
                        <li><a href="javascript:;"value=el>希腊语</a></li>
                        <li><a href="javascript:;"value=es>西班牙语</a></li>
                        <li><a href="javascript:;"value=hu>匈牙利语</a></li>
                        <li><a href="javascript:;"value=hy>亚美尼亚语</a></li>
                        <li><a href="javascript:;"value=ig>伊博语</a></li>
                        <li><a href="javascript:;"value=it>意大利语</a></li>
                        <li><a href="javascript:;"value=yi>意第绪语</a></li>
                        <li><a href="javascript:;"value=hi>印地语</a></li>
                        <li><a href="javascript:;"value=id>印尼语</a></li>
                        <li><a href="javascript:;"value=jw>印尼爪哇语</a></li>
                        <li><a href="javascript:;"SELECTED value=en>英语</a></li>
                        <li><a href="javascript:;"value=yo>约鲁巴语</a></li>
                        <li><a href="javascript:;"value=vi>越南语</a></li>
                        <li><a href="javascript:;"value=zh-CN>中文</a></li>
                    

评论(0) 浏览(2329)

LIUNX主机从百度网盘wget压缩包

2014-11-6 奇Yu 乱七八糟

如果你有一个几百M的大压缩包,在百度网盘,现在想上次到自己的服务器,

首选liunx的wget命令

如果想在自己的服务器解压,先确保你的压缩包是liunx支持的压缩方式,不然上传上去也是徒劳

首先获取下载网址

在百度的下载页面 点击下载

baidu wget liunx.jpg


然后在到 下载的列表内复制出真正的网址

百度网盘 wget下载.jpg



然后使用putty登录liunx服务器

将当前目录 转到你想要下载的目录

使用 wget方法

wget -c -O test.zip "百度网址"

具体的参数 -c是支持断点续传

-O 大写的O是下载到服务器的保存的名字  如果不这样做 默认的百度连接名字会过长

百度网址 两边的英文冒号一定不能少

liunx wget 百度网盘.jpg




评论(0) 浏览(2213)

php 不常用的语法

2014-10-13 奇Yu WEB开发

在wordpress一类博客程序的模板里面看到很多奇怪的PHP语法,比如:
<?php if(empty($GET_['a'])): ?>
<font color=”red”>空的</font>
<?php endif; ?>
对于相当一部分PHP爱好者来说根本没见过啊,这些是什么东西呢?难道是那些博客的开发者自己搞的仿PHP的模板语言?
非也,其实这些都是PHP的语法,只不过不常用而已,这些都是PHP流程控制的替代语法。
这里就就给大家详细说一下PHP流程控制的替代语法。什么是替代语法?
简单的说就是一些语法的另类写法。

 

PHP中那些语法有替代语法?
流程控制(包括if,while,forforeach,switch)这几个语句有替代语法。

 

替代语法的基本形式:
左花括号({)换成冒号(:),把右花括号(})分别换成 endif;,endwhile;,endfor;,endforeach; 以及 endswitch;

 

举个例子吧:
<?php if ($a<0): ?>
是负数拉
<?php endif; ?>
上面的语句等同于
<?php if ($a<0){ ?>
是负数拉
<?php } ?>

 

为什么纯PHP代码里面几乎看不到?
这些语法有点不符合C家族的传统有点另类,大家不大习惯于这种语法,而且不是很方便

 

大家都不习惯,而且这么另类要他有什么用?蛋疼吗?
存在就是合理,它自有它的用处,这些语法能发挥的地方是在PHP和HTML混合页面的代码里面。好处如下:
1.使HTML和PHP混合页面代码更加干净整齐。
有代码洁癖的朋友最惧怕的就是乱七八糟的混合代码,有了这些没有花括号的替代语法,各位爱干净的朋友开心到尿震。
2.流程控制逻辑更清晰,代码更容易阅读
要改别人的PHP和HTML混合代码,打开发现,我擦!太TMD垃圾了!如果用替代语法,我想再垃圾的程序开发人员也不至于写的太乱吧。
3.一些从ASP等其他类basic语言家族转来的朋友,会更容易使用PHP。

 

讲半天没用的,捞点干的行不?这东西怎么用?

 

根据之前描述的使用方法,if语句的替代语法使用如下:
<?php if ($a == 5): ?>
<div>等于5</div>
<?php elseif ($a == 6): ?>
<div>等于5</div>
<?php else: ?>
<div>不是5就是6</div>
<?php endif; ?>

 

while替代语法:
<?php while (expr): ?>
<li>循环点什么</li>
<?php endwhile; ?>

for替代语法:

<?php for (expr1; expr2; expr3): ?>
<li>循环点什么</li>
<?php endfor; ?>
foreach替代语法:
<?php foreach (expr1): ?>
<li>循环点什么</li>
<?php endforeach; ?>

 

switch替代语法:
<?php
switch ($i):
case 0:
echo “i equals 0″;
break;
case 1:
echo “i equals 1″;
break;
case 2:
echo “i equals 2″;
break;
default:
echo “i is not equal to 0, 1 or 2″;
endswitch;
?>

评论(0) 浏览(828)

phonegap(cordova)从手机app跳转到web页面在跳转回APP本地页面思路

2014-10-11 奇Yu 移动应用

项目中需要用到 WAP支付宝支付。

但是 使用PHONEGAP开发 跳转到支付宝支付,然后跳转回来 就回不到APP的本地页面,

就是使用WAP的第三方登录也是一样的。很难从WAP页面在跳转到 app本地的本地页面


可以看下我的实现思路。

QQ截图20141011163811.png

我是使用phongeap +jqmobi 做的

下面是 点击去支付跳转到 打开IFRAME的页面


    <!-----第三方登录------->
    <div id="qi_disanfang" class="panel padding0" data-header="default_head" data-footer="none" data-load="ondisanfang" data-unload="undisanfang">
        <iframe id="login_content" class="pay_content" style="height:100%;width:100%;border:0 none;" src=''></iframe>
    </div>


只是在页面里面创建了一个IFRAME框,SRC为空

页面初始化函数


/*第三方登录*/
function ondisanfang(){
    //设置标题
    qsetTitle("登录");
    //监听消息状态
    window.addEventListener('message',loginStart, false);
    //远程wap页面的地址
    var url=serverURL+'user.php?act=oath&type=qq&callblock=app/login.php';
    //赋值给iframe 的src 并设置iframe的宽高    
    document.getElementById("login_content").src = url;
    var $pay_content = $("#login_content");
    var h = $pay_content.parent().height();
    var w = $pay_content.parent().width();
    $pay_content.css({
        height: h,
        width: w
    });

}
loginStart 监听消息回调函数

//消息回调函数
function loginStart(e) {
    //判断传过来的消息 是不是自己设置的,这个地方如果想严谨一点还可以判断下 发消息的 域地址是不是自己的地址,我这里没有判断
    if(e.data=='login_success'){
        //如果是就执行自己的方法 跳转到其它页面或者做其它的操作
        ongoto('qi_center');
    }
}
页面卸载函数

function undisanfang() {
    //删除刚才的监听
    window.removeEventListener('message',loginStart,false);
}
这样这个打开远程的iframe框就做好了,所有的wap远程页面都在这里操作。登录。支付。当他们支付成功 都会 有一个 回调页面。
这个回调页面就是我们自己服务器的页面
回调页面里只需要发送一个消息给父窗口,让我们刚才的监听收到消息就可以了
可以在回调页面做一个按钮 来执行一个JS函数,也可以直接发送一个消息,具体看业务逻辑
回调页面JS

  <script type="text/javascript">

		 //给iframe框的父窗口发送一个消息  这个消息内容要和刚才你监听的内容一样
         top.postMessage('login_success', '*');

	
  </script>

标签: phonegap cordova

评论(0) 浏览(9723)

php gmstrftime() 函数使用方法详解

2014-10-11 奇Yu WEB开发

Definition and Usage
定义和用法

The gmstrftime() function formats a GMT/UTC time or date according to locale settings.
gmstrftime()函数的作用是:根据区域设置格式化GMT/UTC时间/日期。

Syntax
语法

gmstrftime(format,timestamp)
Parameter参数 Description描述
format Required. Specifies how to return the result: 
必要参数。指定了返回结果的方法:
  • %a - abbreviated weekday name 
    %a – 缩略的表示星期几的名称
  • %A - full weekday name 
    %A – 表示星期几的全称
  • %b - abbreviated month name 
    %b – 月份简称
  • %B - full month name 
    %B – 月份全称
  • %c - preferred date and time representation 
    %c – 首选的日期和时间表示法
  • %C - century number (the year divided by 100, range 00 to 99) 
    %C – 表示世纪的数字(年份除以100,范围从00到99)
  • %d - day of the month (01 to 31) 
    %d – 一个月包含的天数(从01到31)
  • %D - same as %m/%d/%y 
    %D – 时间格式,与%m/%d/%y表示法相同
  • %e - day of the month (1 to 31) 
    %e - 一个月包含的天数,数字前不包括0(从1到31)
  • %g - like %G, but without the century 
    %g – 与%G雷同,但除去“世纪[century]”
  • %G - 4-digit year corresponding to the ISO week number (see %V). 
    %G – 与ISO星期数相对应的4位数年份(见%V)
  • %h - same as %b 
    %h – 与%b相同
  • %H - hour, using a 24-hour clock (00 to 23) 
    %H – 小时,使用24小时时钟(00到23)
  • %I - hour, using a 12-hour clock (01 to 12) 
    %I – 小时,使用12小时时钟(01到12)
  • %j - day of the year (001 to 366) 
    %j – 一年的天数(001到366)
  • %m - month (01 to 12) 
    %m – 月份(01到12)
  • %M - minute 
    %M – 分钟
  • %n - newline character 
    %n – 换行符
  • %p - either am or pm according to the given time value 
    %p – 与给定的时间值相对应的am或pm
  • %r - time in a.m. and p.m. notation 
    %r -用am或pm表示给定的时间
  • %R - time in 24 hour notation 
    %R – 用24小时制表示的时间
  • %S - second 
    %S – 秒
  • %t - tab character 
    %t – tab键/制表符
  • %T - current time, equal to %H:%M:%S 
    %T – 当前时间,与“%H:%M:%S”组合相同
  • %u - weekday as a number (1 to 7), Monday=1. Warning: In Sun Solaris Sunday=1 
    %u – 以数字形式表示星期几(1到7),Monday=1。提醒:在SUN Sloaris系统中,Sunday=1
  • %U - week number of the current year, starting with the first Sunday as the first day of the first week 
    %U – 当今年份中包含的周的总数,以第一个星期日作为第一周的第一天
  • %V - The ISO 8601 week number of the current year (01 to 53), where week 1 is the first week that has at least 4 days in the current year, and with Monday as the first day of the week 
    %V – 在当今年份中所包含的ISO 8601格式下的周的总数(01到53),week 1表示第一周,以周一作为每周的第一天
  • %W - week number of the current year, starting with the first Monday as the first day of the first week 
    %W – 当前年份中包含的周的总数,以第一个星期一作为第一周的第一天
  • %w - day of the week as a decimal, Sunday=0 
    %w – 以数字的形式表示星期几,Sunday[星期日]=0
  • %x - preferred date representation without the time 
    %x – 选取除去时间[time]的日期[date]
  • %X - preferred time representation without the date 
    %X –选取除去日期[date]的时间[time]
  • %y - year without a century (range 00 to 99) 
    %y – 只显示包含年份的数字,不包含表示世纪的数字(00-99)
  • %Y - year including the century 
    %Y – 显示包含世纪数字的年份(即:四位数字表示的年份,如:1999,2001等)
  • %Z or %z - time zone or name or abbreviation 
    %Z或%z – 前者为时区名称;后者为时区名称的简称
  • %% - a literal % character 
    %% - 输出“%”字符串
timestamp Optional. Specifies the date or time to be formatted. If no timestamp is specified, it uses the current GMT time.
可选参数。指定日期或时间的格式。如果没有指定时间戳[timestamp],那么将默认使用当前的GMT时间。

Tips and Notes
提示

Tip: This function is identical to strftime() except that the time returned is Greenwich Mean Time (GMT).
提示:gmstrftime()函数与strftime()函数用法大致相同,唯一的不同点是gmstrftime()函数返回的格林威治时间(GMT:Greenwich Mean Time)。

Example
案例

Example of both strftime() and gmstrftime():
strftime() 和 gmstrftime()的案例:

<?php
echo(strftime("%b %d %Y %X", 
mktime(20,0,0,12,31,98))."<br />");
echo(gmstrftime("%b %d %Y %X", mktime(20,0,0,12,31,98))."<br />");
//Print the current date, time, and time zone.
echo(gmstrftime("It is %a on %b %d, %Y, %X time zone: %Z",time()));
?>

The output of the code above could be:
上述代码将输出下面的结果:

Dec 31 1998 20:00:00Dec 31 1998 19:00:00It is Wed on Jan 25, 2006, 11:32:10 time zone:
 W. Europe Standard Time

标签: php

评论(0) 浏览(3121)

zend studio 11.0.0 11.0.1最新版破解

2014-9-2 奇Yu 乱七八糟

刚破解好的10.61,呵呵手贱,点了下升级,然后就升级到了11.0.1,又变成一个月的试用期。哎呀呀!!

幸好网上有最新版的破解,可是下载下来一看貌似和我的版本不一样。

刚刚升级的是11.0.1 网上的是11.0.0

不过幸好有办法,只需要将破解文件的版本号改成现在的版本号就可以了

现在最新的版本号是Build ID: 11.0.1.v20140715-20140815-1236-245

将破解文件 名称改成:com.zend.verifier_11.0.1.v20140815-1236.jar

然后放到 程序的 plugins目录内覆盖即可


如果是110.0的版本

将解压后的 破解文件放到 plugins内

然后运行 keygen.jar(需要有JAVA环境支持)

生成注册码 就OK

11.0.0破解

Zend11_keygen.rar

11.0.1的破解

com.zend.verifier_11.0.1.v20140815-1236.jar.zip



补充下。。
如果你下载的是11  以后的版本
那么最简单的办法就是
打开 程序的 安装目录
找到插件目录
然后搜索
com.zend.verifier
这个11的破解补丁的前半部分
 然后将 搜索到的这个文件 的  名字 拷贝
将下载的破解补丁名字 替换成  插件目录下的 那个名字

然后用 破解补丁 替换插件下的 



评论(0) 浏览(5104)

Powered by emlog 豫ICP备14014990号-1 sitemap