定义注解类型int取代enum
public static final int LEVEL_FETCH_NONE=0; public static final int LEVEL_FETCH_FULL=1; public static final int LEVEL_FETCH_DISK=2; public static final int LEVEL_FETCH_MEMORY=3; @IntDef(flag=true, value={ImageFetchType.LEVEL_FETCH_FULL,ImageFetchType.LEVEL_FETCH_DISK,ImageFetchType.LEVEL_FETCH_MEMORY}) @Retention(RetentionPolicy.SOURCE) public @interface ImageFetchLevel { }
paint字体
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/digit.TTF");
digitPaint.setTypeface(typeface); digitPaint.setTextAlign(Paint.Align.CENTER);
//直接获取系统对应类型Service,不用强制转型
@SuppressWarnings("unchecked")
static <T> T getService(Context context, String service) {
return (T) context.getSystemService(service);
}
AudioManager audiomanage =getService(mContext,Context.AUDIO_SERVICE);
//检测应用是否有某项权限,
例如检测是否有网络,
hasPermission(context, Manifest.permission.ACCESS_NETWORK_STATE);
static boolean hasPermission(Context context, String permission) {
return context.checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
}
dump Thread stack信息
1,Thread.currentThread().getStackTrace().
2,new Throwable().getStackTrace()
3,Log.d("myapp", Log.getStackTraceString(new Exception()));
线程栈内方法调用 :
String methodName =
Thread.currentThread().getStackTrace()[1].getMethodName();
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
//获取当前函数的函数名称
Thread.currentThread().getStackTrace()[2].getMethodName();
//打印当前函数的系统调用堆栈
java.util.Map<Thread, StackTraceElement[]> ts = Thread.getAllStackTraces(); StackTraceElement[] ste = ts.get(Thread.currentThread()); for (StackTraceElement s : ste) { Log.i(TAG, "StackTraceElement :"+s.toString()); }
获取线程栈异常信息:
public void getInfo(){ String location=""; StackTraceElement[] stacks = Thread.currentThread().getStackTrace(); location = "类名:"+stacks[2].getClassName() + " 函数名:" + stacks[2].getMethodName() + " 文件名:" + stacks[2].getFileName() + " 行号:" + stacks[2].getLineNumber() + ""; System.out.println(location); }
获取异常信息的详细
public static String getExceptionMessage(Exception ex){ String result=""; StackTraceElement[] stes = ex.getStackTrace(); for(int i=0;i<stes.length;i++){ result=result+stes[i].getClassName() + "." + stes[i].getMethodName() + " " + stes[i].getLineNumber() +"line" +" "; } return result; } static String getStackTrace(Throwable t) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw, true); t.printStackTrace(pw); pw.flush(); sw.flush(); return sw.toString(); } String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e) Apache Arrays.toString(Thread.currentThread().getStackTrace())
判断主线程:
static boolean isMain() { return Looper.getMainLooper().getThread() == Thread.currentThread(); } private static void runOnWorkerThread(Runnable r) { if (sWorkerThread.getThreadId() == Process.myTid()) { r.run(); } else { // If we are not on the worker thread, then post to the worker handler sWorker.post(r); } }
字符串md5值:
//字节数组转化为16进制字符串 public static String byteArrayToHex(byte[] byteArray) { char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F' }; char[] resultCharArray =new char[byteArray.length * 2]; int index = 0; for (byte b : byteArray) { resultCharArray[index++] = hexDigits[b>>> 4 & 0xf]; resultCharArray[index++] = hexDigits[b & 0xf]; } return new String(resultCharArray); } //字节数组md5算法 public static byte[] md5 (byte [] bytes) { try { MessageDigest messageDigest = MessageDigest.getInstance("MD5"); messageDigest.update(bytes); return messageDigest.digest(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; }
ActivityManager.clearApplicationUserData() 一键清理你的app产生的用户数据
packageManager
可以用来启动或者禁用程序清单中的组件。对于关闭不需要的功能组件是非常赞的,比如关掉一个当前不用的广播接收器。
public abstract void setComponentEnabledSetting(ComponentName componentName, int newState, int flags)
Set the enabled setting for a package component (activity, receiver, service, provider)
args1:COMPONENT_ENABLED_STATE_ENABLED, COMPONENT_ENABLED_STATE_DISABLED and COMPONENT_ENABLED_STATE_DEFAULT
args2:0
微信分享功能、
测试要签名
1,在接入微信客户端的过程中一定要注意:首先判断是否安装有微信(使用IWXAPI类的isWXAppInstalled()方法),否则你会发现程序是正确的,但是无论如何都不会得到想要的结果,也不会报任何错误。
2、在接入微信客户端的过程中一定要注意:当前的微信版本是否是4.0(使用IWXAPI类的isWXAppSupporAPI()方法),后果如上。
3、在接入微信客户端的过程中一定要注意:分享图片的时候,SDK协议中对缩略图的大小作了限制,大小不能超过32K。另外限制的还有title、description等参数的大小,否则后果如上。
4、如果你的程序需要接收微信发送的请求,或者接收发送到微信请求的响应结果,需要下面3步操作:
a、在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个WXEntryActivity类,该类继承自Activity,并在manifest文件里面加上exported属性,设置为true。
b、 实现IWXAPIEventHandler接口,微信发送的请求将回调到onReq方法,发送到微信请求的响应结果将回调到onResp方法
c、在WXEntryActivity中将接收到的intent及实现了IWXAPIEventHandler接口的对象传递给IWXAPI接口的handleIntent方法。
d、当微信发送请求到你的应用,将通过IWXAPIEventHandler接口的onReq方法进行回调,类似的,应用请求微信的响应结果将通过onResp回调。
最后应该注意:微信开放平台分享图片Url是一个bug,貌似是分享不了的,现在不知道这个bug修复了没有。
########################
静默安装方法:
public void SilentInstall(Context mContext,String packageName, String path) { Uri uri = Uri.fromFile(new File(path)); int installFlags = 0; PackageManager pm = mContext.getPackageManager(); try { PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES); if (packageInfo != null) { installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; } } catch (NameNotFoundException e) { //Log.e(TAG, "NameNotFoundException = " + e.getMessage()); } PackageInstallObserver observer = new PackageInstallObserver(mContext); pm.installPackage(uri, observer, installFlags, packageName); }
创建PackageInstallObserver .java安装监听(安装是否成功)
class PackageInstallObserver extends IPackageInstallObserver.Stub { private Context mcontext; public PackageInstallObserver(Context context){ this.mcontext=context; } public void packageInstalled(String packageName, int returnCode) { Looper.prepare(); if (returnCode == 1) { Toast.makeText(mcontext, "install Success!", Toast.LENGTH_LONG).show(); } else { Toast.makeText(mcontext, "install fail!", Toast.LENGTH_LONG).show(); } Looper.loop(); } }
IPackageInstallObserver.Stub为系统隐藏类,需要引入import android.content.pm.IPackageInstallObserver;
卸载方法:
public void SilentUnstall(Context mContext,String packageName){ PackageDeleteObserver observer = new PackageDeleteObserver(mContext); mContext.getPackageManager().deletePackage(packageName, observer, 0); }
卸载监听:
class PackageDeleteObserver extends IPackageDeleteObserver.Stub { private Context mcontext; public PackageDeleteObserver(Context context){ this.mcontext=context; } public void packageDeleted(String packageName, int returnCode) { Looper.prepare(); if (returnCode == 1) { Toast.makeText(mcontext, "unstall Success!", Toast.LENGTH_LONG).show(); } else { Toast.makeText(mcontext, "unstall fail!", Toast.LENGTH_LONG).show(); } Looper.loop(); } }
需要引入import android.content.pm.IPackageDeleteObserver;
添加权限:
<uses-permission android:name="android.permission.INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.DELETE_PACKAGES" />
加上系统签名,以获取更高权限 android:sharedUserId="android.uid.system"
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.pioneersoft.pacakgeapp" android:sharedUserId="android.uid.system" android:versionCode="1" android:versionName="1.0" >
在根目录下创建编写Android.mk文件,这里Android.mk我是从 源码package/APP/PackageInstaller中的Android.mk拷贝过来,
然后修改LOCAL_PACKAGE_NAME := //你的项目名称
完整文件如下:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := PackageApp LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE)
做完上述所有步骤之后,就可以将这个项目放在源码环境下编译了,在源码编译前需要删除gen,bin目录,然后进行编译
编译成成功后会在out argetproductleader75_6628_ics2systemapp生成改项目的apk,然后push到system/app或者编译在升级包里面就可以使用了
调用android系统关机,重启命令:
准备条件:
1,设备root
2,源码下编译程序
调用关机:
启动关机应用,去掉确认对话框就可以
private void shutdownDevice(){ Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN); intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); }
调用重启:调用系统API实现
private void restartDevice() { PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE); powerManager.reboot(null); }
所需权限:
<uses-permission android:name="android.permission.SHUTDOWN"/> <uses-permission android:name="android.permission.REBOOT"/> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> <uses-permission android:name="android.permission.DEVICE_POWER" />
编译前添加系统签名: android:sharedUserId="android.uid.system"
这里注意问题:
Intent.ACTION_REQUEST_SHUTDOWN
Intent.EXTRA_KEY_CONFIRM
会报错,这是因为该属性是 {@hide} 的。
不要担心放到系统编译就可以了,注意下面的步骤即可。
如果编译成功,在 /out/target/product/generic/system/app 目录下面,会多一个 reboot.apk 文件。
将该 apk 必须放到 system/app 下面,即 adb push reboot.apk /system/app就可以了。