我需要扫描Android媒体商店中的图像文件夹路径,然后传递给另一个显示所选文件夹中图像的活动。我当前的代码完成了这项工作,但在某些图片路径和扩展程序(例如some image &%^$%*5.png
和some image.bin
)上崩溃了:
final String[] columns = {
MediaStore.Images.Media.DATA,
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME
};
final String orderBy = MediaStore.Images.Media.DISPLAY_NAME;
Cursor cursor = activity.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null,
null, orderBy);
mExternalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
mCount = cursor.getCount();
// mAbsolutePath is the absolute path (e.g. //emulated/0/folder/picture.png)
mAbsolutePath = new String[mCount];
mDisplayName = new String[mCount];
// mFolderIntentPath is what will eventually become the folder path (e.g. //emulated/0/folder/)
mFolderIntentPath = new String[mCount];
mBucket = new String[mCount];
for (int i = 0; i < this.mCount; i++) {
cursor.moveToPosition(i);
int absolutePathColumnIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
int displayNameColumnIndex = cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME);
int bucketColumnIndex = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
mAbsolutePath[i]= cursor.getString(absolutePathColumnIndex);
mDisplayName[i] = cursor.getString(displayNameColumnIndex);
mBucket[i] = cursor.getString(bucketColumnIndex);
mFolderIntentPath[i] = mAbsolutePath[i].substring(0, mAbsolutePath[i].length() - mDisplayName[i].length());
}
是否有更好的方法来获取图像文件夹路径?
编辑:这是logcat:
05-05 04:11:36.200 13580-13580/com.sinisa.eyesonly E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.StringIndexOutOfBoundsException: length=64; regionStart=20; regionLength=-1
at java.lang.String.startEndAndLength(String.java:583)
at java.lang.String.substring(String.java:1464)
at com.sinisa.eyesonly.gui.fragment.FragmentGallery.scanMediaStoreFolders(FragmentGallery.java:113)
at com.sinisa.eyesonly.gui.fragment.FragmentGallery.onCreateView(FragmentGallery.java:75)
at android.app.Fragment.performCreateView(Fragment.java:1695)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
at android.app.BackStackRecord.run(BackStackRecord.java:682)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
at android.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:474)
at android.support.v13.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:145)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1068)
at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1436)
at android.view.View.measure(View.java:15513)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4827)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:15513)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4827)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:15513)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4827)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2176)
at android.view.View.measure(View.java:15513)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1874)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1089)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1265)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
at android.view.Choreographer.doCallbacks(Choreographer.java:562)
at android.view.Choreographer.doFrame(Choreographer.java:532)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5039)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
05-05 04:11:36.216 387-669/? W/ActivityManager﹕ Force finishing activity com.sinisa.eyesonly/.gui.MainActivity
当我在Log.d
上拨打mDistinct
和mAbsolutePath
时,就像这样:
mAbsolutePath[i]= cursor.getString(absolutePathColumnIndex);
Log.d("bitmap","abs" + mAbsolutePath[i]);
mDisplayName[i] = cursor.getString(displayNameColumnIndex);
Log.d("bitmap","dis" + mDisplayName[i]);
我得到:
05-05 04:11:36.184 13580-13580/com.sinisa.eyesonly D/bitmap﹕ abs/storage/emulated/0/Snapchat/Snapchat-20140425090242.jpg
05-05 04:11:36.184 13580-13580/com.sinisa.eyesonly D/bitmap﹕ disSnapchat-20140425090242.jpg
05-05 04:11:36.184 13580-13580/com.sinisa.eyesonly D/bitmap﹕ abs/storage/emulated/0/Universal Image Loader @#&=+-_.,!()~'%20.png
05-05 04:11:36.184 13580-13580/com.sinisa.eyesonly D/bitmap﹕ disUniversal Image Loader @#&=+-_.,!()~'%20.png
答案 0 :(得分:1)
你的问题就在这一行:
mFolderIntentPath[i] = mAbsolutePath[i].substring(0, mAbsolutePath[i].length() - mDisplayName[i].length());
根据您获得的例外情况mDisplayName[i].length() > mAbsolutePath[i].length()
。我猜这是因为显示名称不是总是文件的名称。如果要删除基本名称以仅获取目录名称,您可能希望尝试获取以不同方式将其切断的索引,例如
mFolderIntentPath[i] = mAbsolutePath[i].substring(0, mAbsolutePath[i].lastIndexOf('/'));