My goal is to record audio from a Bluetooth Microphone while in Background Mode.
Expected result:
The A2DPService records audio while in the background mode.
Actual result:
The A2DPService can not record audio after in the background mode after 2 minutes. The audio file will be empty.
How to reproduce the issue:
use the #ReactMethod connectDevice(address: string).
went to background mode, wait until 2 minutes.
use the #ReactMethod startBluetoothSco() to record the audio
use the #ReactMethod stopBluetoothSco() to stop the recorder.
play the audio file. the audio file will not run as there is no input from the Bluetooth Microphone. Getting the app to Foreground Mode fixed the issue, but the app is intended to be used most of the time while in Background Mode.
A2DPService.java
package com.satpam.RNBluetoothNM.A2DP;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.media.AudioManager;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class A2DPService {
private BluetoothDevice mBluetoothDevice;
private BluetoothA2dp mBluetoothA2dp;
private AudioManager mAudioManager;
public A2DPService(ReactApplicationContext reactContext) {
mAudioManager = (AudioManager) reactContext.getSystemService(Context.AUDIO_SERVICE);
BluetoothAdapter
.getDefaultAdapter()
.getProfileProxy(reactContext, new BluetoothProfile.ServiceListener() {
#Override
public void onServiceConnected(int i, BluetoothProfile bluetoothProfile) {
if (i == BluetoothProfile.A2DP) {
mBluetoothA2dp = (BluetoothA2dp) bluetoothProfile;
}
}
#Override
public void onServiceDisconnected(int i) {
if (i == BluetoothProfile.A2DP) {
mBluetoothA2dp = null;
}
}
}, BluetoothProfile.A2DP);
}
public boolean createBond(BluetoothDevice bluetoothDevice) {
mBluetoothDevice = bluetoothDevice;
return mBluetoothDevice.createBond();
}
public boolean connectA2DP(BluetoothDevice bluetoothDevice) {
if (mBluetoothDevice == null) {
return false;
} else {
try {
Method method = BluetoothA2dp.class.getMethod("connect", BluetoothDevice.class);
method.invoke(mBluetoothA2dp, bluetoothDevice);
return true;
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
return false;
}
}
}
public int getConnectedState() {
return mBluetoothA2dp.getConnectionState(mBluetoothDevice);
}
public boolean startBluetoothSco() {
if (getConnectedState() != BluetoothProfile.STATE_CONNECTED) {
return false;
} else {
mAudioManager.setBluetoothScoOn(true);
mAudioManager.startBluetoothSco();
return true;
}
}
public boolean stopBluetoothSco() {
if (getConnectedState() != BluetoothProfile.STATE_CONNECTED) {
return false;
} else {
mAudioManager.setBluetoothScoOn(false);
mAudioManager.stopBluetoothSco();
return true;
}
}
}
RNBluetoothNM.java
package com.satpam.RNBluetoothNM;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Intent;
import android.util.Log;
import androidx.annotation.NonNull;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.BaseActivityEventListener;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.satpam.RNBluetoothNM.A2DP.A2DPService;
import com.satpam.RNBluetoothNM.SPP.SPPService;
import java.util.Set;
public class RNBluetoothNMPackage extends ReactContextBaseJavaModule {
#NonNull
#Override
public String getName() {
return "RNBluetoothNM";
}
private static final int getBondedDeviceRequestCode = 0;
private Promise mPromise;
private final ActivityEventListener activityListener = new BaseActivityEventListener() {
#Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
super.onActivityResult(activity, requestCode, resultCode, data);
if (requestCode == getBondedDeviceRequestCode && resultCode == activity.RESULT_OK) {
getBondedDevices(mPromise);
mPromise = null;
}
}
};
public RNBluetoothNMPackage(ReactApplicationContext reactContext) {
super(reactContext);
// Add a listener for `onActivityResult`
reactContext.addActivityEventListener(activityListener);
}
private void _requestEnableBluetooth(Promise promise) {
Intent enableAdapter = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
Activity activity = getCurrentActivity();
// Store the promise to resolve/reject when onActivityResult returns value;
mPromise = promise;
activity.startActivityForResult(enableAdapter, getBondedDeviceRequestCode);
}
#ReactMethod
public void getBondedDevices(final Promise promise) {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
promise.reject("getBondedDevices", "BluetoothAdapter is not supported");
} else {
if (!bluetoothAdapter.isEnabled()) {
_requestEnableBluetooth(promise);
}
Set<BluetoothDevice> devices = bluetoothAdapter.getBondedDevices();
if (devices.size() > 0) {
WritableArray array = Arguments.createArray();
for (BluetoothDevice device : devices) {
WritableMap writableMap = Arguments.createMap();
writableMap.putString("name", device.getName());
writableMap.putString("address", device.getAddress());
writableMap.putInt("bondState", device.getBondState());
array.pushMap(writableMap);
}
promise.resolve(array);
}
}
}
private A2DPService a2DPService;
private SPPService sppService;
#ReactMethod
public void connectDevice(String address, final Promise promise) {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
promise.reject("connectDevice", "BluetoothAdapter is not supported");
} else {
if (!bluetoothAdapter.isEnabled()) {
_requestEnableBluetooth(promise);
}
BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(address);
a2DPService = new A2DPService(getReactApplicationContext());
boolean a2dpIsBonded = a2DPService.createBond(bluetoothDevice);
if (a2dpIsBonded == false) {
promise.reject("A2DPService", "A2DP failed to bond");
} else {
boolean a2dpIsConnected = a2DPService.connectA2DP(bluetoothDevice);
if (a2dpIsConnected == false) {
promise.reject("A2DP", "A2DP failed to connect");
} else {
sppService = new SPPService(getReactApplicationContext());
boolean sppIsConnected = sppService.connectSPP(bluetoothDevice);
if (sppIsConnected == false) {
promise.reject("SPPService", "A2DP failed to bond");
} else {
promise.resolve(true);
Thread listener = new Thread(sppService);
listener.start();
}
}
}
}
}
#ReactMethod
public void startBluetoothSco(final Promise promise) {
if (a2DPService == null) {
promise.reject("startBluetoothSco", "A2DPService is null");
} else {
boolean isBluetoothScoStarted = a2DPService.startBluetoothSco();
if (isBluetoothScoStarted == false) {
promise.reject("startBluetoothSco", "A2DPService is not connected");
} else {
promise.resolve(true);
}
}
}
#ReactMethod
public void stopBluetoothSco(final Promise promise) {
if (a2DPService == null) {
promise.reject("stopBluetoothSco", "A2DPService is null");
} else {
boolean isBluetoothScoStopped = a2DPService.stopBluetoothSco();
if (isBluetoothScoStopped == false) {
promise.reject("stopBluetoothSco", "A2DPService is not connected");
} else {
promise.resolve(true);
}
}
}
}
You're using a background service. There's a limited amount of time those are allowed to run. Use a foreground service, which has no time limitations. This doesn't require your app to be in front, it just causes a notification to appear saying you're running.
The only things you need to change is to start the service with startForegroundService() and to call startForegound in the service itself.
Related
I want to play this link but i m unable to play this link in my exoplayer
I will be able to play this link only when this referer will be added in the exoplayer but i m unable to add this referer. I dont know how can i add this referer to my exoplayer
Referer: http://nbajunkie.xyz/jp1/
https://reels2watch.com/hls/s1.m3u8
dataSourceFactory.getDefaultRequestProperties().set("Referer", "https://yourdomain.com");
I dont know how to add this referer in the header can someone help me about it or Anyone can do it for me ? Because i don’t know much about java kindly let me know how to solve this issue.
import static com.google.android.exoplayer2.util.Util.getUserAgent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.media.session.PlaybackStateCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.mediarouter.app.MediaRouteButton;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.util.Util;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
import com.google.android.gms.cast.MediaInfo;
import com.google.android.gms.cast.MediaLoadOptions;
import com.google.android.gms.cast.MediaMetadata;
import com.google.android.gms.cast.framework.CastButtonFactory;
import com.google.android.gms.cast.framework.CastContext;
import com.google.android.gms.cast.framework.CastSession;
import com.google.android.gms.cast.framework.CastState;
import com.google.android.gms.cast.framework.CastStateListener;
import com.google.android.gms.cast.framework.SessionManagerListener;
import com.google.android.gms.cast.framework.media.RemoteMediaClient;
import com.google.firebase.FirebaseApp;
import com.google.firebase.firestore.FirebaseFirestore;
import com.Myapp.hd.Steaming.R;
import com.Myapp.hd.Steaming.HelperClass;
import com.Myapp.hd.Steaming.BaseActivity;
import com.Myapp.hd.Steaming.Location;
import com.Myapp.hd.Steaming.sessionManager.SessionManager;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
public class Exo_Player extends BaseActivity {
private static final String TAG = "Exo_Player";
String url, userAgent;
boolean tokenEnable = false;
private InterstitialAd interstitial;
private PlayerView playerView;
private SimpleExoPlayer player;
private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
private DataSource.Factory mediaDataSourceFactory;
private Handler mainHandler;
private ProgressBar progressBar;
FirebaseFirestore db;
SessionManager sessionManager;
FirebaseFirestore firebaseFirestore;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
//////////////////////////////////////////////////////
setContentView(R.layout.exo_player_ui);
castContext = CastContext.getSharedInstance(this);
initCast();
db = FirebaseFirestore.getInstance();
sessionManager = new SessionManager(this);
FirebaseApp.initializeApp(this);
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(Exo_Player.this, sessionManager.getBackads(), adRequest,
new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
// The mInterstitialAd reference will be null until
// an ad is loaded.
interstitial = interstitialAd;
Log.i(TAG, "onAdLoaded");
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError) {
// Handle the error
Log.i(TAG, loadAdError.getMessage());
interstitial = null;
}
});
progressBar = findViewById(R.id.progressBar);
processToken();
listenCast();
}
MediaRouteButton mediaRouteButton;
CastContext castContext;
RemoteMediaClient remoteMediaClient;
public boolean initCast() {
url = getIntent().getStringExtra(getString(R.string.url));
userAgent = getIntent().getStringExtra(getString(R.string.user_agent));
tokenEnable = getIntent().getBooleanExtra(getString(R.string.t_enable), false);
mediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button);
CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), mediaRouteButton);
if (castContext == null)
castContext = CastContext.getSharedInstance(this);
castContext.addCastStateListener(new CastStateListener() {
#Override
public void onCastStateChanged(int state) {
/*if (state == CastState.NO_DEVICES_AVAILABLE) {
// mediaRouteButton.setVisibility(View.GONE);
}
else if(state==CastState.CONNECTING) {
showToast("Connecting");
} else*/ if (state == CastState.CONNECTED) {
// showToast("Connected");
// castMetadata();
openCastPlayer();
}/* else if (mediaRouteButton.getVisibility() == View.GONE) {
mediaRouteButton.setVisibility(View.VISIBLE);
}*/
}
});
if (castContext.getCastState() == CastState.CONNECTED) {
openCastPlayer();
return true;
} else {
// showToast("not connected");
}
if (castContext.getCastState() != CastState.NO_DEVICES_AVAILABLE)
mediaRouteButton.setVisibility(View.VISIBLE);
return false;
}
private void registerListener() {
if (mCastContext != null) {
mCastContext.getSessionManager().addSessionManagerListener(
mSessionManagerListener, CastSession.class);
}
}
private void unRegisterListener() {
if (mCastContext != null) {
mCastContext.getSessionManager().removeSessionManagerListener(
mSessionManagerListener, CastSession.class);
}
}
private void showToast(String connecting) {
Toast.makeText(this, connecting, Toast.LENGTH_SHORT).show();
}
private void processToken() {
if (!HelperClass.isValid(url) || !tokenEnable) {
init("");
return;
}
HashMap<String, Object> hashMap = new HashMap<>();
enqueue(getLocInterface().getLoc(sessionManager.getToken(), hashMap), new CallBack<Location>() {
#Override
public void onComplete() {
super.onComplete();
}
#Override
public void onError(Throwable e) {
super.onError(e);
Toast.makeText(Exo_Player.this,
"Failed to process url", Toast.LENGTH_SHORT).show();
}
#Override
public void onNext(#NotNull Location location) {
super.onNext(location);
if (location.appendResult != null)
init(location.appendResult);
}
});
}
private void init(String s) {
url += s;
Log.e(TAG, "init: new url is " + url);
mediaDataSourceFactory = buildDataSourceFactory(true);
mainHandler = new Handler();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
RenderersFactory renderersFactory = new DefaultRenderersFactory(this);
// TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
// TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
// TrackSelector trackSelector = new DefaultTrackSelector();
LoadControl loadControl = new DefaultLoadControl();
player = new SimpleExoPlayer.Builder(this, renderersFactory).setLoadControl(loadControl).build();
playerView = findViewById(R.id.exoPlayerView);
playerView.setPlayer(player);
playerView.setUseController(true);
playerView.requestFocus();
Uri uri = Uri.parse(url);
final MediaSource mediaSource = buildMediaSource(uri, null);
player.prepare(mediaSource);
player.setPlayWhenReady(true);
player.addListener(new Player.Listener() {
#Override
public void onTracksChanged(#NotNull TrackGroupArray trackGroups, #NotNull TrackSelectionArray trackSelections) {
Log.d(TAG, "onTracksChanged: " + trackGroups.length);
}
#Override
public void onIsLoadingChanged(boolean isLoading) {
Log.d(TAG, "onLoadingChanged: " + isLoading);
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Log.d(TAG, "onPlayerStateChanged: " + playWhenReady);
if (playbackState == PlaybackStateCompat.STATE_PLAYING) {
progressBar.setVisibility(View.GONE);
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(#NotNull PlaybackException error) {
Log.e(TAG, "onPlayerError: ", error);
player.stop();
// errorDialog();
player.prepare(mediaSource);
player.setPlayWhenReady(true);
}
#Override
public void onPositionDiscontinuity(int reason) {
Log.d(TAG, "onPositionDiscontinuity: true");
}
#Override
public void onPlaybackParametersChanged(#NotNull PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
});
Log.d("INFO", "ActivityVideoPlayer");
}
private void pausePlayer() {
player.setPlayWhenReady(false);
player.getPlaybackState();
}
private void startPlayer() {
player.setPlayWhenReady(true);
player.getPlaybackState();
}
#Override
protected void onPause() {
super.onPause();
try {
unRegisterListener();
pausePlayer();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onResume() {
super.onResume();
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
/////////////////////////////////////////////
try {
registerListener();
if (HelperClass.vpn(this)) {
finish();
}
startPlayer();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
Log.v(TAG, "onDestroy()...");
if (player != null)
player.release();
}
private MediaSource buildMediaSource(Uri uri, String overrideExtension) {
int type = TextUtils.isEmpty(overrideExtension) ? Util.inferContentType(uri)
: Util.inferContentType("." + overrideExtension);
switch (type) {
case C.TYPE_SS:
return new SsMediaSource.Factory(new DefaultSsChunkSource.Factory(mediaDataSourceFactory), buildDataSourceFactory(false)).createMediaSource(uri);
case C.TYPE_DASH:
return new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(mediaDataSourceFactory), buildDataSourceFactory(false)).createMediaSource(uri);
case C.TYPE_HLS:
return new HlsMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
case C.TYPE_OTHER:
return new ProgressiveMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
default: {
throw new IllegalStateException("Unsupported type: " + type);
}
}
}
private DataSource.Factory buildDataSourceFactory(boolean useBandwidthMeter) {
return buildDataSourceFactory(useBandwidthMeter ? BANDWIDTH_METER : null);
}
public DataSource.Factory buildDataSourceFactory(DefaultBandwidthMeter bandwidthMeter) {
return new DefaultDataSourceFactory(this, bandwidthMeter,
buildHttpDataSourceFactory(bandwidthMeter));
}
public HttpDataSource.Factory buildHttpDataSourceFactory(DefaultBandwidthMeter bandwidthMeter) {
String s = "xxxxx";
if (userAgent != null && !userAgent.isEmpty()) {
s = userAgent;
}
return new DefaultHttpDataSourceFactory(getUserAgent2(this, s), bandwidthMeter);
}
public static String getUserAgent2(Context context, String applicationName) {
return applicationName
+ "";
}
#Override
public void onBackPressed() {
super.onBackPressed();
if (interstitial != null) {
interstitial.show(Exo_Player.this);
}
if (player != null)
player.stop();
}
// public void errorDialog() {
// new AlertDialog.Builder(this)
// .setIcon(android.R.drawable.ic_dialog_alert)
// .setTitle(getResources().getString(R.string.msg_oops))
// .setCancelable(false)
// .setMessage(getResources().getString(R.string.msg_failed))
// .setPositiveButton(getResources().getString(R.string.option_retry), new DialogInterface.OnClickListener() {
// #Override
// public void onClick(DialogInterface dialog, int which) {
// retryLoad();
// z }
//
// })
// .setNegativeButton(getResources().getString(R.string.option_no), new DialogInterface.OnClickListener() {
// #Override
// public void onClick(DialogInterface dialogInterface, int i) {
// finish();
// }
// })
// .show();
// }
// public void retryLoad() {
// Uri uri = Uri.parse(url);
// MediaSource mediaSource = buildMediaSource(uri, null);
// player.prepare(mediaSource);
// player.setPlayWhenReady(true);
// }
public void castplayer(String name, String link, String unique, String img) {
if (!isCastApiAvailable()) {
return;
}
Context context = this;
CastSession castSession = CastContext.getSharedInstance(context).getSessionManager()
.getCurrentCastSession();
if (castSession.isConnected()) {
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_GENERIC);
movieMetadata.putString(MediaMetadata.KEY_TITLE, name);
MediaInfo mediaInfo = new MediaInfo.Builder(link)
.setMetadata(movieMetadata)
.setEntity(unique)
.build();
final RemoteMediaClient remoteMediaClient = castSession.getRemoteMediaClient();
if (remoteMediaClient == null) {
// Timber.tag(TAG).w("showQueuePopup(): null RemoteMediaClient");
return;
}
if (remoteMediaClient.isPlaying()) {
MediaInfo curMedia = remoteMediaClient.getMediaInfo();
if (curMedia != null && curMedia.getEntity().equals(unique)) {
return;
}
}
if (remoteMediaClient.isLoadingNextItem() || remoteMediaClient.isBuffering()) {
return;
}
// final QueueDataProvider provider = QueueDataProvider.getInstance(context);
// PopupMenu popup = new PopupMenu(context, binding.epLayout);
// popup.getMenuInflater().inflate(
// provider.isQueueDetached() || provider.getCount() == 0
// ? R.menu.detached_popup_add_to_queue
// : R.menu.popup_add_to_queue, popup.getMenu());
// PopupMenu.OnMenuItemClickListener clickListener = menuItem -> {
// QueueDataProvider provider1 = QueueDataProvider.getInstance(context);
// MediaQueueItem queueItem = new MediaQueueItem.Builder(mediaInfo).setAutoplay(
// false).setPreloadTime(2).build();
// MediaQueueItem[] newItemArray = new MediaQueueItem[]{queueItem};
// String toastMessage = null;
// if (provider1.isQueueDetached() && provider1.getCount() > 0) {
// if ((menuItem.getItemId() == R.id.action_play_now)
// || (menuItem.getItemId() == R.id.action_add_to_queue)) {
// MediaQueueItem[] items = Utils
// .rebuildQueueAndAppend(provider1.getItems(), queueItem);
// remoteMediaClient.queueLoad(items, provider1.getCount(),
// MediaStatus.REPEAT_MODE_REPEAT_OFF, null);
// } else {
// return false;
// }
// } else {
// if (provider1.getCount() == 0) {
// remoteMediaClient.queueLoad(newItemArray, 0,
// MediaStatus.REPEAT_MODE_REPEAT_OFF, null);
// } else {
// int currentId = provider1.getCurrentItemId();
//// if (menuItem.getItemId() == R.id.action_play_now) {
// remoteMediaClient.queueInsertAndPlayItem(queueItem, currentId, null);
remoteMediaClient.load(mediaInfo, new MediaLoadOptions.Builder().build());
// } else if (menuItem.getItemId() == R.id.action_play_next) {
// int currentPosition = provider1.getPositionByItemId(currentId);
// if (currentPosition == provider1.getCount() - 1) {
// //we are adding to the end of queue
// remoteMediaClient.queueAppendItem(queueItem, null);
// } else {
// int nextItemId = provider1.getItem(currentPosition + 1).getItemId();
// remoteMediaClient.queueInsertItems(newItemArray, nextItemId, null);
// }
// toastMessage = context.getString(
// R.string.queue_item_added_to_play_next);
// } else if (menuItem.getItemId() == R.id.action_add_to_queue) {
// remoteMediaClient.queueAppendItem(queueItem, null);
// toastMessage = context.getString(R.string.queue_item_added_to_queue);
// } else {
// return false;
// }
// }
// }
// if (menuItem.getItemId() == R.id.action_play_now) {
Intent intent = new Intent(context, ExpandedControlsActivity.class);
context.startActivity(intent);
// }
// if (!TextUtils.isEmpty(toastMessage)) {
// Toast.makeText(context, toastMessage, Toast.LENGTH_SHORT).show();
// }
// return true;
// };
// popup.setOnMenuItemClickListener(clickListener);
// popup.show();
// }
} else {
Toast.makeText(context,
"Not Connected", Toast.LENGTH_SHORT).show();
}
}
private CastContext mCastContext;
private CastSession mCastSession;
private SessionManagerListener<CastSession> mSessionManagerListener;
private void listenCast() {
if (!isCastApiAvailable()) {
return;
}
setupCastListener();
mCastContext = CastContext.getSharedInstance(this);
mCastSession = mCastContext.getSessionManager().getCurrentCastSession();
}
private void setupCastListener() {
mSessionManagerListener = new SessionManagerListener<CastSession>() {
#Override
public void onSessionEnded(CastSession session, int error) {
onApplicationDisconnected();
mCastContext = null;
mCastSession = null;
}
#Override
public void onSessionResumed(CastSession session, boolean wasSuspended) {
onApplicationConnected(session);
}
#Override
public void onSessionResumeFailed(CastSession session, int error) {
onApplicationDisconnected();
}
#Override
public void onSessionStarted(CastSession session, String sessionId) {
onApplicationConnected(session);
}
#Override
public void onSessionStartFailed(CastSession session, int error) {
onApplicationDisconnected();
}
#Override
public void onSessionStarting(CastSession session) {
}
#Override
public void onSessionEnding(CastSession session) {
}
#Override
public void onSessionResuming(CastSession session, String sessionId) {
}
#Override
public void onSessionSuspended(CastSession session, int reason) {
}
private void onApplicationConnected(CastSession castSession) {
mCastSession = castSession;
openCastPlayer();
invalidateOptionsMenu();
}
private void onApplicationDisconnected() {
invalidateOptionsMenu();
}
};
}
private void openCastPlayer() {
castplayer(getString(R.string.app_name), url, url, url);
finish();
}
}
I remember that was changed with the newer updates at some point last year. Now you need to pass a map to setDefaultRequestProperties after building a HttpDataSource. Using a DefaultHttpDataSource.Factory should be enough if you are not considering using a custom one.
I'm creating an app using a MLkit and finally I made it. But it's not working and keep send me a errors I can't understand why error keep occurs.. here is my code and error pls help me
I just copied from MLKit example quick start sample for only using a pose
detector and it says " Invalid model name" .. I don't know why it does saying can you guys help me??
/*
* Copyright 2020 Google LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.pose;
import androidx.camera.core.ImageAnalysis;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.util.Size;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.ToggleButton;
import androidx.camera.core.CameraInfoUnavailableException;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback;
import androidx.core.content.ContextCompat;
import com.google.android.gms.common.annotation.KeepName;
import com.google.mlkit.common.MlKitException;
import com.google.mlkit.common.model.LocalModel;
import com.example.pose.CameraXViewModel;
import com.example.pose.GraphicOverlay;
import com.google.mlkit.vision.demo.R;
import com.example.pose.VisionImageProcessor;
import com.example.pose.posedetector.PoseDetectorProcessor;
import com.example.pose.preference.PreferenceUtils;
import com.google.mlkit.vision.pose.PoseDetectorOptions;
import java.util.ArrayList;
import java.util.List;
/** Live preview demo app for ML Kit APIs using CameraX. */
#KeepName
#RequiresApi(VERSION_CODES.LOLLIPOP)
public final class CameraXLivePreviewActivity extends AppCompatActivity
implements OnRequestPermissionsResultCallback,
OnItemSelectedListener,
CompoundButton.OnCheckedChangeListener {
private static final String TAG = "CameraXLivePreview";
private static final int PERMISSION_REQUESTS = 1;
private static final String OBJECT_DETECTION = "Object Detection";
private static final String POSE_DETECTION = "Pose Detection";
private static final String STATE_SELECTED_MODEL = "selected_model";
private static final String STATE_LENS_FACING = "lens_facing";
private PreviewView previewView;
private GraphicOverlay graphicOverlay;
#Nullable private ProcessCameraProvider cameraProvider;
#Nullable private Preview previewUseCase;
#Nullable private ImageAnalysis analysisUseCase;
#Nullable private VisionImageProcessor imageProcessor;
private boolean needUpdateGraphicOverlayImageSourceInfo;
private String selectedModel = OBJECT_DETECTION;
private int lensFacing = CameraSelector.LENS_FACING_BACK;
private CameraSelector cameraSelector;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
Toast.makeText(
getApplicationContext(),
"CameraX is only supported on SDK version >=21. Current SDK version is "
+ VERSION.SDK_INT,
Toast.LENGTH_LONG)
.show();
return;
}
if (savedInstanceState != null) {
selectedModel = savedInstanceState.getString(STATE_SELECTED_MODEL, OBJECT_DETECTION);
lensFacing = savedInstanceState.getInt(STATE_LENS_FACING, CameraSelector.LENS_FACING_BACK);
}
cameraSelector = new CameraSelector.Builder().requireLensFacing(lensFacing).build();
setContentView(R.layout.activity_vision_camerax_live_preview);
previewView = findViewById(R.id.preview_view);
if (previewView == null) {
Log.d(TAG, "previewView is null");
}
graphicOverlay = findViewById(R.id.graphic_overlay);
if (graphicOverlay == null) {
Log.d(TAG, "graphicOverlay is null");
}
ToggleButton facingSwitch = findViewById(R.id.facing_switch);
facingSwitch.setOnCheckedChangeListener(this);
new ViewModelProvider(this, AndroidViewModelFactory.getInstance(getApplication()))
.get(CameraXViewModel.class)
.getProcessCameraProvider()
.observe(
this,
provider -> {
cameraProvider = provider;
if (allPermissionsGranted()) {
bindAllCameraUseCases();
}
});
if (!allPermissionsGranted()) {
getRuntimePermissions();
}
}
#Override
protected void onSaveInstanceState(#NonNull Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putString(STATE_SELECTED_MODEL, selectedModel);
bundle.putInt(STATE_LENS_FACING, lensFacing);
}
#Override
public synchronized void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// An item was selected. You can retrieve the selected item using
// parent.getItemAtPosition(pos)
selectedModel = parent.getItemAtPosition(pos).toString();
Log.d(TAG, "Selected model: " + selectedModel);
bindAnalysisUseCase();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.d(TAG, "Set facing");
if (cameraProvider == null) {
return;
}
int newLensFacing =
lensFacing == CameraSelector.LENS_FACING_FRONT
? CameraSelector.LENS_FACING_BACK
: CameraSelector.LENS_FACING_FRONT;
CameraSelector newCameraSelector =
new CameraSelector.Builder().requireLensFacing(newLensFacing).build();
try {
if (cameraProvider.hasCamera(newCameraSelector)) {
lensFacing = newLensFacing;
cameraSelector = newCameraSelector;
bindAllCameraUseCases();
return;
}
} catch (CameraInfoUnavailableException e) {
// Falls through
}
Toast.makeText(
getApplicationContext(),
"This device does not have lens with facing: " + newLensFacing,
Toast.LENGTH_SHORT)
.show();
}
#Override
public void onResume() {
super.onResume();
bindAllCameraUseCases();
}
#Override
protected void onPause() {
super.onPause();
if (imageProcessor != null) {
imageProcessor.stop();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (imageProcessor != null) {
imageProcessor.stop();
}
}
private void bindAllCameraUseCases() {
if (cameraProvider != null) {
// As required by CameraX API, unbinds all use cases before trying to re-bind any of them.
cameraProvider.unbindAll();
bindPreviewUseCase();
bindAnalysisUseCase();
}
}
private void bindPreviewUseCase() {
if (!PreferenceUtils.isCameraLiveViewportEnabled(this)) {
return;
}
if (cameraProvider == null) {
return;
}
if (previewUseCase != null) {
cameraProvider.unbind(previewUseCase);
}
previewUseCase = new Preview.Builder().build();
previewUseCase.setSurfaceProvider(previewView.createSurfaceProvider());
cameraProvider.bindToLifecycle(/* lifecycleOwner= */ this, cameraSelector, previewUseCase);
}
private void bindAnalysisUseCase() {
if (cameraProvider == null) {
return;
}
if (analysisUseCase != null) {
cameraProvider.unbind(analysisUseCase);
}
if (imageProcessor != null) {
imageProcessor.stop();
}
try {
switch (selectedModel) {
case POSE_DETECTION:
PoseDetectorOptions poseDetectorOptions =
PreferenceUtils.getPoseDetectorOptionsForLivePreview(this);
boolean shouldShowInFrameLikelihood =
PreferenceUtils.shouldShowPoseDetectionInFrameLikelihoodLivePreview(this);
imageProcessor =
new PoseDetectorProcessor(this, poseDetectorOptions, shouldShowInFrameLikelihood);
break;
default:
throw new IllegalStateException("Invalid model name");
}
} catch (Exception e) {
Log.e(TAG, "Can not create image processor: " + selectedModel, e);
Toast.makeText(
getApplicationContext(),
"Can not create image processor: " + e.getLocalizedMessage(),
Toast.LENGTH_LONG)
.show();
return;
}
ImageAnalysis.Builder builder = new ImageAnalysis.Builder();
Size targetAnalysisSize = PreferenceUtils.getCameraXTargetAnalysisSize(this);
if (targetAnalysisSize != null) {
builder.setTargetResolution(targetAnalysisSize);
}
analysisUseCase = builder.build();
needUpdateGraphicOverlayImageSourceInfo = true;
analysisUseCase.setAnalyzer(
// imageProcessor.processImageProxy will use another thread to run the detection underneath,
// thus we can just runs the analyzer itself on main thread.
ContextCompat.getMainExecutor(this),
imageProxy -> {
if (needUpdateGraphicOverlayImageSourceInfo) {
boolean isImageFlipped = lensFacing == CameraSelector.LENS_FACING_FRONT;
int rotationDegrees = imageProxy.getImageInfo().getRotationDegrees();
if (rotationDegrees == 0 || rotationDegrees == 180) {
graphicOverlay.setImageSourceInfo(
imageProxy.getWidth(), imageProxy.getHeight(), isImageFlipped);
} else {
graphicOverlay.setImageSourceInfo(
imageProxy.getHeight(), imageProxy.getWidth(), isImageFlipped);
}
needUpdateGraphicOverlayImageSourceInfo = false;
}
try {
imageProcessor.processImageProxy(imageProxy, graphicOverlay);
} catch (MlKitException e) {
Log.e(TAG, "Failed to process image. Error: " + e.getLocalizedMessage());
Toast.makeText(getApplicationContext(), e.getLocalizedMessage(), Toast.LENGTH_SHORT)
.show();
}
});
cameraProvider.bindToLifecycle(/* lifecycleOwner= */ this, cameraSelector, analysisUseCase);
}
private String[] getRequiredPermissions() {
try {
PackageInfo info =
this.getPackageManager()
.getPackageInfo(this.getPackageName(), PackageManager.GET_PERMISSIONS);
String[] ps = info.requestedPermissions;
if (ps != null && ps.length > 0) {
return ps;
} else {
return new String[0];
}
} catch (Exception e) {
return new String[0];
}
}
private boolean allPermissionsGranted() {
for (String permission : getRequiredPermissions()) {
if (!isPermissionGranted(this, permission)) {
return false;
}
}
return true;
}
private void getRuntimePermissions() {
List<String> allNeededPermissions = new ArrayList<>();
for (String permission : getRequiredPermissions()) {
if (!isPermissionGranted(this, permission)) {
allNeededPermissions.add(permission);
}
}
if (!allNeededPermissions.isEmpty()) {
ActivityCompat.requestPermissions(
this, allNeededPermissions.toArray(new String[0]), PERMISSION_REQUESTS);
}
}
#Override
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
Log.i(TAG, "Permission granted!");
if (allPermissionsGranted()) {
bindAllCameraUseCases();
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private static boolean isPermissionGranted(Context context, String permission) {
if (ContextCompat.checkSelfPermission(context, permission)
== PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission granted: " + permission);
return true;
}
Log.i(TAG, "Permission NOT granted: " + permission);
return false;
}
}
E/CameraXLivePreview: Can not create image processor: Object Detection
java.lang.IllegalStateException: Invalid model name
at com.example.pose.CameraXLivePreviewActivity.bindAnalysisUseCase(CameraXLivePreviewActivity.java:271)
at com.example.pose.CameraXLivePreviewActivity.bindAllCameraUseCases(CameraXLivePreviewActivity.java:229)
at com.example.pose.CameraXLivePreviewActivity.onCheckedChanged(CameraXLivePreviewActivity.java:187)
at android.widget.CompoundButton.setChecked(CompoundButton.java:218)
at android.widget.ToggleButton.setChecked(ToggleButton.java:81)
at android.widget.CompoundButton.toggle(CompoundButton.java:137)
at android.widget.CompoundButton.performClick(CompoundButton.java:142)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Please change this line to let the feature selector to select Pose detection
"private String selectedModel = OBJECT_DETECTION;"
to
"private String selectedModel = POSE_DETECTION;"
I am attempting to to create a widget from a native view navigation map using method channels and AndroidViews but I keep running into this problem:
E/MethodChannel#flutter/platform_views( 2258): Failed to handle method call
E/MethodChannel#flutter/platform_views( 2258): java.lang.IllegalArgumentException: Cannot add a null child view to a ViewGroup.
Here is the flutter Code :
Main.dart
import 'navigation_view.dart';
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'customButton1.dart';
import 'Constantes.dart';
void main() => runApp(MaterialApp(home: TextViewExample()));
class TextViewExample extends StatefulWidget {
#override
_TextViewExampleState createState() => _TextViewExampleState();
}
class _TextViewExampleState extends State<TextViewExample>
with SingleTickerProviderStateMixin {
#override
void initState() {
super.initState();
}
Widget build(BuildContext context) {
// var s = NavigationView(
// onNavigationViewCreated: _onNavigationViewCreated,
// );
double screenWidth, screenHeight;
Size size = MediaQuery.of(context).size;
screenHeight = size.height;
screenWidth = size.width;
print("FLUTTER INIT");
return Scaffold(
body: SafeArea(
child: Stack(children: [
Positioned(
width: screenWidth,
height: screenHeight - 220,
child: Container(
child: NavigationView(
onNavigationViewCreated: _onNavigationViewCreated,
),
),
),
Positioned(
bottom: 75,
child: Container(
height: screenHeight,
width: screenWidth,
void _onNavigationViewCreated(NavigationViewController controller) {}
}
Here is navigation_view.dart
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
typedef void NavigationViewCreatedCallback(NavigationViewController controller);
class NavigationView extends StatefulWidget {
const NavigationView({
Key key,
this.onNavigationViewCreated,
}) : super(key: key);
final NavigationViewCreatedCallback onNavigationViewCreated;
#override
State<StatefulWidget> createState() => _NavigationViewState();
}
class _NavigationViewState extends State<NavigationView> {
#override
Widget build(BuildContext context) {
if (defaultTargetPlatform == TargetPlatform.android) {
return AndroidView(
viewType: 'com.Mavic.Cabinn/navigationview',
onPlatformViewCreated: _onPlatformViewCreated,
);
}
return Text(
'$defaultTargetPlatform is not yet supported by the navigation_view plugin');
}
void _onPlatformViewCreated(int id) {
if (widget.onNavigationViewCreated == null) {
return;
}
widget.onNavigationViewCreated(new NavigationViewController._(id));
}
}
class NavigationViewController {
NavigationViewController._(int id)
: _channel = new MethodChannel(
'com.Mavic.Cabinn/navigationview$id');
final MethodChannel _channel;
// Future<void> setNavigation() async {
// try {
// Future.delayed(const Duration(seconds: 1), () async {
// await _channel.invokeMethod('EmpezarNavegacion');
//
// return;
// });
// } on PlatformException catch (e) {
// print(e);
// }
// Future<void> setNavigation() async {
// assert(AndroidView != null);
// return _channel.invokeMethod('EmpezarNavegacion');
// }
//}
Future<dynamic> setNavigation() async {
String message;
try {
final String result = await _channel.invokeMethod('EmpezarNagevacion');
message = result;
} on PlatformException catch (e) {
print(message);
}
}
}
And Finally the Java Code
package com.example.embeded_java_test;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.location.Location;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.AbsoluteSizeSpan;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.mapbox.api.directions.v5.DirectionsCriteria;
import com.mapbox.api.directions.v5.models.BannerInstructions;
import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute;
import com.example.embeded_java_test.R;
import com.mapbox.services.android.navigation.ui.v5.NavigationView;
import com.mapbox.services.android.navigation.ui.v5.NavigationViewOptions;
import com.mapbox.services.android.navigation.ui.v5.OnNavigationReadyCallback;
//import com.mapbox.services.android.navigation.ui.v5.listeners.BannerInstructionsListener;
//import com.mapbox.services.android.navigation.ui.v5.listeners.InstructionListListener;
import com.mapbox.services.android.navigation.ui.v5.listeners.BannerInstructionsListener;
import com.mapbox.services.android.navigation.ui.v5.listeners.InstructionListListener;
import com.mapbox.services.android.navigation.ui.v5.listeners.NavigationListener;
//import com.mapbox.services.android.navigation.ui.v5.listeners.SpeechAnnouncementListener;
//import com.mapbox.services.android.navigation.ui.v5.voice.SpeechAnnouncement;
import com.mapbox.services.android.navigation.ui.v5.listeners.SpeechAnnouncementListener;
import com.mapbox.services.android.navigation.ui.v5.voice.SpeechAnnouncement;
import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute;
import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
import java.util.Locale;
import java.util.concurrent.Future;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import org.jetbrains.annotations.NotNull;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.platform.PlatformView;
import com.example.embeded_java_test.MainActivity;
public class EmbeddedNavigationActivity extends AppCompatActivity implements OnNavigationReadyCallback,
NavigationListener, ProgressChangeListener, InstructionListListener, SpeechAnnouncementListener,
BannerInstructionsListener,PlatformView, MethodCallHandler {
private Point ORIGIN = Point.fromLngLat(-77.03194990754128, 38.909664963450105);
private Point DESTINATION = Point.fromLngLat(-77.0270025730133, 38.91057077063121);
private final int INITIAL_ZOOM = 16;
private NavigationView navigationView;
private View spacer;
private TextView speedWidget;
private final MethodChannel methodChannel;
private boolean bottomSheetVisible = true;
private boolean instructionListShown = false;
private NavigationMapRoute navigationMapRoute;
// #Override
// public void onCreate(#Nullable Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// navigationView = findViewById(R.id.navigationView);
// navigationView.onCreate(savedInstanceState);
// setTheme(R.style.Theme_AppCompat_Light_NoActionBar);
// //initNightMode();
#Override
public void dispose() {}
private Context context;
private Activity activity;
private Bundle savedInstance;
public EmbeddedNavigationActivity(Context currentContext, Activity currentActivity, Bundle currentBundle,BinaryMessenger messenger, int id)
{
new MainActivity();
MainActivity newMain = new MainActivity();
this.activity=this;
System.out.println(activity + "Activity");
this.context=this;
System.out.println(context + "Context");
System.out.println(activity);
Log.i("Here", "Constructor!!!");
System.out.println(activity + " This Activity");
this.savedInstance=currentBundle;
System.out.println(currentContext + "Context");
//
methodChannel = new MethodChannel(messenger, "com.Mavic.Cabinn/navigationview_" + id);
methodChannel.setMethodCallHandler(this);
}
#Override
public View getView() {
Log.i("Here", "GETVIEW");
return navigationView;
}
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
Log.i("MSG", "CALLING SET TEXT");
switch (methodCall.method) {
case "EmpezarNavegacion":
EmpezarNavegacion(methodCall, result);
result.success(null);
break;
default:
result.notImplemented();
}
}
public void EmpezarNavegacion(MethodCall methodCall, Result result)
{
double LtLang = (double) methodCall.arguments;
result.success(null);
Mapbox.getInstance(context, activity.getString(R.string.access_token));
activity.setContentView(R.layout.cabinn_nav);
navigationView =activity.findViewById(R.id.navigationView);
//super.onCreate(savedInstanceState);
//Mapbox.getInstance(this,getString(R.string.access_token));
//navigationView =(NavigationView)findViewById(R.id.navigationView);
if(navigationView==null)
{
Log.e("ERROR NAVEGACION","NAVIGATION VIEW ES NULL, NO ESTA SETEADO EL CONTENT");
return;
}
//fabNightModeToggle = findViewById(R.id.fabToggleNightMode);
//speedWidget = findViewById(R.id.speed_limit);
//spacer = findViewById(R.id.spacer);
//setSpeedWidgetAnchor(R.id.summaryBottomSheet);
// ORIGIN=ORIGEN;
// DESTINATION=DESTINO;
CameraPosition initialPosition = new CameraPosition.Builder()
.target(new LatLng(ORIGIN.latitude(), ORIGIN.longitude()))
.zoom(INITIAL_ZOOM)
.build();
//navigationView.onCreate(savedInstanceState);
navigationView.onCreate(this.savedInstance);
navigationView.initialize(this, initialPosition);
}
#Override
public void onNavigationReady(boolean isRunning) {
//navigationView.findViewById(R.id.instructionLayoutText).setVisibility(View.INVISIBLE);
navigationView.findViewById(R.id.instructionListLayout).setVisibility(View.INVISIBLE);
//navigationView.findViewById(R.id.maneuverView).setVisibility(View.INVISIBLE);
navigationView.findViewById(R.id.summaryBottomSheet).setVisibility(View.INVISIBLE);
navigationView.findViewById(R.id.feedbackFab).setVisibility(View.INVISIBLE);
navigationView.findViewById(R.id.subStepText).setVisibility(View.INVISIBLE);
navigationView.findViewById(R.id.subStepLayout).setVisibility(View.INVISIBLE);
navigationView.findViewById(R.id.summaryContentLayout).setVisibility(View.INVISIBLE);
//navigationView.findViewById(R.id.subManeuverView).setVisibility(View.INVISIBLE);
//navigationView.findViewById(R.id.stepDistanceText).setVisibility(View.INVISIBLE);
//navigationView.findViewById(R.id.stepPrimaryText).setVisibility(View.INVISIBLE);
//navigationView.findViewById(R.id.stepSecondaryText).setVisibility(View.INVISIBLE);
fetchRoute();
}
public void onStart_() {
Log.i("NAV","NAVIGATION START");
navigationView.onStart();
}
public void onResume_() {
navigationView.onResume();
}
public void onLowMemory_() {
navigationView.onLowMemory();
}
public void onBackPressed_() {
// If the navigation view didn't need to do anything, call super
if (!navigationView.onBackPressed()) {
super.onBackPressed();
}
}
protected void onSaveInstanceState_(Bundle outState) {
navigationView.onSaveInstanceState(outState);
}
protected void onRestoreInstanceState_(Bundle savedInstanceState) {
navigationView.onRestoreInstanceState(savedInstanceState);
}
public void onPause_() {
navigationView.onPause();
}
public void onStop_() {
navigationView.onStop();
}
protected void onDestroy_() {
navigationView.onDestroy();
if (isFinishing()) {
saveNightModeToPreferences(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
}
}
#Override
public void onCancelNavigation() {
// Navigation canceled, finish the activity
finish();
}
#Override
public void onNavigationFinished() {
// Intentionally empty
}
#Override
public void onNavigationRunning() {
// Intentionally empty
}
#Override
public void onProgressChange(Location location, RouteProgress routeProgress) {
setSpeed(location);
}
#Override
public void onInstructionListVisibilityChanged(boolean shown) {
instructionListShown = shown;
speedWidget.setVisibility(shown ? View.GONE : View.VISIBLE);
if (instructionListShown) {
// fabNightModeToggle.hide();
} else if (bottomSheetVisible) {
//fabNightModeToggle.show();
}
}
#Override
public SpeechAnnouncement willVoice(SpeechAnnouncement announcement) {
return SpeechAnnouncement.builder().announcement("All announcements will be the same.").build();
}
#Override
public BannerInstructions willDisplay(BannerInstructions instructions) {
return instructions;
}
private void startNavigation(DirectionsRoute directionsRoute) {
NavigationViewOptions.Builder options =
NavigationViewOptions.builder()
.navigationListener(this)
.directionsRoute(directionsRoute)
.shouldSimulateRoute(true)
.progressChangeListener(this);
//.instructionListListener(this)
//.speechAnnouncementListener(this)
// .bannerInstructionsListener(this);
setBottomSheetCallback(options);
//setupNightModeFab();
navigationView.startNavigation(options.build());
}
private void fetchRoute() {
NavigationRoute.builder(this.context)
.accessToken(this.activity.getString(R.string.access_token))
.origin(ORIGIN)
.voiceUnits(DirectionsCriteria.METRIC)
.destination(DESTINATION)
.alternatives(true)
.build()
.getRoute(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
if(response.body() == null)
{
Log.e("ERROR RUTA","NO RUTA ENCONTRADA");
return;
}else if(response.body().routes().size()==0)
{
Log.e("ERROR RUTA","SIN RUTA ENCONTRADA");
return;
}
DirectionsRoute currentRoute = response.body().routes().get(0);
//navigationMapRoute.addRoute(currentRoute);
startNavigation(currentRoute);
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
}
});
}
void simpleCallBack(Call<DirectionsResponse> call, Response<DirectionsResponse> response)
{
DirectionsRoute directionsRoute = response.body().routes().get(0);
startNavigation(directionsRoute);
}
private void setSpeedWidgetAnchor(#IdRes int res) {
//CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) spacer.getLayoutParams();
//layoutParams.setAnchorId(res);
//spacer.setLayoutParams(layoutParams);
}
private void setBottomSheetCallback(NavigationViewOptions.Builder options) {
options.bottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_HIDDEN:
bottomSheetVisible = false;
//fabNightModeToggle.hide();
setSpeedWidgetAnchor(R.id.recenterBtn);
break;
case BottomSheetBehavior.STATE_EXPANDED:
bottomSheetVisible = true;
break;
case BottomSheetBehavior.STATE_SETTLING:
if (!bottomSheetVisible) {
// View needs to be anchored to the bottom sheet before it is finished expanding
// because of the animation
//fabNightModeToggle.show();
setSpeedWidgetAnchor(R.id.summaryBottomSheet);
}
break;
default:
return;
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
}
});
}
private void setupNightModeFab() {
//fabNightModeToggle.setOnClickListener(view -> toggleNightMode());
}
private void toggleNightMode() {
int currentNightMode = getCurrentNightMode();
alternateNightMode(currentNightMode);
}
private void initNightMode() {
// int nightMode = retrieveNightModeFromPreferences();
//AppCompatDelegate.setDefaultNightMode(nightMode);
}
private int getCurrentNightMode() {
return getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK;
}
private void alternateNightMode(int currentNightMode) {
int newNightMode;
if (currentNightMode == Configuration.UI_MODE_NIGHT_YES) {
newNightMode = AppCompatDelegate.MODE_NIGHT_NO;
} else {
newNightMode = AppCompatDelegate.MODE_NIGHT_YES;
}
saveNightModeToPreferences(newNightMode);
recreate();
}
private void saveNightModeToPreferences(int nightMode) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
//editor.putInt(getString(R.string.current_night_mode), nightMode);
editor.apply();
}
private void setSpeed(Location location) {
String string = String.format("%d\nMPH", (int) (location.getSpeed() * 2.2369));
//int mphTextSize = getResources().getDimensionPixelSize(R.dimen.mph_text_size);
//int speedTextSize = getResources().getDimensionPixelSize(R.dimen.speed_text_size);
SpannableString spannableString = new SpannableString(string);
// spannableString.setSpan(new AbsoluteSizeSpan(mphTextSize),
// string.length() - 4, string.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
// spannableString.setSpan(new AbsoluteSizeSpan(speedTextSize),
// 0, string.length() - 3, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
}
I used this article as reference in order to attempt to replicate this but I hit many a speed bump trying to get this to work properly: https://medium.com/flutter-community/flutter-platformview-how-to-create-flutter-widgets-from-native-views-366e378115b6
This is my flutter doctor output:
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.12.13+hotfix.9, on Linux, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Android Studio (version 3.6)
[✓] Connected device (1 available)
• No issues found!
Like I was saying ive been attempting to find a null value and searched high and low for questions similar to this one but Ive had no such luck as this is not something Ive seen done. I also checked if there were any plugins to create and embedded map and unfortunately there arent any at the moment.
I am creating an android camera app using opencv. First I make it like when I click the start button, it start taking pictures and in every second takes a picture and store it in storage. It works perfectly for me.
Then I tried to make it some tricky by forcing it to take 5 pictures in a second it works well.
But actually I faced problem when I make it to 20 pictures in 1 second. It did not work. The app hangs as soon as I click on the start button. I don't know why. But I think the problem is in threading.
Can someone help me how i will do it.
I have two java files in my project and here is the code.
package org.opencv.samples.tutorial3;
import java.io.FileOutputStream;
import java.util.List;
import org.opencv.android.JavaCameraView;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.util.AttributeSet;
import android.util.Log;
public class Tutorial3View extends JavaCameraView implements PictureCallback {
private static final String TAG = "Sample::Tutorial3View";
private String mPictureFileName;
public Tutorial3View(Context context, AttributeSet attrs) {
super(context, attrs);
}
public List<String> getEffectList() {
return mCamera.getParameters().getSupportedColorEffects();
}
public boolean isEffectSupported() {
return (mCamera.getParameters().getColorEffect() != null);
}
public String getEffect() {
return mCamera.getParameters().getColorEffect();
}
public void setEffect(String effect) {
Camera.Parameters params = mCamera.getParameters();
params.setColorEffect(effect);
mCamera.setParameters(params);
}
public List<Size> getResolutionList() {
return mCamera.getParameters().getSupportedPreviewSizes();
}
public void setResolution(Size resolution) {
disconnectCamera();
mMaxHeight = resolution.height;
mMaxWidth = resolution.width;
connectCamera(getWidth(), getHeight());
}
public Size getResolution() {
return mCamera.getParameters().getPreviewSize();
}
public void takePicture(final String fileName) {
Log.i(TAG, "Taking picture");
this.mPictureFileName = fileName;
// Postview and jpeg are sent in the same buffers if the queue is not empty when performing a capture.
// Clear up buffers to avoid mCamera.takePicture to be stuck because of a memory issue
mCamera.setPreviewCallback(null);
// PictureCallback is implemented by the current class
mCamera.takePicture(null, null, this);
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(TAG, "Saving a bitmap to file");
// The camera preview was automatically stopped. Start it again.
mCamera.startPreview();
mCamera.setPreviewCallback(this);
// Write the image in a file (in jpeg format)
try {
FileOutputStream fos = new FileOutputStream(mPictureFileName);
fos.write(data);
fos.close();
} catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
}
}
And the second one is:
package org.opencv.samples.tutorial3;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
public class Tutorial3Activity extends Activity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
private Tutorial3View mOpenCvCameraView;
private List<Size> mResolutionList;
private MenuItem[] mEffectMenuItems;
private SubMenu mColorEffectsMenu;
private MenuItem[] mResolutionMenuItems;
private SubMenu mResolutionMenu;
Thread thread;
Button start,stop;
boolean loop=false;
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
#Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
public Tutorial3Activity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.tutorial3_surface_view);
start=(Button)findViewById(R.id.button2) ;
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loop=true;
thread = new Thread(new task());
thread.start();
}
});
stop=(Button) findViewById(R.id.button);
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loop=false;
}
});
mOpenCvCameraView = (Tutorial3View) findViewById(R.id.tutorial3_activity_java_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
}
#Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
#Override
public void onResume()
{
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
public void onCameraViewStarted(int width, int height) {
}
public void onCameraViewStopped() {
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
return inputFrame.rgba();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
List<String> effects = mOpenCvCameraView.getEffectList();
if (effects == null) {
Log.e(TAG, "Color effects are not supported by device!");
return true;
}
mColorEffectsMenu = menu.addSubMenu("Color Effect");
mEffectMenuItems = new MenuItem[effects.size()];
int idx = 0;
ListIterator<String> effectItr = effects.listIterator();
while(effectItr.hasNext()) {
String element = effectItr.next();
mEffectMenuItems[idx] = mColorEffectsMenu.add(1, idx, Menu.NONE, element);
idx++;
}
mResolutionMenu = menu.addSubMenu("Resolution");
mResolutionList = mOpenCvCameraView.getResolutionList();
mResolutionMenuItems = new MenuItem[mResolutionList.size()];
ListIterator<Size> resolutionItr = mResolutionList.listIterator();
idx = 0;
while(resolutionItr.hasNext()) {
Size element = resolutionItr.next();
mResolutionMenuItems[idx] = mResolutionMenu.add(2, idx, Menu.NONE,
Integer.valueOf(element.width).toString() + "x" + Integer.valueOf(element.height).toString());
idx++;
}
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);
if (item.getGroupId() == 1)
{
mOpenCvCameraView.setEffect((String) item.getTitle());
Toast.makeText(this, mOpenCvCameraView.getEffect(), Toast.LENGTH_SHORT).show();
}
else if (item.getGroupId() == 2)
{
int id = item.getItemId();
Size resolution = mResolutionList.get(id);
mOpenCvCameraView.setResolution(resolution);
resolution = mOpenCvCameraView.getResolution();
String caption = Integer.valueOf(resolution.width).toString() + "x" + Integer.valueOf(resolution.height).toString();
Toast.makeText(this, caption, Toast.LENGTH_SHORT).show();
}
return true;
}
class task implements Runnable {
public void run() {
while (loop) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
String currentDateandTime = sdf.format(new Date());
final String fileName = Environment.getExternalStorageDirectory().getPath() +
"/sample_picture_" + currentDateandTime + ".jpg";
mOpenCvCameraView.takePicture(fileName);
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(Tutorial3Activity.this, fileName + " saved", Toast.LENGTH_SHORT).show();
}
});
try {
thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Note: The above code works well for taking 5 pictures in 1 second. But when I change thread.sleep(200) to thread.sleep(50) for taking 20 pictures in 1 second it hangs.
I'm trying to create an App that sends a data text via USB Serial from a Android to a computer and receive. I'm using a Sample from Android called AdbTestActivity to try to connect with my device. I am able to find the device but when I try to open the device using UsbDeviceConnection connection = mManager.openDevice(device); It returned me response 'null'
AdbTestActivity.java
package com.android.adb;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Rect;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
/* Main activity for the adb test program */
public class AdbTestActivity extends Activity {
private static final String TAG = "AdbTestActivity";
private TextView mLog;
private UsbManager mManager;
private UsbDevice mDevice;
private UsbDeviceConnection mDeviceConnection;
private UsbInterface mInterface;
private AdbDevice mAdbDevice;
private static final int MESSAGE_LOG = 1;
private static final int MESSAGE_DEVICE_ONLINE = 2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.adb);
mLog = (TextView)findViewById(R.id.log);
mManager = (UsbManager)getSystemService(Context.USB_SERVICE);
// check for existing devices
for (UsbDevice device : mManager.getDeviceList().values()) {
UsbInterface intf = findAdbInterface(device);
if (setAdbInterface(device, intf)) {
break;
}
}
// listen for new devices
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(mUsbReceiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(mUsbReceiver);
setAdbInterface(null, null);
super.onDestroy();
}
public void log(String s) {
Message m = Message.obtain(mHandler, MESSAGE_LOG);
m.obj = s;
mHandler.sendMessage(m);
}
private void appendLog(String text) {
Rect r = new Rect();
mLog.getDrawingRect(r);
int maxLines = r.height() / mLog.getLineHeight() - 1;
text = mLog.getText() + "\n" + text;
// see how many lines we have
int index = text.lastIndexOf('\n');
int count = 0;
while (index > 0 && count <= maxLines) {
count++;
index = text.lastIndexOf('\n', index - 1);
}
// truncate to maxLines
if (index > 0) {
text = text.substring(index + 1);
}
mLog.setText(text);
}
public void deviceOnline(AdbDevice device) {
Message m = Message.obtain(mHandler, MESSAGE_DEVICE_ONLINE);
m.obj = device;
mHandler.sendMessage(m);
}
private void handleDeviceOnline(AdbDevice device) {
log("device online: " + device.getSerial());
device.openSocket("shell:exec logcat");
}
// Sets the current USB device and interface
private boolean setAdbInterface(UsbDevice device, UsbInterface intf) {
if (mDeviceConnection != null) {
if (mInterface != null) {
mDeviceConnection.releaseInterface(mInterface);
mInterface = null;
}
mDeviceConnection.close();
mDevice = null;
mDeviceConnection = null;
}
if (device != null && intf != null) {
//Here returns null connection
UsbDeviceConnection connection = mManager.openDevice(device);
if (connection != null) {
log("open succeeded");
if (connection.claimInterface(intf, false)) {
log("claim interface succeeded");
mDevice = device;
mDeviceConnection = connection;
mInterface = intf;
mAdbDevice = new AdbDevice(this, mDeviceConnection, intf);
log("call start");
mAdbDevice.start();
return true;
} else {
log("claim interface failed");
connection.close();
}
} else {
log("open failed");
}
}
if (mDeviceConnection == null && mAdbDevice != null) {
mAdbDevice.stop();
mAdbDevice = null;
}
return false;
}
// searches for an adb interface on the given USB device
static private UsbInterface findAdbInterface(UsbDevice device) {
Log.d(TAG, "findAdbInterface " + device);
int count = device.getInterfaceCount();
for (int i = 0; i < count; i++) {
UsbInterface intf = device.getInterface(i);
if (intf.getInterfaceClass() == 255 && intf.getInterfaceSubclass() == 66 &&
intf.getInterfaceProtocol() == 1) {
return intf;
}
if (intf.getInterfaceClass() == 2 && intf.getInterfaceSubclass() == 2 &&
intf.getInterfaceProtocol() == 1) {
return intf;
}
}
return null;
}
BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
UsbInterface intf = findAdbInterface(device);
if (intf != null) {
log("Found adb interface " + intf);
setAdbInterface(device, intf);
}
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
String deviceName = device.getDeviceName();
if (mDevice != null && mDevice.equals(deviceName)) {
log("adb interface removed");
setAdbInterface(null, null);
}
}
}
};
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_LOG:
appendLog((String)msg.obj);
break;
case MESSAGE_DEVICE_ONLINE:
handleDeviceOnline((AdbDevice)msg.obj);
break;
}
}
};
}
I also tried to insert my vendor and the product in the device_filter.xml, but it didn't work.
<resources>
<usb-device class="255" subclass="66" protocol="0" />
<usb-device vendor-id="5401" product-id="32" />
</resources>
Manifest
...
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="#xml/device_filter" />
You should ask before permission to open usb device, like that:
final String usbPermissionName = "com.android.example.USB_PERMISSION";
BroadcastReceiver usbPermissionReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (usbPermissionName.equals(intent.getAction())) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
synchronized (this) {
mManager.openDevice(device);
}
}
}
}
};
registerReceiver(usbPermissionReceiver, new IntentFilter(usbPermissionName));
PendingIntent permissionPendingIntent = PendingIntent.getBroadcast(instance, 0, new Intent(usbPermissionName), 0);
usbManager.requestPermission(usbDevice, permissionPendingIntent);