您的位置:首页 > 移动开发 > Android开发

Android杂记(二)

2016-12-18 12:13 357 查看
这篇小杂记主要是广播接收器

Android系统内部相当于一个电台,定义了许多广播事件,例如外拨电话,短信到来,sd卡状态,电池电量变化。。。

(一)IP播放器案例

实现步骤:

1,定义一个广播接收器

2,清单文件中注册,设置意图过滤器,添加action,为
android.intent.action.NEW_OUTGOING_CALL


<receiver
android:name=".OutGoingCallReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>


3,在onReceiver中获取到拨打的号码

String currentNumber = getResultData();


4,判断是否为长途,如果是就加上ip号

if (currentNumber.startsWith("0")){
setResultData(number+currentNumber);
}


IP号不能写死,只能用户输入,所以在xml里面给了个输入框,和保存按钮

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.cd.ipcall.MainActivity">

<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入要保存的号码"/>

<Button
android:id="@+id/btn_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存"/>
</LinearLayout>


获取到输入的值,保存到sp中

package com.cd.ipcall;

import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
EditText mEditText;
Button mButton;
private SharedPreferences mPreferences;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText= (EditText) findViewById(R.id.et);
mButton= (Button) findViewById(R.id.btn_save);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//获取到用户输入的号码
String phone = mEditText.getText().toString();
mPreferences = getSharedPreferences("config", MODE_PRIVATE);
SharedPreferences.Editor edit = mPreferences.edit();
edit.putString("number",phone);
edit.commit();
Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
}
});
}
}


在接收器中获取到输入的ip号和手机号码,如果手机号码是以“0”开头,就表示是长途,则加上ip号

public class OutGoingCallReceiver extends BroadcastReceiver {
public OutGoingCallReceiver() {
}

@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences preferences = context.getSharedPreferences("config", Context.MODE_PRIVATE);
String number = preferences.getString("number", "");
String currentNumber = getResultData();
Log.d("OutGoingCallReceiver", "===currentNumber:" + currentNumber);
if (currentNumber.startsWith("0")){
setResultData(number+currentNumber);
}
}
}


(二)sd卡状态的监听

同样是先创建一个接收sd卡状态变化的接收器,在清单文件中设置意图过滤器,设置action

<receiver android:name=".SdcardStateReceiver">
<intent-filter>
<!--sdcard安转了-->
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
<!--sdcard卸载了-->
<action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
<!--要指定file才会执行这两个action-->
<data android:scheme="file"></data>
</intent-filter>
</receiver>


特别指明,在sd卡中除了设置两个action外还有设置一个data指定scheme为file
<data android:scheme="file"></data>


在接收器中获取到action

public class SdcardStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("android.intent.action.MEDIA_MOUNTED")) {
Log.d("SdcardStateReceiver", "sdcard安装了");
}else if (action.equals("android.intent.action.MEDIA_UNMOUNTED")){
Log.d("SdcardStateReceiver", "sdcard卸载了");

}
}
}


(三)不同版本广播的特点

1,4.0之后的手机谷歌为了安全性,要求第一次安装时,必须有界面

即通过意图过滤器过滤action为MAIN以及category 为LAUNCHER

<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>


设置界面有强行停止的按钮,如果点击了,广播就不会生效

在2.3的时候手机没有这样的安全设置

(四)卸载应用案列

卸载应用的广播和ip拨号以及sd卡状态监听步骤一样都是系统定义好的广播,只是设置的action不一样

要设置的action为PACKAGE_ADDED和PACKAGE_REMOVED还有一个PACKAGE_INSTALL貌似更像是安转应用,但是这个只是预留,暂时无用

除此,还要像sd卡状态监听一样设置data的scheme,scheme为package

这样广播才起作用

(五)开机启动案例

开机启动案例也差不多,因为也是系统广播,只是action不同,action为BOOT_COMPLETED,再加上BOOT_COMPLETED的权限,

值得注意的是,开机广播需要开启一个activity,在广播中开启activity需要设置flag:
Intent.FLAG_ACTIVITY_NEW_TASK


public class BootReceiver extends BroadcastReceiver {
public BootReceiver() {
}

@Override
public void onReceive(Context context, Intent intent) {
Intent intent1=new Intent(context,MainActivity.class);
//在广播中打开activity要设置flag为FLAG_ACTIVITY_NEW_TASK
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
}
}


(六)自定义广播

之前的都是系统定义好的广播,也可以自己定义广播

自己定义的有有序广播无序广播

无序广播类似新闻联播,看不看都发了,有序广播类似中央的红头文件,按照优先级一级一级接收,中间层的广播可以修改广播内容,

有序广播特点:

可以被终止,数据可以被修改

无序广播特点:

不可以被终止,数据不可以被修改

可以通过是否可被终止,来判断是否为有序广播

(七)特殊的广播接收者

怎么个特殊法?比如操作特别频繁的广播事件,屏幕的锁屏与解屏,电池电量的变化,这样的广播在清单文件里面注册无效,必须动态注册

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext=MainActivity.this;
mLockReceiver = new LockReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.SCREEN_ON");
intentFilter.addAction("android.intent.action.SCREEN_OFF");
registerReceiver(mLockReceiver, intentFilter);

}


在初始化时动态注册了,必须在销毁时注销注册,否则会报窗体泄露的错

@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mLockReceiver);
}


写了这个广播想写一个简单的锁屏小软件,,,,,,

我很菜,,,但是我仍在努力,,,,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息