Add QR code scanner button to search tab
This commit is contained in:
parent
e9dde114b7
commit
58259d9fb0
|
@ -282,77 +282,7 @@ public class ProfileQrCodeFragment extends AppKitFragment{
|
||||||
if(scannerIntent.resolveActivity(getActivity().getPackageManager())!=null){
|
if(scannerIntent.resolveActivity(getActivity().getPackageManager())!=null){
|
||||||
startActivityForResult(scannerIntent, SCAN_RESULT);
|
startActivityForResult(scannerIntent, SCAN_RESULT);
|
||||||
}else{
|
}else{
|
||||||
ProgressDialog progress=new ProgressDialog(getActivity());
|
BarcodeScanner.installScannerModule(themeWrapper, ()->startActivityForResult(scannerIntent, SCAN_RESULT));
|
||||||
progress.setMessage(getString(R.string.loading));
|
|
||||||
progress.setCancelable(false);
|
|
||||||
progress.show();
|
|
||||||
GmsClient.getModuleInstallerService(getActivity(), new GmsClient.ServiceConnectionCallback<>(){
|
|
||||||
@Override
|
|
||||||
public void onSuccess(IModuleInstallService service, int connectionID){
|
|
||||||
ApiFeatureRequest req=new ApiFeatureRequest();
|
|
||||||
req.callingPackage=getActivity().getPackageName();
|
|
||||||
Feature feature=new Feature();
|
|
||||||
feature.name="mlkit.barcode.ui";
|
|
||||||
feature.version=1;
|
|
||||||
feature.oldVersion=-1;
|
|
||||||
req.features=List.of(feature);
|
|
||||||
req.urgent=true;
|
|
||||||
try{
|
|
||||||
service.installModules(new IModuleInstallCallbacks.Stub(){
|
|
||||||
@Override
|
|
||||||
public void onModuleAvailabilityResponse(Status status, ModuleAvailabilityResponse response) throws RemoteException{}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onModuleInstallResponse(Status status, ModuleInstallResponse response) throws RemoteException{}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onModuleInstallIntentResponse(Status status, ModuleInstallIntentResponse response) throws RemoteException{}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStatus(Status status) throws RemoteException{}
|
|
||||||
}, req, new IModuleInstallStatusListener.Stub(){
|
|
||||||
@Override
|
|
||||||
public void onModuleInstallStatusUpdate(ModuleInstallStatusUpdate statusUpdate) throws RemoteException{
|
|
||||||
if(statusUpdate.installState==ModuleInstallStatusUpdate.STATE_COMPLETED){
|
|
||||||
Runnable r=new Runnable(){
|
|
||||||
@Override
|
|
||||||
public void run(){
|
|
||||||
if(scannerIntent.resolveActivity(getActivity().getPackageManager())!=null){
|
|
||||||
progress.dismiss();
|
|
||||||
startActivityForResult(scannerIntent, SCAN_RESULT);
|
|
||||||
}else{
|
|
||||||
codeContainer.postDelayed(this, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
getActivity().runOnUiThread(r);
|
|
||||||
GmsClient.disconnectFromService(getActivity(), connectionID);
|
|
||||||
}else if(statusUpdate.installState==ModuleInstallStatusUpdate.STATE_FAILED || statusUpdate.installState==ModuleInstallStatusUpdate.STATE_CANCELED){
|
|
||||||
getActivity().runOnUiThread(()->{
|
|
||||||
progress.dismiss();
|
|
||||||
Toast.makeText(themeWrapper, R.string.error, Toast.LENGTH_SHORT).show();
|
|
||||||
});
|
|
||||||
GmsClient.disconnectFromService(getActivity(), connectionID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}catch(RemoteException e){
|
|
||||||
Log.e(TAG, "onSuccess: ", e);
|
|
||||||
getActivity().runOnUiThread(()->{
|
|
||||||
progress.dismiss();
|
|
||||||
Toast.makeText(themeWrapper, R.string.error, Toast.LENGTH_SHORT).show();
|
|
||||||
});
|
|
||||||
GmsClient.disconnectFromService(getActivity(), connectionID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Exception error){
|
|
||||||
Log.e(TAG, "onError() called with: error = ["+error+"]");
|
|
||||||
Toast.makeText(themeWrapper, R.string.error, Toast.LENGTH_SHORT).show();
|
|
||||||
progress.dismiss();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package org.joinmastodon.android.fragments.discover;
|
package org.joinmastodon.android.fragments.discover;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
@ -11,9 +14,14 @@ import android.widget.FrameLayout;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.MainActivity;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.fragments.ScrollableToTop;
|
import org.joinmastodon.android.fragments.ScrollableToTop;
|
||||||
|
import org.joinmastodon.android.googleservices.GmsClient;
|
||||||
|
import org.joinmastodon.android.googleservices.barcodescanner.Barcode;
|
||||||
|
import org.joinmastodon.android.googleservices.barcodescanner.BarcodeScanner;
|
||||||
import org.joinmastodon.android.model.SearchResult;
|
import org.joinmastodon.android.model.SearchResult;
|
||||||
import org.joinmastodon.android.ui.OutlineProviders;
|
import org.joinmastodon.android.ui.OutlineProviders;
|
||||||
import org.joinmastodon.android.ui.SimpleViewHolder;
|
import org.joinmastodon.android.ui.SimpleViewHolder;
|
||||||
|
@ -33,6 +41,7 @@ import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
public class DiscoverFragment extends AppKitFragment implements ScrollableToTop, OnBackPressedListener{
|
public class DiscoverFragment extends AppKitFragment implements ScrollableToTop, OnBackPressedListener{
|
||||||
private static final int QUERY_RESULT=937;
|
private static final int QUERY_RESULT=937;
|
||||||
|
private static final int SCAN_RESULT=456;
|
||||||
|
|
||||||
private TabLayout tabLayout;
|
private TabLayout tabLayout;
|
||||||
private ViewPager2 pager;
|
private ViewPager2 pager;
|
||||||
|
@ -40,7 +49,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||||
private TabLayoutMediator tabLayoutMediator;
|
private TabLayoutMediator tabLayoutMediator;
|
||||||
private boolean searchActive;
|
private boolean searchActive;
|
||||||
private FrameLayout searchView;
|
private FrameLayout searchView;
|
||||||
private ImageButton searchBack;
|
private ImageButton searchBack, searchScanQR;
|
||||||
private TextView searchText;
|
private TextView searchText;
|
||||||
private View tabsDivider;
|
private View tabsDivider;
|
||||||
|
|
||||||
|
@ -52,6 +61,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||||
|
|
||||||
private String accountID;
|
private String accountID;
|
||||||
private String currentQuery;
|
private String currentQuery;
|
||||||
|
private Intent scannerIntent;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState){
|
public void onCreate(Bundle savedInstanceState){
|
||||||
|
@ -60,6 +70,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||||
setRetainInstance(true);
|
setRetainInstance(true);
|
||||||
|
|
||||||
accountID=getArguments().getString("account");
|
accountID=getArguments().getString("account");
|
||||||
|
scannerIntent=BarcodeScanner.createIntent(Barcode.FORMAT_QR_CODE, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -174,6 +185,12 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||||
tabLayout.setVisibility(View.GONE);
|
tabLayout.setVisibility(View.GONE);
|
||||||
searchView.setVisibility(View.VISIBLE);
|
searchView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
searchScanQR=view.findViewById(R.id.search_scan_qr);
|
||||||
|
if(!GmsClient.isGooglePlayServicesAvailable(getActivity())){
|
||||||
|
searchScanQR.setVisibility(View.GONE);
|
||||||
|
}else{
|
||||||
|
searchScanQR.setOnClickListener(v->openQrScanner());
|
||||||
|
}
|
||||||
|
|
||||||
View searchWrap=view.findViewById(R.id.search_wrap);
|
View searchWrap=view.findViewById(R.id.search_wrap);
|
||||||
searchWrap.setOutlineProvider(OutlineProviders.roundedRect(28));
|
searchWrap.setOutlineProvider(OutlineProviders.roundedRect(28));
|
||||||
|
@ -268,6 +285,28 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data){
|
||||||
|
if(requestCode==SCAN_RESULT && resultCode==Activity.RESULT_OK && BarcodeScanner.isValidResult(data)){
|
||||||
|
Barcode code=BarcodeScanner.getResult(data);
|
||||||
|
if(code!=null){
|
||||||
|
if(code.rawValue.startsWith("https:") || code.rawValue.startsWith("http:")){
|
||||||
|
((MainActivity)getActivity()).handleURL(Uri.parse(code.rawValue), accountID);
|
||||||
|
}else{
|
||||||
|
Toast.makeText(getActivity(), R.string.link_not_supported, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openQrScanner(){
|
||||||
|
if(scannerIntent.resolveActivity(getActivity().getPackageManager())!=null){
|
||||||
|
startActivityForResult(scannerIntent, SCAN_RESULT);
|
||||||
|
}else{
|
||||||
|
BarcodeScanner.installScannerModule(getActivity(), ()->startActivityForResult(scannerIntent, SCAN_RESULT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class DiscoverPagerAdapter extends RecyclerView.Adapter<SimpleViewHolder>{
|
private class DiscoverPagerAdapter extends RecyclerView.Adapter<SimpleViewHolder>{
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,12 +1,35 @@
|
||||||
package org.joinmastodon.android.googleservices.barcodescanner;
|
package org.joinmastodon.android.googleservices.barcodescanner;
|
||||||
|
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.Feature;
|
||||||
|
import com.google.android.gms.common.api.Status;
|
||||||
|
import com.google.android.gms.common.moduleinstall.ModuleAvailabilityResponse;
|
||||||
|
import com.google.android.gms.common.moduleinstall.ModuleInstallIntentResponse;
|
||||||
|
import com.google.android.gms.common.moduleinstall.ModuleInstallResponse;
|
||||||
|
import com.google.android.gms.common.moduleinstall.ModuleInstallStatusUpdate;
|
||||||
|
import com.google.android.gms.common.moduleinstall.internal.ApiFeatureRequest;
|
||||||
|
import com.google.android.gms.common.moduleinstall.internal.IModuleInstallCallbacks;
|
||||||
|
import com.google.android.gms.common.moduleinstall.internal.IModuleInstallService;
|
||||||
|
import com.google.android.gms.common.moduleinstall.internal.IModuleInstallStatusListener;
|
||||||
|
|
||||||
import org.joinmastodon.android.MastodonApp;
|
import org.joinmastodon.android.MastodonApp;
|
||||||
|
import org.joinmastodon.android.R;
|
||||||
|
import org.joinmastodon.android.googleservices.GmsClient;
|
||||||
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class BarcodeScanner{
|
public class BarcodeScanner{
|
||||||
|
private static final String TAG="BarcodeScanner";
|
||||||
|
|
||||||
public static Intent createIntent(int formats, boolean allowManualInout, boolean enableAutoZoom){
|
public static Intent createIntent(int formats, boolean allowManualInout, boolean enableAutoZoom){
|
||||||
Intent intent=new Intent().setPackage("com.google.android.gms").setAction("com.google.android.gms.mlkit.ACTION_SCAN_BARCODE");
|
Intent intent=new Intent().setPackage("com.google.android.gms").setAction("com.google.android.gms.mlkit.ACTION_SCAN_BARCODE");
|
||||||
String appName;
|
String appName;
|
||||||
|
@ -35,4 +58,79 @@ public class BarcodeScanner{
|
||||||
parcel.recycle();
|
parcel.recycle();
|
||||||
return barcode;
|
return barcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void installScannerModule(Context context, Runnable onSuccess){
|
||||||
|
ProgressDialog progress=new ProgressDialog(context);
|
||||||
|
progress.setMessage(context.getString(R.string.loading));
|
||||||
|
progress.setCancelable(false);
|
||||||
|
progress.show();
|
||||||
|
GmsClient.getModuleInstallerService(context, new GmsClient.ServiceConnectionCallback<>(){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(IModuleInstallService service, int connectionID){
|
||||||
|
ApiFeatureRequest req=new ApiFeatureRequest();
|
||||||
|
req.callingPackage=context.getPackageName();
|
||||||
|
Feature feature=new Feature();
|
||||||
|
feature.name="mlkit.barcode.ui";
|
||||||
|
feature.version=1;
|
||||||
|
feature.oldVersion=-1;
|
||||||
|
req.features=List.of(feature);
|
||||||
|
req.urgent=true;
|
||||||
|
try{
|
||||||
|
service.installModules(new IModuleInstallCallbacks.Stub(){
|
||||||
|
@Override
|
||||||
|
public void onModuleAvailabilityResponse(Status status, ModuleAvailabilityResponse response) throws RemoteException{}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onModuleInstallResponse(Status status, ModuleInstallResponse response) throws RemoteException{}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onModuleInstallIntentResponse(Status status, ModuleInstallIntentResponse response) throws RemoteException{}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStatus(Status status) throws RemoteException{}
|
||||||
|
}, req, new IModuleInstallStatusListener.Stub(){
|
||||||
|
@Override
|
||||||
|
public void onModuleInstallStatusUpdate(ModuleInstallStatusUpdate statusUpdate) throws RemoteException{
|
||||||
|
if(statusUpdate.installState==ModuleInstallStatusUpdate.STATE_COMPLETED){
|
||||||
|
Intent scannerIntent=createIntent(0, false, false);
|
||||||
|
Runnable r=new Runnable(){
|
||||||
|
@Override
|
||||||
|
public void run(){
|
||||||
|
if(scannerIntent.resolveActivity(context.getPackageManager())!=null){
|
||||||
|
progress.dismiss();
|
||||||
|
onSuccess.run();
|
||||||
|
}else{
|
||||||
|
UiUtils.runOnUiThread(this, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
UiUtils.runOnUiThread(r);
|
||||||
|
GmsClient.disconnectFromService(context, connectionID);
|
||||||
|
}else if(statusUpdate.installState==ModuleInstallStatusUpdate.STATE_FAILED || statusUpdate.installState==ModuleInstallStatusUpdate.STATE_CANCELED){
|
||||||
|
UiUtils.runOnUiThread(()->{
|
||||||
|
progress.dismiss();
|
||||||
|
Toast.makeText(context, R.string.error, Toast.LENGTH_SHORT).show();
|
||||||
|
});
|
||||||
|
GmsClient.disconnectFromService(context, connectionID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}catch(RemoteException e){
|
||||||
|
Log.e(TAG, "onSuccess: ", e);
|
||||||
|
UiUtils.runOnUiThread(()->{
|
||||||
|
progress.dismiss();
|
||||||
|
Toast.makeText(context, R.string.error, Toast.LENGTH_SHORT).show();
|
||||||
|
});
|
||||||
|
GmsClient.disconnectFromService(context, connectionID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception error){
|
||||||
|
Log.e(TAG, "onError() called with: error = ["+error+"]");
|
||||||
|
Toast.makeText(context, R.string.error, Toast.LENGTH_SHORT).show();
|
||||||
|
progress.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,9 @@
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/search_text"
|
android:id="@+id/search_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
android:gravity="center_vertical|start"
|
android:gravity="center_vertical|start"
|
||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
|
@ -39,6 +40,16 @@
|
||||||
android:textAppearance="@style/m3_body_large"
|
android:textAppearance="@style/m3_body_large"
|
||||||
android:text="@string/search_mastodon"/>
|
android:text="@string/search_mastodon"/>
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/search_scan_qr"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:contentDescription="@string/scan_qr_code"
|
||||||
|
android:background="@drawable/bg_round_ripple"
|
||||||
|
android:tint="?colorM3OnSurfaceVariant"
|
||||||
|
android:src="@drawable/ic_qr_code_scanner_24px"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue