I have the following Java code which downloads an image from an URL.
I can see the image downloaded in the folder, but the image does not appear in gallery. Only if I restart phone, Samsung S7 with android 7, I can see images in gallery. What can I do to have the images in gallery in real time after I downloaded them?
public class DetailsImgActivity extends AppCompatActivity {
private static final String TAG = "DetailsImgActivity";
private ImageView imageViewPoze;
private Button buttonDownload;
private static final int PERMISSION_REQUEST_CODE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details_img);
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
// image url stored in imageID
final String imageId = getIntent().getStringExtra("ImageId");
imageViewPoze = findViewById(R.id.imageViewPozeC);
Picasso.get().load(imageId).into(imageViewPoze);
buttonDownload = findViewById(R.id.btn_Download_Img);
buttonDownload.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
downloadFile(imageId);
}
});
}
private void downloadFile(String url) {
Retrofit.Builder builder = new Retrofit.Builder().baseUrl("https://firebasestorage.blabla.com/");
Retrofit retrofit = builder.build();
FileDownloadClient fileDownloadClient = retrofit.create(FileDownloadClient.class);
Call<ResponseBody> call = fileDownloadClient.downloadFile(url);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, final Response<ResponseBody> response) {
// if (response.isSuccess()) {
Log.d(TAG, "server contacted and has file");
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
boolean writtenToDisk = writeResponseBodyToDisk(response.body());
return null;
}
}.execute();
//after the image has been downloaded -refresh gallery
**Toast.makeText(getApplicationContext(), "File downloaded with success!", Toast.LENGTH_LONG).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File("file://"+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
else
{
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}**
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "error");
}
});
}
private boolean writeResponseBodyToDisk(ResponseBody body) {
try {
String folder_main = Constants.dirName;
File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), folder_main);
if (!f.exists()) {
f.mkdirs();
}
// todo change the file location/name according to your needs
File futureStudioIconFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM+"/"+ Constants.dirName)
+ File.separator + UUID.randomUUID()+".jpg");
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
inputStream = body.byteStream();
outputStream = new FileOutputStream(futureStudioIconFile);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
Log.d(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
}
outputStream.flush();
return true;
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
}
I used the follwing code, but If I don't reboot phone, I can't see the picture in gallery.
**Toast.makeText(getApplicationContext(), "File downloaded with success!", Toast.LENGTH_LONG).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File("file://"+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
else
{
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}**
Related
I am trying to make an app that generates QR Code.
It works well but there is no text when it is saved. People would be confused after saving a few codes because of no name on it.
If people generate QR code with "Wikipedia.com", I want it saved with the name of "Wikipedia.com" at the photo gallery. What should I do?
MainActivity
public class MainActivity extends AppCompatActivity {
private String inputValue;
private String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + "/Camera/";
private Bitmap bitmap;
private QRGEncoder qrgEncoder;
private ImageView qrImage;
private EditText edtValue;
private AppCompatActivity activity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
qrImage = findViewById(R.id.qr_image);
edtValue = findViewById(R.id.edt_value);
activity = this;
/**Barcode Generator*/
findViewById(R.id.generate_barcode).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
inputValue = edtValue.getText().toString().trim();
if (inputValue.length() > 0) {
WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point point = new Point();
display.getSize(point);
int width = point.x;
int height = point.y;
int smallerDimension = width < height ? width : height;
smallerDimension = smallerDimension * 3 / 4;
qrgEncoder = new QRGEncoder(
inputValue, null,
QRGContents.Type.TEXT,
smallerDimension);
qrgEncoder.setColorBlack(Color.BLACK);
qrgEncoder.setColorWhite(Color.WHITE);
try {
bitmap = qrgEncoder.getBitmap();
qrImage.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
} else {
edtValue.setError(getResources().getString(R.string.value_required));
}
}
});
/**Barcode save*/
findViewById(R.id.save_barcode).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
try {
boolean save = new QRGSaver().save(savePath, edtValue.getText().toString().trim(), bitmap, QRGContents.ImageType.IMAGE_JPEG);
String result = save ? "Image Saved. Check your gallery." : "Image Not Saved";
Toast.makeText(activity, result, Toast.LENGTH_LONG).show();
edtValue.setText(null);
} catch (Exception e) {
e.printStackTrace();
}
} else {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
}
}
});
}
}
I tried your code and it works fine. The generated QR codes are saved as you want: QR-code-text.jpg
The only problem is the QRGSaver().save(...) is not compatible with Android10+.
Try to extend your onClickListener of save_barcode button as follows:
/*Barcode save*/
findViewById(R.id.save_barcode).setOnClickListener(v -> {
String filename = edtValue.getText().toString().trim();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
try {
ContentResolver resolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, filename + ".jpg");
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM);
Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
OutputStream fos = resolver.openOutputStream(Objects.requireNonNull(imageUri));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
Objects.requireNonNull(fos).close();
Toast.makeText(activity, "Image Saved. Check your gallery.", Toast.LENGTH_LONG).show();
edtValue.setText(null);
} catch (IOException e) {
e.printStackTrace();
}
} else {
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
try {
boolean save = new QRGSaver().save(savePath, filename, bitmap, QRGContents.ImageType.IMAGE_JPEG);
String result = save ? "Image Saved. Check your gallery." : "Image Not Saved";
Toast.makeText(activity, result, Toast.LENGTH_LONG).show();
edtValue.setText(null);
} catch (Exception e) {
e.printStackTrace();
}
} else {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
}
}
});
I'm setting download manager to download PDF file for server URL.
file is download completely but Broadcast Receiver doesn't call to open file .
I use AsyncTask and doInBackground class for downloading and set permission.INTERNET,permission.WRITE_EXTERNAL_STORAGE,permission.WRITE_INTERNAL_STORAGE ,permission.READ_EXTERNAL_STORAGE in manifest.
i checked my directory in real device and PDF file is completely download without any crash .
in OnCreate
registerReceiver(onComplete, filter);
in onClick Button
downloadPdf(v);
} else {
requestStoragePermission(v);
}
and also set onDestroy
public void onDestroy() {
super.onDestroy();
unregisterReceiver(onComplete);
}
and downloading file
#Override
protected Void doInBackground(String... strings) {
String fileUrl = strings[0];
String fileName = strings[1];
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(extStorageDirectory, DIRECTORY_PDF_NAME);
if (!folder.exists()) {
folder.mkdir();
}
// File pdfFile = new File(folder, fileName);
file_download(fileUrl);
return null;
}
public void file_download(String fileUrl) {
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + DIRECTORY_PDF_NAME + "/" + "au.pdf");
if (file.exists()) {
Intent target = new Intent(Intent.ACTION_VIEW);
target.setDataAndType(Uri.fromFile(file), "application/pdf");
target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Intent intent = Intent.createChooser(target, "انتخاب برنامه");
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(LoginActivity.this, "عدم موفقیت در نمایش فایل", Toast.LENGTH_SHORT).show();
}
} else {
mgr = (DownloadManager) LoginActivity.this.getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadUri = Uri.parse(fileUrl);
DownloadManager.Request request = new DownloadManager.Request(
downloadUri);
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("راهنمای ثبت نام")
.setDescription(" در حال دانلود..." + "فایل راهنمای ثبت نام")
.setDestinationInExternalPublicDir("/" + DIRECTORY_PDF_NAME + "/", "au.pdf");
try {
refid = mgr.enqueue(request);
Log.d(TAG, "Checking download status for id: " + refid);
} catch (ActivityNotFoundException e) {
Toast.makeText(LoginActivity.this, "عدم موفقیت در دانلود فایل", Toast.LENGTH_SHORT).show();
}
}
}
}
and at the end
public void onReceive(Context ctxt, Intent intent) {
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + DIRECTORY_PDF_NAME + "/" + "au.pdf");
Intent target = new Intent(Intent.ACTION_VIEW);
target.setDataAndType(Uri.fromFile(file), "application/pdf");
target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Intent intentPdf = Intent.createChooser(target, "انتخاب برنامه");
try {
startActivity(intentPdf);
} catch (ActivityNotFoundException e) {
}
}
I solve this problem with this solution
I create a a PDF Class and transfer my downloading code in it.
public Pdf(Context context, String url, String fileName) {
this.context = context;
this.url = url;
this.fileName = fileName;
init();
}
private void init() {
downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
context.registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
Download_Uri = Uri.parse(url);
}
public void checkAndDownload() {
if (isStoragePermissionGranted()) {
if (isExistPdfFile()) {
openGeneratedPDF();
}else{
downloadPdf();
}
}
}
public void permissionGranted(int[] grantResults) {
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
downloadPdf();
}
}
private boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (context.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
} else {
return true;
}
}
public BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
isCompeleted = true;
openGeneratedPDF();
}
};
private boolean isExistPdfFile() {
File target = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
file = new File(target, DIRECTORY_PDF_NAME + "/" + fileName + ".pdf");
if (file.exists()) {
return true;
}else{
return false;
}
}
private void openGeneratedPDF() {
if (isExistPdfFile()) {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", file);
Log.e("uri is",uri.toString());
intent.setDataAndType(uri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(context, "برنامهای برای نمایش فایل PDF وجود ندارد", Toast.LENGTH_LONG).show();
}
}else {
Toast.makeText(context,"فایل مورد نظر یافت نشد",Toast.LENGTH_LONG).show();
}
}
private void downloadPdf() {
DownloadManager.Request request = new DownloadManager.Request(Download_Uri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setAllowedOverRoaming(true);
request.setVisibleInDownloadsUi(true);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, Constant.DIRECTORY_PDF_NAME + "/" + fileName + ".pdf");
refid = downloadManager.enqueue(request);
Log.e("OUT", "" + refid);
}
public boolean getIsCompeleted() {
return isCompeleted;
}
and call it in my requirement Activity ,also i use file provider such as
Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", file);
As a preface, I am familiar with coding (2 years in highschool) but am a complete novice when it comes to Android Studio (and Java, in general). I've been searching for solutions for my problem, but due to my inexperience I have no idea how to implement the solutions to my project.
In short, I need to download a pdf from some external URL, store it into external storage, and display it using some pdf-viewer application. I've been getting error:
...
android.os.FileUriExposedException: file:///storage/emulated/0/pdf/Read.pdf exposed beyond app through Intent.getData()
...
I've been using this source on using an intent to open a pdf-viewer and this source on "File Provider" as references.
Below is what I have so far:
Fire (with a clickable TextView that should download and display the pdf)
public class Fire extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fire);
final TextView testButton = findViewById(R.id.testPDF);
// File file = getFilesDir();
testButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Fire.this, pdfView.class);
startActivity(intent);
}
});
pdfView activity
public class pdfView extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_view);
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(extStorageDirectory, "pdf");
folder.mkdir();
File file = new File(folder, "Read.pdf");
try {
file.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
Downloader.DownloadFile(__PDF_URL___, file);
showPdf();
}
public void showPdf()
{
File file = new File(Environment.getExternalStorageDirectory()+"/pdf/Read.pdf");
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
}
Downloader class
public class Downloader {
public static void DownloadFile(String fileURL, File directory) {
try {
FileOutputStream f = new FileOutputStream(directory);
URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
e.printStackTrace();
}
}
From my research, it seems that my problem stems from my usage of URI instead of a "File provider." Also, it seems the solution that implements a "File Provider" uses Context in some form or another, and I'm confused on what the purpose of context is and how to implement it.
If you do not have answers that is fine. Any information on how to figure this out or even understand the concept is good enough for me.
If your targetSdkVersion >= 24, then we have to use FileProvider class to give access to the particular file or folder to make them accessible for other apps.
1) First Add a FileProvider tag in AndroidManifest.xml under tag as below:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...
<application
...
<provider
android:name=".GenericFileProvider"
android:authorities="${applicationId}.my.package.name.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
</application>
</manifest>
2) Then create a provider_paths.xml file in res/xml folder. Folder may be needed to created if it doesn't exist.
<paths>
<external-path name="external_files" path="."/>
</paths>
3) Now create PdfDownload.java class file and paste below code:
public class PdfDownload extends Activity {
TextView tv_loading;
Context context;
int downloadedSize = 0, totalsize;
float per = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
isStoragePermissionGranted();
super.onCreate(savedInstanceState);
tv_loading = new TextView(this);
tv_loading.setGravity(Gravity.CENTER);
tv_loading.setTypeface(null, Typeface.BOLD);
setContentView(tv_loading);
downloadAndOpenPDF();
}
public static String getLastBitFromUrl(final String url) {
return url.replaceFirst(".*/([^/?]+).*", "$1");
}
void downloadAndOpenPDF() {
final String download_file_url = getIntent().getStringExtra("url");
new Thread(new Runnable() {
public void run() {
Uri path = Uri.fromFile(downloadFile(download_file_url));
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri uri = FileProvider.getUriForFile(PdfDownload.this, BuildConfig.APPLICATION_ID, downloadFile(download_file_url));
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
finish();
} catch (ActivityNotFoundException e) {
tv_loading
.setError("PDF Reader application is not installed in your device");
}
}
}).start();
}
File downloadFile(String dwnload_file_path) {
File file = null;
try {
URL url = new URL(dwnload_file_path);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.connect();
String test = getLastBitFromUrl(dwnload_file_path);
String dest_file_path = test.replace("%20", "_");
// set the path where we want to save the file
File SDCardRoot = Environment.getExternalStorageDirectory();
// // create a new file, to save the downloaded file
file = new File(SDCardRoot, dest_file_path);
if (file.exists()) {
return file;
}
FileOutputStream fileOutput = new FileOutputStream(file);
// Stream used for reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
// this is the total size of the file which we are
// downloading
totalsize = urlConnection.getContentLength();
setText("Starting PDF download...");
// create a buffer...
byte[] buffer = new byte[1024 * 1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
per = ((float) downloadedSize / totalsize) * 100;
if ((totalsize / 1024) <= 1024) {
setText("Total PDF File size : " + (totalsize / 1024)
+ " KB\n\nDownloading PDF " + (int) per + "% complete");
} else {
setText("Total PDF File size : " + (totalsize / 1024) / 1024
+ " MB\n\nDownloading PDF " + (int) per + "% complete");
}
// setText("configuring your book pleease wait a moment");
}
// close the output stream when complete //
fileOutput.close();
// setText("Download Complete. Open PDF Application installed in the device.");
setText("configuaration is completed now your book is ready to read");
} catch (final MalformedURLException e) {
setTextError("Some error occured. Press back and try again.",
Color.RED);
} catch (final IOException e) {
setTextError("Some error occured. Press back and try again.",
Color.RED);
} catch (final Exception e) {
setTextError(
"Failed to download image. Please check your internet connection.",
Color.RED);
}
return file;
}
void setTextError(final String message, final int color) {
runOnUiThread(new Runnable() {
public void run() {
tv_loading.setTextColor(color);
tv_loading.setText(message);
}
});
}
void setText(final String txt) {
runOnUiThread(new Runnable() {
public void run() {
tv_loading.setText(txt);
}
});
}
private static final String TAG = "MyActivity";
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission is granted");
return true;
} else {
Log.v(TAG, "Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
} else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG, "Permission is granted");
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission: " + permissions[0] + "was " + grantResults[0]);
}
}
}
Please pardon any bad English as this is my first time posting question on stackoverflow.
I would like to create a OCR Android Application using tesseract OCR engine and faced the following error, I have tried to search around but however did not find any solution, would appreciate your help. Thanks.
Codes I am trying:
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.init(Environment.getExternalStorageDirectory().toString()+"/", `"eng");`
I have already created a tessdata folder in my device root with the eng.traineddata file inside, but I was prompted the following error when I access the function.
Could not initialize Tesseract API with language=eng!
I am using Android 6.0.1, API 23
Would appreciate any help! Thanks in advance~
Try this code out . It allows you to take a picture and displays the text .There are minor bugs in this code .Try this code on letters typed in notepad
Ignore the various files being placed in the tessdata folder . I am trying to read maths equation hence i need those . I have commented out the other files, it shouldn't bother you. If you are willing to try , try Mobile Vision API.
Hope this helps :)
public class MainActivity extends AppCompatActivity {
String imgPath;
Bitmap imgBitmap;
Uri imgUri;
InputStream trainDataInputStream;
OutputStream trainDataOutputStream;
AssetManager assetManager;
String externalDataPath;
TextView t;
String[] fileToBeCopied = {"eng.cube.bigrams", "eng.cube.fold", "eng.cube.lm", "eng.cube.nn", "eng.cube.params", "eng.cube.size", "eng.cube.word-freq", "eng.tesseract_cube.nn", "eng.traineddata","equ.traineddata"};
ProgressDialog pDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t = (TextView) findViewById(R.id.text);
new CopyFile().execute();
//placeFileFromAssetsToExternalStorage();
takePicture();
}
class CopyFile extends AsyncTask {
#Override
protected void onPreExecute() {
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Fetching image...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Object doInBackground(Object[] objects) {
//placeFileFromAssetsToExternalStorage(fileToBeCopied[0]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[1]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[2]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[3]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[4]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[5]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[6]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[7]);
placeFileFromAssetsToExternalStorage(fileToBeCopied[8]);
//placeFileFromAssetsToExternalStorage(fileToBeCopied[9]);
return null;
}
#Override
protected void onPostExecute(Object o) {
pDialog.dismiss();
}
}
private void takePicture() {
File photoFile = null;
Intent iPicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (iPicture.resolveActivity(getPackageManager()) != null) {
try {
photoFile = createImageFile();
} catch (Exception e) {
e.printStackTrace();
}
//if photo file is created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(getApplicationContext(), "com.scorpio.fileprovider", photoFile);
System.out.println(imgPath);
iPicture.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(iPicture, 1);
}
}
}
private File createImageFile() {
File imgFile = null;
String fileStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File storageDir = Environment.getExternalStorageDirectory();
try {
imgFile = File.createTempFile(fileStamp, ".jpeg", storageDir);
} catch (IOException e) {
e.printStackTrace();
}
imgPath = imgFile.getAbsolutePath();
return imgFile;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK) {
galleryAddPic();
}
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(imgPath);
System.out.println("Image path ->" + imgPath);
Uri contentUri = Uri.fromFile(f);
imgUri = contentUri;
System.out.println("Image uri " + imgUri);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
ocrImage();
}
public void ocrImage() {
try {
//getting image for ocr
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
imgBitmap = BitmapFactory.decodeFile(imgPath, options);
} catch (Exception e) {
e.printStackTrace();
}
ExifInterface exif = null;
try {
exif = new ExifInterface(imgPath);
} catch (IOException e) {
e.printStackTrace();
}
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0) {
int w = imgBitmap.getWidth();
int h = imgBitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap & convert to ARGB_8888, required by tess
imgBitmap = Bitmap.createBitmap(imgBitmap, 0, 0, w, h, mtx, false);
}
imgBitmap = imgBitmap.copy(Bitmap.Config.ARGB_8888, true);
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.init(externalDataPath, "eng");
baseApi.setImage(imgBitmap);
String ocrResult = baseApi.getUTF8Text();
System.out.println(ocrResult);
baseApi.end();
t.setText(ocrResult);
}
public void placeFileFromAssetsToExternalStorage(String filename) {
System.out.println("Running DataRunnable class ");
assetManager = getResources().getAssets();
externalDataPath = Environment.getExternalStorageDirectory() + "/tessdata";
System.out.println("external data path " + externalDataPath);
//creating eng.trainedData
File f = new File(externalDataPath);
try {
if (!f.exists()) {
f.mkdir();
}
externalDataPath = externalDataPath + "/" + filename;
f = new File(externalDataPath);
if (!f.exists())
f.createNewFile();
externalDataPath = Environment.getExternalStorageDirectory().toString();
trainDataInputStream = assetManager.open(filename);
trainDataOutputStream = new FileOutputStream(f);
byte[] buffer = new byte[1024];
int read;
while ((read = trainDataInputStream.read(buffer)) != -1) {
trainDataOutputStream.write(buffer, 0, read);
}
trainDataOutputStream.flush();
trainDataOutputStream.close();
trainDataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I want to send the captured image with the help of intent and send image to the remote server. I am using following code:
String image_str;
String URL =**************/image.php?;
ArrayList<NameValuePair> nameValuePairs;
imageview.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
TakePhoto();
}
});
private void TakePhoto() {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, 0);
}
BitmapFactory.Options btmapOptions;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0 && resultCode == RESULT_OK) {
if (data != null) {
/* photo = (Bitmap) data.getExtras().get("data");
imageview.setImageBitmap(photo); *//* this is image view where you want to set image*/
Log.d("camera ---- > ", "" + data.getExtras().get("data"));
Toast.makeText(getApplicationContext(), getLastImageId(), Toast.LENGTH_LONG).show();
btmapOptions = new BitmapFactory.Options();
photo = BitmapFactory.decodeFile( getLastImageId(), btmapOptions);
imageview.setImageBitmap(photo);
}
// sendImg();
dialog = ProgressDialog.show(surakhaActivity.this, "", "Uploading file...", true);
new Thread(new Runnable() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
}
});
sendImg();
// Toast.makeText(getBaseContext(), response, Toast.LENGTH_LONG).show();
}
}).start();
}
}
private String getLastImageId() {
final String[] imageColumns = { MediaStore.Images.Media._ID,
MediaStore.Images.Media.DATA };
final String imageOrderBy = MediaStore.Images.Media._ID + " DESC";
Cursor imageCursor = managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns,
null, null, imageOrderBy);
if (imageCursor.moveToFirst()) {
int id = imageCursor.getInt(imageCursor
.getColumnIndex(MediaStore.Images.Media._ID));
String fullPath = imageCursor.getString(imageCursor
.getColumnIndex(MediaStore.Images.Media.DATA));
imageCursor.close();
return fullPath;
} else {
return "no path";
}
}
InputStream inputStream;
File f;
public String convertResponseToString(HttpResponse response) throws IllegalStateException, IOException {
String res = "";
StringBuffer buffer = new StringBuffer();
inputStream = response.getEntity().getContent();
int contentLength = (int) response.getEntity().getContentLength(); //getting content length…..
Toast.makeText(surakhaActivity.this, "contentLength : " + contentLength, Toast.LENGTH_LONG).show();
if (contentLength < 0) {
}
else {
byte[] data = new byte[512];
int len = 0;
try {
while (-1 != (len = inputStream.read(data)) ) {
buffer.append(new String(data, 0, len)); //converting to string and appending to stringbuffer…..
}
}
catch (IOException e) {
e.printStackTrace();
}
try {
inputStream.close(); // closing the stream…..
}
catch (IOException e) {
e.printStackTrace();
}
res = buffer.toString(); // converting stringbuffer to string…..
// Toast.makeText(MainActivity.this, "Result : " + res, Toast.LENGTH_LONG).show();
}
return res;
}
public void sendImg() {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 90, stream); //compress to which format you want.
byte [] byte_arr = stream.toByteArray();
image_str = Base64.encodeBytes(byte_arr);
nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("imgdata",image_str));
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(URL);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
the_string_response = convertResponseToString(response);
// editor.putString("imgRes", the_string_response);editor.commit();
Toast.makeText(surakhaActivity.this, "Response " + the_string_response, Toast.LENGTH_LONG).show();
}
catch(Exception e) {
Toast.makeText(surakhaActivity.this, "ERROR " + e.getMessage(), Toast.LENGTH_LONG).show();
}
dialog.dismiss();
this.finish();
}
}
But capturing the image and send progress dialog runs infinite and image is not sent.
This looks fishy...
dialog = ProgressDialog.show(surakhaActivity.this, "", "Uploading file...", true);
new Thread(new Runnable() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
}
});
sendImg();
// Toast.makeText(getBaseContext(), response, Toast.LENGTH_LONG).show();
}
}).start();
Can you put a "Log" on the sendImg() method to see if it ever gets called?