Android: android.database.Cursor.moveToFirst()'

2020-08-04 11:40发布

I'm working about photo application and i want to implement cirlcle cropper in my project, but i have a problem about my fragment and cropper class. When i'm selected picture and press crop button and after turning fragment i'm giving this error:

06-04 02:09:34.595 21914-21914/com.stamplessapp E/AndroidRuntime: FATAL EXCEPTION: main
                                                              Process: com.stamplessapp, PID: 21914
                                                              java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=131094, result=-1, data=Intent { dat=file:///storage/emulated/0/Pictures/Stampless/IMG_20160604_020934.jpg }} to activity {com.stamplessapp/com.stamplessapp.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference
                                                                  at android.app.ActivityThread.deliverResults(ActivityThread.java:4058)
                                                                  at android.app.ActivityThread.handleSendResult(ActivityThread.java:4101)
                                                                  at android.app.ActivityThread.access$1400(ActivityThread.java:177)
                                                                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1497)
                                                                  at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                  at android.os.Looper.loop(Looper.java:145)
                                                                  at android.app.ActivityThread.main(ActivityThread.java:5942)
                                                                  at java.lang.reflect.Method.invoke(Native Method)
                                                                  at java.lang.reflect.Method.invoke(Method.java:372)
                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
                                                               Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference
                                                                  at com.stamplessapp.ProfileFragment.onActivityResult(ProfileFragment.java:582)
                                                                  at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:176)
                                                                  at android.app.Activity.dispatchActivityResult(Activity.java:6543)
                                                                  at android.app.ActivityThread.deliverResults(ActivityThread.java:4054)
                                                                  at android.app.ActivityThread.handleSendResult(ActivityThread.java:4101) 
                                                                  at android.app.ActivityThread.access$1400(ActivityThread.java:177) 
                                                                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1497) 
                                                                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                  at android.os.Looper.loop(Looper.java:145) 
                                                                  at android.app.ActivityThread.main(ActivityThread.java:5942) 
                                                                  at java.lang.reflect.Method.invoke(Native Method) 
                                                                  at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) 
                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) 

Circle cropper activity want context and i'm getting in fragment context like this:

     private static Context myContext;
...
OnCreate();
     myContext = getActivity().getApplicationContext();
...
     public static Context getAppContext() {
        return ProfileFragment.myContext;
    }

This is the error:

 Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference

Here is the Cropper Activity

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_circle_crop);
    Intent intent = getIntent();
    final CropImageLayout mCropLayout = (CropImageLayout) findViewById(R.id.cil_crop);
    mCropLayout.setImageUri(intent.getData());
    context = ProfileFragment.getAppContext();
    Uri imageUri = intent.getData();

    try {
        mBitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(),imageUri);
    }catch(IOException ex) {
        //Do something witht the exception
    }

  findViewById(R.id.btn_crop).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mCropLayout.saveOutput(new CropImageLayout.CropListener() {
                @Override
                public void onSuccess(Uri saveUri) {
                    Intent intent = new Intent();
                    intent.setData(saveUri);
                    setResult(RESULT_OK, intent);
                    finish();
                }

And here is my Fragment get code:

 else if (requestCode == REQUEST_CROP && resultCode == Activity.RESULT_OK&& null != data) {
        Uri selectedImage = data.getData();
        String[] filePathColumn = { MediaStore.Images.Media.DATA };

        Cursor cursor = context.getContentResolver().query(selectedImage,
                filePathColumn, null, null, null);
        cursor.moveToFirst();

        // String selectedPhoto contains the path of selected Image
        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        selectedPhoto = cursor.getString(columnIndex);
        cursor.close();

        UploadPhoto uploadProfilePhoto = new UploadPhoto();
        uploadProfilePhoto.execute();

    }

Error line point this line :

 cursor.moveToFirst();

How can i fix this problem?

Here is the saving cropped image code in library :

public class FileUtils {

public static File getOutputMediaFileUri() {
    File mediaStorageDir = new File(
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            "Stampless");
    if (!mediaStorageDir.exists()) {
        if (!mediaStorageDir.mkdirs()) {
            Log.d("crop", "failed to create directory");
            return null;
        }
    }

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp
            + ".jpg");

    return mediaFile;
}


/**
 * Get the file path from the given Uri.
 *
 * @param context The context of the calling activity.
 * @param uri     The Uri whose file path is returned.
 */
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getFilePathFromUri(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];
            }
        }
        // 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 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 column_index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(column_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());
}

}

1条回答
手持菜刀,她持情操
2楼-- · 2020-08-04 12:15

I'm solved my problem, first of all when i debug my app , and it returned file:, however it want to content:. So i'm converting my uri to file first of all :

 Uri uri =data.getData();
 File myFile = new File(uri.getPath());

Then, i'm converting my file to content using this code : example here

Uri selectedImage=getImageContentUri(context,myFile);

then i'm calling this function :

  public static Uri getImageContentUri(Context context, File imageFile) {
    String filePath = imageFile.getAbsolutePath();
    Cursor cursor = context.getContentResolver().query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            new String[] { MediaStore.Images.Media._ID },
            MediaStore.Images.Media.DATA + "=? ",
            new String[] { filePath }, null);

    if (cursor != null && cursor.moveToFirst()) {
        int id = cursor.getInt(cursor
                .getColumnIndex(MediaStore.MediaColumns._ID));
        Uri baseUri = Uri.parse("content://media/external/images/media");
        return Uri.withAppendedPath(baseUri, "" + id);
    } else {
        if (imageFile.exists()) {
            ContentValues values = new ContentValues();
            values.put(MediaStore.Images.Media.DATA, filePath);
            return context.getContentResolver().insert(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        } else {
            return null;
        }
    }}

thats all.

查看更多
登录 后发表回答