问题描述
我有一个android应用程序,允许用户创建,下载和共享图像,视频等内容。
最近,我提供了API版本29的更新,它在下载和共享文件时导致我的应用崩溃太多。他们大多数都像
致命异常:java.lang.NullPointerException尝试在null上调用虚拟方法'java.lang.String android.net.Uri.toString()' 对象引用
致命异常:java.lang.NullPointerException尝试调用 虚拟方法'java.lang.String java.io.File.getAbsolutePath()' 空对象引用
我总共使用两个类来下载和共享文件,一个是用Java编写的,另一个是用kotlin编写的,所以基本上我得到了文件的URL并将其传递给下载程序任务,然后共享URI /下载后的位图从那里共享到我的ShareUtil类中。
下面是我开始下载任务的代码:
if (!UserStatus.isstoragePermissionGranted(DetailImageNew.this)) {
checkPermission();
} else if (!UserStatus.isNetworkConnected(DetailImageNew.this)) {
Toasty.warning(DetailImageNew.this.getApplicationContext(),DetailImageNew.this.getResources().getString(R.string.downloadingoffline),Toast.LENGTH_SHORT,true).show();
mainImage.setDrawingCacheEnabled(true);
Bitmap scaledBitmap = mainImage.getDrawingCache();
other = 1;
ShareUtil.shareImage(scaledBitmap,DetailImageNew.this,catshare);
} else {
if (!maindownloading) {
maindownloading = true;
MyDownloadTask.DownloadListener downloadListener = new MyDownloadTask.DownloadListener() {
@Override
public void status(boolean downloading) {
((Activity) DetailImageNew.this).runOnUiThread(new Runnable() {
public void run() {
if (downloading) {
relative_layout_progress_fragement_video.setVisibility(View.VISIBLE);
} else {
relative_layout_progress_fragement_video.setVisibility(View.GONE);
}
}
});
}
@Override
public void downlodedFile(@NotNull File file) {
sharefile = file;
DetailImageNew.this.sendbroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,Uri.fromFile(sharefile)));
}
@Override
public void onDownloadComplete(boolean download,int pos) {
maindownloading = false;
other = 1;
ShareUtil.share(DetailImageNew.this,sharefile,catshare);
Toasty.success(getApplicationContext(),getResources().getString(R.string.images_downloaded),true).show();
}
@Override
public void downloadProgress(int status) {
((Activity) DetailImageNew.this).runOnUiThread(new Runnable() {
public void run() {
progress_bar_fragement_video.setProgress(status);
text_view_progress_fragement_video.setText(DetailImageNew.this.getResources().getString(R.string.downloading) + " " + status + " %");
}
});
}
};
String basename = FilenameUtils.getName(statusRead.getStatus());
new MyDownloadTask(DetailImageNew.this,statusRead.getStatus(),basename,1,downloadListener).execute(true);
} else {
Toasty.warning(DetailImageNew.this.getApplicationContext(),true).show();
}
}
所以在这里我使用MyDownloadTask kotlin类(MyDownloadTask的代码如下)共享文件:
class MyDownloadTask ( @SuppressLint("StaticFieldLeak") val context: Context,val yourUrl: String,val fileName: String,val position: Int,val listener: DownloadListener
) : AsyncTask<Boolean,Void,Boolean>() {
override fun doInBackground(vararg booleans: Boolean?): Boolean {
var lenghtOfFile: Long = 0
var status = 0
val client = OkHttpClient()
val request = Request.Builder()
.url(yourUrl)
.build()
var response: Response? = null
try {
response = client.newCall(request).execute()
} catch (e: IOException) {
e.printstacktrace()
}
val inputStream: InputStream
try {
lenghtOfFile = response!!.body!!.contentLength()
} catch (e: Exception) {
}
try {
assert(response!!.body != null)
inputStream = response!!.body!!.byteStream()
val buff = ByteArray(1024 * 4)
var downloaded: Long = 0
val folder =
File(Environment.getExternalStorageDirectory().toString() + "/APPNAME/")
if (!folder.exists()) {
folder.mkdir()
}
val documentFile = File("$folder/$fileName")
documentFile.parentFile.mkdirs()
try {
documentFile.createNewFile()
} catch (e: IOException) {
e.printstacktrace()
}
var output: OutputStream? = null
try {
output = FileOutputStream(documentFile,false)
} catch (e: FileNotFoundException) {
e.printstacktrace()
}
while (true) {
val readed = inputStream.read(buff)
if (readed == -1) {
break
}
if (isCancelled) {
break
}
downloaded += readed.toLong()
status = (downloaded * 100 / lenghtOfFile).toInt()
listener.downloadProgress(status)
output!!.write(buff,readed)
}
output!!.flush()
val file: File
listener.downlodedFile(documentFile)
listener.status(false)
output.close()
return true
} catch (e: Exception) {
e.printstacktrace()
return false
}
}
override fun onPreExecute() {
super.onPreExecute()
listener.status(true)
}
override fun onProgressUpdate(vararg values: Void) {
super.onProgressUpdate(*values)
}
override fun onPostExecute(objects: Boolean?) {
super.onPostExecute(objects)
if (objects!!) {
listener.onDownloadComplete(true,position)
} else {
listener.onDownloadComplete(false,position)
}
}
override fun onCancelled(aBoolean: Boolean?) {
super.onCancelled(aBoolean)
val folder = File(Environment.getExternalStorageDirectory().toString() + "/APPNAME/")
val documentFile = File("$folder/$fileName")
documentFile.delete()
}
override fun onCancelled() {
super.onCancelled()
}
public interface DownloadListener {
fun onDownloadComplete(download: Boolean,pos: Int)
fun downloadProgress(status: Int)
fun downlodedFile(file: File)
fun status(state: Boolean)
}
}
文件下载完成后,我以以下方式将文件共享到我的ShareUtil类:
public static void share(Context context,File file,String catshare) {
Bitmap image = BitmapFactory.decodeFile(file.getAbsolutePath());
shareImage(image,context,catshare);
}
public static String shareImage(Bitmap image,Context mContext,String shareurl) {
Bitmap picture = BitmapFactory.decodeResource(mContext.getResources(),R.mipmap.ic_launcher);
image = overlayCustom(image,mContext,0);
String savedImagePath = null;
Uri bmpuri = null;
String imageFileName = "EHS_" + new Date().getTime() + ".jpg";
File storageDir = new File(
Environment.getExternalStorageDirectory().getAbsolutePath() + "/APPNAME");
boolean success = true;
if (!storageDir.exists()) {
success = storageDir.mkdirs();
}
if (success) {
File imageFile = new File(storageDir,imageFileName);
savedImagePath = imageFile.getAbsolutePath();
try {
OutputStream fOut = new FileOutputStream(imageFile);
image.compress(Bitmap.CompressFormat.JPEG,100,fOut);
fOut.close();
bmpuri = FileProvider.getUriForFile(mContext,BuildConfig.APPLICATION_ID,imageFile);
} catch (Exception e) {
e.printstacktrace();
}
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TEXT,"" + "" +
"\n\n" + UserStatus.getConfig(mContext).getSharestring() + " :- " + shareurl);
shareIntent.putExtra(Intent.EXTRA_STREAM,bmpuri);
shareIntent.setType("image/*");
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
mContext.startActivity(Intent.createChooser(shareIntent,"APPNAME"));
}
return savedImagePath;
}
public static Bitmap overlayCustom(Bitmap bmp1,Context context,int ci,int what) {
String appname = "";
if (what == 0)
appname = context.getResources().getString(R.string.kanmani);
else
appname = context.getResources().getString(R.string.kanmani);
Bitmap picture = BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_launcher_white);
bmp1 = overlayBitmapToBottom(bmp1,picture,bmp1.getConfig(),appname);
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(),bmp1.getHeight(),bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1,new Matrix(),null);
return bmOverlay;
}
public static String shareImage(Bitmap image,"APPNAME"));
}
return savedImagePath;
}
我已经遵循了Android Q的文件共享指南,例如:
同一版本在少于10(Q)的Android版本上也会发生多次错误。
虽然进行测试,但我根本没有遇到这些错误,但是无论如何这些错误都会产生,并且最终无法重现。
请帮助我,因为这些错误在我的生产版本中导致太多崩溃。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)