Android音乐App桌面图标制作以及启动页面开发( 浅易音乐 一 )
关于
实在一直想做一款属于自己的音乐app,然后给自己的好朋侪用。但是因为种种原因和事情一直拖了很久没有付诸行动。前两天终于下定刻意要在重新开发一个app。而且开发的过程也根本都会以专栏的形式记录下来,包罗源码啥的。因为会很认真的坐下来,包罗UI细节以及优化等等。
开发工具Android Studio 3.5
版本 Android androidx 9.0
效果
首先上一下启动页面以及桌面图标logo的gif:
第一步
关于桌面图标的实现,参考我的这篇文章 Android 实现App修改应用图标 。这里需要注意的一点是在最后一步,也就是这里选择circle,则显示的是圆形图标,选择square为正方形图标:
第二步
先看一下项目结构:
此中splashActivity是我们的启动页,PermissionHelper是我们的权限申请资助类。
第一步 修改SplashAcitivity的结构页面
第二步 修改androidmanifest.xml
添加要用到的部门权限(背面大概还会新增权限申请)
修改splashactivity为启动页:
第三步 权限申请资助类
单独的权限申请方法如下:
- if (Build.VERSION.SDK_INT>22){ if (ContextCompat.checkSelfPermission(QueryPackingBarrelActivity.this, android.Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED){ //先判定有没有权限 ,没有就在这里举行权限的申请 ActivityCompat.requestPermissions(QueryPackingBarrelActivity.this, new String[]{android.Manifest.permission.CAMERA},991); }else { //说明已经获取到摄像头权限了 想干嘛干嘛 } }else {//这个说明系统版本在6.0之下,不需要动态获取权限。 //说明已经获取到摄像头权限了 想干嘛干嘛 } /** * 高版本动态获取摄像头权限 * @param requestCode 请求码 * @param permissions 请求的权限 * @param grantResults 返回的权限数据 */ @Override public void onRequestPermissionsResult(int requestCode,String[] permissions,int[] grantResults) { switch (requestCode){ case 991: if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){ //这里已经获取到了摄像头的权限,想干嘛干嘛了可以 }else { //这里是拒绝给APP摄像头权限,给个提示什么的说明一下都可以。 Toast.makeText(QueryPackingBarrelActivity.this,"请手动打开相机权限",Toast.LENGTH_SHORT).show(); } break; default: break; } }
复制代码 下面是封装的:
- import android.Manifest;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.Intent;import android.content.pm.PackageManager;import android.net.Uri;import android.provider.Settings;import android.util.Log;import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat;/** * Android 6.0 上权限分为[b]正常[/b]和[b]危险[/b]级别 *
- [list] *
- [*]正常级别权限:开发者仅仅需要在AndroidManifext.xml上声明,那么应用就会被允许拥有该权限,如:android.permission.INTERNET *
- [*]危险级别权限:开发者需要在AndroidManifext.xml上声明,而且在运行时举行申请,而且用户允许了,应用才会被允许拥有该权限,如:android.permission.WRITE_EXTERNAL_STORAGE *
- [/list] * 有米的以下权限需要在Android6.0上被允许,有米广告sdk才气正常工作,开发者需要在调用有米的任何代码之前,提前让用户允许权限 *
- [list] *
- [*]必须申请的权限 *
- [list] *
- [*]android.permission.READ_PHONE_STATE *
- [*]android.permission.WRITE_EXTERNAL_STORAGE *
- [/list] * *
- [*]可选申请的权限 *
- [list] *
- [*]android.permission.ACCESS_FINE_LOCATION *
- [/list] * *
- [/list] * Android 6.0 权限申请助手
- * Created by Alian on 16-1-12. */public class PermissionHelper { private static final String TAG = "PermissionHelper"; /** * 小tips:这里的int数值不能太大,否则不会弹出请求权限提示,测试的时候,改到1000就不会弹出请求了 */ private final static int READ_PHONE_STATE_CODE = 101; private final static int WRITE_EXTERNAL_STORAGE_CODE = 102; private final static int REQUEST_OPEN_APPLICATION_SETTINGS_CODE = 12345; /** * 有米 Android SDK 所需要向用户申请的权限列表 */ private PermissionModel[] mPermissionModels = new PermissionModel[] { new PermissionModel("电话", Manifest.permission.READ_PHONE_STATE, "我们需要读取手机信息的权限来标识您的身份", READ_PHONE_STATE_CODE), new PermissionModel("存储空间", Manifest.permission.WRITE_EXTERNAL_STORAGE, "我们需要您允许我们读写你的存储卡,以方便我们暂时生存一些数据", WRITE_EXTERNAL_STORAGE_CODE) }; private Activity mActivity; private OnApplyPermissionListener mOnApplyPermissionListener; public PermissionHelper(Activity activity) { mActivity = activity; } public void setOnApplyPermissionListener(OnApplyPermissionListener onApplyPermissionListener) { mOnApplyPermissionListener = onApplyPermissionListener; } /** * 这里我们演示如安在Android 6.0+上运行时申请权限 */ public void applyPermissions() { try { for (final PermissionModel model : mPermissionModels) { if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(mActivity, model.permission)) { ActivityCompat.requestPermissions(mActivity, new String[] { model.permission }, model.requestCode); return; } } if (mOnApplyPermissionListener != null) { mOnApplyPermissionListener.onAfterApplyAllPermission(); } } catch (Throwable e) { Log.e(TAG, "", e); } } /** * 对应Activity的 {@code onRequestPermissionsResult(...)} 方法 * * @param requestCode * @param permissions * @param grantResults */ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case READ_PHONE_STATE_CODE: case WRITE_EXTERNAL_STORAGE_CODE: // 如果用户不允许,我们视情况发起二次请求大概引导用户到应用页面手动打开 if (PackageManager.PERMISSION_GRANTED != grantResults[0]) { // 二次请求,体现为:以前请求过这个权限,但是用户拒接了 // 在二次请求的时候,会有一个“不再提示的”checkbox // 因此这里需要给用户表明一下我们为什么需要这个权限,否则用户大概会永久不在激活这个申请 // 方便用户明确我们为什么需要这个权限 if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, permissions[0])) { AlertDialog.Builder builder = new AlertDialog.Builder(mActivity).setTitle("权限申请").setMessage(findPermissionExplain(permissions[0])) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { applyPermissions(); } }); builder.setCancelable(false); builder.show(); } // 到这里就体现已经是第3+次请求,而且此时用户已经永久拒绝了,这个时候,我们引导用户到应用权限页面,让用户自己手动打开 else { AlertDialog.Builder builder = new AlertDialog.Builder(mActivity).setTitle("权限申请") .setMessage("请在打开的窗口的权限中开启" + findPermissionName(permissions[0]) + "权限,以正常使用本应用") .setPositiveButton("去设置", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { openApplicationSettings(REQUEST_OPEN_APPLICATION_SETTINGS_CODE); } }).setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mActivity.finish(); } }); builder.setCancelable(false); builder.show(); } return; } // 到这里就体现用户允许了本次请求,我们继续查抄是否另有待申请的权限没有申请 if (isAllRequestedPermissionGranted()) { if (mOnApplyPermissionListener != null) { mOnApplyPermissionListener.onAfterApplyAllPermission(); } } else { applyPermissions(); } break; } } /** * 对应Activity的 {@code onActivityResult(...)} 方法 * * @param requestCode * @param resultCode * @param data */ public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_OPEN_APPLICATION_SETTINGS_CODE: if (isAllRequestedPermissionGranted()) { if (mOnApplyPermissionListener != null) { mOnApplyPermissionListener.onAfterApplyAllPermission(); } } else { mActivity.finish(); } break; } } /** * 判定是否所有的权限都被授权了 * * @return */ public boolean isAllRequestedPermissionGranted() { for (PermissionModel model : mPermissionModels) { if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(mActivity, model.permission)) { return false; } } return true; } /** * 打开应用设置界面 * * @param requestCode 请求码 * * @return */ private boolean openApplicationSettings(int requestCode) { try { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + mActivity.getPackageName())); intent.addCategory(Intent.CATEGORY_DEFAULT); // Android L 之后Activity的启动模式发生了一些厘革 // 如果用了下面的 Intent.FLAG_ACTIVITY_NEW_TASK ,而且是 startActivityForResult // 那么会在打开新的activity的时候就会立即回调 onActivityResult // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mActivity.startActivityForResult(intent, requestCode); return true; } catch (Throwable e) { Log.e(TAG, "", e); } return false; } /** * 查找申请权限的表明短语 * * @param permission 权限 * * @return */ private String findPermissionExplain(String permission) { if (mPermissionModels != null) { for (PermissionModel model : mPermissionModels) { if (model != null && model.permission != null && model.permission.equals(permission)) { return model.explain; } } } return null; } /** * 查找申请权限的名称 * * @param permission 权限 * * @return */ private String findPermissionName(String permission) { if (mPermissionModels != null) { for (PermissionModel model : mPermissionModels) { if (model != null && model.permission != null && model.permission.equals(permission)) { return model.name; } } } return null; } private static class PermissionModel { /** * 权限名称 */ public String name; /** * 请求的权限 */ public String permission; /** * 剖析为什么请求这个权限 */ public String explain; /** * 请求代码 */ public int requestCode; public PermissionModel(String name, String permission, String explain, int requestCode) { this.name = name; this.permission = permission; this.explain = explain; this.requestCode = requestCode; } } /** * 权限申请事件监听 */ public interface OnApplyPermissionListener { /** * 申请所有权限之后的逻辑 */ void onAfterApplyAllPermission(); } }
复制代码 第四步 修改splashAcitivity.java
[code]/** * 启动页 * @version V1.0.0 * @author Tobey_R1 * @since 2020年8月28日 */public class SplashActivity extends AppCompatActivity { private Context mContext; private PermissionHelper mPermissionHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //隐藏状态栏 getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); //移除标题栏 requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_splash); //党系统版本6.0+,需要权限申请 mPermissionHelper = new PermissionHelper(this); mPermissionHelper.setOnApplyPermissionListener(new PermissionHelper.OnApplyPermissionListener() { @Override public void onAfterApplyAllPermission() { runApp(); } }); if (Build.VERSION.SDK_INT |