I'm trying to create a file using Uri. But when it is checked whether its empty, it is found empty. Below is the code where the Uri is stored in the variable "filePath".
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
So i have created a function to upload the file to server using retrofit library.
On button click the function is called. Below is the code:
private void uploadFile(Uri fileUri) {
String descriptionString = "hello";
File file = new File(fileUri.getPath());
if(file.exists())
{
Toast.makeText(MainActivity.this,file.getPath(),Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this,file.getName(),Toast.LENGTH_SHORT).show();
}
RequestBody requestFile =
RequestBody.create(
MediaType.parse(getContentResolver().getType(fileUri)),
file
);
MultipartBody.Part image =
MultipartBody.Part.createFormData("image", file.getName(), requestFile);
Call<ImageResponse> call = RetrofitClient.getInstance().getApi().uploadImage(descriptionString,image);
call.enqueue(new Callback<ImageResponse>() {
#Override
public void onResponse(Call<ImageResponse> call, Response<ImageResponse> response) {
ImageResponse imageResponse = response.body();
if (imageResponse.isError())
{
Toast.makeText(MainActivity.this,imageResponse.getMessage(),Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this,imageResponse.getMessage(),Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ImageResponse> call, Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
So my request is failing because the file doesn't exist. What could be the reason? I'm using emulator and have added all the required permissions. I have no idea why it shouldn't work. Please help me! I'm new to retrofit.
My Manifest:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
And the final response I'm getting in toast is:
document/image:31 (no such file or directory )
The issue was that no matter you specify permissions in Manifest, you have to check the permissions at runtime from Android v6.0. So all you have to do is check permissions at run time.
Here is the code. Use the below code:
//Check Permissions on runtime
public boolean checkPermissionREAD_EXTERNAL_STORAGE(
final Context context) {
int currentAPIVersion = Build.VERSION.SDK_INT;
if (currentAPIVersion >= android.os.Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(
(Activity) context,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
showDialog("External storage", context,
Manifest.permission.READ_EXTERNAL_STORAGE);
} else {
ActivityCompat
.requestPermissions(
(Activity) context,
new String[] { Manifest.permission.READ_EXTERNAL_STORAGE },
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
public void showDialog(final String msg, final Context context,
final String permission) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage(msg + " permission is necessary");
alertBuilder.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity) context,
new String[] { permission },
MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
}
#Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// do your stuff
} else {
Toast.makeText(MainActivity.this, "GET_ACCOUNTS Denied",
Toast.LENGTH_SHORT).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
//End permission code
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
try {
if (checkPermissionREAD_EXTERNAL_STORAGE(this)) {
filePath=data.getData();
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),filePath);
imageView.setImageBitmap(bitmap);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void uploadFile(Uri fileUri) {
String descriptionString = "hello";
File file=FileUtils.getFile(getApplicationContext(),fileUri);
RequestBody requestFile =
RequestBody.create(
MediaType.parse(getContentResolver().getType(fileUri)),
file
);
MultipartBody.Part image =
MultipartBody.Part.createFormData("image", file.getName(), requestFile);
Call<ImageResponse> call = RetrofitClient.getInstance().getApi().uploadImage(descriptionString,image);
call.enqueue(new Callback<ImageResponse>() {
#Override
public void onResponse(Call<ImageResponse> call, Response<ImageResponse> response) {
ImageResponse imageResponse = response.body();
if (imageResponse.isError())
{
Toast.makeText(MainActivity.this,imageResponse.getMessage(),Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this,imageResponse.getMessage(),Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ImageResponse> call, Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
Below is the FileUtils class:
public class FileUtils {
//replace this with your authority
public static final String AUTHORITY = "com.ianhanniballake.localstorage.documents";
private FileUtils() {
} //private constructor to enforce Singleton pattern
/**
* TAG for log messages.
*/
static final String TAG = "FileUtils";
private static final boolean DEBUG = false; // Set to true to enable logging
/**
* #return Whether the URI is a local one.
*/
public static boolean isLocal(String url) {
if (url != null && !url.startsWith("http://") && !url.startsWith("https://")) {
return true;
}
return false;
}
public static boolean isLocalStorageDocument(Uri uri) {
return AUTHORITY.equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is ExternalStorageProvider.
* #author paulburke
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is DownloadsProvider.
* #author paulburke
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is MediaProvider.
* #author paulburke
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* #param context The context.
* #param uri The Uri to query.
* #param selection (Optional) Filter used in the query.
* #param selectionArgs (Optional) Selection arguments used in the query.
* #return The value of the _data column, which is typically a file path.
* #author paulburke
*/
public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
if (DEBUG)
DatabaseUtils.dumpCursor(cursor);
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* Get a file path from a Uri. This will get the the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.<br>
* <br>
* Callers should check whether the path is local before assuming it
* represents a local file.
*
* #param context The context.
* #param uri The Uri to query.
* #author paulburke
* #see #isLocal(String)
* #see #getFile(Context, Uri)
*/
public static String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// LocalStorageProvider
if (isLocalStorageDocument(uri)) {
// The path is the id
return DocumentsContract.getDocumentId(uri);
}
// ExternalStorageProvider
else if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* Convert Uri into File, if possible.
*
* #return file A local file that the Uri was pointing to, or null if the
* Uri is unsupported or pointed to a remote resource.
* #author paulburke
* #see #getPath(Context, Uri)
*/
public static File getFile(Context context, Uri uri) {
if (uri != null) {
String path = getPath(context, uri);
if (path != null && isLocal(path)) {
return new File(path);
}
}
return null;
}
}
Related
I'm trying to share basic data between 2 applications using SharedPreferences.
I've created a Class that extends ContentProvider:
package com.chou.playground;
///imports...
public class SharedIdProvider extends ContentProvider {
static final String PROVIDER_NAME = BuildConfig.APPLICATION_ID + ".provider";
static final String URL = "content://" + PROVIDER_NAME + "/__hd";
static final int uriCode = 1;
static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PROVIDER_NAME, "/__hd", uriCode);
uriMatcher.addURI(PROVIDER_NAME, "/__hd/*", uriCode);
}
private transient static SharedPreferences prefs;
private transient static String hardwareId;
#Override
public String getType(#NotNull Uri uri) {
if (uriMatcher.match(uri) == uriCode) {
return PROVIDER_NAME + "/__hd";
}
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
#Override
public boolean onCreate() {
Context context = getContext();
if (context != null) {
prefs = context.getSharedPreferences("rsa_application_key_prefs", 0);
hardwareId = getHardwareId(context);
context.getContentResolver().notifyChange(Uri.parse(URL), null);
return true;
}
return true;
}
public static void update(Context context, String value){
hardwareId = value;
storeHardwareID(context.getApplicationContext(), value);
}
static synchronized String getHardwareId(Context context) {
String hardwareId = null;
if (null != context) {
hardwareId = getStoredHardwareId(context.getApplicationContext());
if (TextUtils.isEmpty(hardwareId)) {
hardwareId = generateHardwareId();
storeHardwareID(context.getApplicationContext(), hardwareId);
}
}
return hardwareId;
}
private static void storeHardwareID(Context context, String hardwareId) {
if (prefs == null) {
Log.e("SdkPreferences", "unexpected error in storeHardwareID, can't get shared preferences");
} else {
SharedPreferences.Editor editor = prefs.edit();
editor.putString("com.aes.api.hardware_id", hardwareId);
editor.putBoolean("com.aes.api.can_be_sync", true);
editor.apply();
}
}
private static String getStoredHardwareId(Context context) {
if (prefs == null) {
Log.e("SdkPreferences", "unexpected error in getStoredHardwareId, can't get shared preferences");
return "INVALID";
} else {
return prefs.getString("com.aes.api.hardware_id", null);
}
}
private static String generateHardwareId() {
return UUID.randomUUID().toString();
}
#Override
public Cursor query(#NotNull Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Context context = getContext();
MatrixCursor cursor = new MatrixCursor(new String[] { "__hd" });
cursor.addRow(new Object[]{ getCachedOrLoadHardwareId( context ) });
return cursor;
}
public static boolean canBeSynchronized() {
return prefs.getBoolean("com.aes.api.can_be_sync", false);
}
private String getCachedOrLoadHardwareId(Context context) {
if(hardwareId == null){
hardwareId = getHardwareId(context);
}
return hardwareId;
}
#Override
public Uri insert(#NotNull Uri uri, ContentValues values) {
return null;
}
#Override
public int update(#NotNull Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return 0;
}
#Override
public int delete(#NotNull Uri uri, String selection, String[] selectionArgs) {
return 0;
}
}
also added the class reference in the AndroidManifest.xml:
<provider
android:authorities="${applicationId}.provider"
android:enabled="true"
android:exported="true"
android:grantUriPermissions="true"
android:name="com.chou.playground.SharedIdProvider">
</provider>
then in my MainActivity I'm trying to get the data:
private void trySyncWith() {
Uri kUri = Uri.parse("content://" + "com.chou.app1.provider" + "/__hd");
Context context = getBaseContext();
if (context != null) {
ContentResolver contentResolver = context.getContentResolver();
if (contentResolver != null) {
final Cursor cursor = contentResolver.query(kUri, null, null, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToNext();
String hardwareId = cursor.getString(0);
if (hardwareId != null) {
SharedIdProvider.update(context, hardwareId);
}
cursor.close();
}
}
}
}
everythings works fine when the app is the same, but when I change the applicationId in my gradle.build file in com.chou.app2, com.chou.app2 cannot find the first content provider, the log says:
Failed to find provider info for com.chou.app1.provider
The strange thing it's that when I run from terminal:
adb shell content query --uri content://com.chou.app1.provider/__hd
then everything starts working properly even from the second app.
Someone can help me?
I would like to send the image and text that I received from the user to the server but I have problems.
void sendData(final String username) {
String url = "http://hesabdarbartar.ir/api/update";
final SharedPreferences preferences = getApplicationContext().getSharedPreferences("data_user", Context.MODE_PRIVATE);
AndroidNetworking.upload(url)
.addMultipartFile(Key.IMAGE, new File(path))
.addMultipartParameter(Key.NAME, username)
.addHeaders(Key.TOKEN, preferences.getString("api_token", ""))
.build()
.getAsObject(User.class, new ParsedRequestListener<User>() {
#Override
public void onResponse(User response) {
try {
preferences.edit().putString("name", response.getName()).apply();
preferences.edit().putString("pic", response.getPic()).apply();
startActivity(new Intent(getApplicationContext(), MainActivity.class));
finish();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "خطا در ارتباط با سرور!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onError(ANError anError) {
Log.i("ererer", "" + String.valueOf(anError));
}
});
}
void askReadPermission() {
Dexter.withActivity(this)
.withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
.withListener(new PermissionListener() {
#Override
public void onPermissionGranted(PermissionGrantedResponse response) {
pickImage();
}
#Override
public void onPermissionDenied(PermissionDeniedResponse response) {
if (response != null && response.isPermanentlyDenied()) {
Snackbar.make(btn_confirm, "برای انتخاب فایل دسترسی ضروری است!", Snackbar.LENGTH_LONG).setAction("اجازه دادن!", new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.setData(Uri.fromParts("package", getApplicationContext().getPackageName(), null));
startActivity(i);
}
}).show();
} else {
Snackbar.make(btn_confirm, "برای انتخاب فایل دسترسی ضروری است!", Snackbar.LENGTH_LONG).show();
}
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
}
}).check();
}
private void pickImage() {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, 1);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == Activity.RESULT_OK && data.getData() != null) {
path = data.getData().getPath();
btn_confirm.setEnabled(true);
img_prof.setImageURI(data.getData());
}
}
}
Here's a snapshot of the program's problems
What you receive in onActivityResult() is an Uri of the image, not its real path. You should convert it to the real path, then you can use it in new File(path). There is a converter:
public class RealPathUtil {
public static String getRealPath(Context context, Uri fileUri) {
String realPath;
// SDK < API11
if (Build.VERSION.SDK_INT < 11) {
realPath = RealPathUtil.getRealPathFromURI_BelowAPI11(context, fileUri);
}
// SDK >= 11 && SDK < 19
else if (Build.VERSION.SDK_INT < 19) {
realPath = RealPathUtil.getRealPathFromURI_API11to18(context, fileUri);
}
// SDK > 19 (Android 4.4) and up
else {
realPath = RealPathUtil.getRealPathFromURI_API19(context, fileUri);
}
return realPath;
}
#SuppressLint("NewApi")
public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
String result = null;
CursorLoader cursorLoader = new CursorLoader(context, contentUri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
if (cursor != null) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
cursor.close();
}
return result;
}
public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = 0;
String result = "";
if (cursor != null) {
column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
cursor.close();
return result;
}
return result;
}
/**
* Get a file path from a Uri. This will get the the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.
*
* #param context The context.
* #param uri The Uri to query.
* #author paulburke
*/
#SuppressLint("NewApi")
public static String getRealPathFromURI_API19(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* #param context The context.
* #param uri The Uri to query.
* #param selection (Optional) Filter used in the query.
* #param selectionArgs (Optional) Selection arguments used in the query.
* #return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* #param uri The Uri to check.
* #return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
}
I've done some progress with the Google Drive API, I can create files and folders. However, I cannot seem to figure out how to upload a folder from device storage to google drive, or how to create folders or files inside Drive Folders.
I also want to know how to retrieve files inside any given Drive Folder.
I would much appreciate a detailed explanation with examples and not a link to the official documentation as I have been struggling with it for days (And I Know I'm Not The Only One).
Here's the code I've gotten so far.
public abstract class DriveActivity extends UtilsActivity {
private static final int REQUEST_CODE_SIGN_IN = 77;
public static final String PIONEER_DRIVE_ROOT_FOLDER = "Pioneer Backups ID_77";
public FileManagerHelper mFileManagerHelper;
private GoogleSignInClient mGoogleSignInClient;
private DriveClient mDriveClient;
public OptionsClass mOptionsClass;
/**
* Inits file manager and Google Sign In Client
*/
protected void Init() {
mFileManagerHelper = new FileManagerHelper(this);
mOptionsClass = new OptionsClass(getApplicationContext());
mGoogleSignInClient = buildSignInOptions();
if (loggedIntoGoogleDrive() && mOptionsClass.getEnableDrive()) {
/*
Create the main pioneer folder, where all the backups will be stored.
*/
//TODO heck if the folder already exists
// createFolder(getRootFolderTask(),
// new MetadataChangeSet.Builder()
// .setTitle(PIONEER_DRIVE_ROOT_FOLDER)
// .setDescription("Root Folder For All Pioneer Backups")
// .build(), false);
}
}
/**
* Sign user out of google account
*/
public void signOutOfGoogleDrive() {
onProcessStart(PROCESS_KEY_ACCOUNT_RELATED);
mGoogleSignInClient
.signOut()
/*
Success
*/
.addOnSuccessListener(aVoid -> {
onProcessEnd(PROCESS_KEY_ACCOUNT_RELATED);
Toast.makeText(DriveActivity.this, "Signed Out", Toast.LENGTH_SHORT).show();
})
/*
Failure
*/
.addOnFailureListener(e -> {
onProcessEnd(PROCESS_KEY_ACCOUNT_RELATED);
e.printStackTrace();
Toast.makeText(DriveActivity.this, "Failure " + e.getMessage(), Toast.LENGTH_SHORT).show();
})
/*
Completion
*/
.addOnCompleteListener(task -> {
onProcessEnd(PROCESS_KEY_ACCOUNT_RELATED);
Toast.makeText(DriveActivity.this, "Done", Toast.LENGTH_SHORT).show();
});
}
/**
* Get user data, to enable Google Drive
*
* #return ResourceClient
*/
public DriveResourceClient getDriveResourceClient() {
return Drive.getDriveResourceClient(getApplicationContext(), getGoogleAccount());
}
public boolean loggedIntoGoogleDrive() {
return getGoogleAccount() != null;
}
/**
* #return the las logged in account
*/
public GoogleSignInAccount getGoogleAccount() {
return GoogleSignIn.getLastSignedInAccount(this);
}
/**
* #return the scopes the user needs to grant to the app
*/
private Set<Scope> getRequiredScopes() {
Set<Scope> requiredScopes = new HashSet<>(2);
requiredScopes.add(Drive.SCOPE_FILE);
requiredScopes.add(Drive.SCOPE_APPFOLDER);
return requiredScopes;
}
/**
* Start sign in activity.
*/
public void signInToGoogleDrive() {
onProcessStart(PROCESS_KEY_ACCOUNT_RELATED);
/*
Check if we have all the required scopes and if the user if logged in
*/
if (loggedIntoGoogleDrive() && getGoogleAccount().getGrantedScopes().containsAll(getRequiredScopes())) {
initializeDriveClient(getGoogleAccount());
onProcessEnd(PROCESS_KEY_ACCOUNT_RELATED);
} else {
GoogleSignInOptions signInOptions =
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(Drive.SCOPE_FILE)
.requestScopes(Drive.SCOPE_APPFOLDER)
.build();
GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, signInOptions);
startActivityForResult(googleSignInClient.getSignInIntent(), REQUEST_CODE_SIGN_IN);
}
startActivityForResult(mGoogleSignInClient.getSignInIntent(), REQUEST_CODE_SIGN_IN);
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == REQUEST_CODE_SIGN_IN) {
onProcessEnd(PROCESS_KEY_ACCOUNT_RELATED);
}
}
public void initializeDriveClient(GoogleSignInAccount signInAccount) {
mDriveClient = Drive.getDriveClient(getApplicationContext(), signInAccount);
mDriveClient.getUploadPreferences().addOnSuccessListener(transferPreferences -> {
});
}
/**
* Build a Google SignIn client.
*/
private GoogleSignInClient buildSignInOptions() {
GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(Drive.SCOPE_FILE)
.requestScopes(Drive.SCOPE_APPFOLDER)
.build();
return GoogleSignIn.getClient(this, signInOptions);
}
/**
* Uploads a file to drive
*
* #param file to upload
*/
public void uploadFileToDrive(File file, String des) {
if (!loggedIntoGoogleDrive()) {
signInToGoogleDrive();
return;
} else if (!mOptionsClass.getEnableDrive()) {
makeText("Enable Drive Backup First");
}
// getRootFolderTask()
// .continueWithTask(task -> {
//
// DriveFolder parentFolder = task.getResult();
//
// String fileName = file.getName();
//
// String from = file.getAbsolutePath();
//
// String fileDes =
// "Pioneer Backup File. Uploaded: " + CalendarHelper.getSimpleFormattedDateAndTime(true);
//
// MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
// .setTitle(fileName)
// .setMimeType("text/plain")
// .setDescription(fileDes + "_" + from)
// .setStarred(true)
// .build();
//
// return getDriveResourceClient().createFile(parentFolder, changeSet, null);
// })
// .addOnSuccessListener(this,
// driveFile -> {
// Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show();
// })
// .addOnFailureListener(this, e -> {
// Toast.makeText(this, "Error " + e.getMessage(), Toast.LENGTH_SHORT).show();
// });
}
private Task<DriveFolder> getRootFolderTask() {
return getDriveResourceClient().getRootFolder();
}
/**
* Creates a file inside a folder
*/
private void createFile(#NonNull Task<DriveFolder> folderToGoIn, String name) {
addTaskListenerToDriveFolder(folderToGoIn.continueWithTask(task -> {
if (task.getResult() != null) {
DriveFolder parentFolder = task.getResult();
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(name)
.setMimeType("text/plain")
.setStarred(true)
.build();
return getDriveResourceClient().createFolder(parentFolder, changeSet);
} else {
makeText("Error");
return null;
}
}), false);
}
private void createFolder(#NonNull Task<DriveFolder> folderToGoIn, MetadataChangeSet folderMetadata, boolean notify) {
addTaskListenerToDriveFolder(folderToGoIn
.continueWithTask(task -> {
if (task.getResult() != null) {
DriveFolder parentFolder = task.getResult();
return getDriveResourceClient().createFolder(parentFolder, folderMetadata);
} else {
makeText("Error");
return null;
}
}), notify);
}
private Task<DriveContents> readFile(DriveFile file) {
return getDriveResourceClient().openFile(file, DriveFile.MODE_READ_ONLY);
}
private Task<MetadataBuffer> getFoldersIn(DriveFolder driveFolder) {
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.MIME_TYPE, DriveFolder.MIME_TYPE))
.build();
return getDriveResourceClient().queryChildren(driveFolder, query);
}
public List<File> getDriveBackups() {
//TODO get actual files inside the backup folder
return getLocalBackups();
}
public void viewDriveBackups() {
/*
Open the Google Drive app to view the backups folder
*/
}
/**
* Adds task failure, success, complete and cancelled listeners.
* Automatically notifies the user of state
*
* #param task to add listeners
*/
private void addTaskListenerToDriveFolder(Task<DriveFolder> task, boolean notify) {
onProcessStart(PROCESS_KEY_BACKUP_RELATED);
task
.addOnCanceledListener(() -> {
onProcessEnd(PROCESS_KEY_BACKUP_RELATED);
if (notify)
makeText("Cancelled");
})
.addOnCompleteListener(task1 -> {
onProcessEnd(PROCESS_KEY_BACKUP_RELATED);
if (notify)
makeText("Completed");
})
.addOnSuccessListener(driveFolder -> {
onProcessEnd(PROCESS_KEY_BACKUP_RELATED);
if (notify)
makeText("Success");
})
.addOnFailureListener(this, e -> {
onProcessEnd(PROCESS_KEY_BACKUP_RELATED);
if (notify)
makeText("Error " + e.getMessage());
});
}
}
now my problem is that:
This is a workaround for Onclcick an ImageButton, which tries to cache the previous image Uri. Passing null effectively resets it.
private ImageButton mImageSelect;
private static final int GALLERY_REQUEST =1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post);
mImageSelect=(ImageButton) findViewById(R.id.imageselect);
mImageSelect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent galleryIntent= new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, GALLERY_REQUEST);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
if(requestCode== GALLERY_REQUEST && resultCode==RESULT_OK){
Uri selectedImageUri=data.getData();
if (null != selectedImageUri) {
mImageSelect.setImageURI(selectedImageUri);
Toast.makeText(PostActivity.this, "Image Selected", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(PostActivity.this,"Image Not Selected",Toast.LENGTH_SHORT).show();
}
}
}
even if fileUri is ready, setImageUri() doesn't guarantee to set the image. so its a good practice to always use third party library when dealing with image.
instead of setImageUri(), use Picasso library.
Picasso.with(MainActivity.this).load(fileUri).into(mImageView)
Add as dependancy
compile 'com.squareup.picasso:picasso:2.5.2'
Try this
Uri imgUri=Uri.parse("android.resource://my.package.name/"+R.drawable.image);
mImageSelect.setImageURI(null);
mImageSelect.setImageURI(imgUri);
This is a workaround for refreshing an ImageButton, which tries to cache the previous image Uri. Passing null effectively resets it.
Imagebutton.setImageURI(uri) doesn't work
You can use Glide to load images more easily
Add this to your build.gradle
compile 'com.github.bumptech.glide:glide.3.7.0'
Load image uri using glide as follows
Glide.with(MainActivity.this).load(uri).into(imageView);
Try
mImageSelect.setImageURI(Uri.parse(data.getData());
Try creating Bitmap from uri and setting bitmap on image button.
This can be done as:
String path = getPath(this,uri);
Code for getPath():
public static String getPath(final Context context, final Uri uri) {
Utils.context = context;
Utils.uri = uri;
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] {
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
Now can get Bitmap as:
if(path!=null)
Bitmap bm = getBitmapFromPath(path)
Set Image on imageButton as:
ImageButton.setImageBitmap(bm);
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
i have two classes which i am trying to pass my values in other class for insertion in db, through getters and setters i made but i get the the exception and my application crashes as soon as i click the Save button ..please somebody take a look on it its been three days i cant seem to solve it Thanks
here are my both classes:
/**
* Created by Sanya on 11/22/2015.
*/
public class User_overlay_save extends Activity implements View.OnClickListener
{
private static int RESULT_LOAD_IMAGE = 1;
private static int RESULT_LOAD_VIDEO = 2;
private int position = 0;
private SQLiteDatabase db; DatabaseHelper helper;
File myapp;
private MediaController mediaControls;
Button save_button;
ImageButton vid_button,img_button;
EditText name_overlay;
TextView real_Imgpath, real_Vidpath;
protected void onCreate(Bundle savedInstanceState){
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.user_overlay_save);
save_button=(Button)findViewById(R.id.save_Ouser);
img_button=(ImageButton)findViewById(R.id.img_button);
vid_button=(ImageButton)findViewById(R.id.vid_button);
real_Imgpath =(TextView)findViewById(R.id.real_Imgpath);
real_Vidpath =(TextView)findViewById(R.id.real_Vidpath);
name_overlay=(EditText)findViewById(R.id.name_overlay);
save_button.setOnClickListener(this);
img_button.setOnClickListener(this);
vid_button.setOnClickListener(this);
name_overlay.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.save_Ouser:
{
boolean result= helper.Insert();
if(result==true)
{
Toast.makeText(getApplicationContext(), "saved..in DB..!!!",
Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(), "ERROR--the path could not b saved..!!",
Toast.LENGTH_LONG).show();
}
}
break;
case R.id.img_button:
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
break;
case R.id.vid_button:
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, RESULT_LOAD_VIDEO);
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
String realPath;
//FOR IMAGE PATH SAVING
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
String selectedImagePath;
Uri selectedImageUri = data.getData();
//MEDIA GALLERY
selectedImagePath = ImageFilePath.getPath(getApplicationContext(), selectedImageUri);
Log.i("Image-->File Path-->", " " + selectedImagePath);
setImgTextViews(Build.VERSION.SDK_INT, selectedImagePath);
SET_saveImg(selectedImagePath);
}
else if(Build.VERSION.SDK_INT < 19)
{
realPath = this.getRealPathFromURI_FromAPI11_18(this, data.getData());
setImgTextViews(Build.VERSION.SDK_INT, realPath);
}
//----------->>>>>>>>>>>---------->>>>FOR VIDEO PATH SAVING------>>>>>>------------>>>>>>>>>>>-------->>>>>>>>>---------->>>>
if (requestCode == RESULT_LOAD_VIDEO && resultCode == RESULT_OK && null != data)
{
//FOR VIDEO PATH SAVING
String selectedVidPath;
Uri selectedVidUri = data.getData();
//VIDEO____PLAY___LIST
selectedVidPath = ImageFilePath.getPath(getApplicationContext(), selectedVidUri);
Log.i("VIDEO-->File Path-->", "" + selectedVidPath);
setVIDTextViews(Build.VERSION.SDK_INT, selectedVidPath);
SET_saveVid(selectedVidPath);
}
}
public String getRealPathFromURI_FromAPI11_18(Context context, Uri contentUri)
{
String[] proj = { MediaStore.Images.Media.DATA };
String result = null;
CursorLoader cursorLoader = new CursorLoader(context, contentUri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
if(cursor != null){
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
}
return result;
}
protected void setImgTextViews(int sdk,String realPath){
this.real_Imgpath.setText
("CURRENT VERSION--SDK-->"+sdk+"Real Path: "+realPath);
}
protected void setVIDTextViews(int sdk,String realPath)
{
this.real_Vidpath.setText
("CURRENT VERSION--SDK-->"+sdk+"Real Path: "+realPath);
}
//---->>------>>>------->>>>SETTERS--FOR IMAGE-->SET_saveImg(selectedImagePath) For &VIDEO -->>SET_saveVid(selectedVidPath)--->>AND--->>GETTERS FOR IMAGE AND VIDEO--------->>>>>
String realPath; String vidPath;
public String GET_saveImg()//IS CALLED FROM DATABASE_HELPER CLASS TO PROVIDE THE SETTER VALUES
{
return realPath;
}
protected void SET_saveImg(String realPath)
{
this.realPath=realPath;
}
protected String GET_saveVid()
{
return vidPath;
}
protected void SET_saveVid(String vidPath)
{
this.vidPath= vidPath;
}}
---------------------<<<<<<------------>>>>>>>>>>>>--------- DATABASEHELPER_class
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper {
SQLiteDatabase db; User_overlay_save obj ;
// Database Name
public static String DATABASE_NAME = "MY_database.sql";
// Current version of database
private static final int DATABASE_VERSION = 1;
// Name of table
private static final String TABLE_Images = "images";
// All Keys used in table
static final String KEY_ID = "id";
static final String KEY_IMAGE = "image";
static final String KEY_FILE = "file";
public static String TAG = "tag";
private static final String CREATE_TABLE_Images = "CREATE TABLE "
+ TABLE_Images + "(" + KEY_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_IMAGE + "TEXT" + KEY_FILE + " TEXT );";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/*This method is called by system if the database is accessed but not yet created*/
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_Images); // create Image table
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + CREATE_TABLE_Images);
// drop table if exists
onCreate(db);
}
public boolean Insert()
{ boolean success = false;
String imgpath = obj.GET_saveImg();
String vidPath = obj.GET_saveVid();
db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_IMAGE, imgpath);
values.put(KEY_FILE, vidPath);
db.insert(TABLE_Images, null, values);
success=true;
db.close();
if(success) {
return true;
}
else
{
return false;
}
}
}
Your DatabaseHelper object helper is null. Because you have just declare it, not define anywhere.
put helper = new DatabaseHelper(any arguments if there it is);
inside onCreate before setting onClickListener on save button.
protected void onCreate(Bundle savedInstanceState){
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.user_overlay_save);
...........................
helper = new DatabaseHelper();
save_button.setOnClickListener(this);
..................
}