Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #59 from Myself5/media_controls_poweramp
 MediaService: Add Poweramp handling for media controls
  • Loading branch information
FlorentRevest committed Oct 21, 2018
2 parents eeb05ba + 172396f commit a13dfb1
Show file tree
Hide file tree
Showing 16 changed files with 1,846 additions and 25 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Expand Up @@ -24,6 +24,8 @@ android {
main.res.srcDirs += 'src/main/lib/android-ripple-background/library/src/main/res/'
main.java.srcDirs += 'src/main/lib/material-intro-screen/material-intro-screen/src/main/java/'
main.res.srcDirs += 'src/main/lib/material-intro-screen/material-intro-screen/src/main/res/'
main.java.srcDirs += 'src/main/lib/powerampapi/poweramp_api_lib/src/'
main.res.srcDirs += 'src/main/lib/powerampapi/poweramp_api_lib/res/'
}

lintOptions {
Expand Down
84 changes: 59 additions & 25 deletions app/src/main/java/org/asteroidos/sync/ble/MediaService.java
Expand Up @@ -20,6 +20,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaMetadata;
import android.media.session.MediaController;
import android.media.session.MediaSession;
Expand All @@ -29,6 +30,8 @@
import android.util.Log;

import com.idevicesinc.sweetblue.BleDevice;
import com.maxmpz.poweramp.player.PowerampAPI;
import com.maxmpz.poweramp.player.PowerampAPIHelper;

import org.asteroidos.sync.services.NLService;

Expand All @@ -49,8 +52,13 @@ public class MediaService implements BleDevice.ReadWriteListener, MediaSessionM
private static final byte MEDIA_COMMAND_PLAY = 0x2;
private static final byte MEDIA_COMMAND_PAUSE = 0x3;

public static final String PREFS_NAME = "MediaPreferences";
public static final String PREFS_MEDIA_CONTROLLER_PACKAGE = "media_controller_package";
public static final String PREFS_MEDIA_CONTROLLER_PACKAGE_DEFAULT = "default";

private Context mCtx;
private BleDevice mDevice;
private SharedPreferences mSettings;

private MediaController mMediaController = null;
private MediaSessionManager mMediaSessionManager;
Expand All @@ -59,6 +67,8 @@ public MediaService(Context ctx, BleDevice device)
{
mDevice = device;
mCtx = ctx;

mSettings = mCtx.getSharedPreferences(PREFS_NAME, 0);
}

public void sync() {
Expand Down Expand Up @@ -92,14 +102,43 @@ public void onEvent(ReadWriteEvent e) {
if(e.isNotification() && e.charUuid().equals(mediaCommandsCharac)) {
if (mMediaController != null) {
byte data[] = e.data();
if (data[0] == MEDIA_COMMAND_PREVIOUS)
mMediaController.getTransportControls().skipToPrevious();
else if (data[0] == MEDIA_COMMAND_NEXT)
mMediaController.getTransportControls().skipToNext();
else if (data[0] == MEDIA_COMMAND_PLAY)
mMediaController.getTransportControls().play();
else if (data[0] == MEDIA_COMMAND_PAUSE)
mMediaController.getTransportControls().pause();
boolean isPoweramp = mSettings.getString(PREFS_MEDIA_CONTROLLER_PACKAGE, PREFS_MEDIA_CONTROLLER_PACKAGE_DEFAULT)
.equals(PowerampAPI.PACKAGE_NAME);

switch (data[0]) {
case MEDIA_COMMAND_PREVIOUS:
if(isPoweramp) {
PowerampAPIHelper.startPAService(mCtx, new Intent(PowerampAPI.ACTION_API_COMMAND)
.putExtra(PowerampAPI.COMMAND, PowerampAPI.Commands.PREVIOUS));
} else {
mMediaController.getTransportControls().skipToPrevious();
}
break;
case MEDIA_COMMAND_NEXT:
if(isPoweramp) {
PowerampAPIHelper.startPAService(mCtx, new Intent(PowerampAPI.ACTION_API_COMMAND)
.putExtra(PowerampAPI.COMMAND, PowerampAPI.Commands.NEXT));
} else {
mMediaController.getTransportControls().skipToNext();
}
break;
case MEDIA_COMMAND_PLAY:
if(isPoweramp) {
PowerampAPIHelper.startPAService(mCtx, new Intent(PowerampAPI.ACTION_API_COMMAND)
.putExtra(PowerampAPI.COMMAND, PowerampAPI.Commands.RESUME));
} else {
mMediaController.getTransportControls().play();
}
break;
case MEDIA_COMMAND_PAUSE:
if (isPoweramp) {
PowerampAPIHelper.startPAService(mCtx, new Intent(PowerampAPI.ACTION_API_COMMAND)
.putExtra(PowerampAPI.COMMAND, PowerampAPI.Commands.PAUSE));
} else {
mMediaController.getTransportControls().pause();
}
break;
}
} else {
Intent mediaIntent = new Intent(Intent.ACTION_MAIN);
mediaIntent.addCategory(Intent.CATEGORY_APP_MUSIC);
Expand Down Expand Up @@ -190,29 +229,24 @@ public void onQueueTitleChanged(CharSequence title) {
@Override
public void onActiveSessionsChanged(List<MediaController> controllers) {
if (controllers.size() > 0) {
if (mMediaController != null) {
if (!controllers.get(0).getSessionToken().equals(mMediaController.getSessionToken())) {
// Detach current controller
mMediaController.unregisterCallback(mMediaCallback);
Log.d("MediaService", "MediaController removed");
mMediaController = null;

// Attach new controller
mMediaController = controllers.get(0);
mMediaController.registerCallback(mMediaCallback);
mMediaCallback.onMetadataChanged(mMediaController.getMetadata());
if(mMediaController.getPlaybackState() != null)
mMediaCallback.onPlaybackStateChanged(mMediaController.getPlaybackState());
Log.d("MediaService", "MediaController set: " + mMediaController.getPackageName());
}
} else {
if (mMediaController != null && !controllers.get(0).getSessionToken().equals(mMediaController.getSessionToken())) {
// Detach current controller
mMediaController.unregisterCallback(mMediaCallback);
Log.d("MediaService", "MediaController removed");
mMediaController = null;
}

if(mMediaController == null) {
// Attach new controller
mMediaController = controllers.get(0);
mMediaController.registerCallback(mMediaCallback);
mMediaCallback.onMetadataChanged(mMediaController.getMetadata());
if(mMediaController.getPlaybackState() != null)
if (mMediaController.getPlaybackState() != null)
mMediaCallback.onPlaybackStateChanged(mMediaController.getPlaybackState());
Log.d("MediaService", "MediaController set: " + mMediaController.getPackageName());
SharedPreferences.Editor editor = mSettings.edit();
editor.putString(PREFS_MEDIA_CONTROLLER_PACKAGE, mMediaController.getPackageName());
editor.apply();
}
} else {
byte[] data = new byte[]{0};
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/lib/powerampapi/.gitignore
@@ -0,0 +1,4 @@
local.properties
/bin
/gen
.DS_Store
9 changes: 9 additions & 0 deletions app/src/main/lib/powerampapi/README.md
@@ -0,0 +1,9 @@
Poweramp APIs
===========

Please check https://forum.powerampapp.com/forum/13-developers-area/ for more details

Also see [poweramp_skin_sdk/poweramp_skin_sample/readme.md](poweramp_skin_sdk/poweramp_skin_sample/readme.md)



12 changes: 12 additions & 0 deletions app/src/main/lib/powerampapi/poweramp_api_lib/.classpath
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="org.eclipse.andmore.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="org.eclipse.andmore.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="org.eclipse.andmore.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
3 changes: 3 additions & 0 deletions app/src/main/lib/powerampapi/poweramp_api_lib/.gitignore
@@ -0,0 +1,3 @@
local.properties
/bin
/gen
49 changes: 49 additions & 0 deletions app/src/main/lib/powerampapi/poweramp_api_lib/.project
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>poweramp_api_lib</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.andmore.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.andmore.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.andmore.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.andmore.AndroidNature</nature>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
@@ -0,0 +1 @@
*.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.maxmpz.powerampapilib"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="17"/>
</manifest>
17 changes: 17 additions & 0 deletions app/src/main/lib/powerampapi/poweramp_api_lib/LICENSE.txt
@@ -0,0 +1,17 @@
Copyright (C) 2011-2013 Maksim Petrov

Redistribution and use in source and binary forms, with or without
modification, are permitted for widgets, plugins, applications and other software
which communicate with PowerAMP application on Android platform.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
85 changes: 85 additions & 0 deletions app/src/main/lib/powerampapi/poweramp_api_lib/build.xml
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="poweramp_api_lib" default="help">

<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />

<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />

<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />

<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
unless="sdk.dir"
/>


<!-- extension targets. Uncomment the ones where you want to do custom work
in between standard targets -->
<!--
<target name="-pre-build">
</target>
<target name="-pre-compile">
</target>
/* This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir} */
<target name="-post-compile">
</target>
-->

<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />

</project>
40 changes: 40 additions & 0 deletions app/src/main/lib/powerampapi/poweramp_api_lib/proguard.cfg
@@ -0,0 +1,40 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
native <methods>;
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}

-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
14 changes: 14 additions & 0 deletions app/src/main/lib/powerampapi/poweramp_api_lib/project.properties
@@ -0,0 +1,14 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your
# project structure.
java.source=1.7
java.target=1.7
java.encoding=utf-8
android.library=true
# Project target.
target=android-28

0 comments on commit a13dfb1

Please sign in to comment.