Converting a video to a GIF - java

I am trying to make my app to accept videos from the phone's library to be uploaded and converted into GIF format. My code is giving out this build error though:-
error: <anonymous com.example.bim.Video2gif$2> is not abstract and does not override abstract method onReschedule(String,ErrorInfo) in UploadCallback
and also this warning on my onActivityResult method:-
Overriding method should call super.onActivityResult
The code is as below : -
public class Video2gif extends AppCompatActivity {
private Button uploadBtn;
private ProgressBar progressBar;
private int SELECT_VIDEO = 2;
private ImageView img1;
private DownloadManager downloadManager;
private Button download_btn;
private String gifUrl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video2gif);
MediaManager.init(this);
progressBar = findViewById(R.id.progress_bar);
MediaManager.init(this);
img1 = findViewById(R.id.img1);
uploadBtn = findViewById(R.id.uploadBtn);
uploadBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pickVideoFromGallery();
}
private void pickVideoFromGallery() {
Intent GalleryIntent = new Intent();
GalleryIntent.setType("video/*");
GalleryIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(GalleryIntent,
"select video"), SELECT_VIDEO);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
if (requestCode == SELECT_VIDEO && resultCode == RESULT_OK) {
Uri selectedVideo = data.getData();
MediaManager.get()
.upload(selectedVideo)
.unsigned("myid")
.option("resource_type", "video")
.callback(new UploadCallback(){
#Override
public void onStart(String requestId) {
progressBar.setVisibility(View.VISIBLE);
Toast.makeText(Video2gif.this,
"Upload Started...", Toast.LENGTH_SHORT).show();
}
public void onProgress() {
}
public void onSuccess(String requestId, Map resultData) {
Toast.makeText(Video2gif.this, "Uploaded Succesfully",
Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
uploadBtn.setVisibility(View.INVISIBLE);
String publicId = resultData.get("public_id").toString();
gifUrl = MediaManager.get().url().resourceType("video")
.transformation(new Transformation().videoSampling("25")
.delay("200").height(200).effect("loop:10").crop("scale"))
.resourceType("video").generate(publicId+".gif");
Glide.with(getApplicationContext()).asGif().load(gifUrl).into(img1);
download_btn.setVisibility(View.VISIBLE);
}
public void onError(String requestId, ErrorInfo error) {
Toast.makeText(Video2gif.this,
"Upload Error", Toast.LENGTH_SHORT).show();
Log.v("ERROR!!", error.getDescription());
}
});
}
}
}
I am also using Cloudinary to help process the video to GIF. Any help would be appreciated, many thanks!

When you’re using interfaces in android you need to include in your activity/fragment (override) the callback methods that they include. Also overriding some of the system methods requires you calling their super which means that many activities might be listening for the same callback when they inherit from one another. By adding the super in those callbacks you allow the result to travel through all of them. So in the case of the OnActivityResult just add the following line in your method:
super.onActivityResult(requestCode, resultCode, data);
For onReschedule you can let Android Studio generate that for you. Just go to Code->Generate-Override Methods and select the onReschedule

Related

Problems with Simple OCR app using Firebase ML Kit

I am new to Android development but I have been learning on the way as I create my first OCR app using Firebase in Java. I essentially followed a youtube video to create the app but I had the following problems that I needed help with:
1) If I take the picture in landscape, the app can detect the text. However, when I take the picture in portrait, the captured image is rotated 90 degrees and the app cannot detect the text in the image. Whats the simplest way for me to resolve this?
2) Currently I take the picture with the phone's camera and this image is displayed in the app. I click my detect text button and the text appears. But I would like to see some bounding boxes on the images that shows what Firebase ML kit is seeing.
3) Also when I take a simple screenshot of a smartphone pin screen, the app can detect most of the numbers, but it always seems to miss one. I assume this is because I am using the local on phone version of Firebase ML kit, but is it possible to make it more accurate without running on cloud. I am currently using:
implementation 'com.google.firebase:firebase-core:15.0.2'
implementation 'com.google.firebase:firebase-ml-vision:16.0.0'
Thanks
The following is the code in my main activity (It pretty much the same thing on Firebase):
'''public class MainActivity extends AppCompatActivity {
Button captureImageBtn, detectTextBtn;
ImageView imageView;
TextView textView, outputText;
Bitmap imageBitmap;
static final int REQUEST_IMAGE_CAPTURE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
actionBar.setTitle("Image Reader");
actionBar.setDisplayUseLogoEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
captureImageBtn = findViewById(R.id.capture_image_btn);
detectTextBtn = findViewById(R.id.detect_text_image_btn);
imageView = findViewById(R.id.image_view);
textView = findViewById(R.id.text_display);
outputText = findViewById(R.id.outputText);
outputText.setVisibility(View.INVISIBLE);
imageView.setImageResource(R.mipmap.mi2_foreground);
captureImageBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dispatchTakePictureIntent();
textView.setText("");
}
});
detectTextBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
detectTextFromImage();
}
});
}
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
imageBitmap = (Bitmap) extras.get("data");
imageView.setImageBitmap(imageBitmap);
}
}
private void detectTextFromImage()
{
FirebaseVisionImage firebaseVisionImage = FirebaseVisionImage.fromBitmap(imageBitmap);
FirebaseVisionTextDetector firebaseVisionTextDetector = FirebaseVision.getInstance().getVisionTextDetector();
firebaseVisionTextDetector.detectInImage(firebaseVisionImage).addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() {
#Override
public void onSuccess(FirebaseVisionText firebaseVisionText) {
displayTextFromImage(firebaseVisionText);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void displayTextFromImage(FirebaseVisionText firebaseVisionText) {
List<FirebaseVisionText.Block> blockList = firebaseVisionText.getBlocks();
if (blockList.size() == 0) {
Toast.makeText(MainActivity.this, "No Text Found in Image.", Toast.LENGTH_SHORT).show();
} else {
int i = 0;
String complete ="";
for (FirebaseVisionText.Block block : firebaseVisionText.getBlocks()) {
String text = block.getText();
complete = complete.concat(text+" ");
outputText.setVisibility(View.VISIBLE);
outputText.setText(complete);
}
}
}

Android Studio : How to keep variables from one java file to another

I am developping an application which convert scanned data (barcode) to GoogleSheet data, and I am trying to transfer the barcode number (from Page2.java) into another java file (ListItem.java)
I saw that a usual way to do it is to create intents. So I did it.
But the toast I put in ListItem.java gives me "null" instead of the scanned number (for example 0123456789012)
Please, can you tell me where am I wrong ? Thank you so much !
1st Code (Page2.java , where I get "scanContent2", the variable I need) :
public class Page2 extends Activity implements OnClickListener {
#SuppressLint("ClickableViewAccessibility")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.page2);
scanBtn2 = (Button) findViewById(R.id.scan_button2);
scanBtn2.setOnClickListener(this);
}
public Button scanBtn2;
public String scanContent2;
#Override
public void onClick(View v) {
if (v.getId() == R.id.scan_button2) {
IntentIntegrator scanIntegrator = new IntentIntegrator(this);
scanIntegrator.initiateScan();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if (scanningResult != null) {
scanContent2 = scanningResult.getContents();
Intent intenta = new Intent(getApplicationContext(),ListItem.class);
intenta.putExtra("theScanContent2", scanContent2);
startActivity(intenta);
} else {
Toast toast = Toast.makeText(getApplicationContext(),
"No scan data received!", Toast.LENGTH_SHORT);
toast.show();
}
}
}
2nd code (ListItem.java, where I get "null" on the toast) :
public class ListItem extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_item);
String scanContent2 = getIntent().getStringExtra("theScanContent");
Toast toast = Toast.makeText(getApplicationContext(),
"BarCode number: " + scanContent2, Toast.LENGTH_SHORT);
toast.show();
}
}
In the Listitem.java in the following line,
String scanContent2 = getIntent().getStringExtra("theScanContent");
You are trying to get String with key theScanContent, while you are putting scanContent2 with key theScanContent2 in Page2.java in line
intent.putExtra("theScanContent2", scanContent2);
Make sure the keys are same for the Intent while putting the data in intent and accessing the data from the intent to avoid getting null Results.

how to get file path in java/android , (getPath , alternatives written methods method causes app to crash)

Please would you show a trusted way to get file path , that works across APIs,
// sorry for the long question.
i am trying to make very simple app, it takes a video from the device and then compress it, for compression i use (fishwjy VideoCompressor )library ,as the class(VideoCompressingTask) from the library requires the path of the video and a destination path in its constructor, i try to pass the video path using (getPath() method it make the app crash with illegal argument exception, i then used a function from another question here on the site to get the path it does the same , i finally tried a function from the (Util) class from the library project on github (Util.getFilePath()), it works very fine with the lower APIs (23) ,but with the higher APIs (29,28) it crashes with the same exception, i tried to let it use (getPath()) at higher APIs , use getAbsulotePath() instead it also crashes, what i am missing?? what i am doing wrong???, any help would be really appreciated, thanks in advance.
public class MainActivity extends AppCompatActivity {
Uri videoUri;
static final int GET_VIDEO_REQUEST=64;
private String outputDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
String videoUriPath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getVideoFromPhone();
}
void getVideoFromPhone(){
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,GET_VIDEO_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==GET_VIDEO_REQUEST && resultCode==RESULT_OK){
videoUri=data.getData();
Toast.makeText(this, "Video added", Toast.LENGTH_SHORT).show();
compressVideoForUpload();
}
}
void compressVideoForUpload(){
try{
videoUriPath=Util.getFilePath(this,videoUri);
String distinationDirectory=outputDir+File.separator+"out"+".mp4";
VideoCompressTask task =VideoCompress.compressVideoLow(videoUri.getPath(), distinationDirectory, new VideoCompress.CompressListener() {
#Override
public void onStart() {
Toast.makeText(MainActivity.this, "Compression started", Toast.LENGTH_LONG).show();
}
#Override
public void onSuccess() {
Toast.makeText(MainActivity.this, " video Compressed : ", Toast.LENGTH_LONG).show();
}
#Override
public void onFail() {
Toast.makeText(MainActivity.this, "Compression fail", Toast.LENGTH_LONG).show();
}
#Override
public void onProgress(float percent) {
Toast.makeText(MainActivity.this, "Compressing :"+percent, Toast.LENGTH_LONG).show();
}
});
}catch(Exception e){
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}

How to tell zxing to only read my QR code and ignore all others?

So I have the zxing barcode scanner running and in my main activity I have the onResultActivity function telling my activity to push to a new activity with a result from the scanner.
The problem is that my scanner just scans any old QR code regardless of what it is.
I need the scanner to only accept my QR code to pass a successful result and ignore all other QR codes (this should pass a toaster to say "incorrect QR code, try again").
Here's what I currently have:
MainActivity
...
static final int SCAN_RESULT = 1; // The request code
...
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check which request we're responding to
if (requestCode == SCAN_RESULT) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// Action to take if result successful
Intent intent = new Intent(this, ResultActivity.class);
startActivity(intent);
}
}
}
ScannerActivity
...
public class ScanBarcodeActivity extends AppCompatActivity {
Button mBtnClose;
private CaptureManager capture;
private DecoratedBarcodeView barcodeScannerView;
private ViewfinderView viewfinderView;
private void initViews() {
mBtnClose = findViewById(R.id.barcode_header_close);
barcodeScannerView = findViewById(R.id.zxing_barcode_scanner);
viewfinderView = findViewById(R.id.zxing_viewfinder_view);
}
private void initListener() {
mBtnClose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barcode);
initViews();
initListener();
capture = new CaptureManager(this, barcodeScannerView);
capture.initializeFromIntent(getIntent(), savedInstanceState);
capture.decode();
changeMaskColor(null);
}
#Override
protected void onResume() {
super.onResume();
capture.onResume();
}
#Override
protected void onPause() {
super.onPause();
capture.onPause();
}
#Override
protected void onDestroy() {
super.onDestroy();
capture.onDestroy();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
capture.onSaveInstanceState(outState);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
}
public void changeMaskColor(View view) {
}
}
EDIT: I've tried this but it's obviously not working, this is basically what I'm looking to get working. If the SCAN_RESULT = the QR_CODE then go to next activity, else pop a message saying try again.
static final int SCAN_RESULT = 1; // The request code
String QR_CODE = "EC0111-1234567899";
int RESULT = Integer.parseInt(QR_CODE);
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check which request we're responding to
if (requestCode == SCAN_RESULT) {
// Make sure the request was successful
if (SCAN_RESULT == RESULT) {
Intent intent = new Intent(this, ResultActivity.class);
startActivity(intent);
} else {
Toast.makeText(this, "Incorrect QR code, please try again", Toast.LENGTH_LONG).show();
}
}
}
There are some approaches you can try.
Encrypt information: You can encrypt information coded in QR so that other can't read it as well as you can identify your own QR. To do so
Encrypt information with a key
Generate QR with encrypted information
Read and try to decrypt information. If you can decrypt than it's your QR.
Develop your own QR: It may be costly for you but it is a wonderful idea to generate your own styled QR like facebook messenger , snapchat and whatsapp etc. In that case you can't use standard ZXING library. You have to customised ZXING library or develop a new one.
Add tag to information: You can add a unique tag(text) in your QR information. By which you can identify your QR code.

How to stop a VpnService that was called with prepare() and startService()?

I't trying to implement a local VpnService to have my app do some tasks, but I'm a little confused as to how to stop it one it started. The VpnService class and client activity are based on this repo:
https://github.com/hexene/LocalVPN
The caller activity is basically this:
public class MainActivity extends AppCompatActivity {
private static final int VPN_REQUEST_CODE = 0x0F;
private boolean waitingForVPNStart;
private BroadcastReceiver vpnStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (LocalVPNService.BROADCAST_VPN_STATE.equals(intent.getAction()))
if (intent.getBooleanExtra("running", false))
waitingForVPNStart = false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button vpnButton = (Button)findViewById(R.id.vpn);
vpnButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startVPN();
}
});
final Button vpnStopButton = (Button)findViewById(R.id.stopVpnButton);
vpnStopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
stopVPN();
}
});
waitingForVPNStart = false;
LocalBroadcastManager.getInstance(this).registerReceiver(vpnStateReceiver,
new IntentFilter(LocalVPNService.BROADCAST_VPN_STATE));
}
private void startVPN() {
Intent vpnIntent = VpnService.prepare(this);
if (vpnIntent != null)
startActivityForResult(vpnIntent, VPN_REQUEST_CODE); //Prepare to establish a VPN connection. This method returns null if the VPN application is already prepared or if the user has previously consented to the VPN application. Otherwise, it returns an Intent to a system activity.
else
onActivityResult(VPN_REQUEST_CODE, RESULT_OK, null);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == VPN_REQUEST_CODE && resultCode == RESULT_OK) {
waitingForVPNStart = true;
startService(new Intent(this, LocalVPNService.class));
enableButton(false);
}
}
What confuses me is: how would I call the service's onDestroy() method or something similar if I don't keep an instance if it in my main activity?
I looked at this answer and this and seen implementations of stopService, but I'm not sure how to handle the Intent, because it's not only used to call startService() but also involved in calling VpnService.prepare().
Edit: I tried
stopService(new Intent(this, LocalVPNService.class)); but it doesn't stop it. I tried stopService(vpnIntent); and IT WORKS, but makes my app crash/close.
In your LocalVPNService class create a new broadcast:
private BroadcastReceiver stopBr = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if ("stop_kill".equals(intent.getAction())) {
stopself();
}
}
};
and in the onCreate method add this:
LocalBroadcastManager lbm =
LocalBroadcastManager.getInstance(this);
lbm.registerReceiver(stopBr, new IntentFilter("stop_kill"));
in your activity:
Intent intent = new Intent("stop_kill");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

Categories

Resources