I created an image gallery app.
My requirment: I want to select multiple images, click on button cut and come back to activity which displays all folders (ImageGallery.java). Now, I want to select a folder and paste all the selected images in that folder, on selecting the folder.
What is happening? I am able to select images using my app and come back to activity which displays all folders but not able to move them using my app.
I put the code for moving images in a background thread using task. I select images from one folder, come back to the activity which displays all the folders (ImageGallery.java) and select the folder to which the images are to be moved. But when I try to move images, selected images do not move to other folder being selected, on selecting a folder. I guess the code inside AsyncTask isn't even getting executed.
How do I fix it ?
PhotosActivity.java (Activity used to select images):
int int_position;
private GridView gridView;
GridViewAdapter adapter;
ArrayList<Model_images> al_menu = new ArrayList<>();
private ArrayList<Integer> mSelected = new ArrayList<>();
boolean boolean_folder;
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(final AdapterView<?> parent, View view, final int position, long id) {
if (mSelected.contains(position)) {
mSelected.remove(position);
view.setBackgroundColor(Color.TRANSPARENT);// remove item from list
// update view (v) state here
// eg: remove highlight
} else {
mSelected.add(position);
view.setBackgroundColor(Color.LTGRAY);// add item to list
// update view (v) state here
// eg: add highlight
}
buttoncut.setVisibility(View.VISIBLE);
button2.setVisibility(View.VISIBLE);
button3.setVisibility(View.VISIBLE);
button4.setVisibility(View.VISIBLE);
button5.setVisibility(View.VISIBLE);
buttoncut.setOnClickListener(
new View.OnClickListener() {
public void onClick(View view) {
buttoncut.setVisibility(View.GONE);
button2.setVisibility(View.GONE);
button3.setVisibility(View.GONE);
button4.setVisibility(View.GONE);
button5.setVisibility(View.GONE);
Intent moveIntent = new Intent(PhotosActivity.this, ImageGallery.class);
moveIntent.putIntegerArrayListExtra("selected_images", mSelected);
startActivity(moveIntent);
}
});
ImageGallery.java:
public static ArrayList<Model_images> al_images = new ArrayList<>();
ArrayList<Integer> selectedImages = new ArrayList<>();
boolean boolean_folder;
Adapter_PhotosFolder obj_adapter;
GridView gv_folder;
private static final int REQUEST_PERMISSIONS = 100;
int int_position;
selectedImages = getIntent().getIntegerArrayListExtra("selected_images");
if (selectedImages != null) {
Toast.makeText(ImageGallery.this, "This code gets executed", Toast.LENGTH_SHORT)
.show();
new LongOperation().execute();
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
for (int image : selectedImages) {
File sourceImage = new File(al_images.get(int_position).getAl_imagepath().get(image)); //returns the image File from model class to be moved.
File destinationImage = new File(al_images.get(int_position).getStr_folder(), ".jpeg");
try {
copyOrMoveFile(sourceImage, destinationImage, true);
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
//Method to move the file
private void copyOrMoveFile(File file, File dir, boolean isCopy) throws IOException {
File newFile = new File(dir, file.getName());
FileChannel outChannel = null;
FileChannel inputChannel = null;
try {
outChannel = new FileOutputStream(newFile).getChannel();
inputChannel = new FileInputStream(file).getChannel();
inputChannel.transferTo(0, inputChannel.size(), outChannel);
inputChannel.close();
if (!isCopy)
file.delete();
} finally {
if (inputChannel != null) inputChannel.close();
if (outChannel != null) outChannel.close();
}
}
}
You have to use Intent.ACTION_MEDIA_SCANNER_SCAN_FILE for updating media store.
Inside AsyncTask -> onPostExecute method fetch latest images from MediaStore
private class LongOperation extends AsyncTask<String, Void, File> {
#Override
protected File doInBackground(String... params) {
for (String imagePath : selectedImages) {
File sourceImage = new File(imagePath); //returns the image File from model class to
// be// moved.
File destinationImage = new File(al_images.get(int_position).getDirectoryPath() +
File.separator + sourceImage.getName());
try {
moveFile(sourceImage, destinationImage, true);
return destinationImage;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(File file) {
super.onPostExecute(file);
getBaseContext().sendBroadcast(new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
fn_imagespath(); // Call method to fetch latest images.
}
}, 1000); // additional delay time of 1 sec to update media scanner
}
}
Just a better method to move file
private void moveFile(File file_Source, File file_Destination, boolean isCopy) throws IOException {
FileChannel source = null;
FileChannel destination = null;
if (!file_Destination.exists()) {
file_Destination.createNewFile();
}
try {
source = new FileInputStream(file_Source).getChannel();
destination = new FileOutputStream(file_Destination).getChannel();
long count = 0;
long size = source.size();
while ((count += destination.transferFrom(source, count, size - count)) < size) ;
if (!isCopy) {
file_Source.delete();
}
} finally {
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
}
Not much changes in code added MediaScannerConnection. Give it a try .
private class LongOperation extends AsyncTask<String, Void, Integer> {
#Override
protected Integer doInBackground(String... params) {
int movedCount=0;
for (int i=0;i<selectedImages.size();i++) {
File sourceImage = new File(al_images.get(int_position).getAl_imagepath().get(i));
File destinationImage = new File(al_images.get(int_position).getStr_folder(), ".jpeg");
try {
boolean isMoved= copyOrMoveFile(sourceImage, destinationImage, true);
if(isMoved) {
movedCount++;
callMediaScanner(ImageGallery.this, destinationImage.getAbsolutePath());
}
} catch (IOException e) {
e.printStackTrace();
}
}
return movedCount;
}
#Override
protected void onPostExecute(Integer val) {
super.onPostExecute(val);
// Here you have to modify return type of doInBackground as per your convineance
if(val.intValue()==selectedImages.size()){
Log.e("Moved","Allfile moved");
}else{
Log.e("Moved","Some file missing");
}
}
public boolean copyOrMoveFile(File localFile, File destinationFile, boolean isCopy) {
FileChannel outputChannel = null;
FileChannel inputChannel = null;
try {
outputChannel = new FileOutputStream(destinationFile).getChannel();
inputChannel = new FileInputStream(localFile).getChannel();
inputChannel.transferTo(0, inputChannel.size(), outputChannel);
inputChannel.close();
if (!isCopy)
localFile.delete();
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
if (inputChannel != null) inputChannel.close();
if (outputChannel != null) outputChannel.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return true;
}
}
public void callMediaScanner(Context context, String path) {
MediaScannerConnection.scanFile(context,
new String[] { path }, null,null);
}
Related
I am using following code to upload a file to Dropbox. But I want to check if the file exists on Dropbox already, to avoid duplications. So how can I check if a file already exists or not? As I am new to Android, I don't know what to do now
public class UploadFileToDropbox extends AsyncTask<Void, Void, Boolean>
{
private DropboxAPI<?> dropbox;
private String path;
private Context context;
public UploadFileToDropbox(Context context, DropboxAPI<?> dropbox,
String path) {
this.context = context.getApplicationContext();
this.dropbox = dropbox;
this.path = path;
}
#Override
protected Boolean doInBackground(Void... params) {
final File tempDir = context.getCacheDir();
File tempFile;
FileWriter fr;
try {
tempFile = File.createTempFile("file", ".txt", tempDir);
fr = new FileWriter(tempFile);
fr.write("Test file uploaded using Dropbox API for Android");
fr.close();
FileInputStream fileInputStream = new FileInputStream(tempFile);
dropbox.putFile(path + "sample.txt", fileInputStream,
tempFile.length(), null, null);
tempFile.delete();
return true;
} catch (IOException e) {
e.printStackTrace();
} catch (DropboxException e) {
e.printStackTrace();
}
return false;
}
#Override
protected void onPostExecute(Boolean result) {
if (result) {
Toast.makeText(context, "File Uploaded Successfully!",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, "Failed to upload file", Toast.LENGTH_LONG)
.show();
}
}
}
If the file exists, then the Entry is not null
public boolean isExists(String path) {
boolean ret = false;
try {
Entry existingEntry = metadata(path, 1, null, false, null);
if (existingEntry != null) {
ret = true;
}
} catch (DropboxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ret = false;
}
return ret;
}
private void loadFiles(final String directory) {
new Thread() {
#Override
public void run() {
String mPath = directory;
Entry direntEx = null;
try {
direntEx = mApi.metadata(mPath, 1000, null, true, null);
} catch (DropboxException e) {
e.printStackTrace();
}
if (direntEx.contents.size() != 0) {
for (Entry ent : direntEx.contents) {
String name = ent.fileName();
/*Compare file here*/
}
}
super.run();
}
}.start();
}
I have done Google drive integration and in integration i have created a file and write some text on the file and save it into the Login user's drive it is running fine but i want to to update the contents of the file i have created a save to drive, i have done allot of research but did not able to find the demo or any code, please any one guide me, i will post my code where i am creating file and saving to my drive
public class MainActivity extends Activity implements ConnectionCallbacks,OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
Button b ,editfile;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
b = (Button) findViewById(R.id.createfile);
editfile = (Button) findViewById(R.id.editfile);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
// create new contents resource
/**
* A code to illustrate how to create a new FILE in the Drive.
*/
Drive.DriveApi.newContents(getGoogleApiClient())
.setResultCallback(contentsCallback);
}
});
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
/**
* Called when activity gets visible. A connection to Drive services need to
* be initiated as soon as the activity is visible. Registers
* {#code ConnectionCallbacks} and {#code OnConnectionFailedListener} on the
* activities itself.
*/
#Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
//.addScope(Drive.SCOPE_APPFOLDER) // required for App Folder sample
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(this, 1);
} catch (IntentSender.SendIntentException e) {
// Unable to resolve, message user appropriately
}
} else {
GooglePlayServicesUtil.getErrorDialog(
connectionResult.getErrorCode(), this, 0).show();
}
}
#Override
protected void onActivityResult(final int requestCode,
final int resultCode, final Intent data) {
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
mGoogleApiClient.connect();
}
break;
}
}
public GoogleApiClient getGoogleApiClient() {
return mGoogleApiClient;
}
/**
* A code to illustrate how to create a new FILE with some text on the file in the Google Drive.
*/
final private ResultCallback<ContentsResult> contentsCallback = new ResultCallback<ContentsResult>() {
#Override
public void onResult(ContentsResult result) {
if (!result.getStatus().isSuccess()) {
Toast.makeText(MainActivity.this,"Error while trying to create new file contents" ,Toast.LENGTH_LONG).show();
return;
}
Contents driveContents = result.getContents();
// write content to DriveContents
OutputStream outputStream = driveContents.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
try {
writer.write(information_data());
writer.close();
} catch (IOException e) {
Log.e("IOExceptions=", e.toString());
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("testFile.txt")
.setMimeType("text/plain")
.setStarred(true)
.build();
// create a file on root folder
Drive.DriveApi.getRootFolder(getGoogleApiClient())
.createFile(getGoogleApiClient(), changeSet, result.getContents())
.setResultCallback(fileCallback);
}
};
final private ResultCallback<DriveFileResult> fileCallback = new ResultCallback<DriveFileResult>() {
#Override
public void onResult(DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
Toast.makeText(MainActivity.this,"Error while trying to create the file" ,Toast.LENGTH_LONG).show();
return;
}
Toast.makeText(MainActivity.this,"Created a file: " + result.getDriveFile().getDriveId(),Toast.LENGTH_LONG).show();
Log.e("result.getDriveFile().getDriveId=", ""+result.getDriveFile().getDriveId());
Log.e("result.getStatus()=", ""+result.getStatus().toString());
//Opening the file contents Reading files
driveOpnefileContents(result.getDriveFile());
}
};
public void driveOpnefileContents(DriveFile driveFile) {
// TODO Auto-generated method stub
Log.e("driveOpnefileContents=", "driveOpnefileContents");
driveFile.openContents(getGoogleApiClient(), DriveFile.MODE_READ_ONLY, new DownloadProgressListener() {
#Override
public void onProgress(long bytesDownloaded, long bytesExpected) {
// Update progress dialog with the latest progress.
Log.e("onProgress=", "onProgress");
int progress = (int)(bytesDownloaded*100/bytesExpected);
Log.e("progress", String.format("Loading progress: %d percent=", progress));
}
})
.setResultCallback(contentsOpenedCallback);
}
ResultCallback<ContentsResult> contentsOpenedCallback = new ResultCallback<ContentsResult>() {
#Override
public void onResult(ContentsResult result) {
if (!result.getStatus().isSuccess()) {
// display an error saying file can't be opened
Toast.makeText(MainActivity.this,"display an error saying file can't be opened" ,Toast.LENGTH_LONG).show();
return;
}
// DriveContents object contains pointers
// to the actual byte stream
try {
Contents driveContents = result.getContents();
BufferedReader reader = new BufferedReader(new InputStreamReader(driveContents.getInputStream()));
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
String contentsAsString = builder.toString();
Log.e("Reading File Contents As String=", ""+contentsAsString);
driveContents.close();
/*try {
ParcelFileDescriptor parcelFileDescriptor = driveContents.getParcelFileDescriptor();
FileInputStream fileInputStream = new FileInputStream(parcelFileDescriptor.getFileDescriptor());
// Read to the end of the file.
fileInputStream.read(new byte[fileInputStream.available()]);
// Append to the file.
FileOutputStream fileOutputStream = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
Writer writer = new OutputStreamWriter(fileOutputStream);
writer.write("editing the contents of the saved file");
writer.close();
driveContents.close();
} catch (IOException e) {
Log.e("IOExceptionAppend to the file.=", e.toString());
//java.io.IOException: write failed: EBADF (Bad file number)
}*/
Log.e("Append to the file.=", "Append to the file.");
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("IOExceptionAppend to the file2.=", e.toString());
}
}
};
public String information_data(){
String result = "";
try {
JSONObject jArrayFacebookData = new JSONObject();
JSONObject jObjectType = new JSONObject();
// put elements into the object as a key-value pair
jObjectType.put("info", "facebook_login");
jArrayFacebookData.put("Result", jObjectType);
// 2nd array for user information
JSONObject jObjectData = new JSONObject();
// Create Json Object using Facebook Data
jObjectData.put("facebook_user_id", "facebook_user_id");
jObjectData.put("first_name", "achin");
jObjectData.put("last_name", "verma");
jObjectData.put("email", "xvz");
jObjectData.put("username", "achin");
jObjectData.put("birthday", "28 april 90");
jObjectData.put("gender", "male");
jObjectData.put("location", "mohali");
jObjectData.put("display_photo", "link");
jArrayFacebookData.put("data", jObjectData);
//Log.e("jArrayFacebookData=", ""+jArrayFacebookData);
result = ""+jArrayFacebookData;
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return result;
}
}
Here is a code snippet 'update' that does what you need (I think). It is using the 'await' call version that has to run off the UI thread or you may turn it into a callback version. You actually need only the portion that starts with
dFile.open(mGAC, DriveFile.MODE_WRITE_ONLY, null)
(after turning DriveId into DriveFile) and make sure you call 'commit' on it
/**
* update file in GOODrive
* #param dId file id
* #param titl new file name (optional)
* #param mime new file mime type (optional, null or MIME_FLDR indicates folder)
* #param buf new file contents (optional)
* #return success status
*/
static boolean update(DriveId dId, String titl, String mime, String desc, byte[] buf){
if (dId == null || !isConnected()) return false; //------------>>>
Boolean bOK = false;
Builder mdBd = new MetadataChangeSet.Builder();
if (titl != null) mdBd.setTitle(titl);
if (mime != null) mdBd.setMimeType(mime);
if (desc != null) mdBd.setDescription(desc);
MetadataChangeSet meta = mdBd.build();
if (mime == null || UT.MIME_FLDR.equals(mime)) {
DriveFolder dFldr = Drive.DriveApi.getFolder(mGAC, dId);
MetadataResult r1 = dFldr.updateMetadata(mGAC, meta).await();
bOK = (r1 != null) && r1.getStatus().isSuccess();
} else {
DriveFile dFile = Drive.DriveApi.getFile(mGAC, dId);
MetadataResult r1 = dFile.updateMetadata(mGAC, meta).await();
if ((r1 != null) && r1.getStatus().isSuccess() && buf != null) {
DriveContentsResult r2 = dFile.open(mGAC, DriveFile.MODE_WRITE_ONLY, null).await();
if (r2.getStatus().isSuccess()) {
Status r3 = bytes2Cont(r2.getDriveContents(), buf).commit(mGAC, meta).await();
bOK = (r3 != null && r3.isSuccess());
}
}
}
return bOK;
}
the metadata do not need to be updated in your case, so you may modify the code or just pass nulls. Your new content has to be delivered as a byte buffer (String turned to bytes, jpeg data buffer, ...).
The context of this method can be found here . Good Luck
I know, this answer was late, but google always update's his api, so I desided to add answer.
Here is kotlin code, which working by this time
fun updateDriveFile(fileCache: File, googleRecentFileModel: GoogleRecentFileModel): Deferred<Boolean> = CoroutineScope(Dispatchers.Default).async {
var result = false
val drive = DriveId.decodeFromString(googleRecentFileModel.stringDriveId).asDriveFile()
val openFileTask = driveResourceClient?.openFile(drive, DriveFile.MODE_WRITE_ONLY)
openFileTask?.continueWithTask { task ->
val contents = task.result
contents!!.outputStream.use {
val fileBytes = ByteArray(fileCache.length().toInt())
val fileIS = FileInputStream(fileCache)
fileIS.read(fileBytes)
fileIS.close()
it.write(fileBytes)
it.flush()
it.close()
result = true
}
driveResourceClient?.commitContents(contents, null)
}
result
}
I have created a simple Activity. The activity is responsible for downloading data from parse.com database and populating a linear layout. In the process, I am dynamically creating the linear layout with TextViews and ImageViews according according to the content.
The problem is that, whenever I try to download an image, I use as AsyncTask Downloading class, which results in slowing down the UI thread! I am currently trying to return the bitmap file from the AsyncTask Image downloading class using: returnedBitmap = new LoadImage().execute(src).get(); which might be responsible for slowing down the UI thread. I have to do this because the caller method geneterImageView will return an imageview when it receives the bitmap file.
The complete Activity code:
public class MainActivity extends ActionBarActivity {
ArrayList<String> heightList = new ArrayList<String>();
ArrayList<String> reversedList = new ArrayList<String>();
ImageView imageView1;
Bitmap bitmap;
RelativeLayout parent_layout;
ParseObject user;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// imageView1 = (ImageView)findViewById(R.id.imageView1);
parent_layout = (RelativeLayout) findViewById(R.id.parent_layout);
login("xyz#xyz.com", "xyz");
}
private void loopThroughArrayAndAttach(){
LinearLayout llInner = new LinearLayout(this);
llInner.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
parent_layout.addView(llInner);
for (int i = 0; i < heightList.size(); i++) {
if (hasNoImagess(heightList.get(i)) == true) {
// No images.
TextView myText = geneterTextView(heightList.get(i));
llInner.addView(myText);
// geneterTextView(heightList.get(i));
} else {
ImageView myImage = geneterImageView(heightList.get(i));
llInner.addView(myImage);
// geneterImageView(heightList.get(i));
}
}
}
public static boolean hasNoImagess(String contents){
Document doc = Jsoup.parse(contents);
Element element = doc.body();
Elements elements = element.select("img");
if (elements.isEmpty()) {
return true;
} else {
return false;
}
}
public ImageView geneterImageView(String imgContent){
// Will need to run via background thread - like aysnc
// Extract the image file via jsoup
// Insert it into a imagevieww
// Inser that into a layout.
Log.d("IN IMAGE ", " " + imgContent);
Document doc = Jsoup.parse(imgContent);
Elements img = doc.getElementsByTag("img");
Bitmap returnedBitmap = null;
for (Element el : img) {
String src = el.absUrl("src");
System.out.println("src attribute is : " + src);
// new DownloadImageTask((ImageView)
// findViewById(R.id.imageView1)).execute(src);
try {
returnedBitmap = new LoadImage().execute(src).get();
// imageView1.setImageBitmap(returnedBitmap);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ImageView iv = new ImageView(this);
iv.setImageBitmap(returnedBitmap);
return iv;
}
public TextView geneterTextView(String textContent){
// Will need to run via background thread.
Log.i("In TEXT ", " " + textContent);
TextView tv = new TextView(this);
tv.setText(Html.fromHtml(textContent));
return tv;
}
// to download images
private class LoadImage extends AsyncTask<String, String, Bitmap> {
#Override
protected void onPreExecute(){
super.onPreExecute();
}
protected Bitmap doInBackground(String... args){
try {
bitmap = BitmapFactory.decodeStream((InputStream) new URL(args[0]).getContent());
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
protected void onPostExecute(Bitmap image){
if (image != null) {
} else {
Toast.makeText(MainActivity.this, "Image Does Not exist or Network Error", Toast.LENGTH_SHORT).show();
}
}
}
// to login to parse
private void login(final String username, String password){
ParseUser.logInInBackground(username, password, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException e){
if (e == null) {
// if login sucess
// Start intent
// loginSuccess();
Toast.makeText(MainActivity.this, "Success", Toast.LENGTH_SHORT).show();
CloudCallStudentPosts(user);
} else {
Toast.makeText(MainActivity.this, "Failure", Toast.LENGTH_SHORT).show();
}
}
});
}
// //to get data from parse
public void CloudCallStudentPosts(ParseObject s){
setRichStory(s);
}
private void setRichStory(ParseObject s){
// Simialr to setStory, once implemented delete setStory()
new AddStoryAsync(s).execute();
}
class AddStoryAsync extends AsyncTask<Void, Object, Void> {
private static final String TAG = "LazyListView";
ParseObject s;
public AddStoryAsync(ParseObject s) {
this.s = s;
Log.w("In richStory", "ParseObject Id: " + s.getObjectId());
}
#Override
protected void onPreExecute(){
}
#Override
protected Void doInBackground(Void... unused){
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("userid", this.s.getObjectId());
params.put("skip", 0);
ParseCloud.callFunctionInBackground("studentsPosts", params, new FunctionCallback<List<List<ParseObject>>>() {
#Override
public void done(List<List<ParseObject>> postList, com.parse.ParseException arg1){
if (postList == null) {
} else {
if (postList.size() > 0) {
// CustomWebView cwb;
for (int i = 0; i < postList.size(); i++) {
// final Post post = new Post();
if (postList.get(i).get(0).get("htmlContent") == null) {
}
if (postList.get(i).get(0).get("htmlContent") != null) {
Log.e("htmlContent parse", postList.get(i).get(0).get("htmlContent").toString());
// Parse HTML String using JSoup library
String HTMLSTring = postList.get(i).get(0).get("htmlContent").toString();
Document html = Jsoup.parse(HTMLSTring);
Elements paragraphs = html.getElementsByTag("p");
for (org.jsoup.nodes.Element paragraph : paragraphs) {
String paragraphText = paragraph.toString();
Log.e("paragraphText", paragraphText);
heightList.add(paragraphText);
}
loopThroughArrayAndAttach();
}
}
}
}
}
});
return (null);
}
#Override
protected void onProgressUpdate(Object... object){
Log.w("onProgressUpdate ", " " + object[0].getClass());
Log.w("adding to arrayPostList ", " " + object[0].getClass());
}
#Override
protected void onPostExecute(Void unused){
}
}
}
Is there any substitute for getting the bitmap from the AsyncTask and set it in the imageview? Should there be a logical alteration in the approach?
try this :
dont call get() #praveen. instead pass the imageview Reference in the constructor
WorkerThread mWorkerThread = new WorkerThread(mImageView);
mWorkerThread.execute(src);
private class WorkerThread extends AsyncTask<String, String, Bitmap> {
private WeakReference<ImageView> imageViewReference;
public WorkerThread(ImageView imageView) {
super();
imageViewReference = new WeakReference<ImageView>(imageView);
}
#Override
protected Bitmap doInBackground(String... args) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream((InputStream) new URL(args[0]).getContent());
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (result != null && imageViewReference.get() != null) {
imageViewReference.get().setImageBitmap(result);
}
}
}
Don't call get() method on AsyncTask it makes main thread to wait for AsyncTask to complete. If you really want to start something only after AsyncTask completes put that into onPostExecute() of your AsynTask
As others have mentioned, your code has several design flaws which makes it difficult to provide you a solution to your problem.
The whole purpose of an AsyncTask is to execute on a background thread. Executing networking and bitmap processing on the main thread will never work. You must refactor your code to accommodate this. Consider the following solution to this particular problem at least:
// to download images
private class LoadImage extends AsyncTask<String, Void, Bitmap> {
protected Bitmap doInBackground(String... args) {
String imgContent = args[0];
Document doc = Jsoup.parse(imgContent);
Elements img = doc.getElementsByTag("img");
for (Element el : img) {
String src = el.absUrl("src");
System.out.println("src attribute is : " + src);
try {
return BitmapFactory.decodeStream((InputStream) new URL(src).getContent());
} catch (Exception e) {
// log
}
}
return null;
}
protected void onPostExecute(Bitmap b) {
ImageView iv = new ImageView(MainActivity.this);
iv.setImageBitmap(b);
llInner.addView(iv);
}
}
You can then do something like:
for (int i = 0; i < heightList.size(); i++) {
new LoadImage(heightList.get(i)).execute();
}
However, this may not be desirable depending on how many AsyncTasks you end up creating. But this is the idea.
I am trying to upload a file from dropbox in another activity from where i autenticate to dropbox. I have this RegisterActivity.java where the user registers and then later when the registration is completed the webbrowser comes up and the user has to allow the dropbox authentication.
later in my app on another activity the user is going to upload a video to dropbox. the upload is made by ASyncTask and works well. The problem is now that i dont want to reauthenticate again. How do i fix that? Is it on the same session or do i start a new session? Now Iam trying to use the sam mDBApi form RegisterAcitivity but i think that is wrong. The keys are stored in the storeKeys() method and saves them in SharedPreferences.
Thank you very much in advance
Here is my RegisterActivity in pastebin which works. http://pastebin.com/K06JUWXv
Here is the activity that where i call my ASyncTask UploadFile:
public class ShowVideo extends Activity{
final static private String ACCOUNT_PREFS_NAME = "prefs";
final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";
private DropboxAPI<AndroidAuthSession> mDBApi = RegisterActivity.mDBApi;
private String[] storedKeys = getKeys();
UploadFile upload;
public static String path = "";
public static String fileName;
private VideoView ww;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); //Forces landscape orientation which is what the camera uses.
setContentView(R.layout.showvideo);
Button yesButton = (Button) findViewById(R.id.yesButton);
Button noButton = (Button) findViewById(R.id.NoButton);
Button dbButton = (Button) findViewById(R.id.dropboxButton);
dbButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
if(v.getId() == R.id.dropboxButton){
if (mDBApi.getSession().isLinked() == true){
Log.d("ShowVideo", "TRUE");
}
if (mDBApi.getSession().isLinked() == false){
Log.d("ShowVideo", "FALSE");
}
}
}
});
yesButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(v.getId() == R.id.yesButton){
UploadFile upload = new UploadFile(ShowVideo.this,mDBApi,path);
upload.execute();
}
}
});
noButton.setOnClickListener(new OnClickListener() {
public void onClick(View w) {
File file = new File(path);
boolean deleted = false;
deleted = file.delete();
Log.e("TAG", Boolean.toString(deleted));
Intent intent = new Intent(ShowVideo.this, CaptureVideo.class);
startActivity(intent);
}
});
ww = (VideoView) findViewById(R.id.satisfiedVideoView);
path = getRealPathFromURI(CaptureVideo.uriVideo);
fileName = getFileNameFromUrl(path);
//AndroidAuthSession session = new AndroidAuthSession(new AppKeyPair(ret[0], ret[1]), AccessType.APP_FOLDER);
//mDBApi = new DropboxAPI<AndroidAuthSession>(session);
}
private void playVideo(){
ww.setVideoURI(CaptureVideo.uriVideo);
ww.setMediaController(new MediaController(this));
ww.start();
ww.requestFocus();
}
public static String getFileNameFromUrl(String path) {
String[] pathArray = path.split("/");
return pathArray[pathArray.length - 1];
}
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
/**DROPBOX-METHOD------------------------------------------*/
private String[] getKeys() {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
String key = prefs.getString(ACCESS_KEY_NAME, null);
String secret = prefs.getString(ACCESS_SECRET_NAME, null);
if (key != null && secret != null) {
String[] ret = new String[2];
ret[0] = key;
ret[1] = secret;
return ret;
} else {
return null;
}
}
}
Here is my ASyncTask if you would take a look at that. Shouldn't be needed.
public class UploadFile extends AsyncTask<Void, Long, Boolean> {
DropboxAPI<AndroidAuthSession> dDBApi;
Context dContext;
private String SAVE_PATH;
public UploadFile(Context context,DropboxAPI<AndroidAuthSession> mDBApi, String path) {
dContext = context.getApplicationContext();
dDBApi = mDBApi;
SAVE_PATH = path;
}
#Override
protected Boolean doInBackground(Void... params) {
FileInputStream inputStream = null;
try {
File file = new File(SAVE_PATH);
inputStream = new FileInputStream(file);
Entry newEntry = dDBApi.putFileOverwrite("/GAMES/GAME_BETWEEN_USER_A_USER_B/" + "PresentVideo.mp4", inputStream, file.length(), null);
}
catch (DropboxException e) {
Log.e("DbExampleLog", "Something went wrong while uploading.");
} catch (FileNotFoundException e) {
Log.e("DbExampleLog", "File not found.");
} catch (IOException e) {
Log.e("DbExampleLog", "Another Exception:" + e.getMessage());
e.printStackTrace();
} catch (Exception e) {
Log.e("DbExampleLog", "Another Exception:" + e.getMessage());
e.printStackTrace();
}
finally {
if (inputStream != null) {
try {
inputStream.close();
}
catch (IOException e) {
}
}
}
return null;
}
}
Currently, I have 20 magazine issues and issue 20 has been downloaded and saved into my internal memory.
When I remove issue 20 from the database (including its cover page and url links), the front page would only show 19 issues and by right, issue 20's data should be removed but it does not.
When I read issue 19, data from issue 20 appears. How do I make sure that when issue 20 is removed from database, it's downloaded data should also be removed from my app when user clicks on the refresh button?
This is how I refresh my cover images:
/** REFRESH BUTTON CLICKED **/
ImageButton refresh = (ImageButton) findViewById(R.id.btn_refresh);
refresh.setVisibility(Button.VISIBLE);
refresh.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
deleteCovers();
urlList.clear();
thumbnailList.clear();
previewList.clear();
File strPath = new File(Environment.getExternalStorageDirectory() + folderName+"Covers");
if(!strPath.exists())
{
new downloadCoverImage().execute();
}
}});
This is how I download my magazine covers:
/**
* Background Async Task to Load all product by making HTTP Request
* */
class downloadCoverImage extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(Store.this);
progressDialog.setMessage("Loading.." + "\n" + "加载中..");
progressDialog.setIndeterminate(false);
progressDialog.setCancelable(false);
progressDialog.show();
}
/**
* getting all magazines from url
* */
protected String doInBackground(String... args) {
URL myFileUrl = null;
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_magazine, "GET", params);
// Check your log cat for JSON reponse
Log.d("All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
mag = json.getJSONArray(TAG_MAGAZINE);
for (int i = 0; i < mag.length(); i++) {
JSONObject c = mag.getJSONObject(i);
// Storing each json item in variable
String magLink = c.getString(TAG_MAGAZINE_URL);
String magThumb = c.getString(TAG_MAGAZINE_THUMBNAIL);
urlList.add(magLink);
thumbnailList.add(magThumb);
//System.out.println(thumbnailList);
}
}
else {
}
} catch (JSONException e) {
e.printStackTrace();
}
for (int i = 0; i < thumbnailList.size(); i ++)
{
thumbnail = thumbnailList.get(i).toString();
Log.d("thumbnail", thumbnail);
Log.d("i value",String.valueOf(i));
try {
myFileUrl = new URL(thumbnail); // RETRIEVE IMAGE URL
}
catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream in = conn.getInputStream();
Log.i("im connected", "Download");
bmImg = BitmapFactory.decodeStream(in);
File filename;
try {
// GET EXTERNAL STORAGE, SAVE FILE THERE
File storagePath = new File(Environment.getExternalStorageDirectory(),folderName+"/Covers");
storagePath.mkdirs();
filename = new File(storagePath + "/cover"+i+".jpg");
FileOutputStream out = new FileOutputStream(filename);
bmImg.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
MediaStore.Images.Media.insertImage(getContentResolver(),filename.getAbsolutePath(), filename.getName(),
filename.getName());
// displayImage();
} catch (Exception e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
progressDialog.dismiss();
displayImage();
}
This is how I display my image:
public void displayImage()
{
mStringList= new ArrayList<String>();
File strPath = new File(Environment.getExternalStorageDirectory() + folderName+"/Covers");
int lists = strPath.listFiles().length;
Log.d("number of items in /Futsing/Covers ",String.valueOf(lists));
File yourDir = new File(strPath, "");
for (File f : yourDir.listFiles()) {
if (f.isFile())
{
String name = f.getName();
String v = strPath + "/" + name;
mStringList.add(v);
}
}
mImageIds = new String[mStringList.size()];
mImageIds = mStringList.toArray(mImageIds);
for(int i = 0; i < mImageIds.length ; i++){
//Log.d("string is",(mImageIds[i]));
}
coverFlow = (CoverFlow) findViewById(R.id.coverFlow1);
coverFlow.setAdapter(new ImageAdapter(this));
coverImageAdapter = new ImageAdapter(this);
coverFlow.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
if(process==false)
{
adapter.clear();
File sdCard1 = Environment.getExternalStorageDirectory();
File dir1 = new File (sdCard1.getAbsolutePath() + folderName+"/issue"+issueNumber+"/");
/** IF FILE EXISTS **/
if(dir1.exists())
{
Intent intent = new Intent();
intent.setClass(Store.this, Reader.class);
intent.putExtra("issue", issueNumber);
startActivityForResult(intent, GET_INTENT_CODE);
}
else
{
new LoadPreview().execute();
}
}else{
// nothing to do here it means the process is running
}
}
}
);
coverFlow.setOnItemSelectedListener(new OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> parent, View view, final int position, long i)
{
pos=position;
issueNumber = (mImageIds.length-1 - position)+1;
adapter.clear();
buttonsCheck();
// TODO Auto-generated method stub
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
}
File t=new File("/data/data/com.example.appname/temp/");//delete from internal memory
File t1=new File("/mnt/sdcard/foldername/");//delete from external memory
DeleteWholeDirectory.deleteWholeDirectory(t);
DeleteWholeDirectory.deleteWholeDirectory(t);
public static void deleteWholeDirectory(File fileOrDirectory) {
if (fileOrDirectory.isDirectory())
for (File child : fileOrDirectory.listFiles()) {
child.delete();
deleteWholeDirectory(child);
}
fileOrDirectory.delete();
}
the above code for delete folder