day07

1    为什么需要广播接收
    [1]有什么样的人员听广播
    [2]想听广播必须有电台
    [3]Android系统内部已经定义好了电台    已经定义好了一些广播事件    比如 外拨电话 短信到来 sd卡状态  电池电量....
    [4]使用broadcastReceiver去接收系统已经定义好的这些事件
    [5]定义广播接收者的目的是为了方便开发者进行开发
  
2    广播接收者案例-ip拨号器    17951 024-8856789
    [1]定义广播接收者
    
     [2]在清单文件里配置
     [3]具体调到某一个合适的频道
     [4]记得加权限
 
3    广播接收者案例-sd卡状态监听
    [1]定义广播接收者
  1. package com.phone.sdcardstatusspy;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. public class SdcardStateReceiver extends BroadcastReceiver {
  6. //当sd状态发送改变的时候执行
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. //获取当前广播的事件类型
  10. String action = intent.getAction();
  11. if("android.intent.action.MEDIA_MOUNTED".equals(action)){
  12. System.out.print("说明SD卡挂载了...");
  13. }else if("android.intent.action.MEDIA_UNMOUNTED".equals(action)){
  14. System.out.print("说明SD卡卸载了...");
  15. }
  16. }
  17. }
    [2]在清单文件里配置
  1. <receiver android:name="com.phone.sdcardstatusspy.SdcardStateReceiver">
  2. <intent-filter >
  3. <action android:name="android.intent.action.MEDIA_MOUNTED"/>
  4. <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
  5. <!-- 小细节 这里需要配置一个data 约束类型叫file 因为sd里面存的数据类型是file -->
  6. <data android:scheme="file"/>
  7. </intent-filter>
  8. </receiver>


4    广播接收者案例-短信监听器
[1]定义广播接收者
  1. package com.phone.smslistener;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.telephony.SmsMessage;
  6. public class SmsListenerReceiver extends BroadcastReceiver {
  7. //当短信到来时执行
  8. @Override
  9. public void onReceive(Context context, Intent intent) {
  10. //获取发送者的号码和发送内容
  11. Object[] objects = (Object[]) intent.getExtras().get("pdus");
  12. for(Object obj : objects){
  13. //[1]获取smsmessage实例
  14. SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);
  15. //[2]获取发送短信的内容
  16. String messageBody = smsMessage.getMessageBody();
  17. String address = smsMessage.getOriginatingAddress();
  18. System.out.println("body:"+messageBody+"-----"+address);
  19. }
  20. }
  21. }

[2]在清单文件里配置
  1. <receiver android:name="com.phone.smslistener.SmsListenerReceiver">
  2. <intent-filter >
  3. <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
  4. </intent-filter>
  5. </receiver>
[3]加权限
  1. <uses-permission android:name="android.permission.RECEIVE_SMS"/>


5    不同版本广播的特点
   [1]在4.0    谷歌工程师要求    第一次安装应用的时候必须的有界面    这样广播接收者才生效
   [2]在设置页面有一个强行停止的按钮    如果说用户点击了    强行停止按钮那么广播接收者也不生效
   [3]在2.3的手机上没有这样的安全设计


6    广播接收者案例-卸载安装
[1]定义广播接收者
  1. package com.phone.appstate;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. public class AppStateReceiver extends BroadcastReceiver {
  6. //当有新的应用被安装了 或者有应用被卸载了 这个方法被调用
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. //获取当前广播的事件类型
  10. String action = intent.getAction();
  11. if("android.intent.action.PACKAGE_INSTALL".equals(action)){
  12. System.out.println("应用安装了1111");
  13. }else if("android.intent.action.PACKAGE_REMOVED".equals(action)){
  14. System.out.println("应用卸载了");
  15. }else if("android.intent.action.PACKAGE_ADDED".equals(action)){
  16. System.out.println("应用安装了2222");
  17. }
  18. }
  19. }


[2]在清单文件里配置
  1. <receiver android:name="com.phone.appstate.AppStateReceiver">
  2. <intent-filter >
  3. <action android:name="android.intent.action.PACKAGE_INSTALL"/>
  4. <action android:name="android.intent.action.PACKAGE_REMOVED"/>
  5. <action android:name="android.intent.action.PACKAGE_ADDED"/>
  6. <!-- 小细节 需要配置一个data -->
  7. <data android:scheme="package"/>
  8. </intent-filter>
  9. </receiver>

7    广播接收者案例-开机启动
注意:不能直接在广播接收者中开启activity
[1]定义广播接收者
  1. package com.phone.reboot;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. public class BootReceiver extends BroadcastReceiver {
  6. //当手机重新启动时调用
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. //在这个方法里面开启activity
  10. Intent intent2 = new Intent(context,MainActivity.class);
  11. //★★★★★★★注意不能在广播接收者里面开启activity 需要添加一个标记 添加一个任务栈的标记
  12. intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  13. //开启activity
  14. context.startActivity(intent2);
  15. }
  16. }
[2]在清单文件里配置
  1. <receiver android:name="com.phone.reboot.BootReceiver">
  2. <intent-filter >
  3. <action android:name="android.intent.action.BOOT_COMPLETED"/>
  4. </intent-filter>
  5. </receiver>

[3]加权限
  1. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

8    有序广播和无序广播
   [1]有序广播    类似中央发送红头文件    按照一定的优先级接收
<1>发送有序广播
  1. //点击按钮 发送有序广播 发大米
  2. public void click(View v){
  3. Intent intent = new Intent();
  4. intent.setAction("com.phone.sendrice");
  5. /**
  6. * intent 意图
  7. * receiverPermission 接收的权限
  8. * resultReceiver 最终的receiver
  9. * scheduler handler
  10. * initialCode 初始码
  11. * initialData 初始化数据
  12. * initialExtras 发送数据
  13. */
  14. sendOrderedBroadcast(intent, null, new FinalReceiver(), null, 1, "习总给每个村民发了1000斤大米", null);
  15. }
<2>接收有序广播
  1. package com.phone.receiverice;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.widget.Toast;
  6. public class ProvinceReceiver extends BroadcastReceiver {
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. //[1]获取发送广播携带的数据
  10. String content = getResultData();
  11. //[2]显示结果
  12. Toast.makeText(context, "省"+content, 1).show();
  13. //终止广播
  14. //abortBroadcast();
  15. //[3]修改数据
  16. setResultData("习总给每个村民发了500斤大米");
  17. }
  18. }
  1. package com.phone.receiverice;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.widget.Toast;
  6. public class CityReceiver extends BroadcastReceiver {
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. // [1]获取发送广播携带的数据
  10. String content = getResultData();
  11. // [2]显示结果
  12. Toast.makeText(context, "市" + content, 1).show();
  13. //[3]修改数据
  14. setResultData("习总给每个村民发了250斤大米");
  15. }
  16. }
  1. package com.phone.receiverice;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.widget.Toast;
  6. public class CountryReceiver extends BroadcastReceiver {
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. // [1]获取发送广播携带的数据
  10. String content = getResultData();
  11. // [2]显示结果
  12. Toast.makeText(context, "乡" + content, 1).show();
  13. //[3]修改数据
  14. setResultData("习总给每个村民发了125斤大米");
  15. }
  16. }
  1. package com.phone.receiverice;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.widget.Toast;
  6. public class FarmerReceiver extends BroadcastReceiver {
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. // [1]获取发送广播携带的数据
  10. String content = getResultData();
  11. // [2]显示结果
  12. Toast.makeText(context, "农民" + content, 1).show();
  13. }
  14. }
<3>配置清单文件
  1. <!-- 配置省长receiver 优先级最高 -->
  2. <receiver android:name="com.phone.receiverice.ProvinceReceiver">
  3. <intent-filter android:priority="1000">
  4. <action android:name="com.phone.sendrice"/>
  5. </intent-filter>
  6. </receiver>
  7. <!-- 配置市长receiver 优先级最高 -->
  8. <receiver android:name="com.phone.receiverice.CityReceiver">
  9. <intent-filter android:priority="100">
  10. <action android:name="com.phone.sendrice"/>
  11. </intent-filter>
  12. </receiver>
  13. <!-- 配置乡长receiver 优先级最高 -->
  14. <receiver android:name="com.phone.receiverice.CountryReceiver">
  15. <intent-filter android:priority="10">
  16. <action android:name="com.phone.sendrice"/>
  17. </intent-filter>
  18. </receiver>
  19. <!-- 配置农民receiver 优先级最高 -->
  20. <receiver android:name="com.phone.receiverice.FarmerReceiver">
  21. <intent-filter android:priority="1">
  22. <action android:name="com.phone.sendrice"/>
  23. </intent-filter>
  24. </receiver>


   [2]无序广播    比如新闻联播    每天晚上7点准时开播
  1. //点击按钮 发送一条无序广播
  2. public void click(View v){
  3. Intent intent = new Intent();
  4. intent.setAction("com.phone.custom");
  5. intent.putExtra("name", "新闻联播每天晚上7点准时开播");
  6. //发送无序广播
  7. sendBroadcast(intent);
  8. }
  1. package com.phone.getchaos;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.widget.Toast;
  6. public class ReceiveCustomReceiver extends BroadcastReceiver {
  7. //当接收到我们发送的自定义广播
  8. @Override
  9. public void onReceive(Context context, Intent intent) {
  10. //[1]获取接收发送的数据
  11. String content = intent.getStringExtra("name");
  12. //[2]展示内容
  13. Toast.makeText(context, content, 1).show();
  14. }
  15. }


总结:  (1)有序广播可以被终止
            (2)有序广播的数据可以被修改
            (3)无序广播不可以被终止
            (4)数据不可以被修改

9    特殊广播接收者 
    操作特别频繁的广播事件    比如    屏幕的锁屏和解锁    电池电量的变化    这种事件的广播在清单文件里注册是无效的
手机解锁屏:
  1. package com.phone.screen;
  2. import android.support.v7.app.ActionBarActivity;
  3. import android.content.IntentFilter;
  4. import android.os.Bundle;
  5. import android.view.Menu;
  6. import android.view.MenuItem;
  7. public class MainActivity extends ActionBarActivity {
  8. private ScreenReceiver screenReceiver;
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.activity_main);
  13. screenReceiver = new ScreenReceiver();
  14. // <receiver android:name="com.phone.screen.ScreenReceiver">
  15. // <intent-filter >
  16. // <action android:name="android.intent.action.SCREEN_OFF"/>
  17. // <action android:name="android.intent.action.SCREEN_ON"/>
  18. // </intent-filter>
  19. // </receiver>
  20. //创建IntentFilter对象
  21. IntentFilter filter = new IntentFilter();
  22. //添加要注册的action
  23. filter.addAction("android.intent.action.SCREEN_OFF");
  24. filter.addAction("android.intent.action.SCREEN_ON");
  25. registerReceiver(screenReceiver, filter);
  26. }
  27. @Override
  28. protected void onDestroy() {
  29. //当activity销毁的时候要取消广播接收者
  30. unregisterReceiver(screenReceiver);
  31. super.onDestroy();
  32. }
  33. }
  1. package com.phone.screen;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. public class ScreenReceiver extends BroadcastReceiver {
  6. //当我们进行屏幕锁屏和解锁 这个方法执行
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. //获取当前广播的事件类型
  10. String action = intent.getAction();
  11. if("android.intent.action.SCREEN_OFF".equals(action)){
  12. System.out.println("屏幕锁屏了");
  13. }else if("android.intent.action.SCREEN_ON".equals(action)){
  14. System.out.println("屏幕解屏了");
  15. }
  16. }
  17. }


    注册广播接收者的2种方式
    [1]动态注册    通过代码方式注册
    [2]在清单文件通过receiver    tag节点静态发布

10    样式和主题
    样式一般作用在控件上(button,textview等)    样式作用范围比较窄
    主题一般作用在activity或者Application结点下    样式作用范围比较宽

11    国际化(i18n)
    在res下创建不同国家语言环境集目录    目录的固定写法valuesen(或者其他,这里是每种语言的标号)

12    常见对话框
Toast
Toast.makeText(getApplicationContext(), item, 1).show();
普通对话框  
  1. public void click1(View v) {
  2. // 通过builder构建器来构造
  3. AlertDialog.Builder builder = new Builder(this);
  4. builder.setTitle("警告");
  5. builder.setMessage("世界上最遥远的距离是没有网络");
  6. builder.setPositiveButton("确定", new OnClickListener() {
  7. @Override
  8. public void onClick(DialogInterface dialog, int which) {
  9. System.out.println("点击了确定按钮");
  10. }
  11. });
  12. builder.setNegativeButton("取消", new OnClickListener() {
  13. @Override
  14. public void onClick(DialogInterface dialog, int which) {
  15. System.out.println("点击了取消按钮");
  16. }
  17. });
  18. // 最后一步一定要记得和Toast一样要show()
  19. builder.show();
  20. }

单选对话框  
  1. public void click2(View v) {
  2. // 通过builder构建器来构造
  3. AlertDialog.Builder builder = new Builder(this);
  4. builder.setTitle("请选择你喜欢的课程");
  5. final String items[] = { "Android", "IOS", "C", "C++", "HTML", "C#" };
  6. // -1表示没有条目被选中
  7. builder.setSingleChoiceItems(items, -1, new OnClickListener() {
  8. @Override
  9. public void onClick(DialogInterface dialog, int which) {
  10. // [1]把选择的条目给取出来
  11. String item = items[which];
  12. Toast.makeText(getApplicationContext(), item, 1).show();
  13. // [2]把对话框关闭
  14. dialog.dismiss();
  15. }
  16. });
  17. // 最后一步一定要记得和Toast一样要show()
  18. builder.show();
  19. }

多选对话框  
  1. public void click3(View v) {
  2. // 通过builder构建器来构造
  3. AlertDialog.Builder builder = new Builder(this);
  4. builder.setTitle("请选择你喜欢吃的水果");
  5. final String items[] = { "香蕉", "黄瓜", "哈密瓜", "西瓜", "梨", "柚子","榴莲" };
  6. final boolean[] checkedItems={true,false,false,false,false,false,true};
  7. builder.setMultiChoiceItems(items, checkedItems, new OnMultiChoiceClickListener() {
  8. @Override
  9. public void onClick(DialogInterface dialog, int which, boolean isChecked) {
  10. }
  11. });
  12. builder.setPositiveButton("确定", new OnClickListener() {
  13. @Override
  14. public void onClick(DialogInterface dialog, int which) {
  15. //把选择的条目的数据取出来
  16. StringBuffer sb = new StringBuffer();
  17. for(int i =0; i < checkedItems.length; i++){
  18. //判断一下选中
  19. if(checkedItems[i]){
  20. String fruit = items[i];
  21. sb.append(fruit + " ");
  22. }
  23. }
  24. Toast.makeText(getApplicationContext(), sb.toString(), 1).show();
  25. //关闭对话框
  26. dialog.dismiss();
  27. }
  28. });
  29. // 最后一步一定要记得和Toast一样要show()
  30. builder.show();
  31. }

进度条对话框 
  1. public void click4(View v) {
  2. final ProgressDialog dialog = new ProgressDialog(this);
  3. dialog.setTitle("正在玩命加载中...");
  4. //设置一下进度条的样式
  5. dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
  6. //最后一步一定要记得show()
  7. dialog.show();
  8. //创建一个子线程
  9. //与进度有关的,可以在子线程更新UI
  10. new Thread(){
  11. public void run(){
  12. //设置进度条的最大值
  13. dialog.setMax(100);
  14. //设置当前进度
  15. for(int i = 0; i <= 100; i++){
  16. dialog.setProgress(i);
  17. //睡眠一会
  18. SystemClock.sleep(50);
  19. }
  20. //关闭对话框
  21. dialog.dismiss();
  22. }
  23. }.start();
  24. }

13    2种上下文的区别 (在对话框的情况下用第一种)
    [1]this    最终继承Context
    [2]getApplicationContext()   返回的对象是Context


14    Android中动画
    [1]帧动画
        加载一系列的图片
       <1>在res目录下创建drawable目录,并创建xml文件和放入一系列 的图片
        
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:oneshot="false" >
  4. <item
  5. android:drawable=""
  6. android:duration="200">
  7. </item>
  8. <item
  9. android:drawable=""
  10. android:duration="200">
  11. </item>
  12. <item
  13. android:drawable=""
  14. android:duration="200">
  15. </item>
  16. <item
  17. android:drawable=""
  18. android:duration="200">
  19. </item>
  20. <item
  21. android:drawable=""
  22. android:duration="200">
  23. </item>
  24. <item
  25. android:drawable=""
  26. android:duration="200">
  27. </item>
  28. </animation-list>
        <2>设置
  1. package com.phone.drawableanimate;
  2. import android.graphics.drawable.AnimationDrawable;
  3. import android.os.Bundle;
  4. import android.os.SystemClock;
  5. import android.app.Activity;
  6. import android.widget.ImageView;
  7. public class MainActivity extends Activity {
  8. @Override
  9. protected void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. setContentView(R.layout.activity_main);
  12. //[1]找到控件
  13. final ImageView rocketImage = (ImageView) findViewById(R.id.iv);
  14. //[2]设置背景资源
  15. rocketImage.setBackgroundResource(R.drawable.my_anim);
  16. //兼容低版本的写法
  17. new Thread(){public void run() {
  18. SystemClock.sleep(20);
  19. //[3]获取AnimationDrawable类型
  20. AnimationDrawable rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
  21. //[4]开启动画
  22. rocketAnimation.start();
  23. };}.start();
  24. }
  25. }

    [2]View动画    补间动画
    [3]属性动画




只言片语任我说,提笔句句无需忖。落笔不知寄何人,唯有邀友共斟酌。
原文地址:https://www.cnblogs.com/phonecom/p/2b41576a9c8e342bc2b6020cb9fb007f.html