I am trying to download some files in background, for that I used download manager and I made this method:
/*** media download ***/
public long mediaDownload(ArrayList<DownloadedFile> arrayList, String foldPathName) {
long downloadReference = 0;
// Create request for android download manager
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
for (int i = 0; i < arrayList.size();i++){
DownloadManager.Request request = new DownloadManager.Request(arrayList.get(i).getUri());
request.setTitle("Data Download");
request.setDescription("New media");
//Set the local destination for the downloaded file to a path
//within the application's external files directory
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS + "/" + folder_main + "/" + foldPathName, arrayList.get(i).getName());
File f = new File(Environment.DIRECTORY_DOWNLOADS + "/" + folder_main + "/" + foldPathName + "/" + arrayList.get(i).getName());
Log.e("File:",f.toString());
//Enqueue download and save into referenceId
downloadReference = downloadManager.enqueue(request);
}
return downloadReference;
}
I have a picture and a Video to download for test, and when checking downloaded file in Explorer I find 2 videos and 2 picture, debug that I found that onPostExecute method is called twice and I can't figure out why.
Here is my onPostExecute method:
protected void onPostExecute(String s) {
try {
JSONObject jsonObject = new JSONObject(s);
JSONArray region = null;
region = jsonObject.getJSONArray("regions");
Log.e("Regions:", String.valueOf(region.length()));
for (int i = 0; i < region.length(); i++) {
try {
JSONObject json_data = region.getJSONObject(i);
int height_view = Integer.parseInt(json_data.getString("height"));
int width_view = Integer.parseInt(json_data.getString("width"));
int left_view = Integer.parseInt(json_data.getString("left"));
int top_view = Integer.parseInt(json_data.getString("top"));
int right_view = Integer.parseInt(json_data.getString("right"));
int bottom_view = Integer.parseInt(json_data.getString("bottom"));
/**** Media in region ***/
JSONObject media = json_data.getJSONObject("media");
String type_media = media.getString("type");
url = media.getString("url");
name = media.getString("name");
uri = Uri.parse(url);
} catch (JSONException e) {
e.printStackTrace();
}
downloadedFiles.add(new DownloadedFile(name, uri));
}
Toast.makeText(MainActivity.this, "Layout Created with" + height + "x" + width, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
Log.e("Downloaded Files:",downloadedFiles.toString());
mediaDownload(downloadedFiles, folderName); // region media's download
}
On my logcat I see that my arrayList has 2 elements, but displayed twice, which means files are downloaded twice so the onPostExecute method called 2 times, thanks for help.
I figured out after passing my time debugging all the code, when the activity is created it changes the screen orientation and so it creates a second instance, so my AsyncTask is called twice and thats why i thought onPosteExecute is called twice, thanks for everyone who tried to help.
Related
I am trying to make an app that sends files from my Android Watch to my Android Phone.
The problem I have is that if I record and save multiple files and send all of them at the same time, I do not get all the files back on the phone side. I only receive one file.
The code for sending the file is as follows. This code is implemented on the Watch side.:
public void sendData(View v){
String fname = "_Activity.bin";
int FileCounterCopy = FileCounter;
if(mGoogleApiClient.isConnected()){
for (int i = 0; i < FileCounterCopy ; i++){
String FileName = String.valueOf(i) + fname;
File dataFile = new File(Environment.getExternalStorageDirectory(), FileName);
Log.i("Path", Environment.getExternalStorageDirectory().toString());
Log.i("file", dataFile.toString());
Asset dataAsset = createAssetfromBin(dataFile);
sensorData = PutDataMapRequest.create(SENSOR_DATA_PATH);
sensorData.getDataMap().putAsset("File", dataAsset);
PutDataRequest request = sensorData.asPutDataRequest();
Wearable.DataApi.putDataItem(mGoogleApiClient, request).setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
#Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.e("SENDING IMAGE WAS SUCCESSFUL: ", String.valueOf(dataItemResult.getStatus().isSuccess()));
}
});
boolean deleted = dataFile.delete();
Log.i("Deleted", String.valueOf(deleted));
FileCounter--;
}
mTextView.setText(String.valueOf(FileCounter));
Return();
}
else {
Log.d("Not", "Connecteddddddddd");
}
}
The code for receiving the files is as follows and is implemented on the phone side.
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
Counter++;
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
dataEvents.close();
Log.e("List Size: ", String.valueOf(events.size()));
for (DataEvent event : events) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
Log.v("Data is changed", "========================");
String path = event.getDataItem().getUri().getPath();
if (SENSOR_DATA_PATH.equals(path)) {
DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
fileAsset = dataMapItem.getDataMap().getAsset("File");
myRunnable = createRunnable();
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
new Thread(myRunnable).start();
}
}
}
status.setText("Received" + " File_"+ String.valueOf(Counter) );
}
Right before the for loop, I check the size of the event and it only shows a size of 1, no matter how many files I save.
I am stuck on how to implement this (tbh I used code from youtube video/online resources so I am not 100% sure on how some of the api works).
Thanks in advance!
You're putting all of the files at the same path, with nothing to differentiate them - so each one you put in overwrites the previous ones. The Data API works much like a filesystem in this regard.
In your sendData method, you need code something like this:
sensorData = PutDataMapRequest.create(SENSOR_DATA_PATH + '/' + dataFile.toString());
And then in onDataChanged, either only check the path prefix...
if (path.startsWith(SENSOR_DATA_PATH)) {
...or, preferably, put the value of SENSOR_DATA_PATH in your manifest declaration as an android:pathPrefix element in the intent-filter of your data receiver. You can then remove the path check from your Java code completely. Docs for that are here: https://developers.google.com/android/reference/com/google/android/gms/wearable/WearableListenerService
One other thing: it's good practice to clear stuff like these files out of the Data API when you're done using them, so that they're not taking up space there.
When I insert the videos serially, all the videos get inserted to the playlist but it takes a long time. When I use multithreading more than half of the videos are missing in the end. How can I insert multiple videos quickly without losing any videos?
// Insert videos. 5 videos per asyncTask
List<List<YTVideo>> chunks = Lists.partition(videos, 5);
for (int i = 0; i < chunks.size(); i++) {
videoAndPlaylistContainer container = new videoAndPlaylistContainer();
container.playlistId = playlistId;
List<YTVideo> chunk = chunks.get(i);
container.videos = chunk;
InsertPlayListItemTask insertPlaylistItemsTask = new InsertPlayListItemTask();
runningTasks.add(insertPlaylistItemsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,container));
}
.
private class InsertPlayListItemTask extends AsyncTask<videoAndPlaylistContainer, Void, Void>{
#Override
protected Void doInBackground(videoAndPlaylistContainer... params) {
videoAndPlaylistContainer container = params[0];
List<YTVideo> videosChunk = container.videos;
String playlistId = container.playlistId;
for (int i = 0; i < videosChunk.size(); i++) {
YTVideo video = videosChunk.get(i);
String videoId = video.getId();
long pos = video.getPosition();
try {
ResourceId resourceId = new ResourceId();
resourceId.setKind("youtube#video");
resourceId.setVideoId(videoId);
PlaylistItemSnippet playlistItemSnippet = new PlaylistItemSnippet();
// playlistItemSnippet.setTitle("First video in the test playlist");
playlistItemSnippet.setPlaylistId(playlistId);
playlistItemSnippet.setResourceId(resourceId);
playlistItemSnippet.setPosition(pos);
PlaylistItem playlistItem = new PlaylistItem();
playlistItem.setSnippet(playlistItemSnippet);
YouTube.PlaylistItems.Insert playlistItemsInsertCommand =
youtube.playlistItems().insert("snippet", playlistItem);
playlistItemsInsertCommand.execute();
System.out.println("Inserted video: " + video);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
edit: videos.size() to chunks.size(). Removed insertedCount++;
This line doesn't look right...
for (int i = 0; i < videos.size(); i++) {
The i variable will grow based on the size of the videos collection, but you only ever use the i variable to access an element within the chunks collection here...
List<YTVideo> chunk = chunks.get(i);
I can't imagine why you don't (eventually) get an ArrayIndexOutOfBounds exception, except maybe you're testing your code (so far) with fewer than 5 videos.
I have an Android app.
First, the app do sync process. In this process, the server sends to the device an JSON object as String by which it can build the available questionnaires.
GetQuestionnairesResponse.java:
public class GetQuestionnairesResponse extends ResponseHandler
{
public GetQuestionnairesResponse(String result, AsyncRequest request)
{
super(result, request);
}
#Override
public void handleResponse()
{
DataSyncActivity caller = (DataSyncActivity) request.getCaller();
BackgroundManager bckMng = BackgroundManager.getInstance(caller);
PreferencesManager preference = PreferencesManager.getInstance(null);
boolean status = true;
int numOfWrongJsonVer = 0;
int totalNumOfQuestionnaires = 0;
// Handle data from server
// Creating JSON Parser instance
try
{
QuestionnaireDataSource questionnaireDS = new QuestionnaireDataSource(caller);
questionnaireDS.open();
JSONArray jArr = new JSONArray(result);
JSONObject j = null;
totalNumOfQuestionnaires = jArr.length();
for (int i = 0; i < jArr.length(); i++)
{
j = jArr.getJSONObject(i);
long questId = j.getLong("questionnaireId");
long surveyId = j.getLong("surveyId");
String questName = j.getString("name");
String desc = j.getString("description");
int version = j.getInt("questionnaireVersion");
int jsonVersion = j.getInt("jsonVersion");
if (jsonVersion == PreferencesManager.jsonVersion)
{
// Save the pages part
String filename = questId + "_" + version + "_" + jsonVersion + ".json";
HelpFunctions.writeJSON(filename, j.toString());
Questionnaire quest = questionnaireDS.createQuestionnaire(questId, questName, desc, surveyId, version, jsonVersion, filename);
if (quest == null)
throw new RuntimeException("Cant save the questionnaire: " + questName);
}
else
{
numOfWrongJsonVer ++;
}
}
questionnaireDS.close();
}
catch (Exception e)
{
status = false;
if (e.getMessage() != null)
Log.e(TAG, e.getMessage());
}
caller.setInSync(false);
...
}
The result i get from the server i parse it to Json array.
The result in some cases can bee 3 megabytes.
The solution I found was to add an attribute in manifest.xml:
android:largeHeap="true"
It solved the problem. I don't know why but the problem returned again in the last day.
I will be happy to get suggestions how to solve the problem.
The problem is that the json object not parsed as expected so it
If the JSON was originally 3 MB and you call toString() on the JSONObject parsed from it, the JSONObject is still taking up memory, plus it's going to need to do a 3 MB allocation to hold the String. You may not have that much memory available.
But the thing about OutOfMemoryError is that the allocation that uses up the last bit of RAM isn't necessarily to blame for there being so little RAM available. Big allocations are just more likely to be the thing that pushes it over the edge. It's likely that you have a memory leak somewhere else in your app, and you'll need to use a tool like Eclipse MAT to find it.
Good Morning,
I’am using Jacob 1.17 o read all my Outlook Contact Pictures and save them to an File. The Procedure works pretty fine for the first 199 Contatcs. After that the Dispatch.call fails and terminates with the following Exception:
Exception in thread "main" com.jacob.com.ComFailException: Invoke of: SaveAsFile
Source: Microsoft Outlook
Description: Cannot save the attachment. Cannot create file: ContactPicture.jpg.
Right-click the folder you want to create the file in, and then click Properties on
the shortcut menu to check your permissions for the folder.
at com.jacob.com.Dispatch.invokev(Native Method)
at com.jacob.com.Dispatch.invokev(Dispatch.java:625)
at com.jacob.com.Dispatch.callN(Dispatch.java:453)
at com.jacob.com.Dispatch.call(Dispatch.java:541)
at outlookStuff.ManageContactsOutlook.tmpTest(ManageContactsOutlook.java:217)
at mainPackage.Main.main(Main.java:32)
I’m really not sure way. I tested a different set of Contacts – same Error. Set all Objects to null to make shore that the Garbage Collector is involved but it doesn’t help.
The piece of Code which makes the trouble:
public void tmpTest(int intOutlookFolder, String strWorkingDir) {
Dispatch dipNamespace = this.axc.getProperty("Session").toDispatch();
Dispatch dipContactsFolder = Dispatch.call(dipNamespace, "GetDefaultFolder", (Object) new Integer(intOutlookFolder)).toDispatch();
Dispatch dipContactItems = Dispatch.get(dipContactsFolder, "items").toDispatch();
#SuppressWarnings("deprecation")
int count = Dispatch.call(dipContactItems, "Count").toInt();
for (int i=1; i<=count; i++) {
Dispatch dipContact;
dipContact = Dispatch.call(dipContactItems, "Item", new Integer(i)).toDispatch();
String strEntryID = Dispatch.get(dipContact, "EntryID").toString().trim();
//For Testing
Status.printStatusToConsole("Outlook Contact "+strEntryID+" loaded");
byte[] byteContactPicture = null;
String strPathToTmpPicture = null;
Dispatch dipAttachments = Dispatch.get(dipContact, "Attachments").toDispatch();
#SuppressWarnings("deprecation")
int countAttachements = Dispatch.call((Dispatch) dipAttachments, "Count").toInt();
for (int j=1; j<=countAttachements; j++) {
Dispatch currentAttachement;
currentAttachement = Dispatch.call(dipAttachments, "Item", new Integer(j)).toDispatch();
if (Dispatch.get(currentAttachement, "FileName").toString().equals("ContactPicture.jpg")) {
strPathToTmpPicture = strWorkingDir+strEntryID+".jpg";
//The Crashing Part
Dispatch.call(currentAttachement, "SaveAsFile", strPathToTmpPicture);
File tmpFile = new File(strPathToTmpPicture);
if (tmpFile.exists()) {
try {
byteContactPicture = org.apache.commons.io.FileUtils.readFileToByteArray(tmpFile);
} catch (IOException e) {
e.printStackTrace();
}
}
currentAttachement = null;
tmpFile = null;
}
currentAttachement = null;
}
dipAttachments = null;
}
dipContactItems = null;
dipContactsFolder = null;
dipNamespace = null;
}
May someone has an idea?
Thanks
Aviation
I'm pretty new to Django and Japplet, this is my first project with them.
The Japplet takes some images from the django static folder, and permits the user to add some lines and markers.
At the end of this, when the button "save" on the JApplet is clicked, it should do some POST call to the Django server, to save the markes and lines.
Actually I'm only testing with markers, and I can't get it done.
Here is the Model of a marker:
class Point(models.Model):
id_edificio = models.ForeignKey(Building)
RFID = models.CharField(max_length=200)
x = models.IntegerField()
y = models.IntegerField()
piano = models.IntegerField()
ingresso = models.BooleanField()
His View:
def point(request, id_edificio, RFID, x, y, piano):
point = csrf_exempt(point)
if request.method == 'POST':
get_object_or_404(Building, pk=id_edificio)
p = Point()
p.id_edificio = id_edificio
p.RFID = RFID
p.x = x
p.y= y
p.piano = piano
p.ingresso = True
p.save()
I haven't implemented a template, because I don't need access to this view with web browser.
Urls:
url(r'^buildings/generate/point', 'buildings.views.point'),
JApplet save method:
private void saveData(MarkerArrayList markers, PathArrayList paths) {
String response;
URL endpoint = null;
try {
endpoint = new URL("http://127.0.0.1:8000/buildings/generate/point");
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
for(Marker m: markers) {
Reader data = new StringReader("id_edificio="+id_building+"&"+m.toString());
try {
Post.postData(data, endpoint);
} catch (Exception e) {e.printStackTrace();}
}
}
Marker toString() method:
public String toString() {
return "RFID="+ RFID + "&" +
"x=" +
"y=" + y + "&" +
"piano=" + floor + "&";
}
I assume that my java method Post is correct. If you want to see it, ask me ;)
Error from Django server on POST:
[28/Sep/2012 07:21:46] "POST /buildings/generate/point HTTP/1.1" 403 2294
I don't know wath to try know, I'm in your hands.
Tahnk you
The number of errors was totally incredible.
So this is the new View for markers, for now I will ignore csrf token:
#csrf_exempt
def point(request):
if request.method == 'POST':
p = Point()
building = Building.objects.get(pk = request.POST["id_edificio"])
p.id_edificio = building
p.RFID = request.POST["RFID"]
p.x = request.POST["x"]
p.y= request.POST["y"]
p.piano = request.POST["piano"]
p.ingresso = request.POST["ingresso"]
p.save()
And it works! There was also minor errors in Marker toString() method (as 'X' instead of 'x'), but they were only minor errors.