This is a continuation from my previous quesion. I wanted to open the pdf in the app instead of opening it with third-party apps. I've rewritten the code so that pdf files in assets folder can be copied into sd card.
Here is my code:
package com.dell.pdfreader;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import net.sf.andpdf.pdfviewer.PdfViewerActivity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class PdfMainActivity extends AppCompatActivity implements View.OnClickListener {
private static String TAG = PdfMainActivity.class.getCanonicalName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_main);
Button click = (Button) findViewById(R.id.click);
click.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Context mContext = getApplicationContext();
switch (view.getId()) {
case R.id.click:
try {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("pdffiles");
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
for (String fileName : files != null ? files : new String[0]) {
InputStream is = null;
OutputStream os = null;
try {
is = assetManager.open("pdffiles/" + fileName);
os = new FileOutputStream(Environment.getExternalStorageDirectory().toString() + "/" + fileName);
copyFile(is, os);
is.close();
os.flush();
os.close();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
Uri path = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Dojo_lab_tour.pdf");
String oPath = path.toString();
Intent intent = new Intent(PdfMainActivity.this, ReaderActivity.class);
if (ContextCompat.checkSelfPermission(PdfMainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
intent.setDataAndType(path, "application/pdf");
intent.putExtra(PdfViewerActivity.EXTRA_PDFFILENAME, oPath);
startActivity(intent);
} else {
Log.d(TAG, "No permission!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void copyFile(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = is.read(buffer)) != -1) {
os.write(buffer, 0, read);
}
}
}
And here is my 2nd activity:
package com.dell.pdfreader;
import android.os.Bundle;
public class ReaderActivity extends net.sf.andpdf.pdfviewer.PdfViewerActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reader);
}
#Override
public int getPreviousPageImageResource() {
return R.drawable.left_arrow;
}
#Override
public int getNextPageImageResource() {
return R.drawable.right_arrow;
}
#Override
public int getZoomInImageResource() {
return R.drawable.zoom_in;
}
#Override
public int getZoomOutImageResource() {
return R.drawable.zoom_out;
}
#Override
public int getPdfPasswordLayoutResource() {
return 0;
}
#Override
public int getPdfPageNumberResource() {
return 0;
}
#Override
public int getPdfPasswordEditField() {
return 0;
}
#Override
public int getPdfPasswordOkButton() {
return 0;
}
#Override
public int getPdfPasswordExitButton() {
return 0;
}
#Override
public int getPdfPageNumberEditField() {
return 0;
}
}
When I run that code, I get this error:
03-05 16:19:43.000 14997-14997/com.dell.pdfreader E/com.dell.pdfreader.PdfMainActivity: /storage/emulated/0/Dojo_Lab_Tour.pdf (Permission denied)
03-05 16:19:43.049 14997-14997/com.dell.pdfreader I/PDFVIEWER: onCreate
03-05 16:19:43.049 14997-14997/com.dell.pdfreader E/PDFVIEWER: restoreInstance
03-05 16:19:43.119 14997-14997/com.dell.pdfreader I/PDFVIEWER: Intent { dat=/storage/emulated/0/Dojo_lab_tour.pdf typ=application/pdf cmp=com.dell.pdfreader/.ReaderActivity (has extras) }
03-05 16:19:43.124 14997-14997/com.dell.pdfreader I/PDFVIEWER: ST='file '/storage/emulated/0/Dojo_lab_tour.pdf' not found'
In mainfest file, I've added these two lines:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
How can I fix this error?
EDIT:
My assets folder structure is as given below:
I modified my code as suggested by Tommin and Commonsware:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
Intent intent = new Intent(PdfMainActivity.this, ReaderActivity.class);
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
intent.setDataAndType(path, "application/pdf");
intent.putExtra(PdfViewerActivity.EXTRA_PDFFILENAME, oPath);
startActivity(intent);
} else {
Log.d(TAG, "No permission!");
}
}
Getting this error now:
03-05 17:45:26.526 7888-7888/com.dell.pdfreader E/com.dell.pdfreader.PdfMainActivity: /storage/emulated/0/Dojo_Lab_Tour.pdf (Permission denied)
1- Add the permissions in your manifest, like you did:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.....">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
2- These 2 permissions are considered to be dangerous permissions, which you should request on the Runtime, on your onClick method for ex:
#Override
public void onClick (View view) {
if (ContextCompat.checkSelfPermission (PdfMainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission (PdfMainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions (PdfMainActivity.this, new String [] { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE }, 1000);
return;
}
...
}
3- Make sure the external storage is writable before copying your stream into it:
if (!isExternalStorageWritable ()) {
throw new Exception ("External Storage Not Writable");
}
private boolean isExternalStorageWritable () {
return Environment.MEDIA_MOUNTED.equals (Environment.getExternalStorageState ());
}
4- Your code becomes:
#Override
public void onClick (View v) {
if (ContextCompat.checkSelfPermission (PdfMainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission (PdfMainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions (PdfMainActivity.this, new String [] { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE }, 1000);
return;
}
AssetManager assetManager = getAssets ();
String dir = "pdffiles";
try {
String [] paths = assetManager.list (dir);
for (String path : paths) {
if (!isExternalStorageWritable ()) {
throw new Exception ("External Storage Not Writable");
}
InputStream is = assetManager.open (dir + File.separator + path);
OutputStream os = new FileOutputStream (Environment.getExternalStorageDirectory () + File.separator + path);
copy (is, os);
closeQuietly (os, is);
}
} catch (Exception e) {
// TODO Catch your exception here
}
}
public static int copy (InputStream is, OutputStream os) throws IOException {
long count = 0;
int n;
byte [] buffer = new byte [4 * 1024];
while (-1 != (n = is.read (buffer))) {
os.write (buffer, 0, n);
count += n;
}
if (count > Integer.MAX_VALUE) {
return -1;
}
return (int) count;
}
public static void closeQuietly (Closeable... closeables) {
if (closeables == null || closeables.length == 0) {
return;
}
try {
for (Closeable closeable : closeables) {
if (closeable != null) {
closeable.close ();
}
}
} catch (final IOException ignore) { }
}
5- When trying to read the PDFs, make sure the external storage is readable as well by calling:
private boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState ();
return Environment.MEDIA_MOUNTED.equals (state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals (state);
}
6- Put the copy processing on a background thread not to block the UI. And maybe show a progress Popup to the user.
I got it, guys. I modified my code as:
Uri path = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "EPSF.pdf");
String oPath = path.toString();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(PdfMainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 1000);
Log.d(TAG, "No permission!");
} else {
Intent intent1 = new Intent(PdfMainActivity.this, ReaderActivity.class);
intent1.setDataAndType(path, "application/pdf");
intent1.putExtra(PdfViewerActivity.EXTRA_PDFFILENAME, oPath);
startActivity(intent1);
}
}
I added run time permissions and modified according to what Mehdi had suggested.
Related
Can anyone help me with this error. My app is running properly but when clicking activity button, it crashes and this error logcat appears. Anyway, my .so files are in jniLibs folder.
12-26 12:02:12.393 22612-22612/com.project.voicechanger
E/AndroidRuntime: FATAL EXCEPTION: main Process:
com.project.voicechanger, PID: 22612 java.lang.UnsatisfiedLinkError:
dalvik.system.PathClassLoader[DexPathList[[zip file
"/data/app/com.project.voicechanger-2/base.apk"],nativeLibraryDirectories=[/data/app/com.prject.voicechanger-2/lib/arm64,
/data/app/com.project.voicechanger-2/base.apk!/lib/arm64-v8a,
/vendor/lib64, /system/lib64]]] couldn't find "libbass.so"
at java.lang.Runtime.loadLibrary(Runtime.java:367)
at java.lang.System.loadLibrary(System.java:1076)
at com.un4seen.bass.BASS.(BASS.java:695)
at com.ypyproductions.voicechanger.EffectActivity.onInitAudioDevice(EffectActivity.java:384)
at com.ypyproductions.voicechanger.EffectActivity.setupInfo(EffectActivity.java:119)
at com.ypyproductions.voicechanger.EffectActivity.onCreate(EffectActivity.java:100)
at android.app.Activity.performCreate(Activity.java:6323)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
at android.app.ActivityThread.access$900(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1347)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5451)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
This is the EffectActivity.java appeared on the error:
package com.ypyproductions.voicechanger;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.un4seen.bass.BASS;
import com.ypyproductions.materialdialogs.MaterialDialog;
import com.ypyproductions.voicechanger.adapter.EffectAdapter;
import com.ypyproductions.voicechanger.basseffect.DBMediaPlayer;
import com.ypyproductions.voicechanger.basseffect.IDBMediaListener;
import com.ypyproductions.voicechanger.dataMng.JsonParsingUtils;
import com.ypyproductions.voicechanger.dataMng.TotalDataManager;
import com.ypyproductions.voicechanger.object.EffectObject;
import com.ypyproductions.voicechanger.soundMng.SoundManager;
import com.ypyproductions.voicechanger.task.DBTask;
import com.ypyproductions.voicechanger.task.IDBCallback;
import com.ypyproductions.voicechanger.task.IDBTaskListener;
import com.ypyproductions.voicechanger.utils.ApplicationUtils;
import com.ypyproductions.voicechanger.utils.DBLog;
import com.ypyproductions.voicechanger.utils.DirectionUtils;
import com.ypyproductions.voicechanger.utils.IOUtils;
import com.ypyproductions.voicechanger.utils.StringUtils;
import java.io.File;
import java.util.ArrayList;
/**
*
*
* #author:YPY Productions
* #Skype: baopfiev_k50
* #Mobile : +84 983 028 786
* #Email: dotrungbao#gmail.com
* #Website: www.ypyproductions.com
* #Project:TemplateChangeTheme
* #Date:Aug 4, 2015
*
*/
public class EffectActivity extends DBFragmentActivity implements OnClickListener, EffectAdapter.OnEffectListener {
public static final String TAG = EffectActivity.class.getSimpleName();
private ListView mListViewEffects;
private ArrayList<EffectObject> mListEffectObjects;
private EffectAdapter mEffectApdater;
private String mPathAudio;
private TextView mTvHeader;
private boolean isInit;
private DBMediaPlayer mDBMedia;
private String mNameExportVoice;
private AdView adView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_effects);
Intent mIntent = getIntent();
if (mIntent != null) {
mPathAudio = mIntent.getStringExtra(KEY_PATH_AUDIO);
}
mListViewEffects = (ListView) findViewById(R.id.list_effects);
mTvHeader = (TextView) findViewById(R.id.tv_header);
mTvHeader.setTypeface(mTypefaceLogo);
setUpBlurLayout();
setupLayoutAdmob();
if (!StringUtils.isEmptyString(mPathAudio)) {
File mFile = new File(mPathAudio);
if (mFile.exists() && mFile.isFile()) {
setupInfo();
}
else {
showToast("File not found exception");
backToHome();
}
}
else {
backToHome();
}
}
private void setupInfo(){
mListEffectObjects = TotalDataManager.getInstance().getListEffectObjects();
if (mListEffectObjects != null && mListEffectObjects.size() > 0) {
mEffectApdater = new EffectAdapter(this, mListEffectObjects, mTypefaceAvenir);
mEffectApdater.setOnEffectListener(this);
mListViewEffects.setAdapter(mEffectApdater);
onInitAudioDevice();
createDBMedia();
}
else{
startLoad(new IDBCallback() {
#Override
public void onAction() {
setupInfo();
}
});
}
}
private void startLoad(final IDBCallback mCallback){
DBTask mDBTask = new DBTask(new IDBTaskListener() {
public ArrayList<EffectObject> mListEffects;
#Override
public void onPreExcute() {
showProgressDialog();
}
#Override
public void onDoInBackground() {
String data = IOUtils.readStringFromAssets(EffectActivity.this, "effects.dat");
mListEffects = JsonParsingUtils.parsingListEffectObject(data);
DBLog.d(TAG, "===============>Size=" + mListEffects.size());
if (mListEffects != null && mListEffects.size() > 0) {
mTotalMng.setListEffectObjects(mListEffects);
}
}
#Override
public void onPostExcute() {
dimissProgressDialog();
if (mListEffects == null || mListEffects.size() == 0) {
backToHome();
return;
}
if(mCallback!=null){
mCallback.onAction();
}
}
});
mDBTask.execute();
}
private void setupLayoutAdmob() {
boolean b=SHOW_ADVERTISEMENT;
RelativeLayout layout = (RelativeLayout) findViewById(R.id.layout_ad);
if (ApplicationUtils.isOnline(this) && b) {
adView = new AdView(this);
adView.setAdUnitId(ADMOB_ID_BANNER);
adView.setAdSize(AdSize.SMART_BANNER);
layout.addView(adView);
AdRequest mAdRequest = new AdRequest.Builder().addTestDevice("51F0A3F4C13F05DD49DE0D71F2B369FB").build();
adView.loadAd(mAdRequest);
return;
}
layout.setVisibility(View.GONE);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_back:
mSoundMng.play(this, R.raw.click);
backToHome();
break;
case R.id.btn_gallery:
mSoundMng.play(this, R.raw.click);
deleteMainFile();
onDestroyMedia();
Intent mIntent = new Intent(this, GalleryActivity.class);
DirectionUtils.changeActivity(this, R.anim.slide_in_from_right, R.anim.slide_out_to_left, true, mIntent);
break;
default:
break;
}
}
private void deleteMainFile() {
if (!StringUtils.isEmptyString(mPathAudio)) {
try {
File file = new File(mPathAudio);
file.delete();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
protected void onDestroy() {
if (adView != null) {
adView.destroy();
}
super.onDestroy();
}
private void onDestroyMedia(){
try{
if (mDBMedia != null) {
mDBMedia.releaseAudio();
}
BASS.BASS_PluginFree(0);
BASS.BASS_Free();
TotalDataManager.getInstance().onResetState();
}
catch(Exception e){
e.printStackTrace();
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
backToHome();
return true;
}
return super.onKeyDown(keyCode, event);
}
private void backToHome() {
deleteMainFile();
onDestroyMedia();
Intent mIntent = new Intent(this, RecordActivity.class);
DirectionUtils.changeActivity(this, R.anim.slide_in_from_left, R.anim.slide_out_to_right, true, mIntent);
}
#Override
public void onPlayEffect(EffectObject mEffectObject) {
boolean isPlaying = mEffectObject.isPlaying();
if (isPlaying) {
mEffectObject.setPlaying(false);
if (mDBMedia != null) {
mDBMedia.pauseAudio();
}
}
else {
TotalDataManager.getInstance().onResetState();
mEffectObject.setPlaying(true);
if (mDBMedia != null) {
mDBMedia.setReverse(mEffectObject.isReverse());
mDBMedia.setAudioPitch(mEffectObject.getPitch());
mDBMedia.setAudioRate(mEffectObject.getRate());
mDBMedia.setAudioReverb(mEffectObject.getReverb());
mDBMedia.setAudioEQ(mEffectObject.getEq());
mDBMedia.setFlangerEffect(mEffectObject.isFlanger());
mDBMedia.setAudioEcho(mEffectObject.isEcho());
if (mDBMedia.isPlaying()) {
if(!mEffectObject.isReverse()){
mDBMedia.seekTo(0);
}
else{
mDBMedia.seekTo(mDBMedia.getDuration());
}
}
mDBMedia.startAudio();
}
}
mEffectApdater.notifyDataSetChanged();
}
#Override
protected void onPause() {
super.onPause();
if (mDBMedia != null) {
resetStateAudio();
}
}
#Override
public void onShareEffect(final EffectObject mEffectObject) {
if(mDBMedia!=null){
resetStateAudio();
}
SoundManager.getInstance().play(this, R.raw.click);
mNameExportVoice=String.format(FORMAT_NAME_VOICE, String.valueOf(System.currentTimeMillis()/1000));
showDialogEnterName(new IDBCallback() {
#Override
public void onAction() {
if (mDBMedia != null) {
startSaveEffect(mEffectObject, new IDBCallback() {
#Override
public void onAction() {
File file = new File(mPathAudio);
File mDir = file.getParentFile();
final File mOutPutFile = new File(mDir, mNameExportVoice);
if (mOutPutFile.exists() && mOutPutFile.isFile()) {
String mInfoSave = String.format(getString(R.string.info_save_voice), mOutPutFile.getAbsolutePath());
showToast(mInfoSave);
showDiaglogShare(mEffectObject);
}
}
});
}
}
});
}
private void resetStateAudio() {
TotalDataManager.getInstance().onResetState();
if (mEffectApdater != null) {
mEffectApdater.notifyDataSetChanged();
}
if (mDBMedia!=null && mDBMedia.isPlaying()) {
mDBMedia.pauseAudio();
}
}
private void startSaveEffect(final EffectObject mEffectObject, final IDBCallback mDBCallback) {
File file = new File(mPathAudio);
final File mDir = file.getParentFile();
final File mTempOutPutFile = new File(mDir, mNameExportVoice);
final DBMediaPlayer mDBExportMedia = new DBMediaPlayer(mPathAudio);
DBTask mDBTask = new DBTask(new IDBTaskListener() {
#Override
public void onPreExcute() {
showProgressDialog();
}
#Override
public void onDoInBackground() {
if (mDBExportMedia != null) {
boolean b = mDBExportMedia.initMediaToSave();
if (b) {
mDBExportMedia.setReverse(mEffectObject.isReverse());
mDBExportMedia.setAudioPitch(mEffectObject.getPitch());
mDBExportMedia.setAudioRate(mEffectObject.getRate());
mDBExportMedia.setAudioReverb(mEffectObject.getReverb());
mDBExportMedia.setFlangerEffect(mEffectObject.isFlanger());
mDBExportMedia.setAudioEcho(mEffectObject.isEcho());
mDBExportMedia.setAudioEQ(mEffectObject.getEq());
mDBExportMedia.saveToFile(mTempOutPutFile.getAbsolutePath());
mDBExportMedia.releaseAudio();
}
}
}
#Override
public void onPostExcute() {
dimissProgressDialog();
if (mDBCallback != null) {
mDBCallback.onAction();
}
}
});
mDBTask.execute();
}
public void onInitAudioDevice() {
if (!isInit) {
isInit = true;
if (!BASS.BASS_Init(-1, 44100, 0)) {
new Exception(TAG + " Can't initialize device").printStackTrace();
this.isInit = false;
return;
}
String libpath = getApplicationInfo().nativeLibraryDir;
try{
BASS.BASS_PluginLoad(libpath + "/libbass_fx.so", 0);
BASS.BASS_PluginLoad(libpath + "/libbassenc.so", 0);
BASS.BASS_PluginLoad(libpath + "/libbassmix.so", 0);
BASS.BASS_PluginLoad(libpath + "/libbasswv.so", 0);
}
catch(Exception e){
e.printStackTrace();
}
}
}
private void createDBMedia() {
if (!StringUtils.isEmptyString(mPathAudio)) {
mDBMedia = new DBMediaPlayer(mPathAudio);
mDBMedia.prepareAudio();
mDBMedia.setOnDBMediaListener(new IDBMediaListener() {
#Override
public void onMediaError() {
}
#Override
public void onMediaCompletion() {
TotalDataManager.getInstance().onResetState();
mEffectApdater.notifyDataSetChanged();
}
});
}
}
private void showDiaglogShare(final EffectObject mEffectObject) {
MaterialDialog.Builder mBuilder = new MaterialDialog.Builder(this);
mBuilder.backgroundColor(getResources().getColor(R.color.white));
mBuilder.title(R.string.title_options);
mBuilder.titleColor(getResources().getColor(R.color.black_text));
mBuilder.items(R.array.list_options);
mBuilder.contentColor(getResources().getColor(R.color.black_text));
mBuilder.positiveColor(getResources().getColor(R.color.pink));
mBuilder.negativeColor(getResources().getColor(R.color.black_secondary_text));
mBuilder.positiveText(R.string.title_cancel);
mBuilder.autoDismiss(true);
mBuilder.typeface(mTypefaceBold, mTypefaceLight);
mBuilder.itemsCallback(new MaterialDialog.ListCallback() {
#Override
public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) {
if (which == 0) {
shareFile();
}
else if (which == 1) {
saveAsRingtone();
}
else if (which == 2) {
saveAsNotification();
}
}
});
mBuilder.build().show();
}
private void shareFile() {
File file = new File(mPathAudio);
File mDir = file.getParentFile();
final File mOutPutFile = new File(mDir, mNameExportVoice);
if (mOutPutFile.exists() && mOutPutFile.isFile()) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
if(mNameExportVoice.endsWith(AUDIO_RECORDER_FILE_EXT_MP3)){
shareIntent.setType("audio/mp3");
}
else{
shareIntent.setType("audio/*");
}
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(mOutPutFile));
startActivity(Intent.createChooser(shareIntent, "Share Via"));
}
}
private void saveAsRingtone() {
File file = new File(mPathAudio);
File mDir = file.getParentFile();
final File mOutPutFile = new File(mDir, mNameExportVoice);
if (mOutPutFile != null && mOutPutFile.isFile()) {
Uri mUri=null;
ContentValues values = new ContentValues();
values.put(MediaColumns.DATA, mOutPutFile.getAbsolutePath());
values.put(MediaColumns.TITLE, mNameExportVoice.replaceAll(AUDIO_RECORDER_FILE_EXT_WAV, ""));
values.put(MediaColumns.MIME_TYPE, "audio/*");
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
String id=getIdFromContentUri(mOutPutFile.getAbsolutePath());
if(StringUtils.isEmptyString(id)){
mUri = this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(mOutPutFile.getAbsolutePath()), values);
}
else{
this.getContentResolver().update(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
, values, MediaColumns._ID+" = ?", new String[]{id});
mUri=Uri.parse(String.format(FORMAT_URI, id));
}
RingtoneManager.setActualDefaultRingtoneUri(this, RingtoneManager.TYPE_RINGTONE, mUri);
showToast(R.string.info_set_ringtone_successfully);
}
}
private void saveAsNotification() {
File file = new File(mPathAudio);
File mDir = file.getParentFile();
final File mOutPutFile = new File(mDir, mNameExportVoice);
if (mOutPutFile != null && mOutPutFile.isFile()) {
Uri mUri=null;
ContentValues values = new ContentValues();
values.put(MediaColumns.DATA, mOutPutFile.getAbsolutePath());
values.put(MediaColumns.TITLE, mNameExportVoice.replaceAll(AUDIO_RECORDER_FILE_EXT_WAV, ""));
values.put(MediaColumns.MIME_TYPE, "audio/*");
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
String id=getIdFromContentUri(mOutPutFile.getAbsolutePath());
if(StringUtils.isEmptyString(id)){
mUri = this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(mOutPutFile.getAbsolutePath()), values);
}
else{
this.getContentResolver().update(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
, values, MediaColumns._ID+" = ?", new String[]{id});
mUri=Uri.parse(String.format(FORMAT_URI, id));
}
RingtoneManager.setActualDefaultRingtoneUri(this, RingtoneManager.TYPE_NOTIFICATION, mUri);
showToast(R.string.info_set_notification_successfully);
}
}
private String getIdFromContentUri(String path) {
try {
if(path!=null){
String id;
String[] filePathColumn = {MediaColumns._ID};
String[] selectionArgs = {path};
Cursor cursor = this.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
filePathColumn, MediaColumns.DATA+" = ?", selectionArgs, null);
if(cursor!=null && cursor.moveToFirst()){
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
id = cursor.getString(columnIndex);
cursor.close();
return id;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
private void showDialogEnterName(final IDBCallback mDCallback) {
final EditText mEdName = new EditText(this);
mEdName.setSingleLine(true);
Builder builder = new Builder(this).setTitle(getString(R.string.title_enter_name)).setView(mEdName)
.setPositiveButton(getString(R.string.title_ok), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ApplicationUtils.hiddenVirtualKeyboard(EffectActivity.this, mEdName);
String mNewName = mEdName.getText().toString();
if(!StringUtils.isEmptyString(mNewName)){
if(StringUtils.isContainsSpecialCharacter(mNewName)){
showToast(R.string.info_your_name_error);
return;
}
mNameExportVoice=mNewName+".wav";
}
if(mDCallback!=null){
mDCallback.onAction();
}
}
}).setNegativeButton(getString(R.string.title_skip), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if(mDCallback!=null){
mDCallback.onAction();
}
}
});
AlertDialog mDialogEnterPass = builder.create();
mDialogEnterPass.show();
}
}
This is the app gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
buildToolsVersion '28.0.3'
dexOptions {
javaMaxHeapSize "4g"
}
defaultConfig {
applicationId "com.ypyproductions.voicechanger"
minSdkVersion 15
targetSdkVersion 27
versionCode 20181
versionName "1.0"
multiDexEnabled true
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':nineOldLibrary')
implementation project(':materialDialog')
implementation 'com.android.support:support-fragment:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:support-media-compat:27.1.1'
implementation 'com.android.support:support-compat:27.1.1'
implementation 'com.android.support:customtabs:27.1.1'
implementation 'com.android.support:multidex:1.0.3'
implementation 'com.google.android.gms:play-services-ads:17.1.2'
implementation 'com.google.android.gms:play-services-identity:16.0.0'
implementation 'com.google.android.gms:play-services-gcm:16.0.0'
}
I am using Android Studio and Windows 10 laptop.
From un4seen.com forum:
1 mkdir lib, then, copy armeabi to lib, the tree should bee lib/armeeabi/libbass.so
2 zip lib directory: $zip -r libbass.zip lib
3 rename: $mv libbass.zip libbass.jar
4 copy libbass.jar to YourProject/Youproject/src/main/libs, "YourProject/Youproject/src/main/" includes AndroidManifests.xml, res, java, libs
5 add this line:
compile fileTree(dir: 'libs', include: '*.jar')
to your build.gradle---->dependencies
I want to run a Backgroundservice (FileObserver) that will look for any filechanges in the system (CREATE, DELETE, MOVE, ...).
When I start my application it works a few seconds and logs everything fine. For example at taking a picture by the camera it logs that. After a few seconds the service is still listed in Settings => Developer Options => Running Services but does not work and log anything anymore.
Android Version: 7.0
Device: Samsung Galaxy S7 Edge
I copied the code from Niza Siwale's answer here 1:1 and added only the Logs like that :
How to monitor folder for file changes in background?
#Override
public void onEvent(int event, final String path) {
if (event == FileObserver.OPEN) {
Log.v("Event: ", "Open" + path);
} else if (event == FileObserver.CREATE && (!path.equals(".probe"))) {
Log.v("Event: ", "Create" + path);
} else if (event == FileObserver.DELETE_SELF || event == FileObserver.DELETE) {
Log.v("Event: ", "Delete" + path);
} else if (event == FileObserver.MOVE_SELF || event == FileObserver.MOVED_FROM || event == FileObserver.MOVED_TO) {
Log.v("Event: ", "Move" + path);
}
}
Why is the service running in background (as I can see in Running Services) but not donig any logs, if something changes in the filesystem?
Full Code:
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.spicysoftware.phonesaver">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- Adding the permission -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<service
android:name=".FileSystemObserverService"
android:enabled="true"
android:exported="true" >
</service>
<!-- Declaring broadcast receiver for BOOT_COMPLETED event. -->
<receiver android:name=".StartupReceiver" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity
package com.spicysoftware.phonesaver;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.FileObserver;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
String TAG = "Log: ";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(isReadStoragePermissionGranted()){
Intent myIntent = new Intent(this, FileSystemObserverService.class);
this.startService(myIntent);
}
}
public boolean isReadStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted1");
return true;
} else {
Log.v(TAG,"Permission is revoked1");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 3);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted1");
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 3:
Log.d(TAG, "External storage1");
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]);
}else{
}
break;
}
}
}
FileSystemOberveService
package com.spicysoftware.phonesaver;
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.FileObserver;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class FileSystemObserverService extends Service {
String externalPath = "";
String internalPath = "";
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
observe();
return super.onStartCommand(intent, flags, startId);
}
public File getInternalStoragePath() {
File parent = Environment.getExternalStorageDirectory().getParentFile();
File external = Environment.getExternalStorageDirectory();
File[] files = parent.listFiles();
File internal = null;
if (files != null) {
for (int i = 0; i < files.length; i++) {
if (files[i].getName().toLowerCase().startsWith("sdcard") && !files[i].equals(external)) {
internal = files[i];
}
}
}
return internal;
}
public File getExtenerStoragePath() {
return Environment.getExternalStorageDirectory();
}
public void observe() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
//File[] listOfFiles = new File(path).listFiles();
File str = getInternalStoragePath();
if (str != null) {
internalPath = str.getAbsolutePath();
new Obsever(internalPath).startWatching();
}
str = getExtenerStoragePath();
if (str != null) {
externalPath = str.getAbsolutePath();
new Obsever(externalPath).startWatching();
}
}
});
t.setPriority(Thread.MIN_PRIORITY);
t.start();
}
class Obsever extends FileObserver {
List<SingleFileObserver> mObservers;
String mPath;
int mMask;
public Obsever(String path) {
// TODO Auto-generated constructor stub
this(path, ALL_EVENTS);
}
public Obsever(String path, int mask) {
super(path, mask);
mPath = path;
mMask = mask;
// TODO Auto-generated constructor stub
}
#Override
public void startWatching() {
// TODO Auto-generated method stub
if (mObservers != null)
return;
mObservers = new ArrayList<SingleFileObserver>();
Stack<String> stack = new Stack<String>();
stack.push(mPath);
while (!stack.empty()) {
String parent = stack.pop();
mObservers.add(new SingleFileObserver(parent, mMask));
File path = new File(parent);
File[] files = path.listFiles();
if (files == null) continue;
for (int i = 0; i < files.length; ++i) {
if (files[i].isDirectory() && !files[i].getName().equals(".") && !files[i].getName().equals("..")) {
stack.push(files[i].getPath());
}
}
}
for (int i = 0; i < mObservers.size(); i++) {
mObservers.get(i).startWatching();
}
}
#Override
public void stopWatching() {
// TODO Auto-generated method stub
if (mObservers == null)
return;
for (int i = 0; i < mObservers.size(); ++i) {
mObservers.get(i).stopWatching();
}
mObservers.clear();
mObservers = null;
}
#Override
public void onEvent(int event, final String path) {
if (event == FileObserver.OPEN) {
Log.v("Event: ", "Open" + path);
// makeToast("Opened: "+path);
} else if (event == FileObserver.CREATE && (!path.equals(".probe"))) {
Log.v("Event: ", "Create" + path);
// makeToast("Created: "+path);
} else if (event == FileObserver.DELETE_SELF || event == FileObserver.DELETE) {
Log.v("Event: ", "Delete" + path);
// makeToast("Deleted: "+path);
} else if (event == FileObserver.MOVE_SELF || event == FileObserver.MOVED_FROM || event == FileObserver.MOVED_TO) {
Log.v("Event: ", "Move" + path);
// makeToast("Moved: "+path);
}
}
private class SingleFileObserver extends FileObserver {
private String mPath;
public SingleFileObserver(String path, int mask) {
super(path, mask);
// TODO Auto-generated constructor stub
mPath = path;
}
#Override
public void onEvent(int event, String path) {
// TODO Auto-generated method stub
String newPath = mPath + "/" + path;
Obsever.this.onEvent(event, newPath);
}
}
}
/*
public void makeToast(final String strMessage){
//Let this be the code in your n'th level thread from main UI thread
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), strMessage, Toast.LENGTH_SHORT).show();
}
});
}
*/
}
StartupReceiver
package com.spicysoftware.phonesaver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class StartupReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, FileSystemObserverService.class);
context.startService(myIntent);
}
}
I am testing a camera application which captures high quality images. I want the captured image to be saved in the mobile memory (Internal or external) to check the details of the image.
I've the below code for capturing the image.
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomSheetBehavior;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.Toast;
import com.otaliastudios.cameraview.CameraListener;
import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.CameraOptions;
import com.otaliastudios.cameraview.CameraView;
import com.otaliastudios.cameraview.SessionType;
import com.otaliastudios.cameraview.Size;
import java.io.File;
public class CameraActivity extends AppCompatActivity implements View.OnClickListener, ControlView.Callback {
private CameraView camera;
private ViewGroup controlPanel;
private boolean mCapturingPicture;
private boolean mCapturingVideo;
// To show stuff in the callback
private Size mCaptureNativeSize;
private long mCaptureTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
setContentView(R.layout.activity_camera);
CameraLogger.setLogLevel(CameraLogger.LEVEL_VERBOSE);
camera = findViewById(R.id.camera);
camera.addCameraListener(new CameraListener() {
public void onCameraOpened(CameraOptions options) { onOpened(); }
public void onPictureTaken(byte[] jpeg) { onPicture(jpeg); }
#Override
public void onVideoTaken(File video) {
super.onVideoTaken(video);
onVideo(video);
}
});
findViewById(R.id.edit).setOnClickListener(this);
findViewById(R.id.capturePhoto).setOnClickListener(this);
findViewById(R.id.captureVideo).setOnClickListener(this);
findViewById(R.id.toggleCamera).setOnClickListener(this);
controlPanel = findViewById(R.id.controls);
ViewGroup group = (ViewGroup) controlPanel.getChildAt(0);
Control[] controls = Control.values();
for (Control control : controls) {
ControlView view = new ControlView(this, control, this);
group.addView(view, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
controlPanel.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
BottomSheetBehavior b = BottomSheetBehavior.from(controlPanel);
b.setState(BottomSheetBehavior.STATE_HIDDEN);
}
});
}
private void message(String content, boolean important) {
int length = important ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT;
Toast.makeText(this, content, length).show();
}
private void onOpened() {
ViewGroup group = (ViewGroup) controlPanel.getChildAt(0);
for (int i = 0; i < group.getChildCount(); i++) {
ControlView view = (ControlView) group.getChildAt(i);
view.onCameraOpened(camera);
}
}
private void onPicture(byte[] jpeg) {
mCapturingPicture = false;
long callbackTime = System.currentTimeMillis();
if (mCapturingVideo) {
message("Captured while taking video. Size="+mCaptureNativeSize, false);
return;
}
// This can happen if picture was taken with a gesture.
if (mCaptureTime == 0) mCaptureTime = callbackTime - 300;
if (mCaptureNativeSize == null) mCaptureNativeSize = camera.getPictureSize();
PicturePreviewActivity.setImage(jpeg);
Intent intent = new Intent(CameraActivity.this, PicturePreviewActivity.class);
intent.putExtra("delay", callbackTime - mCaptureTime);
intent.putExtra("nativeWidth", mCaptureNativeSize.getWidth());
intent.putExtra("nativeHeight", mCaptureNativeSize.getHeight());
startActivity(intent);
mCaptureTime = 0;
mCaptureNativeSize = null;
}
private void onVideo(File video) {
mCapturingVideo = false;
Intent intent = new Intent(CameraActivity.this, VideoPreviewActivity.class);
intent.putExtra("video", Uri.fromFile(video));
startActivity(intent);
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.edit: edit(); break;
case R.id.capturePhoto: capturePhoto(); break;
case R.id.captureVideo: captureVideo(); break;
case R.id.toggleCamera: toggleCamera(); break;
}
}
#Override
public void onBackPressed() {
BottomSheetBehavior b = BottomSheetBehavior.from(controlPanel);
if (b.getState() != BottomSheetBehavior.STATE_HIDDEN) {
b.setState(BottomSheetBehavior.STATE_HIDDEN);
return;
}
super.onBackPressed();
}
private void edit() {
BottomSheetBehavior b = BottomSheetBehavior.from(controlPanel);
b.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
private void capturePhoto() {
if (mCapturingPicture) return;
mCapturingPicture = true;
mCaptureTime = System.currentTimeMillis();
mCaptureNativeSize = camera.getPictureSize();
message("Capturing picture...", false);
camera.capturePicture();
}
private void captureVideo() {
if (camera.getSessionType() != SessionType.VIDEO) {
message("Can't record video while session type is 'picture'.", false);
return;
}
if (mCapturingPicture || mCapturingVideo) return;
mCapturingVideo = true;
message("Recording for 8 seconds...", true);
camera.startCapturingVideo(null, 8000);
}
private void toggleCamera() {
if (mCapturingPicture) return;
switch (camera.toggleFacing()) {
case BACK:
message("Switched to back camera!", false);
break;
case FRONT:
message("Switched to front camera!", false);
break;
}
}
#Override
public boolean onValueChanged(Control control, Object value, String name) {
if (!camera.isHardwareAccelerated() && (control == Control.WIDTH || control == Control.HEIGHT)) {
if ((Integer) value > 0) {
message("This device does not support hardware acceleration. " +
"In this case you can not change width or height. " +
"The view will act as WRAP_CONTENT by default.", true);
return false;
}
}
control.applyValue(camera, value);
BottomSheetBehavior b = BottomSheetBehavior.from(controlPanel);
b.setState(BottomSheetBehavior.STATE_HIDDEN);
message("Changed " + control.getName() + " to " + name, false);
return true;
}
//region Boilerplate
#Override
protected void onResume() {
super.onResume();
camera.start();
}
#Override
protected void onPause() {
super.onPause();
camera.stop();
}
#Override
protected void onDestroy() {
super.onDestroy();
camera.destroy();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
boolean valid = true;
for (int grantResult : grantResults) {
valid = valid && grantResult == PackageManager.PERMISSION_GRANTED;
}
if (valid && !camera.isStarted()) {
camera.start();
}
}
//endregion
}
I've also added the permissions to read and write the external storage.
But I just want to know the size of the picture once it is saved.
Adding the code to save the image -
public void KickOut(String filename,Bitmap bitmap){
ActivityCompat.requestPermissions(PicturePreviewActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
OutputStream outputStream;
File filepath=Environment.getExternalStorageDirectory();
// File dir=new File(filepath+"/Olaa/");
File dir=new File("/Environment.getExternalStoragePublicDirectory/Imgs/");
dir.mkdirs();
File file=new File(dir,"filename.png");
Toast.makeText(PicturePreviewActivity.this, file + " -> saved" , Toast.LENGTH_SHORT).show();
try{
outputStream=new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG,100,outputStream);
outputStream.flush();outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Toast.makeText(PicturePreviewActivity.this, filepath + " -> path" , Toast.LENGTH_SHORT).show();
}
You can check the size of the captured image you can also save the file in your custom folder.
you can get the result in onActivityResult() and get the image from the bundle and convert it into the byte and lengthbmp_KB will give you size in kb.
if (resultCode == RESULT_OK) {
//Image capture
if (requestCode == 1) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
byte[] imageInByte = bytes.toByteArray();
long lengthbmp = imageInByte.length;
// save on custom folder
File destination1 = createDirectoryAndSaveFile(thumbnail, System.currentTimeMillis() + ".jpg");
/* File destination = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");*/
picturePath = "" + destination1;
// show image on gallery
scanGallery(getActivity(), picturePath);
long lengthbmp_KB = lengthbmp / 1024;
long length_MB = lengthbmp_KB / 1024;
}
you can save the file at your own folder
private File createDirectoryAndSaveFile(Bitmap imageToSave, String fileName) {
File direct = new File(Environment.getExternalStorageDirectory() + "/My Images");
if (!direct.exists()) {
File wallpaperDirectory = new File("/sdcard/MYfolder Images/");
wallpaperDirectory.mkdirs();
}
File file = new File(new File("/sdcard/Myfolder Images/"), fileName);
/* if (file.exists()) {
file.delete();
}*/
try {
FileOutputStream out = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
You can see your images in Gallery by using this MediaScannerConnection
private void scanGallery(Context cntx, String path) {
try {
MediaScannerConnection.scanFile(cntx, new String[]{path}, null, new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
and use this method in onActivityResult()
To check the size of image saved in phone memory , you could use Bitmapfactory.option
**BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;**
You can use this to save the file provided you've given the permissions in the manifest.
static final int REQUEST_TAKE_PHOTO = 1;
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, REQUEST_TAKE_PHOTO);
}
}
}
Take a look at the docs too over here.
I am trying to send an image file through android using a server socket. I have used AsyncTask class on the client side and created a TransferFile class to send the file. I am getting a NO SUCH FILE OR DIRECTORY exception while creating the file on client's side. The code is attached below.
Permissions.
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
TransferFile class.
import android.app.IntentService;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
public class TransferFile extends IntentService{
private static final int SOCKET_TIMEOUT = 5000;
public static final String ACTION_SEND_FILE = "com.apposite.wifip2p.SEND_FILE";
public static final String EXTRAS_FILE_PATH = "file_url";
public static final String EXTRAS_GROUP_OWNER_ADDRESS = "go_host";
public static final String EXTRAS_GROUP_OWNER_PORT = "go_port";
public TransferFile(){
super("TransferFile");
}
#Override
protected void onHandleIntent(Intent intent) {
Context context = getApplicationContext();
Toast.makeText(this, "Client Socket Intent Handled.", Toast.LENGTH_SHORT).show();
if (intent.getAction().equals(ACTION_SEND_FILE)) {
Toast.makeText(context, "inside ACTION_SEND_FILE.", Toast.LENGTH_SHORT).show();
String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);
String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);
Socket socket = new Socket();
int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
try {
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
Toast.makeText(context, "Client Socket Connected: "+socket.isConnected(), Toast.LENGTH_SHORT).show();
OutputStream stream = socket.getOutputStream();
ContentResolver cr = context.getContentResolver();
InputStream is = null;
try {
is = cr.openInputStream(Uri.parse(fileUri));
}
catch (FileNotFoundException e) {
}
MainActivity.copyFile(is, stream);
} catch (IOException e) {
Toast.makeText(context, "File can't be copied to client.", Toast.LENGTH_SHORT).show();
} finally {
if(socket.isConnected()){
try {
socket.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
}
}
MainActivity class
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements WifiP2pManager.PeerListListener, WifiP2pManager.ConnectionInfoListener{
WifiP2pManager wifi;
private WifiP2pInfo info;
ListView listViewPeer;
WifiP2pManager.Channel channel;
IntentFilter intentFilter = new IntentFilter();
Button discover, send;
List<WifiP2pDevice> peersList;
List<String> peersNameList;
BroadcastReceiver receiver = null;
ProgressDialog progressDialog = null;
boolean isConnected = false;
protected static final int CHOOSE_FILE_RESULT_CODE = 20;
Intent serviceIntent;
boolean isHost = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
listViewPeer = (ListView) findViewById(R.id.ListViewPeer);
discover = (Button) findViewById(R.id.btnDiscover);
send = (Button) findViewById(R.id.btnGallery);
wifi = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = wifi.initialize(this, getMainLooper(), null);
receiver = new WifiP2pBroadcastReceiver(wifi, channel, this);
peersList = new ArrayList<>();
peersNameList = new ArrayList<>();
discover.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
progressDialog = ProgressDialog.show(MainActivity.this, "Press back to cancel", "finding peers", false,
true, new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
if(peersList.size()==0)
Toast.makeText(MainActivity.this, "Peer Not Found.", Toast.LENGTH_SHORT).show();
}
});
Runnable progressRunnable = new Runnable() {
#Override
public void run() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
};
Handler pdCanceller = new Handler();
pdCanceller.postDelayed(progressRunnable, 15000);
wifi.discoverPeers(channel, new WifiP2pManager.ActionListener(){
#Override
public void onSuccess() {
}
#Override
public void onFailure(int reason) {
Toast.makeText(MainActivity.this, "Peer Discovery failed.", Toast.LENGTH_SHORT).show();
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
});
}
});
refreshList();
listViewPeer.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(!isConnected)
connect(position);
else
disconnect();
}
});
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
}
});
if(!isConnected)
send.setVisibility(View.GONE);
else
send.setVisibility(View.VISIBLE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//super.onActivityResult(requestCode, resultCode, data);
Uri uri = data.getData();
serviceIntent = new Intent(this, TransferFile.class);
serviceIntent.setAction(TransferFile.ACTION_SEND_FILE);
serviceIntent.putExtra(TransferFile.EXTRAS_FILE_PATH, uri.toString());
serviceIntent.putExtra(TransferFile.EXTRAS_GROUP_OWNER_ADDRESS, info.groupOwnerAddress.getHostAddress());
serviceIntent.putExtra(TransferFile.EXTRAS_GROUP_OWNER_PORT, 8988);
this.startService(serviceIntent);
Toast.makeText(this, "TransferFile should start.", Toast.LENGTH_SHORT).show();
}
public void connect(int position) {
final WifiP2pDevice device = peersList.get(position);
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC;
wifi.connect(channel, config, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
}
#Override
public void onFailure(int reason) {
Toast.makeText(MainActivity.this, "Connect failed. Retry.", Toast.LENGTH_SHORT).show();
}
});
}
public void disconnect() {
send.setVisibility(View.GONE);
wifi.removeGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onFailure(int reasonCode) {
Toast.makeText(MainActivity.this, "Device disconnecting failed.", Toast.LENGTH_SHORT).show();
}
#Override
public void onSuccess() {
}
});
}
#Override
public void onResume() {
super.onResume();
registerReceiver(receiver, intentFilter);
send.setVisibility(View.GONE);
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
#Override
protected void onDestroy() {
super.onStop();
if(isHost)
stopService(serviceIntent);
}
#Override
public void onPeersAvailable(WifiP2pDeviceList peers) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
peersList.clear();
peersList.addAll(peers.getDeviceList());
refreshList();
}
public void refreshList(){
peersNameList.clear();
if(peersList.size()!=0){
for(int i=0;i<peersList.size();i++){
peersNameList.add(i, peersList.get(i).deviceName);
}
}
else
send.setVisibility(View.GONE);
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, peersNameList);
listViewPeer.setAdapter(arrayAdapter);
}
#Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
this.info = info;
if(!isConnected){
Toast.makeText(MainActivity.this, "Device Connected.", Toast.LENGTH_SHORT).show();
isConnected = true;
if (info.groupFormed && info.isGroupOwner) {
isHost = false;
new FileServerAsyncTask(this).execute();
}
else if(info.groupFormed)
send.setVisibility(View.VISIBLE);
else
Toast.makeText(MainActivity.this, "Nothing matters", Toast.LENGTH_SHORT).show();
}
}
public void reset(){
if(isConnected){
Toast.makeText(MainActivity.this, "Device Disconnected.", Toast.LENGTH_SHORT).show();
isConnected = false;
send.setVisibility(View.GONE);
}
}
public class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
Context context;
FileServerAsyncTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(Void... params) {
try {
ServerSocket serverSocket = new ServerSocket(8988);
Socket client = serverSocket.accept();
final File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/"
+ context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
+ ".jpg");
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
// Here
// is
// the
// ERROR
f.createNewFile();
InputStream inputstream = client.getInputStream();
copyFile(inputstream, new FileOutputStream(f));
serverSocket.close();
return f.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(context, "inside post execute." + result, Toast.LENGTH_SHORT).show();
if (result != null) {
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + result), "image/*");
context.startActivity(intent);
}
}
#Override
protected void onPreExecute() {
Toast.makeText(context, "Opening a server socket", Toast.LENGTH_SHORT).show();
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
} catch (IOException e) {
return false;
}
return true;
}
}
And this is my FileServerAsycTask class
public class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
Context context;
FileServerAsyncTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(Void... params) {
try {
ServerSocket serverSocket = new ServerSocket(8988);
Socket client = serverSocket.accept();
final File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/"
+ context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
+ ".jpg");
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
// Here
// is
// the
// ERROR
f.createNewFile();
InputStream inputstream = client.getInputStream();
copyFile(inputstream, new FileOutputStream(f));
serverSocket.close();
return f.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(context, "inside post execute." + result, Toast.LENGTH_SHORT).show();
if (result != null) {
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + result), "image/*");
context.startActivity(intent);
}
}
#Override
protected void onPreExecute() {
Toast.makeText(context, "Opening a server socket", Toast.LENGTH_SHORT).show();
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
} catch (IOException e) {
return false;
}
return true;
}
When on the client side, I try to create a new file using f.createNewFile(), it gives me an error "No such file or directory".
W/System.err: java.io.IOException: open failed: ENOENT (No such file or directory)
W/System.err: at java.io.File.createNewFile(File.java:939)
W/System.err: at com.apposite.wifip2p.MainActivity$FileServerAsyncTask.doInBackground(MainActivity.java:360)
W/System.err: at com.apposite.wifip2p.MainActivity$FileServerAsyncTask.doInBackground(MainActivity.java:310)
W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:295)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
W/System.err: at java.lang.Thread.run(Thread.java:818)
W/System.err: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
W/System.err: at libcore.io.Posix.open(Native Method)
W/System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
W/System.err: at java.io.File.createNewFile(File.java:932)
W/System.err: ... 8 more
The file's name is...
/storage/emulated/0/com.apposite.wifip2pwifip2pshared-1489935211585.jpg
Please help me how to resolve it!
When creating your Intent to pass the Uri over to the service:
Put in in the data facet of the Intent (setData(), not putExtra()), and
Call addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) on the Intent before calling startService()
Your activity has access to this content; without these changes, your service will not have access to the content.
Also, if your targetSdkVersion is 23 or higher, and you are running on Android 6.0+, you need to handle runtime permissions.
I am developing an app to uploading ,displaying and downloading files from G Drive. Unfortunately When downloading I am getting
com.google.api.client.http.HttpResponseException: 401 Unauthorized.
Please help me to solve this problem.
Here I am assigning
credential = GoogleAccountCredential.usingOAuth2(this,DriveScopes.DRIVE);
service=new Drive.Builder(AndroidHttp.newCompatibleTransport(),new GsonFactory(),credential).build();
My Code Is:
package com.example.googledrive;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Children;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.Drive.Files.Get;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.ChildList;
import com.google.api.services.drive.model.ChildReference;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
static final int REQUEST_ACCOUNT_PICKER = 1;
static final int REQUEST_AUTHORIZATION = 2;
static final int CAPTURE_IMAGE = 3;
private static Uri fileUri;
private static Drive service;
private ProgressDialog progressDialog;
private GoogleAccountCredential credential;
String fileId;
String fileName;
String downloadUrl;
ListView listView;
Activity activity;
String sdCardPadth;
List<File> allFileList;
ArrayList<String> fileType;
ArrayList<String> mainTitleList;
ArrayList<String> fileIdList;
ArrayList<String> alternateUrlList;
ArrayList<Integer> fileSizeList;
FileTitlesAdapter myAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.uploadedFilesList);
allFileList = new ArrayList<File>();
mainTitleList = new ArrayList<String>();
alternateUrlList = new ArrayList<String>();
fileSizeList = new ArrayList<Integer>();
fileType = new ArrayList<String>();
fileIdList=new ArrayList<String>();
progressDialog=new ProgressDialog(getApplicationContext());
progressDialog.setTitle("Please Wait....");
progressDialog.setCancelable(false);
activity = this;
credential = GoogleAccountCredential.usingOAuth2(this,DriveScopes.DRIVE);
startActivityForResult(credential.newChooseAccountIntent(),REQUEST_ACCOUNT_PICKER);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view, final int arg2,long arg3) {
// String str=itemArray.get(arg2).toString().trim();
System.out.println("mainTitleList size==="+mainTitleList.size());
System.out.println("arg2==="+arg2);
fileName = (String)mainTitleList.get(arg2);
mainTitleList.clear();
//fileSizeList.clear();
final String fileTypeStr=fileType.get(arg2);
fileType.clear();
if(fileTypeStr.contains("application/vnd.google-apps.folder"))
{
Thread t = new Thread(new Runnable() {
#Override
public void run() {
boolean b=true;
try {
String dirUrl=alternateUrlList.get(arg2);
alternateUrlList.clear();
System.out.println("Folder Name Is:"+fileName);
System.out.println("Folder Type Is:"+fileTypeStr);
System.out.println("Folder URL Is:"+dirUrl);
String fileId=fileIdList.get(arg2);
System.out.println("Folder Id Is:"+fileId);
//retrieveAllFilesFromDir(service, fileId, b);
//retrieveAllFiles1(service, b, fileId);
//Files.List request = service.children().get(fileId, null);
Files.List request = service.files().list().setQ("'" + fileId + "' in parents ");
retrieveAllFiles(service,request,b);
//retrieveAllFiles(service, b);
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("Exception In retrieveAllFiles Dir Is:"+e);
e.printStackTrace();
}
}
});t.start();
}
else
{
try {
System.out.println("fileSizeList size===="+fileSizeList.size());
System.out.println("arg2===="+arg2);
Integer fileSize = (int) fileSizeList.get(arg2);
downloadUrl = alternateUrlList.get(arg2);
byte[] size = new byte[fileSize];
int byteRead = 0, byteWritten = 0;
sdCardPadth = Environment.getExternalStorageDirectory().getPath();
System.out.println("Download Url==="+downloadUrl);
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
InputStream inStream=downloadFile(service, downloadUrl);
java.io.File inFile=new java.io.File(sdCardPadth+"/"+fileName+"1");
System.out.println("File Succesfully Stored");
}
}).start();
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("Exception In get Integer Is:" + e);
e.printStackTrace();
}
}
}
});
}
#Override
protected void onActivityResult(final int requestCode,
final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_ACCOUNT_PICKER:
if (resultCode == RESULT_OK && data != null
&& data.getExtras() != null) {
String accountName = data
.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
credential.setSelectedAccountName(accountName);
service = getDriveService(credential);
final boolean b=false;
Thread t=new Thread(new Runnable() {
#Override
public void run() {
try
{
Files.List request = service.files().list().setQ("hidden="+b);
retrieveAllFiles(service,request,b);
} catch (Exception e) {
System.out.println("Exception Is:"+e);
e.printStackTrace();
}
}
}) ;t.start();
}
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode == Activity.RESULT_OK) {
System.out.println("REQUEST_AUTHORIZATION case Is:"
+ REQUEST_AUTHORIZATION);
saveFileToDrive();
} else {
startActivityForResult(credential.newChooseAccountIntent(),
REQUEST_ACCOUNT_PICKER);
}
break;
case CAPTURE_IMAGE:
if (resultCode == Activity.RESULT_OK) {
System.out.println("CAPTURE_IMAGE case Is:" + CAPTURE_IMAGE);
saveFileToDrive();
}
}
}
private void saveFileToDrive() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
// File's binary content
System.out.println("run method");
java.io.File fileContent = new java.io.File(fileUri.getPath());
FileContent mediaContent = new FileContent("image/jpeg",fileContent);
// File's metadata.
File body = new File();
body.setTitle(fileContent.getName());
body.setMimeType("image/jpeg");
File file=null;
try {
file = service.files().insert(body, mediaContent).execute();
} catch (Exception e) {
System.out.println("Exception In Insert File Is"+e);
e.printStackTrace();
}
if (file != null) {
showToast("Photo uploaded: " + file.getTitle());
System.out.println("photo sucessfullly uploaded:"+ fileId);boolean b=false;
Files.List request = service.files().list().setQ("hidden="+b);
retrieveAllFiles(service,request,b);
}
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
}
private Drive getDriveService(GoogleAccountCredential credential) {
return new Drive.Builder(AndroidHttp.newCompatibleTransport(),
new GsonFactory(), credential).build();
}
public void showToast(final String toast) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), toast,Toast.LENGTH_SHORT).show();
}
});
}
private List<File> retrieveAllFiles(Drive service,Files.List request,boolean b) throws IOException {
List<File> result = new ArrayList<File>();
final ArrayList<String> titleList = new ArrayList<String>();
String fileUrl = "";
do {
try {
FileList files = request.execute();
result.addAll(files.getItems());
request.setPageToken(files.getNextPageToken());
for (int i = 0; i < result.size(); i++) {
File tempFile = result.get(i);
String fileTypeStr = tempFile.getMimeType();
String fileName = tempFile.getTitle();
titleList.add(fileName);
fileId = tempFile.getId();
fileIdList.add(fileId);
fileUrl = tempFile.getAlternateLink();
System.out.println("<><>< fileUrl Is:" + fileUrl);
alternateUrlList.add(fileUrl);
fileType.add(fileTypeStr);
mainTitleList.add(fileName);
try {
Integer fileSize =tempFile.getFileSize()==null?100:(int) (long) tempFile.getFileSize();
fileSizeList.add(fileSize);
System.out.println("<><>< fileSize Is:" + fileSize);
} catch (Exception e) {
fileSizeList.add(2000);
e.printStackTrace();
}
}
try {
runOnUiThread(new Runnable() {
public void run() {
myAdapter = new FileTitlesAdapter(activity,
fileType, mainTitleList, alternateUrlList,
fileSizeList);
listView.setAdapter(myAdapter);
}
});
} catch (Exception e) {
System.out.println("Exception Setting ListView Is:" + e);
e.printStackTrace();
}
} catch (IOException e) {
System.out.println("An error occurred in retrieveAllFiles:"+ e);
request.setPageToken(null);
}
} while (request.getPageToken() != null
&& request.getPageToken().length() > 0);
return result;
}
private static InputStream downloadFile(Drive service, String url) {
System.out.println("downloadFile is called service=="+service);
if (url != null && url.length() > 0) {
try {
System.out.println("downloadFile is called try");
HttpResponse resp =service.getRequestFactory().buildGetRequest(new GenericUrl(url)).execute();
System.out.println("resp.getContent()===="+resp.getContent());
return resp.getContent();
} catch (Exception e) {
System.out.println("Exception Is:"+e);
e.printStackTrace();
return null;
}
} else {
System.out.println("No Exception No Output");
return null;
}
}
}
This is code that I use to download File from google Drive
new AsyncTask<Void, Integer, Boolean>() {
#Override
protected Boolean doInBackground(Void... params) {
try {
File file = service.files().get("path in drive").execute();
java.io.File toFile = new java.io.File("where you want to store");
toFile.createNewFile();
HttpDownloadManager downloader = new HttpDownloadManager(file, toFile);
downloader.setListener(new HttpDownloadManager.FileDownloadProgressListener() {
public void downloadProgress(long bytesRead, long totalBytes) {
Log.i("chauster",totalBytes);
Log.i("chauster",bytesRead);
}
#Override
public void downloadFinished() {
// TODO Auto-generated method stub
}
#Override
public void downloadFailedWithError(Exception e) {
// TODO Auto-generated method stub
}
});
return downloader.download(service);
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
};
}.execute();
HttpDownloadManager.java
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
import com.grandex.ShareInfomation.ShareData;
import com.grandex.ShareInfomation.ShareData.ToolTapState;
public class HttpDownloadManager {
private String donwloadUrl;
private String toFile;
private FileDownloadProgressListener listener;
private long totalBytes;
public void setListener(FileDownloadProgressListener listener) {
this.listener = listener;
}
public HttpDownloadManager(File sourceFile, java.io.File destinationFile) {
super();
this.donwloadUrl = sourceFile.getDownloadUrl();
this.toFile = destinationFile.toString();
this.totalBytes = sourceFile.getFileSize();
}
public static interface FileDownloadProgressListener {
public void downloadProgress(long bytesRead, long totalBytes);
public void downloadFinished();
public void downloadFailedWithError(Exception e);
}
public boolean download(Drive service) {
HttpResponse respEntity = null;
try {
// URL url = new URL(urlString);
respEntity = service.getRequestFactory()
.buildGetRequest(new GenericUrl(donwloadUrl)).execute();
InputStream in = respEntity.getContent();
if(totalBytes == 0) {
totalBytes = respEntity.getContentLoggingLimit();
}
try {
FileOutputStream f = new FileOutputStream(toFile) {
#Override
public void write(byte[] buffer, int byteOffset,
int byteCount) throws IOException {
// TODO Auto-generated method stub
super.write(buffer, byteOffset, byteCount);
}
}
};
byte[] buffer = new byte[1024];
int len1 = 0;
long bytesRead = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
if (listener != null) {
bytesRead += len1;
listener.downloadProgress(bytesRead, totalBytes);
}
}
f.close();
} catch (Exception e) {
if (listener != null) {
listener.downloadFailedWithError(e);
}
return false;
}
if (listener != null) {
listener.downloadFinished();
}
return true;
} catch (IOException ex) {
if (listener != null) {
listener.downloadFailedWithError(ex);
return false;
}
} finally {
if(respEntity != null) {
try {
respEntity.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return false;
}
}
Nowhere in your code are you setting the Authorization header.
You need something like
setRequestProperty("Authorization", "OAuth " + "***ACCESS_TOKEN***");
For any 401/403 errors it's well worth getting your request working on the Oauth. Try this out
Please check below code for download apk file from google drive
implementation 'com.google.android.material:material:1.0.0'
Add uses permission
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
Create a file provider
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<files-path
name="files"
path="." />
Now declare the file provider inside the manifest
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider_paths" />
Add some value inside strings.xml file
<resources>
<string name="app_name">Download APK</string>
<string name="downloading">Downloading...</string>
<string name="title_file_download">APK is downloading</string>
<string name="storage_access_required">Storage access is required to downloading the file.</string>
<string name="storage_permission_denied">Storage permission request was denied.</string>
<string name="ok">OK</string>
Create a download controller
package com.hktpayment.mytmoney.pos.mauritius.util
import android.app.Dialog
import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.util.Log
import android.widget.ProgressBar
import android.widget.Toast
import androidx.core.content.FileProvider
import com.hktpayment.mytmoney.pos.mauritius.BuildConfig
import com.hktpayment.mytmoney.pos.mauritius.R
import java.io.File
class DownloadController(
private val context: Context,
private val url: String,
private val progressBar: Dialog
) {
companion object {
private const val FILE_NAME = "SampleDownloadApp.apk"
private const val FILE_BASE_PATH = "file://"
private const val MIME_TYPE = "application/vnd.android.package-archive"
private const val PROVIDER_PATH = ".provider"
private const val APP_INSTALL_PATH = "application/vnd.android.package-
archive"
}
private lateinit var downloadManager: DownloadManager
fun enqueueDownload() {
var destination =
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString()
+ "/"
destination += FILE_NAME
val uri = Uri.parse("$FILE_BASE_PATH$destination")
val file = File(destination)
if (file.exists()) file.delete()
downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as
DownloadManager
val downloadUri = Uri.parse(url)
val request = DownloadManager.Request(downloadUri)
request.setMimeType(MIME_TYPE)
request.setTitle(context.getString(R.string.title_file_download))
request.setDescription(context.getString(R.string.downloading))
// set destination
request.setDestinationUri(uri)
showInstallOption(destination, uri)
// Enqueue a new download and same the referenceId
downloadManager.enqueue(request)
Toast.makeText(context, context.getString(R.string.downloading),
Toast.LENGTH_LONG)
.show()
}
private fun showInstallOption(
destination: String,
uri: Uri
) {
// set BroadcastReceiver to install app when .apk is downloaded
progressBar.show()
val onComplete = object : BroadcastReceiver() {
override fun onReceive(
context: Context,
intent: Intent
) {
progressBar.dismiss()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val contentUri = FileProvider.getUriForFile(
context,
BuildConfig.APPLICATION_ID + PROVIDER_PATH,
File(destination)
)
val install = Intent(Intent.ACTION_VIEW)
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
install.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
install.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
install.data = contentUri
context.startActivity(install)
context.unregisterReceiver(this)
// finish()
} else {
val install = Intent(Intent.ACTION_VIEW)
install.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
install.setDataAndType(
uri,
APP_INSTALL_PATH
)
context.startActivity(install)
context.unregisterReceiver(this)
// finish()
}
}
}
context.registerReceiver(onComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
}
}
In this activity, we are checking storage permission first. If permission is granted than calling download function otherwise requesting for storage permission.
val apkUrl = "https://download .apk"
downloadController = DownloadController(this, apkUrl)
downloadController.enqueueDownload()