SCAN_RESULTS_AVAILABLE_ACTION: BroadcastReceiver#onReceive not called on Android 7.0 - android

I'm developing an app for Android in which I have to scan the available WiFi LANs.
I'm testing the app and it works on devices with Android from 4.4 to 6.x, but on Nougat (in fact I've tested on 2 different devices, a Huawei and a HTC, with Android 7) the onReceive of my BroadcastReceiver is never called.
If I try with WIFI_STATE_CHANGED_ACTION I'm able to receive this action even on Android 7.
I've checked the changes' documentation in Nougat, but I found nothing about this. Why doesn't it work on Nougat? What do I have to add/change?
Here is a stripped down version of my app.
In AndroidManifest.xml I've added:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ListView _listSSID;
private ArrayAdapter<String> _adapter;
private WiFiConnection _wifiConnection = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
_wifiConnection = new WiFiConnection(this);
_adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
android.R.id.text1, _wifiConnection.getBestSSIDs());
_listSSID = (ListView) findViewById(R.id.listSSID);
_listSSID.setAdapter(_adapter);
_listSSID.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String ssid = _adapter.getItem(position);
Log.d("OnClick", ssid);
}
});
startScan();
}
#Override
protected void onStop() {
super.onStop();
_wifiConnection.stopScan();
unregisterReceiver(_wifiScanReceiver);
}
void startScan() {
checkPermission(this);
registerReceiver(_wifiScanReceiver,
new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
Thread t = new Thread(_wifiConnection.getWifiScanner());
t.start();
}
private final BroadcastReceiver _wifiScanReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent intent) {
if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
if (_wifiConnection != null && _wifiConnection.isWifiEnabled()) {
_wifiConnection.updateScanData("No WLANs found");
}
_adapter.notifyDataSetChanged();
}
}
};
static final int MY_PERMISSIONS_REQUEST = 1042;
private static final String PERMISSIONS_TAG = "PERMISSION";
#TargetApi(Build.VERSION_CODES.M)
public static boolean checkPermission(Activity activity) {
boolean permission = true;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
permission = activity.checkSelfPermission(Manifest.permission.ACCESS_WIFI_STATE) == PackageManager.PERMISSION_GRANTED;
Log.d(PERMISSIONS_TAG, "ACCESS_WIFI_STATE: " + permission);
permission = activity.checkSelfPermission(Manifest.permission.CHANGE_WIFI_STATE) == PackageManager.PERMISSION_GRANTED;
Log.d(PERMISSIONS_TAG, "CHANGE_WIFI_STATE: " + permission);
permission = activity.checkSelfPermission(Manifest.permission.CHANGE_WIFI_MULTICAST_STATE) == PackageManager.PERMISSION_GRANTED;
Log.d(PERMISSIONS_TAG, "CHANGE_WIFI_MULTICAST_STATE: " + permission);
List<String> requiringList = new ArrayList<>();
permission = activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
Log.d(PERMISSIONS_TAG, "WRITE_EXTERNAL_STORAGE: " + permission);
if (!permission) {
requiringList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
permission = activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
Log.d(PERMISSIONS_TAG, "ACCESS_COARSE_LOCATION: " + permission);
if (!permission) {
requiringList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (requiringList.size() > 0) {
String[] stringArray = requiringList.toArray(new String[0]);
activity.requestPermissions(stringArray, MY_PERMISSIONS_REQUEST);
}
}
return permission;
}
}
WiFiConnection.java
class WiFiConnection
{
private static final int SCAN_INTERVAL = 1200;
final private List<String> _bestSSIDs = new ArrayList<>();
private WifiManager _wifiManager;
private final WiFiScanner _startScan = new WiFiScanner();
WiFiConnection(Activity activity) {
_wifiManager = (WifiManager) activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
}
List<String> getBestSSIDs() {return _bestSSIDs; }
WiFiScanner getWifiScanner() { return _startScan; }
void stopScan() { _startScan.stop(); }
boolean isWifiEnabled() { return _wifiManager.isWifiEnabled(); }
void updateScanData(final String noLansMsg) {
if ((_wifiManager != null && _wifiManager.isWifiEnabled())) {
List<ScanResult> scanResults = _wifiManager.getScanResults();
Log.d("WiFi", "found nets: " + scanResults.size());
// my sorting code
}
}
private class WiFiScanner implements Runnable
{
private boolean _stop = false;
public void stop() {_stop = true;}
#Override
public void run() {
while (!_stop) {
_wifiManager.startScan();
try {
Thread.sleep(SCAN_INTERVAL);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

#TargetApi(Build.VERSION_CODES.M) remove this it will execute for Android M only other wise write greater or equal M version code.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
// Do something for M and above versions
} else{

It seems it is necessary to turn on GPS to receive SCAN_RESULTS_AVAILABLE_ACTION on Android 7.0.

Related

Can't detect type B (iso-14443 B) card using PN7150 on Android

Currently i'm using PN7150 with android board.
The NFC reader (PN7150) can be used to read type A cards, but cannot detect type B cards at all.
Below is the PCB antenna that I used :
The following is a schematic for the antenna matching circuit:
Smith chart simulation results from RFSim99:
Below is the signal shape (Smith chart) of the measurement results on the PCB board using Nano VNA.
This is my android code :
MainActivity.java
package com.iwjo.nfcfieldstrength;
public class MainActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback, NfcThread.UiCallback{
public static final boolean mbUsbExternalUSBManager = false;
private static final String ACTION_USB_PERMISSION = "com.iwjo.ktpfieldstrength.USB_PERMISSION";
private UsbManager mUsbManager = null;
private PendingIntent mPermissionIntent= null;
public static final int REQUEST_WRITE_PERMISSION = 786;
private static final int REQUEST_WRITE_STORAGE_REQUEST_CODE = 112;
private NfcAdapter nfcadapter;
private String[][] nfctechfilter = new String[][] { new String[] { NfcA.class.getName() } };
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver(){
public void onReceive(Context context, Intent intent){
String action = intent.getAction();
if(ACTION_USB_PERMISSION.equals(action)){
synchronized(this){
if (action.equals(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)) {
int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
NfcAdapter.STATE_ON);
if (state == NfcAdapter.STATE_ON
|| state == NfcAdapter.STATE_TURNING_ON) {
///Log.d(TAGCL, "state: " + state);
if (state == NfcAdapter.STATE_ON) {
nfcadapter.enableReaderMode(
MainActivity.this,
MainActivity.this,
NfcAdapter.FLAG_READER_NFC_A
| NfcAdapter.FLAG_READER_NFC_B
//| NfcAdapter.FLAG_READER_NFC_F
//| NfcAdapter.FLAG_READER_NFC_V
//| NfcAdapter.FLAG_READER_NFC_BARCODE
//| NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS
| NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,
null);
}
} else {
showMessage(getString(R.string.nfc_not_activated));
}
}
}
}
}
};
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
/////--Log.d(TAGSAM, "permission granted");
}
}
#Override
protected void onPostResume() {
//bindComponents();
super.onPostResume();
if (!nfcadapter.isEnabled()) {
showMessage(getString(R.string.nfc_not_activated));
return;
}
IntentFilter filter = new IntentFilter(
NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
//registerReceiver(mBroadcastReceiver, filter);
nfcadapter.enableReaderMode(this, this, NfcAdapter.FLAG_READER_NFC_A
| NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK | NfcAdapter.FLAG_READER_NFC_B | NfcAdapter.FLAG_READER_NFC_F, null);
}
#Override
protected void onPause() {
super.onPause();
//unregisterReceiver(mBroadcastReceiver);
nfcadapter.disableReaderMode(this);
}
#Override
protected void onDestroy() {
if( mbUsbExternalUSBManager ){
unregisterReceiver(mUsbReceiver);
}
if( mbUsbExternalUSBManager ){
unregisterReceiver(mUsbReceiver);
}
super.onDestroy();
}
#Override
public void showMessage(final String msg) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
}
});
}
#Override
public void setEditText(final int id, final String txt, final int status) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//EditText edit = (EditText) findViewById(id);
//eMessage.setText(txt);
setMessageText(txt, status);
}
});
}
public void setMessageText(String text, int status)
{
// status 0 : normal proses, 1 : berhasil, 2 : error
}
#Override
public void setBiodata(final Biodata bio) {
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
#Override
public void setProgressBar(final int id, final int value) {
runOnUiThread(new Runnable() {
#Override
public void run() {
ProgressBar pbar = (ProgressBar) findViewById(id);
pbar.setProgress(value);
}
});
}
private void setErrorMessage(String text)
{
//eMessage.setBackground(Color.red());
}
#Override
public void onTagDiscovered(Tag tag) {
if(isSam_authenticate) {
Runnable nfcr = new NfcThread(this, tag, this);
new Thread(nfcr).start();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
//actionBar.setIcon(R.mipmap.ic_launcher);
actionBar.setDisplayShowHomeEnabled(true);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
progressBar = (ProgressBar) findViewById(R.id.progressBar);
eMessage = (TextView) findViewById(R.id.eMessage);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
try {
nfcadapter = NfcAdapter.getDefaultAdapter(this);
if (nfcadapter == null) {
Toast.makeText(this, getString(R.string.nfc_unavailable), Toast.LENGTH_LONG).show();
finish();
}
} catch (Exception f) {
}
mainContext = this;
requestAppPermissions();
}
private void requestAppPermissions() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return;
}
if (hasReadPermissions() && hasWritePermissions()) {
return;
}
ActivityCompat.requestPermissions(this,
new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, REQUEST_WRITE_STORAGE_REQUEST_CODE); // your request code
}
private boolean hasReadPermissions() {
return (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
private boolean hasWritePermissions() {
return (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
}
NfcThread.java
package com.iwjo.nfcfieldstrength;
import android.content.Context;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.util.Log;
import com.iwjo.ktpfieldstrength.R;
import java.io.IOException;
public class NfcThread implements Runnable {
public static final String TAG_CL_IN = ">>";
public static final String TAG_CL_OUT = "<<";
public interface UiCallback {
void showMessage(String msg);
void setEditText(int id, String txt, int status);
void setBiodata(Biodata bio);
void setProgressBar(int id, int value);
}
private Context context;
private Tag tag;
private UiCallback cb;
public NfcThread(Context context, Tag tag, UiCallback cb) {
this.context = context;
this.tag = tag;
this.cb = cb;
}
private IsoDep iso;
#Override
public void run() {
iso = IsoDep.get(tag);
if (iso == null) {
cb.showMessage(context.getString(R.string.non_iso));
return;
}
try {
iso.connect();
} catch (IOException e) {
cb.showMessage(context.getString(R.string.iso_connect_error));
Log.e(TAG, context.getString(R.string.iso_connect_error) + " : " + e.getMessage());
return;
}
try {
byte[] uid = iso.getTag().getId();
String ret = StringUtils.convertByteArrayToHexString(uid);
cb.showMessage("Card detected, UID : "+ret);
cb.setEditText(R.id.eMessage, "", 0);
} catch (Exception e) {
} finally {
try {
iso.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private String send_apdu(String sapdu) throws IOException {
//Log.i(TAG, "SEND -> " + sapdu);
final byte [] apdu = StringUtils.convertHexStringToByteArray(StringUtils.removeSpaces(sapdu));
byte [] recv = iso.transceive(apdu);
String ret = StringUtils.convertByteArrayToHexString(recv);
Log.i(TAG_CL_OUT, ret);
return ret;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.iwjo.nfcfieldstrength">
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<permission android:name="android.permission.REBOOT" />
<permission android:name="android.permission.MODIFY_PHONE_STATE" />
<permission android:name="android.permission.DEVICE_POWER" />
<uses-feature android:name="android.hardware.usb.host" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Please give me advice..

onDestroy() is called when press home button in video call using agora.io

onDestroy() is called when press home button in video call using agora.io .
I have 2 project one is for user and other for astrologer. In User app everything in working fine but in astrologer app onDestroy is calling whenever I press the home button.
This is refernce for agora
https://github.com/AgoraIO/Basic-Video-Call/tree/master/One-to-One-Video/Agora-Android-Tutorial-1to1
public class VideoChatViewActivity extends AppCompatActivity {
private static final String TAG = VideoChatViewActivity.class.getSimpleName();
private static final int PERMISSION_REQ_ID = 22;
// Permission WRITE_EXTERNAL_STORAGE is not mandatory
// for Agora RTC SDK, just in case if you wanna save
// logs to external sdcard.
private static final String[] REQUESTED_PERMISSIONS = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private RtcEngine mRtcEngine;
private boolean mCallEnd;
private boolean mMuted;
private FrameLayout mLocalContainer;
private RelativeLayout mRemoteContainer;
private SurfaceView mLocalView;
private SurfaceView mRemoteView;
private ImageView mCallBtn;
private ImageView mMuteBtn;
private ImageView mSwitchCameraBtn;
// Customized logger view
/**
* Event handler registered into RTC engine for RTC callbacks.
* Note that UI operations needs to be in UI thread because RTC
* engine deals with the events in a separate thread.
*/
private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
#Override
public void onJoinChannelSuccess(String channel, final int uid, int elapsed) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.e("TAG", "Join channel success, uid: " + (uid & 0xFFFFFFFFL));
}
});
}
#Override
public void onFirstRemoteVideoDecoded(final int uid, int width, int height, int elapsed) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.e("TAG", "First remote video decoded, uid: " + (uid & 0xFFFFFFFFL));
setupRemoteVideo(uid);
}
});
}
#Override
public void onUserOffline(final int uid, int reason) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.e("TAG", "User offline, uid: " + (uid & 0xFFFFFFFFL));
onRemoteUserLeft();
}
});
}
};
private void setupRemoteVideo(int uid) {
// Only one remote video view is available for this
// tutorial. Here we check if there exists a surface
// view tagged as this uid.
int count = mRemoteContainer.getChildCount();
View view = null;
for (int i = 0; i < count; i++) {
View v = mRemoteContainer.getChildAt(i);
if (v.getTag() instanceof Integer && ((int) v.getTag()) == uid) {
view = v;
}
}
if (view != null) {
return;
}
mRemoteView = RtcEngine.CreateRendererView(getBaseContext());
mRemoteContainer.addView(mRemoteView);
mRtcEngine.setupRemoteVideo(new VideoCanvas(mRemoteView, VideoCanvas.RENDER_MODE_HIDDEN, uid));
mRemoteView.setTag(uid);
}
private void onRemoteUserLeft() {
removeRemoteVideo();
}
private void removeRemoteVideo() {
if (mRemoteView != null) {
mRemoteContainer.removeView(mRemoteView);
}
mRemoteView = null;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_chat_view);
initUI();
// Ask for permissions at runtime.
// This is just an example set of permissions. Other permissions
// may be needed, and please refer to our online documents.
if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[2], PERMISSION_REQ_ID)) {
initEngineAndJoinChannel();
}
}
private void initUI() {
mLocalContainer = findViewById(R.id.local_video_view_container);
mRemoteContainer = findViewById(R.id.remote_video_view_container);
mCallBtn = findViewById(R.id.btn_call);
mMuteBtn = findViewById(R.id.btn_mute);
mSwitchCameraBtn = findViewById(R.id.btn_switch_camera);
// Sample logs are optional.
showSampleLogs();
}
private void showSampleLogs() {
Log.e("TAG", "Welcome to Agora 1v1 video call");
}
private boolean checkSelfPermission(String permission, int requestCode) {
if (ContextCompat.checkSelfPermission(this, permission) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode);
return false;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQ_ID) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED ||
grantResults[1] != PackageManager.PERMISSION_GRANTED ||
grantResults[2] != PackageManager.PERMISSION_GRANTED) {
showLongToast("Need permissions " + Manifest.permission.RECORD_AUDIO +
"/" + Manifest.permission.CAMERA + "/" + Manifest.permission.WRITE_EXTERNAL_STORAGE);
finish();
return;
}
// Here we continue only if all permissions are granted.
// The permissions can also be granted in the system settings manually.
initEngineAndJoinChannel();
}
}
private void showLongToast(final String msg) {
this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
});
}
private void initEngineAndJoinChannel() {
// This is our usual steps for joining
// a channel and starting a call.
initializeEngine();
setupVideoConfig();
setupLocalVideo();
joinChannel();
}
private void initializeEngine() {
try {
mRtcEngine = RtcEngine.create(getBaseContext(), getString(R.string.agora_app_id), mRtcEventHandler);
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
throw new RuntimeException("NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
}
}
private void setupVideoConfig() {
// In simple use cases, we only need to enable video capturing
// and rendering once at the initialization step.
// Note: audio recording and playing is enabled by default.
mRtcEngine.enableVideo();
// Please go to this page for detailed explanation
// https://docs.agora.io/en/Video/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_rtc_engine.html#af5f4de754e2c1f493096641c5c5c1d8f
mRtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
VideoEncoderConfiguration.VD_640x360,
VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15,
VideoEncoderConfiguration.STANDARD_BITRATE,
VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT));
}
private void setupLocalVideo() {
// This is used to set a local preview.
// The steps setting local and remote view are very similar.
// But note that if the local user do not have a uid or do
// not care what the uid is, he can set his uid as ZERO.
// Our server will assign one and return the uid via the event
// handler callback function (onJoinChannelSuccess) after
// joining the channel successfully.
mLocalView = RtcEngine.CreateRendererView(getBaseContext());
mLocalView.setZOrderMediaOverlay(true);
mLocalContainer.addView(mLocalView);
mRtcEngine.setupLocalVideo(new VideoCanvas(mLocalView, VideoCanvas.RENDER_MODE_HIDDEN, 0));
}
private void joinChannel() {
// 1. Users can only see each other after they join the
// same channel successfully using the same app id.
// 2. One token is only valid for the channel name that
// you use to generate this token.
mRtcEngine.joinChannel(null, getIntent().getExtras().getString("channel_name"), "Extra Optional Data", 0);
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy: ");
if (!mCallEnd) {
leaveChannel();
}
RtcEngine.destroy();
}
#Override
protected void onPause() {
super.onPause();
Log.e(TAG, "onPause: ");
}
#Override
protected void onStop() {
super.onStop();
Log.e(TAG, "onStop: ");
}
private void leaveChannel() {
mRtcEngine.leaveChannel();
}
public void onLocalAudioMuteClicked(View view) {
mMuted = !mMuted;
mRtcEngine.muteLocalAudioStream(mMuted);
int res = mMuted ? R.drawable.btn_mute : R.drawable.btn_mute;
mMuteBtn.setImageResource(res);
}
public void onSwitchCameraClicked(View view) {
mRtcEngine.switchCamera();
}
public void onCallClicked(View view) {
if (mCallEnd) {
startCall();
mCallEnd = false;
mCallBtn.setImageResource(R.drawable.btn_end_call);
} else {
endCall();
mCallEnd = true;
mCallBtn.setImageResource(R.drawable.btn_end_call);
}
showButtons(!mCallEnd);
}
private void startCall() {
setupLocalVideo();
joinChannel();
}
private void endCall() {
removeLocalVideo();
removeRemoteVideo();
leaveChannel();
}
private void removeLocalVideo() {
if (mLocalView != null) {
mLocalContainer.removeView(mLocalView);
}
mLocalView = null;
}
private void showButtons(boolean show) {
int visibility = show ? View.VISIBLE : View.GONE;
mMuteBtn.setVisibility(visibility);
mSwitchCameraBtn.setVisibility(visibility);
}
}
Welcome to codding party.
you should implement
onSaveInstanceState
and
onRestoreInstanceState
properly. The framework may kill your Activity at any time it isn't foreground.
other way u can Use Foreground service for keeping alive your call.

How to add value on Permission Manager

I was wondering how to set value on manager? Here's how I initialize PermissionManager manager or PermissionManager manager = new?
public PermissionManager manager = new PermissionManager(PermissionManager.mActivity, PermissionManager.mContext);
protected void onStart() {
super.onStart();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
/*String[] list = new String[]{PermissionConsts.PHONE_STATE, PermissionConsts.READ_CONTACTS, PermissionConsts.READ_EXTERNAL_STORAGE,
PermissionConsts.READ_SMS};*/
manager.requestPermission(new String[]{Manifest.permission.ACCESS_FINE_LOCATION});
}
Intent serviceIntent = new Intent(this, LocationFetcherService.class);
startService(serviceIntent);
}
Here it doesn't work:
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
initLocationFetching(this);
}
}
Here is BaseActivityLocation class
public class BaseActivityLocation extends AppCompatActivity implements LocationManagerInterface {
public SmartLocationManager mLocationManager;
public PermissionManager manager = new PermissionManager(BaseActivityLocation.this, BaseActivityLocation.this);
public LocationFetcherService mLocationFetcherService;
private static final int REQUEST_FINE_LOCATION = 1;
private Activity mCurrentActivity;
private int count = 0;
#Override
public void locationFetched(Location mLocation, Location oldLocation, String time, String locationProvider) {
// storing it on application level
GetAccurateLocationApplication.mCurrentLocation = mLocation;
GetAccurateLocationApplication.oldLocation = oldLocation;
GetAccurateLocationApplication.locationProvider = locationProvider;
GetAccurateLocationApplication.locationTime = time;
}
public void instatntiate(Activity mActivity){
/*3rd Parametr*/
//For One time Gps Usage: SmartLocationManager.USE_ONE_TIME_GPS;
//For every 10 seconds Gps Usage: SmartLocationManager.USE_UPDATE_TIME_GPS;
/*4th parameter*/
//For All netwrok Provider: SmartLocationManager.ALL_PROVIDERS;
//For Network Provider only: SmartLocationManager.NETWORK_PROVIDER;
//For GPS Provider only: SmartLocationManager.GPS_PROVIDER;
/*Last Parameter*/
//For using Any Api location: SmartLocationManager.ANY_API; //The priority will be google api.
//For using google Api location: SmartLocationManager.ONLY_GOOGLE_API;
//For using android Api Location: SmartLocationManager.ONLY_ANDROID_API;
mLocationManager = new SmartLocationManager(getApplicationContext(), mActivity, SmartLocationManager.USE_ONE_TIME_GPS, this, SmartLocationManager.ALL_PROVIDERS, LocationRequest.PRIORITY_HIGH_ACCURACY, 10 * 1000, 1 * 1000, SmartLocationManager.LOCATION_PROVIDER_RESTRICTION_NONE, SmartLocationManager.ANY_API); // init location manager
}
public void initLocationFetching(Activity mActivity) {
mCurrentActivity = mActivity;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
manager = new PermissionManager(mCurrentActivity, getApplicationContext());
PermissionManagerInterface permissionManagerInterface = new PermissionManagerInterface() {
#Override
public void onPermissionGranted(String message, int requestCode) {
}
Here is the code of Permission Manager class but I am having a null value where I want to eliminate
public class PermissionManager implements RequestPermissionsResultInterface {
public static Activity mActivity;
public static Context mContext;
public String[] permissionList;
public boolean flag;
private PermissionManagerInterface mManagerInterface = new PermissionManagerInterface() {
#Override
public void onPermissionGranted(String message, int requestCode) {
}
#Override
public void onPermissionDenied(String message, int requestCode) {
}
#Override
public void isAllGranted(boolean flag) {
}
};
public PermissionManager(Activity mActivity, Context mContext) {
this.mActivity = mActivity;
this.mContext = mContext;
}
public void requestPermission(String[] mList){
permissionList = mList;
ActivityCompat.requestPermissions(mActivity, mList, REQ_CODE);
}
public void getManagerInterface(PermissionManagerInterface mInterface){
mManagerInterface = mInterface;
}
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode == REQ_CODE){
for (int i = 0, len = permissions.length; i < len; i++) {
String permission = permissions[i];
String packageStrippedPermissionName = permissions[i].substring(permissions[0].lastIndexOf(".")+1);
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
// user rejected the permission
boolean showRationale = mActivity.shouldShowRequestPermissionRationale( permission );
if (! showRationale) {
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setTitle(permission + " Required");
builder.setMessage("You have to grant this permission , otherwise app will not be able to continue, Click Yes to go to Settings else app will not resume!");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", mActivity.getPackageName(), null);
intent.setData(uri);
mActivity.startActivityForResult(intent, REQ_CODE);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(mContext, "App will not Start without this Permission", Toast.LENGTH_SHORT).show();
mActivity.finish();
}
});
builder.setCancelable(false);
builder.show();
// user also CHECKED "never ask again"
// you can either enable some fall back,
// disable features of your app
// or open another dialog explaining
// again the permission and directing to
// the app setting
}else{
mManagerInterface.onPermissionDenied("\'" + packageStrippedPermissionName + "': permission denied", requestCode);
Alert(mActivity, permissions[i]);
}
}else if(grantResults[i] == PackageManager.PERMISSION_GRANTED){
mManagerInterface.onPermissionGranted("\'" + packageStrippedPermissionName + "\': permission granted", requestCode);
}
}
ArrayList<String> list = new ArrayList<>();
for(int k=0; k<grantResults.length; k++){
if(grantResults[k] == PackageManager.PERMISSION_GRANTED){
list.add(permissions[k]);
}
}
if(list.size() == permissions.length){
flag = true;
mManagerInterface.isAllGranted(flag);
}else{
flag = false;
mManagerInterface.isAllGranted(flag);
}
}
}
BaseActivityLocation java class:
BaseActivityLocation extends AppCompatActivity implements LocationManagerInterface {
public SmartLocationManager mLocationManager;
public PermissionManager manager = null;
public LocationFetcherService mLocationFetcherService;
private static final int REQUEST_FINE_LOCATION = 1;
private Activity mCurrentActivity;
private int count = 0;
#Override
public void locationFetched(Location mLocation, Location oldLocation, String time, String locationProvider) {
// storing it on application level
GetAccurateLocationApplication.mCurrentLocation = mLocation;
GetAccurateLocationApplication.oldLocation = oldLocation;
GetAccurateLocationApplication.locationProvider = locationProvider;
GetAccurateLocationApplication.locationTime = time;
}
protected void onStart() {
super.onStart();
manager = new PermissionManager(BaseActivityLocation.this, BaseActivityLocation.this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
/*String[] list = new String[]{PermissionConsts.PHONE_STATE, PermissionConsts.READ_CONTACTS, PermissionConsts.READ_EXTERNAL_STORAGE,
PermissionConsts.READ_SMS};*/
manager.requestPermission(new String[]{Manifest.permission.ACCESS_FINE_LOCATION});
}
Intent serviceIntent = new Intent(this, LocationFetcherService.class);
startService(serviceIntent);
}
protected void onResume(){
super.onResume();
//showLocationPermission();
}
Permission Manager Interface
public interface PermissionManagerInterface extends Serializable
{
String TAG = PermissionManagerInterface.class.getSimpleName();
void onPermissionGranted(String message, int requestCode);
void onPermissionDenied(String message, int requestCode);
void isAllGranted(boolean flag);
}
Try this if this is inside a activity. YourActivity is your activity name:
public PermissionManager manager = null;
protected void onStart() {
super.onStart();
manager = new PermissionManager(YourActivity.this, YourActivity.this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
/*String[] list = new String[]{PermissionConsts.PHONE_STATE, PermissionConsts.READ_CONTACTS, PermissionConsts.READ_EXTERNAL_STORAGE,
PermissionConsts.READ_SMS};*/
manager.requestPermission(new String[]{Manifest.permission.ACCESS_FINE_LOCATION});
}
Intent serviceIntent = new Intent(this, LocationFetcherService.class);
startService(serviceIntent);
}

Android: Turn On/Off WiFi Hotspot Programmatically on Android Marshmallow (6.0)

I have come across this thread (Android: How to Enable/Disable Wifi or Internet Connection Programmatically) which is very similar to what I wanted to ask. I have tried the solution provided by an answer posted by Ashish Sahu (https://stackoverflow.com/users/1780737/ashish-sahu) which seems to work perfectly on other Android versions aside from Marshmallow (6.0).
Is there anyway to toggle and setup a WiFi Hotspot on Android Marshmallow? I tried using mHotspot (http://www.mhotspot.com/) which can do the job on Android Marshmallow but I just don't know how to implement it.
Thanks in advance.
My answer for this question is:
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Build;
import android.util.Log;
public class WifiAPController extends Activity {
public int a;
public int b;
public String password;
public String APname;
private static int g;
private static int h;
private static int i;
private static int j;
private WifiManager wifiManager;
private String logTAG;
private int wifiState;
private boolean o;
class wifiControllerTask extends AsyncTask {
WifiAPController wifiAPControllerClass;
boolean a;
boolean b;
Context mContext;
public wifiControllerTask(WifiAPController wifiAPController, boolean arg3, boolean arg4, Context context) {
this.wifiAPControllerClass = wifiAPController;
this.a = arg3;
this.b = arg4;
this.mContext = context;
}
protected Void a(Void[] arg3) {
try {
WifiAPController.wifiToggle(this.wifiAPControllerClass, this.a);
} catch (Exception v0) {
}
return null;
}
public void a() {
int sdkCurrentVersion = 21;
try {
if (this.a) {
if (Build.VERSION.SDK_INT < sdkCurrentVersion) {
return;
}
this.wifiAPControllerClass.wifiToggle(this.mContext);
return;
}
if (Build.VERSION.SDK_INT < sdkCurrentVersion) {
return;
}
} catch (Exception v0) {
Log.e("noti error", v0.getMessage());
}
}
protected void a(Void arg2) {
super.onPostExecute(arg2);
try {
this.a();
} catch (IllegalArgumentException v0) {
try {
this.a();
} catch (Exception v0_1) {
}
}
if (this.b) {
this.wifiAPControllerClass.finish();
}
}
protected Object doInBackground(Object[] arg2) {
return this.a(((Void[]) arg2));
}
protected void onPostExecute(Object arg1) {
this.a(((Void) arg1));
}
protected void onPreExecute() {
super.onPreExecute();
}
}
static {
WifiAPController.g = 0;
WifiAPController.h = 0;
WifiAPController.i = 1;
WifiAPController.j = 4;
}
public WifiAPController() {
super();
this.a = 2;
this.b = 3;
this.logTAG = "WifiAP";
this.wifiState = -1;
this.o = false;
}
static int wifiToggle(WifiAPController wifiAPController, boolean wifiToggleFlag) {
return wifiAPController.wifiToggle(wifiToggleFlag);
}
private void initWifiAPConfig(WifiConfiguration wifiConfiguration){
wifiConfiguration.SSID = "SomeName";
wifiConfiguration.preSharedKey = "SomeKey1";
wifiConfiguration.hiddenSSID = false;
wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wifiConfiguration.allowedKeyManagement.set(4);
wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
}
private int wifiToggle(boolean wifiToggleFlag) {
int wifiState;
String stateString;
StringBuilder message;
long sleepTimeout = 500;
int maxAttemptCount = 10;
int errorState = -1;
Log.d(this.logTAG, "*** setWifiApEnabled CALLED **** " + wifiToggleFlag);
WifiConfiguration wifiConfiguration = new WifiConfiguration();
initWifiAPConfig(wifiConfiguration);
if ((wifiToggleFlag) && this.wifiState == errorState) {
this.wifiState = this.wifiManager.getWifiState();
}
if (!(!wifiToggleFlag || this.wifiManager.getConnectionInfo() == null)) {
Log.d(this.logTAG, "disable wifi: calling");
this.wifiManager.setWifiEnabled(false);
int attemptCount = maxAttemptCount;
while (attemptCount > 0) {
if (this.wifiManager.getWifiState() == 1) {
break;
}
Log.d(this.logTAG, "disable wifi: waiting, pass: " + (10 - attemptCount));
try {
Thread.sleep(sleepTimeout);
--attemptCount;
} catch (Exception v4_1) {
}
}
Log.d(this.logTAG, "disable wifi: done, pass: " + (10 - attemptCount));
}
try {
message = new StringBuilder();
stateString = wifiToggleFlag ? "enabling" : "disabling";
Log.d(this.logTAG, message.append(stateString).append(" wifi ap: calling").toString());
Log.d(this.logTAG, this.APname);
Log.d(this.logTAG, this.password);
Log.d(this.logTAG, "" + this.wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class).invoke(this.wifiManager, wifiConfiguration, true).toString());
int res = this.wifiManager.addNetwork(wifiConfiguration);
Log.d(this.logTAG, "" + res);
wifiState = (int) this.wifiManager.getClass().getMethod("getWifiApState").invoke(this.wifiManager);
Log.d(this.logTAG, "" + wifiState);
} catch (Exception v0_1) {
Log.e("wifi", v0_1.getMessage());
wifiState = errorState;
}
while (maxAttemptCount > 0) {
if (this.wifiToggle() != WifiAPController.h && this.wifiToggle() != this.b && this.wifiToggle() != WifiAPController.j) {
break;
}
message = new StringBuilder();
stateString = wifiToggleFlag ? "enabling" : "disabling";
Log.d(this.logTAG, message.append(stateString).append(" wifi ap: waiting, pass: ").append(10 - maxAttemptCount).toString());
sleepTimeout = 500;
try {
Thread.sleep(sleepTimeout);
--maxAttemptCount;
} catch (Exception v0_1) {
}
}
message = new StringBuilder();
stateString = wifiToggleFlag ? "enabling" : "disabling";
Log.d(this.logTAG, message.append(stateString).append(" wifi ap: done, pass: ").append(10 - maxAttemptCount).toString());
if (!wifiToggleFlag) {
if ((this.wifiState >= WifiManager.WIFI_STATE_ENABLING && this.wifiState <= WifiManager.WIFI_STATE_UNKNOWN) || (this.o)) {
Log.d(this.logTAG, "enable wifi: calling");
this.wifiManager.setWifiEnabled(true);
}
this.wifiState = errorState;
return wifiState;
}
return wifiState;
}
public int wifiToggle() {
int result;
int v4 = 10;
try {
result = (int) this.wifiManager.getClass().getMethod("getWifiApState").invoke(this.wifiManager);
} catch (Exception v0) {
result = -1;
}
if (result >= v4) {
WifiAPController.g = v4;
}
WifiAPController.h = WifiAPController.g;
WifiAPController.i = WifiAPController.g + 1;
this.a = WifiAPController.g + 2;
this.b = WifiAPController.g + 3;
WifiAPController.j = WifiAPController.g + 4;
return result;
}
public void wifiToggle(Context context) {
Intent v0 = new Intent(context, MainActivity.class);
}
public void wifiToggle(String apname, String pass, WifiManager wifiManager, Context context) {
boolean v2 = true;
if (this.wifiManager == null) {
this.wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
}
this.APname = apname;
this.password = pass;
int v0 = this.wifiToggle() == this.b || this.wifiToggle() == this.a ? 1 : 0;
if (v0 != 0) {
v2 = false;
}
new wifiControllerTask(this, v2, false, context).execute(new Void[0]);
}
}
Also, in main Activity you should call like this:
WifiAPController wifiAPController = new WifiAPController();
wifiAPController.wifiToggle("mHotspot", "12345678", wifiManager, context);
Don't forget about permissions:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
I tested this on Nexus 6 with Marshmallow(6.0)
Anybody give this a try?
http://www.ibtimes.co.uk/how-enable-tethering-android-6-0-marshmallow-update-1524792
It basically says you run an adb shell and do this:
settings put global tether_dun_required 0
Now obviously this isn't something an app can do, but I just want my android program to programmatically turn tethering on and off for me on my phone so if it works for me, I'd be happy.
It sounds though, like it just removes control of the carrier, not sure it gets around whatever new limitations marshmallow itself has inflicted upon us hapless developers.

Android - cast screen to chromecast via custom app

I need to do the same thing of the Chromecast App (com.google.android.apps.chromecast.app) "Mirror screen" functionality:
pressing a custom button the app asks to select the chromecast device to stream to and then start the screen mirroring to the selected chromecast device.
Actually this feature is not documented anywhere. Have i to use the Presentation class?
Reading logs of the Chromecast App i discovered the following receiver app ids:
app id E8C28D3C
app name Backdrop
app id 674A0243
app name Screen Mirroring
How can i do that?
This is my code:
public class MainActivity extends ActionBarActivity
{
private MediaRouter mMediaRouter;
private MediaRouteSelector mMediaRouteSelector;
private android.support.v7.media.MediaRouter.Callback mMediaRouterCallback;
private CastDevice mSelectedDevice;
private GoogleApiClient mApiClient;
private Cast.Listener mCastClientListener;
private ConnectionCallbacks mConnectionCallbacks;
private ConnectionFailedListener mConnectionFailedListener;
private boolean mWaitingForReconnect;
private boolean mApplicationStarted;
private String mSessionId;
private DemoPresentation mPresentation;
private final static String TAG = "CAST-APP";
private String mAppID = "AE85BA70";
private String mirroringAppID="674A0243";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMediaRouter = MediaRouter.getInstance(getApplicationContext());
mMediaRouteSelector = new MediaRouteSelector.Builder()
//.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
//.addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
//.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
//.addControlCategory(CastMediaControlIntent.categoryForCast(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID))
.addControlCategory(CastMediaControlIntent.categoryForCast(mirroringAppID))
.build();
mMediaRouterCallback = new MyMediaRouterCallback();
/*MediaRouteButton btn = (MediaRouteButton) findViewById(R.id.mediabutton);
btn.setRouteSelector(mMediaRouteSelector);*/
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
MediaRouteActionProvider mediaRouteActionProvider =
(MediaRouteActionProvider) MenuItemCompat.getActionProvider(mediaRouteMenuItem);
mediaRouteActionProvider.setRouteSelector(mMediaRouteSelector);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
int id = item.getItemId();
return super.onOptionsItemSelected(item);
}
#Override
protected void onResume() {
super.onResume();
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback,
MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
}
#Override
protected void onPause() {
if (isFinishing()) {
mMediaRouter.removeCallback(mMediaRouterCallback);
}
super.onPause();
}
/*
#Override
protected void onStart() {
super.onStart();
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback,
MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
}
#Override
protected void onStop() {
mMediaRouter.removeCallback(mMediaRouterCallback);
super.onStop();
}
*/
private class MyMediaRouterCallback extends MediaRouter.Callback {
#Override
public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) {
try
{
mSelectedDevice = CastDevice.getFromBundle(info.getExtras());
String routeId = info.getId();
mCastClientListener = new Cast.Listener()
{
#Override
public void onApplicationStatusChanged()
{
if (mApiClient != null)
{
Log.d(TAG, "onApplicationStatusChanged: "
+ Cast.CastApi.getApplicationStatus(mApiClient));
//updatePresentation();
}
}
#Override
public void onVolumeChanged()
{
if (mApiClient != null)
{
Log.d(TAG, "onVolumeChanged: " + Cast.CastApi.getVolume(mApiClient));
}
}
#Override
public void onApplicationDisconnected(int errorCode)
{
teardown();
}
};
mConnectionCallbacks = new ConnectionCallbacks();
mConnectionFailedListener = new ConnectionFailedListener();
Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions
.builder(mSelectedDevice, mCastClientListener);
mApiClient = new GoogleApiClient.Builder(getApplication())
.addApi(Cast.API, apiOptionsBuilder.build())
.addConnectionCallbacks(mConnectionCallbacks)
.addOnConnectionFailedListener(mConnectionFailedListener)
.build();
mApiClient.connect();
} catch (Exception e) {
Log.d(TAG, "onRouteSelected " + e.getMessage());
}
}
#Override
public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) {
Log.d(TAG, "onRouteUnselected: info=" + info);
teardown();
//updatePresentation();
mSelectedDevice = null;
}
#Override
public void onRoutePresentationDisplayChanged(MediaRouter router, MediaRouter.RouteInfo info) {
//updatePresentation();
}
}
private void showPresentation()
{
DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
Display[] presentationDisplays = displayManager.getDisplays();
Log.d("showPresentation", "Displays: " + String.valueOf(presentationDisplays.length));
if (presentationDisplays.length > 0) {
Log.d("showPresentation", "Display : " + presentationDisplays[0].getName());
Display display = presentationDisplays[0];
mPresentation = new DemoPresentation(this, display);
mPresentation.show();
}
//updatePresentation();
}
private class ConnectionCallbacks implements
GoogleApiClient.ConnectionCallbacks {
#Override
public void onConnected(Bundle connectionHint) {
if (mWaitingForReconnect) {
mWaitingForReconnect = false;
//reconnectChannels();
if ((connectionHint != null)
&& connectionHint
.getBoolean(Cast.EXTRA_APP_NO_LONGER_RUNNING)) {
Log.d(TAG, "App is no longer running");
teardown();
}
} else {
try {
Cast.CastApi.launchApplication(mApiClient, mirroringAppID, false)
.setResultCallback(
new ResultCallback<Cast.ApplicationConnectionResult>() {
#Override
public void onResult(Cast.ApplicationConnectionResult result) {
Status status = result.getStatus();
if (status.isSuccess()) {
ApplicationMetadata applicationMetadata =
result.getApplicationMetadata();
mSessionId = result.getSessionId();
String applicationStatus = result.getApplicationStatus();
boolean wasLaunched = result.getWasLaunched();
mApplicationStarted = true;
} else {
teardown();
}
}
});
} catch (Exception e) {
Log.e(TAG, "Failed to launch application", e);
}
}
}
#Override
public void onConnectionSuspended(int cause) {
mWaitingForReconnect = true;
}
}
private class ConnectionFailedListener implements
GoogleApiClient.OnConnectionFailedListener {
#Override
public void onConnectionFailed(ConnectionResult result) {
teardown();
}
}
private void teardown() {
Log.d(TAG, "teardown");
if (mApiClient != null) {
if (mApplicationStarted) {
if (mApiClient.isConnected() || mApiClient.isConnecting()) {
try {
Cast.CastApi.stopApplication(mApiClient, mSessionId);
} catch (Exception e) {
Log.e(TAG, "Exception while removing channel", e);
}
mApiClient.disconnect();
}
mApplicationStarted = false;
}
mApiClient = null;
}
mSelectedDevice = null;
mWaitingForReconnect = false;
mSessionId = null;
}
}
You cannot do that from your own app, currently there are no APIs available for developers to start the cast mirroring from within their apps and it should be done manually by user; this may change in future but that is the current status.
Seems you only need not set up any custom Presentation screen and mirroring will be carried out by default:
https://developer.android.com/reference/android/media/MediaRouter.html#ROUTE_TYPE_LIVE_VIDEO

Categories

Resources