I am trying to download image from internet and store it locally in some hidden folder where the images are not visible to the user in his/her gallery.
Here is my code to do so. The image is getting displayed only when the device is connected to internet. In other words the image is not getting saved in the device and it is throwing an exception.
Here is my ImageStorage class:
package com.example.adhish.downloadretriveimage;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by appy-20 on 6/1/17.
*/
public class ImageStorage {
public static String saveToSdCard(Bitmap bitmap, String filename) {
String stored = null;
File sdcard = Environment.getExternalStorageDirectory() ;
File folder = new File(sdcard.getAbsoluteFile(), ".test_directory");//the dot makes this directory hidden to the user
folder.mkdir();
File file = new File(folder.getAbsoluteFile(), filename + ".jpg") ;
if (file.exists())
return stored ;
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
stored = "success";
} catch (Exception e) {
e.printStackTrace();
}
return stored;
}
public static File getImage(String imagename) {
File mediaImage = null;
try {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root);
if (!myDir.exists())
return null;
mediaImage = new File(myDir.getPath() + "/.test_directory/"+imagename);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mediaImage;
}
public static boolean checkifImageExists(String imagename)
{
Bitmap b = null ;
File file = ImageStorage.getImage("/"+imagename+".jpg");
String path = file.getAbsolutePath();
if (path != null)
b = BitmapFactory.decodeFile(path);
if(b == null || b.equals(""))
{
return false ;
}
return true ;
}
}
and here is my MainActivity.java:
package com.example.adhish.downloadretriveimage;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import java.io.File;
import java.io.FileOutputStream;
import java.net.URL;
import java.net.URLConnection;
public class MainActivity extends AppCompatActivity {
ImageView imageView;
Bitmap b;
String imagename;
String imgurl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView=(ImageView)findViewById(R.id.imageView);
imagename="394968_538b_7";
imgurl="https://udemy-images.udemy.com/course/750x422/394968_538b_7.jpg";
if(ImageStorage.checkifImageExists(imagename))
{
File file = ImageStorage.getImage("/"+imagename+".jpg");
// File file = ImageStorage.getImage("https://udemy-images.udemy.com/course/750x422/394968_538b_7.jpg");
String path = file.getAbsolutePath();
if (path != null){
b = BitmapFactory.decodeFile(path);
imageView.setImageBitmap(b);
}
} else {
new GetImages(imgurl, imageView, imagename).execute() ;
}
}
private class GetImages extends AsyncTask<Object, Object, Object> {
private String requestUrl, imagename_;
private ImageView view;
private Bitmap bitmap;
private FileOutputStream fos;
private GetImages(String requestUrl, ImageView view, String _imagename_) {
this.requestUrl = requestUrl;
this.view = view;
this.imagename_ = _imagename_;
}
#Override
protected Object doInBackground(Object... objects) {
try {
URL url = new URL(requestUrl);
URLConnection conn = url.openConnection();
bitmap = BitmapFactory.decodeStream(conn.getInputStream());
} catch (Exception ex) {
}
return null;
}
#Override
protected void onPostExecute(Object o) {
if (!ImageStorage.checkifImageExists(imagename_)) {
view.setImageBitmap(bitmap);
ImageStorage.saveToSdCard(bitmap, imagename_);
}
}
}
}
I have already given the external storage read write permission in my Manifest.
I found the solution to this problem. I am storing the images in SQLite database and here is the code for it:
https://github.com/adhishlal/URL_to_DB_Image
Related
I have a news app. My app takes so much time to fetch data from server and display it on the listView.But i have seen that apps like flipboard,facebook and Game News which has more data to fetch than mine does it faster.I think my app loads the entire data and displays the entire list together.Is there a way to display the list such that it loads the items in listView one by one?I do the fetching using a AsyncTaskLoader in the background.Also how to display a large list of news like 100 in a list .
MainActivity:
package com.example.android.gametalks;
import android.app.LoaderManager;
import android.content.Intent;
import android.content.Loader;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<GameNews>> {
//IGN url
final String ign_url = "https://newsapi.org/v1/articles?source=ign&sortBy=top&apiKey=679f6fb918d34343b18590ca70f7fcde";
final String google_url = " https://newsapi.org/v1/articles?source=google-news&sortBy=top&apiKey=679f6fb918d34343b18590ca70f7fcde";
final String engadget_url = "https://newsapi.org/v1/articles?source=engadget&sortBy=top&apiKey=679f6fb918d34343b18590ca70f7fcde";
GameAdapter adapter ;
private View progressBar;
final private int game_loader = 0;
ArrayList<String> urls = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
urls.add(ign_url);
urls.add(google_url);
urls.add(engadget_url);
//Getting listView
ListView gameListView = (ListView) findViewById(R.id.listView);
//progress bar finding
progressBar = findViewById(R.id.progress_bar);
ArrayList<GameNews> gameList = new ArrayList<>();
//Making a new arrayAdapter
adapter = new GameAdapter(this,gameList);
//Connecting ArrayAdapter to ListView
gameListView.setAdapter(adapter);
getLoaderManager().initLoader(game_loader, null, this);
//ListView item click listner
gameListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
GameNews currentEarthquake = adapter.getItem(i);
String url = currentEarthquake.getUrl();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
}
});
}
#Override
public Loader<List<GameNews>> onCreateLoader(int i, Bundle bundle) {
return new GameLoader(this,urls);
}
#Override
public void onLoadFinished(Loader<List<GameNews>> loader, List<GameNews> games) {
progressBar.setVisibility(View.INVISIBLE);
adapter.clear();
if(games == null)
{
return;
}
adapter.addAll(games);
}
#Override
public void onLoaderReset(Loader<List<GameNews>> loader) {
adapter.clear();
}
}
GameLoader:
package com.example.android.gametalks;
import android.content.AsyncTaskLoader;
import android.content.Context;
import java.util.ArrayList;
import java.util.List;
/**
* Created by apple on 9/8/17.
*/
public class GameLoader extends AsyncTaskLoader<List<GameNews>> {
private ArrayList<String> Urls = new ArrayList<>();
public GameLoader(Context context, ArrayList<String> Url) {
super(context);
Urls = Url;
}
#Override
protected void onStartLoading()
{
forceLoad();
}
#Override
public List<GameNews> loadInBackground() {
if(Urls == null)
{
return null;
}
// Perform the HTTP request for earthquake data and process the response.
List<GameNews> games = QueryUtils.FetchEarthquakeData(Urls);
return games;
}
}
QueryUtils(Here the network fetching takes place):
package com.example.android.gametalks;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.widget.ListView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Helper methods related to requesting and receiving earthquake data from USGS.
*/
public final class QueryUtils {
private static final String LOG_TAG = QueryUtils.class.getSimpleName();
/**
* Create a private constructor because no one should ever create a {#link QueryUtils} object.
* This class is only meant to hold static variables and methods, which can be accessed
* directly from the class name QueryUtils (and an object instance of QueryUtils is not needed).
*/
private QueryUtils() {
}
public static List<GameNews> FetchEarthquakeData(ArrayList<String> Url) {
List<GameNews> games ;
List<GameNews> Total = new ArrayList<>();
URL url;
Log.d(LOG_TAG,Url.get(0));
for(int i = 0 ; i < Url.size(); i++) {
url = createUrl(Url.get(i));
try {
//Make http request
String jsonResponse = makeHttpRequest(url);
games = extractFeatureFromJson(jsonResponse);
Total.addAll(games);
} catch (IOException e) {
Log.e("IOException", "" + e);
}
}
return Total;
}
private static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error with creating URL ", e);
}
return url;
}
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
InputStream inputStream = null;
HttpURLConnection urlConnection = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readInputStream(inputStream);
} else {
Log.e(LOG_TAG, "" + urlConnection.getResponseCode());
return null;
}
} catch (IOException e) {
Log.d(LOG_TAG, "" + e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// function must handle java.io.IOException here
inputStream.close();
}
}
return jsonResponse;
}
private static String readInputStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
private static ArrayList<GameNews> extractFeatureFromJson(String jsonResponse) {
ArrayList<GameNews> games = new ArrayList<>();
try {
JSONObject jsonObject = new JSONObject(jsonResponse);
JSONArray articles = jsonObject.getJSONArray("articles");
for (int i = 0; i < articles.length(); i++) {
JSONObject currentGame = articles.getJSONObject(i);
// Extract the value for the key called "mag"
String title = currentGame.getString("title");
// Extract the value for the key called "place"
String description = currentGame.getString("description");
// Extract the value for the key called "url"
String url = currentGame.getString("url");
//Extract value from key called urlToImage
String urlToImage = "nn";
urlToImage = currentGame.getString("urlToImage");
URL urlOfImage = null;
Bitmap bmp = null;
try {
urlOfImage = new URL(urlToImage);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
bmp = BitmapFactory.decodeStream(urlOfImage.openConnection().getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
// Create a new {#link Earthquake} object with the magnitude, location, time,
// and url from the JSON response.
GameNews game = new GameNews(title, description,bmp,url);
// Add the new {#link Earthquake} to the list of earthquakes.
games.add(game);
}
} catch (JSONException e) {
Log.d(LOG_TAG, "" + e);
}
return games;
}
}
Thanks in advance.
First of all open camera and capture 10 second video after open next activity and list of audio file then click the audio file this time merge the audio and video but in this my code getting error when select audio in storage.
Activity
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.MediaController;
import android.widget.VideoView;
import com.coremedia.iso.boxes.Container;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
import com.wos.capturevideowithaudio.R;
import com.wos.capturevideowithaudio.adapter.AudioListAdapter;
import com.wos.capturevideowithaudio.utils.Constant;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
public class AudioMixing extends AppCompatActivity {
private ArrayList<String> audio;
private VideoView mVideoView;
private RecyclerView rvAudioFile;
private AudioListAdapter audioListAdapter;
private String musicUri, timeStamp;
private String[] array_spinnerLoad, files;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audiomixing);
initView();
}
private void initView() {
rvAudioFile = (RecyclerView) findViewById(R.id.rvAudioFile);
mVideoView = (VideoView) findViewById(R.id.video_view);
//Display Current Capture Video
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
timeStamp = bundle.getString("timeStamp");
musicUri = bundle.getString("uri");
mVideoView.setVideoURI(Uri.parse(musicUri));
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
mVideoView.start();
}
//Get All AudioList in Mobile Phone
audio = new ArrayList<>();
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath();
File sd = new File(path);
File[] sdDirList = sd.listFiles();
if (sdDirList != null) {
array_spinnerLoad = new String[sdDirList.length];
files = new String[sdDirList.length];
for (int i = 0; i < sdDirList.length; i++) {
array_spinnerLoad[i] = sdDirList[i].getName();
Log.d(Constant.TAG, "getAudioName = " + sdDirList[i].getName());
files[i] = sdDirList[i].getAbsolutePath();
Log.d(Constant.TAG, "getAudioName = " + sdDirList[i].getAbsolutePath());
}
audioListAdapter = new AudioListAdapter(getApplicationContext(), array_spinnerLoad);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
rvAudioFile.setLayoutManager(layoutManager);
rvAudioFile.setAdapter(audioListAdapter);
audioListAdapter.OnItemClickListener(new AudioListAdapter.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
String fileName = array_spinnerLoad[position];
String filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath() + "/" + fileName;
MediaPlayer mediaPlayer = new MediaPlayer();
try {
FileInputStream is = new FileInputStream(filePath);
mediaPlayer.setDataSource(is.getFD());
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
String root = Environment.getExternalStorageDirectory().toString();
String audio = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath() + "/" + fileName;
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "HelloCamera");
String video = mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4";
String output = root + "/" + "jd.mp4";
Log.e(Constant.TAG, "audio:" + audio + " video:" + video + " out:" + output);
mux(video, audio, output);
}
});
}
}
public boolean mux(String videoFile, String audioFile, String outputFile) {
Movie video;
try {
video = new MovieCreator().build(videoFile);
} catch (RuntimeException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
Movie audio;
try {
audio = new MovieCreator().build(audioFile);
} catch (IOException e) {
e.printStackTrace();
return false;
} catch (NullPointerException e) {
e.printStackTrace();//In this Line Error java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.googlecode.mp4parser.BasicContainer.getBoxes
return false;
}
Track audioTrack = audio.getTracks().get(0);
video.addTrack(audioTrack);
Container out = new DefaultMp4Builder().build(video);
FileOutputStream fos;
try {
fos = new FileOutputStream(outputFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
BufferedWritableFileByteChannel byteBufferByteChannel = new BufferedWritableFileByteChannel(fos);
try {
out.writeContainer(byteBufferByteChannel);
byteBufferByteChannel.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
private static class BufferedWritableFileByteChannel implements WritableByteChannel {
private static final int BUFFER_CAPACITY = 1000000;
private boolean isOpen = true;
private final OutputStream outputStream;
private final ByteBuffer byteBuffer;
private final byte[] rawBuffer = new byte[BUFFER_CAPACITY];
private BufferedWritableFileByteChannel(OutputStream outputStream) {
this.outputStream = outputStream;
this.byteBuffer = ByteBuffer.wrap(rawBuffer);
}
#Override
public int write(ByteBuffer inputBuffer) throws IOException {
int inputBytes = inputBuffer.remaining();
if (inputBytes > byteBuffer.remaining()) {
dumpToFile();
byteBuffer.clear();
if (inputBytes > byteBuffer.remaining()) {
throw new BufferOverflowException();
}
}
byteBuffer.put(inputBuffer);
return inputBytes;
}
#Override
public boolean isOpen() {
return isOpen;
}
#Override
public void close() throws IOException {
dumpToFile();
isOpen = false;
}
private void dumpToFile() {
try {
outputStream.write(rawBuffer, 0, byteBuffer.position());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
Error
Process: com.wos.capturevideowithaudio, PID: 7162
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.googlecode.mp4parser.BasicContainer.getBoxes(java.lang.Class)' on a null object reference
at com.googlecode.mp4parser.authoring.container.mp4.MovieCreator.build(MovieCreator.java:48)
at com.googlecode.mp4parser.authoring.container.mp4.MovieCreator.build(MovieCreator.java:35)
at com.wos.capturevideowithaudio.activity.AudioMixing.appendTwoVideo(AudioMixing.java:154)
at com.wos.capturevideowithaudio.activity.AudioMixing$1.onItemClick(AudioMixing.java:142)
at com.wos.capturevideowithaudio.adapter.AudioListAdapter$ViewHolder.onClick(AudioListAdapter.java:60)
at android.view.View.performClick(View.java:5612)
at android.view.View$PerformClick.run(View.java:22285)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
I'm trying to extract URLs from browser history. I've found below code and try to implement it. But the problem is it gives error in BookmarkColumns, BOOKMARKS_URI, noicon.
I tryed this in API levels 16,23,25. But the error dosent solve. It always says that "Cannot resolve symbol 'BookmarkColumns' "
Please help me to resolve this...
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.provider.Browser;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private ArrayList<String> titles;
private ArrayList<String> urls;
private ArrayList<Bitmap> bitmaps;
private ContentResolver cr;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createLists();
}
protected void onResume() {
super.onResume();
getBH();
showHistoryBookmarks();
}
public void createLists() {
titles = new ArrayList<String>();
urls = new ArrayList<String>();
bitmaps = new ArrayList<Bitmap>();
}
public void getBH() {
Bitmap icon;
cr = getContentResolver();
String order = Browser.BookmarkColumns.DATE + " DESC";
String[] projection = {Browser.BookmarkColumns.TITLE, Browser.BookmarkColumns.URL, Browser.BookmarkColumns.FAVICON};
//String selection=projection[0]+"=?";
//String args[]={"Google"};
Cursor rows = cr.query(Browser.BOOKMARKS_URI, projection, null, null, order);
if (rows.getCount() > 0) {
while (rows.moveToNext()) {
//read title
String title = rows.getString(rows.getColumnIndex(projection[0]));
//read url
String url = rows.getString(rows.getColumnIndex(projection[1]));
//read icon
byte[] bicon = rows.getBlob(rows.getColumnIndex(projection[2]));
if (bicon != null) {
//convert blob image data to Bitmap
icon = BitmapFactory.decodeByteArray(bicon, 0, bicon.length);
} else {
//default icon for history and bookmarks that do not icons
icon = BitmapFactory.decodeResource(getResources(), R.drawable.noicon);
}
//add to lists
addToList(title, url, icon);
}
//close the cursor
rows.close();
}
}
public void addToList(String title, String url, Bitmap bitmap) {
titles.add(title);
urls.add(url);
bitmaps.add(bitmap);
}
public void showHistoryBookmarks() {
ListView l = (ListView) findViewById(R.id.hb_list);
if (l != null) {
if (titles.size() > 0) {
ListAdapterModel aa = new ListAdapterModel(this, R.layout.listlayout, R.id.hbtitle, titles, urls, bitmaps);
l.setAdapter(aa);
} else {
Toast.makeText(this, "This is no bookmark or history.", Toast.LENGTH_SHORT).show();
}
}
}
}
try these chrome history API. Read documents and give a try. I didn't try it. But thought would be insperation.
I have this mainActivity java file which I would like to display back the results of the OCR.
ERROR: Creation of directory /storage/emulated/0/TesseractSample/tessdata failed, check does Android Manifest have permission to write to external storage.
Unable to copy files to tessdata java.io.FileNotFoundException: /storage/emulated/0/TesseractSample/tessdata/eng.traineddata: open failed: ENOENT (No such file or directory)
3.Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/TesseractSample/imgs/ocr.jpg: open failed: EACCES (Permission denied)
Data path must contain subfolder tessdata!
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.googlecode.tesseract.android.TessBaseAPI;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
static final int PHOTO_REQUEST_CODE = 1;
private TessBaseAPI tessBaseApi;
TextView textView;
Uri outputFileUri;
private static final String lang = "eng";
String result = "empty";
private static final String DATA_PATH = Environment.getExternalStorageDirectory().toString() + "/TesseractSample/";
private static final String TESSDATA = "tessdata";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button captureImg = (Button) findViewById(R.id.action_btn);
if (captureImg != null) {
captureImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startCameraActivity();
}
});
}
textView = (TextView) findViewById(R.id.textResult);
}
/**
* to get high resolution image from camera
*/
private void startCameraActivity() {
try {
String IMGS_PATH = Environment.getExternalStorageDirectory().toString() + "/TesseractSample/imgs";
prepareDirectory(IMGS_PATH);
String img_path = IMGS_PATH + "/ocr.jpg";
outputFileUri = Uri.fromFile(new File(img_path));
final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, PHOTO_REQUEST_CODE);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
//making photo
if (requestCode == PHOTO_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
prepareTesseract();
startOCR(outputFileUri);
} else {
Toast.makeText(this, "ERROR: Image was not obtained.", Toast.LENGTH_SHORT).show();
}
}
/**
* Prepare directory on external storage
*
* #param path
* #throws Exception
*/
private void prepareDirectory(String path) {
File dir = new File(path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.e(TAG, "ERROR: Creation of directory " + path + " failed, check does Android Manifest have permission to write to external storage.");
}
} else {
Log.i(TAG, "Created directory " + path);
}
}
private void prepareTesseract() {
try {
prepareDirectory(DATA_PATH + TESSDATA);
} catch (Exception e) {
e.printStackTrace();
}
copyTessDataFiles(TESSDATA);
}
/**
* Copy tessdata files (located on assets/tessdata) to destination directory
*
* #param path - name of directory with .traineddata files
*/
private void copyTessDataFiles(String path) {
try {
String fileList[] = getAssets().list(path);
for (String fileName : fileList) {
// open file within the assets folder
// if it is not already there copy it to the sdcard
String pathToDataFile = DATA_PATH + path + "/" + fileName;
if (!(new File(pathToDataFile)).exists()) {
InputStream in = getAssets().open(path + "/" + fileName);
OutputStream out = new FileOutputStream(pathToDataFile);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
Log.d(TAG, "Copied " + fileName + "to tessdata");
}
}
} catch (IOException e) {
Log.e(TAG, "Unable to copy files to tessdata " + e.toString());
}
}
/**
* don't run this code in main thread - it stops UI thread. Create AsyncTask instead.
* https://developer.android.com/reference/android/os/AsyncTask.html
*
* #param imgUri
*/
private void startOCR(Uri imgUri) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4; // 1 - means max size. 4 - means maxsize/4 size. Don't use value <4, because you need more memory in the heap to store your data.
Bitmap bitmap = BitmapFactory.decodeFile(imgUri.getPath(), options);
result = extractText(bitmap);
textView.setText(result);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
private String extractText(Bitmap bitmap) {
try {
tessBaseApi = new TessBaseAPI();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
if (tessBaseApi == null) {
Log.e(TAG, "TessBaseAPI is null. TessFactory not returning tess object.");
}
}
tessBaseApi.init(DATA_PATH, lang);
// //EXTRA SETTINGS
// //For example if we only want to detect numbers
// tessBaseApi.setVariable(TessBaseAPI.VAR_CHAR_WHITELIST, "1234567890");
//
// //blackList Example
// tessBaseApi.setVariable(TessBaseAPI.VAR_CHAR_BLACKLIST, "!##$%^&*()_+=-qwertyuiop[]}{POIU" +
// "YTRWQasdASDfghFGHjklJKLl;L:'\"\\|~`xcvXCVbnmBNM,./<>?");
Log.d(TAG, "Training file loaded");
tessBaseApi.setImage(bitmap);
String extractedText = "empty result";
try {
extractedText = tessBaseApi.getUTF8Text();
} catch (Exception e) {
Log.e(TAG, "Error in recognizing text.");
}
tessBaseApi.end();
return extractedText;
}
}
If you're targeting Android SDK 23 or higher, you have to request permissions from the user at run time in addition to requesting permission in the Android manifest file.
Alternatively, you can target SDK 22 or lower by changing the targetSdkVersion value in your build.gradle.
So I have looked up several ways to write to an SD card in Android but none seem to actually result in something being written. I have already set the permission in the manifest. My FileIO class I wrote:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
//import android.app.Activity;
//import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
public class FileIO {
private static final String TAG = "FileIO";
private String filename;
private File sdCard;
private File dir;
public FileIO(String path, String filename){
Log.d(TAG, "Creating new File IO");
this.filename = filename;
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
Log.d(TAG, "Read and Write OK");
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
Log.w(TAG, "Read only OK");
} else {
// Something else is wrong. It may be one of many other states, but all we need
// to know is we can neither read nor write
Log.w(TAG, "Read and Write BLOCKED");
}
sdCard = Environment.getExternalStorageDirectory();
Log.d(TAG, "Writing to file: " + sdCard.getAbsolutePath()+path);
dir = new File (sdCard.getAbsolutePath()+path);
if (dir.mkdirs() || dir.isDirectory()) {
Log.d(TAG, "SUCCESS - Created directory");
} else {
Log.d(TAG, "FAILED - Create directory");
}
}
public void writeToFile(String s){
File file = new File(dir,this.filename);
try {
FileOutputStream f = new FileOutputStream(file,true); //True = Append to file, false = Overwrite
OutputStreamWriter osw = new OutputStreamWriter(f);
osw.write(s);
osw.flush();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.printf("\nFile not found. Make sure to add WRITE_EXTERNAL_STORAGE permission to the manifest");
} catch (IOException e) {
e.printStackTrace();
}
}
}
And then this is class it is being used in.
import android.app.Activity;
import android.text.format.DateFormat;
import android.widget.TextView;
public class AudioClipLogWrapper implements AudioClipListener
{
private TextView log;
private Activity context;
private double previousFrequency = -1;
private int previousVolume = -1;
private int previousMax = -1;
private FileIO fileIO;
public AudioClipLogWrapper(TextView log, Activity context)
{
this.log = log;
this.context = context;
String dateStamp = (DateFormat.format("dd-MM-yyyy-hh-mm-ss", new java.util.Date()).toString());
fileIO = new FileIO("/Android/data/com.uni.Lab7/files/",String.format("audio-%s.txt",dateStamp));
}
#Override
public boolean heard(short[] audioData, int sampleRate)
{
final double freq = ZeroCrossing.calculate(sampleRate, audioData);
final int maxAmplitude = AudioUtil.getMaxValue(audioData);
final double volume = AudioUtil.rootMeanSquared(audioData);
final StringBuilder message = new StringBuilder();
if ((((int)volume) > (4 * previousVolume)) && (maxAmplitude > (4 * previousMax)) ) {
message.append(" Clap!");
}
previousVolume = (int) volume;
previousMax= (int) maxAmplitude;
fileIO.writeToFile(String.format("%d, %d, %f\n",(int)volume, maxAmplitude, freq));
context.runOnUiThread(new Runnable()
{
#Override
public void run()
{
AudioTaskUtil.appendToStartOfLog(log, message.toString());
}
});
return false;
}
}
When I look at the log it suggests everything should work:
01-12 23:21:55.815 2752-2752/com.uni.Lab7 D/FileIO﹕ Creating new File IO
01-12 23:21:55.825 2752-2752/com.uni.Lab7 D/FileIO﹕ Read and Write OK
01-12 23:21:55.825 2752-2752/com.uni.Lab7 D/FileIO﹕ Writing to file: /storage/sdcard0/Android/data/com.uni.Lab7/files/
01-12 23:21:55.835 2752-2752/com.uni.Lab7 D/FileIO﹕ SUCCESS - Created directory
But when I take the SD card out of the phone, and I look on my computer there is no folder and no file. I have looked at Android write to sd card folder and Write a file in SDcard in Android and I have what they suggested.
The phone is a Samsung GT-S53110B running 4.1.2. So in my gradle and manifest I have minimum SDK as 8 and target as 16.