ML Kit Firebase textDetection does not detect clearly - java

The project that show in textView after taked photo from camera. Using Firebase ML kit for text detection. That's not detect text clearly. It detect some of words but not detect all clearly. Using bitmap for it I don't if this bitmap make this problem. Should I use SurfaceView for camera? Or whats solution to solve that?
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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:layout_height="match_parent"
tools:context=".MainActivity">
<ImageButton
android:id="#+id/cameraButton"
android:layout_width="108dp"
android:layout_height="72dp"
android:layout_marginStart="44dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="32dp"
android:background="#color/white"
android:src="#drawable/ic_baseline_camera_alt_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView"
app:layout_constraintVertical_bias="0.427" />
<ImageButton
android:id="#+id/detectButton"
android:layout_width="108dp"
android:layout_height="72dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="44dp"
android:layout_marginBottom="41dp"
android:background="#color/white"
android:src="#drawable/ic_baseline_done_outline_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView"
app:layout_constraintVertical_bias="0.445" />
<ImageView
android:id="#+id/mImageView"
android:layout_width="0dp"
android:layout_height="346dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:scaleType="fitXY"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_baseline_image_24" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="16dp"
android:fontFamily="#font/segoeui"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/mImageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
ImageView mImageView;
ImageButton cameraBtn;
ImageButton detectBtn;
Bitmap imageBitmap;
TextView textView;
String log = "error";
static final int REQUEST_IMAGE_CAPTURE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.mImageView);
cameraBtn = findViewById(R.id.cameraButton);
detectBtn = findViewById(R.id.detectButton);
textView = findViewById(R.id.textView);
textView.setTypeface(ResourcesCompat.getFont(this, R.font.segoeui));
cameraBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dispatchTakePictureIntent();
textView.setText("");
}
});
detectBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
detectTextFromImage();
}
});
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager())!= null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
imageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(imageBitmap);
}
}
private void detectTextFromImage() {
FirebaseVisionImage firebaseVisionImage = FirebaseVisionImage.fromBitmap(imageBitmap);
FirebaseVisionCloudTextRecognizerOptions options = new FirebaseVisionCloudTextRecognizerOptions.Builder()
.setLanguageHints(Arrays.asList("eng","hi"))
.build();
FirebaseVisionTextRecognizer detector = FirebaseVision.getInstance()
.getCloudTextRecognizer(options);
Task<FirebaseVisionText> result =
detector.processImage(firebaseVisionImage)
.addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() {
#Override
public void onSuccess(FirebaseVisionText firebaseVisionText) {
// Task completed successfully
// ...
displayTextFromImage(firebaseVisionText);
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// Task failed with an exception
}
});
}
private void displayTextFromImage(FirebaseVisionText firebaseVisionText) {
List<FirebaseVisionText.TextBlock> blockList = firebaseVisionText.getTextBlocks();
if (blockList.size() == 0){
Toast.makeText(this,"No Text Found in image!",Toast.LENGTH_SHORT).show();
}
else{
for (FirebaseVisionText.TextBlock block: firebaseVisionText.getTextBlocks()) {
String text = block.getText();
textView.setText(text);
}
}
}

There's a sample app of text recognition on both iOS and Android platform at https://developers.google.com/ml-kit/samples (vision quickstart), and seems like both can detect the text within given image successfully?

private void displayTextFromImage(FirebaseVisionText firebaseVisionText) { List<FirebaseVisionText.TextBlock> blockList = firebaseVisionText.getTextBlocks(); if (blockList.size() == 0){ Toast.makeText(this,"No Text Found in image!",Toast.LENGTH_SHORT).show(); } else{ String text = ""; for (FirebaseVisionText.TextBlock block: firebaseVisionText.getTextBlocks()) { text = text + "\n" + block.getText(); textView.setText(text); } } }
By declaring and initializing String text inside for loop, will cause you lost the text of previous block. Actually, it takes each line as one block. Loop executes so fast, then you see only last line or last block of text set as your textview. Replace that code with this one, to resolve that issue.

Related

How to portrait QR code scanner using Zxing Library?

I'm quite new in Android Studio. How to portrait this simple qr code scanner?
Library
compile 'com.journeyapps:zxing-android-embedded:3.4.0'
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//View Objects
private Button buttonScan;
private TextView textViewName, textViewAddress;
//qr code scanner object
private IntentIntegrator qrScan;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//View objects
buttonScan = (Button) findViewById(R.id.buttonScan);
textViewName = (TextView) findViewById(R.id.textViewName);
textViewAddress = (TextView) findViewById(R.id.textViewAddress);
//intializing scan object
qrScan = new IntentIntegrator(this);
//attaching onclick listener
buttonScan.setOnClickListener(this);
}
//Getting the scan results
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if (result != null) {
//if qrcode has nothing in it
if (result.getContents() == null) {
Toast.makeText(this, "Result Not Found", Toast.LENGTH_LONG).show();
} else {
//if qr contains data
try {
//converting the data to json
JSONObject obj = new JSONObject(result.getContents());
//setting values to textviews
textViewName.setText(obj.getString("name"));
textViewAddress.setText(obj.getString("address"));
} catch (JSONException e) {
e.printStackTrace();
//if control comes here
//that means the encoded format not matches
//in this case you can display whatever data is available on the qrcode
//to a toast
Toast.makeText(this, result.getContents(), Toast.LENGTH_LONG).show();
}
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
#Override
public void onClick(View view) {
//initiating the qr code scan
qrScan.initiateScan();
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Name" />
<TextView
android:id="#+id/textViewName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Address" />
<TextView
android:id="#+id/textViewAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large" />
</LinearLayout>
<Button
android:id="#+id/buttonScan"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Scan QR Code" />
</RelativeLayout>
I already inserted from AndroidManifest.xml in activity like this
android:screenOrientation="portrait" and android:screenOrientation="userPortrait".
The rest, I can't fix the problem.

Set image as wallpaper from url (Glide + json)

app
app
Hi, thanks in advance to those who guide me.
I have a problem with the Set Wallpaper, that when I clicked on the button, I get the following error:
2018-12-28 22: 36: 02.801 13030-13030 /? E / AndroidRuntime: FATAL EXCEPTION: main
     java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress (android.graphics.Bitmap $ CompressFormat, int, java.io.OutputStream)' on a null object reference
I leave the files used.
<?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="match_parent"
android:layout_gravity="center"
android:orientation="vertical"
android:id="#+id/thumbnail2"
android:padding="5dp">
<TextView
android:id="#+id/txtclose"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="end"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:background="#drawable/circulo"
android:gravity="center"
android:text="#string/equis"
android:textColor="#android:color/background_light"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="end">
<Button
android:id="#+id/btn"
android:layout_width="159dp"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:layout_marginBottom="25dp"
android:background="#drawable/borde_redondo"
android:text="Establecer como Fondo de Pantalla"
android:textColor="#ffffff" />
</FrameLayout>
</LinearLayout>
</LinearLayout>
public class infoanimales extends AppCompatActivity {
private RequestOptions options;
TextView txtclose;
LinearLayout img;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_infoanimales);
Button button = findViewById(R.id.btn);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setWallpaper();
}
});
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
this.options = new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC);
String image_url = getIntent().getExtras().getString("img2");
img = findViewById(R.id.thumbnail2);
Glide.with(this).load(image_url).into(new SimpleTarget<Drawable>() {
#Override
public void onResourceReady(#NonNull Drawable fondoreceta, Transition<? super Drawable> transition) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
img.setBackground(fondoreceta);
}
}
});
TextView txtclose = findViewById(R.id.txtclose);
txtclose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
private void setWallpaper() {
Bitmap bitmap = BitmapFactory.decodeFile("img2");
WallpaperManager manager = WallpaperManager.getInstance(getApplicationContext());
try {
manager.setBitmap(bitmap);
Toast.makeText(this, "Listo", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(this, "error", Toast.LENGTH_SHORT).show();
}
}
}
With this function, it works perfect, but that is having the images in the drawable folder, and what you want or what it is that you take the image of the json url, traide with glide
private void setWallpaper() {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.cochinito);
WallpaperManager manager = WallpaperManager.getInstance(getApplicationContext());
try {
manager.setBitmap(bitmap);
Toast.makeText(this, "Listo", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(this, "error", Toast.LENGTH_SHORT).show();
}
}
In conclusion, what I need is that when you click on the button, the displayed image is set as wallpaper
As I can see, you are not using full path for decoding bitmap. You need to obtain full path name like:
String uri = Environment.getExternalStorageDirectory().toString() + "/" + PHOTO_DIR + "/test.jpg";
After that:
Bitmap bitmap = BitmapFactory.decodeFile(uri);
Reference
Set wallpaper with Glide4+ I did like this:
public void setAsWallpaper() {
Glide.with(requireContext())
.asBitmap()
.load(listItem.get(position).getWallpaperImage())
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(#NonNull Bitmap resource, #Nullable Transition<? super Bitmap> transition) {
try {
WallpaperManager.getInstance(requireContext()).setBitmap(resource);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}

textRecognizer.detect(frame); it returns size as 0

I am using google vision API and trying to get the text from the captured image.
I have set the captured image in an image view and then I am trying to get the text from the image. but I am getting SparseArray of size 0. what can be the problem. Here is my java code.
public class MainActivity extends AppCompatActivity {
ImageView imgPic;
TextView tvText;
Button btnClick, btnCapture;
private int REQUEST_IMAGE_CAPTURE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imgPic = findViewById(R.id.img_pic);
tvText = findViewById(R.id.tv_text);
btnClick = findViewById(R.id.btn_click);
btnCapture = findViewById(R.id.btn_capture);
btnCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
});
btnClick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bitmap bitmap;
if (imgPic.getDrawable() != null && imgPic.getDrawable() instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) imgPic.getDrawable()).getBitmap();
}
TextRecognizer textRecognizer = new TextRecognizer.Builder(getApplicationContext()).build();
if (!textRecognizer.isOperational()) {
Toast.makeText(MainActivity.this, "could not get the text", Toast.LENGTH_SHORT).show();
} else {
if (bitmap != null) {
Frame frame = new Frame.Builder().setBitmap(bitmap).build();
SparseArray<TextBlock> items = textRecognizer.detect(frame);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < items.size(); i++) {
TextBlock myItem = items.valueAt(i);
Log.e("hello", (String) myItem.getValue());
sb.append(myItem.getValue());
sb.append("\n");
}
tvText.setText(sb.toString());
} else {
Toast.makeText(MainActivity.this, "returned null", Toast.LENGTH_SHORT).show();
}
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
imgPic.setImageBitmap(imageBitmap);
}
}
}
here is my main activity xml file.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="#+id/btn_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="capture"
/>
<ImageView
android:id="#+id/img_pic"
android:layout_width="370dp"
android:layout_height="300dp" />
<TextView
android:textColor="#color/colorAccent"
android:id="#+id/tv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="25sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click here"
android:id="#+id/btn_click"/>
</LinearLayout>
The main thing is when i set image manually in an imageView it shows the result but when i capture the image by my self and then i try to get the text i am not getting the results i am always gets a 0 sized array.
Why don't you store the bitmap in a global variable? You can of course convert the drawable of an ImageView back to a bitmap but this requires extra ressources.
Anyway the answer to your question would be:
if(imgPic.getDrawable() != null && imgPic.getDrawable() instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable)imgPic.getDrawable()).getBitmap();
}
You should check if the drawable is not null and if the bitmap stored inside the drawable is really of type BitmapDrawable.

How to get value from Radiogroup and change in database

I am working on an application in android studio with firebase where the user can change user settings such as name, phone number and bio.
I also need the ability to change a selected radio group button value.
The Settings activity class is as follows
public class SettingsActivity extends AppCompatActivity {
private EditText mNameField, mPhoneField, mBio;
private Button mBack, mConfirm;
private RadioGroup mSport;
private ImageView mProfileImage;
private FirebaseAuth mAuth;
private DatabaseReference mUserDatabase;
private String userId, name, phone, bio, sport, profileImageUrl, userSex;
private Uri resultUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
mNameField = (EditText) findViewById(R.id.name);
mPhoneField = (EditText) findViewById(R.id.phone);
mBio = (EditText) findViewById(R.id.bio);
mSport = (RadioGroup) findViewById(R.id.sport);
mProfileImage = (ImageView) findViewById(R.id.profileImage);
mBack = (Button) findViewById(R.id.back);
mConfirm = (Button) findViewById(R.id.confirm);
mAuth = FirebaseAuth.getInstance();
userId = mAuth.getCurrentUser().getUid();
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(userId);
getUserInfo();
mProfileImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 1);
}
});
mConfirm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
saveUserInformation();
}
});
mBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
return;
}
});
}
private void getUserInfo() {
mUserDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists() && dataSnapshot.getChildrenCount()>0){
Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();
if(map.get("name")!=null){
name = map.get("name").toString();
mNameField.setText(name);
}
if(map.get("phone")!=null){
phone = map.get("phone").toString();
mPhoneField.setText(phone);
}
if(map.get("bio")!=null){
bio = map.get("bio").toString();
mBio.setText(bio);
}
if(map.get("sport")!=null){
}
if(map.get("sex")!=null){
userSex = map.get("sex").toString();
}
if(map.get("sport") !=null){
}
Glide.clear(mProfileImage);
if(map.get("profileImageUrl")!=null){
profileImageUrl = map.get("profileImageUrl").toString();
switch(profileImageUrl){
case "default":
Glide.with(getApplication()).load(R.mipmap.default_app_image).into(mProfileImage);
break;
default:
Glide.with(getApplication()).load(profileImageUrl).into(mProfileImage);
break;
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void saveUserInformation() {
name = mNameField.getText().toString();
phone = mPhoneField.getText().toString();
bio = mBio.getText().toString();
int selectSport = mSport.getCheckedRadioButtonId();
final RadioButton sportButton = (RadioButton) findViewById(selectSport);
if(sportButton.getText() == null){
return;
}
Map userInfo = new HashMap();
userInfo.put("name", name);
userInfo.put("phone", phone);
userInfo.put("bio", bio);
userInfo.put("sport",sport);
mUserDatabase.updateChildren(userInfo);
if(resultUri != null){
StorageReference filepath = FirebaseStorage.getInstance().getReference().child("profileImages").child(userId);
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(getApplication().getContentResolver(), resultUri);
} catch (IOException e) {
e.printStackTrace();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = filepath.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
finish();
}
});
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
Map userInfo = new HashMap();
userInfo.put("profileImageUrl", downloadUrl.toString());
mUserDatabase.updateChildren(userInfo);
finish();
return;
}
});
}else{
finish();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1 && resultCode == Activity.RESULT_OK){
final Uri imageUri = data.getData();
resultUri = imageUri;
mProfileImage.setImageURI(resultUri);
}
}
and the XML file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.wk001764.finalproject.SettingsActivity"
android:orientation="vertical">
<ImageView
android:id="#+id/profileImage"
android:layout_width="200sp"
android:layout_height="200sp"
android:layout_gravity="center"
android:layout_marginBottom="20sp"
android:src="#mipmap/default_app_image" />
<EditText
android:id="#+id/name"
android:layout_width="398dp"
android:layout_height="wrap_content"
android:layout_marginBottom="20sp"
android:background="#null"
android:hint="Name" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/phone"
android:background="#null"
android:hint="Phone Number"
android:layout_marginBottom="20sp"
android:inputType="phone"/>
<EditText
android:id="#+id/bio"
android:layout_width="398dp"
android:layout_height="wrap_content"
android:layout_marginBottom="20sp"
android:background="#null"
android:hint="Bio" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Please Select the sport you want to change to:"/>
<RadioGroup
android:id="#+id/sport"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<RadioButton
android:id="#+id/badminton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Badminton" />
<RadioButton
android:id="#+id/basketball"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Basketball" />
<RadioButton
android:id="#+id/boxing"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Boxing" />
<RadioButton
android:id="#+id/cricket"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Cricket" />
<RadioButton
android:id="#+id/football"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Football" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<RadioButton
android:id="#+id/golf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Golf" />
<RadioButton
android:id="#+id/hockey"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hockey" />
<RadioButton
android:id="#+id/rugby"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Rugby" />
<RadioButton
android:id="#+id/swimming"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Swimming" />
<RadioButton
android:id="#+id/tennis"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Tennis" />
</LinearLayout>
</LinearLayout>
</RadioGroup>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/confirm"
android:text="Save"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/back"
android:text="Back"/>
</LinearLayout>
How would I get the new selected value of the radio group and save it to the database?
You should be able to do something like this:
int radioButtonId = mSport.getCheckedRadioButtonId();
View radioButton = mSport.findViewById(radioButtonId);
int idx = mSport.indexOfChild(radioButton);
To get selected RadioButton Text in a RadioGroup, please use the following code:
RadioButton rb = (RadioButton) mSport.getChildAt(idx);
String selectedText = rb.getText().toString();
But note, this code will work only if the radio buttons are direct children of your RadioGroup. So you need to remove those "LinearLayouts". In fact, there is no need to use those layouts at all. You can set the orientation of your RadioGroup to "vertical", in your .XML file, using the following line of code:
android:orientation="vertical"

On screen rotate only video should be displayed

I have used exoPlayer Library what i am trying to do is i pass data from recyclerview to next activity that works fine video is been played and title as well as desc is been fetched but when i rotate the phone i only want simpleexovideoview to displayed and video is playing but the activity name is still there.
I have used < android:configChanges="orientation|screenSize" > that handles the orientation change following is snapshot of activity
Portrait view
Landscape view
and code is as follows
videoplayer.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.kaushal.myapplication.MainActivity"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="81dp">
<android.support.constraint.Guideline
android:id="#+id/horizontalHalf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="256dp" />
<TextView
android:id="#+id/VideoTitle"
android:textSize="22sp"
android:text="video title"
android:textStyle="bold"
android:layout_margin="12dp"
android:textColor="#016699"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="#+id/horizontalHalf" />
<com.google.android.exoplayer2.ui.SimpleExoPlayerView
android:id="#+id/videoplayer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:adjustViewBounds="true"
app:layout_constraintBottom_toTopOf="#+id/horizontalHalf"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="#+id/VideoDesc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ems="10"
android:text="Video Desc"
app:layout_constraintLeft_toLeftOf="parent"
android:textSize="18sp"
android:layout_margin="12dp"
app:layout_constraintTop_toBottomOf="#+id/VideoTitle"
tools:layout_editor_absoluteY="477dp"
android:layout_marginLeft="12dp" />
</android.support.constraint.ConstraintLayout>
videoActivity
package com.example.kaushal.myapplication;
/**
* Created by kaushal on 06-09-2017.
*/
public class videoplay extends AppCompatActivity implements
ExoPlayer.EventListener {
TextView vidtitle, videodesc;
String videpath;
SimpleExoPlayer exoplayer;
SimpleExoPlayerView exoPlayerView;
PlaybackStateCompat.Builder videosessionBuilder;
final static String TAG = videoplay.class.getName();
private RelativeLayout.LayoutParams paramsNotFullscreen;
RelativeLayout rl;
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videoplayer);
vidtitle = (TextView) findViewById(R.id.VideoTitle);
videodesc = (TextView) findViewById(R.id.VideoDesc);
exoPlayerView = (SimpleExoPlayerView)
findViewById(R.id.videoplayer);
vidtitle.setText(getIntent().getStringExtra("videotitle"));
videodesc.setText(getIntent().getStringExtra("videodesc"));
videpath = getIntent().getStringExtra("videourl");
mediaSession();
Uri uri = Uri.parse(videpath);
intializePlayer(uri);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE){
paramsnotfullscreen= (RelativeLayout.LayoutParams)exoPlayerView.getLayoutParams();
RelativeLayout.LayoutParams params= new RelativeLayout.LayoutParams(paramsnotfullscreen);
params.setMargins(0, 0, 0, 0);
params.height= ViewGroup.LayoutParams.MATCH_PARENT;
params.width=ViewGroup.LayoutParams.MATCH_PARENT;
params.addRule(RelativeLayout.CENTER_IN_PARENT);
exoPlayerView.setLayoutParams(params);
}else if (newConfig.orientation==Configuration.ORIENTATION_PORTRAIT){
exoPlayerView.setLayoutParams(paramsnotfullscreen);
}
} //refrence = https://stackoverflow.com/questions/13011891/make-a-fullscreen-in-only-layout-land-android-when-play-videoview
public void intializePlayer(Uri uri) {
DefaultTrackSelector dfs = new DefaultTrackSelector();
DefaultLoadControl dfc = new DefaultLoadControl();
exoplayer = ExoPlayerFactory.newSimpleInstance(this, dfs, dfc);
exoPlayerView.setPlayer(exoplayer);
//Prepare Media source
String useragent = Util.getUserAgent(this, "MyApplication");
MediaSource mediaSource = new ExtractorMediaSource(uri, new DefaultDataSourceFactory(this, useragent),
new DefaultExtractorsFactory(), null, null);
exoplayer.prepare(mediaSource);
exoplayer.setPlayWhenReady(true);
}
public void releasePlayer() {
exoplayer.stop();
exoplayer.release();
exoplayer = null;
}
public void mediaSession() {
MediaSessionCompat mediaSessionCompat = new MediaSessionCompat(this, TAG);
mediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mediaSessionCompat.setMediaButtonReceiver(null);
videosessionBuilder = new PlaybackStateCompat.Builder().setActions(PlaybackStateCompat.ACTION_PLAY |
PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_PLAY_PAUSE);
mediaSessionCompat.setPlaybackState(videosessionBuilder.build());
mediaSessionCompat.setCallback(new mediaSessionCallback());
mediaSessionCompat.setActive(true);
}
public class mediaSessionCallback extends MediaSessionCompat.Callback {
#Override
public void onPlay() {
exoplayer.setPlayWhenReady(true);
}
#Override
public void onPause() {
exoplayer.setPlayWhenReady(false);
}
#Override
public void onSkipToPrevious() {
exoplayer.seekTo(0);
}
}
//Exo player methods
#Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if ((playbackState == exoplayer.STATE_READY) && playWhenReady) {
Log.d(TAG, "Player running");
} else if (playbackState == exoplayer.STATE_READY) {
Log.d(TAG, "paused");
}
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity() {
}
//When Activity is been destroyed
#Override
protected void onDestroy() {
super.onDestroy();
releasePlayer();
}
}
Here is an option called same-name-layout-land.xml layout that you can handle your landscape situation and Android will take it and inflate automatically when your device rotated, with this you can manage how your Activity should be shown to the user, as long as this cool option exist, you just have to put your VideoPlayer xml tag with "match_parent" for height and width in landscape version of your xml layout.
UPDATE:
Of course, if you want to your video player to take whole of screen, you have to delete the default margin of it, and for making toolbar disappear you have to create two different styles.xml. Put one into res/values-port and the other into res/values-land, and in the landscape version you have to choose a *.NoActionBar version of your themes for it.

Categories

Resources