Hi I am trying to use the https://github.com/Swati4star/Images-to-PDF ImagesToPDF function from this library. I have added all the classes required in my application.
Now I have used picasso in my application before adding the ImagesToPDF function.
Now after adding it I am getting following error :
java.lang.NoSuchMethodError: No static method with(Landroid/content/Context;)Lcom/squareup/picasso/Picasso; in class Lcom/squareup/picasso/Picasso; or its super classes (declaration of 'com.squareup.picasso.Picasso' appears in /data/app/com.example.onboardingversion2-sJCkixxNOR2KPNLmYYdvpQ==/base.apk!classes2.dex)
Getting error in following function :
/**
* Opens Matisse activity to select Images
*/
private void selectImages() {
Matisse.from(this)
.choose(MimeType.ofImage(), false)
.countable(true)
.capture(true)
.captureStrategy(new CaptureStrategy(true, AUTHORITY_APP))
.maxSelectable(1000)
.imageEngine(new PicassoEngine())
.forResult(INTENT_REQUEST_GET_IMAGES);
}
app gets crashed and gives error. I added application and set Multidex
public class MyApplication extends Application {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(base);
}
}
I also added multidexEnabled true in gradle. Still its throwing the error.
Please help. Thank you.
Picasso in not updated for about 4 years, it has many issues. Maybe You should switch to Glide
The problem is in the line
.imageEngine(new PicassoEngine())
where PicassoEngine() class uses Picasso.with(context).... module which is deprecated. The solution is you have to create a new class, name it NewPicassoEngine() as below;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import com.zhihu.matisse.engine.ImageEngine;
public class NewPicassoEngine implements ImageEngine {
#Override
public void loadThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView, Uri uri) {
Picasso.get().load(uri).placeholder(placeholder)
.resize(resize, resize)
.centerCrop()
.into(imageView);
}
#Override
public void loadGifThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView,
Uri uri) {
loadThumbnail(context, resize, placeholder, imageView, uri);
}
#Override
public void loadImage(Context context, int resizeX, int resizeY, ImageView imageView, Uri uri) {
Picasso.get().load(uri).resize(resizeX, resizeY).priority(Picasso.Priority.HIGH)
.centerInside().into(imageView);
}
#Override
public void loadGifImage(Context context, int resizeX, int resizeY, ImageView imageView, Uri uri) {
loadImage(context, resizeX, resizeY, imageView, uri);
}
#Override
public boolean supportAnimatedGif() {
return false;
}}
and use it as;
private void selectImages() {
Matisse.from(this)
.choose(MimeType.ofImage(), false)
.countable(true)
.capture(true)
.captureStrategy(new CaptureStrategy(true, AUTHORITY_APP))
.maxSelectable(1000)
.imageEngine(new NewPicassoEngine())
.forResult(INTENT_REQUEST_GET_IMAGES);
}
This will solve your problem.
GlideEngine() work for me using latest dependency
fun selectImages(frag: Fragment?, requestCode: Int) {
Matisse.from(frag)
.choose(MimeType.ofImage(), false)
.countable(true)
.capture(true)
.captureStrategy(CaptureStrategy(true, AUTHORITY_APP))
.maxSelectable(1000)
.imageEngine(GlideEngine())
.forResult(requestCode)
}
Related
I want to load the clicked image in the next activity in fullscreen view. I don't know what I am doing wrong. The app is running completely fine but the image is not loading on the next screen. am new to android development and I thought I should start learning by doing a project. I am not understanding what is the problem in my coding.
public class CategoriesAdapter extends RecyclerView.Adapter<CategoriesAdapter.ImageViewHolder> {
private Context mCtx;
private List<Category> imageslist;
public CategoriesAdapter(Context mCtx, List<Category> imageslist) {
this.mCtx = mCtx;
this.imageslist = imageslist;
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(mCtx).inflate(R.layout.recyclerview_images,parent,false);
return new ImageViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ImageViewHolder holder, final int position) {
final Category images=imageslist.get(position);
Glide.with(mCtx).load(images.url).into(holder.imageView);
holder.imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(mCtx, LoadWall.class);
intent.putExtra("url", (Parcelable) imageslist.get(position));
mCtx.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return imageslist.size();
}
class ImageViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
public ImageViewHolder(#NonNull View itemView) {
super(itemView);
imageView=itemView.findViewById(R.id.image_view);
}
}
}
This is the activity where I want to load the image. But its not loading. Please Help
public class LoadWall extends AppCompatActivity {
ImageView imageView;
int myImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_load_wall);
imageView=findViewById(R.id.load_image);
get();
}
private void get(){
if(getIntent().hasExtra("url")){
String image=getIntent().getStringExtra("url");
set(image);
}
else{
Toast.makeText(this,"No Data",Toast.LENGTH_SHORT).show();
}
}
private void set(String image){
Glide.with(this).load(image).into(imageView);
}
}
Here you only need to pass URL as a String. Parcelable is not required.
intent.putExtra("url", imageslist.get(position).getUrl());
Option 1)
In your next activity you are looking for String.
String image=getIntent().getStringExtra("url");
in first activity in onClick() change your code to this.
Intent intent=new Intent(mCtx, LoadWall.class);
intent.putExtra("url", imageslist.get(position));
intent.startActivity(intent);
As i see imageslist.get(position) will return Category so you will need to add your url parameter. Something like this imageslist.get(position).getUrl();
Option 2)
If you want to get Category object then in next activity change to this
Category category = getIntent().getParcelableExtra("url");
Your imagesList contains data of type Category and you send an entry from this list to the next activity. However, the second activity expects a String to be received. It will check to see if it has an extra (it has - but not what you need), then try to retrieve that value as a String which will result in a null String. Having null, Glide will not load anything.
In other words, you made a small mistake on what data you use. When you load the data, you do it correctly by using the url field
final Category images=imageslist.get(position);
Glide.with(mCtx).load(**images.url**).into(holder.imageView);
But when you are passing it to the next activity, you send the entire object
intent.putExtra("url", **(Parcelable) imageslist.get(position)**);
Using the url field as you did in the first case will make your app work properly.
Start your Activity
Intent intent=new Intent(mCtx, LoadWall.class);
intent.putExtra("url", images.url);
mCtx.startActivity(intent);
Regarding this question, I've been trying to get this done via native modules in Android.
I've declared my Module at .../java/com/myproject/multiplecamerastream following the example at React Native ToastModule (functionality here is not important):
public class MultipleCameraStreamModule extends ReactContextBaseJavaModule {
private static final String CAMERA_FRONT = "SHORT";
private static final String CAMERA_BACK = "LONG";
public MultipleCameraStreamModule(ReactApplicationContext reactContext) {
super(reactContext);
}
#Override
public String getName() {
return "MultipleCameraStream";
}
#Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put(CAMERA_FRONT, Toast.LENGTH_SHORT);
constants.put(CAMERA_BACK, Toast.LENGTH_LONG);
return constants;
}
#ReactMethod
public void show(String message, int duration) {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
}
Then, my module packager:
public class MultipleCameraStreamPackage implements ReactPackage {
#Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
#Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new MultipleCameraStreamModule(reactContext));
return modules;
}
}
I've been able to register it and to make it work. However, it only calls to a Toast in Android (no layout involved).
I'd like to set a layout, so when I call <MultipleCameraStream /> in JSX it renders a native Android layout, like the following:
/* .../multiplecamerastream/MultipleCameraStreamLayout.xml */
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView android:id="#+id/multipleCameraText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a TextView"
/>
<Button android:id="#+id/multipleCameraButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button"
/>
</LinearLayout>
How can I make that layout to be invoked from my module scripts (MultipleCameraStreamModule), and how can I make reference to its elements so I can interact with them from the Android module side programatically?
Thank you.
There's explanation in the RN Native UI website itself, but I got lost in it too. :(
But here goes, let me know if there's improvement needed on this:
1) Create a View that will inflate your xml MultipleCameraStreamLayout.xml. Ideally, this CustomView can be used in Android pure code.
public class CustomView extends LinearLayout {
private Context context;
public CustomView(Context context) {
super(context);//ADD THIS
this.context = context;
}
..
public void init() {
//modified here.
inflate(context, R.layout.xxxxxxxxx, this);
...
2) Once set, put this into another class(View Manager) extending SimpleViewManager. Sample:
public class MyCustomReactViewManager extends SimpleViewManager<CustomView> {
public static final String REACT_CLASS = "MyCustomReactViewManager";
#Override
public String getName() {
return REACT_CLASS;
}
#Override
public CustomView createViewInstance(ThemedReactContext context) {
return new CustomView(context); //If your customview has more constructor parameters pass it from here.
}
3) Now add it into the React package createViewManager method, you have created it in MultipleCameraStreamPackage. So, it'll be:
#Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
new MyCustomReactViewManager() //Add here.
);
}
4) You can now use the Android code, by reinstalling it
react-native run-android
5) Expose it in javascript. Create some file CustomView.js
import {requireNativeComponent, ViewPropTypes} from 'react-native';
//
module.exports = requireNativeComponent('MyCustomReactViewManager', null); //Add props are bit different.
6) Start using it into your views. Eg.
import CustomView from './CustomView.js';
...
render() {
return
...
<CustomView style={{height:200, width:200}}/>
...;
}
Hope this helps.
If you need a code sample it's uploaded here.
This question already has answers here:
Extending from two classes
(13 answers)
Closed 7 years ago.
I'm developing an AR Android App using Metaio. I need to show some data when a real object has been tracked. To do this I register a callback, this is the best way that I have found.
Unfortunately to use correctly getFragmentManager(), I need to import Activity properties but i can't extend the class (already extended).
I think that getContext is the right way, but I do not know how to implement it.
This is the callback register in main activity:
metaioSDK.registerCallback(new ProvaTracking());
This is the Tracking class:
package com.metaio.Example;
import android.annotation.TargetApi;
import android.os.Build;
import android.util.Log;
import com.metaio.sdk.jni.IMetaioSDKCallback;
import com.metaio.sdk.jni.TrackingValues;
import com.metaio.sdk.jni.TrackingValuesVector;
public class ProvaTracking extends IMetaioSDKCallback {
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
public void onTrackingEvent(TrackingValuesVector trackingValuesVector) {
super.onTrackingEvent(trackingValuesVector);
for (int i=0; i<trackingValuesVector.size(); i++)
{
final TrackingValues v = trackingValuesVector.get(i);
if (v.isTrackingState())
{
TestFragment trendsFragment = new TestFragment();
getFragmentManager().beginTransaction().add(android.R.id.content, trendsFragment).commit();
Log.d("Alessandro", "Works!!");
}
}
}
}
Add a constructor that takes in Context (Note that you want the Activity context, not the application context)
so you would change your class to be:
public class ProvaTracking extends IMetaioSDKCallback {
private Contect mCtx;
public ProvaTracking(Context context) {
mCtx = context;
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
public void onTrackingEvent(TrackingValuesVector trackingValuesVector) {
super.onTrackingEvent(trackingValuesVector);
for (int i=0; i<trackingValuesVector.size(); i++)
{
final TrackingValues v = trackingValuesVector.get(i);
if (v.isTrackingState())
{
TestFragment trendsFragment = new TestFragment();
if (mCtx instanceof Activity)
((Activity) mCtx).getFragmentManager().beginTransaction().add(android.R.id.content, trendsFragment).commit();
Log.d("Alessandro", "Works!!");
}
}
}
}
then call it with metaioSDK.registerCallback(new ProvaTracking(getContext()));
Please help!
I have a problem with creating a BitmapDrawable in a static context.
I am creating an android app for a student contest and since the MainActivity class starts
to look "dirty" (having lots of code in it) I decided to make MainActivityLayout class that extends the MainActivity. Basicly I moved some methods (the ones for setting layouts) from MainActivity to MainActivityLayout class. The problem is with resize() method where I use BitmapDrawable constructor wich is "bugging me slowly" because needs a reference to resources in order to resize properly the bitmap.
The MainActivity class :
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getLayoutOne();
MainActivityLayouts.setLayoutOne();
getLayoutTwo();
MainActivityLayouts.setLayoutTwo();
}
private void getLayoutOne(){
//here I get the layouts id using findViewById() method
}
private void getLayoutTwo(){
//here I get the layout 2 id using findViewById() method
}
protected static Drawable resize(Drawable image,int xSize,int ySize) {
Bitmap b = ((BitmapDrawable)image).getBitmap();
Bitmap bitmapResized = Bitmap.createScaledBitmap(b, xSize, ySize, false);
return new BitmapDrawable(getResources(),bitmapResized);
}
}
The MainActivityLayout class:
public class MainActivityLayouts extends MainActivity{
public MainActivityLayouts(){
// ...
}
protected final static void setLayoutOne(){
Drawable drawableOne = ImageViewOne.getDrawable();
//here is the problem...cannot make a static refference...
//getResources() from resize method from MainActivity to be more specific
drawableOne = resize(drawableOne,100,100);
ImageViewOne.setImageDrawable(drawableOne);
}
protected final static void setLayoutTwo(){
Drawable drawableTwo = ImageViewTwo.getDrawable();
//here is the problem...cannot make a static refference...
//getResources() from resize method from MainActivity to be more specific
drawableTwo = resize(drawableTwo,200,200);
ImageViewTwo.setImageDrawable(drawableTwo);
}
Is there any solution to my problem? Resizing in another mode or can I avoid creating a BitmapDrawable and still obtain the same effect?
Any critic is highly appreciated :).
I used this code for adding a clock to my app:
<DigitalClock
android:id="#+id/digitalclock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:textSize = "30sp"
/>
The problem is that it shows also seconds..there is a simple and fast way for hide those? I need just hours and minutes in hh:mm format instead of hh:mm:ss! any suggestions? Thanks!
Found the answer here, for anyone else looking for a working answer, here it is:
Clone/copy DigitalClock.java from android source
Change format strings within new CustomDigitalClock
package com.example;
import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.SystemClock;
import android.provider.Settings;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.widget.TextView;
import java.util.Calendar;
/**
* You have to make a clone of the file DigitalClock.java to use in your application, modify in the following manner:-
* private final static String m12 = "h:mm aa";
* private final static String m24 = "k:mm";
*/
public class CustomDigitalClock extends TextView {
Calendar mCalendar;
private final static String m12 = "h:mm aa";
private final static String m24 = "k:mm";
private FormatChangeObserver mFormatChangeObserver;
private Runnable mTicker;
private Handler mHandler;
private boolean mTickerStopped = false;
String mFormat;
public CustomDigitalClock(Context context) {
super(context);
initClock(context);
}
public CustomDigitalClock(Context context, AttributeSet attrs) {
super(context, attrs);
initClock(context);
}
private void initClock(Context context) {
Resources r = context.getResources();
if (mCalendar == null) {
mCalendar = Calendar.getInstance();
}
mFormatChangeObserver = new FormatChangeObserver();
getContext().getContentResolver().registerContentObserver(
Settings.System.CONTENT_URI, true, mFormatChangeObserver);
setFormat();
}
#Override
protected void onAttachedToWindow() {
mTickerStopped = false;
super.onAttachedToWindow();
mHandler = new Handler();
/**
* requests a tick on the next hard-second boundary
*/
mTicker = new Runnable() {
public void run() {
if (mTickerStopped) return;
mCalendar.setTimeInMillis(System.currentTimeMillis());
setText(DateFormat.format(mFormat, mCalendar));
invalidate();
long now = SystemClock.uptimeMillis();
long next = now + (1000 - now % 1000);
mHandler.postAtTime(mTicker, next);
}
};
mTicker.run();
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mTickerStopped = true;
}
/**
* Pulls 12/24 mode from system settings
*/
private boolean get24HourMode() {
return android.text.format.DateFormat.is24HourFormat(getContext());
}
private void setFormat() {
if (get24HourMode()) {
mFormat = m24;
} else {
mFormat = m12;
}
}
private class FormatChangeObserver extends ContentObserver {
public FormatChangeObserver() {
super(new Handler());
}
#Override
public void onChange(boolean selfChange) {
setFormat();
}
}
}
Reference custom class within in layout xml
<com.example.CustomDigitalClock
android:id="#+id/fragment_clock_digital"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DigitalClock" />
Load CustomDigitalClock within activity/fragment
CustomDigitalClock dc = (CustomDigitalClock)
mFragmentView.findViewById(R.id.fragment_clock_digital);
The DigitalClock Javadoc states:
Class Overview
Like AnalogClock, but digital. Shows seconds. FIXME: implement
separate views for hours/minutes/seconds, so proportional fonts don't
shake rendering
Judging by the FIXME, the ability to hide portions of DigitalClock might be implemented eventually. I didn't find anything currently in the Javadoc or source code that would do what you want it to.
Unless you want to write your own class that extends DigitalClock (or your own clock implementation altogether), you could just cover the seconds portion of the DigitalClock with another element if it would serve your purpose.