曾经的坑

过去的开发总是踩到n多的坑,虽然找到了处理的方案并解决,但后继在遇到的时候,大概只记得有这回事,怎么处理又忘记了,所以打算将自己踩过的坑和处理的问题记录下来。

那些坑们:

1、获取的蓝牙的信息没有放在一个统一的单例对象中 T T

设计开发底层库时,涉及到多个应用同时使用同个服务,数据应该要做好分类,那些是不同应用要各自初始化的,那些需要或可以统一使用的。

-----------------------------------------------------------------------------------

好文:开发第三方库最佳实践

     随想录:开发一流Android SDK

    Android 开发:由模块化到组件化(一)

-----------------------------------------------------------------------------------


2、在6.0系统下,无法进行自动的匹配甚至接不到任何的广播

原因:加了一个权限:http://www.jianshu.com/p/376b05ed8f4d 

自动匹配参考:http://blog.csdn.net/qq_25827845/article/details/52400782


3、由于把不同的功能模块分成了多个module,所以在最后合并生成的时候发现不会把依赖打包进去:

http://zkread.com/article/1150352.html


4、aidl回调传输数据:传的对象中不能包含对象(也许是处理的不对);


5、蓝牙BLE:

a.使用ble的扫描方式时,扫描不到蓝牙2.0设备,硬件的哥们解释是说从机(被连接设备)是单模的,只能被蓝牙2.0扫描模式扫到,但也有资料说ble只能是扫描4.0或2.0,不能同时扫描4.0和2.0设备([转载]蓝牙4.0——Android BLE开发官方文档翻译

b.由于2.0和4.0的协议改变,所以连接时需要根据不同版本区分处理,device对象的gettype()可以返回设备支持的连接方式

c.ble的写入操作必须在事件完成后再继续。所以需要在onCharacteristicWrite里加上一些处理(阻塞进程是没有用的,还是会有失败的情况)

-----------------------------------------------------------------------------------

好文:Android 上的低功耗蓝牙实践


6、判断应用是否在后台运行的问题:

红米Note:包名匹配+importance属性比较

其他(华为荣耀,htc):包名匹配即可


7、音/视频声道设置:

音频(AudioTrack):

/**
 * Sets the specified left and right output gain values on the AudioTrack.
 * <p>Gain values are clamped to the closed interval [0.0, max] where
 * max is the value of {@link #getMaxVolume}.
 * A value of 0.0 results in zero gain (silence), and
 * a value of 1.0 means unity gain (signal unchanged).
 * The default value is 1.0 meaning unity gain.
 * <p>The word "volume" in the API name is historical; this is actually a linear gain.
 * @param leftGain output gain for the left channel.
 * @param rightGain output gain for the right channel
 * @return error code or success, see {@link #SUCCESS},
 *    {@link #ERROR_INVALID_OPERATION}
 * @deprecated Applications should use {@link #setVolume} instead, as it
 * more gracefully scales down to mono, and up to multi-channel content beyond stereo.
 */
@Deprecated
public int setStereoVolume(float leftGain, float rightGain) {
    if (mState == STATE_UNINITIALIZED) {
        return ERROR_INVALID_OPERATION;
    }

    baseSetVolume(leftGain, rightGain);
    return SUCCESS;
}

视频(MediaPlayer):

/**
 * Sets the volume on this player.
 * This API is recommended for balancing the output of audio streams
 * within an application. Unless you are writing an application to
 * control user settings, this API should be used in preference to
 * {@link AudioManager#setStreamVolume(int, int, int)} which sets the volume of ALL streams of
 * a particular type. Note that the passed volume values are raw scalars in range 0.0 to 1.0.
 * UI controls should be scaled logarithmically.
 *
 * @param leftVolume left volume scalar
 * @param rightVolume right volume scalar
 */
/*
 * FIXME: Merge this into javadoc comment above when setVolume(float) is not @hide.
 * The single parameter form below is preferred if the channel volumes don't need
 * to be set independently.
 */
public void setVolume(float leftVolume, float rightVolume) {
    baseSetVolume(leftVolume, rightVolume);
}

 这个东西也是让人醉,很简单的东西,但因为用了传说中ijkplayer框架,对这个框架不熟,然后网上也没有找到相关的设置,搞我的又是去找有这功能的app,又是去反编译,那编译功能还出了bug,又远程到自己家里的电脑再折腾才搞定

==========2017_3_5补:

不知安卓原生就是这样,还是各大厂商埋坑能力确实牛x,setVolume(0)的时候也是会有声音的,不管是audiotrack还是mediaplayer都会有,而且残留的声音大小也是不一样的,有些几乎听不到,有些则完全没用。针对这个问题,mediaplayer可以在setVolume后加再调用meadiaplayer的start()方法,应该又可以处理掉一些厂商的,至少我们这是这样的;audiotrack没有处理过这个问题。



还有如果是声音播放产生的电频作为介质跟硬件交互的话

audiotrack的上述几个参数一定要保持一致,不会电频信号是会有误差的 T T。


h5:ChannelSplitterNode

领导随口一问,我也就随手一查,感觉pc可以,但手机不一定行


8.bluetoothsocket/bluetoothsocketService 第一次或某一次连接失败的问题

原因:

/**
 * Get the input stream associated with this socket.
 * <p>The input stream will be returned even if the socket is not yet
 * connected, but operations on that stream will throw IOException until
 * the associated socket is connected.
 * @return InputStream
 */
public InputStream getInputStream() throws IOException {
    return mInputStream;
}
百度翻译了一下上面注释的意思,大概的意思是返回的mInputStream可能是在socket还没准备就获取的,如果没有准备好就去read sream 就会返回read fail的错误。
所以我的处理是在socket.getInputStream之前先阻塞500毫秒以保证socket是准备好的。
 
 
 
 
 

9.使用YuvImage时出现的内存溢出问题

这段时间在做基于seeta的人脸识别功能。功能实现后跑的时候发现会出现内存溢出的问题。试了半天发现在调用了YuvImage的compressToJpeg方法后,内存并没有自动释放,YuvImage也没有提供可以手动释放的方法,源码最后走的是native层方法,所以只能放弃了。百度半天不行,最后在stackoverflow发现别人早遇到这个问题,并给出方案:

/**
 * Converts YUV420 NV21 to RGB8888
 *
 * @param data byte array on YUV420 NV21 format.
 * @param width pixels width
 * @param height pixels height
 * @return a RGB8888 pixels int array. Where each int is a pixels ARGB.
 */
public static int[] convertYUV420_NV21toRGB8888(byte [] data, int width, int height) {
    int size = width*height;
    int offset = size;
    int[] pixels = new int[size];
    int u, v, y1, y2, y3, y4;

    // i percorre os Y and the final pixels
    // k percorre os pixles U e V
    for(int i=0, k=0; i < size; i+=2, k+=2) {
        y1 = data[i  ]&0xff;
        y2 = data[i+1]&0xff;
        y3 = data[width+i  ]&0xff;
        y4 = data[width+i+1]&0xff;

        u = data[offset+k  ]&0xff;
        v = data[offset+k+1]&0xff;
        u = u-128;
        v = v-128;

        pixels[i  ] = convertYUVtoRGB(y1, u, v);
        pixels[i+1] = convertYUVtoRGB(y2, u, v);
        pixels[width+i  ] = convertYUVtoRGB(y3, u, v);
        pixels[width+i+1] = convertYUVtoRGB(y4, u, v);

        if (i!=0 && (i+2)%width==0)
            i+=width;
    }

    return pixels;
}

private static int convertYUVtoRGB(int y, int u, int v) {
    int r,g,b;

    r = y + (int)(1.402f*v);
    g = y - (int)(0.344f*u +0.714f*v);
    b = y + (int)(1.772f*u);
    r = r>255? 255 : r<0 ? 0 : r;
    g = g>255? 255 : g<0 ? 0 : g;
    b = b>255? 255 : b<0 ? 0 : b;
    return 0xff000000 | (b<<16) | (g<<8) | r;
}
上面的方法是上面将camera原始帧数据转成正常RGB数据,调用Bitmap.create即可。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值