概述
0. 实现原理
获取当前进程是音乐进程 && 当前进程是否占有音频服务焦点
1.上层调用方法
AudioManager audio = getSystemService(AudioManager.class);
(audio.isMusicActive() && audio.isAppInFocus(pkgName))
具体工具类调用如下
package com.android.lava.powersave.util;
import java.lang.reflect.Method;
import android.content.Context;
import android.media.AudioManager;
import android.util.Log;
public class AudioManagerUtils {
public static boolean isAudioAppRunning(Context mContext, String packageName) {
boolean result = false;
AudioManager mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
Class ownerClass = mAudioManager.getClass();
try {
Class[] argsClass = new Class[1];
argsClass[0] = String.class;
Method method = ownerClass.getMethod("isAppInFocus", argsClass);
Object[] params = new Object[1];
params[0] = packageName;
boolean isMusicActive = mAudioManager.isMusicActive();
if (isMusicActive) {
boolean isAppInFocus = (Boolean) method.invoke(mAudioManager, params);
result = isMusicActive && isAppInFocus;
Log.d(AudioManagerUtils.class.getSimpleName(), packageName + ", isAudioAppRunning isMusicActive= " + isMusicActive +
", isAppInFocus = " + isAppInFocus + ", result = " + result);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
2.底层Framewoke实现
2.0 移植清单
-m media/java/android/media/AudioManager.java
-m media/java/android/media/IAudioService.aidl
-m services/core/java/com/android/server/audio/AudioService.java
-m services/core/java/com/android/server/audio/MediaFocusControl.java
2.1 AudioManager.java
media/java/android/media/AudioManager.java
package android.media;
/**
* AudioManager provides access to volume and ringer mode control.
*/
@SystemService(Context.AUDIO_SERVICE)
public class AudioManager {
/**
* @hide
* Check if the specified App obtains the focus.
* @param packageName the package name of the App.
* @return ture if the App obtains the focus.
*/
public boolean isAppInFocus(String packageName) {
boolean isFocus = false;
IAudioService service = getService();
try {
isFocus = service.isAppInFocus(packageName);
} catch (RemoteException e) {
Log.e(TAG, "Can't call isAppInFocus() on AudioService due to " + e);
}
return isFocus;
}
2.2 AudioService.java
media/java/android/media/IAudioService.aidl
package com.android.server.audio;
public class AudioService extends IAudioService.Stub
implements AccessibilityManager.TouchExplorationStateChangeListener,
AccessibilityManager.AccessibilityServicesStateChangeListener {
public boolean isAppInFocus(String name) {
return mMediaFocusControl.isAppInFocus(name);
}
2.3 IAudioService.aidl
media/java/android/media/IAudioService.aidl
/**
* Check whether the dolby client application is in audio focus or not.
* @param name the application's package name.
*/
boolean isAppInFocus(String name);
2.4 具体实现 MediaFocusControl.java
services/core/java/com/android/server/audio/MediaFocusControl.java
package com.android.server.audio;
public class MediaFocusControl implements PlayerFocusEnforcer {
protected boolean isAppInFocus(String name) {
boolean isInFocus = false;
synchronized (mAudioFocusLock) {
if (!mFocusStack.empty()) {
isInFocus = mFocusStack.peek().hasSamePackage(name);
}
}
return isInFocus;
}
3. SystemUI 中音乐进程的识别判断方法 (参考或结合使用)
/**
* Get the current state of playback. One of the following:
* <ul>
* <li> {@link PlaybackState#STATE_NONE}</li>0
* <li> {@link PlaybackState#STATE_STOPPED}</li>1
* <li> {@link PlaybackState#STATE_PAUSED}</li>2
* <li> {@link PlaybackState#STATE_PLAYING}</li>3
* <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li>4
* <li> {@link PlaybackState#STATE_REWINDING}</li>5
* <li> {@link PlaybackState#STATE_BUFFERING}</li>6
* <li> {@link PlaybackState#STATE_ERROR}</li>7
* </ul>
* <p>
* Need permission <uses-permission
* android:name="android.permission.MEDIA_CONTENT_CONTROL" />
* <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"
* /> <uses-permission
* android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
*/
public static HashMap<String, Integer> findMediaProcess(Context mContext) {
HashMap<String, Integer> result = new HashMap<String, Integer>();
if (!PowerSaveController.isSystemReady()) {
return result;
}
// TODO: use MediaSessionManager.SessionListener to hook us up to future
// updates
// in session state
MediaSessionManager mMediaSessionManager = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
if (mMediaSessionManager != null) {
final List<MediaController> sessions = mMediaSessionManager.getActiveSessionsForUser(null, UserHandle.USER_ALL);
if (sessions != null && !sessions.isEmpty()) {
for (MediaController aController : sessions) {
if (aController == null)
continue;
// now to see if we have one like this
final String pkg = aController.getPackageName();
final PlaybackState state = aController.getPlaybackState();
int stateInt = state == null ? -11 : state.getState();
result.put(pkg, stateInt);
Log.d(TAG, "findMusicProcess music app = " + pkg + ", status = " + stateInt);
/*
* final PlaybackState state =
* aController.getPlaybackState(); if (state == null)
* continue; switch (state.getState()) { case
* PlaybackState.STATE_STOPPED: case
* PlaybackState.STATE_ERROR: continue; default: // now to
* see if we have one like this final String pkg =
* aController.getPackageName(); result.put(pkg,
* state.getState()); Log.d(TAG,
* "findMusicProcess music app = " + pkg + ", status = " +
* state.getState()); }
*/
}
}
}
return result;
}
最后
以上就是清新翅膀为你收集整理的Android应用场景识别-音乐进程或音频进程识别的全部内容,希望文章能够帮你解决Android应用场景识别-音乐进程或音频进程识别所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复