Android Service 使用,一个简单音乐播放器 DEMO(二)

一,简介
在上一篇文章中,初步了解了一些 Service 的工作属性,这篇文章将更深入地记录一下如何使用 Service .

二,Service 和 Thread
在学习使用之前,我们上一章完了应该还有一个疑问:我们确认了 service 如果需要做耗时操作,也必须要启动一个新的线程来实现,那么这样为何还需要启动一个新的 Service 呢?
1. 首先, 在 activity 中不好对 Thread 进行控制,back 键按一下就有可能丢失了线程的控制,而 Service 不会如此。
2. 线程的优先级太低,在 activity 结束之后, thread 会很容易被系统杀死。
3. Service 可以后台直接运行,不依赖于界面。IM 类软件可以与服务器保持心跳连接。

三,使用 Service
这里使用 Service 做一个简单的音乐播放的功能。我们需要有下面的这些功能:

  1. 查找手机里已经存在的音频
  2. 可以在某个界面控制音频的播放
  3. 可以在后台播放音频

根据这3点我们可以确定该 Service 是需要通过 startService 启动的。但控制方式可以有两种,第一是广播,第二是在 startService 之外另外还 bindService. 这里考虑到查找手机里已存在的音频可能是一个耗时的操作,把这个功能放到 Service 中实现,如此,我们需要讲大量数据从 Service 中传到 Activity 中,所以这里使用 bindService 实现。
首先,我们定义一个简单的界面:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="?android:buttonBarButtonStyle">
        <Button
            android:id="@+id/music_pre"
            android:text="@string/music_pre"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/music_ctrl"
            android:text="@string/play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/music_next"
            android:text="@string/music_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <ListView
        android:id="@+id/music_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

控制方面基本上需要的功能有上一曲,下一曲,播放,单击 ListView 时播放 选中的歌曲。
接下来,我们首先定义一个 Bean 文件,目前选择比较简单的方式,因此这里只定义了三个 Field,没有加上 setter, getter.

class Bean {
    /**
     * 显示的歌曲名称
     */
    String name;
    /**
     * 歌曲路径
     */
    String path;
    /**
     * 是否正在播放
     */
    boolean playing = false;

    @Override
    
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我可以给你一个Android使用Camera2Demo的示例代码:import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.ImageFormat; import android.graphics.SurfaceTexture; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraManager; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.params.StreamConfigurationMap; import android.media.ImageReader; import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.support.annotation.NonNull; import android.support.annotation.RequiresApi; import android.support.v4.app.ActivityCompat; import android.util.Size; import android.util.SparseIntArray; import android.view.Surface; import android.view.TextureView; import android.widget.Toast;@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public class Camera2Demo { private TextureView textureView; private Context context; private Size previewSize; private Handler backgroundHandler; private HandlerThread backgroundThread; private ImageReader imageReader; private CaptureRequest.Builder previewRequestBuilder; private CameraDevice cameraDevice; private CameraCaptureSession captureSession; private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 0); ORIENTATIONS.append(Surface.ROTATION_90, 90); ORIENTATIONS.append(Surface.ROTATION_180, 180); ORIENTATIONS.append(Surface.ROTATION_270, 270); } public Camera2Demo(TextureView textureView, Context context) { this.textureView = textureView; this.context = context; } public void openCamera() { CameraManager cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); try { String cameraID = cameraManager.getCameraIdList()[0]; CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraID); StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); previewSize = map.getOutputSizes(SurfaceTexture.class)[0]; // 权限检查 if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { return; } cameraManager.openCamera(cameraID, stateCallBack, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } private CameraDevice.StateCallback stateCallBack = new CameraDevice.StateCallback() { @Override public void onOpened(@NonNull CameraDevice camera) { cameraDevice = camera; startPreview(); } @Override public void onDisconnected(@NonNull CameraDevice camera) { camera.close(); cameraDevice = null; } @Override public void onError(@NonNull CameraDevice camera, int error) { Toast.makeText(context, "摄像头开启失败", Toast.LENGTH_SHORT).show(); } }; private void startPreview() { SurfaceTexture surfaceTexture = textureView.getSurfaceTexture(); surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); Surface previewSurface = new Surface(surfaceTexture); try { previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); previewRequestBuilder.addTarget(previewSurface); cameraDevice.createCaptureSession(Arrays.asList(previewSurface, imageReader.getSurface()), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { captureSession = session; try { captureSession.setRepeatingRequest(previewRequestBuilder.build(), null, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession session) { } }, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值