Attempt to invoke virtual method 'android.hardware.Display.VirtualDisplay' - java

What to do with this error this code is for screen recorder which is giving error after the toggle button is clicked means it say application closed without doing any furthur operation but app launches initially very well But the problem ocurs when clicked the button
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE = 11;
private static final int MEDIA_CODE = 12;
private static final SparseIntArray ORIENTAIONS = new SparseIntArray();
private MediaProjectionManager mediaProjectionManager;
private MediaProjection mediaProjection;
private VirtualDisplay virtualDisplay;
private MediaRecorder mediaRecorder;
private MediaProjectionCallback mediaProjectionCallback;
private int mScreenDensity;
private static final int DISPLAY_WIDTH = 720;
private static final int DISPLAY_HEIGHT = 1280;
static
{
ORIENTAIONS.append(Surface.ROTATION_0, 90);
ORIENTAIONS.append(Surface.ROTATION_90, 0);
ORIENTAIONS.append(Surface.ROTATION_180, 270);
ORIENTAIONS.append(Surface.ROTATION_270, 180);
}
private ToggleButton btnToggle;
private VideoView videoView;
private String videoUri = "";
private RelativeLayout rootLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnToggle = findViewById(R.id.btnToggle);
videoView = findViewById(R.id.videoView);
rootLayout = findViewById(R.id.rootLayout);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
mScreenDensity = metrics.densityDpi;
mediaRecorder = new MediaRecorder();
mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
btnToggle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO) !=
PackageManager.PERMISSION_GRANTED)
{
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.RECORD_AUDIO))
{
btnToggle.setChecked(false);
Snackbar.make(rootLayout, "Permissions", Snackbar.LENGTH_INDEFINITE)
.setAction("ENABLE", new View.OnClickListener() {
#Override
public void onClick(View v) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO}, REQUEST_CODE);
}
}).show();
}
else
{
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO}, REQUEST_CODE);
}
}
else
{
toggleScreenShare(v);
}
}
});
}
private void toggleScreenShare(View v) {
if (((ToggleButton)v).isChecked())
{
initRecorder();
screenRecord();
}
else
{
mediaRecorder.stop();
mediaRecorder.reset();
stopRecordScreen();
//Video View
videoView.setVisibility(View.VISIBLE);
videoView.setVideoURI(Uri.parse(videoUri));
videoView.start();
}
}
private void screenRecord() {
if (mediaRecorder == null)
{
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), MEDIA_CODE);
return;
}
virtualDisplay = createVirtualDisplay();
mediaRecorder.start();
}
private VirtualDisplay createVirtualDisplay() {
return mediaProjection.createVirtualDisplay("MainActivity", DISPLAY_WIDTH, DISPLAY_HEIGHT, mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.getSurface(), null, null);
}
private void initRecorder() {
try {
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
videoUri = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
+ new StringBuilder("/Video_Screen").append(new SimpleDateFormat("dd-MM-yyyy-hh_mm_ss")
.format(new Date())).append(".mp4").toString();
mediaRecorder.setOutputFile(videoUri);
mediaRecorder.setVideoSize(DISPLAY_WIDTH,DISPLAY_HEIGHT);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoEncodingBitRate(512*1000);
mediaRecorder.setVideoFrameRate(30);
int rotation = getWindowManager().getDefaultDisplay().getRotation();
int orientation = ORIENTAIONS.get(rotation + 90);
mediaRecorder.setOrientationHint(orientation);
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != REQUEST_CODE)
{
Toast.makeText(MainActivity.this, "Unknown error..", Toast.LENGTH_SHORT).show();
return;
}
if (requestCode != RESULT_OK) {
Toast.makeText(MainActivity.this, "Permission denied..", Toast.LENGTH_SHORT).show();
btnToggle.setChecked(false);
return;
}
mediaProjectionCallback = new MediaProjectionCallback();
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
mediaProjection.registerCallback(mediaProjectionCallback, null);
virtualDisplay = createVirtualDisplay();
mediaRecorder.start();
}
private class MediaProjectionCallback extends MediaProjection.Callback {
#Override
public void onStop() {
if (btnToggle.isChecked())
{
btnToggle.setChecked(false);
mediaRecorder.stop();
mediaRecorder.reset();
}
mediaProjection = null;
stopRecordScreen();
super.onStop();
}
}
private void stopRecordScreen() {
if (virtualDisplay == null)
return;
virtualDisplay.release();
destroyMediaProjection();
}
private void destroyMediaProjection() {
if (mediaProjection != null)
{
mediaProjection.unregisterCallback(mediaProjectionCallback);
mediaProjection.stop();
mediaProjection = null;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
{
case REQUEST_CODE:
if ((grantResults.length > 0) && (grantResults[0] + grantResults[1] == PackageManager.PERMISSION_GRANTED))
{
toggleScreenShare(btnToggle);
}
else
{
btnToggle.setChecked(false);
Snackbar.make(rootLayout, "Permissions", Snackbar.LENGTH_INDEFINITE)
.setAction("ENABLE", new View.OnClickListener() {
#Override
public void onClick(View v) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO}, REQUEST_CODE);
}
}).show();
}
return;
}
}
}
Below is Log_cat
Process: com.aman.screenrecorderapp, PID: 32086
java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.display.VirtualDisplay android.media.projection.MediaProjection.createVirtualDisplay(java.lang.String, int, int, int, int, android.view.Surface, android.hardware.display.VirtualDisplay$Callback, android.os.Handler)' on a null object reference
at com.aman.screenrecorderapp.MainActivity.createVirtualDisplay(MainActivity.java:146)
at com.aman.screenrecorderapp.MainActivity.screenRecord(MainActivity.java:140)
at com.aman.screenrecorderapp.MainActivity.toggleScreenShare(MainActivity.java:119)
at com.aman.screenrecorderapp.MainActivity.access$200(MainActivity.java:36)
at com.aman.screenrecorderapp.MainActivity$1.onClick(MainActivity.java:107)
at android.view.View.performClick(View.java:4799)
at android.widget.CompoundButton.performClick(CompoundButton.java:120)
at android.view.View$PerformClick.run(View.java:20042)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5422)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)```

Related

Camera is not working in one android app for Poco X3

// Camera activity code
public class CamActivity extends AppCompatActivity implements
ActivityCompat.OnRequestPermissionsResultCallback,
AspectRatioFragment.Listener {
public static boolean activityStatus;
private Handler handler = new Handler();
private FirebaseAnalytics mFirebaseAnalytics;
private static final String TAG = "CamActivity";
private static final int REQUEST_CAMERA_PERMISSION = 1;
private static final String FRAGMENT_DIALOG = "dialog";
private static final int SELECT_PICTURE = 1;
private static final int[] FLASH_OPTIONS = {
CameraView.FLASH_AUTO,
CameraView.FLASH_OFF,
CameraView.FLASH_ON,
};
private static final int[] FLASH_ICONS = {
R.drawable.ic_flash_auto,
R.drawable.ic_flash_off,
R.drawable.ic_flash_on,
};
private static final int[] FLASH_TITLES = {
R.string.flash_auto,
R.string.flash_off,
R.string.flash_on,
};
private int mCurrentFlash;
private CameraView mCameraView;
private Handler mBackgroundHandler;
private FloatingActionButton fab;
private ImageView open_gallery;
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.take_picture:
if (mCameraView != null) {
try {
mCameraView.takePicture();
/*handler.postDelayed(() ->
mCameraView.takePicture(),
500);*/
}catch (Exception e){
Log.e(TAG,"mCameraView"+e.toString());
}
}
break;
case R.id.open_gallery:
openGallery();
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
Bundle bundle1 = new Bundle();
bundle1.putString(TAG, TAG);
bundle1.putString(TAG, TAG);
mFirebaseAnalytics.logEvent(TAG, bundle1);
setContentView(R.layout.activity_camera_renderer);
mCameraView = findViewById(R.id.camera);
open_gallery = findViewById(R.id.open_gallery);
if (open_gallery!=null)
open_gallery.setOnClickListener(mOnClickListener);
activityStatus = true;
if (mCameraView != null) {
mCameraView.addCallback(mCallback);
}
fab = findViewById(R.id.take_picture);
if (fab != null) {
fab.setOnClickListener(mOnClickListener);
}
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayShowTitleEnabled(false);
}
//toolbar.setTitle("Camera");
toolbar.setNavigationIcon(R.drawable.ic_back_arrow);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
closeCamera();
}
});
//Listen for capture image and close camera
registerReceiver(syncCamReceiver, new IntentFilter("Camera"));
}
#Override
public void onBackPressed() {
closeCamera();
super.onBackPressed();
}
/**CLose camera**/
private void closeCamera(){
try{
unregisterReceiver(syncCamReceiver);
}
catch (Exception e){
Log.d(TAG,"Error while unregistering");
}
SN88Constant.getIk6Obj(getApplicationContext()).sendPhotoSwitch(false);
CamActivity.this.finish();
}
BroadcastReceiver syncCamReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent intent) {
if (intent.getAction().equalsIgnoreCase("Camera")) {
//0 for open cam, 1 take picture 2 close camera
if(intent.getIntExtra(Constants.CAMERA_REQUEST_TYPE,-1)==1){
fab .performClick();
}
else if(intent.getIntExtra(Constants.CAMERA_REQUEST_TYPE,-1)==2){
CamActivity.this.finish();
}
}
}
};
#Override
protected void onResume() {
activityStatus = true;
try {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
if (mCameraView != null)
mCameraView.start();
} else if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
ConfirmationDialogFragment
.newInstance(R.string.camera_permission_confirmation,
new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION,
R.string.camera_permission_not_granted)
.show(getSupportFragmentManager(), FRAGMENT_DIALOG);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION);
}
}catch (Exception e){
Log.d(TAG,"Camera_onresume"+e.toString());
}
super.onResume();
}
#Override
protected void onPause() {
mCameraView.stop();
super.onPause();
}
#Override
protected void onDestroy() {
closeCamera();
activityStatus = false;
if (mBackgroundHandler != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
mBackgroundHandler.getLooper().quitSafely();
} else {
mBackgroundHandler.getLooper().quit();
}
mBackgroundHandler = null;
}
super.onDestroy();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_CAMERA_PERMISSION:
if (permissions.length != 1 || grantResults.length != 1) {
throw new RuntimeException("Error on requesting camera permission.");
}
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, R.string.camera_permission_not_granted,
Toast.LENGTH_SHORT).show();
}
// No need to start camera here; it is handled by onResume
break;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.aspect_ratio:
FragmentManager fragmentManager = getSupportFragmentManager();
if (mCameraView != null
&& fragmentManager.findFragmentByTag(FRAGMENT_DIALOG) == null) {
final Set<AspectRatio> ratios = mCameraView.getSupportedAspectRatios();
final AspectRatio currentRatio = mCameraView.getAspectRatio();
AspectRatioFragment.newInstance(ratios, currentRatio)
.show(fragmentManager, FRAGMENT_DIALOG);
}
return true;
case R.id.switch_flash:
if (mCameraView != null) {
mCurrentFlash = (mCurrentFlash + 1) % FLASH_OPTIONS.length;
item.setTitle(FLASH_TITLES[mCurrentFlash]);
item.setIcon(FLASH_ICONS[mCurrentFlash]);
mCameraView.setFlash(FLASH_OPTIONS[mCurrentFlash]);
}
return true;
case R.id.switch_camera:
if (mCameraView != null) {
try {
int facing = mCameraView.getFacing();
mCameraView.setFacing(facing == CameraView.FACING_FRONT ?
CameraView.FACING_BACK : CameraView.FACING_FRONT);
}catch (Exception e){
e.printStackTrace();
}
}
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onAspectRatioSelected(#NonNull AspectRatio ratio) {
if (mCameraView != null) {
//Toast.makeText(this, ratio.toString(), Toast.LENGTH_SHORT).show();
try {
mCameraView.setAspectRatio(ratio);
}catch (Exception e){
Log.d(TAG,"onAspectRatioSelected"+e.toString());
}
}
}
private Handler getBackgroundHandler() {
if (mBackgroundHandler == null) {
HandlerThread thread = new HandlerThread("background");
thread.start();
mBackgroundHandler = new Handler(thread.getLooper());
}
return mBackgroundHandler;
}
private CameraView.Callback mCallback
= new CameraView.Callback() {
#Override
public void onCameraOpened(CameraView cameraView) {
Log.d(TAG, "onCameraOpened");
}
#Override
public void onCameraClosed(CameraView cameraView) {
Log.d(TAG, "onCameraClosed");
}
#Override
public void onPictureTaken(CameraView cameraView, final byte[] data) {
Log.d(TAG, "onPictureTaken " + data.length);
Toast.makeText(cameraView.getContext(), R.string.picture_taken, Toast.LENGTH_SHORT)
.show();
getBackgroundHandler().post(new Runnable() {
#Override
public void run() {
String folderPath = Environment.getExternalStorageDirectory() + "/DCIM/Camera";
File folder = new File(folderPath);
if (!folder.exists()) {
File wallpaperDirectory = new File(folderPath);
wallpaperDirectory.mkdir();
}
File file = new File(folderPath,"/Img"+System.currentTimeMillis()+ ".png");
OutputStream os = null;
try {
os = new FileOutputStream(file);
os.write(data);
os.close();
scanFile(file.getAbsolutePath());
} catch (IOException e) {
Log.w(TAG, "Cannot write to " + file, e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
// Ignore
}
}
}
}
});
}
};
public static class ConfirmationDialogFragment extends DialogFragment {
private static final String ARG_MESSAGE = "message";
private static final String ARG_PERMISSIONS = "permissions";
private static final String ARG_REQUEST_CODE = "request_code";
private static final String ARG_NOT_GRANTED_MESSAGE = "not_granted_message";
public static ConfirmationDialogFragment newInstance(#StringRes int message,
String[] permissions, int requestCode, #StringRes int notGrantedMessage) {
ConfirmationDialogFragment fragment = new ConfirmationDialogFragment();
Bundle args = new Bundle();
args.putInt(ARG_MESSAGE, message);
args.putStringArray(ARG_PERMISSIONS, permissions);
args.putInt(ARG_REQUEST_CODE, requestCode);
args.putInt(ARG_NOT_GRANTED_MESSAGE, notGrantedMessage);
fragment.setArguments(args);
return fragment;
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Bundle args = getArguments();
return new AlertDialog.Builder(getActivity())
.setMessage(args.getInt(ARG_MESSAGE))
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String[] permissions = args.getStringArray(ARG_PERMISSIONS);
if (permissions == null) {
throw new IllegalArgumentException();
}
ActivityCompat.requestPermissions(getActivity(),
permissions, args.getInt(ARG_REQUEST_CODE));
}
})
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getActivity(),
args.getInt(ARG_NOT_GRANTED_MESSAGE),
Toast.LENGTH_SHORT).show();
}
})
.create();
}
}
//Scans the saved file so it appears in the gallery
private void scanFile(String path) {
MediaScannerConnection.scanFile(this,
new String[] { path }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("TAG", "Finished scanning " + path);
}
});
}
/*
* open gallery for image preview
* */
private void openGallery(){
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);
}
}
// Getting error :
E/CamActivity: mCameraViewjava.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.camera2.CaptureRequest$Builder.set(android.hardware.camera2.CaptureRequest$Key, java.lang.Object)' on a null object reference

How to take a Screenshot from a background-service class using MediaProjection API?

After doing a lot of research on this topic, though I found a few answers, I could not understand how the MediaProjection API works.
I want to take a screenshot of the device from a background Service class. Is it possible to do it. I have one MainActivity.java which starts a serviceIntent to another class which is a service(not an activity). So I want to implement this API in this service class. Please help me
This is tricky way to achieve this.
First of all you need to create transparent background theme like.
<style name="transparentTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:background">#00000000</item> <!-- Or any transparency or color you need -->
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">#null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">#android:style/Animation</item>
<item name="android:navigationBarColor" tools:ignore="NewApi">#00000000</item>
<item name="android:statusBarColor" tools:ignore="NewApi">#00000000</item>
</style>
Now you need to add this apply this theme on your ScreenShotActivity in Manifest file.
<activity
android:name=".Activities.ScreenShotActivity"
android:theme="#style/transparentTheme" />
<activity
Your ScreenShotActivity Class.
public class ScreenShotActivity extends Activity {
private static final int videoTime = 5000;
private static final int REQUEST_CODE = 1000;
private static final int REQUEST_PERMISSION = 1000;
private static final SparseIntArray ORIENTATION = new SparseIntArray();
private MediaProjectionManager mediaProjectionManager;
private MediaProjection mediaProjection;
private VirtualDisplay virtualDisplay;
private ScreenShotActivity.MediaProjectionCallback mediaProjectionCallback;
private MediaRecorder mediaRecorder;
PostWebAPIData postWebAPIData;
private int mScreenDensity;
private static int DISPLAY_WIDTH = 720;
private static int DISPLAY_HEIGHT = 1280;
static {
ORIENTATION.append(Surface.ROTATION_0, 90);
ORIENTATION.append(Surface.ROTATION_90, 0);
ORIENTATION.append(Surface.ROTATION_180, 270);
ORIENTATION.append(Surface.ROTATION_270, 180);
}
private String screenShotUri = "";
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_shot);
init();
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void init() {
//Screen tracking Code Started here..............................
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
mScreenDensity = metrics.densityDpi;
postWebAPIData = new PostWebAPIData();
DISPLAY_HEIGHT = metrics.heightPixels;
DISPLAY_WIDTH = metrics.widthPixels;
mediaRecorder = new MediaRecorder();
mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
if (ContextCompat.checkSelfPermission(ScreenShotActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ ContextCompat.checkSelfPermission(ScreenShotActivity.this, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(ScreenShotActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ||
ActivityCompat.shouldShowRequestPermissionRationale(ScreenShotActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
} else {
ActivityCompat.requestPermissions(ScreenShotActivity.this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO
}, REQUEST_PERMISSION);
}
} else {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
toogleScreenShare();
}
}, 500);
}
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void toogleScreenShare() {
initRecorder();
recordScreen();
}
public void getPathScreenShot(String filePath) {
FFmpegMediaMetadataRetriever med = new FFmpegMediaMetadataRetriever();
med.setDataSource(filePath);
Bitmap bmp = med.getFrameAtTime(2 * 1000000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
String myPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + new StringBuilder("/screenshot").append(".bmp").toString();
File myDir = new File(myPath);
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file = new File(myDir, fname);
Log.i(TAG, "" + myDir);
if (myDir.exists())
myDir.delete();
try {
FileOutputStream out = new FileOutputStream(myDir);
bmp.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
postScreenShot(myPath);
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void recordScreen() {
if (mediaProjection == null) {
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
} else {
virtualDisplay = createVirtualDisplay();
mediaRecorder.start();
onBackPressed();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mediaRecorder.stop();
mediaRecorder.reset();
stopRecordScreen();
destroyMediaProjection();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
getPathScreenShot(screenShotUri);
}
}, 2000);
}
}, videoTime);
}
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private VirtualDisplay createVirtualDisplay() {
return mediaProjection.createVirtualDisplay("MainActivity", DISPLAY_WIDTH, DISPLAY_HEIGHT, mScreenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mediaRecorder.getSurface(), null, null);
}
private void initRecorder() {
try {
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
screenShotUri = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + new StringBuilder("/screenshot").append(".mp4").toString();
mediaRecorder.setOutputFile(screenShotUri);
mediaRecorder.setVideoSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoEncodingBitRate(512 * 1000);
mediaRecorder.setVideoFrameRate(5);
int rotation = getWindowManager().getDefaultDisplay().getRotation();
int orientation = ORIENTATION.get(rotation + 90);
mediaRecorder.setOrientationHint(orientation);
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
Log.d("ExceptionOccured", "" + e.getMessage());
}
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != REQUEST_CODE) {
stopService(new Intent(this, BackgroundService.class));
startService(new Intent(this, BackgroundService.class));
Toast.makeText(ScreenShotActivity.this, "Unknown Error", Toast.LENGTH_SHORT).show();
Log.d("Livetracking", "ScreenShot" + requestCode + " " + resultCode + " " + data);
return;
}
if (resultCode != RESULT_OK) {
stopService(new Intent(this, BackgroundService.class));
startService(new Intent(this, BackgroundService.class));
Toast.makeText(ScreenShotActivity.this, "Permission denied" + requestCode, Toast.LENGTH_SHORT).show();
Log.d("Livetracking", "Screenshot" + requestCode + " " + resultCode + " " + data);
return;
}
Log.d("Livetracking", "Screenshot" + requestCode + " " + resultCode + " " + data);
mediaProjectionCallback = new ScreenShotActivity.MediaProjectionCallback();
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
mediaProjection.registerCallback(mediaProjectionCallback, null);
virtualDisplay = createVirtualDisplay();
mediaRecorder.start();
onBackPressed();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mediaRecorder.stop();
mediaRecorder.reset();
stopRecordScreen();
destroyMediaProjection();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
getPathScreenShot(screenShotUri);
}
}, 2000);
}
}, videoTime);
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
if (am != null) {
List<ActivityManager.AppTask> tasks = am.getAppTasks();
if (tasks != null && tasks.size() > 0) {
Log.d("RemovingApp", "recent");
tasks.get(0).setExcludeFromRecents(true);
}
}
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private class MediaProjectionCallback extends MediaProjection.Callback {
#Override
public void onStop() {
mediaRecorder.stop();
mediaRecorder.reset();
mediaProjection = null;
stopRecordScreen();
destroyMediaProjection();
if (mediaProjection != null) {
destroyMediaProjection();
}
super.onStop();
}
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void stopRecordScreen() {
if (virtualDisplay == null) {
virtualDisplay.release();
if (mediaProjection != null) {
destroyMediaProjection();
}
return;
}
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void destroyMediaProjection() {
if (mediaProjection != null) {
mediaProjection.unregisterCallback(mediaProjectionCallback);
mediaProjection.stop();
mediaProjection = null;
}
}
}
add these permissions in your Manifest file.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Now the magic start here you need to call your ScreenShotActivity from your service like this.
Intent dialogIntent = new Intent(BackgroundService.this, ScreenShotActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);

Paired devices aren't shown on the list

I am a new android studio user. I am trying to build a BLE GATT service app. the app works fine for unpaired devices. However, the issue arises when I tried to scan for a device which is already paired. it does not show on the scan.
I am not using MainActivity, instead of that, I am using DeviceScanActivity as my Main. here's the snippet of that part:
public class DeviceScanActivity extends ListActivity {
private LeDeviceListAdapter mLeDeviceListAdapter;
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
private static final int REQUEST_ENABLE_BT = 1;
private static final long SCAN_PERIOD = 7500;
private static final int LOCATION_REQUEST = 255;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// getActionBar().setTitle(R.string.title_devices);
getActionBar().setDisplayShowTitleEnabled(false);
mHandler = new Handler();
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
if (!mScanning) {
menu.findItem(R.id.menu_stop).setVisible(false);
menu.findItem(R.id.menu_scan).setVisible(true);
menu.findItem(R.id.menu_refresh).setActionView(null);
} else {
menu.findItem(R.id.menu_stop).setVisible(true);
menu.findItem(R.id.menu_scan).setVisible(false);
menu.findItem(R.id.menu_refresh).setActionView(
R.layout.actionbar_indeterminate_progress);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_scan:
mLeDeviceListAdapter.clear();
scanLeDevice(true);
break;
case R.id.menu_stop:
scanLeDevice(false);
break;
}
return true;
}
#Override
protected void onStart(){
super.onStart();
verifyPermissionAndScan();
if (!mBluetoothAdapter.isEnabled()){
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
mBluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
mLeDeviceListAdapter = new LeDeviceListAdapter();
setListAdapter(mLeDeviceListAdapter);
}
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
finish();
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
#Override
protected void onPause() {
super.onPause();
scanLeDevice(false);
mLeDeviceListAdapter.clear();
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
if (device == null) return;
final Intent intent = new Intent(this, DeviceControlActivity.class);
intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME, device.getName());
intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress());
if (mScanning) {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
mScanning = false;
}
startActivity(intent);
}
private void scanLeDevice(final boolean enable) {
if (enable && !mScanning) {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
invalidateOptionsMenu();
}
private class LeDeviceListAdapter extends BaseAdapter {
private ArrayList<BluetoothDevice> mLeDevices;
private LayoutInflater mInflater;
private HashMap<BluetoothDevice, Integer> mDevicesRssi = new HashMap<>();
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList<>();//i removed BluetoothDevice from the diamond bracket
mInflater = DeviceScanActivity.this.getLayoutInflater();
}
public void addDevice(BluetoothDevice device, int rssi) {
if (mDevicesRssi.containsKey(device)) {
int oldRssi = mDevicesRssi.get(device);
if (Math.abs(oldRssi - rssi) > 2) {
mDevicesRssi.put(device, rssi);
notifyDataSetChanged();
}
} else {
mDevicesRssi.put(device, rssi);
notifyDataSetChanged();
}
if(!mLeDevices.contains(device)) {
mLeDevices.add(device);
notifyDataSetChanged();
}
}
public BluetoothDevice getDevice(int position) {
return mLeDevices.get(position);
}
public void clear() {
mLeDevices.clear();
}
#Override
public int getCount() {
return mLeDevices.size();
}
#Override
public Object getItem(int i) {
return mLeDevices.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
//
BluetoothDevice device = mLeDevices.get(i);
//
if (view == null) {
view = mInflater.inflate(R.layout.listitem_device, null);
viewHolder = new ViewHolder();
viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
viewHolder.deviceRssi = (TextView) view.findViewById(R.id.device_rssi);
viewHolder.deviceBonded = (TextView) view.findViewById(R.id.device_bonded);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
final String deviceName = device.getName();
if (deviceName != null && deviceName.length() > 0)
viewHolder.deviceName.setText(deviceName);
else
viewHolder.deviceName.setText(R.string.unknown_device);
viewHolder.deviceAddress.setText(device.getAddress());
updateBondedState(device, viewHolder);
updateRssi(device, viewHolder);
return view;
}
private void updateBondedState(BluetoothDevice device, ViewHolder viewHolder) {
switch(device.getBondState()) {
case BOND_NONE:
viewHolder.deviceBonded.setVisibility(View.INVISIBLE);
break;
case BOND_BONDING:
viewHolder.deviceBonded.setText(R.string.bonding_state);
viewHolder.deviceBonded.setVisibility(View.VISIBLE);
break;
case BOND_BONDED:
viewHolder.deviceBonded.setText(R.string.bonded_state);
viewHolder.deviceBonded.setVisibility(View.VISIBLE);
break;
}
}
private void updateRssi(BluetoothDevice device, ViewHolder viewHolder) {
final int rssi = mDevicesRssi.get(device);
viewHolder.deviceRssi.setText(String.format("%s dBm", String.valueOf(rssi)));
}
}
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLeDeviceListAdapter.addDevice(device,rssi);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
static class ViewHolder {
TextView deviceName;
TextView deviceAddress;
TextView deviceRssi;
TextView deviceBonded;
}
#TargetApi(23)
private void verifyPermissionAndScan() {
if (ContextCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) == PERMISSION_GRANTED) {
Toast.makeText(this, R.string.location_already_given, Toast.LENGTH_LONG);
} else {
requestPermissions(new String[] {ACCESS_COARSE_LOCATION}, LOCATION_REQUEST);
}
}
#Override
public void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults) {
if (requestCode != LOCATION_REQUEST) return;
if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
Toast.makeText(this, R.string.permission_allowed, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, R.string.permission_not_allowed, Toast.LENGTH_LONG).show();
}
}
}
This is my DeviceControlActiviy class file:
public class DeviceControlActivity extends Activity {
private final static String TAG = DeviceControlActivity.class.getSimpleName();
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
private TextView mConnectionState;
private TextView mDataField;
private String mDeviceName;
private String mDeviceAddress;
private ExpandableListView mGattServicesList;
private BluetoothLeService mBluetoothLeService;
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics =
new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private boolean mConnected = false;
private BluetoothGattCharacteristic mNotifyCharacteristic;
private final String LIST_NAME = "NAME";
private final String LIST_UUID = "UUID";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gatt_services_characteristics);
final Intent intent = getIntent();
mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress);
mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);
mGattServicesList.setOnChildClickListener(servicesListClickListner);
mConnectionState = (TextView) findViewById(R.id.connection_state);
mDataField = (TextView) findViewById(R.id.data_value);
// getActionBar().setTitle(mDeviceName);
getActionBar().setDisplayShowTitleEnabled(false);
getActionBar().setDisplayHomeAsUpEnabled(true);
final Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
}
private final ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
finish();
}
// mBluetoothLeService.connect(mDeviceAddress);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
mConnected = false;
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
clearUI();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
displayGattServices(mBluetoothLeService.getSupportedGattServices());
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
}
}
};
private final ExpandableListView.OnChildClickListener servicesListClickListner =
new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
if (mGattCharacteristics != null) {
final BluetoothGattCharacteristic characteristic =
mGattCharacteristics.get(groupPosition).get(childPosition);
final int charaProp = characteristic.getProperties();
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
if (mNotifyCharacteristic != null) {
mBluetoothLeService.setCharacteristicNotification(
mNotifyCharacteristic, false);
mNotifyCharacteristic = null;
}
mBluetoothLeService.readCharacteristic(characteristic);
}
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
mNotifyCharacteristic = characteristic;
mBluetoothLeService.setCharacteristicNotification(
characteristic, true);
}
return true;
}
return false;
}
};
private void clearUI() {
mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);
mDataField.setText(R.string.no_data);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
if (mBluetoothLeService != null) {
final boolean result = mBluetoothLeService.connect(mDeviceAddress);
Log.d(TAG, "Connect request result=" + result);
}
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mGattUpdateReceiver);
}
#Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
mBluetoothLeService = null;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.gatt_services, menu);
if (mConnected) {
menu.findItem(R.id.menu_connect).setVisible(false);
menu.findItem(R.id.menu_disconnect).setVisible(true);
} else {
menu.findItem(R.id.menu_connect).setVisible(true);
menu.findItem(R.id.menu_disconnect).setVisible(false);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_connect:
mBluetoothLeService.connect(mDeviceAddress);
return true;
case R.id.menu_disconnect:
mBluetoothLeService.disconnect();
return true;
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateConnectionState(final int resourceId) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mConnectionState.setText(resourceId);
}
});
}
private void displayData(String data) {
if (data != null) {
mDataField.setText(data);
}
}
private void displayGattServices(List<BluetoothGattService> gattServices) {
if (gattServices == null) return;
String uuid = null;
String unknownServiceString = getResources().getString(R.string.unknown_service);
String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData
= new ArrayList<ArrayList<HashMap<String, String>>>();
mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
for (BluetoothGattService gattService : gattServices) {
HashMap<String, String> currentServiceData = new HashMap<String, String>();
uuid = gattService.getUuid().toString();
currentServiceData.put(
LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString));
currentServiceData.put(LIST_UUID, uuid);
gattServiceData.add(currentServiceData);
ArrayList<HashMap<String, String>> gattCharacteristicGroupData =
new ArrayList<HashMap<String, String>>();
List<BluetoothGattCharacteristic> gattCharacteristics =
gattService.getCharacteristics();
ArrayList<BluetoothGattCharacteristic> charas =
new ArrayList<BluetoothGattCharacteristic>();
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
HashMap<String, String> currentCharaData = new HashMap<String, String>();
uuid = gattCharacteristic.getUuid().toString();
currentCharaData.put(
LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
currentCharaData.put(LIST_UUID, uuid);
gattCharacteristicGroupData.add(currentCharaData);
}
mGattCharacteristics.add(charas);
gattCharacteristicData.add(gattCharacteristicGroupData);
}
SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
this,
gattServiceData,
android.R.layout.simple_expandable_list_item_2,
new String[] {LIST_NAME, LIST_UUID},
new int[] { android.R.id.text1, android.R.id.text2 },
gattCharacteristicData,
android.R.layout.simple_expandable_list_item_2,
new String[] {LIST_NAME, LIST_UUID},
new int[] { android.R.id.text1, android.R.id.text2 }
);
mGattServicesList.setAdapter(gattServiceAdapter);
}
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
return intentFilter;
}
}
I get the device name, address and RSSI for unpaired devices perfectly. but if the device is already paired it does not show on the device list, also if I click on a device on the unpaired device list, it does not automatically pair the device with the phone. I need to do it manually from the phone's BT setting.
This displays all the devices the phone was paired with (even if it is not paired with currently)
JAVA
for(BluetoothDevice device : BluetoothAdapter.getDefaultAdapter().getBondedDevices()){
device.getName(); // name
device.getAddress();// Address
}
KOTLIN
for (device in BluetoothAdapter.getDefaultAdapter().bondedDevices) {
device.name // name
device.address// Address
}
Hope this helps!

device list not showing in one plus 6 connected via bluetooth

Hi in the below code displaying the devices near by via bluetooth.
The below code was working fine for every device except one plus 6 phone.
I found a bug in the one plus 6 phone. If we turn on bluetooth and location then list of the near devices are listed.
can any one help me how to reslove the bug especially on one plus phones.
public class DeviceScanActivity extends AppCompatActivity {
private static final String TAG = DeviceScanActivity.class.getSimpleName();
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
#Bind(R.id.back)
TextView mBack;
#Bind(R.id.refresh)
TextView mRefresh;
#Bind(R.id.toolBar)
Toolbar mToolBar;
#Bind(R.id.scan_status)
TextView mScanStatus;
#Bind(R.id.deviceListView)
RecyclerView mDeviceListView;
#Bind(R.id.scanningProgress)
ProgressBar mScanningProgress;
private DeviceListAdapter mAdapter;
private BleService mBleService;
private List<BluetoothDevice> mBleDevices;
private SharedPreferences mPref;
private ProgressDialog mProgressDialog;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_device);
ButterKnife.bind(this);
mProgressDialog = new ProgressDialog(this);
mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
initToolBar();
mBleDevices = new ArrayList<>();
mAdapter = new DeviceListAdapter(this);
mDeviceListView.setAdapter(mAdapter);
LinearLayoutManager manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mDeviceListView.setLayoutManager(manager);
mDeviceListView.addOnItemTouchListener(new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
showProgressDialog();
List<BluetoothDevice> bluetoothDevices = mAdapter.getBluetoothDevices();
if (bluetoothDevices != null) {
if (bluetoothDevices.size() > position) {
BluetoothDevice bluetoothDevice = bluetoothDevices.get(position);
if (bluetoothDevice != null) {
String address = bluetoothDevice.getAddress();
mBleService.connect(address);
}
}
}
}
}));
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BleService.ACTION_DEVICE_FOUND);
intentFilter.addAction(BleService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BleService.ACTION_GAT_CONNECTING);
intentFilter.addAction(BleService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BleService.ACTION_GAT_SERVICE_DISCOVERED);
registerReceiver(mGattUpdateReceiver, intentFilter);
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.BLUETOOTH,Manifest.permission.ACCESS_FINE_LOCATION
, Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
} else {
if (mServiceConnection != null) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 101);
}
Intent intent = new Intent(this, BleService.class);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
}
private void showProgressDialog() {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this);
}
mProgressDialog.setMessage(getString(R.string.loading));
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show();
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mBleService = ((BleService.LocalBinder) iBinder).getLeService();
if (mBleService != null) {
mBleService.scanLeDevice(true);
mScanStatus.setVisibility(View.VISIBLE);
mScanStatus.setText(R.string.scanning_device);
}
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 101) {
if (mBleService != null) {
mBleService.scanLeDevice(true);
}
}
}
private BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action) {
case BleService.ACTION_DEVICE_FOUND:
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BleService.EXTRA_DEVICE);
if (mBleDevices != null) {
if (!mBleDevices.contains(device)) {
mBleDevices.add(device);
mAdapter.udpateBluetoothDevices(mBleDevices);
mAdapter.notifyDataSetChanged();
}
}
break;
case BleService.ACTION_GATT_CONNECTED:
Log.d(TAG, "!Action gat connected...");
mBleService.scanLeDevice(false);
mScanStatus.setVisibility(View.VISIBLE);
mScanStatus.setText(getString(R.string.connected));
break;
case BleService.ACTION_GAT_CONNECTING:
mScanStatus.setVisibility(View.VISIBLE);
mScanStatus.setText(getString(R.string.connecting));
Log.d(TAG, "!Action Gat Connecting..");
break;
case BleService.ACTION_GATT_DISCONNECTED:
mScanStatus.setVisibility(View.VISIBLE);
mScanStatus.setText(getString(R.string.disconnected));
mScanningProgress.setVisibility(View.GONE);
mRefresh.setVisibility(View.VISIBLE);
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
Log.d(TAG, "!Action Gat Disconnected..");
break;
case BleService.ACTION_GAT_SERVICE_DISCOVERED:
boolean isOperator = mPref.getBoolean(Constants.IS_OPERATOR, false);
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
if (isOperator) {
Intent homeIntent = new Intent(DeviceScanActivity.this, HomeScreenActivity.class);
startActivity(homeIntent);
finish();
} else {
Intent lightControllIntent = new Intent(DeviceScanActivity.this, LightConfigurationActivity.class);
startActivity(lightControllIntent);
finish();
}
mScanStatus.setText(getString(R.string.discoveringService));
Log.d(TAG, "!Action Gat Discovering..");
break;
}
}
};
private void initToolBar() {
mRefresh.setVisibility(View.VISIBLE);
}
#OnClick(R.id.refresh)
public void onClick() {
mScanStatus.setVisibility(View.VISIBLE);
mRefresh.setVisibility(View.GONE);
mScanningProgress.setVisibility(View.VISIBLE);
mBleDevices.clear();
mAdapter.udpateBluetoothDevices(new ArrayList<BluetoothDevice>());
mAdapter.notifyDataSetChanged();
}
#Override
protected void onDestroy() {
if (mServiceConnection != null) {
unbindService(mServiceConnection);
}
if (mGattUpdateReceiver != null) {
unregisterReceiver(mGattUpdateReceiver);
}
super.onDestroy();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_COARSE_LOCATION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (mServiceConnection != null) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 101);
}
Intent intent = new Intent(this, BleService.class);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
} else {
finish();
}
}
}
}

Replacing a button to go a paid layout with a swiping motion

I am building an app. One of the features I have is a paid option in which the user has access to an additional layout. Right now, the user can get there by clicking a button. Instead, I would like to have a swiping motion- if the user swipes down, it will ask for permission for the paid layout. If they do pay, when they swipe up, they can access the original layout.
Here is my main activity :
public class MainActivity extends AppCompatActivity {
EditText editText2;
Button btn_purchase;
ImageView imageView2;
String skuId;
SessionManager sessionManager;
// create new Person
private BillingClient mBillingClient;
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sessionManager=new SessionManager(MainActivity.this);
if(sessionManager.getPurchased()){
Intent intent = new Intent(MainActivity.this, PaidActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
btn_purchase=findViewById(R.id.btn_purchase);
imageView2 = (ImageView) findViewById(R.id.imageView2);
mBillingClient = BillingClient.newBuilder(MainActivity.this).setListener(new PurchasesUpdatedListener() {
#Override
public void onPurchasesUpdated(int responseCode, #Nullable List<Purchase> purchases) {
if (responseCode == BillingClient.BillingResponse.OK
&& purchases != null) {
for (Purchase purchase : purchases) {
//TODO: Handle purchase
// handlePurchase(purchase);
Log.e("Main", "handle Purchase ");
Log.e("MainAct", "onPurchasesUpdated() response: " + responseCode);
Log.e("dev", "successful purchase...");
String purchasedSku = purchase.getSku();
Log.e("dev", "Purchased SKU: " + purchasedSku);
String purchaseToken = purchase.getPurchaseToken();
sessionManager.savePurchased(true);
Intent intent = new Intent(MainActivity.this, PaidActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
} else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) {
// Handle an error caused by a user cancelling the purchase flow.
} else {
// Handle any other error codes.
}
}
}).build();
List<String> skuList = new ArrayList <> ();
skuList.add("appsubscription2018");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
mBillingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
#Override
public void onSkuDetailsResponse(int responseCode, List<SkuDetails> skuDetailsList) {
// Process the result.
if (responseCode == BillingClient.BillingResponse.OK && skuDetailsList != null) {
Log.e("MainActivity", "onSkuDetailsResponse: success");
for (SkuDetails skuDetails : skuDetailsList) {
Log.e("MainActivity", "products: "+skuDetailsList);
String sku = skuDetails.getSku();
skuId = skuDetails.getSku();
String price = skuDetails.getPrice();
if ("appsubscription2018 ".equals(sku)) {
Log.e("MainActivity", "product is appsubscription2018 ");
// mPremiumUpgradePrice = price;
}
}
}
}
});
btn_purchase.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mBillingClient.startConnection(new BillingClientStateListener() {
#Override
public void onBillingSetupFinished(#BillingClient.BillingResponse int billingResponseCode) {
if (billingResponseCode == BillingClient.BillingResponse.OK) {
// The billing client is ready. You can query purchases here.
// The billing client is ready. You can query purchases here.
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
.setSku("appsubscription2018")
.setType(BillingClient.SkuType.INAPP)
.build();
int responseCode = mBillingClient.launchBillingFlow(MainActivity.this, flowParams);
if (responseCode != BillingClient.BillingResponse.OK) {
Log.e("Main", "launchBillingFlow ok");
}
}
}
#Override
public void onBillingServiceDisconnected() {
// Try to restart the connection on the next request to
// Google Play by calling the startConnection() method.
}
});
}
});
imageView2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (checkFilePermission(MainActivity.this)){
getPhoto();
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode ==1 && resultCode == RESULT_OK && data != null) {
Uri selectedImage = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
imageView2.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static boolean checkFilePermission(final Context context) {
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>= Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.READ_EXTERNAL_STORAGE)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage("External storage permission is necessary");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
public void getPhoto() {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent,1);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode ==1){
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED);{
getPhoto();
}
}
}
}

Categories