how to maintain user picture from server? - android

I need to show picture of user in my application and I retrieve that picture from server since my application also works in offline mode so I need to save that picture from server to my SD card , also I when i sync data from server next time If picture has changed then i need to change that picture in my SD card too how to determine if picture for particular user has changed
currently i save the image from server as follow though I use hardcoded url as of now and static user id
public class fetchImage extends Activity implements OnClickListener {
int id;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
id = 1;// declaring static as of now
}
{
new BackgroundTask().execute();
File storagePath = Environment.getExternalStorageDirectory();
File imgFile = new File(storagePath, "/Pictures/" + id + ".jpg");
if (imgFile.exists()) {
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile
.getAbsolutePath());
}
}
class BackgroundTask extends AsyncTask<Void, Void, Void> {
ProgressDialog mDialog;
protected void onPreExecute() {
mDialog = ProgressDialog.show(fetchImage.this, "",
getString(R.string.progress_bar_loading), true);
};
#Override
protected Void doInBackground(Void... params) {
try {
savesd(id, null);
} catch (final Exception e) {
}
return null;
}
private void savesd(int id, URL uri) throws IOException {
URL url;
if (uri == null) {
url = new URL("http://i.zdnet.com/blogs/3-29-androids.jpg");
} else {
url = uri;
}
InputStream input = url.openStream();
try {
File storagePath = Environment.getExternalStorageDirectory();
OutputStream output = new FileOutputStream(new File(
storagePath, "/Pictures/" + id + ".jpg"));
try {
byte[] buffer = new byte[20000];
int bytesRead = 0;
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
output.write(buffer, 0, bytesRead);
}
} finally {
output.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
input.close();
}
}
protected void onPostExecute(Void result) {
mDialog.dismiss();
};
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
Also i've got one problem that when I uninstall this app from Device it should also clear these user images from sd card

I used timestamp to save the time when I last sync data and download files only after that time stamp

Related

programmatically update apk (download&start installation) Android API v26

I read all of the solutions about this problem.Also I know it can be considered as duplicated but it is not.
I see Error: Try Again toast message and I see Update Error log message.
I think at android v26 changed somethings about intent.setDataAndType or I dont know why this is not working.
Also I get the permissions something like this code
ActivityCompat.requestPermissions(Update.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_STORAGE);
Problem can not be solved. I just want to do download and install apk file.
AndroidManifest.xml (I added write permission)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Update.java
package com.my.testapp;
public class Update extends AppCompatActivity {
ProgressDialog bar;
private static String TAG = "Update";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadNewVersion().execute();
}
class DownloadNewVersion extends AsyncTask<String,Integer,Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
bar = new ProgressDialog(Update.this);
bar.setCancelable(false);
bar.setMessage("Downloading...");
bar.setIndeterminate(true);
bar.setCanceledOnTouchOutside(false);
bar.show();
}
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
bar.setIndeterminate(false);
bar.setMax(100);
bar.setProgress(progress[0]);
String msg = "";
if(progress[0]>99){
msg="Finishing... ";
}else {
msg="Downloading... "+progress[0]+"%";
}
bar.setMessage(msg);
}
#Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
bar.dismiss();
if(result){
Toast.makeText(getApplicationContext(),"Update Done",
Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(),"Error: Try Again",
Toast.LENGTH_SHORT).show();
}
}
#Override
protected Boolean doInBackground(String... arg0) {
Boolean flag = false;
try {
URL url = new URL("http://mydownloadurl.com/_download/update.apk");
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String PATH = Environment.getExternalStorageDirectory()+"/Download/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file,"app-debug.apk");
if(outputFile.exists()){
outputFile.delete();
}
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
int total_size = 277962;//size of apk
byte[] buffer = new byte[1024];
int len1 = 0;
int per = 0;
int downloaded=0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
downloaded +=len1;
per = (int) (downloaded * 100 / total_size);
publishProgress(per);
}
fos.close();
is.close();
OpenNewVersion(PATH);
flag = true;
} catch (Exception e) {
Log.e(TAG, "Update Error: " + e.getMessage());
flag = false;
}
return flag;
}
}
void OpenNewVersion(String location) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(location + "app-debug.apk")),
"application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
Commonsware thanks a lot, I waste my 2-3 hours to do different ways.
Actually I added this code before but the problem was not solved.
I tried again and it worked, it might be lazy solution but it is working.
This url have more info about the problem ,other solutions can be applied,
but it is enough for me.
if(Build.VERSION.SDK_INT>=24){
try{
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
}catch(Exception e){
e.printStackTrace();
}
}
It is totally fixed thank you very much again.
Application also need this storage permission.
ActivityCompat.requestPermissions(Update.this,new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE

AsyncTask println needs a message No Exception thrown

My AsyncTask is logging an error "println needs a message" however no exception is being thrown in my class. The task is started in an Activity which implements a callback interface I wrote called TaskCallback. In the onPostExecute() it calles the callback in the Activity. From this callback, I run another AsyncTask. Below is the code:
public class SaveImageTask extends AsyncTask<byte[], String, File> {
private static final String IMAGE_DATA_PATH =
Environment.getExternalStorageDirectory().toString() + "/MyAppFolder/AppImages/";
private static final String TAG = "SaveImageTask";
private TaskCallback mTaskCallback;
private ProgressDialog mProgressDialog;
public SaveImageTask(TaskCallback taskCallback) {
mTaskCallback = taskCallback;
}
#Override
protected void onPreExecute() {
mProgressDialog = new ProgressDialog((Context) mTaskCallback);
mProgressDialog.setMessage("Saving Image...");
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
#Override
protected File doInBackground(byte[]... data) {
File imageFile = createOutputPictureFile();
if(imageFile == null) {
return null;
}
try {
Bitmap image = BitmapFactory.decodeByteArray(data[0], 0, data[0].length);
FileOutputStream out = new FileOutputStream(imageFile);
image.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
return imageFile;
}
#Override
public void onPostExecute(File imageFile) {
if(mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
if(mTaskCallback != null) {
mTaskCallback.onTaskComplete(imageFile);
}
}
private File createOutputPictureFile() {
File imageStorageDirectory = new File(IMAGE_DATA_PATH);
// If the default save directory doesn't exist, try and create it
if (!imageStorageDirectory.exists()){
if (!imageStorageDirectory.mkdirs()){
//Log.e(TAG, "Required media storage does not exist");
return null;
}
}
// Create a timestamp and use it as part of the file name
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.UK);
String timeStamp = dateFormat.format(new Date());
String fileName = "img_"+ timeStamp + ".jpg";
return new File (imageStorageDirectory, fileName);
}
}
The onTaskComplete(File file) looks like this:
#Override
public void onTaskComplete(File file) {
if(file == null) {
Util.showToast(this, "Save Failed.", Toast.LENGTH_SHORT);
return;
}
notifyDeviceOfNewFile(file);
ProcessImageTask pit = new ProcessImageTask(this);
pit.execute(file);
}
And the error logged is:
E/SaveImageTask: println needs a message
As it says in the title, no exception is thrown and the code actually does what it is supposed to do. I've narrowed the issue down to this line of code in the callback:
pit.execute(file);
If I comment out this line the error doesn't appear. I'm a bit stumped on what's going on. If I remove all logging in my SaveImageTask it still appears so something else is logging it.
There is a reason why a exception is not thrown, because you catch it. That is the whole concept about try-catch.
try {
Bitmap image = BitmapFactory.decodeByteArray(data[0], 0, data[0].length);
FileOutputStream out = new FileOutputStream(imageFile);
image.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
// normally you do stuff here when it fails.
}
I believe "println needs a message" is what's shown if you pass a null to Log.x(). You're probably getting an IOException - e.printstacktrace() will probably give you a better idea of why.
Ok, turns out I was being an idiot and the error was from another class which for some reason had the same TAG it was logging with. Thank you for your input and suggestions, an important lesson about copy/pasting code was learned today.

Threading requires that an application's button be clicked twice

I have the following code. submitClick() is triggered when someone clicks the submit button on my application. In the past, submit click would be click once, and all of submitFile() would be carried out. By adding the threading addition to checkContent(), now submitClick has to be clicked twice for all of submitFile() to be completed. Is there any way to make it so that submitFile() finishes (with checkContent()) so the user only has to press my apps submit button?
Thank you in advance.
public void submitClick(View v) throws Exception{
if (!submitted) { submitFile(); }
}
public void submitFile() {
checkContent();
if (valid) {
Picasso.with(this).load(imageAddress).into(imagePreview);
saveImage();
//sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); //refreshes system to show saved file
submitted = true;
submit_but.setText("Encrypt");
}
}
private void checkContent() {
media = null;
if(URLUtil.isValidUrl(imageAddress)) {
Thread thread = new Thread() {
boolean img = false;
boolean youtube = false;
public void run() {
URLConnection connection = null;
try {
connection = new URL(imageAddress).openConnection();
} catch (IOException e) {
e.printStackTrace();
}
String contentType = connection.getHeaderField("Content-Type");
img = contentType.startsWith("image/");
if(img)
media = "image";
if (!img) {
// Check host of url if youtube exists
Uri uri = Uri.parse(imageAddress);
if ("www.youtube.com".equals(uri.getHost())) {
media = "youtube";
youtube = true;
}
}
valid = img || youtube;
}
};
thread.start();
}
}
The problem is that the Thread will finish after the call to if (valid) and the rest in the submitFile().
Easy fix is to include the entire submitFile() in a Thread, instead of just part of it. If the logic is bound to each other, it's better off that they're together.
A more android-esque fix is to use AsyncTask, as such:
public void submitClick(View v) throws Exception {
if (!submitted) { submitFile(); }
}
public void submitFile() {
if(URLUtil.isValidUrl(imageAddress)) {
new AsyncTask<Void, Void, Boolean>() {
protected Long doInBackground(Void... voids) {
boolean img = false;
boolean youtube = false;
URLConnection connection = null;
try {
connection = new URL(imageAddress).openConnection();
} catch (IOException e) {
e.printStackTrace();
}
String contentType = connection.getHeaderField("Content-Type");
img = contentType.startsWith("image/");
if(img)
media = "image";
if (!img) {
// Check host of url if youtube exists
Uri uri = Uri.parse(imageAddress);
if ("www.youtube.com".equals(uri.getHost())) {
media = "youtube";
youtube = true;
}
}
return img || youtube;
}
protected void onPostExecute(Boolean valid) {
if (valid) {
Picasso.with(this).load(imageAddress).into(imagePreview);
saveImage();
//sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); //refreshes system to show saved file
submitted = true;
submit_but.setText("Encrypt");
}
}
}.execute();
}
}

Re-Download the file every time I open the app

My app is depends on PDF files which I download it from URL and unzip it, which works fine.
but it re-download the file.zip every time I open it even if the file is downloaded and existed.
the file size is too big so it make much trouble and hard to use.
I hope you can help
thanks alot
public class MainActivity extends Activity {
String Url="www....zip";
String unzipLocation = Environment.getExternalStorageDirectory() + "/unzipFolder/";
String StorezipFileLocation =Environment.getExternalStorageDirectory() + "/DownloadedZip";
String DirectoryName=Environment.getExternalStorageDirectory() + "/unzipFolder/files/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadZipfile mew = new DownloadZipfile();
mew.execute(Url);
class DownloadZipfile extends AsyncTask<String, String, String>
{
String result ="";
#Override
protected void onPreExecute()
{
super.onPreExecute();
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setMessage("Downloading ... ");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
#Override
protected String doInBackground(String... aurl)
{
int count;
try
{
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(StorezipFileLocation);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1)
{
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.close();
input.close();
result = "true";
}
catch (Exception e) {
result = "false"; }
return null;
}
protected void onProgressUpdate(String... progress)
{
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String unused)
{
mProgressDialog.dismiss();
if(result.equalsIgnoreCase("true"))
{
try
{
unzip();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
}
}
}
Well, onCreate() is called every time the activity is created, which happens every time you open it. You'll have to set a variable or save in a SharedPreference object whether the app should download or not. For example you could add a field boolean isDownloaded = false and just set that to true once the download has finished from within the AsyncTask.
Alternatively you can check whether the file you want to save already exists, meaning you have already saved it there before (if((new File(path)).exists())) {...}). However, if the download has resulted in a corrupt file, you will always keep this corrupt file if you don't take care of the issue otherwise because doing it like this will not guarantee that the download has completed successfully.
The other option I mentioned would mean to get your default SharedPreferences by calling PreferenceManager.getDefaultSharedPreferences(this) and using this to set and get a boolean field which tells you whether the pdf is downloaded.
The advantage with the second method is that the app will remember whether the file is downloaded even after a reboot or after completely unloading the app from memory.
Check is file exist
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try
{
File file = new File(StorezipFileLocation);
if ( ! file.exists())
{
DownloadZipfile mew = new DownloadZipfile();
mew.execute(Url);
}
}
catch (FileNotFoundException fnfe1)
{
}
The solution is by checking if the file exists .. File(path)
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
File f = new File(Environment.getExternalStorageDirectory()+"/unzipFolder/files/");
if(f.exists() == false)
{
DownloadZipfile mew = new DownloadZipfile();
mew.execute(Url);
}
}
thanks to everyone who helped or try to..

Android: How to Load a File From Assets to SD at First Run?

How can a file (SQLlite, Text, etc.) be loaded onto the SD card from the Assets folder and only at first run of the application?
Here is the methods I use. Have this as the main activity of your application and use it to start your real application activity.
public class StartUp extends Activity {
/**
* -- Called when the activity is first created.
* ==============================================================
**/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FirstRun();
}
private void FirstRun() {
SharedPreferences settings = this.getSharedPreferences("YourAppName", 0);
boolean firstrun = settings.getBoolean("firstrun", true);
if (firstrun) { // Checks to see if we've ran the application b4
SharedPreferences.Editor e = settings.edit();
e.putBoolean("firstrun", false);
e.commit();
// If not, run these methods:
SetDirectory();
Intent home = new Intent(StartUp.this, YourMainActivity.class);
startActivity(home);
} else { // Otherwise start the application here:
Intent home = new Intent(StartUp.this, YourMainActivity.class);
startActivity(home);
}
}
/**
* -- Check to see if the sdCard is mounted and create a directory w/in it
* ========================================================================
**/
private void SetDirectory() {
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File txtDirectory = new File(extStorageDirectory + "/yourAppName/txtDirectory/");//Example name for txt files
// Create
// a
// File
// object
// for
// the
// parent
// directory
txtDirectory.mkdirs();// Have the object build the directory
// structure, if needed.
CopyAssets(); // Then run the method to copy the file.
} else if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED_READ_ONLY)) {
AlertsAndDialogs.sdCardMissing(this);//Or use your own method ie: Toast
}
}
/**
* -- Copy the file from the assets folder to the sdCard
* ===========================================================
**/
private void CopyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("tag", e.getMessage());
}
for (int i = 0; i < files.length; i++) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(files[i]);
out = new FileOutputStream(extStorageDirectory + "/yourAppName/txt/" + files[i]);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}

Categories

Resources