Updated Custom tab code and added buttons at the bottom of the article viewer.

This commit is contained in:
Amine 2017-06-03 22:52:01 +02:00
parent b42dc7f87c
commit 041a225992
7 changed files with 212 additions and 78 deletions

View File

@ -6,6 +6,7 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
@ -44,6 +45,9 @@ class ReaderActivity : DragDismissActivity() {
val content = v.findViewById(R.id.content) as HtmlTextView val content = v.findViewById(R.id.content) as HtmlTextView
val url = intent.getStringExtra("url") val url = intent.getStringExtra("url")
val parser = MercuryApi(getString(R.string.mercury)) val parser = MercuryApi(getString(R.string.mercury))
val browserBtn: ImageButton = v.findViewById(R.id.browserBtn) as ImageButton
val shareBtn: ImageButton = v.findViewById(R.id.shareBtn) as ImageButton
val customTabsIntent = buildCustomTabsIntent(this@ReaderActivity) val customTabsIntent = buildCustomTabsIntent(this@ReaderActivity)
mCustomTabActivityHelper = CustomTabActivityHelper() mCustomTabActivityHelper = CustomTabActivityHelper()
@ -52,13 +56,30 @@ class ReaderActivity : DragDismissActivity() {
parser.parseUrl(url).enqueue(object : Callback<ParsedContent> { parser.parseUrl(url).enqueue(object : Callback<ParsedContent> {
override fun onResponse(call: Call<ParsedContent>, response: Response<ParsedContent>) { override fun onResponse(call: Call<ParsedContent>, response: Response<ParsedContent>) {
if (response.body() != null) { if (response.body() != null && response.body()!!.content.isNotEmpty()) {
source.text = response.body()!!.domain source.text = response.body()!!.domain
title.text = response.body()!!.title title.text = response.body()!!.title
if (response.body()!!.content != null && !response.body()!!.content.isEmpty()) if (response.body()!!.content != null && !response.body()!!.content.isEmpty())
content.setHtml(response.body()!!.content, HtmlHttpImageGetter(content, null, true)) content.setHtml(response.body()!!.content, HtmlHttpImageGetter(content, null, true))
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isEmpty()) if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isEmpty())
Glide.with(applicationContext).load(response.body()!!.lead_image_url).asBitmap().fitCenter().into(image) Glide.with(applicationContext).load(response.body()!!.lead_image_url).asBitmap().fitCenter().into(image)
shareBtn.setOnClickListener {
val sendIntent = Intent()
sendIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
sendIntent.action = Intent.ACTION_SEND
sendIntent.putExtra(Intent.EXTRA_TEXT, response.body()!!.url)
sendIntent.type = "text/plain"
startActivity(Intent.createChooser(sendIntent, getString(R.string.share)).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
}
browserBtn.setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.data = Uri.parse(response.body()!!.url)
startActivity(intent)
}
hideProgressBar() hideProgressBar()
} else { } else {
errorAfterMercuryCall() errorAfterMercuryCall()

View File

@ -1,7 +1,6 @@
package apps.amine.bou.readerforselfoss.utils.customtabs; package apps.amine.bou.readerforselfoss.utils.customtabs;
import android.app.Activity; import android.app.Activity;
import android.content.ComponentName;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.customtabs.CustomTabsClient; import android.support.customtabs.CustomTabsClient;
@ -11,28 +10,30 @@ import android.support.customtabs.CustomTabsSession;
import java.util.List; import java.util.List;
@SuppressWarnings("ALL") /**
public class CustomTabActivityHelper { * This is a helper class to manage the connection to the Custom Tabs Service.
*/
public class CustomTabActivityHelper implements ServiceConnectionCallback {
private CustomTabsSession mCustomTabsSession; private CustomTabsSession mCustomTabsSession;
private CustomTabsClient mClient; private CustomTabsClient mClient;
private CustomTabsServiceConnection mConnection; private CustomTabsServiceConnection mConnection;
private ConnectionCallback mConnectionCallback; private ConnectionCallback mConnectionCallback;
/** /**
* Opens the URL on a Custom Tab if possible. Otherwise fallsback to opening it on a WebView * Opens the URL on a Custom Tab if possible. Otherwise fallsback to opening it on a WebView.
* *
* @param activity The host activity * @param activity The host activity.
* @param customTabsIntent a CustomTabsIntent to be used if Custom Tabs is available * @param customTabsIntent a CustomTabsIntent to be used if Custom Tabs is available.
* @param uri the Uri to be opened * @param uri the Uri to be opened.
* @param fallback a CustomTabFallback to be used if Custom Tabs is not available * @param fallback a CustomTabFallback to be used if Custom Tabs is not available.
*/ */
public static void openCustomTab(Activity activity, public static void openCustomTab(Activity activity,
CustomTabsIntent customTabsIntent, CustomTabsIntent customTabsIntent,
Uri uri, Uri uri,
CustomTabFallback fallback) { CustomTabFallback fallback) {
String packageName = CustomTabsHelper.getPackageNameToUse(activity); String packageName = CustomTabsHelper.getPackageNameToUse(activity);
//If we cant find a package name, it means there's no browser that supports //If we cant find a package name, it means theres no browser that supports
//Chrome Custom Tabs installed. So, we fallback to the webview //Chrome Custom Tabs installed. So, we fallback to the webview
if (packageName == null) { if (packageName == null) {
if (fallback != null) { if (fallback != null) {
@ -45,22 +46,21 @@ public class CustomTabActivityHelper {
} }
/** /**
* Unbinds the Activity from the Custom Tabs Service * Unbinds the Activity from the Custom Tabs Service.
* @param activity the activity that is connected to the service * @param activity the activity that is connected to the service.
*/ */
public void unbindCustomTabsService(Activity activity) { public void unbindCustomTabsService(Activity activity) {
try { if (mConnection == null) return;
if (mConnection == null) return; activity.unbindService(mConnection);
activity.unbindService(mConnection); mClient = null;
mClient = null; mCustomTabsSession = null;
mCustomTabsSession = null; mConnection = null;
} catch (RuntimeException e) {}
} }
/** /**
* Creates or retrieves an exiting CustomTabsSession * Creates or retrieves an exiting CustomTabsSession.
* *
* @return a CustomTabsSession * @return a CustomTabsSession.
*/ */
public CustomTabsSession getSession() { public CustomTabsSession getSession() {
if (mClient == null) { if (mClient == null) {
@ -72,7 +72,7 @@ public class CustomTabActivityHelper {
} }
/** /**
* Register a Callback to be called when connected or disconnected from the Custom Tabs Service * Register a Callback to be called when connected or disconnected from the Custom Tabs Service.
* @param connectionCallback * @param connectionCallback
*/ */
public void setConnectionCallback(ConnectionCallback connectionCallback) { public void setConnectionCallback(ConnectionCallback connectionCallback) {
@ -80,65 +80,70 @@ public class CustomTabActivityHelper {
} }
/** /**
* Binds the Activity to the Custom Tabs Service * Binds the Activity to the Custom Tabs Service.
* @param activity the activity to be binded to the service * @param activity the activity to be binded to the service.
*/ */
public void bindCustomTabsService(Activity activity) { public void bindCustomTabsService(Activity activity) {
if (mClient != null) return; if (mClient != null) return;
String packageName = CustomTabsHelper.getPackageNameToUse(activity); String packageName = CustomTabsHelper.getPackageNameToUse(activity);
if (packageName == null) return; if (packageName == null) return;
mConnection = new CustomTabsServiceConnection() {
@Override
public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
mClient = client;
mClient.warmup(0L);
if (mConnectionCallback != null) mConnectionCallback.onCustomTabsConnected();
//Initialize a session as soon as possible.
getSession();
}
@Override mConnection = new ServiceConnection(this);
public void onServiceDisconnected(ComponentName name) {
mClient = null;
if (mConnectionCallback != null) mConnectionCallback.onCustomTabsDisconnected();
}
};
CustomTabsClient.bindCustomTabsService(activity, packageName, mConnection); CustomTabsClient.bindCustomTabsService(activity, packageName, mConnection);
} }
/**
* @see {@link CustomTabsSession#mayLaunchUrl(Uri, Bundle, List)}.
* @return true if call to mayLaunchUrl was accepted.
*/
public boolean mayLaunchUrl(Uri uri, Bundle extras, List<Bundle> otherLikelyBundles) { public boolean mayLaunchUrl(Uri uri, Bundle extras, List<Bundle> otherLikelyBundles) {
if (mClient == null) return false; if (mClient == null) return false;
CustomTabsSession session = getSession(); CustomTabsSession session = getSession();
return session != null && session.mayLaunchUrl(uri, extras, otherLikelyBundles); if (session == null) return false;
return session.mayLaunchUrl(uri, extras, otherLikelyBundles);
}
@Override
public void onServiceConnected(CustomTabsClient client) {
mClient = client;
mClient.warmup(0L);
if (mConnectionCallback != null) mConnectionCallback.onCustomTabsConnected();
}
@Override
public void onServiceDisconnected() {
mClient = null;
mCustomTabsSession = null;
if (mConnectionCallback != null) mConnectionCallback.onCustomTabsDisconnected();
} }
/** /**
* A Callback for when the service is connected or disconnected. Use those callbacks to * A Callback for when the service is connected or disconnected. Use those callbacks to
* handle UI changes when the service is connected or disconnected * handle UI changes when the service is connected or disconnected.
*/ */
public interface ConnectionCallback { public interface ConnectionCallback {
/** /**
* Called when the service is connected * Called when the service is connected.
*/ */
void onCustomTabsConnected(); void onCustomTabsConnected();
/** /**
* Called when the service is disconnected * Called when the service is disconnected.
*/ */
void onCustomTabsDisconnected(); void onCustomTabsDisconnected();
} }
/** /**
* To be used as a fallback to open the Uri when Custom Tabs is not available * To be used as a fallback to open the Uri when Custom Tabs is not available.
*/ */
public interface CustomTabFallback { public interface CustomTabFallback {
/** /**
* *
* @param activity The Activity that wants to open the Uri * @param activity The Activity that wants to open the Uri.
* @param uri The uri to be opened by the fallback * @param uri The uri to be opened by the fallback.
*/ */
void openUri(Activity activity, Uri uri); void openUri(Activity activity, Uri uri);
} }

View File

@ -0,0 +1,32 @@
package apps.amine.bou.readerforselfoss.utils.customtabs;
import android.content.ComponentName;
import android.support.customtabs.CustomTabsClient;
import android.support.customtabs.CustomTabsServiceConnection;
import java.lang.ref.WeakReference;
/**
* Implementation for the CustomTabsServiceConnection that avoids leaking the
* ServiceConnectionCallback
*/
public class ServiceConnection extends CustomTabsServiceConnection {
// A weak reference to the ServiceConnectionCallback to avoid leaking it.
private WeakReference<ServiceConnectionCallback> mConnectionCallback;
public ServiceConnection(ServiceConnectionCallback connectionCallback) {
mConnectionCallback = new WeakReference<>(connectionCallback);
}
@Override
public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
ServiceConnectionCallback connectionCallback = mConnectionCallback.get();
if (connectionCallback != null) connectionCallback.onServiceConnected(client);
}
@Override
public void onServiceDisconnected(ComponentName name) {
ServiceConnectionCallback connectionCallback = mConnectionCallback.get();
if (connectionCallback != null) connectionCallback.onServiceDisconnected();
}
}

View File

@ -0,0 +1,18 @@
package apps.amine.bou.readerforselfoss.utils.customtabs;
import android.support.customtabs.CustomTabsClient;
public interface ServiceConnectionCallback {
/**
* Called when the service is connected.
* @param client a CustomTabsClient
*/
void onServiceConnected(CustomTabsClient client);
/**
* Called when the service is disconnected.
*/
void onServiceDisconnected();
}

View File

@ -62,5 +62,64 @@
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title" /> app:layout_constraintTop_toBottomOf="@+id/title"
tools:text="Some text @android:string/fingerprint_icon_content_description" />
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_marginBottom="0dp"
android:layout_marginEnd="0dp"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp"
android:background="#BBBBBB"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/content"
app:layout_constraintVertical_bias="1.0">
<ImageButton
android:id="@+id/browserBtn"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_toLeftOf="@+id/shareBtn"
android:layout_toStartOf="@+id/shareBtn"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:elevation="5dp"
android:padding="4dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_open_in_browser_black_24dp"
android:tint="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/shareBtn"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/shareBtn"
android:layout_width="35dp"
android:layout_height="35dp"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:elevation="5dp"
android:padding="4dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_share_black_24dp"
android:tint="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/browserBtn"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

View File

@ -54,65 +54,64 @@
android:gravity="start" /> android:gravity="start" />
<RelativeLayout <RelativeLayout
android:id="@+id/actionBar"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="#BBBBBB"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@+id/sourceTitleAndDate">
app:layout_constraintTop_toBottomOf="@+id/sourceTitleAndDate"
android:id="@+id/actionBar"
android:background="#BBBBBB"
android:visibility="gone">
<com.like.LikeButton <com.like.LikeButton
app:icon_type="heart"
app:icon_size="22dp"
android:id="@+id/favButton" android:id="@+id/favButton"
android:layout_width="35dp" android:layout_width="35dp"
android:layout_height="35dp" android:layout_height="35dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_alignParentRight="true" android:layout_marginEnd="8dp"
android:layout_alignParentEnd="true" android:layout_marginRight="8dp"
android:elevation="5dp" android:elevation="5dp"
android:padding="4dp" android:padding="4dp"
android:layout_marginEnd="8dp" app:icon_size="22dp"
android:layout_marginRight="8dp"/> app:icon_type="heart" />
<ImageButton <ImageButton
android:id="@+id/shareBtn"
android:layout_width="35dp" android:layout_width="35dp"
android:layout_height="35dp" android:layout_height="35dp"
android:src="@drawable/ic_share_black_24dp"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_toLeftOf="@+id/favButton" android:layout_toLeftOf="@+id/favButton"
android:layout_toStartOf="@+id/favButton" android:layout_toStartOf="@+id/favButton"
android:id="@+id/shareBtn" android:adjustViewBounds="true"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:elevation="5dp" android:elevation="5dp"
android:layout_marginEnd="16dp" android:padding="4dp"
android:layout_marginRight="16dp"
android:tint="#000000"
android:adjustViewBounds="true"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:padding="4dp"/> android:src="@drawable/ic_share_black_24dp"
android:tint="#000000" />
<ImageButton <ImageButton
android:id="@+id/browserBtn"
android:layout_width="35dp" android:layout_width="35dp"
android:layout_height="35dp" android:layout_height="35dp"
android:src="@drawable/ic_open_in_browser_black_24dp"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/shareBtn"
android:layout_toStartOf="@+id/shareBtn"
android:id="@+id/browserBtn"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:elevation="5dp" android:layout_toLeftOf="@+id/shareBtn"
android:background="@android:color/transparent" android:layout_toStartOf="@+id/shareBtn"
android:tint="#000000"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:elevation="5dp"
android:padding="4dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:padding="4dp"/> android:src="@drawable/ic_open_in_browser_black_24dp"
android:tint="#000000" />
</RelativeLayout> </RelativeLayout>

View File

@ -7,7 +7,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.0.0-alpha2' classpath 'com.android.tools.build:gradle:3.0.0-alpha3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong