《手机卫士》随听笔记:

防止子控件抢占父控件焦点:

android:descendantFocusability="blocksDescendants"

加layout和不加的区别:

padding_top  控件里面的内容距离控件边框的距离

layout_margaintop 控件与控件之间的距离·

android:gravity:设置的是控件自身上面的内容位置

android:layout_gravity:设置控件本身相对于父控件的显示位置。

splash全屏显示:

// 取消标题栏

requestWindowFeature(Window.FEATURE_NO_TITLE);

// 取消状态栏

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

Ps: 也可以通过主题设置窗体全屏显示

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

pull解析器使用:

XmlPullParser parser = Xml.newPullParser();
UpdataInfo info = new UpdataInfo();//info为一实例,里面包含字段:version、description、apkurl
parser.setInput(is, "utf-8"); //is为inputstream文件输入流
int type = parser.getEventType();

while (type != XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_TAG:
if("version".equals(parser.getName())){
String version = parser.nextText();
info.setVersion(version);
}else if("description".equals(parser.getName())){
String description = parser.nextText();
info.setDescription(description);
}else if("apkurl".equals(parser.getName())){
String apkurl = parser.nextText();
info.setApkurl(apkurl);
}
break;
}
type = parser.next();
}
return info;

联网获取服务器返回的输入流:

String path = "服务器下载path";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(2000);
conn.setRequestMethod("GET");
InputStream is = conn.getInputStream();

将输入流转化为字符串:

ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = (is.read(buffer))) != -1) {
bos.write(buffer, 0, len);
}
bos.flush();
bos.close();//关闭是无效的,因为它操作的都是内存中数据,不需要释放资源
is.close();
bos.toString();

或者
new String(bos.toByteArray());
}

获取程序版本号:

PackageManager manager = getPackageManager();
PackageInfo info = manager.getPackageInfo(getPackageName(), 0);
info.versionName;//得到版本号

安装APK:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");//file为apk位置
startActivity(intent);

对话框:

AlertDialog.Builder buider = new Builder(this);//上下文
buider.setIcon(R.drawable.xxx);
buider.setTitle("xxx");
buider.setMessage("xxx");
buider.setCancelable(false); // 让用户按返回键不能取消对话框
buider.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
buider.setNegativeButton("取消", new DialogInterface.OnClickListener() {
});
buider.create().show();//不要忘记了

子线程里面通知主线程ui更新

private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//根据子线程传过来的消息进行响应

msg.what//得到传过来的值
}
};

子线程发出通知:

new Thread(){
@Override
public void run() {
super.run();
handler.sendEmptyMessage(0);//无传递参数时

Message msg = new Message();//应该使用Message msg = Message.obtain();重复利用message
msg.what = 10;//msg.obj
handler.sendMessage(msg);

}
}.start();

判断SD卡是否可用:

Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)  //为true时可用

获得外存储设备的根目录:

Environment.getExternalStorageDirectory()

xml定义颜色渐变色:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://"
    android:shape="rectangle" >
    <!-- 长方形 -->
    <!-- 边框颜色和宽度 -->
     <stroke
        android:width="0.5dip"
        android:color="#ff9d9d9d" />
    <!-- 边角变圆滑 -->
    <corners android:radius="2dip" >
    </corners>
    <!-- 渐变色 -->
    <gradient
        android:centerColor="#ff262626"
        android:endColor="#ff515151"
        android:startColor="#ff2c2d2d" />
</shape>

xml颜色选择器selector,按下按钮变色:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://">
    <item android:drawable="@drawable/button_background" android:state_enabled="true" android:state_window_focused="false"/>//可点,没获得焦点
    <item android:drawable="@drawable/button_background_selected" android:state_pressed="true"/>//按下
    <item android:drawable="@drawable/button_background" android:state_focused="true"/>//获取焦点
    <item android:drawable="@drawable/button_background"/>//默认情况下
</selector>

自定义对话框样式:

<style name="MyDialog" parent="@android:style/Theme.Dialog">
        <!-- 自定义背景 -->
        <item name="android:windowBackground">@drawable/title_background</item>
        <!-- 没有标题 -->
        <item name="android:windowNoTitle">true</item>
</style>

自定义对话框的使用:

dialog = new Dialog(this, R.style.MyDialog);
dialog.setCancelable(false);
View view = View.inflate(this, R.layout.normal_entry_dialog, null);
Button bt_normal_ok = (Button) view.findViewById(R.id.bt_normal_dialog_ok);
Button bt_normal_cancle =  (Button) view.findViewById(R.id.bt_normal_dialog_cancle);
bt_normal_ok.setOnClickListener(this);
bt_normal_cancle.setOnClickListener(this);

//dialog.setContentView(R.layout.first_entry_dialog);//不可以这样写,注册不上监听事件
dialog.setContentView(view);
dialog.show();

具体详细字段可用apktool反编译制定版本的android.jar文件的res/values/style.xml进行查询设置

在receiver和service组件中激活activity:   他们不存在任务栈

Intent intent = new Intent(context, LostProtectedActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// 指定要激活的activity在自己的任务栈里面运行
context.startActivity(intent);

拦截拨打电话配置:

<receiver android:name=".receiver.CallPhoneReceiver" >
            <intent-filter android:priority="1000" >
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
            </intent-filter>
</receiver>

extends BroadcastReceiver类,在onReceive方法中String number = getResultData();得到导出的电话号码

设置切换界面动画(逐渐消失和出现):

overridePendingTransition(R.anim.alpha_in, R.anim.alpha_out);

alpha_in.xml:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://"
    android:fromAlpha="0.0"
    android:toAlpha="1.0"
    android:duration="300"
    >
</alpha>

alpha.out.xml:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://"
    android:fromAlpha="1.0"
    android:toAlpha="0.0"
    android:duration="300"
    >
</alpha>

获取手机服务:

TelephonyManager manager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

获取手机sim卡串号:

String simserial =  manager.getSimSerialNumber();

SharedPreferences的使用:

private SharedPreferences sp;

sp = getSharedPreferences("config", Context.MODE_PRIVATE);

Editor editor = sp.edit();
editor.putString("sim", simserial);
editor.commit();//很重要

得到字段:sp.getString("sim",null);//默认为null

限定EditText只能输入指定文本:

android:digits="0123456789."  //数字和"."

将xml文件转化为view对象:

inflater = LayoutInflater.from(context);

View.inflate(int resource,ViewGroup root);

联系人操作:

三张重要的表:1.data:存放电话等信息   2.raw_contacts:记录联系人id  3.mimetypes:定义联系人每项信息对应的数据类型

查询联系人操作:返回姓名和手机号:

public List<ContactInfo> getContactInfos() {
ContentResolver resolver = context.getContentResolver();
// 1.获取联系人的id
// 2.根据联系人的id 获取联系人名字
// 3.根据联系人的id 数据的type 获取到对应的数据(电话,email);
List<ContactInfo> infos = new ArrayList<ContactInfo>();
ContactInfo info;
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri datauri = Uri.parse("content://com.android.contacts/data");
Cursor cursor = resolver.query(uri, null, null, null, null);
while (cursor.moveToNext()) {
info = new ContactInfo();
String id = cursor.getString(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("display_name"));
info.setName(name);

Cursor datacursor = resolver.query(datauri, null,"raw_contact_id=?", new String[] { id }, null);
while (datacursor.moveToNext()) {
// mimetype
String type = datacursor.getString(datacursor.getColumnIndex("mimetype"));
if ("vnd.android.cursor.item/phone_v2".equals(type)) {
String number = datacursor.getString(datacursor.getColumnIndex("data1"));
info.setPhone(number);
}
}
datacursor.close();
infos.add(info);
info = null;
}
cursor.close();
return infos;

}

获取activity的返回值

例如:A->B->A  即由A界面转向B界面,选择之后返回到A界面并且带回选择的值

首先A中:

Intent intent = new Intent(A.this, B.class);
startActivityForResult(intent, 0);//0为请求码,当请求多个activity返回值时使用

然后进入B:

Intent intent = new Intent();
intent.putExtra("number", phone);
setResult(0, intent);//0为返回码,当有多个activity有返回值时使用

finish();

最后返回到A界面:

重写方法

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null) {
String number = data.getStringExtra("number");
//得到了选择的值
}
}

14.04.17

终止广播:

abortBroadcast();

获取拦截的短信:

权限:<uses-permission android:name="android.permission.RECEIVE_SMS"/>

Object[] pdus = (Object[]) intent.getExtras().get("pdus");
for (Object pdu : pdus) {
SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdu);
String content = sms.getMessageBody();
Log.i(TAG, "短信内容" + content);
String sender = sms.getOriginatingAddress();//短信发送方

}

发送短信:

权限:<uses-permission android:name="android.permission.RECEIVE_SMS"/>

SmsManager smsmanager = SmsManager.getDefault();

smsmanager.sendTextMessage(destinationAddress, scAddress, text, sentIntent, deliveryIntent);

打电话:

Intent intent = new Intent(); // 意图 代表一个要执行动作的意图
intent.setAction(Intent.ACTION_CALL);  //将ACTION_CALL换为ACTION_DIAL是跳转到拨号界面而不是直接拨打电话
intent.setData(Uri.parse("tel:" + number));
startActivity(intent);

简单播放音乐:

MediaPlayer player = MediaPlayer.create(context, R.raw.ylzs);//参数为上下文和资源id
player.setLooping(true);//设置是否循环
player.start();//开始播放

文本框为空时颤动:

Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
et_number.startAnimation(shake);//et_number为晃动文本框的name

R.anim.shake:

<translate xmlns:android="htt://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="0"
    android:interpolator="@anim/cycle_7"
    android:toXDelta="10" />

@anim/cycle_7:

<cycleInterpolator xmlns:android="htt://schemas.android.com/apk/res/android"
    android:cycles="7" />

得到数据库访问对象Dao:

public static SQLiteDatabasegetAddressDB(String path){ 
return SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READWRITE);
}

访问数据库,查询内容:

SQLiteDatabase db = AddressDao.getAddressDB("db路径");
if (db.isOpen()) {
Cursor cursor = db.rawQuery("select city from 表 where 字段=?",new String[] { number.substring(0, 7) });
if (cursor.moveToNext()) {
address = cursor.getString(0);//得到结果集第一列内容
}
cursor.close();
db.close();

}

插入内容:

SQLiteDatabase db = dbHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL("insert into blacknumber (number) values (?)",new Object[] { number });
db.close();
}

手机号码正则表达式:

^1[3458]\\d{9}$

匹配regex:字段.matches(表达式)  返回Boolean值

电话服务使用:

配置: <service android:name=".service.AddressService">

类实现:

public class AddressService extends Service {
private TelephonyManager manager;
private MyPhoneListener listener;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
listener = new MyPhoneListener();
manager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
manager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
}
private class MyPhoneListener extends PhoneStateListener{
// 电话状态发生改变的时候 调用的方法 
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: // 处于静止状态: 没有呼叫
break;
case TelephonyManager.CALL_STATE_RINGING: // 零响状态
Log.i(TAG,"来电号码为"+ incomingNumber);
break;
case TelephonyManager.CALL_STATE_OFFHOOK: //接通电话状态
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
manager.listen(listener, PhoneStateListener.LISTEN_NONE);
listener = null;
}

}

单选框:

AlertDialog.Builder builder = new Builder(this);
builder.setTitle("xxx");
String[] items = new String[] { "半透明", "活力橙", "苹果绿" };
builder.setSingleChoiceItems(items, 0,new DialogInterface.OnClickListener() {   //默认选中第一个条目
public void onClick(DialogInterface dialog, int which) {
}
});
builder.setPositiveButton("确定",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
builder.create().show();

通过布局 更改iv_drag_view在窗体中的位置
LayoutParams params = (LayoutParams) iv_drag_view.getLayoutParams();
params.leftMargin = x;
params.topMargin = y;
iv_drag_view.setLayoutParams(params);

创建数据库:

public class BlackNumberDBHelper extends SQLiteOpenHelper {
public BlackNumberDBHelper(Context context) {
super(context, "blacknumber.db", null, 1);
}
/**
* 第一次创建数据库的时候执行 oncreate方法
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE blacknumber (_id integer primary key autoincrement, number varchar(20))");
}
/**
* 更新数据库的操作
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}

判断字符串是否为null或者长度为0:

TextUtils.isEmpty(number)//返回Boolean值

ListView防止闪烁:

在ListView节点下加上:android:cacheColorHint="@android:color/transparent"

弹出软键盘防止系统重新加载控件:

android:windowSoftInputMode="adjustPan"

防止键盘弹出将菜单栏挤出去:

先用scrollView包裹,再在manifest中activity节点下加上:

android:windowSoftInputMode="stateVisible|adjustResize"

让数据适配器通知listview更新数据

// 重新获取黑名单号码
numbers = dao.getAllNumbers();

//更新数据
adapter.notifyDataSetChanged();

Adapter. NotifydataSetChange(); // 通知数据适配器数据发生了改变 界面会刷新 刷新的位置 是在当前的位置

adapter.notifyDataSetInvalidated();//通知数据适配器数据发生了改变  界面会刷新  导致整个界面的刷新  回到顶部

选择菜单OptionsMenu:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO 自动生成的方法存根
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.bg:

break;
case R.id.text:

break;
}
return false;
}

上下文菜单Contextual Menus:

registerForContextMenu(listviewname or gridviewname);
@Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
int id = (int) info.id;
switch (item.getItemId()) {
case R.id.update_number:

break;
case R.id.delete_number:

break;
}
return false;
}

context_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/update_number"
        android:title="更改黑名单号码">
    </item>
    <item
        android:id="@+id/delete_number"
        android:title="删除黑名单号码">
    </item>
</menu>

删除通话记录:

public void deleteCallLog(String number) {
ContentResolver  resolver = getContentResolver();
Cursor cursor = resolver.query(CallLog.Calls.CONTENT_URI, null, "number=?", new String[]{number}, null);
if(cursor.moveToFirst()){//查询到了呼叫记录
String id =cursor.getString(cursor.getColumnIndex("_id"));
resolver.delete(CallLog.Calls.CONTENT_URI, "_id=?",new String[]{id});
}
}

内容观察者:

// 注册一个内容观察者 观察call_log的uri的信息
getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, true,new MyObserver(new Handler(), incomingNumber));//incomingNumber可无

private class MyObserver extends ContentObserver {

private String incomingnumber;
public MyObserver(Handler handler, String incomingnumber) {
super(handler);
this.incomingnumber = incomingnumber;
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
deleteCallLog(incomingnumber);
// 当删除了呼叫记录后 反注册内容观察者
getContentResolver().unregisterContentObserver(this);
}
}

状态栏通知notification:

// 1. 获取notification的管理服务
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 2 .把一个要想显示的notification 对象创建出来,一闪而过
int icon = R.drawable.notification;
CharSequence tickerText = "发现响一声号码";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
// 3 .配置点击notification后的一些参数
Context context = getApplicationContext();
CharSequence contentTitle = "响一声号码";
CharSequence contentText = incomingNumber;
notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.vibrate = new long[] { 1000, 2000, 1000 };//加入权限 <uses-permission android:name="android.permission.VIBRATE"/>
Intent notificationIntent = new Intent(this, CallSmsActivity.class);//CallSmsActivity为点击后激活的界面
// 把响一声的号码 设置到intent对象里面
notificationIntent.putExtra("number", incomingNumber);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText,contentIntent);
// 4. 通过manger把notification 激活
manager.notify(0, notification);

在子线程中显示吐司:

Looper.prepare();
Toast.makeText(getApplicationContext(), "备份完成", 1).show();
Looper.loop();

写xml文件:

List<SmsInfo>  smsinfos = smsInfoService.getSmsInfos();
File file = new File("/sdcard/smsbackup.xml");
XmlSerializer serializer = Xml.newSerializer();
FileOutputStream os = new FileOutputStream(file);
serializer.setOutput(os, "utf-8");
serializer.startDocument("utf-8", true);

serializer.startTag(null, "smss");

serializer.startTag(null, "count");
serializer.text(smsinfos.size()+"");
serializer.endTag(null, "count");

for(SmsInfo info : smsinfos){
serializer.startTag(null, "sms");

serializer.startTag(null, "id");
serializer.text(info.getId());
serializer.endTag(null, "id");

serializer.startTag(null, "address");
serializer.text(info.getAddress());
serializer.endTag(null, "address");

serializer.startTag(null, "date");
serializer.text(info.getDate());
serializer.endTag(null, "date");

serializer.startTag(null, "type");
serializer.text(info.getType()+"");
serializer.endTag(null, "type");

serializer.startTag(null, "body");
serializer.text(info.getBody());
serializer.endTag(null, "body");

serializer.endTag(null, "sms");
}
serializer.endTag(null, "smss");

serializer.endDocument();
//把文件缓冲区的数据写出去
os.flush();
os.close();

读xml文件,并将读到的内容写入短信数据库:

XmlPullParser parser = Xml.newPullParser();
parser.setInput(new FileInputStream("/sdcard/smsbackup.xml"), "utf-8");
int type = parser.getEventType();
while (type != XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_TAG:
if ("sms".equals(parser.getName())) {
values = new ContentValues();
} else if ("id".equals(parser.getName())) {
values.put("id", parser.nextText());
} else if ("address".equals(parser.getName())) {
values.put("address", parser.nextText());
} else if ("data".equals(parser.getName())) {
values.put("data", parser.nextText());
} else if ("type".equals(parser.getName())) {
values.put("type", parser.nextText());
} else if ("body".equals(parser.getName())) {
values.put("body", parser.nextText());
}
break;
case XmlPullParser.END_TAG:
if ("sms".equals(parser.getName())) {
System.out.println(values);
}
}
type = parser.next();
}

获取本地信息内容:

List<SmsInfo> smsInfos = new ArrayList<SmsInfo>();
ContentResolver resolver = context.getContentResolver();
Uri uri = Uri.parse("content://sms/");
Cursor cursor = resolver.query(uri, new String[] { "_id", "address","date", "type", "body" }, null, null, "date desc");
SmsInfo smsinfo;
while (cursor.moveToNext()) {
String id = cursor.getString(0);
String address = cursor.getString(1);
String date = cursor.getString(2);
int type = cursor.getInt(3);
String body = cursor.getString(4);
smsinfo = new SmsInfo(id, address, date, type, body);
smsInfos.add(smsinfo);
smsinfo = null;
}
return smsInfos;

添加类似toast之类的显示框:

WindowManager.LayoutParams params = new LayoutParams();
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
params.format = PixelFormat.TRANSLUCENT;
params.type = WindowManager.LayoutParams.TYPE_TOAST;
params.setTitle("Toast");
params.gravity = Gravity.LEFT | Gravity.TOP;
View view = View.inflate(getApplicationContext(),cn.itcast.mobilesafe.R.layout.show_location, null);//获取显示的布局文件
LinearLayout ll = (LinearLayout) view.findViewById(R.id.ll_location);
TextView tv = (TextView) view.findViewById(R.id.tv_location);//显示的文字
tv.setTextSize(24);
tv.setText(address);
windowmanager.addView(view, params);

LIstView条目之间分割线:

android:divider="#ffff0000"
android:dividerHeight="2px"

获取手机安装的app程序:

private PackageManager packmanager;

public List<AppInfo> getAllApps() {
List<AppInfo> appinfos = new ArrayList<AppInfo>();
List<PackageInfo> packinfos = packmanager.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);//获取所有的app信息
for (PackageInfo info : packinfos) {
AppInfo myApp = new AppInfo();
String packname = info.packageName;// 获取包名字,卸载时可用到
myApp.setPackname(packname);
ApplicationInfo appinfo = info.applicationInfo;//获取application节点下的信息
Drawable icon = appinfo.loadIcon(packmanager);//app图标
myApp.setIcon(icon);
String appname = appinfo.loadLabel(packmanager).toString();// 得到application名字
myApp.setAppname(appname);
if (filterApp(appinfo)) {
myApp.setSystemApp(false);//第三方软件
} else {
myApp.setSystemApp(true);//系统软件
}
appinfos.add(myApp);
}
return appinfos;
}

判断是否为系统App:

public boolean filterApp(ApplicationInfo info) {
if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
return true;
} else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
return true;
}
return false;
}

当有多个view对象时,可以设置标志:

v.setTag(position);

通过v.getTag();得到标志。。。。。。。。。

在本APP开启另一个程序App:

packname = "App 包名";

PackageInfo info = getPackageManager().getPackageInfo(packname,PackageManager.GET_UNINSTALLED_PACKAGES| PackageManager.GET_ACTIVITIES);
ActivityInfo[] activityinfos = info.activities;
if (activityinfos.length > 0) {
ActivityInfo startActivity = activityinfos[0];
Intent intent = new Intent();
intent.setClassName(packname, startActivity.name);
startActivity(intent);

}else {
Toast.makeText(this, "当前应用程序无法启动", 0).show();
}

弹出小框框localPopupWindow:

// 获取当前view对象在窗体中的位置
int[] arrayOfInt = new int[2];
view.getLocationInWindow(arrayOfInt);
int i = arrayOfInt[0] + 60;
int j = arrayOfInt[1];

localPopupWindow = new PopupWindow(popupview,LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// 不显示设定背景时,一定要记得给popupwindow设置背景颜色
// Drawable background = new ColorDrawable(Color.TRANSPARENT);
Drawable background = getResources().getDrawable(R.drawable.local_popup_bg);
localPopupWindow.setBackgroundDrawable(background);
localPopupWindow.showAtLocation(view, Gravity.LEFT| Gravity.TOP, i, j);//view为要挂载到的对象

消灭小框框localPopupWindow:

dismissPopUpwindow();

渐现动画:

ScaleAnimation sa = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
sa.setDuration(200);

ll.startAnimation(sa);

分享功能实现:

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("text/plain"); // 需要指定意图的数据类型
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "分享1");
shareIntent.putExtra(Intent.EXTRA_TEXT,"推荐你使用一个程序");
shareIntent = Intent.createChooser(shareIntent, "分享2");//分享2为分享对话框上方显示的文字
startActivity(shareIntent);

卸载程序:

String uristr = "package:" + packname;
Uri uri = Uri.parse(uristr);
Intent deleteIntent = new Intent();
deleteIntent.setAction(Intent.ACTION_DELETE);
deleteIntent.setData(uri);
startActivityForResult(deleteIntent, 0);

调用startActivityForResult(deleteIntent, 0);之后可以可以调用以下方法更新UI:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {}

一个ListView,动态设置适配器:

adapter = new AppManagerAdapter(userAppinfos,AppManagerActivity.this);//参数分别为适配器填充内容的list表和上下文

lv.setAdapter(adapter);

获取手机当前正在运行的程序的包名:

ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

List<RunningTaskInfo> taskinfos = am.getRunningTasks(1);
RunningTaskInfo currenttask = taskinfos.get(0);// 获取当前用户可见的activity 所在的程序的包名
String packname = currenttask.topActivity.getPackageName();
Log.i(TAG, "当前运行" + packname);

添加震动效果:

import android.app.Service;

Vibrator vibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
vibrator.vibrate(new long[] { 0, 500 }, -1);//0表示立即震动   -1为不返回值

权限:<uses-permission android:name="android.permission.VIBRATE" />

按下返回键进行相应的操作:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
return true; // 阻止按键事件继续向下分发
}
return super.onKeyDown(keyCode, event);
}

listview的优化

复用convertview 减少getview方法对Inflater的操作

使用static的view对象的应用 减少内存中申请的局部变量的个数

//分批的加载数据

//分页的加载数据

// 懒加载

锁屏时定义对应操作:

<receiver android:name=".receiver.LockScreenReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.SCREEN_OFF" />
    </intent-filter>

</receiver>

public class LockScreenReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//在屏幕锁屏的时候 会调用这个onReceve 方法
}
}

自定义标题;

boolean flag = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

if (flag) {
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.mytitle);
}

获取手机制造商版本号等信息:android.os.Build

杀死应用程序:

ActivityManager am =  (ActivityManager) getSystemService(ACTIVITY_SERVICE);

am.killBackgroundProcesses(Packname());

/**
 * 获取当前系统的剩余的可用内存信息 byte long
 */
private long getAvailMemoryInfo() {
MemoryInfo outInfo = new ActivityManager.MemoryInfo();
am.getMemoryInfo(outInfo);
return outInfo.availMem;
}

自定义吐司:

public class MyToast {
public static void showToast(Context context, int iconid, String text) {
View view = View.inflate(context, R.layout.my_toast, null);
TextView tv = (TextView) view.findViewById(R.id.tv_my_toast);
ImageView iv = (ImageView) view.findViewById(R.id.iv_my_toast);
iv.setImageResource(iconid);
tv.setText(text);
Toast toast = new Toast(context);
toast.setDuration(0);
toast.setView(view);
toast.show();
}
}

自定义吐司显示:

MyToast.showToast(this, R.drawable.notification, "自定义吐司显示");

通过反射技术获得android系统隐藏掉的方法:

1.以下实例为获得类android.widget.AppSecurityPermissions下的getPermissionsView方法,他没有参数

try {
Class clazz = getClass().getClassLoader().loadClass("android.widget.AppSecurityPermissions");
Constructor constructor = clazz.getConstructor(new Class[] {Context.class, String.class });//获得构造方法,上下文  包名
Object object = constructor.newInstance(new Object[] { this,"cn.itcast.mobilesafe" });//获得cn.itcast.mobilesafe的信息
Method method = clazz.getDeclaredMethod("getPermissionsView",new Class[] {});
View view = (View) method.invoke(object, new Object[] {});//通过invoke()方法执行,传入对象,方法无参数传入
} catch (Exception e) {
e.printStackTrace();
}
}

2.通过反射调用PackageManager类中的抽象方法getPackageSizeInfo,传入的参数为 packname,new IPackageStatsObserver.Stub(){}

Method method = PackageManager.class.getMethod("getPackageSizeInfo", new Class[] { String.class,IPackageStatsObserver.class });
method.invoke(pm, new Object[] { packname,new IPackageStatsObserver.Stub() {

public void onGetStatsCompleted(PackageStats pStats,boolean succeeded) throws RemoteException {}

}});

application全局整个程序context上下文共享文件:

1.在根节点包下建立class:

public class MyApplicationextends Application {
public TaskInfo taskinfo;//在application所有的activity中都可以访问到taskinfo对象

}

2.清单文件配置:application节点下:

<application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"

android:name="MyApplication">

..................

3.在activity中使用:

MyApplication myapp = (MyApplication) getApplication();
TaskInfo taskinfo = myapp.taskinfo;//获取到taskinfo

...............//操作

myapp.taskinfo = null;//释放掉内存

TextView隐藏下面的横线:

android:background="@null"

获取当前时间:

String am_or_pm = "上午  ";
final Calendar c = Calendar.getInstance();
c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
String mYear = String.valueOf(c.get(Calendar.YEAR)); // 获取当前年份
String mMonth = String.valueOf(c.get(Calendar.MONTH) + 1);// 获取当前月份
if (mMonth.length() == 1) {
mMonth = "0" + mMonth;
}
String mDay = String.valueOf(c.get(Calendar.DAY_OF_MONTH));// 获取当前月份的日期号码
String mWay = String.valueOf(c.get(Calendar.DAY_OF_WEEK));
String mAm_Pm = String.valueOf(c.get(Calendar.AM_PM));
String mHuor = String.valueOf(c.get(Calendar.HOUR));
if (mHuor.length() == 1) {
mHuor = "0" + mHuor;
}
String mMinute = String.valueOf(c.get(Calendar.MINUTE));
if (mMinute.length() == 1) {
mMinute = "0" + mMinute;
}
if ("1".equals(mWay)) {
mWay = "日";
} else if ("2".equals(mWay)) {
mWay = "一";
} else if ("3".equals(mWay)) {
mWay = "二";
} else if ("4".equals(mWay)) {
mWay = "三";
} else if ("5".equals(mWay)) {
mWay = "四";
} else if ("6".equals(mWay)) {
mWay = "五";
} else if ("7".equals(mWay)) {
mWay = "六";
}
if ("1".equals(mAm_Pm)) {
am_or_pm = "下午";
}
String time = mYear + "年" + mMonth + "月" + mDay + "日" + " 星期" + mWay
+ " " + am_or_pm + mHuor + ":" + mMinute;

获取简单时间方法:

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String time = format.format(new Date());

由资源id获得Drawable对象:

Drawable picture = this.getResources().getDrawable(R.drawable.ic_launcher);

当有多个模拟器时进入指定设备终端:

adb -s 设备名称 shell

手机流量小知识:
1.cmd -> adb shell -> cd proc -> cd uid_stat -> ls-l
2.cmd -> adb root -> adb shell -> cd data ->cd data -> ls-l 
两个步骤得到结果的后两位比对得到app所对应的uid
说明:
步骤1得到的为每个app对应这个应用程序上传和下载产生的流量信息  包名为uid  cd进去 有:
tcp_rcv:采用tcp协议 接收到的数据的大小  tcp receive 
tcp_snd:采用tcp协议 发送的数据的byte大小  snd send 
tcp_rcv_pkt:采用tcp协议 接收到的包的数目
流量信息 :上一次开机到现在这个程序产生的流量
注意:模拟器是不支持流量查询的

获取手机上传下载流量API: android.net.TrafficStats;

获取在桌面产生图标的应用信息:

PackageManager pm = getPackageManager();
Intent intent = new Intent();
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
List<ResolveInfo> activities = pm.queryIntentActivities(intent,PackageManager.GET_RESOLVED_FILTER);

实现抽屉功能:

<SlidingDrawer
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:content="@+id/content"
    android:handle="@+id/handle"
    android:orientation="vertical" >

<ImageView
        android:id="@id/handle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

<ListView
        android:id="@id/content"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>
</SlidingDrawer>

给listview增加上下标题:

lv.addFooterView(View.inflate(this, R.layout.title, null));

lv.addHeaderView(View.inflate(this, R.layout.title, null));

图片大小重新设置:

public class ImageUtil {
/**
* 返回一个宽度和高度都为48个像素的bitmap
* @param drawable
* @return
*/
public static Bitmap getResizedBitmap(BitmapDrawable drawable,
Context context) {
Bitmap bitmap = drawable.getBitmap();
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int height = display.getHeight();
int width = display.getWidth();
if (height <= 480 || width <= 320) {
return Bitmap.createScaledBitmap(bitmap, 32, 32, false);
} else {
return Bitmap.createScaledBitmap(bitmap, 100, 100, false);
}
}
}

定时器的简单使用:

private Timer adapter;

private TimerTask task;
private Timer timer;

private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
adapter.notifyDataSetChanged();
}
};

@Override
protected void onStart() {
timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
// 发送一个消息给主线程
Message msg = Message.obtain();
handler.sendMessage(msg);
}
};
timer.schedule(task, 1000, 2000);
super.onStart();
}

@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
timer.cancel();
timer = null;
task = null;
}

一个activity若有以下节点

<intent-filter>
    <action android:name="android.settings.APPLICATION_DETAILS_SETTINGS" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="package" />
</intent-filter>

可以这样激活:

Intent intent  = new Intent();
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse("package"+pname));
startActivity(intent);

将src目录下文件(如,数据库)复制到SD卡:

private void copyfile() {
try {
InputStream is = getClass().getClassLoader().getResourceAsStream("clearpath.db");
               OutputStream fos = this.openFileOutput("clearpath.db", MODE_PRIVATE);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}

递归删除目录:

private void deleteDir(File file) {
if (file.isDirectory()) {
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
deleteDir(file);
}
} else {
file.delete();
}
}

ProgressBar的简单应用:

private ProgressBar pb = (ProgressBar) this.findViewById(R.id.progressBar);

pb.setMax(infos.size());

pb.setProgress(total);

Map的应用:

private Map<String, CacheInfo> maps;

maps = new HashMap<String, CacheInfo>();

maps.put(packname, cacheinfo);

将maps集合转化为list表:

private Set<Entry<String, CacheInfo>> sets;
private List<CacheInfo> cacheinfos;

sets = maps.entrySet();
cacheinfos = new ArrayList<CacheInfo>();
for (Entry<String, CacheInfo> entry : sets) {
cacheinfos.add(entry.getValue());

}

listview增加快速滑块及修改滑块图像:

lv.setFastScrollEnabled(true);
Field field = AbsListView.class.getDeclaredField("mFastScroller");
field.setAccessible(true);
Object obj = field.get(lv);
field = field.getType().getDeclaredField("mThumbDrawable");
field.setAccessible(true);
Drawable drawable = (Drawable) field.get(obj);
drawable = getResources().getDrawable(R.drawable.book);
field.set(obj, drawable);

list排序:books为     private List<BookInfo> books;

Comparator comp_bid_up = new Comparator() {
public int compare(Object o1, Object o2) {
BookInfo p1 = (BookInfo) o1;
BookInfo p2 = (BookInfo) o2;
if (Integer.parseInt(p1.getBid()) < Integer.parseInt(p2
.getBid()))
return -1;
else if (Integer.parseInt(p1.getBid()) == Integer
.parseInt(p2.getBid()))
return 0;
else if (Integer.parseInt(p1.getBid()) > Integer
.parseInt(p2.getBid()))
return 1;
return 0;
}
};
Collections.sort(books, comp_bid_up);

就这么简单就将books按照bid升序排列,并将排序后的结果放在了books中。

保存图片到sdka:

public void saveFile(String savepath, Bitmap bm, String fileName)
throws IOException {
File dirFile = new File(savepath);
if (!dirFile.exists()) {
dirFile.mkdir();
}
File myCaptureFile = new File(savepath + fileName);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(myCaptureFile));
bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();
bos.close();
}

simpleCursorAdapter 的使用:在列表中显示联系人和手机号码

Uri uri = Uri.parse("content://com.android.contacts/data/phones");
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
// 绑定数据 必须返回一个_id字段
@SuppressWarnings("deprecation")
SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(this,android.R.layout.simple_expandable_list_item_2, cursor,
new String[] { "display_name", "data1" }, new int[] {android.R.id.text1, android.R.id.text2 });
lv.setAdapter(simpleCursorAdapter);

向系统数据库中添加联系人:

public void insertContacts(String name, String number) {
ContentValues cv = new ContentValues();
Uri rawContactUri = getContentResolver().insert(
RawContacts.CONTENT_URI, cv);
long rawContactsId = ContentUris.parseId(rawContactUri);
cv.clear();
cv.put(StructuredName.RAW_CONTACT_ID, rawContactsId);
cv.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
cv.put(StructuredName.DISPLAY_NAME, name);
// 插入联系人姓名等信息
getContentResolver().insert(Data.CONTENT_URI, cv);

cv.clear();
cv.put(Phone.RAW_CONTACT_ID, rawContactsId);
cv.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
cv.put(Phone.NUMBER, number);
getContentResolver().insert(Data.CONTENT_URI, cv);
}

res目录和assets目录主要有以下两个区别:
1.获取res目录中的资源需要使用R类中的资源ID,如:
InputStream is = getResources().openRawResource(R.raw.ic_launcher);
Bitmap bm = BitmapFactory.decodeStream(is);
iv.setImageBitmap(bm);
而获取asserts中的资源只需要文件名,如下面获取图片的代码:
InputStream is = getResources().getAssets().open("ic");
Bitmap bm = BitmapFactory.decodeStream(is);
iv.setImageBitmap(bm);
2.res目录中只能建立相应资源的目录,有:drawable、values、layout、xml、animal、raw、animator。

不能建立其他任何目录,也不能建立二级和多级目录。而asserts目录可以建立任意多级目录。

Bitmap转Drawable:
Bitmap bm=xxx; //xxx根据你的情况获取
BitmapDrawable bd=new BitmapDrawable(bm);
Drawable转Bitmap:
Drawable d=xxx; //xxx根据自己的情况获取drawable
BitmapDrawable bd = (BitmapDrawable) d;
Bitmap bm = bd.getBitmap();

自定义进度条:定义的是进度条显示的视觉效果
drawble下clip.xml:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="horizontal"
    android:drawable="@drawable/progress"
    android:gravity="left" >
</clip>
在布局文件中加入image标签,背景设置为clip
<ImageView
        android:id="@+id/iv"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/clip" />
现在就可以使用了:
ImageView iv = (ImageView) findViewById(R.id.iv);
ClipDrawable drawable = (ClipDrawable) iv.getBackground();
drawable.setLevel(level);//level范围:0-10000

网络专用:把一个inputstream里面的内容转化成一个byte[]

public static byte[] getBytes(InputStream is) throws Exception{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while((len = is.read(buffer))!=-1){
bos.write(buffer, 0, len);
}
is.close();
bos.flush();
byte[] result = bos.toByteArray();
System.out.println(new String(result));
return  result;
}

public static void main(String[] args){

//得到类的简写名称
System.out.println(sample.class.getSimpleName());
 
//得到对象的全路径
System.out.println(sample.class);
 
//得到对象的类模板示例,也就是Class
System.out.println(sample.class.getClass());
 
//得到Class类的名称
System.out.println(sample.class.getClass().getName());
}
}
打印结果为:
sample
class com.lovo.test.sample
class java.lang.Class
java.lang.Class

scrollView滚到最后:

scrollView.fullScroll(ScrollView.FOCUS_DOWN);

两种方式请求服务器并获得返回值:

1.URLConnection

try {
String result = "", str = "";
URL url = new URL("");
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
InputStreamReader inputStreamReader = new InputStreamReader(
connection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(
inputStreamReader);
while ((str = bufferedReader.readLine()) != "") {
result += str;
}
} catch (IOException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();

}

2.HttpClient
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("");
ResponseHandler<String> responseHandler = new BasicResponseHandler();
try {
String result = client.execute(httpGet, responseHandler);
} catch (ClientProtocolException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
} catch (IOException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();

}

2015.12.04 点击事件分发小计:

Android 《手机卫士》随听笔记相关推荐

  1. android手机卫士、3D指南针、动画精选、仿bilibli客户端、身份证银行卡识别等源码...

    Android精选源码 android身份证.银行卡号扫描源码 android仿bilibili客户端 android一款3D 指南针 源码 android手机卫士app源码 android提醒应用, ...

  2. android确认密码代码,Android手机卫士之确认密码对话框

    本文接着实现"确认密码"功能,也即是用户以前设置过密码,现在只需要输入确认密码 布局文件和<Android 手机卫士--设置密码对话框>中的布局基本类似,所有copy一 ...

  3. android 短信位置,浅析Android手机卫士之手机实现短信指令获取位置

    推荐阅读: 获取位置 新建一个service的包 新建一个GPSService类继承系统的Service类 清单文件中注册一下 重写onCreate()方法,服务创建的时候回调 重写onDestroy ...

  4. 手机卫士 java_[Java教程]Android 手机卫士2

    [Java教程]Android 手机卫士2 0 2016-10-17 21:00:07 1,自定义获取焦点的TextView FocusTextView.java 1 package com.ithe ...

  5. android手机卫士,安卓手机卫士

    权限列表[安卓手机卫士] ● (基于网络的)粗略位置 访问粗略的位置源(例如蜂窝网络数据库)以确定手机的大体位置(如果可以).恶意应用程序可借此确定您所处的大体位置. ● 获取定位 允许应用通过网络或 ...

  6. Android 手机卫士(1)

    Android的开发之神兵利器[Android真机/Android模拟器] 否则光秃秃的对着代码,对着UI,很枯燥de~ 我想在座de各位学习Android也正是因为有趣的可视化开发@大家 想要在手机 ...

  7. [android] 手机卫士手机定位的原理

    手机定位的三种方式:网络定位,基站定位,GPS定位 网络定位,手机连上wifi 2g 3g的时候,手机会有一个ip,误差很大 基站定位,精确度与基站的多少有关,几十米到几公里的误差 GPS定位,至少需 ...

  8. [android] 手机卫士来电显示号码归属地

    继续N天前的项目 开启服务监听手机来电,查询数据库,显示归属地 详细内容可以参考这篇博文:http://www.cnblogs.com/taoshihan/p/5331232.html Address ...

  9. [android] 手机卫士欢迎细节和主界面

    splash界面的细节 ctrl + O 搜索 在去标题的时候,对话框主题被去掉了,有点丑,现在既要有新版本的对话框又不显示标题 把清单文件中activity节点的主题去掉 进入到applicatio ...

  10. [android] 手机卫士黑名单功能(列表展示)

    先把要拦截的电话号码保存到数据库中,拦截模式用个字段区分,1 电话拦截,2 短信拦截,3全部拦截 新建Activity类CallSmsSafeActivity.java 新建布局文件activity_ ...

最新文章

  1. SQL取上一条, 下一条记录方法
  2. Ubuntu 16.04~ORB SLAM2~Kinect v1
  3. paho mqtt 订阅主题的处理注意事项
  4. java链表list_数据结构-List:使用Java实现双向链表LinkedList
  5. C#高性能大容量SOCKET并发(十一):编写上传客户端
  6. Java浮点数内存存储
  7. Give root password for maintenance 问题解决.
  8. DialogFragment创建默认dialog
  9. nginx普通配置/负载均衡配置/ssl/https配置
  10. 手写token解析器、语法解析器、LLVM IR生成器(GO语言)
  11. JetBrains(Intellij, pycharm)多行编辑模式
  12. SQL server无法打开项 UNKNOWN\Components\929B2416EC4102B48A989956983ACF45\1F7B2B09C788E7644A0F08CA9C1D解决办法
  13. 数字证书及CA相关理解
  14. android camera x旋转,如何使用android.graphics.Camera.rotateX(角度)在特定点旋转画布
  15. 手把手教你如何破解无线网络密码(蹭网教程)
  16. 流处理引擎:ksql
  17. MySQL开启ssl证书
  18. latex常见错误之缺少sty文件
  19. 10年测试经验,在35岁的生理年龄面前,一文不值
  20. 服务器的全部作用,王者荣耀有哪些服务器_王者荣耀全部服务器功能详解_玩游戏网...

热门文章

  1. 三相并网逆变器电流内环解耦
  2. HTTP 、HTTPS
  3. 五 、Kotlin学习之命名参数默认参数
  4. excel数据透视表总结
  5. 趣图:深度学习之大炮打蚊子
  6. [转]800个有趣句子帮你记忆7000个单词
  7. TCP/IP协议卷一(一)
  8. org.springframework.hateoas.config.HateoasConfiguration required a single bean, but 15 were found:
  9. sort函数数组排序(c++方法)
  10. Node.js卸载与重装,zip与msi安装详解