LYNX

Links

Tags

Categories

Android开发笔记

Music开发笔记

CSDN:实例
cnblogs:其他几种方式

音乐进度

MediaPlayer

MediaPlayer参数–简书

时长

CSDN:数字格式化

total_time = MainPlayer.player.getDuration();
SimpleDateFormat format = new SimpleDateFormat("mm:ss");

// TODO 更新总时长
tmp = new Date(total_time);
formatTime = format.format(tmp);
MainPlayer.totalTime.setText(formatTime);

进度条

媒体信号

  • 蓝牙

CSDN:配对全过程
CSDN:简易

  • 有线耳机

CSDN

  1. 创建一个继承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);// TODO debug
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);// 获取键码
}
}
}

// receiver注册函数
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);
}
}

注意点:

  • 注册函数的函数名随意,可以在onCreateonResume等函数中调用注册函数
  • BroadcastReceiver子类必须要有无参的构造方法,否则会直接崩溃
  1. 修改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>
  1. 初始化MediaReceiver
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();// 获取蓝牙适配器
receiver = new MediaReceiver(this);// 接收蓝牙信号

IntentFilter intentFilter = new IntentFilter();

intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);// 监视蓝牙设备与APP连接的状态
intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);// 监听有线耳机的插拔
intentFilter.addAction(Intent.ACTION_MEDIA_BUTTON);// TODO

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);
  1. 注意区分已经配对的设备
  2. 特殊的蓝牙设备仍未解决

状态栏部件

显示

  1. 不要使用notify,使用startForeground来启动通知栏
  2. 清除不要使用deleteNotificationChannel,使用stopForeground

通信

  1. 注意不同intent要使用不同的requestCode

  2. 切换到MainActivity,MainActivity要使用singleTask

    Intent intent = new Intent(this, MusicList.class);
    remoteViews.setOnClickPendingIntent(R.id.button_open, PendingIntent.getActivity(this, 6, intent, 0));
  3. 使用空pendingIntent来防止点击通知会消失

桌面部件

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);// `允许`返回0,`拒绝`返回-1
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();// 判断本activity启动的方式
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();// TODO 获取点击结果
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.setOutsideTouchable(false);
this.setFocusable(true);// 否则无法进行edittext输入

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) {// `打开`按钮
...
}
}
}
}
  1. Intent.ACTION_GET_CONTENT:用于调用系统程序,比如一个打开一个文件的时候会提示你用哪个软件打开

  2. Intent.setType():设置默认打开格式,如"video/*","audio/amr"

调用相册

Intent intent = new Intent(Intent.ACTION_PICK);//intent  action属性
intent.setType("image/*");
startActivityForResult(intent, 2);

通用框架修改

drawable

添加buttondialog

values

删掉styles,修改colors,添加styles_button(按钮)和styles_tab(工具栏)

manifests

增加权限,删除label,增加android:launchMode="singleTask"

Tags

adb

Categories

1 / 1