现在的位置: 首页 > 综合 > 正文

第二天:防盗功能实现

2018年05月17日 ⁄ 综合 ⁄ 共 10805字 ⁄ 字号 评论关闭
padding_top   ... 控件里面的东西 距离控件边框的距离

layout_margaintop ... 控件与控件之间的距离



需求:
判断用户是否已经进行过设置向导,

如果用户已经设置过了程序,不在提示用户进入设置向导

如果用户没有设置过手机防盗, 提示用户进入设置向导界面


使用@android下的图片资源好处:
1.减少程序apk的体积
2.提高程序获取图片的速度.

****************************************************************
State List
一个StateListDrawable是一个被定义为XML文件的drawable对象, 它可以使用不同的图像去表示
同样的图形,例如,一个按钮可以存在几种不同的状态(按下,获取焦点,两者都不),现在这个东西
可以使用一个状态列表来描绘,你可以为每个状态提供不同的背景图像。

您可以在一个XML文件中描述的状态列表。
每个图形表示由一个在单一的<selector>元素里面的<ITEM>的元素来表示。
每个的<item> 使用各种属性来描述的它的状态。

其实就是配置一个按钮在不同状态下显示不同的背景图片,想想WEB下的超链接,但是这个
不同的状态在安卓里面用配置文件表示。即State List.
在安卓里面它叫安卓选择器。

它在调用的时间,是用在按钮背景上的。

这种选择器在开发中用的是非常广泛的。

其实安卓中的很多图片是根据XML定义出来的,而不是美工。

细节优化“:
第一:处理按钮在不同状态下颜色不同
第二:处理GridView在点击和不点击下颜色不同。
第三:优化显示padding与margin的区别。
button_selector.xml这个就是State List的配置。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/button_background" android:state_enabled="true" android:state_window_focused="false"/>
    <item android:drawable="@drawable/button_background_selected" android:state_pressed="true"/>
    <item android:drawable="@drawable/button_background" android:state_focused="true"/>
    <item android:drawable="@drawable/button_background"/>
</selector>
其实就是对一个按钮在不同状态下给设置不同的图片。
那么这些背景图片的配置是这样的。
button_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <corners android:radius="2dip" >
    </corners>
	<gradient android:startColor="#ff2c2d2d"
	    android:centerColor="#ff262626"
	    android:endColor="#ff515151"
	    />
</shape>
按钮其它背景都是这样,只是颜色不一样。
然后在用按钮的时间这样调用:
 android:background="@drawable/button_selector"
调用的是一个列表,也就是把这个列表作为一个背景列表传到它 ,
然后不同的状态下,显示不同的背景图片。很简单。
也就是说,以前我们可能只用一张图片作为背景 ,但是现在我们用
很多张图片形成一个列表作为它的背景,然后在不同的状态下调用不同的。
例如我们以前可以直接把button_background作为背景了,
 android:background="@drawable/button_background"
 但是现在我们用列表。
 
 如何 让GridView,ListView这些东西也变色呢?
item_background_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 用于配置GridView背景图片列表 -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/item_background" android:state_enabled="true" android:state_window_focused="false"/>
    <item android:drawable="@drawable/item_background_selected" android:state_pressed="true"/>
    <item android:drawable="@drawable/item_background" android:state_focused="true"/>
    <item android:drawable="@drawable/item_background"/>
</selector>
里面引用的是:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle">
    <!-- 这是画一个正文形,下面是对这个正文形的一些作用。 -->
    <!-- 描边 -->  
	<stroke 
	    android:width="0.5dip"
	    android:color="#ff505050"/>
	 <!-- 圆角 --> 
	    <corners android:radius="2dip" ></corners>
	<gradient 
	    android:startColor="#ff404040"
	    android:centerColor="#ff383838"
	    android:endColor="#ff404040"
	    />
</shape>

关键是调用,首先在GridView条目的XML文件里面写上:
android:background="@drawable/item_background_selector"
我就是因为这点没有写,才出现问题的,不能正常显示的。

最后:
<GridView 
       android:listSelector="@drawable/item_background_selector"
	   。。。。。/>
	   
写一个设置向导界面。为了复习Style.
使用系统自带的图片,你先反编译之后,看看想要的图片。
这是使用安卓jar包的资源图片。
好处:
1:减少程序APK的体积。
2:提高程序访问图片的速度。

有一个小Bug,在相对布局里面,如果在控件里面
用了alignParentBottom这些设置为true了,那么
相对布局里面的gravity会失效。

TextView换行,/n 就行。

安卓如何获取表单的值?

两个activity切换之间的动画效果。
overridePendingTransition();
四种那个动画效果
alpha  渐变
rotate
set
translate

联系人Uri一定要看源码才知道怎么写?

raw_contact表查询联系人ID。
data表里面人子联系人的所有基本信息。
mimetypes表示信息的类型。

data表里面关联了这两个表,
每一行表示某个人的鞋类信息,
所以一个的信息可能占有多行。

联系人的布局因为比较简单,直接用代码写了
激活带有返回值的意图。

学习下动画效果,可能是一个动画的集合。

画一条线像<hr/>这样的,可以用ImageView也可以用View.
用一张这样的图片:
<ImageView 
        android:layout_height="1dip"
        android:layout_width="fill_parent"
        android:layout_marginTop="8dip"
        android:background="@drawable/devide_line"
/>
最关键的就是那张背景图片。

主要学习如何定义一个Style然后让大家共用。
一个特殊的:
<!-- 定义小星星的图标 ,注意这个图片是从安卓内部取出来的。 
		 在F:\安卓笔记\八、安卓核心基础\ziliao\apktool-install-windows-r04-brut1\android.jar.out\res\drawable-hdpi
		 目录下找。
 -->
<style name="image_star_style">
	<item name="android:layout_width">wrap_content</item>
	<item name="android:layout_height">wrap_content</item>
	<item name="android:src">@android:drawable/btn_star_big_on</item>
</style>
直接找到jar包下的文件,直接用岂不更舒服。
style调用是完全一样的:
 style="@style/text_content_style"
 
有一个小Bug,在相对布局里面,如果在控件里面
用了alignParentBottom这些设置为true了,那么
相对布局里面的gravity会失效。
所以可以在相对布局里面的某个控件上套上一个线性布局。
相对布局:
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
相对于父窗口的底部和右部。就是这两个属性会和你控件的gravity相冲突。

android:drawableRight="@drawable/next"
这个可以往按钮上面放图片。
之前我们做的都是按钮的背景,在按钮的下面放图片。

操,如此神奇,其实安卓里面定义的ID可以一致。看
官方API。
Views may have an integer id associated with them. 
These ids are typically assigned in the layout XML files, and are used to find specific views within the view tree.
一个ID可能会关联多个View对象。
但是它不能在一个XML文件里面也不能同时出现在一个View里面。
其实很好理解,一个activity就相当于一个命名空间,每次通过ID寻找控件的时间,都是在以父的acitivity为基准的。

activity之间切换动画效果。
复杂的动画,无非就是动画的一个集合。

再注意切换activity时间一定要从任务栈中移除
//一定要把当前的activity从任务栈里面移除finish();

//监听checkbox改变的事件,只用改变才会执行该回调方法 。
		checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			/**
			 * buttonView表示当前组件对象 
			 * isChecked表示它是否有被选中
			 */
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				if (isChecked) {
					System.out.println("onCheckedChanged  run");
					checkBox.setChecked(true);
					checkBox.setText("已绑定");
				}else {
					checkBox.setText("解除绑定");
					checkBox.setChecked(false);
				}
				
			}
});

如何写获取联系人这个东西?
第一,看看它的源码
第二,到data下看看它的内容提供者目录下的数据库

操,无比重要的东西竟然不会了。
activity之间传值。
A:
Intent intentSelect = new Intent(SetupGuide3Activity.this,SelectContactActivity.class);
startActivityForResult(intentSelect, 0);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	if (requestCode == 0 && resultCode == 1 && data != null) {
		String number = data.getStringExtra("number");
		etnumber.setText(number);
	}
}

B:
Intent intent = new Intent();
intent.putExtra("number", number);
setResult(1,intent);
finish();//也可以把另外一个直接关闭。


防盗的逻辑其实就是当别人更换你的卡肯定要关机生词,这个时间你判断一下,
与你之前的串号是不是一样,如果不一样,就往安全号码里面发个短信。
所以我们在每次开机的时间判断一下就行了,利用广播接收器。

#*location*# 获取手机的位置


#*delete*# 手机设置为出厂模式


#*lockscreen*# 给手机加密 锁定屏幕


#*alram*# 发出报警音乐 


必须了解手机如何定位?
其实绝大多数的GPS模块用的是AGPS,因为便宜但是定位范围
在2-10米,真正的GPS定位在1米之内,它们是基于卫星的定位,
它要求,头顶必须空旷,大树和水泥可能会导致AGPS找不到信号,
不过GPS这个专业的可以在一定程度上解决这个问题。
基站网站定位,只要有网络信号,范围在几百米到几千米不等。
为什么会这样?其实它会找到附近的三个基站把信号的重心给计算出来,
然后再根据这个三角形的重心与手机的位置通过公式计算出来,那误差就大了。
对于精度要求不高的应用可以这样用,例如新浪微薄。

手机的GPS设备只有一个,所以我们必须要求整个应用中只有一个实例,通过单态实现。


保证一个方法内的代码必须执行完就在这个方法上加一个同步的标志。可以保证代码全部执行完,
不会被打断。

 *防盗的基本思路是:当发现SIM变更的时间会自动往安全号码里面发送一条信息,内容应该包括提示信息和新换的SIM卡的手机号。
 *然后我们得到对方手机号码后,可以发送各种指令(其实就是短信),然后我们在防盗的软件里面有一个短信的广播接收者,其优先级
 *是最高的,如果其接收到的短信指令与我们的一致,我们就直接中止广播,不让这个手机短信接收器接收到广播,并且给发送者回复相应的
 *信息或者做相应的操作。如果它不换卡更好说,随便找个手机直接往自己手机上发短信。
package cn.itcast.mobilesafe.engine;
//可以重用重用这个GPS工具类
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

/**
 * 保证这个类只存在一个实例 :单态
 * @author chen
 *
 */
public class GPSInfoProvider {
	private static GPSInfoProvider mGpsInfoProvider;
	private static Context context;
	private MyLoactionListener listener;//都是保存只在一个这样的实例 
	LocationManager manager;
	
	//1.私有化构造方法
	private GPSInfoProvider(){};
	
	public static synchronized GPSInfoProvider getInstance(Context context){
		if (mGpsInfoProvider == null) {
			mGpsInfoProvider = new GPSInfoProvider();
			GPSInfoProvider.context = context;
		}
		return mGpsInfoProvider;
	}
	/**
	 * 获取gps 信息 
	 * @return
	 */
	public String getLocation(){
		manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
		//manager.getAllProviders(); // gps //wifi // 它 能够 得到所有的这种东西,但是不能确定哪个是最好的。
		String provider = getProvider(manager);
		// 注册位置的监听器  60000:变化多长时间更新一次,10:变化多少米更新一次  listener:发生变化的时间调用的回调方法
		manager.requestLocationUpdates(provider, 60000, 10, getListener());
		//获取上次存储进去的信息,如果没有返回空
		SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
		String location = sp.getString("location", "");
		return location;
	}
	/**
	 * 保证只有一个实例 
	 * @return
	 */
	private MyLoactionListener getListener(){
		if (listener == null) {
			listener = new MyLoactionListener();
		}
		return listener;
		
	}
	
	// 停止gps监听
	public void stopGPSListener(){
		manager.removeUpdates(getListener());
	}
	
	private class  MyLoactionListener implements LocationListener{
		/**
		 * 当手机位置发生改变的时候 调用的方法
		 */
		@Override
		public void onLocationChanged(Location location) {
			String latitude ="latitude "+ location.getLatitude(); //weidu 
			String longtitude = "longtitude "+ location.getLongitude(); //jingdu
			SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
			Editor editor = sp.edit();
			editor.putString("location", latitude+" - "+ longtitude);
			editor.commit(); //最后一次获取到的位置信息 存放到sharedpreference里面
		}
		/**
		 * 某一个设备的状态发生改变的时候 调用 可用->不可用  不可用->可用
		 */
		@Override
		public void onProviderDisabled(String provider) {
		}
		/**
		 * 某个设备被打开
		 */	
		@Override
		public void onProviderEnabled(String provider) {
		}
		/**某个设备被禁用
		 * 
		 */
		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
		
	}
	
	
	/**
	 * @param manager 位置管理服务
	 * @return 最好的位置提供者
	 */
	private String getProvider(LocationManager manager){
		Criteria criteria = new Criteria();//设置GPS的标准;尺度;准则 
		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		criteria.setAltitudeRequired(false);
		criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
		criteria.setSpeedRequired(true);
		criteria.setCostAllowed(true);
		//true表示保返回已经打开的设备
		return manager.getBestProvider(criteria, true);
	}
	

}


把一个应用程序设置为设备管理器,那么这个软件就不能被xie zai
如果你在设置里面的做了取消激活又可以xie zai.
然后你可以在设置里面把这个选项给隐藏。

更为牛逼的功能,
 file:///D:/android-sdk-windows/docs/guide/topics/admin/device-admin.html
 只要有这个你可以使软件不能卸载,并且可以锁屏,清除手机数据等。
1.创建 MyAdmin 的广播接受者 继承 DeviceAdminReceiver,并注册它
2、写相应的XML文件
3.注册广播接受者为admin设备
ComponentName mAdminName = new ComponentName(this, MyAdmin.class);
if (mService != null) {
		if (!mService.isAdminActive(mAdminName)) {
					Intent intent = new Intent(
					DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
					intent.putExtra				(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
							mAdminName);
					startActivity(intent);
				}
}

 
 
 
 
 
 
 
 
 
 
 




1.欢迎使用防盗设置

您的手机的防盗卫士:
* sim卡变更报警
* gps追踪
* 销毁数据
* 远程锁屏

		下一步
2.手机卡绑定 (sim卡的序列号) 
每次开机启动发现手机sim改变自动发送报警短信

未绑定/已经绑定
上一步
下一步

3.设置安全号码
sim卡更换后,可以把报警发送到该安全号码上
edittext
选择

4.设置完成
您的手机设置已经完成 
保护开启.
完成

显示4个界面有两种做法 :
1. 只有一个activity. setContentView();
2. 4个activity, 通过activity的跳转来实现 
熟悉不同activity之间的动画切换效果.

熟悉style的使用 

http://maps.google.cn/maps/geo?output=csv&key=abcdef&q=37,55

deviceadmin 
2.2以上的android系统支持 


1.创建 MyAdmin 的广播接受者 继承 DeviceAdminReceiver

		<receiver android:name=".MyAdmin">
			<meta-data android:name="android.app.device_admin"
				android:resource="@xml/my_admin" />
			<intent-filter>
				<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
			</intent-filter>
		</receiver>


my_admin.xml

<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
        <uses-policies>
                <limit-password />
                <watch-login />
                <reset-password />
                <force-lock />
                <wipe-data />
        </uses-policies>
</device-admin>

2.获取IDevicePolicyManager



Method method = Class.forName("android.os.ServiceManager")
					.getMethod("getService", String.class);
IBinder binder = (IBinder) method.invoke(null,
					new Object[] { Context.DEVICE_POLICY_SERVICE });
mService = IDevicePolicyManager.Stub.asInterface(binder);

3.注册广播接受者为admin设备
ComponentName mAdminName = new ComponentName(this, MyAdmin.class);
if (mService != null) {
		if (!mService.isAdminActive(mAdminName)) {
					Intent intent = new Intent(
					DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
					intent.putExtra				(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
							mAdminName);
					startActivity(intent);
				}
}





















抱歉!评论已关闭.