我是Android开发新手,当我从相机捕获图像时遇到问题,如果我刷新活动或重新加载它而不是出现在gridview中,它不会立即显示在gridview中。 我已经搜索了很多并实施了各种解决方案,但没有人为我工作,请提供建议,以下是我的代码。
我的xml文件如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/userHeader"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<include
android:layout_width="fill_parent"
android:layout_height="wrap_content"
layout="@layout/header_user" />
</RelativeLayout>
<TableLayout
android:layout_below="@id/userTable"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:stretchColumns="*" >
<TableRow android:id="@+id/historyDateRow">
<TextView android:text="@string/historyDateCaption" style="@style/captionStyle" />
<TextView android:id="@+id/viwHistoryDate" style="@style/captionStyle" />
</TableRow>
<TableRow android:id="@+id/historyUpdateDateRow">
<TextView android:text="@string/historyUpdateDateCaption" style="@style/captionStyle" />
<TextView android:id="@+id/viwHistoryUpdateDate" style="@style/captionStyle" />
</TableRow>
<TableRow android:layout_marginTop="2dp">
<TextView android:text="@string/historyCaption" style="@style/captionStyle" />
<TextView android:text="" style="@style/captionStyle" />
</TableRow>
<EditText
android:id="@+id/txtHistory"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginTop="5dp"
android:scrollbars="vertical"
android:gravity="top"
android:layout_marginRight="5dp" android:layout_marginLeft="5dp"
android:inputType="textMultiLine" />
<GridView
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:layout_weight="1"
android:gravity="center"/>
<Button android:id="@+id/btnSave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp" android:layout_marginLeft="5dp"
android:text="@string/save"/>
<Button android:id="@+id/btnCapture"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp" android:layout_marginLeft="5dp"
android:text="Capture"/>
</TableLayout>
</RelativeLayout>
在我的java文件中,我的代码如下:
String userId=null;
String historyId = null;
private Uri outputFileUri;
ImageAdapter myImageAdapter;
File root = null;
final String filesPath = Environment.getExternalStorageDirectory() + File.separator + "MyProj" + File.separator+ "Images" + File.separator;
private List<String> listOfImagesPath;
Boolean needsRefresh = false;
GridView gridview = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.casehistory);
GlobalVariables gv = ((GlobalVariables)getApplicationContext());
userId=gv.getsUserId();
historyId=getIntent().getStringExtra(ListHistory.ID_History);
gridview = (GridView) findViewById(R.id.gridview);
myImageAdapter = new ImageAdapter(this);
gridview.setAdapter(myImageAdapter);
String targetPath = "";
if(historyId == null)
{
targetPath = filesPath + userId + File.separator;
root = new File(filesPath + userId + File.separator);
}
else
{
targetPath = filesPath + userId + File.separator + historyId + File.separator;
root = new File(filesPath + userId + File.separator + historyId + File.separator);
gv.setsHistoryId(historyId);
}
root.mkdirs();
File targetDirector = new File(targetPath);
File[] files = targetDirector.listFiles();
if(files!=null)
{
for (File file : files){
myImageAdapter.add(file.getAbsolutePath());
}
}
Button btCapture=(Button)findViewById(R.id.btnCapture);
btCapture.setOnClickListener(onCapture);
}
比我在onCapture上:
private View.OnClickListener onCapture=new View.OnClickListener() {
public void onClick(View v) {
openImageIntent();
}
};
比我的openImageIntent为:
private void openImageIntent() {
// Determine Uri of camera image to save.
final String fname = "img_"+ System.currentTimeMillis() + ".jpg";
final File sdImageMainDirectory = new File(root, fname);
outputFileUri = Uri.fromFile(sdImageMainDirectory);
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for(ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
startActivityForResult(chooserIntent, 212);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
//CommonHelper.ShowErrorMessage("Result Code: " + String.valueOf(resultCode), CaseHistory.this);
if(resultCode == RESULT_OK)
{
//CommonHelper.ShowErrorMessage("Request Code: " + String.valueOf(requestCode), CaseHistory.this);
if(requestCode == 212)
{
final boolean isCamera;
if(data == null)
{
isCamera = true;
}
else
{
final String action = data.getAction();
if(action == null)
{
isCamera = false;
}
else
{
isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
}
}
Uri selectedImageUri;
if(isCamera)
{
selectedImageUri = outputFileUri;
}
else
{
selectedImageUri = data == null ? null : data.getData();
}
myImageAdapter.add(selectedImageUri.toString());
//GridView gridview = (GridView) findViewById(R.id.gridview);
//gridview.setAdapter(myImageAdapter);
myImageAdapter.notifyDataSetChanged();
gridview.invalidateViews();
gridview.setAdapter(myImageAdapter);
needsRefresh = true;
//CommonHelper.ShowErrorMessage("Image URI: " + selectedImageUri.toString(), CaseHistory.this);
//CommonHelper.ShowErrorMessage("Extra Data URI: " + data.getExtras().get("data"), CaseHistory.this);
}
}
}
最后我的Image适配器如下:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
ArrayList<String> itemList = new ArrayList<String>();
public ImageAdapter(Context c) {
mContext = c;
}
void add(String path){
itemList.add(path);
}
@Override
public int getCount() {
return itemList.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(220, 220));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
Bitmap bm = decodeSampledBitmapFromUri(itemList.get(position), 220, 220);
imageView.setImageBitmap(bm);
return imageView;
}
public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {
Bitmap bm = null;
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(path, options);
return bm;
}
public int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
}
过去几天我一直在努力奋斗,并且一直在尝试从网上获得不同的解决方案,但都是徒劳的。 任何人都可以帮助我吗?
谦虚的请求 这是我的第一个Android项目以及Java项目,所以如果有人有时间并希望反馈我编码的方式超过欢迎。
提前致谢。
答案 0 :(得分:1)
除了selectedImageUri.toString()
之外,一切似乎都没问题。
只需将selectedImageUri.toString()
替换为selectedImageUri.getPath()
,您应该做得很好。
当您在任何对象上调用toString()时,它将尝试做的是为您提供有关该对象的整体信息。在您调用URI上的toString()的情况下,它不会为您提供该文件的确切路径,而是会提供类似"file:///storage/emulated/0/MyProj/Images/111/222/img_1388856542838.jpg"
this的内容。因为它不是绝对文件路径,这就是为什么decodeFile无法工作你的适配器。另一方面,当您重新启动活动时,您正在使用getAbsolutePath()
处理绝对文件路径,这就是重启后它正常工作的原因。因此,要从URI对象获取路径,您必须调用getPath()。
答案 1 :(得分:1)
我在那里找到了一些useLess代码,只做其中一个,这可能是个问题
selectedImageUri.toString()
不会使用selectedImageUri.getPath()
myImageAdapter.notifyDataSetChanged(); // This will try to load your new Image
gridview.invalidateViews(); // then you are refreshing views and setting the adapter again below
gridview.setAdapter(myImageAdapter);
仅使用
myImageAdapter.notifyDataSetChanged();