Java Android:在不同的Android版本中上传图片时出错

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24573640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 13:07:26  来源:igfitidea点击:

Android: Error upload image in different android versions

javaandroidweb-services

提问by TMoraes

I am having problem with upload image in different android versions. I need to send images for php server, so i'm using a webservice. I did test with the versions Froyo e Jelly Beans, they works but the KitKat don't work. I was reading about MediaStore and I saw different ways and I don't if my its right or wrong.

我在不同的 android 版本中上传图片时遇到问题。我需要为 php 服务器发送图像,所以我使用的是网络服务。我对 Froyo e Jelly Beans 版本进行了测试,它们可以工作,但 KitKat 不工作。我正在阅读有关 MediaStore 的文章,我看到了不同的方式,但我不知道我的对与错。

I debbuged my project and I could see, in KitKat the path is NULL, Logcat tell me "Java Null Pointer" just in KitKat. How can i do a application works for all version.

我调试了我的项目,我可以看到,在 KitKat 中,路径为 NULL,Logcat 在 KitKat 中告诉我“Java Null Pointer”。我如何才能使应用程序适用于所有版本。

UploadImage.java

上传图片.java

package br.gov.rj.barraemexposicao;

import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


public class EnviaFoto extends ActionBarActivity {

    final int PICK_FILE_RESULT_CODE = 1;
    final int CAMERA_IMAGE =2;

    TextView messageText;
    Button uploadButton;
    Button btnTiraFoto;
    Button selectImage;
    ImageView imgFoto;

    int serverResponseCode = 0;
    ProgressDialog dialog = null;

    String upLoadServerUri = "http://www.kweekdesign.com.br/test/recebe/UploadToServer.php";

    String filePath = "";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_envia_foto);

        selectImage = (Button) findViewById(R.id.selectImage);
        imgFoto = (ImageView) findViewById(R.id.imgFoto);
        messageText  = (TextView)findViewById(R.id.messageText);
        uploadButton = (Button)findViewById(R.id.uploadButton);
        btnTiraFoto = (Button) findViewById(R.id.btnTiraFoto);

        upLoadServerUri = "http://www.kweekdesign.com.br/test/recebe/UploadToServer.php";

        addListeners();
    }

    public String uriToPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data){
        if (data != null && (requestCode == PICK_FILE_RESULT_CODE || requestCode == CAMERA_IMAGE)){

            filePath = uriToPath(data.getData());
            imgFoto.setImageURI(data.getData());
            uploadButton.setVisibility(1);

        }
    }

    public int uploadFile(String sourceFileUri) {
        String fileName = sourceFileUri;

        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1 * 1024 * 1024;
        File sourceFile = new File(sourceFileUri);

        if (!sourceFile.isFile()) {

            dialog.dismiss();

            Log.e("uploadFile", "Source File not exist :" + filePath);

            runOnUiThread(new Runnable() {
                public void run() {
                    messageText.setText("Source File not exist :"+filePath);
                }
            });

            return 0;

        }
        else
        {
            try {

                // open a URL connection to the Servlet
                FileInputStream fileInputStream = new FileInputStream(sourceFile);
                URL url = new URL(upLoadServerUri);

                // Open a HTTP  connection to  the URL
                conn = (HttpURLConnection) url.openConnection();
                conn.setDoInput(true); // Allow Inputs
                conn.setDoOutput(true); // Allow Outputs
                conn.setUseCaches(false); // Don't use a Cached Copy
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Connection", "Keep-Alive");
                conn.setRequestProperty("ENCTYPE", "multipart/form-data");
                conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
                conn.setRequestProperty("uploaded_file", fileName);

                dos = new DataOutputStream(conn.getOutputStream());

                dos.writeBytes(twoHyphens + boundary + lineEnd);
                dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
                        + fileName + "\"" + lineEnd);

                dos.writeBytes(lineEnd);

                // create a buffer of  maximum size
                bytesAvailable = fileInputStream.available();

                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                buffer = new byte[bufferSize];

                // read file and write it into form...
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                while (bytesRead > 0) {

                    dos.write(buffer, 0, bufferSize);
                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                }

                // send multipart form data necesssary after file data...
                dos.writeBytes(lineEnd);
                dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

                // Responses from the server (code and message)
                serverResponseCode = conn.getResponseCode();
                String serverResponseMessage = conn.getResponseMessage();

                Log.i("uploadFile", "HTTP Response is : "
                        + serverResponseMessage + ": " + serverResponseCode);

                if(serverResponseCode == 200){

                    runOnUiThread(new Runnable() {
                        public void run() {

                            String msg = "Envio feito com sucesso!";

                            messageText.setText(msg);
                            Toast.makeText(EnviaFoto.this, "File Upload Complete.",
                                    Toast.LENGTH_SHORT).show();
                        }
                    });
                }

                //close the streams //
                fileInputStream.close();
                dos.flush();
                dos.close();

            } catch (MalformedURLException ex) {

                dialog.dismiss();
                ex.printStackTrace();

                runOnUiThread(new Runnable() {
                    public void run() {
                        messageText.setText("MalformedURLException Exception : check script url.");
                        Toast.makeText(EnviaFoto.this, "MalformedURLException",
                                Toast.LENGTH_SHORT).show();
                    }
                });

                Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
            } catch (Exception e) {

                dialog.dismiss();
                e.printStackTrace();

                runOnUiThread(new Runnable() {
                    public void run() {
                        messageText.setText("Got Exception : see logcat ");
                        Toast.makeText(EnviaFoto.this, "Got Exception : see logcat ",
                                Toast.LENGTH_SHORT).show();
                    }
                });
                Log.e("Upload file to server Exception", "Exception : "
                        + e.getMessage(), e);
            }
            dialog.dismiss();
            return serverResponseCode;

        } // End else block
    }

    private void addListeners(){

        selectImage.setOnClickListener(new View.OnClickListener(){
            public void onClick(View view){
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                Intent chooser = Intent.createChooser(intent,"Escolha a foto");
                intent.setType("image/*");
                try {
                    startActivityForResult(chooser, PICK_FILE_RESULT_CODE );
                }catch (ActivityNotFoundException e){
                    Log.e("tag", e.getMessage());
                }
            }
        });

        uploadButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                dialog = ProgressDialog.show(EnviaFoto.this, "", "Enviando foto...", true);

                new Thread(new Runnable() {
                    public String uriToPath(Uri uri) {
                        String[] projection = { MediaStore.Images.Media.DATA };
                        Cursor cursor = managedQuery(uri, projection, null, null, null);
                        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                        cursor.moveToFirst();
                        return cursor.getString(column_index);
                    }


                    protected void onActivityResult (int requestCode, int resultCode, Intent data){
                        if (data != null && requestCode == PICK_FILE_RESULT_CODE){

                            filePath = uriToPath(data.getData());
                            imgFoto.setImageURI(data.getData());
                            uploadButton.setVisibility(1);

                        }
                    } public void run() {
                        runOnUiThread(new Runnable() {
                            public void run() {
                                messageText.setText("Enviando foto...");
                            }
                        });

                        uploadFile(filePath);

                    }
                }).start();
            }
        });

        btnTiraFoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE), CAMERA_IMAGE);
            }
        });


    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.envia_foto, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

Manifest

显现

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="br.gov.rj.barraemexposicao" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="br.gov.rj.barraemexposicao.EnviaFoto"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="br.gov.rj.barraemexposicao.Enquete"
            android:label="@string/title_activity_enquete" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

LogCat

日志猫

07-04 08:46:54.084  13565-13565/br.gov.rj.barraemexposicao I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018_msm8226_LNX.LA.3.5.1_RB1__release_AU ()
    OpenGL ES Shader Compiler Version: E031.24.00.08
    Build Date: 03/07/14 Fri
    Local Branch:
    Remote Branch: quic/LNX.LA.3.5.1_RB1.1
    Local Patches: NONE
    Reconstruct Branch: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018 + f2fd134 +  NOTHING
07-04 08:46:54.157  13565-13565/br.gov.rj.barraemexposicao D/OpenGLRenderer﹕ Enabling debug mode 0
07-04 08:47:03.105  13565-13565/br.gov.rj.barraemexposicao D/AndroidRuntime﹕ Shutting down VM
07-04 08:47:03.121  13565-13565/br.gov.rj.barraemexposicao E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: br.gov.rj.barraemexposicao, PID: 13565
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { act=inline-data (has extras) }} to activity {br.gov.rj.barraemexposicao/br.gov.rj.barraemexposicao.EnviaFoto}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3432)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3475)
            at android.app.ActivityThread.access00(ActivityThread.java:139)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
            at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1420)
            at android.content.ContentResolver.query(ContentResolver.java:445)
            at android.content.ContentResolver.query(ContentResolver.java:404)
            at br.gov.rj.barraemexposicao.EnviaFoto.uriToPath(EnviaFoto.java:80)
            at br.gov.rj.barraemexposicao.EnviaFoto.onActivityResult(EnviaFoto.java:97)
            at android.app.Activity.dispatchActivityResult(Activity.java:5446)
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3428)
????????????at android.app.ActivityThread.handleSendResult(ActivityThread.java:3475)
????????????at android.app.ActivityThread.access00(ActivityThread.java:139)
????????????at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258)
????????????at android.os.Handler.dispatchMessage(Handler.java:102)
????????????at android.os.Looper.loop(Looper.java:136)
????????????at android.app.ActivityThread.main(ActivityThread.java:5086)
????????????at java.lang.reflect.Method.invoke(Native Method)
????????????at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
????????????at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
07-04 08:47:05.066  13565-13565/br.gov.rj.barraemexposicao I/Process﹕ Sending signal. PID: 13565 SIG: 9
07-04 08:51:33.298  15518-15518/br.gov.rj.barraemexposicao I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018_msm8226_LNX.LA.3.5.1_RB1__release_AU ()
    OpenGL ES Shader Compiler Version: E031.24.00.08
    Build Date: 03/07/14 Fri
    Local Branch:
    Remote Branch: quic/LNX.LA.3.5.1_RB1.1
    Local Patches: NONE
    Reconstruct Branch: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018 + f2fd134 +  NOTHING
07-04 08:51:33.393  15518-15518/br.gov.rj.barraemexposicao D/OpenGLRenderer﹕ Enabling debug mode 0
07-04 08:52:08.015  15518-15530/br.gov.rj.barraemexposicao W/CursorWrapperInner﹕ Cursor finalized without prior close()
07-04 08:52:10.068  15518-16522/br.gov.rj.barraemexposicao E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-34287
    Process: br.gov.rj.barraemexposicao, PID: 15518
    java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
            at java.io.File.fixSlashes(File.java:185)
            at java.io.File.<init>(File.java:134)
            at br.gov.rj.barraemexposicao.EnviaFoto.uploadFile(EnviaFoto.java:102)
            at br.gov.rj.barraemexposicao.EnviaFoto.run(EnviaFoto.java:277)
            at java.lang.Thread.run(Thread.java:811)
07-04 08:52:10.815  15518-15518/br.gov.rj.barraemexposicao E/WindowManager﹕ android.view.WindowLeaked: Activity br.gov.rj.barraemexposicao.EnviaFoto has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{65280820 V.E..... R......D 0,0-684,192} that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:359)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at android.app.Dialog.show(Dialog.java:286)
            at android.app.ProgressDialog.show(ProgressDialog.java:116)
            at android.app.ProgressDialog.show(ProgressDialog.java:99)
            at br.gov.rj.barraemexposicao.EnviaFoto.onClick(EnviaFoto.java:250)
            at android.view.View.performClick(View.java:4456)
            at android.view.View$PerformClick.run(View.java:18465)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
07-04 09:03:23.546  18083-18083/br.gov.rj.barraemexposicao I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018_msm8226_LNX.LA.3.5.1_RB1__release_AU ()
    OpenGL ES Shader Compiler Version: E031.24.00.08
    Build Date: 03/07/14 Fri
    Local Branch:
    Remote Branch: quic/LNX.LA.3.5.1_RB1.1
    Local Patches: NONE
    Reconstruct Branch: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018 + f2fd134 +  NOTHING
07-04 09:03:23.614  18083-18083/br.gov.rj.barraemexposicao D/OpenGLRenderer﹕ Enabling debug mode 0
07-04 09:04:14.226  18083-18096/br.gov.rj.barraemexposicao W/CursorWrapperInner﹕ Cursor finalized without prior close()
07-04 09:04:14.428  18083-18083/br.gov.rj.barraemexposicao I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018_msm8226_LNX.LA.3.5.1_RB1__release_AU ()
    OpenGL ES Shader Compiler Version: E031.24.00.08
    Build Date: 03/07/14 Fri
    Local Branch:
    Remote Branch: quic/LNX.LA.3.5.1_RB1.1
    Local Patches: NONE
    Reconstruct Branch: AU_LINUX_ANDROID_LNX.LA.3.5.1_RB1.04.04.02.048.018 + f2fd134 +  NOTHING
07-04 09:04:17.318  18083-19131/br.gov.rj.barraemexposicao E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-34498
    Process: br.gov.rj.barraemexposicao, PID: 18083
    java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference
            at java.io.File.fixSlashes(File.java:185)
            at java.io.File.<init>(File.java:134)
            at br.gov.rj.barraemexposicao.EnviaFoto.uploadFile(EnviaFoto.java:100)
            at br.gov.rj.barraemexposicao.EnviaFoto.run(EnviaFoto.java:275)
            at java.lang.Thread.run(Thread.java:811)
07-04 09:04:18.179  18083-18083/br.gov.rj.barraemexposicao E/WindowManager﹕ android.view.WindowLeaked: Activity br.gov.rj.barraemexposicao.EnviaFoto has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{65280100 V.E..... R......D 0,0-684,192} that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:359)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at android.app.Dialog.show(Dialog.java:286)
            at android.app.ProgressDialog.show(ProgressDialog.java:116)
            at android.app.ProgressDialog.show(ProgressDialog.java:99)
            at br.gov.rj.barraemexposicao.EnviaFoto.onClick(EnviaFoto.java:248)
            at android.view.View.performClick(View.java:4456)
            at android.view.View$PerformClick.run(View.java:18465)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)

Updated after Instance Dialog

实例对话框后更新

07-04 09:54:17.341 26763-26763/br.gov.rj.barraemexposicao D/AndroidRuntime﹕ Shutting down VM 07-04 09:54:17.364 26763-26763/br.gov.rj.barraemexposicao E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: br.gov.rj.barraemexposicao, PID: 26763 java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{br.gov.rj.barraemexposicao/br.gov.rj.barraemexposicao.EnviaFoto}: java.lang.InstantiationException: br.gov.rj.barraemexposicao.EnviaFoto at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2124) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257) at android.app.ActivityThread.access0(ActivityThread.java:139) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5086) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) Caused by: java.lang.InstantiationException: br.gov.rj.barraemexposicao.EnviaFoto at java.lang.Class.newInstance(Class.java:1561) at android.app.Instrumentation.newActivity(Instrumentation.java:1084) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2115) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257) at android.app.ActivityThread.access0(ActivityThread.java:139) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5086) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)

采纳答案by Arun Badole

Okay, regarding this exception

好的,关于这个例外

java.lang.NullPointerException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference

You might get this exception while using Photosapp, but not quite often in Galleryapp. This might be important to know because in Android's latest version 5.0 Lollipop, they have removed Galleryapp now they have Photosapp only (Different vendors may have their own other in-built apps for photos & of course user can use any external apps also)

您在使用照片应用程序时可能会遇到此异常,但在图库应用程序中并不常见。这可能很重要,因为在 Android 的最新版本 5.0 Lollipop 中,他们删除了Gallery应用程序,现在他们只有照片应用程序(不同的供应商可能有自己的其他内置照片应用程序,当然用户也可以使用任何外部应用程序)

And because of this you are getting `filePath = null'. Now the question is why is it null?.

正因为如此,你得到了`filePath = null'。现在的问题是为什么它是空的?.

So there may be two reasons..

所以可能有两个原因..

1st is your uriToPath(Uri uri)method is not working correctly & 2nd is your Uriwhich you are getting from data.getData()is not correct.

第一个是您的uriToPath(Uri uri)方法工作不正常,第二个是您Uri从中获得的data.getData()方法不正确。

Your uriToPath(Uri uri)method seems to be correct, so the problem is in your Uri. You might have noticed that if you are fetching images from Galleryapp, there are less chances that you are getting nullin filePath, but if you are using Photosapp the chances increase.

您的uriToPath(Uri uri)方法似乎是正确的,所以问题出在您的Uri. 您可能已经注意到,如果从获取的图像的应用程序,还有机会少,你得到nullfilePath,但如果你正在使用照片应用程序中的机会增加。

It happens because your Photosapp shows photos which may not be on your local device, these photos are actually on the Google server. So when you ask for Uriby selecting a photo, it gives the Uriwhich is linked to that server.

发生这种情况是因为您的照片应用显示的照片可能不在您的本地设备上,而这些照片实际上在 Google 服务器上。因此,当您Uri通过选择照片来请求时,它会提供链接到该服务器的Uri

The Uri might be like this content://com.google.android.apps.photos.content/0/https%3A%2F%2Flh3.googleusercontent.com%2FL-3Jm0TaSqnuKkitli5mK0-d

Uri 可能是这样的 content://com.google.android.apps.photos.content/0/https%3A%2F%2Flh3.googleusercontent.com%2FL-3Jm0TaSqnuKkitli5mK0-d

& its not of your local device. Local device's Uriwill be like this

&它不是您的本地设备。本地设备的Uri将是这样的

content://media/external/images/media/49518

content://media/external/images/media/49518

Because of this difference your uriToPath(Uri uri)is returning null.

由于这种差异,您uriToPath(Uri uri)正在返回null.

So check the Urifirst & accordingly fetch image from local device or server.

因此,请检查第Uri一个并相应地从本地设备或服务器获取图像。

You can use DocumentsProvider APIso you won't have to worry about the local & server's files.

您可以使用DocumentsProvider API,这样您就不必担心本地和服务器的文件。

private Bitmap getBitmapFromUri(Uri uri) throws IOException {
        ParcelFileDescriptor parcelFileDescriptor =
             getContentResolver().openFileDescriptor(uri, "r");
        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
        Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
        parcelFileDescriptor.close();
        return image;
}

But if you have some local photos in Photosapp then on selecting those you will get the local Uri, which will give you the correct file path.

但是,如果您在照片应用程序中有一些本地照片,那么在选择这些照片时,您将获得本地Uri,这将为您提供正确的文件路径。

You can also download the photos (which are on Google server) in Photosapp itself & later use it.

您还可以在“照片”应用程序本身中下载照片(位于 Google 服务器上)并稍后使用。

回答by Ahmad Arslan

Use this below method in onActivityResult it surley work on every device.

在 onActivityResult 中使用以下方法,它可以在每个设备上工作。

Uri selectedImageUri  =null;
try {
                            Path = data.getExtras().getString("dataImg");

                        } catch (Exception e) {
                        }
                        try {
                            if (Path == null) {

                                Path = data.getData().toString();
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        try {
                            if (Path == null) {
                                Path = data.getExtras().getString("data");
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        try {
                            if (Path == null) {
                                Uri newPhotoUri = null;
                                newPhotoUri = data.getData();
                                String[] projection = { MediaStore.Images.Media.DATA };
                                CursorLoader loader = new CursorLoader(this,
                                        newPhotoUri, projection, null, null,
                                        null);
                                Cursor cursor = loader.loadInBackground();

                                int column_index_data = cursor
                                        .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                                cursor.moveToFirst();
                                Path = cursor.getString(column_index_data);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        try {

                            if (Path == null) {
                                selectedImageUri = data.getData();
                                if (selectedImageUri == null) {
                                    Bitmap photo = (Bitmap) data.getExtras()
                                            .get("data");
                                    selectedImageUri = getImageUri(
                                            Survey_Elabel.this, photo);
                                }

                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

Method used for getting URI.

用于获取 URI 的方法。

public Uri getImageUri(Context inContext, Bitmap inImage) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}

回答by arun-r

You can try this code, for api > 19 the retrieving image differs

您可以尝试此代码,对于 api > 19 检索图像不同

       txtlogochange.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view) {
                   Intent intent = new Intent();
                   intent.setType("image/*");
                   intent.setAction(Intent.ACTION_GET_CONTENT);
                   startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1);
               }
           });

   @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == this.RESULT_OK) {
            if (requestCode == 1) {
                if (Build.VERSION.SDK_INT < 19) {
                    Uri selectedImage = data.getData();
                    // System.out.println("selectedImage "+selectedImage);
                    String[] filePathColumn = {MediaStore.Images.Media.DATA};
                    Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
                    cursor.moveToFirst();
                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    smallImagePath = cursor.getString(columnIndex);
                    cursor.close();
                    System.out.println("smallImagePath" + smallImagePath);
                    logoImg.setImageBitmap(BitmapFactory.decodeFile(smallImagePath));
                    encodeImage();
                }
                else {
                    try {
                        InputStream imInputStream = getContentResolver().openInputStream(data.getData());
                        Bitmap bitmap = BitmapFactory.decodeStream(imInputStream);
                        smallImagePath = saveGalaryImageOnLitkat(bitmap);
                        logoImg.setImageBitmap(BitmapFactory.decodeFile(smallImagePath));
                        encodeImage();
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                    // finishAndSetResult(RESULT_OK, picturePath, false);
                }
            }
        }
    }
    private File temp_path;
    private final int COMPRESS = 100;
    private String saveGalaryImageOnLitkat(Bitmap bitmap) {
        try {
            File cacheDir;
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
                cacheDir = new File(Environment.getExternalStorageDirectory(), getResources().getString(R.string.app_name));
            else
                cacheDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            if (!cacheDir.exists())
                cacheDir.mkdirs();
            String filename = System.currentTimeMillis() + ".jpg";
            File file = new File(cacheDir, filename);
            temp_path = file.getAbsoluteFile();
            // if(!file.exists())
            file.createNewFile();
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, COMPRESS, out);
            return file.getAbsolutePath();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

回答by Saifullah al Mujahid

When moving from activity to camera app, onSaveInstanceState is not called, we have to save our image path / Uri to onPause() method by sharedPreference. On restoreInstanceState method we have to retrieved our image path from shared preference.

当从 Activity 移动到相机应用程序时,不会调用 onSaveInstanceState,我们必须通过 sharedPreference 将我们的图像路径 / Uri 保存到 onPause() 方法。在 restoreInstanceState 方法中,我们必须从共享首选项中检索我们的图像路径。