分类:Android
android相关知识
CMake 手册详解目录
9、CMake手册详解 (九)内容为else elseif enable_language enable_testing endforeach endfunction endif endmacro endwhile
execute_process export
10、file< 文件操作命令
16 、CMake 手册详解(十六)foreach
function
get_cmake_property
get_directory_property
get_filename_component
onInterceptTouchEvent和onTouchEvent
本帖记录onInterceptTouchEvent和onTouchEvent调用关系,即各种return true和return false的运行情况。
return true和return false,代表的是是否消费完该事件,也就是该事件是否会继续传递给下层或者上层组件继续处理。return true代表消费完不会继续传递,return false代表没有消费完将会继续传递。
如果没有onInterceptTouchEvent,只考虑onTouchEvent的话,比较容易分析和理解。假如有三层布局结构,linearLayout1,linearLayout2,textView,从前到后是包含的关系。那么下面分情况说明。
1.如果它们的onTouchEvent都返回false的话,DOWN事件会自上而下(textView位于最上层)依次传递,最终都没有消费完此事件,都只会进入onTouchEvent方法一次并且MotionEvent的action为MotionEvent.ACTION_DOWN,move和up等事件不会继续处理。
2.如果textView的onTouchEvent返回true,表示textView消费了此事件,不会传给父组件linearLayout2和linearLayout1了,并且还会继续处理move和up等事件。
3.linearLayout2和linearLayout1的onTouchEvent返回true和上面的情况一样,都不会继续传给父容器而且本身继续处理move和up等事件。
OK,这种情况还是比较容易理解的。
下面加入onInterceptTouchEvent。
onInterceptTouchEvent只有ViewGroup才会有,用于在进入自身onTouchEvent或者子组件onTouchEvent之前处理事件。注意onTouch是自上而下传递,而onInterceptTouch却是由下而上传递的。来了一个DOWN事件,首先进入的必然是最底层的viewGroup的onInterceptTouchEvent方法,然后根据return的值进入自身或者子组件的onTouch事件,当然如果子组件也是viewgroup的话,在进入子组件的onTouch之前也会进入子组件的onInterceptTouchEvent方法。
下面也分几种情况介绍:
1.当onInterceptTouchEvent返回false时,表示没有消费完此事件,会继续传递个子组件的onTouch继续处理。注意这种情况不会就不会传递给这个ViewGroup自身的onTouch事件处理了。这和onTouch如果返回false,后续的move、up等事件都不会继续处理了可以做同样理解。
2.当onInterceptTouchEvent返回true时,表示消费完此事件,或者说将在此组件上消费该事件。这种情况该事件会传递给ViewGroup自身的onTouch事件去处理,而不会传递给子组件的onTouch方法了。
由此可以总结,onInterceptTouchEvent返回值只是决定了是要把事件传递给自身的onTouch事件还是传递给子组件的onTouch事件。返回false表示没有消费完将传递个子组件的onTouch方法,返回true表示自身消费此事件,将传递给自身的onTouch方法而不会传递给子组件的onTouch方法了。
android 设置APN
android的APN设置,也就是移动网络的接入点设置,有些时候可能项目需要会用到一些专用的apn专网,如果需要用户去手动设置的话显然可行性不高,所以需要在代码中自动为客户生成一个接入点,并在应用启动的时候自动切换到改接入点,退出的时候重新换回用户的默认接入点,这里只讲关键技术点,具体实现自行研究,实践才能出真知;
1、首先了解一下APN的位置,
// APN列表资源
private static Uri APN_LIST_URI = Uri.parse(“content://telephony/carriers”);
// 默认APN资源(当前正在使用的apn)
private static Uri PREFERRED_APN_URI = Uri.parse(“content://telephony/carriers/preferapn”);
2、检测一个APN是否存
int id = -1;
ContentResolver resolver = context.getContentResolver();
Cursor c = resolver.query(APN_LIST_URI, new String[] { “_id”, “name”, “apn” }, “apn like ‘%myapn%'”, null, null); //从apn列表中查找apn名称为myapn的apn信息
if (c != null && c.moveToNext()) {
id = c.getShort(c.getColumnIndex(“_id”)); //获取该apn的id信息
System.out.println(“APN已经存在”);
} else {
System.out.println(“APN不存在”);
}
3、添加一个新的APN,设置apn的信息还需要获取当前SIM卡的运营商信息
protected String getSIMInfo() {
TelephonyManager iPhoneManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return iPhoneManager.getSimOperator();
}
public int AddXFTApn() {
System.out.println(“添加一个新的apn ==> XFT APN”);
int apnId = -1;
String NUMERIC = getSIMInfo();
if (NUMERIC == null) {
Toast.makeText(context, “不存在SIM卡”, Toast.LENGTH_SHORT).show();
return -1;
}
ContentResolver resolver = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(“name”,“专用APN”); //apn中文描述
values.put(“apn”, “myapn”); //apn名称
values.put(“type”, “default,supl”);
values.put(“numeric”, NUMERIC);
values.put(“mcc”, NUMERIC.substring(0, 3));
values.put(“mnc”, NUMERIC.substring(3, NUMERIC.length()));
values.put(“proxy”, “”);
values.put(“port”, “”);
values.put(“mmsproxy”, “”);
values.put(“mmsport”, “”);
values.put(“user”, “”);
values.put(“server”, “”);
values.put(“password”, “”);
values.put(“mmsc”, “”);
Cursor c = null;
// 获取新添加的apn的ID
try {
Uri newRow = resolver.insert(APN_LIST_URI, values);
if (newRow != null) {
c = resolver.query(newRow, null, null, null, null);
int idindex = c.getColumnIndex(“_id”);
c.moveToFirst();
apnId = idindex;
}
} catch (SQLException e) {
e.printStackTrace();
}
if (c != null)
c.close();
return apnId;
}
4、设置使用指定的apn接入点连接网络
public boolean setDefaultApn(int apnId) {
// System.out.println(“设置选中的apnID ==》 ” + apnId);
boolean res = false;
ContentResolver resolver = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(“apn_id”, apnId);
try {
resolver.update(PREFERRED_APN_URI, values, null, null);
Cursor c = resolver.query(PREFERRED_APN_URI, new String[] { “name”, “apn” }, “_id=” + apnId, null, null);
if (c != null) {
res = true;
c.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
return res;
}
如何打开Anroid系统自带邮件应用
在网上很容易找到如何调用系统自带的邮件系统发送邮件,但是关于如何打开邮件应用的主界面的文章很少。
android系统一般都会带系统自带的Email应用,包括一些定制机。android自带的Email应用的包名是com.android.email,这个可以从应用管理器中查找到。只有一个包名信息打开应用不太可能。android系统允许通过组件名(ComponentName)打开一个应用。组件是包含应用包名和主Activity的对象。如何找到Email的主Activity呢?通过执行如下代码可以列如系统中所有应用的主Activity类和主包名。
private String listPackage() {
List<ApplicationInfo> mApplications = null;
PackageManager manager = getPackageManager();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); // 取出Intent
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); // 分辨出位默认Laucher启动的程序
final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0); // 利用包管理器将起取出来
Collections.sort(apps, new ResolveInfo.DisplayNameComparator(manager));
StringBuffer sb = new StringBuffer();
if (apps != null) {
final int count = apps.size();
if (mApplications == null) {
mApplications = new ArrayList<ApplicationInfo>(count);
}
mApplications.clear();
for (int i = 0; i < count; i++) {
ResolveInfo info = apps.get(i);
sb.append(“Label:”).append(info.loadLabel(manager)).append(“;\n\r”);
sb.append(“packageName:”).append(info.activityInfo.applicationInfo.packageName).append(“;\n\r”);
sb.append(“name:”).append(info.activityInfo.name).append(“;\n\r”);
sb.append(“icon:”).append(info.activityInfo.loadIcon(manager)).append(“\n\r\n\r”);
}
}
return sb.toString();
}
通过查找发现Email的主Activity的类名是com.android.email.activity.Welcome。这样打开邮件主界面就很易容了。
ApplicationInfo application = new ApplicationInfo();
application.name = “电邮”;
application.className = “com.android.email.activity.Welcome”;
application.packageName = “com.android.email”;
ComponentName c = new ComponentName(“com.android.email”,”com.android.email.activity.Welcome”);
Intent intent = new Intent();
intent.setComponent(c);
startActivity(intent);
用DisplayMetrics判断屏幕密度
如果用下述代码判断屏幕密度,只能识别出密度为240,160,120的屏幕,其它的将无法识别;
DisplayMetrics dm = new DisplayMetrics();
switch (dm.densityDpi) {
case DisplayMetrics.DENSITY_HIGH:
break;
case DisplayMetrics.DENSITY_MEDIUM:
break;
case DisplayMetrics.DENSITY_LOW:
break;
default :
}
因为android终端种类很多,比如魅族M9的为320 所以在识别时最好加对上不是上述三种类型手机的处理:
DisplayMetrics dm = new DisplayMetrics();
switch (dm.densityDpi) {
case DisplayMetrics.DENSITY_HIGH:
break;
case DisplayMetrics.DENSITY_MEDIUM:
break;
case DisplayMetrics.DENSITY_LOW:
break;
default :
if(dm.densityDpi>DisplayMetrics.DENSITY_HIGH){
} else if(dm.densityDpi < DisplayMetrics.DENSITY_LOW){
} else {
}
}
android: 不需要焦点的 TextView跑马灯 MarqueeTextView
public class MarqueeTextView extends TextView {
public MarqueeTextView(Context appCon) {
super(appCon);
}
public MarqueeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MarqueeTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean isFocused() {
return true;
}
@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
}
}
android文字阴影效果
最近用到文字的阴影效果,特将研究结果写 篇文章。 关于android文字阴影,共有四个属性可以 设置: android:shadowColor :阴影颜色 android:shadowDx :阴影x方向位移 android:shadowDy :阴影y方向位移 android:shadowRadius :阴影的半径 注意:阴影的半径必须设,为0时没有效 果。 下面为改变x位移: android:shadowColor=”#ff000000″
两位为透明度) android:shadowDx=”2″ android:shadowDy=”0″ android:shadowRadius=”1″ 效果(向右为正)
下面为改变y位移: android:textColor=”#979790″ android:shadowColor=”#ff000000″ android:shadowDx=”0″ android:shadowDy=”2″ android:shadowRadius=”1″ 效果(向下为正)
下面改变半径: android:shadowDx=”1″ android:shadowDy=”1″ android:shadowRadius=”1″
阅
android SQLite3
SQLite库可以解析大部分标准SQL语言。但它也省去了一些特性 并且加入了一些自己的新特性。这篇文档就是试图描述那些SQLite支持/不支持的SQL语法的。查看关键字列表 。
如下语法表格中,纯文本用蓝色粗体显示。非终极符号为斜体红色。作为语法一部分的运算符用黑色Roman字体表示。
这篇文档只是对SQLite实现的SQL语法的综述,有所忽略。想要得到更详细的信息,参考源代码和语法文件“parse.y”。 继续阅读android SQLite3
Android下的图形引擎
最低运行环境要求不详。
项目地址:code.google.com/p/angle/ 继续阅读Android下的图形引擎