屏幕适配和广播
屏幕适配:
尽量用相对布局和线性布局
最好不要用相对布局
为了更好地适配我们用九图 画图
列如:480x320 和 320x240
image.png创建一个项目:
在res 下创建 文件夹 layout-480x320 和 layout-320x240
layout-480x320 下的activity_main.xml**********代码如下
···
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="@dimen/x160"
android:layout_height="wrap_content"
android:text="姓名"
android:textSize="20sp"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存"
android:background="@drawable/img1"
android:layout_gravity="center_horizontal"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/img2"
/>
</LinearLayout>
···
**********320x240**************下代码
···
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >
<TextView
android:layout_width="@dimen/x160"
android:layout_height="wrap_content"
android:text="姓名"
android:textSize="20sp"
android:background="#00ff00"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="保存"
android:background="@drawable/img1"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/img2"
/>
</LinearLayout>
···
****************效果图****************
手机屏幕分类和像素密度的对应关系:
image.png
*****点九 自动拉伸图:*****
image.png
**********最终效果图***********
image.png
一、广播接收者概念(****BroadcastReceiver****)****&****为什么需要广播接收者
1、 BroadcastReceiver用来接收sendBroadcast()方法发出来的广播,可以通过Intent传递数据,它是一个抽象类
2、广播特点:数据的传递方向是单向的,调到固定的频率
3、安卓的广播作用范围有限,只在当前手机里有效
4、系统把一些重要的操作,通过广播的形式通知给所有的应用
---------------------IP拨号器--------
广播接收器必须继承BroadcastReceiver 并添加未实现的方法。
在清单文件里注册:
···
<receiver android:name=".DiaReceiver">
<intent-filter >
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
···
需要处理外拨电话权限:
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
创建一个项目
写一个类继承BroadcastReceiver
******如**********
···
//Ip拨号器的广播接收者
public class DiaReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//获取电话号
String number = getResultData();
// Log.e("TAG", "打电话"+number);
//设置拨打电话号
setResultData("17951"+number);
}
}
···
****监听SD卡挂在状态**************
···
//监听SD卡挂载状态的广播
public class SDRecevier extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("android.intent.action.MEDIA_MOUNTED".equals(action)) {
Log.e("TAG", "SDCard已安装");
}else if("android.intent.action.MEDIA_UNMOUNTED".equals(action)){
Log.e("TAG", "SDCard已卸载");
}
}
}
···
同样也需要在清单文件里注册
···
<receiver android:name=".SDRecevier">
<intent-filter >
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
<action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
<data android:scheme="file"/>
</intent-filter>
</receiver>
···
******************效果图********
*****
***********短信监听***********
···
//短信的广播接收者
public class SMS extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Object[] object=(Object[]) intent.getExtras().get("pdus");
for (Object obj : object) {
//创建短信的消息对象
SmsMessage message=SmsMessage.createFromPdu((byte[]) obj);
//获取短信的发送 者
String from=message.getOriginatingAddress();
//获取消息的内容
String msgBody = message.getMessageBody();
Log.e("TAG", "from:"+from+"msgBody:"+msgBody);
//获取验证码
//判断from是不是自己发的‘
if ("122".equals(from)) {
//通知界面,把短信内容添加到EditText
Intent data = new Intent();
data.setAction("com.krr.getcode");
data.putExtra("code", msgBody);
context.sendBroadcast(data);//发送广播
} else {
}
}
}
}
···
在清单文件里注册---------->
···
<receiver android:name=".SMS">
<intent-filter >
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
···
接收短信的权限 :
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
*******效果图************
image.png
总结一下:
1、 IP拨号器
-
写一个类继承BroadcastReceiver,重写onReceive方法
-
清单文件中注册receiver节点,通过intent-filter指定当前广播接收者要处理的广播事件
2、 SD卡状态监听
-
需要监听挂载和卸载的action
-
SD卡状态变化的广播还需要加一个data,scheme是file,否则收不到广播
-
同一个广播接收者接收了多个广播事件,可以通过action来区分
3、 短信监听
1.需要监听的action:
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
广播接收者按例:
1.卸载安装
2.开机启动
***应用安装卸载的广播************
创建一个类
···
//应用安装卸载的广播接收器
public class AppInstall extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//获取应用的包名
Uri data=intent.getData();
if ("android.intent.action.PACKAGE_ADDED".equals(action)) {
Log.e("TAG", "install----->" +data);
} else if("android.intent.action.PACKAGE_REMOVED".equals(action)) {
Log.e("TAG", "removed---->" +data);
}
}
}
···
清单文件注册:
···
<receiver android:name=".AppInstall">
<intent-filter >
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
···
************开机*********
···
//开机启动的广播接收者
public class BootReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Log.e("TAG", "机器开机了") ;
Intent intent2 = new Intent(context,MainActivity.class);
//指定任务栈 现在是在广播接收者中创建一个Activity
//当前应用没有任何Activity运行 所以不在一个任务栈
//需要通过指定一个Flags 在创建Activity的同时创建任务栈
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent2);
}
}
···
在****MainActivity**************
···
public class MainActivity extends Activity {
EditText et_code;
BroadcastReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_code=(EditText) findViewById(R.id.et_code);
receiver=new CodeRecerive();
IntentFilter filter=new IntentFilter();
filter.addAction("com.krr.getcode");
registerReceiver(receiver, filter);
}
//屏蔽返回键
@Override
public void onBackPressed() {
}
private class CodeRecerive extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String code=intent.getStringExtra("code");
et_code.setText(code);
}
}
@Override
protected void onDestroy() {
unregisterReceiver(receiver);
}
}
···
同样在清单文件里注册:
···
<receiver android:name=".BootReceiver">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
···
接收开机广播的权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
开机广播不是点击图标打开Activtiy
这时不会创建任务栈 需要我们自己创建任务栈
Intent i =new Intent ();
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
屏蔽返回键 在Activity中
重写onBackPressed()方法: