Este Demo Tiene 4 Fragment:
- Noticia: Se Utiliza (Async GET , JsonString)
- Trasductor: Se Utiliza (Async POST , Form Parameters Request)
- Descarga: Se Utiliza(Async GET , ByteStream)
- FACE: Se Utiliza (Async POST, Multipart Request)
Main
Layout:
Activity:
- Creamos Un Adapter Para ViewPager
public class JS_FragmentPagerAdapter extends FragmentStatePagerAdapter { //FragmentStatePagerAdapter Se herencia de PagerAdapter
private List mList; // Lista T=> depende Si meter Avtivity o Fragment
private String[] content; // Títulos que Mostrar al TabLayout
public JS_FragmentPagerAdapter(FragmentManager fm,List list, String content[]) {
super(fm);
this.mList = list;
this.content = content;
}
@Override
public Fragment getItem(int position) {
return mList.get(position);
}
@Override
public int getCount() {
return mList.size();
}
@Override
public CharSequence getPageTitle(int position){
return content[position % content.length];
}
}
- MainActivity
/*Variable */
// Títulos Que Va a Poner Cada Fragment
String content[] = {"Traduct","Noticia","Descarga","Face"};
// Lista De Fragments
private ArrayList fragments = new ArrayList<>();
/**
* Códigos Que Falta:
* Aqui Tiene Que Inicial Los Fragments Y Mete A La Lista De Fragments
**/
/*Ajustar*/
JS_FragmentPagerAdapter adapter = new JS_FragmentPagerAdapter(getSupportFragmentManager(),fragments,content);
pagerView.setAdapter(adapter);
tabLayout.setupWithViewPager(pagerView);
tabLayout.setTabMode(TabLayout.MODE_FIXED); // Mode que Mostrar
FRAGMENTS
Fragment => Noticia
-
Layout
NoticiaRecycleView -> ItemRecycleView -> ItemCardView
-
Ademas El Item Para Mostrar Detalle de Cada Tema Es Un CardView
-
Step:
- Inicial RecycleView
Sin Códigos(Es Sencillo)
- Hace Request (Petición)
final Request request = new Request.Builder()// Request
.url(Constant.NOTICIA_URL)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback){
@Override
public void onFailure(Call call, IOException e) {
// Error Connection
}
public void onResponse(Call call, Response response) throws IOException {
// 1 . Guardar Json Con SharedPreferences Como Cache
// 2. Utilizar Gson ,Parse Json A Objeto
// 3. Descarga Imagen Con IntentService
// 4. Set Adapter Para Pintar UI
}
}
- Cache Con SharedPreferences
[ En Fragment
/*
* Cache Propio
* */
private static final String JSON_CACHE = "noticia_Json";
private static final String JSON_CACHE_TIME_OUT = "CACHE_TIME_OUT";
private static final String JSON_CACHE_LAST_SUCCESS = "noticia_Json_last";
]
[ Crear Un Class De Herramiento Por Ejemplo, Aquí Necesitamos ,String Para Json , Int Para Time_Out , long Para El Tiempo De La Ultima Vez De Perticion]
public class SharePrenceUtil {
public static final String XML_FILE_NAME = "cache";
/*
* Guardar String A SharedPreferences
* */
public static void saveString(Context context, String title, String content) {
SharedPreferences share = context.getSharedPreferences(XML_FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = share.edit();
editor.putString(title, content);
editor.apply();
}
/*
* Sacar String
* */
public static String getString(Context context, String title) {
String content;
SharedPreferences share = context.getSharedPreferences(XML_FILE_NAME,Context.MODE_PRIVATE);
content = share.getString(title,"");
return content;
}
public static void savaInt(Context context, String title, int content){
//Codigo
}
public static int getInt(Context context, String title){
//Codigo
}
public static void savaLong(Context context, String title, long content){
// Codigo
}
public static long getLong(Context context, String title){
//Codigo
}
- Json A Objeto (Gson)
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.0'
Usar:
Gson gson = new Gson();
XXX xxx = gson.fromJson(json,xxx.class);
XXX => Es Nombre De Objeto
// Creamos Un Objeto Para Guardar Los Valores De Json
public class Noticias implements Serializable{
/*
String XXX;
getXXX(){}
setXXX(){}
*/
}
- Descarga Imagen Con IntentService
// Si Hay Imagen , Ya Podemos Descargar
public class DownloadImageService extends IntentService {
// Obligatorio:
/**
* Creates an IntentService. Invoked by your subclass's constructor
*/
public DownloadImageService() {
super("DownloadImageService");
}
// Aqui Uso URLConnection Para Conseguir Stream,Y Decode Con Bitmap , Ejemplo:
URLConnection urlConnection = url.openConnection();
Bitmap bitmap = BitmapFactory.decodeStream(urlConnection.getInputStream());
// Y Guardar Al SD Con FileOutputSream
FileOutputStream outputStream = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG,50,outputStream);
}
Nesecita Permisos ,Si Va Toca SD
- recycleView.setAdapter(adapter)
Fragment => Traductor
-
Layout
Funcionalidad
//RequestBody
RequestBody requestBody = new FormBody.Builder()
.add(QUERY,con)
.add(FROM,from_id)
.add(TO,to_id)
.add(APP_ID,appid)
.add(SALT,salt)
.add(SIGN,sign)
.build();
//Request
final Request request = new Request.Builder()
.url(Constant.TRANS_URL)
.post(requestBody)
.build();
Aqui Se Utiliza (Posting form parameters)
Fragment => Descarga
-
Layout
Funcionalida
public synchronized void start(){
if (isDownloading)return;
isDownloading = true;
try {
httpUtil.getContentLength(fileOffet.getUrl(), new okhttp3.Callback() {
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful() && response.code() != 200){
close(response.body());
resetStatus();
return;
}
// Conseguir Recurso
fileLength = response.body().contentLength();
// Gestion I/O
close(response.body());
// Crear un holderFile ,para Ocupar SD => .tmp => invisible can not eliminar
tmpFile = new File(fileOffet.getFilePath(),fileOffet.getFileName());
if (!tmpFile.getParentFile().exists()) {tmpFile.getParentFile().mkdirs();}
RandomAccessFile tmpAccessFile = new RandomAccessFile(tmpFile,"rw"); // Read y Write
tmpAccessFile.setLength(fileLength);
//Start Task => difrentes Hilos
//Estimar size que var a descargar en cada Hilo
long threadSize = fileLength / THREAD_COUNT;
for (int threadId = 0; threadId< THREAD_COUNT; threadId++){
long startIndex = threadId * threadSize;
long endIndex = (threadId + 1) * threadSize - 1;
if (threadId == (THREAD_COUNT - 1)){endIndex = fileLength - 1;}
try { download(startIndex,endIndex,threadId);}
catch (Exception e) { e.printStackTrace();}
}
}
@Override
public void onFailure(Call call, IOException e) {
resetStatus();
}
});
} catch (Exception e) {
e.printStackTrace();
resetStatus();
}
}
private void download(final long startIndex, final long endIndex, final int threadId)throws Exception{
long newStartIndex = startIndex;
final File cacheFile = new File(fileOffet.getFilePath(),"thread"+threadId+"_"+fileOffet.getFileName()+".cache");
cacheFiles[threadId] = cacheFile;
final RandomAccessFile cacheAccessFile = new RandomAccessFile(cacheFile,"rwd");
if (cacheFile.exists()){// Si La Carpeta De Cache Existe File ,Entonces Sigue Descargando
String startIndexStr = cacheAccessFile.readLine();
try{newStartIndex = Integer.parseInt(startIndexStr);}catch (Exception e){
e.printStackTrace();
}
}
private final int THREAD_COUNT = 4; // Maximo 4 Hilos Para Descarga
Se Utilizar ByteStream ( I/O )
Fragment => Face
Es Para Verificar La Imagen Del Facial
-
Layout
Funcionalidad
Si Va Subir Una Imagen ,Tiene Que Tener MediaType , "image/png" etc...
sp:
Para Pintar En Async :
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
//Codigo ,Aqui Ya Esta En El Hilo Principal
}
});
Apartir Api 23 Permiso
/*
* Verificar Permisos
* */
private void verificaRPermission(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
pedirPermiso();
}
}
}
/*
* Perdir Permisos
* */
private void pedirPermiso(){
if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)){
configurarPermiso();
} else {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}
}