我正在编写一个应用程序,用户在名为TranslateActivity
的活动中写入单词。我想将这些文字存储在与用户相关的谷歌硬盘上。
我使用AsyncTask
实现了代码,该代码能够创建文件并将数据附加到驱动器等等。但是,每次用户写一个单词时我都不想将数据推送到驱动器,因为它需要一些时间。相反,我想做以下事情:
当用户按下back
时,上传应在后台开始。但是,它对我不起作用。我假设android关闭了上下文等等,并且会破坏AsyncCall
。
当用户退出活动时我想要进行上传的原因是因为我知道不会有更多的输入。
代码看起来像
@Override
public void onBackPressed(){
googleDriveWrite.execute(mAdapter.getWords());
while(!mIsFinished){
}
}
完成后, GoogleDriveWrite
会返回boolean
。我不喜欢上面的尝试,但我想你明白我的尝试。
我正在寻找一种能够暂停"暂停"用户界面直到上传完成,例如显示进度条,或者在活动发生变化时继续工作的内容。
一种可能的解决方案是添加save
- 按钮,但我希望它能在没有用户输入的情况下顺利运行。
我刚发现:https://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html可以使用
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallbacks = (TaskCallbacks) activity;
}
在旋转等情况下附加片段的新活动。也许可以做一些类似于GoogleDriveWrite
延伸AsyncTask
的事情?虽然AsyncTask
似乎不包含onAttach(Activity activity)
。
Context
需要Activity
和GoogleDriveWrite
来调用Drive.getDriveResourceClient(Context, GoogleSignInAccount)
,问题可能出在哪里?
以下是GoogleDriveWrite.java
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.ParcelFileDescriptor;
import android.support.annotation.NonNull;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveClient;
import com.google.android.gms.drive.DriveContents;
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveFolder;
import com.google.android.gms.drive.DriveResourceClient;
import com.google.android.gms.drive.Metadata;
import com.google.android.gms.drive.MetadataBuffer;
import com.google.android.gms.drive.MetadataChangeSet;
import com.google.android.gms.drive.query.Filters;
import com.google.android.gms.drive.query.Query;
import com.google.android.gms.drive.query.SearchableField;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class GoogleDriveWrite extends AsyncTask<ArrayList<Words>,Void, Boolean> {
private final String TAG = getClass().getSimpleName();
final public static String PARENTNAME = "TAILOREDDICTIONARY";
public final static int MAXTIME = 15000;
private DriveResourceClient mDriveResourceClient;
private DriveClient mDriveClient;
private Context mContext;
private BaseActivity mActivity;
private ProgressDialog progressDialog;
private GoogleSignInAccount mAccount;
protected final static int NBROFITEMS = 6;
protected final static String TEXTNAMES[] = {"w1.txt", "w2.txt", "score.txt", "ctr.txt", "time.txt", "isHidden.txt"};
private GoogleDriveHelper mDriveHelper;
String mKeyName;
private void setUp() {
mDriveClient = Drive.getDriveClient(mContext, mAccount);
mDriveResourceClient = Drive.getDriveResourceClient(mContext, mAccount);
}
public GoogleDriveWrite(String keyName, GoogleSignInAccount account, Context context, BaseActivity activity){
mKeyName = keyName;
mAccount = account;
mContext = context;
mActivity = activity;
mDriveHelper = new GoogleDriveHelper();
setUp();
}
protected void onPreExecute() {
System.out.println("In pre execute");
progressDialog = ProgressDialog.show(mActivity,"ProgressDialog","Wait for saving files");
}
protected void onPostExecute(Boolean result){
System.out.println("In on PosteExecute");
mActivity.setFinishedTask(result);
progressDialog.dismiss();
}
@Override
protected Boolean doInBackground(ArrayList<Words>... words) {
DriveFolder rootFolder = mDriveHelper.getRootFolder(mDriveResourceClient);
if (rootFolder == null){
throw new IllegalStateException("rootFolder is null");
} else {
System.out.println("root is not null!");
}
// Search for parentName
MetadataBuffer metadata = mDriveHelper.searchFolders(PARENTNAME, rootFolder, mDriveResourceClient);
if (metadata == null){
throw new IllegalStateException("metadata is null");
}
DriveFolder parentFolder = getFolderFromMeta(metadata, rootFolder, PARENTNAME);
// Release metadatabuffer
metadata.release();
// Check parentFolder is not null
if (parentFolder == null){
throw new IllegalStateException("Parentfolder is null");
} else {
System.out.println("parentFolder is not null");
}
// Search for keyFolder
metadata = mDriveHelper.searchFolders(mKeyName, parentFolder, mDriveResourceClient);
DriveFolder keyFolder = getFolderFromMeta(metadata, parentFolder, mKeyName);
if (keyFolder == null){
throw new IllegalStateException("Keyfolder is null");
} else {
System.out.println(mKeyName);
System.out.println("keyFolder is not null");
}
metadata.release();
// Write new data to keyFolder
writeFilesToData(keyFolder, words[0]);
// progressDialog.dismiss();
return true;
}
private ArrayList<ArrayList<String>> splitData(ArrayList<Words> words) {
ArrayList<ArrayList<String>> data = new ArrayList<>();
ArrayList<String> tmp[] = new ArrayList[NBROFITEMS];
for (int i = 0; i < NBROFITEMS; ++i) {
tmp[i] = new ArrayList<>();
}
for (int i = 0; i < words.size(); i++) {
tmp[0].add(words.get(i).w1);
tmp[1].add(words.get(i).w2);
tmp[2].add(Double.toString(words.get(i).score));
tmp[3].add(Double.toString(words.get(i).ctr));
tmp[4].add(Double.toString(words.get(i).time));
tmp[5].add(Boolean.toString(words.get(i).isHidden));
}
for (int i = 0; i < NBROFITEMS; i++) {
data.add(tmp[i]);
}
return data;
}
private void writeFilesToData(DriveFolder folder, ArrayList<Words> words){
System.out.println("Size words: " + words.size());
ArrayList<ArrayList<String>> data = splitData(words);
MetadataBuffer metadata = mDriveHelper.searchTextFiles(folder, mDriveResourceClient);
ArrayList<DriveFile> driveFiles = mDriveHelper.getDriveFiles(metadata);
// If files do not exist we must create them
if (driveFiles.isEmpty()){
driveFiles = mDriveHelper.createDriveFiles(folder, mDriveResourceClient);
for (int i = 0; i < NBROFITEMS; i++){
appendData(driveFiles.get(i), data.get(i));
}
} else {
for (Metadata m : metadata) {
if (m.getTitle().equals(TEXTNAMES[0])) {
appendData(driveFiles.get(0), data.get(0));
}
if (m.getTitle().equals(TEXTNAMES[1])) {
appendData(driveFiles.get(1), data.get(1));
}
if (m.getTitle().equals(TEXTNAMES[2])) {
appendData(driveFiles.get(2), data.get(2));
}
if (m.getTitle().equals(TEXTNAMES[3])) {
appendData(driveFiles.get(3), data.get(3));
}
if (m.getTitle().equals(TEXTNAMES[4])) {
appendData(driveFiles.get(4), data.get(4));
}
if (m.getTitle().equals(TEXTNAMES[5])) {
appendData(driveFiles.get(5), data.get(5));
}
}
}
metadata.release();
}
private void appendData(DriveFile driveFiles, ArrayList<String> data){
DriveContents content = mDriveHelper.getTaskResult(mDriveResourceClient.openFile(driveFiles, DriveFile.MODE_READ_WRITE));
if (content == null){
throw new IllegalStateException("Content is null");
}
ParcelFileDescriptor pfd = content.getParcelFileDescriptor();
long bytesToSkip = pfd.getStatSize();
try (InputStream in = new FileInputStream(pfd.getFileDescriptor())) {
// Skip to end of file
while (bytesToSkip > 0) {
long skipped = in.skip(bytesToSkip);
bytesToSkip -= skipped;
}
} catch (IOException e){
e.printStackTrace();
}
try (OutputStream out = new FileOutputStream(pfd.getFileDescriptor())) {
appendToFile(out, data);
} catch (IOException e){
e.printStackTrace();
}
// [START commit_contents_with_metadata]
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setStarred(true)
.setLastViewedByMeDate(new Date())
.build();
Task<Void> commitTask = mDriveResourceClient.commitContents(content, changeSet);
commitTask.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
System.out.println("Files commits");
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
System.out.println("Failed to commit");
}
});
}
private void appendToFile(OutputStream out, ArrayList<String> data){
try {
for (int i = 0; i < data.size(); i++) {
out.write((data.get(i) + "\n").getBytes());
}
} catch (Exception e){
e.printStackTrace();
}
}
private void createFile(ArrayList<String> data, String fileName, DriveFolder folder){
}
/**
* Search metadata for folder. If found return existing fodler. If not found create new folder in rootFolder
* @param metadata Buffer with found folders
* @param rootFolder Folder to create new folder in
* @return drivefolder with name folderName
*/
private DriveFolder getFolderFromMeta(MetadataBuffer metadata, DriveFolder rootFolder, String folderName){
// ArrayList is empty we must create ParentFolder
ArrayList<String> titles = mDriveHelper.getTitles(metadata);
DriveFolder folder = null;
if (titles.isEmpty()){
folder = createFolder(rootFolder,folderName);
} else {
folder = metadata.get(0).getDriveId().asDriveFolder();
}
return folder;
}
private DriveFolder createFolder(DriveFolder folder, String fileName){
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(fileName)
.setMimeType(DriveFolder.MIME_TYPE)
.build();
Task<DriveFolder> newFolder = mDriveResourceClient.createFolder(folder, changeSet);
DriveFolder driveFolder = mDriveHelper.getTaskResult(newFolder);
return driveFolder;
}
private void showMessage(String txt) {
Toast.makeText(mContext, txt, Toast.LENGTH_SHORT).show();
}
}