Related
I want to write Android logcat in a file on my device.
To do that, I used the following code
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if(isExternalStorageWritable()){
File appDirectory = new File(Environment.getExternalStorageDirectory()+ "/MyAppfolder");
File logDirectory = new File(appDirectory + "/log");
File logFile = new File(logDirectory, "logcat"+System.currentTimeMillis()+".txt");
if(!appDirectory.exists()){
appDirectory.mkdir();
}
if(!logDirectory.exists()){
logDirectory.mkdir();
}
if(!logFile.exists()){
try {
logFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
Process process = Runtime.getRuntime().exec("logcat -f "+logFile);
}
}
}
catch (IOException e){
e.printStackTrace();
}
}
else if (isExternalStorageReadable()){
Log.i(TAG, "ONLY READABLE");
}
else{
Log.i(TAG, "NOT ACCESSIBLE");
}}
public boolean isExternalStorageReadable(){
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)){
return true;
}
return false;
}
public boolean isExternalStorageWritable(){
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)){
return true;
}
return false;
}
And I added the permissions in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
The folders and the file were created, but the file is always empty.
How can I improve the code so the logcat will be written in the file.
if(checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
else{
Process process = Runtime.getRuntime().exec("logcat -f "+logFile);
}
Your code is working perfectly may be, by mistake, You had written ask for permission & make log file both together
Maybe you are not writing the log to the file. You are missing this method.
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if ( Environment.MEDIA_MOUNTED.equals( state ) ) {
return true;
}
return false;
}
Your took code from the solution of this question Stack overflow question. Check it out.
It's my pleasure to answer your question.
In my project,I use this to solve the problem.
1.add this class
public class LogcatHelper {
private static LogcatHelper INSTANCE = null;
private static String PATH_LOGCAT;
private LogDumper mLogDumper = null;
private int mPId;
/**
* init data
*/
public void init(Context context) {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {// sd first
PATH_LOGCAT = Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator + "logcat";
} else {
PATH_LOGCAT = context.getFilesDir().getAbsolutePath()
+ File.separator + "logcat";
}
File file = new File(PATH_LOGCAT);
if (!file.exists()) {
file.mkdirs();
}
}
public static LogcatHelper getInstance(Context context) {
if (INSTANCE == null) {
INSTANCE = new LogcatHelper(context);
}
return INSTANCE;
}
private LogcatHelper(Context context) {
init(context);
mPId = android.os.Process.myPid();
}
public void start() {
if (mLogDumper == null)
mLogDumper = new LogDumper(String.valueOf(mPId), PATH_LOGCAT);
mLogDumper.start();
}
public void stop() {
if (mLogDumper != null) {
mLogDumper.stopLogs();
mLogDumper = null;
}
}
private class LogDumper extends Thread {
private Process logcatProc;
private BufferedReader mReader = null;
private boolean mRunning = true;
String cmds = null;
private String mPID;
private FileOutputStream out = null;
public LogDumper(String pid, String dir) {
mPID = pid;
try {
out = new FileOutputStream(new File(dir, "logcat"
+ getFileName() + ".log"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/**
*
* Level:*:v , *:d , *:w , *:e , *:f , *:s
*
*
* */
// cmds = "logcat *:e *:w | grep \"(" + mPID + ")\""; // print e level and ilevel info
// cmds = "logcat | grep \"(" + mPID + ")\"";// print all
// cmds = "logcat -s way";// print filter info
cmds = "logcat *:e *:i | grep \"(" + mPID + ")\"";
}
public void stopLogs() {
mRunning = false;
}
#Override
public void run() {
try {
logcatProc = Runtime.getRuntime().exec(cmds);
mReader = new BufferedReader(new InputStreamReader(
logcatProc.getInputStream()), 1024);
String line = null;
while (mRunning && (line = mReader.readLine()) != null) {
if (!mRunning) {
break;
}
if (line.length() == 0) {
continue;
}
if (out != null && line.contains(mPID)) {
out.write((getDateEN() + " " + line + "\n")
.getBytes());
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (logcatProc != null) {
logcatProc.destroy();
logcatProc = null;
}
if (mReader != null) {
try {
mReader.close();
mReader = null;
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
out = null;
}
}
}
}
public static String getFileName() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String date = format.format(new Date(System.currentTimeMillis()));
return date;
}
public static String getDateEN() {
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1 = format1.format(new Date(System.currentTimeMillis()));
return date1;
}
}
add code in the Application class
LogcatHelper.getInstance((getApplicationContext())).start();
3.add permissions in the Application class
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
Process process = Runtime.getRuntime().exec("logcat -f "+logFile);
}
}
I hope I can help you.
I have tried many example and did not find any good solution.
I want to store the data of my app to store in sqlite database then sync it with the google drive account of the user who installed the app.
There is also a button which will show the data from google drive and user can edit and update the data so the updated data is then store in the google drive.
I'm new in Android development please help me.
I also have applied the following example but did not succeed.
https://github.com/seanpjanson/GDAADemo
Create / Edit / Retrieve DB file with GDAA (Google Drive Api for Android)
Unpredictable result of DriveId.getResourceId() in Google Drive Android API
https://github.com/googledrive/android-quickstart
Thanks
first create a db backup in SD-card using below line
Driver_utils.create_backup(SettingActivity.this);
**add below dependencies in build.gradle **
compile 'com.google.code.gson:gson:2.2.+'
compile 'com.google.android.gms:play-services-drive:10.0.1'`
in_drive.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (Utils.isInternetWorking()) {
File directorys = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Databackup");
if (directorys.exists()) {
String json = preferences_driverId.getString("drive_id", "");
DriveId driveId = gson.fromJson(json, DriveId.class);
//Update file already stored in Drive
Driver_utils.trash(driveId, google_api_client);
// Create the Drive API instance
Driver_utils.creatBackupDrive(SettingActivity.this, google_api_client);
dialog.dismiss();
Toast.makeText(getApplicationContext(), R.string.backupss, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), R.string.inportfirest, Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getApplicationContext(), R.string.nointe, Toast.LENGTH_LONG).show();
}
}
});
**And for Restore use this **
restore_from_drive.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Launch user interface and allow user to select file
IntentSender intentSender = Drive.DriveApi
.newOpenFileActivityBuilder()
.setMimeType(new String[]{"application/zip"})
.build(google_api_client);
try {
startIntentSenderForResult(
intentSender, REQ_CODE_OPEN, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.w(TAG, e.getMessage());
}
dialog.dismiss();
}
});
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == DIALOG_ERROR_CODE) {
mResolvingError = false;
if (resultCode == RESULT_OK) { // Error was resolved, now connect to the client if not done so.
if (!google_api_client.isConnecting() && !google_api_client.isConnected()) {
google_api_client.connect();
}
}
}
if (requestCode == REQ_CODE_OPEN && resultCode == RESULT_OK) {
DriveId mSelectedFileDriveId = data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
Log.e("DriveID ---", mSelectedFileDriveId + "");
Gson gson = new Gson();
String json = gson.toJson(mSelectedFileDriveId); // myObject - instance of MyObject
editor_drive = preferences_driverId.edit();
editor_drive.putString("drive_id", json).commit();
Log.e(TAG, "driveId this 1-- " + mSelectedFileDriveId);
if (Utils.isInternetWorking()) {
//restore Drive file to SDCArd
Driver_utils.restoreDriveBackup(SettingActivity.this, google_api_client, GOOGLE_DRIVE_FILE_NAME, preferences_driverId, mfile);
Driver_utils.restore(SettingActivity.this);
} else {
Toast.makeText(getApplicationContext(), R.string.nointernets, Toast.LENGTH_LONG).show();
}
}
}
**Make a static Driver_utils class **
public class Driver_utils {
public static DriveFile mfile;
public static GoogleApiClient api;
public static DriveId driveId;
public static Context ctxs;
public static SharedPreferences preferences_driverId;
public static SharedPreferences.Editor editor;
private static final String GOOGLE_DRIVE_FILE_NAME = "Databackup";
public static void restoreDriveBackup(Context ctx, GoogleApiClient apis, String GOOGLE_DRIVE_FILE_NAME, SharedPreferences preferences_driverIds, DriveFile mfiles) {
mfile = mfiles;
api = apis;
preferences_driverId = preferences_driverIds;
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.TITLE, GOOGLE_DRIVE_FILE_NAME))
.build();
Drive.DriveApi.query(api, query).setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
#Override
public void onResult(DriveApi.MetadataBufferResult metadataBufferResult) {
Gson gson = new Gson();
String json = preferences_driverId.getString("drive_id", "");
DriveId driveId = gson.fromJson(json, DriveId.class);
Log.e("driveId put", "" + driveId);
Log.e("filesize in cloud ", +metadataBufferResult.getMetadataBuffer().get(0).getFileSize() + "");
metadataBufferResult.getMetadataBuffer().release();
mfile = Drive.DriveApi.getFile(api, driveId);
mfile.open(api, DriveFile.MODE_READ_ONLY, new DriveFile.DownloadProgressListener() {
#Override
public void onProgress(long bytesDown, long bytesExpected) {
Log.e("Downloading..", "" + bytesDown + "/" + bytesExpected);
}
})
.setResultCallback(restoreContentsCallback);
}
});
}
static final private ResultCallback<DriveApi.DriveContentsResult> restoreContentsCallback =
new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(DriveApi.DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.e("Unable to open,try", "data");
return;
}
File sd = Environment.getExternalStorageDirectory();
String backupDBPath = "/Databackup.zip";
File imgFile = new File(sd, backupDBPath);
Log.e("FILE EXIST", imgFile.exists() + "");
if (!imgFile.exists())
try {
imgFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
imgFile = new File(imgFile.getAbsolutePath());
DriveContents contents = result.getDriveContents();
try {
FileOutputStream fos = new FileOutputStream(imgFile.getAbsolutePath());
BufferedOutputStream bos = new BufferedOutputStream(fos);
BufferedInputStream in = new BufferedInputStream(contents.getInputStream());
byte[] buffer = new byte[1024];
int n, cnt = 0;
while ((n = in.read(buffer)) > 0) {
bos.write(buffer, 0, n);
cnt += n;
Log.e("buffer: ", buffer[0] + "");
Log.e("buffer: ", "" + buffer[1]);
Log.e("buffer: ", "" + buffer[2]);
Log.e("buffer: ", "" + buffer[3]);
bos.flush();
}
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Unzip when download from drive
try {
String dest_file_path = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/Databackup";
String src_location = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/Databackup.zip";
Decompress.unzip(new File(src_location), new File(dest_file_path));
} catch (Exception e) {
e.printStackTrace();
}
}
};
public static void creatBackupDrive(Context ctx, GoogleApiClient apis) {
ctxs = ctx;
api = apis;
Drive.DriveApi.newDriveContents(api).setResultCallback(contentsCallback);
}
final public static ResultCallback<DriveApi.DriveContentsResult> contentsCallback = new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(DriveApi.DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.e(TAG, "Error while trying to create new file contents");
return;
}
String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("db");
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(GOOGLE_DRIVE_FILE_NAME) // Google Drive File name
.setMimeType("application/zip")
.setStarred(true).build();
// create a file on root folder
Drive.DriveApi.getRootFolder(api)
.createFile(api, changeSet, result.getDriveContents())
.setResultCallback(fileCallback);
}
};
final public static ResultCallback<DriveFolder.DriveFileResult> fileCallback = new ResultCallback<DriveFolder.DriveFileResult>() {
#Override
public void onResult(DriveFolder.DriveFileResult result) {
preferences_driverId = ctxs.getSharedPreferences("ID", MODE_PRIVATE);
editor = preferences_driverId.edit();
if (!result.getStatus().isSuccess()) {
Log.v(TAG, "Error while trying to create the file");
return;
}
driveId = result.getDriveFile().getDriveId();
Log.e(TAG, "Created a file with content: " + driveId);
Gson gson = new Gson();
String json = gson.toJson(driveId); // myObject - instance of MyObject
editor.putString("drive_id", json).commit();
Log.e(TAG, "driveId " + driveId);
mfile = result.getDriveFile();
mfile.open(api, DriveFile.MODE_WRITE_ONLY, new DriveFile.DownloadProgressListener() {
#Override
public void onProgress(long bytesDownloaded, long bytesExpected) {
Log.e(TAG, "Creating backup file" + bytesDownloaded + "/" + bytesExpected);
}
}).setResultCallback(contentsOpenedCallback);
}
};
final public static ResultCallback<DriveApi.DriveContentsResult> contentsOpenedCallback = new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(DriveApi.DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.v(TAG, "Error opening file");
return;
}
String sd = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DiaryDatabackup.zip";
Log.e("DB FILE NAME---", sd + "");
DriveContents contents = result.getDriveContents();
BufferedOutputStream out = new BufferedOutputStream(contents.getOutputStream());
byte[] buffer = new byte[1024];
int n;
try {
FileInputStream is = new FileInputStream(sd);
BufferedInputStream in = new BufferedInputStream(is);
while ((n = in.read(buffer)) > 0) {
out.write(buffer, 0, n);
Log.e("Backing up...", "Backup");
}
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
contents.commit(api, null).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
Log.e("Backup completed!", "complete"+status);
}
});
}
};
public static void trash(DriveId dId, GoogleApiClient apis) {
api = apis;
try {
Log.e(TAG,"Goes in trans" );
DriveFile sumFile = dId.asDriveFile();
com.google.android.gms.common.api.Status deleteStatus =
sumFile.delete(api).await();
if (!deleteStatus.isSuccess()) {
Log.e(TAG, "Unable to delete app data.");
} else {
// Remove stored DriveId.
preferences_driverId.edit().remove("drive_id").apply();
}
Log.d(TAG, "Past sums deleted.");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void restore(Context ctx) {
OutputStream myOutput;
String dbpath = "//data//" + ctx.getPackageName() + "//databases//databaseName.db";
String sdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Databackup";
File directorys = new File(sdpath + "/backup_sd");
if (directorys.exists()) {
try {
myOutput = new FileOutputStream(Environment.getDataDirectory()
+ dbpath);
// Set the folder on the SDcard
File directory = new File(sdpath + "/backup_sd");
// Set the input file stream up:
InputStream myInputs = new FileInputStream(directory.getPath());
// Transfer bytes from the input file to the output file
byte[] buffer = new byte[1024];
int length;
while ((length = myInputs.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close and clear the streams
myOutput.flush();
myOutput.close();
myInputs.close();
Toast.makeText(ctx, R.string.successss, Toast.LENGTH_LONG)
.show();
} catch (FileNotFoundException e) {
Toast.makeText(ctx, ctx.getString(R.string.err), Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (IOException e) {
Toast.makeText(ctx, ctx.getString(R.string.err), Toast.LENGTH_LONG).show();
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
Log.e("NO DB YET ", "Created");
Toast.makeText(ctx, R.string.savesome, Toast.LENGTH_LONG).show();
}
}
public static void create_backup(Context ctx) {
InputStream myInput;
String dbpath = "//data//" + ctx.getPackageName() + "//databases//databaseName.db";
String sdpath_createbackup = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Databackup";
File file = new File(sdpath_createbackup);
if (!file.exists())
file.mkdirs();
try {
myInput = new FileInputStream(Environment.getDataDirectory()
+ dbpath);
// Set the output folder on the Scard
File directory = new File(file + "/backup_sd");
// Create the folder if it doesn't exist:
if (!directory.exists()) {
directory.createNewFile();
}
// Set the output file stream up:
OutputStream myOutput = new FileOutputStream(directory.getPath());
// Transfer bytes from the input file to the output file
byte[] buffer = new byte[100024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close and clear the streams
myOutput.flush();
myOutput.close();
myInput.close();
Toast.makeText(ctx, R.string.backups, Toast.LENGTH_LONG)
.show();
} catch (FileNotFoundException e) {
Toast.makeText(ctx, ctx.getString(R.string.err), Toast.LENGTH_LONG).show();
Log.e("error", e.getMessage());
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
Toast.makeText(ctx, ctx.getString(R.string.err), Toast.LENGTH_LONG).show();
Log.e("error 1", e.getMessage());
// TODO Auto-generated catch block
e.printStackTrace();
}
String src_file_path = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/Databackup";
String destination_location = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/Databackup.zip";
Decompress.backupfolder(new File(src_file_path), new File(destination_location));
}
}
And You Need Decomposer file just create and Copy this
public class Decompress {
public static boolean unzip(File zipfile, File directory) {
BufferedReader br = null;
try {
ZipFile zfile = new ZipFile(zipfile);
Enumeration<? extends ZipEntry> entries = zfile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
File file = new File(directory, entry.getName());
if (entry.isDirectory()) {
file.mkdirs();
} else {
file.getParentFile().mkdirs();
InputStream in = zfile.getInputStream(entry);
copy(in, file);
in.close();
}
}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
if (br != null) br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
return true;
}
public static boolean backupfolder(File directory, File zipfile) {
try {
URI base = directory.toURI();
Deque<File> queue = new LinkedList<>();
queue.push(directory);
OutputStream out = new FileOutputStream(zipfile);
Closeable res = out;
ZipOutputStream zout = new ZipOutputStream(out);
res = zout;
while (!queue.isEmpty()) {
directory = queue.pop();
for (File kid : directory.listFiles()) {
String name = base.relativize(kid.toURI()).getPath();
if (kid.isDirectory()) {
queue.push(kid);
name = name.endsWith("/") ? name : name + "/";
zout.putNextEntry(new ZipEntry(name));
} else {
zout.putNextEntry(new ZipEntry(name));
copy(kid, zout);
zout.closeEntry();
}
}
}
res.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
private static void copy(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
while (true) {
int readCount = in.read(buffer);
if (readCount < 0) {
break;
}
out.write(buffer, 0, readCount);
}
}
private static void copy(File file, OutputStream out) throws IOException {
InputStream in = new FileInputStream(file);
try {
copy(in, out);
} finally {
in.close();
}
}
private static void copy(InputStream in, File file) throws IOException {
OutputStream out = new FileOutputStream(file);
try {
copy(in, out);
} finally {
out.close();
}
}
}
My answer assumes that you have a keystore file to sign your app with. If you don't, this link shows you how.
The next thing you need to do is to download the Android and Google play Services SDKs and get an Android certificate, as described here
Now your app should be able to access the Google Drive APIs.
In your activity, create these variables
/**
* Handle access to Drive resources/files.
*/
DriveResourceClient mDriveResourceClient;
/**
* Base folder. This is where the backup will be created
*/
DriveFolder baseFolder;
/**
* Request code for google sign-in, to be used for result of Drive sign-in
* Can be any suitable value
*/
protected static final int REQUEST_CODE_SIGN_IN = 0;
/**
* String variables to hold file names, file paths etc.
*/
static final String BACK_UP = <NAME OF BACKUP FILE CREATED ON DRIVE> ;
static final String dbPath = <PATH TO YOUR DATABASE>;
static final String DATABASE_NAME = <NAME OF YOUR DATABASE>;
/*
* This text view is used to show the output from various operations
*/
private TextView tvDriveResult;
When the user starts the backup process call the function singIn()
/**
* Starts the sign-in process and initializes the Drive client.
*/
private void singIn() {
Set<Scope> requiredScopes = new HashSet<>(2);
requiredScopes.add(Drive.SCOPE_FILE);
GoogleSignInAccount signInAccount = GoogleSignIn.getLastSignedInAccount(this);
if (signInAccount != null && signInAccount.getGrantedScopes().containsAll(requiredScopes)) {
initializeDriveClient(signInAccount);
} else {
GoogleSignInOptions signInOptions =
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(Drive.SCOPE_FILE)
.build();
GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, signInOptions);
startActivityForResult(googleSignInClient.getSignInIntent(), REQUEST_CODE_SIGN_IN);
}
}
The singIn() function will handle a user sign - in by starting Google Sign in Client. You will need to handle the result of this client. Use the following code.
/**
* Handles resolution callbacks.
*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_SIGN_IN:
if (resultCode != RESULT_OK) {
/* Sign-in may fail or be cancelled by the user. For this sample, sign-in is
* required and is fatal. For apps where sign-in is optional, handle appropriately
*/
Log.e(TAG, "Sign-in failed.");
return;
}
Task<GoogleSignInAccount> getAccountTask =
GoogleSignIn.getSignedInAccountFromIntent(data);
if (getAccountTask.isSuccessful()) {
initializeDriveClient(getAccountTask.getResult());
} else {
Log.e(TAG, "Sign-in failed.");
tvDriveResult.append("Sign-in failed\n");
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
After sign-in has been successfully completed, the drive client is initialised above by calling the initializeDriveClient(GoogleSignInAccount signInAccount) function.
/**
* Continues the sign-in process, initializing the Drive clients with the current
* user's account.
*/
private void initializeDriveClient(GoogleSignInAccount signInAccount) {
mDriveClient = Drive.getDriveClient(getApplicationContext(), signInAccount);
mDriveResourceClient = Drive.getDriveResourceClient(getApplicationContext(), signInAccount);
onDriveClientReady();
}
After the drive client is set up, onDriveClientReady() is called. This function proceeds to create / restore your back-up. The functionality here is very simple a. Get the base folder of the user's Google Drive account. b. Check if a back-up file exists. c. If yes, copy that backup to the local database file (over write complete file). d. If no, copy the local database file to the user's Google Drive base folder. You can add some finesse to this logic if you wish. My code is to help you understand the process.
/**
* Called after the user has signed in and the Drive client has been initialized.
*/
private void onDriveClientReady(){
/* Initialise the root folder. */
/* Since the tasks are executed in a separate execution threads, the remaining tasks are called from within each other */
getRootFolder();
}
The getRootFolder() function proceeds as follows
private void getRootFolder() {
/* Get the app folder */
Task<DriveFolder> appFolderTask = mDriveResourceClient.getRootFolder();
appFolderTask
.addOnSuccessListener(this, new OnSuccessListener<DriveFolder>() {
#Override
public void onSuccess(DriveFolder driveFolder) {
tvDriveResult.append("Root folder found\n");
baseFolder = driveFolder;
/* Base folder is found, now check if backup file exists */
checkForBackUp();
/* Use this to delete files. Remember to comment out the line able it */
/* listFilesInBaseFolder(); */
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
tvDriveResult.append("Root folder not found, error: " + e.toString() + "\n");
}
});
}
There is also a function in here called listFilesInBaseFolder() to delete (permanently delete not simply trash) all files you created. It has been commented out in. Use it in case you want to delete files you created, use with caution. As far as I can tell it works only on files that were created by your application.
Check for backup.
private void checkForBackUp() {
/* Build a query */
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.TITLE, BACK_UP))
.build();
/* Query contents of app folder */
Task<MetadataBuffer> queryTask = mDriveResourceClient.queryChildren(baseFolder, query);
/* Check for result of query */
queryTask
.addOnSuccessListener(this, new OnSuccessListener<MetadataBuffer>() {
#Override
public void onSuccess(MetadataBuffer metadataBuffer) {
/* if count is 0, the file doesn't exist */
if (metadataBuffer.getCount() == 0){
tvDriveResult.append("File " + BACK_UP + " not found\n");
/* Make file backup */
backUpDatabase();
} else {
tvDriveResult.append(metadataBuffer.getCount() + " Instances of file " + BACK_UP + " found\n");
Metadata metadata = metadataBuffer.get(0);
restoreBackUp(metadata.getDriveId().asDriveFile());
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
tvDriveResult.append("Could not search for file, error: " + e.toString() + "\n");
}
});
}
restoreBackUp(DriveFile driveFile) will over write the local database file with the file found on Goole Drive.
private void restoreBackUp(DriveFile driveFile) {
tvDriveResult.append("Restoring from backup\n");
/* Get the path of the local backup */
File dbFileOld = new File(dbPath + DATABASE_NAME);
/* Check of dbFileExists on device, delete if it does because it needs to be completely over written */
if (dbFileOld.exists()){
dbFileOld.delete();
}
File dbFileNew = new File(dbPath + DATABASE_NAME);
/* File input stream from database to read from */
final FileOutputStream fileOutputStream;
try {
fileOutputStream = new FileOutputStream(dbFileNew);
} catch (FileNotFoundException e) {
tvDriveResult.append("Could not get input stream from local file\n");
return;
}
/* Task to open file */
Task<DriveContents> openFileTask =
mDriveResourceClient.openFile(driveFile, DriveFile.MODE_READ_ONLY);
/* Continue with task */
openFileTask.continueWithTask(new Continuation<DriveContents, Task<Void>>(){
#Override
public Task<Void> then(#NonNull Task<DriveContents> task) throws Exception {
DriveContents backupContents = task.getResult();
InputStream inputStream = backupContents.getInputStream();
tvDriveResult.append("Attempting to restore from database\n");
byte[] buffer = new byte[4096];
int c;
while ((c = inputStream.read(buffer, 0, buffer.length)) > 0){
fileOutputStream.write(buffer, 0, c);
}
fileOutputStream.flush();
fileOutputStream.close();
fileOutputStream.flush();
fileOutputStream.close();
tvDriveResult.append("Database restored\n");
/* Return statement needed to avoid task failure */
Task<Void> discardTask = mDriveResourceClient.discardContents(backupContents);
return discardTask;
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
tvDriveResult.append("Could not read file contents\n");
}
});
}
And lastly, backUpDatabase() creates a backup of your local database.
private void backUpDatabase() {
tvDriveResult.append("Creating Drive back-up");
/* get the path of the local backup */
File dbFile = new File(dbPath + DATABASE_NAME);
/* Check of dbFileExists on device */
if (! dbFile.exists()){
tvDriveResult.append("Local database not found?!\n");
return;
}
/* File input stream from database to read from */
final FileInputStream fileInputStream;
try {
fileInputStream = new FileInputStream(dbFile);
} catch (FileNotFoundException e) {
tvDriveResult.append("Could not get input stream from local file\n");
return;
}
/* Task to make file */
final Task<DriveContents> createContentsTask = mDriveResourceClient.createContents();
tvDriveResult.append("Creating a back-up of the Database File\n");
Tasks.whenAll(createContentsTask).continueWithTask(new Continuation<Void, Task<DriveFile>>() {
#Override
public Task<DriveFile> then(#NonNull Task<Void> task) throws Exception {
/* Retrieved the drive contents returned by the Task */
DriveContents contents = createContentsTask.getResult();
/* Output stream where data will be written */
OutputStream outputStream = contents.getOutputStream();
/* File output stream */
tvDriveResult.append("Attempting to write\n");
byte[] buffer = new byte[4096];
int c;
while ((c = fileInputStream.read(buffer, 0, buffer.length)) > 0){
outputStream.write(buffer, 0, c);
}
outputStream.flush();
outputStream.close();
fileInputStream.close();
tvDriveResult.append("Database written\n");
/* Save the file, using MetadataChangeSet */
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(BACK_UP)
.setMimeType("application/x-sqlite3")
.setStarred(false)
.build();
return mDriveResourceClient.createFile(baseFolder, changeSet, contents);
}
})
/* Task successful */
.addOnSuccessListener(new OnSuccessListener<DriveFile>() {
#Override
public void onSuccess(DriveFile driveFile) {
tvDriveResult.append("Back up file created\n");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
tvDriveResult.append("Could not create back up file\n");
}
});
}
And that is it! This should get you started with basic operations. I recommend going through Google's Developer Guide for a deeper dive.
i'm developing my first Android app and i created a class (not Activity) that downloads a JSON file and writes content to SQLite database at every start-up of the application.
I then use an instance of this class in the main activity class.
If the download takes few seconds the home page of my app hangs on a blank screen.
Do you think i should use service instead of a class to handle download and writing of the db?
Could it be a good idea? If it could, what are the advantages?
If you are writing to a database I would recommend using an IntentService
The intent service runs in it's own thread.
When the download is complete you can use LocalBroadcastManager to notify the activity.
It could also work with ContentProvider and Loaders.
I also wanted to download the list of images in background so I used Services with SharedPreferences and I also Used AQuery With the Service.Here the ConnectionDetector is my Java class which checks the Internet Connection is available or not. It works for me. I hope it will give u some help.
public class MyService extends Service {
String f;
String path;
File file;
Bitmap bm;
String url1;
ArrayList<String> url_img;
AQuery aq;
int count = 1;
String val;
ArrayList<String> completed_url_list;
ArrayList<Integer> _index;
FileOutputStream out;
static ArrayList<String> list;
private Thread updateTask = new Thread(new Runnable() {
#Override
public void run() {
while (count < url_img.size()) {
try {
Log.e("Counter", "" + count);
val = url_img.get(count).toString();
final AjaxCallback<Bitmap> cb = new AjaxCallback<Bitmap>() {
#Override
public void callback(String url, Bitmap bm,
AjaxStatus status) {
try {
System.out.println("url is" + url);
String urll = url.substring(url
.lastIndexOf("/") + 1);
Log.e("Image name", "" + urll);
System.out.println("url111" + urll);
File f = new File(path + urll);
f.createNewFile();
System.out.println(f.getAbsolutePath());
try {
out = new FileOutputStream(f);
bm.compress(Bitmap.CompressFormat.JPEG, 40,
out);
if (out != null) {
out.flush();
out.close();
Log.e("download", "Complete");
completed_url_list.add(url);
System.out
.println("Completed Dowmload Image"
+ completed_url_list);
}
} catch (Exception e) {
boolean del_file = f.delete();
if (del_file == true){
Log.e("File", "deleted");
System.out.println("exception");
}
else{
System.out.println("file not deleted");
}
} finally {
out.close();
if (bm != null) {
bm.recycle();
bm = null;
}
System.gc();
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
} catch (Exception e) {
}
}
};
final AQuery aq = new AQuery(getApplicationContext());
aq.ajax(val, Bitmap.class, 0, cb);
} catch (Exception e) {
}
count++;
}
}
});
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
url_img = getArrayList();
completed_url_list = new ArrayList<String>();
_index = new ArrayList<Integer>();
aq = new AQuery(MyService.this);
System.out.println("I am in super");
if (url_img.size() > 0) {
updateTask.start();
}
} catch (Exception e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public void onCreate() {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
super.onCreate();
try {
System.out.println("Service Creating");
f = Environment.getExternalStorageDirectory().getAbsolutePath();
path = f + "/HRI3mages/";
file = new File(path);
if (!file.exists()) {
file.mkdir();
}
} catch (Exception e) {
}
}
#Override
public void onDestroy() {
try {
for (int index = 0; index < completed_url_list.size(); index++) {
for (int index1 = 0; index1 < url_img.size(); index1++) {
if (completed_url_list.get(index).equals(
url_img.get(index1))) {
_index.add(index1);
}
}
}
Collections.sort(_index, new MyIntComparable());
System.out.println("next_download" + _index);
for(int index=0;index<_index.size();index++){
url_img.remove(index);
}
System.out.println("After_Deletion_of_Image"+url_img);
_addArray(url_img);
updateTask.interrupt();
} catch (Exception e) {
}
System.out.println("Service destroy");
super.onDestroy();
}
public class MyIntComparable implements Comparator<Integer>{
#Override
public int compare(Integer o1, Integer o2) {
return (o1>o2 ? -1 : (o1==o2 ? 0 : 1));
}
}
public ArrayList<String> getArrayList() {
ArrayList<String> list_url = new ArrayList<String>();
SharedPreferences SharedPref = getSharedPreferences("SSO", MODE_PRIVATE);
int size = SharedPref.getInt("list_size", 0);
for (int i = 0; i < size; i++) {
list_url.add(SharedPref.getString("list_" + i, ""));
}
System.out.println(list_url);
return list_url;
}
public void _addArray(ArrayList<String> list) {
SharedPreferences SharedPref = getSharedPreferences("SSO", 0);
SharedPreferences.Editor editor = SharedPref.edit();
int size = list.size();
editor.putInt("list_size", size);
for (int i = 0; i < size; i++) {
editor.putString("list_" + i, list.get(i));
}
editor.commit();
}
}
You might want to use an AsyncTask.
This will do the work in a background thread, so if it takes long your screen won't hang.
While the work is in progress, you can show a ProgressDialog (optional) to inform the user. You can also add a button to that ProgressDialog to cancel the task if needed.
See this: http://developer.android.com/intl/es/reference/android/os/AsyncTask.html
In this case I prefer an AsyncTask and not a Service so it seems easier and simpler to do what you want.
Good luck =)
I have trouble using thread.join in my code below. It should wait for the thread to finish before executing the codes after it, right? It was behaving differently on different occasions.
I have three cases to check if my code goes well
App is used for the first time - works as expected but the loading page don't appear while downloading
App is used the second time (db is up to date) - works okay
App is used the third time (db is outdated, must update) - won't update, screen blacks out, then crashes
I think I have problems with this code on onCreate method:
dropOldSchedule();
dropThread.join();
triggerDownload();
Based on the logs, the code works until before this part... What can be the problem?
MainActivity.java
public class MainActivity extends Activity {
final static int INDEX_ACCTTYPE = 0;
final static int INDEX_ECN = 1;
final static int INDEX_TLN = 2;
final static int INDEX_SIN = 3;
final static int INDEX_MOBILE = 4;
final static int INDEX_CITY = 5;
final static int INDEX_START_DATE = 6;
final static int INDEX_START_TIME = 7;
final static int INDEX_END_DATE = 8;
final static int INDEX_END_TIME = 9;
final static int INDEX_REASON = 10;
final static int INDEX_DETAILS = 11;
DatabaseHandler db;
String str;
ProgressDialog pd;
TextView homeText1, homeText2, homeText3, homeText4;
final private String csvFile = "http://www.meralco.com.ph/pdf/pms/pms_test.csv";
final private String uploadDateFile = "http://www.meralco.com.ph/pdf/pms/UploadDate_test.txt";
Thread dropThread = new Thread(new Runnable() {
public void run() {
db = new DatabaseHandler(MainActivity.this);
db.dropOldSchedule();
runOnUiThread(new Runnable() {
public void run() {
while (!pd.isShowing());
db.close();
pd.dismiss();
}
});
}
});
Thread getUploadDateThread = new Thread(new Runnable() {
public void run() {
try {
URL myURL = new URL(uploadDateFile);
BufferedReader so = new BufferedReader(new InputStreamReader(myURL.openStream()));
while (true) {
String output = so.readLine();
if (output != null) {
str = output;
}
else {
break;
}
}
so.close();
}
catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
while (!pd.isShowing());
pd.dismiss();
}
});
}
});
Thread downloadThread = new Thread(new Runnable() {
public void run() {
db = new DatabaseHandler(MainActivity.this);
db.beginTransaction();
try {
URL url = new URL(csvFile);
Log.i("dl", "start");
InputStream input = url.openStream();
CSVReader reader = new CSVReader(new InputStreamReader(input));
Log.i("dl", "after reading");
String [] sched;
while ((sched = reader.readNext()) != null) {
if(sched[INDEX_CITY].equals("")) sched[INDEX_CITY]="OTHERS";
try {
db.addRow(sched[INDEX_SIN], sched[INDEX_CITY],
sched[INDEX_START_DATE], sched[INDEX_START_TIME],
sched[INDEX_END_DATE], sched[INDEX_END_TIME],
sched[INDEX_DETAILS], sched[INDEX_REASON]);
} catch (IndexOutOfBoundsException e) {
db.addRow(sched[INDEX_SIN], sched[INDEX_CITY],
sched[INDEX_START_DATE], sched[INDEX_START_TIME],
sched[INDEX_END_DATE], sched[INDEX_END_TIME],
"", sched[INDEX_REASON]);
//e.printStackTrace();
}
}
input.close();
Log.i("dl", "finished");
} catch (MalformedURLException e) {
e.printStackTrace();
db.endTransaction();
} catch (IOException e) {
e.printStackTrace();
db.endTransaction();
}
Log.d("Count", ""+db.count());
db.setTransactionSuccessful();
db.endTransaction();
writeUploadDateInTextFile();
}
});
#SuppressWarnings("unqualified-field-access")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pms_main);
Button home = (Button) findViewById(R.id.home);
home.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MeralcoSuite_TabletActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
});
homeText1 = (TextView) findViewById(R.id.home_text1);
homeText2 = (TextView) findViewById(R.id.home_text2);
homeText3 = (TextView) findViewById(R.id.home_text3);
homeText4 = (TextView) findViewById(R.id.home_text4);
homeText1.setVisibility(View.INVISIBLE);
homeText2.setVisibility(View.INVISIBLE);
homeText3.setVisibility(View.INVISIBLE);
homeText4.setVisibility(View.INVISIBLE);
getUploadDate();
try {
getUploadDateThread.join(); //wait for upload date
Log.d("getUploadDate","thread died, upload date=" + str);
if(dbExists()){
db = new DatabaseHandler(MainActivity.this);
Log.d("Count", "" + db.count());
db.close();
if(!uploadDateEqualsDateInFile()){
dropOldSchedule();
dropThread.join();
triggerDownload();
}
showDisclaimer();
Log.i("oncreate", "finished!");
return;
}
triggerDownload();
showDisclaimer();
Log.i("oncreate", "finished!");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void dropOldSchedule(){
if(pd!=null && pd.isShowing())
pd.setTitle("Getting upload date...");
else
pd = ProgressDialog.show(this, "Getting upload date",
"This may take a few minutes...", true, false);
dropThread.start();
}
public void triggerDownload() {
if (!checkInternet()) {
showAlert("An internet connection is required to perform an update, please check that you are connected to the internet");
return;
}
if(pd!=null && pd.isShowing())
pd.setTitle("Getting upload date...");
else
pd = ProgressDialog.show(this, "Getting upload date",
"This may take a few minutes...", true, false);
downloadThread.start();
}
public void getUploadDate() {
Log.d("getUploadDate", "getting upload date of schedule");
if(pd!=null && pd.isShowing())
pd.setTitle("Getting upload date...");
else
pd = ProgressDialog.show(this, "Getting upload date",
"This may take a few minutes...", true, false);
getUploadDateThread.start();
}
public void writeUploadDateInTextFile() {
Log.d("writeUploadDateTextFile", "writing:"+str);
try {
OutputStreamWriter out = new OutputStreamWriter(openFileOutput(
"update.txt", 0));
out.write(str);
out.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
public void showDisclaimer() {
Log.d("ShowDisclaimer", "showing disclaimer");
homeText3
.setText("..." + str
+ "...");
homeText1.setVisibility(View.VISIBLE);
homeText2.setVisibility(View.VISIBLE);
homeText3.setVisibility(View.VISIBLE);
homeText4.setVisibility(View.VISIBLE);
Log.d("showDisclaimer", "finished showing disclaimer");
}
public boolean uploadDateEqualsDateInFile() {
Log.d("uploadDateEqualsDateInFile","comparing schedule upload dates");
try {
String recordedDate = "";
InputStream instream = openFileInput("update.txt");
if (instream != null) { // if file the available for reading
Log.d("uploadDateEqualsDateInFile","update.txt found!");
InputStreamReader inputreader = new InputStreamReader(instream);
BufferedReader buffreader = new BufferedReader(inputreader);
String line = null;
while ((line = buffreader.readLine()) != null) {
recordedDate = line;
Log.d("uploadDateEqualsDateInFile","recorded:"+recordedDate);
}
Log.d("uploadDateEqualsDateInFile","last upload date: " + str + ", recorded:" +recordedDate);
if(str.equals(recordedDate)) return true;
return false;
}
Log.d("uploadDateEqualsDateInFile","update.txt is null!");
return false;
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public boolean checkInternet() {
ConnectivityManager cm = (ConnectivityManager) this
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo infos[] = cm.getAllNetworkInfo();
for (NetworkInfo info : infos)
if (info.getState() == NetworkInfo.State.CONNECTED
|| info.getState() == NetworkInfo.State.CONNECTING) {
return true;
}
return false;
}
public boolean dbExists() {
File database=getApplicationContext().getDatabasePath(DatabaseHandler.DATABASE_NAME);
if (!database.exists()) {
Log.i("Database", "Not Found");
return false;
}
Log.i("Database", "Found");
return true;
}
#Override
protected void onDestroy() {
super.onDestroy();
if (db != null) {
db.close();
}
}
#Override
protected void onPause() {
super.onPause();
if (db != null) {
db.close();
}
}
}
Sorry but I couldn't find mistakes or problems in your code. But I would strongly recommend you to use AsyncTask for doing something in different thread. AsyncTask is very easy to use and I would say that it is one of the biggest advantages of java. I really miss it in obj-c.
http://labs.makemachine.net/2010/05/android-asynctask-example/
http://marakana.com/s/video_tutorial_android_application_development_asynctask_preferences_and_options_menu,257/index.html
check those links hope that will help you.
It was already mentioned that AsyncTask is the better alternative. However, it may be the case, that your call to join will throw InterruptedException. Try to use it like this:
while(getUploadDateThread.isRunning()){
try{
getUploadDateThread.join();
} catch (InterruptedException ie){}
}
// code after join
I think the problem that your facing is that you are blocking the UI thread when you call join in the onCreate() method. You should move this code into another thread which should execute in the background and once its done you can update the UI.
Here is a sample code:
final Thread t1 = new Thread();
final Thread t2 = new Thread();
t1.start();
t2.start();
new Thread(new Runnable() {
#Override
public void run() {
// Perform all your thread joins here.
try {
t1.join();
t2.join();
} catch (Exception e) {
// TODO: handle exception
}
// This thread wont move forward unless all your threads
// mentioned above are executed or timed out.
// ------ Update UI using this method
runOnUiThread(new Runnable() {
#Override
public void run() {
// Update UI code goes here
}
});
}
}).start();
Please check the code below.
I am not able to copy a resource file to external storage in android phone.
Though, i'm able to copy using the code i've commented but I want to know the problem with my original code.
public class ExternalData extends Activity implements OnItemSelectedListener,
OnClickListener {
TextView canRead = null;
TextView canWrite = null;
String state = null;
boolean canR, canW;
EditText userEnteredFileName;
Button bConfirm, bSaveAs;
Spinner spinner = null;
String[] stuff = { "Music", "Pictures", "Downloads" };
File path = null;
File file = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.externaldata);
canRead = (TextView) findViewById(R.id.tvCanRead);
canWrite = (TextView) findViewById(R.id.tvCanWrite);
userEnteredFileName = (EditText) findViewById(R.id.etUserEnteredFileName);
bConfirm = (Button) findViewById(R.id.bConfirm);
bSaveAs = (Button) findViewById(R.id.bSaveAs);
bConfirm.setOnClickListener(this);
bSaveAs.setOnClickListener(this);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, stuff);
spinner = (Spinner) findViewById(R.id.spinner1);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
}
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
int position = spinner.getSelectedItemPosition();
switch (position) {
case 0:
path = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
break;
case 1:
path = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
break;
case 2:
path = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
break;
}
}
public void checkState() {
state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
canRead.setText("Can Read: true");
canWrite.setText("Can Write: true");
canR = canW = true;
} else if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
canRead.setText("Can Read: true");
canWrite.setText("Can Write: false");
canR = true;
canW = false;
} else {
canRead.setText("Can Read: false");
canWrite.setText("Can Write: false");
canR = canW = false;
}
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch (arg0.getId()) {
case R.id.bConfirm:
bSaveAs.setVisibility(View.VISIBLE);
break;
case R.id.bSaveAs:
checkState();
if(canR == canW == true){
file = new File (path, userEnteredFileName.getText().toString() + "/");
try {
if(!file.exists()){
boolean success = file.mkdirs();
if(success){
Toast.makeText(ExternalData.this, "File created", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(ExternalData.this, "Not able to create file", Toast.LENGTH_LONG).show();
}
}
InputStream fis = getResources().openRawResource(R.drawable.darthvader);
/* this works....but wats wrong with the original code
file = new File(file, "darthVader.png");
if(!file.exists()){
file.createNewFile();
}
*/
FileOutputStream fos = new FileOutputStream(file);
byte[] data = new byte[fis.available()];
fis.read(data);
fos.write(data);
fis.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
Toast.makeText(ExternalData.this, "FilNOT", Toast.LENGTH_LONG).show();
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(ExternalData.this, "IO", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
Did you request the permission in your manifest?
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
see this example for How to write file in sdcard (external storage)
InputStream input;
try {
URL url = new URL (strURL);
input = url.openStream();
byte[] buffer = new byte[1500];
OutputStream output = new FileOutputStream ("/sdcard/"+pos+".png");
int bytesRead = 0;
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0)
{
output.write(buffer, 0, bytesRead);
}
finally
{
output.close();
buffer=null;
}
don't forget to give permisson in manifeast file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />