当前位置:  编程技术>移动开发
本页文章导读:
    ▪工作学习札记——6月        工作学习笔记——6月  这个月在工作中碰到的比较有意思的问题有以下几个: 1.ios代码签名机制   没有系统学习过ios的开发,碰到keychain、证书、profile等问题时十分头大。在网上查阅了些.........
    ▪ Andriod phonegap(Cordova)取得通话记录中的信息        Andriod phonegap(Cordova)获得通话记录中的信息 /** * Example of Android PhoneGap Plugin */ package com.tricedesigns; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.EmptyStackExcept.........
    ▪ Andriod phonegap(Cordova)弹出软件盘效能       Andriod phonegap(Cordova)弹出软件盘功能 package com.tricedesigns; import org.json.JSONArray; import android.content.Context; import android.view.inputmethod.InputMethodManager; import com.phonegap.api.Plugin; import com.phonegap.api.Plu.........

[1]工作学习札记——6月
    来源: 互联网  发布时间: 2014-02-18
工作学习笔记——6月

  这个月在工作中碰到的比较有意思的问题有以下几个:


1.ios代码签名机制

  没有系统学习过ios的开发,碰到keychain、证书、profile等问题时十分头大。在网上查阅了些相关信息,发现这块的东西还涉及公私钥等概念。

  按照我的理解,签名机制的作用,是保证客户机上的应用软件,确实是签名的作者写的,没有被恶意修改过。这里要用到非对称加密算法中的私钥加密、公钥解密的认证方式。可不可以使用md5等散列算法来保证软件没有被恶意修改呢?实际上就是这么干的,但是md5计算后的散列码需要使用非对称算法加密并传输。否则传输过程中md5码本身被修改了的话,这个保证就没有任何意义了。

  os x上的keychain就是用来管理公私钥的。证书则是指明签名过程中使用哪一对公私钥。Provisioning Profile这个东西则是证书、app、设备的结合体,三者都满足的话,app才能在设备上运行。


  这里只是简单谈一下自己的理解,也不一定正确。一个比较完整的,有详细操作步骤的说明可以看这里

  (译)iOS Code Signing: 解惑

   http://www.cnblogs.com/zilongshanren/archive/2011/08/30/2159086.html


2.ios retina、ipad适配

  仍然是没有系统学习的缘故,搞得想适配一下ios游戏时,也会碰到很多迷惑的概念。

  要想理解ios retina适配,一个绕不开的概念就是point vs pixel。pixel就是物理屏幕的像素数,point是ios系统特有的逻辑坐标单位。如果进行ios的native开发,程序中的坐标单位一般是point。根据设备屏幕的不同,一个point可能会对应不同的像素数(例如touch 3上两者是point:pixel=1:1,而touch4就是1:2)。这样,程序里统一用point,系统自动根据设备缩放到pixel,达到不同设备应用UI位置比例的一致性。但是如果使用缩放的方式的话,在retina屏(即point:pixel=1:2)上,图像就会因放大显得比较模糊。想达到优质的效果,就要给retina设备准备分辨率更高的图片。系统如果知道正在使用适合retina屏的图片的话,就不再进行放大,使用图片数据完全填充像素区域即可。

  那么系统如何知道使用的是高清图片呢?对于UIImage这类系统高级UI接口,系统会自动尝试使用图片名后带"@2x"的图片。但是像opengl es这种坐标系统、图片数据载入都与系统关系不大的模块来说,这种靠命名来自动适配的方式就不好使了。这时系统将选择权交给了开发者,如果开发者准备了高清纹理图片,那么开发者就要通知系统,给我准备一块够大的opengl缓冲区,我自己往上绘制高清纹理数据,你不要放大,直接用这个缓冲区的像素填充屏幕像素就好了。

  通知的方法是设置opengl所在的UIView下的contentScaleFactor属性。这个属性表示当前view里point和pixel的对应关系。如果没有准备高清纹理,那么这个值设为1.0,准备了的话就设为2.0。

  UIScreen里有个类似的属性scale,不过这个属性是系统根据设备自动设置的。系统会根据这个值以及UIView的contentScaleFactor,共同决定如何将UIView的内容映射到屏幕上去。

  对于retina屏,UIScreen::scale = 2.0,一个point对应屏幕上两个pixel,这时再看UIView的contentScaleFactor 属性:

  a.如果UIView::contentScaleFactor = 1.0,那么这个view一个point只有1个像素的内容,要映射到屏幕的话,需要放大2倍。

  b.如果UIView::contentScaleFactor = 2.0,那么这个view一个point有两个像素,直接填充到屏幕即可


  普通ipad与ipad retina之间的适配应该类似上面。但是itouch、iphone和ipad的适配却和上面没有关系。需要设置xcode的一个项目属性

Targeted Device Family,来决定ipad上面是否使用放大模式来显示itouch、iphone的app。

3.计算机时间

  在使用c库函数mktime时发现两个有意思的计算机历史问题以及几个关键时间点。

  mktime处理的有效时间范围是从1970年1月1日午夜到2038年1月18号,这两个日期之间相差的毫秒数是一个int32的正数范围(2^31),无效的日期会返回-1。2038年1月18号之后的日期可能会从1901年12月13日回卷(考虑整数的负数部分)。

  起始时间从1970年开始,据说是因为unix的兴起是在1970年代。

  mktime的输入参数是一个结构体,里面有一个字段表示年数,这个数字却是从1900年开始算的。网络上的一种说法是,这个结构体刚引入时,作者只给年数保留了两位数字的长度。为了历史兼容性的原因,变成了现在这种减去1900年的形式。

  至于多年前的千年虫讨论,跟这里貌似有一丝关系。早期的软件设计,年数也像上面那样,最初采用了两位数长度,到了2000年,正好溢出。

  mktime这类函数使用的UTC时间,仍然有溢出的bug存在,不过这个溢出时间,是在2038年。

  


  


    
[2] Andriod phonegap(Cordova)取得通话记录中的信息
    来源: 互联网  发布时间: 2014-02-18
Andriod phonegap(Cordova)获得通话记录中的信息

今天上海天气不错哈,18楼能望到东方明珠但看不到虹口足球场,着实有点遗憾~~不过今天phonegap有了大突破,又收获了一个获得通话log的插件。

1.引入.java和.js文件

/**
 * Example of Android PhoneGap Plugin
 */
package com.tricedesigns;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.EmptyStackException;

import org.apache.cordova.api.PluginResult.Status;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog;
import android.provider.Contacts;
import android.provider.ContactsContract;
import android.text.format.DateFormat;
import android.util.Log;

import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;


/**
 * Grab call log data
 * 
 * @author James Hornitzky
 */
public class CallListPlugin extends Plugin {

	/** List Action */
	private static final String ACTION = "list";
	private static final String CONTACT_ACTION = "contact";
	private static final String SHOW_ACTION = "show";
	private static final String TAG = "CallListPlugin";

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.phonegap.api.Plugin#execute(java.lang.String,
	 * org.json.JSONArray, java.lang.String)
	 */
	@Override
	public PluginResult execute(String action, JSONArray data, String callbackId) {
		Log.d(TAG, "Plugin Called");
		PluginResult result = null;
		if (ACTION.equals(action)) {
			try {
				int limit = -1;
				
				//obtain date to limit by
				if (!data.isNull(0)) {
					String d = data.getString(0);
					Log.d(TAG, "Time period is: " + d);
					if (d.equals("week"))
						limit = -7;
					else if (d.equals("month"))
						limit = -30;
					else if (d.equals("all"))
						limit = -1000000; // LOL
				} 
				
				//turn this into a date
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(new Date());
				calendar.add(Calendar.DAY_OF_YEAR, limit);
				Date limitDate = calendar.getTime();
				String limiter = String.valueOf(limitDate.getTime());
				
				//now do required search
				JSONObject callInfo = getCallListing(limiter);
				Log.d(TAG, "Returning " + callInfo.toString());
				//Log.d(TAG,callInfo);
				result = new PluginResult(Status.OK, callInfo);
			} catch (JSONException jsonEx) {
				Log.d(TAG, "Got JSON Exception " + jsonEx.getMessage());
				result = new PluginResult(Status.JSON_EXCEPTION);
			}
		} else if (SHOW_ACTION.equals(action)) {
			try {
				if (!data.isNull(0)) {
					viewContact(data.getString(0));
				} 
			} catch (JSONException jsonEx) {
				Log.d(TAG, "Got JSON Exception " + jsonEx.getMessage());
				result = new PluginResult(Status.JSON_EXCEPTION);
			} catch (Exception e) {}
		} else if (CONTACT_ACTION.equals(action)) {
			try {
				String contactInfo = getContactNameFromNumber(data.getString(0));
				Log.d(TAG, "Returning " + contactInfo.toString());
				result = new PluginResult(Status.OK, contactInfo);
			} catch (JSONException jsonEx) {
				Log.d(TAG, "Got JSON Exception " + jsonEx.getMessage());
				result = new PluginResult(Status.JSON_EXCEPTION);
			}
		} else {
			result = new PluginResult(Status.INVALID_ACTION);
			Log.d(TAG, "Invalid action : " + action + " passed");
		}
		return result;
	}

	/**
	 * Gets the Directory listing for file, in JSON format
	 * 
	 * @param file
	 *            The file for which we want to do directory listing
	 * @return JSONObject representation of directory list. e.g
	 *         {"filename":"/sdcard"
	 *         ,"isdir":true,"children":[{"filename":"a.txt"
	 *         ,"isdir":false},{...}]}
	 * @throws JSONException
	 */
	private JSONObject getCallListing(String period) throws JSONException {

		JSONObject callLog = new JSONObject();

		String[] strFields = { 
				android.provider.CallLog.Calls.DATE,
				android.provider.CallLog.Calls.NUMBER,
				android.provider.CallLog.Calls.TYPE,
				android.provider.CallLog.Calls.DURATION,
				android.provider.CallLog.Calls.NEW,
				android.provider.CallLog.Calls.CACHED_NAME,
				android.provider.CallLog.Calls.CACHED_NUMBER_TYPE,
				android.provider.CallLog.Calls.CACHED_NUMBER_LABEL };

		try {
			Cursor callLogCursor = ctx.getContentResolver().query(
					android.provider.CallLog.Calls.CONTENT_URI, 
					strFields,
					CallLog.Calls.DATE + ">?",
	                new String[] {period},
					android.provider.CallLog.Calls.DEFAULT_SORT_ORDER);

			int callCount = callLogCursor.getCount();

			if (callCount > 0) {
				JSONObject callLogItem = new JSONObject();
				JSONArray callLogItems = new JSONArray();

				callLogCursor.moveToFirst();
				do {
					callLogItem.put("date", callLogCursor.getLong(0));
					callLogItem.put("number", callLogCursor.getString(1));
					callLogItem.put("type", callLogCursor.getInt(2));
					callLogItem.put("duration", callLogCursor.getLong(3));
					callLogItem.put("new", callLogCursor.getInt(4));
					callLogItem.put("cachedName", callLogCursor.getString(5));
					callLogItem.put("cachedNumberType", callLogCursor.getInt(6));
					//callLogItem.put("name", getContactNameFromNumber(callLogCursor.getString(1))); //grab name too
					callLogItems.put(callLogItem);
					callLogItem = new JSONObject(); 
				} while (callLogCursor.moveToNext());
				callLog.put("rows", callLogItems);
			}

			callLogCursor.close();
		} catch (Exception e) {
			Log.d("CallLog_Plugin",
					" ERROR : SQL to get cursor: ERROR " + e.getMessage());
		}

		return callLog;
	}
	
	/**
	 * Show contact data based on id
	 * @param number
	 */
	private void viewContact(String number) {
		Intent i = new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT, 
				Uri.parse(String.format("tel: %s", number)));
		this.ctx.startActivity(i);
	}
	
	
	/**
	 * Util method to grab name based on number
	 * 
	 */
	private String getContactNameFromNumber(String number) {
		// define the columns I want the query to return
		String[] projection = new String[] { Contacts.Phones.DISPLAY_NAME, Contacts.Phones.NUMBER };

		// encode the phone number and build the filter URI
		Uri contactUri = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL, Uri.encode(number));

		// query time
		Cursor c = ctx.getContentResolver().query(contactUri, projection, null, null, null);

		// if the query returns 1 or more results
		// return the first result
		if (c.moveToFirst()) {
			String name = c.getString(c.getColumnIndex(Contacts.Phones.DISPLAY_NAME));
			c.deactivate();
			return name;
		}

		// return the original number if no match was found
		return number;
	}
}

2.calllog.js文件放在assert-》www文件中

var CallLog ={
        list:function(params, successCallback, failureCallback) {
            return cordova.exec(successCallback, failureCallback, 'CallListPlugin', 'list',
                    [ params ]);
        },
        contact:function(params, successCallback, failureCallback) {
            return cordova.exec(successCallback, failureCallback, 'CallListPlugin', 'contact',
                    [ params ]);
        },
        show:function(params, successCallback, failureCallback) {
            return cordova.exec(successCallback, failureCallback, 'CallListPlugin', 'show',
                    [ params ]);
        }
 
};


然后开始例行公事:

3.在plugin.xml中添加语句(记得修改packageName)

<plugin name="CallListPlugin" value="com.tricedesigns.CallListPlugin"/>

4.定义调用的js

function aaa(){
         
        CallLog.list('all', function(data){
            //console.log(data);
            alert(data.rows.length);
            alert(data.rows[0].cachedName)
            //for(var i=0;i<=data.rows.length)
            //alert(data.rows.cachedName);
            }, function(){});
    }

5.效果如下:项目下载可进我的qq群共享(224711028 )




    
[3] Andriod phonegap(Cordova)弹出软件盘效能
    来源: 互联网  发布时间: 2014-02-18
Andriod phonegap(Cordova)弹出软件盘功能

貌似没什么用的软件盘弹出的功能,利用pg怎么去实现,纯属娱乐

1.首先是phonegap必备的两个文件,分别是本地.java代码SoftKeyBoard.java

package com.tricedesigns;

import org.json.JSONArray;

import android.content.Context;
import android.view.inputmethod.InputMethodManager;

import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;

public class SoftKeyBoard extends Plugin {

    public SoftKeyBoard() {
    }

    public void showKeyBoard() {
        InputMethodManager mgr = (InputMethodManager) ((Context) this.ctx).getSystemService(Context.INPUT_METHOD_SERVICE);
        mgr.showSoftInput(webView, InputMethodManager.SHOW_IMPLICIT);
        
        ((InputMethodManager) ((Context) this.ctx).getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(webView, 0); 
    }
    
    public void hideKeyBoard() {
        InputMethodManager mgr = (InputMethodManager) ((Context) this.ctx).getSystemService(Context.INPUT_METHOD_SERVICE);
        mgr.hideSoftInputFromWindow(webView.getWindowToken(), 0);
    }
    
    public boolean isKeyBoardShowing() {
        
    	int heightDiff = webView.getRootView().getHeight() - webView.getHeight();
    	return (100 < heightDiff); // if more than 100 pixels, its probably a keyboard...
    }

	public PluginResult execute(String action, JSONArray args, String callbackId) {
		if (action.equals("show")) {
            this.showKeyBoard();
			return new PluginResult(PluginResult.Status.OK, "done");
		} 
        else if (action.equals("hide")) {
            this.hideKeyBoard();
            return new PluginResult(PluginResult.Status.OK);
        }
        else if (action.equals("isShowing")) {
			
            return new PluginResult(PluginResult.Status.OK, this.isKeyBoardShowing());
        }
		else {
			return new PluginResult(PluginResult.Status.INVALID_ACTION);
		}
	}    
}

2.(.js文件share.js)其中的一个显示方法

var SoftKeyBoard={
        skbShow:function(win, fail){
            return cordova.exec(
                    function (args) { if(win !== undefined) { win(args); } }, 
                    function (args) { if(fail !== undefined) { fail(args); } }, 
                    "SoftKeyBoard", 
                    "show", 
                    []);    
        }
}
 
/*function SoftKeyBoard() {}
 
 
SoftKeyBoard.prototype.show = function(win, fail) {
    return PhoneGap.exec(
            function (args) { if(win !== undefined) { win(args); } }, 
            function (args) { if(fail !== undefined) { fail(args); } }, 
            "SoftKeyBoard", 
            "show", 
            []);    
};
 
SoftKeyBoard.prototype.hide = function(win, fail) {
    return PhoneGap.exec(
            function (args) { if(win !== undefined) { win(args); } }, 
            function (args) { if(fail !== undefined) { fail(args); } },
            "SoftKeyBoard", 
            "hide", 
            []);    
};
 
SoftKeyBoard.prototype.isShowing = function(win, fail) {
    return PhoneGap.exec(
            function (args) { if(win !== undefined) { win(args); } }, 
            function (args) { if(fail !== undefined) { fail(args); } },
            "SoftKeyBoard", 
            "isShowing", 
            []);    
};
 
PhoneGap.addConstructor(function() {
    PhoneGap.addPlugin('SoftKeyBoard', new SoftKeyBoard());
    PluginManager.addService("SoftKeyBoard","com.zenexity.SoftKeyBoardPlugin.SoftKeyBoard");
});
*/

3.然后我们在phonegap项目中添加上述两个文件

 

4.在plugin.xml中添加语句(记得修改packageName)

<plugin name="SoftKeyBoard" value="com.tricedesigns.SoftKeyBoard"/>

5.定义调用的js

function keyBoardClick(){
           SoftKeyBoard.skbShow(function () {
                // success
            },function () {
               // fail
            });
    }

效果如下:项目下载可进我的qq群共享(224711028 )






    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3