首页 文章 精选 留言 我的

精选列表

搜索[android studio],共10000篇文章
优秀的个人博客,低调大师

Android 扫描附近的蓝牙设备并连接蓝牙音响

写了一个可以扫描附近蓝牙设备的小Demo,可以查看蓝牙设备的设备名和Mac地址 代码量不多,很容易看懂 /** * 作者:叶应是叶 * 时间:2017/9/8 20:13 * 描述: */ public class ScanDeviceActivity extends AppCompatActivity { private LoadingDialog loadingDialog; private DeviceAdapter deviceAdapter; private BluetoothAdapter bluetoothAdapter; private Handler handler = new Handler(); private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { case BluetoothAdapter.ACTION_DISCOVERY_STARTED: showLoadingDialog("正在搜索附近的蓝牙设备"); break; case BluetoothAdapter.ACTION_DISCOVERY_FINISHED: Toast.makeText(ScanDeviceActivity.this, "搜索结束", Toast.LENGTH_SHORT).show(); hideLoadingDialog(); break; case BluetoothDevice.ACTION_FOUND: BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); deviceAdapter.addDevice(bluetoothDevice); deviceAdapter.notifyDataSetChanged(); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scan_device); BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); if (bluetoothAdapter == null) { Toast.makeText(this, "当前设备不支持蓝牙", Toast.LENGTH_SHORT).show(); finish(); } initView(); registerDiscoveryReceiver(); startScan(); } @Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacksAndMessages(null); unregisterReceiver(discoveryReceiver); if (bluetoothAdapter.isDiscovering()) { bluetoothAdapter.cancelDiscovery(); } } private void initView() { ListView lv_deviceList = (ListView) findViewById(R.id.lv_deviceList); deviceAdapter = new DeviceAdapter(this); lv_deviceList.setAdapter(deviceAdapter); } private void registerDiscoveryReceiver() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); intentFilter.addAction(BluetoothDevice.ACTION_FOUND); intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); registerReceiver(discoveryReceiver, intentFilter); } private void startScan() { if (!bluetoothAdapter.isEnabled()) { if (bluetoothAdapter.enable()) { handler.postDelayed(new Runnable() { @Override public void run() { scanDevice(); } }, 1500); } else { Toast.makeText(this, "请求蓝牙权限被拒绝,请授权", Toast.LENGTH_SHORT).show(); } } else { scanDevice(); } } private void scanDevice() { if (bluetoothAdapter.isDiscovering()) { bluetoothAdapter.cancelDiscovery(); } bluetoothAdapter.startDiscovery(); } private void showLoadingDialog(String message) { if (loadingDialog == null) { loadingDialog = new LoadingDialog(this); } loadingDialog.show(message, true, false); } private void hideLoadingDialog() { if (loadingDialog != null) { loadingDialog.dismiss(); } } } 此外,还可以通过利用反射来调用系统API,从而与支持蓝牙A2DP协议的蓝牙音响连接上,不过因为我只有一部不算严格意义上的蓝牙音响来做测试,所以这个功能并不确定是否适用于大多数蓝牙设备 /** * 作者:叶应是叶 * 时间:2017/9/8 20:02 * 描述: */ public class ConnectA2dpActivity extends AppCompatActivity { private DeviceAdapter deviceAdapter; private BluetoothAdapter bluetoothAdapter; private Handler handler = new Handler(); private BluetoothA2dp bluetoothA2dp; private LoadingDialog loadingDialog; private final String TAG = "ConnectA2dpActivity"; private BroadcastReceiver a2dpReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED: int connectState = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothA2dp.STATE_DISCONNECTED); if (connectState == BluetoothA2dp.STATE_DISCONNECTED) { Toast.makeText(ConnectA2dpActivity.this, "已断开连接", Toast.LENGTH_SHORT).show(); } else if (connectState == BluetoothA2dp.STATE_CONNECTED) { Toast.makeText(ConnectA2dpActivity.this, "已连接", Toast.LENGTH_SHORT).show(); } break; case BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED: int playState = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothA2dp.STATE_NOT_PLAYING); if (playState == BluetoothA2dp.STATE_PLAYING) { Toast.makeText(ConnectA2dpActivity.this, "处于播放状态", Toast.LENGTH_SHORT).show(); } else if (playState == BluetoothA2dp.STATE_NOT_PLAYING) { Toast.makeText(ConnectA2dpActivity.this, "未在播放", Toast.LENGTH_SHORT).show(); } break; } } }; private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { case BluetoothAdapter.ACTION_DISCOVERY_STARTED: showLoadingDialog("正在搜索蓝牙设备,搜索时间大约一分钟"); break; case BluetoothAdapter.ACTION_DISCOVERY_FINISHED: Toast.makeText(ConnectA2dpActivity.this, "搜索蓝牙设备结束", Toast.LENGTH_SHORT).show(); hideLoadingDialog(); break; case BluetoothDevice.ACTION_FOUND: BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); deviceAdapter.addDevice(bluetoothDevice); deviceAdapter.notifyDataSetChanged(); break; case BluetoothDevice.ACTION_BOND_STATE_CHANGED: int status = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); if (status == BluetoothDevice.BOND_BONDED) { Toast.makeText(ConnectA2dpActivity.this, "已连接", Toast.LENGTH_SHORT).show(); } else if (status == BluetoothDevice.BOND_NONE) { Toast.makeText(ConnectA2dpActivity.this, "未连接", Toast.LENGTH_SHORT).show(); } hideLoadingDialog(); break; } } }; private BluetoothProfile.ServiceListener profileServiceListener = new BluetoothProfile.ServiceListener() { @Override public void onServiceDisconnected(int profile) { if (profile == BluetoothProfile.A2DP) { Toast.makeText(ConnectA2dpActivity.this, "onServiceDisconnected", Toast.LENGTH_SHORT).show(); bluetoothA2dp = null; } } @Override public void onServiceConnected(int profile, final BluetoothProfile proxy) { if (profile == BluetoothProfile.A2DP) { Toast.makeText(ConnectA2dpActivity.this, "onServiceConnected", Toast.LENGTH_SHORT).show(); bluetoothA2dp = (BluetoothA2dp) proxy; } } }; private AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { BluetoothDevice device = deviceAdapter.getDevice(position); if (device.getBondState() == BluetoothDevice.BOND_BONDED) { Toast.makeText(ConnectA2dpActivity.this, "已连接该设备", Toast.LENGTH_SHORT).show(); return; } showLoadingDialog("正在连接"); connectA2dp(device); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_connect_a2dp); BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); if (bluetoothAdapter == null || !getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(ConnectA2dpActivity.this, "当前设备不支持蓝牙", Toast.LENGTH_SHORT).show(); finish(); } bluetoothAdapter.getProfileProxy(this, profileServiceListener, BluetoothProfile.A2DP); initView(); registerDiscoveryReceiver(); registerA2dpReceiver(); startScan(); } @Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacksAndMessages(null); unregisterReceiver(a2dpReceiver); unregisterReceiver(discoveryReceiver); if (bluetoothAdapter.isDiscovering()) { bluetoothAdapter.cancelDiscovery(); } } private void initView() { ListView lv_deviceList = (ListView) findViewById(R.id.lv_deviceList); deviceAdapter = new DeviceAdapter(this); lv_deviceList.setAdapter(deviceAdapter); lv_deviceList.setOnItemClickListener(itemClickListener); } private void registerDiscoveryReceiver() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); intentFilter.addAction(BluetoothDevice.ACTION_FOUND); intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); registerReceiver(discoveryReceiver, intentFilter); } private void registerA2dpReceiver() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); intentFilter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED); registerReceiver(a2dpReceiver, intentFilter); } private void startScan() { if (!bluetoothAdapter.isEnabled()) { if (bluetoothAdapter.enable()) { handler.postDelayed(new Runnable() { @Override public void run() { scanDevice(); } }, 1500); } else { Toast.makeText(ConnectA2dpActivity.this, "请求蓝牙权限被拒绝", Toast.LENGTH_SHORT).show(); } } else { scanDevice(); } } private void scanDevice() { if (bluetoothAdapter.isDiscovering()) { bluetoothAdapter.cancelDiscovery(); } bluetoothAdapter.startDiscovery(); } public void setPriority(BluetoothDevice device, int priority) { try { Method connectMethod = BluetoothA2dp.class.getMethod("setPriority", BluetoothDevice.class, int.class); connectMethod.invoke(bluetoothA2dp, device, priority); } catch (Exception e) { e.printStackTrace(); } } private void connectA2dp(BluetoothDevice bluetoothDevice) { if (bluetoothA2dp == null || bluetoothDevice == null) { return; } setPriority(bluetoothDevice, 100); try { Method connectMethod = BluetoothA2dp.class.getMethod("connect", BluetoothDevice.class); connectMethod.invoke(bluetoothA2dp, bluetoothDevice); } catch (Exception e) { e.printStackTrace(); } } private void showLoadingDialog(String message) { if (loadingDialog == null) { loadingDialog = new LoadingDialog(this); } loadingDialog.show(message, true, false); } private void hideLoadingDialog() { if (loadingDialog != null) { loadingDialog.dismiss(); } } } 这里给出源代码供大家参考:BluetoothDemo

优秀的个人博客,低调大师

Check Point解析CopyCat恶意软件 如何感染全球Android设备

Check Point以色列捷邦安全软件科技有限公司的移动威胁研究人员最近发现一种针对移动设备的恶意软件,并称之为CopyCat。它目前已经感染了1,400万部安卓设备,获取了其中800万部的root权限,在短短两个月内,黑客通过使用CopyCat 已经赚取了约150万美元的假冒广告收入。 Check Point 移动威胁研究人员指出,CopyCat采用一种新的技术来制造和窃取广告收入。CopyCat 主要感染位于东南亚的用户,但它也传播至美国,感染了超过28万名安卓设备用户。 CopyCat是一款完全开发的恶意软件,具有强大的功能,包括对设备获取root权限,能持续进行攻击,以及将代码注入Zygote(Zygote负责在安卓操作系统中启动应用程序),因此它可以控制设备上的任何活动。 CopyCat 是在意图攻击一家受Check Point SandBlast Mobile保护的企业时被发现,Check Point研究人员从这款恶意软件的命令与控制服务器中检索到信息,并且对其内部工作方式进行了完整的逆向操作工程,这些资料在其全面的技术报告中有详细介绍。 CopyCat攻击在2016年4月和5月达到顶峰。研究人员相信此次大型攻击是通过把恶意软件与流行应用程序结合重新包装,然后通过第三方应用商店进行散播,以及采用钓鱼欺诈手段。目前没有证据说明CopyCat是通过Google的官方应用商店Google Play进行发布。 2017年3月,Check Point向Google通报了CopyCat恶意软件以及其操作方法。据Google介绍,他们可以应对这次攻击,并且当前受感染的设备数量远远低于攻击高峰时期。不幸的是,已经受到CopyCat恶意软件感染的设备,至今仍然受到这款病毒的影响。 CopyCat是如何操作的? CopyCat恶意软件感染全球1,400万部设备,对其中约800万部设备获取了root权限,这被研究人员称为是前所未有的攻击成功率。研究人员也表示此恶意软件为黑客创造了150万美元的广告收入。 CopyCat恶意软件采用最新的技术来衍生出多种形式的广告欺诈方式,与Check Point 之前发现的恶意软件Gooligan,DressCode和Skinner相似。一旦感染,CopyCat首先获取用户设备root权限,允许攻击者完全控制设备,并且基本上致使用户毫无办法。 CopyCat将代码注入Zygote应用程序启动功能,允许攻击者利用自己的ID来替换真正推荐人ID,从而获得许可安装欺诈性的应用程序来获得收入。另外,CopyCat使得Zygote发布欺诈性的广告而隐藏他们的真实来源,使得用户难以理解为何这些广告会在屏幕上弹出。CopyCat也使用单独的模块直接在设备上安装欺诈性应用程序。CopyCat恶意软件致使大规模的设备遭受感染,为背后的黑客聚敛巨额钱财。 CopyCat 的灾区分布图 CopyCat的祸害 Check Point研究人员调查了2016年4月到5月期间活跃的其中一台命令与控制服务器,纪录下超过1,400万部受感染设备,其中800万(54%)的设备已被获取root权限。有380万(26%)受感染设备显示欺诈广告,440万设备或30%受感染设备的信用凭证被窃取,用于在Google Play上安装应用程序。 攻击者获得的收益预计超出150万美元,大部分都是在短短两个月内赚到的。CopyCat制造的近1亿条恶意软件广告,总共产生利润多达12万美元。因为我们只能测量出多少设备感染上欺诈性安装套利,而不知道该类活动发生的次数,只能保守估计每台设备只执行一次该类活动。如此计算,攻击者从中赚到的利润预计超过66万美元。最大的收益来源是CopyCat骗取的490万个欺诈性应用程序的安装,从中产生多达73.5万美元的利润。 CopyCat肆虐最厉害的12个国家 如何防御CopyCat 如CopyCat这般复杂的恶意软件要求先进的防护手段,能够通过静态和动态的应用程序分析识别和封锁零日恶意软件的攻击。只有在一个设备上监测到恶意软件的操作环境,才能制定策略,成功封锁。用户和企业应把移动设备视为网络中的其它设备一样对待,并通过最佳的网络安全解决方案保护它们。 Check Point的用户受到SandBlast Mobile的保护,网络前端由Check Point Anti-Bot blade执行防御,可以有效抵御带有Trojan.AndroidOS.CopyCat签名特征的CopyCat恶意软件。 原文发布时间为:2017年7月11日 本文来自云栖社区合作伙伴至顶网,了解相关信息可以关注至顶网。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册