diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e6ea6cff3236beba91521f8272c6aafdd9690d1a..af5e84ee9267d7bdf3977e03173a2d6c745a0d0f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -28,8 +28,6 @@ - - @@ -38,8 +36,9 @@ android:exported="true"> - + + diff --git a/app/src/main/java/foundation/e/pwaplayer/database/Pwa.kt b/app/src/main/java/foundation/e/pwaplayer/database/Pwa.kt index 86418e281eaee7005c871fd619fd7a7adb94e2a9..2c313bea5f11a87af0c71bf12df0c847b4831133 100644 --- a/app/src/main/java/foundation/e/pwaplayer/database/Pwa.kt +++ b/app/src/main/java/foundation/e/pwaplayer/database/Pwa.kt @@ -26,6 +26,7 @@ data class Pwa( @ColumnInfo(name = PwaConstants.TITLE) val title: String, + @ColumnInfo(name = PwaConstants.ICON, typeAffinity = ColumnInfo.BLOB) val iconBlob: ByteArray ) { diff --git a/app/src/main/java/foundation/e/pwaplayer/provider/PwaProvider.kt b/app/src/main/java/foundation/e/pwaplayer/provider/PwaProvider.kt index 7bcd98ab5a945e100b1e74ec7d42d8961eb8de16..54dc564e84c98473426e52a676a94cd3772a1184 100644 --- a/app/src/main/java/foundation/e/pwaplayer/provider/PwaProvider.kt +++ b/app/src/main/java/foundation/e/pwaplayer/provider/PwaProvider.kt @@ -1,10 +1,12 @@ package foundation.e.pwaplayer.provider -import android.content.* +import android.content.ContentProvider +import android.content.ContentUris +import android.content.ContentValues +import android.content.UriMatcher import android.database.Cursor import android.net.Uri import android.util.Log -import androidx.core.content.contentValuesOf import foundation.e.pwaplayer.database.PwaDatabase import foundation.e.pwaplayer.database.mapToPwa import foundation.e.pwaplayer.provider.PwaConstants.Companion.TABLE_NAME diff --git a/app/src/main/java/foundation/e/pwaplayer/ui/home/HomeActivity.kt b/app/src/main/java/foundation/e/pwaplayer/ui/home/HomeActivity.kt index fb3757ca4ca8941b06b82ddac3bae2d66fbecc0a..e0351e3b5f6fa29ec429c8d6ffbfd5ea2f4729a5 100644 --- a/app/src/main/java/foundation/e/pwaplayer/ui/home/HomeActivity.kt +++ b/app/src/main/java/foundation/e/pwaplayer/ui/home/HomeActivity.kt @@ -75,7 +75,6 @@ class HomeActivity : AppCompatActivity() { val cursor = contentResolver.query(CONTENT_URI, null, null, null, null) val data = ArrayList() if (cursor != null) { - Log.d(TAG, "loadData: ${cursor.count} ${cursor.columnCount}") if (cursor.moveToFirst()) { do { val pwa = cursor.mapToPwa() diff --git a/app/src/main/java/foundation/e/pwaplayer/ui/home/HomeRecyclerAdapter.kt b/app/src/main/java/foundation/e/pwaplayer/ui/home/HomeRecyclerAdapter.kt index 0c625abfc66db84d7b8f5987ad113b9dcc407008..a0ef37eb55d7d16d3c18318ff5353df84cfef702 100644 --- a/app/src/main/java/foundation/e/pwaplayer/ui/home/HomeRecyclerAdapter.kt +++ b/app/src/main/java/foundation/e/pwaplayer/ui/home/HomeRecyclerAdapter.kt @@ -14,6 +14,7 @@ import androidx.recyclerview.widget.RecyclerView import foundation.e.pwaplayer.R import foundation.e.pwaplayer.database.Pwa import foundation.e.pwaplayer.ui.player.PwaActivity +import foundation.e.pwaplayer.util.toBitmap class HomeRecyclerAdapter( private val context: Context, @@ -32,7 +33,7 @@ class HomeRecyclerAdapter( intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT or Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) intent.action = "foundation.e.blisslauncher.VIEW_PWA" intent.data = Uri.parse(items[adapterPosition].url) - intent.putExtra("PWA_NAME", items[adapterPosition].title) + intent.putExtra(PwaActivity.KEY_PWA_ID, items[adapterPosition].id) context.startActivity(intent) } } @@ -40,9 +41,6 @@ class HomeRecyclerAdapter( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PwaViewHolder { val view = LayoutInflater.from(context).inflate(R.layout.item_pwa, parent, false) - view.setOnClickListener { - - } return PwaViewHolder(view) } @@ -61,9 +59,3 @@ class HomeRecyclerAdapter( notifyDataSetChanged() } } - -private fun ByteArray.toBitmap(): Bitmap? { - return BitmapFactory.decodeByteArray( - this, 0, this.size - ) -} diff --git a/app/src/main/java/foundation/e/pwaplayer/ui/player/PwaActivity.java b/app/src/main/java/foundation/e/pwaplayer/ui/player/PwaActivity.java deleted file mode 100644 index ac2461419c8cb0ab940d2cae1778438dc57366bf..0000000000000000000000000000000000000000 --- a/app/src/main/java/foundation/e/pwaplayer/ui/player/PwaActivity.java +++ /dev/null @@ -1,104 +0,0 @@ -package foundation.e.pwaplayer.ui.player; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.view.KeyEvent; -import android.webkit.WebSettings; -import android.webkit.WebView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; - -import foundation.e.apps.pwa.PwaWebChromeClient; -import foundation.e.pwaplayer.R; - -public class PwaActivity extends AppCompatActivity { - - public static final String KEY_PWA_NAME = "PWA_NAME"; - public static final String KEY_SCOPE = "pwa_scope"; - - private PwaWebChromeClient pwaWebChromeClient; - private WebView webView; - - private static final String TAG = "PwaActivity"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Intent intent = getIntent(); - if (intent == null) { - Toast.makeText(this, "URL can't be empty", Toast.LENGTH_SHORT).show(); - finish(); - } - String name = getIntent().getStringExtra(KEY_PWA_NAME); - setName(this, name); - setContentView(R.layout.activity_pwa); - - pwaWebChromeClient = new PwaWebChromeClient(this, name); - webView = (WebView) findViewById(R.id.webView); - setWebView(webView, pwaWebChromeClient); - - } - - private void setName(Activity activity, String name) { - if (!name.isEmpty()) { - activity.setTitle(name); - } - } - - @SuppressLint("SetJavaScriptEnabled") - private void setWebView(WebView webView, PwaWebChromeClient pwaWebChromeClient) { - WebSettings webSettings = webView.getSettings(); - webSettings.setJavaScriptEnabled(true); - webSettings.setAllowContentAccess(true); - webSettings.setLoadWithOverviewMode(true); - webSettings.setAllowFileAccess(true); - webSettings.setAllowUniversalAccessFromFileURLs(true); - webSettings.setAllowContentAccess(true); - webSettings.setAllowFileAccessFromFileURLs(true); - webSettings.setDomStorageEnabled(true); - String start_url = getIntent().getData().toString(); - String scope = getIntent().getStringExtra(KEY_SCOPE); - if(scope == null) scope = ""; - webView.setWebChromeClient(pwaWebChromeClient); - webView.setWebViewClient(new PwaWebViewClient(start_url, scope)); - webView.loadUrl(start_url); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - switch (requestCode) { - case PwaWebChromeClient.REQUEST_LOCATION_PERMISSION: { - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - pwaWebChromeClient.locationPermissionGranted(); - } else { - pwaWebChromeClient.locationPermissionDenied(); - } - } - } - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK && webView != null && webView.canGoBack()) { - webView.goBack(); - return true; - } - return super.onKeyDown(keyCode, event); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - if (requestCode == PwaWebChromeClient.REQUEST_FILE_CHOOSER) { - pwaWebChromeClient.onActivityResult(resultCode, data); - } - super.onActivityResult(requestCode, resultCode, data); - - } -} diff --git a/app/src/main/java/foundation/e/pwaplayer/ui/player/PwaActivity.kt b/app/src/main/java/foundation/e/pwaplayer/ui/player/PwaActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..00264da0a3f6ed2c22a12ba69aea547a10a5d105 --- /dev/null +++ b/app/src/main/java/foundation/e/pwaplayer/ui/player/PwaActivity.kt @@ -0,0 +1,145 @@ +package foundation.e.pwaplayer.ui.player + +import android.annotation.SuppressLint +import android.app.Activity +import android.app.ActivityManager.TaskDescription +import android.content.ContentUris +import android.content.Intent +import android.content.pm.PackageManager +import android.graphics.Bitmap +import android.os.Bundle +import android.os.Handler +import android.os.HandlerThread +import android.os.Looper +import android.view.KeyEvent +import android.view.View +import android.webkit.WebView +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import foundation.e.apps.pwa.PwaWebChromeClient +import foundation.e.pwaplayer.R +import foundation.e.pwaplayer.database.mapToPwa +import foundation.e.pwaplayer.provider.PwaConstants +import foundation.e.pwaplayer.util.toBitmap + +class PwaActivity : AppCompatActivity() { + + private var pwaWebChromeClient: PwaWebChromeClient? = null + private var webView: WebView? = null + + private val workerThread: HandlerThread = HandlerThread("WORKER-THREAD") + private lateinit var workerHandler: Handler + private val uiHandler = Handler(Looper.getMainLooper()) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val intent = intent + if (intent == null) { + Toast.makeText(this, "URL can't be empty", Toast.LENGTH_SHORT).show() + finish() + } + + val id = getIntent().getLongExtra(KEY_PWA_ID, -1) + + workerThread.start() + workerHandler = Handler(workerThread.looper) + workerHandler.post { + setPwaTaskInfo( id) + } + setContentView(R.layout.activity_pwa) + } + + private fun setPwaTaskInfo(id: Long) { + val cursor = contentResolver.query( + ContentUris.withAppendedId(PwaConstants.CONTENT_URI, id), + null, null, null, null + ) + if (cursor != null) { + if (cursor.moveToFirst()) { + val pwa = cursor.mapToPwa() + val icon = pwa.iconBlob?.toBitmap() + val name = pwa.title + uiHandler.post { updateTaskInfo(name, icon) } + } + cursor.close() + } + } + + private fun updateTaskInfo(name: String, icon: Bitmap?) { + this.title = name + val taskDescription: TaskDescription + if (icon != null) { + taskDescription = TaskDescription(name, icon) + setTaskDescription(taskDescription) + } else { + taskDescription = TaskDescription(name) + } + setTaskDescription(taskDescription) + + pwaWebChromeClient = PwaWebChromeClient(this, name) + webView = findViewById(R.id.webView) as WebView + setWebView(webView, pwaWebChromeClient!!) + } + + @SuppressLint("SetJavaScriptEnabled") + private fun setWebView(webView: WebView?, pwaWebChromeClient: PwaWebChromeClient) { + val webSettings = webView!!.settings + webSettings.javaScriptEnabled = true + webSettings.allowContentAccess = true + webSettings.loadWithOverviewMode = true + webSettings.allowFileAccess = true + webSettings.allowUniversalAccessFromFileURLs = true + webSettings.allowContentAccess = true + webSettings.allowFileAccessFromFileURLs = true + webSettings.domStorageEnabled = true + val start_url = intent.data.toString() + var scope = intent.getStringExtra(KEY_SCOPE) + if (scope == null) scope = "" + webView.webChromeClient = pwaWebChromeClient + webView.webViewClient = PwaWebViewClient(start_url, scope) + webView.loadUrl(start_url) + } + + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + when (requestCode) { + PwaWebChromeClient.REQUEST_LOCATION_PERMISSION -> { + if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + pwaWebChromeClient!!.locationPermissionGranted() + } else { + pwaWebChromeClient!!.locationPermissionDenied() + } + } + } + } + + override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { + if (keyCode == KeyEvent.KEYCODE_BACK && webView != null && webView!!.canGoBack()) { + webView!!.goBack() + return true + } + return super.onKeyDown(keyCode, event) + } + + override fun onActivityResult( + requestCode: Int, + resultCode: Int, + data: Intent? + ) { + if (requestCode == PwaWebChromeClient.REQUEST_FILE_CHOOSER) { + pwaWebChromeClient!!.onActivityResult(resultCode, data) + } + super.onActivityResult(requestCode, resultCode, data) + } + + companion object { + const val KEY_PWA_NAME = "PWA_NAME" + const val KEY_PWA_ICON = "PWA_ICON" + const val KEY_PWA_ID = "PWA_ID" + const val KEY_SCOPE = "pwa_scope" + private const val TAG = "PwaActivity" + } +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/pwaplayer/util/Extensions.kt b/app/src/main/java/foundation/e/pwaplayer/util/Extensions.kt new file mode 100644 index 0000000000000000000000000000000000000000..0c8a6165655991d02c8b0e5105ed10d739232204 --- /dev/null +++ b/app/src/main/java/foundation/e/pwaplayer/util/Extensions.kt @@ -0,0 +1,10 @@ +package foundation.e.pwaplayer.util + +import android.graphics.Bitmap +import android.graphics.BitmapFactory + +fun ByteArray.toBitmap(): Bitmap? { + return BitmapFactory.decodeByteArray( + this, 0, this.size + ) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000000000000000000000000000000000000..2b068d11462a4b96669193de13a711a3a36220a0 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/home_menu.xml b/app/src/main/res/menu/home_menu.xml index e4ea5b1e52a871fe5e86f13fa7e9b722b7cafc4c..56e8c5f70a8d9030576fff2a45d4eef8e4415e95 100644 --- a/app/src/main/res/menu/home_menu.xml +++ b/app/src/main/res/menu/home_menu.xml @@ -4,7 +4,7 @@ + app:showAsAction="never"/>