Hi everyone is there anybody who has ever worked with Valor Wave F7020? I want to be able to use the fingerprint capability of the device but most of the stuff are in chinese. I have their sample code but I don't know how to make it work.
When I run it whatever I press I get a response in chinese and the captions also are in in chinese
package com.hdsoft.fingerprint;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import com.pwv.gpctrl.fctrl;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
//import android.util.Log;
//import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class LibFpDemo extends Activity {
private static final int MSG_CMD = 0;
private static final int MSG_EXIT = 1;
private static final int MSG_INFO = 2;
private static final int MSG_FIND = 3;
private static final int MSG_CANCEL = 4;
private boolean bContinue = true;
private fctrl gpctrl = new fctrl();
private Button btOpen, btImage, btEnrol, btMatch, btEmpty, btCancel;
private TextView tvInfo;
private static final String TAG = "finger";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gpctrl.SetValue(32, 1);
gpctrl.GetValue(32);
tvInfo = (TextView)findViewById(R.id.tvInfo);
// btOpen = (Button)findViewById(R.id.btOpen);
btImage = (Button)findViewById(R.id.btImage);
btEnrol = (Button)findViewById(R.id.btEnrol);
btMatch = (Button)findViewById(R.id.btMatch);
btEmpty = (Button)findViewById(R.id.btEmpty);
btCancel = (Button)findViewById(R.id.btCancel);
final ImageView iv = (ImageView)findViewById(R.id.imageView1);
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_CMD:
tvInfo.setText(LibFp.GetError(msg.arg1));
if (msg.arg1 == LibFp.FP_OK) {
optFinish();
}
else if (msg.arg1 == LibFp.FP_ERROR_DRIVE) {
closeDrive();
}
break;
case MSG_EXIT:
tvInfo.setText(LibFp.GetError(msg.arg1));
if (msg.arg1 == LibFp.FP_ERROR_DRIVE) {
closeDrive();
}
else {
optFinish();
}
break;
case MSG_INFO:
switch (msg.arg1) {
case 0:
tvInfo.setText("¼ÈëÖ¸ÎÆ, Çë°´ÊÖÖ¸...");
break;
case 1:
tvInfo.setText("ÇëÒÆ¿ªÊÖÖ¸...");
break;
case 2:
tvInfo.setText("Ö¸ÎƳɹ¦Èë¿â, µØÖ·±àºÅ = " + msg.arg2 + ", Çë°´ÊÖÖ¸¼ÌÐø¼Èë...");
break;
default:
break;
}
break;
case MSG_FIND:
optFinish();
tvInfo.setText("Ö¸ÎÆÆ¥Åä³É¹¦, ´æ·ÅµØÖ· = " + msg.arg1 + "±È¶ÔµÃ·Ö = " + msg.arg2);
break;
case MSG_CANCEL:
bContinue = true;
optFinish();
switch (msg.arg1) {
case 0:
tvInfo.setText("²Ù×÷ÒÑÈ¡Ïû...");
break;
default:
break;
}
break;
default:
break;
}
super.handleMessage(msg);
}
};
openDrive();
// btOpen.setOnClickListener(new View.OnClickListener()
// {
// #Override
// public void onClick(View v)
// {
// int nRet = LibFp.FpOpenEx((short)0x2109, (short)0x7638);
// Toast.makeText(LibFpDemo.this,nRet+"111", Toast.LENGTH_SHORT).show();
// if (nRet == LibFp.FP_ERROR_OPEN) {
// LibFp.GetRootRight();
// Toast.makeText(LibFpDemo.this,nRet+"22222222", Toast.LENGTH_SHORT).show();
// nRet = LibFp.FpOpenEx((short)0x2109, (short)0x7638);
// Toast.makeText(LibFpDemo.this,nRet+"444444444444444444", Toast.LENGTH_SHORT).show();
// }
// Toast.makeText(LibFpDemo.this,nRet+"5555555555555555555555555555555", Toast.LENGTH_SHORT).show();
// if (nRet == LibFp.FP_OK) {
// openDrive();
// }
// else {
// System.out.println(nRet+"444444444444444444");
// tvInfo.setText(LibFp.GetError(nRet));
// }
// }
// });
btImage.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
open();
optStart();
bContinue = true;
new Thread(new Runnable() {
public void run() {
byte bmpData[] = new byte[256*288+1078];
int bmpSize[] = new int[1];
while (bContinue) {
int nRet = LibFp.FpGetImage(0xffffffff, 10000);
if (nRet == LibFp.FP_OK) {
if ((nRet = LibFp.FpUpBMP(0xffffffff, bmpData, 256*288 + 1078, bmpSize, 10000)) == LibFp.FP_OK) {
final Bitmap bm = BitmapFactory.decodeByteArray(bmpData, 0, 256*288 + 1078);
iv.post(new Runnable() {
public void run() {
iv.setImageBitmap(bm);
}
});
}
}
else{
sendInfo(handler, MSG_CMD, 2);
}
// if (nRet == LibFp.FP_NO_FINGER) {
// try {
// Thread.sleep(150);
// } catch (InterruptedException e) {
// }
// }
// else {
// return;
// }
}
sendInfo(handler, MSG_CANCEL, 0);
}}).start();
}
});
btEnrol.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
open();
optStart();
bContinue = true;
new Thread(new Runnable() {
public void run() {
byte nBufferId = 1;
byte bmpData[] = new byte[256*288+1078];
int bmpSize[] = new int[1];
short nPageId[] = new short[1];
if (LibFp.FpValidTempleteNum(0xffffffff, nPageId, 10000) != LibFp.FP_OK) return;
sendInfo(handler, MSG_INFO, 0);
while (bContinue) {
int nRet = LibFp.FpGetImage(0xffffffff, 10000);
if (nRet == LibFp.FP_OK) {
if ((nRet = LibFp.FpGenChar(0xffffffff, nBufferId, 10000)) == LibFp.FP_OK) {
if ((nRet = LibFp.FpGetImage(0xffffffff, 10000)) == LibFp.FP_OK) {
if ((nRet = LibFp.FpUpBMP(0xffffffff, bmpData, 256*288 + 1078, bmpSize, 10000)) == LibFp.FP_OK) {
final Bitmap bm = BitmapFactory.decodeByteArray(bmpData, 0, 256*288 + 1078);
iv.post(new Runnable() {
public void run() {
iv.setImageBitmap(bm);
}
});
sendInfo(handler, MSG_INFO, 1);
while ((nRet = LibFp.FpGetImage(0xffffffff, 10000)) != LibFp.FP_NO_FINGER) {
if (nRet != LibFp.FP_OK) {
sendInfo(handler, MSG_EXIT, nRet);
return;
}
if (!bContinue) {
sendInfo(handler, MSG_CANCEL, 0);
return;
}
try {
Thread.sleep(150);
} catch (InterruptedException e) {
}
}
}
}
if (nBufferId == 2) {
if ((nRet = LibFp.FpRegModel(0xffffffff, 10000))== LibFp.FP_OK) {
if ((nRet = LibFp.FpStoreChar(0xffffffff, nBufferId, nPageId[0], 10000)) == LibFp.FP_OK) {
sendInfo(handler, MSG_INFO, 2, nPageId[0]);
nBufferId = 1;
nPageId[0] += 1;
}
}
if (nRet != LibFp.FP_OK) {
sendInfo(handler, MSG_EXIT, nRet);
return;
}
}
else {
nBufferId = 2;
sendInfo(handler, MSG_INFO, 0);
}
}
}
if (nRet != LibFp.FP_OK && nRet != LibFp.FP_NO_FINGER) {
sendInfo(handler, MSG_EXIT, nRet);
return;
}
}
sendInfo(handler, MSG_CANCEL, 0);
}
}).start();
}
});
btMatch.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
open();
optStart();
bContinue = true;
new Thread(new Runnable() {
public void run() {
byte bmpData[] = new byte[256*288+1078];
int bmpSize[] = new int[1];
short nNum[] = new short[1];
short nAddr[] = new short[1];
short nScore[] = new short[1];
if (LibFp.FpValidTempleteNum(0xffffffff, nNum, 10000) != LibFp.FP_OK) return;
while (bContinue) {
int nRet = LibFp.FpGetImage(0xffffffff, 10000);
if (nRet == LibFp.FP_OK) {
if ((nRet = LibFp.FpGenChar(0xffffffff, (byte)1, 10000)) == LibFp.FP_OK) {
if ((nRet = LibFp.FpGetImage(0xffffffff, 10000)) == LibFp.FP_OK) {
if ((nRet = LibFp.FpUpBMP(0xffffffff, bmpData, 256*288 + 1078, bmpSize, 10000)) == LibFp.FP_OK) {
final Bitmap bm = BitmapFactory.decodeByteArray(bmpData, 0, 256*288 + 1078);
iv.post(new Runnable() {
public void run() {
iv.setImageBitmap(bm);
}
});
if ((nRet = LibFp.FpSearch(0xffffffff, (byte)1, (short)0, nNum[0], nAddr, nScore, 10000)) == LibFp.FP_OK) {
sendInfo(handler, MSG_FIND, nAddr[0], nScore[0]);
}
else {
sendInfo(handler, MSG_EXIT, nRet);
}
return;
}
}
}
}
if (nRet == LibFp.FP_NO_FINGER) {
sendInfo(handler, MSG_CMD, nRet);
}
else if (nRet != LibFp.FP_OK) {
sendInfo(handler, MSG_EXIT, nRet);
return;
}
}
sendInfo(handler, MSG_CANCEL, 0);
}
}).start();
}
});
btEmpty.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
open();
short nNum[] = new short[1];
int nRet = LibFp.FpValidTempleteNum(0xffffffff, nNum, 10000);
if (nRet == LibFp.FP_OK) {
if ((nRet = LibFp.FpEmpty(0xffffffff, 10000)) == LibFp.FP_OK) {
tvInfo.setText("Çå¿ÕÖ¸ÎÆ¿âÍê³É£¬×ܹ²Çå¿ÕÖ¸ÎÆ " + nNum[0]+ " Ïî");
return;
}
}
tvInfo.setText(LibFp.GetError(nRet));
}
});
btCancel.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
bContinue = false;
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
System.out.println("onDestroy");
}
#Override
protected void onResume()
{
super.onResume();
}
#Override
public void onPause()
{
bContinue = false;
try {
Thread.sleep(600);
} catch (InterruptedException e) {
}
closeDrive();
super.onPause();
LibFp.FpClose();
}
private void sendInfo(Handler handler, int nMsg, int arg1){
Message msg = handler.obtainMessage();
msg.what = nMsg;
msg.arg1 = arg1;
handler.sendMessage(msg);
System.out.println("sendInfo1");
}
private void sendInfo(Handler handler, int nMsg, int arg1, int arg2){
Message msg = handler.obtainMessage();
msg.what = nMsg;
msg.arg1 = arg1;
msg.arg2 = arg2;
handler.sendMessage(msg);
System.out.println("sendInfo2");
}
private void optStart() {
btImage.setEnabled(false);
btEnrol.setEnabled(false);
btMatch.setEnabled(false);
btEmpty.setEnabled(false);
btCancel.setEnabled(true);
}
private void optFinish() {
btImage.setEnabled(true);
btEnrol.setEnabled(true);
btMatch.setEnabled(true);
btEmpty.setEnabled(true);
btCancel.setEnabled(false);
}
private void openDrive() {
//btOpen.setEnabled(false);
btImage.setEnabled(true);
btEnrol.setEnabled(true);
btMatch.setEnabled(true);
btEmpty.setEnabled(true);
btCancel.setEnabled(false);
tvInfo.setText("É豸ÒÑ´ò¿ª...");
}
private void closeDrive() {
//btOpen.setEnabled(true);
btImage.setEnabled(false);
btEnrol.setEnabled(false);
btMatch.setEnabled(false);
btEmpty.setEnabled(false);
btCancel.setEnabled(false);
tvInfo.setText("ÒѹرÕÉ豸£¬ÇëÖØдò¿ª...");
}
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
gpctrl.SetValue(32, 0);
gpctrl.GetValue(32);
this.finish();
}
public void open(){
int nRet = LibFp.FpOpenEx((short)0x2109, (short)0x7638);
if (nRet == LibFp.FP_ERROR_OPEN) {
LibFp.GetRootRight();
nRet = LibFp.FpOpenEx((short)0x2109, (short)0x7638);
}
if (nRet == LibFp.FP_OK) {
}
else {
tvInfo.setText(LibFp.GetError(nRet));
}
}
}
******************* activity_main.xml ****************
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<!-- <LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:id="#+id/btOpen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/a1" />
</LinearLayout>
-->
<LinearLayout
android:id="#+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/linearLayout1"
android:orientation="horizontal" >
<Button
android:id="#+id/btImage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="false"
android:text="#string/a2" />
<Button
android:id="#+id/btEnrol"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="false"
android:text="#string/a3" />
<Button
android:id="#+id/btMatch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="false"
android:text="#string/a4" />
<Button
android:id="#+id/btEmpty"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="false"
android:text="#string/a5" />
<Button
android:id="#+id/btCancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="false"
android:text="#string/a6" />
</LinearLayout>
<TextView
android:id="#+id/tvInfo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/linearLayout2"
android:layout_marginTop="29dp"
android:text="#string/hello_world"
tools:context=".MainActivity" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/tvInfo"
android:layout_marginLeft="58dp"
android:layout_marginTop="22dp"/>
<!-- android:src="#drawable/logo" -->
</RelativeLayout>
***************** strings.xml *****************
<resources>
<string name="app_name">fingerprint</string>
<string name="hello_world">Demo程序, 仅供参考!</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_main">MainActivity</string>
<string name="a1">打开设备</string>
<string name="a2">获取图像</string>
<string name="a3">录入指纹</string>
<string name="a4">指纹匹配</string>
<string name="a5">清空指纹库</string>
<string name="a6">取消操作</string>
</resources>
Here are the translations of the UI captions in the code snippet you posted.
A1 Open Device 打开设备
A2 Get Image 获取图像
A3 Fingerprint Entry 录入指纹
A4 Fingerprint Matching 指纹匹配
A5 Empty Fingerprint Database 清空指纹库
A6 Cancel 取消操作
Demo Program 程序
Hello world For reference only 仅供参考
Related
fragment_picture.xml
<androidx.constraintlayout.widget.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:id="#+id/picture_fragment"
android:layout_height="match_parent"
android:background="#F1F1F1">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipeRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rcv_picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:spanCount="1"
android:visibility="gone"
tools:listitem="#layout/item_picture" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<androidx.constraintlayout.widget.Group
android:id="#+id/group_no_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="imv_no_data,tv_no_data" />
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/imv_no_data"
android:layout_width="#dimen/_100sdp"
android:layout_height="#dimen/_100sdp"
android:layout_marginBottom="#dimen/_12sdp"
android:padding="#dimen/_8sdp"
android:src="#drawable/ic_no_image"
app:layout_constraintBottom_toTopOf="#id/tv_no_data"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tv_no_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/_16sdp"
android:text="#string/no_image"
android:textColor="#color/color_828282"
android:textSize="#dimen/_14sdp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:visibility="gone"
android:id="#+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/_16sdp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tv_no_data" />
</androidx.constraintlayout.widget.ConstraintLayout>
FragmentPicture.java
public class PictureFragment extends BaseFragment<FragmentPictureBinding> {
private static final int REQUEST_PERMISSION_DELETE = 376;
private PictureAdapter pictureAdapter;
private int pos;
SwipeRefreshLayout swipeRefresh;
#Override
protected void initView() {
pictureAdapter = new PictureAdapter(new ArrayList<>(), getContext());
pictureAdapter.setCallBackAdapter(item -> openMedia(item.getPath()));
pictureAdapter.setCallBackPicture(new PictureAdapter.CallBackPicture() {
#Override
public void onClickMore(String s, int adapterPosition, View v) {
showPopupMenuMore(s, adapterPosition, v);
}
});
binding.rcvPicture.setAdapter(pictureAdapter);
binding.swipeRefresh.setOnRefreshListener(() -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
getData();
}else {
if (getActivity() instanceof MainActivity){
((MainActivity) getActivity()).askPermissionStorageMain();
}
}
} else {
getData();
}
binding.swipeRefresh.setRefreshing(false);
});
binding.swipeRefresh.setColorSchemeResources(R.color.color_accent,
android.R.color.holo_green_dark,
android.R.color.holo_orange_dark,
android.R.color.holo_blue_dark);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
getData();
}
} else {
getData();
}
}
public void onCLickMore(String item, int pos, View view) {
showPopupMenuMore(item, pos, view);
}
private void showPopupMenuMore(String item, int pos, View view) {
PopupMenu popupMenu = new PopupMenu(getContext(), view);
popupMenu.inflate(R.menu.popup_menu_more_picture);
popupMenu.show();
// popupMenu.getMenu().getItem(1).setEnabled(PreferencesHelper.getBoolean(PreferencesHelper.KEY_SAVE_AS_GIF, true));
popupMenu.setOnMenuItemClickListener(menuItem ->{
switch (menuItem.getItemId()) {
case R.id.share_picture:
shareMedia(item);
break;
case R.id.delete_picture:
this.pos = pos;
deletePhoto(item);
break;
}
return true;
});
}
private void getData() {
getAllFilesInPicture()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(this::mapFiles)
.subscribe(datas -> {
if (datas.isEmpty()) {
binding.rcvPicture.setVisibility(View.GONE);
binding.groupNoData.setVisibility(View.VISIBLE);
} else {
binding.rcvPicture.setVisibility(View.VISIBLE);
binding.groupNoData.setVisibility(View.GONE);
pictureAdapter.addDatas(datas);
}
},throwable -> {
});
}
public Single<File[]> getAllFilesInPicture() {
return Single.create(sub -> {
File[] listFile = Storage.getFilesImageInStorage(requireContext());
if (listFile != null) {
sub.onSuccess(listFile);
} else {
sub.onSuccess(new File[]{});
}
});
}
public Single<List<VideoFile>> mapFiles(#NonNull File[] listFile) {
return Single.create(sub -> {
long previousDate = 0;
List<VideoFile> videoFiles = new ArrayList<>();
Arrays.sort(listFile, (f1, f2) -> Long.compare(f1.lastModified(), f2.lastModified()));
List<String> pictureFile = new ArrayList<>();
for (int i = listFile.length - 1; i >= 0; i--) {
VideoFile videoFile = new VideoFile();
if (!Toolbox.isSameDay(previousDate, listFile[i].lastModified())) {
VideoFile header = new VideoFile();
header.setHeader(true);
header.setLastModified(listFile[i].lastModified());
videoFiles.add(header);
}
videoFile.setPath(listFile[i].getAbsolutePath());
videoFile.setName(listFile[i].getName());
videoFile.setSize(listFile[i].length());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(new File(listFile[i].getPath()).getAbsolutePath(), options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
videoFile.setResolution(imageWidth+"x"+imageHeight);
videoFile.setSize(listFile[i].length());
videoFile.setLastModified(listFile[i].lastModified());
videoFiles.add(videoFile);
previousDate = listFile[i].lastModified();
pictureFile.add(listFile[i].getAbsolutePath());
}
sub.onSuccess(videoFiles);
});
}
#Override
protected void initControl() {
}
private void itemToItem(String filepath){
}
private void openMedia(String filePath) {
Uri fileUri = FileProvider.getUriForFile(
getContext(), getContext().getPackageName() + ".provider",
new File(filePath));
try {
Intent openVideoIntent = new Intent();
openVideoIntent.setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK)
.setDataAndType(
fileUri,
getContext().getContentResolver().getType(fileUri));
getContext().startActivity(openVideoIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
private void shareMedia(String filePath) {
Uri fileUri = FileProvider.getUriForFile(
getContext(), getContext().getPackageName() + ".provider",
new File(filePath));
Intent shareIntent = new Intent()
.setAction(Intent.ACTION_SEND)
.putExtra(Intent.EXTRA_STREAM, fileUri)
.setType(filePath.endsWith(".mp4") ? "video/mp4" : "image/*");
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(shareIntent);
}
protected void deletePhoto(String path) {
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
alert.setTitle("Delete");
alert.setMessage("Do you want to delete this image ?");
alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//This will delete my Image from recycleView
deleteMedia(path);
//I Wan't to add here code for refreshing recycle view
}
});
alert.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alert.show();
}
private void deleteMedia(String filePath) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
new File(filePath).delete();
//removeItem(pos);
MediaScannerConnection.scanFile(getActivity(),
new String[]{filePath}, new String[]{"video/mp4"},
(path1, uri) -> {
});
} else {
MediaScannerConnection.scanFile(getActivity(),
new String[]{filePath}, new String[]{"video/mp4"},
(path1, uri) -> {
if (uri != null) {
try {
if (getActivity().getContentResolver().delete(uri, null, null) != -1) {
//removeItem(pos);
}
swipeRefresh.setRefreshing(false);
} catch (SecurityException e) {
List<Uri> uris = new ArrayList<>();
uris.add(uri);
requestDeletePermission(uris);
}
}
});
}
}
private void requestDeletePermission(List<Uri> uriList) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
try {
PendingIntent pi = MediaStore.createDeleteRequest(getActivity().getContentResolver(), uriList);
startIntentSenderForResult(pi.getIntentSender(), REQUEST_PERMISSION_DELETE, null, 0, 0,
0, null);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
}
private void removeItem(int pos) {
getBaseActivity().runOnUiThread(() -> {
pictureAdapter.getList().remove(pos);
pictureAdapter.notifyItemRemoved(pos);
if (pictureAdapter.getList().get(pictureAdapter.getList().size() - 1).isHeader()) {
pictureAdapter.getList().remove(pictureAdapter.getList().size() - 1);
pictureAdapter.notifyItemRemoved(pictureAdapter.getList().size() - 1);
}
if (pictureAdapter.getList().isEmpty()) {
binding.rcvPicture.setVisibility(View.GONE);
binding.groupNoData.setVisibility(View.VISIBLE);
binding.progress.setVisibility(View.GONE);
} else {
binding.rcvPicture.setVisibility(View.VISIBLE);
binding.groupNoData.setVisibility(View.GONE);
}
//Have?
});
}
#Override
protected boolean isNeedRefresh() {
return true;
}
#Override
protected FragmentPictureBinding getViewBinding(LayoutInflater inflater, ViewGroup container) {
return FragmentPictureBinding.inflate(LayoutInflater.from(getContext()));
}
#Override
public void onReceivedEvent(RxBusType type, Object data) {
switch (type) {
case SCREEN_SHOT:
case NOTI_MEDIA_CHANGE:
getData();
break;
}
}
}
I added popup menu on picture_item of recycle view and when we press delete button of popup menu I send String path of that image to deletePhoto(item); and that method delete image.
after delete image we have to manually refresh fragment by pull refresh But can add any automatic method for refreshing fragment In this case?
Please see deletePhoto method where I deleted photo but when
I tried refresh with removepos method its crash
I tried also many methods from stackoverflow but did not worked on my case
Please help me
You have already done everything uncomment your removeItem method and add pictureAdapter.notifyDataSetChanged() at the end of removeItem method
This will reload the data set of your adapter
If you know the position of the deleted element you can use
pictureAdapter.notifyItemRemoved(position)
This will tell your adapter you remove an item from the data set on a specific position
I have this mEpisodeList which is an ArrayList inside this class TvShowEpisodeLoader
I also have another class named TvShowEpisodeDetailsFragment
I want to access mEpisodeListfrom TvShowEpisodeDetailsFragment
I want to get mEpisode (which is the number of the episodes of a season of a tv show)
and display all available episode numbers in a horizonal scrollbar in episode_details layout and upon tapping on a number it will switch to that episode
here is TvShowEpisodeLoader , TvShowEpisodeDetailsFragment
mEpisodeList
here is the code
import com.miz.loader.TvShowEpisodeLoader;
#SuppressLint("InflateParams") public class TvShowEpisodeDetailsFragment extends Fragment {
private TvShowEpisodeLoader.TvShowEpisodeLoaderAsyncTask tab3 = new TvShowEpisodeLoader.TvShowEpisodeLoaderAsyncTask() {
mEpisodeList = new ArrayList<GridEpisode>();
};
private class TvShowEpisodeLoaderAsyncTask extends LibrarySectionAsyncTask<Void, Void, Void> {
private final ArrayList<GridEpisode> mEpisodeList;
public TvShowEpisodeLoaderAsyncTask() {
mEpisodeList = new ArrayList<GridEpisode>();
}
#Override
protected Void doInBackground(Void... params) {
mEpisodeList.addAll(MizuuApplication.getTvEpisodeDbAdapter()
.getEpisodesInSeason(mContext, getShowId(), getShowSeason()));
int totalSize = mEpisodeList.size();
switch (getWatchedFilter()) {
case WATCHED:
for (int i = 0; i < totalSize; i++) {
if (!mEpisodeList.get(i).hasWatched()) {
mEpisodeList.remove(i);
i--;
totalSize--;
}
}
break;
case UNWATCHED:
for (int i = 0; i < totalSize; i++) {
if (mEpisodeList.get(i).hasWatched()) {
mEpisodeList.remove(i);
i--;
totalSize--;
}
}
break;
default:
break;
}
if (showAvailableFiles()) {
for (int i = 0; i < totalSize; i++) {
ArrayList<FileSource> filesources = MizLib.getFileSources(MizLib.TYPE_SHOWS, true);
if (isCancelled())
return null;
boolean condition = false;
for (Filepath path : mEpisodeList.get(i).getFilepaths()) {
if (path.isNetworkFile())
if (FileUtils.hasOfflineCopy(mContext, path)) {
condition = true;
break; // break inner loop to continue to the next episode
} else {
if (path.getType() == FileSource.SMB) {
if (MizLib.isWifiConnected(mContext)) {
FileSource source = null;
for (int j = 0; j < filesources.size(); j++)
if (path.getFilepath().contains(filesources.get(j).getFilepath())) {
source = filesources.get(j);
break;
}
if (source == null)
continue;
try {
final SmbFile file = new SmbFile(
MizLib.createSmbLoginString(
source.getDomain(),
source.getUser(),
source.getPassword(),
path.getFilepath(),
false
));
if (file.exists()) {
condition = true;
break; // break inner loop to continue to the next episode
}
} catch (Exception e) {
} // Do nothing - the file isn't available (either MalformedURLException or SmbException)
}
} else if (path.getType() == FileSource.UPNP) {
if (MizLib.exists(path.getFilepath())) {
condition = true;
break; // break inner loop to continue to the next episode
}
}
}
else {
if (new File(path.getFilepath()).exists()) {
condition = true;
break; // break inner loop to continue to the next episode
}
}
}
if (!condition && mEpisodeList.size() > i) {
mEpisodeList.remove(i);
i--;
totalSize--;
}
}
}
Collections.sort(mEpisodeList, getSortType().getComparator());
return null;
}
#Override
protected void onPostExecute(Void result) {
if (!isCancelled()) {
mResults = new ArrayList<>(mEpisodeList);
mCallback.onLoadCompleted();
} else
mEpisodeList.clear();
}
}
this one is from TvShowEpisodeDetailsFragment
public void onViewCreated(final View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mBackdrop = (ImageView) view.findViewById(R.id.imageBackground);
mEpisodePhoto = (ImageView) view.findViewById(R.id.episodePhoto);
mDetailsArea = view.findViewById(R.id.details_area);
mTitle = (TextView) view.findViewById(R.id.movieTitle);
mSeasonEpisodeNumber = (TextView) view.findViewById(R.id.textView7);
mDescription = (TextView) view.findViewById(R.id.textView2);
mFileSource = (TextView) view.findViewById(R.id.textView3);
mAirDate = (TextView) view.findViewById(R.id.textReleaseDate);
mRating = (TextView) view.findViewById(R.id.textView12);
mDirector = (TextView) view.findViewById(R.id.director);
mWriter = (TextView) view.findViewById(R.id.writer);
mGuestStars = (TextView) view.findViewById(R.id.guest_stars);
mScrollView = (ObservableScrollView) view.findViewById(R.id.observableScrollView);
mFab = (FloatingActionButton) view.findViewById(R.id.fab);
mFab.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ViewUtils.animateFabJump(v, new SimpleAnimatorListener() {
#Override
public void onAnimationEnd(Animator animation) {
play();
}
});
}
});
if (MizLib.isTablet(mContext))
mFab.setType(FloatingActionButton.TYPE_NORMAL);
final int height = MizLib.getActionBarAndStatusBarHeight(getActivity());
mScrollView = (ObservableScrollView) view.findViewById(R.id.observableScrollView);
mScrollView.setOnScrollChangedListener(new OnScrollChangedListener() {
#Override
public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt) {
final int headerHeight = mEpisodePhoto.getHeight() - height;
final float ratio = (float) Math.min(Math.max(t, 0), headerHeight) / headerHeight;
final int newAlpha = (int) (ratio * 255);
mBus.post(new BusToolbarColorObject(mToolbarColor, newAlpha));
if (MizLib.isPortrait(mContext)) {
// Such parallax, much wow
mEpisodePhoto.setPadding(0, (int) (t / 1.5), 0, 0);
}
}
});
mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
ViewUtils.setLayoutParamsForDetailsEmptyView(mContext, view,
mBackdrop, mScrollView, this);
}
});
loadData();
mPicasso.load(mEpisode.getEpisodePhoto()).placeholder(R.drawable.bg).config(MizuuApplication.getBitmapConfig()).into(mEpisodePhoto, new Callback() {
#Override
public void onError() {
if (!isAdded())
return;
int width = getActivity().getResources().getDimensionPixelSize(R.dimen.episode_details_background_overlay_width);
int height = getActivity().getResources().getDimensionPixelSize(R.dimen.episode_details_background_overlay_height);
mPicasso.load(mEpisode.getTvShowBackdrop()).placeholder(R.drawable.bg).error(R.drawable.nobackdrop).resize(width, height).config(MizuuApplication.getBitmapConfig()).into(mEpisodePhoto);
}
#Override
public void onSuccess() {
if (mPaletteLoader == null) {
mPaletteLoader = new PaletteLoader(mPicasso, Uri.fromFile(mEpisode.getEpisodePhoto()), new PaletteLoader.OnPaletteLoadedCallback() {
#Override
public void onPaletteLoaded(int swatchColor) {
mToolbarColor = swatchColor;
}
});
mPaletteLoader.addView(mDetailsArea);
mPaletteLoader.setFab(mFab);
mPaletteLoader.execute();
} else {
// Clear old views after configuration change
mPaletteLoader.clearViews();
// Add views after configuration change
mPaletteLoader.addView(mDetailsArea);
mPaletteLoader.setFab(mFab);
// Re-color the views
mPaletteLoader.colorViews();
}
}
});
if (!MizLib.isPortrait(getActivity()))
mPicasso.load(mEpisode.getEpisodePhoto()).placeholder(R.drawable.bg).error(R.drawable.bg).transform(new BlurTransformation(getActivity().getApplicationContext(), mEpisode.getEpisodePhoto().getAbsolutePath() + "-blur", 4)).into(mBackdrop, new Callback() {
#Override public void onError() {
if (!isAdded())
return;
mPicasso.load(mEpisode.getTvShowBackdrop()).placeholder(R.drawable.bg).error(R.drawable.nobackdrop).transform(new BlurTransformation(getActivity().getApplicationContext(), mEpisode.getTvShowBackdrop().getAbsolutePath() + "-blur", 4)).into(mBackdrop, new Callback() {
#Override
public void onError() {}
#Override
public void onSuccess() {
if (!isAdded())
return;
mBackdrop.setColorFilter(Color.parseColor("#aa181818"), android.graphics.PorterDuff.Mode.SRC_OVER);
}
});
}
#Override
public void onSuccess() {
if (!isAdded())
return;
mBackdrop.setColorFilter(Color.parseColor("#aa181818"), android.graphics.PorterDuff.Mode.SRC_OVER);
}
});
}
I solved the problem by importing the ArrayList from another class called TvShowEpisode instead of GridEpisode and Initialized properly
Huge thanks to [AntiqTech]
here is what I did
the Arraylist was ready to be called so all I needed was
private ArrayList<TvShowEpisode> mEpisodes = new ArrayList<TvShowEpisode>();
private static final String SHOW_ID = "showId";
mShowId = getActivity().getIntent().getExtras().getString(SHOW_ID);
Cursor cursor = mDatabaseHelper.getEpisodes(mShowId);
try {
while (cursor.moveToNext()) {
mEpisodes.add(new TvShowEpisode(mContext, mShowId,
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_TITLE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_PLOT)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_SEASON)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_AIRDATE)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_DIRECTOR)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_WRITER)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_GUESTSTARS)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_EPISODE_RATING)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_HAS_WATCHED)),
cursor.getString(cursor.getColumnIndex(DbAdapterTvShowEpisodes.KEY_FAVOURITE))
));
}
} catch (Exception e) {
} finally {
cursor.close();
}
// populating the listview
mEpisodesList = (ListView) view.findViewById(R.id.episodesList);
ArrayList<String> episodeslist = new ArrayList<String>(mEpisodes.size()); //set initialize capacity as it's know, some negligible performance related reason
for(TvShowEpisode e : mEpisodes){
episodeslist.add(e.mEpisode);
}
// Create The Adapter
ArrayAdapter<String> arrayAdapter =
new ArrayAdapter<String>(mContext,android.R.layout.simple_list_item_1, episodeslist);
// Set The Adapter
mEpisodesList.setAdapter(arrayAdapter);
the xml
<HorizontalScrollView
android:id="#+id/hsv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:measureAllChildren="false"
android:scrollbars="none"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<ListView
android:id="#+id/episodesList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="10dp" />
</LinearLayout>
</HorizontalScrollView>
My program include icons on the tabLayout. I saw only one way to resize icon on tabItem from stackOverflow. I tried to do this way that I saw. But only I can resize first icon on the tabLayout.
MainActivity.java
LinearLayout lilcon;
private Integer[] images;
Integer[] domesticImages = {
R.drawable.ic_directions_bus_black_24dp,
R.drawable.ic_flight_takeoff_black_24dp,
R.drawable.ic_directions_boat_black_24dp,
R.drawable.ic_train_black_24dp,
R.drawable.ic_hotel,
R.drawable.ic_rent_a_car
};
private Integer[] domesticImagesClicked = {
R.drawable.ic_directions_bus_clicked_24dp,
R.drawable.ic_flight_takeoff_clicked_24dp,
R.drawable.ic_directions_boat_clicked_24dp,
R.drawable.ic_train_clicked_24dp,
R.drawable.ic_hotel_clicked,
R.drawable.ic_rent_a_car_clicked
};
private Integer[] abroadImages = {
R.drawable.ic_flight_takeoff_black_24dp,
R.drawable.ic_hotel,
R.drawable.ic_directions_bus_black_24dp,
R.drawable.ic_directions_boat_black_24dp,
R.drawable.ic_train_black_24dp,
R.drawable.ic_rent_a_car
};
private Integer[] abroadImagesClicked = {
R.drawable.ic_flight_takeoff_clicked_24dp,
R.drawable.ic_hotel_clicked,
R.drawable.ic_directions_bus_clicked_24dp,
R.drawable.ic_directions_boat_clicked_24dp,
R.drawable.ic_train_clicked_24dp,
R.drawable.ic_rent_a_car_clicked
};
Integer[] domesticImagesTablet = {
R.drawable.ic_tablet_destination_bus,
R.drawable.ic_tablet_airplane,
R.drawable.ic_tablet_boat,
R.drawable.ic_tablet_train,
R.drawable.ic_tablet_hotel,
R.drawable.ic_tablet_rent_a_car
};
private Integer[] domesticImagesClickedTablet = {
R.drawable.ic_tablet_destination_bus_clicked,
R.drawable.ic_tablet_airplane_clicked,
R.drawable.ic_tablet_boat_clicked,
R.drawable.ic_tablet_train_clicked,
R.drawable.ic_tablet_hotel_clicked,
R.drawable.ic_tablet_rent_a_car_clicked
};
private Integer[] abroadImagesTablet = {
R.drawable.ic_tablet_airplane,
R.drawable.ic_tablet_hotel,
R.drawable.ic_tablet_destination_bus,
R.drawable.ic_tablet_boat,
R.drawable.ic_tablet_train,
R.drawable.ic_tablet_rent_a_car
};
private Integer[] abroadImagesClickedTablet = {
R.drawable.ic_tablet_airplane_clicked,
R.drawable.ic_tablet_hotel_clicked,
R.drawable.ic_tablet_destination_bus_clicked,
R.drawable.ic_tablet_boat_clicked,
R.drawable.ic_tablet_train_clicked,
R.drawable.ic_tablet_rent_a_car_clicked
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
Log.i("stack", "ResultCreated");
init();
initData();
attachFragments();
/* registerCartOperationsReceiver();*/
registerHandlers();
}
void init() {
lilcon = view.findViewById(R.id.licon);
}
void initData(){
if (isDomestic) {
images = domesticImages;
} else {
images = abroadImages;
}
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
/* if (tabletSize) {
if (isDomestic) {
lilcon.setBackgroundResource(R.drawable.ic_tablet_destination_bus_clicked);
// tab.setIcon(domesticImagesTablet[i]);
tabLayout.getTabAt(0).setCustomView(lilcon);
}else{
lilcon.setBackgroundResource(R.drawable.ic_tablet_airplane_clicked);
// tab.setIcon(domesticImagesTablet[i]);
tabLayout.getTabAt(0).setCustomView(lilcon);
}
}else{}*/
if (tab != null && tab.getIcon() != null) {
int i = tab.getPosition();
if (isDomestic) {
tab.setIcon(domesticImagesClicked[i]);
// lilcon.setBackgroundResource(domesticImages[i]);
// tab.setCustomView(lilcon);
} else{
tab.setIcon(abroadImagesClicked[i]);
// lilcon.setBackgroundResource(domesticImages[i]);
// tab.setCustomView(lilcon);
}
}
/* int pos = tab.getPosition();
for (int i = 0; i < tabLayout.getTabCount(); i++) {
View aview = tabLayout.getTabAt(i).getCustomView();
ImageView img = aview.findItemById(R.id.icon);
if (i == pos) {
if (isDomestic)
img.setImageResource(domesticImagesClicked[i];
else
img.setImageResource(abroadImagesClicked[i];
} else {
if (isDomestic)
img.setImageResource(domesticImages[i];
else
img.setImageResource(abroadImages[i];
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
if (tab != null && tab.getIcon() != null) {
int i = tab.getPosition();
/* boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
if (tabletSize) {
if (isDomestic) {
lilcon.setBackgroundResource(R.drawable.ic_tablet_destination_bus_clicked);
// tab.setIcon(domesticImagesTablet[i]);
tabLayout.getTabAt(0).setCustomView(lilcon);
// lilcon.setBackgroundResource(R.drawable.ic_tablet_destination_bus_clicked);
// tab.getTabAt(0).setCustomView(lilcon);
// lilcon.setBackgroundResource(domesticImages[i]);
// tab.setCustomView(lilcon);
}else{
// tab.setIcon(abroadImagesTablet[i]);
lilcon.setBackgroundResource(R.drawable.ic_tablet_airplane_clicked);
// tab.setIcon(domesticImagesTablet[i]);
tabLayout.getTabAt(0).setCustomView(lilcon);
//tab.setIcon(abroadImages[i]);
// lilcon.setBackgroundResource(domesticImages[i]);
// tab.setCustomView(lilcon);
}
}
else{}*/
if (isDomestic) {
tab.setIcon(domesticImages[i]);
// lilcon.setBackgroundResource(domesticImages[i]);
// tab.setCustomView(lilcon);
}else{
tab.setIcon(abroadImages[i]);
// lilcon.setBackgroundResource(domesticImages[i]);
// tab.setCustomView(lilcon);
}
}
}
#Override
public void onTabReselected(TabLayout.Tab tab) { }
void attachFragments() {
try {
for (int i = 0; i < tabLayout.getTabCount(); i++) {
}
boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
if (tabletSize) {
if (isDomestic){
// tabLayout.getTabAt(0).setIcon(R.drawable.ic_icon_bus);
lilcon.setBackgroundResource(R.drawable.ic_tablet_destination_bus_clicked);
tabLayout.getTabAt(0).setCustomView(lilcon);
} else {
// tabLayout.getTabAt(0).setIcon(R.drawable.ic_flight_takeoff_clicked_24dp);
lilcon.setBackgroundResource(R.drawable.ic_tablet_airplane_clicked);
tabLayout.getTabAt(0).setCustomView(lilcon);
}
}else {
if (isDomestic){
tabLayout.getTabAt(0).setIcon(R.drawable.ic_directions_bus_clicked_24dp);
// lilcon.setBackgroundResource(R.drawable.ic_directions_bus_clicked_24dp);
// tabLayout.getTabAt(0).setCustomView(lilcon);
} else {
tabLayout.getTabAt(0).setIcon(R.drawable.ic_flight_takeoff_clicked_24dp);
// lilcon.setBackgroundResource(R.drawable.ic_flight_takeoff_clicked_24dp);
// tabLayout.getTabAt(0).setCustomView(lilcon);
}}
// tabLayout.getTabAt(0).setCustomView(vehicleTypeImageView(1,true));
if (tabletSize){
}else{}
for (int i = 1; i < tabLayout.getTabCount(); i++) {
if (isDomestic) {
tabLayout.getTabAt(i).setIcon(domesticImages[i]);
// lilcon.setBackground(domesticImages[i]);
// tabLayout.getTabAt(i).setCustomView(lilcon);
} else {
tabLayout.getTabAt(i).setIcon(abroadImages[i]);
// lilcon.setBackgroundResource(abroadImages[i]);
// tabLayout.getTabAt(i).setCustomView(lilcon);
}
}
/* for (int i = 1; i < tabLayout.getTabCount(); i++) {
if (isDomestic)
lilcon.setImageResource(domesticImages[i]);
else
lilcon.setImageResource(abroadImages[i]);
tabLayout.getTabAt(i).setCustomView(lilcon);
}*/
// herhangi bir tab item seçildiğinde tetiklenecek yer
tabLayout.addOnTabSelectedListener(this);
}
customtab.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/licon"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:id="#+id/icon"
android:layout_gravity="center_horizontal" />
</LinearLayout>
Try to do it like this
Prepare your tabs somewhere in your activity
for (int i = 0; i < tabLayout.getTabCount(); i++) {
View view1 = getLayoutInflater().inflate(R.layout.customtab, null);
ImageView img = view1.findViewById(R.id.icon);
img.setScaleType(ScaleType.FIT_XY);
if (domestic)
img.setImageResource(domesticImages[i]);
else
img.setImageResource(abroadImages[i]);
tabLayout.getTabAt(i).setCustomView(view1);
}
Then,
#Override
public void onTabSelected(TabLayout.Tab tab) {
int pos = tab.getPosition();
for (int i = 0; i < tabLayout.getTabCount(); i++) {
View aview = tabLayout.getTabAt(i).getCustomView();
ImageView img = aview.findViewById(R.id.icon);
if (i == pos) {
if (isDomestic)
img.setImageResource(domesticImagesClicked[i];
else
img.setImageResource(abroadImagesClicked[i];
} else {
if (isDomestic)
img.setImageResource(domesticImages[i];
else
img.setImageResource(abroadImages[i];
}
}
}
Your customtab xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/licon"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:id="#+id/icon"
android:layout_gravity="center_horizontal" />
</LinearLayout>
I develop an android app for my final year project. This app must collect sensor smartphone information from accelerometer, gyroscope and magnetometer and to save them into a file. So far I have done everything, but now I have some problem with sampling rate frequency of sensors, I do not exactly know how to deal with that.
I tried to use runnable method to delay 10ms for accelerometer and gyroscope and other runnable method to delay 100ms for magnetometer. I did that because with approximation I guess that the values for ACC and GYR are changing every 10 ms. while for MAG this value is changing every 100 ms.
I have NEVER used this runnable method, I am a beginner. My code works, it creates the file, but it has 0 bytes, which means that my code is not entering properly into the RUNNABLE method. What should I change?
package localhost.dev.liverpoolsensorsfusion;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class RecordDataActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private Sensor mGyroscope;
private Sensor mMagnetometer;
Handler handler10;
Runnable runnable10;
Handler handler100;
Runnable runnable100;
CheckBox checkAcc;
CheckBox checkGyro;
CheckBox checkMagne;
TextView accX;
TextView accY;
TextView accZ;
TextView magneX;
TextView magneY;
TextView magneZ;
TextView gyroX;
TextView gyroY;
TextView gyroZ;
String FILENAME;
String content1;
String content2;
String content3;
FileOutputStream out;
Button startButton;
Button stopButton;
boolean startFlag = false;
EditText textData;
private Chronometer chronometer;
private boolean running_chronometer;
boolean isFirstSet = true;
private long currentTime;
private long startTime;
float[] acceleration = new float[3];
float[] gyroscope = new float[3];
float[] magnetometer = new float[3];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_record_data);
// define sensors
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
// define text views
accX = (TextView) findViewById(R.id.raw_value_acc_x);
accY = (TextView) findViewById(R.id.raw_value_acc_y);
accZ = (TextView) findViewById(R.id.raw_value_acc_z);
magneX = (TextView) findViewById(R.id.raw_value_magne_x);
magneY = (TextView) findViewById(R.id.raw_value_magne_y);
magneZ = (TextView) findViewById(R.id.raw_value_magne_z);
gyroX = (TextView) findViewById(R.id.raw_value_gyro_x);
gyroY = (TextView) findViewById(R.id.raw_value_gyro_y);
gyroZ = (TextView) findViewById(R.id.raw_value_gyro_z);
// define checkboxes
checkAcc=(CheckBox)findViewById(R.id.checkBox);
checkGyro=(CheckBox)findViewById(R.id.checkBox2);
checkMagne=(CheckBox)findViewById(R.id.checkBox3);
// file name to be entered
textData = (EditText) findViewById(R.id.edit_text);
textData.setHint("Enter File Name here...");
// define chronometer
chronometer = findViewById(R.id.chronometer);
chronometer.setFormat("Recording: %s");
chronometer.setBase(SystemClock.elapsedRealtime());
// define start button
startButton = (Button) findViewById(R.id.button_record);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// create file
FILENAME= textData.getText() + ".csv";
if(!checkAcc.isChecked() && !checkGyro.isChecked() && !checkMagne.isChecked()) {
Toast.makeText(getBaseContext(), "Please select at least one sensor!",
Toast.LENGTH_LONG).show();
}else if(FILENAME.equals(".csv")){
Toast.makeText(getBaseContext(), "Please insert a valid name for the file to be created!",
Toast.LENGTH_LONG).show();
}else {
// set the recording button ON
startFlag = true;
// make the chronometer run
if (!running_chronometer) {
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.start();
running_chronometer = true;
checkAcc.setClickable(false);
checkGyro.setClickable(false);
checkMagne.setClickable(false);
}
// add screen message to confirm that the app is recording
try{
textData.getText().clear();
Toast.makeText(getBaseContext(), "Start recording the data set", Toast.LENGTH_SHORT).show();
}catch(Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
// Turn off the record button
startButton.setClickable(false);
}
}
}); // starts button ends here
// define stop button
stopButton=(Button)findViewById(R.id.button_stop);
stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// set the recording button OFF
// Stop writing on file
startFlag = false;
isFirstSet = true;
// if there is no file created state the following message
if(FILENAME==null || FILENAME.equals(".csv")){
Toast.makeText(getBaseContext(), "There is no recording taken in this moment!",
Toast.LENGTH_LONG).show();
}else{
// stop the chronometer
chronometer.stop();
running_chronometer = false;
checkAcc.setClickable(true);
checkGyro.setClickable(true);
checkMagne.setClickable(true);
// add screen message to confirm that the app has saved the data set
try{
Toast.makeText(getBaseContext(), "Saved to " + getFilesDir() + "/" + FILENAME,
Toast.LENGTH_LONG).show();
}catch(Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
// Turn back on the Record button
startButton.setClickable(true);
}
}); // stop button ends here
} // onCreate class ends here
#Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
}
#Override
public final void onSensorChanged(SensorEvent event) {
// when recording is ON do this
if (startFlag) {
if (checkAcc.isChecked() && event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
acceleration[0] = event.values[0];
acceleration[1] = event.values[1];
acceleration[2] = event.values[2];
}
if (checkGyro.isChecked() && event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
gyroscope[0] = event.values[0];
gyroscope[1] = event.values[1];
gyroscope[2] = event.values[2];
}
if (checkMagne.isChecked() && event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magnetometer[0] = event.values[0];
magnetometer[1] = event.values[1];
magnetometer[2] = event.values[2];
}
// initialise the content that will be written in the file
if (isFirstSet) {
startTime = System.currentTimeMillis();
isFirstSet = false;
}
currentTime = System.currentTimeMillis();
content1 = (currentTime - startTime) + "," + "ACC" + "," + acceleration[0] + "," + acceleration[1] + "," + acceleration[2] + "\n";
content2 = (currentTime - startTime) + "," + "GYR" + "," + gyroscope[0] + "," + gyroscope[1] + "," + gyroscope[2] + "\n";
content3 = (currentTime - startTime) + "," + "MAG" + "," + magnetometer[0] + "," +magnetometer[1] + "," + magnetometer[2] + "\n";
// as long the recording is ON
for (int i = 0; i < 1; i++){
try {
// create the file
out = openFileOutput(FILENAME, Context.MODE_APPEND);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// write to the file
if (checkAcc.isChecked() && checkGyro.isChecked() && checkMagne.isChecked()) {
if (startFlag) {
handler10 = new Handler();
runnable10 = new Runnable() {
#Override
public void run() {
handler10.postDelayed(this, 10);
updateAccText();
updateGyroText();
try {
out.write(content1.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
try {
out.write(content2.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
};
handler100 = new Handler();
runnable100 = new Runnable() {
#Override
public void run() {
handler100.postDelayed(this, 100);
updateMagneText();
try {
out.write(content3.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
} else if (checkAcc.isChecked() && checkGyro.isChecked()) {
if (startFlag) {
runnable10 = new Runnable() {
#Override
public void run() {
handler10.postDelayed(this, 10);
updateAccText();
updateGyroText();
try {
out.write(content1.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
try {
out.write(content2.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
} else if (checkAcc.isChecked() && checkMagne.isChecked()) {
if (startFlag) {
runnable10 = new Runnable() {
#Override
public void run() {
handler10.postDelayed(this, 10);
updateAccText();
try {
out.write(content1.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
};
runnable100 = new Runnable() {
#Override
public void run() {
handler100.postDelayed(this, 100);
updateMagneText();
try {
out.write(content3.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
} else if (checkGyro.isChecked() && checkMagne.isChecked()) {
if (startFlag) {
runnable10 = new Runnable() {
#Override
public void run() {
handler10.postDelayed(this, 10);
updateGyroText();
try {
out.write(content2.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
};
runnable100 = new Runnable() {
#Override
public void run() {
handler100.postDelayed(this, 100);
updateMagneText();
try {
out.write(content3.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
} else if (checkAcc.isChecked()) {
if (startFlag) {
runnable10 = new Runnable() {
#Override
public void run() {
handler10.postDelayed(this, 10);
updateAccText();
try {
out.write(content1.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
} else if (checkGyro.isChecked()) {
if (startFlag) {
runnable10 = new Runnable() {
#Override
public void run() {
handler10.postDelayed(this, 10);
updateGyroText();
try {
out.write(content2.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
} else if (checkMagne.isChecked()) {
if (startFlag) {
runnable100 = new Runnable() {
#Override
public void run() {
handler100.postDelayed(this, 100);
updateMagneText();
try {
out.write(content3.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
}
} // for loop end
}
}
#Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
protected void updateAccText(){
// Update the gyroscope data
accX.setText(String.format("%.6f", acceleration[0]));
accY.setText(String.format("%.6f", acceleration[1]));
accZ.setText(String.format("%.6f", acceleration[2]));
}
protected void updateGyroText(){
// Update the gyroscope data
gyroX.setText(String.format("%.6f", gyroscope[0]));
gyroY.setText(String.format("%.6f", gyroscope[1]));
gyroZ.setText(String.format("%.6f", gyroscope[2]));
}
protected void updateMagneText(){
// Update the gyroscope data
magneX.setText(String.format("%.6f", magnetometer[0]));
magneY.setText(String.format("%.6f", magnetometer[1]));
magneZ.setText(String.format("%.6f", magnetometer[2]));
}
}
When I press the record (start) button, I expect to create a .csv file that saves every single value from each checked (chosen) sensor before it was changed and so on until the user is pressing the save (stop) button.
You create a runnable code block, but never execute it. Call this when you create a runnable and want to set it running:
new Thread(myRunnable).start();
In the end I have managed to do it.
I save the value for GYR every 5 ms and MAG every 100 ms, and if the saved value is still equal with the new value then wait and write when they are different. I think this is a good example.
I will let the code here, maybe it could help other people:
Java:
package localhost.dev.liverpoolsensorsfusion;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class RecordDataActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private Sensor mGyroscope;
private Sensor mMagnetometer;
CheckBox checkAcc;
CheckBox checkGyro;
CheckBox checkMagne;
TextView accX;
TextView accY;
TextView accZ;
TextView magneX;
TextView magneY;
TextView magneZ;
TextView gyroX;
TextView gyroY;
TextView gyroZ;
String FILENAME;
String content1;
String content2;
String content3;
FileOutputStream out;
Button startButton;
Button stopButton;
boolean isFirstSet = true;
boolean startFlag = false;
EditText textData;
private Chronometer chronometer;
private boolean running_chronometer;
private long currentTime;
private long startTime;
float[] acceleration = new float[3];
float[] gyroscope = new float[3];
float[] magnetometer = new float[3];
float[] new_gyroscope = new float[3];
float[] new_magnetometer = new float[3];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_record_data);
// define sensors
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
// define text views
accX = (TextView) findViewById(R.id.raw_value_acc_x);
accY = (TextView) findViewById(R.id.raw_value_acc_y);
accZ = (TextView) findViewById(R.id.raw_value_acc_z);
magneX = (TextView) findViewById(R.id.raw_value_magne_x);
magneY = (TextView) findViewById(R.id.raw_value_magne_y);
magneZ = (TextView) findViewById(R.id.raw_value_magne_z);
gyroX = (TextView) findViewById(R.id.raw_value_gyro_x);
gyroY = (TextView) findViewById(R.id.raw_value_gyro_y);
gyroZ = (TextView) findViewById(R.id.raw_value_gyro_z);
// define checkboxes
checkAcc=(CheckBox)findViewById(R.id.checkBox);
checkGyro=(CheckBox)findViewById(R.id.checkBox2);
checkMagne=(CheckBox)findViewById(R.id.checkBox3);
// file name to be entered
textData = (EditText) findViewById(R.id.edit_text);
textData.setHint("Enter File Name here...");
// define chronometer
chronometer = findViewById(R.id.chronometer);
chronometer.setFormat("Recording: %s");
chronometer.setBase(SystemClock.elapsedRealtime());
// define start button
startButton = (Button) findViewById(R.id.button_record);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// create file
FILENAME= textData.getText() + ".csv";
if(!checkAcc.isChecked() && !checkGyro.isChecked() && !checkMagne.isChecked()) {
Toast.makeText(getBaseContext(), "Please select at least one sensor!",
Toast.LENGTH_LONG).show();
}else if(FILENAME.equals(".csv")){
Toast.makeText(getBaseContext(), "Please insert a valid name for the file to be created!",
Toast.LENGTH_LONG).show();
}else {
// set the recording button ON
startFlag = true;
// make the chronometer run
if (!running_chronometer) {
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.start();
running_chronometer = true;
checkAcc.setClickable(false);
checkGyro.setClickable(false);
checkMagne.setClickable(false);
}
// add screen message to confirm that the app is recording
try{
textData.getText().clear();
Toast.makeText(getBaseContext(), "Start recording the data set", Toast.LENGTH_SHORT).show();
}catch(Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
// Turn off the record button
startButton.setClickable(false);
}
}
}); // starts button ends here
// define stop button
stopButton=(Button)findViewById(R.id.button_stop);
stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// set the recording button OFF
// Stop writing on file
startFlag = false;
// if there is no file created state the following message
if(FILENAME==null || FILENAME.equals(".csv")){
Toast.makeText(getBaseContext(), "There is no recording taken in this moment!",
Toast.LENGTH_LONG).show();
}else{
// stop the chronometer
chronometer.stop();
running_chronometer = false;
checkAcc.setClickable(true);
checkGyro.setClickable(true);
checkMagne.setClickable(true);
// add screen message to confirm that the app has saved the data set
try{
Toast.makeText(getBaseContext(), "Saved to " + getFilesDir() + "/" + FILENAME,
Toast.LENGTH_LONG).show();
}catch(Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
// Turn back on the Record button
startButton.setClickable(true);
}
}); // stop button ends here
} // onCreate class ends here
#Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
}
#Override
public final void onSensorChanged(SensorEvent event) {
if (startFlag) {
if (checkAcc.isChecked() && event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
acceleration[0] = event.values[0];
acceleration[1] = event.values[1];
acceleration[2] = event.values[2];
}
if (checkGyro.isChecked() && event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
gyroscope[0] = event.values[0];
gyroscope[1] = event.values[1];
gyroscope[2] = event.values[2];
}
if (checkMagne.isChecked() && event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magnetometer[0] = event.values[0];
magnetometer[1] = event.values[1];
magnetometer[2] = event.values[2];
}
// when recording is ON do this
// initialise the content that will be written in the file
if (isFirstSet) {
startTime = System.currentTimeMillis();
isFirstSet = false;
}
currentTime = System.currentTimeMillis();
content1 = (currentTime-startTime) + "," + "ACC" + "," + acceleration[0] + "," + acceleration[1] + "," + acceleration[2] + "\n";
content2 = (currentTime-startTime) + "," + "GYR" + "," + gyroscope[0] + "," + gyroscope[1] + "," + gyroscope[2] + "\n";
content3 = (currentTime-startTime) + "," + "MAG" + "," + magnetometer[0] + "," +magnetometer[1] + "," + magnetometer[2] + "\n";
// as long the recording is ON
for (int i = 0; i < 1; i++){
try {
// create the file
out = openFileOutput(FILENAME, Context.MODE_APPEND);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// write to the file
if (checkAcc.isChecked() && checkGyro.isChecked() && checkMagne.isChecked() && startFlag) {
updateAccText();
writeAcc();
updateGyroText();
HandleGyr();
if(new_gyroscope[0]==gyroscope[0] && new_gyroscope[1]== gyroscope[1] && new_gyroscope[2]==gyroscope[2]){
writeGyr();
}
updateMagneText();
HandleMag();
if(new_magnetometer[0]==magnetometer[0] && new_magnetometer[1] == magnetometer[1] && new_magnetometer[1] == magnetometer[1]){
writeMag();
}
} else if (checkAcc.isChecked() && checkGyro.isChecked() && startFlag) {
updateAccText();
updateGyroText();
writeAcc();
HandleGyr();
if(new_gyroscope[0]==gyroscope[0] && new_gyroscope[1]== gyroscope[1] && new_gyroscope[2]==gyroscope[2]){
writeGyr();
}
} else if (checkAcc.isChecked() && checkMagne.isChecked() && startFlag) {
updateAccText();
updateMagneText();
writeAcc();
HandleMag();
if(new_magnetometer[0]==magnetometer[0] && new_magnetometer[1] == magnetometer[1] && new_magnetometer[1] == magnetometer[1]){
writeMag();
}
} else if (checkGyro.isChecked() && checkMagne.isChecked() && startFlag) {
updateGyroText();
updateMagneText();
HandleGyr();
HandleMag();
if(new_gyroscope[0]==gyroscope[0] && new_gyroscope[1]== gyroscope[1] && new_gyroscope[2]==gyroscope[2]){
writeGyr();
}
if(new_magnetometer[0]==magnetometer[0] && new_magnetometer[1] == magnetometer[1] && new_magnetometer[1] == magnetometer[1]){
writeMag();
}
} else if (checkAcc.isChecked() && startFlag) {
updateAccText();
writeAcc();
} else if (checkGyro.isChecked() && startFlag) {
updateGyroText();
writeGyr();
} else if (checkMagne.isChecked()) {
updateAccText();
writeAcc();
}
} // for loop end
}
}
#Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
protected void updateAccText(){
// Update the gyroscope data
accX.setText(String.format("%.6f", acceleration[0]));
accY.setText(String.format("%.6f", acceleration[1]));
accZ.setText(String.format("%.6f", acceleration[2]));
}
protected void updateGyroText(){
// Update the gyroscope data
gyroX.setText(String.format("%.6f", gyroscope[0]));
gyroY.setText(String.format("%.6f", gyroscope[1]));
gyroZ.setText(String.format("%.6f", gyroscope[2]));
}
protected void updateMagneText(){
// Update the gyroscope data
magneX.setText(String.format("%.6f", magnetometer[0]));
magneY.setText(String.format("%.6f", magnetometer[1]));
magneZ.setText(String.format("%.6f", magnetometer[2]));
}
// Adjust sampling rate for Gyroscope
public void HandleGyr(){
Handler handlerGyroscope = new Handler();
handlerGyroscope.postDelayed(new Runnable() {
#Override
public void run() {
new_gyroscope[0]=gyroscope[0];
new_gyroscope[1]=gyroscope[1];
new_gyroscope[2]=gyroscope[2];
}
}, 5);
}
// Adjust sampling rate for Magnetometer
public void HandleMag(){
Handler handlerMagnetometer = new Handler();
handlerMagnetometer.postDelayed(new Runnable() {
#Override
public void run() {
new_magnetometer[0]=magnetometer[0];
new_magnetometer[1]=magnetometer[1];
new_magnetometer[2]=magnetometer[2];
}
}, 100);
}
public void writeAcc(){
try {
out.write(content1.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
public void writeGyr(){
try {
out.write(content2.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
public void writeMag(){
try {
out.write(content3.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
XML:
<?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=".RecordDataActivity">
<TextView
android:id="#+id/raw_label_acc_x"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="#+id/checkBox"
android:layout_marginStart="133dp"
android:paddingRight="20dp"
android:text="X:"
android:textColor="#color/graphX" />
<TextView
android:id="#+id/raw_label_acc_y"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="133dp"
android:layout_below="#+id/raw_label_acc_x"
android:paddingRight="20dp"
android:text="Y:"
android:textColor="#color/graphY" />
<TextView
android:id="#+id/raw_label_acc_z"
android:layout_width="wrap_content"
android:layout_marginStart="133dp"
android:layout_height="wrap_content"
android:layout_below="#+id/raw_label_acc_y"
android:paddingRight="20dp"
android:text="Z:"
android:textColor="#color/graphZ" />
<TextView
android:id="#+id/raw_value_acc_x"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/raw_label_acc_x"
android:layout_alignBottom="#+id/raw_label_acc_x"
android:layout_toEndOf="#+id/raw_label_acc_x"
android:textColor="#color/graphX" />
<TextView
android:id="#+id/raw_value_acc_y"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/raw_label_acc_y"
android:layout_alignBottom="#+id/raw_label_acc_y"
android:layout_toEndOf="#+id/raw_label_acc_y"
android:textColor="#color/graphY" />
<TextView
android:id="#+id/raw_value_acc_z"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/raw_label_acc_z"
android:layout_alignBottom="#+id/raw_label_acc_z"
android:layout_toEndOf="#+id/raw_label_acc_z"
android:textColor="#color/graphZ" />
<TextView
android:id="#+id/raw_label_gyro_x"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="#+id/checkBox2"
android:layout_marginStart="133dp"
android:paddingRight="20dp"
android:text="X:"
android:textColor="#color/graphX" />
<TextView
android:id="#+id/raw_label_gyro_y"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="133dp"
android:layout_below="#+id/raw_label_gyro_x"
android:paddingRight="20dp"
android:text="Y:"
android:textColor="#color/graphY" />
<TextView
android:id="#+id/raw_label_gyro_z"
android:layout_width="wrap_content"
android:layout_marginStart="133dp"
android:layout_height="wrap_content"
android:layout_below="#+id/raw_label_gyro_y"
android:paddingRight="20dp"
android:text="Z:"
android:textColor="#color/graphZ" />
<TextView
android:id="#+id/raw_value_gyro_x"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/raw_label_gyro_x"
android:layout_alignBottom="#+id/raw_label_gyro_x"
android:layout_toEndOf="#+id/raw_label_gyro_x"
android:textColor="#color/graphX" />
<TextView
android:id="#+id/raw_value_gyro_y"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/raw_label_gyro_y"
android:layout_alignBottom="#+id/raw_label_gyro_y"
android:layout_toEndOf="#+id/raw_label_gyro_y"
android:textColor="#color/graphY" />
<TextView
android:id="#+id/raw_value_gyro_z"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/raw_label_gyro_z"
android:layout_alignBottom="#+id/raw_label_gyro_z"
android:layout_toEndOf="#+id/raw_label_gyro_z"
android:textColor="#color/graphZ" />
<TextView
android:id="#+id/raw_label_magne_x"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="#+id/checkBox3"
android:layout_marginStart="133dp"
android:paddingRight="20dp"
android:text="X:"
android:textColor="#color/graphX" />
<TextView
android:id="#+id/raw_label_magne_y"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="133dp"
android:layout_below="#+id/raw_label_magne_x"
android:paddingRight="20dp"
android:text="Y:"
android:textColor="#color/graphY" />
<TextView
android:id="#+id/raw_label_magne_z"
android:layout_width="wrap_content"
android:layout_marginStart="133dp"
android:layout_height="wrap_content"
android:layout_below="#+id/raw_label_magne_y"
android:paddingRight="20dp"
android:text="Z:"
android:textColor="#color/graphZ" />
<TextView
android:id="#+id/raw_value_magne_x"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/raw_label_magne_x"
android:layout_alignBottom="#+id/raw_label_magne_x"
android:layout_toEndOf="#+id/raw_label_magne_x"
android:textColor="#color/graphX" />
<TextView
android:id="#+id/raw_value_magne_y"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/raw_label_magne_y"
android:layout_alignBottom="#+id/raw_label_magne_y"
android:layout_toEndOf="#+id/raw_label_magne_y"
android:textColor="#color/graphY" />
<TextView
android:id="#+id/raw_value_magne_z"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/raw_label_magne_z"
android:layout_alignBottom="#+id/raw_label_magne_z"
android:layout_toEndOf="#+id/raw_label_magne_z"
android:textColor="#color/graphZ" />
<Chronometer
android:id="#+id/chronometer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="193dp"
android:textSize="22sp" />
<EditText
android:id="#+id/edit_text"
android:layout_width="match_parent"
android:layout_height="58dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:background="#drawable/rounded_edittext"
android:inputType="" />
<Button
android:id="#+id/button_record"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="126dp"
android:background="#drawable/button_quit"
android:shadowColor="#8A8A8A"
android:shadowDx="0"
android:shadowDy="1"
android:text="#string/record"
android:textColor="#FFF1D6"
android:textSize="18sp"
tools:ignore="OnClick"
tools:text="Record" />
<Button
android:id="#+id/button_stop"
android:layout_width="181dp"
android:layout_height="38dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="79dp"
android:background="#drawable/button_bulb_led"
android:shadowColor="#8A8A8A"
android:shadowDx="0"
android:shadowDy="1"
android:text="#string/save"
android:textColor="#FFF1D6"
android:textSize="18sp"
tools:ignore="OnClick"
tools:text="Save" />
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="#string/accelerometer"
android:textSize="20sp" />
<CheckBox
android:id="#+id/checkBox2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/button_record"
android:layout_below="#+id/raw_label_acc_z"
android:text="#string/gyroscope"
android:textSize="20sp" />
<CheckBox
android:id="#+id/checkBox3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/raw_label_gyro_z"
android:layout_centerHorizontal="true"
android:text="#string/magnetometer"
android:textSize="20sp" />
</RelativeLayout>
Are there any additional libraries that contain button graphics for the Android ExoPlayer found here. There are the options for fast forward, rewind, play, pause and a few others but there are no options for a mute/unmute or fast forward 2x/4x/etc. I want those options as I build an alternative UI.
Change the Media Controller to provide the options that going to mute/unmute or fast forward. For adding these view(Buttons) in to the view of controller then for that customize the media controller. Check this also Custom Media Controller
VideoControllerView
public class VideoControllerView extends FrameLayout {
private static final String TAG = "VideoControllerView";
private MediaPlayerControl mPlayer;
private Context mContext;
private ViewGroup mAnchor;
private View mRoot;
private ProgressBar mProgress;
private TextView mEndTime, mCurrentTime;
private boolean mShowing;
private boolean mDragging;
private static final int sDefaultTimeout = 3000;
private static final int FADE_OUT = 1;
private static final int SHOW_PROGRESS = 2;
private boolean mUseFastForward;
private boolean mFromXml;
private boolean mListenersSet;
private OnClickListener mNextListener;
StringBuilder mFormatBuilder;
Formatter mFormatter;
private ImageButton mPauseButton;
private ImageButton mVolumeButton;
private ImageButton mRewButton;
private ImageButton mSettingButton;
private Button mQualityButton;
private ImageButton mFullscreenButton;
private Handler mHandler = new MessageHandler(this);
private SeekBar seekbar;
private AudioManager audioManager;
private TextView txtVolume;
public VideoControllerView(Context context, AttributeSet attrs) {
super(context, attrs);
mRoot = null;
mContext = context;
mUseFastForward = true;
mFromXml = true;
Log.i(TAG, TAG);
}
public VideoControllerView(Context context, boolean useFastForward) {
super(context);
mContext = context;
mUseFastForward = useFastForward;
Log.i(TAG, TAG);
}
public VideoControllerView(Context context) {
this(context, true);
Log.i(TAG, TAG);
}
#SuppressLint("MissingSuperCall")
#Override
public void onFinishInflate() {
if (mRoot != null)
initControllerView(mRoot);
}
public void setMediaPlayer(MediaPlayerControl player) {
mPlayer = player;
updatePausePlay();
updateFullScreen(false);
}
/**
* Set the view that acts as the anchor for the control view.
* This can for example be a VideoView, or your Activity's main view.
*
* #param view The view to which to anchor the controller when it is visible.
*/
public void setAnchorView(ViewGroup view) {
mAnchor = view;
LayoutParams frameParams = new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
removeAllViews();
View v = makeControllerView();
addView(v, frameParams);
}
/**
* Create the view that holds the widgets that control playback.
* Derived classes can override this to create their own.
*
* #return The controller view.
* #hide This doesn't work as advertised
*/
protected View makeControllerView() {
LayoutInflater inflate = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mRoot = inflate.inflate(R.layout.custom_media_controller, null);
initControllerView(mRoot);
return mRoot;
}
#SuppressLint("WrongViewCast")
private void initControllerView(View v) {
mPauseButton = (ImageButton) v.findViewById(R.id.pause);
if (mPauseButton != null) {
mPauseButton.requestFocus();
mPauseButton.setOnClickListener(mPauseListener);
}
mFullscreenButton = (ImageButton) v.findViewById(R.id.fullscreen);
if (mFullscreenButton != null) {
mFullscreenButton.requestFocus();
mFullscreenButton.setOnClickListener(mFullscreenListener);
}
mVolumeButton = (ImageButton) v.findViewById(R.id.volume);
if (mVolumeButton != null) {
mVolumeButton.setOnClickListener(mVolumeListener);
if (!mFromXml) {
//mVolumeButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE);
}
}
mRewButton = (ImageButton) v.findViewById(R.id.rew);
if (mRewButton != null) {
mRewButton.setOnClickListener(mRewListener);
if (!mFromXml) {
mRewButton.setVisibility(mUseFastForward ? View.VISIBLE : View.GONE);
}
}
// By default these are hidden. They will be enabled when setPrevNextListeners() is called
mSettingButton = (ImageButton) v.findViewById(R.id.settings);
if (mSettingButton != null && !mFromXml && !mListenersSet) {
// mSettingButton.setVisibility(View.GONE);
}
mQualityButton = (Button) v.findViewById(R.id.quality);
if (mQualityButton != null && !mFromXml && !mListenersSet) {
//mQualityButton.setVisibility(View.GONE);
}
mProgress = (ProgressBar) v.findViewById(R.id.mediacontroller_progress);
if (mProgress != null) {
if (mProgress instanceof SeekBar) {
SeekBar seeker = (SeekBar) mProgress;
seeker.setOnSeekBarChangeListener(mSeekListener);
}
mProgress.setMax(1000);
}
mEndTime = (TextView) v.findViewById(R.id.time);
mCurrentTime = (TextView) v.findViewById(R.id.time_current);
mFormatBuilder = new StringBuilder();
mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
installPrevNextListeners();
}
/**
* Show the controller on screen. It will go away
* automatically after 3 seconds of inactivity.
*/
public void show() {
show(sDefaultTimeout);
}
/**
* Disable pause or seek buttons if the stream cannot be paused or seeked.
* This requires the control interface to be a MediaPlayerControlExt
*/
private void disableUnsupportedButtons() {
if (mPlayer == null) {
return;
}
try {
if (mPauseButton != null && !mPlayer.canPause()) {
mPauseButton.setEnabled(false);
}
if (mRewButton != null && !mPlayer.canSeekBackward()) {
mRewButton.setEnabled(false);
}
if (mVolumeButton != null && !mPlayer.canSeekForward()) {
mVolumeButton.setEnabled(false);
}
} catch (IncompatibleClassChangeError ex) {
// We were given an old version of the interface, that doesn't have
// the canPause/canSeekXYZ methods. This is OK, it just means we
// assume the media can be paused and seeked, and so we don't disable
// the buttons.
}
}
/**
* Show the controller on screen. It will go away
* automatically after 'timeout' milliseconds of inactivity.
*
* #param timeout The timeout in milliseconds. Use 0 to show
* the controller until hide() is called.
*/
public void show(int timeout) {
if (!mShowing && mAnchor != null) {
setProgress();
if (mPauseButton != null) {
mPauseButton.requestFocus();
}
disableUnsupportedButtons();
LayoutParams tlp = new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
Gravity.BOTTOM
);
mAnchor.addView(this, tlp);
mShowing = true;
}
updatePausePlay();
// cause the progress bar to be updated even if mShowing
// was already true. This happens, for example, if we're
// paused with the progress bar showing the user hits play.
mHandler.sendEmptyMessage(SHOW_PROGRESS);
Message msg = mHandler.obtainMessage(FADE_OUT);
if (timeout != 0) {
mHandler.removeMessages(FADE_OUT);
mHandler.sendMessageDelayed(msg, timeout);
}
}
public boolean isShowing() {
return mShowing;
}
/**
* Remove the controller from the screen.
*/
public void hide() {
if (mAnchor == null) {
return;
}
try {
mAnchor.removeView(this);
mHandler.removeMessages(SHOW_PROGRESS);
} catch (IllegalArgumentException ex) {
Log.w("MediaController", "already removed");
}
mShowing = false;
}
private String stringForTime(int timeMs) {
int totalSeconds = timeMs / 1000;
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
mFormatBuilder.setLength(0);
if (hours > 0) {
return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
} else {
return mFormatter.format("%02d:%02d", minutes, seconds).toString();
}
}
private int setProgress() {
if (mPlayer == null || mDragging) {
return 0;
}
int position = mPlayer.getCurrentPosition();
int duration = mPlayer.getDuration();
//Log.d(TAG, "Duration->" + duration);
//Log.d(TAG, "Duration Current->" + position);
if (mProgress != null) {
if (duration > 0) {
// use long to avoid overflow
long pos = 1000L * position / duration;
mProgress.setProgress((int) pos);
}
int percent = mPlayer.getBufferPercentage();
mProgress.setSecondaryProgress(percent * 10);
}
if (mEndTime != null)
mEndTime.setText(stringForTime(duration));
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime(position));
return position;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
show(sDefaultTimeout);
return true;
}
#Override
public boolean onTrackballEvent(MotionEvent ev) {
show(sDefaultTimeout);
return false;
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (mPlayer == null) {
return true;
}
int keyCode = event.getKeyCode();
final boolean uniqueDown = event.getRepeatCount() == 0
&& event.getAction() == KeyEvent.ACTION_DOWN;
if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK
|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
|| keyCode == KeyEvent.KEYCODE_SPACE) {
if (uniqueDown) {
doPauseResume();
show(sDefaultTimeout);
if (mPauseButton != null) {
mPauseButton.requestFocus();
}
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {
if (uniqueDown && !mPlayer.isPlaying()) {
mPlayer.start();
updatePausePlay();
show(sDefaultTimeout);
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP
|| keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {
if (uniqueDown && mPlayer.isPlaying()) {
mPlayer.pause();
updatePausePlay();
show(sDefaultTimeout);
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_VOLUME_UP
|| keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
// don't show the controls for volume adjustment
return super.dispatchKeyEvent(event);
} else if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU) {
if (uniqueDown) {
hide();
}
return true;
}
show(sDefaultTimeout);
return super.dispatchKeyEvent(event);
}
private OnClickListener mPauseListener = new OnClickListener() {
public void onClick(View v) {
doPauseResume();
show(sDefaultTimeout);
}
};
private OnClickListener mQualityChangeListener = new OnClickListener() {
public void onClick(View v) {
mPlayer.updateVideoQuality();
}
};
private OnClickListener mFullscreenListener = new OnClickListener() {
public void onClick(View v) {
doToggleFullscreen();
show(sDefaultTimeout);
}
};
public void updatePausePlay() {
if (mRoot == null || mPauseButton == null || mPlayer == null) {
return;
}
if (mPlayer.isPlaying()) {
mPauseButton.setImageResource(R.drawable.ic_pause);
} else {
mPauseButton.setImageResource(R.drawable.ic_play);
}
}
public void updateFullScreen(boolean isFullScreen) {
if (mRoot == null || mFullscreenButton == null || mPlayer == null) {
return;
}
if (isFullScreen) {
mFullscreenButton.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_unstretch));
} else {
mFullscreenButton.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_stretch));
}
}
private void doPauseResume() {
if (mPlayer == null) {
return;
}
if (mPlayer.isPlaying()) {
mPlayer.pause();
} else {
mPlayer.start();
}
updatePausePlay();
}
private void doToggleFullscreen() {
if (mPlayer == null) {
return;
}
if (mPlayer.isFullScreen()) {
mFullscreenButton.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_unstretch));
} else {
mFullscreenButton.setImageDrawable(mContext.getResources().getDrawable(R.drawable.ic_stretch));
}
mPlayer.toggleFullScreen();
}
// There are two scenarios that can trigger the seekbar listener to trigger:
//
// The first is the user using the touchpad to adjust the posititon of the
// seekbar's thumb. In this case onStartTrackingTouch is called followed by
// a number of onProgressChanged notifications, concluded by onStopTrackingTouch.
// We're setting the field "mDragging" to true for the duration of the dragging
// session to avoid jumps in the position in case of ongoing playback.
//
// The second scenario involves the user operating the scroll ball, in this
// case there WON'T BE onStartTrackingTouch/onStopTrackingTouch notifications,
// we will simply apply the updated position without suspending regular updates.
private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
public void onStartTrackingTouch(SeekBar bar) {
show(3600000);
mDragging = true;
// By removing these pending progress messages we make sure
// that a) we won't update the progress while the user adjusts
// the seekbar and b) once the user is done dragging the thumb
// we will post one of these messages to the queue again and
// this ensures that there will be exactly one message queued up.
mHandler.removeMessages(SHOW_PROGRESS);
}
public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
if (mPlayer == null) {
return;
}
if (!fromuser) {
// We're not interested in programmatically generated changes to
// the progress bar's position.
return;
}
long duration = mPlayer.getDuration();
long newposition = (duration * progress) / 1000L;
mPlayer.seekTo((int) newposition);
if (mCurrentTime != null)
mCurrentTime.setText(stringForTime((int) newposition));
}
public void onStopTrackingTouch(SeekBar bar) {
mDragging = false;
setProgress();
updatePausePlay();
show(sDefaultTimeout);
// Ensure that progress is properly updated in the future,
// the call to show() does not guarantee this because it is a
// no-op if we are already showing.
mHandler.sendEmptyMessage(SHOW_PROGRESS);
}
};
#Override
public void setEnabled(boolean enabled) {
if (mPauseButton != null) {
mPauseButton.setEnabled(enabled);
}
if (mVolumeButton != null) {
mVolumeButton.setEnabled(enabled);
}
if (mRewButton != null) {
mRewButton.setEnabled(enabled);
}
if (mSettingButton != null) {
mSettingButton.setEnabled(enabled && mNextListener != null);
}
if (mQualityButton != null) {
mQualityButton.setEnabled(enabled && mQualityChangeListener != null);
}
if (mProgress != null) {
mProgress.setEnabled(enabled);
}
disableUnsupportedButtons();
super.setEnabled(enabled);
}
private OnClickListener mRewListener = new OnClickListener() {
public void onClick(View v) {
if (mPlayer == null) {
return;
}
int pos = mPlayer.getCurrentPosition();
pos -= 15000; // milliseconds
mPlayer.seekTo(pos);
setProgress();
show(sDefaultTimeout);
}
};
private OnClickListener mVolumeListener = new OnClickListener() {
public void onClick(View v) {
if (mPlayer == null) {
return;
}
showPopup(mContext);
}
};
private void installPrevNextListeners() {
if (mSettingButton != null) {
mSettingButton.setOnClickListener(mNextListener);
mSettingButton.setEnabled(mNextListener != null);
}
if (mQualityButton != null) {
mQualityButton.setOnClickListener(mQualityChangeListener);
mQualityButton.setEnabled(mQualityChangeListener != null);
}
}
public void setPrevNextListeners(OnClickListener next, OnClickListener prev) {
mNextListener = next;
mQualityChangeListener = prev;
mListenersSet = true;
if (mRoot != null) {
installPrevNextListeners();
if (mSettingButton != null && !mFromXml) {
mSettingButton.setVisibility(View.VISIBLE);
}
if (mQualityButton != null && !mFromXml) {
mQualityButton.setVisibility(View.VISIBLE);
}
}
}
public interface MediaPlayerControl {
void start();
void pause();
int getDuration();
int getCurrentPosition();
void seekTo(int pos);
boolean isPlaying();
int getAudioSessionId();
int getBufferPercentage();
boolean canPause();
boolean canSeekBackward();
boolean canSeekForward();
boolean isFullScreen();
void toggleFullScreen();
void updateVideoQuality();
}
private static class MessageHandler extends Handler {
private final WeakReference<VideoControllerView> mView;
MessageHandler(VideoControllerView view) {
mView = new WeakReference<VideoControllerView>(view);
}
#Override
public void handleMessage(Message msg) {
VideoControllerView view = mView.get();
if (view == null || view.mPlayer == null) {
return;
}
int pos;
switch (msg.what) {
case FADE_OUT:
view.hide();
break;
case SHOW_PROGRESS:
pos = view.setProgress();
if (!view.mDragging && view.mShowing && view.mPlayer.isPlaying()) {
msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, 1000 - (pos % 1000));
}
break;
}
}
}
// The method that displays the popup.
private void showPopup(final Context context) {
final Dialog dialog = new Dialog(context,
android.R.style.Theme_Translucent_NoTitleBar);
// Inflate the popup_layout.xml
LinearLayout viewGroup = (LinearLayout) findViewById(R.id.popup);
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = layoutInflater.inflate(R.layout.popup_volumebar, viewGroup);
seekbar = (SeekBar) layout.findViewById(R.id.seekBar1);
txtVolume = (TextView) layout.findViewById(R.id.txtPopupVolume);
// Setting dialogview
Window window = dialog.getWindow();
window.setGravity(Gravity.CENTER | Gravity.END);
window.setLayout(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
dialog.setTitle(null);
dialog.setCanceledOnTouchOutside(true);
dialog.setContentView(layout);
dialog.setCancelable(true);
dialog.show();
initControls();
}
private void initControls() {
try {
audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
seekbar.setMax(audioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
seekbar.setProgress(audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC));
txtVolume.setText("" + audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar arg0) {
}
#Override
public void onStartTrackingTouch(SeekBar arg0) {
}
#Override
public void onProgressChanged(SeekBar arg0, int progress, boolean arg2) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
progress, 0);
txtVolume.setText("" + progress);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
and custom_media_controller.xml
<?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:layout_gravity="center_horizontal"
android:background="#color/TvControllerBackground"
android:gravity="center_horizontal"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:paddingTop="4dip">
<Button
android:id="#+id/quality"
style="#style/MediaButton.Previous"
android:background="#null"
android:contentDescription="#string/description"
android:paddingLeft="#dimen/size_5"
android:paddingRight="#dimen/size_5"
android:text="#string/hd"
android:textColor="#color/white"
android:textStyle="bold"
android:visibility="gone" />
<ImageButton
android:id="#+id/rew"
style="#style/MediaButton.Rew"
android:contentDescription="#string/description"
android:visibility="gone" />
<ImageButton
android:id="#+id/pause"
style="#style/MediaButton.Play"
android:contentDescription="#string/description" />
<ImageButton
android:id="#+id/volume"
style="#style/MediaButton.Ffwd"
android:contentDescription="#string/description" />
<ImageButton
android:id="#+id/settings"
style="#style/MediaButton.Setting"
android:contentDescription="#string/description"
android:visibility="gone" />
<ImageButton
android:id="#+id/fullscreen"
style="#style/MediaButton.FullScreen"
android:contentDescription="#string/description"
android:visibility="visible" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingBottom="#dimen/size_5">
<TextView
android:id="#+id/time_current"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:paddingTop="4dip"
android:textSize="14sp"
android:textStyle="bold" />
<SeekBar
android:id="#+id/mediacontroller_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dip"
android:layout_height="32dip"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:progressDrawable="#drawable/apptheme_scrubber_progress_horizontal_holo_light"
android:thumb="#drawable/apptheme_scrubber_control_selector_holo_light" />
<TextView
android:id="#+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:paddingTop="4dip"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>