2

在我的小部件中,我不断收到此错误:

11-02 09:35:10.613: D/D&D(1557): onCreate called
11-02 09:35:10.933: E/JavaBinder(1557): !!! FAILED BINDER TRANSACTION !!!
11-02 09:35:10.933: D/AppInfoAdapter(1557): top

无论我似乎在做什么(我尝试减小位图大小,使位图静态,注释掉我的部分编码以查看错误在哪里(顺便说一句,这根本没有帮助)),我总是得到这个错误。这个错误导致的是它使我的用户安装应用程序的列表视图根本没有显示在滑动抽屉中(它只是空白)。我所有的链接和其他课程都可以正常工作。(但我的 listView 是整个小部件的中心部分和主要功能。)

我现在不知所措,所以我只想发布我得出的结论是源于三个可疑课程(因为所有其他课程都可以正常工作)。

请注意,某些代码已被注释掉(例如拖放功能的编码,因为我的真实设备不支持蜂窝。但是,当我的 listView 再次开始工作时,我将实现该代码)

AppInfoAdapter.java:

package com.example.awesomefilebuilderwidget;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

public class AppInfoAdapter extends BaseAdapter implements Filterable {
private Context mContext;
private List<PackageInfo> mListAppInfo;
private PackageManager mPackManager;
private List<PackageInfo> originalListAppInfo;
private Filter filter;

public AppInfoAdapter(Context c, List<PackageInfo> listApp,
        PackageManager pm) {
    mContext = c;
    this.originalListAppInfo = this.mListAppInfo = listApp;
    mPackManager = pm;
    Log.d("AppInfoAdapter", "top");
}

@Override
public int getCount() {
    Log.d("AppInfoAdapter", "getCount()");
    return mListAppInfo.size();
}

@Override
public Object getItem(int position) {
    Log.d("AppInfoAdapter", "getItem");
    return mListAppInfo.get(position);
}

@Override
public long getItemId(int position) {
    Log.d("AppInfoAdapter", "getItemId");
    return position;
}

public static Bitmap scaleDownBitmap(Bitmap default_b, int newHeight, Context c) {

    final float densityMultiplier = c.getResources().getDisplayMetrics().density;

    int h= (int) (100*densityMultiplier);
    int w= (int) (h * default_b.getWidth()/((double) default_b.getHeight()));

    default_b=Bitmap.createScaledBitmap(default_b, w, h, true);
    // TO SOLVE LOOK AT HERE:https://stackoverflow.com/questions/15517176/passing-bitmap-to-other-activity-getting-message-on-logcat-failed-binder-transac
    return default_b;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    // get the selected entry
    final PackageInfo entry = (PackageInfo) mListAppInfo.get(position);

    // reference to convertView
    View v = convertView;

    // inflate new layout if null
    if (v == null) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        v = inflater.inflate(R.layout.layout_appinfo, null);
        Log.d("AppInfoAdapter", "New layout inflated");
    }

    // load controls from layout resources
    ImageView ivAppIcon = (ImageView) v.findViewById(R.id.ivIcon);
    TextView tvAppName = (TextView) v.findViewById(R.id.tvName);
    TextView tvPkgName = (TextView) v.findViewById(R.id.tvPack);
    final CheckBox addCheckbox = (CheckBox) v
            .findViewById(R.id.addCheckbox);
    Log.d("AppInfoAdapter", "Controls from layout Resources Loaded");

    // set data to display
    ivAppIcon.setImageDrawable(entry.applicationInfo.loadIcon(mPackManager));
    tvAppName.setText(entry.applicationInfo.loadLabel(mPackManager));
    tvPkgName.setText(entry.packageName);
    Log.d("AppInfoAdapter", "Data Set To Display");
    addCheckbox
            .setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    if (addCheckbox.isChecked()) {
                        System.out.println("Checked");
                        PackageManager pm = mContext.getPackageManager();
                        Drawable icon = null;
                        try {
                            icon = pm
                                    .getApplicationIcon(entry.packageName);
                        } catch (NameNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        Drawable default_icon = pm.getDefaultActivityIcon();
                        if (icon instanceof BitmapDrawable
                                && default_icon instanceof BitmapDrawable) {
                            BitmapDrawable icon_bd = (BitmapDrawable) icon;
                            Bitmap icon_b = icon_bd.getBitmap();
                            BitmapDrawable default_bd = (BitmapDrawable) pm
                                    .getDefaultActivityIcon();
                            Bitmap default_b = default_bd.getBitmap();
                            if (icon_b == default_b) {
                                // It's the default icon
                                scaleDownBitmap(default_b, 100, v.getContext());
                                Log.d("AppInfoAdapter", "Scale Bitmap Chosen");

                                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                                default_b.compress(Bitmap.CompressFormat.PNG, 100, stream);
                                byte[] byteArray = stream.toByteArray();
                                Log.d("AppInfoAdapter", "Scale Bitmap to Array");

                                Intent intent = new Intent(v.getContext(), GridView.class);
                                intent.putExtra("picture", byteArray);
                                v.getContext().startActivity(intent);
                                Log.d("AppInfoAdapter", "Intent started to send Bitmap");
                            }
                        }
                    } else {
                        System.out.println("Un-Checked");
                    }

                }
            });

    // return view
    return v;
}

@Override
public Filter getFilter() {
    if (filter == null) {
        filter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                List<PackageInfo> myFilteredAppList = new ArrayList<PackageInfo>();
                constraint = constraint.toString().toLowerCase();

                if (constraint.length() == 0) {
                    myFilteredAppList.addAll(originalListAppInfo);

                }

                for (PackageInfo appInfo : originalListAppInfo) {
                    String somefield = appInfo.packageName;
                    String name = appInfo.packageName;
                    if (somefield.toLowerCase().contains(
                            constraint.toString().toLowerCase().toString())
                            || (name != null && name.toLowerCase()
                                    .contains(
                                            constraint.toString()
                                                    .toLowerCase()
                                                    .toString()))) {
                        myFilteredAppList.add(appInfo);
                    }
                }
                results.count = myFilteredAppList.size();
                results.values = myFilteredAppList;
                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint,
                    FilterResults results) {

                if (results.values != null) {
                    mListAppInfo = (List<PackageInfo>) results.values;
                    notifyDataSetChanged();
                }
            }
        };
    }
    return filter;
}

}

Drag_and_Drop_App(片段):

public class Drag_and_Drop_App extends Activity {
private static final int SET_BACKGROUND = 10;

private ListView mListAppInfo;
// Search EditText
EditText inputSearch;
public AppInfoAdapter adapter;
final SwipeDetector swipeDetector = new SwipeDetector();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // set layout for the main screen
    setContentView(R.layout.drag_and_drop_app);

    // import buttons
    Button btnLinkToPersonalize = (Button) findViewById(R.id.btnLinkToPersonalize);
    Log.d("D&D", "onCreate called");

    // create new adapter
    adapter = new AppInfoAdapter(this, (List<PackageInfo>) Utilities.getInstalledApplications(this), getPackageManager());
    // load list application
   mListAppInfo = (ListView)findViewById(R.id.lvApps);
    // set adapter to list view
    mListAppInfo.setAdapter(adapter);
    // search bar
    inputSearch = (EditText) findViewById(R.id.inputSearch);

    inputSearch.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
            // When user changed the Text
            // Drag_and_Drop_App.this.adapter.getFilter().filter(cs);  
             if (Drag_and_Drop_App.this.adapter == null){
                 // some print statement saying it is null
                 Log.d ("msg_error", "adapter_is_null");
             }
                Drag_and_Drop_App.this.adapter.getFilter().filter(cs);

            }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                int arg3) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable arg0) {
            // TODO Auto-generated method stub                          
        }
        });


    // implement event when an item on list view is selected
    mListAppInfo.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
            // get the list adapter
            AppInfoAdapter appInfoAdapter = (AppInfoAdapter)parent.getAdapter();
            // get selected item on the list
            PackageInfo appInfo = (PackageInfo)appInfoAdapter.getItem(pos);
            // launch the selected application
            Utilities.launchApp(parent.getContext(), getPackageManager(), appInfo.packageName);
        }

    });

    // implement event when an item on list view is selected via long-click 
    mListAppInfo.setOnItemLongClickListener(new OnItemLongClickListener(){

        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view,int pos, long id) {
            if (swipeDetector.swipeDetected()){
                // do the onSwipe action 
            } else {
                // do the onItemLongClick action
                // get the list adapter
                AppInfoAdapter appInfoAdapter = (AppInfoAdapter)parent.getAdapter();
                // get selected item on the list
                PackageInfo appInfo = (PackageInfo)appInfoAdapter.getItem(pos);
                // launch the selected application
                Utilities.launchApp(parent.getContext(), getPackageManager(), appInfo.packageName);
                Log.d("D&D", "App launched");

            }
            return true;
        }
    });

    // implement slide event to open up plus button
    mListAppInfo.setOnTouchListener(swipeDetector);
    mListAppInfo.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
                if (swipeDetector.swipeDetected()){
                    // do the onSwipe action 
                    // TEST TO MAKE SURE SWIPE WORKS
                    AppInfoAdapter appInfoAdapter = (AppInfoAdapter)parent.getAdapter();
                    // get selected item on the list
                    PackageInfo appInfo = (PackageInfo)appInfoAdapter.getItem(pos);
                    // launch the selected application
                    Utilities.launchApp(parent.getContext(), getPackageManager(), appInfo.packageName);
                } else {
                    // do the onItemClick action
                    // get the list adapter
                    AppInfoAdapter appInfoAdapter = (AppInfoAdapter)parent.getAdapter();
                    // get selected item on the list
                    PackageInfo appInfo = (PackageInfo)appInfoAdapter.getItem(pos);
                    // launch the selected application
                    Utilities.launchApp(parent.getContext(), getPackageManager(), appInfo.packageName);
                }
            }
    });

最后是 GridView.java:

package com.example.awesomefilebuilderwidget;

import java.util.ArrayList;

import android.app.Activity;
import android.content.ClipData;
import android.content.ClipDescription;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.DragEvent;
import android.view.View;
import android.view.View.OnDragListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;

public class GridView extends Activity { // implements OnItemLongClickListener, OnDragListener{

ArrayList<Integer> drawables = new ArrayList<Integer>();

private BaseAdapter adapter;
private int draggedIndex = -1;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.drag_and_drop_app);
    Log.d("GridView", "onCreate called");
    drawables = new ArrayList<Integer>();
    drawables.add(R.drawable.pattern1);
    drawables.add(R.drawable.pattern2);
    android.widget.GridView gridView = (android.widget.GridView) findViewById(R.id.grid_view);
    // gridView.setOnItemLongClickListener(this);
    gridView.setAdapter(adapter = new BaseAdapter() {

        @Override
        // Get a View that displays the data at the specified position in
        // the data set.
        public View getView(int position, View convertView,
                ViewGroup gridView) {
            // try to reuse the views.
            ImageView view = (ImageView) convertView;
            // if convert view is null then create a new instance else reuse
            // it
            if (view == null) {
                view = new ImageView(GridView.this);
            }
            Bundle extras = getIntent().getExtras();
            byte[] byteArray = extras.getByteArray("picture");

            Bitmap default_b = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);

            view.setImageBitmap(default_b);
            view.setImageResource(drawables.get(position));
            view.setScaleType(ImageView.ScaleType.CENTER_CROP);
            view.setLayoutParams(new android.widget.GridView.LayoutParams(70, 70));
            view.setTag(String.valueOf(position));
            return view;
        }

        @Override
        // Get the row id associated with the specified position in the
        // list.
        public long getItemId(int position) {
            return position;
        }

        @Override
        // Get the data item associated with the specified position in the
        // data set.
        public Object getItem(int position) {
            return drawables.get(position);
        }

        @Override
        // How many items are in the data set represented by this Adapter.
        public int getCount() {
            return drawables.size();
        }
    });
}

/*@Override
public boolean onItemLongClick(AdapterView<?> gridView, View view,
        int position, long row) {
    ClipData.Item item = new ClipData.Item((String) view.getTag());
    ClipData clipData = new ClipData((CharSequence) view.getTag(),
            new String[] { ClipDescription.MIMETYPE_TEXT_PLAIN }, item);
    view.startDrag(clipData, new View.DragShadowBuilder(view), null, 0);
    View trashCan = findViewById(R.id.trash_can);
    trashCan.setVisibility(View.VISIBLE);
    trashCan.setOnDragListener(GridView.this);
    trashCan.setOnDragListener(GridView.this);
    draggedIndex = position;
    return true;
}

@Override
public boolean onDrag(View view, DragEvent dragEvent) {
    switch (dragEvent.getAction()) {
    case DragEvent.ACTION_DRAG_STARTED:
        // Drag has started
        // If called for trash resize the view and return true
        if (view.getId() == R.id.trash_can) {
            view.animate().scaleX(1.0f);
            view.animate().scaleY(1.0f);
            return true;
        } else // else check the mime type and set the view visibility
        if (dragEvent.getClipDescription().hasMimeType(
                ClipDescription.MIMETYPE_TEXT_PLAIN)) {
            view.setVisibility(View.GONE);
            return true;

        } else {
            return false;
        }
    case DragEvent.ACTION_DRAG_ENTERED:
        // Drag has entered view bounds
        // If called for trash can then scale it.
        if (view.getId() == R.id.trash_can) {
            view.animate().scaleX(1.5f);
            view.animate().scaleY(1.5f);
        }
        return true;
    case DragEvent.ACTION_DRAG_EXITED:
        // Drag exited view bounds
        // If called for trash can then reset it.
        if (view.getId() == R.id.trash_can) {
            view.animate().scaleX(1.0f);
            view.animate().scaleY(1.0f);
        }
        view.invalidate();
        return true;
    case DragEvent.ACTION_DRAG_LOCATION:
        // Ignore this event
        return true;
    case DragEvent.ACTION_DROP:
        // Dropped inside view bounds
        // If called for trash can then delete the item and reload the grid
        // view
        if (view.getId() == R.id.trash_can) {
            drawables.remove(draggedIndex);
            draggedIndex = -1;
        }
        adapter.notifyDataSetChanged();
    case DragEvent.ACTION_DRAG_ENDED:
        // Hide the trash can
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                findViewById(R.id.trash_can).setVisibility(View.GONE);
            }
        }, 1000l);
        if (view.getId() == R.id.trash_can) {
            view.animate().scaleX(1.0f);
            view.animate().scaleY(1.0f);
        } else {
            view.setVisibility(View.VISIBLE);
        }
        // remove drag listeners
        view.setOnDragListener(null);
        return true;

    }
    return false;
}*/



}

如果您发现任何看起来不正确或错误的地方,请发表评论。几天来,我一直在尝试修复此错误,并尝试了 stackoverflow 链接hereherehere以及其他链接。

请帮助我解决我不断遇到的这个错误。我现在真的很茫然……

(也感谢您阅读所有这些,我知道这很多)

这是我的实用程序类:

package com.example.awesomefilebuilderwidget;

import java.util.List;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;


public class Utilities {

/*
 * Get all installed application on mobile and return a list
 * @param   c   Context of application
 * @return  list of installed applications
 */
public static List<PackageInfo> getInstalledApplications(Context c) {
    return c.getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES);
}
4

2 回答 2

4

PackageManagergetInstalledPackages()如果返回的信息总和大于 1MB,则诸如 之类的方法可能会导致活页夹事务错误。

减轻这种情况的一种方法是不传递任何标志(例如, skip PackageManager.GET_ACTIVITIES)以减少第一次调用中的数据量。然后,对于您需要其他详细信息的那些包,请致电getPackageInfo()以获取特定包的详细信息。虽然这确实涉及多个 IPC 往返,因此速度较慢,但​​它有助于防止您超出每笔交易 1MB 的限制。

于 2013-11-03T19:35:47.427 回答
1

事实证明,当我获取已安装应用程序的列表时,我从 packageManager 收到了太多信息,即

Utilities.getInstalledApplications(this)

在我的实用程序课上。因此,我认为与其获取所有已安装的应用程序,不如让用户安装应用程序(不包括对我的使用毫无意义的系统应用程序)。这是更新的课程:

public class Utilities {

/*
 * Get all installed application on mobile and return a list
 * @param   c   Context of application
 * @return  list of installed applications
 */
public static List<ResolveInfo> getInstalledApplications(Context c) {
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_LAUNCHER);
    return c.getPackageManager().queryIntentActivities(intent, PackageManager.GET_ACTIVITIES);
}

然后当然是任何列表

<PackageInfo> 

必须改为

<ResolveInfo> 

但它就像一个魅力!

于 2013-11-03T19:36:06.940 回答