2013年2月6日星期三

美亦福推广

点我就赚钱,信不信?

android获取手机号



最近做一个项目 需要获取到手机的相关信息
一个朋友的看法:
从技术层面而言,手机的SIM卡上并不会存储手机号码信息,只会存储IMSI(International Mobile Subscriber Identification Number)。手机号码(MSISDN)都是登记在HLR(Home Location Register)中的,在HLR中会把IMSI和MSISDN关联在一起。

 中国移动的SIM卡里只有IMSI号码而没有存储手机号码,在中国移动的HLR中会有一张映射表,专门用于把用户手机SIM卡的IMSI号映射成为用户的手机号码,这就是移动丢卡不丢号的业务也就是缘于此,也是一卡多号的原理。而电信CDMA(原来联通CDMA)的机卡合一的手机卡里会同时存在IMSI和手机号码。

•客户端获取:在客户端对移动用户而言只能够获取诸如IMSI、IMEI号等,并不能直接获得手机号。而对电信CDMA机卡合一用户可以获取手机号码。
•服务器端获取:在早期的移动白名单中是能够获得明文的手机号的,最近移动策略变了,手机号变成了天书般的唯一串号。因此目前从服务器端直接获取手机号也不行了。
 目前能够想到的能够相对可靠地自动获取用户手机号的方法只有通过短信方式。

•通过短信方式:让用户上行一条短信,通过短信网关获取用户手机号,从而将用户id与手机号绑定
另一个朋友的看法:

android 获取手机号码的方法 这里就不说了,太简单了。
手机号码不是所有的都能获取。只是有一部分可以拿到。这个是由于移动运营商没有把手机号码的数据写入到sim卡中.SIM卡只有唯一的编号,供网络与设备识别那就是IMSI号码,手机的信号也可以说是通过这个号码在网络中传递的,并不是手机号码。试想,你的SIM丢失后,补办一张新的会换号码吗?是不会的.就是因为在你的手机号码对应的IMSI号 在移动运营商中被修改成新SIM卡的IMSI号码。
那么手机号为什么有的就能显示呢?
这个就像是一个变量,当移动运营商为它赋值了,它自然就会有值。不赋值自然为空。
对于移动的用户,手机号码(MDN)保存在运营商的服务器中,而不是保存在SIM卡里。SIM卡只保留了IMSI和一些验证信息。手机每次入网注册的时候,都会以短信的形式将IMSI及验证信息上传到运营商的服务器,服务器在完成注册动作之后,会以短信的形式将注册的结果下发到手机里。下发的内容会因条件不同而不同。
如果服务器在下发的短信中,不包含手机的号码,手机是无法取得电话号码。如果短信中包含了号码,手机才会将其缓存,以备他用.此外,对于其他运行商的SIM卡或者UIM卡,MDN有可能保存在UIM卡中。100%能够取得本机号码不太可能。
移动神州行,联通的卡是可以取到的.动感地带的取不到.别的卡还没有试过.
能够读取SIM卡号的话应该有前提.那就是SIM卡已经写入了本机号码,不然是无法读取的
Android开发平台中,可通过TelephonyManager 获取本机号码。
TelephonyManager phoneMgr=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
txtPhoneNumber.setText(phoneMgr.getLine1Number()); //txtPhoneNumber是一个EditText 用于显示手机号
注:
根据Android的安全机制,在使用TelephonyManager时,必须在AndroidManifest.xml中添加<uses-permission android:name="READ_PHONE_STATE" /> 否则无法获得系统的许可。
手机型号 Build.MODEL
String
MODEL
The end-user-visible name for the end product.
sdk版本 Build.VERSION.SDK
String
SDK
This constant is deprecated. Use SDK_INT to easily get this as an integer.
及frimware版本号(系统版本号) Build.VERSION.RELEASE
String
RELEASE
The user-visible version string.
private void loadPhoneStatus(){ TelephonyManager phoneMgr=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); txtPhoneModel.setText(Build.MODEL); //手机型号 txtPhoneNumber.setText(phoneMgr.getLine1Number());//本机电话号码 txtSdkVersion.setText(Build.VERSION.SDK);//SDK版本号 txtOsVersion.setText(Build.VERSION.RELEASE);//Firmware/OS 版本号}
事实上,Build能向我们提供包括 硬件厂商,硬件编号,序列号等很多信息 调用方法也都同上,很简单。
String
BOARD
The name of the underlying board, like "goldfish".
String
BOOTLOADER
The system bootloader version number.
String
BRAND
The brand (e.g., carrier) the software is customized for, if any.
String
CPU_ABI
The name of the instruction set (CPU type + ABI convention) of native code.
String
CPU_ABI2
The name of the second instruction set (CPU type + ABI convention) of native code.
String
DEVICE
The name of the industrial design.
String
DISPLAY
A build ID string meant for displaying to the user
String
FINGERPRINT
A string that uniquely identifies this build.
String
HARDWARE
The name of the hardware (from the kernel command line or /proc).
String
HOST
String
ID
Either a changelist number, or a label like "M4-rc20".
String
MANUFACTURER
The manufacturer of the product/hardware.
String
MODEL
The end-user-visible name for the end product.
String
PRODUCT
The name of the overall product.
String
RADIO
The radio firmware version number.
String
SERIAL
A hardware serial number, if available.
String
TAGS
Comma-separated tags describing the build, like "unsigned,debug".
long
TIME
String
TYPE
The type of build, like "user" or "eng".
String
UNKNOWN
Value used for when a build property is unknown.
String
USER
=================================================
首先我们来明确几个概念:
SIM卡存储的数据可分为四类:
第一类是固定存放的数据。这类数据在移动电话机被出售之前由SIM卡中心写入,包括国际移动用户识别号(IMSI)、鉴权密钥(KI)、鉴权和加密算法等等。
第二类是暂时存放的有关网络的数据。如位置区域识别码(LAI)、移动用户暂时识别码(TMSI)、禁止接入的公共电话网代码等。
第三类是相关的业务代码,如个人识别码(PIN)、解锁码(PUK)、计费费率等。
第四类是电话号码簿,是手机用户随时输入的电话号码。用户全部资料几乎都存储在SIM卡内,因此SIM卡又称为用户资料识别卡。
IMSI是一个唯一的数字, 标识了GSM和UMTS 网络里的唯一一个用户. 它存储 在手机的SIM卡里,它会通过手机发送到网络上. IMSI 与 SIM唯一对应
IMEI也是一串唯一的数字, 标识了 GSM 和 UMTS网络里的唯一一个手机.它通常被打印在手机里电池下面的那一面,拨 *#06# 也能看到它. IMEI 与 设备唯一对应.
1。IMEI不存在于SIM卡中,它是手机本身的串号。
2。通常我们所说的手机号也不存在于SIM卡中,虽然SIM卡中有一个专门存储SIM卡本身号码的地方,但是此号码是通过手工设定的,而且是可以更改的。 SIM卡的识别通常使用IMSI号,这个对于SIM卡是唯一的。
3。使用SimGetRecordInfo之类的函数获得SIM卡的IMSI号码能否成功依赖于设备制造商是否实现了此函数,据我所知在DOPOD的机器上是可以获得,但是在联想的机器上却不行,其他机器没有。
4。获得IMEI以及IMSI可以通过RIL或者TAPI中的LINE操作的函数获得。
下面给出获取手机本机号码的代码:
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String deviceid = tm.getDeviceId();
String tel = tm.getLine1Number();
String imei = tm.getSimSerialNumber();
String imsi = tm.getSubscriberId();
添加权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
注意,手机号码不是所有的都能获取。只是有一部分可以拿到。这个是由于移动运营商没有把手机号码的数据写入到sim卡中。这个就像是一个变量,当移动运营商为它赋值了,它自然就会有值。不赋值自然为空。这就是为什么很多人得不到本机号码的原因。

这里才是我写的,上面都是开发过程中,转自别的朋友们的有用的资料,在此谢过。这个是我们的测试结果,不同手机,不同卡会得到不同的结果,下面的测试数据也不是绝对的。
运营商 卡类型 结果
中国移动 动感地带:3.0 获取不到
中国移动 神州行卡 可以获取
中国移动  全球通 可以获取
中国电信 全球漫游天翼国际卡 获取不到
中国联通 世界风 64K OTA 获取不到
中国联通 沃 128K USIM 可以获取

Android HTTP session && cookie



HTTP协议与状态保持
HTTP协议本身是无状态的,这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为,每一次请求之间都是独立的,好比一个顾客和一个自动售货机或者一个普通的(非会员制)大卖场之间的关系一样。
   
    然而聪明(或者贪心?)的人们很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用,就像给有线电视加上点播功能一样。这种需求一方面迫使HTML逐步添加了表单、脚本、DOM等客户端行为,另一方面在服务器端则出现了CGI规范以响应客户端的动态请求,作为传输载体的HTTP协议也添加了文件上载、cookie这些特性。其中cookie的作用就是为了解决HTTP协议无状态的缺陷所作出的努力。至于后来出现的session机制则是又一种在客户端与服务器之间保持状态的解决方案。
   
    让我们用几个例子来描述一下cookie和session机制之间的区别与联系。笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:
    1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。
    2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。
    3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。
   
    由于HTTP协议是无状态的,而出于种种考虑也不希望使之成为有状态的,因此,后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。

Cookie 定义




 1 typedef struct CookieEntry
 2 {
 3        PTCHAR     pszName;
 4        PTCHAR     pszValue;
 5        PTCHAR     pszUrlPath;
 6        DWORD      dwFlags;//Security Flags
 7        DWORD      dwLowWordExpiration;//LowWord of FILETIME
 8        DWORD      dwHighWordExpiration;//HighWord ofFILETIME
 9        DWORD      dwLowWordCreation;//LowWord of FILETIME
10        DWORD      dwHighWordCreation;//HighWord of FILETIME
11        CHAR   chEnd;//'*'
12 }COOKIEENTRY, *LPCOOKIEENTRY;



总结起来,每个Cookie有6个属性,分别 为:Cookies Name; Cookies Value; Domain;Path; Secure; Expire Date。这里给出的Cookie的6个属性和C++中定义的结构体不完全一致。其原因将在Cookie的文件格式小节给出解释。
下面对Cookie结构中的各个属性分别给出解释:
Cookies Name <Key>, 必要属性,指明了Cookie的名字,有一系列字符(不包括括号、逗号、空格等)组成;每个cookie由一个唯一的名称代表,这个名称可以包含字母、数 字、下划线。Cookie的名称是不分大小写,所以mycookie和MyCookie是一样。但考虑到服务器端语言可能区分大小写,所以对程序开发者来 说定义和使用时最好还是区分大小写。
Cookies Value,<Value>Cookie 的值,Web服务器储存在Cookie中的信息;保存在Cookie中的字符串值。这个值在存储之前是用encodeURIComponent()对其进 行编码的,否则会丢失数据或占用了Cookie。而且Cookie名字和值加起来的字节数不能超过4095字节,也即4KB。
Domain, 可选,指明了Cookie的有效域的范围,默认的是产生Cookie的服务器的名字;出于安全考虑,网站不能访问由其他域所创建的Cookie。创建 Cookie以后,域的信息会作为cookie的一部分存储下来。关于域,举个例子来说,如http://www.baidu.com/view /index.html, 它的域为:baidu.com。这里不做详述,后面的章节会有所涉及。
Path, 可选,指明了Cookie在有效域中的有效路径,在有效路径外的网页不可以读写Cookie,默认的是产生此Cookie的信息的URL;而该属性也是 Cookie的另一个安全特征,限制对Web服务器上特定目录的访问。即控制哪些访问能触发发送。例如请求的地址是上面的URL,如果 path=/view,这个Cookie就会被发送,但是path为其他路径的话,该Cookie会被忽略。
Secure, 可选,一个true/false值,用于表示Cookie是否只能从安全网站(使用SSL和https协议的网站)中访问;即如果标记一个Cookie为 安全的(这个值被设置为true),那么仅当客户端与服务器的对话通道是安全的(如HTTP over SSL),Cookie才会被传送。
Expire Date, 可选,指明了Cookie的有效时间,一旦过期,Cookie将不再有效,通常由产生Cookie的程序(Date由服务器指明)指定,如果不指明,系统会默认Cookie将在用户会话结束后自动过期。



cookie机制和session机制的区别
*************************************************************************************
Cookie是客户端的存储空间,由浏览器来维持。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于才服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制("PHPSESSID")来达到保存标识的目的,但实际上还有其他选择,比如说重写URL和隐藏表单域。
如何利用实现自动登录
*************************************************************************************
当用户在某个网站注册后,就会收到服务器发送的一个惟一用户ID的cookie。客户后来重新连接时,这个用户ID会自动发送回服务器,服务器对它进行检查,确定它是否为注册用户且选择了自动登录,从而使用户务需给出明确的用户名和密码,就可以访问服务器上的资源。
如何根据用户的爱好定制站点
*************************************************************************************
网站可以使用cookie记录用户的意愿。对于简单的设置,网站可以直接将页面的设置存储在cookie中完成定制。然而对于更复杂的定制,网站只需仅将一个惟一的标识符发送给用户,由服务器端的数据库存储每个标识符对应的页面设置。

通过Cookie实现Session保持




1.import java.io.IOException;

2.import java.io.UnsupportedEncodingException;

3.import java.util.List;

4.

5.import org.apache.http.HttpEntity;

6.import org.apache.http.HttpResponse;

7.import org.apache.http.HttpStatus;

8.import org.apache.http.NameValuePair;

9.import org.apache.http.client.ClientProtocolException;

10.import org.apache.http.client.CookieStore;

11.import org.apache.http.client.entity.UrlEncodedFormEntity;

12.import org.apache.http.client.methods.HttpPost;

13.import org.apache.http.cookie.Cookie;

14.import org.apache.http.impl.client.DefaultHttpClient;

15.import org.apache.http.protocol.HTTP;

16.import org.apache.http.util.EntityUtils;

17.

18.public class MyHttpClient implements InetConfig {

19.private DefaultHttpClient httpClient;

20.private HttpPost httpPost;

21.private HttpEntity httpEntity;

22.private HttpResponse httpResponse;

23.public static String PHPSESSID = null;

24.public LVHttpClient() {

25.

26.    }

27.

28.public String executeRequest(String path, List<NameValuePair> params) {

29.        String ret = "none";

30.       try {

31.            this.httpPost = new HttpPost(BASEPATH + path);

32.            httpEntity = new UrlEncodedFormEntity(params, HTTP.UTF_8);

33.            httpPost.setEntity(httpEntity);

34.             //第一次一般是还未被赋值,若有值则将SessionId发给服务器

35.            if(null != PHPSESSID){

36.                httpPost.setHeader("Cookie", "PHPSESSID=" + PHPSESSID);

37.            }

38.            httpClient = new DefaultHttpClient();

39.        } catch (UnsupportedEncodingException e) {

40.            e.printStackTrace();

41.        }

42.        try {

43.            httpResponse = httpClient.execute(httpPost);

44.            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {

45.                HttpEntity entity = httpResponse.getEntity();

46.                ret = EntityUtils.toString(entity);

47.                CookieStore mCookieStore = httpClient.getCookieStore();

48.                List<Cookie> cookies = mCookieStore.getCookies();

49.                for (int i = 0; i < cookies.size(); i++) {

50.                     //这里是读取Cookie['PHPSESSID']的值存在静态变量中,保证每次都是同一个值

51.                     if ("PHPSESSID".equals(cookies.get(i).getName())) {

52.                        PHPSESSID = cookies.get(i).getValue();

53.                        break;

54.                    }

55.

56.                }

57.            }

58.        } catch (ClientProtocolException e) {

59.            e.printStackTrace();

60.        } catch (IOException e) {

61.            e.printStackTrace();

62.        }

63.        return ret;

64.    }

65.}



基于http协议的,那么如果网站不是php做的话,那个叫做Sessionid的Cookie可能叫做别的了,就不是PHPSESSID了,而是叫做别的名字了,这个可能要具体情况去查

PHPCMS V9 配置文件调用



$upload_url = pc_base::load_config('system','upload_url'); //返回caches/configs/system.php文件中数组的关键字为upload_url的值

注解:

pc_base::load_config(

'配置文件的文件名',

'指定关键字以便返回其对应的元素值,不指定则返回整个数组',

'默认值(默认为空)',

是否(1/0)强制重新加载,默认为false,即调用上次加载的结果

);

android实现session保持




在最近写的一个Android中需要请求web服务器中的数据,有一个登录Activity,登录后会到MainActivity,这中间登录和MainActivity都需要请求php的jsonapi,所以要在网络请求中保持session的,研究了好半天才搞定。其实sesion在浏览器和web服务器直接是通过一个叫做name为sessionid的cookie来传递的,所以只要在每次数据请求时保持sessionid是同一个不变就可以用到web的session了,做法是第一次数据请求时就获取sessionid的值并保存在一个静态变量中,然后在第二次请求数据的时候要将这个sessionid一并放在Cookie中发给服务器,服务器则是通过这个sessionid来识别究竟是那个客户端在请求数据的,在php中这个sessionid的名字叫做PHPSESSID。下面贴下代码


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

public class MyHttpClient implements InetConfig {
    private DefaultHttpClient httpClient;
    private HttpPost httpPost;
    private HttpEntity httpEntity;
    private HttpResponse httpResponse;
    public static String PHPSESSID = null;
    public LVHttpClient() {

    }

    public String executeRequest(String path, List<NameValuePair> params) {
        String ret = "none";
        try {
            this.httpPost = new HttpPost(BASEPATH + path);
            httpEntity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
            httpPost.setEntity(httpEntity);
            //第一次一般是还未被赋值,若有值则将SessionId发给服务器
            if(null != PHPSESSID){
                httpPost.setHeader("Cookie", "PHPSESSID=" + PHPSESSID);
            }          
            httpClient = new DefaultHttpClient();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try {
            httpResponse = httpClient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = httpResponse.getEntity();
                ret = EntityUtils.toString(entity);
                CookieStore mCookieStore = httpClient.getCookieStore();
                List<Cookie> cookies = mCookieStore.getCookies();
                for (int i = 0; i < cookies.size(); i++) {
                    //这里是读取Cookie['PHPSESSID']的值存在静态变量中,保证每次都是同一个值
                    if ("PHPSESSID".equals(cookies.get(i).getName())) {
                        PHPSESSID = cookies.get(i).getValue();
                        break;
                    }

                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return ret;
    }
}

其实web的原理都是一样的,基于http协议的,那么如果网站不是php做的话,那个叫做Sessionid的Cookie可能叫做别的了,就不是PHPSESSID了,而是叫做别的名字了,这个可能要具体情况去查了。

其实不只是Android程序,其他任何程序需要这么用的时候只需要在http协议请求header里头加上发送相应的SessionId就可以了。刚刚这种方法是可以帮助理解sessionid的,其实还有一种方法如果更通用的话,就可以将刚刚所有的Cookie每次都发回到服务器端,也就可以解决session保持的问题了,只是这样可能会稍微大些网络流量开销而已。

这里看到一个SessionId的本质,顺便mark一下。

vagex常见问题



总结一下挂vagex过程中有人问过我以及我自己遇到的问题。

Q:一共可以多少台机器同时挂?

A:一台机器开多个帐号是没用的,最多可同时5个ip同时挂。当然,vagex支持windows和firefox以及安卓三种方式挂机。所以理论上挂满3*5



Q:要几刀才能申请提现呢?

A:一次至少10刀



Q:vagex我已经申请提现3天了,为什么还是没到账

A:根据别人的情况,一般需要7天左右才能到账,所以不要着急



Q:vagex后台显示有效ip,但是为什么不出分呢?

A:vagex抽的相当厉害,可能有一段时间不出分,无需理会。一般只需等待恢复正常即可



Q:我装了插件为什么没有西东刷新视频呢?

A:请确保vagex的插件图标在工具栏的第一个。见图

Q:一台VPS每月大概能赚多少美刀呢?

A:我这边平均一台机器一天能挂1800点,由于汇率一直在变,所以可以根据自己的情况进行换算。

VAGEX挂机赚美刀 2012-03-16
vagex对于经常折腾VPS的人来说应该不算新鲜玩意儿了。之前一直觉得这玩意儿不太可能赚啥钱,由于最近手头上有几个低价的vps,闲置也是闲置。于是准备试试这玩意儿,反正主要目的不是靠它赚钱,就当是玩网游了。

首先你需要

1、一枚paypal

2、一枚vagex帐号

3、一台电脑

paypal帐号申请很方便这边不再讲解。vagex帐号可以猛击这边申请。也是非常简单,10秒即可搞定。

最后就是电脑了,由于vagex是通过刷youtube视频来换取美刀的,所以国内ip没法打开youtube,所以自己家的电脑就没法使用了。一般有两种办法解决。第一挂VPN或者SSH。或者直接使用国外的VPS。我自己属于后者。