要求有一个栏目,右边有一个单选的列表框,点击后弹出归属地风格显示的单选框,打电话的时候服务开启,调用自定义的归属地风格,然后显示出来,相关的数据的存储都是在SharePreference中的
首先模拟SettingItemView一样设置自定义的样式
组快的布局文件view_setting_click.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="70dp"
android:padding="5dp" >
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="22sp" />
<TextView
android:id="@+id/tv_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_title"
android:layout_marginTop="3dp"
android:textColor="#a000"
android:textSize="18sp" />
<ImageView
android:id="@+id/cb_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/jiantou1_pressed"
/>
<View
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:layout_alignParentBottom="true"
android:background="#a000" />
</RelativeLayout>
组快的逻辑代码SettingClickView.java
package com.ldw.safe.view;
import com.ldw.safe.R;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;
/*
* 设置自定义相对布局,布局的结构用view_setting_click进行填充,并初始化SettingClickView的方法,来设置或者获取某些参数
*/
public class SettingClickView extends RelativeLayout {
private static final String NAMESPACE = "http://schemas.android.com/apk/res/com.ldw.safe";
private TextView tvTitle;
private TextView tvDesc;
private CheckBox cbStatus;
private String mDescOff;
private String mDescOn;
private String mTitle;
public SettingClickView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
}
public SettingClickView(Context context, AttributeSet attrs) {
super(context, attrs);
/*获取自定义属性的值
int attributeCount = attrs.getAttributeCount();
for(int i = 0; i< attributeCount; i++){
String attributeName = attrs.getAttributeName(i);
String attributeValue = attrs.getAttributeValue(i);
System.out.println(attributeName + "===" + attributeValue);
}
*/
initView();
}
public SettingClickView(Context context) {
super(context);
initView();
}
//初始化布局
private void initView(){
//将定义的布局文件设置成为当前的SettingClickView
View.inflate(getContext(), R.layout.view_setting_click, this);
tvTitle = (TextView) findViewById(R.id.tv_title);
tvDesc = (TextView) findViewById(R.id.tv_desc);
}
//设置相对布局的元素的属性
public void setTitle(String title){
tvTitle.setText(title);
}
//设置相对布局的元素的属性
public void setDesc(String desc){
tvDesc.setText(desc);
}
}
设置模块的布局文件activity_setting.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ldw="http://schemas.android.com/apk/res/com.ldw.safe"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
style="@style/TitleStyle"
android:text="手机设置"
/>
<com.ldw.safe.view.SettingItemView
android:id="@+id/siv_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ldw:title="自动更新设置"
ldw:desc_on="自动更新已开启"
ldw:desc_off="自动更新已关闭"
/>
<com.ldw.safe.view.SettingItemView
android:id="@+id/siv_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ldw:title="电话归属地显示设置"
ldw:desc_on="电话归属地显示已开启"
ldw:desc_off="电话归属地显示已关闭"
/>
<com.ldw.safe.view.SettingClickView
android:id="@+id/scv_address_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
设置模块中的逻辑代码,点击组合控件,弹出一系列的选择对话框,选择以后保存数据,同时初始化数据
ActivitySetting.java
package com.ldw.safe.Activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import com.ldw.safe.R;
import com.ldw.safe.service.AddressService;
import com.ldw.safe.utils.ServiceStatusUtils;
import com.ldw.safe.view.SettingClickView;
import com.ldw.safe.view.SettingItemView;
/**
* 设置中心
*/
public class SettingActivity extends Activity {
private SettingItemView siv_update;//设置自动更新
private SettingItemView siv_address;//归属地
private SettingClickView scv_address_style;//归属地显示的风格
private SharedPreferences mPref;//把设置的数据保存在mPref
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
//把设置的数据保存在mPref
mPref = getSharedPreferences("config", MODE_PRIVATE);
initUpdateView();//初始化自动升级开关
initAdressView();//初始化归属地开关
initAddressStyle();//初始化归属地样式的选择
}
/*
* 初始化自动升级开关
*/
private void initUpdateView(){
siv_update = (SettingItemView)findViewById(R.id.siv_update);
//siv_update.setTitle("自动更新设置");
//获取保存的数据,判断之前选择的是开始还是关闭,初始化进入界面是否勾选
boolean autoUpdate = mPref.getBoolean("auto_update", true);
if(autoUpdate){
siv_update.setDesc("自动更新已经开启");
siv_update.setChecked(true);
}else{
siv_update.setDesc("自动更新已经关闭");
siv_update.setChecked(false);
}
siv_update.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//判断右边框的勾选状态
if(siv_update.isChecked()){
//设置不勾选
siv_update.setChecked(false);
//siv_update.setDesc("自动更新已经关闭");
//编辑mPref的值
mPref.edit().putBoolean("auto_update", false).commit();
}else{
//设置勾选
siv_update.setChecked(true);
//siv_update.setDesc("自动更新已经开启");
//编辑mPref的值
mPref.edit().putBoolean("auto_update", true).commit();
}
}
});
}
/*
* 初始化归属地开关
*/
private void initAdressView(){
siv_address = (SettingItemView) findViewById(R.id.siv_address);
//判断归属地的服务是否在运行
boolean serviceRunning = ServiceStatusUtils.isServiceRunning(this, "com.ldw.safe.service.AddressService");
//让服务的那个勾选框根据系统中是否有服务来判断是否去开启
if(serviceRunning){
siv_address.setChecked(true);
}else{
siv_address.setChecked(false);
}
siv_address.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
if(siv_address.isChecked()){
siv_address.setChecked(false);
stopService(new Intent(SettingActivity.this, AddressService.class));
}else{
siv_address.setChecked(true);
//号码归属地显示开启的时候要开启服务
startService(new Intent(SettingActivity.this, AddressService.class));
}
}
});
}
/*
* 修改号码归属地提示框的风格
*/
private void initAddressStyle(){
scv_address_style = (SettingClickView) findViewById(R.id.scv_address_style);
scv_address_style.setTitle("归属地提示框风格");
//获取保存的样式
int style = mPref.getInt("address_Style", 0);
//设置样式
scv_address_style.setDesc(items[style]);
scv_address_style.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
showSingleChooseDialog();
}
});
}
final String[] items = new String[]{"半透明", "活力橙", "卫士蓝", "金属灰", "苹果绿"};
/*
* 弹出归属地样式选择的单选框
*/
public void showSingleChooseDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
//设置选择框额logo
builder.setIcon(R.drawable.ic_launcher);
builder.setTitle("归属地提示框风格");
//获取保存的风格样式,默认为0
int style = mPref.getInt("address_Style", 0);
builder.setSingleChoiceItems(items, style,
new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
//保存选择的样式的序号
mPref.edit().putInt("address_Style", which).commit();
//点击以后对话框消失
dialog.dismiss();
//设置组合控件的文字描述
scv_address_style.setDesc(items[which]);
}
});
builder.setNegativeButton("取消", null);
builder.show();
}
}
在服务中使用自己选择的样式,首先获取到保存的样式数据再设置样式
package com.ldw.safe.service;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import com.ldw.safe.R;
import com.ldw.safe.db.dao.AddressDao;
/*
* 来电提醒的服务
*/
public class AddressService extends Service {
private TelephonyManager tm;
private MyListener listener;
private OutCallReceiver receiver;
private WindowManager mWM;
//private TextView view;
private View view;
private SharedPreferences mPref;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate(){
super.onCreate();
//读取样式的配置参数
mPref = getSharedPreferences("config", MODE_PRIVATE);
tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
listener = new MyListener();
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);//监听打电话的状态
receiver = new OutCallReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
registerReceiver(receiver, filter);//动态注册广播
}
class MyListener extends PhoneStateListener{
//监听电话状态的变化
@Override
public void onCallStateChanged(int state, String incomingNumber){
//
switch(state){
//电话铃声响起
case TelephonyManager.CALL_STATE_RINGING:
System.out.println("CALL_STATE_RINGING");
//获取来电的号码归属地
String address = AddressDao.getAddress(incomingNumber);
//Toast的形式弹出号码归属地
//Toast.makeText(AddressService.this, address, Toast.LENGTH_LONG).show();
//自定义的Toast显示号码归属地
showToast(address);
break;
//监听电话闲置的事件
case TelephonyManager.CALL_STATE_IDLE:
//关闭自定义的Toast显示
if(mWM != null && view != null){
//挂断电话的时候,移除窗体
mWM.removeView(view);
}
break;
default:
break;
}
super.onCallStateChanged(state, incomingNumber);
}
}
/*
* 监听去电 的广播接收者,添加权限PROCESS_OUTGOING_CALLS
*/
class OutCallReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//获取到来电的号码
String number = getResultData();
//获取到号码的归属地
String address = AddressDao.getAddress(number);
//Toast的形式弹出号码归属地
//Toast.makeText(context, address, Toast.LENGTH_LONG).show();
//自定义的Toast显示号码归属地
showToast(address);
}
}
@Override
public void onDestroy(){
super.onDestroy();
//关闭服务,停止来电监听
tm.listen(listener, PhoneStateListener.LISTEN_NONE);
//注销广播
unregisterReceiver(receiver);
}
/*
* 自定义归属地显示浮窗,取代Toast
*/
private void showToast(String text){
mWM = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
final WindowManager.LayoutParams params = mParams;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
params.format = PixelFormat.TRANSLUCENT;
params.type = WindowManager.LayoutParams.TYPE_TOAST;
params.setTitle("Toast");
//原始的view显示
//view = new TextView(this);
//自定义的view显示
view = View.inflate(this, R.layout.toast_address, null);
//初始化样式
int[] bgs = new int[] { R.drawable.call_locate_white,
R.drawable.call_locate_orange, R.drawable.call_locate_blue,
R.drawable.call_locate_gray, R.drawable.call_locate_green };
//获取保存的样式数据
int style = mPref.getInt("address_Style", 0);
//设置样式
view.setBackgroundResource(bgs[style]);
TextView tvAddress= (TextView) view.findViewById(R.id.tv_address);
tvAddress.setText(text);
//tvAddress.setTextColor(Color.BLUE);
//将view添加到窗体
mWM.addView(view, params);
}
}