Android常见问题

wangjianme

贡献于2014-02-20

字数:44610 关键词: Android开发 移动开发

Android常见问题 1:模拟器上传文件失败 Failed to push selection: Invalid argument 这说明上传的文件中包含中文,应该将中文去掉,然后再上传就可以了。 2:监听电话状态和取消监听拨打电话 package com.example.broastcastdemo; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.widget.Toast; public class CallService extends Service { TelephonyManager tm; PhoneStateListener listener; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { System.err.println("开始服务。。。"); tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); listener = new PhoneStateListener(){ @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state) { case TelephonyManager.CALL_STATE_IDLE: break; case TelephonyManager.CALL_STATE_OFFHOOK: //可以 Toast.makeText(getApplicationContext(), "去电"+One.tel, Toast.LENGTH_SHORT).show(); break; case TelephonyManager.CALL_STATE_RINGING: Toast.makeText(getApplicationContext(), "来电"+incomingNumber, Toast.LENGTH_SHORT).show(); break; default: break; } } }; tm.listen(listener,PhoneStateListener.LISTEN_CALL_STATE); } @Override public void onDestroy() { System.err.println("停止了服务。。。。"); //取消监听 tm.listen(listener, PhoneStateListener.LISTEN_NONE); listener=null; super.onDestroy(); } } 3、获取SharedPreferences的方式 --(存在需要补充的节点) 3.1、获取PreferencesFragment系统默认的sp对象 //获取系统默认的sp对象 sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 3.2、获取自己项目中的sp文件 //TODO 3.3、获取其他项目中的sp文件 //TODO 4、ListView多次重复使用同一个对象,并减少获取某个元素的次数 1:在BaseAdapter中,获取view对象的ConvertView参数是一个可以重复使用的对象,可以通过查询android的gc回收信息,获知在ListView显示信息时的gc回收。为了加快速度,可以使用ConvertView加快ListView的显示速度。 2:为了减少findViewById的的次数,可以使用view.setTag的方法,来保存需要获取的元素。 3:为了进一步,加快速度,可以直接将TextView定义成静态的成员变量,减少局部变量声明的次数。 5、LinearLayout设置点击时不同的样式 可以设置背景颜色,也可以设置背景图片。 默认值: 按下时: 1:声明两个不现的背景颜色 #d0d0d0 #79FF79 2:声明一个选择器样式表 Pressed : 当按下时 第二个是默认值 3:在LinearLayout元素中设置这个background属性 ../> 6、使用aidl挂断电话-两种方式 如果需要在来电时从底层数据拦截,则必须要使用AT指令,此时需要底层开发。不属性这儿的范围。 公共的配置: 第一步:在 frameworks_base中找到两个aidl文件 第二步:将它放到对应的包目录下 – 会对应的在gen目录下生成对应的java文件 第三步:添加权限 第一种:使用一个Service监听电话状态 第四步:挂断电话的代码 package com.leaf.endcall; import java.lang.reflect.Method; import com.android.internal.telephony.ITelephony; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.telephony.TelephonyManager; import android.view.View; import android.widget.Button; /** * 挂断电话的业务 */ public class MainActivity extends Activity { private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.button1); btn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { //获取TelephonyManager类,此类中可以获取到ITelephony接口的实例 TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); try { //在tm中有一个私有的方法getITelephony可以返回ITelephony接口的实例 Method method = tm.getClass().getDeclaredMethod("getITelephony"); method.setAccessible(true); //获取返回这个实例 ITelephony tel= (ITelephony) method.invoke(tm); //挂断电话 tel.endCall(); } catch (Exception e) { e.printStackTrace(); } } }); } } 第二种方式:通过BroastCastReciver接收广播 通过广播接收者,配置较高的优先级,挂断电话后,在通讯记录中没有此来电记录。而通过service挂断电话后,是有通话记录的。 /** * 来电或是外拨出电话监听器 监听用户的外拨电话,如果电话号为1234则为显示密码输出界面 在4.0上接收不到-WHY? */ public class NewCallReciver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { System.err.println("收到了:" + intent.getAction()); // 判断是来电还是拨出电话 if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) { //这儿判断是打出电话 if (getResultData().equals("1234")) {// 判断打出的电话号码是否是1234 Intent intent2 = new Intent(context, LostProtectedActivity.class); intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// 设置开始一个新的任务栈 context.startActivity(intent2); setResultData(null);// 设置没有数据,此时就是阻止打电话 } else { System.err.println("打出的电话是。。。" + getResultData()); // 设置全局的电话号码 Constant.CALL_TEL_NUMBER = getResultData(); } }else{ //否则就是来电 //则是来电 //判断,是否是的 SharedPreferences sp= PreferenceManager.getDefaultSharedPreferences(context); boolean boo = sp.getBoolean("black_inter",false); if(boo){ //判断是否是来电 TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); int state = tm.getCallState(); if(state==TelephonyManager.CALL_STATE_RINGING){//电话响起 String incoming_number = intent.getStringExtra("incoming_number"); //从intent中获取到来电的电话号码 Log.i("leaf","来电为:"+getResultData()+",,"+incoming_number); //查询电话号是否存在 BlackListDao dao = new BlackListDao(context); boolean exists = dao.exists(incoming_number); if(exists){ Log.i("leaf", "in reciver end call"); //直接挂断电话 try { Method m = //使用同样的方法挂断电话 TelephonyManager.class .getDeclaredMethod("getITelephony"); m.setAccessible(true); ITelephony tel = (ITelephony) m.invoke(tm); tel.endCall(); } catch (Exception e) { e.printStackTrace(); } } } } } } } 7、在命令行上,用adb命令安装软件到模拟器上 D:/> cd 到有apk文件的目录,以便于可以快速的找到这个文件 D:/>adb install somename.apk文件即可 8、操作SMS /** * inbox写入短信邮件箱数据 */ public void test3() { ContentResolver cr = getContext().getContentResolver(); Uri uri = Uri.parse("content://sms/inbox"); ContentValues cv = new ContentValues(); cv.put("address", "1234567890"); cv.put("status", -1); cv.put("body", "new data"); cr.insert(uri, cv); } /** * 查询出所有信息 */ public void test2() { // 查询通话记录表 ContentResolver cr = getContext().getContentResolver(); Uri uri = Uri.parse("content://sms"); Cursor c = cr.query(uri,new String[]{"address","person","date","status","type","body"}, null, null, null); int cols = c.getColumnCount(); System.err.println(cols); for(int i=1;i list= pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES); System.err.println("begin......"); for(PackageInfo info :list){ String packageName = info.packageName;//获取包名 String version = info.versionName;//版本 Drawable icon = info.applicationInfo.loadIcon(pm); String name = info.applicationInfo.loadLabel(pm).toString();//获取名称 //如果为系统应用则是为!=1,如果是用户自己安装的应用,则此值的结果为0 boolean isThird = false;//判断是否为三方应用 //如果程序的标记 & 系统 标识为0,即不是系统应用,则为三方应用 if((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)==0){ isThird = true; //如果程序的标记 &与 上 更新过的标记 不为0,即是指这个程序有可能更新过,则为三方应用 }else if((info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)!=0){ isThird=true; } System.err.println(packageName+","+version+","+name+", 是否是三方应用:"+isThird); } } 12、仅获取系统包含了主Activity的应用 List list= pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES); 上面这句可以获取系统的所有应用。但有些应用,是打不开的,如只包含Reciver的应用。所以,应该只获取包含activty的,可以启动的应用: 包含activty的应用包含以下特点: - 都包含这样的两个条目 所以,可以通过以下方式查询系统的应用: 以下是代码,只查询包含了启动Activity的程序: public void testpk2(){ PackageManager pm = getContext().getPackageManager(); Intent intent = new Intent(); intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); List infos = pm.queryIntentActivities(intent,PackageManager.GET_INTENT_FILTERS); for(ResolveInfo info:infos){ String packageName = info.activityInfo.packageName; System.err.println(packageName+","+info.isDefault+","+info.loadLabel(pm)); } } 13、启动一个应用的方式 14、ActivityManager判断运行的Service服务或Activity ActivityManager是进程管理。 PackageManager是安装程序管理。 /** * 判断某个Service是否正在运行 */ public class RunningServiceProvider { private static final String ActivityManager = Context.ACTIVITY_SERVICE; private static ActivityManager am; /** * 判断某个服务是否在运行 */ public static boolean isRunning(Context context, String serviceName) { boolean boo = false; if (am == null) { am = (android.app.ActivityManager) context .getSystemService(ActivityManager); } try { List ss = am.getRunningServices(100); for (RunningServiceInfo s : ss) { if (s.service.getClassName().equals(serviceName)) { boo = true; break; } } } catch (Exception e) { e.printStackTrace(); } return boo; } } /** * 获取所有运行的Service */ public void ss(View view) { // 判断开启的服务和activity ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); try { // 100是指最多可以获取多少个数量 List rs = am.getRunningServices(100); System.err.println("运行的服务:" + rs.size()); for (RunningServiceInfo s : rs) { System.err.println("类名:"+s.service.getClassName() + ",包名:" + s.service.getPackageName()+",:进程id:"+s.pid+",uid:"+s.uid+","); } } catch (Exception e) { e.printStackTrace(); } } 15、接收系统锁屏的广播 16、activity中excludeFromRecent=true就不会将最近的程序添加到任务列表中 (长按home,可以打开最近的任务列表) 17、在程序中,读取logcat中的数据 1:需要设置权限 2:Runtime.getRuntime().exec(“logcat”); 通过Service可以读取logcat的信息: package com.example.readlogcat; import java.io.BufferedReader; import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import android.app.Service; import android.content.Intent; import android.os.Environment; import android.os.IBinder; public class ReadLogcatService extends Service { @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { try { final Process p = Runtime.getRuntime().exec("logcat"); new Thread() { public void run() { InputStream in = p.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line = null; File file = new File(Environment.getExternalStorageDirectory(),"log.txt"); try { PrintWriter pw = new PrintWriter(file); while ((line=br.readLine())!=null) { //不能再输出,否则就是死循环 pw.println(line); pw.flush(); } } catch (Exception e) { e.printStackTrace(); } }; }.start(); } catch (Exception e) { e.printStackTrace(); } } } 18、在android4.0上获取手机的内存大小和剩余大小 public void test1() throws Exception{ //获取系统内存,以下代码,只可以在android 16以后才可以使用(4.0) ActivityManager am = (ActivityManager) getContext().getSystemService(getContext().ACTIVITY_SERVICE); MemoryInfo outInfo = new MemoryInfo(); am.getMemoryInfo(outInfo); long avaiMem = outInfo.availMem; System.err.println("可用内存:"+avaiMem); long totalMem = outInfo.totalMem; System.err.println("总内存大小:"+totalMem); //格式化的信息 String ame = Formatter.formatFileSize(getContext(), avaiMem); String tme = Formatter.formatFileSize(getContext(),totalMem); System.err.println(ame+"/"+tme); } 输出的结果如下: 在Linux平台上,通过读取linux的文件,来获取内存大小: 以下使用代码读取: /** * 通过读取/proc/meminfo方式来读取内存等信息 * @throws Exception */ public void test2() throws Exception{ InputStream in = new FileInputStream("/proc/meminfo"); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line = null; while((line=br.readLine())!=null){ System.err.println(line); } } 19、比较两个图片是否一样的方式 ImageView iv = (ImageView) view .findViewById(R.id.appmanager_item_iv_check); Log.i("leaf", ">>:" + iv.getDrawable() .getConstantState() .equals(getResources().getDrawable( R.drawable.checked_no) .getConstantState())); 20、自定义吐丝 Toast toast = new Toast(MainActivity.this); toast.setDuration(Toast.LENGTH_SHORT); TextView tv = new TextView(getApplicationContext()); tv.setText("Hello"); //这儿直接放入一个tv对象,可以放入其他任何定义的布局文件 toast.setView(tv); toast.show(); 21、AppWidget – 窗口小组件 1:浮动在桌面上,可以接收用的Click事件。 2:继承AppWidgetProvider,并实现里面的onEnabled,onDisabled方法。 3:开发一个xml文件,用于指定布局文件在哪儿。 4:默认最小更新时间为30分钟。 5:可以使用AppWidgetManager处理小于30分钟的更新操作。 6:按扭的click事件必须要通过PendingIntent实现。 第一步:开发一个AppWidgetProvider的子类 package cn.leaf.appwidget; import java.util.List; import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; import android.util.Log; /** * 用于清理资源的AppWidget */ public class MyWidget extends AppWidgetProvider { /** * 当这个Widget被添加到桌面上时,被调用的方法,此方法只会被调用一次 但在注意,对于不同的UI存有不同的调用规则,在某些UI上有可能被调用两次 */ @Override public void onEnabled(Context context) { Log.i("leaf", "onEnabled.."); // TODO Auto-generated method stub // 判断某个服务是否已经启动 ActivityManager am = (ActivityManager) context .getSystemService(context.ACTIVITY_SERVICE); List ss = am.getRunningServices(100); boolean boo = false; for (RunningServiceInfo info : ss) { Log.i("leaf", info.service.getClassName()); if (info.service.getClassName().equals( UpdateWidgetService.class.getName())) { boo = true; break; } } Log.i("leaf", "是否已经运行:" + boo); if (!boo) { Intent intent = new Intent(); intent.setClass(context, UpdateWidgetService.class); context.startService(intent); } } /** * 当所有这个widget从桌面上移除时,最后被调用的的方法 */ @Override public void onDisabled(Context context) { Log.i("leaf", "onDisabled.."); Intent intent = new Intent(); intent.setClass(context, UpdateWidgetService.class); context.stopService(intent); super.onDisabled(context); } } 第二步:开发一个指定布局的xml文件 内容如下: 第三步:在AndroidManifest.xml清单文件中配置 第三步:开发一个service用户启动一个线程不停止的获取内存信息 /** * 用于获取内存信息 */ public class UpdateWidgetService extends Service { private AppWidgetManager awm; private ActivityManager am; private Timer timer; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { Log.i("leaf", "服务已经启动" + this); am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); // 获取AppWidgetManager awm = AppWidgetManager.getInstance(this); final ComponentName cn = new ComponentName(this, MyWidget.class);// Widget类 final RemoteViews rvs = new RemoteViews(getPackageName(), R.layout.widget);// 布局文件 // 当Click时执行某个工作-可以打开 // 个Activity,也可以激活一个Service或是发出一个广播,此处就发出一个广播,以便于去做某些工作 // 然后开发一个广播接收者 Intent intent = new Intent(); intent.setAction("cn.leaf.widget.broadcast"); PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);// FLAG_UPDATE_CURRENT用于清空之前的数据 rvs.setOnClickPendingIntent(R.id.btn1, pi); // 以下是每隔多长时间更新一个界面 timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { // 设置内存情况: int size = am.getRunningAppProcesses().size(); rvs.setTextViewText(R.id.tv, "运行的进程有:" + size + "个"); // 可用内存 MemoryInfo mi = new MemoryInfo(); am.getMemoryInfo(mi); Long mem = mi.availMem; String str = Formatter.formatFileSize(getApplicationContext(), mem); rvs.setTextViewText(R.id.tv2, "可用内存:" + str); awm.updateAppWidget(cn, rvs); } }, 0, 1000*5); } @Override public void onDestroy() { Log.i("leaf", "服务已经停止" + this); awm = null; am = null; timer.cancel(); timer=null; } } 第四步:(可远的)开发一个BroadCaseRiceiver接收Click事件 – 用于在Click时设置目前的内存 public class SimpleBroadCastReciver extends BroadcastReceiver { private AppWidgetManager awm; private ActivityManager am; @Override public void onReceive(Context context, Intent intent) { //执行清理工作 ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); //查询所有运行的服务 List infos = am.getRunningAppProcesses(); for(RunningAppProcessInfo info:infos){ am.killBackgroundProcesses(info.processName); } Log.i("leaf", "Kill BackGround over..."); awm = AppWidgetManager.getInstance(context); final ComponentName cn = new ComponentName(context, MyWidget.class);//Widget类 final RemoteViews rvs = new RemoteViews(context.getPackageName(),R.layout.widget);//布局文件 //设置内存情况: int size = am.getRunningAppProcesses().size(); rvs.setTextViewText(R.id.tv,"运行的进程有:"+size+"个"); //可用内存 MemoryInfo mi = new MemoryInfo(); am.getMemoryInfo(mi); Long mem = mi.availMem; String str = Formatter.formatFileSize(context, mem); rvs.setTextViewText(R.id.tv2,"可用内存:"+str); awm.updateAppWidget(cn, rvs); } } 22、用WindowManager实现自定义的Widget 1:设置WindowManager.LayoutParamters.type=LayoutParams.TYPE_SYSTEM_ALERT; 2:需要权限: 3:可以设置touch事件 以下是开发步骤: 第一步:开发一个用户启动服务的界面 第二步:在服务中使用WindowManager打开一个View package cn.leaf.appwidget; import java.util.Timer; import java.util.TimerTask; import android.app.ActivityManager; import android.app.ActivityManager.MemoryInfo; import android.app.PendingIntent; import android.app.Service; import android.appwidget.AppWidgetManager; import android.content.ComponentName; import android.content.Intent; import android.os.IBinder; import android.text.format.Formatter; import android.util.Log; import android.widget.RemoteViews; /** * 用于获取内存信息 */ public class UpdateWidgetService extends Service { private AppWidgetManager awm; private ActivityManager am; private Timer timer; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { Log.i("leaf", "服务已经启动" + this); am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); // 获取AppWidgetManager awm = AppWidgetManager.getInstance(this); final ComponentName cn = new ComponentName(this, MyWidget.class);// Widget类 final RemoteViews rvs = new RemoteViews(getPackageName(), R.layout.widget);// 布局文件 // 当Click时执行某个工作-可以打开 // 个Activity,也可以激活一个Service或是发出一个广播,此处就发出一个广播,以便于去做某些工作 // 然后开发一个广播接收者 Intent intent = new Intent(); intent.setAction("cn.leaf.widget.broadcast"); PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);// FLAG_UPDATE_CURRENT用于清空之前的数据 rvs.setOnClickPendingIntent(R.id.btn1, pi); // 以下是每隔多长时间更新一个界面 timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { // 设置内存情况: int size = am.getRunningAppProcesses().size(); rvs.setTextViewText(R.id.tv, "运行的进程有:" + size + "个"); // 可用内存 MemoryInfo mi = new MemoryInfo(); am.getMemoryInfo(mi); Long mem = mi.availMem; String str = Formatter.formatFileSize(getApplicationContext(), mem); rvs.setTextViewText(R.id.tv2, "可用内存:" + str); awm.updateAppWidget(cn, rvs); } }, 0, 1000*5); } @Override public void onDestroy() { Log.i("leaf", "服务已经停止" + this); awm = null; am = null; timer.cancel(); timer=null; } } 第三步:可以开发布局文件的界面(略) 第四步:最后的结果: 关闭这个以后,也可以在Launcher上存在: 23、获取到所有访问网络的应用程序 /** * 获取流量信息 先获取包含了INTENET权限的所有包 */ public void test1() throws Exception { PackageManager pm = getContext().getPackageManager(); // 返回所有信息,包含权限信息 //获取到所有访问网络的应用程序 List infos = pm .getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_PERMISSIONS); Log.i("info","size:"+infos.size()); for (PackageInfo info : infos) { //这儿是获取所有请求过的权限,而info.permissions是指自己声明过向别人展示的权限 String[] pinfos = info.requestedPermissions; if (pinfos != null) { one:for (String pi : pinfos) { if(pi.equals(permission.INTERNET)){ Log.i("info", "访问网络:"+info.packageName); break one; } } } } } 24、获取手机的所有流量信息 手机的总流量信息保存在 /proc/net/dev文件中。 按api上的说明,获取到提从开机开始到目前的流量信息: /** * 以下是从Android2.2开始有的方法 * 获取程序的总流量 */ public void test2(){ long rxbytes = TrafficStats.getMobileRxBytes();//获取通过 3G收到的流量 long txbytes = TrafficStats.getMobileTxBytes();//获取通过3G发送的流量 long trxbytes = TrafficStats.getTotalRxBytes();//获取通过3G+WIFI收到的流量 long ttxbytes = TrafficStats.getTotalTxBytes();//获取通过3G+WIFI发送的流量 Log.i("info","recive from 3G:"+Formatter.formatFileSize(getContext(),rxbytes)); Log.i("info","sent from 3G:"+Formatter.formatFileSize(getContext(), txbytes)); Log.i("info", "Total recived:"+Formatter.formatFileSize(getContext(), trxbytes)); Log.i("info", "Total sent:"+Formatter.formatFileSize(getContext(),ttxbytes)); } 在linu下查找的命令: 获取总的流量信息: 在 /proc/net/dev文件中,保存了收到的和发送的所有字节: 25、获取某一个程序的流量信息 某个程序的流量信息,都保存在 /proc/uid_stat下的很多目录中,一个数字的目录就是一个应用程序安装的id。C语言的ID从1000开始,java写的程序ID从10000开始。 以下查询出ID与数字的对应关系: 在/data/data目录下查询 可以使用ls列所有的程序,也可以使用grep qq只查询部分程序,以下查询出qq这个程序的id,此id为u0_a85: 查询出对应的数字列表 10085就是u0_a85对应的流量信息目录: 里面包含了两个文件: 获取里面的数据: 用4907808/1024/1024=4.68M 与项目计算的相同: 以下是获取某一个应用程序的流量的代码: android.net.TrafficStats类中,提供了多种静态方法,可以直接调用获取,返回类型均为long型,如果返回等于-1代表 UNSUPPORTED 当前设备不支持统计。 1. static long getMobileRxBytes() //获取通过Mobile连接收到的字节总数,不包含WiFi 2. static long getMobileRxPackets() //获取Mobile连接收到的数据包总数,不包含WiFi 3. static long getMobileTxBytes() //Mobile发送的总字节数 4. static long getMobileTxPackets() //Mobile发送的总数据包数 5. static long getTotalRxBytes() //获取总的接受字节数,包含Mobile和WiFi等 6. static long getTotalRxPackets() //总的接受数据包数,包含Mobile和WiFi等 7. static long getTotalTxBytes() //总的发送字节数,包含Mobile和WiFi等 8. static long getTotalTxPackets() //发送的总数据包数,包含Mobile和WiFi等 9. static long getUidRxBytes(int uid) //获取某个网络UID的接受字节数 10. static long getUidTxBytes(int uid) //获取某个网络UID的发送字节数 代码如下: /** * 获取流量信息 先获取包含了INTENET权限的所有包 */ public void test1() throws Exception { PackageManager pm = getContext().getPackageManager(); // 返回所有信息,包含权限信息 //获取到所有访问网络的应用程序 List infos = pm .getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_PERMISSIONS); Log.i("info","size:"+infos.size()); for (PackageInfo info : infos) { //这儿是获取所有请求过的权限,而info.permissions是指自己声明过向别人展示的权限 String[] pinfos = info.requestedPermissions; if (pinfos != null) { one:for (String pi : pinfos) { if(pi.equals(permission.INTERNET)){//如果可以访问网络的话,就获取流量信息 Log.i("info", "访问网络:"+info.packageName+","+info.applicationInfo.uid); long uidrx= TrafficStats.getUidRxBytes(info.applicationInfo.uid);//全部的接收 long uidtx = TrafficStats.getUidTxBytes(info.applicationInfo.uid);//全部的发送 Log.i("info", "uid rx:"+Formatter.formatFileSize(getContext(), uidrx)); Log.i("info", "uid tx:"+Formatter.formatFileSize(getContext(), uidtx)); break one; } } } } } 26、从一种单位转换成另一种单位 package cn.utils; import android.content.Context; /** * 从一种分辨率转换成另一种分辨率 */ public class DisplayUtils { /** * 根据手机的分辨率从dip单位转化成px(像素) */ public static int dip2px(Context context,float dipValue){ final float scale = context.getResources().getDisplayMetrics().density; return (int)(dipValue*scale+0.5f); } /** * 根据手机的分辨率从px转换成dip单位 */ public static int px2dip(Context context,float pxValue){ final float scale = context.getResources().getDisplayMetrics().density; return (int)(pxValue/scale+0.5f); } } 26.1、屏幕适配的方法 在开发android软件的时候 遵循一下的原则,可以有效避免屏幕适配的问题: 1、尽量的使用线性布局 和 相对布局 进行ui的设计。 LieanrLayout/RelativeLayout (示例略) 2、设置ui界面的xml文件的时候宽度和高度的单位都是用dip的单位 dip/dp ->独立于设置的单位. 屏幕宽度与像素值的比例,不要使用px (示例略) 3、文字的大小sp单位 不要使用px (示例略) 4、在内容比较多的界面上 最外面用scrollview进行包裹,ScrollView用于显示滚动的View 示例: 5、可以根据屏幕创建不同分辨率的布局文件 适配一般的屏幕->解决特殊的屏幕 VGA 480*640 HVGA 480*320 QVGA 240*320 WVGA 800*480 FWVGA 854*480 1024 * 768 1200* 800 6、在类中直接定义的int是像素而不是dip,所以可以使用上面的类,进行转换否则: 修改代码: // 同时定义这个窗口的高和宽度 popupWindow = new PopupWindow(popupView, right - left- splayUtils.dip2px(getApplicationContext(),190), //从dip转成像素 bottom - top- DisplayUtils.dip2px(getApplicationContext(),5)); 修改以后: 27、组件-slidingdrawer控件. 实现抽屉效果 28、ExpendableListView 1:实现ListView的分组效果 2:需要ExpendableListAdapter数据适配器 3:子元素的事件:setOnChild…ClickListener事件。 布局文件: Java代码: package cn.leaf.sliderdrawer; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.Toast; import android.widget.ExpandableListView.OnChildClickListener; import android.widget.TextView; public class ExpandableListViewActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.e); ExpandableListView listView = (ExpandableListView) findViewById(R.id.expandableListView1); ExpandableListAdapter adapter = new MyAdapter(); listView.setAdapter(adapter); //设置子项目的Click事件 listView.setOnChildClickListener(new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { TextView tv = (TextView) v; String str = tv.getText().toString(); Toast.makeText(ExpandableListViewActivity.this, str, Toast.LENGTH_SHORT).show(); return true; } }); } //声明数据适配器 class MyAdapter extends BaseExpandableListAdapter{ @Override public int getGroupCount() { return 5;//一共5个 } @Override public int getChildrenCount(int groupPosition) { return 3;//每一个主项目,都有三个 } /** * 返回主项目对象 */ @Override public Object getGroup(int groupPosition) { return null; } /** * 返回子项目对象 */ @Override public Object getChild(int groupPosition, int childPosition) { return null; } /** * 返回主项目id,可以没有 */ @Override public long getGroupId(int groupPosition) { return 0; } @Override public long getChildId(int groupPosition, int childPosition) { return 0; } @Override public boolean hasStableIds() { return false; } @Override //用于生成主项目的View public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { TextView tv = new TextView(getApplicationContext()); tv.setText("主项目"+groupPosition); tv.setPadding(35, 5, 5, 5); tv.setTextColor(Color.BLACK); return tv; } @Override //用于生成子项目的view public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { TextView tv = new TextView(getApplicationContext()); tv.setText("子项目"+groupPosition+","+childPosition); tv.setPadding(35, 5, 5, 5); tv.setTextColor(Color.BLACK); return tv; } /** * 子项目是否可以被选中 */ @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } } } 29、读取程序缓存、数据、代码所占的大小 1:即模拟Settings中的示例获取程序大小,以下是android程序的界面 2:以下是自己开发出来的界面 3:使用ListView显示所有应用程序的 codeSize dataSize cacheSize的大小。 4:可以通过查找Setting源代码获取到系统是如何获取到数据大小的 5:获取一个程序的数据大小,经过以下步骤 * 获取每一个程序的缓存大小 * 1:导入两个aidl文件 * IPackageStatsObserver.aidl * PackageStats.aidl * 2:使用反射调用PackageManager的方法 getPackageSizeInfo * 3:上面的方法被添加了@hide的javaDoc,即此方法不会被javaDoc公开,所以只可以使用反射的方法去调用 * 4:必须添加权限android.Manifest.permission#GET_PACKAGE_SIZE * 5:清除数据:clearApplicationUserData 0 只有root的程序才可以访问。 * 6:清除缓存:deleteApplicationCacheFiles - 权限:android.Manifest.permission#DELETE_CACHE_FILES * 只有获取root的用户才可以拥有这个权限 * 7:reeStorageAndNotify – 这个只是清除本项目自己的,不能删除其他项目的。 第一步:创建两个布局文件

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享文档获得金币 ]
0 人已下载

下载文档

相关文档