一、一般在代码中的调用,要么通过id找到,要么直接new出来:

①、调用setTextSize(<数值单位>,<值>)

这里的数值单位可以为下列的几种:

TypedValue.COMPLEX_UNIT_PX
TypedValue.COMPLEX_UNIT_DIP
TypedValue.COMPLEX_UNIT_SP

当然还有不常用的,比如

TypedValue.COMPLEX_UNIT_PT

1 .如果直接使用固定的数值,那么该数值的单位则由上述的几种枚举决定,比如:

setTextSize(TypedValue.COMPLEX_UNIT_SP,16);//就是设置为16sp的大小

2 .如果使用资源文件中的数值,那么请注意,数值单位 要设置为 COMPLEX_UNIT_PX,比如:

setTextSize(TypedValue.COMPLEX_UNIT_PX,getResources().getDimensionPixelSize(R.dimen.你的资源);

 原因如下

* 获取dimension的方法有几种,区别不大
* 共同点是都会将dp,sp的单位转为px,px单位的保持不变
*
* getDimension() 返回float
* getDimensionPixelSize 返回int 小数部分四舍五入
* getDimensionPixelOffset 返回int,但是会抹去小数部分

getDimensionPixelSize在要求不高的情况下也可以替换为getDimensionPixelSize或者getDimensionPixelOffset,具体根据业务需求决定

②、调用setTextSize(<Size>):

这个方法不带单位,Doc的描述如下:

Set the default text size to the given value, interpreted as “scaled pixel” units. This size is adjusted based on the current density and user font size preference.

大意就是,Size单位是px且当设置为某个值的时候,最后会乘一个destiny后显示出来

没例子,也不建议用

二、自定义控件中调用:

①、使用paint直接画TextView:

调用paint.setTextSize(<px值>)即可

②、在declare-styleable中定义size,在xml中设置size,代码中通过TypedArray取出来:

这是比较常见的情况,此时通过调用TypedArray的对象调用getDimension,getDimensionPixelSize 或者getDimensionPixelOffset 方法来获取。同样的,返回结果是以px为单位的

然后,同(一)里面的做法,设置大小即可

继续阅读

一直以来都被这个onNewIntent(Intent intent)的用法所困扰,直到近期才理解了其用法!

简而言之,如果要通过intent来跳转一个之前已存在/不存在的Activity,onNewIntent(Intent intent)则有可能被调用。

什么意思呢,请看以下解释:

①,如果IntentActivity处于任务栈的顶端,也就是说之前打开过的Activity,现在处于onPause、onStop 状态的话,其他应用再发送Intent的话,执行顺序为:
onNewIntent,onRestart,onStart,onResume。。。

②,系统可能会随时杀掉后台运行的 Activity ,如果这一切发生,那么系统就会调用 onCreate 方法,而不调用 onNewIntent 方法

所以,如果要保证该Activity一定要处理intent,一个好的解决方法就是在 onCreate 和 onNewIntent 方法中调用同一个处理数据的方法。

另外,一般情况下会让这个Activity的启动模式设置为singleTask,以防止实例化多个Activity(如此基本可以让onNewIntent得到调用)

技巧:在onNewIntent里面调用setIntent(Intent intent)可以覆盖原有的intent,但是要慎用

举个简单的例子:Activity A是有5个Tab的FragmentActivity,Activity B是一个普通Activity,包含一个按钮button1。A中的Tab1里面有个button2,点击button2跳转到B。如果点击B中的button1需要跳转回Activity A且让Tab选中在第5个,此时可以将A设置为singleTask,button1点击事件直接设置intent的extra然后调用startActivity(Intent intent),然后在A的onNewIntent中处理。最好在onCreate中也处理一下intent,防止A被销毁后不走onNewIntent

参考:https://my.oschina.net/xsjayz/blog/138447

support-v4中的fragment在现在看来显得有些老旧,因为现在的手机绝大部分都是4.X系统以上了,所以v4包中的fragment其实可以甩掉了。本文教你如何从v4包的fragment转换到原生fragment

首先你要确定一件事情——你想要你的app兼容到哪个系统。如果你想放弃过时的2.X系统,那么就请继续往下看吧

从v4的fragment转换到原生的fragment其实并不困难,有几点需要注意:

1)导入的包:

请将android.support.v4.app.fragment替换为android.app.fragment;

同样的,FragmentManager请替换为android.app.FragmentManager,以及FragmentTransaction

2)修改Activity:

一般情况下继承AppCompatActivity即可,这个也是AS默认的Activity继承类

3)如果使用了viewpager的话,请不要改动viewpager的引用

4)调用viewpager的setAdapter方法的时候,需要实现一个继承于android.support.v13.app.FragmentStatePagerAdapter的适配器,而这个类的引用方式需要引入v13的包:

compile ‘com.android.support:support-v13:23.3.0’

基本就是以上注意点,除此之外的用法均和support-v4中的一致。如果还有其他注意要点的话我会继续补充~

在Android5.0以前的版本中,可以通过简单的反射机制来直接控制手机网络的打开与关闭:

ConnectivityManager connectivityManager =
        (ConnectivityManager) pContext.getSystemService(Context.CONNECTIVITY_SERVICE);
Method setMobileDataEnabl;
try {
    setMobileDataEnabl = connectivityManager.getClass().getDeclaredMethod("setMobileDataEnabled", boolean.class);
    setMobileDataEnabl.invoke(connectivityManager, pBoolean);
} catch (Exception e) {
    e.printStackTrace();
    Log.e("MobileUtil", "移动数据设置错误:" + e.toString());
}

但是,在Android5.0版本及以上,这方法就失效了,于是在StackOverFlow上面有大神提出一个解决方案,前提是手机必须能获取到Root权限:

private static void executeCommandViaSu(Context context, String option, String command) {
    boolean success = false;
    String su = "su";
    for (int i=0; i < 3; i++) {
        // Default "su" command executed successfully, then quit.
        if (success) {
            break;
        }
        // Else, execute other "su" commands.
        if (i == 1) {
            su = "/system/xbin/su";
        } else if (i == 2) {
            su = "/system/bin/su";
        }
        try {
            // Execute command as "su".
            Runtime.getRuntime().exec(new String[]{su, option, command});
        } catch (IOException e) {
            success = false;
            // Oops! Cannot execute `su` for some reason.
            // Log error here.
        } finally {
            success = true;
        }
    }
}
public static void setMobileNetworkfromLollipop(Context context,boolean ii) throws Exception {
    String command = null;
    int state=0;
    if(ii){
        state=1;
    }
    try {
        String transactionCode = getTransactionCode(context);
        // Android 5.1+ (API 22) and later.
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            SubscriptionManager mSubscriptionManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
            // Loop through the subscription list i.e. SIM list.
            for (int i = 0; i < mSubscriptionManager.getActiveSubscriptionInfoCountMax(); i++) {
                if (transactionCode != null && transactionCode.length() > 0) {
                    // Get the active subscription ID for a given SIM card.
                    int subscriptionId = mSubscriptionManager.getActiveSubscriptionInfoList().get(i).getSubscriptionId();
                    // Execute the command via `su` to turn off
                    // mobile network for a subscription service.
                    command = "service call phone " + transactionCode + " i32 " + subscriptionId + " i32 " + state;
                    executeCommandViaSu(context, "-c", command);
                }
            }
        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
            // Android 5.0 (API 21) only.
            if (transactionCode != null && transactionCode.length() > 0) {
                // Execute the command via `su` to turn off mobile network.
                command = "service call phone " + transactionCode + " i32 " + state;
                executeCommandViaSu(context, "-c", command);
            }
        }
    } catch(Exception e) {
        // Oops! Something went wrong, so we throw the exception here.
        throw e;
    }
}
private static String getTransactionCode(Context context) throws Exception {
    try {
        final TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        final Class<?> mTelephonyClass = Class.forName(mTelephonyManager.getClass().getName());
        final Method mTelephonyMethod = mTelephonyClass.getDeclaredMethod("getITelephony");
        mTelephonyMethod.setAccessible(true);
        final Object mTelephonyStub = mTelephonyMethod.invoke(mTelephonyManager);
        final Class<?> mTelephonyStubClass = Class.forName(mTelephonyStub.getClass().getName());
        final Class<?> mClass = mTelephonyStubClass.getDeclaringClass();
        final Field field = mClass.getDeclaredField("TRANSACTION_setDataEnabled");
        field.setAccessible(true);
        return String.valueOf(field.getInt(null));
    } catch (Exception e) {
        // The "TRANSACTION_setDataEnabled" field is not available,
        // or named differently in the current API level, so we throw
        // an exception and inform users that the method is not available.
        throw e;
    }
}

当代码中调用setMobileNetworkfromLollipop方法时,系统会提示应用要获取Root权限,其实这个方法的本质就是在Linux的终端中输入了svc data enable。。。 没有Root的机器是暂时没有解决办法的,因为只有root身份才能执行svc data enable。不知道这是不是Google故意把那个非公开api去掉了,不过回过头想想,不能直接使用这个方法也是为了考虑到系统的安全性,毕竟这个被滥用后会是一件非常麻烦的事 如果有别的方案可以开启数据连接的话欢迎提出来

对于android 3.0以下 的系统,使用Notification.Builder来创建通知;android3.0以上的系统,推荐使用NotificationCompat.Builder,当然也能使用Notification.Builder,这个NotificationCompat在v4包中。不推荐直接使用Notification来创建通知。

首先要获取NotificationManager:(这个无论什么版本的系统都是需要的)

NotificationManager nm = (NotificationManager)mContext.getSystemService(NOTIFICATION_SERVICE);

接下来就是创建一个通知

3.0以上系统写法:

NotificationCompat.Builder mBuilder;

mBuilder = new NotificationCompat.Builder(mContext);

3.0以下的写法:

Notification.Builder mBuilder;

mBuilder = new Notification.Builder(mContext);

其实写法都是大同小异的

有几个常用的设置属性的方法:

setContentTitle(String title) //设置通知的标题

setContentText(String content) //设置通知的内容

setTicker(String ticker)//设置通知出现的的时候显示在顶部/底部通知栏的提示消息

setSmallIcon(int resIcon)//设置通知的图标(经测试,此项必选,否则通知将不显示

setWhen(System.currentTimeMillis())//设置发送通知的时间为当前时间

setContentIntent(Intent contentIntent)//设置点击通知的时候要发送的pendingIntent

setAutoCancel(boolean cancelable)//设置通知是否能被清除

setProgress(int max,int progress,boolean indeterminate)//如果设置这个属性的话通知中就会显示一个进度条,进度值为progress,最大值为max

设置完毕后调用build()即可创建通知,该方法将返回一个Notification的实例

通知创建出来后需要通过NotificationManager来发送:

notify(int uniqueId,Notification notification);//uniqueId是全app的一个唯一id值,如果要清除或者更新这个通知的话需要将uniqueId设置为相同的值

如果要清除这个通知,调用这个方法:

cancel(int uniqueId);

(2015年8月8日补充)

其实在平时的开发中,为了能兼容低版本的系统,同时又为了减少代码中对版本号的判断,可以考虑直接使用NotificationCompat.Builder,因为这个可以说是通用的