学员管理信息android
2017-02-07 15:16:21 abliudede 阅读数 217

个人学习总结,如有侵权请留言联系删除,忘海涵。

例一:apkinfo文件

package com.utils.data;

import com.shennongshi.dingdong.MApplication;

import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;

public class APKInfo {

	public static String getVersionName() {
		try {
			PackageInfo pi = MApplication.getInstance1().getPackageManager().
					getPackageInfo(MApplication.getInstance1().getPackageName(), 0);
			return pi.versionName;
		} catch (NameNotFoundException e) {
		}
		return "";
	}

	public static int getVersionCode() {
		try {
			PackageInfo pi = MApplication.getInstance1().getPackageManager().
					getPackageInfo(MApplication.getInstance1().getPackageName(), 0);
			return pi.versionCode;
		} catch (NameNotFoundException e) {
		}
		return 0;
	}
	
	public static String getMetaData(String key) {
		ApplicationInfo appInfo;
		try {
			appInfo = MApplication.getInstance1().getPackageManager().
					getApplicationInfo(MApplication.getInstance1().getPackageName(), PackageManager.GET_META_DATA);
		} catch (NameNotFoundException e) {
			return "";
		}
		return String.valueOf(appInfo.metaData.get(key));
	}
}



例二:phoneinfo文件


package com.utils.data;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

import org.apache.http.conn.util.InetAddressUtils;

import com.shennongshi.dingdong.MApplication;
import com.shennongshi.dingdong.pztools.PreferenceKey;
import com.utils.crypt.MD5Util;
import com.utils.db.ConfigPreferences;
import com.utils.tools.Reflection;
import com.utils.tools.XLogger;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;

public class PhoneInfo {

	private static final String TAG = PhoneInfo.class.getSimpleName();
	
	private static Application mApplication;
	private static String UUID = "";
	private static String[] sCpuInfo = null;
	private static int mScreenDensity;
	private static DisplayMetrics mDisplayMetrics;
	
	private PhoneInfo() {}
	
	public static void init(Application application) {
		mApplication = application;
	}
	
	public static String getModel() {
		return Build.MODEL;
	}
	
	public static String getBrand() {
		return Build.BRAND;
	}

	public static String getUUID() {
		if (TextUtils.isEmpty(UUID)) {
			UUID = ConfigPreferences.getString(PreferenceKey.UUIDKEY, "");
			if (!TextUtils.isEmpty(UUID)) return UUID;
			final TelephonyManager tm = (TelephonyManager) MApplication
					.getInstance1().getSystemService(Context.TELEPHONY_SERVICE);
			final String tmDevice, tmSerial, androidId;
			tmDevice = tm.getDeviceId();
			tmSerial = tm.getSimSerialNumber();
			androidId = android.provider.Settings.Secure.getString(
						MApplication.getInstance1().getContentResolver(),
						android.provider.Settings.Secure.ANDROID_ID);
			long aIDTime = androidId.hashCode();
			long leastSigBits = System.currentTimeMillis();
			if (!TextUtils.isEmpty(tmDevice)) leastSigBits = (long) tmDevice.hashCode() << 32;
			if (!TextUtils.isEmpty(tmSerial)) leastSigBits |= tmSerial.hashCode();
			UUID deviceUuid = new UUID(aIDTime, leastSigBits);
			UUID = MD5Util.string2MD5(deviceUuid.toString());
			ConfigPreferences.putString(PreferenceKey.UUIDKEY, UUID);
		}
		return UUID;
	}
	
    /**
     * 获取cpu信息 基本上耗时 几毫秒 0型号 1频率 ARMv7
     * 
     * @return
     */
    public static String[] getCpuInfo() {
        if (sCpuInfo == null) {
            String path = "/proc/cpuinfo";
            String data = "";
            String[] cpuInfo = { "", "" };
            String[] arrayOfString;
            try {
                FileReader file = new FileReader(path);
                BufferedReader localBufferedReader = new BufferedReader(file, 8192);
                data = localBufferedReader.readLine();
                arrayOfString = data.split("\\s+");
                for (int i = 2; i < arrayOfString.length; i++) {
                    cpuInfo[0] = cpuInfo[0] + arrayOfString[i] + " ";
                }
                data = localBufferedReader.readLine();
                arrayOfString = data.split("\\s+");
                cpuInfo[1] += arrayOfString[2];
                localBufferedReader.close();

                sCpuInfo = cpuInfo;
            } catch (IOException e) {
            }
        }
        return sCpuInfo;
    }

    public static String getCpuType() {
        String cpu = android.os.Build.CPU_ABI;
        if (TextUtils.isEmpty(cpu)) {
            String[] cpuInfo = getCpuInfo();
            if (cpuInfo != null && !TextUtils.isEmpty(cpuInfo[0])) {
                cpu = cpuInfo[0].toLowerCase();
            }
        } else {
            cpu = cpu.toLowerCase();
        }
        XLogger.d(TAG, "cpu:" + cpu);
        return cpu;
    }

    /**
     * 是否是arm架构cpu arm armv7
     * 
     * @return
     */
    public static boolean isArmCpu() {
        String cpu = getCpuType();
        if (TextUtils.isEmpty(cpu)) {
            return false;
        } else {
            return cpu.contains("arm");
        }
    }

    public static boolean isArmV7Cpu() {
        String cpu = getCpuType();
        if (TextUtils.isEmpty(cpu)) {
            return false;
        } else {
            return cpu.contains("v7");
        }
    }
    
    public static String getImsi() {
        TelephonyManager telephonyManager = (TelephonyManager) MApplication
				.getInstance1().getSystemService(Context.TELEPHONY_SERVICE);
        String imsi = telephonyManager.getSubscriberId();
        return imsi;
    }

    public static String getImei() {
        TelephonyManager telephonyManager = (TelephonyManager) MApplication
				.getInstance1().getSystemService(Context.TELEPHONY_SERVICE);
        String imei = telephonyManager.getDeviceId();
        return imei;
    }

    public static String getWifiMac() {
        WifiManager wifi = (WifiManager) MApplication
				.getInstance1().getSystemService(Context.WIFI_SERVICE);
        WifiInfo mac = wifi.getConnectionInfo();
        String macAdress = (mac != null ? mac.getMacAddress() : "");
        return macAdress;
    }
    
    public static String getWifiBssid() {
        WifiManager wifi = (WifiManager) MApplication
				.getInstance1().getSystemService(Context.WIFI_SERVICE);
        WifiInfo mac = wifi.getConnectionInfo();
        String bssidAdress = (mac != null ? mac.getBSSID() : "");
        return bssidAdress;
    }
    
    /**
     * 获取imsi前5位
     * 
     * @param context
     * @return
     */
    public static String getSimInfo(Context context) {
        String imsi = getImsi();
        String siminfo = "00000";
        if (!TextUtils.isEmpty(imsi) && imsi.length() > 4) {
            siminfo = imsi.substring(0, 5);
        }
        return siminfo;
    }
    
    /**
     * @return  返回当前手机的像素密度,xh 分辨率的是 320,h 的是 240 ,m 的是 160
     */
    public static int  getDefaultDisplayMetricsDensity(){
        if(mScreenDensity < 0){
            mScreenDensity = getDefaultDisplayMetrics().densityDpi;
        }
        return mScreenDensity;
    }
    
    /**
     * 获取手机屏幕宽,高<br>
     * 返回的 DisplayMetricx 不能被 copy ,因为该 DisplayMetricx 会随着手机的变化而变化,比如横竖屏切换时,DisplayMetricx 里面的宽、高的值就会发生对换
     * @return
     */
    public static DisplayMetrics getDefaultDisplayMetrics(){
        if(mDisplayMetrics == null){
            mDisplayMetrics = mApplication.getResources().getDisplayMetrics();
        }
    	return mDisplayMetrics;
    }
    
    public static int getScreenWidth(Activity activity) {
        DisplayMetrics dm = getDisplayMetrics(activity);
        if (dm == null) return 0;
        return dm.widthPixels;
    }

    public static int getScreenHeight(Activity activity) {
        DisplayMetrics dm = getDisplayMetrics(activity);
        if (dm == null) return 0;
        return dm.heightPixels;
    }

    private static DisplayMetrics getDisplayMetrics(Activity activity) {
    	if (activity == null) return null;
        DisplayMetrics dm = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm;
    }
    
    public static float getDimensValue(int resId) {
		return MApplication.getInstance1().getResources().getDimension(resId);
	}
    
	public static int convertDpToPx(int dp) {
		return (int) (getDefaultDisplayMetrics().density * dp + 0.5f);
	}

	public static float convertDpToPx(float dp) {
		return (getDefaultDisplayMetrics().density * dp);
	}

	public static int convertPxToDp(int px) {
		return (int) (px / getDefaultDisplayMetrics().density + 0.5f);
	}

	public static int convertSpToPx(float sp) {
		return (int) (getDefaultDisplayMetrics().scaledDensity * sp);
	}

	public static String getOSVersion() {
		return android.os.Build.VERSION.RELEASE;
	}

	public static int getSDKVersion() {
		return android.os.Build.VERSION.SDK_INT;
	}
    
    //根据IP获取本地Mac
	public static String getLocalMacAddressFromIp() {
		Reflection reflection = new Reflection();

		String mac_s = "";
		try {
			byte[] mac;
			NetworkInterface ne = NetworkInterface.getByInetAddress(InetAddress.getByName(getLocalIpAddress()));
			mac = (byte[]) reflection.invokeMethod(ne, "getHardwareAddress", new Object[] {});
			mac_s = byte2hex(mac);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mac_s;
	}
    
    public static String getLocalIpAddress() {  
	    try {  
	        String ipv4;  
	        List<NetworkInterface>  nilist = Collections.list(NetworkInterface.getNetworkInterfaces());  
	        for (NetworkInterface ni: nilist)   
	        {  
	            List<InetAddress>  ialist = Collections.list(ni.getInetAddresses());  
	            for (InetAddress address: ialist){  
	                if (!address.isLoopbackAddress() && InetAddressUtils.isIPv4Address(ipv4=address.getHostAddress()))   
	                {   
	                    return ipv4;  
	                }  
	            }  
	        }  
	
	    } catch (SocketException ex) {  
	    }  
	    return null;  
	}
    
	public static String byte2hex(byte[] b) {
		StringBuffer hs = new StringBuffer(b.length);
		String stmp = "";
		int len = b.length;
		for (int n = 0; n < len; n++) {
			stmp = Integer.toHexString(b[n] & 0xFF);
			if (stmp.length() == 1)
				hs = hs.append("0").append(stmp);
			else {
				hs = hs.append(stmp);
			}
		}
		return String.valueOf(hs);
	}

}



在使用过程中,将以上两个文件直接导入工程,使用封装好的信息获取函数就可以轻松获取相应信息。

如有纰漏,望指正。



2014-11-22 17:45:23 birdsaction 阅读数 6350

前一段时间有个Android刚入门的朋友想实现一个表格 来展示信息,下面我们通过扩展ViewGroup 来实现一个简单的。

本文通过扩展Android ViewGroup实现表格 可用于课程信息,学生信息视图展示,实现表格方式可以用布局拼凑 也可以自定义ViewGroup方式实现。


最终效果如下:



首先创建基本模型和Activity

public class Student {

	/**
	 * 
	 */
	public Student() {
		// TODO Auto-generated constructor stub
	}
	
	public String stuId;
	public String stuName;
	public String stuFrom;
	public String stuRoom;
	public String stuClass;
	public String stuDate;

}

public class StudentInfoActivity extends Activity {


	public StudentInfoActivity() {
		
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_student);
		StudentInfoView courseInfoView = (StudentInfoView) findViewById(R.id.myview);
		ArrayList<Student> list = new ArrayList<Student>();
		addList(list);
		courseInfoView.addChildViews(list);
		
	}

	private void addList(ArrayList<Student> list) {
		Student c = new Student();
		c.stuId = "stu1001";
		c.stuName = "张帆";
		c.stuFrom = "浙江";
		c.stuDate = "2014-10-09";
		c.stuRoom = "NO2105";
		c.stuClass ="一年级1班";
		list.add(c);
		
		c = new Student();
		c.stuId = "stu1002";
		c.stuName = "汪清";
		c.stuFrom = "湖北";
		c.stuDate = "2014-11-11";
		c.stuRoom = "NO2012";
		c.stuClass ="一年级1班";
		list.add(c);
		
		c = new Student();
		c.stuId = "stu1003";
		c.stuName = "李密";
		c.stuFrom = "东北";
		c.stuDate = "2014-11-10";
		c.stuRoom = "NO1901";
		c.stuClass ="一年级2班";
		list.add(c);
		
		c = new Student();
		c.stuId = "stu1004";
		c.stuName = "李坤";
		c.stuFrom = "北京";
		c.stuDate = "2014-11-12";
		c.stuRoom = "NO1204";
		c.stuClass ="一年级3班";
		list.add(c);
	}

	
}

布局文件

<?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="match_parent"
    android:orientation="vertical" 
    android:background="#ffffff"
    >
    <TextView 
        android:id="@+id/title"
        android:layout_marginTop="5dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="学员基本信息"
        android:textSize="18sp"
        android:textColor="#000000"
        android:layout_centerHorizontal="true"
        />
    <com.birds.mobile.course.StudentInfoView
        android:id="@+id/myview"
        android:layout_below="@+id/title"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    </com.birds.mobile.course.StudentInfoView>
    
</RelativeLayout>

下面重点介绍扩展的ViewGroup类,StudentInfoView.java

每个格子里面都是一个TextView用于显示文本,一行为一个Student信息,包括6个字段 所以这里有6列。

     int itemWidth = 0;
     int itemHeight = 0;
     @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    	int w = getDefaultSize(0, widthMeasureSpec);
    	int h = getDefaultSize(0, heightMeasureSpec);
    	int m = w/colcount;
    	itemWidth = m;
    	itemHeight = m/4;
    	int itemSpecWidth = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
    	int itemSpecHeigh = MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY);
    	Log.d("","get item width:" + itemSpecWidth + ";" + w + ";" + h);
    	Log.d("","h:" + itemHeight + " width:" + m);
    	measureChildren(itemSpecWidth, itemSpecHeigh);
    	setMeasuredDimension(w, h);
    }

public int colcount = 6; //六列

高度我们取宽度的1/4,可以自己调整,我们把宽度和高度通过整个ViewGroup的宽度计算 ,这里刚好是屏幕的宽度 fill_parent


	protected void onLayout(boolean changed, int l, int t, int r, int b) {
			int childCount = getChildCount();
			for (int i = 0 ; i < childCount ; i++) {
				View child = getChildAt(i);
				int row = i % colcount;//第几行
				int col = i / colcount;//第几列
			    int w1 = child.getMeasuredWidth();
			    int padding = itemWidth - w1;
			    if (padding >= 5) {
			    	padding = 5; //这里是为了让每个TextView 都有个左间距,大家可以自己计算 放到中间需要计算文本内容字的宽度
			    }
				int left = row * itemWidth + padding;
				int top = col * child.getMeasuredHeight();
				int right = left + itemWidth;
				int bottom = top + child.getMeasuredHeight();
				child.layout(left, top, right, bottom);
			}
	}

数据方法。

	public void addChildViews(ArrayList<Student> list) {
		if (list == null) 
			return;
		for (Student c : list) {
			addView(createItemView(c.stuId));
			addView(createItemView(c.stuName));
			addView(createItemView(c.stuFrom));
			addView(createItemView(c.stuDate));
			addView(createItemView(c.stuRoom));
			addView(createItemView(c.stuClass));
		}
		courseList = list;
		int totalRow = (courseList.size() / colcount) * colcount;
		Log.d("","totalRow:" + totalRow);
	}
	
	private ViewGroup createItemView(String text){
		ViewGroup v = (ViewGroup) LayoutInflater.from(getContext()).inflate(R.layout.item_view, null);
		((TextView)v.findViewById(R.id.text)).setText(text);
		return v;
	}

item_view布局内容

<?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="match_parent" >
    <TextView 
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="" 
        android:textSize = "16sp"
        android:textColor="#00CD00"
        />
</RelativeLayout>

好,现在数据基本能显示到ui上,只是还没画线。我门需要复写dispatchDraw 方法进行Canvas绘画

	protected void dispatchDraw(Canvas canvas) {
		super.dispatchDraw(canvas);
		Log.d("", "width:" + itemWidth + " heigh:" + itemHeight);
		//画水平线
		int totalRow = courseList.size();
     	for (int i = 0 ; i <= totalRow; i++) {
     		int startY = i * itemHeight;
     		int stopY = startY;
     		canvas.drawLine(0, startY, itemWidth * colcount, stopY, linePaint);
     	}
     	//画垂直线
     	for (int i = 0 ; i <= colcount; i++) {
     		int startX = i*itemWidth;
     		int stopX  = i*itemWidth;
     		int startY = 0;	
     		int stopY = itemHeight * totalRow;
     		canvas.drawLine(startX, startY, stopX, stopY, linePaint);
     	}	
        
	}

画线就是计算的过程,通过每个item的宽和高,下面是线的属性代码。

	private Paint linePaint;
	
	private void init(){
        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setStyle(Paint.Style.STROKE);
        linePaint.setColor(Color.GRAY);
        linePaint.setStrokeWidth(0.5f);
	}

表格上并未显示表头 其实这个也能画出来,或者用布局拼凑也是可以的。

今天就到这里,有问题请指出,谢谢。




2013-12-26 17:08:33 q10123 阅读数 840

1、发送短信

a、获取SmsManager

b、创建PendingIntent对象

c、发送短信

权限:

<!-- 授予发送短信的权限 -->
	<uses-permission android:name="android.permission.SEND_SMS"/>
代码片段:

SmsManager sManager = SmsManager.getDefault();
// 创建一个PendingIntent对象
				PendingIntent pi = PendingIntent.getActivity(SendSms.this
					, 0, new Intent(), 0);
				// 发送短信
				sManager.sendTextMessage("电话号码"
					, null, "发送信息", pi, null);
2、拦截信息

a、建立一个广播

b、设置广播接收

c、屏蔽系统的信息接收

d、对信息进行简单解析显示

权限:

<!-- 授予发送短信的权限 -->
	<uses-permission android:name="android.permission.SEND_SMS"/>
代码片段:

public void onReceive(Context context, Intent intent)
	{
		// 当街收到短信时触发
		if (intent.getAction().equals(
			"android.provider.Telephony.SMS_RECEIVED"))
		{
			//取消广播(这行代码会让系统收不到短信)
			abortBroadcast();
			StringBuilder sb = new StringBuilder();
			//接收有SMS传过来的数据
			Bundle bundle = intent.getExtras();
			//判断是否有数据
			if (bundle != null)
			{				
				Object[] pdus = (Object[]) bundle.get("pdus");				
				SmsMessage[] messages = new SmsMessage[pdus.length];
				for (int i = 0; i < pdus.length; i++)
				{
					messages[i] = SmsMessage
						.createFromPdu((byte[]) pdus[i]);
				}				
				for (SmsMessage message : messages)
				{
					sb.append("短信来源:");					
					sb.append(message.getDisplayOriginatingAddress());
					sb.append("\n------短信内容------\n");
					sb.append(message.getDisplayMessageBody());
				}
			}
			Toast.makeText(context, sb.toString()
					,150000).show();
		}	
	}




2012-03-23 11:09:00 weixin_34362875 阅读数 3

 android下配置偏好信息的管理

佣工7001

 

       应用程序一般都有这样的需求,为了应用有更好的适应性,有一些参数设置需要独立出来放在配置文件里面。这个配置文件应该是开发的时候就编辑好的设好了默认值,安装后应该可以让用户修改一些设置并保存。程序运行的时候读取这些设置并根据设置不同进行不同的操作。比如windows下程序惯用的INI文件,如果是j2ee项目我们会使用property文件来保存这些参数,那么在android下面如何实现呢?在android中提供了SharedPreference这个类来配置参数设置,书上网上很多例子都是用程序对SharedPreference的读写操作,可是怎样拥有初始设置的值呢?当然可以自己读取资源中的xml文件,然后手动写程序保存到SharedPreference中,可这样太麻烦了一点都不方便、不专业。

        经过我的一番搜索研究,发现最好的方法就是使用Preference管理设置,android sdk已内置了良好的支持,所有的功能都在android.preference这个命名空间中。经学习发现这个preference的管理是和SharedPreference结合实现的,完美的实现了我的需求,并且是实现了和android系统设置中一样的设置管理界面,显得很专业微笑。闲言少叙,下面就具体来看如何使用preference实现配置功能。

        一、建立配置文件。

        在项目res目录下xml目录下(如果没有请建立)建立一个settings.xml的xml文件(文件名不一定叫settings,但是一定要放在xml目录下),文件内容如下:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:title="Settings" >

    <PreferenceCategory android:key="general" android:title="基本设置">
			<ListPreference android:key="superman" android:entries="@array/choice"  android:entryValues="@array/choiceId" 
			    android:dialogTitle="我的最爱" android:summary=""
			    android:defaultValue="value5" android:title="你选哪个"/>    
			<CheckBoxPreference android:key="bigman" android:title="我要做大英雄"
            android:defaultValue="true"
            android:summaryOn="唯大英雄能本色,是真名士自风流" android:summaryOff="请君暂上凌烟阁,若个书生万户侯"/>
			<EditTextPreference
            android:defaultValue="宁可我负天下人,不可天下人负我!"
            android:key="maxim"
            android:summary="有了信仰就要干,不要无志者常立志"
            android:title="我最爱的格言" />    
      <EditTextPreference
            android:defaultValue="星球大战"
            android:key="favoriteFilm"
            android:summary="没有最好,只有更好"
            android:title="我最爱的电影" /> 
    </PreferenceCategory>
    <PreferenceCategory android:key="advanced" android:title="高级设置">
    <PreferenceScreen android:key="basicSettings" android:title="高级设置" android:summary="点击进入高级设置" >
        <CheckBoxPreference android:key="checkVersion" android:title="自动更新"
            android:defaultValue="false"
            android:summaryOn="程序将每隔一段时间自动检查新版本" android:summaryOff="自动更新已关闭"/>
        <EditTextPreference
            android:defaultValue="1"
            android:key="checkVersionTime"
            android:summary=""
            android:title="检查新版本间隔时间(天)" />
        <EditTextPreference
            android:defaultValue="http://192.168.0.99:8008/crx/xtgl.User"
            android:key="url"
            android:summary=""
            android:title="URL" />

        <EditTextPreference
            android:defaultValue="http://60.29.99.76:8008/crx/xtgl.Unit?__fn_=initdata"
            android:key="url1"
            android:summary=""
            android:title="URL2" />

        <EditTextPreference
            android:defaultValue="htt2.p://192.168.0.100:8558/crx/manage.HistVote"
            android:key="URL3"
            android:summary=""
            android:title="URL3" />
        
    </PreferenceScreen>
	</PreferenceCategory>
</PreferenceScreen>


         文件的根元素就是PreferenceScreen,望文生义,就是一个屏幕显示的配置内容,并且可以嵌套使用。PreferenceScreen下面还可以分类,这就是PreferenceCategory元素,并且PreferenceCategory元素下面同样可以嵌套PreferenceScreen元素(其实PreferenceScreen就是PreferenceCategory的子类)。详细的配置内容可用的元素有EditTextPreference,CheckBoxPreference,ListPreference,Preference,RingtongPreference......

        从上面的配置文件中可以看出一个Preference配置项目主要拥有的属性。其中Key为这个PreferenceID,设置了才可以在代码中引用,Title是显示的标题,Summary是显示在标题下的文字介绍,Dependency是指依赖的其他配置项(注:一般在Dependency中填写一个CheckBoxPreferenceKey,这样就会在填写的那个CheckBoxPreference勾选时当前这个Preference才可用),Default Value为初始值,等等。其他的请大家自己看sdk,在这里就不赘述了。

        值得一提的就是ListPreference的使用稍微复杂一些,ListPreference除了继承自Preference的属性外,还有自己ListPreference的属性和继承自DialogPreference的属性。其中属于ListPreference的属性有两个:Entries填的为一个字符串数组,是列表显示出来的值(用户看到的说明文字),而Entry Values是实际要保存的值对应的字符串数组。DialogPreference只要填一个Dialog title标题和一个取消按钮显示的字即可。下面建立两个String array供ListPreference的选择对话框使用,在res/values目录下建立一个新的myarrays.xml文件(文件名随便),内容如下.

 

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="choice">
        <item >超人</item>
        <item >蜘蛛侠</item>
        <item >夜魔侠</item>
        <item >青蜂侠</item>
        <item >蝙蝠侠</item>
        <item >闪电侠</item>
        <item >钢铁侠</item>
        <item >超胆侠</item>
        <item >绿灯侠</item>
    </string-array>
    <string-array name="choiceId">
        <item >value1</item>
        <item >value2</item>
        <item >value3</item>
        <item >value4</item>
        <item >value5</item>
        <item >value6</item>
        <item >value7</item>
        <item >value8</item>
        <item >value9</item>
    </string-array>
    
</resources>
好了,我们的前期准备已经搞定了。

 

       二、读取配置内容。

       配置信息已经建好了,下面就是读取了,怎么读取呢?看到网上的解决方法很简单,就是得到默认的SharedPreference,然后按照Preference的key值读取,好的,马上试验:在Activity中添加一个按钮BtnTestConfig,设置OnClick事件如下:

OnClickListener onBtnTestConfig = new OnClickListener() {
		public void onClick(View v) {
			String s = "not read!";
			IndexActivity me = IndexActivity.this;
			SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(me);
			try {
				s = sp.getString("favoriteFilm", s);
			} catch (Exception e) {
				e.printStackTrace();
			}
			DialogUtil.ShowMsgDlg(IndexActivity.this, String.valueOf(s));
		}
	};
可是一运行发现,显示的是程序中给出的默认值,根本不是配置写的“星球大战”!咋回事儿呢,老办法google一下,发现有说要用XmlResourceParser自己解析XML,可是这就有违初衷了!不行再搜,终于在老外哪里找到了,原来android不会自动将你的Preference配置同步到SharedPreference中,所以需要用到PreferenceManager.setDefaultValues(Context context, int resId, boolean readAgain)方法,修改程序如下:

 

 

OnClickListener onBtnTestConfig = new OnClickListener() {
		public void onClick(View v) {
			String s = "not read!";
			IndexActivity me = IndexActivity.this;
			PreferenceManager.setDefaultValues(IndexActivity.this, R.xml.settings, true);
			SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(me);
			
			try {
				s = sp.getString("favoriteFilm", s);
			} catch (Exception e) {
				e.printStackTrace();
			}
			DialogUtil.ShowMsgDlg(IndexActivity.this, String.valueOf(s));
		}
	};
再次运行,ok,终于读到了!这里注意PreferenceManager.setDefaultValues方法的第三个参数readAgain,false表示只会执行一次,也就是说SharedPreference已经同步过一次,此函数就不会再执行了,这样如果在调试阶段你会发现新增加的配置项目就读不到了(打开设置界面编辑后是可以的),所以调试时最好用true。当然这里只是试验,在实际程序中,最好放在主Activity中执行这个函数。另外,readAgain设为true,不会覆盖已经存在于SharedPreference中的配置值,不会造成用户修改的配置丢失。

 

注意,如果你想清除修改的配置,那么在你要这样

PreferenceManager.getDefaultSharedPreferences(Context context),之后调用
PreferenceManager.setDefaultValues(Context context, int resId, boolean readAgain),并且readAgain设为true)
       三、实现配置管理界面。

 

       到现在,Preference已经建立好并且可以读取了,那么怎么实现用户修改Preference设置呢?这个就更简单了,新建立一个Activity并继承PreferenceActivity,

 

public class MyPreference extends PreferenceActivity

 

然后再onCreate函数中这样写:

 

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.addPreferencesFromResource(R.xml.settings);
	}
然后要做的就是在主界面中添加菜单或按钮调用这个Activity(这个就赘述了),怎么样,是不是和系统的设置界面一样漂亮。

 


         四、更完美的设置界面。

         试了试,搞好的Preference界面,忽然发现了还有一个缺点,每个配置项目下面的Summary信息都是固定的,如果能够显示用户的当前设置那就完美了。废话少说还是网上学习去,过程不必细说,结果发现还真没有方便的手段可用。没办法,只能程序代码实现。所用技术就是Perference.setSummary这个函数。思想就是在初始化的时候,更据当前配置内容,遍历配置项设置summary内容,然后注册SharedPreference的OnSharedPreferenceChangeListener事件监听配置项的变化,随时更新已变化项目的summary信息。

        由于需要注册OnSharedPreferenceChangeListener事件,所以我们的Activity还要实现OnSharedPreferenceChangeListener这个接口。

 

public class MyPreference extends PreferenceActivity implements OnSharedPreferenceChangeListener {
        然后添加三个方法:

 

 

/**
	 * Set the summaries of all preferences
	 */
	private void initSummaries(PreferenceGroup pg) {
		for (int i = 0; i < pg.getPreferenceCount(); ++i) {
			Preference p = pg.getPreference(i);
			if (p instanceof PreferenceGroup)
				this.initSummaries((PreferenceGroup) p); // recursion
			else
				this.setSummary(p);
		}
	}

	/**
	 * Set the summaries of the given preference
	 */
	private void setSummary(Preference pref) {
		// react on type or key
		if (pref instanceof ListPreference) {
			ListPreference listPref = (ListPreference) pref;
			listPref.setSummary(listPref.getEntry());
		}
		if (pref instanceof EditTextPreference) {
			EditTextPreference etp = (EditTextPreference) pref;
			etp.setSummary(etp.getText());
		}

	}

	/**
	 * used to change the summary of a preference
	 */
	public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
		Toast.makeText(this, "preference changed! " + key, 3000);
		Preference pref = findPreference(key);
		this.setSummary(pref);
	}

      最后在onCrate方法中添加两行代码:

 

 

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	this.addPreferencesFromResource(R.xml.settings);
	this.getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
      this.initSummaries(this.getPreferenceScreen());
}
ok,打完收工,运行起来再看效果:

 


怎么样,堪称完美吧。吐舌头下面试试我们的ListPreference,选择一个新的英雄:

 

 

选择完成后,再看Preference管理界面,提示信息已变为“夜魔侠”一切ok。

转载于:https://www.cnblogs.com/dajianshi/archive/2012/03/23/2827108.html

2012-03-23 11:09:00 weixin_34216107 阅读数 5

 android下配置偏好信息的管理

佣工7001

 

       应用程序一般都有这样的需求,为了应用有更好的适应性,有一些参数设置需要独立出来放在配置文件里面。这个配置文件应该是开发的时候就编辑好的设好了默认值,安装后应该可以让用户修改一些设置并保存。程序运行的时候读取这些设置并根据设置不同进行不同的操作。比如windows下程序惯用的INI文件,如果是j2ee项目我们会使用property文件来保存这些参数,那么在android下面如何实现呢?在android中提供了SharedPreference这个类来配置参数设置,书上网上很多例子都是用程序对SharedPreference的读写操作,可是怎样拥有初始设置的值呢?当然可以自己读取资源中的xml文件,然后手动写程序保存到SharedPreference中,可这样太麻烦了一点都不方便、不专业。

        经过我的一番搜索研究,发现最好的方法就是使用Preference管理设置,android sdk已内置了良好的支持,所有的功能都在android.preference这个命名空间中。经学习发现这个preference的管理是和SharedPreference结合实现的,完美的实现了我的需求,并且是实现了和android系统设置中一样的设置管理界面,显得很专业微笑。闲言少叙,下面就具体来看如何使用preference实现配置功能。

        一、建立配置文件。

        在项目res目录下xml目录下(如果没有请建立)建立一个settings.xml的xml文件(文件名不一定叫settings,但是一定要放在xml目录下),文件内容如下:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:title="Settings" >

    <PreferenceCategory android:key="general" android:title="基本设置">
			<ListPreference android:key="superman" android:entries="@array/choice"  android:entryValues="@array/choiceId" 
			    android:dialogTitle="我的最爱" android:summary=""
			    android:defaultValue="value5" android:title="你选哪个"/>    
			<CheckBoxPreference android:key="bigman" android:title="我要做大英雄"
            android:defaultValue="true"
            android:summaryOn="唯大英雄能本色,是真名士自风流" android:summaryOff="请君暂上凌烟阁,若个书生万户侯"/>
			<EditTextPreference
            android:defaultValue="宁可我负天下人,不可天下人负我!"
            android:key="maxim"
            android:summary="有了信仰就要干,不要无志者常立志"
            android:title="我最爱的格言" />    
      <EditTextPreference
            android:defaultValue="星球大战"
            android:key="favoriteFilm"
            android:summary="没有最好,只有更好"
            android:title="我最爱的电影" /> 
    </PreferenceCategory>
    <PreferenceCategory android:key="advanced" android:title="高级设置">
    <PreferenceScreen android:key="basicSettings" android:title="高级设置" android:summary="点击进入高级设置" >
        <CheckBoxPreference android:key="checkVersion" android:title="自动更新"
            android:defaultValue="false"
            android:summaryOn="程序将每隔一段时间自动检查新版本" android:summaryOff="自动更新已关闭"/>
        <EditTextPreference
            android:defaultValue="1"
            android:key="checkVersionTime"
            android:summary=""
            android:title="检查新版本间隔时间(天)" />
        <EditTextPreference
            android:defaultValue="http://192.168.0.99:8008/crx/xtgl.User"
            android:key="url"
            android:summary=""
            android:title="URL" />

        <EditTextPreference
            android:defaultValue="http://60.29.99.76:8008/crx/xtgl.Unit?__fn_=initdata"
            android:key="url1"
            android:summary=""
            android:title="URL2" />

        <EditTextPreference
            android:defaultValue="htt2.p://192.168.0.100:8558/crx/manage.HistVote"
            android:key="URL3"
            android:summary=""
            android:title="URL3" />
        
    </PreferenceScreen>
	</PreferenceCategory>
</PreferenceScreen>


         文件的根元素就是PreferenceScreen,望文生义,就是一个屏幕显示的配置内容,并且可以嵌套使用。PreferenceScreen下面还可以分类,这就是PreferenceCategory元素,并且PreferenceCategory元素下面同样可以嵌套PreferenceScreen元素(其实PreferenceScreen就是PreferenceCategory的子类)。详细的配置内容可用的元素有EditTextPreference,CheckBoxPreference,ListPreference,Preference,RingtongPreference......

        从上面的配置文件中可以看出一个Preference配置项目主要拥有的属性。其中Key为这个PreferenceID,设置了才可以在代码中引用,Title是显示的标题,Summary是显示在标题下的文字介绍,Dependency是指依赖的其他配置项(注:一般在Dependency中填写一个CheckBoxPreferenceKey,这样就会在填写的那个CheckBoxPreference勾选时当前这个Preference才可用),Default Value为初始值,等等。其他的请大家自己看sdk,在这里就不赘述了。

        值得一提的就是ListPreference的使用稍微复杂一些,ListPreference除了继承自Preference的属性外,还有自己ListPreference的属性和继承自DialogPreference的属性。其中属于ListPreference的属性有两个:Entries填的为一个字符串数组,是列表显示出来的值(用户看到的说明文字),而Entry Values是实际要保存的值对应的字符串数组。DialogPreference只要填一个Dialog title标题和一个取消按钮显示的字即可。下面建立两个String array供ListPreference的选择对话框使用,在res/values目录下建立一个新的myarrays.xml文件(文件名随便),内容如下.

 

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="choice">
        <item >超人</item>
        <item >蜘蛛侠</item>
        <item >夜魔侠</item>
        <item >青蜂侠</item>
        <item >蝙蝠侠</item>
        <item >闪电侠</item>
        <item >钢铁侠</item>
        <item >超胆侠</item>
        <item >绿灯侠</item>
    </string-array>
    <string-array name="choiceId">
        <item >value1</item>
        <item >value2</item>
        <item >value3</item>
        <item >value4</item>
        <item >value5</item>
        <item >value6</item>
        <item >value7</item>
        <item >value8</item>
        <item >value9</item>
    </string-array>
    
</resources>
好了,我们的前期准备已经搞定了。

 

       二、读取配置内容。

       配置信息已经建好了,下面就是读取了,怎么读取呢?看到网上的解决方法很简单,就是得到默认的SharedPreference,然后按照Preference的key值读取,好的,马上试验:在Activity中添加一个按钮BtnTestConfig,设置OnClick事件如下:

OnClickListener onBtnTestConfig = new OnClickListener() {
		public void onClick(View v) {
			String s = "not read!";
			IndexActivity me = IndexActivity.this;
			SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(me);
			try {
				s = sp.getString("favoriteFilm", s);
			} catch (Exception e) {
				e.printStackTrace();
			}
			DialogUtil.ShowMsgDlg(IndexActivity.this, String.valueOf(s));
		}
	};
可是一运行发现,显示的是程序中给出的默认值,根本不是配置写的“星球大战”!咋回事儿呢,老办法google一下,发现有说要用XmlResourceParser自己解析XML,可是这就有违初衷了!不行再搜,终于在老外哪里找到了,原来android不会自动将你的Preference配置同步到SharedPreference中,所以需要用到PreferenceManager.setDefaultValues(Context context, int resId, boolean readAgain)方法,修改程序如下:

 

 

OnClickListener onBtnTestConfig = new OnClickListener() {
		public void onClick(View v) {
			String s = "not read!";
			IndexActivity me = IndexActivity.this;
			PreferenceManager.setDefaultValues(IndexActivity.this, R.xml.settings, true);
			SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(me);
			
			try {
				s = sp.getString("favoriteFilm", s);
			} catch (Exception e) {
				e.printStackTrace();
			}
			DialogUtil.ShowMsgDlg(IndexActivity.this, String.valueOf(s));
		}
	};
再次运行,ok,终于读到了!这里注意PreferenceManager.setDefaultValues方法的第三个参数readAgain,false表示只会执行一次,也就是说SharedPreference已经同步过一次,此函数就不会再执行了,这样如果在调试阶段你会发现新增加的配置项目就读不到了(打开设置界面编辑后是可以的),所以调试时最好用true。当然这里只是试验,在实际程序中,最好放在主Activity中执行这个函数。另外,readAgain设为true,不会覆盖已经存在于SharedPreference中的配置值,不会造成用户修改的配置丢失。

 

注意,如果你想清除修改的配置,那么在你要这样

PreferenceManager.getDefaultSharedPreferences(Context context),之后调用
PreferenceManager.setDefaultValues(Context context, int resId, boolean readAgain),并且readAgain设为true)
       三、实现配置管理界面。

 

       到现在,Preference已经建立好并且可以读取了,那么怎么实现用户修改Preference设置呢?这个就更简单了,新建立一个Activity并继承PreferenceActivity,

 

public class MyPreference extends PreferenceActivity

 

然后再onCreate函数中这样写:

 

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.addPreferencesFromResource(R.xml.settings);
	}
然后要做的就是在主界面中添加菜单或按钮调用这个Activity(这个就赘述了),怎么样,是不是和系统的设置界面一样漂亮。

 


         四、更完美的设置界面。

         试了试,搞好的Preference界面,忽然发现了还有一个缺点,每个配置项目下面的Summary信息都是固定的,如果能够显示用户的当前设置那就完美了。废话少说还是网上学习去,过程不必细说,结果发现还真没有方便的手段可用。没办法,只能程序代码实现。所用技术就是Perference.setSummary这个函数。思想就是在初始化的时候,更据当前配置内容,遍历配置项设置summary内容,然后注册SharedPreference的OnSharedPreferenceChangeListener事件监听配置项的变化,随时更新已变化项目的summary信息。

        由于需要注册OnSharedPreferenceChangeListener事件,所以我们的Activity还要实现OnSharedPreferenceChangeListener这个接口。

 

public class MyPreference extends PreferenceActivity implements OnSharedPreferenceChangeListener {
        然后添加三个方法:

 

 

/**
	 * Set the summaries of all preferences
	 */
	private void initSummaries(PreferenceGroup pg) {
		for (int i = 0; i < pg.getPreferenceCount(); ++i) {
			Preference p = pg.getPreference(i);
			if (p instanceof PreferenceGroup)
				this.initSummaries((PreferenceGroup) p); // recursion
			else
				this.setSummary(p);
		}
	}

	/**
	 * Set the summaries of the given preference
	 */
	private void setSummary(Preference pref) {
		// react on type or key
		if (pref instanceof ListPreference) {
			ListPreference listPref = (ListPreference) pref;
			listPref.setSummary(listPref.getEntry());
		}
		if (pref instanceof EditTextPreference) {
			EditTextPreference etp = (EditTextPreference) pref;
			etp.setSummary(etp.getText());
		}

	}

	/**
	 * used to change the summary of a preference
	 */
	public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
		Toast.makeText(this, "preference changed! " + key, 3000);
		Preference pref = findPreference(key);
		this.setSummary(pref);
	}

      最后在onCrate方法中添加两行代码:

 

 

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	this.addPreferencesFromResource(R.xml.settings);
	this.getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
      this.initSummaries(this.getPreferenceScreen());
}
ok,打完收工,运行起来再看效果:

 


怎么样,堪称完美吧。吐舌头下面试试我们的ListPreference,选择一个新的英雄:

 

 

选择完成后,再看Preference管理界面,提示信息已变为“夜魔侠”一切ok。

没有更多推荐了,返回首页