问题描述
我知道互联网上有无数这样的示例,但是由于某些原因,尽管我已经阅读了所有资源/答案,但我无法使其在我正在处理的特定代码中起作用。而且我周围没有任何具有Java技能的人可以提供帮助。希望这里有所改变。
我正在更新现有的Android媒体选择器插件(用于cordova应用程序),以使其除了显示设备库中的图片外,还显示视频缩略图。我遇到了“静态上下文中的非静态变量”错误,但是我很难确定需要更改的内容。以下是我所拥有的代码。我删除了一些部分,希望将重点放在相关部分上。本质上,当我尝试获取视频缩略图时,错误发生在decodeSampledBitmapFromUri
内部。我使用的方法是MediaStore.Video.Thumbnails.getThumbnail
,它的第一个参数是上下文,这是错误开始的地方。您可以看到,在loadThumbnail
中,我尝试使用cordova.getActivity()
获取上下文,然后将其传递给decodeSampledBitmapFromUri
,但是即使在loadThumbnail
内,我仍然遇到非静态错误。我不确定如何从这里开始(我对Java非常陌生)。这是代码(删除了其他部分,因为我认为它们不相关):
public class MediaPicker extends CordovaPlugin {
private static final String HEIGHT = "height";
private static final String COLUMNS = "columns";
private static final String SELECTION_LIMIT = "selectionLimit";
private MediaPickerView view;
public static int getResourceId(Context context,String group,String key) {
return context.getResources().getIdentifier(key,group,context.getPackageName());
}
public static int DP2PX(Context context,float dipValue) {
displayMetrics metrics = context.getResources().getdisplayMetrics();
return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dipValue,metrics);
}
@Override
public void initialize(CordovaInterface cordova,CordovaWebView webView) {
super.initialize(cordova,webView);
}
@Override
public boolean execute(String action,JSONArray data,CallbackContext callbackContext) throws JSONException {
if (action.equals("display")) {
JSONObject store = data.getJSONObject(0);
double height = Double.parseDouble(store.getString(HEIGHT));
int columns = Integer.parseInt(store.getString(COLUMNS));
int selectionLimit = Integer.parseInt(store.getString(SELECTION_LIMIT));
display(height,columns,selectionLimit,callbackContext);
return true;
} else {
return false;
}
}
private void display(final double height,final int columns,final int selectionLimit,final CallbackContext callbackContext) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (view == null) {
view = new MediaPickerView(cordova.getActivity());
}
view.setoptions(height,callbackContext);
view.load();
cordova.getActivity().addContentView(view,new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
}
});
}
public static class MediaPickerView extends FrameLayout implements StateController {
private GridView grid;
private View balanceView;
private int selectionLimit;
private CallbackContext callbackContext;
private TreeMap<Integer,PictureInfo> selection = new TreeMap();
public MediaPickerView(Context context) {
super(context);
init();
}
public MediaPickerView(Context context,AttributeSet attrs) {
super(context,attrs);
init();
}
private void init() {
LayoutInflater.from(getContext()).inflate(getResourceId(getContext(),"layout","view_media"),this);
grid = (GridView)findViewById(getResourceId(getContext(),"id","gridView"));
balanceView = findViewById(getResourceId(getContext(),"vBalancer"));
}
public void setoptions(double height,int columns,int selectionLimit,CallbackContext callbackContext) {
this.selectionLimit = selectionLimit;
this.callbackContext = callbackContext;
grid.setNumColumns(columns);
LinearLayout.LayoutParams glp = (LinearLayout.LayoutParams) grid.getLayoutParams();
glp.weight = (float) height;
LinearLayout.LayoutParams blp = (LinearLayout.LayoutParams) balanceView.getLayoutParams();
blp.weight = (float) (1 - height);
requestLayout();
}
public void load() {
final GridAdapter adapter = new GridAdapter(getContext(),this);
grid.setAdapter(adapter);
new Thread() {
@Override
public void run() {
final String[] columns = new String[]{
MediaStore.Video.VideoColumns._ID,MediaStore.Video.VideoColumns.DATA,MediaStore.Video.VideoColumns.BUCKET_disPLAY_NAME,MediaStore.Video.VideoColumns.disPLAY_NAME,MediaStore.Video.VideoColumns.DATE_TAKEN,MediaStore.Video.VideoColumns.MIME_TYPE,MediaStore.Files.FileColumns.MEDIA_TYPE};
final String orderBy = MediaStore.Video.VideoColumns.DATE_TAKEN
+ " DESC";
final String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
Uri queryUri = MediaStore.Files.getContentUri("external");
final Cursor cursor = getContext().getContentResolver().query(
queryUri,selection,// Which rows to return (all rows)
null,// Selection arguments (none)
orderBy);
if (cursor.movetoFirst()) {
adapter.setCursor(cursor);
}
}
}.start();
}
}
public static class MediaCache extends LruCache<String,Bitmap> {
public MediaCache(int maxSize) {
super(maxSize);
}
@Override
protected int sizeOf(String key,Bitmap value) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
return value.getAllocationByteCount();
}
return value.getByteCount();
}
}
public static class GridAdapter extends BaseAdapter implements AsyncPictureLoader{
private Cursor cursor;
private Executor executor = Executors.newFixedThreadPool(4);
private MediaCache pictureCache;
private int dataColumn;
private StateController stateController;
private ArrayList<PictureView> createdViews = new ArrayList<PictureView>();
public GridAdapter(Context context,StateController stateController) {
this.stateController = stateController;
int memClass = ( (ActivityManager)context.getSystemService( Context.ACTIVITY_SERVICE ) ).getMemoryClass();
int cacheSize = 1024 * 1024 * memClass / 10;
pictureCache = new MediaCache(cacheSize);
}
@Override
public int getCount() {
return cursor != null ? cursor.getCount() : 0;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position,View convertView,ViewGroup parent) {
PictureView view;
if (convertView != null) {
view = (PictureView) convertView;
} else {
view = new PictureView(pictureCache,parent.getContext(),this,stateController);
createdViews.add(view);
}
view.load(position);
return view;
}
public void setCursor(Cursor cursor) {
this.cursor = cursor;
dataColumn = cursor
.getColumnIndex(MediaStore.Video.VideoColumns.DATA);
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
}
@Override
public void loadThumbnail(final PictureInfo pictureInfo,final AsyncPictureLoaderCallback callback) {
if (cursor == null) {
return;
}
executor.execute(new Runnable() {
@Override
public void run() {
if (cursor == null || pictureInfo.cancelled) {
return;
}
synchronized (cursor) {
cursor.movetoPosition(pictureInfo.position);
pictureInfo.uri = cursor.getString(dataColumn);
}
if (pictureInfo.uri == null) {
return;
}
synchronized (pictureCache) {
Bitmap cachedBitmap = pictureCache.get(pictureInfo.uri);
if (cachedBitmap != null) {
pictureInfo.thumbnail = cachedBitmap;
callback.onLoad(pictureInfo);
return;
}
}
int thumbSideSize = callback.getThumbnailSideSize();
if (thumbSideSize <= 0) {
thumbSideSize = 128;
}
// the next 4 variables are needed for videos,see https://stackoverflow.com/a/29555484/7987987
int type = cursor.getColumnIndex(MediaStore.Files.FileColumns.MEDIA_TYPE);
int tInt = cursor.getInt(type);
int colId = cursor.getColumnIndex(MediaStore.Video.VideoColumns._ID);
int id = cursor.getInt(colId);
pictureInfo.thumbnail = decodeSampledBitmapFromUri(pictureInfo.uri,thumbSideSize,tInt,id,cordova.getActivity());
if (pictureInfo.thumbnail != null) {
callback.onLoad(pictureInfo);
synchronized (pictureCache) {
pictureCache.put(pictureInfo.uri,pictureInfo.thumbnail);
}
} else {
}
}
});
}
private Bitmap decodeSampledBitmapFromUri(String path,int reqWidth,int reqHeight,int typeInt,int id,Context context) {
Bitmap bm = null;
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
if (typeInt == 3) {
// this is a video,handle according to https://stackoverflow.com/a/29555484/7987987
// using BitmapFactory options as seen in the link above
options.inSampleSize = 4; // hardcoded for Now until this works,then I'll make it dynamic
options.inPurgeable = true;
bm = MediaStore.Video.Thumbnails.getThumbnail(
context.getContentResolver(),MediaStore.Video.Thumbnails.MINI_KIND,options);
} else {
// this is an image
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path,options);
// Calculate inSampleSize
options.inSampleSize = calculateSampleSize(options,reqWidth,reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(path,options);
}
return bm;
}
public int calculateSampleSize(BitmapFactory.Options options,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;
}
}
public interface AsyncPictureLoader {
void loadThumbnail(PictureInfo position,AsyncPictureLoaderCallback callback);
}
public interface AsyncPictureLoaderCallback {
void onLoad(PictureInfo picture);
int getThumbnailSideSize();
}
public interface StateController {
// stuff here that controls selection
}
public static class PictureInfo {
public int position;
public String uri;
public Bitmap thumbnail;
public volatile boolean cancelled = false;
}
public static class PictureView extends FrameLayout implements AsyncPictureLoaderCallback,CompoundButton.OnCheckedchangelistener {
private final AsyncPictureLoader loader;
private final CheckBox checkBox;
private final StateController stateController;
private final MediaCache pictureCache;
private ImageView vImage;
private PictureInfo pictureInfo;
public PictureView(MediaCache pictureCache,Context context,AsyncPictureLoader loader,StateController stateController) {
super(context);
this.pictureCache = pictureCache;
this.loader = loader;
this.stateController = stateController;
LayoutInflater.from(getContext()).inflate(getResourceId(getContext(),"view_media_item"),this);
vImage = (ImageView)findViewById(getResourceId(getContext(),"vImage"));
checkBox = (CheckBox)findViewById(getResourceId(getContext(),"checkBox"));
}
public void load(int position) {
if (pictureInfo != null) {
pictureInfo.cancelled = true;
}
pictureInfo = new PictureInfo();
pictureInfo.position = position;
pictureInfo.thumbnail = null;
pictureInfo.uri = null;
vImage.setimageResource(0);
vImage.setVisibility(INVISIBLE);
loader.loadThumbnail(pictureInfo,this);
updateSelection();
}
@Override
public void onLoad(PictureInfo picture) {
if (this.pictureInfo != picture) {
return;
}
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
vImage.setimageBitmap(pictureInfo.thumbnail);
vImage.setVisibility(VISIBLE);
}
});
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)