我试图将图片上传到php,因为我需要将文件发送到服务器。所以我试图从data参数创建一个文件。
但我收到此错误Cannot resolve constructor File
这是我的代码:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
// Get the url from data
Uri selectedImageUri = data.getData();
if (null != selectedImageUri) {
// File
File imageFilePath = new File(selectedImageUri);
答案 0 :(得分:14)
适当的方法是getContentResolver().openInputStream(uri_of_your_file);
并使用FileOutputStream
到您想要的路径,然后使用该文件。
您可以使用ContentResolver和openInputStream()来获取 由Uri表示的内容上的InputStream。你可以创建一个 您控制的某个文件上的FileOutputStream。而且,您可以使用Java 要从InputStream复制到OutputStream的I / O,制作自己的 您控制的文件中的内容副本。
执行此操作的示例代码,
InputStream in = getContentResolver().openInputStream("your_uri_here");
OutputStream out = new FileOutputStream(new File("your_file_here"));
byte[] buf = new byte[1024];
int len;
while((len=in.read(buf))>0){
out.write(buf,0,len);
}
out.close();
in.close();
答案 1 :(得分:4)
@GeekDroid's答案是正确的,但我想我会提供更多信息以帮助澄清。
我创建了一个类,该类将在您的应用程序目录内复制/创建一个新文件。这是在后台线程上完成的,应该这样做。
我还创建了一个回调接口来获取“状态”并显示 $table->increments('id');
$table->integer('user_id')->unique()->unsigned();
$table->integer('store_id')->unique()->unsigned();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->foreign('store_id')
->references('id')
->on('storeinfos')
->onDelete('cascade');
$user=User::create($request->except(['store_id']));
} catch (\Exception $exception) {
logger()->error($exception);
return redirect()->back()->with('message', 'Unable to create new user.');
}
CatererUser::create([
'user_id' => $user->id,
'store_id' =>$request->input('store_id'),
]);
这里是接口(您可以将名称和回调更改为任何内容):
ProgressBar
这是复制文件的类:
interface CallBackTask {
void onCopyPreExecute();
void onCopyProgressUpdate(int progress);
void onCopyPostExecute(String path, boolean wasSuccessful, String reason);
}
在您的public class CopyFileAsyncTask extends AsyncTask<Uri, Integer, String> {
private Uri mUri;
private CallBackTask callback;
private WeakReference<Context> mContext;
private String pathPlusName;
private File folder;
private Cursor returnCursor;
private InputStream is = null;
private String errorReason = "";
DownloadAsyncTask(Uri uri, Context context, CallBackTask callback) {
this.mUri = uri;
mContext = new WeakReference<>(context);
this.callback = callback;
}
@Override
protected void onPreExecute() {
callback.onCopyPreExecute();
Context context = mContext.get();
if (context != null) {
folder = context.getExternalFilesDir("Temp");
returnCursor = context.getContentResolver().query(mUri, null, null, null, null);
try {
is = context.getContentResolver().openInputStream(mUri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
int post = values[0];
callback.onCopyProgressUpdate(post);
}
@Override
protected String doInBackground(Uri... params) {
File file = null;
int size = -1;
try {
try {
if (returnCursor != null && returnCursor.moveToFirst()){
if (mUri.getScheme() != null)
if (mUri.getScheme().equals("content")) {
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
size = (int) returnCursor.getLong(sizeIndex);
}else if (mUri.getScheme().equals("file")) {
File ff = new File(mUri.getPath());
size = (int) ff.length();
}
}
}
finally {
if (returnCursor != null)
returnCursor.close();
}
pathPlusName = folder + "/" + getFileName(mUri, mContext.get());
file = new File(folder + "/" + getFileName(mUri, mContext.get()));
BufferedInputStream bis = new BufferedInputStream(is);
FileOutputStream fos = new FileOutputStream(file);
byte[] data = new byte[1024];
long total = 0;
int count;
while ((count = bis.read(data)) != -1) {
if (!isCancelled()) {
total += count;
if (size != -1) {
publishProgress((int) ((total * 100) / size));
}
fos.write(data, 0, count);
}
}
fos.flush();
fos.close();
} catch (IOException e) {
errorReason = e.getMessage();
}
return file.getAbsolutePath();
}
private String getFileName(Uri uri, Context context) {
String result = null;
if (uri.getScheme() != null) {
if (uri.getScheme().equals("content")) {
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
if (cursor != null) {
cursor.close();
}
}
}
if (result == null) {
result = uri.getPath();
assert result != null;
int cut = result.lastIndexOf('/');
if (cut != -1) {
result = result.substring(cut + 1);
}
}
return result;
}
protected void onPostExecute(String result) {
if(result == null){
callback.onCopyPostExecute(pathPlusName, false, errorReason);
}else {
callback.onCopyPostExecute(pathPlusName, true, "");
}
}
}
中,您应该执行以下操作:
Activity
您可以随时通过以下方式取消文件的复制:
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class ExampleActivity extends AppCompatActivity implements CallBackTask{
Button someBtn;
Uri someUri = .... //This is just an example, you should provide your own Uri
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
someBtn = findViewById(R.id.someBtn);
someBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CopyFileAsyncTask asyntask = new CopyFileAsyncTask(someUri, ExampleActivity.this, ExampleActivity.this);
asyntask.execute();
}
});
}
ProgressBar mProgressBar;
TextView percentText;
private AlertDialog mdialog;
@Override
public void onCopyPreExecute() {
final AlertDialog.Builder mPro = new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.myDialog));
@SuppressLint("InflateParams") final View mPView = LayoutInflater.from(this).inflate(R.layout.dailog_layout, null);
percentText = mPView.findViewById(R.id.percentText);
mProgressBar = mPView.findViewById(R.id.mProgressBar);
mProgressBar.setMax(100);
mPro.setView(mPView);
mdialog = mPro.create();
mdialog.show();
}
@Override
public void onCopyProgressUpdate(int progress) {
String progressPlusPercent = progress + "%";
percentText.setText(progressPlusPercent);
mProgressBar.setProgress(progress);
}
@Override
public void onCopyPostExecute(String path, boolean wasSuccessful, String reason) {
if (mdialog != null && mdialog.isShowing()) {
mdialog.cancel();
}
if (wasSuccessful){
Toast.makeText(this, "File was created at - "+path, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "Error - "+reason, Toast.LENGTH_SHORT).show();
}
}
}
如果要完全按照我的方式实施它,并在复制文件时显示if (asyntask!=null){
asyntask.cancel(true);
}
,那么这是对话框的布局和样式:
ProgressBar
:
R.style.myDialog
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="myDialog" parent="Theme.AppCompat.Dialog.Alert">
<item name="android:windowNoTitle">true</item>
<item name="android:background">#fff</item>
<item name="android:windowBackground">@null</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
</resources>
:
R.layout.dailog_layout
在复制文件时,出现以下对话框:
结论:
使用上述方法,您的文件将被复制到<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/loadContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:padding="20dp">
<RelativeLayout
android:id="@+id/dotRel"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/percentText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="15dp"
android:text="0 %"
android:textColor="@android:color/black"
android:textSize="25sp" />
<ProgressBar
android:id="@+id/mProgressBar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_below="@+id/percentText"
android:progressDrawable="@drawable/progressbar" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
。复制文件时,将显示一个进度对话框,以百分比形式指示进度(这对于复制大文件很有用)。如果复制文件时出错,则将在/storage/emulated/0/Android/data/yourPackageName/files/Temp/YourFile.jpg
这将与文件和内容Uri一起使用。
答案 2 :(得分:1)
解决您问题的一线解决方案
File imageFile = new File(selectedImageUri.getPath());
你错过了
.getPath()
答案 3 :(得分:0)
您可以使用此功能从 uri 获取文件:
fun getFileFromUri(uri: Uri): File? {
if (uri.path == null) {
return null
}
var realPath = String()
val databaseUri: Uri
val selection: String?
val selectionArgs: Array<String>?
if (uri.path!!.contains("/document/image:")) {
databaseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
selection = "_id=?"
selectionArgs = arrayOf(DocumentsContract.getDocumentId(uri).split(":")[1])
} else {
databaseUri = uri
selection = null
selectionArgs = null
}
try {
val column = "_data"
val projection = arrayOf(column)
val cursor = context.contentResolver.query(
databaseUri,
projection,
selection,
selectionArgs,
null
)
cursor?.let {
if (it.moveToFirst()) {
val columnIndex = cursor.getColumnIndexOrThrow(column)
realPath = cursor.getString(columnIndex)
}
cursor.close()
}
} catch (e: Exception) {
Log.i("GetFileUri Exception:", e.message ?: "")
}
val path = if (realPath.isNotEmpty()) realPath else {
when {
uri.path!!.contains("/document/raw:") -> uri.path!!.replace(
"/document/raw:",
""
)
uri.path!!.contains("/document/primary:") -> uri.path!!.replace(
"/document/primary:",
"/storage/emulated/0/"
)
else -> return null
}
}
return File(path)
}
答案 4 :(得分:-3)
你可以试试这个;
try {
Uri uri = data.getData();
String selectedFilePath = FilePath.getPath(getActivity(), uri);
final File file = new File(selectedFilePath);
new UploadFileToServer().execute(file);
}
catch (Exception e)
{
e.printStackTrace();
}
并像这样定义FilePath
类;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
public class FilePath {
/**
* Method for return file path of Gallery image/ Document / Video / Audio
*
* @param context
* @param uri
* @return path of the selected image file from gallery
*/
public static String getPath(final Context context, final Uri uri) {
// check here to KITKAT or new version
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 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());
}
}