andrewilley Posted July 23, 2023 Share Posted July 23, 2023 Feel free to continue here, other people may find it of use in the future. Andre Link to comment Share on other sites More sharing options...
flyingdutchman Posted July 23, 2023 Share Posted July 23, 2023 1 hour ago, Pumila said: MediaSessionCompat this appears to be related to playing tracks. You are more interested in using the Poweramp API. I assume you are using Android Studio. Create your new project Get the Poweramp API from Github and add it to your project structure now have a good look at the section with uri;'s as these are the things that give you access to the databse /** * Data:<br> * - uri, following URIs are recognized:<br> * - file://path (NOTE: depending on Android version, uris like this can fail due to missing filesystem permissions)<br> * - content://com.maxmpz.audioplayer.data/... (see below)<br><br> * - any other content:// uri compatible with ContentResolver.openFile<br> * - http/https url (stream or remote track file)<br><br> *......etc for example public final Uri powerampuri = Uri.parse("content://com.maxmpz.audioplayer.data/files"); // powerampfoldersuri =SELECT folder_files._id FROM folder_files //INNER JOIN folders ON folders._id=folder_id //INNER JOIN albums //ON albums._id=folder_files.album_id //INNER JOIN artists ON artists._id=folder_files.artist_id Cursor test = cr.query(powerampuri, null, null, null, null); below will return the content of the composer table pcursor = pamp.get_table_content(context, pamp.composersuri, proj, null, null, null); public Cursor get_table_content(Context context, Uri table_uri, String[] proj, String where, String[] sel_args, String order_by) { Cursor cursor = null; if (context != null) { ContentResolver cr = context.getContentResolver(); try { cursor = cr.query(table_uri, proj, where, sel_args, order_by); } catch (Exception e) { e.printStackTrace(); } } return cursor; } Link to comment Share on other sites More sharing options...
Pumila Posted August 5, 2023 Author Share Posted August 5, 2023 @flyingdutchman I wonder if I should use Android Studio. For now, I managed to build it, and when I run it, "Hello World" is displayed on Android. However, I get the following error log, and I can't get the desired play count. This is my first time using both Android Studio and JAVA, so I'm not sure how to resolve this issue. I would greatly appreciate it if you could suggest a solution. 2023-08-06 00:24:21.590 4371-4371 Perf com.example.myapplication I Connecting to perf service. 2023-08-06 00:24:21.602 4371-4371 FeatureParser com.example.myapplication I can't find dipper.xml in assets/device_features/,it may be in /system/etc/device_features 2023-08-06 00:24:21.612 4371-4371 libc com.example.myapplication E Access denied finding property "ro.vendor.df.effect.conflict" 2023-08-06 00:24:21.615 4371-4408 Perf com.example.myapplication E Fail to get file list com.example.myapplication 2023-08-06 00:24:21.615 4371-4408 Perf com.example.myapplication E getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array 2023-08-06 00:24:21.615 4371-4408 Perf com.example.myapplication E Fail to get file list com.example.myapplication 2023-08-06 00:24:21.615 4371-4408 Perf com.example.myapplication E getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array 2023-08-06 00:24:21.615 4371-4408 Perf com.example.myapplication E Fail to get file list oat 2023-08-06 00:24:21.615 4371-4408 Perf com.example.myapplication E getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array 2023-08-06 00:24:21.633 4371-4371 e.myapplicatio com.example.myapplication E Invalid ID 0x00000000. 2023-08-06 00:24:21.641 4371-4371 ForceDarkHelper com.example.myapplication D updateByCheckExcludeList: pkg: com.example.myapplication activity: com.example.myapplication.MainActivity@7b4d340 2023-08-06 00:24:21.643 4371-4371 chatty com.example.myapplication I uid=10348(com.example.myapplication) identical 1 line 2023-08-06 00:24:21.646 4371-4371 ForceDarkHelper com.example.myapplication D updateByCheckExcludeList: pkg: com.example.myapplication activity: com.example.myapplication.MainActivity@7b4d340 2023-08-06 00:24:21.683 4371-4371 ForceDarkHelper com.example.myapplication D updateByCheckExcludeList: pkg: com.example.myapplication activity: com.example.myapplication.MainActivity@7b4d340 2023-08-06 00:24:21.742 4371-4371 e.myapplicatio com.example.myapplication W Accessing hidden method Landroid/graphics/Canvas;->drawPatch(Landroid/graphics/NinePatch;Landroid/graphics/Rect;Landroid/graphics/Paint;)V (greylist-max-o, linking, denied) 2023-08-06 00:24:21.742 4371-4371 e.myapplicatio com.example.myapplication W Accessing hidden method Landroid/graphics/Canvas;->drawPatch(Landroid/graphics/NinePatch;Landroid/graphics/RectF;Landroid/graphics/Paint;)V (greylist-max-o, linking, denied) 2023-08-06 00:24:21.754 4371-4409 AdrenoGLES com.example.myapplication I QUALCOMM build : 033a5b0, I0e419467bc Build Date : 03/11/20 OpenGL ES Shader Compiler Version: EV031.27.05.01 Local Branch : Remote Branch : refs/tags/AU_LINUX_ANDROID_LA.UM.8.3.R1.10.00.00.520.058 Remote Branch : NONE Reconstruct Branch : NOTHING 2023-08-06 00:24:21.754 4371-4409 AdrenoGLES com.example.myapplication I Build Config : S P 8.0.11 AArch64 2023-08-06 00:24:21.756 4371-4409 AdrenoGLES com.example.myapplication I PFP: 0x016ee187, ME: 0x00000000 2023-08-06 00:24:21.757 4371-4409 AdrenoUtils com.example.myapplication W <ReadGpuID_from_sysfs:194>: Failed to open /sys/class/kgsl/kgsl-3d0/gpu_model 2023-08-06 00:24:21.757 4371-4409 AdrenoUtils com.example.myapplication W <ReadGpuID:218>: Failed to read chip ID from gpu_model. Fallback to use the GSL path 2023-08-06 00:24:21.772 4371-4409 Gralloc3 com.example.myapplication W mapper 3.x is not supported 2023-08-06 00:24:23.481 4371-4371 Looper com.example.myapplication W Slow Looper main: Long Msg: seq=25 plan=00:24:22.470 late=0ms wall=1007ms running=1ms runnable=1ms io=3ms h=android.app.ActivityThread$H w=127 2023-08-06 00:24:27.041 4371-4427 ProfileInstaller com.example.myapplication D Installing profile for com.example.myapplication 2023-08-06 00:24:29.626 4371-4407 e.myapplicatio com.example.myapplication I ProcessProfilingInfo new_methods=0 is saved saved_to_disk=0 resolve_classes_delay=8000 2023-08-06 00:24:33.553 4371-4371 IInputConnectionWrapper com.example.myapplication W requestCursorAnchorInfo on inactive InputConnection The source code I'm using is as follows. import android.util.Log; import com.maxmpz.Poweramp.player.PowerampAPI; public Cursor getPowerampTrackcursor(Context context, String where, String sort_order) { String[] proj = {pamptrack_id, pamptrack_name, pampalbum, pampartist, pamprating, pampduration, pamppath, pamptimes_played}; try { Cursor cursor = context.getContentResolver().query(powerampuri, proj, where, null, sort_order); return cursor; } catch (Exception e) { e.printStackTrace(); } } cursor cursor = getPowerampTrackcursor(this, null, null); while (cursor.moveToNext()) { String trackName = cursor.getString(cursor.getColumnIndex(PowerampAPI.Track.PAMPTRACK_NAME)); // do something with trackName Log.d("Track Information", "Track Name: " + trackName); // Add this line } cursor.close(); Link to comment Share on other sites More sharing options...
flyingdutchman Posted August 5, 2023 Share Posted August 5, 2023 @Pumila you are on the right track in my example I have predefined the columns used for the projection. You do not show these so I cannot tell if your query actually works. For play count I have done the following defined my variable "folder_files_played_times" and assigned the folder_files.played_times public String folder_files_played_times = "folder_files.played_times as count_of_played"; When you run this query and it returns values, there will be a column called count_of_played Iterating over the cursor you find out which column it actually is integer column_number_count = cursor.getInt(cursor.getColumnIndex("count_of_played")); then you can get the string value or int value int cnt = cursor.getInt(column_number_count); for only 1 column you could use the hard coded approach int cnt = cursor.getInt(0); Some additional points Cursor.Movefirst to go to the beginning Cursor.getCount() to check if you actually have something. Any operations with a cursor which is null will give you a crash Set breakpoints and run in debug mode. It will allow you to investigate values Link to comment Share on other sites More sharing options...
Pumila Posted August 13, 2023 Author Share Posted August 13, 2023 @flyingdutchman I apologize for asking repeatedly. I've tried various things using ChatGPT, but it doesn't seem to be working out. Here's the source code I'm running. Does this look right to you? If any corrections are needed, it would be greatly appreciated if you could make them. Thank you in advance. package com.example.myapplication; import android.net.Uri; import android.content.Context; import android.database.Cursor; import android.content.ContentResolver; import android.util.Log; class PlayCount { public static final Uri POWERAMP_URI = Uri.parse("content://com.maxmpz.audioplayer.data/files"); public String folder_files_played_times = "folder_files.played_times as count_of_played"; public void queryPowerampData(Context context) { String[] projection = { folder_files_played_times }; Cursor cursor = null; try { cursor = get_table_content(context, POWERAMP_URI, projection, null, null, null); if (cursor != null && cursor.moveToFirst()) { int column_number_count = cursor.getColumnIndex("count_of_played"); do { int cnt = cursor.getInt(column_number_count); Log.d("PlayCount", "再生回数: " + cnt); } while (cursor.moveToNext()); } } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) { cursor.close(); } } } public Cursor get_table_content(Context context, Uri table_uri, String[] proj, String where, String[] sel_args, String order_by) { Cursor cursor = null; if (context != null) { ContentResolver cr = context.getContentResolver(); try { cursor = cr.query(table_uri, proj, where, sel_args, order_by); } catch (Exception e) { e.printStackTrace(); } } return cursor; } } Link to comment Share on other sites More sharing options...
flyingdutchman Posted August 13, 2023 Share Posted August 13, 2023 @Pumila works fine for me 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 1 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 1 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 2023-08-13 11:09:39.091 25397-25397 PlayCount com...ngdutchman.newplaylistmanager D 再生回数: 0 I would run your methods from the MainActivity add to the top private final PlayCount playcount = new PlayCount(); (it should ask you to import the class) playcount.queryPowerampData(mContext); If you want to execute operations on the returned data you could do this within the do.. while loop Link to comment Share on other sites More sharing options...
Pumila Posted August 13, 2023 Author Share Posted August 13, 2023 @flyingdutchman Thank you for your answer. I'm relieved that it's proven to be actual working code. Next is to see if it can run in my environment. Also, I'd like to ask for some advice. I'm getting the following warning messages in the runtime logs, but these aren't related, right? transport W type=1400 audit(0.0:318683): avc: denied { getattr } for path="/proc/fb" dev="proc" ino=4026531977 scontext=u:r:shell:s0 tcontext=u:object_r:proc:s0 tclass=file permissive=0 transport W type=1400 audit(0.0:318684): avc: denied { getattr } for path="/proc/keys" dev="proc" ino=4026532132 scontext=u:r:shell:s0 tcontext=u:object_r:proc_keys:s0 tclass=file permissive=0 transport W type=1400 audit(0.0:318685): avc: denied { getattr } for path="/proc/kmsg" dev="proc" ino=4026532083 scontext=u:r:shell:s0 tcontext=u:object_r:proc_kmsg:s0 tclass=file permissive=0 transport W type=1400 audit(0.0:318686): avc: denied { getattr } for path="/proc/misc" dev="proc" ino=4026531978 scontext=u:r:shell:s0 tcontext=u:object_r:proc_misc:s0 tclass=file permissive=0 transport W type=1400 audit(0.0:318687): avc: denied { getattr } for path="/proc/iomem" dev="proc" ino=4026532108 scontext=u:r:shell:s0 tcontext=u:object_r:proc_iomem:s0 tclass=file permissive=0 I don't access the /proc folder, and it's a hassle to disable SELinux, so I'm hoping that this isn't the cause. As for the execution environment, it's as shown in the attached image. I hope that's correct. I'm new to Android Studio and have never done Android app development, so I'm really sorry for not understanding much. I'd greatly appreciate it if you could teach me. Thank you in advance. Link to comment Share on other sites More sharing options...
flyingdutchman Posted August 13, 2023 Share Posted August 13, 2023 @Pumila to just see logcat relating to your app set the log level as in general you are not interested in all the other messages.You can click on the litte icon for options As for the Manifest, as far as I know you should have only 1 <action android:name="android.intent.action.MAIN" /> Remember I am not an expert in using Studio. Most help and solutions I get from StackOverflow Link to comment Share on other sites More sharing options...
BoringName Posted July 14 Share Posted July 14 Working on a similar issue so I hope it isn't off topic posting my query in here. I actually don't use Poweramp so I've just installed the trial version to trouble shoot a problem with Musicbee's wifi app that I'm trying to get working again. It queries different music players including the Poweramp database. It does say the trial is a fully functioning version for 15 days but I just wanted to check queries to the API work in the trial version? I'm not against paying for it to trouble shoot the problem but I don't want to throw my money at an app I'm not going to use if the trial version isn't the actual problem. ContentResolver contentResolver = getContentResolver(); String[] projection = {"folders.path", "folder_files.name", "folder_files.rating", "folder_files.played_times", "folder_files.played_at"}; Cursor cursor = contentResolver.query(Uri.parse("content://com.maxmpz.audioplayer.data/files"), projection, null, null, null)) With the code above, cursor is null. I've tried just using "folder_files.name" for the projection string but it still comes back as null. This is on a device running android 14. I've got a small playlist with 8 songs and played a few of them a couple of times to get some stats going. Am I missing something or is my problem the trial version? Thanks. Link to comment Share on other sites More sharing options...
flyingdutchman Posted July 14 Share Posted July 14 @BoringName query seems ok. FIY Music Playlist Manager will work with the Poweramp database when Pa is installed. otherwise it will query the andriod Mediastore. If you simply want to check values, counts etc, there are a number of criteria such as ratings and times played etc, but also a query builder "Smart Playlist" FWIW this is wat some uris actually execute // uris public static final Uri powerampuri = Uri.parse("content://com.maxmpz.audioplayer.data/files"); //powerampuri = SELECT folder_files._id FROM folder_files //INNER JOIN folders ON folders._id=folder_id //LEFT JOIN artists ON artists._id=folder_files.artist_id // LEFT JOIN albums // ON albums._id=folder_files.album_id ; public static final Uri powerampfoldersuri = Uri.parse("content://com.maxmpz.audioplayer.data/folders/files"); // powerampfoldersuri =SELECT folder_files._id FROM folder_files //INNER JOIN folders ON folders._id=folder_id //INNER JOIN albums //ON albums._id=folder_files.album_id //INNER JOIN artists ON artists._id=folder_files.artist_id public final Uri powerampgenreuri = Uri.parse("content://com.maxmpz.audioplayer.data/genres/files"); /* SELECT * FROM genre_entries INNER JOIN genres ON genres._id=genre_entries.genre_id INNER JOIN folder_files ON folder_files._id=genre_entries.folder_file_id INNER JOIN folders ON folders._id=folder_files.folder_id LEFT JOIN albums ON albums._id=folder_files.album_id LEFT JOIN artists ON artists._id=folder_files.artist_id ORDER BY genre COLLATE NOCASE , album_sort COLLATE NOCASE, track_number, title_tag COLLATE NOCASE */ Link to comment Share on other sites More sharing options...
BoringName Posted July 14 Share Posted July 14 2 hours ago, flyingdutchman said: query seems ok. Thanks. I figured out the problem. The manifest file was missing the following. <queries> <package android:name="com.maxmpz.audioplayer" /> </queries> The null result threw me off, If it produced an exception instead I might have figured it out sooner. Thanks. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now