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 は私のウィジェット全体の中心部分であり、主要な機能です。)

私は今途方に暮れているので、これが原因であると結論付けた 3 つの疑わしいクラスを投稿します (他のすべてのクラスは正常に動作するため)。

一部のコードがコメントアウトされていることに注意してください (実際のデバイスはハニカムをサポートしていないため、ドラッグ アンド ドロップ機能のコーディングなどです。ただし、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;
}*/



}

正しくないように思われるものや間違っているものに気付いた場合は、コメントしてください。私は何日もこのエラーを修正しようとしてきましたが、ここ、ここ、ここ、およびそれらの上にあるその他のスタックオーバーフローのリンク試しまし

発生し続けるこのエラーを修正するのを手伝ってください。今から何をするか本当に迷ってます…

(これもすべて読んでくれてありがとう、私はそれがたくさんあったことを知っています)

ここに私のユーティリティクラスがあります:

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

PackageManagerのようなメソッドは、getInstalledPackages()返される情報の合計が 1MB を超える場合、バインダー トランザクション エラーになる可能性があります。

PackageManager.GET_ACTIVITIESこれを軽減する 1 つの方法は、最初の呼び出しでデータの量を減らすためにフラグを渡さない (例: skip ) ことです。次に、追加の詳細が必要なパッケージについて、 を呼び出し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 に答える