xml 如何使用URI以json格式将多个图像保存到localdb

从本地数据库获取数据从json转换为字符串并使用multipart将多个文件发送到服务器

mainActivity
package com.multipart.mainactivity;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;


import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_PERMISSION_CODE = 3;
    private static final int REQUEST_CAMERA = 1;
    private static final String TAG = "MainActivity";
    private static final int REQUEST_GALLERY = 2;
    private static final int REQUEST_STORAGE_PERMISSION_CODE = 500;
    private static final int REQUEST_APP_SETTINGS = 1;
    private static Retrofit mRetrofit;

    private File photoFile = null;
    private RecyclerView recyclerView;
    private Button attachImage,sendBtn,saveBtn,getBtn;
    private ImageView ViewImage;
    private UploadImageAdapter adapter;
    MainActivity mActivity;

    private String TAKE_PIC = "Camera";
    private String GALLERY_PIC = "Gallery";
    private String CANCEL = "Cancel";
    private String userChoosenTask;
    private Uri photoURI;
    private String mCurrentPhotoPath;

    private String uriFromDocument;
    private List<Uri> dataUriList = new ArrayList<>();
    private List<File> fileList = new ArrayList<>();
    private static final String MULTIPART_FORMDATA = "multipart/form-data";
    private DataBaseHelper dataBaseHelper;
    private List<String> mUriList;
    int count;

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

        dataBaseHelper = new DataBaseHelper(MainActivity.this);
        mUriList = new ArrayList<>();
        mActivity = MainActivity.this;
        saveBtn = findViewById(R.id.save);
        getBtn = findViewById(R.id.button2);

        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        LinearLayoutManager layoutmanager = new LinearLayoutManager(MainActivity.this);
        layoutmanager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager(layoutmanager);
        intializeAdapter();

        attachImage =  findViewById(R.id.attachimage);
        ViewImage = (ImageView) findViewById(R.id.viewImage);
        sendBtn = findViewById(R.id.button);

        attachImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity,
                            Manifest.permission.CAMERA) && ActivityCompat.shouldShowRequestPermissionRationale(mActivity,
                            Manifest.permission.CAMERA)) {

                    } else {
                        ActivityCompat.requestPermissions(mActivity,
                                new String[]{Manifest.permission.CAMERA},
                                REQUEST_PERMISSION_CODE);
                    }
                } else
                    selectImage();
            }
        });

        sendBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                updateProfileAPI();
            }
        });

        saveBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                count++;
                dataBaseHelper.insertUploadImagedata(mUriList,String.valueOf(count));
            }
        });

        getBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                List<String> list =  dataBaseHelper.getUploadedImageDataList();
                List<Uri> uriList = new ArrayList<>();

                for(int i=0;i<list.size();i++) {
                    uriList.add(Uri.parse(list.get(i)));
                }

           /*     Gson gson = new Gson();
                List<String> mOptionTarget = new ArrayList<>();
                List<String>  targetList = gson.fromJson(typeUrl, mOptionTarget);*/
                Log.d(TAG, "onClick: list " + list);
                dataUriList.clear();
                Log.d(TAG, "onClick: uri List " + uriList);
                intializeAdapter(uriList);
            }
        });
    }

    private void intializeAdapter(List<Uri> list) {
        adapter = new UploadImageAdapter(list, MainActivity.this);
        recyclerView.setAdapter(adapter);
    }

    private void intializeAdapter() {
        adapter = new UploadImageAdapter(dataUriList, MainActivity.this);
        recyclerView.setAdapter(adapter);
    }

    private void selectImage() {

        final CharSequence[] items = {TAKE_PIC, GALLERY_PIC, CANCEL};
        android.support.v7.app.AlertDialog.Builder alertdialog = new android.support.v7.app.AlertDialog.Builder(this);
        alertdialog.setTitle(R.string.select_pic);

        alertdialog.setItems(items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int position) {
                boolean result = PermissionUtils.checkPermission(mActivity);
                if (items[position].equals(TAKE_PIC)) {
                    userChoosenTask = TAKE_PIC;
                    cameraIntent();

                } else if (items[position].equals(GALLERY_PIC)) {
                    userChoosenTask = GALLERY_PIC;
                    galleryIntent();

                } else if (items[position].equals(CANCEL)) {
                    dialog.dismiss();
                }
            }
        });
        alertdialog.show();
    }

    private void cameraIntent() {
        if (PermissionUtils.checkStoragePermission(mActivity)) {
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // Ensure that there's a camera activity to handle the intent
            if (takePictureIntent.resolveActivity(mActivity.getPackageManager()) != null) {
                // Create the File where the photo should go
                // File photoFile = null;
                try {
                    photoFile = createImageFile();
                } catch (IOException ex) {
                    Log.d(TAG, "cameraIntent: excep " + ex.getMessage());
                }
                // Continue only if the File was successfully created
                if (photoFile != null) {

                    if (Build.VERSION.SDK_INT < 23) {
                        photoURI = Uri.fromFile(photoFile);
                    }
                    else {
                        photoURI = FileProvider.getUriForFile(mActivity,
                                "com.sgs.bamp_app.fileprovider",
                                photoFile);
                    }

                    mCurrentPhotoPath = photoFile.getAbsolutePath();

                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                    startActivityForResult(takePictureIntent, REQUEST_CAMERA);
                } else {
                    Toast.makeText(mActivity, "file is null", Toast.LENGTH_SHORT).show();
                }
            }
        }
        else {
            ActivityCompat.requestPermissions(mActivity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    REQUEST_STORAGE_PERMISSION_CODE);
        }
    }

    private void galleryIntent() {
        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(Intent.createChooser(intent, "Select File"), REQUEST_GALLERY);
    }

    private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyy_MM_dd", Locale.getDefault()).format(new Date());
        String imageFileName = timeStamp + "_";
        File albumF = mActivity.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        return File.createTempFile(imageFileName, ".png", albumF);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_STORAGE_PERMISSION_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    if (userChoosenTask.equals(TAKE_PIC))
                        cameraIntent();
                    else if (userChoosenTask.equals(GALLERY_PIC))
                        galleryIntent();
                } else {
                    alertForCamera();
                }
                break;
        }
    }

    private void alertForCamera() {
        final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
        dialog.setTitle("Enable Camera permmissions")
                .setMessage("Your Camera Settings is 'Off'")
                .setPositiveButton("SETTINGS", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                        Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
                        myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
                        myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivityForResult(myAppSettings, REQUEST_APP_SETTINGS);
                    }
                })
                .setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                        finish();
                    }
                });
        dialog.show();
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == REQUEST_GALLERY)
                onSelectFromGalleryResult(data);
            if (requestCode == REQUEST_CAMERA)
                onCaptureImageResult(data);
        }
    }

    private void onCaptureImageResult(Intent data) {
  /*      Bundle extras = data.getExtras();
        mImageBitmap = (Bitmap) extras.get("data");
        profilePic.setImageBitmap(mImageBitmap);*/
        photoURI = Uri.fromFile(photoFile);
        dataUriList.add(photoURI);

        // save the uri String in to the localDb
        mUriList.add(photoURI.toString());

        if (mCurrentPhotoPath != null) {
            RequestOptions options = new RequestOptions();
            options.autoClone();
            Log.d(TAG, "onActivityResult: " + photoFile);
            Glide.with(this)
                    .load(photoFile)
                    .into(ViewImage);

            fileList.add(photoFile);
        }
        else {
            Log.d(TAG, "onActivityResult: null path");
        }
    }

    private void onSelectFromGalleryResult(Intent data) {

        if (data != null && data.getData() != null) {
            photoURI = data.getData();

            // save the uri String in to the localDb
            mUriList.add(photoURI.toString());

            if (photoURI != null) {
                try {
                    dataUriList.add(photoURI);
                    Log.d(TAG, "onActivityResult: " + photoURI);
                    photoFile = new File(getPath(photoURI));
                    RequestOptions options = new RequestOptions();
                    options.autoClone();

                    Glide.with(this)
                            .load(photoFile)
                            .apply(options)
                            .into(ViewImage);

                    fileList.add(photoFile);
                }
                catch (Exception e) {
                    Log.d(TAG, "onActivityResult: " + e.getMessage());
                    Toast.makeText(this, "Choose proper image", Toast.LENGTH_SHORT).show();
                }
            }
        }
        else {
            Log.d(TAG, "onActivityResult: null path");
            Toast.makeText(this, "Image not selected! Try Again", Toast.LENGTH_LONG).show();
        }
    }

    public String getPath(Uri uri) {
        try {
            String[] projection = {MediaStore.Images.Media.DATA};
            Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
            if (cursor == null) return null;
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

            String s = null;
            if (cursor.moveToFirst()) {
                s = cursor.getString(column_index);
            } else {
                Log.d(TAG, "Cursor is not moving");
            }
            cursor.close();

            return s;
        } catch (Exception e) {
            Log.d(TAG, "getPath: " + e.getMessage());
            return null;
        }
    }

    private void updateProfileAPI() {

        int fileSize = fileList.size();
        RegisterService updateProfileAPI = getRetrofit().create(RegisterService.class);

        RequestBody rbBridgeId = null;
        RequestBody rbUserId = null;

        MultipartBody.Part photo1 = null;
        MultipartBody.Part photo2 = null;
        MultipartBody.Part photo3 = null;
        MultipartBody.Part photo4 = null;
        MultipartBody.Part photo5 = null;
        MultipartBody.Part photo6 = null;
        MultipartBody.Part photo7 = null;
        MultipartBody.Part photo8 = null;

        rbBridgeId = RequestBody.create(MediaType.parse(MULTIPART_FORMDATA), "KAKA-17N098DV6577654355");
        rbUserId = RequestBody.create(MediaType.parse(MULTIPART_FORMDATA), "678");


        if (!fileList.isEmpty() && fileSize > 0) {

            RequestBody requestFile =
                    RequestBody.create(MediaType.parse(MULTIPART_FORMDATA), fileList.get(0));
            photo1 =
                    MultipartBody.Part.createFormData("images[]", fileList.get(0).getName(), requestFile);

            RequestBody requestFile2 =
                    RequestBody.create(MediaType.parse(MULTIPART_FORMDATA), fileList.get(1));
            photo2 =
                    MultipartBody.Part.createFormData("images[]", fileList.get(1).getName(), requestFile2);

            RequestBody requestFile3 =
                    RequestBody.create(MediaType.parse(MULTIPART_FORMDATA), fileList.get(2));

            photo3 =
                    MultipartBody.Part.createFormData("images[]", fileList.get(2).getName(), requestFile3);

            RequestBody requestFile4 =
                    RequestBody.create(MediaType.parse(MULTIPART_FORMDATA), fileList.get(4));
            photo4 =
                    MultipartBody.Part.createFormData("images[]", fileList.get(4).getName(), requestFile4);

            RequestBody requestFile5 =
                    RequestBody.create(MediaType.parse(MULTIPART_FORMDATA), fileList.get(5));
            photo5 =
                    MultipartBody.Part.createFormData("images[]", fileList.get(5).getName(), requestFile5);

            RequestBody requestFile6 =
                    RequestBody.create(MediaType.parse(MULTIPART_FORMDATA), fileList.get(1));
            photo6 =
                    MultipartBody.Part.createFormData("images[]", fileList.get(1).getName(), requestFile6);

         /*   RequestBody requestFile7 =
                    RequestBody.create(MediaType.parse(MULTIPART_FORMDATA), fileList.get(7));
            photo7 =
                    MultipartBody.Part.createFormData("images[]", fileList.get(7).getName(), requestFile7);*/

            RequestBody requestFile33 =
                    RequestBody.create(MediaType.parse(MULTIPART_FORMDATA), fileList.get(3));
            photo8 =
                    MultipartBody.Part.createFormData("images[]", fileList.get(3).getName(), requestFile33);
        }

        Call<List<ResponseBody1>> call = updateProfileAPI.uploadImage(photo1,photo2,photo3,photo4,photo5,photo6,photo7,photo8,rbBridgeId,rbUserId);
        call.enqueue(new Callback<List<ResponseBody1>>() {
            @Override
            public void onResponse(Call<List<ResponseBody1>> call, Response<List<ResponseBody1>> response) {
                if(response.isSuccessful()) {
                    Toast.makeText(MainActivity.this, "Success!", Toast.LENGTH_SHORT).show();
                }
                else {
                    try {
                        Log.d(TAG, "onResponse: failure " + response.errorBody().string());
                        Toast.makeText(MainActivity.this, "Failure!", Toast.LENGTH_SHORT).show();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailure(Call<List<ResponseBody1>> call, Throwable t) {
                Log.d(TAG, "onFailure: " + t.getMessage());
                Toast.makeText(MainActivity.this, "Failure", Toast.LENGTH_SHORT).show();
            }
        });

    }

    public interface  RegisterService {
        @Multipart
        @POST("add_images")
        Call<List<ResponseBody1>> uploadImage(
                @Part MultipartBody.Part file1,
                @Part MultipartBody.Part file2,
                @Part MultipartBody.Part file3,
                @Part MultipartBody.Part file4,
                @Part MultipartBody.Part file5,
                @Part MultipartBody.Part file6,
                @Part MultipartBody.Part file7,
                @Part MultipartBody.Part file8,
                @Part("bridge_id") RequestBody rbBridgeId,
                @Part("user_id") RequestBody rbUserId );
    }

    private static Retrofit initializeRetrofit() {
        Gson gson = new GsonBuilder()
                .setLenient()
                .create();
        mRetrofit = new Retrofit.Builder()
                .baseUrl("http://bampstage.shrigowri.com/ibms/index.php/bamp_api/")
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addConverterFactory(ScalarsConverterFactory.create())
                .build();

        return mRetrofit;
    }

    public static Retrofit getRetrofit() {

        if (mRetrofit != null) {
            return mRetrofit;
        } else {
            return initializeRetrofit();
        }
    }

}

DataBaseContract
package com.multipart.mainactivity;

import android.provider.BaseColumns;

public class DataBaseContract {

    public static final class UploadImageEntry implements BaseColumns {
        public static final String TABLE_NAME = "uploadimage_table";
        public static final String COLUMN_BRIDGE_ID= "bridged_id";
        public static final String COLUMN_IMAGE_URL_SCOR_EFFICIENCY = "uploadimage_url_scor_efficiency";
        public static final String COLUMN_IMG_URL_NONINTEGRAL = "images_for_nonintegral";
        public static final String COLUMN_IMG_URL_SUPER_STRUCTURE = "images_for_superstructure";
        public static final String COLUMN_IMG_URL_SUB_STRUCTURE = "images_for_subtructure";
        public static final String COLUMN_TOTAL_IMG= "totalImg";
    }
}
DataBaseHelper
package com.multipart.mainactivity;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

public class DataBaseHelper extends SQLiteOpenHelper {

    private static final String TAG = "BampDbHelper";
    private static final int DATABASE_VERSION = 8;
    private static final String DATABASE_NAME = "BampIndia.db";

    private SQLiteDatabase db;

    public DataBaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {

        final String SQL_CREATE_UPLOADIMAGE_TABLE = "CREATE TABLE " + DataBaseContract.UploadImageEntry.TABLE_NAME + " ( " +
                DataBaseContract.UploadImageEntry.COLUMN_BRIDGE_ID + " TEXT PRIMARY KEY, " +
                DataBaseContract.UploadImageEntry.COLUMN_IMG_URL_NONINTEGRAL + " TEXT, " +
                DataBaseContract.UploadImageEntry.COLUMN_IMG_URL_SUPER_STRUCTURE + " TEXT, " +
                DataBaseContract.UploadImageEntry.COLUMN_IMG_URL_SUB_STRUCTURE + " TEXT, " +
                DataBaseContract.UploadImageEntry.COLUMN_TOTAL_IMG + " INTEGER, " +
                DataBaseContract.UploadImageEntry.COLUMN_IMAGE_URL_SCOR_EFFICIENCY + " TEXT " + " )";

        Log.d(TAG, "onCreate: table created is " + SQL_CREATE_UPLOADIMAGE_TABLE);
        sqLiteDatabase.execSQL(SQL_CREATE_UPLOADIMAGE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }

    //INSERTING AND RETRIEVIBG UPLOAD IMAGE DATA FROM AND TO SQLITE DATABASE
    public boolean insertUploadImagedata(List<String> mUriList, String bridgeId) {
        int length = mUriList.size();
        SQLiteDatabase db = this.getWritableDatabase();
        Gson gson = new Gson();
//        for (int i = 0; i < length; i++) {
        ContentValues contentvalues = new ContentValues();
        contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_BRIDGE_ID, bridgeId);
        contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_IMAGE_URL_SCOR_EFFICIENCY, gson.toJson(mUriList));
    /*        contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_IMG_URL_NONINTEGRAL, mUriList.get(i));
            contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_IMG_URL_SUPER_STRUCTURE, mUriList.get(i));
            contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_IMG_URL_SUB_STRUCTURE, mUriList.get(i));*/
        contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_TOTAL_IMG, length);

        long result = db.insert(DataBaseContract.UploadImageEntry.TABLE_NAME, null, contentvalues);
        Log.d(TAG, "insertDeckdata: " + result);
//        }
        db.close();
        return result > 0;
    }

    public List<String> getUploadedImageDataList() {
        SQLiteDatabase db = this.getReadableDatabase();
        Type mOptionTarget = new TypeToken<List<String>>() {}.getType();

        List<Uri> responses = new ArrayList<>();
        List<String> targetList = null;

 /*       Gson gson = new Gson();
        Type mOptionTarget = new TypeToken<List<Zone>>() {
        }.getType();
*/

        Cursor cursor = db.query(DataBaseContract.UploadImageEntry.TABLE_NAME, null, null, null, null, null, null);
        if (cursor != null) {
         Gson gson = new Gson();
            if (cursor.moveToFirst()) {
                do {
                    try {

//                        String typeCode = cursor.getString(cursor.getColumnIndex(DataBaseContract.UploadImageEntry.COLUMN_IMG_URL_NONINTEGRAL));
                        String typeUrl = cursor.getString(cursor.getColumnIndex(DataBaseContract.UploadImageEntry.COLUMN_IMAGE_URL_SCOR_EFFICIENCY));
//                        String typeUrl = cursor.getString(cursor.getColumnIndex(BampContract.UploadImageEntry.COLUMN_IMG_URL_SUPER_STRUCTURE));
//                        String typeUrl = cursor.getString(cursor.getColumnIndex(BampContract.UploadImageEntry.COLUMN_IMG_URL_SUB_STRUCTURE));
                        int fd = cursor.getInt(cursor.getColumnIndex(DataBaseContract.UploadImageEntry.COLUMN_TOTAL_IMG));
                        targetList = gson.fromJson(typeUrl, mOptionTarget);
                        //imageData.setStringUri(typeCode);
//                        imageData.setUri(Uri.parse(typeUrl));
                       /* ArrayList<String> playersList = (ArrayList<String>) gson.fromJson(playersString,
                                new TypeToken<ArrayList<String>>() {
                                }.getType());*/
                        responses.add(Uri.parse(typeUrl));
                    }
                    catch (SQLiteException e) {
                        e.printStackTrace();
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }

                } while (cursor.moveToNext());
                cursor.close();
            }
        }
        db.close();
        return targetList;
    }

    public boolean updateImageList(List<String> mUriList,String bridgeId) {

        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentvalues = new ContentValues();

        for(int i=0; i<mUriList.size(); i++) {
            contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_BRIDGE_ID, bridgeId);
            contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_IMAGE_URL_SCOR_EFFICIENCY, mUriList.get(i));
            contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_IMG_URL_NONINTEGRAL, mUriList.get(i));
            contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_IMG_URL_SUPER_STRUCTURE, mUriList.get(i));
            contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_IMG_URL_SUB_STRUCTURE, mUriList.get(i));
            contentvalues.put(DataBaseContract.UploadImageEntry.COLUMN_TOTAL_IMG, mUriList.get(i));
        }

        int result = db.update(DataBaseContract.UploadImageEntry.TABLE_NAME, contentvalues,
                DataBaseContract.UploadImageEntry.COLUMN_BRIDGE_ID + " = ? ",
                new String[]{String.valueOf(bridgeId)});

        return result>0;
    }
}

adapter
package com.multipart.mainactivity;

import android.content.Context;
import android.net.Uri;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;

import com.bumptech.glide.Glide;

import java.util.List;

public class UploadImageAdapter extends RecyclerView.Adapter<UploadImageAdapter.ImageViewHolder> {

    private static final String TAG = "UploadImageAdapter1";
    private List<Uri> uriList = null;
    private Context context;
    //    private OnSelectImageClickListener onSelectImageClickListener;
    private ImageView imageViewnull;


    public UploadImageAdapter(List<Uri> uriList, Context context) {
        this.uriList = uriList;
        this.context = context;
        /*try {
            onSelectImageClickListener = (OnSelectImageClickListener) fragment;
        } catch (Exception e) {
            Log.d(TAG, "UploadImageAdapter: " + e.getMessage());
        }*/
    }

    @Override
    public int getItemCount() {
        return uriList.size();
    }


    @Override
    public void onBindViewHolder(ImageViewHolder viewHolder, int i) {
        Uri ci = uriList.get(i);
        ImageView image = viewHolder.mImage;

        if (ci != null) {
            Log.d(TAG, "onBindViewHolder: image is " + ci);
            Glide.with(context).load(ci).into(image);
        } else {
            Glide.with(context).load("").into(image);
        }
//     viewHolder.mImage.setImageResource(ci.getImage());
    }

    @Override
    public ImageViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View itemView = LayoutInflater.
                from(viewGroup.getContext()).
                inflate(R.layout.recycler_list_item, viewGroup, false);
        return new UploadImageAdapter.ImageViewHolder(itemView);
    }


    public class ImageViewHolder extends RecyclerView.ViewHolder {
        private ImageView mImage;
        private ImageView imageViewDelete;
        private View mView;


        public ImageViewHolder(View view) {
            super(view);
            this.mView = view;
            mImage = (ImageView) view.findViewById(R.id.upload_image);
            imageViewDelete = (ImageView) view.findViewById(R.id.imageview_recyler_delete);

            mView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition();
                    Uri uri = uriList.get(position);
                   /* if (onSelectImageClickListener != null) {
                        onSelectImageClickListener.onSelectedImageClicked(uri, position);
                    }*/

                    imageViewDelete.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            int position = getAdapterPosition();
                            Uri uri = uriList.get(position);
                          /*  if (onSelectImageClickListener != null) {
                                onSelectImageClickListener.onClickImageDelete(uri, position);
                                uriList.remove(position);
                                notifyItemRemoved(position);
                                Toast.makeText(context, "image succesfully deleted", Toast.LENGTH_SHORT).show();
                            }*/
                        }
                    });

                }
            });
        }
    }

    public interface OnSelectImageClickListener {
        public void onSelectedImageClicked(Uri uri, int postion);
        public void onClickImageDelete(Uri uri, int postion);
    }
}
pernissionUtil
package com.multipart.mainactivity;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;

public class PermissionUtils {

    public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 123;
    public static final String TAG = "PermissionUtil";

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public static boolean checkPermission(final Context context)
    {
        int currentAPIVersion = Build.VERSION.SDK_INT;
        if (currentAPIVersion >= android.os.Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
                    alertBuilder.setCancelable(true);
                    alertBuilder.setTitle("Permission necessary");
                    alertBuilder.setMessage("External storage permission is necessary");
                    alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener()
                    {
                        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
                        }
                    });
                    AlertDialog alert = alertBuilder.create();
                    alert.show();
                } else
                {
                    ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                            MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
                }
                return false;
            }
            else
            {
                return true;
            }
        }
        else
        {
            return true;
        }
    }

    public static boolean checkStoragePermission(Context context)
    {
        return ((Build.VERSION.SDK_INT < 23) || (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
                ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED));
    }

    public static boolean checkLocationPermission(final Context context)
    {
        int currentAPIVersion = Build.VERSION.SDK_INT;
        if (currentAPIVersion >= android.os.Build.VERSION_CODES.M)
        {
            return  (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED);

        }
        else
        {
            return true;
        }
    }


    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public static boolean checkingCameraPermission(final Context context)
    {
        int currentAPIVersion = Build.VERSION.SDK_INT;
        if (currentAPIVersion >= android.os.Build.VERSION_CODES.M)
        {
            return  (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED );

        }
        else
        {
            return true;
        }
    }


    public static boolean verifyPermissions(int[] grantResults)
    {
        // At least one result must be checked.
        if(grantResults.length < 1)
        {
            return false;
        }

        // Verify that each required permission has been granted, otherwise return false.
        for (int result : grantResults)
        {
            Log.d(TAG, "verifyPermissions: ");
            if (result != PackageManager.PERMISSION_GRANTED)
            {
                return false;
            }
        }
        return true;
    }
}
model
package com.multipart.mainactivity;

public class ResponseBody1 {

    private String Status;

    public String getStatus() {
        return Status;
    }

    public void setStatus(String status) {
        Status = status;
    }

    @Override
    public String toString() {
        return "ResponseBody1{" +
                "Status='" + Status + '\'' +
                '}';
    }
}
main
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Attach Image"
        android:textSize="18sp"
        android:textColor="@android:color/white"
        android:textStyle="bold"
        android:textAllCaps="false"
        android:layout_marginRight="32dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginLeft="32dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="20dp"
        android:id="@+id/attachimage"
        android:layout_marginStart="32dp"
        android:layout_marginEnd="32dp" />


    <ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/attachimage"
        android:scaleType="fitXY"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:id="@+id/viewImage"
        app:layout_constraintHorizontal_bias="0.498"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toTopOf="@+id/recyclerView"
        app:layout_constraintVertical_bias="0.502" />


    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent">
    </android.support.v7.widget.RecyclerView>

    <Button
        android:id="@+id/button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="Send"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.537"
        app:layout_constraintStart_toStartOf="parent"/>

    <Button
        android:id="@+id/save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginBottom="8dp"
        android:text="save"
        app:layout_constraintBottom_toTopOf="@+id/recyclerView"
        app:layout_constraintStart_toStartOf="parent"/>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="12dp"
        android:text="get"
        app:layout_constraintBottom_toTopOf="@+id/recyclerView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.962"
        app:layout_constraintStart_toEndOf="@+id/save"/>


</android.support.constraint.ConstraintLayout>
mainfest
      <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
provider_paths
?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="/"/>
</paths>

xml Maps SDK

Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.it.lec11v1_maps">
    <!--
         The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but you must specify either coarse or fine
         location permissions for the 'MyLocation' functionality. 
    -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <!--
             The API key for Google Maps-based APIs is defined as a string resource.
             (See the file "res/values/google_maps_api.xml").
             Note that the API key is linked to the encryption key used to sign the APK.
             You need a different API key for each encryption key, including the release key that is used to
             sign the APK for publishing.
             You can define the keys for the debug and release targets in src/debug/ and src/release/. 
        -->
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
activity_maps
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MapsActivity" />
MapsActivity
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }


    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // Add a marker in Sydney and move the camera
        LatLng sydney = new LatLng(31.511335, 34.4373716);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Gaza"));
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney,12));
        mMap.getUiSettings().setZoomControlsEnabled(true);
        mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);

        mMap.addPolygon(new PolygonOptions()
                .add(new LatLng(31.511335, 34.4373716)
                        ,new LatLng(31.611335, 35.4373716)
                        ,new LatLng(31.411335, 34.2373716))
                .fillColor(Color.BLUE).strokeColor(Color.BLACK));
    }
}
google_maps_api
<resources>
    <!--
    TODO: Before you run your application, you need a Google Maps API key.

    To get one, follow this link, follow the directions and press "Create" at the end:

    https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=AB:E2:56:DD:FC:9F:58:E3:35:CE:3A:20:F6:A2:3D:BE:E1:F0:01:0E%3Bcom.example.it.lec11v1_maps

    You can also add your credentials to an existing key, using these values:

    Package name:
    AB:E2:56:DD:FC:9F:58:E3:35:CE:3A:20:F6:A2:3D:BE:E1:F0:01:0E

    SHA-1 certificate fingerprint:
    AB:E2:56:DD:FC:9F:58:E3:35:CE:3A:20:F6:A2:3D:BE:E1:F0:01:0E

    Alternatively, follow the directions here:
    https://developers.google.com/maps/documentation/android/start#get-key

    Once you have your key (it starts with "AIza"), replace the "google_maps_key"
    string in this file.
    -->
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyAugQ5RCcPA5Te4RwCXpZUw2l3bnwtRqoU</string>
</resources>

xml 广播接收器/通知

myBroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction()==Intent.ACTION_POWER_CONNECTED){
            NewMessageNotification.notify(context,"power connected",1);
        }else if(intent.getAction()=="com.example.it.lec10_v2broadcastsender.App1Message"){
            String receivedMessage = intent.getStringExtra("msg");
            NewMessageNotification.notify(context,receivedMessage,1);
        }
    }
}
newMessageNotification
public class NewMessageNotification {
    /**
     * The unique identifier for this type of notification.
     */
    private static final String NOTIFICATION_TAG = "NewMessage";

    /**
     * Shows the notification, or updates a previously shown notification of
     * this type, with the given parameters.
     * <p>
     * TODO: Customize this method's arguments to present relevant content in
     * the notification.
     * <p>
     * TODO: Customize the contents of this method to tweak the behavior and
     * presentation of new message notifications. Make
     * sure to follow the
     * <a href="https://developer.android.com/design/patterns/notifications.html">
     * Notification design guidelines</a> when doing so.
     *
     * @see #cancel(Context)
     */
    public static void notify(final Context context,
                              final String exampleString, final int number) {
        final Resources res = context.getResources();

        // This image is used as the notification's large icon (thumbnail).
        // TODO: Remove this if your notification has no relevant thumbnail.
        final Bitmap picture = BitmapFactory.decodeResource(res, R.drawable.example_picture);


        final String ticker = exampleString;
        final String title = res.getString(
                R.string.new_message_notification_title_template, exampleString);
        final String text = res.getString(
                R.string.new_message_notification_placeholder_text_template, exampleString);

        final NotificationCompat.Builder builder = new NotificationCompat.Builder(context)

                // Set appropriate defaults for the notification light, sound,
                // and vibration.
                .setDefaults(Notification.DEFAULT_ALL)

                // Set required fields, including the small icon, the
                // notification title, and text.
                .setSmallIcon(R.drawable.ic_stat_new_message)
                .setContentTitle(title)
                .setContentText(text)

                // All fields below this line are optional.

                // Use a default priority (recognized on devices running Android
                // 4.1 or later)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)

                // Provide a large icon, shown with the notification in the
                // notification drawer on devices running Android 3.0 or later.
                .setLargeIcon(picture)

                // Set ticker text (preview) information for this notification.
                .setTicker(ticker)

                // Show a number. This is useful when stacking notifications of
                // a single type.
                .setNumber(number)

                // If this notification relates to a past or upcoming event, you
                // should set the relevant time information using the setWhen
                // method below. If this call is omitted, the notification's
                // timestamp will by set to the time at which it was shown.
                // TODO: Call setWhen if this notification relates to a past or
                // upcoming event. The sole argument to this method should be
                // the notification timestamp in milliseconds.
                //.setWhen(...)

                // Set the pending intent to be initiated when the user touches
                // the notification.
                .setContentIntent(
                        PendingIntent.getActivity(
                                context,
                                0,
                                new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com")),
                                PendingIntent.FLAG_UPDATE_CURRENT))

                // Example additional actions for this notification. These will
                // only show on devices running Android 4.1 or later, so you
                // should ensure that the activity in this notification's
                // content intent provides access to the same actions in
                // another way.
                .addAction(
                        R.drawable.ic_action_stat_share,
                        res.getString(R.string.action_share),
                        PendingIntent.getActivity(
                                context,
                                0,
                                Intent.createChooser(new Intent(Intent.ACTION_SEND)
                                        .setType("text/plain")
                                        .putExtra(Intent.EXTRA_TEXT, "Dummy text"), "Dummy title"),
                                PendingIntent.FLAG_UPDATE_CURRENT))
                .addAction(
                        R.drawable.ic_action_stat_reply,
                        res.getString(R.string.action_reply),
                        null)

                // Automatically dismiss the notification when it is touched.
                .setAutoCancel(true);

        notify(context, builder.build());
    }

    @TargetApi(Build.VERSION_CODES.ECLAIR)
    private static void notify(final Context context, final Notification notification) {
        final NotificationManager nm = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
            nm.notify(NOTIFICATION_TAG, 0, notification);
        } else {
            nm.notify(NOTIFICATION_TAG.hashCode(), notification);
        }
    }

    /**
     * Cancels any notifications of this type previously shown using
     * {@link #notify(Context, String, int)}.
     */
    @TargetApi(Build.VERSION_CODES.ECLAIR)
    public static void cancel(final Context context) {
        final NotificationManager nm = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
            nm.cancel(NOTIFICATION_TAG, 0);
        } else {
            nm.cancel(NOTIFICATION_TAG.hashCode());
        }
    }
}
MainActivity
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.it.lec10_v1notification">

    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
                <action android:name="com.example.it.lec10_v2broadcastsender.App1Message"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

xml Volley / JSON / AppController / Recycler / PicassoLibrary(https://square.github.io/picasso/)

MainActivity
public class MainActivity extends AppCompatActivity {

    ArrayList<Movie> movies = new ArrayList<>();
    ProgressDialog progressDialog;
    RecyclerView movieRecycler;
    MovieAdapter movieAdapter;

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

        getPosts();


    }

    public void getPosts() {
        showDialog();

        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, URL.URL, null, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray response) {

                Log.e("hzm", response.toString());
                for (int i = 0; i < response.length(); i++) {

                    try {
                        JSONObject object = response.getJSONObject(i);

                        String title = object.getString("title");
                        String image = object.getString("image");
                        Double rating = object.getDouble("rating");
                        int releaseYear = object.getInt("releaseYear");
                        String genreString = "";

                        JSONArray genres = object.getJSONArray("genre");

                        for (int j=0; j<genres.length();j++){
                            genreString += genres.getString(j);
                            if(j!=genres.length()-1){
                                genreString += ", ";
                            }
                        }


                        movies.add(new Movie(title,image,rating,releaseYear,genreString));

                        hideDialog();
                    } catch (JSONException e) {
                        e.printStackTrace();
                        hideDialog();
                    }
                }

                movieRecycler = findViewById(R.id.postRecycler);
                movieRecycler.setLayoutManager(new LinearLayoutManager(MainActivity.this));
                movieAdapter = new MovieAdapter(movies, MainActivity.this);
                movieRecycler.setAdapter(movieAdapter);

            }
        },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        hideDialog();
                        Log.e("hzm", error.getMessage());
                    }
                });

        AppController.getInstance().addToRequestQueue(jsonArrayRequest);
    }

    private void showDialog() {
        progressDialog = new ProgressDialog(MainActivity.this);
        progressDialog.setCancelable(false);
        progressDialog.setTitle("Loading... ");
        progressDialog.show();
    }
    private void hideDialog() {
        progressDialog.hide();
    }

}
URL
public class URL {
    public static final String URL = "https://api.androidhive.info/json/movies.json?fbclid=IwAR2PXO8XpcGBxNxtVIew2xWJrqP23FySE46CEI7NcXTMBOPKeg1ul8yDWdE";
}
Movie
public class Movie {
    private String title;
    private String image;
    private Double rating;
    private int releaseYear;
    private String genres;

    public Movie(String title, String image, Double rating, int releaseYear, String genres) {
        this.title = title;
        this.image = image;
        this.rating = rating;
        this.releaseYear = releaseYear;
        this.genres = genres;
    }
}
AppController___appfolder
public class AppController extends Application {

    public static final String TAG = AppController.class.getSimpleName();

    private RequestQueue mRequestQueue;

    private static AppController mInstance;

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }

    public static synchronized AppController getInstance() {
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }

        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req, String tag) {
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }

    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }

    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}
MovieAdapter_recycler
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MyViewHolder> {

    ArrayList<Movie> data;
    Activity activity;

    public MovieAdapter(ArrayList<Movie> data, Activity activity) {
        this.data = data;
        this.activity = activity;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View itemView = (View) LayoutInflater.from(activity).inflate(R.layout.movie_item, viewGroup, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {

        myViewHolder.tvTitle.setText(data.get(i).getTitle() + "");
        myViewHolder.tvRating.setText(data.get(i).getRating() + "");
        myViewHolder.tvReleaseYear.setText(data.get(i).getReleaseYear()+"");
        myViewHolder.tvGenres.setText(data.get(i).getGenres());
        Picasso.get().load(data.get(i).getImage()).into(myViewHolder.tvImage);

        //myViewHolder.tvImage.set(data.get(i).getGenres());
        myViewHolder.linear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });

    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {

        public TextView tvTitle;
        public TextView tvRating;
        public TextView tvReleaseYear;
        public TextView tvGenres;
        public ImageView tvImage;
        public LinearLayout linear;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tvTitle = itemView.findViewById(R.id.tvTitle);
            tvRating = itemView.findViewById(R.id.tvRating);
            tvReleaseYear = itemView.findViewById(R.id.tvYear);
            tvGenres = itemView.findViewById(R.id.tvGenres);
            tvImage = itemView.findViewById(R.id.tvImage);
            linear = itemView.findViewById(R.id.linear);
        }
    }
}
movie_item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:id="@+id/linear"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <android.support.v7.widget.CardView
        android:padding="10dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:elevation="20dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/tvImage"
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:layout_gravity="center"
                android:layout_margin="20dp"/>

            <LinearLayout
                android:layout_gravity="center"
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:orientation="vertical">

                <TextView
                    android:layout_weight="1"
                    android:textColor="@android:color/black"
                    android:textStyle="bold"
                    android:textSize="18dp"
                    android:id="@+id/tvTitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Title" />

                <TextView
                    android:textColor="@android:color/black"
                    android:layout_weight="1"
                    android:id="@+id/tvRating"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Rating" />

                <TextView
                    android:layout_weight="1"
                    android:id="@+id/tvGenres"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Genres" />

                <TextView
                    android:textAlignment="textEnd"
                    android:layout_gravity="end"
                    android:layout_weight="1"
                    android:id="@+id/tvYear"
                    android:layout_marginRight="10dp"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="TextView" />

            </LinearLayout>



        </LinearLayout>




    </android.support.v7.widget.CardView>
</LinearLayout>
main_actvity
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/postRecycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.it.lec9_v1">
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:name=".app.AppController"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

xml RecyclerView

RecyclerAdapter
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.MyViewHolder> {

    ArrayList<Product> data;
    Activity activity;

    public ProductAdapter(ArrayList<Product> data, Activity activity) {
        this.data = data;
        this.activity = activity;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View itemView = LayoutInflater.from(activity).inflate(R.layout.product_item,viewGroup,false);
        return new ProductAdapter.MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
        myViewHolder.product_id.setText(String.valueOf(data.get(i).getId()));
        myViewHolder.product_name.setText(data.get(i).getName());
        myViewHolder.product_price.setText(String.valueOf(data.get(i).getPrice()));
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder{

        public TextView product_id;
        public TextView product_name;
        public TextView product_price;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);

            product_id = itemView.findViewById(R.id.product_id);
            product_name = itemView.findViewById(R.id.product_name);
            product_price = itemView.findViewById(R.id.product_price);

        }
    }
}
MainActivity
public class MainActivity extends AppCompatActivity {

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

        RecyclerView recyclerView = findViewById(R.id.productRecyclerView);
        ArrayList<Product> data = new ArrayList<>();

        for(int i=0; i<100;i++){
            data.add(new Product(i,"Product "+i,99.9));
        }

        ProductAdapter productAdapter = new ProductAdapter(data,this);
        recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));

        recyclerView.setAdapter(productAdapter);
    }
}
product
public class Product {

    private int id;
    private String name;
    private double price;

    public Product(int id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
activity_main
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/productRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.constraint.ConstraintLayout>
list_item
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:elevation="@dimen/cardview_default_elevation">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical">

            <TextView
                android:id="@+id/product_id"
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:text="Product ID" />

            <TextView
                android:id="@+id/product_name"
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:text="Product Name" />

            <TextView
                android:id="@+id/product_price"
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:text="Product Price" />

        </LinearLayout>



    </android.support.v7.widget.CardView>

</android.support.constraint.ConstraintLayout>

xml ImagePicker(Camera或Galery)https://github.com/jrvansuita/PickImage

MainActivity
public class MainActivity extends AppCompatActivity implements IPickResult {

    Button addImage;

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

        addImage = findViewById(R.id.add_news_image);

        addImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PickImageDialog.build(new PickSetup()).show(MainActivity.this);
            }
        });


    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void onPickResult(PickResult pickResult) {
        BitmapDrawable ob = new BitmapDrawable(getResources(), pickResult.getBitmap());
        addImage.setBackground(ob);
    }
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/add_news_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:hint="عنوان الخبر"
        android:textSize="24sp" />

    <EditText
        android:hint="وقت الخبر"
        android:layout_margin="5dp"
        android:textSize="15sp"
        android:id="@+id/add_news_time"
        android:layout_gravity="end"
        android:layout_width="100dp"
        android:layout_height="wrap_content" />

    <Button

        android:id="@+id/add_news_image"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:text="Click To Add Image"
        android:layout_gravity="center" />

    <EditText
        android:hint="وصف الخبر"
        android:layout_margin="5dp"
        android:textSize="20sp"
        android:id="@+id/add_news_description"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:layout_width="wrap_content"
        android:layout_gravity="center"
        android:layout_height="wrap_content"
        android:text="Add News"/>





</LinearLayout>

xml ListView + SQLiteDatabase

CustomAdapter
public class CustomAdapter extends BaseAdapter {

    Activity activity;
    ArrayList<Student> data;
    LayoutInflater layoutInflater;

    public CustomAdapter(Activity activity, ArrayList<Student> data) {
        this.activity = activity;
        this.data = data;
        layoutInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return data.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View root = convertView;
        if(root == null){
            root = layoutInflater.inflate(R.layout.student_list_item,null);
        }

        TextView studentName = root.findViewById(R.id.student_name);
        TextView studentAvg = root.findViewById(R.id.student_avg);

        studentName.setText("Name: "+data.get(position).getName());
        studentAvg.setText("Avg: "+data.get(position).getAvg());

        return root;
    }
}
DatabaseHelper
public class DbHelper extends SQLiteOpenHelper {

    SQLiteDatabase sqLiteDatabase;

    public DbHelper(Context context) {
        super(context, Student.DB_NAME, null, 1);
        sqLiteDatabase = getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(Student.CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(Student.DROP_TABLE);
        onCreate(sqLiteDatabase);
    }

    public boolean insertStudent(String name,String average){
        ContentValues contentValues = new ContentValues();
        contentValues.put(Student.COL_NAME,name);
        contentValues.put(Student.COL_AVERAGE,average);
        return sqLiteDatabase.insert(Student.TABLE_NAME,null,contentValues)>0;
    }

    public boolean updateStudent(String oldID, String name,String average){
        ContentValues contentValues = new ContentValues();
        contentValues.put(Student.COL_NAME,name);
        contentValues.put(Student.COL_AVERAGE,average);
        return sqLiteDatabase.update(Student.TABLE_NAME,contentValues,Student.COL_ID+"= ?",new String[]{oldID})>0;
    }

    public boolean deleteStudent(String oldID){
        return sqLiteDatabase.delete(Student.TABLE_NAME,Student.COL_ID+"= ?",new String[]{oldID})>0;
    }

    public ArrayList<Student> getAllStudents(){
        ArrayList<Student> studentArrayList = new ArrayList<>();

        String query = "SELECT * FROM"+Student.TABLE_NAME+"ORDER BY ID DESC";
        Cursor cursor = sqLiteDatabase.rawQuery(query,null);

        if(cursor.moveToFirst()){
            do {
                Student student = new Student();
                student.setId(cursor.getString(cursor.getColumnIndex("id")));
                student.setName(cursor.getString(cursor.getColumnIndex("name")));
                student.setAvg(cursor.getString(cursor.getColumnIndex("average")));

                studentArrayList.add(student);
            }while (cursor.moveToNext());
        }
        cursor.close();
        return studentArrayList;
    }
}
Student
public class Student {

    public static final String DB_NAME = " university ";
    public static final String TABLE_NAME = " students ";

    public static final String COL_ID = " id ";
    public static final String COL_NAME = " name ";
    public static final String COL_AVERAGE = " average ";

    public static final String CREATE_TABLE =
            "CREATE TABLE "+TABLE_NAME+"("
            +COL_ID+" INTEGER PRIMARY KEY AUTOINCREMENT,"
            +COL_NAME+"TEXT,"
            +COL_AVERAGE+"FLOAT)";

    public static final String DROP_TABLE = "DROP TABLE IF EXISTS"+TABLE_NAME;

    String id;
    String name;
    String avg;

    public Student(String id, String name, String avg) {
        this.id = id;
        this.name = name;
        this.avg = avg;
    }
}
MainActivity_addToDB
public class MainActivity extends AppCompatActivity {

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

        final DbHelper dbHelper = new DbHelper(this);

        final EditText studentName = findViewById(R.id.nameEditText);
        final EditText studentAvg = findViewById(R.id.avgEditText);
        Button addStudentButton = findViewById(R.id.addButton);
        Button getAllStudentsButton = findViewById(R.id.getStudentsButton);

        addStudentButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(dbHelper.insertStudent(studentName.getText().toString(),studentAvg.getText().toString())){
                        Toast.makeText(MainActivity.this, "Student Added Successfully", Toast.LENGTH_SHORT).show();
                }
                else{
                    Toast.makeText(MainActivity.this, "Insertion Failed", Toast.LENGTH_SHORT).show();
                }
            }
        });

        getAllStudentsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,StudentList.class);
                startActivity(intent);
            }
        });
    }
}
DBListActivity
public class StudentList extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_student_list);

        DbHelper dbHelper = new DbHelper(this);
        ListView listView = findViewById(R.id.studentListView);

        CustomAdapter customAdapter = new CustomAdapter(this,dbHelper.getAllStudents());
        listView.setAdapter(customAdapter);
    }
}
student_list_item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_margin="5dp">

    <ImageView
        android:src="@mipmap/ic_launcher"
        android:id="@+id/student_image"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_margin="5dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >

        <TextView
            android:id="@+id/student_name"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:text="Name: "
            android:textAlignment="center"
            android:textColor="#000"
            android:textSize="18sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/student_avg"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:text="Avg: "
            android:textAlignment="center"
            android:textColor="#000"
            android:textSize="14sp" />

    </LinearLayout>

</LinearLayout>
student_list_activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".StudentList">

    <ListView
        android:id="@+id/studentListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
main_activity
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:textAlignment="center"
        android:id="@+id/nameEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="100dp"
        android:ems="10"
        android:hint="Student Name"
        android:inputType="textPersonName" />

    <EditText
        android:textAlignment="center"
        android:id="@+id/avgEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="161dp"
        android:ems="10"
        android:hint="Student Average"
        android:inputType="textPersonName"/>

    <Button
        android:id="@+id/addButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="180dp"
        android:text="Add Student" />

    <Button
        android:id="@+id/getStudentsButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="109dp"
        android:text="Get All Students" />
</RelativeLayout>

xml ListView CustomAdapter + Intent Serializable

CustomAdapter
public class CustomAdapter extends BaseAdapter {

    Activity activity;
    ArrayList<Movie> data;
    LayoutInflater layoutInflater;

    public CustomAdapter(Activity activity, ArrayList<Movie> data) {
        this.activity = activity;
        this.data = data;
        layoutInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return data.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View root = convertView;
        if(root == null){
            root = layoutInflater.inflate(R.layout.movie_item,null);
        }
        ImageView movie_poster = root.findViewById(R.id.movie_poster);
        TextView movie_title = root.findViewById(R.id.movie_title);
        TextView movie_rating = root.findViewById(R.id.movie_rating);
        TextView movie_genres = root.findViewById(R.id.movie_genres);
        TextView movie_year = root.findViewById(R.id.movie_year);

        movie_poster.setImageResource(data.get(position).getPoster());
        movie_title.setText(data.get(position).getTitle());
        movie_rating.setText(Double.toString(data.get(position).getRating()));
        movie_year.setText(Integer.toString(data.get(position).getYear()));

        StringBuilder genres = new StringBuilder();
        ArrayList<String> genresArrayList = data.get(position).getGenres();
        for (int i=0;i<genresArrayList.size();i++){
            genres.append(genresArrayList.get(i));
            if(i+1!=genresArrayList.size()){
                genres.append(", ");
            }
        }
        movie_genres.setText(genres.toString());
        return root;
    }
}
Movie
public class Movie implements Serializable {
    private int id;
    private String title;
    private int poster;
    private double rating;
    private ArrayList<String> genres;
    private int year;
    private String description;

    public Movie(int id, String title, int poster, double rating, ArrayList<String> genres, int year, String description) {
        this.id = id;
        this.title = title;
        this.poster = poster;
        this.rating = rating;
        this.genres = genres;
        this.year = year;
        this.description = description;
    }
}
MainActivity
public class MainActivity extends AppCompatActivity {

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

        final ListView movieListView = findViewById(R.id.moviewListView);
        final ArrayList<Movie> movies = new ArrayList<>();


        movies.add(new Movie(1,"The Shawshank Redemption", R.drawable.shawshank,9.3,new ArrayList<String>(Arrays.asList("Drama")),1994,"Chronicles the experiences of a formerly successful banker as a prisoner in the gloomy jailhouse of Shawshank after being found guilty of a crime he did not commit. The film portrays the man's unique way of dealing with his new, torturous life; along the way he befriends a number of fellow prisoners, most notably a wise long-term inmate named Red."));

        movies.add(new Movie(2,"The Godfather",R.drawable.godfather,9.2,new ArrayList<String>(Arrays.asList("Crime","Drama")),1972,"When the aging head of a famous crime family decides to transfer his position to one of his subalterns, a series of unfortunate events start happening to the family, and a war begins between all the well-known families leading to insolence, deportation, murder and revenge, and ends with the favorable successor being finally chosen."));

        movies.add(new Movie(1,"The Shawshank Redemption", R.drawable.shawshank,9.3,new ArrayList<String>(Arrays.asList("Drama")),1994,"Chronicles the experiences of a formerly successful banker as a prisoner in the gloomy jailhouse of Shawshank after being found guilty of a crime he did not commit. The film portrays the man's unique way of dealing with his new, torturous life; along the way he befriends a number of fellow prisoners, most notably a wise long-term inmate named Red."));

        movies.add(new Movie(2,"The Godfather",R.drawable.godfather,9.2,new ArrayList<String>(Arrays.asList("Crime","Drama")),1972,"When the aging head of a famous crime family decides to transfer his position to one of his subalterns, a series of unfortunate events start happening to the family, and a war begins between all the well-known families leading to insolence, deportation, murder and revenge, and ends with the favorable successor being finally chosen."));

        movies.add(new Movie(1,"The Shawshank Redemption", R.drawable.shawshank,9.3,new ArrayList<String>(Arrays.asList("Drama")),1994,"Chronicles the experiences of a formerly successful banker as a prisoner in the gloomy jailhouse of Shawshank after being found guilty of a crime he did not commit. The film portrays the man's unique way of dealing with his new, torturous life; along the way he befriends a number of fellow prisoners, most notably a wise long-term inmate named Red."));

        movies.add(new Movie(2,"The Godfather",R.drawable.godfather,9.2,new ArrayList<String>(Arrays.asList("Crime","Drama")),1972,"When the aging head of a famous crime family decides to transfer his position to one of his subalterns, a series of unfortunate events start happening to the family, and a war begins between all the well-known families leading to insolence, deportation, murder and revenge, and ends with the favorable successor being finally chosen."));

        movies.add(new Movie(1,"The Shawshank Redemption", R.drawable.shawshank,9.3,new ArrayList<String>(Arrays.asList("Drama")),1994,"Chronicles the experiences of a formerly successful banker as a prisoner in the gloomy jailhouse of Shawshank after being found guilty of a crime he did not commit. The film portrays the man's unique way of dealing with his new, torturous life; along the way he befriends a number of fellow prisoners, most notably a wise long-term inmate named Red."));

        movies.add(new Movie(2,"The Godfather",R.drawable.godfather,9.2,new ArrayList<String>(Arrays.asList("Crime","Drama")),1972,"When the aging head of a famous crime family decides to transfer his position to one of his subalterns, a series of unfortunate events start happening to the family, and a war begins between all the well-known families leading to insolence, deportation, murder and revenge, and ends with the favorable successor being finally chosen."));




        CustomAdapter customAdapter = new CustomAdapter(this,movies);

        movieListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent intent = new Intent(MainActivity.this,MovieDescription.class);
                intent.putExtra("movie",movies.get(position));
                startActivity(intent);
            }
        });

        movieListView.setAdapter(customAdapter);


    }
}
itemPage
public class MovieDescription extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_description);

        Bundle bundle = getIntent().getExtras();

        if(bundle!=null){
            Movie movie = (Movie) bundle.getSerializable("movie");

            TextView selected_movie_description = findViewById(R.id.selected_movie_description);
            TextView selected_movie_title = findViewById(R.id.selected_movie_title);
            ImageView selected_movie_poster = findViewById(R.id.selected_movie_poster);

            selected_movie_description.setText(movie.getDescription());
            selected_movie_title.setText(movie.getTitle());
            selected_movie_poster.setImageResource(movie.getPoster());
        }
    }
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/moviewListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.constraint.ConstraintLayout>
movieItem
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_margin="5dp">

    <ImageView
        android:src="@mipmap/ic_launcher"
        android:id="@+id/movie_poster"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_margin="5dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <TextView
            android:textStyle="bold"
            android:text="Movie Title"
            android:textColor="#000"
            android:textSize="18sp"
            android:id="@+id/movie_title"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <TextView
            android:text="Rating: "
            android:textColor="#000"
            android:textSize="14sp"
            android:id="@+id/movie_rating"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <TextView
            android:textStyle="bold"
            android:text="Movie genres"
            android:textSize="12sp"
            android:id="@+id/movie_genres"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <TextView
            android:text="Year"
            android:textSize="12sp"
            android:id="@+id/movie_year"
            android:gravity="end"
            android:layout_marginRight="10dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

</LinearLayout>
moviePage
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MovieDescription"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_margin="20dp">

        <ImageView
            android:layout_margin="10dp"
            android:id="@+id/selected_movie_poster"
            android:layout_width="200dp"
            android:layout_height="200dp" />

        <TextView
            android:id="@+id/selected_movie_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            />

    </LinearLayout>




    <TextView
        android:textColor="@android:color/black"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Movie Description:"
        android:textSize="24dp"
        android:layout_marginBottom="12dp"/>

    <TextView
        android:id="@+id/selected_movie_description"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:textSize="18dp" />


</LinearLayout>

xml ListView CustomAdapter

adapter
public class CustomAdapter extends BaseAdapter {

    Activity activity;
    ArrayList<Product> data;
    LayoutInflater layoutInflater;

    public CustomAdapter(Activity activity, ArrayList<Product> data) {
        this.activity = activity;
        this.data = data;
        layoutInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return data.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View root = convertView;
        if(root == null){
            root = layoutInflater.inflate(R.layout.product_item,null);
        }
        ImageView product_image = root.findViewById(R.id.product_image);
        TextView product_title = root.findViewById(R.id.product_title);
        TextView product_summary = root.findViewById(R.id.product_summary);

        product_image.setImageResource(data.get(position).getImage());
        product_title.setText(data.get(position).getTitle());
        product_summary.setText(data.get(position).getSummary());
        return root;
    }
}
product
public class Product {
    private int id;
    private int image;
    private String title;
    private String summary;

    public Product(int id, int image, String title, String summary) {
        this.id = id;
        this.image = image;
        this.title = title;
        this.summary = summary;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }
}
activity
//listview
final ListView dataListView = findViewById(R.id.dataListView);
//gridview 
//final GridView dataListView = findViewById(R.id.dataGridView);

ArrayList<Product> products = new ArrayList<>();
products.add(new Product(1,R.drawable.apple,"Apple","Apppppppppppple"));
products.add(new Product(2,R.drawable.android,"Android","Anddrrooooiiiiid"));
products.add(new Product(3,R.drawable.apple,"Apple","Apppppppppppple"));
products.add(new Product(4,R.drawable.android,"Android","Anddrrooooiiiiid"));
products.add(new Product(5,R.drawable.apple,"Apple","Apppppppppppple"));
products.add(new Product(6,R.drawable.android,"Android","Anddrrooooiiiiid"));
products.add(new Product(7,R.drawable.apple,"Apple","Apppppppppppple"));
CustomAdapter customAdapter = new CustomAdapter(this,products);
dataListView.setAdapter(customAdapter);
product_list_item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <ImageView
        android:src="@mipmap/ic_launcher"
        android:id="@+id/product_image"
        android:layout_width="100dp"
        android:layout_height="100dp" />

    <LinearLayout

        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:textAlignment="center"
            android:text="Product Title"
            android:textColor="#000"
            android:textSize="24sp"
            android:id="@+id/product_title"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <TextView
            android:textAlignment="center"
            android:text="Product Summary"
            android:textSize="14sp"
            android:id="@+id/product_summary"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

</LinearLayout>
activity_main
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
/*
    <GridView
        android:numColumns="2"
        android:id="@+id/dataGridView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
*/
    <ListView
        android:id="@+id/dataListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.constraint.ConstraintLayout>

xml 自动短信阅读器

使用广播reciver自动读取短信

SmsReciver
import android.content.BroadcastReceiver;
        import android.content.Context;
        import android.content.Intent;
        import android.os.Bundle;
        import android.support.v4.content.LocalBroadcastManager;
        import android.telephony.SmsManager;
        import android.telephony.SmsMessage;
        import android.util.Log;

        import java.util.regex.Matcher;
        import java.util.regex.Pattern;

public class SmsReceiver extends BroadcastReceiver {

    private static SmsListener mListener;
    Boolean b;
    String abcd,xyz;

    private static String  TAG = "";

    @Override
    public void onReceive(Context context, Intent intent) {

        Bundle bundle = intent.getExtras();
        SmsMessage[] smsm = null;
        String sms_str ="";

        if (bundle != null)
        {
            // Get the SMS message
            Object[] pdus = (Object[]) bundle.get("pdus");
            smsm = new SmsMessage[pdus.length];

            for (int i=0; i<smsm.length; i++){
                smsm[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
                sms_str += smsm[i].getMessageBody().toString();

                String Sender = smsm[i].getOriginatingAddress();
                //Check here sender is yours
                Intent smsIntent = new Intent("otp");

                String pattern = String.valueOf(Pattern.compile( "(\\d{4})"));
                Log.d(TAG, "onReceive: "+pattern);
                // Create a Pattern object
                Pattern filter = Pattern.compile(pattern);

                // Now create matcher object.
                Matcher m = filter.matcher(sms_str);
                Log.d(TAG, "onReceive: filtered " + m);
                smsIntent.putExtra("message",sms_str);
                Log.d(TAG, "onReceive: " + sms_str);
                LocalBroadcastManager.getInstance(context).sendBroadcast(smsIntent);
            }
        }
    }

// methd for communication sending sms to actvity
    public static void bindListener(SmsListener listener) {
        mListener = listener;
    }

}
MainActivity
 private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equalsIgnoreCase("otp")) {
                final String message = intent.getStringExtra("message");
//                editTextOtp.setText(message);
//                firstDigitOtpEdt.setText(message);
                myString = message;

                String[] digitsArray = myString.split("");
                firstDigitOtpEdt.setText(digitsArray[1]);
                secondDigitOtpEdt.setText(digitsArray[2]);
                thirdDigitOtpEdt.setText(digitsArray[3]);
                fourthDigitOtpEdt.setText(digitsArray[4]);
                //Do whatever you want with the code here
            }
        }
    };
    
      @Override
    public void onResume() {
        LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter("otp"));
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
    }
    
    onCreate(Bundle s) {
      checkPermissions();
    }
    
    private void checkPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if ((ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_GRANTED)
                    && (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) == PackageManager.PERMISSION_GRANTED)) {
                receiveOtp();
            } else {
                ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST);
            }
        } else {
            receiveOtp();
        }
    }
    
    // recving otp from broadcast reciver
     private void receiveOtp() {
        SmsReceiver.bindListener(new SmsListener() {
            @Override
            public void messageReceived(String messageText) {
                myString = messageText;
            }
        });
    }
    
    //result of runtime permission 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST) {
            if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "Please Enable sms read and recieve permissions for auto OTP", Toast.LENGTH_LONG).show();
            } else {
                receiveOtp();
            }
        }
    }

SmsListener
public interface SmsListener {
    public void messageReceived(String messageText);
}

// interface for communicating otp
otpview
 <LinearLayout
        android:id="@+id/otpView"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center_horizontal"
        android:orientation="horizontal"
        app:layout_constraintBottom_toTopOf="@+id/linearLayout"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2">

        <EditText
            android:id="@+id/et1"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:inputType="number"
            android:maxLength="1"
            android:textAlignment="center"
            android:theme="@style/Theme.App.Base" />

        <android.support.v4.widget.Space
            android:layout_width="2dp"
            android:layout_height="0dp" />

        <EditText
            android:id="@+id/et2"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:inputType="number"
            android:maxLength="1"
            android:textAlignment="center"
            android:theme="@style/Theme.App.Base" />

        <android.support.v4.widget.Space
            android:layout_width="2dp"
            android:layout_height="0dp" />

        <EditText
            android:id="@+id/et3"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:inputType="number"
            android:maxLength="1"
            android:textAlignment="center"
            android:theme="@style/Theme.App.Base" />

        <android.support.v4.widget.Space
            android:layout_width="2dp"
            android:layout_height="0dp" />

        <EditText
            android:id="@+id/et4"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:inputType="number"
            android:maxLength="1"
            android:textAlignment="center"
            android:theme="@style/Theme.App.Base" />

        <android.support.v4.widget.Space
            android:layout_width="2dp"
            android:layout_height="0dp" />


    </LinearLayout>