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;
}
}
Related
I'm parsing a json to display a list of files a user can tap to download. I want to display the files the users have chosen to download on my main screen. this is the code when they download a file.
public final class Main extends Activity {
// Log tag for this class
private static final String TAG = "Main";
// Callback code for request of storage permission
final private int PERMISSIONS_REQUEST_STORAGE = 735;
// JSON Node Names
private static final String TAG_TYPE = "plans";
private static final String TAG_NAME = "name";
private static final String TAG_FILENAME = "filename";
private static final String TAG_URL = "url";
private static final String TAG_SHOULD_NOT_CACHE = "shouldNotCache";
// Files to delete
private static final ArrayList<String> filesToGetDeleted = new ArrayList<>();
// Strings displayed to the user
private static String offline;
private static String noPDF;
private static String localLoc;
private static String jsonURL;
// PDF Download
private static DownloadManager downloadManager;
private static long downloadID;
private static File file;
#SuppressLint("StaticFieldLeak")
private static SwipeRefreshLayout swipeRefreshLayout;
private final BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent arg1) {
final DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadID);
final Cursor cursor = downloadManager.query(query);
if (cursor.moveToFirst()) {
final int columnIndex = cursor
.getColumnIndex(DownloadManager.COLUMN_STATUS);
final int status = cursor.getInt(columnIndex);
switch (status) {
case DownloadManager.STATUS_SUCCESSFUL:
final Uri path = Uri.fromFile(file);
final Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(pdfIntent);
} catch (ActivityNotFoundException e) {
Utils.makeLongToast(Main.this, noPDF);
Log.e(TAG, e.getMessage());
}
break;
case DownloadManager.STATUS_FAILED:
Utils.makeLongToast(Main.this,
getString(R.string.down_error));
break;
case DownloadManager.STATUS_PAUSED:
Utils.makeLongToast(Main.this,
getString(R.string.down_paused));
break;
case DownloadManager.STATUS_PENDING:
Utils.makeLongToast(Main.this,
getString(R.string.down_pending));
break;
case DownloadManager.STATUS_RUNNING:
Utils.makeLongToast(Main.this,
getString(R.string.down_running));
break;
}
}
}
};
// Data from JSON file
private ArrayList<HashMap<String, String>> downloadList = new ArrayList<>();
private static void checkDir() {
final File dir = new File(Environment.getExternalStorageDirectory() + "/"
+ localLoc + "/");
if (!dir.exists()) dir.mkdir();
}
#Override
protected void onResume() {
super.onResume();
final IntentFilter intentFilter = new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(downloadReceiver, intentFilter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(downloadReceiver);
}
#Override
protected void onDestroy() {
super.onDestroy();
// Delete files which should not get cached.
for (String file : filesToGetDeleted) {
final File f = new File(file);
if (f.exists()) {
f.delete();
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_STORAGE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Utils.makeLongToast(Main.this, getString(R.string.permission_write_external_storage_success));
}
else {
final String permission_write_external_storage_failure = getString(R.string.permission_write_external_storage_failure);
final String app_title = getString(R.string.app_name);
final String message = String.format(permission_write_external_storage_failure, app_title);
Utils.makeLongToast(Main.this, message);
boolean showRationale = ActivityCompat.shouldShowRequestPermissionRationale(Main.this, permissions[0]);
if (!showRationale) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
}
break;
}
}
private void update(boolean force, boolean firstLoad) {
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout_main);
offline = getString(R.string.status_offline);
noPDF = getString(R.string.except_nopdf);
localLoc = getString(R.string.gen_loc);
jsonURL = getString(R.string.gen_json);
checkDir();
if (firstLoad) {
try {
downloadList = (ArrayList<HashMap<String, String>>) Utils.readObject(this, "downloadList");
if (downloadList != null) {
setList(true, true);
}
} catch (ClassNotFoundException | IOException e) {
Log.e(TAG, e.getMessage());
}
}
// Parse the JSON file of the plans from the URL
JSONParse j = new JSONParse();
j.force = force;
j.online = !Utils.isNoNetworkAvailable(this);
j.execute();
}
private void setList(final boolean downloadable, final boolean itemsAvailable) {
if (itemsAvailable) {
try {
Utils.writeObject(this, "downloadList", downloadList);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
final ListView list = (ListView) findViewById(R.id.listView_main);
final ListAdapter adapter = new SimpleAdapter(this, downloadList,
android.R.layout.simple_list_item_1, new String[]{TAG_NAME},
new int[]{android.R.id.text1});
list.setAdapter(adapter);
// React when user click on item in the list
if (itemsAvailable) {
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View v, int pos,
long id) {
int hasStoragePermission = ContextCompat.checkSelfPermission(Main.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (hasStoragePermission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(Main.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST_STORAGE);
return;
}
final Uri downloadUri = Uri.parse(downloadList.get(pos).get(TAG_URL));
final String title = downloadList.get(pos).get(TAG_NAME);
final String shouldNotCache = downloadList.get(pos).get(TAG_SHOULD_NOT_CACHE);
file = new File(Environment.getExternalStorageDirectory() + "/"
+ localLoc + "/"
+ downloadList.get(pos).get(TAG_FILENAME) + ".pdf");
final Uri dst = Uri.fromFile(file);
if (file.exists()) {
final Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(dst, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(pdfIntent);
} catch (ActivityNotFoundException e) {
Utils.makeLongToast(Main.this, noPDF);
Log.e(TAG, e.getMessage());
}
return;
}
if (downloadable && !Utils.isNoNetworkAvailable(Main.this)) {
// Download PDF
final Request request = new Request(downloadUri);
request.setTitle(title).setDestinationUri(dst);
downloadID = downloadManager.enqueue(request);
if (shouldNotCache.equals("true")) {
filesToGetDeleted.add(file.toString());
}
} else {
Utils.makeLongToast(Main.this, offline);
}
}
});
}
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
update(true, false);
}
});
}
private class JSONParse extends AsyncTask<String, String, JSONObject> {
public boolean force = false;
public boolean online = false;
#Override
protected void onPreExecute() {
super.onPreExecute();
swipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
}
});
}
#Override
protected JSONObject doInBackground(String... args) {
return JSONParser.getJSONFromUrl(Main.this, jsonURL, force, online);
}
#Override
protected void onPostExecute(JSONObject json) {
swipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
}
});
downloadList.clear();
if (json == null) {
String error = getString(R.string.except_json);
if (!online) {
error = offline;
}
final HashMap<String, String> map = new HashMap<>();
map.put(TAG_NAME, error);
downloadList.add(map);
setList(false, false);
return;
}
try {
// Get JSON Array from URL
final JSONArray j_plans = json.getJSONArray(TAG_TYPE);
for (int i = 0; i < j_plans.length(); i++) {
final JSONObject c = j_plans.getJSONObject(i);
// Storing JSON item in a Variable
final String ver = c.getString(TAG_FILENAME);
final String name = c.getString(TAG_NAME);
final String api = c.getString(TAG_URL);
String shouldNotCache = "";
if (c.has(TAG_SHOULD_NOT_CACHE)) {
shouldNotCache = c.getString(TAG_SHOULD_NOT_CACHE);
}
// Adding value HashMap key => value
final HashMap<String, String> map = new HashMap<>();
map.put(TAG_FILENAME, ver);
map.put(TAG_NAME, name);
map.put(TAG_URL, api);
map.put(TAG_SHOULD_NOT_CACHE, shouldNotCache);
downloadList.add(map);
setList(online, true);
}
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
}
}
}
SO how do I get the result of the above code and display it on main screen every time the user opens app
I know how to Write and Read data from External Storage, I don't know How to encrypt and decrypt this data to my external storage, so that whoever is trying to access that file using file explorer, It should be encrypted.
Here I have written the for storing and reading the data, for which I am using the buttons.
public class SOSActivity extends AppCompatActivity {
public EditText contact1;
Button saveButton, readButton;
private Context context;
public SharedPreferences.Editor editorcache;
private String filename = "SampleFile.txt";
private String filepath = "MyFileStorage";
File myExternalFile;
String myData = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sos);
context = this.getApplicationContext();
saveButton = (Button) findViewById(R.id.save);
contact1 = ((EditText) findViewById(R.id.contact1));
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
FileOutputStream fos = new FileOutputStream(myExternalFile);
fos.write(contact1.getText().toString().getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
// response.setText("SampleFile.txt saved to External
// Storage...");
finish();
}
});
readButton = (Button) findViewById(R.id.read);
readButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
contact1.setText("");
try {
FileInputStream fis = new FileInputStream(myExternalFile);
DataInputStream in = new DataInputStream(fis);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
myData = myData + strLine;
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
contact1.setText(myData);
// response.setText("SampleFile.txt data retrieved from Internal
// Storage...");
}
});
if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
saveButton.setEnabled(false);
} else {
myExternalFile = new File(getExternalFilesDir(filepath), filename);
}
}
private static boolean isExternalStorageReadOnly() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
return true;
}
return false;
}
private static boolean isExternalStorageAvailable() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
return true;
}
return false;
}
}
Follow the link to explore 2-way encryption.
https://stackoverflow.com/a/40175319/2761151
Warning: This method may not work for Android N
I have a little camera app that is storing the image to the Pictures folder:
File photo = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "preview.jpg");
Later I want to copy this Image and save it with a new Filename. Therefore i used this copy function i found here:
private void copyFile(File sourceFile, File destFile) throws IOException {
if (!sourceFile.exists()) {
return;
}
FileChannel source = null;
FileChannel destination = null;
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
if (destination != null && source != null) {
destination.transferFrom(source, 0, source.size());
}
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
The copyFile is called here:
// OLD FILE
File oldFile = new File(imageUri.getPath());
// NEW FILE
File newFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "test123.jpg");
// COPY FILE
copyFile(oldFile,newFile);
But it is doing nothing. Also no Exception or something. What am I doing wrong?
EDIT: Full Code
public class ParticipateActivity extends AppCompatActivity {
private static String logtag = "Camera APP";
private static int TAKE_PICTURE = 1;
private Uri imageUri;
private Bitmap cameraImage;
static final String appDirectoryName = "album name";
static final File imageRoot = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), appDirectoryName);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageRoot.mkdirs();
verifyStoragePermissions(this);
setContentView(R.layout.activity_participate);
Button cameraButton = (Button) findViewById(R.id.camera_button);
Button saveButton = (Button) findViewById(R.id.save_button);
cameraButton.setOnClickListener(cameraListener);
saveButton.setOnClickListener(saveListener);
}
private View.OnClickListener cameraListener = new View.OnClickListener() {
public void onClick(View v) {
takePhoto(v);
}
};
private View.OnClickListener saveListener = new View.OnClickListener() {
public void onClick(View v) {
try {
savePhoto(v);
} catch (IOException e) {
e.printStackTrace();
Log.e(logtag,"Error copying file!");
}
}
};
private void takePhoto(View v) {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
File photo = new File(imageRoot, "preview.jpg");
//Log.e(logtag,"test");
imageUri = Uri.fromFile(photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, TAKE_PICTURE);
}
private Boolean copyFile(File sourceFile, File destFile) throws IOException {
if (!sourceFile.exists()) {
//Log.e(logtag,sourceFile.getAbsolutePath());
return false;
} else {
//Log.e(logtag,sourceFile.getAbsolutePath());
}
FileChannel source = null;
FileChannel destination = null;
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
if (destination != null && source != null) {
try {
destination.transferFrom(source, 0, source.size());
} catch (Exception e) {
e.printStackTrace();
return false;
}
//source.transferTo(0, source.size(), destination);
Log.e(logtag,"transfer started");
}
if (source != null) {
source.close();
} else {return false;}
if (destination != null) {
destination.close();
return true;
} else {return false;}
}
private void savePhoto(View v) throws IOException {
EditText input_name = (EditText) findViewById(R.id.input_name);
EditText input_mail = (EditText) findViewById(R.id.input_mail);
EditText input_phone = (EditText) findViewById(R.id.input_phone);
String name = input_name.getText().toString();
String mail = input_mail.getText().toString();
String phone = input_phone.getText().toString();
if (name.length() != 0 && mail.length() != 0) {
if (phone.length() == 0) {
phone = "NoPhone";
}
// set fileName
String fileName = name + "-" + mail + "-" + phone;
// Log.e(logtag,fileName);
// OLD FILE
File oldFile = new File(imageUri.getPath());
//Log.e(logtag,"Path: " + imageUri.getPath());
// NEW FILE
File newFile = new File(imageRoot, "test123.jpg");
Log.e(logtag,"path: " + newFile.getAbsolutePath());
// COPY FILE
if(oldFile.exists()) {
Boolean copied = copyFile(oldFile,newFile);
Log.e(logtag,copied.toString());
// log text
if(copied) Toast.makeText(ParticipateActivity.this, "Gespeichert!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(ParticipateActivity.this, "Konnte nicht gespeichert werden! Kein Foto?", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(ParticipateActivity.this, "Bitte Name und Email ausfüllen!", Toast.LENGTH_LONG).show();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = imageUri;
getContentResolver().notifyChange(selectedImage, null);
ImageView imageView = (ImageView) findViewById(R.id.image_camera);
ContentResolver cr = getContentResolver();
Bitmap bitmap;
try {
bitmap = MediaStore.Images.Media.getBitmap(cr, selectedImage);
imageView.setImageBitmap(bitmap);
// Change height of image
android.view.ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();
layoutParams.height = (int) getResources().getDimension(R.dimen.imageView_height);
imageView.setLayoutParams(layoutParams);
// Hide Label and Button
TextView uploadText = (TextView) findViewById(R.id.upload_text);
uploadText.setVisibility(View.GONE);
Button uploadButton = (Button) findViewById(R.id.camera_button);
uploadButton.setVisibility(View.GONE);
// Show Image Name
//Toast.makeText(ParticipateActivity.this,selectedImage.toString(),Toast.LENGTH_LONG).show();
} catch (Exception e) {
Log.e(logtag, e.toString());
}
}
}
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
* <p>
* If the app does not has permission then the user will be prompted to grant permissions
*
* #param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
}
I download an image from the internet with a service. When the download is complete it changes the textview. I tried this on my device and it works.
Now i want the imageview in my layout to change to the downloaded image.
ServiceFile java
public class ServiceFile extends IntentService {
private int result = Activity.RESULT_CANCELED;
public static final String URL = "urlpath";
public static final String FILENAME = "filename";
public static final String FILEPATH = "filepath";
public static final String RESULT = "result";
public static final String NOTIFICATION = "be.ehb.arnojansens.fragmentexampleii";
public ServiceFile() {
super("ServiceFile");
}
// will be called asynchronously by Android
#Override
protected void onHandleIntent(Intent intent) {
String urlPath = intent.getStringExtra(URL);
String fileName = intent.getStringExtra(FILENAME);
File output = new File(Environment.getExternalStorageDirectory(),
fileName);
if (output.exists()) {
output.delete();
}
InputStream stream = null;
FileOutputStream fos = null;
try {
java.net.URL url = new URL(urlPath);
stream = url.openConnection().getInputStream();
InputStreamReader reader = new InputStreamReader(stream);
fos = new FileOutputStream(output.getPath());
int next = -1;
while ((next = reader.read()) != -1) {
fos.write(next);
}
// successfully finished
result = Activity.RESULT_OK;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
publishResults(output.getAbsolutePath(), result);
}
private void publishResults(String outputPath, int result) {
Intent intent = new Intent(NOTIFICATION);
intent.putExtra(FILEPATH, outputPath);
intent.putExtra(RESULT, result);
sendBroadcast(intent);
}
}
This is my main activity where i have my textview and the future imageview
private TextView textView;
private ImageView imageView;
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
String string = bundle.getString(ServiceFile.FILEPATH);
int resultCode = bundle.getInt(ServiceFile.RESULT);
if (resultCode == RESULT_OK) {
Toast.makeText(MainActivity.this,
"Download complete. Download URI: " + string,
Toast.LENGTH_LONG).show();
textView.setText("Download done");
// here i shoud load my image i downloaded with my service
} else {
Toast.makeText(MainActivity.this, "Download failed",
Toast.LENGTH_LONG).show();
textView.setText("Download failed");
}
}
}
};
public void service (View view) {
Intent intent = new Intent(this, ServiceFile.class);
// add infos for the service which file to download and where to store
intent.putExtra(ServiceFile.FILENAME, "index.html");
intent.putExtra(ServiceFile.URL,
"http://en.wikipedia.org/wiki/Star_Wars#mediaviewer/File:Star_Wars_Logo.svg");
startService(intent);
textView.setText("Service started");
}
Better to use Picasso or Universal Image Loader than to pass the information per Intent.
If not, your service should write the image into a readable folder and you can send by intent the Uri to that file to whom it concerns with EventBus for instance
The following app upload video to Dropbox when it is start, I added finish() in the end of onCreate to exit the app when its completed the uploading, but I got "Unfortunately, DBRoulette has stopped.".
In the Eclipse LogCat:
Activity com.dropbox.android.sample.DBRoulette has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView#42a7ee38 that was originally added here
android.view.WindowLeaked: Activity com.dropbox.android.sample.DBRoulette has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView#42a7ee38 that was originally added here
I have Progress viewer which may cause the problem but I don't know how to solve it!
What I want to do is closing the app automatically when the uploading completed.
DBRoulette.java
#SuppressLint("SimpleDateFormat")
public class DBRoulette extends Activity {
private static final String TAG = "DBRoulette";
final static private String APP_KEY = "<My APP_KEY>";
final static private String APP_SECRET = "<My APP_SECRET>";
// You don't need to change these, leave them alone.
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 static final boolean USE_OAUTH1 = false;
DropboxAPI<AndroidAuthSession> mApi;
private boolean mLoggedIn;
// Android widgets
private Button mSubmit;
private RelativeLayout mDisplay;
private Button mGallery;
private ImageView mImage;
private final String PHOTO_DIR = "/Motion/";
#SuppressWarnings("unused")
final static private int NEW_PICTURE = 50;
private String mCameraFileName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mCameraFileName = savedInstanceState.getString("mCameraFileName");
}
// We create a new AuthSession so that we can use the Dropbox API.
AndroidAuthSession session = buildSession();
mApi = new DropboxAPI<AndroidAuthSession>(session);
// Basic Android widgets
setContentView(R.layout.main);
checkAppKeySetup();
mSubmit = (Button) findViewById(R.id.auth_button);
mSubmit.setOnClickListener(new OnClickListener() {
#SuppressWarnings("deprecation")
public void onClick(View v) {
// This logs you out if you're logged in, or vice versa
if (mLoggedIn) {
logOut();
} else {
// Start the remote authentication
if (USE_OAUTH1) {
mApi.getSession().startAuthentication(DBRoulette.this);
} else {
mApi.getSession().startOAuth2Authentication(
DBRoulette.this);
}
}
}
});
mDisplay = (RelativeLayout) findViewById(R.id.logged_in_display);
// This is where a photo is displayed
mImage = (ImageView) findViewById(R.id.image_view);
File outFile = new File("/mnt/sdcard/ipwebcam_videos/video.mov");
mCameraFileName = outFile.toString();
UploadPicture upload = new UploadPicture(DBRoulette.this, mApi, PHOTO_DIR,outFile);
upload.execute();
// Display the proper UI state if logged in or not
setLoggedIn(mApi.getSession().isLinked());
finish();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("mCameraFileName", mCameraFileName);
super.onSaveInstanceState(outState);
}
#Override
protected void onResume() {
super.onResume();
AndroidAuthSession session = mApi.getSession();
if (session.authenticationSuccessful()) {
try {
session.finishAuthentication();
storeAuth(session);
setLoggedIn(true);
} catch (IllegalStateException e) {
showToast("Couldn't authenticate with Dropbox:"
+ e.getLocalizedMessage());
Log.i(TAG, "Error authenticating", e);
}
}
}
private void logOut() {
// Remove credentials from the session
mApi.getSession().unlink();
clearKeys();
// Change UI state to display logged out version
setLoggedIn(false);
}
#SuppressWarnings("deprecation")
public String getRealPathFromURI(Uri contentUri)
{
String[] proj = { MediaStore.Audio.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
private void setLoggedIn(boolean loggedIn) {
mLoggedIn = loggedIn;
if (loggedIn) {
mSubmit.setText("Logout from Dropbox");
mDisplay.setVisibility(View.VISIBLE);
} else {
mSubmit.setText("Login with Dropbox");
mDisplay.setVisibility(View.GONE);
mImage.setImageDrawable(null);
}
}
private void checkAppKeySetup() {
// Check to make sure that we have a valid app key
if (APP_KEY.startsWith("CHANGE") || APP_SECRET.startsWith("CHANGE")) {
showToast("You must apply for an app key and secret from developers.dropbox.com, and add them to the DBRoulette ap before trying it.");
finish();
return;
}
// Check if the app has set up its manifest properly.
Intent testIntent = new Intent(Intent.ACTION_VIEW);
String scheme = "db-" + APP_KEY;
String uri = scheme + "://" + AuthActivity.AUTH_VERSION + "/test";
testIntent.setData(Uri.parse(uri));
PackageManager pm = getPackageManager();
if (0 == pm.queryIntentActivities(testIntent, 0).size()) {
showToast("URL scheme in your app's "
+ "manifest is not set up correctly. You should have a "
+ "com.dropbox.client2.android.AuthActivity with the "
+ "scheme: " + scheme);
finish();
}
}
private void showToast(String msg) {
Toast error = Toast.makeText(this, msg, Toast.LENGTH_LONG);
error.show();
}
/**
* Shows keeping the access keys returned from Trusted Authenticator in a
* local store, rather than storing user name & password, and
* re-authenticating each time (which is not to be done, ever).
*/
private void loadAuth(AndroidAuthSession session) {
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 || key.length() == 0
|| secret.length() == 0)
return;
if (key.equals("oauth2:")) {
// If the key is set to "oauth2:", then we can assume the token is
// for OAuth 2.
session.setOAuth2AccessToken(secret);
} else {
// Still support using old OAuth 1 tokens.
session.setAccessTokenPair(new AccessTokenPair(key, secret));
}
}
/**
* Shows keeping the access keys returned from Trusted Authenticator in a
* local store, rather than storing user name & password, and
* re-authenticating each time (which is not to be done, ever).
*/
private void storeAuth(AndroidAuthSession session) {
// Store the OAuth 2 access token, if there is one.
String oauth2AccessToken = session.getOAuth2AccessToken();
if (oauth2AccessToken != null) {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME,
0);
Editor edit = prefs.edit();
edit.putString(ACCESS_KEY_NAME, "oauth2:");
edit.putString(ACCESS_SECRET_NAME, oauth2AccessToken);
edit.commit();
return;
}
// Store the OAuth 1 access token, if there is one. This is only
// necessary if
// you're still using OAuth 1.
AccessTokenPair oauth1AccessToken = session.getAccessTokenPair();
if (oauth1AccessToken != null) {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME,
0);
Editor edit = prefs.edit();
edit.putString(ACCESS_KEY_NAME, oauth1AccessToken.key);
edit.putString(ACCESS_SECRET_NAME, oauth1AccessToken.secret);
edit.commit();
return;
}
}
private void clearKeys() {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
Editor edit = prefs.edit();
edit.clear();
edit.commit();
}
private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session = new AndroidAuthSession(appKeyPair);
loadAuth(session);
return session;
}
}
UploadPicture.java
public class UploadPicture extends AsyncTask<Void, Long, Boolean> {
private DropboxAPI<?> mApi;
private String mPath;
private File mFile;
private long mFileLen;
private UploadRequest mRequest;
private Context mContext;
private final ProgressDialog mDialog;
private String mErrorMsg;
private File outFiles;
public UploadPicture(Context context, DropboxAPI<?> api, String dropboxPath,
File file) {
// We set the context this way so we don't accidentally leak activities
mContext = context.getApplicationContext();
mFileLen = file.length();
mApi = api;
mPath = dropboxPath;
mFile = file;
Date dates = new Date();
DateFormat dfs = new SimpleDateFormat("yyyyMMdd-kkmmss");
String newPicFiles = dfs.format(dates) + ".mov";
String outPaths = new File(Environment
.getExternalStorageDirectory(), newPicFiles).getPath();
outFiles = new File(outPaths);
mDialog = new ProgressDialog(context);
mDialog.setMax(100);
mDialog.setMessage("Uploading " + outFiles.getName());
mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mDialog.setProgress(0);
mDialog.setButton(ProgressDialog.BUTTON_POSITIVE, "Cancel", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// This will cancel the putFile operation
mRequest.abort();
}
});
mDialog.show();
}
#Override
protected Boolean doInBackground(Void... params) {
try {
// By creating a request, we get a handle to the putFile operation,
// so we can cancel it later if we want to
FileInputStream fis = new FileInputStream(mFile);
String path = mPath + outFiles.getName();
mRequest = mApi.putFileOverwriteRequest(path, fis, mFile.length(),
new ProgressListener() {
#Override
public long progressInterval() {
// Update the progress bar every half-second or so
return 500;
}
#Override
public void onProgress(long bytes, long total) {
publishProgress(bytes);
}
});
if (mRequest != null) {
mRequest.upload();
return true;
}
} catch (DropboxUnlinkedException e) {
// This session wasn't authenticated properly or user unlinked
mErrorMsg = "This app wasn't authenticated properly.";
} catch (DropboxFileSizeException e) {
// File size too big to upload via the API
mErrorMsg = "This file is too big to upload";
} catch (DropboxPartialFileException e) {
// We canceled the operation
mErrorMsg = "Upload canceled";
} catch (DropboxServerException e) {
// Server-side exception. These are examples of what could happen,
// but we don't do anything special with them here.
if (e.error == DropboxServerException._401_UNAUTHORIZED) {
// Unauthorized, so we should unlink them. You may want to
// automatically log the user out in this case.
} else if (e.error == DropboxServerException._403_FORBIDDEN) {
// Not allowed to access this
} else if (e.error == DropboxServerException._404_NOT_FOUND) {
// path not found (or if it was the thumbnail, can't be
// thumbnailed)
} else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE) {
// user is over quota
} else {
// Something else
}
// This gets the Dropbox error, translated into the user's language
mErrorMsg = e.body.userError;
if (mErrorMsg == null) {
mErrorMsg = e.body.error;
}
} catch (DropboxIOException e) {
// Happens all the time, probably want to retry automatically.
mErrorMsg = "Network error. Try again.";
} catch (DropboxParseException e) {
// Probably due to Dropbox server restarting, should retry
mErrorMsg = "Dropbox error. Try again.";
} catch (DropboxException e) {
// Unknown error
mErrorMsg = "Unknown error. Try again.";
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return false;
}
#Override
protected void onProgressUpdate(Long... progress) {
int percent = (int)(100.0*(double)progress[0]/mFileLen + 0.5);
mDialog.setProgress(percent);
}
#Override
protected void onPostExecute(Boolean result) {
mDialog.dismiss();
if (result) {
showToast("Image successfully uploaded");
} else {
showToast(mErrorMsg);
}
}
private void showToast(String msg) {
Toast error = Toast.makeText(mContext, msg, Toast.LENGTH_LONG);
error.show();
}
}
Your problem is that you are trying to update an Activity's UI after the activity has finished.
First, you kick of an AsyncTask which posts progress updates to the UI thread. Then, before the task completes, you call finish(). Any updates to the Activity's UI after finish() is called are liable to throw exceptions, cause window leak issues, etc.
If you want to have any UI behavior as you perform your AsyncTask, you do not want to finish() the Activity until it the task is completed.
To achieve this, you could include a callback in the onPostExecute which tells the activity it is OK to finish once the AsyncTask completes.
This is how I would do it:
Change the signature of UploadPicture:
final Activity callingActivity;
public UploadPicture(final Activity callingActivity, DropboxAPI api, String dropboxPath, File file) {
Context mContext = callingActivity.getApplicationContext();
this.callingActivity = callingActivity;
Add the finish call to onPostExecute:
#Override
protected void onPostExecute(Boolean result) {
mDialog.dismiss();
if (result) {
showToast("Image successfully uploaded");
} else {
showToast(mErrorMsg);
}
callingActivity.finish(); //Finish activity only once you are done
}