抛出NullPointer异常的FileProvider.getUriForFile上下文

时间:2018-11-06 17:08:59

标签: java android android-fileprovider

我从FileProvider.getUriForFile收到以下错误消息

  

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'android.content.res.Resources android.content.Context.getResource()'

但是,当我显示context.toString()时,我得到了这个(我认为)证明该对象不是null:

  

uk.co.letsdelight.letsdelight.MainActivity@8eec139

该代码将Completed download of update file写入logcat,但未在API 24设备上写入URI successfully set。它适用于API23。这是代码的重要部分。 Update类是通过MainActivitynew Update(status, message).check(this);调用的

public class Update extends Activity {

    private File outputFile;
    private TextView status;
    private TextView message;
    private String TAG = "LETSDELIGHT";

    public Update(TextView status){
        this.status = status;
    }
    public Update(TextView status, TextView message){
        this.status  = status;
        this.message = message;
    }

    public void check(final Context c) {
        status.setText("Checking for updates");

        // Check for updates and give user option to update

            // UPDATE button pressed
            UpdateApp updateApp = new UpdateApp();
            updateApp.setContext(c);
            updateApp.execute(c.getString(R.string.apk_uri));
            status.setText("Downloading update");
    }

    public class UpdateApp extends AsyncTask<String,Void,Void> {
        private Context context;
        private Throwable thrown = null;
        private String statusMessage;
        public void setContext(Context contextf){
            context = contextf;
        }

        @Override
        protected Void doInBackground(String... arg0) {
            try {
                URL url = new URL(arg0[0]);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setDoOutput(true);
                conn.connect();

                Log.i(TAG,"Starting download of update file");
                statusMessage = "Starting download of update file";

                File file = context.getCacheDir();
                file.mkdirs();
                outputFile = new File(file, "update.apk");
                if(outputFile.exists()){
                    outputFile.delete();
                }
                FileOutputStream fos = new FileOutputStream(outputFile);

                InputStream is = conn.getInputStream();

                byte[] buffer = new byte[1024];
                int len1 = 0;
                while ((len1 = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, len1);
                }
                fos.close();
                is.close();
                outputFile.setReadable(true, false);

                Log.i(TAG, "Completed download of update file");
                statusMessage = "Completed download of update file";

                Uri uri;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    uri = FileProvider.getUriForFile(context, getString(R.string.file_provider_authority), outputFile);
                } else {
                    uri = Uri.fromFile(outputFile);
                }

                Log.i(TAG, "URI successfully set");
                statusMessage = "URI successfully set";

                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "application/vnd.android.package-archive");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);

            } catch (Throwable ex) {
                Log.e(TAG, ex.toString());
                thrown = ex;
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void v) {
            status.setText("");
            if (statusMessage != null) {
                status.setText(statusMessage);
            }
            if (thrown != null) {
                status.setText(context.toString());
                message.setText(thrown.toString());
            }
            outputFile.delete();
            super.onPostExecute(v);
        }
    }
}

AndroidManifest.xml文件包含以下条目:

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="@strings/file_provider_authority"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_paths" />
    </provider>

file_provider_paths.xml看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <cache-path name="cache" path="."/>
</paths>

我尝试将context更改为getApplication()getApplicationContext()两者都导致生成NullPointerException,但资源措辞略有不同。

我还能尝试解决什么问题?

编辑:

我修改了代码以尝试探究问题的根源:

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                statusMessage = "Context is: " + context.getString(R.string.file_provider_authority);
                uri = FileProvider.getUriForFile(context, context.getString(R.string.file_provider_authority), outputFile);
                statusMessage = "uri set";
            } else {
                uri = Uri.fromFile(outputFile);
            }

statusMessage已设置为显示正确的提供者授权字符串。它不会设置为“ uri set”。因此,肯定是FileProvider.getUriForFile()失败了。

假设context不为null,并且Authority是正确的字符串,那么还有什么可能在这里引发错误?

1 个答案:

答案 0 :(得分:0)

您正在尝试在非活动类中调用getString尝试替换

getString(R.string.file_provider_authority)

使用

context.getString(R.string.file_provider_authority)

edit:我看到您正在扩展Update类中的活动,您是否在清单中声明了它?如果您已经传递了上下文,为什么还要扩展活动?