如何完成在后台播放录音的任务并从事不同的活动?

Posted

技术标签:

【中文标题】如何完成在后台播放录音的任务并从事不同的活动?【英文标题】:How to accomplish task of playing recording in background and work on different activities? 【发布时间】:2014-01-08 15:41:14 【问题描述】:

我对 android 开发有点陌生,我遇到了一个场景,想从专家那里得到宝贵的反馈。

在我的应用程序中,用户在 Activity1 上,用户从中选择一个客户端并导航到 Activity2。在 Activity2 上,用户应该能够播放录音文件,在播放录音时,用户可以导航到 Activity3、Activity4 或 Activity5,收听音频并进行输入。在 Activity3、Activity4 和 Activity5 用户将拥有暂停或停止音频的控件。 如果用户从 Activity2 导航回 Activity1,音频将自动停止。

我很困惑它可以通过服务或后台任务来完成。

非常感谢任何有价值的建议/代码示例。

【问题讨论】:

【参考方案1】:

我肯定会使用service。您可以绑定到服务并从中调用方法。

Intent it = new Intent(MainActivity.this, MyService.class);
bindService(it, mConnection, Context.BIND_AUTO_CREATE);

在每个活动中绑定到服务,这样你就可以对它做任何你想做的事情。 不要忘记在你的活动中取消绑定它的'onDestroy。

if(mBound)unbindService(mConnection);

只需停止服务即可停止播放。

stopService(new Intent(this, MyService.class));

这是我使用的 serviceConnection。

private ServiceConnection mConnection = new ServiceConnection() 

    @Override
    public void onServiceConnected(ComponentName className,IBinder service) 
        // We've bound to LocalService, cast the IBinder and get LocalService instance
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;            
    

    @Override
    public void onServiceDisconnected(ComponentName arg0) 
        mBound = false;
    
; 

将它放在你的服务中以返回到活动中:

@Override
public IBinder onBind(Intent intent) 
    return mBinder;


public class LocalBinder extends Binder 
    MyService getService() 
        // Return this instance of LocalService so clients can call public methods
        return MyService.this;
    

最后会在你的服务启动后调用startService(intent); 请注意,它返回Service.START_STICKY。这将防止您的服务被杀死,除非操作系统的内存非常少。

public int onStartCommand(Intent intent, int flags, int startid)       
    return Service.START_STICKY;

希望我的回答能帮到你,祝你好运。

【讨论】:

【参考方案2】:

我创建了一个工作示例,供您全面理解该概念。 我创建了一个服务,因为您想在服务内播放媒体。

否则,这种情况下不需要服务,我们可以直接使用 MediaPlayer api 来播放/暂停和停止歌曲,方法是保留一个单例对象。

此外,播放器控件不必位于每个活动屏幕上,而是可以成为操作栏的一部分。

如果您有兴趣查看播放器控件位于操作栏中且单例用于媒体播放而不是像我的示例中那样具有单独服务的示例,请告诉我,我将创建一个项目并发布相同的内容。

(在 Note2 和 Nexus 模拟器中测试)

项目网址:发布在 Git Hub 中。

https://github.com/gansBhat/AndroidProjects/tree/master

也发布在 Google 云端硬盘中

https://drive.google.com/folderview?id=0BxHClVwHSqq5dVRvT1Qyd0hYN0k&usp=sharing

【讨论】:

非常感谢您的帮助和详细的代码,如果您可以提供单例和操作栏控件的示例,这将非常有帮助,我此示例代码的主要目的是比较两者实现,它也会让我学到更多。提前致谢 嗨,Imran,其他人的建议是有效的。如果我们不运行服务,那么您的应用程序很有可能被杀死。目前在我的示例中,我在 UI 线程(服务)中打开了文件。目的只是为了展示它必须如何完成(只是一个工作示例)。现在,我使用异步处理和拾取音频资源创建了更具体的示例。我在实现中遗漏了音频焦点更改处理。 github.com/gansBhat/AndroidProjects/tree/master/Examples/…【参考方案3】:

您将需要使用包含MediaPlayerService,您的各种Activities 可以在它在后台播放媒体时与之交互。有关在 Android 中设置媒体播放的大量信息,请参阅以下链接,特别是 Running asynchronously 部分:

Media Playback | Android Developers

【讨论】:

我已经开始赏金了,如果你感兴趣的话,想告诉你。 @Yjay 是对的——使用服务。这是他提到的非常有用的部分的链接:developer.android.com/guide/topics/media/…【参考方案4】:

您可以按照@Yjay 的建议使用服务,也可以使用应用程序上下文创建 MediaPlayer 实例,并通过应用程序对象/单音/静态字段在活动之间共享它。

【讨论】:

【参考方案5】:

您需要在您的应用程序中使用服务,服务完成后台任务,它们没有用户界面,它一定会对您有所帮助。

【讨论】:

【参考方案6】:

活动一:

调用服务 //start Service(new Intent(this, your Service.class))

活动 2:

stop service //stop Service(new Intent(this, your Service.class))

服务:

创建媒体播放器 //Media Player.create(this, file name.mp3); //媒体播放器.start();

【讨论】:

【参考方案7】:

你所要做的就是实现Service组件: http://developer.android.com/reference/android/app/Service.html

你也应该把它标记为前台服务,以便在内存不足的情况下给他更多的生存机会

http://developer.android.com/reference/android/app/Service.html#startForeground(int, android.app.Notification)

然后我想你需要根据向服务器发送一些命令(如开始/停止播放等)与服务器通信。在这种特殊情况下最方便的方法是本地广播:

http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html

您只需要在您的服务中调用 registerReceiver(...) 并在您想要发送某些命令时使用 sendBroadcast(...)。

以防万一 - 由于 Android 4.0 我们通常不使用这么多的活动 - 考虑使用 Fragment 代替。

【讨论】:

以上是关于如何完成在后台播放录音的任务并从事不同的活动?的主要内容,如果未能解决你的问题,请参考以下文章

Android 服务交互

iOS 后台状态监控通话状态

将活动发送到后台而不完成

如何刷新活动

Android - 为视频创建后台服务

仅启动一次后台服务,并在任务完成后停止