dp 如何关掉android_android关闭a2dp通道 - CSDN
  • A2dp profile是android支持的一种蓝牙情景模式,一般用于蓝牙立体声耳机,即蓝牙音频的输出 在android的app层中,A2dp的使用并不是很开放,api只提供了非常少的操作接口,连基本的连接都只能用反射来调用底层的方法...

    A2dp profile是android支持的一种蓝牙情景模式,一般用于蓝牙立体声耳机,即蓝牙音频的输出

    在android的app层中,A2dp的使用并不是很开放,api只提供了非常少的操作接口,连基本的连接都只能用反射来调用底层的方法。a2dp的使用是通过BluetoothA2dp这个代理类来控制A2dp服务的,这里简单举例使用的方法:

     

    private BluetoothAdapter mBluetooth = BluetoothAdapter.getDefaultAdapter();
    mBluetooth.getProfileProxy(this, new profileListener(), BluetoothProfile.A2DP);
    
    public class profileListener implements ServiceListener {
    	@Override
    	public void onServiceConnected(int profile, BluetoothProfile proxy) {
    		// TODO Auto-generated method stub
    		Log.i(TAG, "onServiceConnected()");
    		mBluetoothProfile = proxy;
    		mHandler.sendEmptyMessage(MESSAGE_A2DP_PROXY_CHANGED);
    	}
    
    	@Override
    	public void onServiceDisconnected(int profile) {
    		// TODO Auto-generated method stub
    		Log.i(TAG, "onServiceDisconnected()");
    	}    	
    }


    该profile的连接和断开的方法在Android源码中有定义,因此可以通过反射来获取到接口:

     

     

    public void a2dpConnect(BluetoothDevice device){
    	BluetoothA2dp a2dp = (BluetoothA2dp) mBluetoothProfile;
    	a2dp.isA2dpPlaying(device);
    	Class<? extends BluetoothA2dp> clazz = a2dp.getClass();
    	Method m2;
    	try {
    		Log.i(TAG,"use reflect to connect a2dp");
    		m2 = clazz.getMethod("connect",BluetoothDevice.class);
    		m2.invoke(a2dp, device);
    	} catch (Exception e) {
    		// TODO Auto-generated catch block
    		e.printStackTrace();
    		Log.e(TAG,"error:" + e.toString());
    	}	
    }


    另外需要注意的是,由于使用了反射的方法,并非适用于所有版本的android系统,4.2.2以上的连接的成功率还是较高的;同时,在获取连接的状态上,也并非所有的系统都能或得到正确的状态,有些系统或硬件平台不支持该profile的操作,所以在实际使用时,要因地制宜,因机而异。

    转载于:https://www.cnblogs.com/Free-Thinker/p/4565250.html

    展开全文
  • 蓝牙A2DP-android

    2018-03-13 18:20:51
    Android 是Google 于2007 年11 月5 日宣布的基于Linux平台开源手机操作系统名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。本文通过研究蓝牙无线...

    转自:http://blog.csdn.net/zoe6553/article/details/7195860
    Android 是Google 于2007 年11 月5 日宣布的基于Linux平台开源手机操作系统名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。本文通过研究蓝牙无线通信协议栈,在Android 手机平台上设计并实现了蓝牙立体声耳机收听高保真音乐的功能(即A2DP 应用框架的实现)。
      
      关键词:蓝牙;A2DP ;Android
      
      1.引言
      蓝牙(Bluetooth)技术规范由蓝牙特别兴趣小组(SIG)制订,在使用通用无线传输模块和数据通信协议的基础上,开发交互式服务和应用,多用于便携式通信设备。
      蓝牙规范包括核心协议与应用框架(profiles)两个文件。协议规范部分定义了蓝牙的各层通信协议,应用框架只出了如何采用这些协议实现具体的应用产品[1]。
      蓝牙协议规范遵循开放系统互联参考模型(Open System Interconnection/ReferencedModel, OSI/RM),从低到高地定义了蓝牙协议栈的各个层次。
      逻辑链路控制与适配协议以下的协议都是蓝牙无线通信的核心协议,为蓝牙通信提供无连接与面向连接的数据通道。串口仿真协议将很容易地实现有具有电缆的串行通信应用模型向无线串行通信领域的转移。服务发现协议服务发现协议(SDP)是蓝牙技术框架中非常重要的一个部分,它是所有应用模型的基础。任一蓝牙应用模型的实现都是利用某些服务的结果。
      在设备之间组网的基本动机就是使这些设备相互通信,并且获得彼此的服务。其他协议都是蓝牙应用协议,本文就是在AVDTP(音视频发布传输协议)基础上实现A2DP的功能[2]。
      
      2.开发平台及Android系统
      文本的硬件平台是以Mavell公司的Tavor平台为基础,Tavor平台包换两各部分:应用程序子系统和通信子系统。其中XscaleCPU(624 MHz)用于应用程序子系统,ARMCPU(34.67MHz to 208MHz)与MSA core(52 MHzto 312MHz)一同专门处理通信模块子系统,当手机处于待机状态时,XScaleCPU会处于休眠状态以节省电量,两个CPU使用自己的DDR内存,通信通过MSL串行总线。蓝牙芯片通过串口与XScale相连。
      
      2.1 音频系统
      蓝牙芯片(WLAN/Bluetooth88W8688,串口连接最大3.6Mbps,64-byteFIFOs)作为外设有两条数据通路,一条是SSP3串行接口用于语音通信PCM数据的收发,用于创建SCO链路。另一条是和串口控制器的连接用于ACL数据分组的收发以及以数据分组为基础的其他应用。I2C总线用与控制音频解码芯片进行选路的操作(声音从哪里出来,喇叭,有线耳机或蓝牙设备)。SSP2接口是音频数据传送的通道。
      
      2.2 Android 系统
      Android是一个为移动设备设计的软件平台,包括操作系统、中间件和一些关键应用。
      目前发布的Android SDK提供了必须的工具和进行应用开发所必须的API,在Android上的开发使用Java语言。
      开发者开发自己的应用时可以调用核心应用所使用的相同的API接口。这个应用程序架构被设计用来简化组件的重用;任何应用都可以宣布它的功能,其他的任何应用都可以使用这些功能。相同的机制允许组件被用户替换。
      Android包括了一套C/C++库,这些功能是通过Android应用框架提供给开发者的。
      每个Android应用程序在它自己的进程中运行,有它自己的Dalvik虚拟机的实例。Dalvik已经被改写过,使得一个设备可以有效得运行多个VM。Dalvik虚拟机运行自己独特的可执行文件格式–.dex,该格式经过优化,使用尽量少的内存。Dalvik虚拟机依赖LinuxKernel提供底层功能支持,如线程、底层内存管理。
      Android依赖Linux内核2.6提供核心系统服务,比如安全、内存管理、进程管理、网络、硬件驱动。蓝牙的驱动也包含其中。在这里,Linux内核扮演的是硬件层和系统其他层次之间的一个抽象层的概念。
      
      3. A2DP的实现
      A2DPProfile定义了高质量音频数据传输的协议和过程,包括立体声和单声道数据的传输。这里的高质量音频指的是单声道(Mono)和立体声(Sterco)的音频,主要区别于蓝牙SCO链路上传输的普通语音。A2DP的典型应用是将音乐播放器的音频数据发送到耳机或音箱。
      由于蓝牙提供的带宽较窄,音频数据可能需要进行有效的压缩才能保证接收端的实时播放。
      目前A2DP只定义了点对点的音频传输,没有定义广播式的音频传输,可能是由于速率的原因。
      A2DP建立在AVDTP传输协议的基础之上,AVDTP规定了链接是如何建立的,连接建立好之后,音频数据经过压缩之后,便可以收发了。音频数据是双向的[4]。
      此应用框架定义了两个音频设备角色:音频源和汇点。
      源(SRC)–当设备充当被传输至微微网 SNK 的数字音频流时,则设备称为数据流源。
      汇点(SNK)–当设备充当从在同一微微网上的数据流源传输的数字音频流时,则设备称为数据流汇。
      
      3.1 信令过程
      首先使用Stream_End_Point_Discover命令发现ACP中的流端点,主要工作是要去查询远端的蓝牙设备(需要远端蓝牙设备的地址,这个地址是唯一的)可以提供的SEP,每个SEP可以提供一些服务。远端的蓝牙设备会返回一个respond,respond包含一些信息,最重到是有多少个SEID,媒体服务类型等信息并不十分重要,服务类型可以通过Get_Capablities来获得。
      然后从中选择将要建立的流端点。发送Stream_End_Point_Discover命令之后,会获得很多个SEID,然后就要发送Get_Capabilites命令来获得每个SEP所能提供的服务。(一个SEID代表一个SEP)具体的服务类型,以及字段detail参见AVDTP的手册。我们感兴趣的是,蓝牙设备(例如蓝牙头戴式设备)是否拥有SBC解码的能力,A2DP规定,蓝牙立体声耳机必须支持SBC解码,其他的解码方式是可选的,有关SBC的内容要参见A2DP协议。
      再使用Set_Configuration命令对流端点进行配置,通过Get_Capabilites,可以知道 SEP可以支持的服务,然后根据服务类型再进行一下具体的配置。需要配置音频的声道,采样率等信息。当然配置的时候,要给出SEID参数,指明对哪个SEP进行配置。
      最后就是启动流Stream_Start,如果某个SEP具有AudioMedia的服务,那么打开一个stream,给出SEID参数,stream 是对应某个SEP。开启stream之后,就可以利用write系统调用向socket里写音频数据了,写的时候不需要再指明具体的SEID。
      链路建立好之后,就可以进行数据传输,建链的过程,属于AVDTP 协议的内容, 而传输的内容要符合A2DP的规定,当然 A2DP 与AVDTP是密不可分的。
      
      3.2 音频编码
      PCM码流,需要很大的带宽,即低效又费电,不适合无线传输。因此需要编码压缩之后,再进行传输。
      A2DP要求SRC和SNK至少要支持低于复杂度自带编解码(Low ComplexitySubbandCodec,SBC)标准。MPEG-1 Audio,Mpeg-2Audio,MPEG-2,4高级音频编码(AdvancedAudio Coding,ACC)和自适应变换音频编码(AdaptiveTransform AcousticCoding,ATRAC)这几种音频编码标准是可选的。除此之外的其他编码标准称为“非A2DP编码(Non-A2DPCodec)[5]。
      低复杂度自带编解码(SBC)是专门为蓝牙音视频设计的,它可以在中等传码率下获得较高的音频质量,并且具有较低的计算复杂度。
      在信令交互的过程中,需要发现蓝牙设备的SEP并获得其服务能力,如果SEP具有SBC解码能力,那么需要对SBC有关参数进行配置,相关参数如下:
      采样频率(48K,44.1K,32K,16K)声道模式(Mono,DualChannel,Stereo)块长度(4,8,12,16)子带(4,8)分配方法(SNR、LOUDNES)BitPool(2~250)决定传码率的编解码信息包含于SBC数据帧头部,并且和音频数据流一起被不断的发送到SNK。
      
      3.3 Android下的实现
      Android系统中,应用程序只能看到AudioSystem这个接口,AudioFlinger是一个实现类,主要用于音频选路和PCM包的混音与重采样,并把PCM数据包传送给底层。AudioFlinger在所有进程中只有一个实体,其他进程如需要访问通过Binder进程间通信的方式进行访问。
      AudioHardware是一层硬件抽象层,主要负责音频数据的收发与控制。AudioFlinger把他看成实际的硬件。当音频路径设置成A2DP时,通过Bluetooth模块收发数据,通过立体声蓝牙耳机即可听到高保真音乐。
      AudioAccessory主要用于事件的监听,并把这些事件发送给AudioFlinger模块进行音频路径的重新设定。当蓝牙立体声耳机匹配之后,AudioAccessory会从kernel中获得相应的信息(监听HCI层的事件),然后把音频路径配置成A2DP模式,这样音频数据就只会发送到蓝牙耳机当中,如有必要,也可以设置扬声器的音频解码芯片转入休眠状态。
      当有音频数据播放时,由于SBC音频压缩的开源代码只能压缩512bytes大小的数据因此,AudioHardware每次发送下来4096Bytes,然后把这4096个字节分割成N个512Bytes的小块,放入一个队列当中。经过SBC压缩之后变成113bytes。另外一个线程会每次对SBC压缩好的包进行再封装,封装成一个标准的A2DP packet,然后再把这样的A2DP packet移动到发送队列当中。
      最后设定好软件定时器,每隔一段时间回发送一个A2DP包。这个时间间隔是SBC编码期间返回的推荐值。
      
      4.结果与性能评估
      测试用的耳机是Motorola的S9型蓝牙耳机,耳机配对之后,选择一首MP3音乐进行播放,最开始的程序是A2DP开源的测试程序,在Linuxshell下播放PCM数据流的音频文件可以正常播放,但整合到Android系统中便产生了较大的延迟。后来引入缓存队列和定时器后,效果有了明显改善。
      
      5.总结
      本文通过研究蓝牙无线通信协议栈,并分析了蓝牙音频视频分布传输协议,简要介绍了Android系统的特点,并在开源测试程序的基础上做了相应的改进并改善了音频文件播放的效果。较完整地在Android手机平台上设计并实现了蓝牙立体声耳机收听高保真音乐的功能(即A2DP 应用框架的实现)。
      
    十年论文机构京都名师论文中心,正规全面的论文刊物为您提供职称论文,毕业论文,硕士论文,医学论文,教育论文等各类论文发表服务。
      参考文献
      [1] 金纯 林金朝 万宝红.蓝牙协议及其源代码分析.国防工业出版社,2006
      [2] 米勒.蓝牙核心技术:全球无线通信开放规范的权威性指南.机械工业出版社,2001
      [3] Bluetooth SIG.Generic Audio/Video Distribution Profile,2007
      [4] Bluetooth SIG.Core Specification of the Bluetooth 2.0 +EDR,2004
      [5] Bluetooth SIG.Advanced Audio Distribution Profile Specification,2007

    展开全文
  • android:layout_width="286dp" android:layout_height="377dp" android:layout_centerInParent="true" android:id="@+id/mmmmm" android:background="#e0000000" > android:id="@+id/dialogseven_title" ...
  • 本文是蓝牙音频相关的第3篇文章,查阅其他内容,请点击《Android蓝牙开发系列文章-策划篇》。...2.如何实现a2dp和a2dp sink状态的切换? 2.1将设备暂停a2dp 2.2启动a2dp sink 1.什么是a2dp sink? ...

    本文是蓝牙音频相关的第3篇文章,查阅其他内容,请点击《Android蓝牙开发系列文章-策划篇》。

    目前a2dp相关的内容有:

    《Android蓝牙开发系列文章-AudioTrack播放PCM音频》

    《Android蓝牙开发系列文章-蓝牙音箱连接》

    我们通常直接手机听歌或者接个蓝牙音箱来听歌,其实你的手机也可以变成一个蓝牙音箱来使用。

    怎么来做这个转变呢?让我一起学起来吧~

    本文主要内容包括:1.什么是a2dp sink? 2.如何实现a2dp和a2dp sink状态的切换?

    目录

    1.什么是a2dp sink?

    2.如何实现a2dp和a2dp sink状态的切换?

    2.1将设备暂停a2dp

    2.2启动a2dp sink


    1.什么是a2dp sink?

    两个蓝牙设备连接之后,一个设备提供音频数据,另外一个设备出声音,我们将提供数据的一端称为a2dp source(源端),发出声音的一端称为a2dp sink(目的端)。

    也就是说,a2dp与a2dp sink是两个相对的状态,一个蓝牙设备一个时刻只能处于其中的一种状态。

    现在一些智能设备可以实现a2dp与a2dp sink状态之间的切换(但一个时刻只能是其中一个状态)。

    与a2dp/a2dp sink协议紧密关联的一个协议之avrcp(Audio/Video Remote Control Profile)协议,该协议实现了从sink端到souce端的反向控制,例如,暂停、停止、启动重放、音量控制及其它类型的远程控制操作。

     

    2.如何实现a2dp和a2dp sink状态的切换?

    在实际动手完成两个状态切换前,需要明确你的设备是否支持这两种状态。对于耳机、音箱这类设备而言,即使将它砸了,它也很难切到a2dp source状态,因为它一出生就决定了自己没有这个状态的使用场景,不信你可以砸了试一下,O(∩_∩)O哈哈~

    而对于通常作为音乐播放端的某些手机和智能电视是可能切到sink状态的。 

    怎么来判断自己的手机或者电视是否支持a2dp sink呢?大体可以按照如下步骤确定,但是不是说这个步骤都满足了,你的设备肯定是支持a2dp sink的,因为我们看不到设备的源码,甚至我们连root权限都没有。

    1. 确认设备是否自带sink功能的使用场景(一般来说,如果没有自带使用场景,sink功能应该要默认关闭,不然就是给自己的产品挖了一个坑)
    2. 串口执行:dumpsys package com.android.bluetooth,看一下是否支持A2dpSinkService
    3. 去跟蓝牙芯片方案商确认是否支持sink功能
    4. 参考本文的代码,写一个demo来试一下

    下面来讲一下我们的demo实现:

    2.1将设备暂停a2dp

    在停掉a2dp前,我们需要将处于连接状态的设备进行断开。

    为了让我们的设备可以被其他设备扫描到和可被连接,我们需要将设备的蓝牙扫描模式设置成可被发现、可被连接。

    如上提到的两点也是很重要的,我的demo里面没有实现它,是通过在设置中进行操作来替代了代码实现。

    停掉a2d的动作对于应用层来说就是停掉a2dp service,这个动作会触发一些系列的a2dp状态清理动作,这个动作是从上而下的一整套,不仅仅是设计Host端,也涉及Controller。

        public void stopSource() {
            Intent intent = new Intent();
            intent.setAction("com.android.bluetooth/.a2dp.A2dpService");
            intent.setPackage("com.android.bluetooth");
            intent.putExtra("action", "com.android.bluetooth.btservice.action.STATE_CHANGED");
            intent.putExtra(BluetoothAdapter.EXTRA_STATE, 10);
            startService(intent);
        }

    你也许会问:你怎么知道这样写就可以启动A2dpService的?

    如果,你研究过蓝牙开关流程的话,你应该看到过各种profile的启动流程,也就是说以上这段代码就是从源码中摘出来的,

    Android源码如下:

    @SuppressWarnings("rawtypes")
        private void setGattProfileServiceState(Class[] services, int state) {
            if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) {
                Log.w(TAG,"setGattProfileServiceState(): invalid state...Leaving...");
                return;
            }
    
            int expectedCurrentState= BluetoothAdapter.STATE_OFF;
            int pendingState = BluetoothAdapter.STATE_TURNING_ON;
    
            if (state == BluetoothAdapter.STATE_OFF) {
                expectedCurrentState= BluetoothAdapter.STATE_ON;
                pendingState = BluetoothAdapter.STATE_TURNING_OFF;
            }
    
            for (int i=0; i <services.length;i++) {
                String serviceName = services[i].getName();
                String simpleName = services[i].getSimpleName();
    
                if (simpleName.equals("GattService")) {
                    Integer serviceState = mProfileServicesState.get(serviceName);
    
                    if(serviceState != null && serviceState != expectedCurrentState) {
                        debugLog("setProfileServiceState() - Unable to "
                            + (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" )
                            + " service " + serviceName
                            + ". Invalid state: " + serviceState);
                            continue;
                    }
                    debugLog("setProfileServiceState() - "
                        + (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting")
                        + " service " + serviceName);
    
                    mProfileServicesState.put(serviceName,pendingState);
                    Intent intent = new Intent(this,services[i]);
                    intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED);
                    intent.putExtra(BluetoothAdapter.EXTRA_STATE,state);
                    startService(intent);
                    return;
                }

    2.2启动a2dp sink

    直接上代码:

    public void startSink() {
            Intent intent = new Intent();
            intent.setAction("com.android.bluetooth/.a2dp.A2dpSinkService");
            intent.setPackage("com.android.bluetooth");
            intent.putExtra("action", "com.android.bluetooth.btservice.action.STATE_CHANGED");
            intent.putExtra(BluetoothAdapter.EXTRA_STATE, 12);
            startService(intent);
        }

    这么写的原因在上面已经说了哈~ 

    这里要说一下,在不同的Android版本中,a2dp sink的路径有所改变,也就是intent action的写法会有所区别。可以针对具体设备就行分析,一个方法:dumpsys package com.android.bluetooth看一下,例如,我的设备显示长这个样子:

    好了,本篇内容到这里就结束了~

    欢迎留言讨论问题哈

    如果想持续关注本博客内容,请扫描关注个人微信公众号,或者微信搜索:万物互联技术。

     

    展开全文
  • 最近抽时间学习一下Android,做个笔记: 布局xml: <LinearLayout android:id="@+id/date_label" android:layout_width="35dp" android:layout_height="wr...

    最近抽时间学习一下Android,做个笔记:

    布局xml:

       <LinearLayout
                         android:id="@+id/date_label"
                        android:layout_width="35dp"
                        android:layout_height="wrap_content"
                        android:background="@layout/slipercornerenable"
                        android:gravity="right|center"
                        android:padding="1dp" >
    
                        <LinearLayout
                            android:layout_width="18dp"
                            android:layout_height="18dp"
                            android:background="@layout/slipercircle" >
                        </LinearLayout>
                    </LinearLayout>
    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        view = View.inflate(this, layout.listview_select_date, null);
    //设置两个选项的监听
                view.findViewById(id.date_label).setOnClickListener(this);
                view.findViewById(id.auto_update_date).setOnClickListener(this);
    
    }

    切换方法:

     
        void switchControl(View view) {
            LinearLayout llLayout = (LinearLayout) view;
            int tag = 0;
            if (view.getTag() != null) {
                tag = Integer.parseInt(view.getTag().toString());
            }
            if (tag == 0) {
                // 打开
                view.setTag(1);
                view.setBackgroundResource(layout.slipercornerenable);
                llLayout.setGravity(Gravity.RIGHT);
            } else {
                // 关闭
                view.setTag(0);
                view.setBackgroundResource(layout.slipercornerdisenable);
                llLayout.setGravity(Gravity.LEFT);
            }
        }

     

    实现onClick事件:

        @Override
        public void onClick(View arg0) {
            int cid = arg0.getId();
            switch (cid) {         
            case id.date_label:// 日期标签
                switchControl(arg0);
                return;            
            case id. auto_update_date:// 自动同步日期
                switchControl(arg0);
                return;
            default:
                break;
            }
            super.onClick(arg0);
        }

     

    开发中效果:

    运行效果:

     

    转载于:https://www.cnblogs.com/allen0118/p/4921891.html

    展开全文
  • uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.pe...
  • android DrawerLayout问题

    2016-03-08 07:05:25
    android:dividerHeight="0dp" android:background="#111"/> android:id="@+id/left_drawer_2" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity=...
  • Google发布了Android Things新的Developer Preview 8版本,按照官网的说法,DP8已经是发布候选版(RC版)了,DP8的Android Things支持库代表了即将发布的1.0 stable release的最终版的API接口。在DP8之后,API将不会...
  • android:textSize="25dp" android:layout_marginLeft="10dp" android:text="账户:"/> android:id="@+id/username" android:layout_toRightOf="@id/name" android:layout_width="fill_parent" ...
  • 假设有如下界面(输入法的上面的输入区域是用Dialog实现的)要求当输入法关闭的时候,Dialog也一起关闭,这样用户就不需要返回两次了。网上找了很多资料都没有很好的解决这个问题,输入法是第三方程序,确实不好检测...
  • android 自定义带关闭按钮的dialog  在android的开发过程中,使用android常用的那几种dialog样式是远远不够的,不符合设计给出的设计图,尤其是右上角带有关闭按钮的dialog,之前一直都没有太在意这方面的,但是在...
  • package t1; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException;... static int[] i = {1,2,3,4,5,6,7,8,9,10,12,14,15,16,18,20,2...
  • 博客还是要多写,有些知识点就能方便记住。 先看看效果。 在这个布局纠结了好久,最终解决了。show_list_fragment.xml布局 xmlns:android="http://schemas.android.com/apk/res/android" android:lay
  • 自定义Switch样式 自定义Switch首先要熟悉两个属性,thumb与trace -. thumb 代表按钮的意思,就是switch左右两边那个 -. trace 代表轨迹的意思,...shape xmlns:android="http://schemas.android.com/apk/...
  • 对于一般的软件开发人员来说,... Android对于蓝牙开发从2.0版本的sdk才开始支持,而且模拟器不支持,测试至少需要两部手机,所以制约了很多技术人员的开发,刚巧这段时间公司有蓝牙开发的需求,我看了很多国内
  • Android滑动关闭Activity

    2018-06-21 17:38:38
    #定制Android滑动关闭Activity 现在手机屏幕越来越大,而页面的退出按键通常设置在屏幕左上角,这就导致了当单手操作时用户体验及其不好。虽然也能通过实体按键返回和现在流行的全面屏手势解决,但是感觉会很...
  • 布局文件 <?xml version="1.0" encoding="utf-8"?>... xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:to...
  • <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/nav_view" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginS...
1 2 3 4 5 ... 20
收藏数 21,009
精华内容 8,403
关键字:

dp 如何关掉android