/*
* Copyright 2014 ParanoidAndroid Project
* Modifications Copyright (C) 2014 Alexander "Evisceration" Martinz
*
* This file is part of Paranoid OTA.
*
* Paranoid OTA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Paranoid OTA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Paranoid OTA. If not, see <http://www.gnu.org/licenses/>.
*/
package org.namelessrom.devicecontrol.activities;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.widget.Toast;
import org.namelessrom.devicecontrol.R;
import org.namelessrom.devicecontrol.utils.IOUtils;
import org.namelessrom.devicecontrol.utils.Utils;
import java.io.Serializable;
import timber.log.Timber;
public class RequestFileActivity extends Activity {
private static final String ROOT_ID_PRIMARY_EMULATED = "primary";
private static final int REQUEST_PICK_FILE = 203;
private static final int REQUEST_PICK_FILE_TWO = 204;
public interface RequestFileCallback extends Serializable {
void fileRequested(String filePath);
}
private static RequestFileCallback sCallback;
public static void setRequestFileCallback(RequestFileCallback callback) {
sCallback = callback;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final PackageManager pm = getPackageManager();
if (pm == null) {
launchInternalPicker();
return;
}
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/zip");
try {
if (pm.queryIntentActivities(intent, PackageManager.GET_ACTIVITIES).size() > 0) {
intent = new Intent();
intent.setType("application/zip");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, REQUEST_PICK_FILE);
} else {
throw new ActivityNotFoundException();
}
} catch (ActivityNotFoundException e) {
Timber.e(e, "No activity found to handle file picking! Falling back to default!");
launchInternalPicker();
}
}
private void launchInternalPicker() {
final Intent intent = new Intent();
final Intent i = new Intent(this, FilePickerActivity.class);
i.setType("application/zip");
try {
startActivityForResult(intent, REQUEST_PICK_FILE_TWO);
} catch (ActivityNotFoundException e) {
Timber.wtf(e, "Could not start default activity to pick files");
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && (requestCode == REQUEST_PICK_FILE || requestCode == REQUEST_PICK_FILE_TWO)) {
if (data == null) {
Toast.makeText(this, getString(R.string.something_went_wrong), Toast.LENGTH_LONG).show();
} else {
try {
// some file pickers like AndroZip allow to pick the file but we error out when
// trying to read the provider as it is not exported
handleActivityResult(data, requestCode);
} catch (SecurityException se) {
Timber.e(se, "could not handle activity result");
Toast.makeText(this, getString(R.string.something_went_wrong), Toast.LENGTH_LONG).show();
}
}
}
finish();
}
private void handleActivityResult(@NonNull Intent data, int reqCode) throws SecurityException {
final Uri uri;
String filePath = null;
if (reqCode == REQUEST_PICK_FILE) {
uri = data.getData();
if (uri != null) {
filePath = uri.getPath();
}
} else {
uri = null;
filePath = data.getStringExtra("path");
}
Timber.i("uri: %s, filepath: %s", uri, filePath);
if (!Utils.fileExists(filePath) && uri != null) {
final ContentResolver cr = getContentResolver();
Cursor cursor = null;
try {
cursor = cr.query(uri, null, null, null, null);
if (cursor != null && cursor.moveToNext()) {
int index = cursor.getColumnIndex(MediaStore.MediaColumns.DATA);
if (index >= 0) {
filePath = cursor.getString(index);
} else if (Build.VERSION.SDK_INT >= 19
&& uri.toString().startsWith(ContentResolver.SCHEME_CONTENT)) {
String newUri = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(uri.getAuthority())
.appendPath("document")
.build().toString();
String path = uri.toString();
index = filePath.indexOf(":");
if (path.startsWith(newUri) && index >= 0) {
String firstPath = filePath.substring(0, index);
filePath = filePath.substring(index + 1);
String storage = IOUtils.get().getPrimarySdCard();
if (!firstPath.contains(ROOT_ID_PRIMARY_EMULATED)) {
storage = IOUtils.get().getSecondarySdCard();
}
filePath = storage + "/" + filePath;
} else {
filePath = null;
}
}
}
} finally {
if (cursor != null) cursor.close();
}
}
if (sCallback != null) {
sCallback.fileRequested(filePath);
}
}
}