百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

挖穿Android第三十七天

bigegpt 2024-08-27 11:56 2 浏览

1、为什么需要广播接收

[1]什么样的人群听广播:老年人 出租车 大学生
[2]听广播的前提:必须有电台
[3]android系统相当于一个电台
[4]broadcastReceiver Android提供的接收广播的组件 这个组件存在的目地 就是方便开发

广播接收者案例_ip拨号器

 第一个版本:
Receiver:
 // [1]获取当前的电话号码
 String currentData = getResultData();
 // [2]判断当前的电话号码是否是以0开头 如果是在现有电话号码前面加上17951
 if (currentData.startsWith("0")) {
 // [3]给现有电话号码加上17951
 setResultData("17951" + currentData);
 }
Manifest:
 <!-- 添加接收电话广播的权限 -->
 <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
 <receiver android:name="com.chuanzhi.ip.OutGoingCallReceiver" >
 <!-- 配置当前广播接收者 接收哪个广播 -->
 <intent-filter>
 <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
 </intent-filter>
 </receiver>
第二个版本
点击事件代码:
 // [1]获取EditText控件上面的ip号
 String ip = et_ip.getText().toString();
 // [2]把IP号保存起来
 SharedPreferences sp = getSharedPreferences("ip", MODE_PRIVATE);
 Editor edit = sp.edit();
 edit.putString("ip", ip);
 edit.commit();
Receiver:
 // [1]获取当前的电话号码
 String currentData = getResultData();
 // [2]判断当前的电话号码是否是以0开头 如果是在现有电话号码前面加上17951
 if (currentData.startsWith("0")) {
 //[3]从缓存中读取保存的IP号
 SharedPreferences sp = context.getSharedPreferences("ip", Context.MODE_PRIVATE);
 String ip = sp.getString("ip", "");
 // [4]给现有电话号码加上Ip号
 setResultData(ip+ currentData);
 } 

监听sd卡状态

Receiver:
@Override
public void onReceive(Context context, Intent intent) {
 // [1]获取接收广播的Action
 String action = intent.getAction();
 // [2]根据接收到的Action进行判断
 if ("android.intent.action.MEDIA_UNMOUNTED".equals(action)) {
 System.out.println("sd卡卸载了");
 } else if ("android.intent.action.MEDIA_MOUNTED".equals(action)) {
 System.out.println("sd卡挂载了");
 }
}
Manifest
<receiver android:name="com.chuanzhi.sd.SdcardReceiver" >
 <intent-filter>
 <!-- sd卡挂载 -->
 <action android:name="android.intent.action.MEDIA_MOUNTED" />
 <!-- sd卡卸载 -->
 <action android:name="android.intent.action.MEDIA_UNMOUNTED" />
 <!-- 如果是监听sd卡需要添加数据类型 -->
 <data android:scheme="file" />
 </intent-filter>
</receiver> 

广播接收者案例_短信监听器

低版本的ADT可以找到这个action。
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
广播接收者的特点:只要应用注册了广播 不管什么时候,只要接收到到相应的事件,当前广播都会启动
为什么要这样设计:为了开发者方便开发
注意广播的问题:
 [1]4.0以前
 广播不需要应用第一次启动有界面,就可以接收广播,并且在应用管理里面强行停止应用,也能够接收到广播
 [2]4.0以后
 [2.1]如果应用里面有广播,google要求你的程序第一次启动的时候必须有界面,否则广播是无法启动的
 [2.2]如果在应用管理了强行停止应用,广播也会停止不会接收广播了
Manifest:
 <uses-permission android:name="android.permission.RECEIVE_SMS"/>
 <receiver android:name="com.chuanzhi.sms.SmsReceiver" >
 <!-- 注意这个Action在高版本的ADT当中没有提示了,但是代码里面还有 -->
 <intent-filter>
 <action android:name="android.provider.Telephony.SMS_RECEIVED" />
 </intent-filter>
 </receiver>
Receiver:
 // 收听短信的广播
 @Override
 public void onReceive(Context context, Intent intent) {
 //[1]通过获取puds的方式获取短信的内容
 Object[] object = (Object[]) intent.getExtras().get("pdus");
 //[2]遍历puds里面的内容
 for (Object obj : object) {
 //[3]通过SmsMessage对象将puds信息转成一个Message对象
 SmsMessage msg = SmsMessage.createFromPdu((byte[]) obj);
 //[4]获取message里面的内容
 String msgBody = msg.getMessageBody();
 //[5]获取message里面发送的电话号码
 String address = msg.getOriginatingAddress();
 //[6]输出电话号码和内容
 System.out.println("address = " + address + " body = " + msgBody);
 }
 }

广播接收者案例_卸载安装

Receiver:
 @Override
 public void onReceive(Context context, Intent intent) {
 // [1]获取广播的Action
 String action = intent.getAction();
 // [2]判断接收广播的Action
 if ("android.intent.action.PACKAGE_INSTALL".equals(action)) {
 System.out.println("install");
 } else if ("android.intent.action.PACKAGE_REMOVED".equals(action)) {
 System.out.println("remove");
 } else if ("android.intent.action.PACKAGE_ADDED".equals(action)) {
 System.out.println("add");
 }
 }
Manifest:
 <receiver android:name="com.chuanzhi.pack.PackReceiver" >
 <intent-filter>
 <action android:name="android.intent.action.PACKAGE_INSTALL" />
 <action android:name="android.intent.action.PACKAGE_REMOVED" />
 <action android:name="android.intent.action.PACKAGE_ADDED" />
 <!-- 如果要监听应用安装和卸载必须添加以下约束 -->
 <data android:scheme="package" />
 </intent-filter>
 </receiver> 

广播接收者案例_开机启动

 Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
activity是由任务栈来维护,在广播里面没有任务栈的环境,所以不能够在广播里面开启Activity.所有要指定任务栈的环境
Receiver:
 @Override
 public void onReceive(Context context, Intent intent) {
 // [1]创建一个开始Activity的意图
 Intent intent2 = new Intent(context, MainActivity.class);
 // [2]设置开启一个新的任务栈的标记
 intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 // [3]开启这个Activity
 context.startActivity(intent2);
 } 
Manifest:
 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 <receiver android:name="com.chuanzhi.boot.BootReceiver" >
 <intent-filter>
 <action android:name="android.intent.action.BOOT_COMPLETED" />
 </intent-filter>
 </receiver>

应用场景:开机要钱

屏幕Activity关闭键
@Override
public void onBackPressed() {
 //super.onBackPressed();
}

有序广播和无序广播

无序广播:
 [1]发送方
 MainActivity:
 // [2]创建一个意图对象
 Intent intent = new Intent();
 // [3]设置广播的内容
 intent.putExtra("content", "xxxx正在修路");
 // [4]设置广播的Action
 intent.setAction("com.chuanzhi.broadcast");
 // [1]发送一个无序的广播
 sendBroadcast(intent);
 [2]接收方
 Manifest:
 <receiver android:name="com.chuanzhi.custom.CustomBroadCastReceiver" >
 <intent-filter>
 <!-- 接收自定义广播的Action -->
 <action android:name="com.chuanzhi.broadcast" />
 </intent-filter>
 </receiver>
 CustomBroadCastReceiver:
 // [1]获取广播里面的内容
 String content = intent.getStringExtra("content");
 // [2]利用Toast显示广播的内容
 Toast.makeText(context, content, 0).show();
有序广播:
 发送方:
 MainActivity:
 // [2]准备一个Intent的对象
 Intent intent = new Intent();
 // [2]给这个Intent设置一个acton
 intent.setAction("com.chuanzhi.order");
 // [1]发送一个有序的广播
 // 参数1:意图对象
 // 参数2:接收这个广播的权限
 // 参数3:自己定义一个最后的接收者
 // 参数4:初始化一个int类型的标记
 // 参数5:广播的内容
 // 参数6:额外的数据
 sendOrderedBroadcast(intent, null, new FinalReceiver(), null, 1,"国家给农民工兄弟每人发10000块钱", null);
 最后一个接收者 
 //获取数据
 String resultData = getResultData();
 Toast.makeText(context, resultData, 1).show();
 接收方:
 ManiFest:
 <!-- 有序广播需要给广播指定优先级 使用priority指定优先级 google规定这个值的范围是-1000~1000 -->
 <receiver android:name="com.chuanzhi.rcorder.ShengReceiver" >
 <intent-filter android:priority="1000" >
 <action android:name="com.chuanzhi.order" />
 </intent-filter>
 </receiver>
 <receiver android:name="com.chuanzhi.rcorder.ShiReceiver" >
 <intent-filter android:priority="500" >
 <action android:name="com.chuanzhi.order" />
 </intent-filter>
 </receiver>
 <receiver android:name="com.chuanzhi.rcorder.NongMinReceiver" >
 <intent-filter android:priority="0" >
 <action android:name="com.chuanzhi.order" />
 </intent-filter>
 </receiver>
 receiver:
 // 接收广播的数据
 String resultData = getResultData();
 // 中断广播
 abortBroadcast();
 // 修改广播的数据
 setResultData("国家给农民工发1000块钱");
 // 显示广播内容
 Toast.makeText(context, "省长:" + resultData, 1).show();
区别:有序广播,可以被中止,数据可以被修改.
 无序广播,不可以被中止,数据不可以被修改.

特殊广播接收者

操作特别频繁的广播事件.这种广播事件在清单文件注册无效
例如:锁屏、电池电量更新
MainActivity:
 // [2]创建一个广播接收者对象
 ScreenReceiver screenReceiver = new ScreenReceiver();
 // [3]创建一个IntentFilter对象
 IntentFilter filter = new IntentFilter();
 // [3]IntentFilter添加屏幕锁住Action
 filter.addAction("android.intent.action.SCREEN_OFF");
 // [4]IntentFilter添加屏幕解锁Action
 filter.addAction("android.intent.action.SCREEN_ON");
 // [1]动态的注册一个广播接收者
 registerReceiver(screenReceiver, filter);
ScreenReceiver:
 // [1]获取接收的action
 String action = intent.getAction();
 if ("android.intent.action.SCREEN_OFF".equals(action)) {
 System.out.println("屏幕锁了");
 } else if ("android.intent.action.SCREEN_ON".equals(action)) {
 System.out.println("屏幕解锁");
 }
错误:
 Activity com.chuanzhi.other.MainActivity has leaked IntentReceiver com.chuanzhi.other.ScreenReceiver@b41eb1e0 that was originally registered here. Are you missing a call to unregisterReceiver()?
 需要在Activity中销毁这个广播接收者
 @Override
 protected void onDestroy() {
 super.onDestroy();
 // [5]销毁广播接收者
 unregisterReceiver(screenReceiver);
 }

样式和主题

[1]定义样式和主题的方式是一样的
style:
 <style name="tv">
 <item name="android:layout_width">wrap_content</item>
 <item name="android:layout_height">wrap_content</item>
 <item name="android:textColor">#AA00FF</item>
 <item name="android:textSize">24sp</item>
 </style>
theme:
 <style name="mytheme">
 <item name="android:background">#AA00CC</item>
 </style>

国际化 I18N

values-国家简写字母
主要对字符串进行国际化

常见的对话框

[1]普通对话框
 // [1]创建一个Dialog Builder对象
 Builder builder = new AlertDialog.Builder(this);
 // [2]设置Dialog标题
 builder.setTitle("警告");
 // [3]设置Dialog内容
 builder.setMessage("你的手机有病毒需要升级!");
 // [4]设置Dialog确定按钮并且添加点击事件
 builder.setPositiveButton("确定", new OnClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which) {
 Toast.makeText(MainActivity.this, "正在升级", 1).show();
 }
 });
 // [5]设置Dialog取消按钮并且添加点击事件
 builder.setNegativeButton("取消", new OnClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which) {
 Toast.makeText(MainActivity.this, "在不升级手机就要报废了", 0).show();
 }
 });
 // [6]显示这个Dialog
 builder.show();
[2]单选对话框
 // [1]创建一个Dialog Builder对象
 Builder builder = new AlertDialog.Builder(this);
 // [2]设置Dialog标题
 builder.setTitle("请选择你喜欢的课程!");
 // [3.1]单选Dialog里面的数据
 final String[] items = { "Android", "IOS", "JavaEE", "c++" };
 // [3]设置单选Dialog
 // 参数1:单选数据
 // 参数2:指定哪个单选被选中,如果不想指定就使用-1
 // 参数3:给这个Dialog添加点击事件
 builder.setSingleChoiceItems(items, -1, new OnClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which) {
 // [4]获取用户选择的选项
 Toast.makeText(MainActivity.this, items[which], 0).show();
 // [5]关闭当前Dialog
 dialog.dismiss();
 }
 });
 // [6]显示这个Dialog
 builder.show();
[3]多选对话框
 // [1]创建一个Dialog Builder对象
 Builder builder = new AlertDialog.Builder(this);
 // [2]设置Dialog标题
 builder.setTitle("选择你喜欢吃的水果");
 // [3.1]多选框数据
 final String[] items = { "苹果", "黄瓜", "火龙果", "哈密瓜" };
 // [3.2]多选框数据的状态
 final boolean[] checkedItems = { false, false, true, false };
 // [3]设置一个多选的Dialog
 // 参数1:多选框数据
 // 参数2:多选框里面的数据是否被选中
 // 参数3:多选框监听
 builder.setMultiChoiceItems(items, checkedItems,new OnMultiChoiceClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which,boolean isChecked) {
 }
 });
 // [4]点击确定把选听数据取出来
 builder.setPositiveButton("确定", new OnClickListener() {
 @Override
 public void onClick(DialogInterface dialog, int which) {
 // [5]创建一个StringBuffer存储数据
 StringBuffer sb = new StringBuffer();
 // [6]循环数据 并且把每个数据的状态取出来
 for (int i = 0; i < items.length; i++) {
 //[7]如果数据的状态是true 那么就把数据取出来存入到StringBuffer当中
 if (checkedItems[i]) {
 sb.append(items[i] + " ~~ ");
 }
 }
 // [7]显示数据
 Toast.makeText(MainActivity.this, sb.toString(), 1).show();
 }
 });
 // [8]显示Dialog
 builder.show();
[4]进度条对话框
 //[1]创建一个ProgressDialog对象
 final ProgressDialog dialog = new ProgressDialog(this);
 //[2]设置一个Dialog的内容 如果不指定Dialog的样式 默认是一个转圈的Dialog
 dialog.setMessage("玩命加载中.....");
 //[2.1]设置一个水平的进度条
 dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
 //[3]让Dialog显示
 dialog.show();
 //[3.1]开启一个子线程更新Dialog的进度
 new Thread(){public void run() {
 //[4]设置Dialog的最大值
 dialog.setMax(100);
 for (int i = 0; i < 100; i++) {
 //[5]睡1秒执行一次循环
 SystemClock.sleep(1000);
 //[6]设置Dialog当前的进度
 dialog.setProgress(i);
 }
 };}.start();

android的动画

[1]属性动画
[2]补间动画
[3]帧动画 
 1)在res/drawable 文件夹创建xml文件,代码如下
 <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
 android:oneshot="false" >
 <!-- oneshot:true代表循环一次, false代表无限循环 -->
 <!-- duration:代表执行的时长 -->
 <item android:drawable="@drawable/girl_1" android:duration="200"/>
 <item android:drawable="@drawable/girl_2" android:duration="200"/>
 <item android:drawable="@drawable/girl_3" android:duration="200"/>
 <item android:drawable="@drawable/girl_4" android:duration="200"/>
 <item android:drawable="@drawable/girl_5" android:duration="200"/>
 <item android:drawable="@drawable/girl_6" android:duration="200"/>
 <item android:drawable="@drawable/girl_7" android:duration="200"/>
 <item android:drawable="@drawable/girl_8" android:duration="200"/>
 <item android:drawable="@drawable/girl_9" android:duration="200"/>
 <item android:drawable="@drawable/girl_10" android:duration="200"/>
 <item android:drawable="@drawable/girl_11" android:duration="200"/>
 </animation-list>
 2)在代码中开启动画
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 // [1]初始化ImageView控件
 ImageView img = (ImageView) findViewById(R.id.img);
 // [2]给ImageView设置背景资源,当前资源是一个帧动画
 img.setBackgroundResource(R.drawable.frame_gif);
 // [3]获取ImageView的背景资源对象,因为当前是帧动画资源,所以要转成AnimatonDrawable对象
 AnimationDrawable background = (AnimationDrawable) img.getBackground();
 // [4]开启帧动画
 background.start();
 }

相关推荐

10w qps缓存数据库——Redis(redis缓存调优)

一、Redis数据库介绍:Redis:非关系型缓存数据库nosql:非关系型数据库没有表,没有表与表之间的关系,更不存在外键存储数据的形式为key:values的形式c语言写的服务(监听端口),用来存...

Redis系列专题4--Redis配置参数详解

本文基于windowsX64,3.2.100版本讲解,不同版本默认配置参数不同在Redis中,Redis的根目录中有一个配置文件(redis.conf,windows下为redis.windows....

开源一夏 | 23 张图,4500 字从入门到精通解释 Redis

redis是目前出场率最高的NoSQL数据库,同时也是一个开源的数据结构存储系统,在缓存、数据库、消息处理等场景使用的非常多,本文瑞哥就带着大家用一篇文章入门这个强大的开源数据库——Redis。...

redis的简单与集群搭建(redis建立集群)

Redis是什么?是开源免费用c语言编写的单线程高性能的(key-value形式)内存数据库,基于内存运行并支持持久化的nosql数据库作用主要用来做缓存,单不仅仅是做缓存,比如:redis的计数器生...

推荐几个好用Redis图形化客户端工具

RedisPlushttps://gitee.com/MaxBill/RedisPlusRedisPlus是为Redis可视化管理开发的一款开源免费的桌面客户端软件,支持Windows、Linux...

关于Redis在windows上运行及fork函数问题

Redis在将数据库进行持久化操作时,需要fork一个进程,但是windows并不支持fork,导致在持久化操作期间,Redis必须阻塞所有的客户端直至持久化操作完成。微软的一些工程师花费时间在解决在...

你必须懂的Redis十大应用场景(redis常见应用场景)

Redis作为一款高性能的键值存储数据库,在互联网业务中有着广泛的应用。今天,我们就来详细盘点一下Redis的十大常用业务场景,并附上Golang的示例代码和简图,帮助大家更好地理解和应用Redis。...

极简Redis配置(redis的配置)

一、概述Redis的配置文件位于Redis安装目录下,文件名为redis.conf(Windows名为redis.windows.conf,linux下的是redis.conf)你可以通过C...

什么是redis,怎么启动及如何压测

从今天起咱们一起来学习一下关于“redis监控与调优”的内容。一、Redis介绍Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。...

一款全新Redis UI可视化管理工具,支持WebUI和桌面——P3X Redis UI

介绍P3XRedisUI这是一个非常实用的RedisGUI,提供响应式WebUI访问或作为桌面应用程序使用,桌面端是跨平台的,而且完美支持中文界面。Githubhttps://github....

windows系统的服务器快速部署java项目环境地址

1、mysql:https://dev.mysql.com/downloads/mysql/(msi安装包)2、redis:https://github.com/tporadowski/redis/r...

window11 下 redis 下载与安装(windows安装redis客户端)

#热爱编程是一种怎样的体验#window11下redis下载与安装1)各个版本redis下载(windows)https://github.com/MicrosoftArchive/r...

一款轻量级的Redis客户端工具,贼好用!

使用命令行来操作Redis是一件非常麻烦的事情,我们一般会选用客户端工具来操作Redis。今天给大家分享一款好用的Redis客户端工具TinyRDM,它的界面清新又优雅,希望对大家有所帮助!简介Ti...

一个.NET开发且功能强大的Windows远程控制系统

我们致力于探索、分享和推荐最新的实用技术栈、开源项目、框架和实用工具。每天都有新鲜的开源资讯等待你的发现!项目介绍SiMayRemoteMonitorOS是一个基于Windows的远程控制系统,完...

Redis客户端工具详解(4款主流工具)

大家好,我是mikechen。Redis是大型架构的基石,也是大厂最爱考察内容,今天就给大家重点详解4款Redis工具@mikechen本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集...