Android开发笔记
2019-09-04
Music
开发笔记
CSDN:实例
cnblogs:其他几种方式
音乐进度
MediaPlayer参数–简书
时长
CSDN:数字格式化
total_time = MainPlayer.player.getDuration(); SimpleDateFormat format = new SimpleDateFormat("mm:ss");
tmp = new Date(total_time); formatTime = format.format(tmp); MainPlayer.totalTime.setText(formatTime);
|
进度条
媒体信号
CSDN:配对全过程
CSDN:简易
CSDN
- 创建一个继承
BroadcastReceiver
的类
public class MediaReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action != null) { MainPlayer.infoLog("action: " + action); switch (action) { case Intent.ACTION_HEADSET_PLUG: int mediaState = intent.getIntExtra("state", 0);
case BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED: int bluetoothState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
case Intent.ACTION_MEDIA_BUTTON: KeyEvent keyEvent = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); } } }
public void registerReceiver(Context context) { AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); ComponentName name = new ComponentName(context.getPackageName(), MediaReceiver.class.getName()); audioManager.registerMediaButtonEventReceiver(name); }
public void unregisterReceiver(Context context){ AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); ComponentName name = new ComponentName(context.getPackageName(), MediaReceiver.class.getName()); audioManager.unregisterMediaButtonEventReceiver(name); } }
|
注意点:
- 注册函数的函数名随意,可以在
onCreate
或onResume
等函数中调用注册函数
BroadcastReceiver
子类必须要有无参的构造方法,否则会直接崩溃
- 修改
AndroidManifest.xml
父节点为application
,android:name
要和BroadcastReceiver
的子类名相同,priority
可以不要
<receiver android:name=".MediaReceiver"> <intent-filter android:priority="1000"> <action android:name="android.intent.action.MEDIA_BUTTON"></action> </intent-filter> </receiver>
|
- 初始化
MediaReceiver
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); receiver = new MediaReceiver(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); intentFilter.addAction(Intent.ACTION_HEADSET_PLUG); intentFilter.addAction(Intent.ACTION_MEDIA_BUTTON);
registerReceiver(this.receiver, intentFilter); receiver.registerReceiver(this);
|
adb
华为手机配置adb:*#*#2846579#*#*
->后台设置
->usb端口设置
->生产模式
adb devices adb tcpip 5555
adb connect 手机ip
|
若安卓设备显示offline
,可能是由于adb
版本过低
蓝牙连接管理
无需在AndroidManifest
里注册
蓝牙连接
Method createBond = device.getClass().getMethod("createBond"); createBond.setAccessible(true); result = (Boolean) createBond.invoke(device);
|
- 注意区分已经配对的设备
- 特殊的蓝牙设备仍未解决
状态栏部件
创建
简书:notification channel
可使用NotificationCompat
或Notification
,注意常量取值
NotificationManager notificationManager = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { notificationManager = getSystemService(NotificationManager.class); CharSequence name = "fuck"; String description = "shit"; String id = "111"; NotificationChannel channel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_HIGH); channel.setDescription(description); notificationManager.createNotificationChannel(channel); }
NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this, id) .setSmallIcon(R.drawable.ic_launcher_background) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
显示
首先保证系统更新并能够支持notification category
保证给应用程序提供锁屏通知权限
startForeground
常驻通知栏
for (int i = 0; i < 10; i ++) { stopForeground(true); Thread.sleep(500); startForeground(10, builder.build()); }
|
在mainifest
节点下增加权限
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
清除通知不要使用deleteNotificationChannel
,否则无法控制音效/震动,使用stopForeground
notify
可以被作为通知清除
for (int i = 0; i < 10; i ++) { notificationManager.cancel(0); Thread.sleep(500); notificationManager.notify(0, builder.build()); }
|
注意channel
的id
和Builder
的id
要一致
通信
- 注意不同
intent
要使用不同的requestCode
- 切换到
MainActivity
,MainActivity
要使用singleTask
Intent intent = new Intent(this, MusicList.class); remoteViews.setOnClickPendingIntent(R.id.button_open, PendingIntent.getActivity(this, 6, intent, 0));
|
- 使用空
pendingIntent
来防止点击通知会消失
锁屏通知
只能够从系统中手动打开权限
事件 |
intent |
亮屏 |
Intent.ACTION_SCREEN_ON |
关屏 |
Intent.ACTION_SCREEN_OFF |
解锁 |
Intent.ACTION_USER_PRESENT |
桌面部件
在进程完全被杀死后通过widget
启动app
PendingIntent.getActivity()
/startActivity()
PendingIntent.getForegroundService()
/startForegroundService()
,不要使用Service
Editor
开发笔记
获取读写权限
AndroidManifest
<!-- manifest节点下 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
Activity
String permission = "android.permission.WRITE_EXTERNAL_STORAGE"; int check_result = ActivityCompat.checkSelfPermission(this, permission); if (check_result != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{permission}, 1); }
|
关联文件类型
文本文件
<intent-filter android:scheme="http" tools:ignore="AppLinkUrlError"> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/*"/> </intent-filter>
|
修改默认Toast
static public void info(Context context, String log) { Toast toast = Toast.makeText(context, log, Toast.LENGTH_SHORT); View view = toast.getView(); view.setBackgroundResource(R.drawable.toast); TextView textView = view.findViewById(android.R.id.message); textView.setTextColor(Color.rgb(0xff, 0xff, 0xff)); toast.show(); }
|
由外部打开文件
Intent intent = getIntent(); String action = intent.getAction(); if (action.equals("android.intent.action.VIEW")) { }
|
控制activity
数目
<activity android:name=".Editor" android:launchMode="singleTask">
|
获取根view
View view = getWindow().getDecorView().findViewById(android.R.id.content);
|
数据保存
SharedPreferences
SharedPreferences
:基于xml的键值对,存储于/data/data/应用程序包/shared_prefs
提示框/窗口
Dialog
参考
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.save_layout);
yes.setOnClickListener(new View.OnClickListener() { });
cancel.setOnClickListener(new View.OnClickListener() { });
no.setOnClickListener(new View.OnClickListener() { }); }
private void initButton() { yes = findViewById(R.id.yes_button); cancel = findViewById(R.id.cancel_button); no = findViewById(R.id.no_button); }
|
myWindow = new MyWindow(MainActivity.this, R.style.save_style); myWindow.setCanceledOnTouchOutside(false); myWindow.setOnDismissListener(new DialogInterface.OnDismissListener() { }); myWindow.show();
|
public class MyWindow extends PopupWindow { public Button yes; public Button cancel; public Button no; public int result;
public MyWindow(Context context, View view) { super(context); this.setContentView(LayoutInflater.from(context).inflate(R.layout.manager_layout, null)); this.setFocusable(true);
this.showAsDropDown(view); this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); this.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); } }
|
- 响应键盘:
this.setFocusable(true);
,否则无法进行EditText输入
DialogFragment
参考
public class MyWindow extends DialogFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.manager_layout, container); getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0x00000000)); return view; }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStyle(STYLE_NO_FRAME, android.R.style.Theme); } }
|
myWindow = new MyWindow(); myWindow.show(getSupportFragmentManager(), "edit");
|
全景相机开发笔记
自定义相机界面
过期内容
调用系统文件浏览器
1.绑定点击事件
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(intent, 1);
|
2.根据requestCode
接收数据
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { if (requestCode == 1) { ... } } } }
|
Intent.ACTION_GET_CONTENT
:用于调用系统程序,比如一个打开一个文件的时候会提示你用哪个软件打开
Intent.setType()
:设置默认打开格式,如"video/*"
,"audio/amr"
调用相册
Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, 2);
|
通用框架修改
drawable
添加button
和dialog
values
删掉styles
,修改colors
,添加styles_button
(按钮)和styles_tab
(工具栏)
manifests
增加权限,删除label
,增加android:launchMode="singleTask"
相机相关