How to upload file to firebase storage from sd card - android-studio

This is my code. i tried to upload file from my sd card to firebasae storage but it throwing "An unknown error occurred. Please check the HTTP result code and inner exception for server response." i have checked many solution but nothing worked for me. so please help me to fix this issue.
//upload file
private void uploadFile() throws FileNotFoundException {
if (fileuri != null) {
//displaying a progress dialog while upload is going on
final ProgressDialog progress = new ProgressDialog(this);
progress.setMessage("Uploading....");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setIndeterminate(true);
progress.setCancelable(true);
progress.setProgress(0);
progress.show();
StorageReference riversRef = storageReference.child("path");
riversRef.putFile(fileuri).addOnSuccessListener(new
OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//if the upload is successfull
//hiding the progress dialog
progress.dismiss();
//and displaying a success toast
Intent intent = new Intent(UploadActivity.this, hanksActivity.class);
startActivity(intent);
finish();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
//if the upload is not successfull
//hiding the progress dialog
progress.dismiss();
//and displaying error message
Toast.makeText(getApplicationContext(), exception.getMessage(),
Toast.LENGTH_LONG).show();
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>
() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
//calculating progress percentage
#SuppressWarnings("VisibleForTests")
double progresstime = (100.0 * taskSnapshot.getBytesTransferred()) /
taskSnapshot.getTotalByteCount();
//displaying percentage in progress dialog
progress.setProgress((int) progresstime);
}
});
} else {
Toast.makeText(getApplicationContext(), "Choose file",
Toast.LENGTH_LONG).show();
}
}

Related

Bitmap compress quality ok in emulator, but not in real device

In my app, images are saving successfully to gallery after editing. but quality is not up to the mark on physical device. I got 0.5mp to 0.7mp highest. but same app I open in emulator and after saving image I got pretty good quality of images (about 1.5mp to 3mp). didn't find the exact reason of this. will be glad if you help to find out. attaching my image saving code below.
public void saveAsFile(#NonNull final String str, #NonNull final SaveSettings saveSettings, #NonNull final OnSaveListener onSaveListener) {
Log.d(TAG, "Image Path: " + str);
this.parentView.saveFilter((OnSaveBitmap) new OnSaveBitmap() {
#Override
public void onBitmapReady(Bitmap bitmap) {
new AsyncTask<String, String, Exception>() {
#Override
public void onPreExecute() {
super.onPreExecute();
PhotoEditor.this.clearHelperBox();
PhotoEditor.this.parentView.setDrawingCacheEnabled(false);
}
#SuppressLint({"MissingPermission"})
public Exception doInBackground(String... strArr) {
Bitmap bitmap;
try {
FileOutputStream fileOutputStream = new FileOutputStream(new File(str), false);
if (PhotoEditor.this.parentView != null) {
PhotoEditor.this.parentView.setDrawingCacheEnabled(true);
if (saveSettings.isTransparencyEnabled()) {
bitmap = BitmapUtil.removeTransparency(PhotoEditor.this.parentView.getDrawingCache());
} else {
bitmap = PhotoEditor.this.parentView.getDrawingCache();
}
bitmap.compress(Bitmap.CompressFormat.PNG, 100 , fileOutputStream);
}
Log.d(PhotoEditor.TAG, "Filed Saved Successfully");
return null;
} catch (Exception e) {
e.printStackTrace();
Log.d(PhotoEditor.TAG, "Failed to save File");
return e;
}
}
#Override
public void onPostExecute(Exception exc) {
super.onPostExecute(exc);
if (exc == null) {
if (saveSettings.isClearViewsEnabled()) {
PhotoEditor.this.clearAllViews();
}
onSaveListener.onSuccess(str);
return;
}
onSaveListener.onFailure(exc);
}
}.execute();
}
public void onFailure(Exception exc) {
onSaveListener.onFailure(exc);
}
});
}
I tried in many ways but couldn't find the solution.

Go to another activity not main activity after splash screen

I have a splash screen in which i am checking user is logged in or not if logged in go to dashboard otherwise go to login activity. I am using sharedpref. Issue is (which I am unable to resolve) after splash screen login screen appears for a brief moment than dashboard. Splash > Login > Dash what i Want is Splash > Dash (if user logged in). Login is the main activity of my project. Here is the code:
public class SplashScreen extends AppCompatActivity {
private SessionManager sessionManager;
private BroadcastReceiver broadcastReceiver;
private SharedPreferences prefs;
private boolean isLogin;
private int accessID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sessionManager = new SessionManager(this);
broadcastReceiver = new CheckNetStatus();
broadcastIntent();
}
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onResume(){
super.onResume();
new CheckNetStatus().onReceive(SplashScreen.this,new
Intent(ConnectivityManager.CONNECTIVITY_ACTION));
try {
prefs = getSharedPreferences(SessionManager.PREF_NAME, 0); // Declare
SharedPreferences
accessID = prefs.getInt(SessionManager.KEY_ACCESSID, 0); // get Access Id from
SharedPreferences
isLogin = Utils.getLoginStatus(SplashScreen.this); // Check Login is true or false
} catch (Exception e) {
e.printStackTrace();
}
Thread splashTread = new Thread() {
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public void run() { // run thread
try {
synchronized (this) {
Thread.sleep(3000); // Screen stay for 3 sec.
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (isLogin)
{
// if (accessID == 0) { // access Id is ZERO open AddMoneyActivity.class
// try {
// } catch (Exception e) {
// e.printStackTrace();
// }
// } else if (accessID == 1) {// access Id is ONE open
ProfileStepOneActivity.class
try {
Intent intent = new Intent(SplashScreen.this, Dashboard.class);
startActivity(intent);
finishAffinity(); // Finish stack
} catch (Exception e) {
e.printStackTrace();
}
} else {// Login is False goto Login Activity
try {
Intent intent = new Intent(SplashScreen.this, MainActivity.class);
startActivity(intent);
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
};
splashTread.start();
}
public void broadcastIntent() {
registerReceiver(broadcastReceiver, new
IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
#Override
protected void onPause() {
super.onPause();
try {
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
//unregisterReceiver(broadcastReceiver);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onStop(){
super.onStop();
try {
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
// unregisterReceiver(broadcastReceiver);
} catch (Exception e) {
e.printStackTrace();
}
}
}
My mistake....i was redirecting to main activity ie login activity in netstats class(where i was checking the net connection) ie why it was showing login screen for a moment issue resolved now

Download File using download manager and save file based on click

I have my download manager, and it work perfect if I try to download a file. But I have a problem.
I have 4 CardView in my activity and I set it onClickListener, so when I click one CardView it will download the file.
Here is the code to call the download function
cardviewR1 = findViewById(R.id.card_viewR1);
cardviewR1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pDialogDL = new ProgressDialog(this);
pDialogDL.setMessage("A message");
pDialogDL.setIndeterminate(true);
pDialogDL.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialogDL.setCancelable(true);
final DownloadTask downloadTask = new DownloadTask(this);
downloadTask.execute(R1Holder);
pDialogDL.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
downloadTask.cancel(true);
}
});
}
});
and here is the download function
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
private PowerManager.WakeLock mWakeLock;
public DownloadTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/"+getString(R.string.r1)+"_"+NameHolder+".zip");
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
mWakeLock.acquire();
pDialogDL.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
pDialogDL.setIndeterminate(false);
pDialogDL.setMax(100);
pDialogDL.setProgress(progress[0]);
}
#Override
protected void onPostExecute(String result) {
mWakeLock.release();
pDialogDL.dismiss();
if (result != null)
Toast.makeText(context, "Download error: " + result, Toast.LENGTH_LONG).show();
else
Toast.makeText(context, "File downloaded", Toast.LENGTH_SHORT).show();
}
}
The code work in my app, but the problem is, when I try to add second CardView which is like this
cardviewR2 = findViewById(R.id.card_viewR2);
cardviewR2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pDialogDL = new ProgressDialog(this);
pDialogDL.setMessage("A message");
pDialogDL.setIndeterminate(true);
pDialogDL.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialogDL.setCancelable(true);
final DownloadTask downloadTask = new DownloadTask(this);
downloadTask.execute(R2Holder);
pDialogDL.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
downloadTask.cancel(true);
}
});
}
});
Yes it will download the second file, but it will overwrite the first file. I think the problem is right here
output = new FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/"+getString(R.string.r1)+"_"+NameHolder+".zip");
Anyone can help me with this code?
I need your help, Thanks
Fixed it by create a new Download Class separately in different file with activity, so the AsyncTask will be call again and again
thanks

Image capture with camera & upload to Firebase (Uri in onActivityResult() is null)

So I've got a problem, previously mentioned in the question I've asked: Uploading image (ACTION_IMAGE_CAPTURE) to Firebase storage
I've searched for the issue a bit more, and applied the Android Studio documentation: https://developer.android.com/training/camera/photobasics.html#TaskPhotoView
So, before you read the code, I basically want to say what is needed: I just want to capture a photo with camera and upload it directly to Firebase storage. To do that I need the Uri to contain the picture I just took (Uri.getLastPathSegment()), however I still couldn't succeed doing this.
So now, this is what my code look like (only related parts):
AndroidManifest.xml:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
I have the res/xml/file_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="Android/data/com.serjardovic.firebasesandbox/files/Pictures" />
</paths>
and finaly the MainActivity.java:
public class MainActivity extends AppCompatActivity {
private Button b_gallery, b_capture;
private ImageView iv_image;
private StorageReference storage;
private static final int GALLERY_INTENT = 2;
private static final int CAMERA_REQUEST_CODE = 1;
private ProgressDialog progressDialog;
String mCurrentPhotoPath;
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File...
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, CAMERA_REQUEST_CODE);
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
storage = FirebaseStorage.getInstance().getReference();
b_gallery = (Button) findViewById(R.id.b_gallery);
b_capture = (Button) findViewById(R.id.b_capture);
iv_image = (ImageView) findViewById(R.id.iv_image);
progressDialog = new ProgressDialog(this);
b_capture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
dispatchTakePictureIntent();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK){
progressDialog.setMessage("Uploading...");
progressDialog.show();
Uri uri = data.getData();
StorageReference filepath = storage.child("Photos").child(uri.getLastPathSegment());
filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(MainActivity.this, "Upload Successful!", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, "Upload Failed!", Toast.LENGTH_SHORT).show();
}
});
}
}
}
Need a solution! Still, the app crashes after I take the picture and press the confirm button and I get the following crash report:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {com.serjardovic.firebasesandbox/com.serjardovic.firebasesandbox.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.net.Uri android.content.Intent.getData()' on a null object reference
Try changing mCurrentPhotoPath = image.getAbsolutePath(); to mCurrentPhotoPath = "file:" + image.getAbsolutePath();.
I didnt spot any other differences from my code, which has worked.
So the answer is simple, thanks to #wilkas help in the comments. I just forgot to add the photoURI into filepath.putFile(photoURI), it was just filepath.putFile(uri), so the addition of code simply did nothing until I notices this. Hope this Q&A will help someone else with a similar problem!

Handler (android.os.Handler) sending message to a Handler on a dead thread - Android background thread AlarmManager with Upload Service

I am currently using the AlarmManager, Broadcast receiver and Intent Service to implement upload service to server rub by background instead of Ui Main Thread but the problem is when it comes to the execution , there is no response for the upload message . At least, in the logcat, I can see any message reporting the progress for the upload weven I have typed and tested correctly.
But afer the upload service is finished , it shows
java.lang.RuntimeException: Handler (android.os.Handler) sending message to a Handler on a dead thread
Would you please tell me what else is missing ?
The below is my code
Intnt Service
public class TaskService extends IntentService {
public TaskService() {
super("TaskService");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent arg0) {
// Do some task
Log.i("TaskService","Service running");
boolean ss = uploadRecording("TEST_RECORD" , "test.mp4" , "http://210.177.246.83/uploadFile");
Log.d("Is file uploaded" , String.valueOf(ss));
}
public boolean uploadRecording(String directoryname , String filename , String destination) {
// TODO Auto-generated method stub
boolean result = false;
String destinationPath = destination;
File tes = new File(Environment.getExternalStorageDirectory() + File.separator + directoryname);
File frecord = new File(tes.getAbsolutePath() + File.separator + filename);
if(tes.exists()){
if(frecord.exists()){
List< NameValuePair> httpContents = new ArrayList< NameValuePair>();
httpContents.add(new BasicNameValuePair("file",frecord.getAbsolutePath()));
HttpClient client=new DefaultHttpClient();
HttpPost post=new HttpPost(destinationPath);
try{
//setup multipart entity
MultipartEntity entity=new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
for(int i=0;i< httpContents.size();i++){
//identify param type by Key
if(httpContents.get(i).getName().equals("file")){
File f=new File(httpContents.get(i).getValue());
FileBody fileBody=new FileBody(f);
entity.addPart("file"+i,fileBody);
}
}
post.setEntity(entity);
//create response handler
//execute and get response
HttpResponse uploadReponse = client.execute(post);
Log.d("debug" , "Response : " + uploadReponse);
if(uploadReponse.getStatusLine().getStatusCode() == 200){
result = true;
Toast.makeText(getApplicationContext(), "Upload Success", Toast.LENGTH_SHORT).show();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
return result;
}
}
BroadCast Receiver
public static String ACTION_ALARM = "com.alarammanager.alaram";
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Alarm Receiver", "Entered");
Toast.makeText(context, "Entered", Toast.LENGTH_SHORT).show();
Bundle bundle = intent.getExtras();
String action = bundle.getString(ACTION_ALARM);
if (action.equals(ACTION_ALARM)) {
Log.i("Alarm Receiver", "If loop");
Toast.makeText(context, "If loop", Toast.LENGTH_SHORT).show();
Intent inService = new Intent(context, TaskService.class);
inService.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(inService);
}
else
{
Log.i("Alarm Receiver", "Else loop");
Toast.makeText(context, "Else loop", Toast.LENGTH_SHORT).show();
}
}
Main Acitvity
public class AlaramScheduleActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void btnStartSchedule(View v) {
try {
AlarmManager alarms = (AlarmManager) this
.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(),
AlaramReceiver.class);
intent.putExtra(AlaramReceiver.ACTION_ALARM,
AlaramReceiver.ACTION_ALARM);
final PendingIntent pIntent = PendingIntent.getBroadcast(this,
1234567, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarms.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 1000 * 10, pIntent);
toast("Started...");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void btnCancelSchedules(View v) {
Intent intent = new Intent(getApplicationContext(),
AlaramReceiver.class);
intent.putExtra(AlaramReceiver.ACTION_ALARM,
AlaramReceiver.ACTION_ALARM);
final PendingIntent pIntent = PendingIntent.getBroadcast(this, 1234567,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarms = (AlarmManager) this
.getSystemService(Context.ALARM_SERVICE);
alarms.cancel(pIntent);
toast("Canceled...");
}
public void toast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT)
.show();
}
Android Manifest
INTERNET Permisson is acquired
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".TaskService" >
</service>
<receiver
android:name="AlaramReceiver"
android:process=":remote" >
</receiver>
Your problem is in Toast message shown from IntentService.
Fix is simple: create Handler in onCreate of your service and post Runnable to show toast from it.
public class TaskService extends IntentService {
...
private Handler mHandler;
protected void onCreate() {
mHandler = new Handler();
}
...
public boolean uploadRecording(... {
...
mHandler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Upload Success", Toast.LENGTH_SHORT).show();
}
});
...
}
}
Internally toast uses Handler to communicate with INotificationManager. Once toast created it create instance of Handler, which uses looper from the thread it is created. In your case it is HandlerThread of IntentService. It is interrupted once service finished all work. That is why it is dead.

Resources