[Android] 获取Android设备的唯一识别码|设备号|序号|UUID

mikel阅读(952)

如何获取一个能唯一标识每台Android设备的序号?

这个问题有很多答案,但是他们中的大部分只在某些情况下有效。

根据测试:

  • 所有的设备都可以返回一个 TelephonyManager.getDeviceId()
  • 所有的GSM设备 (测试设备都装载有SIM卡) 可以返回一个TelephonyManager.getSimSerialNumber()
  • 所有的CDMA 设备对于 getSimSerialNumber() 却返回一个空值!
  • 所有添加有谷歌账户的设备可以返回一个 Android_ID
  • 所有的CDMA设备对于 Android_ID 和 TelephonyManager.getDeviceId() 返回相同的值(只要在设置时添加了谷歌账户)
  • 目前尚未测试的:没有SIM卡的GSM设备、没有添加谷歌账户的GSM设备、处于飞行模式的设备。

所以如果你想得到设备的唯一序号, TelephonyManager.getDeviceId() 就足够了。但很明显暴露了DeviceID会使一些用户不满,所以最好把这些id加密了。实际上加密后的序号仍然可以唯一的识别该设备,并且不会明显的暴露用户的特定设备,例如,使用 String.hashCode() ,结合UUID:

<div class="container">
<div class="line number1 index0 alt2"><code class="java keyword">final</code> <code class="java plain">TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);</code></div>
<div class="line number2 index1 alt1"></div>
<div class="line number3 index2 alt2"><code class="java spaces">    </code><code class="java keyword">final</code> <code class="java plain">String tmDevice, tmSerial, tmPhone, androidId;</code></div>
<div class="line number4 index3 alt1"><code class="java spaces">    </code><code class="java plain">tmDevice = </code><code class="java string">""</code> <code class="java plain">+ tm.getDeviceId();</code></div>
<div class="line number5 index4 alt2"><code class="java spaces">    </code><code class="java plain">tmSerial = </code><code class="java string">""</code> <code class="java plain">+ tm.getSimSerialNumber();</code></div>
<div class="line number6 index5 alt1"><code class="java spaces">    </code><code class="java plain">androidId = </code><code class="java string">""</code> <code class="java plain">+ android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);</code></div>
<div class="line number7 index6 alt2"></div>
<div class="line number8 index7 alt1"><code class="java spaces">    </code><code class="java plain">UUID deviceUuid = </code><code class="java keyword">new</code> <code class="java plain">UUID(androidId.hashCode(), ((</code><code class="java keyword">long</code><code class="java plain">)tmDevice.hashCode() &lt;&lt; </code><code class="java value">32</code><code class="java plain">) | tmSerial.hashCode());</code></div>
<div class="line number9 index8 alt2"><code class="java spaces">    </code><code class="java plain">String uniqueId = deviceUuid.toString();</code></div>
<div class="line number9 index8 alt2"><code class="java plain">
最后的deviceID可能是这样的结果: 00000000-54b3-e7c7-0000-000046bffd97

Qt浅谈之十七:飞舞的蝴蝶(GraphicsView框架)

mikel阅读(1233)

一、简介

GraphicsView框架结构主要包含三个主要的类QGraphicsScene(容器)、QGraphicsView(视图)、QGraphicsItem(图形项)。QGraphicsScene本 身不可见必须通过与之相连的QGraphicsView视口类来显示及与外界进行互操作,主要提供项目的操作接口、传递事件和管理各个项目状 态;QGraphicsView提供一个可视的窗口,用于显示场景中的项目,一个场景中可以有多个视口;QGraphicsItem是场景中各个项目的基 础类。

二、关系图

(1)三者间的关系

(2)坐标系统

QGraphicsScene坐标系是以中心为原点(0,0),QGraphicsView继承自QWidget以窗口的左上角作为自己坐标系的原点,而QGraphicsItem则有自己的坐标系其paint()函数重画时以此坐标系为基准。

(3)坐标映射

三个坐标系之间的相互转换函数及图形项与图形项之间的转换函数。

三、详解

1、运行图

2、解析

(1)利用定时器实现QGraphicsItem不停上下飞舞的蝴蝶的动画效果

  1. #include <QGraphicsItem>
  2. #include <QObject>
  3. class Butterfly : public QObject, public QGraphicsItem
  4. {
  5.     Q_OBJECT
  6. public:
  7.     Butterfly();
  8.     void timerEvent(QTimerEvent *);
  9.     QRectF boundingRect() const;
  10. protected:
  11.     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
  12. private:
  13.     bool up;
  14.     QPixmap pix_up;
  15.     QPixmap pix_down;
  16.     qreal angle;
  17. };
  1. static const double PI = 3.14159265358979323846264338327950288419717;
  2. Butterfly::Butterfly()
  3. {
  4.     setFlag(QGraphicsItem::ItemIsMovable);
  5.     pix_up.load(“:/images/butterfly1.PNG”);
  6.     pix_down.load(“:/images/butterfly2.PNG”);
  7.     up = true;
  8.     startTimer(100);
  9. }
  10. QRectF Butterfly::boundingRect() const
  11. {
  12.     qreal adjust = 8;
  13.     return QRectF(-pix_up.width()/2-adjust,-pix_up.height()/2-adjust,
  14.                 pix_up.width()+adjust*2,pix_up.height()+2*adjust);
  15. }
  16. void Butterfly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
  17. {
  18.     if(up)
  19.     {
  20.         painter->drawPixmap(boundingRect().topLeft(),pix_up);
  21.         up = !up;
  22.     }
  23.     else
  24.     {
  25.         painter->drawPixmap(boundingRect().topLeft(),pix_down);
  26.         up = !up;
  27.     }
  28. //    painter->setPen(Qt::NoPen);
  29. //    painter->setBrush(Qt::darkGray);
  30. //    painter->drawEllipse(-7,-7,40,40);
  31. //    painter->setPen(QPen(Qt::black,0));
  32. //    painter->setBrush(flash ? (Qt::red):(Qt::yellow));
  33. //    painter->drawEllipse(-10,-10,40,40);
  34. }
  35. void Butterfly::timerEvent(QTimerEvent *)
  36. {
  37.     // edge controll
  38.     qreal edgex = scene()->sceneRect().right()+boundingRect().width()/2;
  39.     qreal edgetop = scene()->sceneRect().top()+boundingRect().height()/2;
  40.     qreal edgebottom = scene()->sceneRect().bottom()+boundingRect().height()/2;
  41.     //qDebug() << scene()->itemsBoundingRect();
  42.     if (pos().x() >= edgex)
  43.         setPos(scene()->sceneRect().left(),pos().y());
  44.     if (pos().y() <= edgetop)
  45.         setPos(pos().x(),scene()->sceneRect().bottom());
  46.     if (pos().y() >= edgebottom)
  47.         setPos(pos().x(),scene()->sceneRect().top());
  48.     angle += (qrand()%10)/20.0;
  49.     qreal dx = fabs(sin(angle*PI)*10.0);
  50.     qreal dy = (qrand()%20)-10.0;
  51.     setPos(mapToParent(dx,dy));
  52.     update();
  53. }

分 析:在定时器的timeEvent()中对QGraphicsItem进行重画,重画paint()函数中飞舞的蝴蝶是由两幅图片组成,蝴蝶的移动边界做 一个限定,dx和dy是相对于蝴蝶的坐标系而言的,调用setPos函数时使用mapToParent()函数映射成场景的坐标。 setFlag(QGraphicsItem::ItemIsMovable);使蝴蝶可以通过鼠标移动。

(2)来回移动的星星

  1. class StarItem : public QGraphicsItem
  2. {
  3. public:
  4.     StarItem();
  5.     QRectF boundingRect() const;
  6.     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
  7. private:
  8.     QPixmap pix;
  9. };
  1. StarItem::StarItem()
  2. {
  3.     pix.load(“:/images/star.png”);
  4. }
  5. QRectF StarItem::boundingRect() const
  6. {
  7.     return QRectF(-pix.width()/2,-pix.height()/2,pix.width(),pix.height());
  8. }
  9. void
  10. StarItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
  11. {
  12.     painter->drawPixmap(boundingRect().topLeft(),pix);
  13. }
  1. {
  2.     StarItem *star = new StarItem;
  3.     QGraphicsItemAnimation *anim = new QGraphicsItemAnimation;
  4.     anim->setItem(star);
  5.     QTimeLine *timeLine = new QTimeLine(4000);
  6.     timeLine->setCurveShape(QTimeLine::SineCurve);
  7.     timeLine->setLoopCount(0);
  8.     anim->setTimeLine(timeLine);
  9.     int y = (qrand()%400) – 200;
  10.     for (int i=0; i<400; i++)
  11.     {
  12.         anim->setPosAt(i/400.0, QPointF(i-200,y));
  13.     }
  14.     timeLine->start();
  15.     scene->addItem(star);
  16. }

分析:利用QGraphicsItemAnimation类和QTimeLine实现项目的动画效果(也可使用定时器QTimer结合重绘函数来实现)。

(3)简单正方形

  1. {
  2.     QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(0,0,60,60));
  3.     QPen pen;
  4.     pen.setWidth(3);
  5.     pen.setColor(QColor(qrand()%256,qrand()%256,qrand()%256));
  6.     item->setPen(pen);

Android学习笔记23:时间日期控件的使用

mikel阅读(880)

Android中,时间日期控件相对来说还是比较丰富的。其 中,DatePicker用来实现日期输入设置,TimePicker用来实现时间输入设置。DatePickerDialog用来显示日期对话 框,TimePickerDialog用来显示时间对话框。AnalogClock用来显示一个指针式时钟,DigitalClock用来显示一个数字式 时钟。

下面就分别对这些时间日期控件做一个简单的介绍。

 

1.DatePicker

Android中,DatePicker用来实现日期输入设置,日期的设置范围为1900年1月1日至2100年12月31日。

1.1常用xml属性

DatePicker的常用xml属性如图1所示:

图1 DatePicker常用xml属性

其 中,android:calendarViewShown[boolean]用于设置是否显示 calendar view;android:endYear[int]用于设置截至日期;android:maxDate[int]用于设置最大的日 期;android:minDate[int]用于设置最小的日期;android:spinnersShown[boolean]用于设置是否显示 spinners;android:startYear[int]用于设置起始日期。

1.2常用方法

DatePicker的常用方法有以下一些:

(1)public CalendarView getCalendarView();   //获取CalendarView

(2)public boolean getCalendarViewShown();   //获取CalendarView是否显示

(3)public int getDayOfMonth();         //获取当前日期的日

(4)public long getMaxDate();            //获取最大日期

(5)public long getMinDate();            //获取最小日期

(6)public int getMonth();               //获取当前日期的月

(7)public boolean getSpinnersShown();        //获取Spinners是否显示

(8)public int getYear();             //获取当前日期的年

(9)public void init(int year,int monthOfYear,int dayOfMonth,

DatePicker.OnDateChangedListener onDateChangedListener);     //初始化日期

(10)public void setCalendarViewShown(boolean shown);      //设置是否显示CalendarView

(11)public void setMaxDate(long maxDate);       //设置最大日期

(12)public void setMinDate(long minDate);        //设置最小日期

(13)public void setSpinnersShown(boolean shown);   //设置是否显示Spinners

(14)public void updateDate(int year,int month,int dayOfMonth);    //更新当前日期

 

2.TimePicker

在Android中,TimePicker用来实现时间输入设置,可以选择12或24小时模式。TimePicker的常用方法有以下一些:

(1)public Integer getCurrentHour();       //获取当前时间的小时

(2)public Integer getCurrentMinute();       //获取当前时间的分钟

(3)public boolean is24HourView();        //获取是否为24小时模式

(4)public void setCurrentHour(Integer currentHour);            //设置当前时间的小时

(5)public void setCurrentMinute(Integer currentMinute);      //设置当前时间的分钟

(6)public void setIs24HourView(Boolean is24HourView);      //设置24小时模式

 

3.DatePickerDialog

在Android中,DatePickerDialog用来显示日期对话框。DatePickerDialog的常用方法有以下一些:

(1)public DatePicker getDatePicker();                                //获取DatePicker中的日期值

(2)public void onClick(DialogInterface dialog,int which);       //响应对话框中的点击事件

(3)public void onDateChanged(DatePicker view,int year,int month,int day);       //响应日期改变事件

(4)public void updateDate(int year,int monthOfYear,int dayOfMonth);              //更新当前日期

 

4.TimePickerDialog

在Android中,TimePickerDialog用来显示时间对话框。TimePickerDialog的常用方法有以下一些:

(1)public void onClick(DialogInterface dialog,int which);                             //响应对话框中的点击事件

(2)public void onTimeChanged(TimePicker view,int hourOfDay,int minute);    //响应时间改变事件

(3)public void updateTime(int hourOfDay,int minuteOfHour);                       //更新当前时间

 

5.AnalogClock

在Android中,AnalogClock用于显示指针式时钟,该时钟仅有时钟和分钟两个指针。

 

6.DigitalClock

在Android中,DigitalClock用来显示数字式时钟,显示格式为HH:MM:SS AM/PM。

 

7.实例

清楚了上面一些关于时间日期控件的属性和方法之后,我们就可以很容易的使用时间日期控件了。

在本例中,我们通过DatePicker实现了日期输入设置控件的显示,通过 TimePicker实现了时间输入设置控件的显示。并在主界面中中添加了两个Button控件,分别用于弹出日期设置对话框 DatePickerDialog和时间设置对话框TimePickerDialog。主界面如图2所示:

图2 主界面

通过DatePicker控件中的“+”和“-”按钮可以分别调整年月日的 值,通过TimePicker的“+”和“-”按钮可以分别调整小时和分钟的值。要监听年月日值的改变,需要实现接口 android.widget.DatePicker.OnDateChangedListener中的onDateChanged()方法;要监听小时 和分钟的值的改变,需要实现接口android.widget.TimePicker.OnTimeChangedListener中的 onTimeChanged()方法。具体实现方法如下:


/*
* Function  :    时间改变触发函数
* Param         :    view时间控件对象;hourOfDay小时;minute分钟
* Author      :    博客园-依旧淡然
*/
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
Toast.makeText(MainActivity.this, "当前时间为 " + hourOfDay + ":" + minute,
Toast.LENGTH_LONG).show();
}

/*
* Function  :    日期改变触发函数
* Param         :    view日期控件对象;year年;monthOfYear月;dayOfMonth日
* Author      :    博客园-依旧淡然
*/
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
Toast.makeText(MainActivity.this, "当前日期为" + year + "年" + monthOfYear + "月" + dayOfMonth + "日",
Toast.LENGTH_LONG).show();
}

通过对DatePicker控件和TimePicker控件进行监听,当点击DatePicker控件或TimePicker控件中的“+”或“-”按钮时,将弹出当前日期或当前时间的提示信息,如图3所示:

图3 调整日期控件的日期值

除此之外,我们也可以通过日期对话框DatePickerDialog和时间 对话框TimePickerDialog来调整日期和时间值。通过点击按钮“通过DatePickerDialog设置日期值”可以弹出日期对话框,通过 点击按钮“通过TimePickerDialog设置时间值”可以弹出时间对话框,时间设置对话框如图4所示。

图4 时间设置对话框

在时间设置对话框中,同样可以调整时间值。需要注意的是,在 DatePickerDialog控件中需要实现DatePickerDialog.OnDateSetListener接口,并实现该接口中的 onDateSet()方法。在TimePickerDialog控件中需要实现TimePickerDialog.OnTimeSetListener 接口,并实现该接口中的onTimeSet()方法。具体实现方法如下:


/*
* Function  :        Button按钮响应
* Param         :        v按钮对象
* Author      :    博客园-依旧淡然
*/
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonChangeDate:
MyDatePickerDialog myDatePickerDialog = new MyDatePickerDialog();
DatePickerDialog datePickerDialog = new DatePickerDialog(MainActivity.this,
myDatePickerDialog, mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
datePickerDialog.show();                //显示日期设置对话框
break;
case R.id.buttonChangeTime:
MyTimePickerDialog myTimePickerDialog = new MyTimePickerDialog();
TimePickerDialog timePickerDialog = new TimePickerDialog(MainActivity.this,
myTimePickerDialog, mTimePicker.getCurrentHour(), mTimePicker.getCurrentMinute(), true);
timePickerDialog.show();            //显示时间设置对话框
break;
}
}

/*
* Function  :       自定义MyDatePickerDialog类,用于实现DatePickerDialog.OnDateSetListener接口,
*                           当点击日期设置对话框中的“设置”按钮时触发该接口方法
* Author      :    博客园-依旧淡然
*/
public class MyDatePickerDialog implements DatePickerDialog.OnDateSetListener {
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
mDatePicker.updateDate(year, monthOfYear, dayOfMonth);        //更新日期值
}
}

/*
* Function  :       自定义MyTimePickerDialog类,用于实现TimePickerDialog.OnTimeSetListener接口,
*                           当点击时间设置对话框中的“设置”按钮时触发该接口方法
* Author      :    博客园-依旧淡然
*/
public class MyTimePickerDialog implements TimePickerDialog.OnTimeSetListener {
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
mTimePicker.setCurrentHour(hourOfDay);        //设置TimePicker的小时值
mTimePicker.setCurrentMinute(minute);            //设置TimePicker的分钟值
}
}

 

随机生成手机短信验证码

mikel阅读(1152)


/**
* 创建指定数量的随机字符串
* @param numberFlag 是否是数字
* @param length
* @return
*/
public static String createRandom(boolean numberFlag, int length){
String retStr = "";
String strTable = numberFlag ? "1234567890" : "1234567890abcdefghijkmnpqrstuvwxyz";
int len = strTable.length();
boolean bDone = true;
do {
retStr = "";
int count = 0;
for (int i = 0; i &lt; length; i++) {
double dblR = Math.random() * len;
int intR = (int) Math.floor(dblR);
char c = strTable.charAt(intR);
if (('0' &lt;= c) &amp;&amp; (c &lt;= '9')) {
count++;
}
retStr += strTable.charAt(intR);
}
if (count &gt;= 2) {
bDone = false;
}
} while (bDone);

return retStr;
}

 

手机号码归属地最新数据库2015年6月(附带采集更新程序)

mikel阅读(1065)

昨天发现数据库的手机号归属地判断不准确,数据库该更新了,百度了下好像没有什么共享好的。
以前是去淘宝上买的数据库,每次更新还得加钱,干脆自己做个算了,共享给大家。

使用说明:
1.单独号段的更新,请在手机号段里输入开始号段和结束号段,也可以在选择号段里选择,这样就不用填写了。
2.所有号段的更新,该功能将更新所有号段,执行时间较长。
3.清空按钮将清空数据库,请谨慎操作。
4.统计按钮显示数据库总数据及各个号段的数据总数,执行时间长,请稍微等待一会。
5.手机号码框里输入手机号码可以对数据库进行查询已校验数据。
采集过程中想把旧数据覆盖掉请勾选覆盖旧数据
采集过程中想跳过归属地为空的数据请勾选跳过空数据
采集过程请勿再点击其他按钮

更新说明:
2013.3.4  修正showji.com接口获取数据失败的问题
2013.3.25 加入184号段,并更新184号段信息2844个
2013.4.15 修正部分地区邮编和区号获取出错的问题
2013.8.15 修改网易接口失效为360接口,修正跳过方式为先判断再获取网络数据。
2014.1.22 根据网友yy2918的反映,增加了170,176,177号段,并更新数据
2014.4.10 根据网友yy2918、aspire的反映,增加了170号段,并更新数据。
2014.8.26 修改IP138接口获取数据错误的问题。
数据导出:
1.下载并安装office2003http://pan.baidu.com/share/link?shareid=2943813224&uk=1294197440
2.双击打开data.mdb,在Dm_Mobile表右键点导出,选择你想要的格式即可

数据信息:
程序所带ACCESS数据库为2015年6月15日更新,数据来源IP138,数据总数【316609】条

电信133 -> 9648 电信153 -> 9848 电信180 -> 9798 电信189 -> 9995
电信181 -> 9840 电信170 -> 4292 电信177 -> 6487 移动134 -> 9746
移动135 -> 10000 移动136 -> 10000 移动137 -> 9976 移动138 -> 9994
移动139 -> 9998 移动150 -> 10000 移动151 -> 10000 移动152 -> 10000
移动157 -> 8256 移动158 -> 10000 移动159 -> 10000 移动178 -> 2556
移动182 -> 9960 移动183 -> 9975 移动184 -> 7994 移动187 -> 9980
移动188 -> 9750 联通130 -> 9879 联通131 -> 10000 联通132 -> 10000
联通155 -> 10000 联通156 -> 9802 联通185 -> 8924 联通186 -> 9954
联通176 -> 3570 数据卡145 -> 6858 数据卡147 -> 9529

大笑点击下载手机号码归属地最新数据库(附带采集更新程序)

[转载]随机GPS数据(地图坐标) - 汤包 - 博客园

mikel阅读(1102)

来源: [转载]随机GPS数据(地图坐标) – 汤包 – 博客园

随机GPS数据(地图坐标)

昨天又接了个小任务,还是GPS的,要做一个随机生成GPS坐标数据的工具,而且要求生成的数据不能太”离谱”,也就是说要在一定范围之内,因为是模拟车行,所以可能有个限速的要求吧,不能一辆汽车每小时1w公里的速度行驶。。那就~~!

快下班接的任务~~!然后。。马上关机回家。。吃饭,看了会电视~~!11点了。。才想起来有任务。打开电脑~~!

既然是不能太离谱。。那就要在某个范围内移动。。唉,百度了下经纬度的2点距离公式~~!

double lat1,long1;//经度,纬度1

double lat2,long2;//经度,纬度2

const float pi = float(3.1415926);//pi

const float EarthRadiu = float(6378.245);//地球半径

float Wei_Km = ( pi * EarthRadiu )/180 ; //每度纬度多少公里

double lat0; //比较纬度,取两点小纬度的那个

if(lat1<lat2) lat0 = lat1;

else lat0 = lat2;

Jing_Km = (pi * (EarthRadiu * float( cos(Lat*pi/180 ))))/180;//在lat0上,每度经度间的距离

double cx, cy, r;//x方向距离,y方向距离,两点距离;

cx = abs(lat2-lat1) * Wei_Km;//根据纬度差计算距离

cy = abs(long2-long1)*Jing_Km;//根据经度差计算距离

r = sqrt(cx*cx + cy *cy);

唉看了一大堆,三角函数。。。弧度。。。。公里。。英尺。。弄的头晕了。

以前算这个都是口算啊,唉,大学几年以后。。什么都忘记了~~!

还好我们有google,baidu,还有”病”。。信息检索这么发达的社会,还愁什么呢。唉~~!不会玩检索的人怎么冲浪呢~~!

检索了半天中文网页~~!没发现一个有用的,唉,直接google英文吧。Random longitude latitude 第一条记录俺就发现了想要的东西。。

http://www.geomidpoint.com/random/calculation.html

Calculation Methods – Random Points

详细内容自己看去吧,呵呵看不懂有google翻译。

意思大概就是2种方法,一个圆形区域一个矩形区域。详细内容只能意会不能言转,因为感觉把英语翻译成汉语是件十分恶心的事情,所以就不多说了,

  1. Circular region
  2. B. Rectangular region

Circular region calculation detail

  1. Convert all latitudes and longitudes to radians.
  2. rand1 and rand2 are unique random numbers generated in the range 0 to 1.0.
  3. Given the initial values startlat, startlon and maxdist. (maxdist is in miles or kms).
  4. For the mean radius of the earth use:
    radiusEarth = 3960.056052 miles or radiusEarth = 6372.796924 km
  5. Convert maximum distance to radians.
    maxdist=maxdist/radiusEarth
  6. Compute a random distance from 0 to maxdist scaled so that points on larger circles have a greater probability of being chosen than points on smaller circles as described earlier.
    dist = acos(rand1*(cos(maxdist) – 1) + 1)
  7. Compute a random bearing from 0 to 2*PI radians (0 to 360 degrees), with all bearings having an equal probability of being chosen.
    brg = 2*PI*rand2
  8. Use the starting point, random distance and random bearing to calculate the coordinates of the final random point.
    lat = asin(sin(startlat)*cos(dist) + cos(startlat)*sin(dist)*cos(brg))
    lon = startlon + atan2(sin(brg)*sin(dist)*cos(startlat), cos(dist)-sin(startlat)*sin(lat))
  9. If lon is less than -PI then:
    lon = lon + 2*PI
    If lon is greater than PI then:
    lon = lon – 2*PI

Circular region calculation detail

  1. Convert all latitudes and longitudes to radians.
  2. rand1 and rand2 are unique random numbers generated in the range 0 to 1.0.
  3. Given the initial values startlat, startlon and maxdist. (maxdist is in miles or kms).
  4. For the mean radius of the earth use:
    radiusEarth = 3960.056052 miles or radiusEarth = 6372.796924 km
  5. Convert maximum distance to radians.
    maxdist=maxdist/radiusEarth
  6. Compute a random distance from 0 to maxdist scaled so that points on larger circles have a greater probability of being chosen than points on smaller circles as described earlier.
    dist = acos(rand1*(cos(maxdist) – 1) + 1)
  7. Compute a random bearing from 0 to 2*PI radians (0 to 360 degrees), with all bearings having an equal probability of being chosen.
    brg = 2*PI*rand2
  8. Use the starting point, random distance and random bearing to calculate the coordinates of the final random point.
    lat = asin(sin(startlat)*cos(dist) + cos(startlat)*sin(dist)*cos(brg))
    lon = startlon + atan2(sin(brg)*sin(dist)*cos(startlat), cos(dist)-sin(startlat)*sin(lat))
  9. If lon is less than -PI then:
    lon = lon + 2*PI
    If lon is greater than PI then:
    lon = lon – 2*PI

大概讲述了计算过程,正准备还是用C#进行解析上面的内容。。。看了一下首页的图标突然发现了很多功能~~!唉,有的时候还是要多点击一下的~~!

Random point Generator哈哈这不是我正需要的么?

爱因斯坦都不记自己家的电话,咱何必费那劲用C#解释那2段方法呢?

打开http://www.geomidpoint.com/random/

右键查看源码Ctrl+f 输入.js只有一个结果

<scripttype=”text/JavaScript” src=”jFunc.js”>

下载吧呵呵,虽然js方面是个小菜鸟,但是学习的精神是挡不住的~~!

点了跟烟,开始研究js~~!…………

主要算法calculate()

其实就是用JavaScript解释了一下上面那2段英文

好,C#转码~~!…………15分钟搞定,测试一下

~~!怎么随机出来的都是一样的。。。好吧线程休息一下

这次就对了,距离在设定的500Km以内,没什么问题。

睡了~~!

话说第二天~~!

来弄数据库的东西,根据数据库的设备生成”合理”数据

直接上图

根据最大速度,在间隔时间内生成一个点,然后继续以最后的点为中心继续移动~~!

主要方法:

 

var cosdif = Math.Cos(maxdist) – 1;

var sinstartlat = Math.Sin(startlat);

var cosstartlat = Math.Cos(startlat);

double dist = 0;

var rad360 = 2 * Math.PI;//圆周率

for (var i = 0; i < p; i++)//点数

{

//Thread.Sleep(100);

dist = Math.Acos((newRandom().NextDouble() * cosdif + 1));//随机数

brg[0] = rad360 * new Random().NextDouble();

lat = Math.Asin(sinstartlat * Math.Cos(dist) + cosstartlat * Math.Sin(dist) * Math.Cos(brg[0]));

lon = deg(normalizeLongitude(startlon * 1 + Math.Atan2(Math.Sin(brg[0]) * Math.Sin(dist) * cosstartlat, Math.Cos(dist) – sinstartlat * Math.Sin(lat))));

lat = deg(lat);

dist = Math.Round(dist * radiusEarth * 10000) / 10000;

brg[0] = Math.Round(deg(brg[0]) * 1000) / 1000;//随机距离

 

rtnList.Add(new GPSData() { Latitude = padZeroRight(lat), longtitude = padZeroRight(lon), distance = dist.ToString(), bearing = brg[j].ToString() });

}

 

就写到这里吧,也算个记录了~~!

Android 自动获取经纬度,计算距离、经纬度、方位角

mikel阅读(1326)

两点经纬度,计算距离
这种公式我必然是不知道的,谷歌翻了翻,有人(http://xxyyyboy.blog.163.com/blog/static/765832620110410457662/)说是
1.Lat1 Lung1 表示A点经纬度,Lat2 Lung2 表示B点经纬度;
2.a=Lat1 – Lat2 为两点纬度之差 b=Lung1 -Lung2 为两点经度之差;
3.6378.137为地球半径,单位为千米;
计算出来的结果单位为千米。
也有人http://panyee.cnblogs.com/archive/2006/07/04/442771.html)说直接从google maps的脚本里扒了段代码,maps的代码:计算的结果是米为单位。
    // 计算两点距离
    privatefinaldoubleEARTH_RADIUS = 6378137.0;
privatedouble gps2m(double lat_a, double lng_a, double lat_b, double lng_b) {
       double radLat1 = (lat_a * Math.PI / 180.0);
       double radLat2 = (lat_b * Math.PI / 180.0);
       double a = radLat1 – radLat2;
       double b = (lng_a – lng_b) * Math.PI / 180.0;
       double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
              + Math.cos(radLat1) * Math.cos(radLat2)
              * Math.pow(Math.sin(b / 2), 2)));
       s = s * EARTH_RADIUS;
       s = Math.Round(s * 10000) / 10000;
       return s;
    }
两点经纬度,计算方位角
计算方位角pab,
其中lat_a, lng_a是A的纬度和经度; lat_b, lng_b是B的纬度和经度。代码如下:
    // 计算方位角pab。
    privatedouble gps2d(double lat_a, double lng_a, double lat_b, double lng_b) {
       double d = 0;
       lat_a=lat_a*Math.PI/180;
       lng_a=lng_a*Math.PI/180;
       lat_b=lat_b*Math.PI/180;
       lng_b=lng_b*Math.PI/180;
        d=Math.sin(lat_a)*Math.sin(lat_b)+Math.cos(lat_a)*Math.cos(lat_b)*Math.cos(lng_b-lng_a);
       d=Math.sqrt(1-d*d);
       d=Math.cos(lat_b)*Math.sin(lng_b-lng_a)/d;
       d=Math.asin(d)*180/Math.PI;
//     d = Math.round(d*10000);
       return d
}

Android手机出现"已安装了存在签名冲突的同名数据包"的原因及解决办法

mikel阅读(846)

如果你不是开发者:如果你在Android上更新一个已经安装过较早版本软件时,安装到最后一步提示你:已安装了存在签名冲突的同名数据包,然后安装失败。这是因为旧版软件的签名信息与新版不一致造成的。你可以卸载这个软件,然后安装新版软件。

如果无法卸载,可能手机(pad)在发售前将该软件内置在手机中无法卸载。如果是这个原因的话,你可以尝试“root”系统,然后卸载掉该软件的旧版本,然后安装。

 

如 果你是一个开发人员,那么出现这个问题可能是因为,较旧的版本你是使用eclipse自动发布到模拟器上的,而eclipse自动发布时使用的是一个测试 用签名,这个签名与你正式打包的签名不是一个。(这个问题一般发生在测试自动更新功能上,嘿嘿)。想继续测试自动更新,解决的办法也很简单,手工删除该软 件的旧版(eclipse自动安装的那个),然后使用adb工具安装旧版再测试新版就好。

自动更新的安装代码一般是调用Intent安装

Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(Uri.parse("file://" + apkfile.toString()),"application/vnd.android.package-archive");
mContext.startActivity(i);

或许你和这略有不同,不用担心,没什么,问题不在这里。

转自:http://hi.baidu.com/cenxcen/item/824ff249eb5909f2dd0f6c64

View.VISIBLE、INVISIBLE、GONE的区别

mikel阅读(1240)

Android中UI应用的开发中经常会使用view.setVisibility()来设置控件的可见性,其中该函数有3个可选值,他们有着不同的含义:

View.VISIBLE—>可见
View.INVISIBLE—>不可见,但这个View仍然会占用在xml文件中所分配的布局空间,不重新layout
View.GONE—->不可见,但这个View在ViewGroup中不保留位置,会重新layout,不再占用空间,那后面的view就会取代他的位置,
所以在使用时要小心,尤其要善用INVISIBLE和GONE;

[Android Lint] xxx is not translated in xxx 的解决方法

mikel阅读(656)

Android SDK Tool r19之后, Export的时候遇到xxx is not translated in xxx的问题。

例如:

  1. “auto_exit” is not translated in zh, zh_CN

这是因为Android SDK Tool 將 Android_LINT_COMPLETE_REGIONS 改为了需要检查。

 

建议先尝试Clean, 一般可以解决。实在不行修改Lint设置,如下。

临时解决方法:
Eclipse > Preference > Android > Lint Error Checking的Correctness: Messages > MissingTranslate
将 Severity 从 Fetal 改为 Warming

VIA http://haking.iteye.com/blog/1525758

版权声明:本文为博主原创文章,未经博主允许不得转载。