The moment I bind an Android 11 device using startBluetoothSco I loose audio. It works fine till Android 10
Sample code I tried with below.
Audio works as it should when i do not bind using startBluetoothSco.
I also added queries tag in AndroidManifest.xml
android:name="android.intent.action.TTS_SERVICE"
That didn't help either!
package com.example.ttssample;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.speech.tts.TextToSpeech;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
public static final Integer RecordAudioRequestCode = 1;
Intent speechRecognizerIntent;
private EditText editText;
private TextToSpeech textToSpeech;
private EditText editText2;
private SpeechRecognizer speechRecognizer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
checkPermission();
}
editText = findViewById(R.id.editText);
textToSpeech = new TextToSpeech(getApplicationContext(), i -> textToSpeech.setLanguage(Locale.ENGLISH));
editText2 = findViewById(R.id.editTextRecord);
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
speechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
speechRecognizer.setRecognitionListener(new RecognitionListener() {
#Override
public void onReadyForSpeech(Bundle bundle) {
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onRmsChanged(float v) {
}
#Override
public void onBufferReceived(byte[] bytes) {
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onError(int i) {
}
#Override
public void onResults(Bundle bundle) {
ArrayList<String> matches = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
if (matches != null)
editText2.setText(matches.get(0));
}
#Override
public void onPartialResults(Bundle bundle) {
}
#Override
public void onEvent(int i, Bundle bundle) {
}
});
findViewById(R.id.btnRecord).setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_UP:
speechRecognizer.stopListening();
editText2.setHint("You will see the input here");
break;
case MotionEvent.ACTION_DOWN:
editText2.setText("");
editText2.setHint("Listening...");
speechRecognizer.startListening(speechRecognizerIntent);
break;
}
return false;
}
});
}
private void checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, RecordAudioRequestCode);
}
}
public void TextToSpeechButton(View view) {
textToSpeech.speak(editText.getText().toString(), TextToSpeech.QUEUE_FLUSH, null, null);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == RecordAudioRequestCode && grantResults.length > 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
}
}
public void doBind(View view) {
redirectToBTHeadset();
}
private void redirectToBTHeadset() {
final AudioManager localAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
if (localAudioManager.isBluetoothScoOn())
return;
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
if (btAdapter != null && btAdapter.isEnabled() && btAdapter.getProfileConnectionState(BluetoothProfile.HEADSET) == BluetoothProfile.STATE_CONNECTED) {
if (localAudioManager.isBluetoothScoAvailableOffCall()) {
Bundle extrasBundle = registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int conState = intent.getExtras().getInt(AudioManager.EXTRA_SCO_AUDIO_STATE);
if (conState == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
localAudioManager.setBluetoothScoOn(true);
context.unregisterReceiver(this);
} else {
if (conState == AudioManager.SCO_AUDIO_STATE_CONNECTING) {
System.out.println("Bluetooth Receiver :SCO Connecting....");
} else if (conState == AudioManager.SCO_AUDIO_STATE_ERROR) {
System.out.println("Bluetooth Receiver : SCO Error.");
context.unregisterReceiver(this);
} else if (conState == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
System.out.println("Bluetooth Receiver :SCO Disconnected");
localAudioManager.setBluetoothScoOn(false);
}
}
}
}, new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)).getExtras();
Iterator<String> iter = extrasBundle.keySet().iterator();
while (iter.hasNext()) {
String key = iter.next();
System.out.println("Bluetooth Receiver Key :" + key + ", value: " + extrasBundle.get(key));
}
if (extrasBundle.getInt(AudioManager.EXTRA_SCO_AUDIO_STATE) != 2) {
localAudioManager.setMode(AudioManager.MODE_IN_CALL);
localAudioManager.startBluetoothSco();
}
}
}
}
public void doUnBind(View view) {
stopBluetoothSco();
}
private void stopBluetoothSco() {
System.out.println("stopBluetoothSco called");
AudioManager localAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
localAudioManager.setMode(AudioManager.MODE_NORMAL);
localAudioManager.setSpeakerphoneOn(true);
localAudioManager.setBluetoothScoOn(false);
localAudioManager.stopBluetoothSco();
}
}
activity_main.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=".MainActivity">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="120dp"
android:layout_marginTop="60dp"
android:onClick="TextToSpeechButton"
android:text="#string/text_to_speech" />
<EditText
android:id="#+id/editText"
android:layout_width="360dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="150dp"
android:ems="10"
android:gravity="start|top"
android:hint="#string/your_text_here"
android:text="Hello"
android:inputType="textMultiLine"
android:autofillHints="" />
<EditText
android:id="#+id/editTextRecord"
android:layout_width="360dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="300dp"
android:ems="10"
android:inputType="textPersonName" />
<Button
android:id="#+id/btnRecord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="120dp"
android:layout_marginTop="400dp"
android:text="Click to Record" />
<Button
android:id="#+id/btnBind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="120dp"
android:layout_marginTop="500dp"
android:onClick="doBind"
android:text="Bind" />
<Button
android:id="#+id/btnUnBind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="120dp"
android:layout_marginTop="600dp"
android:onClick="doUnBind"
android:text="Unbind" />
</RelativeLayout>
I was able to figure it out. I did try it once before, but didn't work then. Not sure why.
Document reference AudioManager#startBluetoothSco
public void TextToSpeechButton(View view) {
Bundle ttsBundle = new Bundle();
//Setting the stream to STREAM_VOICE_CALL was the key
ttsBundle.putInt(TextToSpeech.Engine.KEY_PARAM_STREAM, AudioManager.STREAM_VOICE_CALL);
textToSpeech.speak(editText.getText().toString(), TextToSpeech.QUEUE_FLUSH, ttsBundle, null);
}
Related
I have recently created a chatting application, which gets crash due to these lines :-
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
t_username.setText(user.getUsername());
if (user.getImageURL().equals("No image")){
profile_image.setImageResource(R.drawable.profile_img);
} else {
//change this
Glide.with(getApplicationContext()).load(user.getImageURL()).into(profile_image);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I don't understand why this crashes my application.
MainActivity.java :-
package com.dccodes.chugli;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.bumptech.glide.Glide;
import com.dccodes.chugli.Adapter.OnItemClick;
import com.dccodes.chugli.Fragments.ChatsFragment;
import com.dccodes.chugli.Fragments.ProfileFragment;
import com.dccodes.chugli.Fragments.UsersFragment;
import com.dccodes.chugli.Model.Chat;
import com.dccodes.chugli.Model.User;
import com.google.android.material.tabs.TabLayout;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
import de.hdodenhof.circleimageview.CircleImageView;
public class MainActivity extends AppCompatActivity implements OnItemClick {
boolean doubleBackToExitPressedOnce = false;
CircleImageView profile_image;
TextView t_username;
ProgressDialog dialog;
Typeface MR,MRR;
FirebaseUser firebaseUser;
DatabaseReference reference;
OnItemClick onItemClick;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.onItemClick = this;
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
profile_image = findViewById(R.id.profile_image);
final TabLayout tabLayout = findViewById(R.id.tab_layout);
final ViewPager viewPager = findViewById(R.id.view_pager);
profile_image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TabLayout.Tab tab = tabLayout.getTabAt(2);
tab.select();
}
});
t_username = findViewById(R.id.t_username);
t_username.setTypeface(MR);
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
t_username.setText(user.getUsername());
if (user.getImageURL().equals("No image")){
profile_image.setImageResource(R.drawable.profile_img);
} else {
//change this
Glide.with(getApplicationContext()).load(user.getImageURL()).into(profile_image);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
reference = FirebaseDatabase.getInstance().getReference("Chats");
dialog = com.dccodes.chugli.Utils.showLoader(MainActivity.this);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
int unread = 0;
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Chat chat = snapshot.getValue(Chat.class);
if (chat.getReceiver().equals(firebaseUser.getUid()) && !chat.isIsseen()){
unread++;
}
}
if (unread == 0){
viewPagerAdapter.addFragment(ChatsFragment.newInstance(onItemClick), "Chats");
} else {
viewPagerAdapter.addFragment(ChatsFragment.newInstance(onItemClick), "("+unread+") Chats");
}
viewPagerAdapter.addFragment(UsersFragment.newInstance(onItemClick), "Users");
viewPagerAdapter.addFragment(new ProfileFragment(), "Profile");
viewPager.setAdapter(viewPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
if(dialog!=null){
dialog.dismiss();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.logout:
FirebaseAuth.getInstance().signOut();
// change this code beacuse your app will crash
startActivity(new Intent(MainActivity.this, StartActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
return true;
}
return false;
}
#Override
public void onItemCLick(String uid, View view) {
ViewProfileActivity viewProfileActivity =
ViewProfileActivity.newInstance(uid,this);
viewProfileActivity.show(getSupportFragmentManager(),
"view_profile");
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragments;
private ArrayList<String> titles;
ViewPagerAdapter(FragmentManager fm){
super(fm);
this.fragments = new ArrayList<>();
this.titles = new ArrayList<>();
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
public void addFragment(Fragment fragment, String title){
fragments.add(fragment);
titles.add(title);
}
// Ctrl + O
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
private void status(String status){
reference = FirebaseDatabase.getInstance().getReference("User").child(firebaseUser.getUid());
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("status", status);
reference.updateChildren(hashMap);
}
#Override
protected void onResume() {
super.onResume();
status("online");
}
#Override
protected void onPause() {
super.onPause();
status("offline");
}
#Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Tap again to exit", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000); }
}
MainActivity.xml :-
<?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="wrap_content"
android:background="#color/white"
android:orientation="vertical"
tools:context="com.dccodes.chugli.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/dgreen"
android:padding="#dimen/padding_10_dp"
android:theme="#style/Base.ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/MenuStyle">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/profile_img"
android:id="#+id/profile_image"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/t_username"
android:textSize="22sp"
android:layout_marginLeft="25dp"
android:textColor="#fff"
android:textStyle="bold"
android:layout_marginStart="25dp" />
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/dgreen"
app:tabIndicatorColor="#fff"
app:tabSelectedTextColor="#fff"
app:tabTextColor="#fff"
tools:ignore="SpeakableTextPresentCheck,SpeakableTextPresentCheck" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:ignore="SpeakableTextPresentCheck,SpeakableTextPresentCheck" />
</LinearLayout>
I don't understand why I get this error, I have searched it everywhere, but I couldn't find the answer. I hope anyone will help me!
I have build an app which is running nicely on lower versions in android but shows exception on activity main activity which I inherit from base activity in android 9 after updation. This app is working fine on android 4.
Any suggestion is appciated
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.owaisqadri, PID: 16322
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.owaisqadri/com.owaisqadri.playaudio.activities.MainActivityAudio}: android.view.InflateException: Binary XML file line #17 in com.owaisqadri:layout/abc_screen_simple: Binary XML file line #17 in com.owaisqadri:layout/abc_screen_simple: Error inflating class androidx.appcompat.widget.FitWindowsLinearLayout
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: android.view.InflateException: Binary XML file line #17 in com.owaisqadri:layout/abc_screen_simple: Binary XML file line #17 in com.owaisqadri:layout/abc_screen_simple: Error inflating class androidx.appcompat.widget.FitWindowsLinearLayout
Caused by: android.view.InflateException: Binary XML file line #17 in com.owaisqadri:layout/abc_screen_simple: Error inflating class androidx.appcompat.widget.FitWindowsLinearLayout
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Field.get(java.lang.Object)' on a null object reference
at uk.co.chrisjenx.calligraphy.ReflectionUtils.getValue(ReflectionUtils.java:29)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.createCustomViewInternal(CalligraphyLayoutInflater.java:203)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.access$000(CalligraphyLayoutInflater.java:20)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater$PrivateWrapperFactory2.onCreateView(CalligraphyLayoutInflater.java:302)
at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:239)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1069)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:997)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
at android.view.LayoutInflater.inflate(LayoutInflater.java:659)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.inflate(CalligraphyLayoutInflater.java:60)
at android.view.LayoutInflater.inflate(LayoutInflater.java:534)
at android.view.LayoutInflater.inflate(LayoutInflater.java:481)
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:920)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:806)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:693)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:170)
at com.owaisqadri.playaudio.activities.BaseActivityAudio.onCreate(BaseActivityAudio.java:36)
at com.owaisqadri.playaudio.activities.MainActivityAudio.onCreate(MainActivityAudio.java:76)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
E/AndroidRuntime: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
My activity is
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageSwitcher;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.res.ResourcesCompat;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.owaisqadri.playaudio.adapters.SlidePagerAdapter;
import com.owaisqadri.R;
import com.owaisqadri.playaudio.services.MediaService;
import com.owaisqadri.playaudio.models.Song;
import com.owaisqadri.playaudio.dataloaders.SongLoader;
import com.owaisqadri.playaudio.utils.Constants;
import com.owaisqadri.playaudio.utils.MediaControlUtils;
import com.owaisqadri.playaudio.utils.MediaDataUtils;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.PicassoTools;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;
public class MainActivityAudio extends BaseActivityAudio {
private static final String TAG = MainActivityAudio.class.getName();
private final Activity activity = this;
private SeekBar progressBar;
private ImageSwitcher songPlayButton;
private ViewPager viewPager;
private Thread getSongs;
private List<Song> songList;
private Handler handler;
TextView title;
private boolean isChanging;
private boolean musicBound;
private long albumId;
public MainActivityAudio() {
super(R.layout.activity_main_audio);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// External storage permissions
getPermissions();
// Get data
getData();
// Setup player
initPlayer();
// Initial fragment
waitForData();
initMainView();
}
#Override
protected void onStart() {
super.onStart();
// Setup songbar
initSongbar();
}
private void getPermissions() {
if (Build.VERSION.SDK_INT < 23) {
Log.d(TAG, "Don't need permissions.");
} else {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) {
Log.d(TAG, "PERMISSIONS: App needs permissions to read external storage.");
}
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 100);
}
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Log.d(TAG, "PERMISSIONS: App needs permissions to read external storage.");
}
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}
}
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
}
private void getData() {
// Multi-thread for performance
getSongs = new Thread(new Runnable() {
#Override
public void run() {
songList = SongLoader.getSongList(activity);
}
});
getSongs.start();
}
private void initPlayer() {
MediaControlUtils.initController(this);
}
#SuppressLint("NewApi")
private void initSongbar() {
// Get the song bar
progressBar = findViewById(R.id.songbar_progress);
progressBar.getProgressDrawable().setColorFilter(getResources().getColor(R.color.red), PorterDuff.Mode.SRC_IN);
progressBar.getThumb().setColorFilter(getResources().getColor(R.color.red), PorterDuff.Mode.SRC_IN);
songPlayButton = findViewById(R.id.songbar_play);
songPlayButton.setBackgroundResource(R.drawable.ic_pause);
musicBound = true;
// Add play button listener
songPlayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (musicBound) {
MediaControlUtils.pause(activity);
songPlayButton.setBackgroundResource(R.drawable.ic_play);
} else {
MediaControlUtils.start(activity);
songPlayButton.setBackgroundResource(R.drawable.ic_pause);
}
}
});
// Receive changes in bar
progressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar sb, int position, boolean userPressed) {
if (userPressed) {
MediaControlUtils.seek(activity, position);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
isChanging = true;
MediaControlUtils.pause(activity);
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
MediaControlUtils.start(activity);
songPlayButton.setBackgroundResource(R.drawable.ic_pause);
isChanging = false;
}
});
// Get receiver
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
try {
// Get music status
boolean status = MediaService.getStatus();
if (musicBound != status && !isChanging) {
if (status) {
songPlayButton.setBackgroundResource(R.drawable.ic_pause);
} else {
songPlayButton.setBackgroundResource(R.drawable.ic_play);
}
}
musicBound = status;
// Update if different song
long tempSong = MediaService.getCurrSong();
if (tempSong != currSong) {
currSong = tempSong;
}
// Set location based on position/duration
int songPosition = MediaService.getSongPos();
int songDuration = MediaService.getSongDur();
if (!isChanging && songPosition != Constants.MEDIA_ERROR && songDuration != Constants.MEDIA_ERROR) {
progressBar.setMax(songDuration);
progressBar.setProgress(songPosition);
// Set new text in time
String songPositionTime = String.format(
Locale.US, "%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(songPosition),
TimeUnit.MILLISECONDS.toSeconds(songPosition) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(songPosition))
);
String songDurationTime = String.format(
Locale.US, "%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(songDuration),
TimeUnit.MILLISECONDS.toSeconds(songDuration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(songDuration))
);
String totalSongTime = songPositionTime + "/" + songDurationTime;
TextView songTimeView = findViewById(R.id.songbar_time);
songTimeView.setText(totalSongTime);
}
} catch (Exception ignored) {}
handler.postDelayed(this, Constants.HANDLER_DELAY);
}
}, Constants.HANDLER_DELAY);
}
private void waitForData() {
// Join threads
try {
getSongs.join();
} catch (Exception e) {
e.printStackTrace();
}
}
private void initMainView() {
// Init views
viewPager = findViewById(R.id.headers);
PagerAdapter pagerAdapter = new SlidePagerAdapter(getSupportFragmentManager(), this);
viewPager.setAdapter(pagerAdapter);
// Give tab layout
//FontTabLayout tabLayout = (FontTabLayout) findViewById(R.id.slider);
//tabLayout.setupWithViewPager(viewPager);
// Set title
//MainActivityAudio.this.setTitle();
title = findViewById(R.id.title_top);
Typeface tf = ResourcesCompat.getFont(this,R.font.jameel);
title.setText("آڈیو کولیکشن");
title.setTypeface(tf);
}
public void updateContent() {
Log.d(TAG, "Updating content.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Objects.requireNonNull(viewPager.getAdapter()).notifyDataSetChanged();
}
});
}
public void updateAll() {
Log.d(TAG, "Updating all.");
runOnUiThread(new Runnable() {
#Override
public void run() {
// Get data
getData();
waitForData();
// Update adapter
Objects.requireNonNull(viewPager.getAdapter()).notifyDataSetChanged();
}
});
}
public void updateNew(final String path, final String url) {
Log.d(TAG, "Updating new.");
runOnUiThread(new Runnable() {
#Override
public void run() {
// Get data
Log.e(TAG, "Updating on UI thread.");
getData();
waitForData();
// Update individual song
//for (Song song: songList) {
// if (song.getPath().equals(path)) {
// Log.e(TAG, "Updating new song metadata: " + song.getName() + " " + Long.toString(song.getAlbumId()));
// MediaDataUtils.updateSongMetadata(song.getId(), song.getAlbumId(), url, path, activity);
// break;
// }
//}
// Update adapter
getData();
waitForData();
Objects.requireNonNull(viewPager.getAdapter()).notifyDataSetChanged();
}
});
}
public void choosePhoto(long id) {
albumId = id;
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), Constants.RESULT_CHOOSE_ALBUM_COVER);
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Update main activity request
if (requestCode == Constants.RESULT_UPDATE_ACTIVITY && resultCode == RESULT_OK) {
if (data != null) {
boolean change = data.getBooleanExtra(Constants.RESULT_DEFAULT, false);
if (change) {
updateAll();
}
}
}
// Change photo request
if (requestCode == Constants.RESULT_CHOOSE_ALBUM_COVER && resultCode == RESULT_OK) {
if (data != null) {
Uri uri = data.getData();
String[] file = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(Objects.requireNonNull(uri), file, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(file[0]));
cursor.close();
MediaDataUtils.changeAlbumArt(path, albumId, getApplicationContext());
updateAll();
}
} else {
Log.e(TAG, "Error, no data.");
}
}
}
#Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
public List<Song> getSongList() {
return songList;
}
public long getCurrSong() {
return currSong;
}
public void setMusicBound(boolean bound) {
this.musicBound = bound;
}
#Override
public void onDestroy() {
PicassoTools.clearCache(Picasso.get());
super.onDestroy();
}
#Override public View onCreateView(#NonNull View parent, #NonNull String name, #NonNull Context context, #NonNull AttributeSet attrs) {
if (name.equals("androidx.appcompat.view.menu.ListMenuItemView") &&
parent.getParent() instanceof FrameLayout) {
((View) parent.getParent()).setBackgroundColor(Color.WHITE);
}
return super.onCreateView(parent, name, context, attrs);
}
}
base activity is from which app inhereted is
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import com.owaisqadri.R;
import com.owaisqadri.playaudio.utils.Constants;
import java.util.Objects;
import uk.co.chrisjenx.calligraphy.CalligraphyConfig;
public abstract class BaseActivityAudio extends AppCompatActivity {
protected int id;
protected long currSong;
protected Toolbar toolbar;
public BaseActivityAudio(int id) {
this.id = id;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add fonts
CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
.setDefaultFontPath(Constants.FONT_PATH)
.setFontAttrId(R.attr.fontPath)
.build());
setContentView(id);
// Setup the toolbar
initToolbar();
}
protected void initToolbar() {
// Init toolbar
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
}
and xml that i have used is
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="ContentDescription"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- Container -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Toolbar -->
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
app:elevation="0dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#null">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#251868" />
<View
android:id="#+id/view"
android:layout_width="match_parent"
android:layout_height="7dp"
android:layout_below="#+id/toolbar"
android:background="#FDDF58" />
<ImageView
android:id="#+id/icon"
android:layout_width="72dp"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentStart="false"
android:layout_centerVertical="true"
android:src="#drawable/launcher" />
<TextView
android:id="#+id/title_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginStart="120dp"
android:ellipsize="end"
android:fontFamily="#font/jameel"
android:gravity="center"
android:maxLines="1"
android:textColor="#fff"
android:textSize="20sp" />
</RelativeLayout>
</com.google.android.material.appbar.AppBarLayout>
<!-- Fragment holding frame -->
<androidx.viewpager.widget.ViewPager
android:id="#+id/headers"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#drawable/back1"
android:layout_weight="1"/>
<!-- Song bar -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:background="#636363">
<ImageSwitcher
android:id="#+id/songbar_play"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center_vertical"
android:background="#drawable/ic_play"/>
<SeekBar
android:id="#+id/songbar_progress"
android:gravity="center_vertical"
android:layout_height="48dp"
android:layout_width="0dp"
android:layout_weight="1"
style="#style/Widget.AppCompat.ProgressBar.Horizontal"/>
<TextView
android:id="#+id/songbar_time"
android:layout_marginEnd="#dimen/activity_horizontal_margin"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:gravity="center_vertical|end"
android:textColor="#android:color/white"
android:text="#string/song_default_time"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
I have tried a lot but not successful I am new to android. Please suggest some solution thanks
Getting Error while sharing a news on whatsapp using my Webview App
**package com.agraleaks.imgauravanimator;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.view.View;
import android.graphics.Bitmap;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import com.agraleaks.imgauravanimator.Common.Config;
public class MainActivity extends AppCompatActivity implements OnRefreshListener {
private WebView webView;
private ProgressDialog dialog;
private BroadcastReceiver mRegistrationBroadcastReceiver;
private SwipeRefreshLayout swipeLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
//WebView
webView = (WebView)findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
//hide loading image
findViewById(R.id.imageView1).setVisibility(View.GONE);
findViewById(R.id.progressBar1).setVisibility(View.GONE);
//show webview
findViewById(R.id.webView).setVisibility(View.VISIBLE);
}
});
webView.loadUrl("http://www.agraleaks.com/");
webView.setHorizontalScrollBarEnabled(false);
webView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
webView.setBackgroundColor(128);
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Config.STR_PUSH))
{
String message = intent.getStringExtra(Config.STR_PUSH);
showNotification ("Agra Leaks- Fastest News Channel in the City",message);
}
}
};
onNewIntent(getIntent());
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
if(url != null && url.startsWith("whatsapp://"))
{
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "Agra Leaks - Digital Newspaper.");
sendIntent.setType("text/plain");
sendIntent.setPackage("com.whatsapp");
startActivity(sendIntent);
return true;
}else
{
return false;
}
}
private void showNotification(String title, String message) {
Intent intent = new Intent(getBaseContext(),MainActivity.class);
intent.putExtra(Config.STR_KEY,message);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(getBaseContext(),0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext());
builder.setAutoCancel(true)
.setWhen(System.currentTimeMillis())
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle(title)
.setContentText(message)
.setContentIntent(contentIntent);
NotificationManager notificationManager = (NotificationManager)getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1,builder.build());
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getAction()== KeyEvent.ACTION_DOWN){
switch (keyCode){
case KeyEvent.KEYCODE_BACK:
if (webView.canGoBack()){
webView.goBack();
}
else {
finish();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,new IntentFilter("registrationComplete"));
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,new IntentFilter(Config.STR_PUSH));
}
#Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
#Override public void run() {
// webView.reload();
swipeLayout.setRefreshing(false);
webView.loadUrl( "javascript:window.location.reload( true )" );
}
}, 5000);
}
}**
These are my code
Unable to share on Whatsapp from my WebView. Getting Error - The webpage at whatsapp://send?text= could not be load because net::ERR_UNKNOWN_URL_SCHEME.
here is my activity_main
<?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="com.agraleaks.imgauravanimator.MainActivity">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="#+id/webView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.v4.widget.SwipeRefreshLayout>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/splash" />
<ProgressBar
android:id="#+id/progressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/imageView1"
android:layout_centerHorizontal="true" />
</RelativeLayout>
i found my Answer myself ,
i just need to put these codes
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(url != null && url.startsWith("whatsapp://"))
{
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "Moon TV");
sendIntent.setType("text/plain");
sendIntent.setPackage("com.whatsapp");
startActivity(sendIntent);return true;
}else
{
return false;
}
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.airbnb.android.airmapview.AirMapInterface;
import com.airbnb.android.airmapview.AirMapMarker;
import com.airbnb.android.airmapview.AirMapPolygon;
import com.airbnb.android.airmapview.AirMapPolyline;
import com.airbnb.android.airmapview.AirMapView;
import com.airbnb.android.airmapview.AirMapViewTypes;
import com.airbnb.android.airmapview.DefaultAirMapViewBuilder;
import com.airbnb.android.airmapview.GoogleChinaMapType;
import com.airbnb.android.airmapview.MapType;
import com.airbnb.android.airmapview.WebAirMapViewBuilder;
import com.airbnb.android.airmapview.listeners.OnCameraChangeListener;
import com.airbnb.android.airmapview.listeners.OnCameraMoveListener;
import com.airbnb.android.airmapview.listeners.OnInfoWindowClickListener;
import com.airbnb.android.airmapview.listeners.OnLatLngScreenLocationCallback;
import com.airbnb.android.airmapview.listeners.OnMapClickListener;
import com.airbnb.android.airmapview.listeners.OnMapInitializedListener;
import com.airbnb.android.airmapview.listeners.OnMapMarkerClickListener;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity
implements OnCameraChangeListener, OnMapInitializedListener,
OnMapClickListener, OnCameraMoveListener, OnMapMarkerClickListener,
OnInfoWindowClickListener, OnLatLngScreenLocationCallback {
Context context;
ImageView imageView;
int[] image = {
R.drawable.chopper,
R.drawable.cruise,
R.drawable.sport,
R.drawable.zx,
};
private AirMapView map;
private DefaultAirMapViewBuilder mapViewBuilder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapViewBuilder = new DefaultAirMapViewBuilder(this);
map = (AirMapView) findViewById(R.id.map);
imageView = (ImageView) findViewById(R.id.imageview);
Button btnMapTypeNormal = (Button) findViewById(R.id.btnMapTypeNormal);
Button btnMapTypeSattelite = (Button) findViewById(R.id.btnMapTypeSattelite);
Button btnMapTypeTerrain = (Button) findViewById(R.id.btnMapTypeTerrain);
btnMapTypeNormal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(#NonNull View v) {
map.setMapType(MapType.MAP_TYPE_NORMAL);
}
});
btnMapTypeSattelite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(#NonNull View v) {
map.setMapType(MapType.MAP_TYPE_SATELLITE);
}
});
btnMapTypeTerrain.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(#NonNull View v) {
map.setMapType(MapType.MAP_TYPE_TERRAIN);
}
});
map.setOnMapClickListener(this);
map.setOnCameraChangeListener(this);
map.setOnCameraMoveListener(this);
map.setOnMarkerClickListener(this);
map.setOnMapInitializedListener(this);
map.setOnInfoWindowClickListener(this);
map.initialize(getSupportFragmentManager());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
AirMapInterface airMapInterface = null;
switch (id) {
case R.id.action_native_map:
try {
airMapInterface = mapViewBuilder.builder(AirMapViewTypes.NATIVE).build();
} catch (UnsupportedOperationException e) {
Toast.makeText(this, "Sorry, native Google Maps are not supported by this device. " +
"Please make sure you have Google Play Services installed.",
Toast.LENGTH_SHORT).show();
}
break;
case R.id.action_mapbox_map:
airMapInterface = mapViewBuilder.builder(AirMapViewTypes.WEB).build();
break;
case R.id.action_google_web_map:
// force Google Web maps since otherwise AirMapViewTypes.WEB returns MapBox by default.
airMapInterface = new WebAirMapViewBuilder().build();
break;
case R.id.action_google_china_web_map:
airMapInterface = new WebAirMapViewBuilder().withOptions(new GoogleChinaMapType()).build();
break;
case R.id.action_clear_logs:
Uri imgUri = Uri.parse("android.resource://com.airbnb.airmapview.sample/" + R.drawable.chopper);
Bitmap bitmap = BitmapFactory.decodeStream(imgUri);
imageView.setImageURI(null);
imageView.setImageURI(imgUri);
break;
default:
break;
}
if (airMapInterface != null) {
map.initialize(getSupportFragmentManager(), airMapInterface);
}
return super.onOptionsItemSelected(item);
}
#Override
public void onCameraChanged(LatLng latLng, int zoom) {
// appendLog("Map onCameraChanged triggered with lat: " + latLng.latitude + ", lng: "
// + latLng.longitude);
}
#Override
public void onMapInitialized() {
appendLog("Map onMapInitialized triggered");
final LatLng airbnbLatLng = new LatLng(37.771883, -122.405224);
addMarker("Airbnb HQ", airbnbLatLng, 1);
addMarker("Performance Bikes", new LatLng(37.773975, -122.40205), 2);
addMarker("REI", new LatLng(37.772127, -122.404411), 3);
addMarker("Mapbox", new LatLng(37.77572, -122.41354), 4);
map.animateCenterZoom(airbnbLatLng, 10);
// Add Polylines
LatLng[] latLngs = {
new LatLng(37.77977, -122.38937),
new LatLng(37.77811, -122.39160),
new LatLng(37.77787, -122.38864)};
map.addPolyline(new AirMapPolyline(Arrays.asList(latLngs), 5));
// Add Polygons
LatLng[] polygonLatLngs = {
new LatLng(37.784, -122.405),
new LatLng(37.784, -122.406),
new LatLng(37.785, -122.406),
new LatLng(37.785, -122.405)
};
map.addPolygon(new AirMapPolygon.Builder().add(polygonLatLngs).strokeWidth(3.f).build());
// Add Circle
map.drawCircle(new LatLng(37.78443, -122.40805), 1000);
// enable my location
map.setMyLocationEnabled(true);
}
private void addMarker(String title, LatLng latLng, int id) {
map.addMarker(new AirMapMarker.Builder()
.id(id)
.position(latLng)
.title(title)
.iconId(R.mipmap.icon_location_pin)
.build());
}
#Override
public void onMapClick(LatLng latLng) {
if (latLng != null) {
appendLog(
"Map onMapClick triggered with lat: " + latLng.latitude + ", lng: "
+ latLng.longitude);
map.getMapInterface().getScreenLocation(latLng, this);
} else {
appendLog("Map onMapClick triggered with null latLng");
}
}
#Override
public void onCameraMove() {
appendLog("Map onCameraMove triggered");
}
private void appendLog(String msg) {
//imageView.setImageURI(imageView.getDrawable() + "\n" + msg);
}
#Override
public void onMapMarkerClick(long id) {
//appendLog("Map onMapMarkerClick triggered with id " + id);
}
#Override
public void onMapMarkerClick(Marker marker) {
//appendLog("Map onMapMarkerClick triggered with marker " + marker.getId());
}
#Override
public void onInfoWindowClick(long id) {
//appendLog("Map onInfoWindowClick triggered with id " + id);
}
#Override
public void onInfoWindowClick(Marker marker) {
//appendLog("Map onInfoWindowClick triggered with marker " + marker.getId());
}
#Override
public void onLatLngScreenLocationReady(Point point) {
//appendLog("LatLng location on screen (x,y): (" + point.x + "," + point.y + ")");
}
}
my xml code:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<com.airbnb.android.airmapview.AirMapView
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<Button
android:id="#+id/btnMapTypeNormal"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Normal" />
<Button
android:id="#+id/btnMapTypeSattelite"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sattelite" />
<Button
android:id="#+id/btnMapTypeTerrain"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Terrain" />
</LinearLayout>
</FrameLayout>
<FrameLayout
android:id="#+id/logsScrollView"
android:layout_width="match_parent"
android:layout_height="100dp"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<ImageView
android:id="#+id/imageview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:padding="0dp"
android:textSize="10sp"
/>
</FrameLayout>
</LinearLayout>
I want to implement OnItemClickListener in this ListView ,But when i add code for this,my app will not work even there is no error. its closes automatically when I click on the Listview item. Please help me, I am a beginner in Android. I am adding my whole code here.
I am doing a bluetooth device connectivity code.
MainActivity.java
import java.util.ArrayList;
import java.util.Set;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.app.Activity;
import android.app.ProgressDialog;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
public class MainActivity extends Activity {
private TextView mStatusTv;
private Button mActivateBtn;
private Button mPairedBtn;
private Button mScanBtn;
private Button ledBtn;
private ProgressDialog mProgressDlg;
private ArrayList<BluetoothDevice> mDeviceList = new ArrayList<BluetoothDevice>();
private BluetoothAdapter mBluetoothAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStatusTv = (TextView) findViewById(R.id.tv_status);
mActivateBtn = (Button) findViewById(R.id.btn_enable);
mPairedBtn = (Button) findViewById(R.id.btn_view_paired);
mScanBtn = (Button) findViewById(R.id.btn_scan);
ledBtn = (Button) findViewById(R.id.led);
ledBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i=new Intent(getApplicationContext(),Ledbuttons.class);
startActivity(i);
}
});
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mProgressDlg = new ProgressDialog(this);
mProgressDlg.setMessage("Scanning...");
mProgressDlg.setCancelable(false);
mProgressDlg.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mBluetoothAdapter.cancelDiscovery();
}
});
if (mBluetoothAdapter == null) {
showUnsupported();
} else {
mPairedBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices == null || pairedDevices.size() == 0) {
showToast("No Paired Devices Found");
} else {
ArrayList<BluetoothDevice> list = new ArrayList<BluetoothDevice>();
list.addAll(pairedDevices);
Intent intent = new Intent(MainActivity.this, DeviceListActivity.class);
intent.putParcelableArrayListExtra("device.list", list);
startActivity(intent);
}
}
});
mScanBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
mBluetoothAdapter.startDiscovery();
}
});
mActivateBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
showDisabled();
} else {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1000);
}
}
});
if (mBluetoothAdapter.isEnabled()) {
showEnabled();
} else {
showDisabled();
}
}
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter);
}
#Override
public void onPause() {
if (mBluetoothAdapter != null) {
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
}
super.onPause();
}
#Override
public void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
private void showEnabled() {
mStatusTv.setText("Bluetooth is On");
mStatusTv.setTextColor(Color.BLUE);
mActivateBtn.setText("Disable");
mActivateBtn.setEnabled(true);
mPairedBtn.setEnabled(true);
mScanBtn.setEnabled(true);
ledBtn.setEnabled(true);
}
private void showDisabled() {
mStatusTv.setText("Bluetooth is Off");
mStatusTv.setTextColor(Color.RED);
mActivateBtn.setText("Enable");
mActivateBtn.setEnabled(true);
mPairedBtn.setEnabled(false);
mScanBtn.setEnabled(false);
ledBtn.setEnabled(false);
}
private void showUnsupported() {
mStatusTv.setText("Bluetooth is unsupported by this device");
mActivateBtn.setText("Enable");
mActivateBtn.setEnabled(false);
mPairedBtn.setEnabled(false);
mScanBtn.setEnabled(false);
}
private void showToast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if (state == BluetoothAdapter.STATE_ON) {
showToast("Enabled");
showEnabled();
}
} else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
mDeviceList = new ArrayList<BluetoothDevice>();
mProgressDlg.show();
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
mProgressDlg.dismiss();
Intent newIntent = new Intent(MainActivity.this, DeviceListActivity.class);
newIntent.putParcelableArrayListExtra("device.list", mDeviceList);
startActivity(newIntent);
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device);
showToast("Found device " + device.getName());
}
}
};
DeviceListActivity.java
import java.lang.reflect.Method;
import java.util.ArrayList;
import android.app.Activity;
import android.bluetooth.BluetoothDevice;
import android.os.Bundle;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
public class DeviceListActivity extends Activity {
private ListView mListView;
private DeviceListAdapter mAdapter;
private ArrayList<BluetoothDevice> mDeviceList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDeviceList = getIntent().getExtras().getParcelableArrayList("device.list");
mListView = (ListView) findViewById(R.id.lv_paired);
mAdapter = new DeviceListAdapter(this);
mAdapter.setData(mDeviceList);
mAdapter.setListener(new DeviceListAdapter.OnPairButtonClickListener() {
#Override
public void onPairButtonClick(int position) {
BluetoothDevice device = mDeviceList.get(position);
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
unpairDevice(device);
} else {
showToast("Pairing...");
pairDevice(device);
}
}
});
mListView.setAdapter(mAdapter);
registerReceiver(mPairReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
}
#Override
public void onDestroy() {
unregisterReceiver(mPairReceiver);
super.onDestroy();
}
private void showToast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
private void pairDevice(BluetoothDevice device) {
try {
Method method = device.getClass().getMethod("createBond", (Class[]) null);
method.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void unpairDevice(BluetoothDevice device) {
try {
Method method = device.getClass().getMethod("removeBond", (Class[]) null);
method.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {
showToast("Paired");
} else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED){
showToast("Unpaired");
}
mAdapter.notifyDataSetChanged();
}
}
};
}
DeviceListAdapter.java
import java.util.List;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
public class DeviceListAdapter extends BaseAdapter{
private LayoutInflater mInflater;
private List<BluetoothDevice> mData;
private OnPairButtonClickListener mListener;
public DeviceListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public void setData(List<BluetoothDevice> data) {
mData = data;
}
public void setListener(OnPairButtonClickListener listener) {
mListener = listener;
}
public int getCount() {
return (mData == null) ? 0 : mData.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item_device, null);
holder = new ViewHolder();
holder.nameTv = (TextView) convertView.findViewById(R.id.tv_name);
holder.addressTv = (TextView) convertView.findViewById(R.id.tv_address);
holder.pairBtn = (Button) convertView.findViewById(R.id.btn_pair);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
BluetoothDevice device = mData.get(position);
holder.nameTv.setText(device.getName());
holder.addressTv.setText(device.getAddress());
holder.pairBtn.setText((device.getBondState() == BluetoothDevice.BOND_BONDED) ? "Unpair" : "Pair");
holder.pairBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mListener != null) {
mListener.onPairButtonClick(position);
}
}
});
return convertView;
}
static class ViewHolder {
TextView nameTv;
TextView addressTv;
TextView pairBtn;
}
public interface OnPairButtonClickListener {
public abstract void onPairButtonClick(int position);
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#060606"
android:orientation="vertical"
android:padding="#dimen/activity_vertical_margin" >
<TextView
android:id="#+id/tv_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/text_bluetooth_off"
android:textColor="#ff0000"
android:textSize="17sp" />
<Button
android:id="#+id/btn_enable"
android:layout_width="match_parent"
android:layout_height="33dp"
android:layout_marginTop="#dimen/activity_vertical_margin"
android:background="#585858"
android:text="#string/text_enable" />
<Button
android:id="#+id/btn_view_paired"
android:layout_width="match_parent"
android:layout_height="33dp"
android:layout_marginTop="#dimen/activity_vertical_margin"
android:background="#585858"
android:enabled="false"
android:text="#string/text_view_paired"
android:textColor="#FFFFFF" />
<Button
android:id="#+id/btn_scan"
android:layout_width="match_parent"
android:layout_height="33dp"
android:layout_marginTop="#dimen/activity_vertical_margin"
android:background="#585858"
android:enabled="false"
android:text="#string/text_scan_devices"
android:textColor="#FFFFFF" />
<Button
android:id="#+id/led"
android:layout_width="match_parent"
android:layout_height="33dp"
android:layout_marginTop="#dimen/activity_vertical_margin"
android:background="#585858"
android:enabled="false"
android:text="LEDS"
android:textColor="#FFFFFF" />
<TextView
android:id="#+id/TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="List Of Devices"
android:textColor="#ff0000"
android:textSize="15sp" />
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ScrollView>
<ListView
android:id="#+id/lv_paired"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
list_item_device.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<Button
android:id="#+id/btn_pair"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="Pair"
android:textColor="#ff4444" />
<TextView
android:id="#+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignTop="#+id/btn_pair"
android:layout_toLeftOf="#+id/btn_pair"
android:text="Galaxy Nexus"
android:textColor="#99cc00"
android:textSize="16sp" />
<TextView
android:id="#+id/tv_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/btn_pair"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/btn_pair"
android:text="000000000"
android:textColor="#ffbd21" />
</RelativeLayout>
My Problems that not solved are
The app is not working when I add an onItemclicklistener to the list view.
bluetooth search result is filling with the same device name.
I cannot access the buttons after viewing pairing devices and
scanned devices(it seems like that the same layout is popping to screen).
Anyone please help me to solve these issues.
Thanks in advance.
You can just do like this -
mListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(), " ITEM CLICKED POSITION = "+String.valueOf(position), Toast.LENGTH_SHORT).show();
}
});
You can add OnItemClickListener like this
mListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) { {
Toast.makeText(getApplicationContext(),String.valueOf(arg2), Toast.LENGTH_LONG).show();
}
});`
look at this code it contain how you set the list view listener with detect the clicked row and getting sub view in that row
ListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
View row= adapter.getView(position, view, parent);
CheckBox box=(CheckBox) row.findViewById(R.id.checkBox1);
box.performClick();
}
});
adapter is your list view adapter
hope it help