27_手机防盗的原理_30
手机防盗的前提就是绑定sim,如果不绑定没意义;
1、在Setup2Activity页面时,当点击下一个按钮是校验是否设置了sim绑定,没绑定的话不让进入;
2、在SelectContactAcitivity得到手机里的联系人并选择后传给Setup3Activity显示出来;
需要读取联系人权限:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
在Setup3Activity启动代码:
Intent intent = new Intent(this,SelectContactActivity.class);
startActivityForResult(intent, 0);
点击返回代码
String phone =data.get(position).get("phone");
Intent intent = new Intent();
intent.putExtra("phone", phone);
setResult(0, intent);
finish();
在onActivityResult()得到号码的代码:
String phone = data.getStringExtra("phone").replace("-", "");
显示号码:
et_setup3_phone.setText(phone);
3、在Setup3Activit点击下一步的时候校验安全号码是否设置
if(TextUtils.isEmpty(safeNumber)){
Toast.makeText(this, "安全号码不能为空", 0).show();
return;
}
4、安全号码如果没设置就设置保存起来
Editor editor = sp.edit();
editor.putString("safenumber", safeNumber);
editor.commit();
5、安全号码显示在onCreate()已经设置好的;
et_setup3_phone.setText(sp.getString("safenumber", ""));
6、Setup4Activit防盗保护的状态setOnCheckedChangeListener();
7、LostFindActivity界面读取状态并显示;
8、在BootCompleteReceiver 里处理防盗开启和不开启的情况;
开启:
发SmSManager sim card change短信;
//sim卡变更了,需要偷偷发短信;
System.out.println("sim卡变更了,需要偷偷发短信;");
String safenumber = sp.getString("safenumber", "");
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(safenumber, null, "sim card change !", null, null);
知识回顾
manager.sendTextMessage(mobile,null,text,null,null);
//第一个参数:对方手机号码
//第二个参数:短信中心号码,一般设置为空
//第三个参数:短信内容
//第四个参数:sentIntent判断短信是否发送成功,如果你没有SIM卡,或者网络中断,则可以通过这个intent来判断。
//注意强调的是“发送”的动作是否成功。那么至于对于对方是否收到,另当别论
//第五个参数:当短信发送到收件人时,会收到这个deliveryIntent。即强调了“发送”后的结果
//就是说是在"短信发送成功"和"对方收到此短信"才会激活sentIntent和deliveryIntent这两个Intent。这也相当于是延迟执行了Intent
9、发短信权限
<uses-permission android:name="android.permission.SEND_SMS"/>
28_短信指令的广播接受者_20
准备条件:启动另外一个模拟器
1、创建新的类SmsReceiver 并继承
2、功能清单文件配置:最大自然数:2147483647
<receiver android:name="com.itheima.mobilesafe.receiver.SmsReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
3、写配置权限:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
4、写代码
Object[] objs = (Object[]) intent.getExtras().get("pdus");
for(Object obj: objs){
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);
// String sender = smsMessage.getOriginatingAddress();
String body = smsMessage.getMessageBody();
if("#*location*#".equals(body)){
//获得手机位置地址
Log.e(TAG, "获得手机位置地址");
abortBroadcast();
}else if("#*alarm*#".equals(body)){
//手机报警
Log.e(TAG, "手机报警");
abortBroadcast();
}else if("#*lockscreen*#".equals(body)){
//远程锁屏
Log.e(TAG, "远程锁屏");
abortBroadcast();
}else if("#*wipedata*#".equals(body)){
//清除手机数据
Log.e(TAG, "清楚数据");
abortBroadcast();
}
}
29_播放报警音乐_10
1、创建raw 目录拷贝需要用的音乐文件
2、写播放音乐的代码;
MediaPlayer mediaPlayer =MediaPlayer.create(context, R.raw.ylzs);
mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.setLooping(false);
mediaPlayer.start();
abortBroadcast();
3、演示默默音乐,并说明Android手机声音系统:铃声和多媒体音的区别
30_三种获取手机的位置的方式_20
1、网络定位(network)。前提是必须连上网络:wifi、3G、2G;
获取到IP地址
例如:传美版QQ,彩虹版QQ,珊瑚虫版QQ,就有一个功能显示对方的IP;
根据IP显示具体的位置;
原理是建立一个库那个IP地址对应那个地方;早期警方破案就采用此特点;
有局限性:针对固定的IP地址。
如果手机网或者ip地址是动态分布IP,这个偏差就很大。这种情况是无法满足需求的。
2、基站定位(passive)。
工作原理:手机能打电话,是需要基站的。手机定位也是用基站的。
手机附近能收到3个基站的信号,就可以定位了。
基站定位有可能很准确,比如基站多的地方;
如果基站少的话就会相差很大。
精确度:几十米到几公里不等;
3、GPS定位(gps)。
A-GPS 使用了卫星定位 需要联网辅助修正位置
需要3颗卫星;
特点是:需要搜索卫星, 头顶必须是空旷的;
影响条件:云层、大厦、大树。
卫星:美国人、欧洲人的卫星。
北斗:中国的,但没有民用,只是在大巴,战机等使用。
精确度:15米左右
31_代码实现获取手机位置_20
1.写代码单独创建一个工程(TestGPS)演示;
package com.example.testgps;
public class MainActivity extends Activity {
private LocationManager lm;
private MyLocationListener listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lm = (LocationManager) getSystemService(LOCATION_SERVICE);
listener = new MyLocationListener();
// 第二个参数:两次位置更新的时间间隔
lm.requestLocationUpdates("gps", 0, 0, listener);
}
class MyLocationListener implements LocationListener {
// 当位置发生变化 执行者方法
@Override
public void onLocationChanged(Location location) {
String longitude = "经度:" + location.getLongitude() + "\n";
String latitude = "纬度:" + location.getLatitude() + "\n";
String accuracy = "精度:" + location.getAccuracy() + "\n";
TextView textView = new TextView(getApplicationContext());
textView.setText(longitude + latitude + accuracy);
setContentView(textView);
}
// 当某一个位置提供者状态发生变化的时候 关闭--》开启 或者开启--》关闭
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
@Override
protected void onDestroy() {
super.onDestroy();
lm.removeUpdates(listener);
listener = null;
}
}
2.权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
32_获取手机位置的细节-火星坐标_12
准备条件是:得到GPS坐标
1、在ditu.google.cn上输入显示,找出偏移的原因;
2、介绍火星坐标
3、如何解决火星坐标的偏移的问题、创建Java工程使用代码
public static void main(String[] args) throws Exception {
ModifyOffset modifyOffset = ModifyOffset.getInstance(GetHuoxingLocation.class.getResourceAsStream("axisoffset.dat"));
PointDouble double1 =modifyOffset.s2c(new PointDouble(116.35372477, 40.06813447));
System.out.println(double1);
}
33_代码实现获取手机位置_10
1、创建服务GPSService 并移植代码到里面面,并优化细节。
2、 优化代码细节
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
String provider = lm.getBestProvider(criteria, true);
lm.requestLocationUpdates(provider, 0, 0, listener);
设置参数细化:
criteria.setAccuracy(Criteria.ACCURACY_FINE);//设置为最大精度
criteria.setAltitudeRequired(false);//不要求海拔信息
criteria.setBearingRequired(false);//不要求方位信息
criteria.setCostAllowed(true);//是否允许付费
criteria.setPowerRequirement(Criteria.POWER_LOW);//对电量的要求
3、发短信代码
Intent gpsintent = new Intent(context,GPSService.class);
context.startService(gpsintent);
SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
String lastlocation = sp.getString("lastlocation", null);
if(TextUtils.isEmpty(lastlocation)){
SmsManager.getDefault().sendTextMessage(sender, null, "location getting...", null, null);
}else{
SmsManager.getDefault().sendTextMessage(sender, null, lastlocation, null, null);
}
34_一键锁屏&清除手机数据_50
1、引入设备超级管理员(device admin)
2、看文档 Develop-->API Guides--->Administration
如果你是一个企业管理员,您可以利用api和Android设备管理系统功能和控制访问。
android 2.2引入了支持企业应用程序提供Android设备管理API。设备管理API提供了设备管理功能在系统级别。这些api允许您创建安全性敏感的应用程序是有用的在企业设置,IT专业人员需要丰富的控制员工的设备。例如,内置Android电子邮件应用程序利用了新的api来改善交流的支持。通过电子邮件应用程序,交流管理员可以执行密码策略——包括字母数字密码或数字针——在设备。管理员也可以远程擦(即恢复工厂默认值)丢失或被盗的手机。用户可以同步他们的电子邮件和日历数据交换。
3、在模拟器的ApiDemo里(打开/app/device admin)看这个功能,并演示锁屏;
4、创建工程、创建 MyAdmin
5、https://play.google.com 查看当前这类软件的下载量多少。
6、在设置里面去掉激活勾选框后,点击崩溃;
DevicePolicyManager;
7、注册超级管理员代码
//声明一个意图,作用是开启设备的超级管理员
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
ComponentName cn = new ComponentName(this, MyAdmin.class);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, cn);
//劝说用户开启管理员
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
"开启我把。开启我就可以锁屏了,开启送积分");
startActivity(intent);
8、演示一键锁屏,并展示无法卸载;
9、卸载当前应用的功能代码;
ComponentName cn = new ComponentName(this, MyAdmin.class);
//可以移除管理员
dpm.removeActiveAdmin(cn);
Intent intent = new Intent();
intent.setAction("android.intent.action.UNINSTALL_PACKAGE");
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse("package:"+getPackageName()));
startActivity(intent);
9、点击锁屏的时候验证是否已经锁屏
ComponentName cn = new ComponentName(this, MyAdmin.class);
if(dpm.isAdminActive(cn)){
//设备管理员的api
dpm.lockNow();
}else{
// openAdmin(null);
Toast.makeText(this, "请先激活管理员", 0).show();
}
10、设置密码
dpm.resetPassword("123", 0);
11、取消密码:用代码、设置页面;
/data/system # 密码存放在这里
35_号码归属地查询的UI_15
1、创建AtoolsActivity 类并写布局文件;(ic_menu_camera)
<TextView
android:background="@drawable/button"
android:clickable="true"
android:onClick="numberAddressQuery"
android:textColor="#000000"
android:drawableLeft="@android:drawable/ic_menu_camera"
android:textSize="18sp"
android:text="电话归属地查询"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
2、写代码进入该类
3、创建具体查询类NumberAddressActivity 并在功能清单文件注册
4、NumberAddressActivity 的布局文件
5、并写查询的基本框架,把输入框得到的号码打印出来。
36_号码归属地查询的原理_15
准备:需要联网:
http://api.showji.com/locating/help.htm
号码归属地查询几种做法:
第一种:联网查询;
第二种:把数据库 放在本地;
1、百度上输入:手机号码归属地
2、数据库的来源,可以在淘宝上购买;
买的数据不一定是Android下用的数据库;
如果在Android上使用得自己做一个;把数据写到Android的数据库里;
3、对数据库的优化;
数据库:address.db 174495 条数据 文件大小:16.3MB
去重SQL语句:select area , city , cardtype from info group by area , city , cardtype 2872 条
优化后:naddress.db 2872条数据 文件大小:3.21MB 减少了
4、因为上面的数据不完整,使用小米手机的数据库;
小米数据库:telocation.db 文件大小:7.46MB ;
mob_location: 254349 条数据
tel_location: 326 条数据
优化
优化后:address.db 文件大小:3.57MB
data1 254349 条数据
data2 1032 条数据
数据库如何使用了:
第一个SQL语句: select outkey from data1 where id = "1356666" 得到的是:646
第二个SQL语句:select location from data2 where id = "646" 得到的是:浙江台州移动
做集联查询
select location from data2 where id = (select outkey from data1 where id = '1358888')
37_号码归属地的查询实现_40
1、把数据库拷贝到assets目录并创建包com.itheima.mobilesafe.db.dao 包创建该类
file:///android_aset/address.db 这种无法访问
知识回顾:
WebView还可以加载图片String str = "file:///android_asset/icon.png";
AddressDao 实现getAddress()方法;
public static String getAddress(String number){
//把address.db拷贝到我们的/data/data/包名/files/address.db
String address = number;
SQLiteDatabase database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
Cursor cursor = database.rawQuery("select location from data2 where id = (select outkey from data1 where id = ?)",
new String[]{number.substring(0, 7)});
if(cursor.moveToNext()){
address = cursor.getString(0);
}
cursor.close();
database.close();
return address;
}
2、在SplashActivit页面做从Assets目录拷贝到data/data/com.itheima.moblesafe/files/address.db数据库的代码;
private void copyDB() {
try {
File file = new File(getFilesDir(),"address.db");
if(file.exists()&&file.length()>0){
Log.e(TAG, "数据库文件只需要拷贝一下,如果拷贝了,不需要重新拷贝了");
}else{
//数据库文件只需要拷贝一下,如果拷贝了,不需要重新拷贝了。
AssetManager am = getAssets();
InputStream is = am.open("address.db");
//创建一个文件/data/data/包名/files/address.db
FileOutputStream fos = new FileOutputStream(file);
byte [] buffer = new byte[1024];
int len = 0;
while((len=is.read(buffer)) != -1){
fos.write(buffer, 0, len);
}
is.close();
fos.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
3、实现查询代码把查询的结果显示
演示查号码:13412345678、13666666666、18666666666、18888888888、
查不到号码:16412345678
查询:168报错误引入支持其他号码查询
手机号码:
我国使用的手机号码为11位,其中各段有不同的编码方向:前3位———网络识别号;第4-7位———地区编码;第8-11位———用户号码。
知识点:手机号码11位,开头13x 、14x、15x、18x;
手机号码正则表达式:^1[3458]\\d{9}$
3位的号码:120、119、110、999(香港急救电话) 特殊号码:
4位的号码:5554 模拟器
5位的号码:10086 、10010客服电话
7位号码:3543243 本地号码
8位号码:83551234 本地号码
4、长途电话的查询
021 12345678 010-59790386
select location from data2 where area = "21"
public class AddressDao {
private static String path = "/data/data/com.itheima.mobilesafe/files/address.db";
public static String getAddress(String number){
//拷贝到到/data/data/包名/files/address.db
String address = number;
SQLiteDatabase db =SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
//手机号码11位,开头13x 、14x、15x、18x;
//手机电话号码
if(number.matches("^1[3458]\\d{9}$")){
Cursor cursor= db.rawQuery("select location from data2 where id = (select outkey from data1 where id = ? )",
new String[]{number.substring(0, 7)});
if(cursor.moveToNext()){
address = cursor.getString(0);
}
}else{
//119 、110
switch (number.length()) {
case 3:
address = "特殊号码";
break;
case 4://5556
address = "模拟器";
break;
case 5:
address = "客服电话";
break;
case 7:
address = "本地电话";
break;
case 8:
address = "本地电话";
break;
default:
if(number.length()>10&& number.startsWith("0")){
//010 12345678
Cursor cursor = db.rawQuery("select location from data2 where area = ?",
new String[]{number.substring(1, 3)});
if(cursor.moveToNext()){
String location = cursor.getString(0);
address = location.substring(0, location.length()-2);
}
cursor.close();
//0855 12345678
cursor = db.rawQuery("select location from data2 where area = ?",
new String[]{number.substring(1, 4)});
if(cursor.moveToNext()){
String location = cursor.getString(0);
address = location.substring(0, location.length()-2);
}
cursor.close();
}
break;
}
}
return address;
}
}
5、演示号码:01012345678、110、5556、95588、079912345678、08332142342.;
38_号码归属地的查询效果优化_10
1、当号码发生变化的时候addTextChangedListener();
et_phone.addTextChangedListener(new TextWatcher() {
//当文本发生变化的时候调
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.length()>=3){
String address = AddressDao.getAddress(s.toString());
tv_result.setText(address);
}
}
//当文本发生变化之前的时候调
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
//当文本发生变化之后的时候调
@Override
public void afterTextChanged(Editable s) {
}
});
2、演示号码:110、95533、01012345678
----------------------------------------------------------------------------------------------------------------------------------------------------------
常用网站
http://www.androiddevtools.cn/
手机定位原理
经纬度介绍
经纬度介绍
A-GPS