第一天: 
 adb命令:
  adb devices 列出所有的设备
  adb shell 挂载到Linux的空间,可以执行Linux指令
  adb install xxx.apk 如果多个设备adb install -s 设备名
  adb push 把文件推到手机里
  adb pull把文件从手机里拉出来
  netstat -ano查看端口号
  taskkill /pid pid /f 杀死pid对应的进程
 电话拨号器
  1、找到控件并且得到控件对象
   et_phone = (EditText) findViewById(R.id.et_phone);
   Button bt_call  = (Button) findViewById(R.id.bt_call);
  2、为按钮设置点击事件,并且拿到用户在文本框中输入的值
   String phone = et_phone.getText().toString().trim();
  3、创建一个拨打电话的意图,并开启
   Intent intent = new Intent();
   //设置拨打电话号码的动作
   intent.setAction(Intent.ACTION_CALL);
   //设置拨打的电话号码
   intent.setData(Uri.parse("tel://"+phone));
   //开启拨打电话的意图
   startActivity(intent);
 四种点击事件
  1、采用内部类的方式去实现OnClickListener
  2、使用匿名内部类
  3、让当前类去实现OnClickListener,并实现未实现的方法
  4、在layout文件的Button中定义onclick方法,并在代码中去实现对应的方法
   标准:public void XXX(View view){}
   
第二天:
 1、Junit测试方法
  写一个测试类继承AndroidTestCase类
    在清单文件中添加
   <!-- 添加指令集,添加到manifest节点里面,指令集会把应用程序部署到模拟器上运行 -->
  <instrumentation android:name="android.test.InstrumentationTestRunner"
   android:targetPackage="com.itheima.junit">
  </instrumentation>
  <!-- 添加JUnit的测试包 ,添加到application节点的里面-->
        <uses-library android:name="android.test.runner"/>
 2、从文件中读取数据并显示到控件
  1、把文件保存到SD卡
   File file = new File(Environment.getExternalStorageDirectory(),"xx.txt");
   FileOutputStream fos = new FileOutputStream(file);
   fos.write("xxx".getBytes());
   fos.close();
  2、从SD卡中读取文件
   File file = new File(Environment.getExternalStorageDirectory(),"xx.txt");
   FileReader fr = new FileReader(file);
   BufferedReader br = new BufferedReader(fr);
   String info = br.readLine();
  3、在清单文件中添加访问SD卡的权限
   写SD卡
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
   读SD卡
   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
 3、SharedPreferences存储和读取数据
  保存数据
  SharedPreferences sp = getSharedPreferences("xxx",0);
  sp.edit.putString("Key","Value").commit;
  读取数据
  String data = sp.getString("Key","默认值");
 4、XML文件的创建与解析
  1、创建XML文件
   1、初始化一个xml文件的序列化器
   XmlSerializer serializer = XML.newSerializer();
   2、初始化序列器参数
   File file = new File(Environment.getExternalStorageDirectory(),"backup.xml");
   FileOutputStream fos = new FileOutputStream(file);
   serializer.setOutput(fos,"UTF-8");
   //3.开始写xml文件.
   serializer.startDocument("UTF-8", true);
   serializer.startTag(null, "smss");
   //开始写body节点
   serializer.startTag(null, "body");
   serializer.text(info.getBody());
   //body节点结束
   serializer.endTag(null, "body");
   //smss根节点结束
   serializer.endTag(null, "smss");
   //xml 结束
   serializer.endDocument();
   fos.close();
  2、解析XML文件
   /**
   * 解析服务器返回的数据 获取天气信息
   * @param is 服务器返回的包含天气信息的流 (xml)
   * @return
   */
  public static List<Channel> getAllWeatherInfos(InputStream is) throws Exception{
   List<Channel> channels = null;
   Channel channel = null;
   //1.获取xml解析器
   XmlPullParser parser = Xml.newPullParser();
   //2.设置xml解析器的参数
   parser.setInput(is, "utf-8");
   //3.开始解析xml文件.
   
   int type = parser.getEventType();// 获取当前的事件的类型
   while (type!=XmlPullParser.END_DOCUMENT){ //需要让pull解析器解析到文件的末尾
    switch (type) {
    case XmlPullParser.START_TAG:
     if("weather".equals(parser.getName())){//总的开始节点
      channels = new ArrayList<Channel>(); //初始化集合
     }else if("channel".equals(parser.getName())){//某个城市的信息开始了.
      channel = new Channel();
      //获取到id的属性值
      String id = parser.getAttributeValue(0);
      channel.setId(Integer.parseInt(id));
      //解析city节点
     }
     break;
    //判断xml的结束节点
    case XmlPullParser.END_TAG:
     if("channel".equals(parser.getName())){
      //把解析的内容加入到集合中
      channels.add(channel);
      channel = null;
     }
     break;
    }
    type = parser.next();
   }
   is.close();
   return channels;//把所有的频道的集合返回回去
   }
第三天:
 1、创建数据库的步骤
  创建一个类继承SQLiteOpenHelper
   //创建数据库
  DBHelper helper = new DBHelper(this, "account.db", null, 1);
     onCreate是在数据库创建的时候调用的,主要用来初始化数据表结构和插入数据初始化的记录    
  onUpGrade是在数据库版本升级的时候调用的,主要用来改变表结构
  1、插入数据
   ContentValues values = new ContentValues();
   values.put("name", "zhangsan");
   long rowId =  db.insert("person", null, values);
  2、查询数据
   Cursor cursor = db.query("person", new String[]{"id","name" }, null, null, null, null, null);
   while(cursor.moveToNext()){
    int id = cursor.getInt(0);
    String name = cursor.getString(1);
    System.out.println("id="+id+"; name="+name);
   }
  3、更新数据
   ContentValues values = new ContentValues();
   values.put("name", "wangwu");
   db.update("person", values, "id=?", new String[]{"1"});
  4、删除数据
   db.delete("person", "id=?", new String[]{"2"});
 2、ListView的使用
  1、得到ListView对象
  2、lv.setAdapter(new MyAdapter())填充数据
  3、创建一个类继承BaseAdapter并实现未实现的方法
   主要是getCount和getView
   TextView tv_id = (TextView) view.findViewById(R.id.tv_id);
   TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
   Person p = list.get(position);
   tv_id.setText(p.getId()+"");
   tv_name.setText(p.getName());
   return view;
第四天:
 1、网络图片查看器
  1、发送请求
   1、创建一个URL对象
    URL url = new URL(path);
    HttpURLConnection conn = (HttpURLConnection)url.openConnection();
   2、设置请求头信息
    conn.setRequestMethod("GET");
    conn.setConnectTimeout(3000);
  2、服务器返回数据
   1、判断状态码200 ok,404 没有找到资源、503、509 服务器端错误
    conn.getResponseCode();
   2、解析服务器返回的二进制数据
    InputStream is = conn.getInputStream();
    String data = StreamTools.readStream(is);
   3、把图片显示在控件上
    Message msg = Message.obtain();
    msg.obj = data;
    handler.sendMessage(msg);
    private Handler handler = new Handler(){
     public void handleMessage(android.os.Message msg) {
     String data = (String) msg.obj;
     
     tv_content.setText(data);
     };
    };
   4、添加访问互联网的权限:
    <uses-permission android:name="android.permission.INTERNET"/>
 2、线程不能修改UI界面
  activity中的onCreate方法和点击事件的方法都是运行在主线程中的
  只有创建UI界面的那个线程才能修改UI Only the original thread that created a view hierarchy can touch its views.
  主线程(UI线程):只有主线程才能修改UI,如果子线程修改UI,系统验证当前线程是不是主线程,如果不是主线程,就会终止运行
  runOnUiThread
    3、消息处理机制的原理
  步骤:
   1、主线程中创建handler
    private Handler handler = new Handler(){};
   2、在线程中得到handler的引用,调用发送消息的方法
    Message msg = new Message();
    msg.obj = bm;
    handler.sendMessage(msg);
   3、handler修改UI界面
    public void handleMessage(Message msg){
     super.handleMessage(msg);
     //2、handler修改UI界面
     Bitmap bm = (Bitmap) msg.obj;
     iv.setImageBitmap(bm);
    }
  Handler、Message、Looper(消息处理机制的原理):
   前提知识
    所有使用UI界面的操作系统,后台都运行着一个死循环,在不停的监视和接受用户发送的指令,一旦接受指令就立即执行
    当我们的Android应用程序的进程一创建的时候,系统就给这个进程提供了一个Looper
    Looper是一个死循环,它内部维护这个一个消息队列,Loop不停地从消息队列中取消息(Message),取到消息就发送给了Handler,最后Handler根据接收到的消息去修改UI。
   
 4、使用POST方式提交数据
  业务场景:
   1、用户登录
   2、文件上传
  1、设置请求头信息POST、Content-Length:
    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
   //必须添加的两个请求头信息
    conn.setRequestProperty("Content-Length", data.length()+"");
   conn.setRequestMethod("POST");
     2、设置把数据提交到服务器端:
    conn.setDoOutput(true);
    //把数据写到服务器端
   conn.getOutputStream().write(data.getBytes());
     缺点:
   1、代码复杂
     优点:
   1、安全;
   2、提交大量的数据
第五天: 
 1、使用POST方式提交数据是的中文乱码解决方法
  解决办法:使用客户端和服务器两边的字符集编码保持一致。UTF-8,
 2、 使用GET方式提交数据的中文乱码的解决方法
  使用URLEncoder.encode(name,"UTF-8")进行url编码:
  String path = "http://192.168.22.136:8080/web/servlet/LoginServlet?username="+URLEncoder.encode(name,"UTF-8")+"&password="+URLEncoder.encode(pwd,"UTF-8"); 
 3、 
第六天:
 1、显示意图和隐式意图的区别
  显示意图只能打开自己应用程序中的界面
  隐式意图可以打开别的应用程序的界面
 2、意图的设计的目的
  解耦,实现应用程序的高内聚、低耦合.保证应用程序之间能够相互独立运行,又能彼此相互调用
  保证自己写代码能够重复使用
  结构师:保证项目多快好省的把项目做完
 3、Activity的生命周期
  onCreate:在activity被创建的时候调用,初始化界面
  onStart:当界面可见的时候调用
  onResume:按钮可以被点击的时候
  onPause:按钮失去焦点的时候
  onStop:界面不可见的时候调用
  onDestroy:销毁activity实例
  1、activity创建时调用onCreate、onStart、onResume;
  2、关闭activity时调用:onPause、onStop、onDestroy;
  3、最小化activity时调用:onPause、onStop;
  4、最小后重新打时调用:onRestart、onStart、onResume;
 4、启动模式
  singletop:单一顶部模式在activity的配置文件中设置android:launchMode="singleTop"
   如果任务栈的栈顶存在这个要开启的activity,不会重新的创建activity,而是复用已经存在的activity。保证栈顶如果存在,不会重复创建。
   应用场景:浏览器的书签
  singletask:单一任务栈,在当前任务栈里面只能有一个实例存在
   如果有实例存在,则清空这个实例上面的所有别的activity,并复用这个实例
   应用场景:浏览器的activity
  singleInstance:启动模式非常特殊,activity会运行在自己的任务栈里面,并且这个任务栈里面只有一个实例存在
   如果你要保证一个activity在整个手机操作系统里面只有一个实例存在,使用singleInstance
   应用场景: 来电页面   有道词典
第七天:
 如何创建广播
  1、创建一个类,继承BroadcastReceiver类,并重写onReceive方法
  2、在清单文件中注册
   <receiver android:name="包名.类名" />
  3、在意图过滤器中指定要过滤的内容
   <intent-filter >
      <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
   </intent-filter>
  4、自定义广播
   1、创建一个传递消息的意图对象
    Intent intent = new Intent();
   2、设置要广播的事件类型
    intent.setAction("自定义包名");
   3、设置广播的消息数据
    intent.putExtra("Key","Value");
   4、发送一个广播
    sendBroadcast(intent);
  5、发送有序广播
   Intent intent = new Intent();
   intent.setAction("com.itheima.orderedbroadcast.ZYFFNTBT");
   //发送一个有序的广播
   //intent 意图
   //permission 指定接收者需要添加了权限
   //resultReceiver 指定哪个广播接收者最后接到消息
   //scheduler 消息处理器
   //initialCode 给消息指定初始代码
   //initialData 指定消息的数据
   //initialExtras 指定额外的参数
   sendOrderedBroadcast(intent, null, null, null, 1, "广播内容..", null);
   广播接收者的配置文件:
    <receiver android:name="com.itheima.zf.ProvinceBroadCastReceiver">
      <intent-filter android:priority="1000" >
       <action  android:name="com.itheima.orderedbroadcast.ZYFFNTBT"/>
      </intent-filter>
    </receiver>
   广播接收者的代码:
  
   String info = getResultData();
   System.out.println("---------广播内容:"+info);
   修改广播内容
   setResultData("国务院开始发放2014年农田补贴:400元");
第八天:
 1、什么是服务
  Windows下的服务:没有界面、长期运行在后台的应用程序
  Android下的服务:应用程序的一个组件,没有界面activity,长期运行在后台
  进程:是应用程序运行的载体
  进程与应用程序直接的关系:Linux操作系统创建一个进程,这个进程负责运行dalvik虚拟机,Android的应用程序都是运行在dalvik虚拟机上的
 2、进程的生命周期
  1、应用程序一启动的时候就创建了进程
  2、当应用程序退出的时候进程并没有退出
  3、只有手工停止这个进程,进程才会结束
  了解:操作系统尽量长时间运行应用程序的进程,为了保证内存空间不被大量占用,它会按照进程的优先级,从低到高一级一级的杀死进程,直到内存空间被清理的差不多为止
 3、进程的等级
  1、Foreground process(前台进程)
   应用程序,用户正在操作,activity的onResume方法被执行了,可以响应点击事件
  2、Visible process(可视进程)
   应用程序的UI界面,用户还可以看到,但是不能操作了
  3、Service process(服务进程)
   应用程序没有界面,但是有一个后台的服务还处于运行状态
  4、Background process(后台进程)
   应用程序没有服务处于运行状态,应用程序被最小化了,activity执行了onStop方法
  5、Empty process(空进程)
   没有任何组件运行,所有的activity都关闭了,任务栈清空了
 4、服务的特点
  服务被创建时调用onCreate、onStartCommand
  服务只能被创建一次,可以开启多次onStartCommand
  服务只能被停止一次
  没有onPause、onStop、onResume、onRestart方法,因为service没有界面,长期运行在后台。
 5、bind方式开启服务的生命周期
  bindService绑定服务、unBindService解除绑定的服务
  服务是在被绑定的时候被创建,调用onUnbind、onDestrory方法,如果多次解除绑定会抛出异常
  推荐的方式:
  startService:开启并创建一个服务,服务长期运行在后台;
  bindService:绑定服务,可以调用服务里面的方法;
  unBindService:解除服务,停止服务里面的方法;
  stopService:停止服务,销毁服务对象;
 08_远程服务aidl的写法(重点)
  本地服务:写在自己的应用程序的工程里的服务 ,使用自己应用程序的进程运行这个服务;
  远程服务:写在别的应用程序的工程里的服务,使用别的应用程序的进程运行这个服务(安装在同一个手机上的应用程序);
  IPC: Inter Process Communication(进程间的通讯);
  aidl: Android Interface definition language 安卓接口定义语言;
  aidl的接口类里面不需要public 、protected、private 等修饰符,默认是公开共享;
  步骤:
  1、创建一个服务的接口类,里面包含需要对外暴露的业务逻辑方法: 
  2、让服务中的中间人实现了服务的接口类: 
  3、修改并拷贝接口文件:
  4、在本地服务的工程中的activity里,绑定服务:
  5、通过接口调用远程服务的方法: 
第九天:
 1、如何使用内容提供者
  定义类继承 ContentProvider,根据需要重写内部方法
 2、在清单文件的<application>节点下进行配置,<provider标签中需要>
  
第十天:
 1、在内存中创建原图的副本
  1、得到原图
   Bitmap srcPic = BitmapFactory.decodeResource(getResources(), R.drawable.meinv);
  2、创建一个空白的纸张,参考原图
    Bitmap copyPic = Bitmap.createBitmap(srcPic.getWidth(), srcPic.getHeight(), srcPic.getConfig()); 
  3、创建一个画板,参考空白纸张
   Canvas canvas = new Canvas(copyPic);
  4、创建一个画笔 
   Paint paint = new Paint();
   //默认是使用黑色,后面会根据原图的颜色画画
   paint.setColor(Color.BLACK);
  5、在画板上画画
   canvas.drawBitmap(srcPic, matrix,paint);
  6、为控件设置图片
   iv.setImageBitmap(copyPic);
  
  1、获得设备屏幕的分辨率
   WindowManager wm = getSystemService(WINDOW_SERVICE);
   获得设备分辨率对象
   Display display = wm.getDefaultDisplay();
  按照比例值缩放图片
           opts.inJustDecodeBounds = false;
           opts.inSampleSize = scale; // 1/scale * 1/scale
           Bitmap bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/lp.jpg", opts);