Compare a file in the device with one in firebase - android

My app download html files from the database the first time the app is opened.
When a button is clicked I want to check every html file and download an "updated" html version (Only if the html in the device is different from the one in the database)
How can I do that kind of comparison?
My main activity onCreate with a boolean to check if is the first time the app is opened then a function getFiles() is called to download every html file.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_horarios = (Button)findViewById(R.id.btn_horarios);
Boolean isrunfirst = getSharedPreferences("PREFERENCE", MODE_PRIVATE).getBoolean("first", true);
if(isrunfirst){
getFiles();
getSharedPreferences("PREFERENCE", MODE_PRIVATE).edit().putBoolean("first", false).apply();
} else {
}
}
getFiles function with a loop used to "loop" through a String array containing the name of the files, with the name the file is retrieved from the database and finally the file is saved using a function saveFile()
public void getFiles(){
FirebaseStorage storage = FirebaseStorage.getInstance();
final StorageReference storageRef = storage.getReference();
final String[] grupos = getResources().getStringArray(R.array.array_grupos);
for(int i = 0; i < 97; i += 1) {
final int finalI = i;
StorageReference htmlRef = storageRef.child("grupos/" + grupos[finalI] + ".html");
final long ONE_MEGABYTE = 1024 * 1024;
htmlRef.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
saveFile(grupos[finalI] + ".html", bytes);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
}
});
}
}
saveFile() takes the file name and the bytes, the bytes are converted into a string an saved.
private void saveFile(String file, byte[] bytes) {
try {
String text = new String(bytes, "UTF-8");
FileOutputStream fis = openFileOutput(file, Context.MODE_PRIVATE);
fis.write(text.getBytes());
fis.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
}

Related

Trying to store a PDF file on Users android device using getExternalStorageDir() function

So I am trying to store a PDF file on the user's android device by creating a Folder and then storing it. I am using getExternalStorageDir() but this has been deprecated under API29. The problem is Andriod guidelines say to opt-out out of scoped storage I have to put this in Manifest File
<manifest xmlns:android="http://schemas.android.com/apk/res/android
....
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:requestLegacyExternalStorage="true"
....
</application>
This is not working anymore. I can download on Devices with andriod M but Not able to in recent 9/10 devices.
public class FinalActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {
private static final int WRITE_REQUEST_CODE = 300;
private static final String TAG = MainActivity.class.getSimpleName();
private String url;
SessionManagement sessionManagement;
String userID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_final);
sessionManagement = new SessionManagement(this);
HashMap<String, String> user = sessionManagement.getUserDetail();
userID = user.get(sessionManagement.ID);
TextView submit = findViewById(R.id.download);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (EasyPermissions.hasPermissions(FinalActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//Get the URL entered
url = F.url1 + userID + "/FPO.pdf";
new DownloadFile().execute(url.replaceAll(" ", "%20"));
} else {
//If permission is not present request for the same.
EasyPermissions.requestPermissions(FinalActivity.this, "This app needs access to your file storage so that it can write files.", WRITE_REQUEST_CODE, Manifest.permission.READ_EXTERNAL_STORAGE);
}
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, FinalActivity.this);
}
#Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
//Download the file once permission is granted
url = F.url1 + userID + "/FPO.pdf";
new DownloadFile().execute(url.replaceAll(" ", "%20"));
}
#Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
Log.d(TAG, "Permission has been denied");
}
private class DownloadFile extends AsyncTask<String, String, String> {
private ProgressDialog progressDialog;
private String fileName;
private String folder;
private boolean isDownloaded;
#Override
protected void onPreExecute() {
super.onPreExecute();
this.progressDialog = new ProgressDialog(FinalActivity.this);
this.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
this.progressDialog.setCancelable(false);
this.progressDialog.show();
}
#Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection connection = url.openConnection();
connection.connect();
// getting file length
int lengthOfFile = connection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
String timestamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
//Extract file name from URL
fileName = f_url[0].substring(f_url[0].lastIndexOf('/') + 1, f_url[0].length());
//External directory path to save fileb n
folder = Environment.getExternalStorageDirectory() + File.separator + "FPO/";
//Create LSK folder if it does not exist
File directory = new File(folder);
if (!directory.exists()) {
directory.mkdirs();
}
// Output stream to write file
OutputStream output = new FileOutputStream(folder + fileName.replaceAll("%20", " "));
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lengthOfFile));
Log.d(TAG, "Progress: " + (int) ((total * 100) / lengthOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
return "Downloaded at: " + folder + fileName.replaceAll("%20", " ");
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
Log.i("error123", e.getMessage());
return e.getMessage();
}
// return "Something went wrong";
}
protected void onProgressUpdate(String... progress) {
// setting progress percentage
progressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String message) {
// dismiss the dialog after the file was downloaded
this.progressDialog.dismiss();
Intent intent = new Intent(FinalActivity.this, Welcome_screen1.class);
startActivity(intent);
// Display File path after downloading
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
}
}
"Use getExternalFilesDir(), getExternalCacheDir(), or getExternalMediaDirs() (methods on Context) instead of Environment.getExternalStorageDirectory()."
Check this;
https://stackoverflow.com/a/57116787/5924743
After a bit of analysis. Here is my suggestion
//External directory path to save fileb n
folder = Environment.getExternalStoragePublicDirectory("FPO")+File.separator;// Deprecated I know but it works
//Create LSK folder if it does not exist
File file = new File(folder + fileName.replaceAll("%20"," "));// create file in particular path with name and extension
if (!file.exists()) {
file.createNewFile(); //creates file for writing
}
// Output stream to write file
OutputStream output = new FileOutputStream(file);
First create a File before starting to write using OutputStream. Don't just create directory.
Hope helpful!

How to fix "download file store on google drive" error in android

I've made an app for downloading a pdf file from direct link to internal storage. When I try to download a direct link of google drive link it works fine, if the file is less than 3MB. But if the file is more than 3MB, it is not downloaded. Here is my code below:
public class MainActivity extends AppCompatActivity {
private final String Pdf_LINK =
("https://drive.google.com/uc?export=download&id=13mE9gCyTGmLrFOZqu6Lz-yz0mcfjGoJc");
private final String My_PDF ="my100.pdf";
private AppCompatSeekBar seekBar;
private PDFView pdfView;
private TextView txtView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pdfView = findViewById(R.id.pdfView);
txtView = findViewById(R.id.txtView);
initSeekar();
downloadpdf(My_PDF);
}
private void initSeekar(){
seekBar = findViewById(R.id.seeBar);
seekBar.getProgressDrawable().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
seekBar.getThumb().setColorFilter(Color.RED,PorterDuff.Mode.SRC_IN);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int val = (progress * (seekBar.getWidth() - 3 * seekBar.getThumbOffset())) / seekBar.getMax();
txtView.setText("" + progress);
txtView.setX(seekBar.getX() + val + seekBar.getThumbOffset() / 2);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
private void downloadpdf(final String fileName) {
new AsyncTask<Void, Integer, Boolean>() {
#Override
protected Boolean doInBackground(Void... params) {return downloadpdf();}
#Nullable
private Boolean downloadpdf() {
try {
File file = getFileStreamPath(fileName);
if (file.exists())
return true;
try {
FileOutputStream fileOutputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
URL u = new URL(Pdf_LINK);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
InputStream input = new BufferedInputStream(u.openStream());
byte data[] = new byte[contentLength];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress((int) ((total * 100) / contentLength));
fileOutputStream.write(data, 0, count);
}
fileOutputStream.flush();
fileOutputStream.close();
input.close();
return true;
} catch (final Exception e) {
e.printStackTrace();
return false;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
seekBar.setProgress(values[0]);
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if (aBoolean) {
openPdf(fileName);
} else {
Toast.makeText(MainActivity.this, "Unable to download this file", Toast.LENGTH_SHORT).show();
}
}
}.execute();
}
private void openPdf(String fileName) {
try {
File file = getFileStreamPath(fileName);
Log.e("file", "file: " + file.getAbsolutePath());
seekBar.setVisibility(View.GONE);
pdfView.setVisibility(View.VISIBLE);
pdfView.fromFile(file)
.enableSwipe(true)
.swipeHorizontal(false)
.load();
} catch (Exception e) {
e.printStackTrace();
}
}
}
What is the error in this code? How can I solve this? If I try to download a pdf file from another site, it works well. But the problem is only, when trying to download from google drive. please help me.
I was able to download large public shareable files from google drive.
Use the URL:
https://drive.google.com/uc?id=<FILE_ID>&export=download
Replace <FILE_ID> with your shareable file ID.
I used the code in 'private class DownloadTask'
in this solution:
Download a file with Android, and showing the progress in a ProgressDialog
The code inside the doInBackground function works, I modified it for my own needs, used ProgressBar instead. I am not posting my code since it's too long.
Hope you can solve your problem.

store the Sugar ORM database in sd card rather than default path android

i am using sugar orm to store my data in sqlite database in android and it is working perfectly so now i want to store the data in the local storage rather than the default path so how can i achieve that and moreover that is it possible to do this
Thanks.
This is my mainactivity code
public class MainActivity extends AppCompatActivity {
EditText firstname;
EditText lastname;
Button button;
Note note;
public SQLiteDatabase database;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
firstname=findViewById(R.id.edit1);
lastname=findViewById(R.id.edit2);
button=findViewById(R.id.button);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
return id == R.id.action_settings || super.onOptionsItemSelected(item);
}
public void click(View view) {
String first = firstname.getText().toString();
String last = lastname.getText().toString();
note = new Note(first, last);
note.save();
if (note.getFirstname() != null && note.getLastname() != null) {
firstname.setText("");
lastname.setText("");
}
onShareDb();
//Log.e("Notes saved", String.valueOf(onShareDb()));
}
public void show(View view) {
String one=note.getFirstname();
String two=note.getLastname();
Log.e("firstName",one);
Log.e("lastName",two);
}
public void update(View view) {
note = Note.findById(Note.class, 4);
Log.e("firstName",note.getFirstname());
note.setFirstname("kullu");
Log.e("firstName",note.getFirstname());
note.save();
}
public void delete(View view) {
note = Note.findById(Note.class, 2);
if(note.getId()==null){
Toast.makeText(this,"there is no such data",Toast.LENGTH_SHORT).show();
}
Log.e("firstName",note.getFirstname());
note.delete();
Log.e("firstName",note.getFirstname());
}
public void onShareDb() {
#SuppressLint("SimpleDateFormat") SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String output_name = "YourApp_" + df.format(new Date()) + ".db";
File output_file = new File(getExternalCacheDir() + File.separator + output_name);
try {
File file = new File(new SugarDb(MainActivity.this).getDB().getPath()); // get private db reference
if (!file.exists() || file.length() == 0) throw new Exception("Empty DB");
//IOUtils.copy(new FileInputStream(file), new FileOutputStream(output_file));
/* Intent i = new Intent(Intent.ACTION_SEND);
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(output_file));
startActivity(Intent.createChooser(i, "Send db"));*/
database = SQLiteDatabase.openDatabase(output_file
+ File.separator + "notes.db", null,
SQLiteDatabase.OPEN_READWRITE);
Log.e("storage", String.valueOf(database));
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Unable to export db: " + e.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("storage", e.getMessage());
}
}
}
So, basically i m trying to get the path of stored images by using the shareDB() property of sugar orm and trying to overwrite the default path to my new path so how do i get it done, i m calling shareDB method in button click listener, the exception is something like unknown error: could not open database.
After a lot of research and trial error, I somehow manage to succeed in copying the sqllite file from one folder to another folder in the directory
Here is the code,
private void copyDatabase() throws IOException {
File actualFile = new File(new SugarDb(MainActivity.this).getDB().getPath());
File cuurentfile = new File(actualFile.toString());
Log.e("actualPath", actualFile.toString());
File newFile = createTempFile("sugarFiles",".db",Environment.getExternalStorageDirectory());
Log.e("newPath", newFile.toString());
boolean yes=FileUtils.copyFile(cuurentfile,newFile);
if(yes) {
Log.e("result", "" + true);
}
}
call this copydatabase function inside the click listener or wherever you are inserting into the database, make sure it is after you set the insertion values, in my case
public void click(View view) {
String first = firstname.getText().toString();
String last = lastname.getText().toString();
note = new Note(first, last);
note.save();
if (note.getFirstname() != null && note.getLastname() != null) {
firstname.setText("");
lastname.setText("");
}
try {
copyDatabase();
} catch (IOException e) {
e.printStackTrace();
}
}
FileUtils.java
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
public class FileUtils {
FileUtils instance = null;
public FileUtils getInstance() {
instance = new FileUtils();
return instance;
}
public static Boolean copyFile(File sourceFile, File destFile)
throws IOException {
// if (!destFile.exists()) {
destFile.createNewFile();
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
destination.transferFrom(source, 0, source.size());
} finally {
if (source != null)
source.close();
if (destination != null)
destination.close();
}
return true;
// }
// return false;
}
/**
* Read a text file into a String.
*
* #param file
* File to read (will not seek, so things like /proc files are
* OK).
* #return The contents of the file as a String.
* #throws IOException
*/
public static String readTextFile(File file) throws IOException {
byte[] buffer = new byte[(int) file.length()];
BufferedInputStream stream = new BufferedInputStream(
new FileInputStream(file));
stream.read(buffer);
stream.close();
return new String(buffer);
}
}
Hope it helps someone someday...Have a nice day

How store data from Firebase to native GearVR Framework?

I want to load different cubemaps from database. Following code I used, but it is not working. It crashes every time.
I can t get the path to the primary external storage in Android. Does anyone know how I can store Data from Database to the native GearVR Framework?
public class SampleActivity extends GVRActivity {
final File externalFilesDir = getExternalFilesDir(null);
private SampleMain main;
private long lastDownTime = 0;
//ref to storage firebase
private StorageReference cubemap_ref;
#Override
protected void onCreate(Bundle icicle) {
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReference();
cubemap_ref = storageRef.child("cubemaps/cubemap_example.zip");
final long TEN_MEGABYTE = 1024 * 1024 * 10;
cubemap_ref.getBytes(TEN_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
File file = new File(externalFilesDir.getAbsolutePath(), "cubemap.zip");
try {
OutputStream os = new FileOutputStream(file);
os.write(bytes);
os.close();
} catch (IOException e) {
android.util.Log.w("ExternalStorage", "Error writing " + file, e);
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(Exception exception) {
// Handle any errors
}
});
super.onCreate(icicle);
main = new SampleMain(this);
setMain(main, "gvr.xml");
}
}
Thanks in advance.
I don t know why, but this code works now.

getting images from firebase storage in android

In my Activity I use FireBase to download pics of my game from the storage.
If I run this code on my Activity it works but if I use it in my level class as a method, it just returns null.
This is my Activity:
pic = null;
answer = null;
option = null;
picture = null;
try {
answer = File.createTempFile("buttonanswer", "png");
StorageReference storageRef = storage.getReferenceFromUrl("gs://yougotit-8ce92.appspot.com");
StorageReference levelDifficultRef = storageRef.child("easy");
final StorageReference levelRef = levelDifficultRef.child(Game.LEVEL + 1);
StorageReference levelAnswerRef = levelRef.child("pic" + "." + "jpg");
levelAnswerRef.getFile(answer).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
answerV = new ImageView(getApplicationContext());
Bitmap myBitmap = BitmapFactory.decodeFile(answer.getPath());
answerV.setImageBitmap(myBitmap);
runOnUiThread(new Runnable() {
#Override
public void run() {
maingameLinarLayout.addView(answerV);
}
});
}
});
}
catch (IOException e) {
e.printStackTrace();
}
In the level class this my code that doesn't work and returns null.
This is my level class:
public class Level {
public static final String ANSWER="answer";
public static final String OPTION="ops";
public static final String PICTURE="pic";
public static final String QUESTION="question";
public static final String PNG = "png";
public static final String JPG = "jpg";
private File mainPicture,fadedPicture,opt1,opt2,opt3,answer,question;
private int flag;//in easy level when reach to 6 it indicate that that level is ready //in medium and hard level when reach to 7
private StorageReference storageRef;
private String difficult;
private Game game;
public Level(Game game,FirebaseStorage storageIns,String difficult,int level) {
flag = 0 ;
this.game = game;
this.difficult = difficult;
this.storageRef = storageIns.getReferenceFromUrl("gs://yougotit-8ce92.appspot.com");
StorageReference levelDifficultRef = storageRef.child(difficult);
final StorageReference levelRef = levelDifficultRef.child(Game.LEVEL+level);
if(difficult.equals(Game.LEVEL_HARD) ) {
}
if(difficult.equals(Game.LEVEL_MEDIUM) ) {
}
else {
downloadPicture(levelRef, mainPicture, PICTURE, JPG);
downloadPicture(levelRef, answer, ANSWER, PNG);
downloadPicture(levelRef, opt1, OPTION + 1, PNG);
downloadPicture(levelRef, opt2, OPTION + 2, PNG);
downloadPicture(levelRef, opt3, OPTION + 3, PNG);
}
}
private void downloadPicture(StorageReference levelRef,File f,String picName,String picFormat) {
StorageReference pictureRef = levelRef.child(picName+"."+picFormat);
f = null;
try {
f = File.createTempFile(picName,picFormat);
pictureRef.getFile(f).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
flag++;
if(flag == 5) {
activeCallBack();
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
Can anyone please help me figuring out what's going wrong?
You are downloading different references in your Level class so this looks like an apples to orange comparison.
Try adding a addOnFailure in addition to addOnSuccess as I suspect that you are getting 404's for these other files.

Categories

Resources