设备相关信息:
计算设备尺寸:
public static double getScreenPhysicalSize(Activity ctx) { DisplayMetrics dm = new DisplayMetrics(); ctx.getWindowManager().getDefaultDisplay().getMetrics(dm); double diagonalPixels = Math.sqrt(Math.pow(dm.widthPixels, 2) + Math.pow(dm.heightPixels, 2)); return diagonalPixels / (160 * dm.density); }
public static boolean isTablet(Context context) { return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; }
获取状态栏和标题栏的高度
获取状态栏高度:
getWindowVisibleDisplayFrame方法可以获取到程序显示的区域,包括标题栏,但不包括状态栏。
于是,我们就可以算出状态栏的高度了。
Rect frame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
获取标题栏高度:
getWindow().findViewById(Window.ID_ANDROID_CONTENT)这个方法获取到的view就是程序不包括标题栏的部分,然后就可以知道标题栏的高度了。
int contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
//statusBarHeight是上面所求的状态栏的高度
int titleBarHeight = contentTop - statusBarHeight
隐去标题栏, 隐去状态栏 android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
设置透明背景,修改AndroidManifest.xml文件,在对应的Activity里面加上下面的属性:
android:theme="@android:style/Theme.Translucent"
使用系统背景作为应用的背景,在onCreate的时候添加窗口标志:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
android:theme="@android:style/Theme.Dialog"
//初始化屏幕分辨率
private void initDisplayMetrics()
{
/* 取得屏幕分辨率大小 */
DisplayMetrics dm=new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
this.width=dm.widthPixels;
this.height=dm.heightPixels;
}
计算字体宽度:
public static float GetTextWidth(String text, float Size) {
TextPaint FontPaint = new TextPaint();
FontPaint.setTextSize(Size);
return FontPaint.measureText(text);
}
文本分割处理
/** * 在文字信息绘制前对文本信息进行文字分割,文字间距,文字位置计算处理 * @param text */ private void initDrawText(String text){ if(texts==null){ texts=getTexts(text); } if(tposy==null){ tposy=getTextLinePosy(); } if(stepBack==null){ stepBack=new Float[tposy.length]; int i=0; float interval=0.0f; FontMetrics fm = textPaint.getFontMetrics(); float baseline = fm.descent - fm.ascent; while(i<stepBack.length){ stepBack[i]=interval; interval-=baseline; i++; } } if(step==null){ step=stepBack.clone(); } } /** * 获取分割后的文本信息 * @param text * @return */ private String[] getTexts(String text){ if(text.contains("\n")){ List<String> totalList=new ArrayList<String>(10); String[] str=text.split("\n"); int len=str.length; for(int i=0;i<len;i++){ String[] ss=autoSplit(str[i], textPaint, getWidth()/3*2); for(String s:ss){ totalList.add(s); } } if(texts==null) texts=(String[]) totalList.toArray(new String[0]); } else texts=autoSplit(text, textPaint, getWidth()/3*2); return texts; } /** * 获取每行文本的纵坐标信息 * @return */ private Float[] getTextLinePosy(){ FontMetrics fm = textPaint.getFontMetrics(); float baseline = fm.descent - fm.ascent; float y = posy+baseline; //由于系统基于字体的底部来绘制文本,所有需要加上字体的高度 int len=texts.length; Float[] groups=new Float[len]; for(int i=0;i<len;i++) { groups[i]=y; y =y+ baseline + fm.leading; //添加字体行间距 } return groups; } /** * 自动分割文本 * @param content 需要分割的文本 * @param p 画笔,用来根据字体测量文本的宽度 * @param width 最大的可显示像素(一般为控件的宽度) * @return 一个字符串数组,保存每行的文本 */ private String[] autoSplit(String content, Paint p, float width) { float textWidth = p.measureText(content); if(textWidth <= width) { return new String[]{content}; } int length = content.length(); int start = 0, end = 1, i = 0; int lines = (int) Math.ceil(textWidth / width); //计算行数 String[] lineTexts = new String[lines]; while(start < length) { if(p.measureText(content, start, end) > width) { //文本宽度超出控件宽度时 lineTexts[i++] = content.substring(start, end);//(String) content.subSequence(start, end); start = end; } if(end == length) { //不足一行的文本 lineTexts[i] = content.substring(start, end);//(String) content.subSequence(start, end); break; } end += 1; } return lineTexts; }
// 计算文本,行数,高度
FontMetrics fm = mTextView.getPaint().getFontMetrics();
mFontHeight = (int) (Math.ceil(fm.descent - fm.top) + 2);// 获得每行高度
mPageLineNum = (int) (mTextHeight / mFontHeight);// 获得行数
//TextView 分页设置相关
getLineBounds(int line, Rect bounds) // 得到指定行的边界
只要从第一行开始一行一行往下看, 直到找到超出边界的那一行, 就能知道这个 TextView 能显示多少行了.
或者用 getHeight() / getLineHeight() 也能获取 TextView 的最大显示行数
getLineForVertical(int vertical) // 根据纵坐标得到对应的行号
getLineEnd(int line) // 返回指定行中最后一个字在整个字符串中的位置
public class ReadView extends TextView { // 构造函数略... @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); resize(); } /** * 去除当前页无法显示的字 * @return 去掉的字数 */ public int resize() { CharSequence oldContent = getText(); CharSequence newContent = oldContent.subSequence(0, getCharNum()); setText(newContent); return oldContent.length() - newContent.length(); } /** * 获取当前页总字数 */ public int getCharNum() { return getLayout().getLineEnd(getLineNum()); } /** * 获取当前页总行数 */ public int getLineNum() { Layout layout = getLayout(); int topOfLastLine = getHeight() - getPaddingTop() - getPaddingBottom() - getLineHeight(); return layout.getLineForVertical(topOfLastLine); } }
//实际获取高度方法
/** * * @param pTextView * @return */ private int getTextViewHeight(TextView pTextView) { Layout layout = pTextView.getLayout(); int desired = layout.getLineTop(pTextView.getLineCount()); int padding = pTextView.getCompoundPaddingTop() + pTextView.getCompoundPaddingBottom(); return desired + padding; }
自定义View绘制文本时,格式化文本内容StaticLayout实现:
public void onDraw(Canvas canvas){ super.onDraw(canvas); TextPaint tp = new TextPaint(); tp.setColor(Color.BLUE); tp.setStyle(Style.FILL); tp.setTextSize(50); String message = "paint,draw paint指用颜色画,如油画颜料、水彩或者水墨画,而draw 通常指用铅笔、钢笔或者粉笔画,后者一般并不涂上颜料。两动词的相应名词分别为p"; StaticLayout myStaticLayout = new StaticLayout(message, tp, canvas.getWidth(), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); myStaticLayout.draw(canvas); canvas.restore(); }
android 动态设置TextView值,例:金额增加
public static void autoIncrement(final TextView target, final float start, final float end, long duration) { ValueAnimator animator = ValueAnimator.ofFloat(start, end); animator.addUpdateListener(new AnimatorUpdateListener() { private FloatEvaluator evalutor = new FloatEvaluator(); private DecimalFormat format = new DecimalFormat("####0.0#"); @Override public void onAnimationUpdate(ValueAnimator animation) { float fraction = animation.getAnimatedFraction(); float currentValue = evalutor.evaluate(fraction, start, end); target.setText(format.format(currentValue)); } }); animator.setDuration(duration); animator.start(); }
view背景透明设置
android:background
以下两种方法设置背景为透明:"@android :color/transparent"和"@null"
//强制为横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
<activity android:name=".HandlerActivity" android:screenOrientation="landscape"/>
//强制为竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
<activity android:name=".HandlerActivity" android:screenOrientation="portrait"/>
AndroidManifest.xml 中设置属性禁止重新创建Activity,并且添加屏幕切换监听。
<activity android:name=".HandlerActivity"
sdk<3.2 android:configChanges="orientation|keyboardHidden"/>
dk>3.2 android:configChanges="orientation|screenSize"
@Override public void onConfigurationChanged(Configuration newConfig) { int type = this.getResources().getConfiguration().orientation; if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { } super.onConfigurationChanged(newConfig); }
使用Java获取系统内存信息;
void memery(){
String m1=(Runtime.getRuntime().maxMemory()/ (1024 * 1024)) + "MB" ;
String m2=(Runtime.getRuntime().totalMemory()/ (1024 * 1024)) + "MB" ;
String m3=(Runtime.getRuntime().freeMemory()/ (1024 * 1024)) + "MB" ;
System.out.println("MaxMemory= "+m1+" totalMemory= "+m2+" freeMemory= "+m3);
}
ActivityManager mActManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
/** 获得系统正在运行的进程. */
List<RunningAppProcessInfo> mAllSysAppProcesses = mActManager.getRunningAppProcesses();
android 获取设备型号、OS版本号:
// .....
Build bd = new Build();
String model = bd.MODEL;
android.os.Build.MODEL
android.os.Build.VERSION.RELEASE
获取系统语言环境:
Locale.getDefault().getLanguage();
language=Locale.getDefault().toString();//en_US zh_CN
获取设备MAC地址:
private String getMac(Context context){
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
return info.getMacAddress();
}
获取设备ip地址字符串形式表示 public String getLocalIpAddress() { String strIP=null; try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress()) { strIP= inetAddress.getHostAddress().toString(); } } } } catch (SocketException ex) { Log.e("msg", ex.toString()); } return strIP; }
获取Android设备的唯一识别码。由于设备杂乱,为了保证设备号唯一性,可以采用获取UUID方式。
final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, tmPhone, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
String uniqueId = deviceUuid.toString();
所有的设备都可以返回一个 TelephonyManager.getDeviceId()
所有的GSM设备 (测试设备都装载有SIM卡) 可以返回一个TelephonyManager.getSimSerialNumber()
所有的CDMA 设备对于 getSimSerialNumber() 却返回一个空值!
所有添加有谷歌账户的设备可以返回一个 ANDROID_ID
所有的CDMA设备对于 ANDROID_ID 和 TelephonyManager.getDeviceId() 返回相同的值(只要在设置时添加了谷歌账户)
//获取电池电量: Intent batteryIntent = getApplicationContext().registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); int currLevel = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); int total = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1); int percent = currLevel * 100 / total; //或者 private BroadcastReceiver batteryReceiver=new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { int level = intent.getIntExtra("level", 0); // level加%就是当前电量了 } }; registerReceiver(batteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
//开机时间: private String getOpenDeviceTimes() { long ut = SystemClock.elapsedRealtime() / 1000; if (ut == 0) { ut = 1; } int m = (int) ((ut / 60) % 60); int h = (int) ((ut / 3600)); return h + " " + mContext.getString(R.string.info_times_hour) + m + " " + mContext.getString(R.string.info_times_minute); }
public String[] getCpuInfo() { String str1 = "/proc/cpuinfo"; String str2=""; String[] cpuInfo={"",""}; String[] arrayOfString; try { FileReader fr = new FileReader(str1); BufferedReader localBufferedReader = new BufferedReader(fr, 8192); str2 = localBufferedReader.readLine(); arrayOfString = str2.split("\\s+"); for (int i = 2; i < arrayOfString.length; i++) { cpuInfo[0] = cpuInfo[0] + arrayOfString[i] + " "; } str2 = localBufferedReader.readLine(); arrayOfString = str2.split("\\s+"); cpuInfo[1] += arrayOfString[2]; localBufferedReader.close(); } catch (IOException e) { } return cpuInfo; }
/** * Role:获取当前设置的电话号码 * <BR>Date:2012-3-12 * <BR>@author CODYY)peijiangping */ public String getNativePhoneNumber() { String NativePhoneNumber=null; NativePhoneNumber=telephonyManager.getLine1Number(); return NativePhoneNumber; } /** * Role:Telecom service providers获取手机服务商信息 <BR> * 需要加入权限<uses-permission * android:name="android.permission.READ_PHONE_STATE"/> <BR> * Date:2012-3-12 <BR> * * @author CODYY)peijiangping */ public String getProvidersName() { String ProvidersName = null; // 返回唯一的用户ID;就是这张卡的编号神马的 IMSI = telephonyManager.getSubscriberId(); // IMSI号前面3位460是国家,紧接着后面2位00 02是中国移动,01是中国联通,03是中国电信。 System.out.println(IMSI); if (IMSI.startsWith("46000") || IMSI.startsWith("46002")) { ProvidersName = "中国移动"; } else if (IMSI.startsWith("46001")) { ProvidersName = "中国联通"; } else if (IMSI.startsWith("46003")) { ProvidersName = "中国电信"; } return ProvidersName; }
public static int dipToPX(final Context ctx, float dip) { return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, ctx.getResources().getDisplayMetrics()); }
public static String generateTime(long time) { int totalSeconds = (int) (time / 1000); int seconds = totalSeconds % 60; int minutes = (totalSeconds / 60) % 60; int hours = totalSeconds / 3600; return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes, seconds) : String.format("%02d:%02d", minutes, seconds); }
/** * 毫秒转换几分几秒 * @param dur * @return */ private String formatDuration(long dur){ long min=dur/1000/60; long sec=dur/1000%60; return ""+min+"'"+sec+"\""; }
静默安装:
静默安装方法:
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); }
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(); } }
卸载方法:
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(); } }
添加权限:
<uses-permission android:name="android.permission.INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.DELETE_PACKAGES" />
<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" >
完整文件如下:
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目录,然后进行编译
调用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); }
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" />
/** 从assets 文件夹中读取文本数据 */ public static String getTextFromAssets(final Context context, String fileName) { String result = ""; try { InputStream in = context.getResources().getAssets().open(fileName); // 获取文件的字节数 int lenght = in.available(); // 创建byte数组 byte[] buffer = new byte[lenght]; // 将文件中的数据读到byte数组中 in.read(buffer); result = EncodingUtils.getString(buffer, "UTF-8"); in.close(); } catch (Exception e) { e.printStackTrace(); } return result; } /** 从assets 文件夹中读取图片 */ public static Drawable loadImageFromAsserts(final Context ctx, String fileName) { try { InputStream is = ctx.getResources().getAssets().open(fileName); return Drawable.createFromStream(is, null); } catch (IOException e) { if (e != null) { e.printStackTrace(); } } catch (OutOfMemoryError e) { if (e != null) { e.printStackTrace(); } } catch (Exception e) { if (e != null) { e.printStackTrace(); } } return null; }
从Assert目录复制文件到本地:
public static boolean copyFileFromAsset(Context mcontext,String destDir,String assetFile){ boolean copyok=false; File fdest=new File(destDir); if(!fdest.exists()) fdest.mkdirs(); InputStream is=null; FileOutputStream fos=null; byte[] buf=new byte[1024]; int readSize = 0; try { is = mcontext.getResources().getAssets().open(assetFile); fos=new FileOutputStream(fdest); while((readSize = is.read(buf)) > 0){ fos.write(buf, 0, readSize); } fos.flush(); copyok=true; } catch (IOException e) { copyok=false; e.printStackTrace(); } finally{ if(is!=null) try { is.close(); } catch (IOException e) { e.printStackTrace(); } if(fos!=null) try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } return copyok; }