归属地显示&归属地显示风格设置&归属地显示的位置&趣味小火箭&4.趣味题:两次点击退出

知识点

概念

注意事项

归属地显示功能

用户外拨 来电 时显示归属地

 

 

Service

运行后台程序:

所有界面都退出 仍然运行程序

1.继承

2.重写

3.配置

4.启动

来电

TelephoneManager通讯参数

1.sim卡号码

2.状态  响铃 接通 空闲

PhoneStateListener(来电号码)

权限 READ_PHONE

外拨

BroadcastReceiver拦截外拨电话的广播

 

action

权限 PROCESS_OUT_CALL

注意优先级

WindowManager

1.系统级服务getSystemService

2.SYSTEM_ALERT

3.addView remove updateViewLayout

顶级布局:显示在Activity这个布局

Layoutparams

布局参数对象

宽 高 对齐  背景  ...类型 

x

y

OnTouchListener

触摸监听器
action  按下  移动  提起

注意事项

一个控件focusable =false

clickable=false;或者 not_touchable

风格设置

AlertDialog.Builder:对话框快速创建工具

setSingleChoiceItems();

保存下标

把下标对应一张图片。

 

位置设置

Activity 布局一个视图

TouchListener

保存x,y  marginLeft marginRight

显示布局的设置p.x p.y

 

小火箭

1.Service

2.WindowUtils

3.Animaton-List 帧布局

4.TouchListener

5.范围判围

6.Thread+handler修改y-=50;

7.Activity  2000关闭

8.背景设置为透明theme

9.launchMode启动模式singleInstance

 

两次点击退击

监听返回键onKeyDown return true

保存点击时间

时间间隔小于等于2000退出

1.系统时钟SystemClock 启动手机

2.System.arraycopy(

源数组,开始,目标数组,开始,个数)


归属地显示

① 创建Service  1.继承2.重写3.配置4.启动 startService/stopService  bindService/unbindService

② 监听来电号码

TelephonyManager:

 

1.系统级别的服务 getSystemService();

2.权限  READ_PHONE

3.跟通讯参数相关的服务 sim  电话

 

PhoneStateListener

监听器 

状态 响铃 空闲  通话

获取号码 

1.On...Listener

2.类


<span style="font-size:14px;"><!-- 获取手机状态 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />


		// ---------------------来电
		// TelephonyManager:
		// 1.系统级别的服务 getSystemService();
		// 2.权限 READ_PHONE
		// 3.跟通讯参数相关的服务 sim 电话
		//
		tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
		// PhoneStateListener 监听器
		// int state
		// 状态 响铃 空闲 通话
		listener = new PhoneStateListener() {
			// 监听电话状态
			// String incomingNumber来电话码
			@Override
			public void onCallStateChanged(int state, String incomingNumber) {
				// TODO Auto-generated method stub
				super.onCallStateChanged(state, incomingNumber);
				switch (state) {
				case TelephonyManager.CALL_STATE_IDLE:// 空闲
					Log.i("wzx", "CALL_STATE_IDLE---");
					break;
				case TelephonyManager.CALL_STATE_RINGING:// 响铃
					Log.i("wzx", "CALL_STATE_RINGING---");
					Toast.makeText(getBaseContext(), "来电:" + incomingNumber, 0).show();
					break;
				case TelephonyManager.CALL_STATE_OFFHOOK:// 接通
					Log.i("wzx", "CALL_STATE_OFFHOOK---");
					break;
				}
			}
		};
		tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);// 添加监听器
		// tm.listen(listener, PhoneStateListener.LISTEN_NONE);// 移除监听器</span>

3, 监听外拨号码

BroadcastReciever:广播接收者 接收广播 的对象

广播:Intent

1.继承 2.重写 3.配置

注意事项:1.action类型 例:外拨  boot sms

         2.权限

         3.优先级priority

注册方式:

a.标签注册

b.代码注册  在service

<span style="font-size:14px;"><!-- 外拨电话 -->
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
	// 获取号码
		// 1.On...Listener
		// 2.类
		// ---------------------------外拨------
		// BroadcastReciever:广播接收者 接收广播 的对象
		// 广播:Intent
		// 1.继承 2.重写 3.配置
		// 注意事项:1.action类型 例:外拨 boot sms
		// 2.权限
		// 3.优先级priority
		// 注册方式:
		// a.标签注册
		// b.代码注册 在service
		// IntentFilter:给四大组件 绑定参数
		IntentFilter filter = new IntentFilter();
		filter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);
		registerReceiver(receiver, filter);
	}

	private CallReceiver receiver = new CallReceiver();
	private class CallReceiver extends BroadcastReceiver {

		// getResultData()获取号码
		// 接收广播的时候
		@Override
		public void onReceive(Context context, Intent intent) {
			Toast.makeText(getBaseContext(), "外拨:" + getResultData(), 0).show();
		}
	}
	@Override
	public void onDestroy() {
		super.onDestroy();
		tm.listen(listener, PhoneStateListener.LISTEN_NONE);// 移除监听器
		Log.i("wzx", "归属地显示服务 销毁.....$$$$$");
		unregisterReceiver(receiver);
	}</span>

4, 自定义吐司

顶级布局:显示在Activity之上的一个布局

 

WindowManager

1. 系统级的服务 getSystemService(); 

vibrator gps sim

2. 工具:可以把视图对象添加顶级布

add  remove

3. 权限 

a. 布局

b. 获取windowManager

c. 添加

<span style="font-size:14px;"><!--     添加权限 -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
public class WindowUtils {
	/**
	 * 自定义吐司:添加视图到顶级布局
	 * @param context
	 * @param layoutId
	 * @param x
	 * @param y
	 * @return
	 */
	// 添加
	public static View show(Context context, int layoutId,int x ,int y) {
		// a.布局
		// b.获取windowManager
		View view = View.inflate(context, layoutId, null);
		//
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

		//
		// LayoutParams:布局参数对象
		WindowManager.LayoutParams params = new WindowManager.LayoutParams();
		// layout_width宽
		// layout_height高
		params.width = WindowManager.LayoutParams.WRAP_CONTENT;
		params.height = WindowManager.LayoutParams.WRAP_CONTENT;

		// 内容对齐
		params.gravity = Gravity.LEFT | Gravity.TOP;
		// gravity
		// background
		// 背景
		params.format = PixelFormat.TRANSLUCENT;
		// flags其它
		// focusable="true"
		// clickable="false"
		params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE// 不支持焦点
				| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE// 不支持点击 触摸
				| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;// 屏幕亮
		params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;// 类型 :层级
		params.x = x;
		params.y = y;

		// 坐标
		// c.添加
		wm.addView(view, params);// 往顶级布局里面添加视图对象

		return view;
	}

	/**
	 * 从顶级布局里面移除
	 * @param context
	 * @param view
	 */
	// 删除
	public static void remove(Context context, View view) {
		// a.布局
		// b.获取windowManager
		//
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		// c.添加
		wm.removeView(view);// 往顶级布局里面删除 视图对象
	}

}</span>

5,拖动事件



<span style="font-size:14px;">//获取显示对象
		final Display display=wm.getDefaultDisplay();
		final int SCREE_WIDHT=display.getWidth();
		final int SCREE_HEIGHT=display.getHeight();
		OnTouchListener listener = new OnTouchListener() {
			// 用户触摸屏幕

			private float x;
			private float y;

			// MotionEvent事件参数对象:封装 动作 1.按下 2.移动 3.提起
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:// 按下

					x=event.getRawX();
					y=event.getRawY();
					break;
				case MotionEvent.ACTION_MOVE:// 移动
					float newx=event.getRawX();
					float newy=event.getRawY();
					//偏移量
					float offx=newx-x;
					float offy=newy-y;
					//布局参数对象
					WindowManager.LayoutParams params=(LayoutParams) view.getLayoutParams();
					
					params.x+=offx;
					params.y+=offy;
					
					//
					if(params.x<=0)
					{
						params.x=0;
					}
					if(params.y<=0)
					{
						params.y=0;
					}
					
					if(params.x>=(SCREE_WIDHT-view.getWidth()))
					{
						params.x=(SCREE_WIDHT-view.getWidth());
					}
					
					if(params.y>=(SCREE_HEIGHT	-view.getHeight()))
					{
						params.y=(SCREE_HEIGHT	-view.getHeight());
					}
					
					
					
					//更新视图在顶级布局中的位置
					wm.updateViewLayout(view, params);
					x=event.getRawX();
					y=event.getRawY();
					break;
				case MotionEvent.ACTION_UP:// 提起
					x=event.getRawX();
					y=event.getRawY();
					break;

				}

				return true;// 处理了事件
			}
		};
		view.setOnTouchListener(listener);//添加事件</span>



params.x+=offx;

params.y+=offy;

//

if(params.x<=0)

{

params.x=0;

}

if(params.y<=0)

{

params.y=0;

}

if(params.x>=(SCREE_WIDHT-view.getWidth()))

{

params.x=(SCREE_WIDHT-view.getWidth());

}

if(params.y>=(SCREE_HEIGHT-view.getHeight()))

{

params.y=(SCREE_HEIGHT-view.getHeight());

}

WindowManager:添加的视图对象一定要注册移除。。

(6) 查询数据库

1.1. 归属地显示风格设置

修改  背景图片。

① 提供素材

② 设置中心添加 设置选项

③ 写点击事件

④ 弹出对话框 

⑤ 选择:保存 下标SP-->对应一张图片

<span style="font-size:14px;">private String[] items=new String[]{"半透明","橙","蓝","灰","绿"};
	@OnClick(R.id.set_address_style)
	public void set_address_style(View view)
	{
		
//		① 提供素材
//		② 设置中心添加 设置选项
//		③ 写点击事件
//		④ 弹出对话框 
//		AlertDialog.Builder//对话框快速创建 器
//		AlertDialog.Builder  builder=new AlertDialog.Builder(this);
		AlertDialog.Builder  builder=new AlertDialog.Builder(SetCenterActivity.this);
		
		builder.setTitle("归属地提示框风格");
		int which=SharedPreferencesUtils.getInt(this, "set_address_style", 0);
		//显示时选中 第几个项
		builder.setSingleChoiceItems(items, which, new AlertDialog.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				SharedPreferencesUtils.saveInt(getBaseContext(), "set_address_style",which);
				
				//更新显示值 绿
				set_address_style.getDesc().setText(items[which]);
				
				dialog.dismiss();
				
			}
		});
		builder.setNegativeButton("取消", null);
		AlertDialog dialog=builder.create();
//		⑤ 选择:保存 下标SP-->对应一张图片
		dialog.show();
	}
注意回显
	//更新显示值 绿
		int which=SharedPreferencesUtils.getInt(this, "set_address_style", 0);
		set_address_style.getDesc().setText(items[which]);</span>

1.2 归属地显示的位置

1.创建Activity

2.添加移动事件

3.退出页面 时保存

4. 使用保存的x,y

5.根据拖动的位置 显示  按钮

<span style="font-size:14px;">public class DragViewActivity extends Activity {

	private int SCREEN_WIDTH;
	private int SCREEN_HEGHT;
	RelativeLayout view_adress_show;

	private TextView top;
	private TextView bottom;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_drag_view);
		top = (TextView) findViewById(R.id.top);
		bottom = (TextView) findViewById(R.id.bottom);

		// 获取WindowManager
		WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		view_adress_show = (RelativeLayout) findViewById(R.id.view_adress_show);
		Display display = wm.getDefaultDisplay();
		SCREEN_WIDTH = display.getWidth();
		SCREEN_HEGHT = display.getHeight();

		// 1.创建Activity
		// 2.添加移动事件

		// left top 120
		// android:layout_marginLeft="120dp"
		// android:layout_marginTop="120dp"
		RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) view_adress_show.getLayoutParams();
		int x = SharedPreferencesUtils.getInt(this, "x", 0);
		int y = SharedPreferencesUtils.getInt(this, "y", 0);
		p.leftMargin = x;
		p.topMargin = y;

		// 以外
		if (p.topMargin <= SCREEN_HEGHT / 3) {
			top.setVisibility(View.INVISIBLE);
			bottom.setVisibility(View.VISIBLE);
		} else if (p.topMargin >= SCREEN_HEGHT * 2 / 3) {
			top.setVisibility(View.VISIBLE);
			bottom.setVisibility(View.INVISIBLE);
		}
		// view_adress_show.setLayoutParams(p);//方式一
		view_adress_show.requestLayout();// 方式二
		// OnTouchListener:监听拖动
		OnTouchListener listener = new OnTouchListener() {

			private float x = 0;
			private float y = 0;

			// 监听 触摸
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:// 按下
					x = event.getRawX();
					y = event.getRawY();
					break;
				case MotionEvent.ACTION_MOVE:// 移动
					float newx = event.getRawX();
					float newy = event.getRawY();

					// 偏移量
					float offx = newx - x;
					float offy = newy - y;
					RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) view_adress_show.getLayoutParams();
					p.leftMargin += offx;
					p.topMargin += offy;

					final int leftMarginMax = SCREEN_WIDTH - view_adress_show.getWidth();
					final int topMarginMax = SCREEN_HEGHT - view_adress_show.getHeight();
					Log.i("wzx", "leftMarginMax=" + leftMarginMax);
					Log.i("wzx", "topMarginMax=" + topMarginMax);

					// 处理越界
					if (p.leftMargin <= 0) {
						p.leftMargin = 0;
					}

					if (p.leftMargin >= leftMarginMax) {
						p.leftMargin = leftMarginMax;
					}

					if (p.topMargin <= 0) {
						p.topMargin = 0;
					}

					if (p.topMargin >= topMarginMax) {
						p.topMargin = topMarginMax;
					}

					// 以外
					if (p.topMargin <= SCREEN_HEGHT / 3) {
						top.setVisibility(View.INVISIBLE);
						bottom.setVisibility(View.VISIBLE);
					} else if (p.topMargin >= SCREEN_HEGHT * 2 / 3) {
						top.setVisibility(View.VISIBLE);
						bottom.setVisibility(View.INVISIBLE);
					}

					// 请求刷新
					view_adress_show.requestLayout();
					//
					x = event.getRawX();
					y = event.getRawY();
					break;
				case MotionEvent.ACTION_UP:// 提起
					x = event.getRawX();
					y = event.getRawY();
					break;
				}

				return true;
			}
		};
		view_adress_show.setOnTouchListener(listener);
		// 3.退出页面 时保存
		// 4. 使用保存的x,y
		// 5.根据拖动的位置 显示 按钮
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) view_adress_show.getLayoutParams();
		// p.leftMargin
		// p.topMargin ;
		SharedPreferencesUtils.saveInt(this, "x", p.leftMargin);
		SharedPreferencesUtils.saveInt(this, "y", p.topMargin);

	}

}</span>


1. 趣味小火箭

开发步骤

① 素材  (apk解压缩获取)

② 创建Service:运行于后台,没有界面,隐蔽程序(a.继承b.重写c.配置,d启动)

③ 通过WindowManager添加视图(小火箭+发射台)顶级布局。

④ 动画  帧动画。(帧动画(包含素材)+补间动画(旋转 透明度 移动 缩放))

帧动画:创建Animation-list 添加素材  设置时间 让素材快速播放。

⑤ OnTouchListener+修改坐标布局参数对象LayoutParams x ,y

⑥ 火箭移动画。Thread+Handler 

⑦ 创建Activity显示云  Activity的透明效果

1. 趣味题:两次点击退出

① 返回的监听

② 保存两次点击的时间值 

③ 时间间隔小于等于2000

④  在主页面进行finish

<span style="font-size:14px;">/ 回调:由开发者重写的方法 但是 由系统去调用。 以on开头,注意:调用条件
	// keyCode 键的id
	private long[] twotimes = new long[2];
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// return true 处理事件 消费事件 不要系统处理
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			// 往前移动时间
			twotimes[0] = twotimes[1];
			twotimes[1] = System.currentTimeMillis();
			Log.i("wzx", Arrays.toString(twotimes));
			// ① 返回的监听
			// ② 保存两次点击的时间值
			// ③ 时间间隔小于等于2000
			if (twotimes[1] - twotimes[0] <= 2000) {
				// ④  在主页面进行finish
				finish();
			} else {
				Toast.makeText(getBaseContext(), "点击两次退出", 0).show();
			}
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

SystemClock.uptimeMillis()	开机时间为0
System.currentMillions	以格林尼治时间准备开始

	long[] arrays = new long[] { 1, 2, 3, 4, 5, 6 };
	public void arraycopy(View view) {

		Log.i("wzx", Arrays.toString(arrays));
		// System.arraycopy(源数组, 源数组开始复制的位置, 目标数组, 目标数组的开始复制位置, 个数);
		System.arraycopy(arrays, 0, arrays, 3, 3);
		Log.i("wzx", "复制后" + Arrays.toString(arrays));
	}</span>

SystemClock.uptimeMillis()

开机时间为0

System.currentMillions

以格林尼治时间准备开始
























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值