BroadcastReceiver заменяет одну ячейку в GridView - PullRequest
0 голосов
/ 25 января 2019

Я загружаю изображения в защищенную память через URL-соединение.Как только изображения загружены, BroadcastReceiver в моем MainActivity должен обновить GridView в моем основном фрагменте, чтобы включить недавно загруженный образ.

При загрузке из хранилища Gridview заполняется правильно.Однако при обновлении из BroadcastReceiver каждое последовательное изображение заменяет последнее в одном дочернем представлении, а не заполняет новое дочернее представление, как ожидается.

Любой совет будет принят с благодарностью.

Вотмоя основная активность:

Context mContext;
DisplayImageReceiver displayImageReceiver;

public static final String ACTION_SHOW_IMAGE = "com.mack.john.mackjohn_ce06.ACTION_SHOW_IMAGE";



// System generated methods
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mContext = this;
    displayImageReceiver = new DisplayImageReceiver();

    IntentFilter filter = new IntentFilter(ACTION_SHOW_IMAGE);
    filter.addAction(ACTION_SHOW_IMAGE);

    registerReceiver(displayImageReceiver, filter);

    populateGrid();
}

@Override
protected void onDestroy() {
    super.onDestroy();

    unregisterReceiver(displayImageReceiver);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_main, menu);

    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if(item.getItemId() == R.id.menu_download) {
        Intent imageIntentService = new Intent(this, ImageIntentService.class);
        startService(imageIntentService);
    }

    return super.onOptionsItemSelected(item);
}




// Custom methods
private void populateGrid() {
    getSupportFragmentManager()
            .beginTransaction()
            .replace(R.id.gridFrame, GridFragment.newInstance(this))
            .commit();
}



// Broadcast Receiver
private class DisplayImageReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        GridFragment.populateGrid(GridFragment.mView);
    }
}

Вот мой фрагмент:

public class GridFragment extends Fragment {



// Class properties
public static int mImageCount = 0;

private static Context mContext;
public static View mView;




// Constructor
public GridFragment() {}



// System generated methods
public static GridFragment newInstance(Context context) {
    Bundle args = new Bundle();

    mContext = context;

    GridFragment fragment = new GridFragment();
    fragment.setArguments(args);
    return fragment;
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_image_grid, container, false);

    mView = view;
    countFiles();
    populateGrid(view);

    return view;
}



// Custom methods
public void countFiles() {
    File protectedStorage = getActivity().getExternalFilesDir("images");
    mImageCount = protectedStorage.listFiles().length;
}

public static void populateGrid(View view) {
    File protectedStorage = mContext.getExternalFilesDir("images");
    File[] files = protectedStorage.listFiles();
    mImageCount = files.length;

    ImageGridAdapter imageGridAdapter = new ImageGridAdapter(mContext, files);

    GridView imageGrid = view.findViewById(R.id.imageGrid);
    TextView emptyState = view.findViewById(R.id.emptyState);

    if(mImageCount > 0) {
        imageGrid.setVisibility(View.VISIBLE);
        emptyState.setVisibility(View.GONE);

        imageGrid.setAdapter(imageGridAdapter);
    }

    else {
        imageGrid.setVisibility(View.GONE);
        emptyState.setVisibility(View.VISIBLE);
    }
}

}

Вот мой адаптер:

public class ImageGridAdapter extends BaseAdapter {




// Class properties
public static final String TAG = "ImageGridAdapter";
private static final int ID_CONSTANT = 0x0000001;
private final Context mContext;
private final File[] mFiles;



// Constructor
public ImageGridAdapter(Context mContext, File[] mFiles) {
    this.mContext = mContext;
    this.mFiles = mFiles;
}




// System generated methods
@Override
public int getCount() {
    // Return number of items in collection
    if(mFiles != null) {
        return mFiles.length;
    }

    else {
        Log.i(TAG, "getCount: There is no collection");

        return 0;
    }
}

@Override
public Object getItem(int position) {
    // Return an item at a specified position
    if(mFiles != null && position >= 0 && position < mFiles.length) {
        return mFiles[position];
    }

    else {
        Log.i(TAG, "getItem: There was a problem retreiving an item");

        return null;
    }
}

@Override
public long getItemId(int position) {
    // Return a unique ID for an item at a specified position
    if(mFiles != null && position >= 0 && position < mFiles.length) {
        return ID_CONSTANT + position;
    }

    else {
        Log.i(TAG, "getItemId: There was a problem assigning an ID");

        return 0;
    }
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Return a unique child view for an item at a specified position
    if(convertView ==  null) {
        convertView = LayoutInflater.from(mContext).inflate(R.layout.cell_image_grid, parent, false);
    }

    File imageFile = mFiles[position];

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 8;

    Bitmap image = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);

    ImageView gridCell = convertView.findViewById(R.id.gridCell);
    gridCell.setImageBitmap(image);

    return convertView;
}

}

Вот мой код IntentService:

public static final String TAG = "ImageIntentService";
private static String currentFileName;

public static File protectedStorage;

private final String URL_BASE = "https://i.imgur.com/";
private final String[] IMAGES = {
        "Df9sV7x.jpg", "nqnegVs.jpg", "JDCG1tP.jpg",
        "tUvlwvB.jpg", "2bTEbC5.jpg", "Jnqn9NJ.jpg",
        "xd2M3FF.jpg", "atWe0me.jpg", "UJROzhm.jpg",
        "4lEPonM.jpg", "vxvaFmR.jpg", "NDPbJfV.jpg",
        "ZPdoCbQ.jpg", "SX6hzar.jpg", "YDNldPb.jpg",
        "iy1FvVh.jpg", "OFKPzpB.jpg", "P0RMPwI.jpg",
        "lKrCKtM.jpg", "eXvZwlw.jpg", "zFQ6TwY.jpg",
        "mTY6vrd.jpg", "QocIraL.jpg", "VYZGZnk.jpg",
        "RVzjXTW.jpg", "1CUQgRO.jpg", "GSZbb2d.jpg",
        "IvMKTro.jpg", "oGzBLC0.jpg", "55VipC6.jpg"
};


// Constructor
public ImageIntentService() {
    super("ImageIntentService");
}


// System generated methods
@Override
protected void onHandleIntent(Intent intent) {


    checkForSavedImages();
}

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

    protectedStorage = getExternalFilesDir("images");
}

@Override
public void onDestroy() {
    super.onDestroy();
}


// Custom methods
private void checkForSavedImages() {
    for (int i = 0; i < IMAGES.length; i++) {
        File imageFile = new File(protectedStorage, IMAGES[i]);

        if (imageFile.exists()) {
            Log.i(TAG, "checkForSavedImages: " + IMAGES[i] + " found in protected storage");

            int fileCount = protectedStorage.listFiles().length;

            Log.i(TAG, "checkForSavedImages: " + fileCount + " files in protected storage");

            // TODO: Send file with broadcast receiver
            broadcast();
        }

        else {
            Log.i(TAG, "checkForSavedImages: " + IMAGES[i] + " NOT found in protected storage");

            // TODO: Download image file and send with broadcast receiver
            currentFileName = IMAGES[i];
            String urlString = URL_BASE + IMAGES[i];

            createConnection(urlString);
        }
    }
}

private void broadcast() {
    Intent broadcastIntent = new Intent(MainActivity.ACTION_SHOW_IMAGE);
    sendBroadcast(broadcastIntent);
}




// Data Helper
public class ImageDownloadHelper extends AsyncTask<String, Void, Void> {
    // System generated methods
    @Override
    protected Void doInBackground(String... strings) {
        String urlString = strings[0];

        downloadData(urlString);

        return null;
    }
}



// Data helper methods
public void createConnection(String urlString) {
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    if (connectivityManager != null) {
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

        if (networkInfo != null) {
            boolean isConnected = networkInfo.isConnected();

            if (isConnected) {
                ImageDownloadHelper imageDownloadHelper = new ImageDownloadHelper();
                imageDownloadHelper.execute(urlString);
            } else {
                Toast.makeText(this, getString(R.string.no_connection), Toast.LENGTH_SHORT);
            }
        } else {
            Toast.makeText(this, getString(R.string.no_connection), Toast.LENGTH_SHORT);
        }
    } else {
        Toast.makeText(this, getString(R.string.no_connection), Toast.LENGTH_SHORT);
    }
}

private void downloadData(String urlString) {
    try {
        URL imageURL = new URL(urlString);
        HttpsURLConnection connection = (HttpsURLConnection) imageURL.openConnection();

        InputStream inputStream = connection.getInputStream();
        byte[] imageDate = IOUtils.toByteArray(inputStream);

        inputStream.close();
        connection.disconnect();

        saveImage(imageDate);
    }

    catch (IOException e) {
        e.printStackTrace();
    }
}

private void saveImage(byte[] data) {
    File imageFile = new File(protectedStorage, currentFileName);

    try {
        FileOutputStream fileOutputStream = new FileOutputStream(imageFile);
        fileOutputStream.write(data);
        fileOutputStream.close();

        Log.i(TAG, "saveImage: Image Saved");

        broadcast();
    }

    catch (IOException e) {
        e.printStackTrace();
    }
}

1 Ответ

0 голосов
/ 25 января 2019

РЕШИТЬ:

Изменен мой метод сохранения для обратного вызова метода, который проверяет наличие файла в защищенном хранилище:

private void saveImage(byte[] data) {
    File imageFile = new File(protectedStorage, currentFileName);

    try {
        FileOutputStream fileOutputStream = new FileOutputStream(imageFile);
        fileOutputStream.write(data);
        fileOutputStream.close();

        Log.i(TAG, "saveImage: Image Saved");

        //broadcast();

        checkForSavedImages();
    }

    catch (IOException e) {
        e.printStackTrace();
    }
}

Затем изменил метод проверки, чтобы он ломался, как только он сталкивался с файлом, который не находится в хранилище:

private void checkForSavedImages() {
    for (int i = 0; i < IMAGES.length; i++) {
        File imageFile = new File(protectedStorage, IMAGES[i]);

        if (imageFile.exists()) {
            Log.i(TAG, "checkForSavedImages: " + IMAGES[i] + " found in protected storage");

            int fileCount = protectedStorage.listFiles().length;

            Log.i(TAG, "checkForSavedImages: " + fileCount + " files in protected storage");

            // TODO: Send file with broadcast receiver
            broadcast();
        }

        else {
            Log.i(TAG, "checkForSavedImages: " + IMAGES[i] + " NOT found in protected storage");

            // TODO: Download image file and send with broadcast receiver
            currentFileName = IMAGES[i];
            String urlString = URL_BASE + IMAGES[i];

            createConnection(urlString);

            break;
        }
    }
}
...