工作中的总结

一、滑屏与点击事件的冲突,主要是onInterceptTouchEvent和onTouchEvent调用时序

touch事件在onInterceptTouchEvent()和onTouchEvent以及各个childView间的传递机制完全取决于onInterceptTouchEvent()和onTouchEvent()的返回值。并且,针对down事件处理的返回值直接影响到后续move和up事件的接收和传递。 

关于返回值的问题,基本规则是:如果return true,那么表示该方法消费了此次事件,如果return false,那么表示该方法并未处理完全,该事件仍然需要以某种方式传递下去继续等待处理。

 

由于onInterceptTouchEvent()的机制比较复杂,上面的说明写的也比较复杂,总结一下,基本的规则是:

1. down事件首先会传递到onInterceptTouchEvent()方法。

2. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理。

3. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。

4. 如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一层次的view的onTouchEvent()处理。

5. 如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递给该view的onTouchEvent()处理。

二、切换动画效果的展示,主要是线程与动画

 

三、锁键盘

//重写View的onKeyDown来实现监控/拦截/屏蔽返回键、菜单键、音量调节键以及打/挂电话键

publicboolean onKeyDown(int keyCode, KeyEvent event)

   {

        switch (keyCode)

        {

            case KeyEvent.KEYCODE_BACK:

            case KeyEvent.KEYCODE_CALL:

            case KeyEvent.KEYCODE_ENDCALL:

            case KeyEvent.KEYCODE_MENU:

            case KeyEvent.KEYCODE_VOLUME_UP:

            case KeyEvent.KEYCODE_VOLUME_DOWN:

                returntrue;

               

        }

        returnsuper.onKeyDown(keyCode, event);

    }

 //由于Home键为系统键,onKeyDown()中不能捕获,需要重写onAttachedToWindow()来监控/拦截系统Home键

    publicvoid onAttachedToWindow()

    {

      this.getWindow().setType

(WindowManager.LayoutParams.TYPE_KEYGUARD);

        super.onAttachedToWindow();

    }

四、拍照上传实现了SurfaceHolder.Callback接口(在SurfaceHolder.Callback接口的surfaceCreated()的方法中初始化,在surfaceDestroyed()方法中释放摄像头资源)和Camera.PictureCallback接口(onPictureTaken()方法中保存图片数据到指定文件里)。

 1.检测手机是否有前置摄像头

for (int i = 0; i < Camera.getNumberOfCameras(); i++)

      {

        CameraInfo info = new CameraInfo();

        Camera.getCameraInfo(i, info);

        if (info.facing == CameraInfo.CAMERA_FACING_FRONT)

          {

             mCamera = Camera.open(i);

             mCamera.setPreviewDisplay(mSurfaceHolder);                                  

          }

       }

//获取摄像头参数

   Camera.Parameters mParameters = mCamera.getParameters();

   //设置图片格式

   mParameters.setPictureFormat(PixelFormat.JPEG);

   mCamera.setParameters(mParameters);

   //开始预览

   mCamera.startPreview();

  2. 拍照回调

   publicvoid onPictureTaken(byte[] data, Camera camera)

    {

Bitmap mBitmap = BitmapFactory.decodeByteArray

(data, 0, data.length);

    //文件路径和文件名

    File pictureFile = new File(

           Environment.getExternalStorageDirectory(), "camera.jpg");

    FileOutputStream mFileOutputStream = new FileOutputStream(

                        pictureFile);

    //将图像数据压入文件

    mBitmap.compress(Bitmap.CompressFormat.JPEG,75,

                        mFileOutputStream);

    }

3.拍照后将获取文件以流的方式上传

/**

     * 提交参数里有文件的数据

     * @param url  服务器地址

     * @param file 照片文件

     * @return服务器返回照片保存路径

     * @throws Exception

     */

    public String uploadSubmit(String url, File file) throws Exception

    {

        HttpPost post = new HttpPost(url);

        MultipartEntity entity = new MultipartEntity();

       

        // 添加文件参数

        if (file != null && file.exists())

        {

            entity.addPart("file", new FileBody(file));

        }

        post.setEntity(entity);

        HttpClient httpClient = new DefaultHttpClient();

        HttpResponse response = httpClient.execute(post);

        int stateCode = response.getStatusLine().getStatusCode();

        StringBuffer sb = new StringBuffer();

       

        if (stateCode == HttpStatus.SC_OK)

        {

            HttpEntity result = response.getEntity();

            if (result != null)

            {

                InputStream is = result.getContent();

                BufferedReader br = new BufferedReader(

                        new InputStreamReader(is));

                String tempLine;

                while ((tempLine = br.readLine()) != null)

                {

                    sb.append(tempLine);

                }

            }

        }

        post.abort();

        return sb.toString();

    }

五、其他

1.LinearLayout对onTouchEvent事件无作用

    解决方案:使mainLayout获取焦点====》 mainLayout.setClickable(true);

2.ListView获取不了焦点

    解决方案:在适配器中添加

    adapterView.setFocusable(true);

    adapterView.setFocusableInTouchMode(true);

    adapterView.requestFocus();

3.linearlayout的背景适应不了定义高度:

解决方案:可能跟分辨率有关,试着将图片放高、中、低分辨率的文件夹中

4.获取SD卡的路径:Environment.getExternalStorageDirectory()

5. 获取本机电话号码

   TelephonyManager tm = (TelephonyManager)this.getSystemService

(Context.TELEPHONY_SERVICE);

   String phoneNumber = tm.getLine1Number();

//********************************************************************

扩展TelephonyManager

获取SIM卡信息。在SIM卡中并没有保存用户的手机,区分每一张SIM是通过IMSI码。在运营商的数据库中存在手机号码和IMSI码的映射,所以手机是通过发送IMSI码到运营商的一端,获得自己的手机号码。

TelephonyManager tm = (TelephonyManager)this.getSystemService

(Context.TELEPHONY_SERVICE);

 

    //获取手机号码一般是为空的,因为运营商没有基本没有把本机电话保存在SIM卡中   标识每一张SIM卡是通过IMSI(tm.getSubscriberId()).

    //在运营商的数据库表中有IMSI码与电话号码的映射。所以,手机是通过发送IMSI码到运营商一端,才获得自己的手机号码

    String phonenumber = tm.getLine1Number();

     //获得每一张电话卡的唯一标识IMSI

    String subscriberid = tm.getSubscriberId();

    //获取网络的类型

    int phonetype = tm.getPhoneType();

    String phonetype_str = "null";

    switch(phonetype){

      case TelephonyManager.PHONE_TYPE_GSM:

          phonetype_str ="GSM网络";

          break;

      case TelephonyManager.PHONE_TYPE_CDMA:

          phonetype_str ="CDMA网络";

          break;

      case TelephonyManager.PHONE_TYPE_NONE:

          phonetype_str ="未识别网络";

          break;

    }

    //获取手机状态

    int simstate = tm.getSimState();

    String simstatestr = "null";

    switch(simstate ){

      case TelephonyManager.SIM_STATE_UNKNOWN:

          simstatestr = "未知状态";

          break;

      case TelephonyManager.SIM_STATE_ABSENT:

          simstatestr = "未插卡";

          break;

      case TelephonyManager.SIM_STATE_PIN_REQUIRED:

          simstatestr = "需要PIN密码解锁";

          break;

      case TelephonyManager.SIM_STATE_PUK_REQUIRED:

          simstatestr = "需要PUK密码解锁";

          break;

      case TelephonyManager.SIM_STATE_READY:

          simstatestr = "就绪";

          break;

      case TelephonyManager.SIM_STATE_NETWORK_LOCKED:

          simstatestr = "SIM已经被锁住";

          break;

    }

读取这些数据需要权限

<uses-permission android:name="android.permission.READ_PHONE_STATE">
</uses-permission>
****************************************************************//

6.发送短信

//信息管理对象

SmsManager smsManager = SmsManager.getDefault();

PendingIntent intent = PendingIntent.getBroadcast

(context, 0, new Intent(),0);

// 按照一条短信,最大容量拆分成多条短信

List<String> divideContents = smsManager.divideMessage("手机IMSI码为" + safedSubscriberid + " 已被更换SIM卡,更换的SIMIMSI码为:" + subscriberid);

for (String text : divideContents)

{smsManager.sendTextMessage

(<参数1>, <参数2>, <参数3>, <参数4>, <参数5>);}

-- 参数1: destinationAddress:目标电话号码

-- 参数2: scAddress:短信中心号码,测试可以不填

-- 参数3: text: 短信内容

-- 参数4: sentIntent:发送 -->中国移动 --> 中国移动发送失败 --> 返回发送成功或失败信号 --> 后续处理   即,这个意图包装了短信发送状态的信息

-- 参数5: deliveryIntent: 发送 -->中国移动 --> 中国移动发送成功 --> 返回对方是否收到这个信息 --> 后续处理  即:这个意图包装了短信是否被对方收到的状态信息(供应商已经发送成功,但是对方没有收到)。

 声明短信发送权限

  <uses-permission android:name="android.permission.SEND_SMS"/>

//*****************************************************************************

扩展SmsManager之 读取短信内容

接收短信时发送的广播

<receiver android:name=".ReceiveSMSReceiver">

<intent-filter>

<action android:name="android.provider.Telephony.SMS_RECEIVED" />

</intent-filter>

</receiver>

在接收某些广播的时候需要权限,例如接收短信的广播就需要

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

 <uses-permission android:name="android.permission.READ_SMS"/>

当短信到来的时候,系统会将短信的内容封装成pdu的格式,然后放到intent里面。所以要获得短信的内容,就通过intent,将puds拿出来就可以了,它返回的是Object数组

Object[] messages = (Object[]) intent.getSerializableExtra("pdus");

  创建一个二维字节数组

byte[][] pduObjs = new byte[messages.length][];

for (int i = 0; i < messages.length; i++){
 
pduObjs[i] = (byte[]) messages[i];

}

byte[][] pdus = new byte[pduObjs.length][];

int pduCount = pdus.length;

SmsMessage[] msgs = new SmsMessage[pduCount];

for (int i = 0; i < pduCount; i++){

pdus[i] = pduObjs[i];

msgs[i] = SmsMessage.createFromPdu(pdus[i]);

}

return msgs;

}

一条短信就是一个SmsMessage ,这个SmsMessage可以通过一个byte[]来创建

*************************************************************************//

7. 关于SharedPreferences

在android平台下用于保存数据有三种方式:

1、SQLite 2、SharedPreferences 3、File

SharedPreferences是将数据保存在一个xml文件中,并且是以Map的形式保存,一个Key对应一个Value,但获取某一个Key的时候,都会有一个默认值,这个默认值是在xml不存在这个key值的时候使用

获得SharedPreferences是通过上下文(Context)中的getSharedPreferences方法获得。SharedPreferences  sp = this.getSharedPreferences("data",

         MODE_WORLD_READABLE);

  第一个参数是指定xml文件的名字,当不存在的时候就会创建它。

第二个参数是获得这个SharedPreferences的模式,一共有四种模式:

MODE_APPENDMODE_PRIVATEMODE_WORLD_READABLE MODE_WORLD_WRITEABLE

SharedPreferences中取值是通过sp.getXXX的方式可以获得对应key的值,在getXXX的时候,需要指定一个默认的值,当key值不存在的时候使用。

ShaSharedPreferences中设值需要用到Editor

 Editor editor = sp.edit();

获得了Editor之后,才能对SharedPreferences进行写

editor.putXXX(“key”,value) 

最后需要注意的一点是别忘了commit

Xml文件存放的位置位于data/data/包名/shared_prefs/xxx.xml

8.java监听者模式

9. 触摸ListView背景会变黑

出现原因:如果不使用手机上下按键的时候,直接用触摸拖动视图的方式,会发现ListView的背景一片黑色,而且所有被选中的文字都变成一片漆黑。

其实这个问题发生的原因在于ListView存在缓存颜色机制,

解决方案:可以通过设定缓存颜色为透明的方法来解决这个问题:

A、通过布局属性来设定(ListView的属性中直接定义)

android:cacheColorHint=#00000000

B、在代码中直接设定

listView.setCacheColorHint(Color.TRANSPARENT)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值